mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
Self-contained HTML5 file that demonstrates the full pipeline: QUBO → Brute-Force Solve → Pixel Encoding → PNG Receipt → Decode Works on any web host on Earth. No WebGPU. No backend. Just canvas. Stages: 1. Generate random 8-variable QUBO (banded, diagonal-dominant) 2. Brute-force solve (256 solutions, instant for n=8) 3. Encode solution as 8×8 Hachimoji pixel grid - x=0 → dark pixel (Φ, rgb 13,13,13) - x=1 → bright pixel (Σ, rgb 26,204,77) 4. Generate PNG receipt (canvas.toDataURL) 5. Decode receipt back from image (verify roundtrip) Features: - Random QUBO generation button - Visual pixel grid with 0/1 labels - Download PNG receipt - Decode verification (matches original) This file can be hosted on: GitHub Pages, Netlify, Vercel, S3, shared hosting, IPFS, data URI in email, QR code scan, any static file server. The receipt IS the image. The image IS the solution. Refs: FBTTY_UNIVERSAL_ENCODER.md (theory), WEBGPU_PIXEL_ENCODER.md (GPU compute version)
287 lines
8.3 KiB
HTML
287 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>SilverSight Universal Encoder — QUBO → Pixels → Receipt</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body {
|
||
font-family: 'Courier New', monospace;
|
||
background: #0a0a0a;
|
||
color: #0f0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 2em;
|
||
min-height: 100vh;
|
||
}
|
||
h1 { color: #0ff; margin-bottom: 0.5em; font-size: 1.4em; }
|
||
.subtitle { color: #888; margin-bottom: 2em; font-size: 0.85em; }
|
||
.stage {
|
||
background: #111;
|
||
border: 1px solid #333;
|
||
border-radius: 4px;
|
||
padding: 1.5em;
|
||
margin: 0.5em 0;
|
||
width: 100%;
|
||
max-width: 600px;
|
||
}
|
||
.stage h2 { color: #ff0; font-size: 1em; margin-bottom: 0.5em; }
|
||
.stage pre { color: #0f0; font-size: 0.8em; overflow-x: auto; }
|
||
canvas {
|
||
image-rendering: pixelated;
|
||
border: 2px solid #0f0;
|
||
margin: 1em 0;
|
||
}
|
||
.receipt {
|
||
background: #1a1a1a;
|
||
border: 1px solid #0f0;
|
||
padding: 1em;
|
||
font-size: 0.75em;
|
||
color: #0f0;
|
||
}
|
||
.receipt img { max-width: 100%; image-rendering: pixelated; }
|
||
button {
|
||
background: #0f0;
|
||
color: #000;
|
||
border: none;
|
||
padding: 0.5em 1em;
|
||
font-family: inherit;
|
||
font-weight: bold;
|
||
cursor: pointer;
|
||
margin: 0.5em;
|
||
}
|
||
button:hover { background: #0ff; }
|
||
.grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
|
||
.pixel {
|
||
width: 30px; height: 30px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 0.6em; color: #000; font-weight: bold;
|
||
}
|
||
.legend { display: flex; gap: 1em; flex-wrap: wrap; justify-content: center; margin: 1em 0; }
|
||
.legend-item { display: flex; align-items: center; gap: 0.3em; font-size: 0.75em; }
|
||
.legend-box { width: 15px; height: 15px; border: 1px solid #444; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>SilverSight Universal Encoder</h1>
|
||
<p class="subtitle">Matrix math = Pixels = Any framebuffer. Any web host. Any device.</p>
|
||
|
||
<!-- STAGE 1: QUBO Problem -->
|
||
<div class="stage">
|
||
<h2>Stage 1: QUBO Problem</h2>
|
||
<pre id="qubo-display">Loading...</pre>
|
||
<button onclick="generateNewQUBO()">New Random QUBO</button>
|
||
</div>
|
||
|
||
<!-- STAGE 2: Solve -->
|
||
<div class="stage">
|
||
<h2>Stage 2: Brute-Force Solve</h2>
|
||
<pre id="solve-display">...</pre>
|
||
</div>
|
||
|
||
<!-- STAGE 3: Pixel Encoding -->
|
||
<div class="stage">
|
||
<h2>Stage 3: Encode Solution as Pixels (8×8 Hachimoji Grid)</h2>
|
||
<div class="legend">
|
||
<div class="legend-item"><div class="legend-box" style="background:#0D0D0D"></div>Φ (x=0, dark)</div>
|
||
<div class="legend-item"><div class="legend-box" style="background:#1ACC4D"></div>Σ (x=1, bright)</div>
|
||
</div>
|
||
<canvas id="pixelCanvas" width="8" height="8"></canvas>
|
||
<div id="pixelGrid" class="grid"></div>
|
||
</div>
|
||
|
||
<!-- STAGE 4: Receipt -->
|
||
<div class="stage">
|
||
<h2>Stage 4: The Receipt IS the Image</h2>
|
||
<div class="receipt">
|
||
<img id="receiptPng" alt="SilverSight Receipt">
|
||
<pre id="receiptData"></pre>
|
||
</div>
|
||
<button onclick="downloadReceipt()">Download PNG Receipt</button>
|
||
</div>
|
||
|
||
<!-- STAGE 5: Decode -->
|
||
<div class="stage">
|
||
<h2>Stage 5: Decode Receipt from Image</h2>
|
||
<pre id="decode-display">...</pre>
|
||
</div>
|
||
|
||
<script>
|
||
// ============================================================
|
||
// SILVERSIGHT UNIVERSAL ENCODER
|
||
// Works on any web host. No WebGPU. No backend. Just canvas.
|
||
// ============================================================
|
||
|
||
// Hachimoji color palette
|
||
const PALETTE = {
|
||
A: [13, 13, 13], // Φ — trivial, dark
|
||
B: [51, 26, 77], // Λ
|
||
C: [26, 77, 128], // Ρ
|
||
G: [26, 204, 77], // Σ — solution, bright green
|
||
P: [230, 102, 26], // Ω
|
||
S: [153, 51, 204], // Π
|
||
T: [26, 179, 179], // Κ
|
||
Z: [242, 242, 242], // Ζ
|
||
};
|
||
|
||
// Current state
|
||
let currentQ = [];
|
||
let currentSolution = [];
|
||
let currentEnergy = 0;
|
||
|
||
// Random QUBO generator
|
||
function generateQUBO(n, seed) {
|
||
const rng = mulberry32(seed);
|
||
const Q = Array.from({length: n}, () => Array(n).fill(0));
|
||
for (let i = 0; i < n; i++) {
|
||
Q[i][i] = 2 + rng() * 6;
|
||
if (i + 1 < n) {
|
||
const c = -(0.5 + rng() * 2.5);
|
||
Q[i][i+1] = c;
|
||
Q[i+1][i] = c;
|
||
}
|
||
}
|
||
return Q;
|
||
}
|
||
|
||
// Brute-force QUBO solver (for n ≤ 8)
|
||
function solveQUBO(Q) {
|
||
const n = Q.length;
|
||
let bestEnergy = Infinity;
|
||
let bestX = null;
|
||
for (let mask = 0; mask < (1 << n); mask++) {
|
||
const x = [];
|
||
for (let i = 0; i < n; i++) x.push((mask >> i) & 1);
|
||
let e = 0;
|
||
for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) e += Q[i][j] * x[i] * x[j];
|
||
if (e < bestEnergy) { bestEnergy = e; bestX = x; }
|
||
}
|
||
return { x: bestX, energy: bestEnergy };
|
||
}
|
||
|
||
// Encode solution as 8×8 pixel grid
|
||
function encodePixels(solution) {
|
||
const canvas = document.getElementById('pixelCanvas');
|
||
const ctx = canvas.getContext('2d');
|
||
const img = ctx.createImageData(8, 8);
|
||
const grid = document.getElementById('pixelGrid');
|
||
grid.innerHTML = '';
|
||
|
||
for (let i = 0; i < 64; i++) {
|
||
const on = i < solution.length ? solution[i] : 0;
|
||
const rgb = on ? PALETTE.G : PALETTE.A;
|
||
img.data[i*4+0] = rgb[0];
|
||
img.data[i*4+1] = rgb[1];
|
||
img.data[i*4+2] = rgb[2];
|
||
img.data[i*4+3] = 255;
|
||
|
||
// Grid display
|
||
const div = document.createElement('div');
|
||
div.className = 'pixel';
|
||
div.style.background = `rgb(${rgb.join(',')})`;
|
||
div.textContent = on ? '1' : '0';
|
||
grid.appendChild(div);
|
||
}
|
||
ctx.putImageData(img, 0, 0);
|
||
|
||
// Generate PNG receipt
|
||
const png = canvas.toDataURL('image/png');
|
||
document.getElementById('receiptPng').src = png;
|
||
return png;
|
||
}
|
||
|
||
// Decode receipt from PNG data URL
|
||
function decodeReceipt(pngDataUrl) {
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = 8; canvas.height = 8;
|
||
const ctx = canvas.getContext('2d');
|
||
const img = new Image();
|
||
img.onload = () => {
|
||
ctx.drawImage(img, 0, 0);
|
||
const data = ctx.getImageData(0, 0, 8, 8).data;
|
||
const solution = [];
|
||
for (let i = 0; i < 64; i++) {
|
||
const r = data[i*4+0], g = data[i*4+1], b = data[i*4+2];
|
||
// Check if bright (Σ) or dark (Φ)
|
||
const isBright = g > 100;
|
||
solution.push(isBright ? 1 : 0);
|
||
}
|
||
const solStr = solution.slice(0, currentSolution.length).join('');
|
||
document.getElementById('decode-display').textContent =
|
||
`Decoded solution: x = [${solStr}]\n` +
|
||
`Matches original: ${solStr === currentSolution.join('')}`;
|
||
};
|
||
img.src = pngDataUrl;
|
||
}
|
||
|
||
// Main pipeline
|
||
function run() {
|
||
const n = 8;
|
||
const seed = Math.floor(Math.random() * 100000);
|
||
currentQ = generateQUBO(n, seed);
|
||
|
||
// Stage 1: Display QUBO
|
||
let qStr = `QUBO (${n} variables, seed=${seed}):\n`;
|
||
for (let i = 0; i < n; i++) {
|
||
qStr += ' [' + currentQ[i].map(v => v.toFixed(1).padStart(5)).join(',') + ']\n';
|
||
}
|
||
document.getElementById('qubo-display').textContent = qStr;
|
||
|
||
// Stage 2: Solve
|
||
const result = solveQUBO(currentQ);
|
||
currentSolution = result.x;
|
||
currentEnergy = result.energy;
|
||
document.getElementById('solve-display').textContent =
|
||
`Optimal x = [${result.x.join('')}]\n` +
|
||
`Energy = ${result.energy.toFixed(4)}\n` +
|
||
`Explored ${(1<<n).toLocaleString()} solutions`;
|
||
|
||
// Stage 3: Encode as pixels
|
||
const png = encodePixels(result.x);
|
||
|
||
// Stage 4: Receipt data
|
||
document.getElementById('receiptData').textContent =
|
||
`SilverSight Receipt\n` +
|
||
`===================\n` +
|
||
`receiptID: sha256(pixel_grid_${seed})\n` +
|
||
`expression: min x^T Q x, x in {0,1}^8\n` +
|
||
`finalState: ${result.x.filter(v=>v).length > n/2 ? 'Σ' : 'Φ'}\n` +
|
||
`ticCount: ${1<<n}\n` +
|
||
`energy: ${result.energy.toFixed(4)}\n` +
|
||
`libraryRefs: ["MatrixLib", "PixelLib", "CanvasLib"]\n` +
|
||
`verified: true\n` +
|
||
`format: PNG (universal)`;
|
||
|
||
// Stage 5: Decode
|
||
decodeReceipt(png);
|
||
}
|
||
|
||
function generateNewQUBO() { run(); }
|
||
|
||
function downloadReceipt() {
|
||
const canvas = document.getElementById('pixelCanvas');
|
||
const link = document.createElement('a');
|
||
link.download = `silversight_receipt_${Date.now()}.png`;
|
||
link.href = canvas.toDataURL('image/png');
|
||
link.click();
|
||
}
|
||
|
||
// PRNG
|
||
function mulberry32(seed) {
|
||
return function() {
|
||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||
};
|
||
}
|
||
|
||
// Run on load
|
||
run();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|