MODEL Amistral-small:24bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
Answers below are anonymized and shuffled. Read, judge, pick a favourite — then scroll down and reveal the models.
2 of the 8 local models delivered nothing through our test harness in this round — for reasons that lie with our setup, not with the models. Those cards are marked DNF like any other, but they are not evidence about those models. Which ones, and why, is spelled out in the reveal.
The reveal also holds a frontier reference on the same task (Claude Opus 5) — kept out of sight here so it cannot steer your judgement.
Create ONE self-contained HTML file (STRICT LIMIT: max 120 lines total) that animates a flood fill on a 60x40 grid of coloured cells drawn on a <canvas>. Generate a few random blobs of colour, pick a start cell, and expand the fill one frontier step at a time so the growing region is clearly visible. Show the number of cells filled and the current frontier size. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flood Fill Animation</title>
<style>body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; flex-direction: column;} canvas { border: 2px solid #444; }</style>
</head>
<body>
<canvas id="grid"></canvas>
<div id="stats">Filled Cells: 0 | Frontier Size: 0</div>
<script>
const canvas = document.getElementById('grid');
const ctx = canvas.getContext('2d');
const GRID_W = 60;
const GRID_H = 40;
canvas.width = GRID_W * 8;
canvas.height = GRID_H * 8;
let grid = [];
let startX, startY;
let queue = [];
let isAnimating = false;
function initializeGrid() {
grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
grid[y][x] = '#000'; // Default background color
}
}
const blobsToDraw = Math.floor(Math.random() * 3) + 2;
for (let i = 0; i < blobsToDraw; i++) {
let startX_b = Math.floor(Math.random() * GRID_W);
let startY_b = Math.floor(Math.random() * GRID_H);
let color = `hsl(${Math.random() * 360}, 70%, ${Math.random() * 40 + 50}%)`;
const blobSize = Math.max(1, Math.floor(Math.random() * 8) + 2);
for (let dy = -blobSize; dy <= blobSize; dy++) {
for (let dx = -blobSize; dx <= blobSize; dx++) {
const x = startX_b + dx;
const y = startY_b + dy;
if (x >= 0 && x < GRID_W && y >= 0 && y < GRID_H) {
grid[y][x] = color;
}
}
}
}
// Pick a random starting cell that is not the background color
do {
startX = Math.floor(Math.random() * GRID_W);
startY = Math.floor(Math.random() * GRID_H);
} while (grid[startY][startX] === null || grid[startY][startX].startsWith('#000'));
queue = [ { x: startX, y: startY } ];
}
function drawGrid() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
ctx.fillStyle = grid[y][x];
ctx.fillRect(x * 8, y * 8, 8, 8);
}
}
}
function animateStep() {
if (queue.length === 0) {
isAnimating = false;
document.getElementById('stats').innerHTML = 'Flood Fill Complete!';
setTimeout(() => { initializeGrid(); requestAnimationFrame(gameLoop); }, 1500);
return;
}
const nextQueue = [];
let frontierCoords = [];
let filledCount = 0;
// Process the current queue (the cells to fill in this step)
for (let i = 0; i < queue.length; i++) {
const { x, y } = queue[i];
if (!grid[y][x].startsWith('#FILL')) {
grid[y][x] = '#FILL'; // Mark as filled
filledCount++;
}
// Check neighbors for the new frontier
const neighbors = [[0, 1], [0, -1], [1, 0], [-1, 0]];
for (let [dx, dy] of neighbors) {
const nx = x + dx;
const ny = y + dy;
if (nx >= 0 && nx < GRID_W && ny >= 0 && ny < GRID_H && grid[ny][nx].startsWith('#BLOB') && !grid[ny][nx].startsWith('#FILL')) {
frontierCoords.push({ x: nx, y: ny });
}
}
}
// Update queue and draw
queue = frontierCoords;
drawGrid();
const frontierSize = queue.length;
document.getElementById('stats').innerHTML = `Filled Cells: ${filledCount} | Frontier Size: ${frontierSize}`;
if (isAnimating) {
requestAnimationFrame(gameLoop);
}
}
function gameLoop() {
animateStep();
}
// Start the animation immediately
initializeGrid();
requestAnimationFrame(gameLoop);
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html>
<head>
<title>Flood Fill Animation</title>
<style>body {background:#111;display:flex;justify-content:center;align-items:center;min-height:100vh;margin:0;color:white;}canvas {border:2px solid #333;}</style>
</head>
<body>
<canvas id="canvas" width="60"*50" height="40"*50"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let GRID_W = 60;
let GRID_H = 40;
let CELL_SIZE = 50 / 60; // Scale down slightly for fit
// Grid state: 0=Empty, 1=Target Color, 2=Filled
let grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(0));
let colorGrid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));
function randomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function initializeGrid() {
grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(0));
colorGrid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));
const numBlobs = 5;
let filledCount = 0;
for (let i = 0; i < numBlobs; i++) {
let startX = Math.floor(Math.random() * GRID_W);
let startY = Math.floor(Math.random() * GRID_H);
let color = randomColor();
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
if (!colorGrid[y][x] && Math.random() > 0.8) {
colorGrid[y][x] = color;
grid[y][x] = 1; // Mark as colored cell
}
}
}
}
// Select a target starting point (a random colored cell)
let startY, startX;
do {
startY = Math.floor(Math.random() * GRID_H);
startX = Math.floor(Math.random() * GRID_W);
} while (!colorGrid[startY][startX]);
return { startX, startY, targetColor: colorGrid[startY][startX] };
}
let state = initializeGrid();
let isRunning = true;
function drawGrid(filledCells) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
const color = colorGrid[y][x];
ctx.fillStyle = color || '#111';
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE - 0.5, CELL_SIZE - 0.5);
if (grid[y][x] === 2) { // Filled state indicator
ctx.strokeStyle = 'rgba(0, 150, 255, 0.8)';
ctx.lineWidth = 3;
ctx.strokeRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
}
}
}
// Draw the current frontier (cells about to be filled)
if (filledCells && filledCells.length > 0) {
ctx.fillStyle = 'rgba(0, 255, 0, 0.6)';
for (const [y, x] of filledCells) {
ctx.fillRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
}
}
}
function animateFill() {
if (!isRunning) return;
let startY = state.startY;
let startX = state.startX;
const targetColor = state.targetColor;
const frontier = new Set(); // Stores [y, x] coordinates for the next step
const visited = new Set(); // Tracks cells already in queue or processed
// Initial setup: Queue for BFS/Frontier search
let currentQueue = [[startY, startX]];
frontier.add([startY, startX]);
visited.add(`${startY},${startX}`);
// Optimization: Instead of full BFS every step, we maintain the frontier boundary explicitly
// To keep complexity down for line count, we use a simplified queue-based expansion.
let currentFrontier = [[startY, startX]];
let filledCount = 1;
let maxSteps = GRID_W * GRID_H * 0.2; // Limit steps to prevent infinite loop/slowness
// We need a loop structure that processes step-by-step and updates the state object
if (state._currentStep === undefined) {
state._currentQueue = [[startY, startX]];
state._visited = new Set([`${startY},${startX}`]);
state._fillCount = 1;
}
let queue = state._currentQueue || [];
let newlyFilledFrontier = [];
if (queue.length > 0) {
const nextQueue = [];
for (const [y, x] of queue) {
// Check neighbors (N, S, E, W)
[[0, 1], [0, -1], [1, 0], [-1, 0]].forEach(([dy, dx]) => {
let ny = y + dy;
let nx = x + dx;
if (ny >= 0 && ny < GRID_H && nx >= 0 && nx < GRID_W) {
const key = `${ny},${nx}`;
// Check if it matches the target color, is not filled, and hasn't been processed
if (!state._visited.has(key) && colorGrid[ny][nx] === targetColor) {
newlyFilledFrontier.push([ny, nx]);
nextQueue.push([ny, nx]);
state._visited.add(key);
}
}
});
}
if (newlyFilledFrontier.length > 0) {
// Process the step: Change state and update metrics
const currentNeighbors = newlyFilledFrontier;
currentNeighbors.forEach(([y, x]) => {
grid[y][x] = 2; // Mark as filled
});
state._fillCount += newlyFilledFrontier.length;
state._currentQueue = nextQueue;
// Redraw with the new frontier
drawGrid(newlyFilledFrontier);
document.getElementById('stats').innerHTML = `Cells: ${state._fillCount} | Frontier: ${newlyFilledFrontier.length}`;
} else {
// Fill finished
isRunning = false;
document.getElementById('stats').innerHTML = `Finished! Total Cells Filled: ${state._fillCount}`;
}
}
if (isRunning) {
requestAnimationFrame(animateFill);
}
}
// Initialization and setup for the first run/restart
function startAnimation() {
const statsDiv = document.createElement('div');
statsDiv.id = 'stats';
statsDiv.style.position = 'absolute';
statsDiv.style.top = '20px';
statsDiv.style.left = '50%';
statsDiv.style.transform = 'translate(-50%, 0)';
statsDiv.style.fontSize = '24px';
document.body.appendChild(statsDiv);
// Reset state for fresh run
state = initializeGrid();
state._currentQueue = [];
state._visited = new Set();
state._fillCount = 0;
drawGrid(null); // Clear and draw initial colors
document.getElementById('stats').innerText = "Starting Animation...";
animateFill();
}
startAnimation();
</script>
<div id="stats" style="position: absolute; top: 20px; left: 50%; transform: translate(-50%, 0); font-size: 24px;"></div>
</body>
</html>
``````html
<!DOCTYPE html>
<html>
<head>
<title>Flood Fill Animation</title>
<style>
body { background-color: #111; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
canvas { border: 1px solid #333; image-rendering: pixelated; }
#info { color: white; font-family: monospace; position: absolute; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.6); padding: 10px; border-radius: 5px;}
</style>
</head>
<body>
<canvas id="gameCanvas" width="600" height="400"></canvas>
<div id="info">Cells Filled: 0 | Frontier Size: 0</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const infoDiv = document.getElementById('info');
let GRID_WIDTH = 60;
let GRID_HEIGHT = 40;
let CELL_SIZE = 10;
let grid = [];
// Color constants
const BACKGROUND_COLOR = [20, 20, 30]; // Dark background
const BLOB_COLORS = ["#FF6B6B", "#4ECDC4", "#5F9EA0", "#8D6E63", "#A1C4FD"];
let currentGridState;
let startX, startY, targetColor;
let queue = [];
let running = false;
let filledCount = 0;
function initializeGrid() {
grid = new Array(GRID_WIDTH).fill(0).map(() => new Array(GRID_HEIGHT).fill(null));
// Initialize background (simulate an empty canvas)
for (let x = 0; x < GRID_WIDTH; x++) {
for (let y = 0; y < GRID_HEIGHT; y++) {
grid[x][y] = BACKGROUND_COLOR.join(',');
}
}
// Generate random blobs and set target color
const blobCount = Math.floor(Math.random() * 3) + 2;
let potentialTargetColor = null;
for (let i = 0; i < blobCount; i++) {
let startX_blob = Math.floor(Math.random() * GRID_WIDTH);
let startY_blob = Math.floor(Math.random() * GRID_HEIGHT);
let color = BLOB_COLORS[Math.floor(Math.random() * 5)];
if (!potentialTargetColor) potentialTargetColor = color;
// Draw a blob (filling connected area with the same random color)
const tempBlobGrid = JSON.parse(JSON.stringify(grid));
let queueBlob = [[startX_blob, startY_blob]];
tempBlobGrid[startX_blob][startY_blob] = color;
while (queueBlob.length > 0) {
const [x, y] = queueBlob.shift();
[[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT && tempBlobGrid[nx][ny] === null) {
tempBlobGrid[nx][ny] = color;
queueBlob.push([nx, ny]);
}
});
}
// Merge the blob into the main grid
for (let x = 0; x < GRID_WIDTH; x++) {
for (let y = 0; y < GRID_HEIGHT; y++) {
if (tempBlobGrid[x][y] !== null) {
grid[x][y] = tempBlobGrid[x][y];
}
}
}
}
// Select starting point and target color
startX = Math.floor(Math.random() * GRID_WIDTH);
startY = Math.floor(Math.random() * GRID_HEIGHT);
targetColor = grid[startX][startY];
// Reset state
currentGridState = JSON.parse(JSON.stringify(grid));
queue = [];
filledCount = 0;
running = true;
}
function drawGrid() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let x = 0; x < GRID_WIDTH; x++) {
for (let y = 0; y < GRID_HEIGHT; y++) {
const color = currentGridState[x][y];
ctx.fillStyle = color;
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
function updateCanvas() {
// Draw the underlying grid state first
drawGrid();
// Highlight the current frontier cells (the queue)
if (queue.length > 0) {
ctx.strokeStyle = 'rgba(255, 255, 0, 0.8)';
ctx.lineWidth = 3;
for (const [x, y] of queue) {
ctx.strokeRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
}
}
// Update stats display
infoDiv.innerHTML = `Cells Filled: ${filledCount} | Frontier Size: ${queue.length}`;
}
function findFrontier() {
if (queue.length === 0) return [];
let frontier = [];
for(const [x, y] of queue) {
[[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
// Check if it's the target color and hasn't been processed/queued already
const cell = grid[nx][ny];
if (cell === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
frontier.push([nx, ny]);
}
}
});
}
return frontier;
}
function stepFloodFill() {
if (!running) return;
// 1. Update the queue with all potential next cells (the true frontier)
let potentialFrontier = [];
for(const [x, y] of queue) {
[[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
const cell = grid[nx][ny];
// Only add valid target cells that are not already in the queue or filled
if (cell === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
potentialFrontier.push([nx, ny]);
}
}
});
}
// 2. Select a random cell from the frontier to fill (simulating guided growth)
if (potentialFrontier.length === 0) {
running = false; // Finished filling
return;
}
const randomIndex = Math.floor(Math.random() * potentialFrontier.length);
const [nextX, nextY] = potentialFrontier[randomIndex];
// 3. Process the step: Fill and update queue/count
if (currentGridState[nextX][nextY] === targetColor) {
// Update state
currentGridState[nextX][nextY] = '#00FFFF'; // Filled color
filledCount++;
// Add neighbors of the newly filled cell to the queue for the next step's frontier calculation
[[nextX + 1, nextY], [nextX - 1, nextY], [nextX, nextY + 1], [nextX, nextY - 1]].forEach(([nx, ny]) => {
if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
const neighborColor = grid[nx][ny];
// Only add viable candidates to the queue
if (neighborColor === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
queue.push([nx, ny]);
}
}
});
} else {
// Should not happen if logic is correct, but handles safety break
running = false;
return;
}
}
function animate() {
if (running) {
stepFloodFill();
updateCanvas();
} else {
// Restart sequence when finished
setTimeout(() => {
initializeGrid();
animate();
}, 500);
}
if (running) {
requestAnimationFrame(animate);
}
}
window.onload = () => {
initializeGrid();
// Initial draw before the animation starts
drawGrid();
updateCanvas();
animate();
};
</script>
</body>
</html>
```| Blind label | Model | Blind score | Latency | Status |
|---|---|---|---|---|
| MODEL A | mistral-small:24b | — | — | DNF |
| MODEL B | qwen3:8b | — | — | harness |
| MODEL C | qwen3:14b | — | 19.4 s | OK |
| MODEL D | qwen3.5:9b | — | 33.3 s | OK |
| MODEL E | llama3.1:8b | — | — | DNF |
| MODEL F | qwen3-coder:30b | — | 34.6 s | OK |
| MODEL G | deepseek-r1:14b | — | — | DNF |
| MODEL H | gemma4:26b | — | — | harness |
These models answered the identical prompt outside the blind field. They are deliberately not scored and not part of the blind comparison — they are there so you can see where a frontier model lands on the same task.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Flood Fill — 60×40</title>
<style>
html,body{height:100%;margin:0;background:#080b12;color:#dbe4f0;font:14px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;display:flex;align-items:center;justify-content:center}
.wrap{display:flex;flex-direction:column;gap:10px;padding:16px;max-width:100%}
canvas{background:#05070c;border-radius:8px;box-shadow:0 0 0 1px #1d2635,0 18px 50px -20px #000;width:100%;height:auto;image-rendering:pixelated}
.hud{display:flex;flex-wrap:wrap;gap:8px}
.chip{background:#111827;border:1px solid #202b3d;border-radius:6px;padding:6px 10px;letter-spacing:.04em}
.chip b{color:#7dd3fc;font-weight:600}
.chip.f b{color:#fff}
</style>
</head>
<body>
<div class="wrap">
<canvas id="c" width="960" height="640"></canvas>
<div class="hud">
<div class="chip">filled <b id="a">0</b></div>
<div class="chip f">frontier <b id="b">0</b></div>
<div class="chip">step <b id="d">0</b></div>
<div class="chip">region <b id="e">0</b></div>
</div>
</div>
<script>
const W=60,H=40,S=16,c=document.getElementById('c'),x=c.getContext('2d');
const base=document.createElement('canvas');base.width=c.width;base.height=c.height;
const bx=base.getContext('2d');
const PAL=['#16233a','#22405c','#2e6f7a','#3f8f6b','#7fae4b','#c9a227','#c86b3c','#a03e5a','#5b3a7e','#3d5a8c'];
const A=document.getElementById('a'),B=document.getElementById('b'),D=document.getElementById('d'),E=document.getElementById('e');
let grid,seen,depth,frontier,filled,step,total,done,hold,acc,last=0;
function region(s,mark){
const q=[s],v=new Uint8Array(W*H);v[s]=1;let n=0,col=grid[s];
while(q.length){const p=q.pop();n++;if(mark)mark[p]=1;
const i=p%W,j=(p/W)|0;
if(i>0&&!v[p-1]&&grid[p-1]===col){v[p-1]=1;q.push(p-1)}
if(i<W-1&&!v[p+1]&&grid[p+1]===col){v[p+1]=1;q.push(p+1)}
if(j>0&&!v[p-W]&&grid[p-W]===col){v[p-W]=1;q.push(p-W)}
if(j<H-1&&!v[p+W]&&grid[p+W]===col){v[p+W]=1;q.push(p+W)}}
return n;
}
function gen(){
const n=7+((Math.random()*5)|0),seeds=[];
for(let i=0;i<n;i++)seeds.push({x:Math.random()*W,y:Math.random()*H,c:PAL[(Math.random()*PAL.length)|0],
w:.65+Math.random()*.9,f:2+((Math.random()*4)|0),p:Math.random()*6.283,a:.14+Math.random()*.3});
grid=new Array(W*H);
for(let j=0;j<H;j++)for(let i=0;i<W;i++){
let bd=1e9,bc=PAL[0];
for(const s of seeds){
const dx=i+.5-s.x,dy=j+.5-s.y;
const d=Math.hypot(dx,dy)*(1+s.a*Math.sin(Math.atan2(dy,dx)*s.f+s.p))/s.w;
if(d<bd){bd=d;bc=s.c}}
grid[j*W+i]=bc;
}
bx.fillStyle='#05070c';bx.fillRect(0,0,base.width,base.height);
for(let j=0;j<H;j++)for(let i=0;i<W;i++){bx.fillStyle=grid[j*W+i];bx.fillRect(i*S,j*S,S-1,S-1)}
let start=0,bestN=-1;
for(let t=0;t<28;t++){
const s=(Math.random()*W*H)|0,sz=region(s);
if(sz>bestN){bestN=sz;start=s}
if(bestN>=260)break;
}
seen=new Uint8Array(W*H);depth=new Int16Array(W*H).fill(-1);
seen[start]=1;depth[start]=0;frontier=[start];filled=1;step=0;total=bestN;done=false;hold=0;acc=0;
}
function advance(){
const col=grid[frontier[0]],next=[];
for(const p of frontier){
const i=p%W,j=(p/W)|0,nb=[];
if(i>0)nb.push(p-1);if(i<W-1)nb.push(p+1);if(j>0)nb.push(p-W);if(j<H-1)nb.push(p+W);
for(const q of nb)if(!seen[q]&&grid[q]===col){seen[q]=1;depth[q]=step+1;next.push(q);filled++}
}
frontier=next;step++;
if(!frontier.length)done=true;
}
function frame(t){
const dt=Math.min(80,t-last);last=t;
if(done){hold+=dt;if(hold>1000)gen()}
else{acc+=dt;while(acc>=42&&!done){acc-=42;advance()}}
x.drawImage(base,0,0);
for(let p=0;p<W*H;p++){
if(!seen[p])continue;
const i=p%W,j=(p/W)|0,d=depth[p];
x.fillStyle='hsl('+((196+d*4+t*.02)%360)+' 92% '+(48+8*Math.sin(d*.4+t*.003))+'%)';
x.fillRect(i*S,j*S,S-1,S-1);
}
x.fillStyle='#fff';
for(const p of frontier){const i=p%W,j=(p/W)|0;x.fillRect(i*S,j*S,S-1,S-1)}
x.fillStyle='rgba(255,255,255,.28)';
for(const p of frontier){const i=p%W,j=(p/W)|0;x.fillRect(i*S-2,j*S-2,S+3,S+3)}
A.textContent=filled;B.textContent=frontier.length;D.textContent=step;E.textContent=total;
requestAnimationFrame(frame);
}
gen();requestAnimationFrame(frame);
</script>
</body>
</html>