loop-benchmarking

Controlled experiments across agentic coding configurations. Same task, one variable, what actually works.
git clone https://git.shiptheloop.com/loop-benchmarking.git
Log | Files | Refs | README

commit 0ca83ec36a6d5269688a7186328a7d0d3a97fddf
parent f213f5a1831e271fcf572e9de9073fe5c85985ba
Author: Brian Graham <brian@buildingbetterteams.de>
Date:   Sun,  5 Apr 2026 21:42:02 +0200

Add 4 new runs (124 total)

Profile: main_effects
Completed: 4 | Skipped: 53 | Failed: 0

Diffstat:
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/index.html | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package-lock.json | 2583+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package.json | 24++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/report/jscpd-report.json | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/src/tetris.ts | 607+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/tsconfig.json | 12++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/index.html | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package-lock.json | 2519+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package.json | 21+++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/report/jscpd-report.json | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/src/tetris.ts | 512+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/tsconfig.json | 12++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/index.html | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package-lock.json | 2519+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package.json | 23+++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/report/jscpd-report.json | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/src/tetris.ts | 735+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/style.css | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/tsconfig.json | 14++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/index.html | 245+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package-lock.json | 2583+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package.json | 24++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/report/jscpd-report.json | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/src/tetris.ts | 736+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/tsconfig.json | 15+++++++++++++++
Mresults/analysis/main_effects_code_quality.json | 232++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_cost.json | 220++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_gameplay.json | 216++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_score.json | 224++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_turns.json | 214++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_wall_time.json | 230++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/index.jsonl | 4++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_output.json | 2++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_stderr.log | 0
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/eval_results.json | 262+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/gameplay-bot-report.json | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/meta.json | 31+++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/transcript.jsonl | 41+++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_output.json | 2++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_stderr.log | 0
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/eval_results.json | 262+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/gameplay-bot-report.json | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/meta.json | 31+++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/transcript.jsonl | 46++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_output.json | 2++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_stderr.log | 0
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/eval_results.json | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/gameplay-bot-report.json | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/meta.json | 31+++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/transcript.jsonl | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_output.json | 2++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_stderr.log | 0
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/eval_results.json | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/gameplay-bot-report.json | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/meta.json | 31+++++++++++++++++++++++++++++++
Aresults/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/transcript.jsonl | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 files changed, 17212 insertions(+), 668 deletions(-)

diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/index.html b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/index.html @@ -0,0 +1,227 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Tetris</title> + <style> + * { box-sizing: border-box; margin: 0; padding: 0; } + + body { + background: #0a0a0a; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + font-family: 'Courier New', Courier, monospace; + color: #eee; + user-select: none; + } + + #game-wrapper { + display: flex; + gap: 20px; + align-items: flex-start; + } + + /* ── Board ── */ + #board-container { + position: relative; + } + + #board { + display: block; + border: 2px solid #444; + background: #111; + } + + #message { + display: none; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(0,0,0,0.85); + color: #fff; + font-size: 26px; + font-weight: bold; + padding: 16px 32px; + border: 2px solid #fff; + border-radius: 6px; + text-align: center; + white-space: nowrap; + pointer-events: none; + letter-spacing: 2px; + } + + #message .sub { + font-size: 14px; + font-weight: normal; + margin-top: 8px; + letter-spacing: 1px; + color: #aaa; + } + + /* ── Side Panel ── */ + #side-panel { + display: flex; + flex-direction: column; + gap: 16px; + min-width: 160px; + } + + .panel-box { + background: #1a1a1a; + border: 1px solid #333; + border-radius: 6px; + padding: 12px 16px; + } + + .panel-box h3 { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 2px; + color: #666; + margin-bottom: 6px; + } + + .panel-box .value { + font-size: 28px; + font-weight: bold; + color: #0cf; + letter-spacing: 1px; + } + + #preview-box h3 { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 2px; + color: #666; + margin-bottom: 8px; + } + + #preview { + display: block; + border: 1px solid #333; + border-radius: 4px; + background: #111; + } + + /* ── Controls reference ── */ + #controls-box { + font-size: 11px; + color: #555; + line-height: 1.8; + } + + #controls-box .key { + display: inline-block; + background: #2a2a2a; + border: 1px solid #444; + border-radius: 3px; + padding: 0 4px; + font-size: 10px; + color: #999; + margin-right: 4px; + } + + /* ── Buttons ── */ + #btn-panel { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + + #btn-panel button { + flex: 1 1 calc(50% - 3px); + padding: 8px 4px; + background: #222; + border: 1px solid #444; + border-radius: 4px; + color: #ccc; + font-family: inherit; + font-size: 11px; + cursor: pointer; + letter-spacing: 1px; + transition: background 0.15s; + } + + #btn-panel button:hover { + background: #333; + color: #fff; + } + + #btn-panel button:active { + background: #0cf; + color: #000; + } + + #btn-restart { + flex: 1 1 100% !important; + background: #1a1a2a !important; + border-color: #0cf !important; + color: #0cf !important; + font-weight: bold; + letter-spacing: 2px; + } + + #btn-restart:hover { + background: #0cf !important; + color: #000 !important; + } + </style> +</head> +<body> + <div id="game-wrapper"> + <div id="board-container"> + <canvas id="board"></canvas> + <div id="message"> + GAME OVER + <div class="sub">Press ENTER or SPACE to restart</div> + </div> + </div> + + <div id="side-panel"> + <div class="panel-box" id="preview-box"> + <h3>Next</h3> + <canvas id="preview"></canvas> + </div> + + <div class="panel-box"> + <h3>Score</h3> + <div class="value" id="score">0</div> + </div> + + <div class="panel-box"> + <h3>Lines</h3> + <div class="value" id="lines">0</div> + </div> + + <div class="panel-box"> + <h3>Level</h3> + <div class="value" id="level">0</div> + </div> + + <div class="panel-box" id="btn-panel"> + <button id="btn-left">◀ Left</button> + <button id="btn-right">Right ▶</button> + <button id="btn-rotate">↻ Rotate</button> + <button id="btn-down">▼ Soft</button> + <button id="btn-drop">⬇ Hard Drop</button> + <button id="btn-restart">↺ RESTART</button> + </div> + + <div class="panel-box" id="controls-box"> + <div><span class="key">← →</span> Move</div> + <div><span class="key">↑</span> / <span class="key">X</span> Rotate CW</div> + <div><span class="key">Z</span> Rotate CCW</div> + <div><span class="key">↓</span> Soft Drop</div> + <div><span class="key">Space</span> Hard Drop</div> + <div><span class="key">P</span> Pause</div> + </div> + </div> + </div> + + <script src="dist/tetris.js"></script> +</body> +</html> diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package-lock.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package-lock.json @@ -0,0 +1,2583 @@ +{ + "name": "loop-bench-294r5yrr", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-294r5yrr", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@playwright/test": "^1.59.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.4", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@html-validate/stylish": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-5.1.0.tgz", + "integrity": "sha512-Tyx/ZbHBpVZjvSleNplNMUhqT4UY1HwAMC97GSmasJXggWuvjNFLBS2scqnEb+ZG1szLq4zgjOioj7cVWV9WuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": "^20.11 || >= 22.16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jscpd/badge-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/badge-reporter/-/badge-reporter-4.0.4.tgz", + "integrity": "sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "badgen": "^3.2.3", + "colors": "^1.4.0", + "fs-extra": "^11.2.0" + } + }, + "node_modules/@jscpd/core": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/core/-/core-4.0.4.tgz", + "integrity": "sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@jscpd/finder": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/finder/-/finder-4.0.4.tgz", + "integrity": "sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "blamer": "^1.0.6", + "bytes": "^3.1.2", + "cli-table3": "^0.6.5", + "colors": "^1.4.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "markdown-table": "^2.0.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/html-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/html-reporter/-/html-reporter-4.0.4.tgz", + "integrity": "sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "1.4.0", + "fs-extra": "^11.2.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/tokenizer": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/tokenizer/-/tokenizer-4.0.4.tgz", + "integrity": "sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "reprism": "^0.0.11", + "spark-md5": "^3.0.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@playwright/test": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz", + "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/badgen": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/badgen/-/badgen-3.2.3.tgz", + "integrity": "sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blamer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/blamer/-/blamer-1.0.7.tgz", + "integrity": "sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^4.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gitignore-to-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", + "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.4 <5 || >=6.9" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-validate": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-10.11.3.tgz", + "integrity": "sha512-wKUq9iR6bukMgiHhs/ORThZzEbQoFiiPNN7aZfQ8dlmhttPb2sM2Ji2p+Fy5Xj1aH7QHJ1biT2SUDw7A01P2oA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/html-validate" + } + ], + "license": "MIT", + "dependencies": { + "@html-validate/stylish": "^5.0.0", + "@sidvind/better-ajv-errors": "4.0.1", + "ajv": "^8.0.0", + "glob": "^13.0.0", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.mjs" + }, + "engines": { + "node": "^20.19.0 || >= 22.16.0" + }, + "peerDependencies": { + "jest": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-diff": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-snapshot": "^28.1.3 || ^29.0.3 || ^30.0.0", + "vitest": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.1" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/@sidvind/better-ajv-errors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-4.0.1.tgz", + "integrity": "sha512-6arF1ssKxItxgitPYXafUoLmsVBA6K7m9+ZGj6hLDoBl7nWpJ33EInwQUdHTle2METeWGxgQiqSex20KZRykew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "ajv": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jscpd": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-4.0.8.tgz", + "integrity": "sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/badge-reporter": "4.0.4", + "@jscpd/core": "4.0.4", + "@jscpd/finder": "4.0.4", + "@jscpd/html-reporter": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "colors": "^1.4.0", + "commander": "^5.0.0", + "fs-extra": "^11.2.0", + "gitignore-to-glob": "^0.3.0", + "jscpd-sarif-reporter": "4.0.6" + }, + "bin": { + "jscpd": "bin/jscpd" + } + }, + "node_modules/jscpd-sarif-reporter": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/jscpd-sarif-reporter/-/jscpd-sarif-reporter-4.0.6.tgz", + "integrity": "sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "^1.4.0", + "fs-extra": "^11.2.0", + "node-sarif-builder": "^3.4.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-sarif-builder": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.4.0.tgz", + "integrity": "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/reprism": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/reprism/-/reprism-0.0.11.tgz", + "integrity": "sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/package.json @@ -0,0 +1,24 @@ +{ + "name": "loop-bench-294r5yrr", + "version": "1.0.0", + "description": "Browser Tetris game in TypeScript", + "main": "index.js", + "scripts": { + "build": "tsc --project tsconfig.json", + "dev": "tsc --project tsconfig.json --watch", + "test": "playwright test" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@playwright/test": "^1.59.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/report/jscpd-report.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/report/jscpd-report.json @@ -0,0 +1,144 @@ +{ + "statistics": { + "detectionDate": "2026-04-05T19:39:17.972Z", + "formats": { + "typescript": { + "sources": { + "src/tetris.ts": { + "lines": 606, + "tokens": 6963, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 606, + "tokens": 6963, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "javascript": { + "sources": { + "dist/tetris.js": { + "lines": 541, + "tokens": 6863, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 541, + "tokens": 6863, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "json": { + "sources": { + "tsconfig.json": { + "lines": 11, + "tokens": 73, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + }, + "package.json": { + "lines": 23, + "tokens": 146, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 34, + "tokens": 219, + "sources": 2, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "markup": { + "sources": { + "index.html": { + "lines": 226, + "tokens": 1527, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 226, + "tokens": 1527, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + } + }, + "total": { + "lines": 1407, + "tokens": 15572, + "sources": 5, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "duplicates": [] +} +\ No newline at end of file diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/src/tetris.ts b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/src/tetris.ts @@ -0,0 +1,607 @@ +// ─── Constants ─────────────────────────────────────────────────────────────── + +const COLS = 10; +const ROWS = 20; +const BLOCK = 32; // px +const PREVIEW_BLOCK = 24; // px + +const COLORS: Record<string, string> = { + I: "#00f0f0", + O: "#f0f000", + T: "#a000f0", + S: "#00f000", + Z: "#f00000", + J: "#0000f0", + L: "#f0a000", +}; + +const GHOST_ALPHA = 0.25; + +// Each piece defined as a set of rotation states (array of [row, col] offsets) +const PIECES: Record<string, number[][][]> = { + I: [ + [[0,0],[0,1],[0,2],[0,3]], + [[0,2],[1,2],[2,2],[3,2]], + [[2,0],[2,1],[2,2],[2,3]], + [[0,1],[1,1],[2,1],[3,1]], + ], + O: [ + [[0,1],[0,2],[1,1],[1,2]], + [[0,1],[0,2],[1,1],[1,2]], + [[0,1],[0,2],[1,1],[1,2]], + [[0,1],[0,2],[1,1],[1,2]], + ], + T: [ + [[0,1],[1,0],[1,1],[1,2]], + [[0,1],[1,1],[1,2],[2,1]], + [[1,0],[1,1],[1,2],[2,1]], + [[0,1],[1,0],[1,1],[2,1]], + ], + S: [ + [[0,1],[0,2],[1,0],[1,1]], + [[0,1],[1,1],[1,2],[2,2]], + [[1,1],[1,2],[2,0],[2,1]], + [[0,0],[1,0],[1,1],[2,1]], + ], + Z: [ + [[0,0],[0,1],[1,1],[1,2]], + [[0,2],[1,1],[1,2],[2,1]], + [[1,0],[1,1],[2,1],[2,2]], + [[0,1],[1,0],[1,1],[2,0]], + ], + J: [ + [[0,0],[1,0],[1,1],[1,2]], + [[0,1],[0,2],[1,1],[2,1]], + [[1,0],[1,1],[1,2],[2,2]], + [[0,1],[1,1],[2,0],[2,1]], + ], + L: [ + [[0,2],[1,0],[1,1],[1,2]], + [[0,1],[1,1],[2,1],[2,2]], + [[1,0],[1,1],[1,2],[2,0]], + [[0,0],[0,1],[1,1],[2,1]], + ], +}; + +const PIECE_TYPES = Object.keys(PIECES); + +// Wall kick data (SRS) for J, L, S, T, Z +const KICKS_JLSTZ: Record<string, [number, number][]> = { + "0->1": [[ 0,0],[-1,0],[-1, 1],[0,-2],[-1,-2]], + "1->0": [[ 0,0],[ 1,0],[ 1,-1],[0, 2],[ 1, 2]], + "1->2": [[ 0,0],[ 1,0],[ 1,-1],[0, 2],[ 1, 2]], + "2->1": [[ 0,0],[-1,0],[-1, 1],[0,-2],[-1,-2]], + "2->3": [[ 0,0],[ 1,0],[ 1, 1],[0,-2],[ 1,-2]], + "3->2": [[ 0,0],[-1,0],[-1,-1],[0, 2],[-1, 2]], + "3->0": [[ 0,0],[-1,0],[-1,-1],[0, 2],[-1, 2]], + "0->3": [[ 0,0],[ 1,0],[ 1, 1],[0,-2],[ 1,-2]], +}; + +// Wall kick data (SRS) for I +const KICKS_I: Record<string, [number, number][]> = { + "0->1": [[ 0,0],[-2,0],[ 1,0],[-2,-1],[ 1, 2]], + "1->0": [[ 0,0],[ 2,0],[-1,0],[ 2, 1],[-1,-2]], + "1->2": [[ 0,0],[-1,0],[ 2,0],[-1, 2],[ 2,-1]], + "2->1": [[ 0,0],[ 1,0],[-2,0],[ 1,-2],[-2, 1]], + "2->3": [[ 0,0],[ 2,0],[-1,0],[ 2, 1],[-1,-2]], + "3->2": [[ 0,0],[-2,0],[ 1,0],[-2,-1],[ 1, 2]], + "3->0": [[ 0,0],[ 1,0],[-2,0],[ 1,-2],[-2, 1]], + "0->3": [[ 0,0],[-1,0],[ 2,0],[-1, 2],[ 2,-1]], +}; + +// Scoring per lines cleared +const LINE_SCORES = [0, 100, 300, 500, 800]; +// Speed levels (ms per drop tick) +const LEVEL_SPEEDS = [800, 720, 630, 550, 470, 380, 300, 215, 130, 100, 80, 80, 80, 70, 70, 70, 50, 50, 50, 30]; + +// ─── Types ──────────────────────────────────────────────────────────────────── + +type Cell = string | null; // null = empty, string = color +type Board = Cell[][]; + +interface Piece { + type: string; + rot: number; // 0-3 + row: number; + col: number; +} + +// ─── Game State ─────────────────────────────────────────────────────────────── + +let board: Board = []; +let current: Piece | null = null; +let next: Piece | null = null; +let score = 0; +let lines = 0; +let level = 0; +let gameOver = false; +let paused = false; +let dropTimer = 0; +let lastTime = 0; +let animFrameId = 0; +let lockDelay = 0; +let lockDelayMax = 500; // ms +let onGround = false; +let lockMoves = 0; +let lockMovesMax = 15; + +// ─── Canvas Setup ───────────────────────────────────────────────────────────── + +const canvas = document.getElementById("board") as HTMLCanvasElement; +const ctx = canvas.getContext("2d")!; +canvas.width = COLS * BLOCK; +canvas.height = ROWS * BLOCK; + +const previewCanvas = document.getElementById("preview") as HTMLCanvasElement; +const previewCtx = previewCanvas.getContext("2d")!; +previewCanvas.width = 6 * PREVIEW_BLOCK; +previewCanvas.height = 4 * PREVIEW_BLOCK; + +const scoreEl = document.getElementById("score")!; +const linesEl = document.getElementById("lines")!; +const levelEl = document.getElementById("level")!; +const msgEl = document.getElementById("message")!; + +// ─── Board Helpers ──────────────────────────────────────────────────────────── + +function createBoard(): Board { + return Array.from({ length: ROWS }, () => Array(COLS).fill(null)); +} + +function getBlocks(piece: Piece): [number, number][] { + return PIECES[piece.type][piece.rot].map(([r, c]) => [piece.row + r, piece.col + c]); +} + +function isValid(piece: Piece): boolean { + for (const [r, c] of getBlocks(piece)) { + if (r < 0 || r >= ROWS || c < 0 || c >= COLS) return false; + if (r >= 0 && board[r][c] !== null) return false; + } + return true; +} + +function placePiece(piece: Piece): void { + const color = COLORS[piece.type]; + for (const [r, c] of getBlocks(piece)) { + if (r >= 0) board[r][c] = color; + } +} + +function clearLines(): number { + let cleared = 0; + for (let r = ROWS - 1; r >= 0; r--) { + if (board[r].every(cell => cell !== null)) { + board.splice(r, 1); + board.unshift(Array(COLS).fill(null)); + cleared++; + r++; // recheck same row index + } + } + return cleared; +} + +// ─── Piece Factory ──────────────────────────────────────────────────────────── + +function randomPiece(): Piece { + const type = PIECE_TYPES[Math.floor(Math.random() * PIECE_TYPES.length)]; + return { type, rot: 0, row: 0, col: 3 }; +} + +function spawnPiece(): boolean { + current = next ?? randomPiece(); + next = randomPiece(); + // Center spawn + current.col = Math.floor((COLS - 4) / 2); + current.row = 0; + + // Try spawning; if invalid try row -1 + if (!isValid(current)) { + current.row = -1; + if (!isValid(current)) return false; + } + lockDelay = 0; + lockMoves = 0; + onGround = false; + return true; +} + +// ─── Rotation with SRS kicks ────────────────────────────────────────────────── + +function tryRotate(dir: 1 | -1): boolean { + if (!current) return false; + const newRot = ((current.rot + dir) + 4) % 4 as 0 | 1 | 2 | 3; + const key = `${current.rot}->${newRot}`; + const kicks = current.type === "I" ? KICKS_I : (current.type === "O" ? null : KICKS_JLSTZ); + + const testPiece: Piece = { ...current, rot: newRot }; + + if (kicks) { + for (const [kr, kc] of kicks[key] ?? [[0,0]]) { + testPiece.row = current.row + kr; + testPiece.col = current.col + kc; + if (isValid(testPiece)) { + current = { ...testPiece }; + resetLockOnMove(); + return true; + } + } + } else { + // O piece — no kick needed + testPiece.row = current.row; + testPiece.col = current.col; + if (isValid(testPiece)) { + current = { ...testPiece }; + return true; + } + } + return false; +} + +function resetLockOnMove(): void { + if (onGround && lockMoves < lockMovesMax) { + lockDelay = 0; + lockMoves++; + } +} + +// ─── Movement ───────────────────────────────────────────────────────────────── + +function moveLeft(): void { + if (!current || gameOver || paused) return; + const moved: Piece = { ...current, col: current.col - 1 }; + if (isValid(moved)) { current = moved; resetLockOnMove(); } +} + +function moveRight(): void { + if (!current || gameOver || paused) return; + const moved: Piece = { ...current, col: current.col + 1 }; + if (isValid(moved)) { current = moved; resetLockOnMove(); } +} + +function softDrop(): void { + if (!current || gameOver || paused) return; + const moved: Piece = { ...current, row: current.row + 1 }; + if (isValid(moved)) { + current = moved; + dropTimer = 0; + score += 1; + updateUI(); + } +} + +function hardDrop(): void { + if (!current || gameOver || paused) return; + let dropped = 0; + while (true) { + const moved: Piece = { ...current, row: current.row + 1 }; + if (!isValid(moved)) break; + current = moved; + dropped++; + } + score += dropped * 2; + lockPiece(); +} + +function ghostRow(): number { + if (!current) return 0; + let ghost = { ...current }; + while (true) { + const next: Piece = { ...ghost, row: ghost.row + 1 }; + if (!isValid(next)) break; + ghost = next; + } + return ghost.row; +} + +// ─── Piece Locking ──────────────────────────────────────────────────────────── + +function lockPiece(): void { + if (!current) return; + placePiece(current); + const cleared = clearLines(); + if (cleared > 0) { + score += LINE_SCORES[cleared] * (level + 1); + lines += cleared; + level = Math.min(Math.floor(lines / 10), LEVEL_SPEEDS.length - 1); + updateUI(); + } + if (!spawnPiece()) { + gameOver = true; + msgEl.textContent = "GAME OVER"; + msgEl.style.display = "block"; + } +} + +// ─── Update / Game Loop ─────────────────────────────────────────────────────── + +function update(timestamp: number): void { + const dt = timestamp - lastTime; + lastTime = timestamp; + + if (!gameOver && !paused && current) { + const speed = LEVEL_SPEEDS[Math.min(level, LEVEL_SPEEDS.length - 1)]; + + // Check if on ground + const below: Piece = { ...current, row: current.row + 1 }; + const nowOnGround = !isValid(below); + + if (nowOnGround) { + if (!onGround) { + onGround = true; + lockDelay = 0; + } + lockDelay += dt; + if (lockDelay >= lockDelayMax) { + lockPiece(); + } + } else { + onGround = false; + lockDelay = 0; + dropTimer += dt; + if (dropTimer >= speed) { + dropTimer = 0; + current = { ...current, row: current.row + 1 }; + } + } + } + + draw(); + animFrameId = requestAnimationFrame(update); +} + +// ─── Drawing ────────────────────────────────────────────────────────────────── + +function drawBlock( + context: CanvasRenderingContext2D, + r: number, c: number, + color: string, + size: number, + alpha = 1 +): void { + context.globalAlpha = alpha; + context.fillStyle = color; + context.fillRect(c * size + 1, r * size + 1, size - 2, size - 2); + + // Highlight + context.fillStyle = "rgba(255,255,255,0.3)"; + context.fillRect(c * size + 1, r * size + 1, size - 2, 4); + context.fillRect(c * size + 1, r * size + 1, 4, size - 2); + + // Shadow + context.fillStyle = "rgba(0,0,0,0.3)"; + context.fillRect(c * size + 1, r * size + size - 5, size - 2, 4); + context.fillRect(c * size + size - 5, r * size + 1, 4, size - 2); + + context.globalAlpha = 1; +} + +function draw(): void { + // Board background + ctx.fillStyle = "#111"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // Grid lines + ctx.strokeStyle = "rgba(255,255,255,0.05)"; + ctx.lineWidth = 1; + for (let r = 0; r < ROWS; r++) { + for (let c = 0; c < COLS; c++) { + ctx.strokeRect(c * BLOCK, r * BLOCK, BLOCK, BLOCK); + } + } + + // Placed blocks + for (let r = 0; r < ROWS; r++) { + for (let c = 0; c < COLS; c++) { + if (board[r][c]) { + drawBlock(ctx, r, c, board[r][c]!, BLOCK); + } + } + } + + // Ghost piece + if (current && !gameOver) { + const gr = ghostRow(); + if (gr !== current.row) { + const ghostBlocks = PIECES[current.type][current.rot]; + const color = COLORS[current.type]; + for (const [br, bc] of ghostBlocks) { + drawBlock(ctx, gr + br, current.col + bc, color, BLOCK, GHOST_ALPHA); + } + } + } + + // Current piece + if (current && !gameOver) { + const color = COLORS[current.type]; + for (const [r, c] of getBlocks(current)) { + if (r >= 0) drawBlock(ctx, r, c, color, BLOCK); + } + } + + // Paused overlay + if (paused && !gameOver) { + ctx.fillStyle = "rgba(0,0,0,0.6)"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "#fff"; + ctx.font = "bold 28px 'Courier New', monospace"; + ctx.textAlign = "center"; + ctx.fillText("PAUSED", canvas.width / 2, canvas.height / 2); + } + + drawPreview(); +} + +function drawPreview(): void { + previewCtx.fillStyle = "#111"; + previewCtx.fillRect(0, 0, previewCanvas.width, previewCanvas.height); + + if (!next) return; + const color = COLORS[next.type]; + const blocks = PIECES[next.type][0]; + + // Find bounding box + const minR = Math.min(...blocks.map(([r]) => r)); + const maxR = Math.max(...blocks.map(([r]) => r)); + const minC = Math.min(...blocks.map(([, c]) => c)); + const maxC = Math.max(...blocks.map(([, c]) => c)); + const pieceH = maxR - minR + 1; + const pieceW = maxC - minC + 1; + const offsetR = Math.floor((4 - pieceH) / 2) - minR; + const offsetC = Math.floor((6 - pieceW) / 2) - minC; + + for (const [br, bc] of blocks) { + drawBlock(previewCtx, br + offsetR, bc + offsetC, color, PREVIEW_BLOCK); + } +} + +// ─── UI Helpers ─────────────────────────────────────────────────────────────── + +function updateUI(): void { + scoreEl.textContent = score.toString(); + linesEl.textContent = lines.toString(); + levelEl.textContent = level.toString(); +} + +// ─── Input Handling ─────────────────────────────────────────────────────────── + +const keys: Record<string, boolean> = {}; +let dasTimer = 0; +let arrTimer = 0; +const DAS = 170; // Delayed Auto Shift ms +const ARR = 50; // Auto Repeat Rate ms + +document.addEventListener("keydown", (e: KeyboardEvent) => { + if (gameOver) { + if (e.code === "Enter" || e.code === "Space") { + restartGame(); + } + return; + } + + if (e.code === "KeyP" || e.code === "Escape") { + paused = !paused; + msgEl.textContent = paused ? "PAUSED" : ""; + msgEl.style.display = paused ? "block" : "none"; + return; + } + + if (paused) return; + + switch (e.code) { + case "ArrowLeft": + case "KeyA": + if (!keys[e.code]) { moveLeft(); dasTimer = 0; } + keys[e.code] = true; + break; + case "ArrowRight": + case "KeyD": + if (!keys[e.code]) { moveRight(); dasTimer = 0; } + keys[e.code] = true; + break; + case "ArrowDown": + case "KeyS": + softDrop(); + keys[e.code] = true; + break; + case "ArrowUp": + case "KeyW": + tryRotate(1); + e.preventDefault(); + break; + case "KeyZ": + tryRotate(-1); + break; + case "KeyX": + tryRotate(1); + break; + case "Space": + hardDrop(); + e.preventDefault(); + break; + case "KeyC": + // hold piece could be added; for now just prevent default + break; + } +}); + +document.addEventListener("keyup", (e: KeyboardEvent) => { + keys[e.code] = false; + if (e.code === "ArrowLeft" || e.code === "KeyA" || e.code === "ArrowRight" || e.code === "KeyD") { + dasTimer = 0; + arrTimer = 0; + } +}); + +// DAS/ARR loop - run in the main update loop via separate interval +let dasLastTime = 0; +function dasLoop(timestamp: number): void { + const dt = timestamp - dasLastTime; + dasLastTime = timestamp; + + if (!paused && !gameOver) { + const leftHeld = keys["ArrowLeft"] || keys["KeyA"]; + const rightHeld = keys["ArrowRight"] || keys["KeyD"]; + const downHeld = keys["ArrowDown"] || keys["KeyS"]; + + if (leftHeld || rightHeld) { + dasTimer += dt; + if (dasTimer >= DAS) { + arrTimer += dt; + if (arrTimer >= ARR) { + arrTimer = 0; + if (leftHeld) moveLeft(); + if (rightHeld) moveRight(); + } + } + } + + if (downHeld) { + softDrop(); + } + } + + requestAnimationFrame(dasLoop); +} + +// ─── Game Init / Restart ────────────────────────────────────────────────────── + +function startGame(): void { + board = createBoard(); + score = 0; + lines = 0; + level = 0; + gameOver = false; + paused = false; + dropTimer = 0; + lockDelay = 0; + lockMoves = 0; + onGround = false; + next = randomPiece(); + spawnPiece(); + updateUI(); + msgEl.style.display = "none"; +} + +function restartGame(): void { + cancelAnimationFrame(animFrameId); + startGame(); + lastTime = performance.now(); + animFrameId = requestAnimationFrame(update); +} + +// ─── Button Controls ────────────────────────────────────────────────────────── + +document.getElementById("btn-left")?.addEventListener("click", moveLeft); +document.getElementById("btn-right")?.addEventListener("click", moveRight); +document.getElementById("btn-rotate")?.addEventListener("click", () => tryRotate(1)); +document.getElementById("btn-down")?.addEventListener("click", softDrop); +document.getElementById("btn-drop")?.addEventListener("click", hardDrop); +document.getElementById("btn-restart")?.addEventListener("click", restartGame); + +// ─── Boot ───────────────────────────────────────────────────────────────────── + +startGame(); +lastTime = performance.now(); +dasLastTime = performance.now(); +animFrameId = requestAnimationFrame(update); +requestAnimationFrame(dasLoop); diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/tsconfig.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "None", + "lib": ["ES2020", "DOM"], + "strict": true, + "outFile": "dist/tetris.js", + "rootDir": "src", + "ignoreDeprecations": "6.0" + }, + "include": ["src/**/*.ts"] +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/index.html b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/index.html @@ -0,0 +1,199 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Tetris</title> + <style> + /* ── Reset & base ─────────────────────────────────────────────────── */ + *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + + body { + background: #0f172a; + color: #e2e8f0; + font-family: "Segoe UI", system-ui, sans-serif; + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 100vh; + padding: 24px 16px; + gap: 0; + } + + /* ── Layout wrapper ───────────────────────────────────────────────── */ + #app { + display: flex; + gap: 20px; + align-items: flex-start; + } + + /* ── Board area ───────────────────────────────────────────────────── */ + #board-wrapper { + position: relative; + flex-shrink: 0; + } + + #board { + display: block; + border: 2px solid #334155; + border-radius: 4px; + box-shadow: 0 0 40px rgba(0,0,0,0.6); + } + + /* ── Overlay (start / pause / game-over) ─────────────────────────── */ + #overlay { + position: absolute; + inset: 0; + background: rgba(15, 23, 42, 0.88); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 12px; + border-radius: 4px; + backdrop-filter: blur(4px); + } + + #overlay-title { + font-size: 2.4rem; + font-weight: 800; + letter-spacing: 4px; + color: #facc15; + text-shadow: 0 0 20px rgba(250,204,21,0.6); + } + + #overlay-msg { + font-size: 0.9rem; + color: #94a3b8; + } + + /* ── Side panel ───────────────────────────────────────────────────── */ + #panel { + display: flex; + flex-direction: column; + gap: 16px; + min-width: 140px; + } + + .panel-box { + background: #1e293b; + border: 1px solid #334155; + border-radius: 8px; + padding: 12px 16px; + } + + .panel-box h3 { + font-size: 0.65rem; + font-weight: 700; + letter-spacing: 2px; + text-transform: uppercase; + color: #64748b; + margin-bottom: 6px; + } + + .stat-value { + font-size: 1.6rem; + font-weight: 700; + color: #f1f5f9; + line-height: 1; + } + + /* ── Preview canvas ───────────────────────────────────────────────── */ + #preview { + display: block; + border-radius: 4px; + } + + /* ── Buttons ──────────────────────────────────────────────────────── */ + .btn { + display: block; + width: 100%; + padding: 10px 0; + background: #facc15; + color: #0f172a; + font-size: 0.85rem; + font-weight: 800; + letter-spacing: 1px; + text-transform: uppercase; + border: none; + border-radius: 6px; + cursor: pointer; + transition: background 0.15s, transform 0.1s; + } + .btn:hover { background: #fde047; } + .btn:active { transform: scale(0.97); } + + /* ── Controls legend ──────────────────────────────────────────────── */ + .controls { + font-size: 0.72rem; + color: #64748b; + line-height: 1.8; + } + + .controls span { + display: inline-block; + background: #334155; + color: #cbd5e1; + border-radius: 3px; + padding: 0 4px; + font-family: monospace; + font-size: 0.68rem; + } + + /* ── Responsive tweak ─────────────────────────────────────────────── */ + @media (max-width: 520px) { + body { padding: 12px 8px; } + #app { gap: 12px; } + } + </style> +</head> +<body> + <div id="app"> + <!-- Main board --> + <div id="board-wrapper"> + <canvas id="board" width="300" height="600"></canvas> + <div id="overlay"> + <div id="overlay-title">TETRIS</div> + <div id="overlay-msg">Press Start or Enter to play</div> + </div> + </div> + + <!-- Side panel --> + <div id="panel"> + <div class="panel-box"> + <h3>Next</h3> + <canvas id="preview" width="120" height="96"></canvas> + </div> + + <div class="panel-box"> + <h3>Score</h3> + <div class="stat-value" id="score">0</div> + </div> + + <div class="panel-box"> + <h3>Lines</h3> + <div class="stat-value" id="lines">0</div> + </div> + + <div class="panel-box"> + <h3>Level</h3> + <div class="stat-value" id="level">1</div> + </div> + + <button class="btn" id="start-btn">Start</button> + + <div class="panel-box controls"> + <h3>Controls</h3> + <span>← →</span> Move<br/> + <span>↑</span> / <span>X</span> Rotate CW<br/> + <span>Z</span> Rotate CCW<br/> + <span>↓</span> Soft drop<br/> + <span>Space</span> Hard drop<br/> + <span>P</span> Pause + </div> + </div> + </div> + + <script type="module" src="dist/tetris.js"></script> +</body> +</html> diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package-lock.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package-lock.json @@ -0,0 +1,2519 @@ +{ + "name": "loop-bench-kncx228p", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-kncx228p", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.4", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@html-validate/stylish": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-5.1.0.tgz", + "integrity": "sha512-Tyx/ZbHBpVZjvSleNplNMUhqT4UY1HwAMC97GSmasJXggWuvjNFLBS2scqnEb+ZG1szLq4zgjOioj7cVWV9WuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": "^20.11 || >= 22.16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jscpd/badge-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/badge-reporter/-/badge-reporter-4.0.4.tgz", + "integrity": "sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "badgen": "^3.2.3", + "colors": "^1.4.0", + "fs-extra": "^11.2.0" + } + }, + "node_modules/@jscpd/core": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/core/-/core-4.0.4.tgz", + "integrity": "sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@jscpd/finder": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/finder/-/finder-4.0.4.tgz", + "integrity": "sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "blamer": "^1.0.6", + "bytes": "^3.1.2", + "cli-table3": "^0.6.5", + "colors": "^1.4.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "markdown-table": "^2.0.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/html-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/html-reporter/-/html-reporter-4.0.4.tgz", + "integrity": "sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "1.4.0", + "fs-extra": "^11.2.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/tokenizer": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/tokenizer/-/tokenizer-4.0.4.tgz", + "integrity": "sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "reprism": "^0.0.11", + "spark-md5": "^3.0.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/badgen": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/badgen/-/badgen-3.2.3.tgz", + "integrity": "sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blamer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/blamer/-/blamer-1.0.7.tgz", + "integrity": "sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^4.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gitignore-to-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", + "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.4 <5 || >=6.9" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-validate": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-10.11.3.tgz", + "integrity": "sha512-wKUq9iR6bukMgiHhs/ORThZzEbQoFiiPNN7aZfQ8dlmhttPb2sM2Ji2p+Fy5Xj1aH7QHJ1biT2SUDw7A01P2oA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/html-validate" + } + ], + "license": "MIT", + "dependencies": { + "@html-validate/stylish": "^5.0.0", + "@sidvind/better-ajv-errors": "4.0.1", + "ajv": "^8.0.0", + "glob": "^13.0.0", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.mjs" + }, + "engines": { + "node": "^20.19.0 || >= 22.16.0" + }, + "peerDependencies": { + "jest": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-diff": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-snapshot": "^28.1.3 || ^29.0.3 || ^30.0.0", + "vitest": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.1" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/@sidvind/better-ajv-errors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-4.0.1.tgz", + "integrity": "sha512-6arF1ssKxItxgitPYXafUoLmsVBA6K7m9+ZGj6hLDoBl7nWpJ33EInwQUdHTle2METeWGxgQiqSex20KZRykew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "ajv": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jscpd": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-4.0.8.tgz", + "integrity": "sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/badge-reporter": "4.0.4", + "@jscpd/core": "4.0.4", + "@jscpd/finder": "4.0.4", + "@jscpd/html-reporter": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "colors": "^1.4.0", + "commander": "^5.0.0", + "fs-extra": "^11.2.0", + "gitignore-to-glob": "^0.3.0", + "jscpd-sarif-reporter": "4.0.6" + }, + "bin": { + "jscpd": "bin/jscpd" + } + }, + "node_modules/jscpd-sarif-reporter": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/jscpd-sarif-reporter/-/jscpd-sarif-reporter-4.0.6.tgz", + "integrity": "sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "^1.4.0", + "fs-extra": "^11.2.0", + "node-sarif-builder": "^3.4.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-sarif-builder": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.4.0.tgz", + "integrity": "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/reprism": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/reprism/-/reprism-0.0.11.tgz", + "integrity": "sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/package.json @@ -0,0 +1,21 @@ +{ + "name": "loop-bench-kncx228p", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/report/jscpd-report.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/report/jscpd-report.json @@ -0,0 +1,217 @@ +{ + "statistics": { + "detectionDate": "2026-04-05T19:39:05.027Z", + "formats": { + "typescript": { + "sources": { + "src/tetris.ts": { + "lines": 511, + "tokens": 5682, + "sources": 1, + "clones": 2, + "duplicatedLines": 20, + "duplicatedTokens": 230, + "percentage": 3.91, + "percentageTokens": 4.05, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 511, + "tokens": 5682, + "sources": 1, + "clones": 1, + "duplicatedLines": 10, + "duplicatedTokens": 115, + "percentage": 1.96, + "percentageTokens": 2.02, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "javascript": { + "sources": { + "dist/tetris.js": { + "lines": 438, + "tokens": 5241, + "sources": 1, + "clones": 2, + "duplicatedLines": 18, + "duplicatedTokens": 224, + "percentage": 4.11, + "percentageTokens": 4.27, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 438, + "tokens": 5241, + "sources": 1, + "clones": 1, + "duplicatedLines": 9, + "duplicatedTokens": 112, + "percentage": 2.05, + "percentageTokens": 2.14, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "json": { + "sources": { + "tsconfig.json": { + "lines": 11, + "tokens": 73, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + }, + "package.json": { + "lines": 20, + "tokens": 125, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 31, + "tokens": 198, + "sources": 2, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "markup": { + "sources": { + "index.html": { + "lines": 198, + "tokens": 1360, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 198, + "tokens": 1360, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + } + }, + "total": { + "lines": 1178, + "tokens": 12481, + "sources": 5, + "clones": 2, + "duplicatedLines": 19, + "duplicatedTokens": 227, + "percentage": 1.61, + "percentageTokens": 1.82, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "duplicates": [ + { + "format": "typescript", + "lines": 11, + "fragment": "const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n const candidate = { ...rotated, col: rotated.col + kick };\n if (!collides(this.board, pieceCells(candidate))) {\n this.current = candidate;\n return;\n }\n }\n }\n\n private hardDrop", + "tokens": 0, + "firstFile": { + "name": "src/tetris.ts", + "start": 423, + "end": 433, + "startLoc": { + "line": 423, + "column": 5, + "position": 4889 + }, + "endLoc": { + "line": 433, + "column": 9, + "position": 5004 + } + }, + "secondFile": { + "name": "src/tetris.ts", + "start": 409, + "end": 419, + "startLoc": { + "line": 409, + "column": 5, + "position": 4695 + }, + "endLoc": { + "line": 419, + "column": 10, + "position": 4810 + } + } + }, + { + "format": "javascript", + "lines": 10, + "fragment": "const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n const candidate = { ...rotated, col: rotated.col + kick };\n if (!collides(this.board, pieceCells(candidate))) {\n this.current = candidate;\n return;\n }\n }\n }\n hardDrop", + "tokens": 0, + "firstFile": { + "name": "dist/tetris.js", + "start": 348, + "end": 357, + "startLoc": { + "line": 348, + "column": 9, + "position": 4464 + }, + "endLoc": { + "line": 357, + "column": 9, + "position": 4576 + } + }, + "secondFile": { + "name": "dist/tetris.js", + "start": 335, + "end": 344, + "startLoc": { + "line": 335, + "column": 9, + "position": 4276 + }, + "endLoc": { + "line": 344, + "column": 10, + "position": 4388 + } + } + } + ] +} +\ No newline at end of file diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/src/tetris.ts b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/src/tetris.ts @@ -0,0 +1,512 @@ +// ─── Constants ──────────────────────────────────────────────────────────────── + +const COLS = 10; +const ROWS = 20; +const BLOCK = 30; // px per cell on the main board +const PREVIEW_BLOCK = 24; // px per cell in the preview box + +// Colours for each tetromino (index 0 = empty) +const COLORS: string[] = [ + "transparent", // 0 – empty + "#00CFCF", // 1 – I (cyan) + "#1E90FF", // 2 – J (blue) + "#FF8C00", // 3 – L (orange) + "#FFD700", // 4 – O (yellow) + "#32CD32", // 5 – S (green) + "#A020F0", // 6 – T (purple) + "#FF3030", // 7 – Z (red) +]; + +// Tetromino shapes – each piece is defined as all 4 rotations (arrays of [row,col] offsets) +type Cells = [number, number][]; + +interface PieceDef { + rotations: Cells[]; + colorIndex: number; +} + +function rotateCW(cells: Cells): Cells { + // Rotate 90° clockwise: (r, c) → (c, -r) + return cells.map(([r, c]) => [c, -r]); +} + +function normalise(cells: Cells): Cells { + const minR = Math.min(...cells.map(([r]) => r)); + const minC = Math.min(...cells.map(([, c]) => c)); + return cells.map(([r, c]) => [r - minR, c - minC]); +} + +function buildRotations(base: Cells): Cells[] { + const rots: Cells[] = [normalise(base)]; + for (let i = 0; i < 3; i++) { + rots.push(normalise(rotateCW(rots[rots.length - 1]))); + } + return rots; +} + +const PIECES: PieceDef[] = [ + // I + { rotations: buildRotations([[0,0],[0,1],[0,2],[0,3]]), colorIndex: 1 }, + // J + { rotations: buildRotations([[0,0],[1,0],[1,1],[1,2]]), colorIndex: 2 }, + // L + { rotations: buildRotations([[0,2],[1,0],[1,1],[1,2]]), colorIndex: 3 }, + // O + { rotations: buildRotations([[0,0],[0,1],[1,0],[1,1]]), colorIndex: 4 }, + // S + { rotations: buildRotations([[0,1],[0,2],[1,0],[1,1]]), colorIndex: 5 }, + // T + { rotations: buildRotations([[0,1],[1,0],[1,1],[1,2]]), colorIndex: 6 }, + // Z + { rotations: buildRotations([[0,0],[0,1],[1,1],[1,2]]), colorIndex: 7 }, +]; + +// Scoring table (points per lines cleared simultaneously) +const SCORE_TABLE = [0, 100, 300, 500, 800]; + +// Initial drop interval in ms +const BASE_INTERVAL = 800; +// Interval decrease per level (ms) +const LEVEL_SPEED = 60; +// Minimum interval +const MIN_INTERVAL = 80; + +// ─── Game State ─────────────────────────────────────────────────────────────── + +type Board = number[][]; // ROWS × COLS, value = colorIndex + +interface Piece { + def: PieceDef; + rotIdx: number; + row: number; + col: number; +} + +function createBoard(): Board { + return Array.from({ length: ROWS }, () => Array(COLS).fill(0)); +} + +function randomPiece(): Piece { + const def = PIECES[Math.floor(Math.random() * PIECES.length)]; + const cells = def.rotations[0]; + const maxCol = Math.max(...cells.map(([, c]) => c)); + const col = Math.floor((COLS - maxCol - 1) / 2); + return { def, rotIdx: 0, row: 0, col }; +} + +function pieceCells(p: Piece): Cells { + return p.def.rotations[p.rotIdx].map(([r, c]) => [r + p.row, c + p.col]); +} + +function collides(board: Board, cells: Cells): boolean { + for (const [r, c] of cells) { + if (r >= ROWS || c < 0 || c >= COLS) return true; + if (r >= 0 && board[r][c] !== 0) return true; + } + return false; +} + +// ─── Renderer ───────────────────────────────────────────────────────────────── + +class Renderer { + private ctx: CanvasRenderingContext2D; + private pCtx: CanvasRenderingContext2D; + + constructor( + private canvas: HTMLCanvasElement, + private previewCanvas: HTMLCanvasElement, + ) { + this.ctx = canvas.getContext("2d")!; + this.pCtx = previewCanvas.getContext("2d")!; + } + + drawBlock(ctx: CanvasRenderingContext2D, r: number, c: number, color: string, size: number): void { + const x = c * size; + const y = r * size; + const inset = 2; + + ctx.fillStyle = color; + ctx.fillRect(x, y, size, size); + + // Highlight top-left + ctx.fillStyle = "rgba(255,255,255,0.35)"; + ctx.fillRect(x + inset, y + inset, size - inset * 2, inset); + ctx.fillRect(x + inset, y + inset, inset, size - inset * 2); + + // Shadow bottom-right + ctx.fillStyle = "rgba(0,0,0,0.25)"; + ctx.fillRect(x + inset, y + size - inset * 2, size - inset * 2, inset); + ctx.fillRect(x + size - inset * 2, y + inset, inset, size - inset * 2); + } + + drawBoard(board: Board): void { + const { ctx } = this; + ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + // Grid background + ctx.fillStyle = "#111827"; + ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + // Subtle grid lines + ctx.strokeStyle = "rgba(255,255,255,0.05)"; + ctx.lineWidth = 0.5; + for (let r = 0; r <= ROWS; r++) { + ctx.beginPath(); + ctx.moveTo(0, r * BLOCK); + ctx.lineTo(COLS * BLOCK, r * BLOCK); + ctx.stroke(); + } + for (let c = 0; c <= COLS; c++) { + ctx.beginPath(); + ctx.moveTo(c * BLOCK, 0); + ctx.lineTo(c * BLOCK, ROWS * BLOCK); + ctx.stroke(); + } + + // Locked blocks + for (let r = 0; r < ROWS; r++) { + for (let c = 0; c < COLS; c++) { + if (board[r][c] !== 0) { + this.drawBlock(ctx, r, c, COLORS[board[r][c]], BLOCK); + } + } + } + } + + drawGhost(board: Board, piece: Piece): void { + // Find lowest valid position + let ghostPiece = { ...piece }; + while (true) { + const next = { ...ghostPiece, row: ghostPiece.row + 1 }; + if (collides(board, pieceCells(next))) break; + ghostPiece = next; + } + if (ghostPiece.row === piece.row) return; + + const { ctx } = this; + for (const [r, c] of pieceCells(ghostPiece)) { + if (r < 0) continue; + const x = c * BLOCK; + const y = r * BLOCK; + ctx.strokeStyle = COLORS[piece.def.colorIndex]; + ctx.lineWidth = 2; + ctx.strokeRect(x + 1, y + 1, BLOCK - 2, BLOCK - 2); + } + } + + drawPiece(piece: Piece): void { + const { ctx } = this; + for (const [r, c] of pieceCells(piece)) { + if (r < 0) continue; + this.drawBlock(ctx, r, c, COLORS[piece.def.colorIndex], BLOCK); + } + } + + drawPreview(next: Piece): void { + const { pCtx, previewCanvas } = this; + const size = PREVIEW_BLOCK; + pCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height); + pCtx.fillStyle = "#111827"; + pCtx.fillRect(0, 0, previewCanvas.width, previewCanvas.height); + + const cells = next.def.rotations[0]; + const maxR = Math.max(...cells.map(([r]) => r)); + const maxC = Math.max(...cells.map(([, c]) => c)); + const offR = Math.floor((previewCanvas.height / size - maxR - 1) / 2); + const offC = Math.floor((previewCanvas.width / size - maxC - 1) / 2); + + for (const [r, c] of cells) { + this.drawBlock(pCtx, r + offR, c + offC, COLORS[next.def.colorIndex], size); + } + } +} + +// ─── Game ───────────────────────────────────────────────────────────────────── + +type GameState = "idle" | "playing" | "paused" | "gameover"; + +class TetrisGame { + private board: Board = createBoard(); + private current: Piece = randomPiece(); + private next: Piece = randomPiece(); + private score = 0; + private lines = 0; + private level = 1; + private state: GameState = "idle"; + private lastDrop = 0; + private animId = 0; + + private renderer: Renderer; + private scoreEl: HTMLElement; + private linesEl: HTMLElement; + private levelEl: HTMLElement; + private overlayEl: HTMLElement; + private overlayTitleEl: HTMLElement; + private overlayMsgEl: HTMLElement; + private startBtn: HTMLElement; + + constructor() { + const canvas = document.getElementById("board") as HTMLCanvasElement; + const preview = document.getElementById("preview") as HTMLCanvasElement; + this.renderer = new Renderer(canvas, preview); + this.scoreEl = document.getElementById("score")!; + this.linesEl = document.getElementById("lines")!; + this.levelEl = document.getElementById("level")!; + this.overlayEl = document.getElementById("overlay")!; + this.overlayTitleEl = document.getElementById("overlay-title")!; + this.overlayMsgEl = document.getElementById("overlay-msg")!; + this.startBtn = document.getElementById("start-btn")!; + + this.startBtn.addEventListener("click", () => this.startOrRestart()); + document.addEventListener("keydown", (e) => this.handleKey(e)); + + this.showOverlay("TETRIS", "Press Start or Enter to play"); + } + + private get dropInterval(): number { + return Math.max(MIN_INTERVAL, BASE_INTERVAL - (this.level - 1) * LEVEL_SPEED); + } + + private showOverlay(title: string, msg: string): void { + this.overlayTitleEl.textContent = title; + this.overlayMsgEl.textContent = msg; + this.overlayEl.style.display = "flex"; + } + + private hideOverlay(): void { + this.overlayEl.style.display = "none"; + } + + private startOrRestart(): void { + if (this.state === "gameover" || this.state === "idle") { + this.board = createBoard(); + this.current = randomPiece(); + this.next = randomPiece(); + this.score = 0; + this.lines = 0; + this.level = 1; + this.updateUI(); + } + if (this.state === "paused") { + this.resume(); + return; + } + this.state = "playing"; + this.hideOverlay(); + this.lastDrop = performance.now(); + cancelAnimationFrame(this.animId); + this.animId = requestAnimationFrame((t) => this.loop(t)); + } + + private pause(): void { + if (this.state !== "playing") return; + this.state = "paused"; + cancelAnimationFrame(this.animId); + this.showOverlay("PAUSED", "Press P or Start to resume"); + } + + private resume(): void { + if (this.state !== "paused") return; + this.state = "playing"; + this.hideOverlay(); + this.lastDrop = performance.now(); + this.animId = requestAnimationFrame((t) => this.loop(t)); + } + + private loop(timestamp: number): void { + if (this.state !== "playing") return; + + if (timestamp - this.lastDrop >= this.dropInterval) { + this.lastDrop = timestamp; + this.drop(); + } + + this.render(); + this.animId = requestAnimationFrame((t) => this.loop(t)); + } + + private render(): void { + this.renderer.drawBoard(this.board); + this.renderer.drawGhost(this.board, this.current); + this.renderer.drawPiece(this.current); + this.renderer.drawPreview(this.next); + } + + private drop(): void { + const moved = { ...this.current, row: this.current.row + 1 }; + if (collides(this.board, pieceCells(moved))) { + this.lock(); + } else { + this.current = moved; + } + } + + private lock(): void { + for (const [r, c] of pieceCells(this.current)) { + if (r < 0) { + this.gameOver(); + return; + } + this.board[r][c] = this.current.def.colorIndex; + } + this.clearLines(); + this.current = this.next; + this.next = randomPiece(); + this.renderer.drawPreview(this.next); + + // Check if new piece immediately collides → game over + if (collides(this.board, pieceCells(this.current))) { + this.gameOver(); + } + } + + private clearLines(): void { + let cleared = 0; + for (let r = ROWS - 1; r >= 0; r--) { + if (this.board[r].every((v) => v !== 0)) { + this.board.splice(r, 1); + this.board.unshift(Array(COLS).fill(0)); + cleared++; + r++; // re-check same row index + } + } + if (cleared > 0) { + this.score += SCORE_TABLE[cleared] * this.level; + this.lines += cleared; + this.level = Math.floor(this.lines / 10) + 1; + this.updateUI(); + } + } + + private gameOver(): void { + this.state = "gameover"; + cancelAnimationFrame(this.animId); + this.render(); + this.showOverlay("GAME OVER", `Score: ${this.score} — Press Start to play again`); + this.startBtn.textContent = "Restart"; + } + + private updateUI(): void { + this.scoreEl.textContent = String(this.score); + this.linesEl.textContent = String(this.lines); + this.levelEl.textContent = String(this.level); + } + + private moveLeft(): void { + const moved = { ...this.current, col: this.current.col - 1 }; + if (!collides(this.board, pieceCells(moved))) this.current = moved; + } + + private moveRight(): void { + const moved = { ...this.current, col: this.current.col + 1 }; + if (!collides(this.board, pieceCells(moved))) this.current = moved; + } + + private rotate(): void { + const nextRotIdx = (this.current.rotIdx + 1) % this.current.def.rotations.length; + const rotated = { ...this.current, rotIdx: nextRotIdx }; + // Wall-kick: try offsets 0, -1, +1, -2, +2 + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + const candidate = { ...rotated, col: rotated.col + kick }; + if (!collides(this.board, pieceCells(candidate))) { + this.current = candidate; + return; + } + } + } + + private rotateCCW(): void { + const len = this.current.def.rotations.length; + const nextRotIdx = (this.current.rotIdx + len - 1) % len; + const rotated = { ...this.current, rotIdx: nextRotIdx }; + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + const candidate = { ...rotated, col: rotated.col + kick }; + if (!collides(this.board, pieceCells(candidate))) { + this.current = candidate; + return; + } + } + } + + private hardDrop(): void { + while (true) { + const moved = { ...this.current, row: this.current.row + 1 }; + if (collides(this.board, pieceCells(moved))) break; + this.current = moved; + this.score += 2; + } + this.updateUI(); + this.lock(); + } + + private softDrop(): void { + const moved = { ...this.current, row: this.current.row + 1 }; + if (!collides(this.board, pieceCells(moved))) { + this.current = moved; + this.score += 1; + this.updateUI(); + this.lastDrop = performance.now(); // reset auto-drop timer + } + } + + private handleKey(e: KeyboardEvent): void { + if (e.key === "Enter") { + if (this.state === "idle" || this.state === "gameover") { + this.startOrRestart(); + return; + } + } + if (e.key === "p" || e.key === "P") { + if (this.state === "playing") { this.pause(); return; } + if (this.state === "paused") { this.resume(); return; } + } + if (this.state !== "playing") return; + + switch (e.key) { + case "ArrowLeft": + case "a": + case "A": + e.preventDefault(); + this.moveLeft(); + break; + case "ArrowRight": + case "d": + case "D": + e.preventDefault(); + this.moveRight(); + break; + case "ArrowDown": + case "s": + case "S": + e.preventDefault(); + this.softDrop(); + break; + case "ArrowUp": + case "w": + case "W": + case "x": + case "X": + e.preventDefault(); + this.rotate(); + break; + case "z": + case "Z": + e.preventDefault(); + this.rotateCCW(); + break; + case " ": + e.preventDefault(); + this.hardDrop(); + break; + } + this.render(); + } +} + +// ─── Bootstrap ──────────────────────────────────────────────────────────────── + +window.addEventListener("DOMContentLoaded", () => { + new TetrisGame(); +}); diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/tsconfig.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "bundler", + "strict": true, + "outDir": "./dist", + "rootDir": "./src", + "lib": ["ES2020", "DOM"] + }, + "include": ["src/**/*"] +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/index.html b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/index.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Tetris</title> + <link rel="stylesheet" href="style.css" /> +</head> +<body> + +<div id="wrapper"> + + <!-- ── Left panel: Hold + Controls ── --> + <div class="side-panel"> + <div class="panel-box"> + <div class="panel-label">Hold</div> + <canvas id="hold-canvas" width="120" height="120"></canvas> + </div> + + <div class="panel-box" style="gap:2px"> + <div class="panel-label" style="margin-bottom:4px">Controls</div> + <div id="controls"> + <span>← →</span> <span>Move</span> + <span>↓</span> <span>Soft drop</span> + <span>Space</span> <span>Hard drop</span> + <span>↑ / X</span> <span>Rotate CW</span> + <span>Z</span> <span>Rotate CCW</span> + <span>C</span> <span>Hold</span> + <span>P / Esc</span> <span>Pause</span> + </div> + </div> + </div> + + <!-- ── Main board ── --> + <div id="game-wrap"> + <canvas id="game-canvas" width="300" height="600"></canvas> + + <!-- Overlay for title / pause / game-over --> + <div id="overlay"> + <div id="ov-title">TETRIS</div> + <div id="ov-msg">Press Space to start</div> + <div class="controls" style="margin-top:8px"> + <span>← →</span> <span>Move</span> + <span>↓</span> <span>Soft drop</span> + <span>Space</span> <span>Hard drop</span> + <span>↑ / X</span> <span>Rotate CW</span> + <span>Z</span> <span>Rotate CCW</span> + <span>C</span> <span>Hold piece</span> + <span>P</span> <span>Pause</span> + </div> + <button id="start-btn">START</button> + </div> + </div> + + <!-- ── Right panel: Next + Stats ── --> + <div class="side-panel"> + <div class="panel-box"> + <div class="panel-label">Next</div> + <canvas id="next-canvas" width="120" height="120"></canvas> + </div> + + <div class="panel-box"> + <div class="panel-label">Score</div> + <div class="panel-value" id="score">0</div> + </div> + + <div class="panel-box"> + <div class="panel-label">Level</div> + <div class="panel-value" id="level">1</div> + </div> + + <div class="panel-box"> + <div class="panel-label">Lines</div> + <div class="panel-value" id="lines">0</div> + </div> + </div> + +</div> + +<script type="module" src="dist/tetris.js"></script> +</body> +</html> diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package-lock.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package-lock.json @@ -0,0 +1,2519 @@ +{ + "name": "loop-bench-6c3p0wr6", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-6c3p0wr6", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.4", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@html-validate/stylish": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-5.1.0.tgz", + "integrity": "sha512-Tyx/ZbHBpVZjvSleNplNMUhqT4UY1HwAMC97GSmasJXggWuvjNFLBS2scqnEb+ZG1szLq4zgjOioj7cVWV9WuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": "^20.11 || >= 22.16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jscpd/badge-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/badge-reporter/-/badge-reporter-4.0.4.tgz", + "integrity": "sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "badgen": "^3.2.3", + "colors": "^1.4.0", + "fs-extra": "^11.2.0" + } + }, + "node_modules/@jscpd/core": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/core/-/core-4.0.4.tgz", + "integrity": "sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@jscpd/finder": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/finder/-/finder-4.0.4.tgz", + "integrity": "sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "blamer": "^1.0.6", + "bytes": "^3.1.2", + "cli-table3": "^0.6.5", + "colors": "^1.4.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "markdown-table": "^2.0.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/html-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/html-reporter/-/html-reporter-4.0.4.tgz", + "integrity": "sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "1.4.0", + "fs-extra": "^11.2.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/tokenizer": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/tokenizer/-/tokenizer-4.0.4.tgz", + "integrity": "sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "reprism": "^0.0.11", + "spark-md5": "^3.0.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/badgen": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/badgen/-/badgen-3.2.3.tgz", + "integrity": "sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blamer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/blamer/-/blamer-1.0.7.tgz", + "integrity": "sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^4.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gitignore-to-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", + "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.4 <5 || >=6.9" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-validate": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-10.11.3.tgz", + "integrity": "sha512-wKUq9iR6bukMgiHhs/ORThZzEbQoFiiPNN7aZfQ8dlmhttPb2sM2Ji2p+Fy5Xj1aH7QHJ1biT2SUDw7A01P2oA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/html-validate" + } + ], + "license": "MIT", + "dependencies": { + "@html-validate/stylish": "^5.0.0", + "@sidvind/better-ajv-errors": "4.0.1", + "ajv": "^8.0.0", + "glob": "^13.0.0", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.mjs" + }, + "engines": { + "node": "^20.19.0 || >= 22.16.0" + }, + "peerDependencies": { + "jest": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-diff": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-snapshot": "^28.1.3 || ^29.0.3 || ^30.0.0", + "vitest": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.1" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/@sidvind/better-ajv-errors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-4.0.1.tgz", + "integrity": "sha512-6arF1ssKxItxgitPYXafUoLmsVBA6K7m9+ZGj6hLDoBl7nWpJ33EInwQUdHTle2METeWGxgQiqSex20KZRykew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "ajv": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jscpd": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-4.0.8.tgz", + "integrity": "sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/badge-reporter": "4.0.4", + "@jscpd/core": "4.0.4", + "@jscpd/finder": "4.0.4", + "@jscpd/html-reporter": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "colors": "^1.4.0", + "commander": "^5.0.0", + "fs-extra": "^11.2.0", + "gitignore-to-glob": "^0.3.0", + "jscpd-sarif-reporter": "4.0.6" + }, + "bin": { + "jscpd": "bin/jscpd" + } + }, + "node_modules/jscpd-sarif-reporter": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/jscpd-sarif-reporter/-/jscpd-sarif-reporter-4.0.6.tgz", + "integrity": "sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "^1.4.0", + "fs-extra": "^11.2.0", + "node-sarif-builder": "^3.4.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-sarif-builder": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.4.0.tgz", + "integrity": "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/reprism": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/reprism/-/reprism-0.0.11.tgz", + "integrity": "sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/package.json @@ -0,0 +1,23 @@ +{ + "name": "loop-bench-6c3p0wr6", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/report/jscpd-report.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/report/jscpd-report.json @@ -0,0 +1,245 @@ +{ + "statistics": { + "detectionDate": "2026-04-05T19:39:05.000Z", + "formats": { + "typescript": { + "sources": { + "src/tetris.ts": { + "lines": 734, + "tokens": 9012, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 734, + "tokens": 9012, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "javascript": { + "sources": { + "dist/tetris.js": { + "lines": 678, + "tokens": 8762, + "sources": 1, + "clones": 2, + "duplicatedLines": 10, + "duplicatedTokens": 162, + "percentage": 1.47, + "percentageTokens": 1.85, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 678, + "tokens": 8762, + "sources": 1, + "clones": 1, + "duplicatedLines": 5, + "duplicatedTokens": 81, + "percentage": 0.74, + "percentageTokens": 0.92, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "json": { + "sources": { + "tsconfig.json": { + "lines": 13, + "tokens": 87, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + }, + "package.json": { + "lines": 22, + "tokens": 139, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 35, + "tokens": 226, + "sources": 2, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "css": { + "sources": { + "style.css": { + "lines": 150, + "tokens": 934, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 150, + "tokens": 934, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "markup": { + "sources": { + "index.html": { + "lines": 81, + "tokens": 907, + "sources": 1, + "clones": 2, + "duplicatedLines": 12, + "duplicatedTokens": 232, + "percentage": 14.81, + "percentageTokens": 25.58, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 81, + "tokens": 907, + "sources": 1, + "clones": 1, + "duplicatedLines": 6, + "duplicatedTokens": 116, + "percentage": 7.41, + "percentageTokens": 12.79, + "newDuplicatedLines": 0, + "newClones": 0 + } + } + }, + "total": { + "lines": 1678, + "tokens": 19841, + "sources": 6, + "clones": 2, + "duplicatedLines": 11, + "duplicatedTokens": 197, + "percentage": 0.66, + "percentageTokens": 0.99, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "duplicates": [ + { + "format": "javascript", + "lines": 6, + "fragment": "ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n ctx.lineWidth = 1;\n for (let c = 0; c <= BOARD_W; c++) {\n ctx.beginPath();\n ctx.moveTo(c * CELL, 0);\n ctx.lineTo(c * CELL, BOARD_H", + "tokens": 0, + "firstFile": { + "name": "dist/tetris.js", + "start": 653, + "end": 658, + "startLoc": { + "line": 653, + "column": 9, + "position": 8421 + }, + "endLoc": { + "line": 658, + "column": 8, + "position": 8502 + } + }, + "secondFile": { + "name": "dist/tetris.js", + "start": 566, + "end": 571, + "startLoc": { + "line": 566, + "column": 9, + "position": 7273 + }, + "endLoc": { + "line": 571, + "column": 2, + "position": 7354 + } + } + }, + { + "format": "markup", + "lines": 7, + "fragment": "\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece", + "tokens": 0, + "firstFile": { + "name": "index.html", + "start": 42, + "end": 48, + "startLoc": { + "line": 42, + "column": 15, + "position": 472 + }, + "endLoc": { + "line": 48, + "column": 6, + "position": 588 + } + }, + "secondFile": { + "name": "index.html", + "start": 22, + "end": 28, + "startLoc": { + "line": 22, + "column": 9, + "position": 211 + }, + "endLoc": { + "line": 28, + "column": 3, + "position": 326 + } + } + } + ] +} +\ No newline at end of file diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/src/tetris.ts b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/src/tetris.ts @@ -0,0 +1,735 @@ +// ============================================================= +// TETRIS – Full browser implementation in TypeScript +// ============================================================= + +// ── Constants ────────────────────────────────────────────── +const BOARD_W = 10; +const BOARD_H = 20; +const CELL = 30; // px per cell on main board +const PREVIEW_W = 120; // px wide of hold / next canvas +const PREVIEW_H = 120; + +// ── Types ────────────────────────────────────────────────── +type PieceType = 'I' | 'O' | 'T' | 'S' | 'Z' | 'J' | 'L'; +type Cell = string | null; +type Board = Cell[][]; +type GameState = 'idle' | 'playing' | 'paused' | 'gameover'; + +interface Piece { + type: PieceType; + x: number; // board column of shape origin + y: number; // board row of shape origin + rotation: number; // 0–3 +} + +// ── Colours ──────────────────────────────────────────────── +const COLORS: Record<PieceType, string> = { + I: '#00f0f0', + O: '#f0f000', + T: '#a020f0', + S: '#00e000', + Z: '#f00000', + J: '#2040f0', + L: '#f0a000', +}; + +// Slightly darker shade used for 3-D inner shadow +const DARK: Record<PieceType, string> = { + I: '#009090', + O: '#909000', + T: '#601890', + S: '#008000', + Z: '#900000', + J: '#102080', + L: '#905800', +}; + +// ── Shapes (4 rotations each) ────────────────────────────── +// 1 = filled, 0 = empty +const SHAPES: Record<PieceType, readonly (readonly number[])[][]> = { + I: [ + [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]], + [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]], + [[0,0,0,0],[0,0,0,0],[1,1,1,1],[0,0,0,0]], + [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]], + ], + O: [ + [[0,1,1,0],[0,1,1,0],[0,0,0,0]], + [[0,1,1,0],[0,1,1,0],[0,0,0,0]], + [[0,1,1,0],[0,1,1,0],[0,0,0,0]], + [[0,1,1,0],[0,1,1,0],[0,0,0,0]], + ], + T: [ + [[0,1,0],[1,1,1],[0,0,0]], + [[0,1,0],[0,1,1],[0,1,0]], + [[0,0,0],[1,1,1],[0,1,0]], + [[0,1,0],[1,1,0],[0,1,0]], + ], + S: [ + [[0,1,1],[1,1,0],[0,0,0]], + [[0,1,0],[0,1,1],[0,0,1]], + [[0,0,0],[0,1,1],[1,1,0]], + [[1,0,0],[1,1,0],[0,1,0]], + ], + Z: [ + [[1,1,0],[0,1,1],[0,0,0]], + [[0,0,1],[0,1,1],[0,1,0]], + [[0,0,0],[1,1,0],[0,1,1]], + [[0,1,0],[1,1,0],[1,0,0]], + ], + J: [ + [[1,0,0],[1,1,1],[0,0,0]], + [[0,1,1],[0,1,0],[0,1,0]], + [[0,0,0],[1,1,1],[0,0,1]], + [[0,1,0],[0,1,0],[1,1,0]], + ], + L: [ + [[0,0,1],[1,1,1],[0,0,0]], + [[0,1,0],[0,1,0],[0,1,1]], + [[0,0,0],[1,1,1],[1,0,0]], + [[1,1,0],[0,1,0],[0,1,0]], + ], +}; + +// ── SRS Wall-kick tables ─────────────────────────────────── +// Offsets are [dx, dy] in canvas coords (positive-Y = DOWN) +// Derived from the Tetris Guideline with Y axis flipped. + +const KICKS_JLSTZ: Record<string, readonly [number, number][]> = { + '0>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]], + '1>0': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]], + '1>2': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]], + '2>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]], + '2>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]], + '3>2': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]], + '3>0': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]], + '0>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]], +}; + +const KICKS_I: Record<string, readonly [number, number][]> = { + '0>1': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]], + '1>0': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]], + '1>2': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]], + '2>1': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]], + '2>3': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]], + '3>2': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]], + '3>0': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]], + '0>3': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]], +}; + +// ── Scoring ──────────────────────────────────────────────── +const LINE_SCORE = [0, 100, 300, 500, 800]; // 0–4 lines + +/** Drop interval in ms for a given level (Tetris guideline formula). */ +function dropInterval(level: number): number { + const sec = Math.pow(0.8 - (level - 1) * 0.007, level - 1); + return Math.max(50, Math.floor(sec * 1000)); +} + +// ── Helpers ──────────────────────────────────────────────── +const ALL_TYPES: PieceType[] = ['I','O','T','S','Z','J','L']; + +function getShape(type: PieceType, rotation: number): readonly (readonly number[])[] { + return SHAPES[type][((rotation % 4) + 4) % 4]; +} + +/** Returns [boardX, boardY] for every filled cell of the piece. */ +function cells(p: Piece): [number, number][] { + const out: [number, number][] = []; + const shape = getShape(p.type, p.rotation); + for (let r = 0; r < shape.length; r++) { + for (let c = 0; c < shape[r].length; c++) { + if (shape[r][c]) out.push([p.x + c, p.y + r]); + } + } + return out; +} + +// ── 7-bag randomiser ─────────────────────────────────────── +class Bag { + private pool: PieceType[] = []; + + private refill() { + this.pool = [...ALL_TYPES]; + for (let i = this.pool.length - 1; i > 0; i--) { + const j = (Math.random() * (i + 1)) | 0; + [this.pool[i], this.pool[j]] = [this.pool[j], this.pool[i]]; + } + } + + next(): PieceType { + if (!this.pool.length) this.refill(); + return this.pool.pop()!; + } + + peek(): PieceType { + if (!this.pool.length) this.refill(); + return this.pool[this.pool.length - 1]; + } +} + +// ══════════════════════════════════════════════════════════ +// Main Game Class +// ══════════════════════════════════════════════════════════ +class TetrisGame { + + // Canvases + private readonly ctx: CanvasRenderingContext2D; + private readonly nextCtx: CanvasRenderingContext2D; + private readonly holdCtx: CanvasRenderingContext2D; + + // Board + private board: Board = this.emptyBoard(); + + // Pieces + private current: Piece | null = null; + private nextType: PieceType = 'I'; + private heldType: PieceType | null = null; + private canHold = true; + private bag = new Bag(); + + // Stats + private score = 0; + private level = 1; + private lines = 0; + + // Game loop + private state: GameState = 'idle'; + private animId: number = 0; + private lastTime = 0; + private dropCtr = 0; // accumulated ms toward next gravity drop + private softDrop = false; + + // DAS (Delayed Auto-Shift) + private dasDir = 0; // -1 | 0 | 1 + private dasTimer = 0; + private dasRepeat = 0; + private readonly DAS_DELAY = 133; + private readonly DAS_PERIOD = 50; + + // Key state + private held = new Set<string>(); + + // ── Constructor ────────────────────────────────────────── + constructor() { + this.ctx = this.getCtx('game-canvas'); + this.nextCtx = this.getCtx('next-canvas'); + this.holdCtx = this.getCtx('hold-canvas'); + + this.nextType = this.bag.next(); + + document.addEventListener('keydown', e => this.onKeyDown(e)); + document.addEventListener('keyup', e => this.onKeyUp(e)); + document.getElementById('start-btn')! + .addEventListener('click', () => this.onStartBtn()); + + this.showOverlay('TETRIS', 'Press Space to start'); + this.drawIdleBoard(); + this.drawPreview(this.nextCtx, null); + this.drawPreview(this.holdCtx, null); + } + + private getCtx(id: string): CanvasRenderingContext2D { + return (document.getElementById(id) as HTMLCanvasElement) + .getContext('2d')!; + } + + // ── Overlay helpers ────────────────────────────────────── + private showOverlay(title: string, msg: string) { + document.getElementById('overlay')!.style.display = 'flex'; + document.getElementById('ov-title')!.textContent = title; + // handle literal \n line breaks in msg + const msgEl = document.getElementById('ov-msg')!; + msgEl.innerHTML = msg.split('\n').map(l => `<span>${l}</span>`).join('<br>'); + } + + private hideOverlay() { + document.getElementById('overlay')!.style.display = 'none'; + } + + private setBtn(txt: string) { + (document.getElementById('start-btn') as HTMLButtonElement).textContent = txt; + } + + private updateStats() { + document.getElementById('score')!.textContent = this.score.toLocaleString(); + document.getElementById('level')!.textContent = String(this.level); + document.getElementById('lines')!.textContent = String(this.lines); + } + + // ── Button / start flow ────────────────────────────────── + private onStartBtn() { + if (this.state === 'idle' || this.state === 'gameover') this.startGame(); + else if (this.state === 'playing') this.pauseGame(); + else if (this.state === 'paused') this.resumeGame(); + } + + startGame() { + this.board = this.emptyBoard(); + this.score = 0; + this.level = 1; + this.lines = 0; + this.heldType = null; + this.canHold = true; + this.bag = new Bag(); + this.nextType = this.bag.next(); + this.dropCtr = 0; + this.softDrop = false; + this.dasDir = 0; + + this.updateStats(); + this.drawPreview(this.holdCtx, null); + this.spawnPiece(); + + if (this.state === 'playing') cancelAnimationFrame(this.animId); + this.state = 'playing'; + this.hideOverlay(); + this.setBtn('PAUSE'); + + this.lastTime = performance.now(); + this.animId = requestAnimationFrame(t => this.loop(t)); + } + + pauseGame() { + this.state = 'paused'; + cancelAnimationFrame(this.animId); + this.showOverlay('PAUSED', 'Press P or Space to resume'); + this.setBtn('RESUME'); + } + + resumeGame() { + this.state = 'playing'; + this.hideOverlay(); + this.setBtn('PAUSE'); + this.lastTime = performance.now(); + this.animId = requestAnimationFrame(t => this.loop(t)); + } + + private endGame() { + this.state = 'gameover'; + cancelAnimationFrame(this.animId); + this.showOverlay( + 'GAME OVER', + `Score: ${this.score.toLocaleString()}\nLines: ${this.lines} Level: ${this.level}\nPress Space to play again` + ); + this.setBtn('RESTART'); + } + + // ── Board helpers ──────────────────────────────────────── + private emptyBoard(): Board { + return Array.from({ length: BOARD_H }, () => new Array<Cell>(BOARD_W).fill(null)); + } + + private isValid(p: Piece): boolean { + for (const [x, y] of cells(p)) { + if (x < 0 || x >= BOARD_W || y >= BOARD_H) return false; + if (y >= 0 && this.board[y][x] !== null) return false; + } + return true; + } + + private lock() { + if (!this.current) return; + const color = COLORS[this.current.type]; + for (const [x, y] of cells(this.current)) { + if (y >= 0) this.board[y][x] = color; + } + this.clearLines(); + this.canHold = true; + this.spawnPiece(); + } + + private clearLines() { + let cleared = 0; + for (let r = BOARD_H - 1; r >= 0; r--) { + if (this.board[r].every(c => c !== null)) { + this.board.splice(r, 1); + this.board.unshift(new Array<Cell>(BOARD_W).fill(null)); + cleared++; + r++; // recheck the row that slid into position r + } + } + if (cleared) { + this.lines += cleared; + this.score += LINE_SCORE[cleared] * this.level; + const newLevel = Math.floor(this.lines / 10) + 1; + if (newLevel > this.level) { + this.level = newLevel; + } + this.updateStats(); + } + } + + // ── Spawn ──────────────────────────────────────────────── + private spawnPiece() { + const type = this.nextType; + this.nextType = this.bag.next(); + + const shape = getShape(type, 0); + const w = shape[0].length; + const spawnX = Math.floor((BOARD_W - w) / 2); + // I piece rotation-0 has an empty top row → spawn 1 row higher + const spawnY = type === 'I' ? -1 : 0; + + this.current = { type, x: spawnX, y: spawnY, rotation: 0 }; + + if (!this.isValid(this.current)) { + this.current.y--; + if (!this.isValid(this.current)) { + this.current = null; + this.endGame(); + return; + } + } + + this.dropCtr = 0; + this.drawPreview(this.nextCtx, this.nextType); + } + + // ── Movement ───────────────────────────────────────────── + private tryShift(dx: number, dy: number): boolean { + if (!this.current) return false; + const moved: Piece = { ...this.current, x: this.current.x + dx, y: this.current.y + dy }; + if (this.isValid(moved)) { this.current = moved; return true; } + return false; + } + + /** Gravity tick – returns false if piece locked. */ + private gravityDrop(): boolean { + if (!this.current) return false; + if (!this.tryShift(0, 1)) { + this.lock(); + return false; + } + return true; + } + + private hardDrop() { + if (!this.current) return; + let rows = 0; + while (this.tryShift(0, 1)) rows++; + this.score += rows * 2; + this.updateStats(); + this.lock(); + } + + private rotate(dir: 1 | -1) { + if (!this.current) return; + const from = this.current.rotation; + const to = ((from + dir + 4) % 4) as 0|1|2|3; + const key = `${from}>${to}`; + + const kicks: readonly [number,number][] = + this.current.type === 'I' ? KICKS_I[key] : + this.current.type === 'O' ? [[0,0]] : + KICKS_JLSTZ[key]; + + for (const [dx, dy] of kicks) { + const attempt: Piece = { ...this.current, rotation: to, + x: this.current.x + dx, + y: this.current.y + dy }; + if (this.isValid(attempt)) { this.current = attempt; return; } + } + } + + private holdPiece() { + if (!this.current || !this.canHold) return; + const type = this.current.type; + if (this.heldType === null) { + this.heldType = type; + this.spawnPiece(); + } else { + const swap = this.heldType; + this.heldType = type; + const shape = getShape(swap, 0); + const w = shape[0].length; + this.current = { type: swap, + x: Math.floor((BOARD_W - w) / 2), + y: swap === 'I' ? -1 : 0, + rotation: 0 }; + this.dropCtr = 0; + } + this.canHold = false; + this.drawPreview(this.holdCtx, this.heldType); + } + + // Ghost: lowest valid position of current piece + private ghost(): Piece | null { + if (!this.current) return null; + let g = { ...this.current }; + while (true) { + const down = { ...g, y: g.y + 1 }; + if (this.isValid(down)) g = down; else break; + } + return g; + } + + // ── Input ──────────────────────────────────────────────── + private readonly GAME_KEYS = new Set([ + 'ArrowLeft','ArrowRight','ArrowDown','ArrowUp', + 'Space','KeyZ','KeyX','KeyC','KeyP','Escape', + ]); + + private onKeyDown(e: KeyboardEvent) { + if (this.GAME_KEYS.has(e.code)) e.preventDefault(); + if (this.held.has(e.code)) return; // ignore key-repeat from OS + this.held.add(e.code); + + if (e.code === 'KeyP' || e.code === 'Escape') { + if (this.state === 'playing') this.pauseGame(); + else if (this.state === 'paused') this.resumeGame(); + return; + } + + if (e.code === 'Space') { + if (this.state === 'idle' || this.state === 'gameover') this.startGame(); + else if (this.state === 'paused') this.resumeGame(); + else if (this.state === 'playing') this.hardDrop(); + return; + } + + if (this.state !== 'playing') return; + + switch (e.code) { + case 'ArrowLeft': + this.tryShift(-1, 0); + this.startDAS(-1); + break; + case 'ArrowRight': + this.tryShift(1, 0); + this.startDAS(1); + break; + case 'ArrowDown': + this.softDrop = true; + break; + case 'ArrowUp': + case 'KeyX': + this.rotate(1); + break; + case 'KeyZ': + this.rotate(-1); + break; + case 'KeyC': + this.holdPiece(); + break; + } + } + + private onKeyUp(e: KeyboardEvent) { + this.held.delete(e.code); + if (e.code === 'ArrowLeft' && this.dasDir === -1) this.stopDAS(); + if (e.code === 'ArrowRight' && this.dasDir === 1) this.stopDAS(); + if (e.code === 'ArrowDown') this.softDrop = false; + } + + private startDAS(dir: -1 | 1) { + this.dasDir = dir; + this.dasTimer = 0; + this.dasRepeat = 0; + } + + private stopDAS() { + // Re-engage for the other direction if still held + if (this.held.has('ArrowLeft') && this.dasDir !== -1) this.startDAS(-1); + else if (this.held.has('ArrowRight') && this.dasDir !== 1) this.startDAS(1); + else { this.dasDir = 0; this.dasTimer = 0; this.dasRepeat = 0; } + } + + // ── Game loop ──────────────────────────────────────────── + private loop(ts: number) { + const dt = Math.min(ts - this.lastTime, 100); // cap to avoid spiral after tab-switch + this.lastTime = ts; + + // DAS + if (this.dasDir !== 0) { + this.dasTimer += dt; + if (this.dasTimer >= this.DAS_DELAY) { + this.dasRepeat += dt; + while (this.dasRepeat >= this.DAS_PERIOD) { + this.dasRepeat -= this.DAS_PERIOD; + this.tryShift(this.dasDir, 0); + } + } + } + + // Gravity + const interval = this.softDrop + ? Math.max(dropInterval(this.level) / 20, 33) + : dropInterval(this.level); + + this.dropCtr += dt; + while (this.dropCtr >= interval && this.state === 'playing') { + this.dropCtr -= interval; + if (this.softDrop && this.current) { + this.score += 1; + document.getElementById('score')!.textContent = this.score.toLocaleString(); + } + if (!this.gravityDrop()) break; // piece locked → new piece spawned + } + + this.draw(); + if (this.state === 'playing') this.animId = requestAnimationFrame(t => this.loop(t)); + } + + // ── Rendering ──────────────────────────────────────────── + + /** Draw one cell at grid coords (gx, gy) using given pixel size. */ + private drawCell( + ctx: CanvasRenderingContext2D, + gx: number, gy: number, + type: PieceType, + size: number, + alpha = 1, + ) { + const px = gx * size; + const py = gy * size; + const s = size; + const b = Math.max(2, (s / 10) | 0); // border/bevel thickness + + ctx.globalAlpha = alpha; + + // Fill + ctx.fillStyle = COLORS[type]; + ctx.fillRect(px, py, s, s); + + // Inner bevel – bright top/left + ctx.fillStyle = 'rgba(255,255,255,0.45)'; + ctx.fillRect(px, py, s, b); // top strip + ctx.fillRect(px, py, b, s); // left strip + + // Inner bevel – dark bottom/right + ctx.fillStyle = DARK[type]; + ctx.fillRect(px, py + s - b, s, b); // bottom + ctx.fillRect(px + s - b, py, b, s); // right + + // Inset highlight square + ctx.fillStyle = COLORS[type]; + ctx.fillRect(px + b, py + b, s - b * 2, s - b * 2); + + // Subtle inner shine + ctx.fillStyle = 'rgba(255,255,255,0.18)'; + ctx.fillRect(px + b, py + b, s - b * 2, Math.max(1, (s - b * 2) / 2 | 0)); + + ctx.globalAlpha = 1; + } + + /** Main board render. */ + private draw() { + const ctx = this.ctx; + const W = BOARD_W * CELL; + const H = BOARD_H * CELL; + + // ── Background ── + ctx.fillStyle = '#111122'; + ctx.fillRect(0, 0, W, H); + + // ── Grid lines ── + ctx.strokeStyle = 'rgba(255,255,255,0.04)'; + ctx.lineWidth = 1; + for (let c = 0; c <= BOARD_W; c++) { + ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, H); ctx.stroke(); + } + for (let r = 0; r <= BOARD_H; r++) { + ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(W, r * CELL); ctx.stroke(); + } + + // ── Locked cells ── + for (let r = 0; r < BOARD_H; r++) { + for (let c = 0; c < BOARD_W; c++) { + const color = this.board[r][c]; + if (color) { + // find which type this color belongs to + const type = (Object.keys(COLORS) as PieceType[]) + .find(k => COLORS[k] === color) ?? 'I'; + this.drawCell(ctx, c, r, type, CELL); + } + } + } + + // ── Ghost piece ── + const gh = this.ghost(); + if (gh && this.current && gh.y !== this.current.y) { + for (const [x, y] of cells(gh)) { + if (y >= 0) this.drawCell(ctx, x, y, gh.type, CELL, 0.18); + } + } + + // ── Current piece ── + if (this.current) { + for (const [x, y] of cells(this.current)) { + if (y >= 0) this.drawCell(ctx, x, y, this.current.type, CELL); + } + } + } + + /** Draw a piece centred inside the given small canvas context. */ + private drawPreview(ctx: CanvasRenderingContext2D, type: PieceType | null) { + ctx.fillStyle = '#111122'; + ctx.fillRect(0, 0, PREVIEW_W, PREVIEW_H); + + if (!type) return; + + const shape = getShape(type, 0); + const rows = shape.length; + const cols = shape[0].length; + + // Compute the tightest bounding box of filled cells + let minR = rows, maxR = 0, minC = cols, maxC = 0; + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + if (shape[r][c]) { + if (r < minR) minR = r; if (r > maxR) maxR = r; + if (c < minC) minC = c; if (c > maxC) maxC = c; + } + } + } + const bRows = maxR - minR + 1; + const bCols = maxC - minC + 1; + + const cellSz = Math.min( + Math.floor((PREVIEW_W - 16) / bCols), + Math.floor((PREVIEW_H - 16) / bRows), + 28, + ); + + const offX = Math.floor((PREVIEW_W - bCols * cellSz) / 2) - minC * cellSz; + const offY = Math.floor((PREVIEW_H - bRows * cellSz) / 2) - minR * cellSz; + + ctx.save(); + ctx.translate(offX, offY); + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + if (shape[r][c]) this.drawCell(ctx, c, r, type, cellSz); + } + } + ctx.restore(); + } + + /** Idle screen: a partially-filled board with random blocks. */ + private drawIdleBoard() { + const ctx = this.ctx; + ctx.fillStyle = '#111122'; + ctx.fillRect(0, 0, BOARD_W * CELL, BOARD_H * CELL); + + ctx.strokeStyle = 'rgba(255,255,255,0.04)'; + ctx.lineWidth = 1; + for (let c = 0; c <= BOARD_W; c++) { + ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, BOARD_H * CELL); ctx.stroke(); + } + for (let r = 0; r <= BOARD_H; r++) { + ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(BOARD_W * CELL, r * CELL); ctx.stroke(); + } + + for (let r = 14; r < BOARD_H; r++) { + for (let c = 0; c < BOARD_W; c++) { + if (Math.random() > 0.35) { + const t = ALL_TYPES[(Math.random() * ALL_TYPES.length) | 0]; + this.drawCell(ctx, c, r, t, CELL); + } + } + } + } +} + +// ── Bootstrap ───────────────────────────────────────────── +window.addEventListener('DOMContentLoaded', () => { new TetrisGame(); }); diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/style.css b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/style.css @@ -0,0 +1,151 @@ +/* ── Reset / Base ─────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +body { + background: #0a0a18; + color: #e0e0ff; + font-family: 'Segoe UI', system-ui, sans-serif; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + overflow: hidden; + user-select: none; +} + +/* ── Layout ───────────────────────────────────────────── */ +#wrapper { + display: flex; + gap: 12px; + align-items: flex-start; +} + +/* ── Side panels ──────────────────────────────────────── */ +.side-panel { + display: flex; + flex-direction: column; + gap: 12px; + width: 120px; + padding-top: 4px; +} + +.panel-box { + background: #16162e; + border: 1px solid #2a2a50; + border-radius: 6px; + padding: 10px 8px; + display: flex; + flex-direction: column; + align-items: center; + gap: 6px; +} + +.panel-label { + font-size: 10px; + font-weight: 700; + letter-spacing: 2px; + color: #7070b0; + text-transform: uppercase; +} + +.panel-value { + font-size: 22px; + font-weight: 700; + color: #d0d0ff; + letter-spacing: 1px; + font-variant-numeric: tabular-nums; +} + +canvas { + display: block; +} + +/* ── Game canvas wrapper ──────────────────────────────── */ +#game-wrap { + position: relative; + border: 2px solid #2a2a50; + border-radius: 4px; + overflow: hidden; + box-shadow: + 0 0 30px rgba(80, 80, 200, 0.25), + 0 0 8px rgba(80, 80, 200, 0.15); +} + +/* ── Overlay ──────────────────────────────────────────── */ +#overlay { + position: absolute; + inset: 0; + background: rgba(5, 5, 20, 0.88); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 14px; + backdrop-filter: blur(2px); + z-index: 10; +} + +#ov-title { + font-size: 42px; + font-weight: 900; + letter-spacing: 6px; + text-transform: uppercase; + background: linear-gradient(135deg, #00f0f0, #a020f0, #f0a000); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-shadow: none; + line-height: 1; +} + +#ov-msg { + font-size: 13px; + color: #9090c0; + text-align: center; + line-height: 1.8; +} + +/* ── Controls hint ────────────────────────────────────── */ +#controls, .controls { + margin-top: 4px; + font-size: 11px; + color: #5a5a8a; + display: grid; + grid-template-columns: auto auto; + column-gap: 14px; + row-gap: 4px; + text-align: left; +} + +#controls span:nth-child(odd), +.controls span:nth-child(odd) { color: #8080b8; font-weight: 600; } +#controls span:nth-child(even), +.controls span:nth-child(even) { color: #5a5a8a; } + +/* ── Button ───────────────────────────────────────────── */ +#start-btn { + margin-top: 6px; + padding: 9px 32px; + background: linear-gradient(135deg, #1a1a60, #2a2a90); + border: 1px solid #4040a0; + border-radius: 4px; + color: #c0c0ff; + font-size: 13px; + font-weight: 700; + letter-spacing: 2px; + cursor: pointer; + transition: background 0.15s, transform 0.1s; +} + +#start-btn:hover { background: linear-gradient(135deg, #2a2a80, #3a3ab0); } +#start-btn:active { transform: scale(0.97); } + +/* ── Preview canvases ─────────────────────────────────── */ +#next-canvas, #hold-canvas { + border-radius: 4px; +} + +/* ── Responsive: shrink on small screens ─────────────── */ +@media (max-width: 560px) { + #wrapper { gap: 6px; transform: scale(0.82); transform-origin: top center; } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/tsconfig.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "bundler", + "strict": true, + "outDir": "./dist", + "rootDir": "./src", + "lib": ["ES2020", "DOM"], + "noEmitOnError": true, + "sourceMap": true + }, + "include": ["src/**/*"] +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/index.html b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/index.html @@ -0,0 +1,245 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Tetris</title> + <style> + /* ── Reset & base ─────────────────────────────────────────────── */ + *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + + body { + background: #060610; + color: #e0e0f0; + font-family: "Segoe UI", system-ui, sans-serif; + display: flex; + flex-direction: column; + align-items: center; + min-height: 100vh; + padding: 24px 16px; + user-select: none; + } + + h1 { + font-size: 2.4rem; + font-weight: 900; + letter-spacing: 0.18em; + text-transform: uppercase; + background: linear-gradient(135deg, #00d4ff 0%, #bf5fff 50%, #ff9900 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 20px; + } + + /* ── Layout ───────────────────────────────────────────────────── */ + .game-area { + display: flex; + gap: 16px; + align-items: flex-start; + } + + /* ── Side panels ──────────────────────────────────────────────── */ + .side-panel { + display: flex; + flex-direction: column; + gap: 14px; + min-width: 96px; + } + + .panel-box { + background: #12122a; + border: 1px solid #2a2a50; + border-radius: 10px; + padding: 10px 12px; + } + + .panel-label { + font-size: 0.65rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: #7070a0; + margin-bottom: 6px; + } + + .panel-value { + font-size: 1.45rem; + font-weight: 800; + color: #ffffff; + letter-spacing: 0.04em; + } + + canvas.preview { + display: block; + background: #0e0e1a; + border-radius: 6px; + image-rendering: pixelated; + } + + /* ── Board wrapper ────────────────────────────────────────────── */ + .board-wrap { + position: relative; + border: 2px solid #2a2a50; + border-radius: 8px; + overflow: hidden; + box-shadow: + 0 0 0 1px #1a1a3a, + 0 0 40px rgba(0, 212, 255, 0.08), + 0 0 80px rgba(191, 95, 255, 0.05); + } + + #board { + display: block; + image-rendering: pixelated; + } + + /* ── Overlay ──────────────────────────────────────────────────── */ + #overlay { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: rgba(6, 6, 20, 0.82); + backdrop-filter: blur(4px); + gap: 12px; + text-align: center; + padding: 24px; + transition: opacity 0.15s; + } + + #overlay.hidden { + display: none; + } + + #overlay-title { + font-size: 2.8rem; + font-weight: 900; + letter-spacing: 0.14em; + background: linear-gradient(90deg, #00d4ff, #bf5fff); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } + + #overlay-msg { + font-size: 0.9rem; + color: #a0a0c0; + white-space: pre-line; + line-height: 1.6; + } + + .start-btn { + margin-top: 8px; + padding: 10px 28px; + font-size: 0.95rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + background: linear-gradient(135deg, #00d4ff, #bf5fff); + color: #fff; + border: none; + border-radius: 6px; + cursor: pointer; + transition: transform 0.1s, box-shadow 0.1s; + } + + .start-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 20px rgba(0, 212, 255, 0.4); + } + + .start-btn:active { transform: translateY(0); } + + /* ── Controls legend ──────────────────────────────────────────── */ + .controls { + margin-top: 18px; + display: grid; + grid-template-columns: auto auto; + column-gap: 20px; + row-gap: 4px; + font-size: 0.72rem; + color: #6060a0; + text-align: left; + } + + .controls .key { + font-family: monospace; + background: #1e1e3a; + border: 1px solid #2e2e50; + border-radius: 4px; + padding: 1px 6px; + color: #a0a0d0; + justify-self: end; + } + </style> +</head> +<body> + <h1>Tetris</h1> + + <div class="game-area"> + + <!-- Left panel: Hold + Stats --> + <div class="side-panel" style="align-items: flex-end;"> + <div class="panel-box"> + <div class="panel-label">Hold</div> + <canvas id="hold" class="preview" width="88" height="66"></canvas> + </div> + <div class="panel-box"> + <div class="panel-label">Score</div> + <div class="panel-value" id="score">0</div> + </div> + <div class="panel-box"> + <div class="panel-label">Lines</div> + <div class="panel-value" id="lines">0</div> + </div> + <div class="panel-box"> + <div class="panel-label">Level</div> + <div class="panel-value" id="level">1</div> + </div> + </div> + + <!-- Board --> + <div class="board-wrap"> + <canvas id="board"></canvas> + <div id="overlay"> + <div id="overlay-title">TETRIS</div> + <div id="overlay-msg">Press Space or Enter to start</div> + <button class="start-btn" id="start-btn">Start Game</button> + </div> + </div> + + <!-- Right panel: Next --> + <div class="side-panel"> + <div class="panel-box"> + <div class="panel-label">Next</div> + <canvas id="next" class="preview" width="88" height="198"></canvas> + </div> + + <div class="panel-box"> + <div class="panel-label" style="margin-bottom:10px;">Controls</div> + <div class="controls"> + <span class="key">← →</span><span>Move</span> + <span class="key">↓</span><span>Soft drop</span> + <span class="key">Space</span><span>Hard drop</span> + <span class="key">↑ / X</span><span>Rotate CW</span> + <span class="key">Z</span><span>Rotate CCW</span> + <span class="key">C / ⇧</span><span>Hold</span> + <span class="key">P / Esc</span><span>Pause</span> + </div> + </div> + </div> + + </div> + + <script type="module" src="dist/tetris.js"></script> + <script> + // Wire up the overlay start button + document.getElementById("start-btn").addEventListener("click", () => { + window.dispatchEvent(new KeyboardEvent("keydown", { code: "Space", bubbles: true })); + }); + </script> +</body> +</html> diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package-lock.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package-lock.json @@ -0,0 +1,2583 @@ +{ + "name": "loop-bench-elvty8os", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-elvty8os", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@playwright/test": "^1.59.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.4.tgz", + "integrity": "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.4", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.4.tgz", + "integrity": "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.0.tgz", + "integrity": "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.4.tgz", + "integrity": "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.0.tgz", + "integrity": "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@html-validate/stylish": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-5.1.0.tgz", + "integrity": "sha512-Tyx/ZbHBpVZjvSleNplNMUhqT4UY1HwAMC97GSmasJXggWuvjNFLBS2scqnEb+ZG1szLq4zgjOioj7cVWV9WuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": "^20.11 || >= 22.16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jscpd/badge-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/badge-reporter/-/badge-reporter-4.0.4.tgz", + "integrity": "sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "badgen": "^3.2.3", + "colors": "^1.4.0", + "fs-extra": "^11.2.0" + } + }, + "node_modules/@jscpd/core": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/core/-/core-4.0.4.tgz", + "integrity": "sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@jscpd/finder": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/finder/-/finder-4.0.4.tgz", + "integrity": "sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "blamer": "^1.0.6", + "bytes": "^3.1.2", + "cli-table3": "^0.6.5", + "colors": "^1.4.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "markdown-table": "^2.0.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/html-reporter": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/html-reporter/-/html-reporter-4.0.4.tgz", + "integrity": "sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "1.4.0", + "fs-extra": "^11.2.0", + "pug": "^3.0.3" + } + }, + "node_modules/@jscpd/tokenizer": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@jscpd/tokenizer/-/tokenizer-4.0.4.tgz", + "integrity": "sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/core": "4.0.4", + "reprism": "^0.0.11", + "spark-md5": "^3.0.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@playwright/test": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz", + "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/badgen": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/badgen/-/badgen-3.2.3.tgz", + "integrity": "sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blamer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/blamer/-/blamer-1.0.7.tgz", + "integrity": "sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^4.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", + "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.4", + "@eslint/config-helpers": "^0.5.4", + "@eslint/core": "^1.2.0", + "@eslint/plugin-kit": "^0.7.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gitignore-to-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", + "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.4 <5 || >=6.9" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-validate": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-10.11.3.tgz", + "integrity": "sha512-wKUq9iR6bukMgiHhs/ORThZzEbQoFiiPNN7aZfQ8dlmhttPb2sM2Ji2p+Fy5Xj1aH7QHJ1biT2SUDw7A01P2oA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/html-validate" + } + ], + "license": "MIT", + "dependencies": { + "@html-validate/stylish": "^5.0.0", + "@sidvind/better-ajv-errors": "4.0.1", + "ajv": "^8.0.0", + "glob": "^13.0.0", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.mjs" + }, + "engines": { + "node": "^20.19.0 || >= 22.16.0" + }, + "peerDependencies": { + "jest": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-diff": "^28.1.3 || ^29.0.3 || ^30.0.0", + "jest-snapshot": "^28.1.3 || ^29.0.3 || ^30.0.0", + "vitest": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.1" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/@sidvind/better-ajv-errors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-4.0.1.tgz", + "integrity": "sha512-6arF1ssKxItxgitPYXafUoLmsVBA6K7m9+ZGj6hLDoBl7nWpJ33EInwQUdHTle2METeWGxgQiqSex20KZRykew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "ajv": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jscpd": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-4.0.8.tgz", + "integrity": "sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jscpd/badge-reporter": "4.0.4", + "@jscpd/core": "4.0.4", + "@jscpd/finder": "4.0.4", + "@jscpd/html-reporter": "4.0.4", + "@jscpd/tokenizer": "4.0.4", + "colors": "^1.4.0", + "commander": "^5.0.0", + "fs-extra": "^11.2.0", + "gitignore-to-glob": "^0.3.0", + "jscpd-sarif-reporter": "4.0.6" + }, + "bin": { + "jscpd": "bin/jscpd" + } + }, + "node_modules/jscpd-sarif-reporter": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/jscpd-sarif-reporter/-/jscpd-sarif-reporter-4.0.6.tgz", + "integrity": "sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "colors": "^1.4.0", + "fs-extra": "^11.2.0", + "node-sarif-builder": "^3.4.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-sarif-builder": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.4.0.tgz", + "integrity": "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/reprism": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/reprism/-/reprism-0.0.11.tgz", + "integrity": "sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/package.json @@ -0,0 +1,24 @@ +{ + "name": "loop-bench-elvty8os", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@playwright/test": "^1.59.1", + "@types/node": "^25.5.2", + "eslint": "^10.2.0", + "html-validate": "^10.11.3", + "jscpd": "^4.0.8", + "typescript": "^6.0.2" + } +} diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/report/jscpd-report.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/report/jscpd-report.json @@ -0,0 +1,289 @@ +{ + "statistics": { + "detectionDate": "2026-04-05T19:29:13.537Z", + "formats": { + "typescript": { + "sources": { + "src/tetris.ts": { + "lines": 735, + "tokens": 8299, + "sources": 1, + "clones": 2, + "duplicatedLines": 10, + "duplicatedTokens": 188, + "percentage": 1.36, + "percentageTokens": 2.27, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 735, + "tokens": 8299, + "sources": 1, + "clones": 1, + "duplicatedLines": 5, + "duplicatedTokens": 94, + "percentage": 0.68, + "percentageTokens": 1.13, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "javascript": { + "sources": { + "dist/tetris.js": { + "lines": 645, + "tokens": 7675, + "sources": 1, + "clones": 6, + "duplicatedLines": 30, + "duplicatedTokens": 552, + "percentage": 4.65, + "percentageTokens": 7.19, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 645, + "tokens": 7675, + "sources": 1, + "clones": 3, + "duplicatedLines": 15, + "duplicatedTokens": 276, + "percentage": 2.33, + "percentageTokens": 3.6, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "json": { + "sources": { + "tsconfig.json": { + "lines": 14, + "tokens": 94, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + }, + "package.json": { + "lines": 23, + "tokens": 146, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 37, + "tokens": 240, + "sources": 2, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "markup": { + "sources": { + "index.html": { + "lines": 244, + "tokens": 1755, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "total": { + "lines": 244, + "tokens": 1755, + "sources": 1, + "clones": 0, + "duplicatedLines": 0, + "duplicatedTokens": 0, + "percentage": 0, + "percentageTokens": 0, + "newDuplicatedLines": 0, + "newClones": 0 + } + } + }, + "total": { + "lines": 1661, + "tokens": 17969, + "sources": 5, + "clones": 4, + "duplicatedLines": 20, + "duplicatedTokens": 370, + "percentage": 1.2, + "percentageTokens": 2.06, + "newDuplicatedLines": 0, + "newClones": 0 + } + }, + "duplicates": [ + { + "format": "typescript", + "lines": 6, + "fragment": ";\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY", + "tokens": 0, + "firstFile": { + "name": "src/tetris.ts", + "start": 609, + "end": 614, + "startLoc": { + "line": 609, + "column": 2, + "position": 7026 + }, + "endLoc": { + "line": 614, + "column": 5, + "position": 7120 + } + }, + "secondFile": { + "name": "src/tetris.ts", + "start": 586, + "end": 591, + "startLoc": { + "line": 586, + "column": 6, + "position": 6693 + }, + "endLoc": { + "line": 591, + "column": 6, + "position": 6787 + } + } + }, + { + "format": "javascript", + "lines": 6, + "fragment": "(piece) {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c])\n continue;\n const y", + "tokens": 0, + "firstFile": { + "name": "dist/tetris.js", + "start": 84, + "end": 89, + "startLoc": { + "line": 84, + "column": 5, + "position": 1285 + }, + "endLoc": { + "line": 89, + "column": 2, + "position": 1377 + } + }, + "secondFile": { + "name": "dist/tetris.js", + "start": 69, + "end": 74, + "startLoc": { + "line": 69, + "column": 8, + "position": 1085 + }, + "endLoc": { + "line": 74, + "column": 2, + "position": 1177 + } + } + }, + { + "format": "javascript", + "lines": 6, + "fragment": ") {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c])\n continue;\n const px", + "tokens": 0, + "firstFile": { + "name": "dist/tetris.js", + "start": 431, + "end": 436, + "startLoc": { + "line": 431, + "column": 8, + "position": 5302 + }, + "endLoc": { + "line": 436, + "column": 3, + "position": 5392 + } + }, + "secondFile": { + "name": "dist/tetris.js", + "start": 69, + "end": 74, + "startLoc": { + "line": 69, + "column": 6, + "position": 1087 + }, + "endLoc": { + "line": 74, + "column": 2, + "position": 1177 + } + } + }, + { + "format": "javascript", + "lines": 6, + "fragment": ";\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c])\n continue;\n this.drawBlock(ctx, offX + c, offY", + "tokens": 0, + "firstFile": { + "name": "dist/tetris.js", + "start": 506, + "end": 511, + "startLoc": { + "line": 506, + "column": 2, + "position": 6477 + }, + "endLoc": { + "line": 511, + "column": 5, + "position": 6571 + } + }, + "secondFile": { + "name": "dist/tetris.js", + "start": 485, + "end": 490, + "startLoc": { + "line": 485, + "column": 6, + "position": 6151 + }, + "endLoc": { + "line": 490, + "column": 6, + "position": 6245 + } + } + } + ] +} +\ No newline at end of file diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/src/tetris.ts b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/src/tetris.ts @@ -0,0 +1,736 @@ +// ─── Types ─────────────────────────────────────────────────────────────────── + +type Matrix = number[][]; +type Color = string; + +interface Piece { + matrix: Matrix; + color: Color; + x: number; + y: number; +} + +interface Particle { + x: number; + y: number; + vx: number; + vy: number; + alpha: number; + color: string; + size: number; +} + +// ─── Constants ──────────────────────────────────────────────────────────────── + +const COLS = 10; +const ROWS = 20; +const BLOCK = 32; // px per cell +const HIDDEN = 2; // hidden rows above visible area (spawn buffer) +const TOTAL_ROWS = ROWS + HIDDEN; + +const COLORS: Record<string, Color> = { + I: "#00d4ff", + O: "#ffd700", + T: "#bf5fff", + S: "#39d353", + Z: "#ff4d4d", + J: "#4d79ff", + L: "#ff9900", +}; + +const TETROMINOES: Record<string, Matrix> = { + I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]], + O: [[1,1],[1,1]], + T: [[0,1,0],[1,1,1],[0,0,0]], + S: [[0,1,1],[1,1,0],[0,0,0]], + Z: [[1,1,0],[0,1,1],[0,0,0]], + J: [[1,0,0],[1,1,1],[0,0,0]], + L: [[0,0,1],[1,1,1],[0,0,0]], +}; + +// Scoring per lines cleared (multiplied by level) +const LINE_SCORES = [0, 100, 300, 500, 800]; + +// Drop interval in ms at each level (capped at level 20) +function levelInterval(level: number): number { + return Math.max(50, 1000 - (level - 1) * 47); +} + +// ─── SRS Wall-Kick Data ─────────────────────────────────────────────────────── + +// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces +const KICKS_JLSTZ: [number,number][][] = [ + // 0→1 + [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]], + // 1→2 + [[0,0],[1,0],[1,-1],[0,2],[1,2]], + // 2→3 + [[0,0],[1,0],[1,1],[0,-2],[1,-2]], + // 3→0 + [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]], +]; + +// Kick table for I piece +const KICKS_I: [number,number][][] = [ + // 0→1 + [[0,0],[-2,0],[1,0],[-2,-1],[1,2]], + // 1→2 + [[0,0],[-1,0],[2,0],[-1,2],[2,-1]], + // 2→3 + [[0,0],[2,0],[-1,0],[2,1],[-1,-2]], + // 3→0 + [[0,0],[1,0],[-2,0],[1,-2],[-2,1]], +]; + +// ─── Utility ────────────────────────────────────────────────────────────────── + +function rotateCW(m: Matrix): Matrix { + const rows = m.length, cols = m[0].length; + return Array.from({ length: cols }, (_, c) => + Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c]) + ); +} + +function rotateCCW(m: Matrix): Matrix { + return rotateCW(rotateCW(rotateCW(m))); +} + +// ─── Board ──────────────────────────────────────────────────────────────────── + +class Board { + grid: Color[][]; + + constructor() { + this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill("")); + } + + isValid(piece: Piece): boolean { + for (let r = 0; r < piece.matrix.length; r++) { + for (let c = 0; c < piece.matrix[r].length; c++) { + if (!piece.matrix[r][c]) continue; + const x = piece.x + c; + const y = piece.y + r; + if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false; + if (y >= 0 && this.grid[y][x]) return false; + } + } + return true; + } + + lock(piece: Piece): void { + for (let r = 0; r < piece.matrix.length; r++) { + for (let c = 0; c < piece.matrix[r].length; c++) { + if (!piece.matrix[r][c]) continue; + const y = piece.y + r; + const x = piece.x + c; + if (y >= 0) this.grid[y][x] = piece.color; + } + } + } + + clearLines(): number { + const cleared: number[] = []; + for (let r = 0; r < TOTAL_ROWS; r++) { + if (this.grid[r].every(cell => cell !== "")) cleared.push(r); + } + for (const r of cleared) { + this.grid.splice(r, 1); + this.grid.unshift(Array(COLS).fill("")); + } + return cleared.length; + } + + getGhostY(piece: Piece): number { + let gy = piece.y; + while (this.isValid({ ...piece, y: gy + 1 })) gy++; + return gy; + } +} + +// ─── Random Bag ────────────────────────────────────────────────────────────── + +class Bag { + private queue: string[] = []; + + private refill(): void { + const keys = Object.keys(TETROMINOES); + for (let i = keys.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [keys[i], keys[j]] = [keys[j], keys[i]]; + } + this.queue.push(...keys); + } + + next(): string { + if (this.queue.length < 5) this.refill(); + return this.queue.shift()!; + } + + peek(n: number): string[] { + while (this.queue.length < n + 5) this.refill(); + return this.queue.slice(0, n); + } +} + +// ─── Tetris Game ───────────────────────────────────────────────────────────── + +class Tetris { + // Canvases + private canvas: HTMLCanvasElement; + private ctx: CanvasRenderingContext2D; + private nextCanvas: HTMLCanvasElement; + private nextCtx: CanvasRenderingContext2D; + private holdCanvas: HTMLCanvasElement; + private holdCtx: CanvasRenderingContext2D; + + // Game state + private board: Board; + private bag: Bag; + private current!: Piece; + private holdKey: string | null = null; + private holdUsed: boolean = false; + private rotation: number = 0; // 0..3 + private score: number = 0; + private lines: number = 0; + private level: number = 1; + private gameOver: boolean = false; + private paused: boolean = false; + private started: boolean = false; + + // Timers + private dropTimer: number = 0; + private lastTime: number = 0; + private rafId: number = 0; + + // Lock-delay + private lockTimer: number = 0; + private lockDelay: number = 500; // ms + private lockMoves: number = 0; + private maxLockMoves: number = 15; + private onGround: boolean = false; + + // Particles + private particles: Particle[] = []; + + // DOM + private scoreEl: HTMLElement; + private linesEl: HTMLElement; + private levelEl: HTMLElement; + private overlayEl: HTMLElement; + private overlayTitle: HTMLElement; + private overlayMsg: HTMLElement; + + constructor() { + this.canvas = document.getElementById("board") as HTMLCanvasElement; + this.ctx = this.canvas.getContext("2d")!; + this.nextCanvas = document.getElementById("next") as HTMLCanvasElement; + this.nextCtx = this.nextCanvas.getContext("2d")!; + this.holdCanvas = document.getElementById("hold") as HTMLCanvasElement; + this.holdCtx = this.holdCanvas.getContext("2d")!; + + this.canvas.width = COLS * BLOCK; + this.canvas.height = ROWS * BLOCK; + + this.scoreEl = document.getElementById("score")!; + this.linesEl = document.getElementById("lines")!; + this.levelEl = document.getElementById("level")!; + this.overlayEl = document.getElementById("overlay")!; + this.overlayTitle = document.getElementById("overlay-title")!; + this.overlayMsg = document.getElementById("overlay-msg")!; + + this.board = new Board(); + this.bag = new Bag(); + + this.bindKeys(); + this.showOverlay("TETRIS", "Press Space or Enter to start"); + } + + // ── Spawn ──────────────────────────────────────────────────────────────── + + private spawn(key: string): Piece { + const matrix = TETROMINOES[key].map(r => [...r]); + const color = COLORS[key]; + const x = Math.floor((COLS - matrix[0].length) / 2); + const y = key === "I" ? HIDDEN - 2 : HIDDEN - 1; + return { matrix, color, x, y }; + } + + private spawnNext(): void { + const key = this.bag.next(); + this.current = this.spawn(key); + this.rotation = 0; + this.lockTimer = 0; + this.lockMoves = 0; + this.onGround = false; + + if (!this.board.isValid(this.current)) { + this.endGame(); + } + } + + // ── Movement & Rotation ────────────────────────────────────────────────── + + private move(dx: number, dy: number, softDrop = false): boolean { + const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy }; + if (!this.board.isValid(next)) return false; + this.current = next; + if (softDrop && dy > 0) { + // +1 per row for player-initiated soft drop + this.score += 1; + this.updateHUD(); + } + return true; + } + + private rotate(dir: 1 | -1): void { + const fromRot = this.rotation; + const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4; + const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix); + + const isI = this.current.matrix.length === 4; + const kicks = isI ? KICKS_I : KICKS_JLSTZ; + const kickIdx = dir === 1 ? fromRot : toRot; + const kickSet = kicks[kickIdx]; + + for (const [kx, ky] of kickSet) { + const nx = this.current.x + (dir === 1 ? kx : -kx); + const ny = this.current.y + (dir === 1 ? ky : -ky); + const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny }; + if (this.board.isValid(candidate)) { + this.current = candidate; + this.rotation = toRot; + this.resetLockDelay(); + return; + } + } + } + + private hardDrop(): void { + const gy = this.board.getGhostY(this.current); + const dropped = gy - this.current.y; + this.score += dropped * 2; + this.current = { ...this.current, y: gy }; + this.lockPiece(); + } + + private hold(): void { + if (this.holdUsed) return; + this.holdUsed = true; + if (this.holdKey === null) { + // Infer key by matching the color + const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!; + this.holdKey = key; + this.spawnNext(); + } else { + const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!; + const prev = this.holdKey; + this.holdKey = key; + this.current = this.spawn(prev); + this.rotation = 0; + this.lockTimer = 0; + this.lockMoves = 0; + this.onGround = false; + } + this.drawHold(); + } + + // ── Lock Delay ─────────────────────────────────────────────────────────── + + private resetLockDelay(): void { + if (this.onGround && this.lockMoves < this.maxLockMoves) { + this.lockTimer = 0; + this.lockMoves++; + } + } + + private lockPiece(): void { + this.board.lock(this.current); + const cleared = this.board.clearLines(); + + if (cleared > 0) { + this.spawnLineClearParticles(cleared); + this.score += LINE_SCORES[cleared] * this.level; + this.lines += cleared; + const newLevel = Math.floor(this.lines / 10) + 1; + if (newLevel > this.level) this.level = newLevel; + } + + this.holdUsed = false; + this.updateHUD(); + this.spawnNext(); + } + + // ── Particles ──────────────────────────────────────────────────────────── + + private spawnLineClearParticles(_count: number): void { + const colors = ["#fff", "#ffd700", "#ff9900", "#39d353", "#00d4ff", "#bf5fff"]; + for (let i = 0; i < 80; i++) { + this.particles.push({ + x: Math.random() * this.canvas.width, + y: Math.random() * this.canvas.height, + vx: (Math.random() - 0.5) * 6, + vy: (Math.random() - 0.5) * 6, + alpha: 1, + color: colors[Math.floor(Math.random() * colors.length)], + size: Math.random() * 5 + 2, + }); + } + } + + // ── Game Loop ──────────────────────────────────────────────────────────── + + private loop(time: number): void { + const dt = Math.min(time - this.lastTime, 100); + this.lastTime = time; + + if (!this.paused && !this.gameOver) { + this.dropTimer += dt; + + const interval = levelInterval(this.level); + if (this.dropTimer >= interval) { + this.dropTimer = 0; + const moved = this.move(0, 1); + if (!moved) { + this.onGround = true; + } + } + + // Lock delay + const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 }); + if (landedNow) { + this.onGround = true; + this.lockTimer += dt; + if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) { + this.lockPiece(); + } + } else { + this.onGround = false; + this.lockTimer = 0; + } + + // Update particles + this.particles = this.particles.filter(p => p.alpha > 0.02); + for (const p of this.particles) { + p.x += p.vx; + p.y += p.vy; + p.vy += 0.15; + p.alpha *= 0.93; + } + } + + this.draw(); + this.rafId = requestAnimationFrame(t => this.loop(t)); + } + + // ── Start / Pause / End ────────────────────────────────────────────────── + + start(): void { + if (this.started && !this.gameOver) { + this.togglePause(); + return; + } + this.board = new Board(); + this.bag = new Bag(); + this.holdKey = null; + this.holdUsed = false; + this.score = 0; + this.lines = 0; + this.level = 1; + this.gameOver = false; + this.paused = false; + this.started = true; + this.particles = []; + this.spawnNext(); + this.updateHUD(); + this.hideOverlay(); + this.lastTime = performance.now(); + this.dropTimer = 0; + cancelAnimationFrame(this.rafId); + this.rafId = requestAnimationFrame(t => this.loop(t)); + } + + private togglePause(): void { + this.paused = !this.paused; + if (this.paused) { + this.showOverlay("PAUSED", "Press P or Space to resume"); + } else { + this.hideOverlay(); + this.lastTime = performance.now(); + } + } + + private endGame(): void { + this.gameOver = true; + this.showOverlay("GAME OVER", `Score: ${this.score.toLocaleString()}\nPress Space or Enter to restart`); + } + + // ── Draw ───────────────────────────────────────────────────────────────── + + private draw(): void { + const ctx = this.ctx; + ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + this.drawBackground(); + this.drawBoard(); + this.drawGhost(); + this.drawPiece(ctx, this.current, -HIDDEN); + this.drawParticles(); + this.drawNext(); + this.drawHold(); + } + + private drawBackground(): void { + const ctx = this.ctx; + ctx.fillStyle = "#0e0e1a"; + ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + // Grid lines + ctx.strokeStyle = "rgba(255,255,255,0.04)"; + ctx.lineWidth = 1; + for (let c = 0; c <= COLS; c++) { + ctx.beginPath(); + ctx.moveTo(c * BLOCK, 0); + ctx.lineTo(c * BLOCK, this.canvas.height); + ctx.stroke(); + } + for (let r = 0; r <= ROWS; r++) { + ctx.beginPath(); + ctx.moveTo(0, r * BLOCK); + ctx.lineTo(this.canvas.width, r * BLOCK); + ctx.stroke(); + } + } + + private drawBoard(): void { + const ctx = this.ctx; + for (let r = HIDDEN; r < TOTAL_ROWS; r++) { + for (let c = 0; c < COLS; c++) { + const color = this.board.grid[r][c]; + if (color) { + this.drawBlock(ctx, c, r - HIDDEN, color); + } + } + } + } + + private drawGhost(): void { + const gy = this.board.getGhostY(this.current); + if (gy === this.current.y) return; + const ctx = this.ctx; + ctx.globalAlpha = 0.25; + const ghost: Piece = { ...this.current, y: gy }; + this.drawPiece(ctx, ghost, -HIDDEN); + ctx.globalAlpha = 1; + } + + private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void { + for (let r = 0; r < piece.matrix.length; r++) { + for (let c = 0; c < piece.matrix[r].length; c++) { + if (!piece.matrix[r][c]) continue; + const px = piece.x + c; + const py = piece.y + r + yOffset; + if (py < 0) continue; + this.drawBlock(ctx, px, py, piece.color); + } + } + } + + private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void { + const px = x * size; + const py = y * size; + const pad = size * 0.05; + + // Base fill + ctx.fillStyle = color; + ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2); + + // Highlight (top-left) + ctx.fillStyle = "rgba(255,255,255,0.35)"; + ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2); + ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2); + + // Shadow (bottom-right) + ctx.fillStyle = "rgba(0,0,0,0.3)"; + ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2); + ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2); + } + + private drawParticles(): void { + const ctx = this.ctx; + for (const p of this.particles) { + ctx.globalAlpha = p.alpha; + ctx.fillStyle = p.color; + ctx.beginPath(); + ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); + ctx.fill(); + } + ctx.globalAlpha = 1; + } + + private drawNext(): void { + const ctx = this.nextCtx; + const next3 = this.bag.peek(3); + const cellW = 4; + const cellH = 3; + const bSize = 22; + + ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height); + ctx.fillStyle = "#0e0e1a"; + ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height); + + next3.forEach((key, idx) => { + const matrix = TETROMINOES[key]; + const color = COLORS[key]; + const offX = Math.floor((cellW - matrix[0].length) / 2); + const offY = Math.floor((cellH - matrix.length) / 2); + const baseY = idx * cellH; + + for (let r = 0; r < matrix.length; r++) { + for (let c = 0; c < matrix[r].length; c++) { + if (!matrix[r][c]) continue; + this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize); + } + } + }); + } + + private drawHold(): void { + const ctx = this.holdCtx; + const bSize = 22; + + ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height); + ctx.fillStyle = "#0e0e1a"; + ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height); + + if (!this.holdKey) return; + const matrix = TETROMINOES[this.holdKey]; + const color = this.holdUsed ? "#555" : COLORS[this.holdKey]; + const offX = Math.floor((4 - matrix[0].length) / 2); + const offY = Math.floor((3 - matrix.length) / 2); + + for (let r = 0; r < matrix.length; r++) { + for (let c = 0; c < matrix[r].length; c++) { + if (!matrix[r][c]) continue; + this.drawBlock(ctx, offX + c, offY + r, color, bSize); + } + } + } + + // ── HUD ────────────────────────────────────────────────────────────────── + + private updateHUD(): void { + this.scoreEl.textContent = this.score.toLocaleString(); + this.linesEl.textContent = String(this.lines); + this.levelEl.textContent = String(this.level); + } + + private showOverlay(title: string, msg: string): void { + this.overlayTitle.textContent = title; + this.overlayMsg.textContent = msg; + this.overlayEl.classList.remove("hidden"); + } + + private hideOverlay(): void { + this.overlayEl.classList.add("hidden"); + } + + // ── Key Bindings ───────────────────────────────────────────────────────── + + private bindKeys(): void { + // DAS (Delayed Auto Shift) state + const DAS_DELAY = 170; + const DAS_RATE = 50; + const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {}; + + const startDAS = (key: string, fn: () => void) => { + if (dasState[key]?.active) return; + fn(); + dasState[key] = { + active: true, + timer: setTimeout(() => { + dasState[key].interval = setInterval(fn, DAS_RATE); + }, DAS_DELAY), + interval: null, + }; + }; + + const stopDAS = (key: string) => { + if (!dasState[key]) return; + clearTimeout(dasState[key].timer!); + clearInterval(dasState[key].interval!); + dasState[key].active = false; + }; + + window.addEventListener("keydown", (e) => { + if (!this.started || this.gameOver) { + if (e.code === "Space" || e.code === "Enter") this.start(); + return; + } + + switch (e.code) { + case "ArrowLeft": + e.preventDefault(); + startDAS("left", () => { + if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); } + }); + break; + case "ArrowRight": + e.preventDefault(); + startDAS("right", () => { + if (!this.paused) { this.move(1, 0); this.resetLockDelay(); } + }); + break; + case "ArrowDown": + e.preventDefault(); + startDAS("down", () => { + if (!this.paused) { this.move(0, 1, true); this.resetLockDelay(); } + }); + break; + case "ArrowUp": + e.preventDefault(); + if (!this.paused) { this.rotate(1); } + break; + case "KeyZ": + e.preventDefault(); + if (!this.paused) { this.rotate(-1); } + break; + case "KeyX": + e.preventDefault(); + if (!this.paused) { this.rotate(1); } + break; + case "Space": + e.preventDefault(); + if (this.paused) { this.togglePause(); return; } + this.hardDrop(); + break; + case "KeyC": + case "ShiftLeft": + case "ShiftRight": + e.preventDefault(); + if (!this.paused) this.hold(); + break; + case "KeyP": + case "Escape": + e.preventDefault(); + this.togglePause(); + break; + case "Enter": + e.preventDefault(); + if (this.paused) this.togglePause(); + break; + } + }); + + window.addEventListener("keyup", (e) => { + if (e.code === "ArrowLeft") stopDAS("left"); + if (e.code === "ArrowRight") stopDAS("right"); + if (e.code === "ArrowDown") stopDAS("down"); + }); + } +} + +// ─── Bootstrap ─────────────────────────────────────────────────────────────── + +window.addEventListener("DOMContentLoaded", () => { + new Tetris(); +}); diff --git a/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/tsconfig.json b/dashboard/public/artifacts/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "rootDir": "./src", + "outDir": "./dist", + "lib": ["ES2020", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts"] +} diff --git a/results/analysis/main_effects_code_quality.json b/results/analysis/main_effects_code_quality.json @@ -3,265 +3,265 @@ "values": { "haiku": { "mean": 0.7104, - "effect": -0.0737, + "effect": -0.0759, "n": 57 }, "opus": { "mean": 0.8219, - "effect": 0.0378, + "effect": 0.0357, "n": 16 }, "sonnet": { - "mean": 0.8606, - "effect": 0.0766, - "n": 47 + "mean": 0.8598, + "effect": 0.0736, + "n": 51 } }, - "spread": 0.1502 + "spread": 0.1494 }, "claude_version": { "values": { "2.1.91 (Claude Code)": { "mean": 0.7055, - "effect": -0.0786, + "effect": -0.0807, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 0.8422, - "effect": 0.0581, - "n": 69 + "mean": 0.8426, + "effect": 0.0564, + "n": 73 } }, - "spread": 0.1367 + "spread": 0.1371 }, "language": { "values": { "javascript": { "mean": 0.8944, - "effect": 0.1104, + "effect": 0.1082, "n": 9 }, "typescript": { - "mean": 0.7703, - "effect": -0.0138, - "n": 103 + "mean": 0.7733, + "effect": -0.0129, + "n": 107 }, "unspecified": { "mean": 0.8375, - "effect": 0.0534, + "effect": 0.0513, "n": 8 } }, - "spread": 0.1241 - }, - "playwright": { - "values": { - "off": { - "mean": 0.7167, - "effect": -0.0674, - "n": 9 - }, - "on": { - "mean": 0.7895, - "effect": 0.0055, - "n": 111 - } - }, - "spread": 0.0728 + "spread": 0.1211 }, "max_budget": { "values": { "high": { "mean": 0.7256, - "effect": -0.0585, + "effect": -0.0607, "n": 9 }, "low": { - "mean": 0.7888, + "mean": 0.791, "effect": 0.0047, - "n": 111 + "n": 115 } }, - "spread": 0.0632 + "spread": 0.0654 }, "prompt_style": { "values": { "detailed": { "mean": 0.84, - "effect": 0.0559, + "effect": 0.0538, "n": 10 }, "simple": { - "mean": 0.779, - "effect": -0.0051, - "n": 110 + "mean": 0.7815, + "effect": -0.0047, + "n": 114 } }, - "spread": 0.061 + "spread": 0.0585 }, "context_file": { "values": { "none": { - "mean": 0.7877, + "mean": 0.7898, "effect": 0.0036, - "n": 111 + "n": 115 }, "provided": { "mean": 0.74, - "effect": -0.0441, + "effect": -0.0462, "n": 9 } }, - "spread": 0.0477 + "spread": 0.0498 + }, + "playwright": { + "values": { + "off": { + "mean": 0.7409, + "effect": -0.0453, + "n": 11 + }, + "on": { + "mean": 0.7906, + "effect": 0.0044, + "n": 113 + } + }, + "spread": 0.0497 }, "human_language": { "values": { "en": { - "mean": 0.7863, - "effect": 0.0022, - "n": 113 + "mean": 0.7885, + "effect": 0.0023, + "n": 117 }, "es": { "mean": 0.7486, - "effect": -0.0355, + "effect": -0.0376, "n": 7 } }, - "spread": 0.0377 + "spread": 0.0399 }, - "linter": { + "tool_read": { "values": { "off": { - "mean": 0.755, - "effect": -0.0291, - "n": 10 + "mean": 0.8167, + "effect": 0.0305, + "n": 9 }, "on": { - "mean": 0.7867, - "effect": 0.0026, - "n": 110 + "mean": 0.7838, + "effect": -0.0024, + "n": 115 } }, - "spread": 0.0317 + "spread": 0.0329 }, - "tool_grep": { + "web_search": { "values": { "off": { - "mean": 0.8122, - "effect": 0.0281, - "n": 9 + "mean": 0.757, + "effect": -0.0292, + "n": 10 }, "on": { - "mean": 0.7818, - "effect": -0.0023, - "n": 111 + "mean": 0.7888, + "effect": 0.0026, + "n": 114 } }, - "spread": 0.0304 + "spread": 0.0318 }, - "tool_read": { + "tool_grep": { "values": { "off": { - "mean": 0.8125, - "effect": 0.0284, - "n": 8 + "mean": 0.8122, + "effect": 0.026, + "n": 9 }, "on": { - "mean": 0.7821, + "mean": 0.7842, "effect": -0.002, - "n": 112 + "n": 115 } }, - "spread": 0.0304 + "spread": 0.028 }, - "web_search": { + "linter": { "values": { "off": { - "mean": 0.757, - "effect": -0.0271, - "n": 10 + "mean": 0.7636, + "effect": -0.0226, + "n": 11 }, "on": { - "mean": 0.7865, - "effect": 0.0025, - "n": 110 + "mean": 0.7884, + "effect": 0.0022, + "n": 113 } }, - "spread": 0.0295 + "spread": 0.0248 }, "sub_agents": { "values": { "off": { "mean": 0.7709, - "effect": -0.0132, + "effect": -0.0153, "n": 11 }, "on": { - "mean": 0.7854, - "effect": 0.0013, - "n": 109 - } - }, - "spread": 0.0145 - }, - "tool_edit": { - "values": { - "off": { - "mean": 0.7956, - "effect": 0.0115, - "n": 9 - }, - "on": { - "mean": 0.7832, - "effect": -0.0009, - "n": 111 + "mean": 0.7877, + "effect": 0.0015, + "n": 113 } }, - "spread": 0.0124 + "spread": 0.0168 }, "effort": { "values": { "high": { - "mean": 0.7847, - "effect": 0.0006, - "n": 111 + "mean": 0.787, + "effect": 0.0007, + "n": 115 }, "max": { "mean": 0.7767, - "effect": -0.0074, + "effect": -0.0095, + "n": 9 + } + }, + "spread": 0.0103 + }, + "tool_edit": { + "values": { + "off": { + "mean": 0.7956, + "effect": 0.0093, "n": 9 + }, + "on": { + "mean": 0.7855, + "effect": -0.0007, + "n": 115 } }, - "spread": 0.008 + "spread": 0.0101 }, "tool_glob": { "values": { "off": { "mean": 0.7778, - "effect": -0.0063, + "effect": -0.0084, "n": 9 }, "on": { - "mean": 0.7846, - "effect": 0.0005, - "n": 111 + "mean": 0.7869, + "effect": 0.0007, + "n": 115 } }, - "spread": 0.0068 + "spread": 0.0091 }, "tool_write": { "values": { "off": { "mean": 0.7811, - "effect": -0.003, + "effect": -0.0051, "n": 9 }, "on": { - "mean": 0.7843, - "effect": 0.0002, - "n": 111 + "mean": 0.7866, + "effect": 0.0004, + "n": 115 } }, - "spread": 0.0032 + "spread": 0.0055 } } \ No newline at end of file diff --git a/results/analysis/main_effects_cost.json b/results/analysis/main_effects_cost.json @@ -3,265 +3,265 @@ "values": { "haiku": { "mean": 0.2578, - "effect": -0.4834, + "effect": -0.5, "n": 57 }, "opus": { "mean": 0.7091, - "effect": -0.0321, + "effect": -0.0487, "n": 16 }, "sonnet": { - "mean": 1.3383, - "effect": 0.5972, - "n": 47 + "mean": 1.3319, + "effect": 0.5741, + "n": 51 } }, - "spread": 1.0805 + "spread": 1.0741 }, "claude_version": { "values": { "2.1.91 (Claude Code)": { "mean": 0.266, - "effect": -0.4752, + "effect": -0.4918, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 1.0924, - "effect": 0.3512, - "n": 69 + "mean": 1.1014, + "effect": 0.3436, + "n": 73 } }, - "spread": 0.8264 - }, - "playwright": { - "values": { - "off": { - "mean": 0.4135, - "effect": -0.3277, - "n": 9 - }, - "on": { - "mean": 0.7677, - "effect": 0.0266, - "n": 111 - } - }, - "spread": 0.3542 + "spread": 0.8354 }, "effort": { "values": { "high": { - "mean": 0.7192, - "effect": -0.022, - "n": 111 + "mean": 0.7379, + "effect": -0.0199, + "n": 115 }, "max": { "mean": 1.0123, - "effect": 0.2711, + "effect": 0.2545, "n": 9 } }, - "spread": 0.2931 + "spread": 0.2744 }, "tool_glob": { "values": { "off": { "mean": 0.5395, - "effect": -0.2017, + "effect": -0.2183, "n": 9 }, "on": { - "mean": 0.7575, - "effect": 0.0164, - "n": 111 + "mean": 0.7749, + "effect": 0.0171, + "n": 115 } }, - "spread": 0.218 + "spread": 0.2354 }, "tool_edit": { "values": { "off": { "mean": 0.5544, - "effect": -0.1868, + "effect": -0.2033, "n": 9 }, "on": { - "mean": 0.7563, - "effect": 0.0151, - "n": 111 + "mean": 0.7737, + "effect": 0.0159, + "n": 115 } }, - "spread": 0.2019 - }, - "linter": { - "values": { - "off": { - "mean": 0.5621, - "effect": -0.1791, - "n": 10 - }, - "on": { - "mean": 0.7575, - "effect": 0.0163, - "n": 110 - } - }, - "spread": 0.1954 + "spread": 0.2193 }, "language": { "values": { "javascript": { "mean": 0.5923, - "effect": -0.1489, + "effect": -0.1655, "n": 9 }, "typescript": { - "mean": 0.7582, - "effect": 0.017, - "n": 103 + "mean": 0.7768, + "effect": 0.019, + "n": 107 }, "unspecified": { "mean": 0.69, - "effect": -0.0512, + "effect": -0.0678, "n": 8 } }, - "spread": 0.1659 + "spread": 0.1845 }, "tool_write": { "values": { "off": { "mean": 0.5934, - "effect": -0.1477, + "effect": -0.1643, "n": 9 }, "on": { - "mean": 0.7532, - "effect": 0.012, - "n": 111 + "mean": 0.7706, + "effect": 0.0129, + "n": 115 } }, - "spread": 0.1598 + "spread": 0.1772 }, "sub_agents": { "values": { "off": { "mean": 0.6013, - "effect": -0.1399, + "effect": -0.1565, "n": 11 }, "on": { - "mean": 0.7553, - "effect": 0.0141, - "n": 109 + "mean": 0.773, + "effect": 0.0152, + "n": 113 } }, - "spread": 0.154 + "spread": 0.1717 }, "max_budget": { "values": { "high": { "mean": 0.6017, - "effect": -0.1395, + "effect": -0.1561, "n": 9 }, "low": { - "mean": 0.7525, - "effect": 0.0113, - "n": 111 + "mean": 0.77, + "effect": 0.0122, + "n": 115 } }, - "spread": 0.1508 + "spread": 0.1683 }, - "tool_read": { + "playwright": { "values": { "off": { - "mean": 0.6084, - "effect": -0.1328, - "n": 8 + "mean": 0.6095, + "effect": -0.1483, + "n": 11 }, "on": { - "mean": 0.7507, - "effect": 0.0095, - "n": 112 + "mean": 0.7722, + "effect": 0.0144, + "n": 113 } }, - "spread": 0.1423 + "spread": 0.1627 }, "context_file": { "values": { "none": { - "mean": 0.7516, - "effect": 0.0104, - "n": 111 + "mean": 0.7691, + "effect": 0.0113, + "n": 115 }, "provided": { "mean": 0.6129, - "effect": -0.1283, + "effect": -0.1449, + "n": 9 + } + }, + "spread": 0.1562 + }, + "tool_read": { + "values": { + "off": { + "mean": 0.6164, + "effect": -0.1414, "n": 9 + }, + "on": { + "mean": 0.7688, + "effect": 0.0111, + "n": 115 } }, - "spread": 0.1387 + "spread": 0.1524 + }, + "linter": { + "values": { + "off": { + "mean": 0.6346, + "effect": -0.1232, + "n": 11 + }, + "on": { + "mean": 0.7698, + "effect": 0.012, + "n": 113 + } + }, + "spread": 0.1352 }, "tool_grep": { "values": { "off": { "mean": 0.6512, - "effect": -0.09, + "effect": -0.1066, "n": 9 }, "on": { - "mean": 0.7485, - "effect": 0.0073, - "n": 111 + "mean": 0.7661, + "effect": 0.0083, + "n": 115 } }, - "spread": 0.0973 + "spread": 0.1149 }, "web_search": { "values": { "off": { "mean": 0.6893, - "effect": -0.0519, + "effect": -0.0684, "n": 10 }, "on": { - "mean": 0.7459, - "effect": 0.0047, - "n": 110 + "mean": 0.7638, + "effect": 0.006, + "n": 114 } }, - "spread": 0.0566 + "spread": 0.0745 }, "human_language": { "values": { "en": { - "mean": 0.7394, - "effect": -0.0018, - "n": 113 + "mean": 0.757, + "effect": -0.0007, + "n": 117 }, "es": { "mean": 0.7702, - "effect": 0.029, + "effect": 0.0124, "n": 7 } }, - "spread": 0.0308 + "spread": 0.0132 }, "prompt_style": { "values": { "detailed": { "mean": 0.75, - "effect": 0.0088, + "effect": -0.0078, "n": 10 }, "simple": { - "mean": 0.7404, - "effect": -0.0008, - "n": 110 + "mean": 0.7585, + "effect": 0.0007, + "n": 114 } }, - "spread": 0.0096 + "spread": 0.0085 } } \ No newline at end of file diff --git a/results/analysis/main_effects_gameplay.json b/results/analysis/main_effects_gameplay.json @@ -2,266 +2,266 @@ "tool_read": { "values": { "off": { - "mean": 0.3925, - "effect": -0.2261, - "n": 8 + "mean": 0.3489, + "effect": -0.2714, + "n": 9 }, "on": { - "mean": 0.6347, - "effect": 0.0161, - "n": 112 + "mean": 0.6416, + "effect": 0.0212, + "n": 115 } }, - "spread": 0.2422 + "spread": 0.2927 }, "language": { "values": { "javascript": { "mean": 0.4178, - "effect": -0.2008, + "effect": -0.2025, "n": 9 }, "typescript": { - "mean": 0.6482, - "effect": 0.0296, - "n": 103 + "mean": 0.6491, + "effect": 0.0287, + "n": 107 }, "unspecified": { "mean": 0.4637, - "effect": -0.1548, + "effect": -0.1566, "n": 8 } }, - "spread": 0.2304 + "spread": 0.2313 }, "model": { "values": { "haiku": { "mean": 0.5749, - "effect": -0.0437, + "effect": -0.0454, "n": 57 }, "opus": { "mean": 0.5563, - "effect": -0.0623, + "effect": -0.0641, "n": 16 }, "sonnet": { - "mean": 0.6928, - "effect": 0.0742, - "n": 47 + "mean": 0.6912, + "effect": 0.0709, + "n": 51 } }, - "spread": 0.1365 + "spread": 0.1349 }, "human_language": { "values": { "en": { - "mean": 0.6259, - "effect": 0.0073, - "n": 113 + "mean": 0.6275, + "effect": 0.0072, + "n": 117 }, "es": { "mean": 0.5, - "effect": -0.1186, + "effect": -0.1203, "n": 7 } }, - "spread": 0.1259 + "spread": 0.1275 }, "effort": { "values": { "high": { - "mean": 0.6095, - "effect": -0.0091, - "n": 111 + "mean": 0.6117, + "effect": -0.0087, + "n": 115 }, "max": { "mean": 0.7311, - "effect": 0.1125, + "effect": 0.1108, "n": 9 } }, - "spread": 0.1216 + "spread": 0.1194 }, "tool_grep": { "values": { "off": { "mean": 0.7311, - "effect": 0.1125, + "effect": 0.1108, "n": 9 }, "on": { - "mean": 0.6095, - "effect": -0.0091, - "n": 111 + "mean": 0.6117, + "effect": -0.0087, + "n": 115 } }, - "spread": 0.1216 + "spread": 0.1194 }, "tool_edit": { "values": { "off": { "mean": 0.7178, - "effect": 0.0992, + "effect": 0.0975, "n": 9 }, "on": { - "mean": 0.6105, - "effect": -0.008, - "n": 111 + "mean": 0.6127, + "effect": -0.0076, + "n": 115 } }, - "spread": 0.1073 + "spread": 0.1051 }, "tool_write": { "values": { "off": { "mean": 0.71, - "effect": 0.0914, + "effect": 0.0897, "n": 9 }, "on": { - "mean": 0.6112, - "effect": -0.0074, - "n": 111 + "mean": 0.6133, + "effect": -0.007, + "n": 115 } }, - "spread": 0.0988 + "spread": 0.0967 + }, + "playwright": { + "values": { + "off": { + "mean": 0.7055, + "effect": 0.0851, + "n": 11 + }, + "on": { + "mean": 0.612, + "effect": -0.0083, + "n": 113 + } + }, + "spread": 0.0935 }, "web_search": { "values": { "off": { "mean": 0.539, - "effect": -0.0796, + "effect": -0.0813, "n": 10 }, "on": { - "mean": 0.6258, - "effect": 0.0072, - "n": 110 + "mean": 0.6275, + "effect": 0.0071, + "n": 114 } }, - "spread": 0.0868 + "spread": 0.0885 }, "context_file": { "values": { "none": { - "mean": 0.6129, - "effect": -0.0057, - "n": 111 + "mean": 0.615, + "effect": -0.0054, + "n": 115 }, "provided": { "mean": 0.6889, - "effect": 0.0703, + "effect": 0.0686, "n": 9 } }, - "spread": 0.076 + "spread": 0.0739 }, "tool_glob": { "values": { "off": { "mean": 0.6822, - "effect": 0.0636, + "effect": 0.0619, "n": 9 }, "on": { - "mean": 0.6134, - "effect": -0.0052, - "n": 111 + "mean": 0.6155, + "effect": -0.0048, + "n": 115 } }, - "spread": 0.0688 + "spread": 0.0667 }, "claude_version": { "values": { "2.1.91 (Claude Code)": { "mean": 0.5824, - "effect": -0.0362, + "effect": -0.038, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 0.6454, - "effect": 0.0268, - "n": 69 + "mean": 0.6468, + "effect": 0.0265, + "n": 73 } }, - "spread": 0.063 + "spread": 0.0644 }, "sub_agents": { "values": { "off": { "mean": 0.6718, - "effect": 0.0532, + "effect": 0.0515, "n": 11 }, "on": { - "mean": 0.6132, - "effect": -0.0054, - "n": 109 - } - }, - "spread": 0.0586 - }, - "playwright": { - "values": { - "off": { - "mean": 0.6678, - "effect": 0.0492, - "n": 9 - }, - "on": { - "mean": 0.6146, - "effect": -0.004, - "n": 111 + "mean": 0.6153, + "effect": -0.005, + "n": 113 } }, - "spread": 0.0532 + "spread": 0.0565 }, "max_budget": { "values": { "high": { "mean": 0.6611, - "effect": 0.0425, + "effect": 0.0408, "n": 9 }, "low": { - "mean": 0.6151, - "effect": -0.0034, - "n": 111 + "mean": 0.6171, + "effect": -0.0032, + "n": 115 } }, - "spread": 0.046 + "spread": 0.044 }, - "linter": { + "prompt_style": { "values": { - "off": { - "mean": 0.595, - "effect": -0.0236, + "detailed": { + "mean": 0.628, + "effect": 0.0077, "n": 10 }, - "on": { - "mean": 0.6207, - "effect": 0.0021, - "n": 110 + "simple": { + "mean": 0.6196, + "effect": -0.0007, + "n": 114 } }, - "spread": 0.0257 + "spread": 0.0084 }, - "prompt_style": { + "linter": { "values": { - "detailed": { - "mean": 0.628, - "effect": 0.0094, - "n": 10 + "off": { + "mean": 0.6264, + "effect": 0.006, + "n": 11 }, - "simple": { - "mean": 0.6177, - "effect": -0.0009, - "n": 110 + "on": { + "mean": 0.6197, + "effect": -0.0006, + "n": 113 } }, - "spread": 0.0103 + "spread": 0.0067 } } \ No newline at end of file diff --git a/results/analysis/main_effects_score.json b/results/analysis/main_effects_score.json @@ -3,52 +3,52 @@ "values": { "haiku": { "mean": 0.576, - "effect": -0.0601, + "effect": -0.0623, "n": 57 }, "opus": { "mean": 0.6671, - "effect": 0.0311, + "effect": 0.0288, "n": 16 }, "sonnet": { - "mean": 0.6983, - "effect": 0.0623, - "n": 47 + "mean": 0.6989, + "effect": 0.0606, + "n": 51 } }, - "spread": 0.1223 + "spread": 0.1229 }, "claude_version": { "values": { "2.1.91 (Claude Code)": { "mean": 0.5734, - "effect": -0.0626, + "effect": -0.0648, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 0.6823, - "effect": 0.0463, - "n": 69 + "mean": 0.6836, + "effect": 0.0453, + "n": 73 } }, - "spread": 0.1089 + "spread": 0.1102 }, "language": { "values": { "javascript": { "mean": 0.6957, - "effect": 0.0597, + "effect": 0.0574, "n": 9 }, "typescript": { - "mean": 0.6333, - "effect": -0.0027, - "n": 103 + "mean": 0.6361, + "effect": -0.0022, + "n": 107 }, "unspecified": { "mean": 0.6031, - "effect": -0.0329, + "effect": -0.0352, "n": 8 } }, @@ -57,211 +57,211 @@ "tool_read": { "values": { "off": { - "mean": 0.5704, - "effect": -0.0656, - "n": 8 - }, - "on": { - "mean": 0.6407, - "effect": 0.0047, - "n": 112 - } - }, - "spread": 0.0703 - }, - "playwright": { - "values": { - "off": { - "mean": 0.5861, - "effect": -0.05, + "mean": 0.5777, + "effect": -0.0606, "n": 9 }, "on": { - "mean": 0.6401, - "effect": 0.0041, - "n": 111 - } - }, - "spread": 0.054 - }, - "linter": { - "values": { - "off": { - "mean": 0.6008, - "effect": -0.0353, - "n": 10 - }, - "on": { - "mean": 0.6392, - "effect": 0.0032, - "n": 110 + "mean": 0.643, + "effect": 0.0047, + "n": 115 } }, - "spread": 0.0384 + "spread": 0.0653 }, "max_budget": { "values": { "high": { "mean": 0.6052, - "effect": -0.0308, + "effect": -0.0331, "n": 9 }, "low": { - "mean": 0.6385, - "effect": 0.0025, - "n": 111 + "mean": 0.6409, + "effect": 0.0026, + "n": 115 } }, - "spread": 0.0333 + "spread": 0.0357 }, "prompt_style": { "values": { "detailed": { "mean": 0.6089, - "effect": -0.0271, + "effect": -0.0294, "n": 10 }, "simple": { - "mean": 0.6385, - "effect": 0.0025, - "n": 110 + "mean": 0.6409, + "effect": 0.0026, + "n": 114 } }, - "spread": 0.0296 + "spread": 0.032 }, "tool_edit": { "values": { "off": { "mean": 0.6104, - "effect": -0.0256, + "effect": -0.0278, "n": 9 }, "on": { - "mean": 0.6381, - "effect": 0.0021, - "n": 111 + "mean": 0.6405, + "effect": 0.0022, + "n": 115 } }, - "spread": 0.0277 + "spread": 0.0301 }, - "effort": { + "linter": { "values": { - "high": { - "mean": 0.634, - "effect": -0.002, - "n": 111 + "off": { + "mean": 0.6116, + "effect": -0.0266, + "n": 11 }, - "max": { - "mean": 0.6612, - "effect": 0.0252, - "n": 9 + "on": { + "mean": 0.6409, + "effect": 0.0026, + "n": 113 } }, - "spread": 0.0272 + "spread": 0.0293 }, "web_search": { "values": { "off": { "mean": 0.6119, - "effect": -0.0241, + "effect": -0.0263, "n": 10 }, "on": { - "mean": 0.6382, - "effect": 0.0022, - "n": 110 + "mean": 0.6406, + "effect": 0.0023, + "n": 114 } }, - "spread": 0.0263 + "spread": 0.0287 }, "human_language": { "values": { "en": { - "mean": 0.6375, - "effect": 0.0015, - "n": 113 + "mean": 0.6399, + "effect": 0.0016, + "n": 117 }, "es": { "mean": 0.6113, - "effect": -0.0247, + "effect": -0.027, "n": 7 } }, - "spread": 0.0262 + "spread": 0.0286 + }, + "playwright": { + "values": { + "off": { + "mean": 0.613, + "effect": -0.0253, + "n": 11 + }, + "on": { + "mean": 0.6407, + "effect": 0.0025, + "n": 113 + } + }, + "spread": 0.0277 }, "sub_agents": { "values": { "off": { "mean": 0.6132, - "effect": -0.0228, + "effect": -0.0251, "n": 11 }, "on": { - "mean": 0.6383, - "effect": 0.0023, - "n": 109 + "mean": 0.6407, + "effect": 0.0024, + "n": 113 } }, - "spread": 0.0251 + "spread": 0.0275 }, "tool_write": { "values": { "off": { "mean": 0.6136, - "effect": -0.0224, + "effect": -0.0247, "n": 9 }, "on": { - "mean": 0.6378, - "effect": 0.0018, - "n": 111 + "mean": 0.6402, + "effect": 0.0019, + "n": 115 + } + }, + "spread": 0.0266 + }, + "effort": { + "values": { + "high": { + "mean": 0.6365, + "effect": -0.0018, + "n": 115 + }, + "max": { + "mean": 0.6612, + "effect": 0.0229, + "n": 9 } }, - "spread": 0.0242 + "spread": 0.0247 }, "tool_glob": { "values": { "off": { "mean": 0.6318, - "effect": -0.0042, + "effect": -0.0065, "n": 9 }, "on": { - "mean": 0.6364, - "effect": 0.0003, - "n": 111 + "mean": 0.6388, + "effect": 0.0005, + "n": 115 } }, - "spread": 0.0046 + "spread": 0.007 }, "tool_grep": { "values": { "off": { "mean": 0.6388, - "effect": 0.0028, + "effect": 0.0006, "n": 9 }, "on": { - "mean": 0.6358, - "effect": -0.0002, - "n": 111 + "mean": 0.6382, + "effect": -0.0, + "n": 115 } }, - "spread": 0.003 + "spread": 0.0006 }, "context_file": { "values": { "none": { - "mean": 0.6358, - "effect": -0.0002, - "n": 111 + "mean": 0.6383, + "effect": -0.0, + "n": 115 }, "provided": { "mean": 0.6383, - "effect": 0.0023, + "effect": 0.0001, "n": 9 } }, - "spread": 0.0025 + "spread": 0.0 } } \ No newline at end of file diff --git a/results/analysis/main_effects_turns.json b/results/analysis/main_effects_turns.json @@ -3,38 +3,38 @@ "values": { "javascript": { "mean": 8.6667, - "effect": -14.175, + "effect": -14.1075, "n": 9 }, "typescript": { - "mean": 25.0, - "effect": 2.1583, - "n": 103 + "mean": 24.8411, + "effect": 2.0669, + "n": 107 }, "unspecified": { "mean": 11.0, - "effect": -11.8417, + "effect": -11.7742, "n": 8 } }, - "spread": 16.3333 + "spread": 16.1744 }, "model": { "values": { "haiku": { "mean": 26.807, - "effect": 3.9654, + "effect": 4.0328, "n": 57 }, "opus": { "mean": 17.0625, - "effect": -5.7792, + "effect": -5.7117, "n": 16 }, "sonnet": { - "mean": 20.0, - "effect": -2.8417, - "n": 47 + "mean": 20.0588, + "effect": -2.7154, + "n": 51 } }, "spread": 9.7445 @@ -43,225 +43,225 @@ "values": { "2.1.91 (Claude Code)": { "mean": 27.5686, - "effect": 4.727, + "effect": 4.7944, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 19.3478, - "effect": -3.4938, - "n": 69 + "mean": 19.4247, + "effect": -3.3495, + "n": 73 } }, - "spread": 8.2208 + "spread": 8.1439 }, "tool_write": { "values": { "off": { "mean": 30.0, - "effect": 7.1583, + "effect": 7.2258, "n": 9 }, "on": { - "mean": 22.2613, - "effect": -0.5804, - "n": 111 + "mean": 22.2087, + "effect": -0.5655, + "n": 115 } }, - "spread": 7.7387 + "spread": 7.7913 }, "tool_read": { "values": { "off": { - "mean": 29.5, - "effect": 6.6583, - "n": 8 - }, - "on": { - "mean": 22.3661, - "effect": -0.4756, - "n": 112 - } - }, - "spread": 7.1339 - }, - "playwright": { - "values": { - "off": { - "mean": 29.3333, - "effect": 6.4917, + "mean": 29.5556, + "effect": 6.7814, "n": 9 }, "on": { - "mean": 22.3153, - "effect": -0.5264, - "n": 111 + "mean": 22.2435, + "effect": -0.5307, + "n": 115 } }, - "spread": 7.018 + "spread": 7.3121 }, "context_file": { "values": { "none": { - "mean": 22.4324, - "effect": -0.4092, - "n": 111 + "mean": 22.3739, + "effect": -0.4003, + "n": 115 }, "provided": { "mean": 27.8889, - "effect": 5.0472, + "effect": 5.1147, "n": 9 } }, - "spread": 5.4565 + "spread": 5.515 }, "max_budget": { "values": { "high": { "mean": 27.6667, - "effect": 4.825, + "effect": 4.8925, "n": 9 }, "low": { - "mean": 22.4505, - "effect": -0.3912, - "n": 111 + "mean": 22.3913, + "effect": -0.3829, + "n": 115 } }, - "spread": 5.2162 + "spread": 5.2754 + }, + "playwright": { + "values": { + "off": { + "mean": 27.4545, + "effect": 4.6804, + "n": 11 + }, + "on": { + "mean": 22.3186, + "effect": -0.4556, + "n": 113 + } + }, + "spread": 5.1359 }, "tool_grep": { "values": { "off": { "mean": 27.1111, - "effect": 4.2694, + "effect": 4.3369, "n": 9 }, "on": { - "mean": 22.4955, - "effect": -0.3462, - "n": 111 + "mean": 22.4348, + "effect": -0.3394, + "n": 115 } }, - "spread": 4.6156 + "spread": 4.6763 }, "web_search": { "values": { "off": { "mean": 26.4, - "effect": 3.5583, + "effect": 3.6258, "n": 10 }, "on": { - "mean": 22.5182, - "effect": -0.3235, - "n": 110 + "mean": 22.4561, + "effect": -0.3181, + "n": 114 } }, - "spread": 3.8818 + "spread": 3.9439 }, "tool_glob": { "values": { "off": { "mean": 26.3333, - "effect": 3.4917, + "effect": 3.5591, "n": 9 }, "on": { - "mean": 22.5586, - "effect": -0.2831, - "n": 111 + "mean": 22.4957, + "effect": -0.2785, + "n": 115 } }, - "spread": 3.7747 + "spread": 3.8376 }, "human_language": { "values": { "en": { - "mean": 22.6283, - "effect": -0.2133, - "n": 113 + "mean": 22.5641, + "effect": -0.2101, + "n": 117 }, "es": { "mean": 26.2857, - "effect": 3.444, + "effect": 3.5115, "n": 7 } }, - "spread": 3.6574 + "spread": 3.7216 }, "prompt_style": { "values": { "detailed": { "mean": 19.7, - "effect": -3.1417, + "effect": -3.0742, "n": 10 }, "simple": { - "mean": 23.1273, - "effect": 0.2856, - "n": 110 + "mean": 23.0439, + "effect": 0.2697, + "n": 114 } }, - "spread": 3.4273 - }, - "linter": { - "values": { - "off": { - "mean": 25.8, - "effect": 2.9583, - "n": 10 - }, - "on": { - "mean": 22.5727, - "effect": -0.2689, - "n": 110 - } - }, - "spread": 3.2273 + "spread": 3.3439 }, "effort": { "values": { "high": { - "mean": 22.6126, - "effect": -0.2291, - "n": 111 + "mean": 22.5478, + "effect": -0.2264, + "n": 115 }, "max": { "mean": 25.6667, - "effect": 2.825, + "effect": 2.8925, "n": 9 } }, - "spread": 3.0541 + "spread": 3.1189 }, "sub_agents": { "values": { "off": { "mean": 25.0909, - "effect": 2.2492, + "effect": 2.3167, "n": 11 }, "on": { - "mean": 22.6147, - "effect": -0.227, - "n": 109 + "mean": 22.5487, + "effect": -0.2255, + "n": 113 } }, - "spread": 2.4762 + "spread": 2.5422 }, "tool_edit": { "values": { "off": { "mean": 24.8889, - "effect": 2.0472, + "effect": 2.1147, "n": 9 }, "on": { - "mean": 22.6757, - "effect": -0.166, - "n": 111 + "mean": 22.6087, + "effect": -0.1655, + "n": 115 + } + }, + "spread": 2.2802 + }, + "linter": { + "values": { + "off": { + "mean": 24.8182, + "effect": 2.044, + "n": 11 + }, + "on": { + "mean": 22.5752, + "effect": -0.199, + "n": 113 } }, - "spread": 2.2132 + "spread": 2.243 } } \ No newline at end of file diff --git a/results/analysis/main_effects_wall_time.json b/results/analysis/main_effects_wall_time.json @@ -3,265 +3,265 @@ "values": { "haiku": { "mean": 214.0351, - "effect": -235.8982, + "effect": -247.4891, "n": 57 }, "opus": { "mean": 248.9375, - "effect": -200.9958, + "effect": -212.5867, "n": 16 }, "sonnet": { - "mean": 804.4468, - "effect": 354.5135, - "n": 47 + "mean": 804.8235, + "effect": 343.2993, + "n": 51 } }, - "spread": 590.4117 + "spread": 590.7884 }, "claude_version": { "values": { "2.1.91 (Claude Code)": { "mean": 221.7843, - "effect": -228.149, + "effect": -239.7399, "n": 51 }, "2.1.92 (Claude Code)": { - "mean": 618.5652, - "effect": 168.6319, - "n": 69 - } - }, - "spread": 396.7809 - }, - "playwright": { - "values": { - "off": { - "mean": 284.6667, - "effect": -165.2667, - "n": 9 - }, - "on": { - "mean": 463.3333, - "effect": 13.4, - "n": 111 - } - }, - "spread": 178.6666 - }, - "effort": { - "values": { - "high": { - "mean": 440.5045, - "effect": -9.4288, - "n": 111 - }, - "max": { - "mean": 566.2222, - "effect": 116.2889, - "n": 9 + "mean": 629.0137, + "effect": 167.4895, + "n": 73 } }, - "spread": 125.7177 + "spread": 407.2294 }, "language": { "values": { "javascript": { "mean": 348.5556, - "effect": -101.3778, + "effect": -112.9686, "n": 9 }, "typescript": { - "mean": 464.0583, - "effect": 14.1249, - "n": 103 + "mean": 476.9626, + "effect": 15.4384, + "n": 107 }, "unspecified": { "mean": 382.125, - "effect": -67.8083, + "effect": -79.3992, "n": 8 } }, - "spread": 115.5027 + "spread": 128.407 }, "tool_glob": { "values": { "off": { "mean": 349.4444, - "effect": -100.4889, + "effect": -112.0797, "n": 9 }, "on": { - "mean": 458.0811, - "effect": 8.1477, - "n": 111 + "mean": 470.2957, + "effect": 8.7715, + "n": 115 } }, - "spread": 108.6367 + "spread": 120.8513 }, "sub_agents": { "values": { "off": { "mean": 352.6364, - "effect": -97.297, + "effect": -108.8878, "n": 11 }, "on": { - "mean": 459.7523, - "effect": 9.819, - "n": 109 + "mean": 472.1239, + "effect": 10.5997, + "n": 113 } }, - "spread": 107.1159 + "spread": 119.4875 }, "prompt_style": { "values": { "detailed": { "mean": 357.4, - "effect": -92.5333, + "effect": -104.1242, "n": 10 }, "simple": { - "mean": 458.3455, - "effect": 8.4121, - "n": 110 + "mean": 470.6579, + "effect": 9.1337, + "n": 114 } }, - "spread": 100.9455 + "spread": 113.2579 + }, + "effort": { + "values": { + "high": { + "mean": 453.3304, + "effect": -8.1938, + "n": 115 + }, + "max": { + "mean": 566.2222, + "effect": 104.698, + "n": 9 + } + }, + "spread": 112.8918 }, "context_file": { "values": { "none": { - "mean": 455.4685, - "effect": 5.5351, - "n": 111 + "mean": 467.7739, + "effect": 6.2497, + "n": 115 }, "provided": { "mean": 381.6667, - "effect": -68.2667, + "effect": -79.8575, "n": 9 } }, - "spread": 73.8018 + "spread": 86.1072 }, - "linter": { + "tool_write": { "values": { "off": { - "mean": 383.5, - "effect": -66.4333, - "n": 10 + "mean": 401.5556, + "effect": -59.9686, + "n": 9 }, "on": { - "mean": 455.9727, - "effect": 6.0394, - "n": 110 + "mean": 466.2174, + "effect": 4.6932, + "n": 115 } }, - "spread": 72.4727 + "spread": 64.6618 }, - "tool_write": { + "playwright": { "values": { "off": { - "mean": 401.5556, - "effect": -48.3778, - "n": 9 + "mean": 406.3636, + "effect": -55.1606, + "n": 11 }, "on": { - "mean": 453.8559, - "effect": 3.9225, - "n": 111 + "mean": 466.8938, + "effect": 5.3696, + "n": 113 } }, - "spread": 52.3003 + "spread": 60.5302 }, "human_language": { "values": { "en": { - "mean": 452.4336, - "effect": 2.5003, - "n": 113 + "mean": 464.6325, + "effect": 3.1083, + "n": 117 }, "es": { "mean": 409.5714, - "effect": -40.3619, + "effect": -51.9528, "n": 7 } }, - "spread": 42.8622 + "spread": 55.0611 }, "max_budget": { "values": { "high": { "mean": 414.6667, - "effect": -35.2667, + "effect": -46.8575, "n": 9 }, "low": { - "mean": 452.7928, - "effect": 2.8595, - "n": 111 + "mean": 465.1913, + "effect": 3.6671, + "n": 115 } }, - "spread": 38.1261 + "spread": 50.5246 }, "tool_edit": { "values": { "off": { "mean": 419.0, - "effect": -30.9333, + "effect": -42.5242, "n": 9 }, "on": { - "mean": 452.4414, - "effect": 2.5081, - "n": 111 + "mean": 464.8522, + "effect": 3.328, + "n": 115 } }, - "spread": 33.4414 + "spread": 45.8522 }, "tool_grep": { "values": { "off": { "mean": 433.7778, - "effect": -16.1556, + "effect": -27.7464, "n": 9 }, "on": { - "mean": 451.2432, - "effect": 1.3099, - "n": 111 + "mean": 463.6957, + "effect": 2.1715, + "n": 115 } }, - "spread": 17.4654 + "spread": 29.9179 + }, + "linter": { + "values": { + "off": { + "mean": 436.7273, + "effect": -24.7969, + "n": 11 + }, + "on": { + "mean": 463.9381, + "effect": 2.4139, + "n": 113 + } + }, + "spread": 27.2108 }, "tool_read": { "values": { "off": { - "mean": 459.75, - "effect": 9.8167, - "n": 8 + "mean": 448.6667, + "effect": -12.8575, + "n": 9 }, "on": { - "mean": 449.2321, - "effect": -0.7012, - "n": 112 + "mean": 462.5304, + "effect": 1.0062, + "n": 115 } }, - "spread": 10.5179 + "spread": 13.8637 }, "web_search": { "values": { "off": { "mean": 454.1, - "effect": 4.1667, + "effect": -7.4242, "n": 10 }, "on": { - "mean": 449.5545, - "effect": -0.3788, - "n": 110 + "mean": 462.1754, + "effect": 0.6512, + "n": 114 } }, - "spread": 4.5455 + "spread": 8.0754 } } \ No newline at end of file diff --git a/results/index.jsonl b/results/index.jsonl @@ -118,3 +118,7 @@ {"run_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1","task":"tetris","model":"sonnet","cell_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on","completed_at":"2026-04-05T06:02:26.660332+00:00"} {"run_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2","task":"tetris","model":"sonnet","cell_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on","completed_at":"2026-04-05T06:03:58.503906+00:00"} {"run_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3","task":"tetris","model":"sonnet","cell_id":"tetris_context_file=provided_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on","completed_at":"2026-04-05T05:58:32.199764+00:00"} +{"run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2", "task": "tetris", "model": "sonnet", "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on", "completed_at": "2026-04-05T19:29:03.407545+00:00"} +{"run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3", "task": "tetris", "model": "sonnet", "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", "completed_at": "2026-04-05T19:39:10.870002+00:00"} +{"run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1", "task": "tetris", "model": "sonnet", "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", "completed_at": "2026-04-05T19:38:54.914546+00:00"} +{"run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2", "task": "tetris", "model": "sonnet", "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", "completed_at": "2026-04-05T19:38:55.252420+00:00"} diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_output.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":969070,"duration_api_ms":966371,"num_turns":15,"result":"Everything is in place. Here's a summary of what was built:\n\n---\n\n## Tetris — Browser Game in TypeScript\n\n### File structure\n```\nindex.html ← main page (open this in a browser)\nsrc/tetris.ts ← full game logic in TypeScript\ndist/tetris.js ← compiled output (auto-generated)\ntsconfig.json ← TS config (ES2020, single outFile)\npackage.json ← npm scripts: build / dev / test\n```\n\n### Features implemented\n\n| Feature | Detail |\n|---|---|\n| **7 Tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Super Rotation System with full wall-kick tables for all pieces |\n| **Ghost piece** | Translucent preview of where piece will land |\n| **Lock delay** | 500 ms lock delay with up to 15 move resets (standard Tetris rules) |\n| **Line clearing** | Clears filled rows, drops board above |\n| **Scoring** | 100/300/500/800 × (level+1) for 1/2/3/4 lines; +1 per soft-drop cell; +2 per hard-drop cell |\n| **Levels** | Level increases every 10 lines; 20 speed tiers down to 30 ms/tick |\n| **DAS/ARR** | Proper Delayed Auto Shift (170 ms) + Auto Repeat Rate (50 ms) for smooth movement |\n| **Next piece** | Preview panel shows upcoming piece |\n| **Pause** | `P` or `Escape` |\n| **Restart** | `Enter` / `Space` on game-over screen |\n| **On-screen buttons** | Mobile-friendly click controls |\n\n### Keyboard controls\n| Key | Action |\n|---|---|\n| `← →` / `A D` | Move left / right |\n| `↑` / `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` / `S` | Soft drop (+1 pt/cell) |\n| `Space` | Hard drop (+2 pt/cell) |\n| `P` / `Esc` | Pause / unpause |\n| `Enter` / `Space` | Restart (on game-over) |\n\n### Run\nJust open **`index.html`** directly in any modern browser — no server needed. \nTo rebuild after editing TypeScript: `npm run build`","stop_reason":"end_turn","session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","total_cost_usd":1.3602285,"usage":{"input_tokens":23,"cache_creation_input_tokens":17256,"cache_read_input_tokens":163115,"output_tokens":83101,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":17256},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":23,"outputTokens":83101,"cacheReadInputTokens":163115,"cacheCreationInputTokens":17256,"webSearchRequests":0,"costUSD":1.3602285,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"d3ebfce3-50aa-4fca-886d-a4ca94e16562"} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_stderr.log b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/claude_stderr.log diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/eval_results.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/eval_results.json @@ -0,0 +1,261 @@ +{ + "structural": { + "pass": true, + "checks": [ + { + "name": "entry_point_exists", + "pass": true, + "detail": "index.html found" + }, + { + "name": "package_json_exists", + "pass": true, + "detail": "package.json found" + }, + { + "name": "build_succeeds", + "pass": true, + "detail": "npm run build completed successfully" + }, + { + "name": "typescript_compiles", + "pass": true, + "detail": "tsc --noEmit passed" + } + ], + "score": 1.0 + }, + "functional": { + "pass": false, + "error": "playwright eval not yet wired", + "score": 0 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": true + }, + "performance": { + "bundle_size_bytes": 19141, + "size_under_512kb": true + }, + "score": 0.67 + }, + "code_analysis": { + "files": { + "total": 6, + "code": 3, + "docs": 0, + "unnecessary": 0, + "unnecessary_list": [] + }, + "lines_of_code": 1376, + "dependencies": { + "production": 0, + "dev": 5, + "total": 5 + }, + "complexity": "moderate", + "console_logs": 0, + "magic_numbers": { + "count": 58, + "excessive": true + }, + "function_length": { + "count": 69, + "average": 5.9, + "max": 17, + "long_functions": 0 + }, + "max_nesting_depth": 12, + "global_declarations": 84, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 100.0, + "camel_case": 538, + "snake_case": 0 + }, + "error_handling": { + "try_catch_blocks": 0, + "has_error_handling": false + }, + "comments": { + "comment_lines": 71, + "source_lines": 995, + "ratio_pct": 7.1 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 2, + "files_with_logic": 2, + "files_with_both": 2 + }, + "html_validation": { + "valid": false, + "errors": 8 + }, + "duplication_percentage": 0.0, + "score": 0.85 + }, + "transcript_analysis": { + "total_events": 41, + "tool_calls": { + "total": 14, + "bash": 13, + "write": 0, + "edit": 0, + "read": 1 + }, + "wasted_turns": { + "total": 2, + "docs": 0, + "ascii_art": 2, + "server_starts": 0 + }, + "errors_encountered": 0, + "thinking_blocks": 4, + "text_blocks": 5, + "productivity_ratio": 0.86, + "self_tested": false, + "score": 0.9 + }, + "gameplay_bot": { + "pass": false, + "score": 0.94, + "total": 16, + "passed": 15, + "failed": 1, + "report": { + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 320, + "height": 640 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "auto", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via auto" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "grid state changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": true, + "detail": "rotated: [other] failed: [] (tested 1 piece types in 60 attempts)" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "piece immediately dropped and new piece appeared" + }, + { + "name": "piece_locks", + "pass": true, + "detail": "filled cells persist at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "new piece detected at top of grid" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "game still responding after 10 piece drops" + }, + { + "name": "line_clear", + "pass": true, + "detail": "10 line(s) cleared during AI play" + }, + { + "name": "score_changes", + "pass": false, + "detail": "score did not increase: [0] -> no change after polling" + }, + { + "name": "game_over", + "pass": true, + "detail": "game stopped after stacking to top" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 85 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 15, + "failed": 1, + "score": 0.94 + }, + "gameplay": { + "pieces_placed": 126, + "lines_cleared": 39, + "max_score_observed": 0, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 22 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 2, + "pass": false + } + } + }, + "score": 0.7205 +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/gameplay-bot-report.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/gameplay-bot-report.json @@ -0,0 +1,127 @@ +{ + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 320, + "height": 640 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "auto", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via auto" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "grid state changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": true, + "detail": "rotated: [other] failed: [] (tested 1 piece types in 60 attempts)" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "piece immediately dropped and new piece appeared" + }, + { + "name": "piece_locks", + "pass": true, + "detail": "filled cells persist at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "new piece detected at top of grid" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "game still responding after 10 piece drops" + }, + { + "name": "line_clear", + "pass": true, + "detail": "10 line(s) cleared during AI play" + }, + { + "name": "score_changes", + "pass": false, + "detail": "score did not increase: [0] -> no change after polling" + }, + { + "name": "game_over", + "pass": true, + "detail": "game stopped after stacking to top" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 85 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 15, + "failed": 1, + "score": 0.94 + }, + "gameplay": { + "pieces_placed": 126, + "lines_cleared": 39, + "max_score_observed": 0, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 22 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 2, + "pass": false + } +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/meta.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/meta.json @@ -0,0 +1,30 @@ +{ + "model": "sonnet", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "on", + "linter": "off", + "playwright": "on", + "context_file": "none", + "sub_agents": "on", + "web_search": "on", + "max_budget": "low", + "task": "tetris", + "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3", + "run_number": 3, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-05T19:22:56.142170+00:00", + "wall_time_seconds": 969, + "exit_code": 0, + "completed_at": "2026-04-05T19:39:10.870002+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/transcript.jsonl b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=off_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run3/transcript.jsonl @@ -0,0 +1,41 @@ +{"type": "harness", "subtype": "config", "model": "sonnet", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "Agent", "WebSearch", "WebFetch"], "max_budget_usd": 2.0, "timeout_seconds": 1200, "task": "tetris", "language": "typescript", "prompt_style": "simple"} +{"type": "user", "subtype": "prompt", "message": {"role": "user", "content": "Build a playable Tetris game that runs in a browser. It should have all the standard mechanics: piece rotation, line clearing, scoring, and increasing speed. Use keyboard controls for movement and rotation.\n\n\nUse TypeScript."}} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-294r5yrr","session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"claude-sonnet-4-6","permissionMode":"dontAsk","slash_commands":["update-config","debug","simplify","batch","loop","schedule","claude-api","compact","context","cost","heapdump","init","review","security-review","insights"],"apiKeySource":"apiKeyHelper","claude_code_version":"2.1.92","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan"],"skills":["update-config","debug","simplify","batch","loop","schedule","claude-api"],"plugins":[{"name":"claude-hud","path":"/root/.claude/plugins/marketplaces/claude-hud/","source":"claude-hud@claude-hud"},{"name":"rust-analyzer-lsp","path":"/root/.claude/plugins/marketplaces/claude-plugins-official/plugins/rust-analyzer-lsp","source":"rust-analyzer-lsp@claude-plugins-official"}],"uuid":"7c0bb12c-5819-4439-bb7f-3294efba0b48","fast_mode_state":"off"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01LwyRWGNLraJ86ynTuD3ixy","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants a playable Tetris game in a browser using TypeScript. Let me build a complete Tetris game with all standard mechanics:\n\n1. All 7 Tetris pieces (I, O, T, S, Z, J, L)\n2. Piece rotation\n3. Line clearing\n4. Scoring system\n5. Increasing speed\n6. Keyboard controls (arrow keys for movement, up arrow or W for rotation)\n\nI'll create a clean, self-contained implementation. Let me structure this as:\n- `index.html` - The main HTML file\n- `src/tetris.ts` - The TypeScript source\n\n\n- `tsconfig.json` - TypeScript configuration\n- `package.json` - Project setup with build instructions\n\nI'll provide a complete project structure that can be compiled and run in the browser.\n\nNow I'm designing the game mechanics: a 10x20 grid with the standard seven Tetris pieces, rotation handling, collision detection, and line clearing with progressive difficulty. The scoring follows classic Tetris rules where clearing multiple lines at once gives exponential bonuses, and the game speeds up every 10 lines cleared. For controls, I'm using arrow keys for movement and rotation, space for hard drop, and P to pause.\n\nWriting the TypeScript game logic... Defining the tetromino shapes with their four rotation states, where each piece is represented as a 4x4 grid pattern, and assigning the appropriate color to each tetromino type. Defining all the tetromino rotation states... Defining the remaining Tetris piece configurations... I'm defining the complete Tetris game structure with TypeScript, setting up the project with a minimal HTML file, the main game logic, and configuration files for compilation. The game will include all seven standard Tetrominos with proper colors, ghost piece preview, wall kick rotation, progressive scoring based on lines cleared and level, speed increases tied to level progression, next piece preview, hold functionality, soft and hard drop mechanics, pause capability, and game over detection with a polished visual design.\n\nWriting the HTML and TypeScript implementation... Implementing proper SRS wall kick data...\n\nActually, I'll keep this simpler with just basic wall kick checks in the four cardinal directions—that'll give a solid Tetris feel without the complexity of the full system. Now I'm writing out the complete game implementation with the core Tetromino definitions and game logic.\n\nDefining piece shapes... I need to make sure the O piece has all four rotation states defined identically since it doesn't actually rotate. Now I'm ready to write out the complete Tetris game in one clean TypeScript file with a canvas-based rendering system—I'll set up the main board canvas along with separate preview areas for the next and hold pieces, then define all the core constants like grid dimensions, block size, and color mappings.\n\nWriting the complete game implementation... Writing the Tetris implementation... Defining the rotation states for each Tetris piece... Defining the rotation states for the Z and J tetromino pieces...\n\nNow I'm setting up the scoring system with points for clearing lines, soft drops, and hard drops, then establishing the level progression with increasing speeds.\n\nDefining the game interfaces and utility functions... Setting up the canvas elements... Setting up the game state with initial values for score, level, and lines, then initializing the current piece and input handlers before displaying the start screen. The spawn piece method generates the next tetromino by getting its shape and calculating the starting position.\n\nNow I'm checking if a piece placement is valid by iterating through its shape and verifying that all occupied cells stay within the board boundaries.\n\nImplementing rotation logic with wall kick mechanics... Writing piece locking logic... Writing the line-clearing logic...\n\nNow I'm implementing the hold piece mechanic, which lets the player swap their current piece with a stored one, but only once per turn. If there's no held piece yet, I store the current one and spawn a new piece; otherwise I swap them and position the retrieved piece at the top center of the board.\n\nImplementing ghost piece logic...","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4728,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":4728,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"2cd6e8c9-2c82-43fa-8b27-70195f1d5c73"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GvdJRcePa388tiExnRxmmF","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants a Tetris game built with TypeScript that runs in a browser. I'll create a complete Tetris implementation with:\n\n1. All standard Tetris pieces (I, O, T, S, Z, J, L)\n2. Piece rotation\n3. Line clearing\n4. Scoring system\n5. Increasing speed\n6. Keyboard controls (arrow keys for movement, up arrow or Z/X for rotation)\n\nLet me plan the structure:\n- `index.html` - Main HTML file\n\n\n- `src/tetris.ts` - Main game logic\n- `tsconfig.json` - TypeScript configuration\n\nFor simplicity and to make it runnable in a browser without complex build tooling, I'll structure it so the user can easily compile and run it. I'll create the HTML file, TypeScript source, and configuration needed to get this working.\n\nNow I'm setting up the configuration files and planning out the full Tetris implementation with all the standard features - the seven tetrominoes with proper colors, rotation mechanics with wall kicks, line clearing, scoring based on Tetris standards, a level system that increases speed, piece preview, hold functionality, ghost piece display, and game over detection. The controls will cover movement, rotation in both directions, soft and hard drops, holding pieces, and pause functionality.\n\nWriting the Tetris game logic... Defining the remaining tetromino shapes...\n\nNow I'm setting up the core game structure with type definitions for pieces and planning out the full implementation—I'll use canvas rendering with the Super Rotation System for rotation mechanics, add a ghost piece preview, implement hold and next piece queues, and build out the complete game loop with scoring and level progression.\n\nWriting the game code... Defining the rotation states for the remaining tetromino pieces... I'm switching to a cleaner approach and implementing the full TypeScript file with proper SRS rotation system and wall kick mechanics for all piece types. I need to be careful about the coordinate system here—in standard SRS the y-axis points up in the rotation tables, but canvas rendering has y pointing down. Let me use the standard SRS kick data from the Tetris wiki and flip the y coordinates when rendering.\n\nFor JLSTZ pieces, I'm mapping out all the rotation transitions with their kick offsets. For the I piece, I'm doing the same but with different offset values since it rotates around a different center point.\n\nDefining kick data for all piece rotations... I need to be careful about the coordinate system conversion—the Tetris wiki uses y increasing upward, but my board has y increasing downward, so I'll need to negate the y values when applying the wall kick offsets. Let me trace through the SRS kick data for the standard pieces to make sure I'm implementing this correctly. Defining rotation offsets for the I-piece...\n\nNow I'm understanding how these offsets work—they're adjustments to apply when rotating, with x being horizontal movement and y being vertical. Since canvas coordinates have y increasing downward while the wiki uses the opposite convention, I need to flip the y values when converting them.\n\nSetting up the project structure with TypeScript and a build pipeline to compile everything for the browser.\n\nWriting the complete game implementation... Setting up the color palette for each piece type and the ghost piece, then planning the canvas layout with separate sections for the hold box, main game board, and next queue display on the right side.\n\nDefining piece data structures... Defining the base shapes for each tetromino and planning to compute all rotations dynamically using a standard rotation algorithm rather than hardcoding every orientation. Finishing the rotation logic for non-square matrices, though I realize Tetris pieces need consistent square grids to rotate properly. I'll standardize everything to 3×3 or 4×4 grids depending on the piece, with the O piece being a special case since it doesn't actually rotate.\n\nDefining all rotation states... Defining all rotation states for each piece...\n\nI'm settling on 3×3 grids for most pieces and 4×4 for the I piece, which keeps things consistent. For the O piece, I'll use a 3×3 grid with the square positioned in the upper-left area. Looking at the official Tetris Guideline, I should account for specific spawn columns—most pieces spawn at column 3, while O spawns at column 4.\n\nRather than keep tweaking the positioning, I'll define each piece with its rotation states and spawn offsets upfront. I'm creating a TypeScript interface that holds the rotation data, color, and spawn position for each piece, then I'll populate it with well-tested rotation matrices.\n\nDefining rotation states... Defining the rotation states for the remaining tetromino pieces...\n\nI need to be more careful about how the spawn position maps to the actual board columns. When I place a piece at x=3 with a 3-wide shape, it occupies columns 3, 4, and 5, so I should spawn the O piece at x=4 to center it properly on the 10-wide board.\n\nDefining the rotation states for the I piece...\n\nNow I need to figure out the spawn positions. The I piece should start at x=3 with its top row just above the visible board, while the O piece spawns at x=4, y=0, and other pieces at x=3, y=0. I'm thinking through where exactly pieces should appear so they're positioned correctly relative to the board's top edge. I'm going to simplify this and just implement it—spawn all pieces at y=0, and cells with negative y-coordinates simply won't render, creating the effect of pieces entering from the top. The board is 10×20, and each piece has an (x, y) position that I'll use to determine where it sits. Writing the game code... Defining the rotation states for each Tetris piece... I'm realizing the O piece needs to fit the same grid structure as the other pieces for consistency. Let me standardize everything to 3×3 grids except for the I piece which uses 4×4, and I'll position the O piece centered on the board by spawning it at column 4 so it occupies the middle columns. I'm going to simplify this by using dynamic rotation with square matrices for all pieces—4×4 for I, 2×2 for O, and 3×3 for the rest—then render based on actual matrix dimensions rather than fixed sizes. For spawning, I'll place I at column 3 to fill columns 3-6 and O at column 4 to fill columns 4-5.\n\nDefining the piece structure... I'm verifying the rotation logic works correctly—transposing the matrix and then reversing each row produces a clockwise rotation, which I can confirm with a simple 2x2 example where the corners move in the right direction.\n\nNow I'm precomputing all four rotations...\n\nSetting up the rotation cache...\n\nBuilding the core functions to retrieve piece matrices and validate placements...\n\nImplementing collision detection...\n\nSetting up wall kick data... Defining the kick offset tables...\n\nI'm realizing I need to account for the coordinate system difference—the Tetris wiki uses y increasing upward, but my board has y increasing downward, so I'll need to flip the y values when applying these kicks. I'm double-checking the wiki to make sure I have the right rotation kick tables, and I'm seeing the specific offsets for each rotation transition for the JLSTZ pieces. I'm realizing the wiki might use different coordinate conventions than I initially thought, so let me just go with the standard approach I know works for Tetris rotation kicks. For the JLSTZ pieces, I'm mapping out the wall kick offsets in column and row deltas where positive row means downward movement, covering all four rotation transitions.\n\nDefining the kick sequences for the I piece... Defining the wall kick data...\n\nI'm realizing I need to verify the coordinate system—the Tetris wiki uses y-positive-up convention, but my implementation uses y-positive-down (screen coordinates), so I'll need to negate all the y values when translating from the wiki's rotation system. I'm working through the kick offset data more carefully, comparing my screen coordinate conversions against the wiki values to make sure I'm getting the transformations right. Now I'm working through the I piece rotations with y-coordinates negated from the wiki data, checking each transformation state to verify the rotation mappings are correct. Now I have the wall kick data. Let me structure the game with a state object tracking the board, current and next pieces, hold functionality, score, lines, level, and game status, then build a game loop using requestAnimationFrame that handles drop timing based on level and processes input. I'll also set up the scoring system where line clears multiply by level—single lines worth 100 points, doubles 300, triples 500, and a full Tetris 800.\n\nFor drop speed, I'm using a simpler formula that decreases the interval by 90ms per level, capping at 50ms minimum, so the piece falls faster as difficulty increases. I'm settling on a linear drop interval formula that decreases by 75ms per level, capped at 50ms minimum, which gives reasonable progression from 800ms at level 1 down to faster speeds. Now I need to implement the lock delay mechanic properly—when a piece lands, it should have a 500ms window where the player can still move or rotate it before it permanently locks, which is standard Tetris behavior.\n\nWriting the TypeScript game code... Defining the tetromino shapes and wall kick offsets... Defining rotation kick data for the I and O pieces... Writing rotation and game logic... Initializing the game board and setting up the piece queue system...\n\nNow I'm implementing the bag randomization for piece selection—when the bag runs out, I refill it with a shuffled set of all tetromino types and draw from it. Then I'm handling piece spawning by pulling from the queue, calculating the correct horizontal position based on piece width, and positioning new pieces above the board.\n\nSetting up the spawn logic... Still writing collision detection... Updating the score and level based on cleared lines, then recalculating the drop speed to make the game progressively harder. After that, I'm implementing the ghost piece logic to show where the current piece would land.\n\nNow handling player input for movement and soft drops... Writing rotation logic... Still writing game logic... Now I'm adding getter methods to expose the game state—board, current piece, held piece, next queue, score, lines, level, and various flags like game over and paused status, along with animation timing properties.\n\nMoving on to the renderer class that handles all the canvas drawing. I'm setting up the canvas context and starting the main render method that clears the background and positions the board in the center of the canvas...\n\nContinuing with the render method...\n\nI'm drawing the game board with a dark background and then overlaying a grid pattern by iterating through rows and columns to create the visual cell boundaries. Writing cell rendering... Writing the ghost piece renderer...\n\nNow I'm implementing the line clear animation that fades out completed rows over 300 milliseconds, using the elapsed time to calculate the opacity.\n\nWriting piece preview logic... Writing the left panel UI... Writing the right panel... Writing the overlay rendering... Setting up the game loop and event listeners...\n\nNow I'm configuring the keyboard input system with key repeat timing so that held keys trigger actions at the right intervals, then mapping each key to its corresponding game action like movement, rotation, holding pieces, and pausing. Setting up keyboard event listeners to track key presses and handle repeating movement inputs with proper timing delays and cleanup when keys are released. I'm realizing the current approach is getting messy, so I should refactor the key repeat logic to be cleaner. Setting up the key repeat logic...\n\nNow I'm planning the project structure with an HTML file, TypeScript source, and build configuration using npm and TypeScript. I need to think through the canvas dimensions carefully—the game board will be 10 columns by 20 rows with 30-pixel cells, giving me specific width and height constraints for the layout.\n\nI'm working through the rendering details, particularly how the `Renderer` class accesses module-level constants like `ALL_ROTATIONS` for the piece preview, and I'm considering edge cases like pieces spawning partially above the visible board and how to detect game over when a piece locks in place.\n\nNow I'm realizing there's a potential issue with my `lockPiece` flow—when I set `this.current = null` before spawning the next piece, I need to make sure the game state doesn't try to update while line-clearing animations are happening. The logic checks if lines are pending before allowing updates, so the spawn should happen correctly after the animation completes, but I want to trace through the exact sequence to confirm it's solid.\n\nRestructuring the code... I'm finishing the line-clearing logic by checking if any rows are completely filled, then either triggering the clear animation or spawning the next piece. Now I'm thinking through the scoring system—standard Tetris awards points based on how many lines are cleared at once, with multipliers for higher levels.\n\nI'm also mapping out the progression: leveling up every 10 lines cleared, and adjusting the drop speed accordingly using the official Tetris Guideline frame rates, which get progressively faster as the level increases. I'm settling on a simpler exponential formula for the drop interval that scales smoothly across all levels, then planning out the complete file structure for the final implementation with TypeScript, HTML, and configuration files. I'm settling on 600×660 pixels for the canvas, which should display nicely on a standard laptop screen. I'll add some CSS styling to make the HTML look polished. For the implementation, I'm going to keep everything in a single TypeScript file for simplicity rather than splitting it across multiple files. Before I start writing the actual code, I need to verify my SRS wall kick data against a reliable reference to make sure the rotation system is correct. I'm continuing through the wallkick data for the other rotation transitions, and since my coordinate system has y increasing downward instead of upward, I need to negate all the y values from the wiki reference to match my implementation. Now I'm working through the wall kick offsets for the I piece, which has a different rotation system than the standard Tetris pieces—these are the specific coordinate adjustments needed when rotating between each orientation. I've got the complete wall kick data for all rotation transitions now. Let me implement this into the final code, making sure the Renderer class properly references the rotation constants.\n\nBefore I write everything out, I should verify the spawn positions are correct for a 10-column board—the I piece centers at column 3, the O piece at column 4, and the standard 3×3 pieces at column 3, which all look right.\n\nWriting the complete TypeScript implementation... Looking at the specific spawn configurations, the T piece has its horizontal bar at the top of the board with the stem extending upward into the invisible row, while the I piece's horizontal line sits right at board row 0 when spawned at y=-1. Both follow the standard Tetris spawn pattern where pieces start partially above the visible area. That's expected behavior. Now I'm thinking through the game over condition—a piece should fail to spawn if it would overlap with existing cells on the board. I'm writing a spawn function that checks whether the initial position is valid, and if not, sets the game over flag and clears the current piece.\n\nI'm reconsidering how the collision detection works at y=-1. When a piece spawns one row above the visible board, only the lower rows of the piece matrix actually collide with board cells at y=0 and below. So if the board is already filled at row 0, the spawn check would correctly detect an invalid position and trigger game over. Let me refine the spawn logic to match standard Tetris behavior.\n\nModifying lockPiece to detect game over...\n\nWhen a piece locks with cells above the visible board (y < 0), that triggers game over immediately. I also need to check at spawn time: if the new piece overlaps with existing blocks right away, the game ends too. The cleanest approach is spawning at y = -1 and validating the position, including checking for collisions with any existing pieces on the board. I'm simplifying the spawn logic: pieces appear at y=-1, and if that position overlaps with existing cells on the board, the game ends immediately. The validation function handles cells above the board correctly, so I just need to check if the spawn position is valid.\n\nLet me trace through a game over scenario to verify this works: if the board fills up to row 0 and a T piece spawns at y=-1, the cells at y=0 will collide with occupied spaces, triggering game over. For normal gameplay, pieces spawn at y=-1 and can move down freely if the position is valid.\n\nNow I'm thinking through the DAS (Delayed Auto Shift) implementation—when holding left or right, there should be an immediate move, then a delay before repeating every 50ms. I need to refine this logic and also handle the interaction between soft drop and horizontal movement.\n\nFor soft drop specifically, I'm resetting `lastDropTime` when the player holds down, which means the piece drops at the ARR rate (50ms per row) rather than the slower gravity speed. This is actually correct behavior—soft drop should move faster than normal gravity. The key is making sure that resetting `lastDropTime` prevents gravity from also triggering on the same frame, so the piece doesn't move twice.\n\nNow I'm ready to start writing the actual implementation. I'll structure everything in a single `src/tetris.ts` file and lay out the canvas as a 620 × 680px space with the game board centered at 300 × 600px, flanked by panels for hold/controls on the left and stats/next pieces on the right.\n\nWriting the game code... Configuring TypeScript settings...\n\nI'm settling on a clean setup with ES2020 as the target, using ES2020 modules so I can reference the compiled file directly in HTML with a module script tag. This keeps things straightforward for a browser-based game without needing to bundle or use a module system like AMD. Configuring TypeScript with `\"module\": \"none\"` to skip module wrapping, which lets the compiled output work directly in a browser script tag without any module system overhead. I'm settling on ES2020 modules with a module script tag, which handles deferred execution automatically—so I can access the DOM directly without needing event listeners.\n\nNow I'm ready to start writing the actual implementation, beginning with the core constants and structure for the Tetris game.\n\nWriting TypeScript code... Defining the piece shapes and wall kick data... Defining the kick rotation data... Setting up the rotation precomputation...\n\nNow I'm defining the core game types and the Game class that manages the board state, current piece, hold functionality, and score tracking.\n\nInitializing the game constructor and implementing the piece drawing logic with a Fisher-Yates shuffle for randomizing the tetromino bag... Continuing with the validation logic for piece placement, checking each block in the current rotation against the board boundaries and existing pieces to ensure the move is legal, then moving into the lock function that finalizes a piece's position when it can't move down anymore.\n\nNow I'm placing the piece blocks onto the board, tracking whether any blocks ended up above the visible area which would end the game, then scanning through all rows to identify which ones are completely filled and ready to be cleared. Writing game logic... Writing rotation logic...\n\nNow I'm implementing the hold piece mechanic, which lets players swap their current piece with a previously held one, or store the current piece if they haven't held anything yet.\n\nContinuing with game logic...\n\nNow I'm handling the update cycle—checking if the game is paused or over, then managing the piece's automatic drop based on the timer interval, either moving it down or locking it in place when it can't move further. I'm also initializing the drop timer when the game starts.\n\nSetting up the renderer... Writing the board rendering... Writing cell rendering... Still writing rendering logic... Writing the clear animation and preview logic... Writing the rendering logic... Writing the controls section... Writing the stats panel... Still writing canvas rendering... Writing the input handler... Setting up the game loop...\n\nNow I'm double-checking the piece spawn position and wall kick data to make sure the coordinate system conversion is correct—the piece should start at y = -1 with its main body at board y = 0, and I need to verify the wall kick offsets were properly negated when converting from the wiki's y-up system to my y-down system. Tracing through the rotation mapping to verify each element lands in the right position, checking that the result array dimensions and indexing work out correctly for the 3×3 case. I'm verifying the rotation is correct by checking the visual representation—the T piece rotated clockwise matches what I'd expect. Now I need to handle the game over condition, which occurs when a new piece can't be placed in a valid starting position.\n\nFor line clearing, I'm sorting the full row indices in descending order so I can remove them from the top down without messing up the indices of rows I haven't processed yet. Let me trace through the splice logic to make sure it's working correctly—when I remove a row and then add a new empty one at the top, the indices should stay consistent as long as I'm working from highest to lowest. I see the issue now—when processing full rows in descending order, removing a row shifts all the indices below it, so the next row I'm trying to remove is no longer at its original index. After splicing out row 10, row 5 is still at index 5 in the original board, but the board structure has changed, so I'm actually removing the wrong row.\n\nLet me reconsider this by processing in ascending order instead, starting from the lowest index to avoid index shifting problems.\n\nWhen I splice at index 5 and then prepend an empty row, the indices shift in a specific way: the removed element at index 5 causes everything after it to shift down, then the unshift operation shifts everything up by one. So after both operations, the old rows 6-19 end up at indices 6-19, while rows 0-4 stay in place and the new empty row takes index 0.\n\nThe second full row that was originally at index 10 ends up at index 10 after these operations, which is convenient. But tracking index shifts as I process multiple rows gets complicated. The cleaner approach is to sort the full rows in descending order by index—that way, removing higher-indexed rows won't affect the indices of the rows I still need to process. I'm realizing the descending sort approach has the same flaw—when I splice row 10 and unshift a new row, the indices of all remaining rows shift, so when I try to splice row 5 next, it's no longer at index 5. I need to reconsider the order of operations or track index changes more carefully. Let me trace through a concrete example to verify the logic. Starting with a simple board of 5 rows where rows 1 and 3 are full, I'll process them in ascending order. After removing row 1 and adding an empty row at the top, the board shifts. Now I need to carefully track what happens when I process row 3 next, accounting for how the indices have changed after the first operation. Now I'm tracing through what happens with descending sort when processing row 10 — after splicing it out and unshifting an empty row, the indices shift in a specific way that I need to verify against the original bug scenario.\n\nWhen I then try to process row 5 using its original index, I'm actually hitting the wrong element because the board state has changed. This confirms that descending sort breaks the algorithm.\n\nLet me check ascending sort instead — processing row 5 first, then row 10, to see if the index tracking stays consistent throughout both operations. I've confirmed that ascending sort maintains each full row's original index throughout the splice and unshift operations, since removing a row and adding one to the top cancels out for rows below it. I'm implementing this with an ascending sort that processes rows from top to bottom, then splicing each one out and unshifting a new empty row to the top.\n\nActually, there's a cleaner approach that sidesteps the index shifting problem entirely—I can filter out all the full rows at once and rebuild the board by collecting the non-full rows, then prepending the appropriate number of new empty rows. This is much simpler and avoids the complexity of managing indices during the loop.\n\nNow I'm thinking about the `dropTimer` initialization and when it gets called on the first animation frame. I can simplify this further by initializing `dropTimer` directly in the constructor rather than checking on the first update call, which eliminates the need for the `initTimer` method altogether. I see the issue—using 0 as the initial value causes the piece to drop immediately since `now - 0` will be a huge timestamp. Instead, I'll initialize `dropTimer` to -1 and check for that sentinel value on the first update, setting it to the current time and returning early so the actual drop logic waits for the next frame.\n\nRefining the drop timing logic...\n\nNow I'm thinking through the visual design—I want a polished, modern look with a dark space-themed background, lighter side panels, 3D beveled pieces, subtle grid lines, and a clean monospace font. I'll also add a title and proper HTML structure to tie it all together.\n\nFor the game feel, I'm focusing on responsive movement with DAS and ARR, a satisfying hard drop, brief flash effects on line clears, and a clear game over overlay. The hold and next preview pieces should match the in-game styling but at a smaller scale, around 20-22px per cell.\n\nBuilding the input handler... Writing the key handler logic... I see the issue with mixing `clearTimeout` and `clearInterval` — they need to be kept separate since `setTimeout` and `setInterval` return different timer types. I'm restructuring this to use dedicated maps for each timer type, so DAS timers go in one map and ARR intervals go in another. Then I'm setting up the event listeners and defining the key handler logic...\n\nRefactoring the timer management... Cleaning up the event handlers and preparing to write out the complete implementation files.\n\nWriting HTML and CSS...\n\nNow I'm thinking through the TypeScript setup—since I'm using `type=\"module\"` in the HTML, I need to make sure the compiled code works as an ES module, even though I'm not explicitly using import/export statements. I need to explicitly set `\"module\": \"ES2020\"` to ensure TypeScript outputs ES module syntax rather than defaulting to CommonJS, which would break in the browser. I'm realizing that TypeScript actually does add the `\"use strict\"` and exports boilerplate even for files without imports or exports when using CommonJS mode, which would break in the browser. So I need to either use ES modules with `\"module\": \"ES2020\"` and add a dummy export statement, or find a way to output clean JavaScript that works in the browser without module wrapping. Finalizing the TypeScript config...\n\nSince `\"module\": \"none\"` disables imports and exports entirely, I can't use any module syntax—but that's actually perfect for a single-file browser game where everything lives in one script tag anyway. I'm overthinking the global scope issue—for a small game like this, it's fine to let the classes exist at the top level without wrapping them in an IIFE. My final setup will be straightforward: TypeScript compiling with `\"module\": \"none\"` to a single JavaScript file, loaded via a script tag in the HTML, with no import/export statements needed.\n\nNow I'm laying out the complete Tetris implementation, organizing it into logical sections: constants, piece definitions, wall kick data, utility functions, and the main game, renderer, and input handler classes.\n\nWriting the Tetris implementation... Defining game constants and piece shapes... Defining wall-kick offset tables for the standard rotation system, mapping each rotation transition to a series of position adjustments to try when a piece can't rotate in place. Defining rotation kick data... Finishing the rotation function and then precomputing all four rotations for each piece type into a lookup table. After that, I'm defining the core types for the game—a Cell can be a string or null, a Board is a 2D array of cells, and a Piece tracks its type, rotation state, and position on the board.\n\nNow I'm setting up the Game class with all the state it needs: the board itself, the current falling piece, the held piece, a 7-bag system for randomization, a queue of upcoming pieces, score and level tracking, flags for game over and pause states, and a drop timer to control piece gravity. Writing game logic... Continuing with the lock method...\n\nNow I'm placing the piece onto the board by iterating through its shape matrix, marking cells with the piece's color while checking if any blocks extend above the top. Then I'm clearing the piece reference and checking for game over conditions, followed by scanning for any completely filled rows to mark for clearing.\n\nIf there are full rows, I'm scheduling them for removal after a delay and updating the score and level based on how many lines were cleared, otherwise spawning the next piece. Writing the movement and drop logic... Completing the rotation logic and implementing the hold piece mechanic...\n\nNow I'm setting up the restart function to reset all game state—clearing the board, resetting the score and level, and pre-populating the piece queue before spawning the first piece. Then I'm starting the update loop that runs each frame to handle game logic.\n\nWriting the renderer class... Writing the board grid... Finishing the cell rendering method with highlight and shadow effects...\n\nNow I'm moving on to draw the active piece by iterating through its rotation matrix and rendering each block that's part of the piece, skipping any that are out of bounds. Still writing the rendering logic... Still writing preview logic... Writing the controls panel... Writing the right panel layout... Writing the UI rendering functions... Writing the input handler... Writing the input handler...\n\nNow I'm setting up the main game loop—initializing the canvas, creating the game and renderer instances, then using requestAnimationFrame to continuously update and render the game state. I should double-check the wall kick data for the SRS rotation system to make sure the offsets are accurate.\n\nVerifying the kick offsets for JLSTZ and I pieces by converting from the Tetris wiki coordinates (where y increases upward) to screen coordinates (where y increases downward). The JLSTZ 0→1 rotation looks correct, and I'm checking the I piece offsets now to confirm they match the expected values.\n\nNow I'm testing the rotation function itself with the I piece to make sure the matrix transformation is working properly—rotating a horizontal line of four blocks clockwise should produce a vertical line. I'm verifying that my rotation logic produces the correct state 2 by applying another clockwise rotation to state 1, which should give me the horizontal I piece. So when I apply the rotation formula out[c][R-1-r] = m[r][c] to each element in column 2, I get the entire second row of the output filled with 1s, while everything else stays 0.\n\nNow I'm verifying this matches the standard SRS I state 2, which shows a horizontal line of blocks across the middle row—that checks out. Moving to state 3, I'm rotating again and this time the 1s from row 2 map into column 1, creating a vertical line down the second column from the top.\n\nNow I'm checking the T piece rotations. Starting with state 0, I have the T-shape with the stem pointing up. After one clockwise rotation, I'm applying the rotation formula to map each cell to its new position, and I can see the pattern emerging as the T rotates to point right. Continuing through the transformation, I'm mapping each cell from the input state to its rotated position, and the result shows a horizontal line across the middle with an additional cell below—this matches the standard T-tetromino in its second rotation state. I'm finishing the O piece verification—it stays as a 2x2 square in all rotations, which is correct. Now I'm checking that all the piece rotations are working properly across the board.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":0,"cache_read_input_tokens":4728,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"dfc6cfe7-6b39-4de7-9f3c-c67f790268ab"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01ACdj1x7pi89w5SZs2jCvXn","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Let me start building a Tetris game in TypeScript. I'll create the necessary files for a browser-based Tetris game.\n\nLet me plan the structure:\n1. `index.html` - Main HTML file\n2. `src/tetris.ts` - Main TypeScript game logic\n3. `tsconfig.json` - TypeScript configuration\n4. `package.json` - Package configuration\n\nLet me first check what's in the current directory.","signature":"EqsEClsIDBgCKkDBaYyGNbwqw3fSRgHLVrZpIgO0PnLCK4JN7Q8F+Evc4OV0lC21eB8+qIh0M9JhZVaDlLiwMTJNLR5OIIHs28pfMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgyS/pbaNj8A38x2N6saDOU7QxOmOFM4g47eQCIw7u9BXiFFbtBsF8AkHtw1h6lkbamMF64MnEn7OvWMNjG0nASBTy9Kr6VpLS0+kxeaKv0CrAwRN4ptIsPKUNgfGLkxn88ntEU20/Fgfvzd3s2P9I3LRFIT7sWkKDyEd7yAk9k66hGwLROGNdaxv6/M+6mz720m4nCAPL8ECn7D93b5l2g5cW3me9NI2CMsVJdyw/KwxxpvsUYzEHe0CVstdF+xGb/sUlB+FRXHVUlxVr14biyKaZt7mY1paFIWC5t5yW7LIJpiv0n3obFcKFQLVTAcouBpVYvA103HHpwfTiRChm5FxsdmsqvelMKBN149arq8CrOI0LbuPgann7K9eQGD4NqQecpnhPG7euB6vBrug19N8XycKocnYqBiBYvFbAkH1RUASD3gS+C4oAjkAVg8ddeEmqlX+ybvQvYcOb5KQJ+74Eiq/5Rceskhx3uidVif8kXOEtBGdLy7ND3rtnT86q/1dz5lueEeodPfgzPDhb+w46SwCOH9XL/o21V5m3B1YDm5aA9H9GlKtc7WWf1M3gmEZgCL01P4Q9NL7A01CWM4vtRJ/KttMVgoD4DXGAE="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":528,"cache_read_input_tokens":4241,"cache_creation":{"ephemeral_5m_input_tokens":528,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"a74ac2e4-eb9d-4b6e-8e0e-07403cd0a7ba"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01ACdj1x7pi89w5SZs2jCvXn","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01S4qs5gHYRjUdWDmfSoyYYn","name":"Bash","input":{"command":"ls /tmp/loop-bench-294r5yrr","description":"List current directory contents"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":528,"cache_read_input_tokens":4241,"cache_creation":{"ephemeral_5m_input_tokens":528,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"be8d0dc2-df4a-4a36-8dec-2361fab7ba83"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01S4qs5gHYRjUdWDmfSoyYYn","type":"tool_result","content":"node_modules\npackage.json\npackage-lock.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"1829f58a-b9f5-472c-80bf-ce550e1ac86c","timestamp":"2026-04-05T19:36:54.504Z","tool_use_result":{"stdout":"node_modules\npackage.json\npackage-lock.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Q15mJ3nB3EtDKX22VZoWhd","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01UkKwity3KKskVtukTxK4Nd","name":"Read","input":{"file_path":"/tmp/loop-bench-294r5yrr/package.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":228,"cache_read_input_tokens":4769,"cache_creation":{"ephemeral_5m_input_tokens":228,"ephemeral_1h_input_tokens":0},"output_tokens":60,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"d5248cb6-afda-4c61-8399-a4f062b043c8"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01UkKwity3KKskVtukTxK4Nd","type":"tool_result","content":"1\t{\n2\t \"name\": \"loop-bench-294r5yrr\",\n3\t \"version\": \"1.0.0\",\n4\t \"description\": \"\",\n5\t \"main\": \"index.js\",\n6\t \"scripts\": {\n7\t \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n8\t },\n9\t \"keywords\": [],\n10\t \"author\": \"\",\n11\t \"license\": \"ISC\",\n12\t \"type\": \"commonjs\",\n13\t \"devDependencies\": {\n14\t \"@playwright/test\": \"^1.59.1\",\n15\t \"@types/node\": \"^25.5.2\",\n16\t \"typescript\": \"^6.0.2\"\n17\t }\n18\t}\n19\t"}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"7f0cfe83-45ab-4ca1-98c8-299b8be174c2","timestamp":"2026-04-05T19:36:56.119Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-294r5yrr/package.json","content":"{\n \"name\": \"loop-bench-294r5yrr\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@playwright/test\": \"^1.59.1\",\n \"@types/node\": \"^25.5.2\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","numLines":19,"startLine":1,"totalLines":19}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NKGwJ7CFcgXrCghvgcNpd6","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"I'll build a Tetris game in TypeScript. The game will be self-contained in an HTML file with embedded TypeScript compiled to JavaScript. Since we have TypeScript available, I'll create:\n\n1. `src/tetris.ts` - The game logic in TypeScript\n2. `index.html` - HTML file\n3. `tsconfig.json` - TypeScript config\n4. A build script\n\nLet me create the complete Tetris game.","signature":"EqgEClsIDBgCKkBOBV8nKG2h7oAvBbjF/Rdt2CK4lyuSJ1HJXVWR6sgXTbYPDkPdu1OTC+PLjcZrj2O0c7h6igP1sq7FYryMnDAsMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgx+3snA17L+r3y7/QUaDOKRUZ9o0HVgoSl38CIwP7/qBVDuy665QpdkZOvjmjBKnt8ms7p+Op6fI2i8ULsLntd/nc8hTVU4OuQn61vdKvoC/lAu0nA00saxo3AnO7/yyCJjKdVw4G6SegXwaUtYTMfhqQxq+QCzpEtAZuWts2uSJWvbk5lBxm+bqOjlro0mb2gwsYqp2UzQEhIO4Uo7H/U/8IQS0kubHaFsSW+e1dziJDKftUw0eg0SaBde4qD9+M1mXdBIuaouXmTEAdSnx3n6Qqr9Ib1r5k5zGumuDKDSWNpU30pPK5aKLvD+H5FfZdBSnnzPD9M6Sp6p8XC0fwROaGgvl/R+nhKouf1ZY5f7W1pSImyz2Yym60Y1AayL1Kd3Hd8hkuJJrFviXysj8hFtpcZGn3/K/2QEmJjUbmHP9AhRBcW7XAecGS6rXleX14+2YTDoXFd6HyCCMbRj+YoP+yY8ZRiwmjMdqz2A1Q+rqra/7uE0Un26R5uuGeYvCZlfP/cAJQbIWPq2TZCZKi5ds6pvjzCebPsQAFR3IBlscSV+PXI1c/O0GDB20jCFmZAsGn0FE66Ow/DXG43nP9UAZYvS+fzEdCssGAE="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":509,"cache_read_input_tokens":4769,"cache_creation":{"ephemeral_5m_input_tokens":509,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"0e15ccd9-61fc-4207-829a-e0bd570a209f"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NKGwJ7CFcgXrCghvgcNpd6","type":"message","role":"assistant","content":[{"type":"text","text":"Now I'll create the Tetris game. Let me build all the files:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":509,"cache_read_input_tokens":4769,"cache_creation":{"ephemeral_5m_input_tokens":509,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"06a1b180-6f78-468a-affc-26b2e2b778ec"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NKGwJ7CFcgXrCghvgcNpd6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Ng14XZv182ebDeB9ohMGyr","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-294r5yrr/src","description":"Create src directory"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":509,"cache_read_input_tokens":4769,"cache_creation":{"ephemeral_5m_input_tokens":509,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"00216172-49e5-4c15-8721-7c333f2b785e"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Ng14XZv182ebDeB9ohMGyr","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"1eb57945-e78b-4de6-9766-08afb76fdd1d","timestamp":"2026-04-05T19:36:59.839Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":true}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01JUmEy6irf9PNGJ3jbpaGnn","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01KkDERxBCcNhWKEiKBc9Qse","name":"Bash","input":{"command":"cat > /tmp/loop-bench-294r5yrr/tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"None\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"strict\": true,\n \"outFile\": \"dist/tetris.js\",\n \"removeComments\": false,\n \"sourceMap\": false\n },\n \"include\": [\"src/**/*.ts\"]\n}\nEOF","description":"Create TypeScript config"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":240,"cache_read_input_tokens":5278,"cache_creation":{"ephemeral_5m_input_tokens":240,"ephemeral_1h_input_tokens":0},"output_tokens":58,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"6550c227-f063-40ab-86ec-88d31ae6a1b9"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01KkDERxBCcNhWKEiKBc9Qse","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"527ffb08-7496-4f83-931c-7a5a9b04de4a","timestamp":"2026-04-05T19:37:02.729Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01UjqQSnRLzTkX2w6WettxG8","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XJaPJ5dmyhnnSTzQZTY6FW","name":"Bash","input":{"command":"cat > /tmp/loop-bench-294r5yrr/src/tetris.ts << 'TSEOF'\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px\nconst PREVIEW_BLOCK = 24; // px\n\nconst COLORS: Record<string, string> = {\n I: \"#00f0f0\",\n O: \"#f0f000\",\n T: \"#a000f0\",\n S: \"#00f000\",\n Z: \"#f00000\",\n J: \"#0000f0\",\n L: \"#f0a000\",\n};\n\nconst GHOST_ALPHA = 0.25;\n\n// Each piece defined as a set of rotation states (array of [row, col] offsets)\nconst PIECES: Record<string, number[][][]> = {\n I: [\n [[0,0],[0,1],[0,2],[0,3]],\n [[0,2],[1,2],[2,2],[3,2]],\n [[2,0],[2,1],[2,2],[2,3]],\n [[0,1],[1,1],[2,1],[3,1]],\n ],\n O: [\n [[0,1],[0,2],[1,1],[1,2]],\n [[0,1],[0,2],[1,1],[1,2]],\n [[0,1],[0,2],[1,1],[1,2]],\n [[0,1],[0,2],[1,1],[1,2]],\n ],\n T: [\n [[0,1],[1,0],[1,1],[1,2]],\n [[0,1],[1,1],[1,2],[2,1]],\n [[1,0],[1,1],[1,2],[2,1]],\n [[0,1],[1,0],[1,1],[2,1]],\n ],\n S: [\n [[0,1],[0,2],[1,0],[1,1]],\n [[0,1],[1,1],[1,2],[2,2]],\n [[1,1],[1,2],[2,0],[2,1]],\n [[0,0],[1,0],[1,1],[2,1]],\n ],\n Z: [\n [[0,0],[0,1],[1,1],[1,2]],\n [[0,2],[1,1],[1,2],[2,1]],\n [[1,0],[1,1],[2,1],[2,2]],\n [[0,1],[1,0],[1,1],[2,0]],\n ],\n J: [\n [[0,0],[1,0],[1,1],[1,2]],\n [[0,1],[0,2],[1,1],[2,1]],\n [[1,0],[1,1],[1,2],[2,2]],\n [[0,1],[1,1],[2,0],[2,1]],\n ],\n L: [\n [[0,2],[1,0],[1,1],[1,2]],\n [[0,1],[1,1],[2,1],[2,2]],\n [[1,0],[1,1],[1,2],[2,0]],\n [[0,0],[0,1],[1,1],[2,1]],\n ],\n};\n\nconst PIECE_TYPES = Object.keys(PIECES);\n\n// Wall kick data (SRS) for J, L, S, T, Z\nconst KICKS_JLSTZ: Record<string, [number, number][]> = {\n \"0->1\": [[ 0,0],[-1,0],[-1, 1],[0,-2],[-1,-2]],\n \"1->0\": [[ 0,0],[ 1,0],[ 1,-1],[0, 2],[ 1, 2]],\n \"1->2\": [[ 0,0],[ 1,0],[ 1,-1],[0, 2],[ 1, 2]],\n \"2->1\": [[ 0,0],[-1,0],[-1, 1],[0,-2],[-1,-2]],\n \"2->3\": [[ 0,0],[ 1,0],[ 1, 1],[0,-2],[ 1,-2]],\n \"3->2\": [[ 0,0],[-1,0],[-1,-1],[0, 2],[-1, 2]],\n \"3->0\": [[ 0,0],[-1,0],[-1,-1],[0, 2],[-1, 2]],\n \"0->3\": [[ 0,0],[ 1,0],[ 1, 1],[0,-2],[ 1,-2]],\n};\n\n// Wall kick data (SRS) for I\nconst KICKS_I: Record<string, [number, number][]> = {\n \"0->1\": [[ 0,0],[-2,0],[ 1,0],[-2,-1],[ 1, 2]],\n \"1->0\": [[ 0,0],[ 2,0],[-1,0],[ 2, 1],[-1,-2]],\n \"1->2\": [[ 0,0],[-1,0],[ 2,0],[-1, 2],[ 2,-1]],\n \"2->1\": [[ 0,0],[ 1,0],[-2,0],[ 1,-2],[-2, 1]],\n \"2->3\": [[ 0,0],[ 2,0],[-1,0],[ 2, 1],[-1,-2]],\n \"3->2\": [[ 0,0],[-2,0],[ 1,0],[-2,-1],[ 1, 2]],\n \"3->0\": [[ 0,0],[ 1,0],[-2,0],[ 1,-2],[-2, 1]],\n \"0->3\": [[ 0,0],[-1,0],[ 2,0],[-1, 2],[ 2,-1]],\n};\n\n// Scoring per lines cleared\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n// Speed levels (ms per drop tick)\nconst LEVEL_SPEEDS = [800, 720, 630, 550, 470, 380, 300, 215, 130, 100, 80, 80, 80, 70, 70, 70, 50, 50, 50, 30];\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ntype Cell = string | null; // null = empty, string = color\ntype Board = Cell[][];\n\ninterface Piece {\n type: string;\n rot: number; // 0-3\n row: number;\n col: number;\n}\n\n// ─── Game State ───────────────────────────────────────────────────────────────\n\nlet board: Board = [];\nlet current: Piece | null = null;\nlet next: Piece | null = null;\nlet score = 0;\nlet lines = 0;\nlet level = 0;\nlet gameOver = false;\nlet paused = false;\nlet dropTimer = 0;\nlet lastTime = 0;\nlet animFrameId = 0;\nlet lockDelay = 0;\nlet lockDelayMax = 500; // ms\nlet onGround = false;\nlet lockMoves = 0;\nlet lockMovesMax = 15;\n\n// ─── Canvas Setup ─────────────────────────────────────────────────────────────\n\nconst canvas = document.getElementById(\"board\") as HTMLCanvasElement;\nconst ctx = canvas.getContext(\"2d\")!;\ncanvas.width = COLS * BLOCK;\ncanvas.height = ROWS * BLOCK;\n\nconst previewCanvas = document.getElementById(\"preview\") as HTMLCanvasElement;\nconst previewCtx = previewCanvas.getContext(\"2d\")!;\npreviewCanvas.width = 6 * PREVIEW_BLOCK;\npreviewCanvas.height = 4 * PREVIEW_BLOCK;\n\nconst scoreEl = document.getElementById(\"score\")!;\nconst linesEl = document.getElementById(\"lines\")!;\nconst levelEl = document.getElementById(\"level\")!;\nconst msgEl = document.getElementById(\"message\")!;\n\n// ─── Board Helpers ────────────────────────────────────────────────────────────\n\nfunction createBoard(): Board {\n return Array.from({ length: ROWS }, () => Array(COLS).fill(null));\n}\n\nfunction getBlocks(piece: Piece): [number, number][] {\n return PIECES[piece.type][piece.rot].map(([r, c]) => [piece.row + r, piece.col + c]);\n}\n\nfunction isValid(piece: Piece): boolean {\n for (const [r, c] of getBlocks(piece)) {\n if (r < 0 || r >= ROWS || c < 0 || c >= COLS) return false;\n if (r >= 0 && board[r][c] !== null) return false;\n }\n return true;\n}\n\nfunction placePiece(piece: Piece): void {\n const color = COLORS[piece.type];\n for (const [r, c] of getBlocks(piece)) {\n if (r >= 0) board[r][c] = color;\n }\n}\n\nfunction clearLines(): number {\n let cleared = 0;\n for (let r = ROWS - 1; r >= 0; r--) {\n if (board[r].every(cell => cell !== null)) {\n board.splice(r, 1);\n board.unshift(Array(COLS).fill(null));\n cleared++;\n r++; // recheck same row index\n }\n }\n return cleared;\n}\n\n// ─── Piece Factory ────────────────────────────────────────────────────────────\n\nfunction randomPiece(): Piece {\n const type = PIECE_TYPES[Math.floor(Math.random() * PIECE_TYPES.length)];\n return { type, rot: 0, row: 0, col: 3 };\n}\n\nfunction spawnPiece(): boolean {\n current = next ?? randomPiece();\n next = randomPiece();\n // Center spawn\n current.col = Math.floor((COLS - 4) / 2);\n current.row = 0;\n\n // Try spawning; if invalid try row -1\n if (!isValid(current)) {\n current.row = -1;\n if (!isValid(current)) return false;\n }\n lockDelay = 0;\n lockMoves = 0;\n onGround = false;\n return true;\n}\n\n// ─── Rotation with SRS kicks ──────────────────────────────────────────────────\n\nfunction tryRotate(dir: 1 | -1): boolean {\n if (!current) return false;\n const newRot = ((current.rot + dir) + 4) % 4 as 0 | 1 | 2 | 3;\n const key = `${current.rot}->${newRot}`;\n const kicks = current.type === \"I\" ? KICKS_I : (current.type === \"O\" ? null : KICKS_JLSTZ);\n\n const testPiece: Piece = { ...current, rot: newRot };\n\n if (kicks) {\n for (const [kr, kc] of kicks[key] ?? [[0,0]]) {\n testPiece.row = current.row + kr;\n testPiece.col = current.col + kc;\n if (isValid(testPiece)) {\n current = { ...testPiece };\n resetLockOnMove();\n return true;\n }\n }\n } else {\n // O piece — no kick needed\n testPiece.row = current.row;\n testPiece.col = current.col;\n if (isValid(testPiece)) {\n current = { ...testPiece };\n return true;\n }\n }\n return false;\n}\n\nfunction resetLockOnMove(): void {\n if (onGround && lockMoves < lockMovesMax) {\n lockDelay = 0;\n lockMoves++;\n }\n}\n\n// ─── Movement ─────────────────────────────────────────────────────────────────\n\nfunction moveLeft(): void {\n if (!current || gameOver || paused) return;\n const moved: Piece = { ...current, col: current.col - 1 };\n if (isValid(moved)) { current = moved; resetLockOnMove(); }\n}\n\nfunction moveRight(): void {\n if (!current || gameOver || paused) return;\n const moved: Piece = { ...current, col: current.col + 1 };\n if (isValid(moved)) { current = moved; resetLockOnMove(); }\n}\n\nfunction softDrop(): void {\n if (!current || gameOver || paused) return;\n const moved: Piece = { ...current, row: current.row + 1 };\n if (isValid(moved)) {\n current = moved;\n dropTimer = 0;\n score += 1;\n updateUI();\n }\n}\n\nfunction hardDrop(): void {\n if (!current || gameOver || paused) return;\n let dropped = 0;\n while (true) {\n const moved: Piece = { ...current, row: current.row + 1 };\n if (!isValid(moved)) break;\n current = moved;\n dropped++;\n }\n score += dropped * 2;\n lockPiece();\n}\n\nfunction ghostRow(): number {\n if (!current) return 0;\n let ghost = { ...current };\n while (true) {\n const next: Piece = { ...ghost, row: ghost.row + 1 };\n if (!isValid(next)) break;\n ghost = next;\n }\n return ghost.row;\n}\n\n// ─── Piece Locking ────────────────────────────────────────────────────────────\n\nfunction lockPiece(): void {\n if (!current) return;\n placePiece(current);\n const cleared = clearLines();\n if (cleared > 0) {\n score += LINE_SCORES[cleared] * (level + 1);\n lines += cleared;\n level = Math.min(Math.floor(lines / 10), LEVEL_SPEEDS.length - 1);\n updateUI();\n }\n if (!spawnPiece()) {\n gameOver = true;\n msgEl.textContent = \"GAME OVER\";\n msgEl.style.display = \"block\";\n }\n}\n\n// ─── Update / Game Loop ───────────────────────────────────────────────────────\n\nfunction update(timestamp: number): void {\n const dt = timestamp - lastTime;\n lastTime = timestamp;\n\n if (!gameOver && !paused && current) {\n const speed = LEVEL_SPEEDS[Math.min(level, LEVEL_SPEEDS.length - 1)];\n\n // Check if on ground\n const below: Piece = { ...current, row: current.row + 1 };\n const nowOnGround = !isValid(below);\n\n if (nowOnGround) {\n if (!onGround) {\n onGround = true;\n lockDelay = 0;\n }\n lockDelay += dt;\n if (lockDelay >= lockDelayMax) {\n lockPiece();\n }\n } else {\n onGround = false;\n lockDelay = 0;\n dropTimer += dt;\n if (dropTimer >= speed) {\n dropTimer = 0;\n current = { ...current, row: current.row + 1 };\n }\n }\n }\n\n draw();\n animFrameId = requestAnimationFrame(update);\n}\n\n// ─── Drawing ──────────────────────────────────────────────────────────────────\n\nfunction drawBlock(\n context: CanvasRenderingContext2D,\n r: number, c: number,\n color: string,\n size: number,\n alpha = 1\n): void {\n context.globalAlpha = alpha;\n context.fillStyle = color;\n context.fillRect(c * size + 1, r * size + 1, size - 2, size - 2);\n\n // Highlight\n context.fillStyle = \"rgba(255,255,255,0.3)\";\n context.fillRect(c * size + 1, r * size + 1, size - 2, 4);\n context.fillRect(c * size + 1, r * size + 1, 4, size - 2);\n\n // Shadow\n context.fillStyle = \"rgba(0,0,0,0.3)\";\n context.fillRect(c * size + 1, r * size + size - 5, size - 2, 4);\n context.fillRect(c * size + size - 5, r * size + 1, 4, size - 2);\n\n context.globalAlpha = 1;\n}\n\nfunction draw(): void {\n // Board background\n ctx.fillStyle = \"#111\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.05)\";\n ctx.lineWidth = 1;\n for (let r = 0; r < ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n ctx.strokeRect(c * BLOCK, r * BLOCK, BLOCK, BLOCK);\n }\n }\n\n // Placed blocks\n for (let r = 0; r < ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n if (board[r][c]) {\n drawBlock(ctx, r, c, board[r][c]!, BLOCK);\n }\n }\n }\n\n // Ghost piece\n if (current && !gameOver) {\n const gr = ghostRow();\n if (gr !== current.row) {\n const ghostBlocks = PIECES[current.type][current.rot];\n const color = COLORS[current.type];\n for (const [br, bc] of ghostBlocks) {\n drawBlock(ctx, gr + br, current.col + bc, color, BLOCK, GHOST_ALPHA);\n }\n }\n }\n\n // Current piece\n if (current && !gameOver) {\n const color = COLORS[current.type];\n for (const [r, c] of getBlocks(current)) {\n if (r >= 0) drawBlock(ctx, r, c, color, BLOCK);\n }\n }\n\n // Paused overlay\n if (paused && !gameOver) {\n ctx.fillStyle = \"rgba(0,0,0,0.6)\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = \"#fff\";\n ctx.font = \"bold 28px 'Courier New', monospace\";\n ctx.textAlign = \"center\";\n ctx.fillText(\"PAUSED\", canvas.width / 2, canvas.height / 2);\n }\n\n drawPreview();\n}\n\nfunction drawPreview(): void {\n previewCtx.fillStyle = \"#111\";\n previewCtx.fillRect(0, 0, previewCanvas.width, previewCanvas.height);\n\n if (!next) return;\n const color = COLORS[next.type];\n const blocks = PIECES[next.type][0];\n\n // Find bounding box\n const minR = Math.min(...blocks.map(([r]) => r));\n const maxR = Math.max(...blocks.map(([r]) => r));\n const minC = Math.min(...blocks.map(([, c]) => c));\n const maxC = Math.max(...blocks.map(([, c]) => c));\n const pieceH = maxR - minR + 1;\n const pieceW = maxC - minC + 1;\n const offsetR = Math.floor((4 - pieceH) / 2) - minR;\n const offsetC = Math.floor((6 - pieceW) / 2) - minC;\n\n for (const [br, bc] of blocks) {\n drawBlock(previewCtx, br + offsetR, bc + offsetC, color, PREVIEW_BLOCK);\n }\n}\n\n// ─── UI Helpers ───────────────────────────────────────────────────────────────\n\nfunction updateUI(): void {\n scoreEl.textContent = score.toString();\n linesEl.textContent = lines.toString();\n levelEl.textContent = level.toString();\n}\n\n// ─── Input Handling ───────────────────────────────────────────────────────────\n\nconst keys: Record<string, boolean> = {};\nlet dasTimer = 0;\nlet arrTimer = 0;\nconst DAS = 170; // Delayed Auto Shift ms\nconst ARR = 50; // Auto Repeat Rate ms\n\ndocument.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (gameOver) {\n if (e.code === \"Enter\" || e.code === \"Space\") {\n restartGame();\n }\n return;\n }\n\n if (e.code === \"KeyP\" || e.code === \"Escape\") {\n paused = !paused;\n msgEl.textContent = paused ? \"PAUSED\" : \"\";\n msgEl.style.display = paused ? \"block\" : \"none\";\n return;\n }\n\n if (paused) return;\n\n switch (e.code) {\n case \"ArrowLeft\":\n case \"KeyA\":\n if (!keys[e.code]) { moveLeft(); dasTimer = 0; }\n keys[e.code] = true;\n break;\n case \"ArrowRight\":\n case \"KeyD\":\n if (!keys[e.code]) { moveRight(); dasTimer = 0; }\n keys[e.code] = true;\n break;\n case \"ArrowDown\":\n case \"KeyS\":\n softDrop();\n keys[e.code] = true;\n break;\n case \"ArrowUp\":\n case \"KeyW\":\n tryRotate(1);\n e.preventDefault();\n break;\n case \"KeyZ\":\n tryRotate(-1);\n break;\n case \"KeyX\":\n tryRotate(1);\n break;\n case \"Space\":\n hardDrop();\n e.preventDefault();\n break;\n case \"KeyC\":\n // hold piece could be added; for now just prevent default\n break;\n }\n});\n\ndocument.addEventListener(\"keyup\", (e: KeyboardEvent) => {\n keys[e.code] = false;\n if (e.code === \"ArrowLeft\" || e.code === \"KeyA\" || e.code === \"ArrowRight\" || e.code === \"KeyD\") {\n dasTimer = 0;\n arrTimer = 0;\n }\n});\n\n// DAS/ARR loop - run in the main update loop via separate interval\nlet dasLastTime = 0;\nfunction dasLoop(timestamp: number): void {\n const dt = timestamp - dasLastTime;\n dasLastTime = timestamp;\n\n if (!paused && !gameOver) {\n const leftHeld = keys[\"ArrowLeft\"] || keys[\"KeyA\"];\n const rightHeld = keys[\"ArrowRight\"] || keys[\"KeyD\"];\n const downHeld = keys[\"ArrowDown\"] || keys[\"KeyS\"];\n\n if (leftHeld || rightHeld) {\n dasTimer += dt;\n if (dasTimer >= DAS) {\n arrTimer += dt;\n if (arrTimer >= ARR) {\n arrTimer = 0;\n if (leftHeld) moveLeft();\n if (rightHeld) moveRight();\n }\n }\n }\n\n if (downHeld) {\n softDrop();\n }\n }\n\n requestAnimationFrame(dasLoop);\n}\n\n// ─── Game Init / Restart ──────────────────────────────────────────────────────\n\nfunction startGame(): void {\n board = createBoard();\n score = 0;\n lines = 0;\n level = 0;\n gameOver = false;\n paused = false;\n dropTimer = 0;\n lockDelay = 0;\n lockMoves = 0;\n onGround = false;\n next = randomPiece();\n spawnPiece();\n updateUI();\n msgEl.style.display = \"none\";\n}\n\nfunction restartGame(): void {\n cancelAnimationFrame(animFrameId);\n startGame();\n lastTime = performance.now();\n animFrameId = requestAnimationFrame(update);\n}\n\n// ─── Button Controls ──────────────────────────────────────────────────────────\n\ndocument.getElementById(\"btn-left\")?.addEventListener(\"click\", moveLeft);\ndocument.getElementById(\"btn-right\")?.addEventListener(\"click\", moveRight);\ndocument.getElementById(\"btn-rotate\")?.addEventListener(\"click\", () => tryRotate(1));\ndocument.getElementById(\"btn-down\")?.addEventListener(\"click\", softDrop);\ndocument.getElementById(\"btn-drop\")?.addEventListener(\"click\", hardDrop);\ndocument.getElementById(\"btn-restart\")?.addEventListener(\"click\", restartGame);\n\n// ─── Boot ─────────────────────────────────────────────────────────────────────\n\nstartGame();\nlastTime = performance.now();\ndasLastTime = performance.now();\nanimFrameId = requestAnimationFrame(update);\nrequestAnimationFrame(dasLoop);\nTSEOF","description":"Write Tetris TypeScript source file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":210,"cache_read_input_tokens":5518,"cache_creation":{"ephemeral_5m_input_tokens":210,"ephemeral_1h_input_tokens":0},"output_tokens":60,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"53c76d47-1a7c-46b8-8c49-c0d479582a03"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01XJaPJ5dmyhnnSTzQZTY6FW","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"91549a59-7bea-407b-905f-a5d3611c4628","timestamp":"2026-04-05T19:38:10.751Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0153J6VxAffoWPcqgkbAACHG","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Bvn3mEqBcdPLfb79L3GccH","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-294r5yrr/dist && npx tsc --project tsconfig.json 2>&1","description":"Compile TypeScript to JavaScript"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":6567,"cache_read_input_tokens":5728,"cache_creation":{"ephemeral_5m_input_tokens":6567,"ephemeral_1h_input_tokens":0},"output_tokens":39,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"521c1648-2df3-4594-9ae0-32160ad47b9d"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\ntsconfig.json(4,15): error TS5107: Option 'module=None' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\ntsconfig.json(7,5): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.\n Visit https://aka.ms/ts6 for migration information.\ntsconfig.json(7,5): error TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.","is_error":true,"tool_use_id":"toolu_01Bvn3mEqBcdPLfb79L3GccH"}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"33a415bc-9cfb-4bf7-a26d-0c4593776e56","timestamp":"2026-04-05T19:38:14.231Z","tool_use_result":"Error: Exit code 2\ntsconfig.json(4,15): error TS5107: Option 'module=None' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\ntsconfig.json(7,5): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.\n Visit https://aka.ms/ts6 for migration information.\ntsconfig.json(7,5): error TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error."} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MxMy1Fq66tCPCDeyhNdLsD","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_012Noa74JH9hDwnE93wxxsgA","name":"Bash","input":{"command":"cat > /tmp/loop-bench-294r5yrr/tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"None\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"strict\": true,\n \"outFile\": \"dist/tetris.js\",\n \"rootDir\": \"src\",\n \"ignoreDeprecations\": \"6.0\"\n },\n \"include\": [\"src/**/*.ts\"]\n}\nEOF\nnpx tsc --project /tmp/loop-bench-294r5yrr/tsconfig.json 2>&1","description":"Fix tsconfig and recompile"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":320,"cache_read_input_tokens":12295,"cache_creation":{"ephemeral_5m_input_tokens":320,"ephemeral_1h_input_tokens":0},"output_tokens":56,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"4e5ad49e-a528-4e17-b211-4560ac2afde5"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_012Noa74JH9hDwnE93wxxsgA","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"caad2277-1449-4f93-951c-9677d1300207","timestamp":"2026-04-05T19:38:18.886Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01YBkGwXDhJ9iCfzkGj5aSjP","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01EDzExc7sVGQPyM48coPH6T","name":"Bash","input":{"command":"ls -lh /tmp/loop-bench-294r5yrr/dist/","description":"Check compiled output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":249,"cache_read_input_tokens":12615,"cache_creation":{"ephemeral_5m_input_tokens":249,"ephemeral_1h_input_tokens":0},"output_tokens":49,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"0977a961-9073-4fbb-b793-7b864666348c"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01EDzExc7sVGQPyM48coPH6T","type":"tool_result","content":"total 20K\n-rw-r--r-- 1 root root 19K Apr 5 21:38 tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"a95a5161-e312-4fcc-9839-323f78fa7e89","timestamp":"2026-04-05T19:38:20.513Z","tool_use_result":{"stdout":"total 20K\n-rw-r--r-- 1 root root 19K Apr 5 21:38 tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01YB24eGNe2gu2UPKFXsz7Tk","type":"message","role":"assistant","content":[{"type":"text","text":"Now create the HTML file:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":384,"cache_read_input_tokens":12615,"cache_creation":{"ephemeral_5m_input_tokens":384,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"148257b5-e516-4b51-923a-f2d2ee83e241"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01YB24eGNe2gu2UPKFXsz7Tk","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01DqESx7svqSDz4sLfJAgHq3","name":"Bash","input":{"command":"cat > /tmp/loop-bench-294r5yrr/index.html << 'EOF'\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n\n body {\n background: #0a0a0a;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n font-family: 'Courier New', Courier, monospace;\n color: #eee;\n user-select: none;\n }\n\n #game-wrapper {\n display: flex;\n gap: 20px;\n align-items: flex-start;\n }\n\n /* ── Board ── */\n #board-container {\n position: relative;\n }\n\n #board {\n display: block;\n border: 2px solid #444;\n background: #111;\n }\n\n #message {\n display: none;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: rgba(0,0,0,0.85);\n color: #fff;\n font-size: 26px;\n font-weight: bold;\n padding: 16px 32px;\n border: 2px solid #fff;\n border-radius: 6px;\n text-align: center;\n white-space: nowrap;\n pointer-events: none;\n letter-spacing: 2px;\n }\n\n #message .sub {\n font-size: 14px;\n font-weight: normal;\n margin-top: 8px;\n letter-spacing: 1px;\n color: #aaa;\n }\n\n /* ── Side Panel ── */\n #side-panel {\n display: flex;\n flex-direction: column;\n gap: 16px;\n min-width: 160px;\n }\n\n .panel-box {\n background: #1a1a1a;\n border: 1px solid #333;\n border-radius: 6px;\n padding: 12px 16px;\n }\n\n .panel-box h3 {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: #666;\n margin-bottom: 6px;\n }\n\n .panel-box .value {\n font-size: 28px;\n font-weight: bold;\n color: #0cf;\n letter-spacing: 1px;\n }\n\n #preview-box h3 {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: #666;\n margin-bottom: 8px;\n }\n\n #preview {\n display: block;\n border: 1px solid #333;\n border-radius: 4px;\n background: #111;\n }\n\n /* ── Controls reference ── */\n #controls-box {\n font-size: 11px;\n color: #555;\n line-height: 1.8;\n }\n\n #controls-box .key {\n display: inline-block;\n background: #2a2a2a;\n border: 1px solid #444;\n border-radius: 3px;\n padding: 0 4px;\n font-size: 10px;\n color: #999;\n margin-right: 4px;\n }\n\n /* ── Buttons ── */\n #btn-panel {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n }\n\n #btn-panel button {\n flex: 1 1 calc(50% - 3px);\n padding: 8px 4px;\n background: #222;\n border: 1px solid #444;\n border-radius: 4px;\n color: #ccc;\n font-family: inherit;\n font-size: 11px;\n cursor: pointer;\n letter-spacing: 1px;\n transition: background 0.15s;\n }\n\n #btn-panel button:hover {\n background: #333;\n color: #fff;\n }\n\n #btn-panel button:active {\n background: #0cf;\n color: #000;\n }\n\n #btn-restart {\n flex: 1 1 100% !important;\n background: #1a1a2a !important;\n border-color: #0cf !important;\n color: #0cf !important;\n font-weight: bold;\n letter-spacing: 2px;\n }\n\n #btn-restart:hover {\n background: #0cf !important;\n color: #000 !important;\n }\n </style>\n</head>\n<body>\n <div id=\"game-wrapper\">\n <div id=\"board-container\">\n <canvas id=\"board\"></canvas>\n <div id=\"message\">\n GAME OVER\n <div class=\"sub\">Press ENTER or SPACE to restart</div>\n </div>\n </div>\n\n <div id=\"side-panel\">\n <div class=\"panel-box\" id=\"preview-box\">\n <h3>Next</h3>\n <canvas id=\"preview\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <h3>Score</h3>\n <div class=\"value\" id=\"score\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <h3>Lines</h3>\n <div class=\"value\" id=\"lines\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <h3>Level</h3>\n <div class=\"value\" id=\"level\">0</div>\n </div>\n\n <div class=\"panel-box\" id=\"btn-panel\">\n <button id=\"btn-left\">◀ Left</button>\n <button id=\"btn-right\">Right ▶</button>\n <button id=\"btn-rotate\">↻ Rotate</button>\n <button id=\"btn-down\">▼ Soft</button>\n <button id=\"btn-drop\">⬇ Hard Drop</button>\n <button id=\"btn-restart\">↺ RESTART</button>\n </div>\n\n <div class=\"panel-box\" id=\"controls-box\">\n <div><span class=\"key\">← →</span> Move</div>\n <div><span class=\"key\">↑</span> / <span class=\"key\">X</span> Rotate CW</div>\n <div><span class=\"key\">Z</span> Rotate CCW</div>\n <div><span class=\"key\">↓</span> Soft Drop</div>\n <div><span class=\"key\">Space</span> Hard Drop</div>\n <div><span class=\"key\">P</span> Pause</div>\n </div>\n </div>\n </div>\n\n <script src=\"dist/tetris.js\"></script>\n</body>\n</html>\nEOF","description":"Create index.html for the Tetris game"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":384,"cache_read_input_tokens":12615,"cache_creation":{"ephemeral_5m_input_tokens":384,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"949d22c3-8bf4-4a1d-883f-2b8169b508d3"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01DqESx7svqSDz4sLfJAgHq3","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"e6ee9e5b-1cef-4f95-a87e-9f3d65891556","timestamp":"2026-04-05T19:38:40.555Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01M4cgCCCoZgRgaBeSvo5h7S","type":"message","role":"assistant","content":[{"type":"text","text":"Now let's add a build script to `package.json` and verify everything looks right:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1961,"cache_read_input_tokens":12999,"cache_creation":{"ephemeral_5m_input_tokens":1961,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"b2d41786-5e0d-4d03-be0a-b005f88c0242"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01M4cgCCCoZgRgaBeSvo5h7S","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01UqkqkHsTXXm7PuSf9KFgSh","name":"Bash","input":{"command":"cat > /tmp/loop-bench-294r5yrr/package.json << 'EOF'\n{\n \"name\": \"loop-bench-294r5yrr\",\n \"version\": \"1.0.0\",\n \"description\": \"Browser Tetris game in TypeScript\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"build\": \"tsc --project tsconfig.json\",\n \"dev\": \"tsc --project tsconfig.json --watch\",\n \"test\": \"playwright test\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@playwright/test\": \"^1.59.1\",\n \"@types/node\": \"^25.5.2\",\n \"typescript\": \"^6.0.2\"\n }\n}\nEOF","description":"Update package.json with build scripts"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1961,"cache_read_input_tokens":12999,"cache_creation":{"ephemeral_5m_input_tokens":1961,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"41fce942-9011-48fe-b0f3-7ea4d8ac71bf"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01UqkqkHsTXXm7PuSf9KFgSh","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"880c693d-fe36-4889-9f0b-ff8ba9f996e5","timestamp":"2026-04-05T19:38:45.855Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01RVASUdbiZtNadTPwGr5TCD","type":"message","role":"assistant","content":[{"type":"text","text":"Now let me do a quick sanity-check on the compiled output and also verify the HTML references the right file:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":331,"cache_read_input_tokens":14960,"cache_creation":{"ephemeral_5m_input_tokens":331,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"f447e3a6-9e93-4671-9691-9544138c6552"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01RVASUdbiZtNadTPwGr5TCD","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_011WDmbebRouuU85PHmtyMQv","name":"Bash","input":{"command":"wc -l /tmp/loop-bench-294r5yrr/dist/tetris.js && head -5 /tmp/loop-bench-294r5yrr/dist/tetris.js && echo \"---\" && tail -5 /tmp/loop-bench-294r5yrr/dist/tetris.js","description":"Check compiled JS output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":331,"cache_read_input_tokens":14960,"cache_creation":{"ephemeral_5m_input_tokens":331,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"0d7d1f07-4681-4b20-ad8e-254614177d3b"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_011WDmbebRouuU85PHmtyMQv","type":"tool_result","content":"542 /tmp/loop-bench-294r5yrr/dist/tetris.js\n\"use strict\";\n// ─── Constants ───────────────────────────────────────────────────────────────\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px\n---\nstartGame();\nlastTime = performance.now();\ndasLastTime = performance.now();\nanimFrameId = requestAnimationFrame(update);\nrequestAnimationFrame(dasLoop);","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"3c99f744-42e1-4c50-9ddd-3a752fc2e21d","timestamp":"2026-04-05T19:38:49.009Z","tool_use_result":{"stdout":"542 /tmp/loop-bench-294r5yrr/dist/tetris.js\n\"use strict\";\n// ─── Constants ───────────────────────────────────────────────────────────────\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px\n---\nstartGame();\nlastTime = performance.now();\ndasLastTime = performance.now();\nanimFrameId = requestAnimationFrame(update);\nrequestAnimationFrame(dasLoop);","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01WtT8Thm4qbEmHJSzBA1RjZ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_018vs9uk1fzt8XynarQx8hhc","name":"Bash","input":{"command":"# Verify no TypeScript errors with a fresh compile\nnpx tsc --project tsconfig.json --noEmit 2>&1 && echo \"✓ No type errors\"","description":"Type-check TypeScript source"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":308,"cache_read_input_tokens":15291,"cache_creation":{"ephemeral_5m_input_tokens":308,"ephemeral_1h_input_tokens":0},"output_tokens":40,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"b7a3a6b8-6f2d-42a2-8835-2c4e4f526ed2"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_018vs9uk1fzt8XynarQx8hhc","type":"tool_result","content":"✓ No type errors","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"1c1d5551-dab7-4953-87cf-3efa990630e7","timestamp":"2026-04-05T19:38:52.107Z","tool_use_result":{"stdout":"✓ No type errors","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Jj8wTx5tyiEXDEFsuym96w","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01LaG7qKf84qfUpwofJGuB44","name":"Bash","input":{"command":"# Verify all game functions are present in the compiled output\nfor fn in startGame restartGame lockPiece clearLines tryRotate ghostRow hardDrop softDrop drawBlock drawPreview; do\n grep -q \"$fn\" /tmp/loop-bench-294r5yrr/dist/tetris.js && echo \"✓ $fn\" || echo \"✗ $fn MISSING\"\ndone","description":"Check all key functions are in compiled output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":132,"cache_read_input_tokens":15599,"cache_creation":{"ephemeral_5m_input_tokens":132,"ephemeral_1h_input_tokens":0},"output_tokens":40,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"fe3ef43b-6443-4063-8410-a4c811fbe8c1"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01LaG7qKf84qfUpwofJGuB44","type":"tool_result","content":"✓ startGame\n✓ restartGame\n✓ lockPiece\n✓ clearLines\n✓ tryRotate\n✓ ghostRow\n✓ hardDrop\n✓ softDrop\n✓ drawBlock\n✓ drawPreview","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"f30eb3f7-7251-4541-8b78-db2d68f493fb","timestamp":"2026-04-05T19:38:55.614Z","tool_use_result":{"stdout":"✓ startGame\n✓ restartGame\n✓ lockPiece\n✓ clearLines\n✓ tryRotate\n✓ ghostRow\n✓ hardDrop\n✓ softDrop\n✓ drawBlock\n✓ drawPreview","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01AFF5VpQTSxrzfjv3pnW9zm","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Chs2YnWcHeqN32oGPfb8bM","name":"Bash","input":{"command":"ls -lh /tmp/loop-bench-294r5yrr/","description":"List all project files"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":248,"cache_read_input_tokens":15731,"cache_creation":{"ephemeral_5m_input_tokens":248,"ephemeral_1h_input_tokens":0},"output_tokens":47,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"e7022b96-c9c0-4074-b72e-787117ca6aa3"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Chs2YnWcHeqN32oGPfb8bM","type":"tool_result","content":"total 32K\ndrwxr-xr-x 2 root root 4.0K Apr 5 21:38 dist\n-rw-r--r-- 1 root root 5.0K Apr 5 21:38 index.html\ndrwxr-xr-x 9 root root 4.0K Apr 5 21:22 node_modules\n-rw-r--r-- 1 root root 474 Apr 5 21:38 package.json\n-rw-r--r-- 1 root root 3.4K Apr 5 21:22 package-lock.json\ndrwxr-xr-x 2 root root 4.0K Apr 5 21:38 src\n-rw-r--r-- 1 root root 244 Apr 5 21:38 tsconfig.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"42c3f7d6-a79e-441c-a598-a73c3d142305","timestamp":"2026-04-05T19:38:57.479Z","tool_use_result":{"stdout":"total 32K\ndrwxr-xr-x 2 root root 4.0K Apr 5 21:38 dist\n-rw-r--r-- 1 root root 5.0K Apr 5 21:38 index.html\ndrwxr-xr-x 9 root root 4.0K Apr 5 21:22 node_modules\n-rw-r--r-- 1 root root 474 Apr 5 21:38 package.json\n-rw-r--r-- 1 root root 3.4K Apr 5 21:22 package-lock.json\ndrwxr-xr-x 2 root root 4.0K Apr 5 21:38 src\n-rw-r--r-- 1 root root 244 Apr 5 21:38 tsconfig.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MhXS83BZMJ8RjcXikYbLTZ","type":"message","role":"assistant","content":[{"type":"text","text":"Everything is in place. Here's a summary of what was built:\n\n---\n\n## Tetris — Browser Game in TypeScript\n\n### File structure\n```\nindex.html ← main page (open this in a browser)\nsrc/tetris.ts ← full game logic in TypeScript\ndist/tetris.js ← compiled output (auto-generated)\ntsconfig.json ← TS config (ES2020, single outFile)\npackage.json ← npm scripts: build / dev / test\n```\n\n### Features implemented\n\n| Feature | Detail |\n|---|---|\n| **7 Tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Super Rotation System with full wall-kick tables for all pieces |\n| **Ghost piece** | Translucent preview of where piece will land |\n| **Lock delay** | 500 ms lock delay with up to 15 move resets (standard Tetris rules) |\n| **Line clearing** | Clears filled rows, drops board above |\n| **Scoring** | 100/300/500/800 × (level+1) for 1/2/3/4 lines; +1 per soft-drop cell; +2 per hard-drop cell |\n| **Levels** | Level increases every 10 lines; 20 speed tiers down to 30 ms/tick |\n| **DAS/ARR** | Proper Delayed Auto Shift (170 ms) + Auto Repeat Rate (50 ms) for smooth movement |\n| **Next piece** | Preview panel shows upcoming piece |\n| **Pause** | `P` or `Escape` |\n| **Restart** | `Enter` / `Space` on game-over screen |\n| **On-screen buttons** | Mobile-friendly click controls |\n\n### Keyboard controls\n| Key | Action |\n|---|---|\n| `← →` / `A D` | Move left / right |\n| `↑` / `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` / `S` | Soft drop (+1 pt/cell) |\n| `Space` | Hard drop (+2 pt/cell) |\n| `P` / `Esc` | Pause / unpause |\n| `Enter` / `Space` | Restart (on game-over) |\n\n### Run\nJust open **`index.html`** directly in any modern browser — no server needed. \nTo rebuild after editing TypeScript: `npm run build`"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":313,"cache_read_input_tokens":15979,"cache_creation":{"ephemeral_5m_input_tokens":313,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","uuid":"652b1252-b180-4e29-81ee-16848a7e1227"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":969070,"duration_api_ms":966371,"num_turns":15,"result":"Everything is in place. Here's a summary of what was built:\n\n---\n\n## Tetris — Browser Game in TypeScript\n\n### File structure\n```\nindex.html ← main page (open this in a browser)\nsrc/tetris.ts ← full game logic in TypeScript\ndist/tetris.js ← compiled output (auto-generated)\ntsconfig.json ← TS config (ES2020, single outFile)\npackage.json ← npm scripts: build / dev / test\n```\n\n### Features implemented\n\n| Feature | Detail |\n|---|---|\n| **7 Tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Super Rotation System with full wall-kick tables for all pieces |\n| **Ghost piece** | Translucent preview of where piece will land |\n| **Lock delay** | 500 ms lock delay with up to 15 move resets (standard Tetris rules) |\n| **Line clearing** | Clears filled rows, drops board above |\n| **Scoring** | 100/300/500/800 × (level+1) for 1/2/3/4 lines; +1 per soft-drop cell; +2 per hard-drop cell |\n| **Levels** | Level increases every 10 lines; 20 speed tiers down to 30 ms/tick |\n| **DAS/ARR** | Proper Delayed Auto Shift (170 ms) + Auto Repeat Rate (50 ms) for smooth movement |\n| **Next piece** | Preview panel shows upcoming piece |\n| **Pause** | `P` or `Escape` |\n| **Restart** | `Enter` / `Space` on game-over screen |\n| **On-screen buttons** | Mobile-friendly click controls |\n\n### Keyboard controls\n| Key | Action |\n|---|---|\n| `← →` / `A D` | Move left / right |\n| `↑` / `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` / `S` | Soft drop (+1 pt/cell) |\n| `Space` | Hard drop (+2 pt/cell) |\n| `P` / `Esc` | Pause / unpause |\n| `Enter` / `Space` | Restart (on game-over) |\n\n### Run\nJust open **`index.html`** directly in any modern browser — no server needed. \nTo rebuild after editing TypeScript: `npm run build`","stop_reason":"end_turn","session_id":"7ae599a1-1ead-49c7-a309-f21fb836f0af","total_cost_usd":1.3602285,"usage":{"input_tokens":23,"cache_creation_input_tokens":17256,"cache_read_input_tokens":163115,"output_tokens":83101,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":17256},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":23,"outputTokens":83101,"cacheReadInputTokens":163115,"cacheCreationInputTokens":17256,"webSearchRequests":0,"costUSD":1.3602285,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"d3ebfce3-50aa-4fca-886d-a4ca94e16562"} diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_output.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":953675,"duration_api_ms":952188,"num_turns":17,"result":"The Tetris game is complete. Here's a summary of everything that was built:\n\n---\n\n## 📁 Project Structure\n\n```\nindex.html ← game page (open this in a browser)\nsrc/tetris.ts ← TypeScript source (~500 lines)\ndist/tetris.js ← compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config\n```\n\n**To play:** open `index.html` in a browser (e.g. `python3 -m http.server` then navigate to `localhost:8000`).\n\n---\n\n## 🎮 Features Implemented\n\n| Feature | Details |\n|---|---|\n| **All 7 tetrominoes** | I, J, L, O, S, T, Z with correct shapes |\n| **Piece rotation** | CW (↑/X) and CCW (Z) with **wall-kick** (tries ±1, ±2 column offsets) |\n| **Ghost piece** | Outline shows where the piece will land |\n| **Soft drop** | ↓ / S — moves piece down one row, +1 point |\n| **Hard drop** | Space — slams piece to bottom, +2 pts/row |\n| **Line clearing** | Removes full rows, shifts board down |\n| **Scoring** | 100/300/500/800 pts × level for 1/2/3/4 lines |\n| **Levels** | Increases every 10 lines cleared |\n| **Speed increase** | Drop interval decreases 60 ms/level (min 80 ms) |\n| **Next piece preview** | Shown in side panel |\n| **Pause / Resume** | P key or Start button |\n| **Game over detection** | Triggers when piece spawns in collision |\n\n## ⌨️ Keyboard Controls\n\n| Key | Action |\n|---|---|\n| `← →` or `A D` | Move left / right |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` or `S` | Soft drop |\n| `Space` | Hard drop |\n| `P` | Pause / Resume |\n| `Enter` | Start / Restart |","stop_reason":"end_turn","session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","total_cost_usd":1.3401081000000001,"usage":{"input_tokens":25,"cache_creation_input_tokens":16886,"cache_read_input_tokens":163152,"output_tokens":81851,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":16886},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":25,"outputTokens":81851,"cacheReadInputTokens":163152,"cacheCreationInputTokens":16886,"webSearchRequests":0,"costUSD":1.3401081000000001,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"d2d35a0d-5a2c-49f9-9bc4-9b12e2f77d2c"} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_stderr.log b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/claude_stderr.log diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/eval_results.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/eval_results.json @@ -0,0 +1,261 @@ +{ + "structural": { + "pass": true, + "checks": [ + { + "name": "entry_point_exists", + "pass": true, + "detail": "index.html found" + }, + { + "name": "package_json_exists", + "pass": true, + "detail": "package.json found" + }, + { + "name": "build_succeeds", + "pass": true, + "detail": "no build script defined (static project)" + }, + { + "name": "typescript_compiles", + "pass": true, + "detail": "tsc --noEmit passed" + } + ], + "score": 1.0 + }, + "functional": { + "pass": false, + "error": "playwright eval not yet wired", + "score": 0 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": true + }, + "performance": { + "bundle_size_bytes": 15602, + "size_under_512kb": true + }, + "score": 0.67 + }, + "code_analysis": { + "files": { + "total": 6, + "code": 3, + "docs": 0, + "unnecessary": 0, + "unnecessary_list": [] + }, + "lines_of_code": 1150, + "dependencies": { + "production": 0, + "dev": 4, + "total": 4 + }, + "complexity": "moderate", + "console_logs": 0, + "magic_numbers": { + "count": 22, + "excessive": true + }, + "function_length": { + "count": 66, + "average": 6.8, + "max": 37, + "long_functions": 0 + }, + "max_nesting_depth": 10, + "global_declarations": 20, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 100.0, + "camel_case": 455, + "snake_case": 0 + }, + "error_handling": { + "try_catch_blocks": 0, + "has_error_handling": false + }, + "comments": { + "comment_lines": 51, + "source_lines": 833, + "ratio_pct": 6.1 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 2, + "files_with_logic": 2, + "files_with_both": 2 + }, + "html_validation": { + "valid": false, + "errors": 8 + }, + "duplication_percentage": 0.0, + "score": 0.85 + }, + "transcript_analysis": { + "total_events": 46, + "tool_calls": { + "total": 16, + "bash": 13, + "write": 0, + "edit": 0, + "read": 3 + }, + "wasted_turns": { + "total": 0, + "docs": 0, + "ascii_art": 0, + "server_starts": 0 + }, + "errors_encountered": 0, + "thinking_blocks": 4, + "text_blocks": 6, + "productivity_ratio": 1.0, + "self_tested": false, + "score": 1.0 + }, + "gameplay_bot": { + "pass": false, + "score": 0.94, + "total": 16, + "passed": 15, + "failed": 1, + "report": { + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 300, + "height": 600 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "enter", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via enter" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "grid state changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": true, + "detail": "rotated: [I] failed: [] (tested 1 piece types in 60 attempts)" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "piece immediately dropped and new piece appeared" + }, + { + "name": "piece_locks", + "pass": true, + "detail": "filled cells persist at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "new piece detected after drop" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "grid accumulated cells: 20 -> 41" + }, + { + "name": "line_clear", + "pass": true, + "detail": "line cleared via strategic placement" + }, + { + "name": "score_changes", + "pass": false, + "detail": "score did not increase: [180] -> no change after polling" + }, + { + "name": "game_over", + "pass": true, + "detail": "game stopped after stacking to top" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 80 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 15, + "failed": 1, + "score": 0.94 + }, + "gameplay": { + "pieces_placed": 131, + "lines_cleared": 1, + "max_score_observed": 208, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 22 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 2, + "pass": false + } + } + }, + "score": 0.7405 +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/gameplay-bot-report.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/gameplay-bot-report.json @@ -0,0 +1,127 @@ +{ + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 300, + "height": 600 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "enter", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via enter" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "grid state changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": true, + "detail": "rotated: [I] failed: [] (tested 1 piece types in 60 attempts)" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "piece immediately dropped and new piece appeared" + }, + { + "name": "piece_locks", + "pass": true, + "detail": "filled cells persist at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "new piece detected after drop" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "grid accumulated cells: 20 -> 41" + }, + { + "name": "line_clear", + "pass": true, + "detail": "line cleared via strategic placement" + }, + { + "name": "score_changes", + "pass": false, + "detail": "score did not increase: [180] -> no change after polling" + }, + { + "name": "game_over", + "pass": true, + "detail": "game stopped after stacking to top" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 80 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 15, + "failed": 1, + "score": 0.94 + }, + "gameplay": { + "pieces_placed": 131, + "lines_cleared": 1, + "max_score_observed": 208, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 22 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 2, + "pass": false + } +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/meta.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/meta.json @@ -0,0 +1,30 @@ +{ + "model": "sonnet", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "on", + "linter": "on", + "playwright": "off", + "context_file": "none", + "sub_agents": "on", + "web_search": "on", + "max_budget": "low", + "task": "tetris", + "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1", + "run_number": 1, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-05T19:22:56.142802+00:00", + "wall_time_seconds": 954, + "exit_code": 0, + "completed_at": "2026-04-05T19:38:54.914546+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/transcript.jsonl b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run1/transcript.jsonl @@ -0,0 +1,46 @@ +{"type": "harness", "subtype": "config", "model": "sonnet", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "Agent", "WebSearch", "WebFetch"], "max_budget_usd": 2.0, "timeout_seconds": 1200, "task": "tetris", "language": "typescript", "prompt_style": "simple"} +{"type": "user", "subtype": "prompt", "message": {"role": "user", "content": "Build a playable Tetris game that runs in a browser. It should have all the standard mechanics: piece rotation, line clearing, scoring, and increasing speed. Use keyboard controls for movement and rotation.\n\n\nUse TypeScript."}} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-kncx228p","session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"claude-sonnet-4-6","permissionMode":"dontAsk","slash_commands":["update-config","debug","simplify","batch","loop","schedule","claude-api","compact","context","cost","heapdump","init","review","security-review","insights"],"apiKeySource":"apiKeyHelper","claude_code_version":"2.1.92","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan"],"skills":["update-config","debug","simplify","batch","loop","schedule","claude-api"],"plugins":[{"name":"claude-hud","path":"/root/.claude/plugins/marketplaces/claude-hud/","source":"claude-hud@claude-hud"},{"name":"rust-analyzer-lsp","path":"/root/.claude/plugins/marketplaces/claude-plugins-official/plugins/rust-analyzer-lsp","source":"rust-analyzer-lsp@claude-plugins-official"}],"uuid":"6bafaf95-427c-4b49-b940-e32ed5b4659d","fast_mode_state":"off"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01XcYaQW2NCbwuie5b2uDjJ4","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Let me build a complete Tetris game in TypeScript that runs in the browser. I'll create a self-contained implementation with:\n\n1. All 7 standard Tetris pieces (I, O, T, S, Z, J, L)\n2. Piece rotation\n3. Line clearing\n4. Scoring system\n5. Increasing speed\n6. Keyboard controls\n\nI'll structure it as:\n- `index.html` - Main HTML file\n- `src/tetris.ts` - TypeScript source\n- A compiled output or use a simple setup\n\nSince this needs to run in a browser and we want to use TypeScript, I'll either:\n\n\nUse a build tool like esbuild/webpack or write TypeScript and compile it inline. Let me go with esbuild for quick compilation and set up a project with `index.html`, `src/game.ts` for the main game logic, and `package.json` with a build script.\n\nNow I'm planning out the core game structure: a 10×20 board where each cell stores either empty space or a color, and I need to define all seven tetrominoes with their rotation states.\n\nWriting the game mechanics... Defining the piece rotations... Writing the TypeScript implementation... Now I'm setting up the HTML structure with a game board canvas and sidebar for the next piece preview and stats display. Let me work through the piece rotation matrices for SRS, starting with how each tetromino rotates through its four states. Defining the remaining piece rotations... Defining the Tetris piece rotations... Writing the Tetris game implementation... Implementing SRS wall kick system... I need to adjust my coordinate system so y increases downward like screen coordinates, which means negating the y values from the standard Tetris kick data. Rather than implementing the full SRS system, I'll go with a simpler rotation approach that tries the piece in place first, then attempts fallback offsets along the x-axis if there's a collision. Now I'm writing out the TypeScript implementation, starting with the core constants like board dimensions, cell size, and piece colors.\n\nSetting up the data structures... Setting up the Tetris class with canvas contexts for the main board, next piece preview, and hold piece display, along with game state variables for tracking the current piece, score, level, and game status.\n\nNow I'm adding the input handling mechanics with delayed auto-shift for smooth left-right movement, plus tracking which lines are cleared for the animation sequence.\n\nI'm planning the project structure with separate files for HTML, TypeScript, and config, then building out the UI with a centered game board, sidebars for the hold and next piece previews, score display, and control instructions.\n\nWriting the HTML layout... Defining the piece shapes and rotations... Defining the rotation states for the remaining Tetris pieces... I'm realizing my S piece rotations aren't quite right—let me reconsider the standard S tetromino shape and how it rotates in a 3x3 grid to make sure I have the correct orientations. Verifying the rotation states for the Z, J, and L pieces...\n\nNow I'm working through the L piece rotations more carefully. For L R1, rotating clockwise from the base orientation gives me the correct state. Moving to L R2, I need to rotate again from R1 to see what the next configuration should be.\n\nContinuing with L R3, I'm verifying each rotation step by step to make sure the matrices match the visual representations. Now I'm moving on to the J piece and checking its rotation states across all four orientations, starting with J R1 and working through to verify the array representations match the expected shapes.\n\nWith J confirmed, I'm now validating the T piece across its four rotations, checking that each 3x3 matrix correctly represents the block positions. Finally, I'm starting to verify the I piece. I'm working through the piece definitions for a Tetris game, settling on using 4x4 matrices for the I piece and a simpler 2x2 representation for the O piece since all its rotations are identical, then deciding on consistent sizing across all pieces.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4727,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":4727,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"5013a457-1145-4fc3-9a5e-5d5e46343439"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01PEZtjxLsmgoGjvz1EZmtvH","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants me to build a playable Tetris game in TypeScript that runs in a browser. Let me plan out the implementation:\n\n1. **Game Board**: 10x20 grid (standard Tetris)\n2. **Pieces (Tetrominoes)**: I, O, T, S, Z, J, L pieces\n3. **Mechanics**:\n - Piece rotation\n - Line clearing\n - Scoring (standard Tetris scoring)\n - Increasing speed\n4. **Keyboard Controls**:\n - Arrow Left/Right: Move piece\n - Arrow Down: Soft drop\n - Arrow Up: Rotate\n - Space: Hard drop\n5. **Display**: HTML Canvas\n\nI'll create a complete Tetris game with an HTML entry point, TypeScript game logic, and the necessary configuration files for compilation. Since this needs to run directly in a browser, I'll set up a straightforward build process with TypeScript compilation.\n\nSetting up the project structure...\n\nNow I'm defining the core game mechanics. I'll use the standard Tetromino shapes with their traditional colors: cyan I-piece, yellow O-piece, purple T-piece, green S-piece, red Z-piece, blue J-piece, and orange L-piece. For scoring, I'm implementing the classic Tetris system where clearing multiple lines gives exponentially higher points multiplied by the current level. The game will progress through levels every 10 lines cleared, with the drop speed starting around one second and accelerating as difficulty increases.\n\nWriting the game logic... Writing the Tetris game code... Defining the rotation states for the remaining Tetris pieces... Finishing up the piece rotation data structures, then I'm shifting to a simpler approach—basic rotation with straightforward boundary checking instead of implementing the full Super Rotation System, which would add unnecessary complexity. I'll build out a complete Tetris game with canvas rendering, a ghost piece preview, and a next piece display.\n\nSetting up the game constants and data structures... Defining the tetromino rotation states... I'm reviewing the standard Tetromino shapes and their visual representations to make sure I have them correct. Now I need to work through the rotation states systematically, starting with how the I piece rotates in a 4x4 grid.\n\nFor the other pieces that fit in a 3x3 grid, I'll implement a general rotation algorithm that handles clockwise rotation by transposing the matrix and reversing each row.\n\nImplementing rotation logic...\n\nActually, storing all rotation states explicitly will be cleaner and avoid edge cases with non-square matrices. Now I'm building out the full Tetris game with all seven tetrominoes, proper colors, a ghost piece preview, next piece display, standard scoring, level progression with increasing speed, and pause functionality.\n\nWriting the TypeScript implementation... Defining the rotation states for each tetromino piece... I'm realizing the S piece rotation states I defined earlier might be incorrect. Let me verify the actual rotations by working through them manually—starting with the base S shape and rotating it clockwise to check if my array definitions match the expected visual layout. Now I'm rotating state 1 another 90° clockwise to get the 180° rotation, applying the same transformation formula to each position and arriving at the S-piece's second state. Now I'm working through the Z piece rotations, applying the same clockwise transformation to get each state and verify the coordinates match up correctly. Continuing the rotation, I'm applying the same clockwise transformation to state 2 to get state 3, mapping each position from the rotated coordinates. Continuing to verify the J piece rotations by applying the clockwise transformation formula to each state, working through the matrix calculations to confirm state 2 matches the expected configuration. I've verified the J piece rotations are correct, so now I'm checking the L piece states. I'm working through the clockwise rotation formula for L state 1, mapping each position from the original configuration.\n\nContinuing with L state 2, I'm applying the same rotation transformation to get the next clockwise orientation. Finishing that rotation calculation, then moving on to verify the T-piece states. I'm working through the clockwise rotation transformations for each tetromino, mapping out how the grid coordinates shift with each 90-degree turn. Continuing the rotation pattern through state 3, applying the same clockwise transformation to get the next configuration.\n\nNow I'm moving on to the I piece, which operates on a 4x4 grid instead, and I need to work through its rotation states using the transformation formula for that larger grid size. Finishing the rotation mapping, then checking what the actual SRS standard specifies for the I piece—it looks like state 1 should have the piece in column 2 of the 4x4 grid, which matches what I'm getting here. I need to recalculate the rotation matrix more carefully. Let me work through the clockwise rotation formula for a 4x4 grid where new[i][j] = old[N-1-j][i], mapping out what each position should contain after the rotation. I'm working through state 3 by rotating the matrix clockwise from state 2, applying the transformation formula where each new position maps from the old matrix in a specific pattern. The rotation produces another configuration with a horizontal line of 1s in the third row. My rotation logic checks out, so now I'm setting up the overall game architecture with a class-based structure to keep everything organized—I'll manage the canvas, game board, pieces, score tracking, and game state all in one place.\n\nDefining the complete method signatures...\n\nNow I'm thinking about the implementation details and polish—I want to add some nice visual touches like a dark theme with gradients, and I should include DAS (Delayed Auto Shift) for smoother controls.\n\nFor the layout, I'm picturing the game board on the left side at 300x600 pixels with 30-pixel cells, and a sidebar on the right showing the next piece, score, level, and line count. I could draw everything on canvas, but using HTML and CSS for the sidebar might be cleaner and easier to style. I'm settling on a cell size of 30 pixels with a 10×20 board, making the canvas 480×620 to fit everything including the side panel. Now I'll set up the constants for the board dimensions and canvas layout, then start drawing the score display directly on the canvas.\n\nFor the visual style, I'm going with a dark navy color scheme—a deep background with a slightly lighter board area, subtle grid lines, standard Tetris piece colors, and white text for contrast. I'll structure this as an HTML page with a canvas element and a TypeScript game module to handle all the logic.\n\nWriting the game code... Defining the rotation states for each tetromino piece... Finishing up the piece rotations, then setting up the scoring system with exponential rewards for clearing multiple lines at once. I'm defining the game speed function so it accelerates with each level, and now I'm structuring the core TetrisGame class with the canvas, board state, and active piece tracking.\n\nSetting up game state properties... Writing the game logic... Finishing the piece locking logic...\n\nWhen a piece locks in place, I'm checking if any part of it spawned above the board—if so, the game ends. Otherwise, I place the piece on the board and then check for completed lines. I calculate the score based on how many lines were cleared and the current level, update the level based on total lines cleared, and spawn the next piece. If that new piece can't be placed validly, the game is over.\n\nFor clearing lines, I'm iterating from the bottom of the board upward, checking each row to see if it's completely filled. When I find a full row, I remove it and add a new empty row at the top, incrementing the cleared count and rechecking that same row position since rows shift down.\n\nNow I'm implementing the movement controls—left and right shifts check if the move is valid before updating the piece's x position, and soft drop moves the piece down one row if possible while adding a point to the score.\n\nImplementing hard drop and rotation mechanics... Setting up the input handlers for arrow keys and rotation controls, tracking which keys are pressed and managing the delayed auto-repeat timing for left and right movement, while also handling hard drop and rotation inputs. Setting up the game state reset and then handling the update loop with delta time calculations to manage the left and right movement delays using a DAS system.\n\nStill writing game logic... Still writing canvas rendering... Writing the game UI... Writing the game overlay and cell rendering... Still writing the panel code... Writing the stats display... Finishing the initialization code...\n\nI'm realizing the soft drop timing is problematic—calling it every frame at 60fps is way too aggressive. I need to throttle it so the piece drops at a reasonable speed, probably around every 3 frames or so to match classic Tetris behavior where soft drop moves at roughly 20 lines per second.\n\nI'm switching to a cleaner approach where I check if down is held in the main gravity loop and reduce the drop interval accordingly, capping it at around 50ms instead of the normal drop interval. This way the piece accelerates smoothly when the player holds down, and I can award bonus points for soft dropping.\n\nFor DAS, I need to distinguish between the initial delay before repeated key presses start and the interval between those repeats. I'm also reconsidering the random piece selection—while simple randomness works, implementing the 7-bag system that modern Tetris uses would be better since it guarantees all pieces appear before repeating, improving playability. Let me go ahead and implement that with a bag that shuffles all seven piece types and draws from it sequentially.\n\nImplementing 7-bag randomizer...\n\nNow I'm working through the piece definitions and their spawn positions. The O piece is tricky because it's defined as a 4×4 matrix but only uses the center 2×2 area, which wastes space. I should standardize the piece matrices—maybe use 3×3 for most pieces and 4×4 only for the I piece, or find a cleaner way to handle the O piece's centering during spawn. The centering math checks out for all piece sizes. Now I'm writing out the complete implementation, and I'm noticing an issue with how the delayed auto-shift works—when I first press a direction key, it moves immediately and starts the delay timer, but I need to make sure the subsequent repeats trigger at the right intervals.\n\nFor soft drop, I should let gravity handle the faster descent rather than calling it every frame. And I need to refine the collision detection to handle pieces that spawn partially above the board by skipping those rows instead of rejecting the placement outright.\n\nDefining the validation logic... Checking piece collision logic...\n\nI'm realizing the spawn position matters here—when a piece spawns at y=0, parts of its shape might be above the visible board, which is actually fine since we skip those rows. Looking at the I piece example, when it spawns at y=0, the actual blocks land at rows 1-3, which works correctly. But I need to think through what the standard Tetris spawn behavior should be.\n\nFor pieces like the T that have blocks in their first row, spawning at y=0 means those blocks appear at row 0 of the board. The simplest approach is to just spawn everything at y=0 and let the shape's internal structure handle where the actual blocks land—if there are empty rows at the top of the shape, they'll be above the board, which is valid since negative board rows are allowed during collision checks.\n\nNow looking at the I piece in its default orientation, it has empty rows at the top before the actual blocks appear at row 1, so spawning at y=0 would place those blocks at row 1 of the board, which works fine.\n\nThe simplest approach is to just spawn everything at y=0 and accept that pieces with empty top rows will naturally sit lower on the board. Alternatively, I could calculate the spawn position dynamically based on where the first non-empty row actually is in each shape, but that's more complex than needed.\n\nWriting the spawn logic... I need to make sure the isValid function properly handles pieces that spawn partially off the top of the board by skipping cells with negative row indices. Now I'm thinking through the O piece specifically—it's a 4x4 matrix with blocks in the top-left 2x2 area, so it spawns at y=0 and occupies board rows 0-1 and columns 4-5.\n\nActually, using a 2x2 representation for the O piece would be cleaner and still center it properly on the board. But then I'm running into the issue that different piece sizes would render at different scales in the preview. I think the best approach is to stick with a consistent 4x4 bounding box for all pieces, even though it's a bit wasteful for the smaller ones—that's what most Tetris implementations do anyway.\n\nFor the O piece specifically, I'd pad it with zeros so it sits centered in a 4x4 grid, which puts the actual blocks at columns 1-2 and rows 1-2. That way the spawn positioning logic stays uniform across all piece types.\n\nDefining piece shapes as minimal bounding boxes...\n\nDefining tetromino shapes... I'm working through the spawn positions for each piece type by calculating the centered x-coordinate based on board width and piece width, then determining the starting y based on where the first filled row appears in each rotation state—for most pieces that's row 0, but the I-piece needs special handling since its first filled row is at index 1.\n\nNow I'm thinking through the canvas dimensions with a cell size of 30 pixels, accounting for the game board, side panel for next piece and score, and padding around everything.\n\nI need to prevent the browser's default scrolling behavior when the player uses arrow keys and spacebar, so I'll add a keydown listener that calls preventDefault for those specific keys before handling the game logic.\n\nWriting the complete game code... Defining the piece shapes... Defining the Tetris game class with the board state, current piece, and next piece tracking... Setting up the canvas context and initializing the game board with an empty grid, then picking the first piece from a randomized bag of piece types and binding keyboard controls before starting the animation loop. I'm also implementing helper methods for generating the board, managing the piece bag with a shuffle system, and retrieving rotation states for pieces.\n\nNow I'm handling piece spawning by selecting the next piece type, calculating its starting position centered on the board, and adjusting the vertical offset based on where the piece's blocks actually begin, then checking if the spawn position is valid or if the game is over.\n\nContinuing with validation logic... Writing the game logic... Still writing game logic... Writing key binding logic... Setting up the game loop with delta time capping, then handling the DAS (delayed auto shift) logic for left and right movement inputs...\n\nStill writing game loop code... Still writing the rendering code... Finishing the current piece rendering, then drawing the board border in purple, rendering the side panel, and handling overlay states for pause and game over screens.\n\nStill writing block rendering... Writing the panel rendering... Finishing the preview rendering with highlights, then displaying the game stats like score, level, and lines cleared, along with the control scheme for the player. Writing the controls display... Finishing the rounded rectangle drawing function...\n\nNow I'm thinking through the game logic more carefully. The `clearFull` method mutates the board array directly with splice and unshift, which works fine. But I'm realizing there's a potential issue in the spawn flow—when gravity triggers a lock and `spawnNext()` gets called, I need to make sure the collision detection doesn't immediately fail on the newly spawned piece.\n\nActually, I should reset the drop accumulator when spawning a new piece so the gravity timing doesn't carry over from the previous piece. That way each piece starts fresh with its own gravity cycle.\n\nThe `valid` function takes an optional rotation parameter to check if a rotation would be valid at the current position—it creates a temporary piece object with the new rotation and tests it against the board, which is cleaner than modifying the actual piece. Now I need to make sure the soft drop also applies during the gravity section when the down arrow is held.\n\nLooking at the timing, both DAS and gravity are firing independently—DAS every 50ms for the down arrow, and gravity every `dropInterval(level)` ms. When both trigger, the piece moves down twice per cycle, which creates a faster drop effect. The real concern is whether the piece locks prematurely when gravity fires and the piece can't move, since DAS just returns false without locking, but gravity will eventually call `lock()` when movement fails.\n\nI'm thinking I should make the soft drop (holding down) also trigger locking immediately when the piece can't move anymore, rather than waiting for gravity. This would give more responsive feedback and prevent the piece from sitting at the bottom for an extra gravity tick.\n\nRefining the DAS handler... Still writing gravity logic...\n\nNow I'm thinking through the DAS (Delayed Auto Shift) behavior for horizontal movement—when a player first presses left or right, it should move immediately, then after an initial delay it repeats at a faster rate. The tricky part is making sure the keydown event doesn't fire multiple times for a held key, and I need to distinguish between the actual first press and the browser's key repeat events.\n\nMy approach is to track which keys are currently held in a set. When a keydown fires, I check if the key is already in the set—if it is, that means it's a repeat event from the browser and I skip it. If it's not in the set, it's the first press, so I add it and trigger the movement. This way the DAS timer handles the repeated movement, not the browser's repeat events.\n\nRefining the game loop... I'm reconsidering the gravity loop—a while loop handles multiple drop ticks per frame better, but I need to cap it to prevent runaway iterations on high levels, so I'm adding a safeguard that limits it to 5 ticks maximum.\n\nSetting up the project files... Setting up the TypeScript configuration... I'm setting up the package.json with build scripts for TypeScript compilation and a local dev server, then planning out the canvas dimensions—500 × 640 pixels with the game board on the left and a side panel for stats on the right.\n\nWriting the TypeScript code... Writing the game code... Defining the rotation states for each tetromino piece... Defining the remaining tetromino rotations and setting up the scoring system...\n\nNow I'm establishing the gravity mechanics—pieces fall faster at higher levels, bottoming out at 50ms per drop. I'm also laying out the core Tetris class structure with the canvas context and board state.\n\nSetting up the game properties... Setting up the game state with initial values, then I'm implementing a bag randomizer that shuffles through all seven piece types to ensure fair distribution, and defining helper methods to retrieve piece shapes and spawn new pieces. Writing collision detection... Writing rotation logic... Writing the game logic... Writing input handler... Setting up the game loop with delta time capping to prevent performance issues, then handling the horizontal movement with delayed auto-shift timing for both left and right directions, and now moving into gravity calculations.\n\nHandling soft drop mechanics where holding down accelerates the piece fall rate and awards points, then checking if the piece can move down or if it needs to lock in place. After that, I'm setting up the rendering system by getting the canvas context and dimensions along with the base positioning offsets.\n\nNow I'm drawing the game board visuals... Writing the piece rendering... Writing overlay text... Writing the block rendering logic... Drawing the preview blocks with shading effects, then moving on to render the stats section below showing the current score and level.\n\nNow I'm setting up the controls display with a list of keyboard inputs and their corresponding actions. Writing utility functions... Setting up the canvas initialization and verifying the layout dimensions—the board takes up 300×600 pixels starting at position 20,20, the side panel sits at x=344 with width 140, and I'm settling on a canvas width of 500 to give proper margins around everything while keeping the total height at 640.\n\nNow I'm working through the panel positioning more carefully, stacking the NEXT preview box, score, level, and lines displays vertically with appropriate spacing, then fitting the controls section below—everything fits comfortably within the board's 600-pixel height. The LINES box sits at y=268 with height 56, ending at 324. Controls start at y=340 with the header, then the list runs from 354 down to 459—all fitting comfortably within the 640px canvas height. The stat boxes have consistent 8px gaps between them, which looks clean.\n\nNow I'm checking the NEXT piece preview positioning. The calculation centers pieces vertically within an 80px space, but for taller pieces like the I tetromino (88px tall), it actually overflows upward by 4px and overlaps the label. Smaller pieces like the O tetromino (44px) center properly with plenty of breathing room.\n\nThe real issue is that the I piece's spawn orientation is mostly empty rows—it's only 1 row visually but takes up a 4x4 matrix. I should compute a tighter bounding box that only measures the actual occupied cells instead of the full matrix dimensions.\n\nComputing tight bounding box... I'm adjusting the preview sizing to fit pieces better—I'll use a 20px cell size with a 120px tall NEXT box, which gives enough room to center smaller pieces like the I tetromino while keeping everything proportional.\n\nNow I'm switching to a tighter bounding box approach instead of fixed offsets. I'm writing a helper function that finds the minimal bounds of the actual shape...\n\nWriting preview rendering logic... Writing the preview rendering... I need to handle the first frame's delta time carefully—if `lastTs` starts at 0, the initial dt could be huge since the timestamp is measured from page load. I'll cap it at 100ms and set `lastTs` on the first frame to avoid that spike.\n\nRefining the cap further...\n\nNow I'm writing out the actual implementation. The `isValid` function needs to handle checking different rotations without modifying the current piece, so I'm creating a helper that takes an optional rotation parameter and uses it to look up the correct shape state while keeping the position calculations based on the current piece's coordinates.\n\nFor rendering, I'm deciding between clipping the canvas to the board boundaries or just skipping cells that fall outside the visible area. Since pieces already have bounds checks for the vertical axis, I need to handle the horizontal edges too—cells that partially extend beyond the left or right edge of the board.\n\nActually, looking at the constraints: pieces start at x >= 0 and the board begins at BX, so there's no overflow on the left. Similarly, pieces are constrained to fit within COLS-1, so the right edge is safe. The only problematic edge is the top, where spawning pieces at y < 0 could have cells partially above the board. My current condition skips cells entirely above the board, but partially visible cells would still render fully, which looks slightly off at spawn time. I could use canvas clipping to handle this properly, though it's a minor visual issue that only happens briefly.\n\nSetting up canvas clipping...\n\nNow I'm finalizing the canvas dimensions: the board is 300px wide and 600px tall starting at (20, 20), the panel sits at x=340 with width 140, and accounting for margins, the total canvas should be 496 pixels wide and 640 pixels tall.\n\nI'm noticing a bug in my `clearLines` function where the loop logic doesn't properly handle row removal. I'm verifying the logic of the splice and unshift operations—after removing the full row at index r and adding an empty row at the start, the row that was at r-1 is now at r, so I need to check it again without decrementing. The loop will eventually terminate when r reaches 0 and the empty row fails the fullness check. The clearLines logic checks out. Now I'm ready to write all the files. For a Tetris (four lines cleared at once), my function naturally handles it—clearing all four full rows and returning a count of 4, which gives a score of 800 times the current level. The level-up mechanic increments every 10 lines using a simple formula that maps 0 lines to level 1, 10 lines to level 2, and so on. Now I need to think through the display logic.\n\nI should skip fancy level-up animations for now and focus on writing the actual code. One thing I want to make sure of: the key handler already prevents hardDrop and rotation when the game is paused or over, so that's covered. But I also need to handle the case where `this.over` gets set during the `lock()` function—both when a new piece overlaps on spawn and when a piece is placed above the board. Let me trace through the logic to make sure both scenarios are handled correctly. I'll keep that behavior since the game ends anyway once `this.over` is set. Now I'm ready to start writing the actual implementation files. Before I do, let me double-check the S-piece rotation states to make sure they're correct—I want to verify that rotating from state 0 produces the right configuration for state 1. I'm verifying the rotation formula against the standard Tetris S piece, and there's a mismatch between what I calculated and what the expected rotation should be. Let me look up the correct SRS rotation states for the S piece to see where the discrepancy is. I'm realizing my rotation formula isn't producing the correct SRS states for the S piece. Let me trace through the calculation step by step to find where the discrepancy is between my computed rotation and the actual SRS specification. I'm getting a mismatch between my calculated rotation and the actual SRS states for the S piece—my matrix rotation gives a different result than what the standard Tetris rotation system specifies, so I need to reconsider whether SRS uses pure rotation or applies specific offset tables instead.\n\nLet me visualize the S piece rotating clockwise manually: the shape that looks like a tilted S, when rotated 90° clockwise, should transform into a vertical orientation where the blocks stack differently, giving me that characteristic vertical S pattern.\n\nNow I'm checking this against the SRS rotation states and realizing my pure matrix rotation formula produces a different result—the blocks end up shifted one column to the right compared to what SRS specifies. The issue is that SRS uses the center of the 3x3 grid as the rotation pivot, whereas a straightforward mathematical matrix rotation doesn't account for that centering. Rather than trying to match pure rotation math, Tetris implementations typically just use predefined rotation states for each piece, which is what SRS does. for the actual block positions. The visual difference is that my S rotated piece appears shifted right compared to SRS, which would cause it to jump when rotating—something that might feel off to players familiar with standard Tetris. For proper SRS compliance, I should use the exact rotation states from the official specification.\n\nLooking up the SRS rotation matrices for S and Z pieces...\n\nDefining the rotation states...\n\nComparing my original S piece rotations against the standard SRS definitions and finding some mismatches in the intermediate states. I'm seeing that my rotation states don't match the standard SRS definitions—my state 1 and state 3 are flipped compared to the reference. State 2 matches perfectly, but the others are mirror images. Rather than debug my implementation further, I should just use the correct SRS rotation states directly.\n\nDefining the I piece states... I'm verifying the SRS rotation states match my implementation, and they do. Now I need to think through the S piece spawn state more carefully—specifically which blocks are positioned where in that initial configuration. I'm realizing my rotated S piece positions it differently than the standard SRS rotation—mine shifts one column to the right. This matters because in an actual game, rotating a piece shouldn't cause it to slide unexpectedly. I need to switch to the official SRS states to avoid this frustrating behavior and ensure rotations work correctly. I'm realizing my rotation states are backwards—states 1 and 3 are swapped compared to the standard SRS sequence. My current setup has the clockwise and counterclockwise rotations inverted, so I need to swap those two states to fix the rotation logic. Verifying the Z piece rotations against the SRS standard—I've confirmed the first three states match, but now I need to work through the L rotation manually to see what the correct state should be. I've verified the Z states are rotating correctly in clockwise order, so now I'm working through the S piece states with the same rotation logic to make sure those are also accurate. Continuing the rotation, I'm computing state 2 by rotating state 1 clockwise, which gives me the S-piece in its second orientation—a horizontal line at the bottom with two blocks stacked on the left. Now I'm applying another clockwise rotation to get state 3. Verifying the rotation cycles back correctly by applying the clockwise transformation to state 3 and checking that each position maps to the expected value in the starting configuration. I'm noticing my rotation states don't match the standard SRS system—my states 1 and 3 are swapped, which means I'm actually rotating counterclockwise when I increment. To align with proper Tetris behavior, I need to swap those states so state 1 becomes what I had as state 3, and continue building out the corrected rotation table. I'm working through the rotation math for the S-piece and realizing it has 2-fold rotational symmetry—rotating clockwise twice brings it back to the original state, which explains why I'm getting only two distinct visual configurations instead of four.\n\nBut wait, SRS actually defines four rotation states for S and Z pieces anyway, not because the piece looks different, but because the offset positions change with each rotation to handle wall kicks correctly. Let me recalculate what state 2 should actually be when I rotate the R-piece clockwise—I'm getting a different result than expected, so something's off in my transformation logic. I'm realizing the S piece has 2-fold rotational symmetry, so rotating CW twice returns to the original state. But SRS defines four distinct states (0, R, 2, L), which means the grid positions must be shifting even when the visual shape repeats—pure rotation alone can't explain the state transitions SRS specifies.\n\nLooking at the actual grid positions, state 0 and state 2 have the same shape but shifted vertically, and states R and L occupy different column ranges entirely. So SRS uses all four states to account for both the piece's orientation and its position on the board, not just its visual rotation.\n\nWhen I physically rotate state R clockwise, I get state 0, but SRS specifies state R rotates to state 2 instead. This discrepancy points to how SRS defines rotation around a specific pivot point rather than just the geometric center of the 3x3 bounding box. For the S piece, the pivot isn't at the center cell but somewhere else that causes this offset behavior.\n\nNow I'm working through the rotation formula around the actual pivot point to see how the coordinates transform and why the SRS state system produces a different result than naive geometric rotation. I'm seeing that rotating state R by 90° clockwise actually gives me state 0, not state 2 as I'd expect. Looking at what SRS state 2 actually is, it's clearly different from a simple rotation of state R, so the SRS system must be using a different approach for how these rotation states connect.\n\nNow I'm realizing that SRS defines each rotation state not just by the piece shape, but also by applying positional offsets alongside the rotation. That's what creates the illusion of different positions on the grid—the offset is baked into how each state is defined. For pieces like S and Z, many non-SRS implementations just use 2 states since they have 2-fold symmetry anyway, but I should think about what actually feels right visually for my game rather than strictly following the mathematical rotation.\n\nLooking at my S piece states, I'm seeing that incrementing rotation goes from state 0 to state 1, but visually that's a counter-clockwise rotation, not clockwise. The opposite happens when I go backwards to state 3. My rotation direction is inverted.\n\nThe cleanest fix is to swap states 1 and 3 in my S array so that incrementing actually produces the visual rotation the user expects. I'm reordering the states so state 1 becomes the right-facing rotation and state 3 becomes the left-facing one.\n\nNow I'm checking whether this matches the visual rotation: going from the spawn state to state 1 should show a clockwise rotation of the S piece. It does look correct visually, even though mathematically it doesn't follow a pure matrix rotation—but for gameplay purposes, what matters is that the piece rotates the way players expect when they press the button. So incrementing through the rotation states follows the SRS sequence for clockwise rotation. Now I'm checking whether the visual transformation from state R to state 2 actually looks like a 90° clockwise rotation—examining the S-tetromino shape as it shifts from a vertical orientation to a horizontal one. I'm observing the actual rotation sequence by watching how the S piece transforms: it cycles through horizontal, left-leaning vertical, horizontal (shifted down), right-leaning vertical, and back to horizontal. Matching these to the SRS states, I can see the pattern clearly now—each 90° clockwise rotation moves through these four distinct orientations, with the vertical states differing in which side the protruding block leans toward. I'm verifying the rotation logic by working through a concrete example with the S piece. Starting from state 0 where the piece forms an S shape, I need to trace what happens when I rotate it 90 degrees clockwise—the top portion shifts right, the right side moves down, and so on. Let me map out how the filled cells transform through this rotation to confirm the state transitions are correct. I need to clarify the rotation formula I'm using. The correct formula for a 90° clockwise rotation is `new[r][c] = old[N-1-c][r]`, so let me apply that to state R and work through the matrix transformation step by step.\n\nWorking through each position, I get the result `[[0,1,1],[1,1,0],[0,0,0]]`, which is state 0. But SRS defines CW rotation of state R as state 2, so SRS clearly isn't using pure mathematical matrix rotation—it's using predefined state mappings instead.\n\nNow I'm deciding between two approaches: stick with pure matrix rotation where states cycle through mathematically rotated versions, or match SRS's specific state definitions for visual correctness. If I go with pure rotation, I can trace how each state transforms through a full cycle, though the states won't align with SRS's standard definitions.\n\nLet me verify whether the transition from state 0 to state 1 actually represents a clockwise rotation visually. I'm checking the transformation formula to see if rotating the initial state 90 degrees clockwise produces state 1 or if it gives me a different state entirely. I need to reconsider the rotation formula itself. For a 90° clockwise rotation, the mapping should be new[r][c] = old[N-1-c][r], which means elements shift in a specific pattern around the matrix. Let me verify this works correctly by applying it to state 0 and checking if I get the expected result. I need to reconsider the mapping more carefully. If a cell at position (r, c) moves to (c, N-1-r), then to find what goes into position (r, c) in the new matrix, I need to reverse that: new[r][c] comes from old[N-1-c][r]. Let me verify this with the actual values for the 3×3 matrix.\n\nBut wait—there's a mismatch between what the math gives me and what rotating the S piece visually should produce. Let me trace through the physical rotation step by step to see where the discrepancy is. what was the \"right\" side. After rotating 90° clockwise, I need to think through the transformation more carefully. The top row becomes the rightmost column, the bottom row becomes the leftmost column, the left column becomes the top row, and the right column becomes the bottom row. So each new row corresponds to reading an original column from bottom to top. Let me apply this to the S piece by taking each column and reversing it to get the new rows. → new row 1 = [0,1,1]\nOriginal column 2: rows 0,1,2 = 1,0,0 → bottom-to-top = 0,0,1 → new row 2 = [0,0,1]\n\nNew matrix:\n```\n. # .\n. # #\n. . #\n```\n= `[[0,1,0],[0,1,1],[0,0,1]]`\n\nSo both the mathematical approach and visual rotation give me `[[0,1,0],[0,1,1],[0,0,1]]`. But I claimed earlier that rotating the S piece clockwise should produce `[[1,0,0],[1,1,0],[0,1,0]]` according to SRS. That doesn't match, so let me reconsider the actual rotation.\n\nStarting with the S piece in its initial state and thinking through what a 90° clockwise rotation actually does physically—the top edge becomes the right edge, the left edge becomes the top. Let me trace through this more carefully with the actual grid positions. I'm verifying that both my physical rotation and the mathematical formula produce the same result—the new matrix represents SRS L, not SRS R as I initially thought, so my two approaches are actually consistent. then earlier I said \"physically rotating state 0 CW gives `[[1,0,0],[1,1,0],[0,1,0]]`\", which is SRS R. That was wrong!\n\nLet me also verify: is `[[0,1,0],[0,1,1],[0,0,1]]` the SRS L state?\n\nSRS L for S is `[[0,1,0],[1,1,0],[1,0,0]]`... wait, I need to look this up properly.\n\nThe SRS L state for S should be: starting from state 0, rotating CCW. CCW from state 0 = the state before 0, which is state 3 in a 4-state cycle.\n\nIf the CW cycle is 0→1→2→3→0, then CCW is 0→3→2→1→0.\n\nNow I'm checking my mathematical rotation against the actual SRS cycle. When I rotate state 0 clockwise mathematically, I get `[[0,1,0],[0,1,1],[0,0,1]]`, which matches SRS's L state. Comparing my full rotation sequence against SRS's documented states, my state 1 corresponds to SRS L, state 2 to SRS 2, and state 3 to SRS R—so the cycle is 0 → R → 2 → L → 0 in SRS notation. Now I'm verifying this by checking the actual coordinates—state 0 has blocks at specific positions, and I need to see what a true 90° clockwise rotation would produce versus what the SRS formula gives. I think I've been mixing up my rotation directions. Let me clarify what clockwise actually means when looking at the Tetris board—the top moves right, right goes down, bottom goes left, and left goes up. So I need to recalculate the cell transformation formula based on this visual definition rather than the abstract math I was using.\n\nFor a 90° clockwise rotation, a cell at position (r, c) maps to (c, N-1-r). Testing this on my four cells gives me the new shape, which turns out to be the S tetromino.\n\nBut wait—the SRS rotation system says rotating the 0 state clockwise should give the R state, not S. I'm realizing there might be confusion about what \"clockwise\" means in Tetris. When the player presses rotate, does the piece spin clockwise as they see it on screen? And since screen coordinates have Y increasing downward, what appears clockwise visually might actually correspond to a different mathematical direction.\n\nLet me verify my rotation formula against what the official Tetris guideline actually specifies for the L-piece.\n\nLooking at the S piece specifically: rotating it 90° clockwise should transform the landscape orientation into portrait, but my formula is producing the opposite result—it's giving me the counterclockwise rotation instead of clockwise. This means I need to reconsider whether my coordinate transformation is actually correct for screen-based rotations. So the key difference is just positioning within the bounding box—SRS R aligns the rotated S piece to the left while my approach puts it on the right. Both are valid representations of the same rotated shape, but SRS's left-aligned choice is the standard convention that affects how wall kicks and rotation feel in actual gameplay. For my implementation, I can use either approach depending on what works best. work. The key difference is:\n1. Using my formula: rotating CW appears to shift the piece slightly right\n2. Using SRS states: rotating CW keeps the piece position more stable\n\nFor a good Tetris game, SRS states are preferred. But implementing pure SRS with wall kick tables is complex. For simplicity, I'll use my mathematically-derived states (my CW formula) and just accept the slight shift.\n\nThe user won't notice this too much, especially since it's consistent. My states are mathematically correct, derived from pure CW matrix rotation, and they maintain the S shape across all four rotations. What really matters for playability is that the piece can be placed in all expected positions and rotation feels natural when pressing the CW button. Whether my rotation states match the official SRS convention exactly doesn't affect whether the game is fair and fun to play.\n\nI should stick with my original states since they're mathematically sound and should result in a playable game. But I need to double-check my earlier concern about whether these states actually produce CCW rotation instead of CW when the player presses the rotate button. new[r][c] = old[N-1-c][r]\n\nState 0 = `[[0,1,1],[1,1,0],[0,0,0]]` (N=3)\n\nLet me work through the rotation cell by cell. For each position in the new grid, I'm pulling from the corresponding old position using the formula. Starting with the first row: new[0][0] gets old[2][0] which is 0, new[0][1] gets old[1][0] which is 1, new[0][2] gets old[0][0] which is 0. Moving to the second row: new[1][0] gets old[2][1] which is 0, new[1][1] gets old[1][1] which is 1, new[1][2] gets old[0][1] which is 1. And for the third row, I'm pulling from column 2 of the old state...\n\nNow I'm tracing where the actual visual blocks move after a clockwise rotation. Using the transformation (r,c) → (c, N-1-r), I can map each block's new position: the block at (0,1) moves to (1,2), the block at (0,2) moves to (2,2), and the block at (1,0) moves to...\n\nActually, let me finish verifying this rotation. After mapping all four blocks through the transformation, I get the grid `[[0,1,0],[0,1,1],[0,0,1]]`, which forms a vertical S-shape on the right side of the 3x3 grid. Looking at the original state, the blocks were arranged with two on top-right and two on bottom-left in a diagonal pattern, and after rotating clockwise, they've shifted to form this S configuration.\n\nComparing this to the standard SRS rotation result, which places blocks at the top-left, center-left/center, and bottom-center, I can see both are valid 90° rotations of the S piece—just positioned differently horizontally on the grid. positions within the 3x3.\n\nVisually, which one looks more like a CW rotation to a Tetris player? If the S piece's bumps are on the right in landscape orientation, rotating clockwise should keep them on the right side—and my result does that with blocks at (0,1), (1,1), (1,2), (2,2), while SRS R puts them on the left at (0,0), (1,0), (1,1), (2,1).\n\nThe real gameplay difference is that these two rotations produce different absolute board positions: if a piece starts at column 4, my rotation and SRS's rotation would place the blocks at different columns, creating that visual \"jump\" some Tetris games have. SRS avoids this by keeping the center cell (1,1) as the invariant rotation point, whereas my formula doesn't maintain that constraint.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":0,"cache_read_input_tokens":4727,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"0c681e08-169e-4a0d-ac8d-f1ef69847a1e"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0122RiU7u8heDtan1Wd89ckP","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Let me start building a Tetris game in TypeScript. I'll create a complete, playable Tetris game that runs in the browser.\n\nLet me plan the structure:\n1. `index.html` - Main HTML file\n2. `src/tetris.ts` - Main TypeScript file\n3. `tsconfig.json` - TypeScript configuration\n4. `package.json` - Package configuration\n\nLet me create a complete Tetris game with all standard mechanics.","signature":"ErgEClsIDBgCKkCjo8HVSfwGe5x90JyvNG3LMt7VGIqjzrDnceJ8tNTXcD/MLQCk5m8ws7i5FRF0EXxM8/NFtOR3mJmxmuRYlJevMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgxpkK/owlYKHsF8aNkaDKyf2qZuOBTCql0HCCIwEDX3IuH9TTdetyOP4RmTO/MMs5i03AONMpKQyGRX31mLtQnN2vs/cUHIsI4d8qvEKooDjdSnkIXmCACUPReKGtPUzAvcpnAZk4Jk669d0zm7nUsFUdmIgeflGXE6/UqqdlwE9Lxw/U6m614s8Bx/LqwIJh5jznsnxwWWORLYUwuXR7Vq71PSTD0NrmHi5LIYpVuwfNQRTyKxYfkkuBTFmyZAHeU+U3fP543zmlP5KyD36OBXo+FSLiod1BS6wXSrJC+kv/fmSHi2TFpsIg+X2iMHJ+klPKt4t6MZSDZOWZMaveZ/dFqF+upI23JRgJCub8X42ec4o0Dqilyk6natXnwsRogRwoiTYuN/0W5qQaz2IG2GZIoxkTJ4bvyizAsz0laoPK/N/VpwuwK5KD5mhqWdMCMb9oG1hTA2xVsucAVZRQ+5+4nVidmDg5ik/LtQFB5FcYFJaeF5BrVdi6eeiBpEaK0Jw0zODBEBOjnj1tFGT+qrrNRoczEZZzAGXS51iZxGPzkPjr3NiBK8Sj3x8siOyJZ40jy17LMewncGooH3t2lpMMHyZahtR4RbcB8aSk73Z4cQ3T1UUFZivxgB"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":527,"cache_read_input_tokens":4241,"cache_creation":{"ephemeral_5m_input_tokens":527,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"2f6c3e94-e9dc-410e-b0ce-04d38bdcce0d"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0122RiU7u8heDtan1Wd89ckP","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Y9eKnCc5y4wGy4tCrSzEB7","name":"Bash","input":{"command":"ls /tmp/loop-bench-kncx228p","description":"List current directory contents"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":527,"cache_read_input_tokens":4241,"cache_creation":{"ephemeral_5m_input_tokens":527,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"fdba1206-568a-4f26-ab35-144be84d2f41"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Y9eKnCc5y4wGy4tCrSzEB7","type":"tool_result","content":"node_modules\npackage.json\npackage-lock.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"42e02162-5b2a-4197-9391-9251739e637d","timestamp":"2026-04-05T19:36:50.254Z","tool_use_result":{"stdout":"node_modules\npackage.json\npackage-lock.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MZBE1zcJQC9fUWVgeLEuVs","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01K1QHzVSehZ83upTP5tvUXV","name":"Read","input":{"file_path":"/tmp/loop-bench-kncx228p/package.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":230,"cache_read_input_tokens":4768,"cache_creation":{"ephemeral_5m_input_tokens":230,"ephemeral_1h_input_tokens":0},"output_tokens":68,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"9b8b2d75-18de-4bac-8869-174b1604c7ba"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01K1QHzVSehZ83upTP5tvUXV","type":"tool_result","content":"1\t{\n2\t \"name\": \"loop-bench-kncx228p\",\n3\t \"version\": \"1.0.0\",\n4\t \"description\": \"\",\n5\t \"main\": \"index.js\",\n6\t \"scripts\": {\n7\t \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n8\t },\n9\t \"keywords\": [],\n10\t \"author\": \"\",\n11\t \"license\": \"ISC\",\n12\t \"type\": \"commonjs\",\n13\t \"devDependencies\": {\n14\t \"@eslint/js\": \"^10.0.1\",\n15\t \"@types/node\": \"^25.5.2\",\n16\t \"eslint\": \"^10.2.0\",\n17\t \"typescript\": \"^6.0.2\"\n18\t }\n19\t}\n20\t"}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"47bac1cf-21dd-4115-b1ea-9b492f479db9","timestamp":"2026-04-05T19:36:52.123Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-kncx228p/package.json","content":"{\n \"name\": \"loop-bench-kncx228p\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^25.5.2\",\n \"eslint\": \"^10.2.0\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","numLines":20,"startLine":1,"totalLines":20}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011xR72Nj8McgoRBzg4ELx4q","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Good, I have TypeScript available. Let me create the Tetris game. I'll create:\n1. `index.html` - Main HTML file with canvas\n2. `src/tetris.ts` - TypeScript source\n3. `tsconfig.json` - TypeScript configuration\n\nSince this runs in a browser without a build step complexity, I'll use a single TypeScript file that gets compiled to JavaScript, and reference it from the HTML. Let me write the full game.","signature":"Es0EClsIDBgCKkAEjO4VM3F/2uu7BcFjnJ+7Fwn5QcZ5J0RTEYXyDF8BM4qipbgVc6GS1KiDBFqKXOkWyVHRG1KsSc7VRJZYxPEXMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgwd3ZT2Ju58LzVvzB8aDO0gHOLUS/Tj5+IldSIw1sTCrkgIup6UHTtSJoGEGmMmF7v0YCBZwb4IjT03FQ8A5MWYPZ/O/q4eAyjqgJ7WKp8DyOGidHGXp9WQVYNPdt4twXDz+RwT+nI1armuY+latzysT0TTxKE7O/DnL/WrFu1rA7389yvywPPbKiQb74MgrdYOJ744x0AI+17Ttfoz1MhBvEYEmLKJfoYfQhLxM/StOGZPGCO1rMv+S66yQZQLNKa9kc++Q1NrO48nKCYnj1N6nmuX+8MhoNMdtLM5fpyONO9WIx1hTCKcCXwkg751iIH7stMuEXjwqiapMpbABhL4bgIBNhMxgQQw7IFdxPsJtZGozJsRR5q1EPS+1KVw39I1D3Pi38R9c8RAW4PiRTUizZFeP8atQxdq1qivdBFwj5K96104sqw3DH51wsbgJJUnauB1Kfa9Hg/vqfO2U+H+hHt0EelDgdVb/VqIpumYtUilCGh2nvqxez6s/t84U4+ZtkFNYIUoi3iAHma/aT9ul18S+RMMsneAnhfCnVI2AnaCZU7qWyszQeTSiGwionjN60Axo1g3VOlrf41nd6INBqzmwDXngQD4zqNzT0YLUq4AAmT9+5UcyWEY3UxC3QHAAuEBOizsoxPrXtnyPxgB"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":296,"cache_read_input_tokens":4998,"cache_creation":{"ephemeral_5m_input_tokens":296,"ephemeral_1h_input_tokens":0},"output_tokens":12,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"05802d6e-e6ce-49e7-8412-e6d0942bcc1b"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011xR72Nj8McgoRBzg4ELx4q","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_0192R23keXEyQCrCuk2Qov1D","name":"Bash","input":{"command":"ls /tmp/loop-bench-kncx228p/node_modules | head -20","description":"Check available node modules"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":296,"cache_read_input_tokens":4998,"cache_creation":{"ephemeral_5m_input_tokens":296,"ephemeral_1h_input_tokens":0},"output_tokens":12,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"af4ccc4d-d448-465f-87ce-30225e9436d0"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_0192R23keXEyQCrCuk2Qov1D","type":"tool_result","content":"acorn\nacorn-jsx\najv\nbalanced-match\nbrace-expansion\ncross-spawn\ndebug\ndeep-is\nescape-string-regexp\n@eslint\neslint\n@eslint-community\neslint-scope\neslint-visitor-keys\nespree\nesquery\nesrecurse\nestraverse\nesutils\nfast-deep-equal","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"e0f4cbb6-b209-4edb-846e-07cca0666eee","timestamp":"2026-04-05T19:36:55.560Z","tool_use_result":{"stdout":"acorn\nacorn-jsx\najv\nbalanced-match\nbrace-expansion\ncross-spawn\ndebug\ndeep-is\nescape-string-regexp\n@eslint\neslint\n@eslint-community\neslint-scope\neslint-visitor-keys\nespree\nesquery\nesrecurse\nestraverse\nesutils\nfast-deep-equal","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01G2TEhaZR7FspaRMGXD8afJ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_0152WHDtKv3avkUttMCXWGqQ","name":"Bash","input":{"command":"cat /tmp/loop-bench-kncx228p/node_modules/.bin/tsc --version 2>/dev/null || /tmp/loop-bench-kncx228p/node_modules/.bin/tsc --version","description":"Check TypeScript version"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":307,"cache_read_input_tokens":5294,"cache_creation":{"ephemeral_5m_input_tokens":307,"ephemeral_1h_input_tokens":0},"output_tokens":58,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"6f4e8253-21c3-4b8a-ba62-be1cb615dd6a"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_0152WHDtKv3avkUttMCXWGqQ","type":"tool_result","content":"cat (GNU coreutils) 9.4\nCopyright (C) 2023 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n\nWritten by Torbjörn Granlund and Richard M. Stallman.","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"8de695a1-84fe-4bd6-8690-6f9a04508233","timestamp":"2026-04-05T19:36:58.448Z","tool_use_result":{"stdout":"cat (GNU coreutils) 9.4\nCopyright (C) 2023 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n\nWritten by Torbjörn Granlund and Richard M. Stallman.","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01QKgUKKcTzkNWyRMFFdnRtt","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01JBcvuSTmEAaZepFrSrinCV","name":"Bash","input":{"command":"/tmp/loop-bench-kncx228p/node_modules/.bin/tsc --version","description":"Check TypeScript compiler version"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":240,"cache_read_input_tokens":5601,"cache_creation":{"ephemeral_5m_input_tokens":240,"ephemeral_1h_input_tokens":0},"output_tokens":68,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"9c9d05c2-f6db-482c-b6fb-e551a294b813"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01JBcvuSTmEAaZepFrSrinCV","type":"tool_result","content":"Version 6.0.2","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"fdc767fd-3002-4881-88e4-86743126f748","timestamp":"2026-04-05T19:37:00.609Z","tool_use_result":{"stdout":"Version 6.0.2","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01PFiEZPPAQfQ7cWpywAHcx1","type":"message","role":"assistant","content":[{"type":"text","text":"Now let me build the complete Tetris game:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":114,"cache_read_input_tokens":5841,"cache_creation":{"ephemeral_5m_input_tokens":114,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"6905bbaa-56d0-4a07-8b5d-7735dc4361c3"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01PFiEZPPAQfQ7cWpywAHcx1","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01J7quE6GbEwK45LaExyv8j5","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-kncx228p/src","description":"Create src directory"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":114,"cache_read_input_tokens":5841,"cache_creation":{"ephemeral_5m_input_tokens":114,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"ceb3fb4e-702e-44ec-b1ee-67a6cdf20869"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01J7quE6GbEwK45LaExyv8j5","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"dee3e3fb-0e84-463f-b6d4-4682affa8f71","timestamp":"2026-04-05T19:37:02.500Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":true}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01QNW8QaZn2vjT6P2VPjFz8g","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01YXGsG27jTb61yC6MWdANEQ","name":"Bash","input":{"command":"cat > /tmp/loop-bench-kncx228p/tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ES2020\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"lib\": [\"ES2020\", \"DOM\"]\n },\n \"include\": [\"src/**/*\"]\n}\nEOF","description":"Create tsconfig.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":117,"cache_read_input_tokens":5955,"cache_creation":{"ephemeral_5m_input_tokens":117,"ephemeral_1h_input_tokens":0},"output_tokens":73,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"3c76174f-fa64-45ef-b5b3-e74201a21cd5"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01YXGsG27jTb61yC6MWdANEQ","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"4867a84c-d459-485c-8c79-88d13b315694","timestamp":"2026-04-05T19:37:05.309Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_016xReqFQGJG9KKNRfEC46xD","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01M7WpUqhGFxHxQBbfYYQYUL","name":"Bash","input":{"command":"cat > /tmp/loop-bench-kncx228p/src/tetris.ts << 'TSEOF'\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 30; // px per cell on the main board\nconst PREVIEW_BLOCK = 24; // px per cell in the preview box\n\n// Colours for each tetromino (index 0 = empty)\nconst COLORS: string[] = [\n \"transparent\", // 0 – empty\n \"#00CFCF\", // 1 – I (cyan)\n \"#1E90FF\", // 2 – J (blue)\n \"#FF8C00\", // 3 – L (orange)\n \"#FFD700\", // 4 – O (yellow)\n \"#32CD32\", // 5 – S (green)\n \"#A020F0\", // 6 – T (purple)\n \"#FF3030\", // 7 – Z (red)\n];\n\n// Tetromino shapes – each piece is defined as all 4 rotations (arrays of [row,col] offsets)\ntype Cells = [number, number][];\n\ninterface PieceDef {\n rotations: Cells[];\n colorIndex: number;\n}\n\nfunction rotateCW(cells: Cells): Cells {\n // Rotate 90° clockwise: (r, c) → (c, -r)\n return cells.map(([r, c]) => [c, -r]);\n}\n\nfunction normalise(cells: Cells): Cells {\n const minR = Math.min(...cells.map(([r]) => r));\n const minC = Math.min(...cells.map(([, c]) => c));\n return cells.map(([r, c]) => [r - minR, c - minC]);\n}\n\nfunction buildRotations(base: Cells): Cells[] {\n const rots: Cells[] = [normalise(base)];\n for (let i = 0; i < 3; i++) {\n rots.push(normalise(rotateCW(rots[rots.length - 1])));\n }\n return rots;\n}\n\nconst PIECES: PieceDef[] = [\n // I\n { rotations: buildRotations([[0,0],[0,1],[0,2],[0,3]]), colorIndex: 1 },\n // J\n { rotations: buildRotations([[0,0],[1,0],[1,1],[1,2]]), colorIndex: 2 },\n // L\n { rotations: buildRotations([[0,2],[1,0],[1,1],[1,2]]), colorIndex: 3 },\n // O\n { rotations: buildRotations([[0,0],[0,1],[1,0],[1,1]]), colorIndex: 4 },\n // S\n { rotations: buildRotations([[0,1],[0,2],[1,0],[1,1]]), colorIndex: 5 },\n // T\n { rotations: buildRotations([[0,1],[1,0],[1,1],[1,2]]), colorIndex: 6 },\n // Z\n { rotations: buildRotations([[0,0],[0,1],[1,1],[1,2]]), colorIndex: 7 },\n];\n\n// Scoring table (points per lines cleared simultaneously)\nconst SCORE_TABLE = [0, 100, 300, 500, 800];\n\n// Initial drop interval in ms\nconst BASE_INTERVAL = 800;\n// Interval decrease per level (ms)\nconst LEVEL_SPEED = 60;\n// Minimum interval\nconst MIN_INTERVAL = 80;\n\n// ─── Game State ───────────────────────────────────────────────────────────────\n\ntype Board = number[][]; // ROWS × COLS, value = colorIndex\n\ninterface Piece {\n def: PieceDef;\n rotIdx: number;\n row: number;\n col: number;\n}\n\nfunction createBoard(): Board {\n return Array.from({ length: ROWS }, () => Array(COLS).fill(0));\n}\n\nfunction randomPiece(): Piece {\n const def = PIECES[Math.floor(Math.random() * PIECES.length)];\n const cells = def.rotations[0];\n const maxCol = Math.max(...cells.map(([, c]) => c));\n const col = Math.floor((COLS - maxCol - 1) / 2);\n return { def, rotIdx: 0, row: 0, col };\n}\n\nfunction pieceCells(p: Piece): Cells {\n return p.def.rotations[p.rotIdx].map(([r, c]) => [r + p.row, c + p.col]);\n}\n\nfunction collides(board: Board, cells: Cells): boolean {\n for (const [r, c] of cells) {\n if (r >= ROWS || c < 0 || c >= COLS) return true;\n if (r >= 0 && board[r][c] !== 0) return true;\n }\n return false;\n}\n\n// ─── Renderer ─────────────────────────────────────────────────────────────────\n\nclass Renderer {\n private ctx: CanvasRenderingContext2D;\n private pCtx: CanvasRenderingContext2D;\n\n constructor(\n private canvas: HTMLCanvasElement,\n private previewCanvas: HTMLCanvasElement,\n ) {\n this.ctx = canvas.getContext(\"2d\")!;\n this.pCtx = previewCanvas.getContext(\"2d\")!;\n }\n\n drawBlock(ctx: CanvasRenderingContext2D, r: number, c: number, color: string, size: number): void {\n const x = c * size;\n const y = r * size;\n const inset = 2;\n\n ctx.fillStyle = color;\n ctx.fillRect(x, y, size, size);\n\n // Highlight top-left\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(x + inset, y + inset, size - inset * 2, inset);\n ctx.fillRect(x + inset, y + inset, inset, size - inset * 2);\n\n // Shadow bottom-right\n ctx.fillStyle = \"rgba(0,0,0,0.25)\";\n ctx.fillRect(x + inset, y + size - inset * 2, size - inset * 2, inset);\n ctx.fillRect(x + size - inset * 2, y + inset, inset, size - inset * 2);\n }\n\n drawBoard(board: Board): void {\n const { ctx } = this;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid background\n ctx.fillStyle = \"#111827\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Subtle grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.05)\";\n ctx.lineWidth = 0.5;\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(COLS * BLOCK, r * BLOCK);\n ctx.stroke();\n }\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, ROWS * BLOCK);\n ctx.stroke();\n }\n\n // Locked blocks\n for (let r = 0; r < ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n if (board[r][c] !== 0) {\n this.drawBlock(ctx, r, c, COLORS[board[r][c]], BLOCK);\n }\n }\n }\n }\n\n drawGhost(board: Board, piece: Piece): void {\n // Find lowest valid position\n let ghostPiece = { ...piece };\n while (true) {\n const next = { ...ghostPiece, row: ghostPiece.row + 1 };\n if (collides(board, pieceCells(next))) break;\n ghostPiece = next;\n }\n if (ghostPiece.row === piece.row) return;\n\n const { ctx } = this;\n for (const [r, c] of pieceCells(ghostPiece)) {\n if (r < 0) continue;\n const x = c * BLOCK;\n const y = r * BLOCK;\n ctx.strokeStyle = COLORS[piece.def.colorIndex];\n ctx.lineWidth = 2;\n ctx.strokeRect(x + 1, y + 1, BLOCK - 2, BLOCK - 2);\n }\n }\n\n drawPiece(piece: Piece): void {\n const { ctx } = this;\n for (const [r, c] of pieceCells(piece)) {\n if (r < 0) continue;\n this.drawBlock(ctx, r, c, COLORS[piece.def.colorIndex], BLOCK);\n }\n }\n\n drawPreview(next: Piece): void {\n const { pCtx, previewCanvas } = this;\n const size = PREVIEW_BLOCK;\n pCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);\n pCtx.fillStyle = \"#111827\";\n pCtx.fillRect(0, 0, previewCanvas.width, previewCanvas.height);\n\n const cells = next.def.rotations[0];\n const maxR = Math.max(...cells.map(([r]) => r));\n const maxC = Math.max(...cells.map(([, c]) => c));\n const offR = Math.floor((previewCanvas.height / size - maxR - 1) / 2);\n const offC = Math.floor((previewCanvas.width / size - maxC - 1) / 2);\n\n for (const [r, c] of cells) {\n this.drawBlock(pCtx, r + offR, c + offC, COLORS[next.def.colorIndex], size);\n }\n }\n}\n\n// ─── Game ─────────────────────────────────────────────────────────────────────\n\ntype GameState = \"idle\" | \"playing\" | \"paused\" | \"gameover\";\n\nclass TetrisGame {\n private board: Board = createBoard();\n private current: Piece = randomPiece();\n private next: Piece = randomPiece();\n private score = 0;\n private lines = 0;\n private level = 1;\n private state: GameState = \"idle\";\n private lastDrop = 0;\n private animId = 0;\n\n private renderer: Renderer;\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitleEl: HTMLElement;\n private overlayMsgEl: HTMLElement;\n private startBtn: HTMLElement;\n\n constructor() {\n const canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n const preview = document.getElementById(\"preview\") as HTMLCanvasElement;\n this.renderer = new Renderer(canvas, preview);\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitleEl = document.getElementById(\"overlay-title\")!;\n this.overlayMsgEl = document.getElementById(\"overlay-msg\")!;\n this.startBtn = document.getElementById(\"start-btn\")!;\n\n this.startBtn.addEventListener(\"click\", () => this.startOrRestart());\n document.addEventListener(\"keydown\", (e) => this.handleKey(e));\n\n this.showOverlay(\"TETRIS\", \"Press Start or Enter to play\");\n }\n\n private get dropInterval(): number {\n return Math.max(MIN_INTERVAL, BASE_INTERVAL - (this.level - 1) * LEVEL_SPEED);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitleEl.textContent = title;\n this.overlayMsgEl.textContent = msg;\n this.overlayEl.style.display = \"flex\";\n }\n\n private hideOverlay(): void {\n this.overlayEl.style.display = \"none\";\n }\n\n private startOrRestart(): void {\n if (this.state === \"gameover\" || this.state === \"idle\") {\n this.board = createBoard();\n this.current = randomPiece();\n this.next = randomPiece();\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.updateUI();\n }\n if (this.state === \"paused\") {\n this.resume();\n return;\n }\n this.state = \"playing\";\n this.hideOverlay();\n this.lastDrop = performance.now();\n cancelAnimationFrame(this.animId);\n this.animId = requestAnimationFrame((t) => this.loop(t));\n }\n\n private pause(): void {\n if (this.state !== \"playing\") return;\n this.state = \"paused\";\n cancelAnimationFrame(this.animId);\n this.showOverlay(\"PAUSED\", \"Press P or Start to resume\");\n }\n\n private resume(): void {\n if (this.state !== \"paused\") return;\n this.state = \"playing\";\n this.hideOverlay();\n this.lastDrop = performance.now();\n this.animId = requestAnimationFrame((t) => this.loop(t));\n }\n\n private loop(timestamp: number): void {\n if (this.state !== \"playing\") return;\n\n if (timestamp - this.lastDrop >= this.dropInterval) {\n this.lastDrop = timestamp;\n this.drop();\n }\n\n this.render();\n this.animId = requestAnimationFrame((t) => this.loop(t));\n }\n\n private render(): void {\n this.renderer.drawBoard(this.board);\n this.renderer.drawGhost(this.board, this.current);\n this.renderer.drawPiece(this.current);\n this.renderer.drawPreview(this.next);\n }\n\n private drop(): void {\n const moved = { ...this.current, row: this.current.row + 1 };\n if (collides(this.board, pieceCells(moved))) {\n this.lock();\n } else {\n this.current = moved;\n }\n }\n\n private lock(): void {\n for (const [r, c] of pieceCells(this.current)) {\n if (r < 0) {\n this.gameOver();\n return;\n }\n this.board[r][c] = this.current.def.colorIndex;\n }\n this.clearLines();\n this.current = this.next;\n this.next = randomPiece();\n this.renderer.drawPreview(this.next);\n\n // Check if new piece immediately collides → game over\n if (collides(this.board, pieceCells(this.current))) {\n this.gameOver();\n }\n }\n\n private clearLines(): void {\n let cleared = 0;\n for (let r = ROWS - 1; r >= 0; r--) {\n if (this.board[r].every((v) => v !== 0)) {\n this.board.splice(r, 1);\n this.board.unshift(Array(COLS).fill(0));\n cleared++;\n r++; // re-check same row index\n }\n }\n if (cleared > 0) {\n this.score += SCORE_TABLE[cleared] * this.level;\n this.lines += cleared;\n this.level = Math.floor(this.lines / 10) + 1;\n this.updateUI();\n }\n }\n\n private gameOver(): void {\n this.state = \"gameover\";\n cancelAnimationFrame(this.animId);\n this.render();\n this.showOverlay(\"GAME OVER\", `Score: ${this.score} — Press Start to play again`);\n this.startBtn.textContent = \"Restart\";\n }\n\n private updateUI(): void {\n this.scoreEl.textContent = String(this.score);\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private moveLeft(): void {\n const moved = { ...this.current, col: this.current.col - 1 };\n if (!collides(this.board, pieceCells(moved))) this.current = moved;\n }\n\n private moveRight(): void {\n const moved = { ...this.current, col: this.current.col + 1 };\n if (!collides(this.board, pieceCells(moved))) this.current = moved;\n }\n\n private rotate(): void {\n const nextRotIdx = (this.current.rotIdx + 1) % this.current.def.rotations.length;\n const rotated = { ...this.current, rotIdx: nextRotIdx };\n // Wall-kick: try offsets 0, -1, +1, -2, +2\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n const candidate = { ...rotated, col: rotated.col + kick };\n if (!collides(this.board, pieceCells(candidate))) {\n this.current = candidate;\n return;\n }\n }\n }\n\n private rotateCCW(): void {\n const len = this.current.def.rotations.length;\n const nextRotIdx = (this.current.rotIdx + len - 1) % len;\n const rotated = { ...this.current, rotIdx: nextRotIdx };\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n const candidate = { ...rotated, col: rotated.col + kick };\n if (!collides(this.board, pieceCells(candidate))) {\n this.current = candidate;\n return;\n }\n }\n }\n\n private hardDrop(): void {\n while (true) {\n const moved = { ...this.current, row: this.current.row + 1 };\n if (collides(this.board, pieceCells(moved))) break;\n this.current = moved;\n this.score += 2;\n }\n this.updateUI();\n this.lock();\n }\n\n private softDrop(): void {\n const moved = { ...this.current, row: this.current.row + 1 };\n if (!collides(this.board, pieceCells(moved))) {\n this.current = moved;\n this.score += 1;\n this.updateUI();\n this.lastDrop = performance.now(); // reset auto-drop timer\n }\n }\n\n private handleKey(e: KeyboardEvent): void {\n if (e.key === \"Enter\") {\n if (this.state === \"idle\" || this.state === \"gameover\") {\n this.startOrRestart();\n return;\n }\n }\n if (e.key === \"p\" || e.key === \"P\") {\n if (this.state === \"playing\") { this.pause(); return; }\n if (this.state === \"paused\") { this.resume(); return; }\n }\n if (this.state !== \"playing\") return;\n\n switch (e.key) {\n case \"ArrowLeft\":\n case \"a\":\n case \"A\":\n e.preventDefault();\n this.moveLeft();\n break;\n case \"ArrowRight\":\n case \"d\":\n case \"D\":\n e.preventDefault();\n this.moveRight();\n break;\n case \"ArrowDown\":\n case \"s\":\n case \"S\":\n e.preventDefault();\n this.softDrop();\n break;\n case \"ArrowUp\":\n case \"w\":\n case \"W\":\n case \"x\":\n case \"X\":\n e.preventDefault();\n this.rotate();\n break;\n case \"z\":\n case \"Z\":\n e.preventDefault();\n this.rotateCCW();\n break;\n case \" \":\n e.preventDefault();\n this.hardDrop();\n break;\n }\n this.render();\n }\n}\n\n// ─── Bootstrap ────────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new TetrisGame();\n});\nTSEOF","description":"Write the main Tetris TypeScript source file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":210,"cache_read_input_tokens":6072,"cache_creation":{"ephemeral_5m_input_tokens":210,"ephemeral_1h_input_tokens":0},"output_tokens":60,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"13488d60-2d7f-4fa8-ac32-a054c58ddb19"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01M7WpUqhGFxHxQBbfYYQYUL","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"eec97108-3968-45af-8ced-6b7a91312a32","timestamp":"2026-04-05T19:38:01.660Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NUwNZNenxSe7Lw862PiYuM","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01GEbnbNR27rms9AncsiTKf5","name":"Bash","input":{"command":"node_modules/.bin/tsc --project tsconfig.json 2>&1","description":"Compile TypeScript to JavaScript"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":5445,"cache_read_input_tokens":6282,"cache_creation":{"ephemeral_5m_input_tokens":5445,"ephemeral_1h_input_tokens":0},"output_tokens":38,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"abc04e98-bf1a-4573-b6b8-543eb11db2ae"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01GEbnbNR27rms9AncsiTKf5","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"c3617556-9f5a-4108-913e-51efc1c930a2","timestamp":"2026-04-05T19:38:05.193Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01EDJUimeUnUqVuqkhhsXZyq","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_017t4vvtX93tsgipRtczBpGf","name":"Bash","input":{"command":"ls /tmp/loop-bench-kncx228p/dist/","description":"Check compiled output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":109,"cache_read_input_tokens":11727,"cache_creation":{"ephemeral_5m_input_tokens":109,"ephemeral_1h_input_tokens":0},"output_tokens":38,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"790b60ac-a9c8-4cdf-b27b-ec075732d150"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_017t4vvtX93tsgipRtczBpGf","type":"tool_result","content":"tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"4fb346cd-2966-4736-8b00-793c9a2e12f6","timestamp":"2026-04-05T19:38:07.421Z","tool_use_result":{"stdout":"tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Vm8dsNeuEzJwYHJMe6NFfT","type":"message","role":"assistant","content":[{"type":"text","text":"Good, compilation succeeded. Now create the HTML file:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":102,"cache_read_input_tokens":11836,"cache_creation":{"ephemeral_5m_input_tokens":102,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"cf7d8a75-ccf1-404d-8b6c-42ae8905db01"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Vm8dsNeuEzJwYHJMe6NFfT","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_014T9Nz1QHYooY9DeobrFk3x","name":"Bash","input":{"command":"cat > /tmp/loop-bench-kncx228p/index.html << 'EOF'\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <style>\n /* ── Reset & base ─────────────────────────────────────────────────── */\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n body {\n background: #0f172a;\n color: #e2e8f0;\n font-family: \"Segoe UI\", system-ui, sans-serif;\n display: flex;\n justify-content: center;\n align-items: flex-start;\n min-height: 100vh;\n padding: 24px 16px;\n gap: 0;\n }\n\n /* ── Layout wrapper ───────────────────────────────────────────────── */\n #app {\n display: flex;\n gap: 20px;\n align-items: flex-start;\n }\n\n /* ── Board area ───────────────────────────────────────────────────── */\n #board-wrapper {\n position: relative;\n flex-shrink: 0;\n }\n\n #board {\n display: block;\n border: 2px solid #334155;\n border-radius: 4px;\n box-shadow: 0 0 40px rgba(0,0,0,0.6);\n }\n\n /* ── Overlay (start / pause / game-over) ─────────────────────────── */\n #overlay {\n position: absolute;\n inset: 0;\n background: rgba(15, 23, 42, 0.88);\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 12px;\n border-radius: 4px;\n backdrop-filter: blur(4px);\n }\n\n #overlay-title {\n font-size: 2.4rem;\n font-weight: 800;\n letter-spacing: 4px;\n color: #facc15;\n text-shadow: 0 0 20px rgba(250,204,21,0.6);\n }\n\n #overlay-msg {\n font-size: 0.9rem;\n color: #94a3b8;\n }\n\n /* ── Side panel ───────────────────────────────────────────────────── */\n #panel {\n display: flex;\n flex-direction: column;\n gap: 16px;\n min-width: 140px;\n }\n\n .panel-box {\n background: #1e293b;\n border: 1px solid #334155;\n border-radius: 8px;\n padding: 12px 16px;\n }\n\n .panel-box h3 {\n font-size: 0.65rem;\n font-weight: 700;\n letter-spacing: 2px;\n text-transform: uppercase;\n color: #64748b;\n margin-bottom: 6px;\n }\n\n .stat-value {\n font-size: 1.6rem;\n font-weight: 700;\n color: #f1f5f9;\n line-height: 1;\n }\n\n /* ── Preview canvas ───────────────────────────────────────────────── */\n #preview {\n display: block;\n border-radius: 4px;\n }\n\n /* ── Buttons ──────────────────────────────────────────────────────── */\n .btn {\n display: block;\n width: 100%;\n padding: 10px 0;\n background: #facc15;\n color: #0f172a;\n font-size: 0.85rem;\n font-weight: 800;\n letter-spacing: 1px;\n text-transform: uppercase;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s, transform 0.1s;\n }\n .btn:hover { background: #fde047; }\n .btn:active { transform: scale(0.97); }\n\n /* ── Controls legend ──────────────────────────────────────────────── */\n .controls {\n font-size: 0.72rem;\n color: #64748b;\n line-height: 1.8;\n }\n\n .controls span {\n display: inline-block;\n background: #334155;\n color: #cbd5e1;\n border-radius: 3px;\n padding: 0 4px;\n font-family: monospace;\n font-size: 0.68rem;\n }\n\n /* ── Responsive tweak ─────────────────────────────────────────────── */\n @media (max-width: 520px) {\n body { padding: 12px 8px; }\n #app { gap: 12px; }\n }\n </style>\n</head>\n<body>\n <div id=\"app\">\n <!-- Main board -->\n <div id=\"board-wrapper\">\n <canvas id=\"board\" width=\"300\" height=\"600\"></canvas>\n <div id=\"overlay\">\n <div id=\"overlay-title\">TETRIS</div>\n <div id=\"overlay-msg\">Press Start or Enter to play</div>\n </div>\n </div>\n\n <!-- Side panel -->\n <div id=\"panel\">\n <div class=\"panel-box\">\n <h3>Next</h3>\n <canvas id=\"preview\" width=\"120\" height=\"96\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <h3>Score</h3>\n <div class=\"stat-value\" id=\"score\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <h3>Lines</h3>\n <div class=\"stat-value\" id=\"lines\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <h3>Level</h3>\n <div class=\"stat-value\" id=\"level\">1</div>\n </div>\n\n <button class=\"btn\" id=\"start-btn\">Start</button>\n\n <div class=\"panel-box controls\">\n <h3>Controls</h3>\n <span>← →</span> Move<br/>\n <span>↑</span> / <span>X</span> Rotate CW<br/>\n <span>Z</span> Rotate CCW<br/>\n <span>↓</span> Soft drop<br/>\n <span>Space</span> Hard drop<br/>\n <span>P</span> Pause\n </div>\n </div>\n </div>\n\n <script type=\"module\" src=\"dist/tetris.js\"></script>\n</body>\n</html>\nEOF","description":"Create the main HTML file with full styling"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":102,"cache_read_input_tokens":11836,"cache_creation":{"ephemeral_5m_input_tokens":102,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"d8459c86-fc22-44ec-a64f-f865df6b1937"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_014T9Nz1QHYooY9DeobrFk3x","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"df6022a3-dad6-411c-8395-3cb5267a3a88","timestamp":"2026-04-05T19:38:27.692Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015qLJkfseZw7EYKtrgQyPq7","type":"message","role":"assistant","content":[{"type":"text","text":"Now let's verify the compiled JS looks correct and the files are all in order:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1902,"cache_read_input_tokens":11938,"cache_creation":{"ephemeral_5m_input_tokens":1902,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"fefeaee7-fae9-49eb-87aa-b961f8769f43"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015qLJkfseZw7EYKtrgQyPq7","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01FVKHYbaD7M4TkpFqEJY7LU","name":"Bash","input":{"command":"wc -l /tmp/loop-bench-kncx228p/dist/tetris.js /tmp/loop-bench-kncx228p/src/tetris.ts /tmp/loop-bench-kncx228p/index.html","description":"Check line counts of generated files"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1902,"cache_read_input_tokens":11938,"cache_creation":{"ephemeral_5m_input_tokens":1902,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"b3b3fe47-3920-4bb9-b17b-f6f4333c58c9"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01FVKHYbaD7M4TkpFqEJY7LU","type":"tool_result","content":" 439 /tmp/loop-bench-kncx228p/dist/tetris.js\n 512 /tmp/loop-bench-kncx228p/src/tetris.ts\n 199 /tmp/loop-bench-kncx228p/index.html\n 1150 total","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"4965bc47-bd3e-4e36-81b3-1047abd8c2f2","timestamp":"2026-04-05T19:38:30.393Z","tool_use_result":{"stdout":" 439 /tmp/loop-bench-kncx228p/dist/tetris.js\n 512 /tmp/loop-bench-kncx228p/src/tetris.ts\n 199 /tmp/loop-bench-kncx228p/index.html\n 1150 total","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01KCkXUg5ELKKnK1ASx2HKzu","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01G2U3oTkAKYbeGGuKeGxaCc","name":"Read","input":{"file_path":"/tmp/loop-bench-kncx228p/dist/tetris.js","limit":50},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":232,"cache_read_input_tokens":13840,"cache_creation":{"ephemeral_5m_input_tokens":232,"ephemeral_1h_input_tokens":0},"output_tokens":72,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"ec519649-395c-437a-bc46-70d4400882f9"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01G2U3oTkAKYbeGGuKeGxaCc","type":"tool_result","content":"1\t\"use strict\";\n2\t// ─── Constants ────────────────────────────────────────────────────────────────\n3\tconst COLS = 10;\n4\tconst ROWS = 20;\n5\tconst BLOCK = 30; // px per cell on the main board\n6\tconst PREVIEW_BLOCK = 24; // px per cell in the preview box\n7\t// Colours for each tetromino (index 0 = empty)\n8\tconst COLORS = [\n9\t \"transparent\", // 0 – empty\n10\t \"#00CFCF\", // 1 – I (cyan)\n11\t \"#1E90FF\", // 2 – J (blue)\n12\t \"#FF8C00\", // 3 – L (orange)\n13\t \"#FFD700\", // 4 – O (yellow)\n14\t \"#32CD32\", // 5 – S (green)\n15\t \"#A020F0\", // 6 – T (purple)\n16\t \"#FF3030\", // 7 – Z (red)\n17\t];\n18\tfunction rotateCW(cells) {\n19\t // Rotate 90° clockwise: (r, c) → (c, -r)\n20\t return cells.map(([r, c]) => [c, -r]);\n21\t}\n22\tfunction normalise(cells) {\n23\t const minR = Math.min(...cells.map(([r]) => r));\n24\t const minC = Math.min(...cells.map(([, c]) => c));\n25\t return cells.map(([r, c]) => [r - minR, c - minC]);\n26\t}\n27\tfunction buildRotations(base) {\n28\t const rots = [normalise(base)];\n29\t for (let i = 0; i < 3; i++) {\n30\t rots.push(normalise(rotateCW(rots[rots.length - 1])));\n31\t }\n32\t return rots;\n33\t}\n34\tconst PIECES = [\n35\t // I\n36\t { rotations: buildRotations([[0, 0], [0, 1], [0, 2], [0, 3]]), colorIndex: 1 },\n37\t // J\n38\t { rotations: buildRotations([[0, 0], [1, 0], [1, 1], [1, 2]]), colorIndex: 2 },\n39\t // L\n40\t { rotations: buildRotations([[0, 2], [1, 0], [1, 1], [1, 2]]), colorIndex: 3 },\n41\t // O\n42\t { rotations: buildRotations([[0, 0], [0, 1], [1, 0], [1, 1]]), colorIndex: 4 },\n43\t // S\n44\t { rotations: buildRotations([[0, 1], [0, 2], [1, 0], [1, 1]]), colorIndex: 5 },\n45\t // T\n46\t { rotations: buildRotations([[0, 1], [1, 0], [1, 1], [1, 2]]), colorIndex: 6 },\n47\t // Z\n48\t { rotations: buildRotations([[0, 0], [0, 1], [1, 1], [1, 2]]), colorIndex: 7 },\n49\t];\n50\t// Scoring table (points per lines cleared simultaneously)"}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"8afc68f8-2634-417b-8bfc-9c6cc59c51f3","timestamp":"2026-04-05T19:38:32.876Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-kncx228p/dist/tetris.js","content":"\"use strict\";\n// ─── Constants ────────────────────────────────────────────────────────────────\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 30; // px per cell on the main board\nconst PREVIEW_BLOCK = 24; // px per cell in the preview box\n// Colours for each tetromino (index 0 = empty)\nconst COLORS = [\n \"transparent\", // 0 – empty\n \"#00CFCF\", // 1 – I (cyan)\n \"#1E90FF\", // 2 – J (blue)\n \"#FF8C00\", // 3 – L (orange)\n \"#FFD700\", // 4 – O (yellow)\n \"#32CD32\", // 5 – S (green)\n \"#A020F0\", // 6 – T (purple)\n \"#FF3030\", // 7 – Z (red)\n];\nfunction rotateCW(cells) {\n // Rotate 90° clockwise: (r, c) → (c, -r)\n return cells.map(([r, c]) => [c, -r]);\n}\nfunction normalise(cells) {\n const minR = Math.min(...cells.map(([r]) => r));\n const minC = Math.min(...cells.map(([, c]) => c));\n return cells.map(([r, c]) => [r - minR, c - minC]);\n}\nfunction buildRotations(base) {\n const rots = [normalise(base)];\n for (let i = 0; i < 3; i++) {\n rots.push(normalise(rotateCW(rots[rots.length - 1])));\n }\n return rots;\n}\nconst PIECES = [\n // I\n { rotations: buildRotations([[0, 0], [0, 1], [0, 2], [0, 3]]), colorIndex: 1 },\n // J\n { rotations: buildRotations([[0, 0], [1, 0], [1, 1], [1, 2]]), colorIndex: 2 },\n // L\n { rotations: buildRotations([[0, 2], [1, 0], [1, 1], [1, 2]]), colorIndex: 3 },\n // O\n { rotations: buildRotations([[0, 0], [0, 1], [1, 0], [1, 1]]), colorIndex: 4 },\n // S\n { rotations: buildRotations([[0, 1], [0, 2], [1, 0], [1, 1]]), colorIndex: 5 },\n // T\n { rotations: buildRotations([[0, 1], [1, 0], [1, 1], [1, 2]]), colorIndex: 6 },\n // Z\n { rotations: buildRotations([[0, 0], [0, 1], [1, 1], [1, 2]]), colorIndex: 7 },\n];\n// Scoring table (points per lines cleared simultaneously)","numLines":50,"startLine":1,"totalLines":440}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01AHpMRkohy38ab62bHATYmK","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01RcVUJYjjFUqb23gVhS8pG6","name":"Read","input":{"file_path":"/tmp/loop-bench-kncx228p/dist/tetris.js","limit":50,"offset":420},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1211,"cache_read_input_tokens":13840,"cache_creation":{"ephemeral_5m_input_tokens":1211,"ephemeral_1h_input_tokens":0},"output_tokens":64,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"1ea0b68a-1fa2-4662-b3e7-00174428ce32"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01RcVUJYjjFUqb23gVhS8pG6","type":"tool_result","content":"420\t e.preventDefault();\n421\t this.rotate();\n422\t break;\n423\t case \"z\":\n424\t case \"Z\":\n425\t e.preventDefault();\n426\t this.rotateCCW();\n427\t break;\n428\t case \" \":\n429\t e.preventDefault();\n430\t this.hardDrop();\n431\t break;\n432\t }\n433\t this.render();\n434\t }\n435\t}\n436\t// ─── Bootstrap ────────────────────────────────────────────────────────────────\n437\twindow.addEventListener(\"DOMContentLoaded\", () => {\n438\t new TetrisGame();\n439\t});\n440\t"}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"fbaf4dd1-0c08-43a9-8edc-8c0d60661aac","timestamp":"2026-04-05T19:38:35.335Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-kncx228p/dist/tetris.js","content":" e.preventDefault();\n this.rotate();\n break;\n case \"z\":\n case \"Z\":\n e.preventDefault();\n this.rotateCCW();\n break;\n case \" \":\n e.preventDefault();\n this.hardDrop();\n break;\n }\n this.render();\n }\n}\n// ─── Bootstrap ────────────────────────────────────────────────────────────────\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new TetrisGame();\n});\n","numLines":21,"startLine":420,"totalLines":440}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NjjGbkHrhRFM38nXToz35s","type":"message","role":"assistant","content":[{"type":"text","text":"The compiled output looks perfect. Let me do a quick sanity check to make sure the HTML references everything correctly and there are no issues:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":292,"cache_read_input_tokens":15051,"cache_creation":{"ephemeral_5m_input_tokens":292,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"96df970a-3ef5-468a-a3a2-a3544c2ba405"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NjjGbkHrhRFM38nXToz35s","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XgrAVguecjGg8m9j7Jev8b","name":"Bash","input":{"command":"node -e \"\nconst fs = require('fs');\nconst js = fs.readFileSync('/tmp/loop-bench-kncx228p/dist/tetris.js', 'utf8');\n// Quick sanity checks\nconst checks = [\n ['TetrisGame class', js.includes('class TetrisGame')],\n ['Renderer class', js.includes('class Renderer')],\n ['DOMContentLoaded bootstrap', js.includes('DOMContentLoaded')],\n ['randomPiece fn', js.includes('function randomPiece')],\n ['collides fn', js.includes('function collides')],\n ['hardDrop method', js.includes('hardDrop')],\n ['clearLines method', js.includes('clearLines')],\n ['ghost piece drawing', js.includes('drawGhost')],\n ['wall kick', js.includes('kicks')],\n ['scoring table', js.includes('SCORE_TABLE')],\n];\nchecks.forEach(([name, pass]) => console.log(pass ? '✓' : '✗', name));\n\"\n","description":"Sanity-check the compiled output for key game features"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":292,"cache_read_input_tokens":15051,"cache_creation":{"ephemeral_5m_input_tokens":292,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"14ce4e07-06a8-429f-8e26-7212f07d9c11"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01XgrAVguecjGg8m9j7Jev8b","type":"tool_result","content":"✓ TetrisGame class\n✓ Renderer class\n✓ DOMContentLoaded bootstrap\n✓ randomPiece fn\n✓ collides fn\n✓ hardDrop method\n✓ clearLines method\n✓ ghost piece drawing\n✓ wall kick\n✓ scoring table","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"1e0bc96e-ee53-4192-a158-bad0913fa9be","timestamp":"2026-04-05T19:38:40.669Z","tool_use_result":{"stdout":"✓ TetrisGame class\n✓ Renderer class\n✓ DOMContentLoaded bootstrap\n✓ randomPiece fn\n✓ collides fn\n✓ hardDrop method\n✓ clearLines method\n✓ ghost piece drawing\n✓ wall kick\n✓ scoring table","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01A1zZDUbU9zVYHLXB62vhNK","type":"message","role":"assistant","content":[{"type":"text","text":"All checks pass. Let me also verify the final project structure:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":455,"cache_read_input_tokens":15343,"cache_creation":{"ephemeral_5m_input_tokens":455,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"6f8a7d01-8d05-4c69-9480-f5d5d6ba75c4"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01A1zZDUbU9zVYHLXB62vhNK","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01JzNQztdJbZzN5DXZ9m92C9","name":"Bash","input":{"command":"ls -la /tmp/loop-bench-kncx228p/","description":"List final project structure"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":455,"cache_read_input_tokens":15343,"cache_creation":{"ephemeral_5m_input_tokens":455,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"976f7640-b8c7-49f1-add9-7e0341480002"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01JzNQztdJbZzN5DXZ9m92C9","type":"tool_result","content":"total 112\ndrwx------ 5 root root 4096 Apr 5 21:38 .\ndrwxrwxrwt 42 root root 45056 Apr 5 21:38 ..\ndrwxr-xr-x 2 root root 4096 Apr 5 21:38 dist\n-rw-r--r-- 1 root root 5763 Apr 5 21:38 index.html\ndrwxr-xr-x 63 root root 4096 Apr 5 21:22 node_modules\n-rw-r--r-- 1 root root 394 Apr 5 21:23 package.json\n-rw-r--r-- 1 root root 32398 Apr 5 21:23 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 5 21:38 src\n-rw-r--r-- 1 root root 238 Apr 5 21:37 tsconfig.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"77b074d5-3505-4b5b-9399-a54804faf3f5","timestamp":"2026-04-05T19:38:42.766Z","tool_use_result":{"stdout":"total 112\ndrwx------ 5 root root 4096 Apr 5 21:38 .\ndrwxrwxrwt 42 root root 45056 Apr 5 21:38 ..\ndrwxr-xr-x 2 root root 4096 Apr 5 21:38 dist\n-rw-r--r-- 1 root root 5763 Apr 5 21:38 index.html\ndrwxr-xr-x 63 root root 4096 Apr 5 21:22 node_modules\n-rw-r--r-- 1 root root 394 Apr 5 21:23 package.json\n-rw-r--r-- 1 root root 32398 Apr 5 21:23 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 5 21:38 src\n-rw-r--r-- 1 root root 238 Apr 5 21:37 tsconfig.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01QUjVVfhNs4wG4S6AKdzuTs","type":"message","role":"assistant","content":[{"type":"text","text":"The Tetris game is complete. Here's a summary of everything that was built:\n\n---\n\n## 📁 Project Structure\n\n```\nindex.html ← game page (open this in a browser)\nsrc/tetris.ts ← TypeScript source (~500 lines)\ndist/tetris.js ← compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config\n```\n\n**To play:** open `index.html` in a browser (e.g. `python3 -m http.server` then navigate to `localhost:8000`).\n\n---\n\n## 🎮 Features Implemented\n\n| Feature | Details |\n|---|---|\n| **All 7 tetrominoes** | I, J, L, O, S, T, Z with correct shapes |\n| **Piece rotation** | CW (↑/X) and CCW (Z) with **wall-kick** (tries ±1, ±2 column offsets) |\n| **Ghost piece** | Outline shows where the piece will land |\n| **Soft drop** | ↓ / S — moves piece down one row, +1 point |\n| **Hard drop** | Space — slams piece to bottom, +2 pts/row |\n| **Line clearing** | Removes full rows, shifts board down |\n| **Scoring** | 100/300/500/800 pts × level for 1/2/3/4 lines |\n| **Levels** | Increases every 10 lines cleared |\n| **Speed increase** | Drop interval decreases 60 ms/level (min 80 ms) |\n| **Next piece preview** | Shown in side panel |\n| **Pause / Resume** | P key or Start button |\n| **Game over detection** | Triggers when piece spawns in collision |\n\n## ⌨️ Keyboard Controls\n\n| Key | Action |\n|---|---|\n| `← →` or `A D` | Move left / right |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` or `S` | Soft drop |\n| `Space` | Hard drop |\n| `P` | Pause / Resume |\n| `Enter` | Start / Restart |"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":370,"cache_read_input_tokens":15798,"cache_creation":{"ephemeral_5m_input_tokens":370,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","uuid":"0bc00f27-9457-445d-b561-1b806bc1e3d1"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":953675,"duration_api_ms":952188,"num_turns":17,"result":"The Tetris game is complete. Here's a summary of everything that was built:\n\n---\n\n## 📁 Project Structure\n\n```\nindex.html ← game page (open this in a browser)\nsrc/tetris.ts ← TypeScript source (~500 lines)\ndist/tetris.js ← compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config\n```\n\n**To play:** open `index.html` in a browser (e.g. `python3 -m http.server` then navigate to `localhost:8000`).\n\n---\n\n## 🎮 Features Implemented\n\n| Feature | Details |\n|---|---|\n| **All 7 tetrominoes** | I, J, L, O, S, T, Z with correct shapes |\n| **Piece rotation** | CW (↑/X) and CCW (Z) with **wall-kick** (tries ±1, ±2 column offsets) |\n| **Ghost piece** | Outline shows where the piece will land |\n| **Soft drop** | ↓ / S — moves piece down one row, +1 point |\n| **Hard drop** | Space — slams piece to bottom, +2 pts/row |\n| **Line clearing** | Removes full rows, shifts board down |\n| **Scoring** | 100/300/500/800 pts × level for 1/2/3/4 lines |\n| **Levels** | Increases every 10 lines cleared |\n| **Speed increase** | Drop interval decreases 60 ms/level (min 80 ms) |\n| **Next piece preview** | Shown in side panel |\n| **Pause / Resume** | P key or Start button |\n| **Game over detection** | Triggers when piece spawns in collision |\n\n## ⌨️ Keyboard Controls\n\n| Key | Action |\n|---|---|\n| `← →` or `A D` | Move left / right |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `↓` or `S` | Soft drop |\n| `Space` | Hard drop |\n| `P` | Pause / Resume |\n| `Enter` | Start / Restart |","stop_reason":"end_turn","session_id":"3d0a2cec-badd-4e75-b992-c22f5acb694e","total_cost_usd":1.3401081000000001,"usage":{"input_tokens":25,"cache_creation_input_tokens":16886,"cache_read_input_tokens":163152,"output_tokens":81851,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":16886},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":25,"outputTokens":81851,"cacheReadInputTokens":163152,"cacheCreationInputTokens":16886,"webSearchRequests":0,"costUSD":1.3401081000000001,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"d2d35a0d-5a2c-49f9-9bc4-9b12e2f77d2c"} diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_output.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":953979,"duration_api_ms":951531,"num_turns":21,"result":"Everything compiles cleanly and the output is correct. Here's a summary of everything that was built:\n\n---\n\n## Project structure\n\n```\nindex.html ← Open this in a browser to play\nstyle.css ← Dark neon theme, responsive layout\nsrc/tetris.ts ← Full TypeScript source (~735 lines)\ndist/tetris.js ← Compiled output (loaded by the HTML)\ntsconfig.json ← ES2020, strict mode\npackage.json ← npm build / watch scripts\n```\n\n**To play:** `open index.html` (or serve with any static file server — no backend needed). To rebuild after edits: `npm run build` (or `npm run watch` for live recompilation).\n\n---\n\n## What's implemented\n\n| Feature | Detail |\n|---|---|\n| **All 7 tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces, including the separate I-piece kick table |\n| **7-bag randomiser** | Guarantees each piece appears exactly once per bag — no drought |\n| **Ghost piece** | Translucent outline shows where the piece will land |\n| **Hold piece** | Press **C** to swap the current piece into hold (once per drop) |\n| **Next preview** | Shows the upcoming piece in a small canvas |\n| **Scoring** | Guideline scoring: 100 / 300 / 500 / 800 × level for 1–4 lines; +1 per soft-drop row; +2 per hard-drop row |\n| **Levels & speed** | Level up every 10 lines; speed follows the official guideline formula `(0.8 − 0.007(L−1))^(L−1)` seconds/row |\n| **DAS** | Delayed Auto-Shift (133 ms delay, 50 ms repeat) for smooth left/right movement |\n| **Pause / resume** | **P** or **Esc** toggles pause; overlay shows current state |\n| **Game over** | Detected at spawn time; overlay shows final score |\n| **3-D cell rendering** | Bevel highlight + dark shadow + inner shine per cell |\n\n### Keyboard controls\n\n| Key | Action |\n|---|---|\n| `← →` | Move left / right |\n| `↓` | Soft drop (20× speed) |\n| `Space` | Hard drop |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` | Hold piece |\n| `P` / `Esc` | Pause / resume |","stop_reason":"end_turn","session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","total_cost_usd":1.6425389999999997,"usage":{"input_tokens":28,"cache_creation_input_tokens":68070,"cache_read_input_tokens":972475,"output_tokens":73030,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":68070},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":28,"outputTokens":73030,"cacheReadInputTokens":972475,"cacheCreationInputTokens":68070,"webSearchRequests":0,"costUSD":1.6425389999999997,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"6bf86f7c-c436-458d-a7a9-5d3c15d43ced"} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_stderr.log b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/claude_stderr.log diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/eval_results.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/eval_results.json @@ -0,0 +1,263 @@ +{ + "structural": { + "pass": true, + "checks": [ + { + "name": "entry_point_exists", + "pass": true, + "detail": "index.html found" + }, + { + "name": "package_json_exists", + "pass": true, + "detail": "package.json found" + }, + { + "name": "build_succeeds", + "pass": true, + "detail": "npm run build completed successfully" + }, + { + "name": "typescript_compiles", + "pass": true, + "detail": "tsc --noEmit passed" + } + ], + "score": 1.0 + }, + "functional": { + "pass": false, + "error": "playwright eval not yet wired", + "score": 0 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": true + }, + "performance": { + "bundle_size_bytes": 56061, + "size_under_512kb": true + }, + "score": 0.67 + }, + "code_analysis": { + "files": { + "total": 8, + "code": 4, + "docs": 0, + "unnecessary": 0, + "unnecessary_list": [] + }, + "lines_of_code": 1647, + "dependencies": { + "production": 0, + "dev": 4, + "total": 4 + }, + "complexity": "moderate", + "console_logs": 0, + "magic_numbers": { + "count": 58, + "excessive": true + }, + "function_length": { + "count": 89, + "average": 7.7, + "max": 45, + "long_functions": 0 + }, + "max_nesting_depth": 15, + "global_declarations": 24, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 100.0, + "camel_case": 567, + "snake_case": 0 + }, + "error_handling": { + "try_catch_blocks": 0, + "has_error_handling": false + }, + "comments": { + "comment_lines": 119, + "source_lines": 1195, + "ratio_pct": 10.0 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 2, + "files_with_logic": 2, + "files_with_both": 2 + }, + "html_validation": { + "valid": false, + "errors": 7 + }, + "duplication_percentage": 0.0, + "score": 0.85 + }, + "transcript_analysis": { + "total_events": 64, + "tool_calls": { + "total": 20, + "bash": 12, + "write": 0, + "edit": 4, + "read": 4 + }, + "wasted_turns": { + "total": 0, + "docs": 0, + "ascii_art": 0, + "server_starts": 0 + }, + "errors_encountered": 0, + "thinking_blocks": 9, + "text_blocks": 11, + "productivity_ratio": 1.0, + "self_tested": false, + "score": 1.0 + }, + "gameplay_bot": { + "pass": false, + "score": 0.81, + "total": 16, + "passed": 13, + "failed": 3, + "report": { + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 60, + "height": 120 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "space", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via space" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "pixels changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": false, + "detail": "could not detect any piece rotations" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "visual change detected after hard drop" + }, + { + "name": "piece_locks", + "pass": false, + "detail": "could not verify piece locking at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "visual change suggests new piece spawned" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "game still responding after 10 piece drops" + }, + { + "name": "line_clear", + "pass": true, + "detail": "line cleared via strategic placement" + }, + { + "name": "score_changes", + "pass": true, + "detail": "score changed from 198 to 284" + }, + { + "name": "game_over", + "pass": false, + "detail": "could not trigger or detect game over" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 79 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 13, + "failed": 3, + "score": 0.81 + }, + "gameplay": { + "pieces_placed": 189, + "lines_cleared": 1, + "max_score_observed": 246, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 34 + }, + "accessibility": { + "issues": [ + "no headings found", + "canvas without aria-label or role", + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 4, + "pass": false + } + } + }, + "score": 0.7275 +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/gameplay-bot-report.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/gameplay-bot-report.json @@ -0,0 +1,129 @@ +{ + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 60, + "height": 120 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "x", + "drop": "Space" + }, + "start_mechanism": "space", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via space" + }, + { + "name": "auto_drop", + "pass": true, + "detail": "pixels changed after 5s with no input" + }, + { + "name": "move_left", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_right", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": false, + "detail": "could not detect any piece rotations" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "visual change detected after hard drop" + }, + { + "name": "piece_locks", + "pass": false, + "detail": "could not verify piece locking at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "visual change suggests new piece spawned" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "game still responding after 10 piece drops" + }, + { + "name": "line_clear", + "pass": true, + "detail": "line cleared via strategic placement" + }, + { + "name": "score_changes", + "pass": true, + "detail": "score changed from 198 to 284" + }, + { + "name": "game_over", + "pass": false, + "detail": "could not trigger or detect game over" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 79 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 13, + "failed": 3, + "score": 0.81 + }, + "gameplay": { + "pieces_placed": 189, + "lines_cleared": 1, + "max_score_observed": 246, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 34 + }, + "accessibility": { + "issues": [ + "no headings found", + "canvas without aria-label or role", + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 4, + "pass": false + } +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/meta.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/meta.json @@ -0,0 +1,30 @@ +{ + "model": "sonnet", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "on", + "linter": "on", + "playwright": "off", + "context_file": "none", + "sub_agents": "on", + "web_search": "on", + "max_budget": "low", + "task": "tetris", + "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2", + "run_number": 2, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-05T19:22:56.147290+00:00", + "wall_time_seconds": 954, + "exit_code": 0, + "completed_at": "2026-04-05T19:38:55.252420+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/transcript.jsonl b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=off_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=on_tool_write=on_web_search=on_run2/transcript.jsonl @@ -0,0 +1,64 @@ +{"type": "harness", "subtype": "config", "model": "sonnet", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "Agent", "WebSearch", "WebFetch"], "max_budget_usd": 2.0, "timeout_seconds": 1200, "task": "tetris", "language": "typescript", "prompt_style": "simple"} +{"type": "user", "subtype": "prompt", "message": {"role": "user", "content": "Build a playable Tetris game that runs in a browser. It should have all the standard mechanics: piece rotation, line clearing, scoring, and increasing speed. Use keyboard controls for movement and rotation.\n\n\nUse TypeScript."}} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-6c3p0wr6","session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"claude-sonnet-4-6","permissionMode":"dontAsk","slash_commands":["update-config","debug","simplify","batch","loop","schedule","claude-api","compact","context","cost","heapdump","init","review","security-review","insights"],"apiKeySource":"apiKeyHelper","claude_code_version":"2.1.92","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan"],"skills":["update-config","debug","simplify","batch","loop","schedule","claude-api"],"plugins":[{"name":"claude-hud","path":"/root/.claude/plugins/marketplaces/claude-hud/","source":"claude-hud@claude-hud"},{"name":"rust-analyzer-lsp","path":"/root/.claude/plugins/marketplaces/claude-plugins-official/plugins/rust-analyzer-lsp","source":"rust-analyzer-lsp@claude-plugins-official"}],"uuid":"94a20f96-9d49-4329-8d9d-723b886556c0","fast_mode_state":"off"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01P8zY9SMrseRyPnf461sgVR","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants a playable Tetris game in the browser using TypeScript. Let me build a complete Tetris game with all standard mechanics:\n\n1. All 7 standard Tetromino pieces (I, O, T, S, Z, J, L)\n2. Piece rotation (with wall kicks)\n3. Line clearing\n4. Scoring system\n5. Increasing speed (levels)\n6. Keyboard controls (arrow keys for movement, up arrow or Z/X for rotation)\n\nI'll create:\n- `index.html` - The main HTML file\n- `style.css` - Styling\n- `src/tetris.ts` - Main game TypeScript file\n\n\n- `tsconfig.json` - TypeScript configuration\n- `package.json` - Package configuration\n\nFor the build setup, I'll compile TypeScript to JavaScript so it runs directly in the browser. I'll define the seven Tetromino pieces with their standard colors: cyan for I, yellow for O, purple for T, green for S, red for Z, blue for J, and orange for L.\n\nNow I'm mapping out the controls: arrow keys for movement and rotation, space for hard drop, and P or Escape to pause. The scoring system awards points based on lines cleared with a multiplier for the current level, and the difficulty ramps up every ten lines. I'll write the complete TypeScript implementation with a clean structure that handles the game loop, piece rotation, collision detection, and line clearing.\n\nSetting up the project structure...\n\nI'm building the HTML layout with a game wrapper containing the main canvas for the board and a side panel that displays the next piece preview, score, level, and lines cleared. Writing the game logic... Defining the rotation states for the remaining Tetris pieces... Defining the color palette for each piece type, then moving on to implement the wall kick system for rotations. I'll use a simplified version of SRS rather than the full complexity, setting up the offset data that handles piece collisions during rotation.\n\nStill writing wall kick data...\n\nNow I'm settling on a standard SRS wall kick system and planning out the scoring mechanics—singles through tetrises with level multipliers, plus bonuses for soft and hard drops. I'll also implement a level progression system where every ten lines cleared bumps up the difficulty, with the game speed increasing accordingly. Time to write out the complete implementation as a TypeScript class.\n\nWriting the game class... Defining the piece shapes... Defining the rotation states for the remaining Tetris pieces...\n\nNow I'm setting up the color mapping for each piece type, assigning distinct hex values so they're visually distinguishable on the board. Next I'll need to implement the wall kick system for handling rotations near boundaries.\n\nDefining wall kick offsets... Defining the kick offset data for each rotation transition, then setting up the core game structures with piece types, scoring rules, and a function to generate random pieces with initial rotation and position.\n\nSetting up the Tetris class with canvas rendering contexts for both the main game board and a preview window, along with private properties to track game state like the current and next pieces, score, level, lines cleared, and various game flags. Initializing the game state with default values for lines, game over status, pause state, and timing variables, then setting up event listeners and starting the game loop. I'm also defining helper methods to create the board and calculate the drop speed based on the current level.\n\nNow I'm writing the collision detection logic... Continuing with the game logic after locking a piece - I'm clearing completed lines from the board, spawning the next piece, and resetting the drop counters before checking if the new piece can be placed without triggering a game over.\n\nNow I'm finishing the line-clearing logic by updating the score and level based on how many lines were cleared, then handling the left and right movement functions which validate the move and reset the lock timer if the piece is on the ground.\n\nImplementing the drop mechanics... Writing rotation and kick logic... Writing game loop logic... Writing the render method... Drawing the grid and board cells...","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4730,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":4730,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"e85bb02e-03e8-4d2e-8795-88c7e00f3a71"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NYGqdLTCL5JKfzSea3M1PS","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants me to build a playable Tetris game that runs in a browser using TypeScript. Let me plan the implementation:\n\n1. **Project Structure:**\n - `index.html` - Main HTML file\n - `src/tetris.ts` - Main TypeScript file\n - `tsconfig.json` - TypeScript configuration\n - `package.json` - Package configuration\n - `style.css` - Styling\n\n2. **Game Features:**\n - All 7 Tetromino pieces (I, O, T, S, Z, J, L)\n - Piece rotation with wall kicks, line clearing, and a scoring system that rewards clearing multiple lines at once\n - Progressive difficulty where the game speeds up as you advance levels\n - Arrow key controls for movement and Z/X keys for rotation, plus a preview window showing the next piece\n - Game over detection when pieces stack to the top\n\nNow I'll set up the HTML with a canvas for the main board and another for the next piece preview, along with displays for score, level, and lines cleared, plus a start/pause button. For the TypeScript side, I need to define all the Tetromino shapes with their rotation states, manage a 10x20 game grid, implement the game loop using requestAnimationFrame, handle collision detection, clear completed lines, calculate scores, and manage the increasing speed mechanic.\n\nI'm defining the seven Tetromino pieces with their colors—cyan for I, yellow for O, purple for T, green for S, red for Z, blue for J, and orange for L. The scoring follows standard Tetris rules where clearing four lines at once gives the biggest bonus multiplied by the current level. Speed increases every 10 lines cleared, making the game progressively harder.\n\nFor implementation, I'll write this as a self-contained solution that compiles TypeScript to JavaScript...\n\nActually, the cleanest approach is to set up a proper project structure with TypeScript configuration, then provide the source files and build instructions. I'll create a package.json for dependencies, a tsconfig for compilation settings, and organize the code into a main tetris.ts file alongside an HTML file and stylesheet.\n\nDefining the core game constants and Tetromino shapes... Defining the tetromino shapes... Defining the remaining Tetris piece configurations...\n\nNow I'm thinking about the overall structure for a complete Tetris game implementation. I should organize this as a proper project with all the game logic, rendering, and controls working together seamlessly.\n\nFor a polished experience, I want to include the key features that make Tetris engaging: a ghost piece to preview where blocks will land, a next piece preview so players can plan ahead, basic wall kick mechanics for rotation near walls, standard scoring rules, a level progression system, pause functionality, and a proper game over screen. These features strike a good balance between being feature-rich and not overly complicated.\n\nI'll structure this as a multi-file project with TypeScript for type safety, a configuration file for the build setup, and separate styling. This approach keeps everything organized and maintainable while still being straightforward to run.\n\nNow I'm setting up the core game logic with TypeScript... Building the HTML structure...\n\nNow I'm thinking through the TypeScript architecture—I need to set up constants for the board and pieces, define the tetromino shapes and their rotations, then build out the game logic for movement, collision detection, and line clearing. Defining the tetromino shapes... Defining the remaining tetromino rotations... Defining wall kick data for the I piece...\n\nI'm second-guessing the offset values here—need to verify I'm using the correct SRS standard format where positive x goes right and positive y goes up. up (in math coordinates). But in our game, positive y is down. So I need to be careful.\n\nLet me use a different approach - just define simple wall kicks:\n- Try original position\n- Try moving left 1\n- Try moving right 1\n- Try moving left 2\n- Try moving right 2\n- For I piece, also try up/down adjustments\n\nActually, for a simpler implementation, let me just use basic wall kicks that handle most cases. For a browser game, this should be sufficient.\n\nActually, let me implement proper SRS. Now I'm looking at the specific wall kick offsets for each piece type and rotation state transition. For J, L, S, T, Z pieces, there are different offset sequences depending on which rotation states we're transitioning between - like going from state 0 to 1 has one set of offsets, while 1 to 2 has another. The I piece will have its own separate offset table. I need to map out all these transitions carefully. Now I'm mapping out all the rotation state transitions for the JLSTZ pieces with the Y coordinates negated for screen space, working through each direction change systematically.\n\nI'm realizing the wall kick offsets are getting complex, so I'll simplify with a basic set of kick attempts that should handle most rotation cases in a browser environment. Let me start writing out the full game implementation with the core mechanics in place.\n\nSetting up the project structure... Defining the tetromino shapes and colors... Defining the rotation states for the remaining Tetris pieces... Defining the wall kick offsets for the standard Tetris rotation system, which specifies the sequence of position adjustments to try when a piece rotation would otherwise collide with walls or other blocks. I'm realizing I need to account for the coordinate system difference between the Tetris Guideline and HTML canvas—the guideline uses Y increasing upward while canvas has Y increasing downward, so I need to flip the sign on all Y offsets when converting the standard SRS wall kick data. Finishing the rotation state transitions and converting them to canvas coordinates by negating the Y values... I'm working through the coordinate transformations for the tetromino rotations, converting between guideline coordinates and canvas coordinates by negating the Y-axis. I need to recalculate the transitions more carefully—particularly state 2 to state 3 and state 3 back to state 2, making sure the negation is applied consistently to each point. Completing the wall kick data structure... Defining rotation state transitions for the I piece... I've got the wall kick data sorted out. Now I'm ready to write the full TypeScript implementation with proper comments. Let me think through the spawn positions — pieces typically start at column 3 with row 0 or -1 depending on the piece type, so 3-wide pieces spawn at (3, 0) and the I-piece at (3, -1) to keep them properly visible at the top of the board. I'm settling on a simpler approach: spawn all pieces at y=0, and for the I piece specifically, since its actual blocks sit in row 1 of the 4x4 matrix, they'll naturally appear at y=1 when rendered, which is fine for the visible play area. Spawning at y=0 means the I piece's filled cells land at y=1 (since the shape has an empty top row), which is visible and works fine. For the T piece, the top row is also empty, so its filled cells would start at y=1 as well—this keeps all pieces consistently visible on the board.\n\nNow I'm checking the O piece positioning: with x=3 and the shape [[0,1,1,0]], the occupied columns would be 4 and 5, which centers it nicely in a 10-wide board.\n\nActually, I should simplify this—the O piece should just be the minimal 2x2 square [[1,1],[1,1]] without padding. Then I can calculate spawn positions dynamically based on each shape's width to center them: spawn_x = floor((10 - shape_width) / 2), with spawn_y = -1 to keep pieces hidden until they drop into view. This gives me spawn_x = 3 for the 4-wide I piece, spawn_x = 4 for the 2-wide O piece, and spawn_x = 3 for the 3-wide pieces.\n\nFollowing standard Tetris guidelines, I need to verify the spawn positions match the official spec—I at columns 3-6, O at columns 4-5, and the rest at columns 3-5. For the I piece specifically, I'm checking where the actual blocks land when spawned at different y-coordinates to ensure they start just above the visible board. I'll settle on spawning everything at y=0 with x=3 for simplicity. Now I'm setting up the scoring system using standard Tetris guidelines—singles through Tetris awards points multiplied by level, soft and hard drops give bonus points, and levels increase every 10 lines cleared. I'm also defining the drop speed progression, starting at 1000ms for level 1 and decreasing as the level increases.\n\nWriting the implementation... Defining the piece types and colors... Defining the rotation states for the remaining Tetris pieces... Defining the rotation kick offsets... Defining kick offset data... Defining the piece class and helper functions...\n\nNow I'm implementing a bag randomizer that uses the 7-bag system to ensure fair piece distribution, shuffling all seven Tetris pieces and drawing from them sequentially before refilling.\n\nBuilding the game class... Setting up the canvas contexts and DOM elements...\n\nNow I'm initializing the game state by getting the next piece from the bag, setting up keyboard and button input handlers, and displaying the idle screen with instructions to start. Writing game control methods... Writing game logic... Writing game logic... Writing movement and collision logic... Writing rotation logic...\n\nNow I'm implementing the hold piece mechanic, which swaps the current piece with a previously held one, spawning it at the top of the board with the appropriate starting position based on its type.\n\nImplementing ghost piece logic... Writing the input handler... Handling key release events for directional input, resetting the delayed auto-shift state when arrow keys are released, and managing the soft drop flag. Now I'm setting up the game loop to process timing and handle the DAS mechanism for continuous movement... I'm realizing the DAS logic is getting messy, so I need to clean it up. The approach should be straightforward: move immediately when a key is pressed, then after a delay start repeating the movement at a fixed interval. I'll use separate timers to track the initial delay and the repeat rate independently. I see the issue—when dasTimer first crosses the dasDelay threshold, dasRepeatTimer hasn't started accumulating yet, so I need to trigger an immediate repeat on that first frame, then continue with the regular interval-based repeats using a while loop to handle any accumulated time. I'm realizing this is getting too complicated with the nested timers. Let me step back and use a simpler single-timer approach where I track how long the key has been held, then calculate whether we're in the delay phase or the repeat phase based on elapsed time. Finishing the DAS movement logic to handle left and right inputs, then I'm ready to write out the complete Tetris implementation from scratch with a clean structure across HTML, CSS, and TypeScript files.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":0,"cache_read_input_tokens":4730,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"1a33595a-af46-42a5-814c-2e9f6892cb5e"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NYGqdLTCL5JKfzSea3M1PS","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Nb67drKRseVyvbTMTH32DV","name":"Bash","input":{"command":"ls /tmp/loop-bench-6c3p0wr6/","description":"List current directory contents"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":0,"cache_read_input_tokens":4730,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"4b0d2b1b-64a9-4fc3-80a6-b6b48cb12e76"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Nb67drKRseVyvbTMTH32DV","type":"tool_result","content":"node_modules\npackage.json\npackage-lock.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"ff47ace5-851c-47ea-bd3f-57cbfb9be843","timestamp":"2026-04-05T19:28:58.171Z","tool_use_result":{"stdout":"node_modules\npackage.json\npackage-lock.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01PkDa4ttbS32nAXWdb95jyf","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Qc31J9SWYYwGDjhnsFokBh","name":"Read","input":{"file_path":"/tmp/loop-bench-6c3p0wr6/package.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":20336,"cache_read_input_tokens":4730,"cache_creation":{"ephemeral_5m_input_tokens":20336,"ephemeral_1h_input_tokens":0},"output_tokens":51,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"9b661d4d-f3eb-4f34-8597-707ea12d2673"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Qc31J9SWYYwGDjhnsFokBh","type":"tool_result","content":"1\t{\n2\t \"name\": \"loop-bench-6c3p0wr6\",\n3\t \"version\": \"1.0.0\",\n4\t \"description\": \"\",\n5\t \"main\": \"index.js\",\n6\t \"scripts\": {\n7\t \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n8\t },\n9\t \"keywords\": [],\n10\t \"author\": \"\",\n11\t \"license\": \"ISC\",\n12\t \"type\": \"commonjs\",\n13\t \"devDependencies\": {\n14\t \"@eslint/js\": \"^10.0.1\",\n15\t \"@types/node\": \"^25.5.2\",\n16\t \"eslint\": \"^10.2.0\",\n17\t \"typescript\": \"^6.0.2\"\n18\t }\n19\t}\n20\t"}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"60d61d64-543d-48f8-92b9-8dcb1bf031e1","timestamp":"2026-04-05T19:29:00.822Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-6c3p0wr6/package.json","content":"{\n \"name\": \"loop-bench-6c3p0wr6\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^25.5.2\",\n \"eslint\": \"^10.2.0\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","numLines":20,"startLine":1,"totalLines":20}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01RvDPJJMVNFCnPsHLbDMqA3","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Good, TypeScript is already installed. Let me check what version of TypeScript is available and then create the project files.\n\nNow let me create all the necessary files for the Tetris game.","signature":"EvwCClsIDBgCKkAC1bpYdxHsXOXzssWQCi/l19TXP3cIqmGEHNWkzIQ+cZJqog7qB1BLV/oov8FqcB5suoQJdYgsbcT8reW3ozO9MhFjbGF1ZGUtc29ubmV0LTQtNjgAEgzqM+ebYv6e+uPibWgaDNFELvosi2lOKSSprCIwbNetVdWwy9pOKVOqO3b6styPYj8/szWZiD+znjROTHom853xVm+qkh46p5fiSqP4Ks4B6v3Lm3OxG/54LjivNLLLtWdVHu1u6q2r+J/1CLlb/BPgS5v9ti70oEdoC+7X1vZYWZLH/eBN/YC2xmx61eonSNLHwcPo8I2A3JrkBgoOH932DC+l7I29dqAiJg/dC7fmY1+H2SK4VoA/qkIgT7TKDy5O6ms8kOb5uyfy8g6yRvZDrjifIwN4AhzGAtzK4D+ABFVt78WOU+X0KR7RjnUMQZXnGKrud3hHc8/i2AsCFxJSkuPidCZgvH4mQZSagfz7T0zRZijJAa2r2iJFnekYAQ=="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":302,"cache_read_input_tokens":25066,"cache_creation":{"ephemeral_5m_input_tokens":302,"ephemeral_1h_input_tokens":0},"output_tokens":10,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"80860c05-a154-47f0-b9f9-669b1cca1879"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01RvDPJJMVNFCnPsHLbDMqA3","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Xeyy6KKV8CSEy4gu6HC3ms","name":"Bash","input":{"command":"ls /tmp/loop-bench-6c3p0wr6/node_modules/.bin/ | grep -i tsc","description":"Check tsc availability"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":302,"cache_read_input_tokens":25066,"cache_creation":{"ephemeral_5m_input_tokens":302,"ephemeral_1h_input_tokens":0},"output_tokens":10,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"b224a4ff-9003-4592-85f2-ec5f283e3b78"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Xeyy6KKV8CSEy4gu6HC3ms","type":"tool_result","content":"tsc","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"f4c5f951-a702-4a31-a60c-f5cc4b2f5e05","timestamp":"2026-04-05T19:29:04.787Z","tool_use_result":{"stdout":"tsc","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GNGpXvq15ZhCFGVvzcChSe","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"TypeScript is available. Now let me create all the files:\n\n1. `tsconfig.json`\n2. `src/tetris.ts`\n3. `index.html`\n4. `style.css`\n\nLet me write the complete implementation. I'll update `package.json` to add build scripts too.\n\nLet me write the TypeScript file first as it's the most complex.\n\nFor the wall kicks, let me go with the standard SRS. Let me think about this one more time.\n\nIn the Tetris Guideline, the wall kick data is specified in a coordinate system where:\n- Column increases to the right (+x = right)\n\n\n- Row increases upward (opposite of canvas/screen)\n\nIn our implementation (screen/canvas coordinates):\n- Column (x) increases to the right (same)\n- Row (y) increases downward (opposite)\n\nSo when converting wall kick data from Tetris guideline to screen coordinates, I need to negate the y values. From the Tetris wiki, for J, L, S, T, Z pieces, the wall kick offsets are specified in guideline coordinates, and I'll need to transform them appropriately for the screen coordinate system. Now I'm converting these rotation offsets to screen coordinates by negating the y-values, which flips the vertical axis to match how pixels are typically rendered from top to bottom.\n\nFor the I piece, I'm looking up the official Super Rotation System guidelines from the Tetris wiki to get the correct rotation kick offsets, since my initial calculations don't seem to match the standard. I'm realizing I should double-check this against an authoritative source rather than relying on my initial list. Looking at the official Tetris Guideline documentation for SRS rotation offsets, I need to convert between the guideline's coordinate system and screen coordinates—specifically accounting for how the y-axis is inverted between them. I'm noticing that the rotation offsets for R→0 and R→2 are identical in the guideline data, which seems odd. Let me double-check against the Tetris wiki to confirm this pattern holds, and I need to verify the complete set of offsets for the 0→R transition as well.\n\nNow I'm converting these guideline offsets to screen coordinates for the JLSTZ pieces, flipping the y-axis and adjusting the rotation state labels from the guideline notation to the standard 0-1-2-3 rotation states. I can see the pattern emerging where opposite rotations share the same offset values but with inverted signs. Finishing the coordinate conversion for the last rotation, then compiling all the JLSTZ kick offsets in screen coordinates for each state transition. Defining rotation offsets for the I piece... Finishing up the wall kick offsets for the I-piece rotations, completing the set of all four rotation states. (+1,+2)]\n\nNow I'm ready to write out the full implementation. For the O piece, since it's rotationally symmetric, I only need to test the center position without any wall kicks. I'm planning the visual design with 30x30 pixel cells, a 300x600 pixel board, subtle grid lines, and a 3D effect on pieces using highlight and shadow shading.\n\nWriting the HTML and CSS... Building the right panel... Writing the styling... Still writing styles...\n\nNow I'm moving into the TypeScript logic to handle the core game mechanics—I'll implement the 7-bag randomizer system for piece generation and add ghost piece rendering to show where pieces will land.\n\nFor lock delay, I'm going to keep it straightforward: when a piece can't move down anymore, it locks after a brief 500ms delay, and if the player manages to move or rotate it during that window, the timer resets (up to 15 times max, following a simplified infinity rule). This gives the game that satisfying feel without overcomplicating things.\n\nActually, let me simplify even further for the initial version—I'll just lock the piece immediately when it hits the bottom. That's cleaner to start with.\n\nNow I'm thinking through the DAS (delayed auto-shift) mechanics more carefully. The standard approach is: first press moves instantly, then if held down, there's a delay before auto-repeat kicks in, followed by rapid repeats. For soft drop, I want it to feel snappy—maybe 20 times faster than normal gravity. Let me set the initial DAS delay to around 150ms and work from there.\n\nWriting the game code... Finishing the highlight and shadow rectangles...\n\nNow I need to map board coordinates to canvas positions correctly—each cell at column and row translates directly by multiplying by the cell size, so I can render the full grid with proper positioning.\n\nSetting up the main render function... Finishing up the rendering logic...\n\nNow I'm thinking about adding a line clear animation to make it more visually satisfying. A simple white flash when lines are cleared would be nice, though I could also just clear them immediately to keep things simple. Let me go with the flash animation since it's not too complex.\n\nFor the piece spawn position, I need to make sure pieces appear at the top of the board centered horizontally, with the I piece positioned correctly so its line starts at row 0. I'm realizing I should simplify the O piece to a standard 2x2 instead of padding it to 4 wide, and I need to make sure all pieces conform to their proper SRS bounding boxes—I piece at 4x4, O piece at 3x3, and the others at 3x3 as well.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":170,"cache_read_input_tokens":25368,"cache_creation":{"ephemeral_5m_input_tokens":170,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"2e10e0e1-3d6d-4274-82f0-5959564a8354"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011WhYBKj5V7MWHRw7qgKpAy","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"TypeScript is available. Now let me create all the necessary files.\n\nHere's my plan:\n1. `tsconfig.json` - TypeScript configuration\n2. `src/tetris.ts` - Main game file\n3. `index.html` - HTML shell\n4. `style.css` - Styling\n5. Update `package.json` to add build script\n\nLet me write them all now.\n\nFor the TypeScript game, I'll implement:\n- Full Tetris with all 7 tetrominoes\n- SRS wall kicks\n- 7-bag randomizer\n\n\n- Ghost piece, hold piece, and next piece preview\n- Scoring, levels, and increasing speed\n- DAS for smooth controls\n- Pause/resume and game over screen\n- Clean visual design\n\nI'll use a class-based approach for the game to keep everything well-organized. Now I need to verify the SRS wall kick offsets from the Tetris Wiki, making sure I convert the coordinate system correctly since Y+ is up in their specification.\n\nWriting the TypeScript game logic... L, S, T, Z pieces with their rotation state transitions and corresponding offset tests. Now I'm converting these coordinates to canvas space by negating the Y component, so positive Y values in the wiki notation become negative in canvas coordinates. Continuing through the rotation test cases for the I piece, checking how the wiki coordinates translate to canvas offsets across all the different rotation transitions. Generating rotation offset table... Now I have the complete wall kick offset table for all rotation transitions. With that locked in, I'm ready to build out the full implementation. For the visual design, I'm going for a polished look with a dark background, colored pieces with bright borders, subtle grid lines, and clean UI panels—keeping it modern and clean overall.\n\nWriting the Tetris implementation... Defining the piece shapes... Defining the rotation states for the remaining Tetris pieces... Defining wall kick data for different piece types... Still writing game logic... Setting up the game class with canvas contexts for the main board and next/hold piece displays, then initializing all the game state variables like the current piece, score tracking, input handling, and the game loop timing. Setting up event listeners for keyup and the start button, then displaying the initial overlay with instructions and drawing the idle screen. Now I'm working on the UI methods—showing and hiding overlays, and updating the stats display...\n\nUpdating the score, level, and lines on screen, then handling the start button logic to transition between idle, playing, paused, and gameover states. When starting a fresh game, I'm initializing the board, resetting the score and level, clearing the held piece, and setting up a new randomizer for the piece bag.\n\nSetting up the next piece, calculating the drop interval based on the current level, and spawning the first piece. Then I'm transitioning to the playing state, hiding any overlay, changing the button text to \"PAUSE\", and kicking off the game loop with requestAnimationFrame.\n\nHandling the pause state by showing an overlay with pause instructions and updating the button text... Writing game logic... Writing game logic... Writing rotation and hold logic... Writing input handler... Still writing the input handler... Writing game loop logic... Writing the rendering logic... Now I'm rendering the locked cells from the board, then drawing the ghost piece with reduced opacity to show where the current piece will land, and finally drawing the active piece itself on top.\n\nFor the preview window, I'm setting up a dark background and calculating the appropriate cell size to center the piece shape within the given dimensions, then preparing to iterate through and render each cell of that preview.\n\nNow I'm completing the nested loop to draw each active cell in the piece preview, then I'm setting up separate methods to render the next piece and hold piece previews by retrieving their respective canvas elements and calling the preview drawing function with the appropriate context and piece type.\n\nFor the idle screen, I'm filling the canvas with a dark background and then randomly populating the bottom rows with colored blocks for visual interest. Finally, I'm initializing the game when the page loads.\n\nNow I need to build out the HTML structure with a centered layout featuring the main game board, hold and next piece previews on the sides, score displays, and control buttons. I'm also noticing an issue with the DAS timer logic—when it first exceeds the delay threshold, the repeat timer should reset properly rather than accumulating from the current delta time. Finishing up the DAS logic with the repeat timer loop, then I'm ready to write out the actual files. Let me double-check the O piece spawn positioning—with a 3x4 shape matrix, the spawn x-coordinate should center it properly on the 10-wide board, placing the actual filled cells at columns 4-5. So the I piece starts with its top row off-screen at y=-1, making the visible cells appear at the board's top edge. For the T and O pieces spawning at y=0, their top rows are immediately visible, with the T piece occupying rows 0-1 and the O piece doing the same.\n\nNow I'm ready to implement the actual code. I need to make sure the `isValid` function allows cells above the board (y < 0) for spawning, which my current check handles by only validating occupied cells within bounds. The game over detection will trigger if any cell placement during spawn is blocked.\n\nI'm going to write the implementation now, keeping it clean and functional without extra visual flourishes like score animations.\n\nWriting the game code... I'm settling on a fixed cell size of 24 pixels for the preview canvases, which gives me nice centering offsets for different piece shapes—the I piece gets 12 pixels of horizontal padding while the T piece gets 24.\n\nFor the tall I piece in rotation, the 4-row height of 96 pixels fits comfortably within the 120-pixel canvas, so this approach works across all rotations. Rather than overthinking conditional sizing based on piece dimensions, I'll just compute the cell size dynamically in the preview function like I had before—it's cleaner and handles all cases.\n\nTime to write out all the files.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":25538,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"9597ef9c-7e86-4ac9-bf77-36b597dad2fc"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011WhYBKj5V7MWHRw7qgKpAy","type":"message","role":"assistant","content":[{"type":"text","text":"Now I have a clear picture of the environment. Let me build the complete Tetris game with all files."}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":25538,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"38a49425-50f7-4828-b510-aef6c074582e"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011WhYBKj5V7MWHRw7qgKpAy","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XaqRU2kunwQ6WmNDeQBUJc","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-6c3p0wr6/src","description":"Create src directory"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":25538,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"5e1191c0-cf49-4317-aa9a-bc438c16ac30"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01XaqRU2kunwQ6WmNDeQBUJc","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"8f5d6b78-bdb0-41a6-9ff4-ba27860487bc","timestamp":"2026-04-05T19:33:07.904Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":true}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_019XRoiGEQRyhetJSgSYizDT","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Jt7bgAFEi9wf82bMHocwBK","name":"Bash","input":{"command":"cat > /tmp/loop-bench-6c3p0wr6/tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ES2020\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"noEmitOnError\": true,\n \"sourceMap\": true\n },\n \"include\": [\"src/**/*\"]\n}\nEOF","description":"Create tsconfig.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":11443,"cache_read_input_tokens":25538,"cache_creation":{"ephemeral_5m_input_tokens":11443,"ephemeral_1h_input_tokens":0},"output_tokens":55,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"d8fcdd22-1b16-4f39-aad9-5094878d7651"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Jt7bgAFEi9wf82bMHocwBK","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"acaa8d55-a1d7-49b9-bd6d-dfcb104e7792","timestamp":"2026-04-05T19:33:11.855Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01WLFSVAMca3dv1pjpWBs1Sf","type":"message","role":"assistant","content":[{"type":"text","text":"Now let's write the main TypeScript game file:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":231,"cache_read_input_tokens":36981,"cache_creation":{"ephemeral_5m_input_tokens":231,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"5b688582-2bd8-4d25-aa38-c1e780dc6938"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01KxRHpMV51ZHxFQcc9WGKgM","type":"message","role":"assistant","content":[{"type":"text","text":"Now the main game file — this is the heart of everything:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":37212,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"6e162e28-362c-44d6-92e1-d3ec42cd92b3"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01KxRHpMV51ZHxFQcc9WGKgM","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_014Jzgb2mZfLgyb56Aogzsk3","name":"Bash","input":{"command":"cat > /tmp/loop-bench-6c3p0wr6/src/tetris.ts << 'TSEOF'\n// =============================================================\n// TETRIS – Full browser implementation in TypeScript\n// =============================================================\n\n// ── Constants ──────────────────────────────────────────────\nconst BOARD_W = 10;\nconst BOARD_H = 20;\nconst CELL = 30; // px per cell on main board\nconst PREVIEW_W = 120; // px wide of hold / next canvas\nconst PREVIEW_H = 120;\n\n// ── Types ──────────────────────────────────────────────────\ntype PieceType = 'I' | 'O' | 'T' | 'S' | 'Z' | 'J' | 'L';\ntype Cell = string | null;\ntype Board = Cell[][];\ntype GameState = 'idle' | 'playing' | 'paused' | 'gameover';\n\ninterface Piece {\n type: PieceType;\n x: number; // board column of shape origin\n y: number; // board row of shape origin\n rotation: number; // 0–3\n}\n\n// ── Colours ────────────────────────────────────────────────\nconst COLORS: Record<PieceType, string> = {\n I: '#00f0f0',\n O: '#f0f000',\n T: '#a020f0',\n S: '#00e000',\n Z: '#f00000',\n J: '#2040f0',\n L: '#f0a000',\n};\n\n// Slightly darker shade used for 3-D inner shadow\nconst DARK: Record<PieceType, string> = {\n I: '#009090',\n O: '#909000',\n T: '#601890',\n S: '#008000',\n Z: '#900000',\n J: '#102080',\n L: '#905800',\n};\n\n// ── Shapes (4 rotations each) ──────────────────────────────\n// 1 = filled, 0 = empty\nconst SHAPES: Record<PieceType, readonly (readonly number[])[][]> = {\n I: [\n [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]],\n [[0,0,0,0],[0,0,0,0],[1,1,1,1],[0,0,0,0]],\n [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],\n ],\n O: [\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n ],\n T: [\n [[0,1,0],[1,1,1],[0,0,0]],\n [[0,1,0],[0,1,1],[0,1,0]],\n [[0,0,0],[1,1,1],[0,1,0]],\n [[0,1,0],[1,1,0],[0,1,0]],\n ],\n S: [\n [[0,1,1],[1,1,0],[0,0,0]],\n [[0,1,0],[0,1,1],[0,0,1]],\n [[0,0,0],[0,1,1],[1,1,0]],\n [[1,0,0],[1,1,0],[0,1,0]],\n ],\n Z: [\n [[1,1,0],[0,1,1],[0,0,0]],\n [[0,0,1],[0,1,1],[0,1,0]],\n [[0,0,0],[1,1,0],[0,1,1]],\n [[0,1,0],[1,1,0],[1,0,0]],\n ],\n J: [\n [[1,0,0],[1,1,1],[0,0,0]],\n [[0,1,1],[0,1,0],[0,1,0]],\n [[0,0,0],[1,1,1],[0,0,1]],\n [[0,1,0],[0,1,0],[1,1,0]],\n ],\n L: [\n [[0,0,1],[1,1,1],[0,0,0]],\n [[0,1,0],[0,1,0],[0,1,1]],\n [[0,0,0],[1,1,1],[1,0,0]],\n [[1,1,0],[0,1,0],[0,1,0]],\n ],\n};\n\n// ── SRS Wall-kick tables ───────────────────────────────────\n// Offsets are [dx, dy] in canvas coords (positive-Y = DOWN)\n// Derived from the Tetris Guideline with Y axis flipped.\n\nconst KICKS_JLSTZ: Record<string, readonly [number, number][]> = {\n '0>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n '1>0': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n '1>2': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n '2>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n '2>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n '3>2': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n '3>0': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n '0>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n};\n\nconst KICKS_I: Record<string, readonly [number, number][]> = {\n '0>1': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n '1>0': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n '1>2': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n '2>1': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n '2>3': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n '3>2': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n '3>0': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n '0>3': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n};\n\n// ── Scoring ────────────────────────────────────────────────\nconst LINE_SCORE = [0, 100, 300, 500, 800]; // 0–4 lines\n\n/** Drop interval in ms for a given level (Tetris guideline formula). */\nfunction dropInterval(level: number): number {\n const sec = Math.pow(0.8 - (level - 1) * 0.007, level - 1);\n return Math.max(50, Math.floor(sec * 1000));\n}\n\n// ── Helpers ────────────────────────────────────────────────\nconst ALL_TYPES: PieceType[] = ['I','O','T','S','Z','J','L'];\n\nfunction getShape(type: PieceType, rotation: number): readonly (readonly number[])[] {\n return SHAPES[type][((rotation % 4) + 4) % 4];\n}\n\n/** Returns [boardX, boardY] for every filled cell of the piece. */\nfunction cells(p: Piece): [number, number][] {\n const out: [number, number][] = [];\n const shape = getShape(p.type, p.rotation);\n for (let r = 0; r < shape.length; r++) {\n for (let c = 0; c < shape[r].length; c++) {\n if (shape[r][c]) out.push([p.x + c, p.y + r]);\n }\n }\n return out;\n}\n\n// ── 7-bag randomiser ───────────────────────────────────────\nclass Bag {\n private pool: PieceType[] = [];\n\n private refill() {\n this.pool = [...ALL_TYPES];\n for (let i = this.pool.length - 1; i > 0; i--) {\n const j = (Math.random() * (i + 1)) | 0;\n [this.pool[i], this.pool[j]] = [this.pool[j], this.pool[i]];\n }\n }\n\n next(): PieceType {\n if (!this.pool.length) this.refill();\n return this.pool.pop()!;\n }\n\n peek(): PieceType {\n if (!this.pool.length) this.refill();\n return this.pool[this.pool.length - 1];\n }\n}\n\n// ══════════════════════════════════════════════════════════\n// Main Game Class\n// ══════════════════════════════════════════════════════════\nclass TetrisGame {\n\n // Canvases\n private readonly ctx: CanvasRenderingContext2D;\n private readonly nextCtx: CanvasRenderingContext2D;\n private readonly holdCtx: CanvasRenderingContext2D;\n\n // Board\n private board: Board = this.emptyBoard();\n\n // Pieces\n private current: Piece | null = null;\n private nextType: PieceType = 'I';\n private heldType: PieceType | null = null;\n private canHold = true;\n private bag = new Bag();\n\n // Stats\n private score = 0;\n private level = 1;\n private lines = 0;\n\n // Game loop\n private state: GameState = 'idle';\n private animId: number = 0;\n private lastTime = 0;\n private dropCtr = 0; // accumulated ms toward next gravity drop\n private softDrop = false;\n\n // DAS (Delayed Auto-Shift)\n private dasDir = 0; // -1 | 0 | 1\n private dasTimer = 0;\n private dasRepeat = 0;\n private readonly DAS_DELAY = 133;\n private readonly DAS_PERIOD = 50;\n\n // Key state\n private held = new Set<string>();\n\n // ── Constructor ──────────────────────────────────────────\n constructor() {\n this.ctx = this.getCtx('game-canvas');\n this.nextCtx = this.getCtx('next-canvas');\n this.holdCtx = this.getCtx('hold-canvas');\n\n this.nextType = this.bag.next();\n\n document.addEventListener('keydown', e => this.onKeyDown(e));\n document.addEventListener('keyup', e => this.onKeyUp(e));\n document.getElementById('start-btn')!\n .addEventListener('click', () => this.onStartBtn());\n\n this.showOverlay('TETRIS', 'Press Space to start');\n this.drawIdleBoard();\n this.drawPreview(this.nextCtx, null);\n this.drawPreview(this.holdCtx, null);\n }\n\n private getCtx(id: string): CanvasRenderingContext2D {\n return (document.getElementById(id) as HTMLCanvasElement)\n .getContext('2d')!;\n }\n\n // ── Overlay helpers ──────────────────────────────────────\n private showOverlay(title: string, msg: string) {\n document.getElementById('overlay')!.style.display = 'flex';\n document.getElementById('ov-title')!.textContent = title;\n // handle literal \\n line breaks in msg\n const msgEl = document.getElementById('ov-msg')!;\n msgEl.innerHTML = msg.split('\\n').map(l => `<span>${l}</span>`).join('<br>');\n }\n\n private hideOverlay() {\n document.getElementById('overlay')!.style.display = 'none';\n }\n\n private setBtn(txt: string) {\n (document.getElementById('start-btn') as HTMLButtonElement).textContent = txt;\n }\n\n private updateStats() {\n document.getElementById('score')!.textContent = this.score.toLocaleString();\n document.getElementById('level')!.textContent = String(this.level);\n document.getElementById('lines')!.textContent = String(this.lines);\n }\n\n // ── Button / start flow ──────────────────────────────────\n private onStartBtn() {\n if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n else if (this.state === 'playing') this.pauseGame();\n else if (this.state === 'paused') this.resumeGame();\n }\n\n startGame() {\n this.board = this.emptyBoard();\n this.score = 0;\n this.level = 1;\n this.lines = 0;\n this.heldType = null;\n this.canHold = true;\n this.bag = new Bag();\n this.nextType = this.bag.next();\n this.dropCtr = 0;\n this.softDrop = false;\n this.dasDir = 0;\n\n this.updateStats();\n this.drawPreview(this.holdCtx, null);\n this.spawnPiece();\n\n if (this.state === 'playing') cancelAnimationFrame(this.animId);\n this.state = 'playing';\n this.hideOverlay();\n this.setBtn('PAUSE');\n\n this.lastTime = performance.now();\n this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n pauseGame() {\n this.state = 'paused';\n cancelAnimationFrame(this.animId);\n this.showOverlay('PAUSED', 'Press P or Space to resume');\n this.setBtn('RESUME');\n }\n\n resumeGame() {\n this.state = 'playing';\n this.hideOverlay();\n this.setBtn('PAUSE');\n this.lastTime = performance.now();\n this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n private endGame() {\n this.state = 'gameover';\n cancelAnimationFrame(this.animId);\n this.showOverlay(\n 'GAME OVER',\n `Score: ${this.score.toLocaleString()}\\nLines: ${this.lines} Level: ${this.level}\\nPress Space to play again`\n );\n this.setBtn('RESTART');\n }\n\n // ── Board helpers ────────────────────────────────────────\n private emptyBoard(): Board {\n return Array.from({ length: BOARD_H }, () => new Array<Cell>(BOARD_W).fill(null));\n }\n\n private isValid(p: Piece): boolean {\n for (const [x, y] of cells(p)) {\n if (x < 0 || x >= BOARD_W || y >= BOARD_H) return false;\n if (y >= 0 && this.board[y][x] !== null) return false;\n }\n return true;\n }\n\n private lock() {\n if (!this.current) return;\n const color = COLORS[this.current.type];\n for (const [x, y] of cells(this.current)) {\n if (y >= 0) this.board[y][x] = color;\n }\n this.clearLines();\n this.canHold = true;\n this.spawnPiece();\n }\n\n private clearLines() {\n let cleared = 0;\n for (let r = BOARD_H - 1; r >= 0; r--) {\n if (this.board[r].every(c => c !== null)) {\n this.board.splice(r, 1);\n this.board.unshift(new Array<Cell>(BOARD_W).fill(null));\n cleared++;\n r++; // recheck the row that slid into position r\n }\n }\n if (cleared) {\n this.lines += cleared;\n this.score += LINE_SCORE[cleared] * this.level;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) {\n this.level = newLevel;\n }\n this.updateStats();\n }\n }\n\n // ── Spawn ────────────────────────────────────────────────\n private spawnPiece() {\n const type = this.nextType;\n this.nextType = this.bag.next();\n\n const shape = getShape(type, 0);\n const w = shape[0].length;\n const spawnX = Math.floor((BOARD_W - w) / 2);\n // I piece rotation-0 has an empty top row → spawn 1 row higher\n const spawnY = type === 'I' ? -1 : 0;\n\n this.current = { type, x: spawnX, y: spawnY, rotation: 0 };\n\n if (!this.isValid(this.current)) {\n this.current.y--;\n if (!this.isValid(this.current)) {\n this.current = null;\n this.endGame();\n return;\n }\n }\n\n this.dropCtr = 0;\n this.drawPreview(this.nextCtx, this.nextType);\n }\n\n // ── Movement ─────────────────────────────────────────────\n private tryShift(dx: number, dy: number): boolean {\n if (!this.current) return false;\n const moved: Piece = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (this.isValid(moved)) { this.current = moved; return true; }\n return false;\n }\n\n /** Gravity tick – returns false if piece locked. */\n private gravityDrop(): boolean {\n if (!this.current) return false;\n if (!this.tryShift(0, 1)) {\n this.lock();\n return false;\n }\n return true;\n }\n\n private hardDrop() {\n if (!this.current) return;\n let rows = 0;\n while (this.tryShift(0, 1)) rows++;\n this.score += rows * 2;\n this.updateStats();\n this.lock();\n }\n\n private rotate(dir: 1 | -1) {\n if (!this.current) return;\n const from = this.current.rotation;\n const to = ((from + dir + 4) % 4) as 0|1|2|3;\n const key = `${from}>${to}`;\n\n const kicks: readonly [number,number][] =\n this.current.type === 'I' ? KICKS_I[key] :\n this.current.type === 'O' ? [[0,0]] :\n KICKS_JLSTZ[key];\n\n for (const [dx, dy] of kicks) {\n const attempt: Piece = { ...this.current, rotation: to,\n x: this.current.x + dx,\n y: this.current.y + dy };\n if (this.isValid(attempt)) { this.current = attempt; return; }\n }\n }\n\n private holdPiece() {\n if (!this.current || !this.canHold) return;\n const type = this.current.type;\n if (this.heldType === null) {\n this.heldType = type;\n this.spawnPiece();\n } else {\n const swap = this.heldType;\n this.heldType = type;\n const shape = getShape(swap, 0);\n const w = shape[0].length;\n this.current = { type: swap,\n x: Math.floor((BOARD_W - w) / 2),\n y: swap === 'I' ? -1 : 0,\n rotation: 0 };\n this.dropCtr = 0;\n }\n this.canHold = false;\n this.drawPreview(this.holdCtx, this.heldType);\n }\n\n // Ghost: lowest valid position of current piece\n private ghost(): Piece | null {\n if (!this.current) return null;\n let g = { ...this.current };\n while (true) {\n const down = { ...g, y: g.y + 1 };\n if (this.isValid(down)) g = down; else break;\n }\n return g;\n }\n\n // ── Input ────────────────────────────────────────────────\n private readonly GAME_KEYS = new Set([\n 'ArrowLeft','ArrowRight','ArrowDown','ArrowUp',\n 'Space','KeyZ','KeyX','KeyC','KeyP','Escape',\n ]);\n\n private onKeyDown(e: KeyboardEvent) {\n if (this.GAME_KEYS.has(e.code)) e.preventDefault();\n if (this.held.has(e.code)) return; // ignore key-repeat from OS\n this.held.add(e.code);\n\n if (e.code === 'KeyP' || e.code === 'Escape') {\n if (this.state === 'playing') this.pauseGame();\n else if (this.state === 'paused') this.resumeGame();\n return;\n }\n\n if (e.code === 'Space') {\n if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n else if (this.state === 'paused') this.resumeGame();\n else if (this.state === 'playing') this.hardDrop();\n return;\n }\n\n if (this.state !== 'playing') return;\n\n switch (e.code) {\n case 'ArrowLeft':\n this.tryShift(-1, 0);\n this.startDAS(-1);\n break;\n case 'ArrowRight':\n this.tryShift(1, 0);\n this.startDAS(1);\n break;\n case 'ArrowDown':\n this.softDrop = true;\n break;\n case 'ArrowUp':\n case 'KeyX':\n this.rotate(1);\n break;\n case 'KeyZ':\n this.rotate(-1);\n break;\n case 'KeyC':\n this.holdPiece();\n break;\n }\n }\n\n private onKeyUp(e: KeyboardEvent) {\n this.held.delete(e.code);\n if (e.code === 'ArrowLeft' && this.dasDir === -1) this.stopDAS();\n if (e.code === 'ArrowRight' && this.dasDir === 1) this.stopDAS();\n if (e.code === 'ArrowDown') this.softDrop = false;\n }\n\n private startDAS(dir: -1 | 1) {\n this.dasDir = dir;\n this.dasTimer = 0;\n this.dasRepeat = 0;\n }\n\n private stopDAS() {\n // Re-engage for the other direction if still held\n if (this.held.has('ArrowLeft') && this.dasDir !== -1) this.startDAS(-1);\n else if (this.held.has('ArrowRight') && this.dasDir !== 1) this.startDAS(1);\n else { this.dasDir = 0; this.dasTimer = 0; this.dasRepeat = 0; }\n }\n\n // ── Game loop ────────────────────────────────────────────\n private loop(ts: number) {\n const dt = Math.min(ts - this.lastTime, 100); // cap to avoid spiral after tab-switch\n this.lastTime = ts;\n\n // DAS\n if (this.dasDir !== 0) {\n this.dasTimer += dt;\n if (this.dasTimer >= this.DAS_DELAY) {\n this.dasRepeat += dt;\n while (this.dasRepeat >= this.DAS_PERIOD) {\n this.dasRepeat -= this.DAS_PERIOD;\n this.tryShift(this.dasDir, 0);\n }\n }\n }\n\n // Gravity\n const interval = this.softDrop\n ? Math.max(dropInterval(this.level) / 20, 33)\n : dropInterval(this.level);\n\n this.dropCtr += dt;\n while (this.dropCtr >= interval && this.state === 'playing') {\n this.dropCtr -= interval;\n if (this.softDrop && this.current) {\n this.score += 1;\n document.getElementById('score')!.textContent = this.score.toLocaleString();\n }\n if (!this.gravityDrop()) break; // piece locked → new piece spawned\n }\n\n this.draw();\n if (this.state === 'playing') this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Rendering ────────────────────────────────────────────\n\n /** Draw one cell at grid coords (gx, gy) using given pixel size. */\n private drawCell(\n ctx: CanvasRenderingContext2D,\n gx: number, gy: number,\n type: PieceType,\n size: number,\n alpha = 1,\n ) {\n const px = gx * size;\n const py = gy * size;\n const s = size;\n const b = Math.max(2, (s / 10) | 0); // border/bevel thickness\n\n ctx.globalAlpha = alpha;\n\n // Fill\n ctx.fillStyle = COLORS[type];\n ctx.fillRect(px, py, s, s);\n\n // Inner bevel – bright top/left\n ctx.fillStyle = 'rgba(255,255,255,0.45)';\n ctx.fillRect(px, py, s, b); // top strip\n ctx.fillRect(px, py, b, s); // left strip\n\n // Inner bevel – dark bottom/right\n ctx.fillStyle = DARK[type];\n ctx.fillRect(px, py + s - b, s, b); // bottom\n ctx.fillRect(px + s - b, py, b, s); // right\n\n // Inset highlight square\n ctx.fillStyle = COLORS[type];\n ctx.fillRect(px + b, py + b, s - b * 2, s - b * 2);\n\n // Subtle inner shine\n ctx.fillStyle = 'rgba(255,255,255,0.18)';\n ctx.fillRect(px + b, py + b, s - b * 2, Math.max(1, (s - b * 2) / 2 | 0));\n\n ctx.globalAlpha = 1;\n }\n\n /** Main board render. */\n private draw() {\n const ctx = this.ctx;\n const W = BOARD_W * CELL;\n const H = BOARD_H * CELL;\n\n // ── Background ──\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, W, H);\n\n // ── Grid lines ──\n ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n ctx.lineWidth = 1;\n for (let c = 0; c <= BOARD_W; c++) {\n ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, H); ctx.stroke();\n }\n for (let r = 0; r <= BOARD_H; r++) {\n ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(W, r * CELL); ctx.stroke();\n }\n\n // ── Locked cells ──\n for (let r = 0; r < BOARD_H; r++) {\n for (let c = 0; c < BOARD_W; c++) {\n const color = this.board[r][c];\n if (color) {\n // find which type this color belongs to\n const type = (Object.keys(COLORS) as PieceType[])\n .find(k => COLORS[k] === color) ?? 'I';\n this.drawCell(ctx, c, r, type, CELL);\n }\n }\n }\n\n // ── Ghost piece ──\n const gh = this.ghost();\n if (gh && this.current && gh.y !== this.current.y) {\n for (const [x, y] of cells(gh)) {\n if (y >= 0) this.drawCell(ctx, x, y, gh.type, CELL, 0.18);\n }\n }\n\n // ── Current piece ──\n if (this.current) {\n for (const [x, y] of cells(this.current)) {\n if (y >= 0) this.drawCell(ctx, x, y, this.current.type, CELL);\n }\n }\n }\n\n /** Draw a piece centred inside the given small canvas context. */\n private drawPreview(ctx: CanvasRenderingContext2D, type: PieceType | null) {\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, PREVIEW_W, PREVIEW_H);\n\n if (!type) return;\n\n const shape = getShape(type, 0);\n const rows = shape.length;\n const cols = shape[0].length;\n\n // Compute the tightest bounding box of filled cells\n let minR = rows, maxR = 0, minC = cols, maxC = 0;\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n if (shape[r][c]) {\n if (r < minR) minR = r; if (r > maxR) maxR = r;\n if (c < minC) minC = c; if (c > maxC) maxC = c;\n }\n }\n }\n const bRows = maxR - minR + 1;\n const bCols = maxC - minC + 1;\n\n const cellSz = Math.min(\n Math.floor((PREVIEW_W - 16) / bCols),\n Math.floor((PREVIEW_H - 16) / bRows),\n 28,\n );\n\n const offX = Math.floor((PREVIEW_W - bCols * cellSz) / 2) - minC * cellSz;\n const offY = Math.floor((PREVIEW_H - bRows * cellSz) / 2) - minR * cellSz;\n\n ctx.save();\n ctx.translate(offX, offY);\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n if (shape[r][c]) this.drawCell(ctx, c, r, type, cellSz);\n }\n }\n ctx.restore();\n }\n\n /** Idle screen: a partially-filled board with random blocks. */\n private drawIdleBoard() {\n const ctx = this.ctx;\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, BOARD_W * CELL, BOARD_H * CELL);\n\n ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n ctx.lineWidth = 1;\n for (let c = 0; c <= BOARD_W; c++) {\n ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, BOARD_H * CELL); ctx.stroke();\n }\n for (let r = 0; r <= BOARD_H; r++) {\n ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(BOARD_W * CELL, r * CELL); ctx.stroke();\n }\n\n for (let r = 14; r < BOARD_H; r++) {\n for (let c = 0; c < BOARD_W; c++) {\n if (Math.random() > 0.35) {\n const t = ALL_TYPES[(Math.random() * ALL_TYPES.length) | 0];\n this.drawCell(ctx, c, r, t, CELL);\n }\n }\n }\n }\n}\n\n// ── Bootstrap ─────────────────────────────────────────────\nwindow.addEventListener('DOMContentLoaded', () => { new TetrisGame(); });\nTSEOF","description":"Write the main TypeScript game file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":37212,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"3d6ef0d9-7450-4b08-a759-91a819cd4a93"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_014Jzgb2mZfLgyb56Aogzsk3","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"a75fba6a-a9b1-47ff-be50-882254166066","timestamp":"2026-04-05T19:36:35.293Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01CZKXniGDKNKn8V8di9Rnhq","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01G2t7H6PiQ6CxDNzqNk3B2U","name":"Bash","input":{"command":"cat > /tmp/loop-bench-6c3p0wr6/style.css << 'EOF'\n/* ── Reset / Base ─────────────────────────────────────── */\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\nbody {\n background: #0a0a18;\n color: #e0e0ff;\n font-family: 'Segoe UI', system-ui, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n overflow: hidden;\n user-select: none;\n}\n\n/* ── Layout ───────────────────────────────────────────── */\n#wrapper {\n display: flex;\n gap: 12px;\n align-items: flex-start;\n}\n\n/* ── Side panels ──────────────────────────────────────── */\n.side-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 120px;\n padding-top: 4px;\n}\n\n.panel-box {\n background: #16162e;\n border: 1px solid #2a2a50;\n border-radius: 6px;\n padding: 10px 8px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.panel-label {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 2px;\n color: #7070b0;\n text-transform: uppercase;\n}\n\n.panel-value {\n font-size: 22px;\n font-weight: 700;\n color: #d0d0ff;\n letter-spacing: 1px;\n font-variant-numeric: tabular-nums;\n}\n\ncanvas {\n display: block;\n}\n\n/* ── Game canvas wrapper ──────────────────────────────── */\n#game-wrap {\n position: relative;\n border: 2px solid #2a2a50;\n border-radius: 4px;\n overflow: hidden;\n box-shadow:\n 0 0 30px rgba(80, 80, 200, 0.25),\n 0 0 8px rgba(80, 80, 200, 0.15);\n}\n\n/* ── Overlay ──────────────────────────────────────────── */\n#overlay {\n position: absolute;\n inset: 0;\n background: rgba(5, 5, 20, 0.88);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 14px;\n backdrop-filter: blur(2px);\n z-index: 10;\n}\n\n#ov-title {\n font-size: 42px;\n font-weight: 900;\n letter-spacing: 6px;\n text-transform: uppercase;\n background: linear-gradient(135deg, #00f0f0, #a020f0, #f0a000);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n text-shadow: none;\n line-height: 1;\n}\n\n#ov-msg {\n font-size: 13px;\n color: #9090c0;\n text-align: center;\n line-height: 1.8;\n}\n\n/* ── Controls hint ────────────────────────────────────── */\n#controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even) { color: #5a5a8a; }\n\n/* ── Button ───────────────────────────────────────────── */\n#start-btn {\n margin-top: 6px;\n padding: 9px 32px;\n background: linear-gradient(135deg, #1a1a60, #2a2a90);\n border: 1px solid #4040a0;\n border-radius: 4px;\n color: #c0c0ff;\n font-size: 13px;\n font-weight: 700;\n letter-spacing: 2px;\n cursor: pointer;\n transition: background 0.15s, transform 0.1s;\n}\n\n#start-btn:hover { background: linear-gradient(135deg, #2a2a80, #3a3ab0); }\n#start-btn:active { transform: scale(0.97); }\n\n/* ── Preview canvases ─────────────────────────────────── */\n#next-canvas, #hold-canvas {\n border-radius: 4px;\n}\n\n/* ── Responsive: shrink on small screens ─────────────── */\n@media (max-width: 560px) {\n #wrapper { gap: 6px; transform: scale(0.82); transform-origin: top center; }\n}\nEOF","description":"Write the CSS stylesheet"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":8902,"cache_read_input_tokens":37212,"cache_creation":{"ephemeral_5m_input_tokens":8902,"ephemeral_1h_input_tokens":0},"output_tokens":38,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"eefce481-0362-4361-a57d-32fa46447e02"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01G2t7H6PiQ6CxDNzqNk3B2U","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"36561963-e72b-4494-a939-662a1115edc6","timestamp":"2026-04-05T19:36:55.022Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01BU4HYm5dJCu1jjBagwNNms","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_011AWagec2thxdd7aMct1Gh2","name":"Bash","input":{"command":"cat > /tmp/loop-bench-6c3p0wr6/index.html << 'EOF'\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <link rel=\"stylesheet\" href=\"style.css\" />\n</head>\n<body>\n\n<div id=\"wrapper\">\n\n <!-- ── Left panel: Hold + Controls ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Hold</div>\n <canvas id=\"hold-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\" style=\"gap:2px\">\n <div class=\"panel-label\" style=\"margin-bottom:4px\">Controls</div>\n <div id=\"controls\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold</span>\n <span>P / Esc</span> <span>Pause</span>\n </div>\n </div>\n </div>\n\n <!-- ── Main board ── -->\n <div id=\"game-wrap\">\n <canvas id=\"game-canvas\" width=\"300\" height=\"600\"></canvas>\n\n <!-- Overlay for title / pause / game-over -->\n <div id=\"overlay\">\n <div id=\"ov-title\">TETRIS</div>\n <div id=\"ov-msg\">Press Space to start</div>\n <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>\n <button id=\"start-btn\">START</button>\n </div>\n </div>\n\n <!-- ── Right panel: Next + Stats ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Next</div>\n <canvas id=\"next-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Score</div>\n <div class=\"panel-value\" id=\"score\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Level</div>\n <div class=\"panel-value\" id=\"level\">1</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Lines</div>\n <div class=\"panel-value\" id=\"lines\">0</div>\n </div>\n </div>\n\n</div>\n\n<script type=\"module\" src=\"dist/tetris.js\"></script>\n</body>\n</html>\nEOF","description":"Write the HTML file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1459,"cache_read_input_tokens":46114,"cache_creation":{"ephemeral_5m_input_tokens":1459,"ephemeral_1h_input_tokens":0},"output_tokens":36,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"55339ba9-6e35-4627-b3ce-15bf9c73bae5"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_011AWagec2thxdd7aMct1Gh2","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"def40cb7-83b6-45fe-b0cd-b9bd57424e12","timestamp":"2026-04-05T19:37:08.392Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0168WucC3zyELrcxLoJeEyJ5","type":"message","role":"assistant","content":[{"type":"text","text":"Now update `package.json` with build scripts and compile:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1013,"cache_read_input_tokens":47573,"cache_creation":{"ephemeral_5m_input_tokens":1013,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"79b1beb8-5a6a-4cb6-82b7-b533313f2cd2"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0168WucC3zyELrcxLoJeEyJ5","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01L8xrtXdLbYUWdr4KXqCu3H","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-6c3p0wr6/package.json","old_string":" \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","new_string":" \"scripts\": {\n \"build\": \"tsc\",\n \"watch\": \"tsc --watch\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1013,"cache_read_input_tokens":47573,"cache_creation":{"ephemeral_5m_input_tokens":1013,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"eb2563ee-74f7-4382-acf6-b72ee1a48716"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01L8xrtXdLbYUWdr4KXqCu3H","type":"tool_result","content":"The file /tmp/loop-bench-6c3p0wr6/package.json has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"db4450fa-96de-463b-870e-f02f261e3e5f","timestamp":"2026-04-05T19:37:12.123Z","tool_use_result":{"filePath":"/tmp/loop-bench-6c3p0wr6/package.json","oldString":" \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","newString":" \"scripts\": {\n \"build\": \"tsc\",\n \"watch\": \"tsc --watch\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","originalFile":"{\n \"name\": \"loop-bench-6c3p0wr6\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@types/node\": \"^25.5.2\",\n \"eslint\": \"^10.2.0\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","structuredPatch":[{"oldStart":4,"oldLines":6,"newStart":4,"newLines":8,"lines":[" \"description\": \"\","," \"main\": \"index.js\","," \"scripts\": {","+ \"build\": \"tsc\",","+ \"watch\": \"tsc --watch\","," \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\""," },"," \"keywords\": [],"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01UNULdGeSTWgytYJdGxouT2","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01F81J7Qrt8KZgnZ8igQZyze","name":"Bash","input":{"command":"npm run build 2>&1","description":"Compile TypeScript to JavaScript"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":251,"cache_read_input_tokens":48586,"cache_creation":{"ephemeral_5m_input_tokens":251,"ephemeral_1h_input_tokens":0},"output_tokens":62,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"d0104a6d-3970-4370-a36c-2c543f4d6695"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01F81J7Qrt8KZgnZ8igQZyze","type":"tool_result","content":"> loop-bench-6c3p0wr6@1.0.0 build\n> tsc","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"2bc794d9-e6e2-4ca8-8abc-3a9a0c922d19","timestamp":"2026-04-05T19:37:15.216Z","tool_use_result":{"stdout":"> loop-bench-6c3p0wr6@1.0.0 build\n> tsc","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01SiKqrqcUnQFstHZXGH4kKw","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The build succeeded with no errors. Let me check the dist directory to make sure the output was created.","signature":"EqUCClsIDBgCKkBKSNp2MJXY/XoJdtdDIP7kDuUpMiIvlEC7zCaY3xGN4y0e69iUi3iJWr0tAksShJVlaqDZoOCTjPSBC5mT8lUAMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgxThOZX33jDcIoTcV0aDDDDV0YtZJDCYCVVByIwYXKRtTVDok8gWoKWegCrQomPTRsCsWB3W9yVnampSWyAl7V4gZyPphxEHriWxCOcKnhHwZbMmmQ9o5xAWdi+p6G9F4kM/fj56aQKwoblbI4EirYt5XeLkjoqmFFXpgbl6n9A0o4tsBZ0k4NpO+PH61nKv3Yrc87vzNm4FyMRaKJ4mzriIgDROq4kbRbfhmprhnAY6TzbY2apVVvJER+XiscVX0P/Z9k0FxMYAQ=="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":116,"cache_read_input_tokens":48837,"cache_creation":{"ephemeral_5m_input_tokens":116,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"8db6a972-6e3f-4722-ba96-d2a2aac8c34c"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01SiKqrqcUnQFstHZXGH4kKw","type":"message","role":"assistant","content":[{"type":"text","text":"Clean compile. Let me verify the output:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":116,"cache_read_input_tokens":48837,"cache_creation":{"ephemeral_5m_input_tokens":116,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"e88be3e5-eabf-4c23-8b70-651e246dabd3"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01SiKqrqcUnQFstHZXGH4kKw","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01WCA8pJsMp7B3vkvoeYKjFx","name":"Bash","input":{"command":"ls -lh /tmp/loop-bench-6c3p0wr6/dist/","description":"List compiled output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":116,"cache_read_input_tokens":48837,"cache_creation":{"ephemeral_5m_input_tokens":116,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"653ef957-7507-45d2-9dd2-7c34dd80f9ae"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01WCA8pJsMp7B3vkvoeYKjFx","type":"tool_result","content":"total 60K\n-rw-r--r-- 1 root root 25K Apr 5 21:37 tetris.js\n-rw-r--r-- 1 root root 30K Apr 5 21:37 tetris.js.map","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"3b970225-b9d0-4e96-bf44-ecab0162d900","timestamp":"2026-04-05T19:37:18.002Z","tool_use_result":{"stdout":"total 60K\n-rw-r--r-- 1 root root 25K Apr 5 21:37 tetris.js\n-rw-r--r-- 1 root root 30K Apr 5 21:37 tetris.js.map","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GXxkcdq6P6rUaptddAAQu5","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The compilation succeeded. Let me do a quick review of the compiled JavaScript to make sure it looks correct.\n\nLet me also review the TypeScript source to double-check everything, particularly:\n1. The `clearLines` function - when we find a full row, we splice it out and unshift an empty row, then increment `r` to recheck. Wait, actually after splicing, the row at index `r` is now the row that was below, so we need to check it again. With `r++` and the loop doing `r--` at the end... wait, we have `for (let r = BOARD_H - 1; r >= 0; r--)`. \n\nInside the loop, if we found a full row and do `r++`, then the loop does `r--` which brings us back to the same index. That's correct!\n\n2. The `findType` in the draw function - I'm doing a reverse lookup from color to piece type by checking against the COLORS object. It's a bit inefficient since the board only stores color strings, but it works. I could optimize this by storing the type directly on the board instead, but for now this approach is fine.\n\n3. The ghost piece...\n\nNow I'm checking the ghost piece rendering - I skip drawing it when it's at the same position as the current piece, which prevents the visual overlap. The DAS handling looks right too - when the delay elapses, we move and decrement the repeat timer. For soft drop, I'm using a formula that makes it about 20 times faster than normal gravity, which should feel responsive.\n\nThe scoring system multiplies the line clear value by the current level - so clearing 4 lines at level 1 gives 800 points, which matches the standard Tetris guideline. Now I'm checking the wall kick data for the rotation states...\n\nThe wall kick offsets for clockwise rotation follow the standard SRS pattern - starting with no offset, then trying left, left-up, down, and left-down positions. These are correctly converted from the standard Y-up coordinate system to the canvas Y-down system.\n\nI'm noticing a problem with the HTML though - I've used `id=\"controls\"` twice, once in the left panel and once in the overlay. IDs need to be unique, so I need to fix that. I'm fixing the duplicate ID issue by converting the overlay controls to use a class instead, since they're only for display purposes and don't need JavaScript references.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":214,"cache_read_input_tokens":48953,"cache_creation":{"ephemeral_5m_input_tokens":214,"ephemeral_1h_input_tokens":0},"output_tokens":28,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"49c2419c-6387-4a60-8e85-4d3266970587"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GXxkcdq6P6rUaptddAAQu5","type":"message","role":"assistant","content":[{"type":"text","text":"Good. Let me fix a duplicate `id` issue in the HTML (the controls grid appears twice):"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":214,"cache_read_input_tokens":48953,"cache_creation":{"ephemeral_5m_input_tokens":214,"ephemeral_1h_input_tokens":0},"output_tokens":28,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"0c03cbfe-e5a1-422c-9e05-4a0750ceaa24"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GXxkcdq6P6rUaptddAAQu5","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01UqyM3ycvNuhovkPJDTQhmx","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-6c3p0wr6/index.html","old_string":" <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>","new_string":" <div class=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":214,"cache_read_input_tokens":48953,"cache_creation":{"ephemeral_5m_input_tokens":214,"ephemeral_1h_input_tokens":0},"output_tokens":28,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"c1b4cf2a-499d-4762-af57-94f70f8e910b"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>","is_error":true,"tool_use_id":"toolu_01UqyM3ycvNuhovkPJDTQhmx"}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"60b8601c-eba6-4118-a760-897d05324d8f","timestamp":"2026-04-05T19:37:42.205Z","tool_use_result":"Error: File has not been read yet. Read it first before writing to it."} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01ALa3bpgMjhJ7gZxxrHLiCQ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01PZSTLLDG9FrPBg4Fyqdjy5","name":"Read","input":{"file_path":"/tmp/loop-bench-6c3p0wr6/index.html"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1417,"cache_read_input_tokens":49167,"cache_creation":{"ephemeral_5m_input_tokens":1417,"ephemeral_1h_input_tokens":0},"output_tokens":62,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"607c373e-81ac-4a46-afa3-280586a1f1c8"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01PZSTLLDG9FrPBg4Fyqdjy5","type":"tool_result","content":"1\t<!DOCTYPE html>\n2\t<html lang=\"en\">\n3\t<head>\n4\t <meta charset=\"UTF-8\" />\n5\t <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n6\t <title>Tetris</title>\n7\t <link rel=\"stylesheet\" href=\"style.css\" />\n8\t</head>\n9\t<body>\n10\t\n11\t<div id=\"wrapper\">\n12\t\n13\t <!-- ── Left panel: Hold + Controls ── -->\n14\t <div class=\"side-panel\">\n15\t <div class=\"panel-box\">\n16\t <div class=\"panel-label\">Hold</div>\n17\t <canvas id=\"hold-canvas\" width=\"120\" height=\"120\"></canvas>\n18\t </div>\n19\t\n20\t <div class=\"panel-box\" style=\"gap:2px\">\n21\t <div class=\"panel-label\" style=\"margin-bottom:4px\">Controls</div>\n22\t <div id=\"controls\">\n23\t <span>← →</span> <span>Move</span>\n24\t <span>↓</span> <span>Soft drop</span>\n25\t <span>Space</span> <span>Hard drop</span>\n26\t <span>↑ / X</span> <span>Rotate CW</span>\n27\t <span>Z</span> <span>Rotate CCW</span>\n28\t <span>C</span> <span>Hold</span>\n29\t <span>P / Esc</span> <span>Pause</span>\n30\t </div>\n31\t </div>\n32\t </div>\n33\t\n34\t <!-- ── Main board ── -->\n35\t <div id=\"game-wrap\">\n36\t <canvas id=\"game-canvas\" width=\"300\" height=\"600\"></canvas>\n37\t\n38\t <!-- Overlay for title / pause / game-over -->\n39\t <div id=\"overlay\">\n40\t <div id=\"ov-title\">TETRIS</div>\n41\t <div id=\"ov-msg\">Press Space to start</div>\n42\t <div id=\"controls\" style=\"margin-top:8px\">\n43\t <span>← →</span> <span>Move</span>\n44\t <span>↓</span> <span>Soft drop</span>\n45\t <span>Space</span> <span>Hard drop</span>\n46\t <span>↑ / X</span> <span>Rotate CW</span>\n47\t <span>Z</span> <span>Rotate CCW</span>\n48\t <span>C</span> <span>Hold piece</span>\n49\t <span>P</span> <span>Pause</span>\n50\t </div>\n51\t <button id=\"start-btn\">START</button>\n52\t </div>\n53\t </div>\n54\t\n55\t <!-- ── Right panel: Next + Stats ── -->\n56\t <div class=\"side-panel\">\n57\t <div class=\"panel-box\">\n58\t <div class=\"panel-label\">Next</div>\n59\t <canvas id=\"next-canvas\" width=\"120\" height=\"120\"></canvas>\n60\t </div>\n61\t\n62\t <div class=\"panel-box\">\n63\t <div class=\"panel-label\">Score</div>\n64\t <div class=\"panel-value\" id=\"score\">0</div>\n65\t </div>\n66\t\n67\t <div class=\"panel-box\">\n68\t <div class=\"panel-label\">Level</div>\n69\t <div class=\"panel-value\" id=\"level\">1</div>\n70\t </div>\n71\t\n72\t <div class=\"panel-box\">\n73\t <div class=\"panel-label\">Lines</div>\n74\t <div class=\"panel-value\" id=\"lines\">0</div>\n75\t </div>\n76\t </div>\n77\t\n78\t</div>\n79\t\n80\t<script type=\"module\" src=\"dist/tetris.js\"></script>\n81\t</body>\n82\t</html>\n83\t"}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"2c1516e0-05cb-4d2b-80ad-d5a70f1dd92b","timestamp":"2026-04-05T19:37:44.003Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-6c3p0wr6/index.html","content":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <link rel=\"stylesheet\" href=\"style.css\" />\n</head>\n<body>\n\n<div id=\"wrapper\">\n\n <!-- ── Left panel: Hold + Controls ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Hold</div>\n <canvas id=\"hold-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\" style=\"gap:2px\">\n <div class=\"panel-label\" style=\"margin-bottom:4px\">Controls</div>\n <div id=\"controls\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold</span>\n <span>P / Esc</span> <span>Pause</span>\n </div>\n </div>\n </div>\n\n <!-- ── Main board ── -->\n <div id=\"game-wrap\">\n <canvas id=\"game-canvas\" width=\"300\" height=\"600\"></canvas>\n\n <!-- Overlay for title / pause / game-over -->\n <div id=\"overlay\">\n <div id=\"ov-title\">TETRIS</div>\n <div id=\"ov-msg\">Press Space to start</div>\n <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>\n <button id=\"start-btn\">START</button>\n </div>\n </div>\n\n <!-- ── Right panel: Next + Stats ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Next</div>\n <canvas id=\"next-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Score</div>\n <div class=\"panel-value\" id=\"score\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Level</div>\n <div class=\"panel-value\" id=\"level\">1</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Lines</div>\n <div class=\"panel-value\" id=\"lines\">0</div>\n </div>\n </div>\n\n</div>\n\n<script type=\"module\" src=\"dist/tetris.js\"></script>\n</body>\n</html>\n","numLines":83,"startLine":1,"totalLines":83}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01KoWVcYizu1LeSmx4Sc9U3E","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01MpSQWXaMRQyrQHnizKdEYP","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-6c3p0wr6/index.html","old_string":" <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>","new_string":" <div class=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1156,"cache_read_input_tokens":50584,"cache_creation":{"ephemeral_5m_input_tokens":1156,"ephemeral_1h_input_tokens":0},"output_tokens":55,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"4103df43-b8c1-424c-a791-c536b22a3113"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01MpSQWXaMRQyrQHnizKdEYP","type":"tool_result","content":"The file /tmp/loop-bench-6c3p0wr6/index.html has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"f3cbd53c-edee-4784-afe9-711bb4bf0ae9","timestamp":"2026-04-05T19:37:49.026Z","tool_use_result":{"filePath":"/tmp/loop-bench-6c3p0wr6/index.html","oldString":" <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>","newString":" <div class=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>","originalFile":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <link rel=\"stylesheet\" href=\"style.css\" />\n</head>\n<body>\n\n<div id=\"wrapper\">\n\n <!-- ── Left panel: Hold + Controls ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Hold</div>\n <canvas id=\"hold-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\" style=\"gap:2px\">\n <div class=\"panel-label\" style=\"margin-bottom:4px\">Controls</div>\n <div id=\"controls\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold</span>\n <span>P / Esc</span> <span>Pause</span>\n </div>\n </div>\n </div>\n\n <!-- ── Main board ── -->\n <div id=\"game-wrap\">\n <canvas id=\"game-canvas\" width=\"300\" height=\"600\"></canvas>\n\n <!-- Overlay for title / pause / game-over -->\n <div id=\"overlay\">\n <div id=\"ov-title\">TETRIS</div>\n <div id=\"ov-msg\">Press Space to start</div>\n <div id=\"controls\" style=\"margin-top:8px\">\n <span>← →</span> <span>Move</span>\n <span>↓</span> <span>Soft drop</span>\n <span>Space</span> <span>Hard drop</span>\n <span>↑ / X</span> <span>Rotate CW</span>\n <span>Z</span> <span>Rotate CCW</span>\n <span>C</span> <span>Hold piece</span>\n <span>P</span> <span>Pause</span>\n </div>\n <button id=\"start-btn\">START</button>\n </div>\n </div>\n\n <!-- ── Right panel: Next + Stats ── -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Next</div>\n <canvas id=\"next-canvas\" width=\"120\" height=\"120\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Score</div>\n <div class=\"panel-value\" id=\"score\">0</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Level</div>\n <div class=\"panel-value\" id=\"level\">1</div>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\">Lines</div>\n <div class=\"panel-value\" id=\"lines\">0</div>\n </div>\n </div>\n\n</div>\n\n<script type=\"module\" src=\"dist/tetris.js\"></script>\n</body>\n</html>\n","structuredPatch":[{"oldStart":39,"oldLines":7,"newStart":39,"newLines":7,"lines":[" <div id=\"overlay\">"," <div id=\"ov-title\">TETRIS</div>"," <div id=\"ov-msg\">Press Space to start</div>","- <div id=\"controls\" style=\"margin-top:8px\">","+ <div class=\"controls\" style=\"margin-top:8px\">"," <span>← →</span> <span>Move</span>"," <span>↓</span> <span>Soft drop</span>"," <span>Space</span> <span>Hard drop</span>"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Kdmm5uee2k8ccyHoMs9SNC","type":"message","role":"assistant","content":[{"type":"text","text":"Also update the CSS to target both `#controls` and `.controls`:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":475,"cache_read_input_tokens":51740,"cache_creation":{"ephemeral_5m_input_tokens":475,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"6697c3c1-5caf-421a-9bbd-d4936425e710"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Kdmm5uee2k8ccyHoMs9SNC","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Rz7tPjVUjuucxtZFp6a24J","name":"Read","input":{"file_path":"/tmp/loop-bench-6c3p0wr6/style.css"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":475,"cache_read_input_tokens":51740,"cache_creation":{"ephemeral_5m_input_tokens":475,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"770349ba-b334-4b13-9852-4ad72cde6556"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Rz7tPjVUjuucxtZFp6a24J","type":"tool_result","content":"1\t/* ── Reset / Base ─────────────────────────────────────── */\n2\t*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n3\t\n4\tbody {\n5\t background: #0a0a18;\n6\t color: #e0e0ff;\n7\t font-family: 'Segoe UI', system-ui, sans-serif;\n8\t display: flex;\n9\t justify-content: center;\n10\t align-items: center;\n11\t min-height: 100vh;\n12\t overflow: hidden;\n13\t user-select: none;\n14\t}\n15\t\n16\t/* ── Layout ───────────────────────────────────────────── */\n17\t#wrapper {\n18\t display: flex;\n19\t gap: 12px;\n20\t align-items: flex-start;\n21\t}\n22\t\n23\t/* ── Side panels ──────────────────────────────────────── */\n24\t.side-panel {\n25\t display: flex;\n26\t flex-direction: column;\n27\t gap: 12px;\n28\t width: 120px;\n29\t padding-top: 4px;\n30\t}\n31\t\n32\t.panel-box {\n33\t background: #16162e;\n34\t border: 1px solid #2a2a50;\n35\t border-radius: 6px;\n36\t padding: 10px 8px;\n37\t display: flex;\n38\t flex-direction: column;\n39\t align-items: center;\n40\t gap: 6px;\n41\t}\n42\t\n43\t.panel-label {\n44\t font-size: 10px;\n45\t font-weight: 700;\n46\t letter-spacing: 2px;\n47\t color: #7070b0;\n48\t text-transform: uppercase;\n49\t}\n50\t\n51\t.panel-value {\n52\t font-size: 22px;\n53\t font-weight: 700;\n54\t color: #d0d0ff;\n55\t letter-spacing: 1px;\n56\t font-variant-numeric: tabular-nums;\n57\t}\n58\t\n59\tcanvas {\n60\t display: block;\n61\t}\n62\t\n63\t/* ── Game canvas wrapper ──────────────────────────────── */\n64\t#game-wrap {\n65\t position: relative;\n66\t border: 2px solid #2a2a50;\n67\t border-radius: 4px;\n68\t overflow: hidden;\n69\t box-shadow:\n70\t 0 0 30px rgba(80, 80, 200, 0.25),\n71\t 0 0 8px rgba(80, 80, 200, 0.15);\n72\t}\n73\t\n74\t/* ── Overlay ──────────────────────────────────────────── */\n75\t#overlay {\n76\t position: absolute;\n77\t inset: 0;\n78\t background: rgba(5, 5, 20, 0.88);\n79\t display: flex;\n80\t flex-direction: column;\n81\t align-items: center;\n82\t justify-content: center;\n83\t gap: 14px;\n84\t backdrop-filter: blur(2px);\n85\t z-index: 10;\n86\t}\n87\t\n88\t#ov-title {\n89\t font-size: 42px;\n90\t font-weight: 900;\n91\t letter-spacing: 6px;\n92\t text-transform: uppercase;\n93\t background: linear-gradient(135deg, #00f0f0, #a020f0, #f0a000);\n94\t -webkit-background-clip: text;\n95\t -webkit-text-fill-color: transparent;\n96\t background-clip: text;\n97\t text-shadow: none;\n98\t line-height: 1;\n99\t}\n100\t\n101\t#ov-msg {\n102\t font-size: 13px;\n103\t color: #9090c0;\n104\t text-align: center;\n105\t line-height: 1.8;\n106\t}\n107\t\n108\t/* ── Controls hint ────────────────────────────────────── */\n109\t#controls {\n110\t margin-top: 4px;\n111\t font-size: 11px;\n112\t color: #5a5a8a;\n113\t display: grid;\n114\t grid-template-columns: auto auto;\n115\t column-gap: 14px;\n116\t row-gap: 4px;\n117\t text-align: left;\n118\t}\n119\t\n120\t#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n121\t#controls span:nth-child(even) { color: #5a5a8a; }\n122\t\n123\t/* ── Button ───────────────────────────────────────────── */\n124\t#start-btn {\n125\t margin-top: 6px;\n126\t padding: 9px 32px;\n127\t background: linear-gradient(135deg, #1a1a60, #2a2a90);\n128\t border: 1px solid #4040a0;\n129\t border-radius: 4px;\n130\t color: #c0c0ff;\n131\t font-size: 13px;\n132\t font-weight: 700;\n133\t letter-spacing: 2px;\n134\t cursor: pointer;\n135\t transition: background 0.15s, transform 0.1s;\n136\t}\n137\t\n138\t#start-btn:hover { background: linear-gradient(135deg, #2a2a80, #3a3ab0); }\n139\t#start-btn:active { transform: scale(0.97); }\n140\t\n141\t/* ── Preview canvases ─────────────────────────────────── */\n142\t#next-canvas, #hold-canvas {\n143\t border-radius: 4px;\n144\t}\n145\t\n146\t/* ── Responsive: shrink on small screens ─────────────── */\n147\t@media (max-width: 560px) {\n148\t #wrapper { gap: 6px; transform: scale(0.82); transform-origin: top center; }\n149\t}\n150\t"}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"ba7d6541-7b8a-4ff3-b8db-aa254ef571cc","timestamp":"2026-04-05T19:37:52.381Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-6c3p0wr6/style.css","content":"/* ── Reset / Base ─────────────────────────────────────── */\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\nbody {\n background: #0a0a18;\n color: #e0e0ff;\n font-family: 'Segoe UI', system-ui, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n overflow: hidden;\n user-select: none;\n}\n\n/* ── Layout ───────────────────────────────────────────── */\n#wrapper {\n display: flex;\n gap: 12px;\n align-items: flex-start;\n}\n\n/* ── Side panels ──────────────────────────────────────── */\n.side-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 120px;\n padding-top: 4px;\n}\n\n.panel-box {\n background: #16162e;\n border: 1px solid #2a2a50;\n border-radius: 6px;\n padding: 10px 8px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.panel-label {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 2px;\n color: #7070b0;\n text-transform: uppercase;\n}\n\n.panel-value {\n font-size: 22px;\n font-weight: 700;\n color: #d0d0ff;\n letter-spacing: 1px;\n font-variant-numeric: tabular-nums;\n}\n\ncanvas {\n display: block;\n}\n\n/* ── Game canvas wrapper ──────────────────────────────── */\n#game-wrap {\n position: relative;\n border: 2px solid #2a2a50;\n border-radius: 4px;\n overflow: hidden;\n box-shadow:\n 0 0 30px rgba(80, 80, 200, 0.25),\n 0 0 8px rgba(80, 80, 200, 0.15);\n}\n\n/* ── Overlay ──────────────────────────────────────────── */\n#overlay {\n position: absolute;\n inset: 0;\n background: rgba(5, 5, 20, 0.88);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 14px;\n backdrop-filter: blur(2px);\n z-index: 10;\n}\n\n#ov-title {\n font-size: 42px;\n font-weight: 900;\n letter-spacing: 6px;\n text-transform: uppercase;\n background: linear-gradient(135deg, #00f0f0, #a020f0, #f0a000);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n text-shadow: none;\n line-height: 1;\n}\n\n#ov-msg {\n font-size: 13px;\n color: #9090c0;\n text-align: center;\n line-height: 1.8;\n}\n\n/* ── Controls hint ────────────────────────────────────── */\n#controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even) { color: #5a5a8a; }\n\n/* ── Button ───────────────────────────────────────────── */\n#start-btn {\n margin-top: 6px;\n padding: 9px 32px;\n background: linear-gradient(135deg, #1a1a60, #2a2a90);\n border: 1px solid #4040a0;\n border-radius: 4px;\n color: #c0c0ff;\n font-size: 13px;\n font-weight: 700;\n letter-spacing: 2px;\n cursor: pointer;\n transition: background 0.15s, transform 0.1s;\n}\n\n#start-btn:hover { background: linear-gradient(135deg, #2a2a80, #3a3ab0); }\n#start-btn:active { transform: scale(0.97); }\n\n/* ── Preview canvases ─────────────────────────────────── */\n#next-canvas, #hold-canvas {\n border-radius: 4px;\n}\n\n/* ── Responsive: shrink on small screens ─────────────── */\n@media (max-width: 560px) {\n #wrapper { gap: 6px; transform: scale(0.82); transform-origin: top center; }\n}\n","numLines":150,"startLine":1,"totalLines":150}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01L2DxXJkQfr8V7EKMYM5nDN","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01DHbwunTswGf7ha5Nb3YVtA","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-6c3p0wr6/style.css","old_string":"/* ── Controls hint ────────────────────────────────────── */\n#controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even) { color: #5a5a8a; }","new_string":"/* ── Controls hint ────────────────────────────────────── */\n#controls, .controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd),\n.controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even),\n.controls span:nth-child(even) { color: #5a5a8a; }"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1758,"cache_read_input_tokens":52215,"cache_creation":{"ephemeral_5m_input_tokens":1758,"ephemeral_1h_input_tokens":0},"output_tokens":65,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"835d10ec-9cf0-4ae0-ae14-ab235d7c1648"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01DHbwunTswGf7ha5Nb3YVtA","type":"tool_result","content":"The file /tmp/loop-bench-6c3p0wr6/style.css has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"9f0df301-d57e-48c9-a8e0-44cc19301885","timestamp":"2026-04-05T19:37:56.783Z","tool_use_result":{"filePath":"/tmp/loop-bench-6c3p0wr6/style.css","oldString":"/* ── Controls hint ────────────────────────────────────── */\n#controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even) { color: #5a5a8a; }","newString":"/* ── Controls hint ────────────────────────────────────── */\n#controls, .controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd),\n.controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even),\n.controls span:nth-child(even) { color: #5a5a8a; }","originalFile":"/* ── Reset / Base ─────────────────────────────────────── */\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\nbody {\n background: #0a0a18;\n color: #e0e0ff;\n font-family: 'Segoe UI', system-ui, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n overflow: hidden;\n user-select: none;\n}\n\n/* ── Layout ───────────────────────────────────────────── */\n#wrapper {\n display: flex;\n gap: 12px;\n align-items: flex-start;\n}\n\n/* ── Side panels ──────────────────────────────────────── */\n.side-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 120px;\n padding-top: 4px;\n}\n\n.panel-box {\n background: #16162e;\n border: 1px solid #2a2a50;\n border-radius: 6px;\n padding: 10px 8px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n}\n\n.panel-label {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 2px;\n color: #7070b0;\n text-transform: uppercase;\n}\n\n.panel-value {\n font-size: 22px;\n font-weight: 700;\n color: #d0d0ff;\n letter-spacing: 1px;\n font-variant-numeric: tabular-nums;\n}\n\ncanvas {\n display: block;\n}\n\n/* ── Game canvas wrapper ──────────────────────────────── */\n#game-wrap {\n position: relative;\n border: 2px solid #2a2a50;\n border-radius: 4px;\n overflow: hidden;\n box-shadow:\n 0 0 30px rgba(80, 80, 200, 0.25),\n 0 0 8px rgba(80, 80, 200, 0.15);\n}\n\n/* ── Overlay ──────────────────────────────────────────── */\n#overlay {\n position: absolute;\n inset: 0;\n background: rgba(5, 5, 20, 0.88);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 14px;\n backdrop-filter: blur(2px);\n z-index: 10;\n}\n\n#ov-title {\n font-size: 42px;\n font-weight: 900;\n letter-spacing: 6px;\n text-transform: uppercase;\n background: linear-gradient(135deg, #00f0f0, #a020f0, #f0a000);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n text-shadow: none;\n line-height: 1;\n}\n\n#ov-msg {\n font-size: 13px;\n color: #9090c0;\n text-align: center;\n line-height: 1.8;\n}\n\n/* ── Controls hint ────────────────────────────────────── */\n#controls {\n margin-top: 4px;\n font-size: 11px;\n color: #5a5a8a;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 14px;\n row-gap: 4px;\n text-align: left;\n}\n\n#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }\n#controls span:nth-child(even) { color: #5a5a8a; }\n\n/* ── Button ───────────────────────────────────────────── */\n#start-btn {\n margin-top: 6px;\n padding: 9px 32px;\n background: linear-gradient(135deg, #1a1a60, #2a2a90);\n border: 1px solid #4040a0;\n border-radius: 4px;\n color: #c0c0ff;\n font-size: 13px;\n font-weight: 700;\n letter-spacing: 2px;\n cursor: pointer;\n transition: background 0.15s, transform 0.1s;\n}\n\n#start-btn:hover { background: linear-gradient(135deg, #2a2a80, #3a3ab0); }\n#start-btn:active { transform: scale(0.97); }\n\n/* ── Preview canvases ─────────────────────────────────── */\n#next-canvas, #hold-canvas {\n border-radius: 4px;\n}\n\n/* ── Responsive: shrink on small screens ─────────────── */\n@media (max-width: 560px) {\n #wrapper { gap: 6px; transform: scale(0.82); transform-origin: top center; }\n}\n","structuredPatch":[{"oldStart":106,"oldLines":7,"newStart":106,"newLines":7,"lines":[" }"," "," /* ── Controls hint ────────────────────────────────────── */","-#controls {","+#controls, .controls {"," margin-top: 4px;"," font-size: 11px;"," color: #5a5a8a;"]},{"oldStart":117,"oldLines":8,"newStart":117,"newLines":10,"lines":[" text-align: left;"," }"," ","-#controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }","-#controls span:nth-child(even) { color: #5a5a8a; }","+#controls span:nth-child(odd),","+.controls span:nth-child(odd) { color: #8080b8; font-weight: 600; }","+#controls span:nth-child(even),","+.controls span:nth-child(even) { color: #5a5a8a; }"," "," /* ── Button ───────────────────────────────────────────── */"," #start-btn {"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01FUazBQtkZ6AFmZWDPeP5zX","type":"message","role":"assistant","content":[{"type":"text","text":"Now let me do a final review of the TypeScript source to make sure there are no logic issues:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":494,"cache_read_input_tokens":53973,"cache_creation":{"ephemeral_5m_input_tokens":494,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"2426a2df-d3fb-4649-bd3e-1793c588753c"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01FUazBQtkZ6AFmZWDPeP5zX","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01TBJGk1KJxJRwMxcsdjZp47","name":"Read","input":{"file_path":"/tmp/loop-bench-6c3p0wr6/src/tetris.ts"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":494,"cache_read_input_tokens":53973,"cache_creation":{"ephemeral_5m_input_tokens":494,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"72e9d0f3-fbd7-4d59-bc92-fc74bcb67593"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01TBJGk1KJxJRwMxcsdjZp47","type":"tool_result","content":"1\t// =============================================================\n2\t// TETRIS – Full browser implementation in TypeScript\n3\t// =============================================================\n4\t\n5\t// ── Constants ──────────────────────────────────────────────\n6\tconst BOARD_W = 10;\n7\tconst BOARD_H = 20;\n8\tconst CELL = 30; // px per cell on main board\n9\tconst PREVIEW_W = 120; // px wide of hold / next canvas\n10\tconst PREVIEW_H = 120;\n11\t\n12\t// ── Types ──────────────────────────────────────────────────\n13\ttype PieceType = 'I' | 'O' | 'T' | 'S' | 'Z' | 'J' | 'L';\n14\ttype Cell = string | null;\n15\ttype Board = Cell[][];\n16\ttype GameState = 'idle' | 'playing' | 'paused' | 'gameover';\n17\t\n18\tinterface Piece {\n19\t type: PieceType;\n20\t x: number; // board column of shape origin\n21\t y: number; // board row of shape origin\n22\t rotation: number; // 0–3\n23\t}\n24\t\n25\t// ── Colours ────────────────────────────────────────────────\n26\tconst COLORS: Record<PieceType, string> = {\n27\t I: '#00f0f0',\n28\t O: '#f0f000',\n29\t T: '#a020f0',\n30\t S: '#00e000',\n31\t Z: '#f00000',\n32\t J: '#2040f0',\n33\t L: '#f0a000',\n34\t};\n35\t\n36\t// Slightly darker shade used for 3-D inner shadow\n37\tconst DARK: Record<PieceType, string> = {\n38\t I: '#009090',\n39\t O: '#909000',\n40\t T: '#601890',\n41\t S: '#008000',\n42\t Z: '#900000',\n43\t J: '#102080',\n44\t L: '#905800',\n45\t};\n46\t\n47\t// ── Shapes (4 rotations each) ──────────────────────────────\n48\t// 1 = filled, 0 = empty\n49\tconst SHAPES: Record<PieceType, readonly (readonly number[])[][]> = {\n50\t I: [\n51\t [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n52\t [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]],\n53\t [[0,0,0,0],[0,0,0,0],[1,1,1,1],[0,0,0,0]],\n54\t [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],\n55\t ],\n56\t O: [\n57\t [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n58\t [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n59\t [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n60\t [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n61\t ],\n62\t T: [\n63\t [[0,1,0],[1,1,1],[0,0,0]],\n64\t [[0,1,0],[0,1,1],[0,1,0]],\n65\t [[0,0,0],[1,1,1],[0,1,0]],\n66\t [[0,1,0],[1,1,0],[0,1,0]],\n67\t ],\n68\t S: [\n69\t [[0,1,1],[1,1,0],[0,0,0]],\n70\t [[0,1,0],[0,1,1],[0,0,1]],\n71\t [[0,0,0],[0,1,1],[1,1,0]],\n72\t [[1,0,0],[1,1,0],[0,1,0]],\n73\t ],\n74\t Z: [\n75\t [[1,1,0],[0,1,1],[0,0,0]],\n76\t [[0,0,1],[0,1,1],[0,1,0]],\n77\t [[0,0,0],[1,1,0],[0,1,1]],\n78\t [[0,1,0],[1,1,0],[1,0,0]],\n79\t ],\n80\t J: [\n81\t [[1,0,0],[1,1,1],[0,0,0]],\n82\t [[0,1,1],[0,1,0],[0,1,0]],\n83\t [[0,0,0],[1,1,1],[0,0,1]],\n84\t [[0,1,0],[0,1,0],[1,1,0]],\n85\t ],\n86\t L: [\n87\t [[0,0,1],[1,1,1],[0,0,0]],\n88\t [[0,1,0],[0,1,0],[0,1,1]],\n89\t [[0,0,0],[1,1,1],[1,0,0]],\n90\t [[1,1,0],[0,1,0],[0,1,0]],\n91\t ],\n92\t};\n93\t\n94\t// ── SRS Wall-kick tables ───────────────────────────────────\n95\t// Offsets are [dx, dy] in canvas coords (positive-Y = DOWN)\n96\t// Derived from the Tetris Guideline with Y axis flipped.\n97\t\n98\tconst KICKS_JLSTZ: Record<string, readonly [number, number][]> = {\n99\t '0>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n100\t '1>0': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n101\t '1>2': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n102\t '2>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n103\t '2>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n104\t '3>2': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n105\t '3>0': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n106\t '0>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n107\t};\n108\t\n109\tconst KICKS_I: Record<string, readonly [number, number][]> = {\n110\t '0>1': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n111\t '1>0': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n112\t '1>2': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n113\t '2>1': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n114\t '2>3': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n115\t '3>2': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n116\t '3>0': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n117\t '0>3': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n118\t};\n119\t\n120\t// ── Scoring ────────────────────────────────────────────────\n121\tconst LINE_SCORE = [0, 100, 300, 500, 800]; // 0–4 lines\n122\t\n123\t/** Drop interval in ms for a given level (Tetris guideline formula). */\n124\tfunction dropInterval(level: number): number {\n125\t const sec = Math.pow(0.8 - (level - 1) * 0.007, level - 1);\n126\t return Math.max(50, Math.floor(sec * 1000));\n127\t}\n128\t\n129\t// ── Helpers ────────────────────────────────────────────────\n130\tconst ALL_TYPES: PieceType[] = ['I','O','T','S','Z','J','L'];\n131\t\n132\tfunction getShape(type: PieceType, rotation: number): readonly (readonly number[])[] {\n133\t return SHAPES[type][((rotation % 4) + 4) % 4];\n134\t}\n135\t\n136\t/** Returns [boardX, boardY] for every filled cell of the piece. */\n137\tfunction cells(p: Piece): [number, number][] {\n138\t const out: [number, number][] = [];\n139\t const shape = getShape(p.type, p.rotation);\n140\t for (let r = 0; r < shape.length; r++) {\n141\t for (let c = 0; c < shape[r].length; c++) {\n142\t if (shape[r][c]) out.push([p.x + c, p.y + r]);\n143\t }\n144\t }\n145\t return out;\n146\t}\n147\t\n148\t// ── 7-bag randomiser ───────────────────────────────────────\n149\tclass Bag {\n150\t private pool: PieceType[] = [];\n151\t\n152\t private refill() {\n153\t this.pool = [...ALL_TYPES];\n154\t for (let i = this.pool.length - 1; i > 0; i--) {\n155\t const j = (Math.random() * (i + 1)) | 0;\n156\t [this.pool[i], this.pool[j]] = [this.pool[j], this.pool[i]];\n157\t }\n158\t }\n159\t\n160\t next(): PieceType {\n161\t if (!this.pool.length) this.refill();\n162\t return this.pool.pop()!;\n163\t }\n164\t\n165\t peek(): PieceType {\n166\t if (!this.pool.length) this.refill();\n167\t return this.pool[this.pool.length - 1];\n168\t }\n169\t}\n170\t\n171\t// ══════════════════════════════════════════════════════════\n172\t// Main Game Class\n173\t// ══════════════════════════════════════════════════════════\n174\tclass TetrisGame {\n175\t\n176\t // Canvases\n177\t private readonly ctx: CanvasRenderingContext2D;\n178\t private readonly nextCtx: CanvasRenderingContext2D;\n179\t private readonly holdCtx: CanvasRenderingContext2D;\n180\t\n181\t // Board\n182\t private board: Board = this.emptyBoard();\n183\t\n184\t // Pieces\n185\t private current: Piece | null = null;\n186\t private nextType: PieceType = 'I';\n187\t private heldType: PieceType | null = null;\n188\t private canHold = true;\n189\t private bag = new Bag();\n190\t\n191\t // Stats\n192\t private score = 0;\n193\t private level = 1;\n194\t private lines = 0;\n195\t\n196\t // Game loop\n197\t private state: GameState = 'idle';\n198\t private animId: number = 0;\n199\t private lastTime = 0;\n200\t private dropCtr = 0; // accumulated ms toward next gravity drop\n201\t private softDrop = false;\n202\t\n203\t // DAS (Delayed Auto-Shift)\n204\t private dasDir = 0; // -1 | 0 | 1\n205\t private dasTimer = 0;\n206\t private dasRepeat = 0;\n207\t private readonly DAS_DELAY = 133;\n208\t private readonly DAS_PERIOD = 50;\n209\t\n210\t // Key state\n211\t private held = new Set<string>();\n212\t\n213\t // ── Constructor ──────────────────────────────────────────\n214\t constructor() {\n215\t this.ctx = this.getCtx('game-canvas');\n216\t this.nextCtx = this.getCtx('next-canvas');\n217\t this.holdCtx = this.getCtx('hold-canvas');\n218\t\n219\t this.nextType = this.bag.next();\n220\t\n221\t document.addEventListener('keydown', e => this.onKeyDown(e));\n222\t document.addEventListener('keyup', e => this.onKeyUp(e));\n223\t document.getElementById('start-btn')!\n224\t .addEventListener('click', () => this.onStartBtn());\n225\t\n226\t this.showOverlay('TETRIS', 'Press Space to start');\n227\t this.drawIdleBoard();\n228\t this.drawPreview(this.nextCtx, null);\n229\t this.drawPreview(this.holdCtx, null);\n230\t }\n231\t\n232\t private getCtx(id: string): CanvasRenderingContext2D {\n233\t return (document.getElementById(id) as HTMLCanvasElement)\n234\t .getContext('2d')!;\n235\t }\n236\t\n237\t // ── Overlay helpers ──────────────────────────────────────\n238\t private showOverlay(title: string, msg: string) {\n239\t document.getElementById('overlay')!.style.display = 'flex';\n240\t document.getElementById('ov-title')!.textContent = title;\n241\t // handle literal \\n line breaks in msg\n242\t const msgEl = document.getElementById('ov-msg')!;\n243\t msgEl.innerHTML = msg.split('\\n').map(l => `<span>${l}</span>`).join('<br>');\n244\t }\n245\t\n246\t private hideOverlay() {\n247\t document.getElementById('overlay')!.style.display = 'none';\n248\t }\n249\t\n250\t private setBtn(txt: string) {\n251\t (document.getElementById('start-btn') as HTMLButtonElement).textContent = txt;\n252\t }\n253\t\n254\t private updateStats() {\n255\t document.getElementById('score')!.textContent = this.score.toLocaleString();\n256\t document.getElementById('level')!.textContent = String(this.level);\n257\t document.getElementById('lines')!.textContent = String(this.lines);\n258\t }\n259\t\n260\t // ── Button / start flow ──────────────────────────────────\n261\t private onStartBtn() {\n262\t if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n263\t else if (this.state === 'playing') this.pauseGame();\n264\t else if (this.state === 'paused') this.resumeGame();\n265\t }\n266\t\n267\t startGame() {\n268\t this.board = this.emptyBoard();\n269\t this.score = 0;\n270\t this.level = 1;\n271\t this.lines = 0;\n272\t this.heldType = null;\n273\t this.canHold = true;\n274\t this.bag = new Bag();\n275\t this.nextType = this.bag.next();\n276\t this.dropCtr = 0;\n277\t this.softDrop = false;\n278\t this.dasDir = 0;\n279\t\n280\t this.updateStats();\n281\t this.drawPreview(this.holdCtx, null);\n282\t this.spawnPiece();\n283\t\n284\t if (this.state === 'playing') cancelAnimationFrame(this.animId);\n285\t this.state = 'playing';\n286\t this.hideOverlay();\n287\t this.setBtn('PAUSE');\n288\t\n289\t this.lastTime = performance.now();\n290\t this.animId = requestAnimationFrame(t => this.loop(t));\n291\t }\n292\t\n293\t pauseGame() {\n294\t this.state = 'paused';\n295\t cancelAnimationFrame(this.animId);\n296\t this.showOverlay('PAUSED', 'Press P or Space to resume');\n297\t this.setBtn('RESUME');\n298\t }\n299\t\n300\t resumeGame() {\n301\t this.state = 'playing';\n302\t this.hideOverlay();\n303\t this.setBtn('PAUSE');\n304\t this.lastTime = performance.now();\n305\t this.animId = requestAnimationFrame(t => this.loop(t));\n306\t }\n307\t\n308\t private endGame() {\n309\t this.state = 'gameover';\n310\t cancelAnimationFrame(this.animId);\n311\t this.showOverlay(\n312\t 'GAME OVER',\n313\t `Score: ${this.score.toLocaleString()}\\nLines: ${this.lines} Level: ${this.level}\\nPress Space to play again`\n314\t );\n315\t this.setBtn('RESTART');\n316\t }\n317\t\n318\t // ── Board helpers ────────────────────────────────────────\n319\t private emptyBoard(): Board {\n320\t return Array.from({ length: BOARD_H }, () => new Array<Cell>(BOARD_W).fill(null));\n321\t }\n322\t\n323\t private isValid(p: Piece): boolean {\n324\t for (const [x, y] of cells(p)) {\n325\t if (x < 0 || x >= BOARD_W || y >= BOARD_H) return false;\n326\t if (y >= 0 && this.board[y][x] !== null) return false;\n327\t }\n328\t return true;\n329\t }\n330\t\n331\t private lock() {\n332\t if (!this.current) return;\n333\t const color = COLORS[this.current.type];\n334\t for (const [x, y] of cells(this.current)) {\n335\t if (y >= 0) this.board[y][x] = color;\n336\t }\n337\t this.clearLines();\n338\t this.canHold = true;\n339\t this.spawnPiece();\n340\t }\n341\t\n342\t private clearLines() {\n343\t let cleared = 0;\n344\t for (let r = BOARD_H - 1; r >= 0; r--) {\n345\t if (this.board[r].every(c => c !== null)) {\n346\t this.board.splice(r, 1);\n347\t this.board.unshift(new Array<Cell>(BOARD_W).fill(null));\n348\t cleared++;\n349\t r++; // recheck the row that slid into position r\n350\t }\n351\t }\n352\t if (cleared) {\n353\t this.lines += cleared;\n354\t this.score += LINE_SCORE[cleared] * this.level;\n355\t const newLevel = Math.floor(this.lines / 10) + 1;\n356\t if (newLevel > this.level) {\n357\t this.level = newLevel;\n358\t }\n359\t this.updateStats();\n360\t }\n361\t }\n362\t\n363\t // ── Spawn ────────────────────────────────────────────────\n364\t private spawnPiece() {\n365\t const type = this.nextType;\n366\t this.nextType = this.bag.next();\n367\t\n368\t const shape = getShape(type, 0);\n369\t const w = shape[0].length;\n370\t const spawnX = Math.floor((BOARD_W - w) / 2);\n371\t // I piece rotation-0 has an empty top row → spawn 1 row higher\n372\t const spawnY = type === 'I' ? -1 : 0;\n373\t\n374\t this.current = { type, x: spawnX, y: spawnY, rotation: 0 };\n375\t\n376\t if (!this.isValid(this.current)) {\n377\t this.current.y--;\n378\t if (!this.isValid(this.current)) {\n379\t this.current = null;\n380\t this.endGame();\n381\t return;\n382\t }\n383\t }\n384\t\n385\t this.dropCtr = 0;\n386\t this.drawPreview(this.nextCtx, this.nextType);\n387\t }\n388\t\n389\t // ── Movement ─────────────────────────────────────────────\n390\t private tryShift(dx: number, dy: number): boolean {\n391\t if (!this.current) return false;\n392\t const moved: Piece = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n393\t if (this.isValid(moved)) { this.current = moved; return true; }\n394\t return false;\n395\t }\n396\t\n397\t /** Gravity tick – returns false if piece locked. */\n398\t private gravityDrop(): boolean {\n399\t if (!this.current) return false;\n400\t if (!this.tryShift(0, 1)) {\n401\t this.lock();\n402\t return false;\n403\t }\n404\t return true;\n405\t }\n406\t\n407\t private hardDrop() {\n408\t if (!this.current) return;\n409\t let rows = 0;\n410\t while (this.tryShift(0, 1)) rows++;\n411\t this.score += rows * 2;\n412\t this.updateStats();\n413\t this.lock();\n414\t }\n415\t\n416\t private rotate(dir: 1 | -1) {\n417\t if (!this.current) return;\n418\t const from = this.current.rotation;\n419\t const to = ((from + dir + 4) % 4) as 0|1|2|3;\n420\t const key = `${from}>${to}`;\n421\t\n422\t const kicks: readonly [number,number][] =\n423\t this.current.type === 'I' ? KICKS_I[key] :\n424\t this.current.type === 'O' ? [[0,0]] :\n425\t KICKS_JLSTZ[key];\n426\t\n427\t for (const [dx, dy] of kicks) {\n428\t const attempt: Piece = { ...this.current, rotation: to,\n429\t x: this.current.x + dx,\n430\t y: this.current.y + dy };\n431\t if (this.isValid(attempt)) { this.current = attempt; return; }\n432\t }\n433\t }\n434\t\n435\t private holdPiece() {\n436\t if (!this.current || !this.canHold) return;\n437\t const type = this.current.type;\n438\t if (this.heldType === null) {\n439\t this.heldType = type;\n440\t this.spawnPiece();\n441\t } else {\n442\t const swap = this.heldType;\n443\t this.heldType = type;\n444\t const shape = getShape(swap, 0);\n445\t const w = shape[0].length;\n446\t this.current = { type: swap,\n447\t x: Math.floor((BOARD_W - w) / 2),\n448\t y: swap === 'I' ? -1 : 0,\n449\t rotation: 0 };\n450\t this.dropCtr = 0;\n451\t }\n452\t this.canHold = false;\n453\t this.drawPreview(this.holdCtx, this.heldType);\n454\t }\n455\t\n456\t // Ghost: lowest valid position of current piece\n457\t private ghost(): Piece | null {\n458\t if (!this.current) return null;\n459\t let g = { ...this.current };\n460\t while (true) {\n461\t const down = { ...g, y: g.y + 1 };\n462\t if (this.isValid(down)) g = down; else break;\n463\t }\n464\t return g;\n465\t }\n466\t\n467\t // ── Input ────────────────────────────────────────────────\n468\t private readonly GAME_KEYS = new Set([\n469\t 'ArrowLeft','ArrowRight','ArrowDown','ArrowUp',\n470\t 'Space','KeyZ','KeyX','KeyC','KeyP','Escape',\n471\t ]);\n472\t\n473\t private onKeyDown(e: KeyboardEvent) {\n474\t if (this.GAME_KEYS.has(e.code)) e.preventDefault();\n475\t if (this.held.has(e.code)) return; // ignore key-repeat from OS\n476\t this.held.add(e.code);\n477\t\n478\t if (e.code === 'KeyP' || e.code === 'Escape') {\n479\t if (this.state === 'playing') this.pauseGame();\n480\t else if (this.state === 'paused') this.resumeGame();\n481\t return;\n482\t }\n483\t\n484\t if (e.code === 'Space') {\n485\t if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n486\t else if (this.state === 'paused') this.resumeGame();\n487\t else if (this.state === 'playing') this.hardDrop();\n488\t return;\n489\t }\n490\t\n491\t if (this.state !== 'playing') return;\n492\t\n493\t switch (e.code) {\n494\t case 'ArrowLeft':\n495\t this.tryShift(-1, 0);\n496\t this.startDAS(-1);\n497\t break;\n498\t case 'ArrowRight':\n499\t this.tryShift(1, 0);\n500\t this.startDAS(1);\n501\t break;\n502\t case 'ArrowDown':\n503\t this.softDrop = true;\n504\t break;\n505\t case 'ArrowUp':\n506\t case 'KeyX':\n507\t this.rotate(1);\n508\t break;\n509\t case 'KeyZ':\n510\t this.rotate(-1);\n511\t break;\n512\t case 'KeyC':\n513\t this.holdPiece();\n514\t break;\n515\t }\n516\t }\n517\t\n518\t private onKeyUp(e: KeyboardEvent) {\n519\t this.held.delete(e.code);\n520\t if (e.code === 'ArrowLeft' && this.dasDir === -1) this.stopDAS();\n521\t if (e.code === 'ArrowRight' && this.dasDir === 1) this.stopDAS();\n522\t if (e.code === 'ArrowDown') this.softDrop = false;\n523\t }\n524\t\n525\t private startDAS(dir: -1 | 1) {\n526\t this.dasDir = dir;\n527\t this.dasTimer = 0;\n528\t this.dasRepeat = 0;\n529\t }\n530\t\n531\t private stopDAS() {\n532\t // Re-engage for the other direction if still held\n533\t if (this.held.has('ArrowLeft') && this.dasDir !== -1) this.startDAS(-1);\n534\t else if (this.held.has('ArrowRight') && this.dasDir !== 1) this.startDAS(1);\n535\t else { this.dasDir = 0; this.dasTimer = 0; this.dasRepeat = 0; }\n536\t }\n537\t\n538\t // ── Game loop ────────────────────────────────────────────\n539\t private loop(ts: number) {\n540\t const dt = Math.min(ts - this.lastTime, 100); // cap to avoid spiral after tab-switch\n541\t this.lastTime = ts;\n542\t\n543\t // DAS\n544\t if (this.dasDir !== 0) {\n545\t this.dasTimer += dt;\n546\t if (this.dasTimer >= this.DAS_DELAY) {\n547\t this.dasRepeat += dt;\n548\t while (this.dasRepeat >= this.DAS_PERIOD) {\n549\t this.dasRepeat -= this.DAS_PERIOD;\n550\t this.tryShift(this.dasDir, 0);\n551\t }\n552\t }\n553\t }\n554\t\n555\t // Gravity\n556\t const interval = this.softDrop\n557\t ? Math.max(dropInterval(this.level) / 20, 33)\n558\t : dropInterval(this.level);\n559\t\n560\t this.dropCtr += dt;\n561\t while (this.dropCtr >= interval && this.state === 'playing') {\n562\t this.dropCtr -= interval;\n563\t if (this.softDrop && this.current) {\n564\t this.score += 1;\n565\t document.getElementById('score')!.textContent = this.score.toLocaleString();\n566\t }\n567\t if (!this.gravityDrop()) break; // piece locked → new piece spawned\n568\t }\n569\t\n570\t this.draw();\n571\t if (this.state === 'playing') this.animId = requestAnimationFrame(t => this.loop(t));\n572\t }\n573\t\n574\t // ── Rendering ────────────────────────────────────────────\n575\t\n576\t /** Draw one cell at grid coords (gx, gy) using given pixel size. */\n577\t private drawCell(\n578\t ctx: CanvasRenderingContext2D,\n579\t gx: number, gy: number,\n580\t type: PieceType,\n581\t size: number,\n582\t alpha = 1,\n583\t ) {\n584\t const px = gx * size;\n585\t const py = gy * size;\n586\t const s = size;\n587\t const b = Math.max(2, (s / 10) | 0); // border/bevel thickness\n588\t\n589\t ctx.globalAlpha = alpha;\n590\t\n591\t // Fill\n592\t ctx.fillStyle = COLORS[type];\n593\t ctx.fillRect(px, py, s, s);\n594\t\n595\t // Inner bevel – bright top/left\n596\t ctx.fillStyle = 'rgba(255,255,255,0.45)';\n597\t ctx.fillRect(px, py, s, b); // top strip\n598\t ctx.fillRect(px, py, b, s); // left strip\n599\t\n600\t // Inner bevel – dark bottom/right\n601\t ctx.fillStyle = DARK[type];\n602\t ctx.fillRect(px, py + s - b, s, b); // bottom\n603\t ctx.fillRect(px + s - b, py, b, s); // right\n604\t\n605\t // Inset highlight square\n606\t ctx.fillStyle = COLORS[type];\n607\t ctx.fillRect(px + b, py + b, s - b * 2, s - b * 2);\n608\t\n609\t // Subtle inner shine\n610\t ctx.fillStyle = 'rgba(255,255,255,0.18)';\n611\t ctx.fillRect(px + b, py + b, s - b * 2, Math.max(1, (s - b * 2) / 2 | 0));\n612\t\n613\t ctx.globalAlpha = 1;\n614\t }\n615\t\n616\t /** Main board render. */\n617\t private draw() {\n618\t const ctx = this.ctx;\n619\t const W = BOARD_W * CELL;\n620\t const H = BOARD_H * CELL;\n621\t\n622\t // ── Background ──\n623\t ctx.fillStyle = '#111122';\n624\t ctx.fillRect(0, 0, W, H);\n625\t\n626\t // ── Grid lines ──\n627\t ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n628\t ctx.lineWidth = 1;\n629\t for (let c = 0; c <= BOARD_W; c++) {\n630\t ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, H); ctx.stroke();\n631\t }\n632\t for (let r = 0; r <= BOARD_H; r++) {\n633\t ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(W, r * CELL); ctx.stroke();\n634\t }\n635\t\n636\t // ── Locked cells ──\n637\t for (let r = 0; r < BOARD_H; r++) {\n638\t for (let c = 0; c < BOARD_W; c++) {\n639\t const color = this.board[r][c];\n640\t if (color) {\n641\t // find which type this color belongs to\n642\t const type = (Object.keys(COLORS) as PieceType[])\n643\t .find(k => COLORS[k] === color) ?? 'I';\n644\t this.drawCell(ctx, c, r, type, CELL);\n645\t }\n646\t }\n647\t }\n648\t\n649\t // ── Ghost piece ──\n650\t const gh = this.ghost();\n651\t if (gh && this.current && gh.y !== this.current.y) {\n652\t for (const [x, y] of cells(gh)) {\n653\t if (y >= 0) this.drawCell(ctx, x, y, gh.type, CELL, 0.18);\n654\t }\n655\t }\n656\t\n657\t // ── Current piece ──\n658\t if (this.current) {\n659\t for (const [x, y] of cells(this.current)) {\n660\t if (y >= 0) this.drawCell(ctx, x, y, this.current.type, CELL);\n661\t }\n662\t }\n663\t }\n664\t\n665\t /** Draw a piece centred inside the given small canvas context. */\n666\t private drawPreview(ctx: CanvasRenderingContext2D, type: PieceType | null) {\n667\t ctx.fillStyle = '#111122';\n668\t ctx.fillRect(0, 0, PREVIEW_W, PREVIEW_H);\n669\t\n670\t if (!type) return;\n671\t\n672\t const shape = getShape(type, 0);\n673\t const rows = shape.length;\n674\t const cols = shape[0].length;\n675\t\n676\t // Compute the tightest bounding box of filled cells\n677\t let minR = rows, maxR = 0, minC = cols, maxC = 0;\n678\t for (let r = 0; r < rows; r++) {\n679\t for (let c = 0; c < cols; c++) {\n680\t if (shape[r][c]) {\n681\t if (r < minR) minR = r; if (r > maxR) maxR = r;\n682\t if (c < minC) minC = c; if (c > maxC) maxC = c;\n683\t }\n684\t }\n685\t }\n686\t const bRows = maxR - minR + 1;\n687\t const bCols = maxC - minC + 1;\n688\t\n689\t const cellSz = Math.min(\n690\t Math.floor((PREVIEW_W - 16) / bCols),\n691\t Math.floor((PREVIEW_H - 16) / bRows),\n692\t 28,\n693\t );\n694\t\n695\t const offX = Math.floor((PREVIEW_W - bCols * cellSz) / 2) - minC * cellSz;\n696\t const offY = Math.floor((PREVIEW_H - bRows * cellSz) / 2) - minR * cellSz;\n697\t\n698\t ctx.save();\n699\t ctx.translate(offX, offY);\n700\t for (let r = 0; r < rows; r++) {\n701\t for (let c = 0; c < cols; c++) {\n702\t if (shape[r][c]) this.drawCell(ctx, c, r, type, cellSz);\n703\t }\n704\t }\n705\t ctx.restore();\n706\t }\n707\t\n708\t /** Idle screen: a partially-filled board with random blocks. */\n709\t private drawIdleBoard() {\n710\t const ctx = this.ctx;\n711\t ctx.fillStyle = '#111122';\n712\t ctx.fillRect(0, 0, BOARD_W * CELL, BOARD_H * CELL);\n713\t\n714\t ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n715\t ctx.lineWidth = 1;\n716\t for (let c = 0; c <= BOARD_W; c++) {\n717\t ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, BOARD_H * CELL); ctx.stroke();\n718\t }\n719\t for (let r = 0; r <= BOARD_H; r++) {\n720\t ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(BOARD_W * CELL, r * CELL); ctx.stroke();\n721\t }\n722\t\n723\t for (let r = 14; r < BOARD_H; r++) {\n724\t for (let c = 0; c < BOARD_W; c++) {\n725\t if (Math.random() > 0.35) {\n726\t const t = ALL_TYPES[(Math.random() * ALL_TYPES.length) | 0];\n727\t this.drawCell(ctx, c, r, t, CELL);\n728\t }\n729\t }\n730\t }\n731\t }\n732\t}\n733\t\n734\t// ── Bootstrap ─────────────────────────────────────────────\n735\twindow.addEventListener('DOMContentLoaded', () => { new TetrisGame(); });\n736\t"}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"4e5c6990-13d5-41cc-be27-f2e034cd5f86","timestamp":"2026-04-05T19:38:02.783Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-6c3p0wr6/src/tetris.ts","content":"// =============================================================\n// TETRIS – Full browser implementation in TypeScript\n// =============================================================\n\n// ── Constants ──────────────────────────────────────────────\nconst BOARD_W = 10;\nconst BOARD_H = 20;\nconst CELL = 30; // px per cell on main board\nconst PREVIEW_W = 120; // px wide of hold / next canvas\nconst PREVIEW_H = 120;\n\n// ── Types ──────────────────────────────────────────────────\ntype PieceType = 'I' | 'O' | 'T' | 'S' | 'Z' | 'J' | 'L';\ntype Cell = string | null;\ntype Board = Cell[][];\ntype GameState = 'idle' | 'playing' | 'paused' | 'gameover';\n\ninterface Piece {\n type: PieceType;\n x: number; // board column of shape origin\n y: number; // board row of shape origin\n rotation: number; // 0–3\n}\n\n// ── Colours ────────────────────────────────────────────────\nconst COLORS: Record<PieceType, string> = {\n I: '#00f0f0',\n O: '#f0f000',\n T: '#a020f0',\n S: '#00e000',\n Z: '#f00000',\n J: '#2040f0',\n L: '#f0a000',\n};\n\n// Slightly darker shade used for 3-D inner shadow\nconst DARK: Record<PieceType, string> = {\n I: '#009090',\n O: '#909000',\n T: '#601890',\n S: '#008000',\n Z: '#900000',\n J: '#102080',\n L: '#905800',\n};\n\n// ── Shapes (4 rotations each) ──────────────────────────────\n// 1 = filled, 0 = empty\nconst SHAPES: Record<PieceType, readonly (readonly number[])[][]> = {\n I: [\n [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n [[0,0,1,0],[0,0,1,0],[0,0,1,0],[0,0,1,0]],\n [[0,0,0,0],[0,0,0,0],[1,1,1,1],[0,0,0,0]],\n [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]],\n ],\n O: [\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n [[0,1,1,0],[0,1,1,0],[0,0,0,0]],\n ],\n T: [\n [[0,1,0],[1,1,1],[0,0,0]],\n [[0,1,0],[0,1,1],[0,1,0]],\n [[0,0,0],[1,1,1],[0,1,0]],\n [[0,1,0],[1,1,0],[0,1,0]],\n ],\n S: [\n [[0,1,1],[1,1,0],[0,0,0]],\n [[0,1,0],[0,1,1],[0,0,1]],\n [[0,0,0],[0,1,1],[1,1,0]],\n [[1,0,0],[1,1,0],[0,1,0]],\n ],\n Z: [\n [[1,1,0],[0,1,1],[0,0,0]],\n [[0,0,1],[0,1,1],[0,1,0]],\n [[0,0,0],[1,1,0],[0,1,1]],\n [[0,1,0],[1,1,0],[1,0,0]],\n ],\n J: [\n [[1,0,0],[1,1,1],[0,0,0]],\n [[0,1,1],[0,1,0],[0,1,0]],\n [[0,0,0],[1,1,1],[0,0,1]],\n [[0,1,0],[0,1,0],[1,1,0]],\n ],\n L: [\n [[0,0,1],[1,1,1],[0,0,0]],\n [[0,1,0],[0,1,0],[0,1,1]],\n [[0,0,0],[1,1,1],[1,0,0]],\n [[1,1,0],[0,1,0],[0,1,0]],\n ],\n};\n\n// ── SRS Wall-kick tables ───────────────────────────────────\n// Offsets are [dx, dy] in canvas coords (positive-Y = DOWN)\n// Derived from the Tetris Guideline with Y axis flipped.\n\nconst KICKS_JLSTZ: Record<string, readonly [number, number][]> = {\n '0>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n '1>0': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n '1>2': [[ 0,0],[ 1, 0],[ 1, 1],[0,-2],[ 1,-2]],\n '2>1': [[ 0,0],[-1, 0],[-1,-1],[0, 2],[-1, 2]],\n '2>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n '3>2': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n '3>0': [[ 0,0],[-1, 0],[-1, 1],[0,-2],[-1,-2]],\n '0>3': [[ 0,0],[ 1, 0],[ 1,-1],[0, 2],[ 1, 2]],\n};\n\nconst KICKS_I: Record<string, readonly [number, number][]> = {\n '0>1': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n '1>0': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n '1>2': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n '2>1': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n '2>3': [[ 0,0],[ 2, 0],[-1, 0],[ 2,-1],[-1, 2]],\n '3>2': [[ 0,0],[-2, 0],[ 1, 0],[-2, 1],[ 1,-2]],\n '3>0': [[ 0,0],[ 1, 0],[-2, 0],[ 1, 2],[-2,-1]],\n '0>3': [[ 0,0],[-1, 0],[ 2, 0],[-1,-2],[ 2, 1]],\n};\n\n// ── Scoring ────────────────────────────────────────────────\nconst LINE_SCORE = [0, 100, 300, 500, 800]; // 0–4 lines\n\n/** Drop interval in ms for a given level (Tetris guideline formula). */\nfunction dropInterval(level: number): number {\n const sec = Math.pow(0.8 - (level - 1) * 0.007, level - 1);\n return Math.max(50, Math.floor(sec * 1000));\n}\n\n// ── Helpers ────────────────────────────────────────────────\nconst ALL_TYPES: PieceType[] = ['I','O','T','S','Z','J','L'];\n\nfunction getShape(type: PieceType, rotation: number): readonly (readonly number[])[] {\n return SHAPES[type][((rotation % 4) + 4) % 4];\n}\n\n/** Returns [boardX, boardY] for every filled cell of the piece. */\nfunction cells(p: Piece): [number, number][] {\n const out: [number, number][] = [];\n const shape = getShape(p.type, p.rotation);\n for (let r = 0; r < shape.length; r++) {\n for (let c = 0; c < shape[r].length; c++) {\n if (shape[r][c]) out.push([p.x + c, p.y + r]);\n }\n }\n return out;\n}\n\n// ── 7-bag randomiser ───────────────────────────────────────\nclass Bag {\n private pool: PieceType[] = [];\n\n private refill() {\n this.pool = [...ALL_TYPES];\n for (let i = this.pool.length - 1; i > 0; i--) {\n const j = (Math.random() * (i + 1)) | 0;\n [this.pool[i], this.pool[j]] = [this.pool[j], this.pool[i]];\n }\n }\n\n next(): PieceType {\n if (!this.pool.length) this.refill();\n return this.pool.pop()!;\n }\n\n peek(): PieceType {\n if (!this.pool.length) this.refill();\n return this.pool[this.pool.length - 1];\n }\n}\n\n// ══════════════════════════════════════════════════════════\n// Main Game Class\n// ══════════════════════════════════════════════════════════\nclass TetrisGame {\n\n // Canvases\n private readonly ctx: CanvasRenderingContext2D;\n private readonly nextCtx: CanvasRenderingContext2D;\n private readonly holdCtx: CanvasRenderingContext2D;\n\n // Board\n private board: Board = this.emptyBoard();\n\n // Pieces\n private current: Piece | null = null;\n private nextType: PieceType = 'I';\n private heldType: PieceType | null = null;\n private canHold = true;\n private bag = new Bag();\n\n // Stats\n private score = 0;\n private level = 1;\n private lines = 0;\n\n // Game loop\n private state: GameState = 'idle';\n private animId: number = 0;\n private lastTime = 0;\n private dropCtr = 0; // accumulated ms toward next gravity drop\n private softDrop = false;\n\n // DAS (Delayed Auto-Shift)\n private dasDir = 0; // -1 | 0 | 1\n private dasTimer = 0;\n private dasRepeat = 0;\n private readonly DAS_DELAY = 133;\n private readonly DAS_PERIOD = 50;\n\n // Key state\n private held = new Set<string>();\n\n // ── Constructor ──────────────────────────────────────────\n constructor() {\n this.ctx = this.getCtx('game-canvas');\n this.nextCtx = this.getCtx('next-canvas');\n this.holdCtx = this.getCtx('hold-canvas');\n\n this.nextType = this.bag.next();\n\n document.addEventListener('keydown', e => this.onKeyDown(e));\n document.addEventListener('keyup', e => this.onKeyUp(e));\n document.getElementById('start-btn')!\n .addEventListener('click', () => this.onStartBtn());\n\n this.showOverlay('TETRIS', 'Press Space to start');\n this.drawIdleBoard();\n this.drawPreview(this.nextCtx, null);\n this.drawPreview(this.holdCtx, null);\n }\n\n private getCtx(id: string): CanvasRenderingContext2D {\n return (document.getElementById(id) as HTMLCanvasElement)\n .getContext('2d')!;\n }\n\n // ── Overlay helpers ──────────────────────────────────────\n private showOverlay(title: string, msg: string) {\n document.getElementById('overlay')!.style.display = 'flex';\n document.getElementById('ov-title')!.textContent = title;\n // handle literal \\n line breaks in msg\n const msgEl = document.getElementById('ov-msg')!;\n msgEl.innerHTML = msg.split('\\n').map(l => `<span>${l}</span>`).join('<br>');\n }\n\n private hideOverlay() {\n document.getElementById('overlay')!.style.display = 'none';\n }\n\n private setBtn(txt: string) {\n (document.getElementById('start-btn') as HTMLButtonElement).textContent = txt;\n }\n\n private updateStats() {\n document.getElementById('score')!.textContent = this.score.toLocaleString();\n document.getElementById('level')!.textContent = String(this.level);\n document.getElementById('lines')!.textContent = String(this.lines);\n }\n\n // ── Button / start flow ──────────────────────────────────\n private onStartBtn() {\n if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n else if (this.state === 'playing') this.pauseGame();\n else if (this.state === 'paused') this.resumeGame();\n }\n\n startGame() {\n this.board = this.emptyBoard();\n this.score = 0;\n this.level = 1;\n this.lines = 0;\n this.heldType = null;\n this.canHold = true;\n this.bag = new Bag();\n this.nextType = this.bag.next();\n this.dropCtr = 0;\n this.softDrop = false;\n this.dasDir = 0;\n\n this.updateStats();\n this.drawPreview(this.holdCtx, null);\n this.spawnPiece();\n\n if (this.state === 'playing') cancelAnimationFrame(this.animId);\n this.state = 'playing';\n this.hideOverlay();\n this.setBtn('PAUSE');\n\n this.lastTime = performance.now();\n this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n pauseGame() {\n this.state = 'paused';\n cancelAnimationFrame(this.animId);\n this.showOverlay('PAUSED', 'Press P or Space to resume');\n this.setBtn('RESUME');\n }\n\n resumeGame() {\n this.state = 'playing';\n this.hideOverlay();\n this.setBtn('PAUSE');\n this.lastTime = performance.now();\n this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n private endGame() {\n this.state = 'gameover';\n cancelAnimationFrame(this.animId);\n this.showOverlay(\n 'GAME OVER',\n `Score: ${this.score.toLocaleString()}\\nLines: ${this.lines} Level: ${this.level}\\nPress Space to play again`\n );\n this.setBtn('RESTART');\n }\n\n // ── Board helpers ────────────────────────────────────────\n private emptyBoard(): Board {\n return Array.from({ length: BOARD_H }, () => new Array<Cell>(BOARD_W).fill(null));\n }\n\n private isValid(p: Piece): boolean {\n for (const [x, y] of cells(p)) {\n if (x < 0 || x >= BOARD_W || y >= BOARD_H) return false;\n if (y >= 0 && this.board[y][x] !== null) return false;\n }\n return true;\n }\n\n private lock() {\n if (!this.current) return;\n const color = COLORS[this.current.type];\n for (const [x, y] of cells(this.current)) {\n if (y >= 0) this.board[y][x] = color;\n }\n this.clearLines();\n this.canHold = true;\n this.spawnPiece();\n }\n\n private clearLines() {\n let cleared = 0;\n for (let r = BOARD_H - 1; r >= 0; r--) {\n if (this.board[r].every(c => c !== null)) {\n this.board.splice(r, 1);\n this.board.unshift(new Array<Cell>(BOARD_W).fill(null));\n cleared++;\n r++; // recheck the row that slid into position r\n }\n }\n if (cleared) {\n this.lines += cleared;\n this.score += LINE_SCORE[cleared] * this.level;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) {\n this.level = newLevel;\n }\n this.updateStats();\n }\n }\n\n // ── Spawn ────────────────────────────────────────────────\n private spawnPiece() {\n const type = this.nextType;\n this.nextType = this.bag.next();\n\n const shape = getShape(type, 0);\n const w = shape[0].length;\n const spawnX = Math.floor((BOARD_W - w) / 2);\n // I piece rotation-0 has an empty top row → spawn 1 row higher\n const spawnY = type === 'I' ? -1 : 0;\n\n this.current = { type, x: spawnX, y: spawnY, rotation: 0 };\n\n if (!this.isValid(this.current)) {\n this.current.y--;\n if (!this.isValid(this.current)) {\n this.current = null;\n this.endGame();\n return;\n }\n }\n\n this.dropCtr = 0;\n this.drawPreview(this.nextCtx, this.nextType);\n }\n\n // ── Movement ─────────────────────────────────────────────\n private tryShift(dx: number, dy: number): boolean {\n if (!this.current) return false;\n const moved: Piece = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (this.isValid(moved)) { this.current = moved; return true; }\n return false;\n }\n\n /** Gravity tick – returns false if piece locked. */\n private gravityDrop(): boolean {\n if (!this.current) return false;\n if (!this.tryShift(0, 1)) {\n this.lock();\n return false;\n }\n return true;\n }\n\n private hardDrop() {\n if (!this.current) return;\n let rows = 0;\n while (this.tryShift(0, 1)) rows++;\n this.score += rows * 2;\n this.updateStats();\n this.lock();\n }\n\n private rotate(dir: 1 | -1) {\n if (!this.current) return;\n const from = this.current.rotation;\n const to = ((from + dir + 4) % 4) as 0|1|2|3;\n const key = `${from}>${to}`;\n\n const kicks: readonly [number,number][] =\n this.current.type === 'I' ? KICKS_I[key] :\n this.current.type === 'O' ? [[0,0]] :\n KICKS_JLSTZ[key];\n\n for (const [dx, dy] of kicks) {\n const attempt: Piece = { ...this.current, rotation: to,\n x: this.current.x + dx,\n y: this.current.y + dy };\n if (this.isValid(attempt)) { this.current = attempt; return; }\n }\n }\n\n private holdPiece() {\n if (!this.current || !this.canHold) return;\n const type = this.current.type;\n if (this.heldType === null) {\n this.heldType = type;\n this.spawnPiece();\n } else {\n const swap = this.heldType;\n this.heldType = type;\n const shape = getShape(swap, 0);\n const w = shape[0].length;\n this.current = { type: swap,\n x: Math.floor((BOARD_W - w) / 2),\n y: swap === 'I' ? -1 : 0,\n rotation: 0 };\n this.dropCtr = 0;\n }\n this.canHold = false;\n this.drawPreview(this.holdCtx, this.heldType);\n }\n\n // Ghost: lowest valid position of current piece\n private ghost(): Piece | null {\n if (!this.current) return null;\n let g = { ...this.current };\n while (true) {\n const down = { ...g, y: g.y + 1 };\n if (this.isValid(down)) g = down; else break;\n }\n return g;\n }\n\n // ── Input ────────────────────────────────────────────────\n private readonly GAME_KEYS = new Set([\n 'ArrowLeft','ArrowRight','ArrowDown','ArrowUp',\n 'Space','KeyZ','KeyX','KeyC','KeyP','Escape',\n ]);\n\n private onKeyDown(e: KeyboardEvent) {\n if (this.GAME_KEYS.has(e.code)) e.preventDefault();\n if (this.held.has(e.code)) return; // ignore key-repeat from OS\n this.held.add(e.code);\n\n if (e.code === 'KeyP' || e.code === 'Escape') {\n if (this.state === 'playing') this.pauseGame();\n else if (this.state === 'paused') this.resumeGame();\n return;\n }\n\n if (e.code === 'Space') {\n if (this.state === 'idle' || this.state === 'gameover') this.startGame();\n else if (this.state === 'paused') this.resumeGame();\n else if (this.state === 'playing') this.hardDrop();\n return;\n }\n\n if (this.state !== 'playing') return;\n\n switch (e.code) {\n case 'ArrowLeft':\n this.tryShift(-1, 0);\n this.startDAS(-1);\n break;\n case 'ArrowRight':\n this.tryShift(1, 0);\n this.startDAS(1);\n break;\n case 'ArrowDown':\n this.softDrop = true;\n break;\n case 'ArrowUp':\n case 'KeyX':\n this.rotate(1);\n break;\n case 'KeyZ':\n this.rotate(-1);\n break;\n case 'KeyC':\n this.holdPiece();\n break;\n }\n }\n\n private onKeyUp(e: KeyboardEvent) {\n this.held.delete(e.code);\n if (e.code === 'ArrowLeft' && this.dasDir === -1) this.stopDAS();\n if (e.code === 'ArrowRight' && this.dasDir === 1) this.stopDAS();\n if (e.code === 'ArrowDown') this.softDrop = false;\n }\n\n private startDAS(dir: -1 | 1) {\n this.dasDir = dir;\n this.dasTimer = 0;\n this.dasRepeat = 0;\n }\n\n private stopDAS() {\n // Re-engage for the other direction if still held\n if (this.held.has('ArrowLeft') && this.dasDir !== -1) this.startDAS(-1);\n else if (this.held.has('ArrowRight') && this.dasDir !== 1) this.startDAS(1);\n else { this.dasDir = 0; this.dasTimer = 0; this.dasRepeat = 0; }\n }\n\n // ── Game loop ────────────────────────────────────────────\n private loop(ts: number) {\n const dt = Math.min(ts - this.lastTime, 100); // cap to avoid spiral after tab-switch\n this.lastTime = ts;\n\n // DAS\n if (this.dasDir !== 0) {\n this.dasTimer += dt;\n if (this.dasTimer >= this.DAS_DELAY) {\n this.dasRepeat += dt;\n while (this.dasRepeat >= this.DAS_PERIOD) {\n this.dasRepeat -= this.DAS_PERIOD;\n this.tryShift(this.dasDir, 0);\n }\n }\n }\n\n // Gravity\n const interval = this.softDrop\n ? Math.max(dropInterval(this.level) / 20, 33)\n : dropInterval(this.level);\n\n this.dropCtr += dt;\n while (this.dropCtr >= interval && this.state === 'playing') {\n this.dropCtr -= interval;\n if (this.softDrop && this.current) {\n this.score += 1;\n document.getElementById('score')!.textContent = this.score.toLocaleString();\n }\n if (!this.gravityDrop()) break; // piece locked → new piece spawned\n }\n\n this.draw();\n if (this.state === 'playing') this.animId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Rendering ────────────────────────────────────────────\n\n /** Draw one cell at grid coords (gx, gy) using given pixel size. */\n private drawCell(\n ctx: CanvasRenderingContext2D,\n gx: number, gy: number,\n type: PieceType,\n size: number,\n alpha = 1,\n ) {\n const px = gx * size;\n const py = gy * size;\n const s = size;\n const b = Math.max(2, (s / 10) | 0); // border/bevel thickness\n\n ctx.globalAlpha = alpha;\n\n // Fill\n ctx.fillStyle = COLORS[type];\n ctx.fillRect(px, py, s, s);\n\n // Inner bevel – bright top/left\n ctx.fillStyle = 'rgba(255,255,255,0.45)';\n ctx.fillRect(px, py, s, b); // top strip\n ctx.fillRect(px, py, b, s); // left strip\n\n // Inner bevel – dark bottom/right\n ctx.fillStyle = DARK[type];\n ctx.fillRect(px, py + s - b, s, b); // bottom\n ctx.fillRect(px + s - b, py, b, s); // right\n\n // Inset highlight square\n ctx.fillStyle = COLORS[type];\n ctx.fillRect(px + b, py + b, s - b * 2, s - b * 2);\n\n // Subtle inner shine\n ctx.fillStyle = 'rgba(255,255,255,0.18)';\n ctx.fillRect(px + b, py + b, s - b * 2, Math.max(1, (s - b * 2) / 2 | 0));\n\n ctx.globalAlpha = 1;\n }\n\n /** Main board render. */\n private draw() {\n const ctx = this.ctx;\n const W = BOARD_W * CELL;\n const H = BOARD_H * CELL;\n\n // ── Background ──\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, W, H);\n\n // ── Grid lines ──\n ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n ctx.lineWidth = 1;\n for (let c = 0; c <= BOARD_W; c++) {\n ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, H); ctx.stroke();\n }\n for (let r = 0; r <= BOARD_H; r++) {\n ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(W, r * CELL); ctx.stroke();\n }\n\n // ── Locked cells ──\n for (let r = 0; r < BOARD_H; r++) {\n for (let c = 0; c < BOARD_W; c++) {\n const color = this.board[r][c];\n if (color) {\n // find which type this color belongs to\n const type = (Object.keys(COLORS) as PieceType[])\n .find(k => COLORS[k] === color) ?? 'I';\n this.drawCell(ctx, c, r, type, CELL);\n }\n }\n }\n\n // ── Ghost piece ──\n const gh = this.ghost();\n if (gh && this.current && gh.y !== this.current.y) {\n for (const [x, y] of cells(gh)) {\n if (y >= 0) this.drawCell(ctx, x, y, gh.type, CELL, 0.18);\n }\n }\n\n // ── Current piece ──\n if (this.current) {\n for (const [x, y] of cells(this.current)) {\n if (y >= 0) this.drawCell(ctx, x, y, this.current.type, CELL);\n }\n }\n }\n\n /** Draw a piece centred inside the given small canvas context. */\n private drawPreview(ctx: CanvasRenderingContext2D, type: PieceType | null) {\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, PREVIEW_W, PREVIEW_H);\n\n if (!type) return;\n\n const shape = getShape(type, 0);\n const rows = shape.length;\n const cols = shape[0].length;\n\n // Compute the tightest bounding box of filled cells\n let minR = rows, maxR = 0, minC = cols, maxC = 0;\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n if (shape[r][c]) {\n if (r < minR) minR = r; if (r > maxR) maxR = r;\n if (c < minC) minC = c; if (c > maxC) maxC = c;\n }\n }\n }\n const bRows = maxR - minR + 1;\n const bCols = maxC - minC + 1;\n\n const cellSz = Math.min(\n Math.floor((PREVIEW_W - 16) / bCols),\n Math.floor((PREVIEW_H - 16) / bRows),\n 28,\n );\n\n const offX = Math.floor((PREVIEW_W - bCols * cellSz) / 2) - minC * cellSz;\n const offY = Math.floor((PREVIEW_H - bRows * cellSz) / 2) - minR * cellSz;\n\n ctx.save();\n ctx.translate(offX, offY);\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n if (shape[r][c]) this.drawCell(ctx, c, r, type, cellSz);\n }\n }\n ctx.restore();\n }\n\n /** Idle screen: a partially-filled board with random blocks. */\n private drawIdleBoard() {\n const ctx = this.ctx;\n ctx.fillStyle = '#111122';\n ctx.fillRect(0, 0, BOARD_W * CELL, BOARD_H * CELL);\n\n ctx.strokeStyle = 'rgba(255,255,255,0.04)';\n ctx.lineWidth = 1;\n for (let c = 0; c <= BOARD_W; c++) {\n ctx.beginPath(); ctx.moveTo(c * CELL, 0); ctx.lineTo(c * CELL, BOARD_H * CELL); ctx.stroke();\n }\n for (let r = 0; r <= BOARD_H; r++) {\n ctx.beginPath(); ctx.moveTo(0, r * CELL); ctx.lineTo(BOARD_W * CELL, r * CELL); ctx.stroke();\n }\n\n for (let r = 14; r < BOARD_H; r++) {\n for (let c = 0; c < BOARD_W; c++) {\n if (Math.random() > 0.35) {\n const t = ALL_TYPES[(Math.random() * ALL_TYPES.length) | 0];\n this.drawCell(ctx, c, r, t, CELL);\n }\n }\n }\n }\n}\n\n// ── Bootstrap ─────────────────────────────────────────────\nwindow.addEventListener('DOMContentLoaded', () => { new TetrisGame(); });\n","numLines":736,"startLine":1,"totalLines":736}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01A4LjVYBkqsu2dY2bbKmrTi","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The code looks good. Let me check a few potential issues:\n\n1. **Board stores color strings but `drawCell` needs `PieceType`**: In the `draw()` method at line 641-644, I'm doing a reverse lookup from color → type. This works correctly since each piece type has a unique color. This is a bit inefficient but works fine.\n\n2. **`clearLines` counter increment**: On line 349, `r++` inside the loop where the outer `for` does `r--` at each iteration end. So when a row is cleared: we splice it out, unshift a new empty row at the top, increment cleared, and do `r++`. \n\nThen the for loop does `r--`, bringing us back to the same index `r`. This correctly rechecks the same position. ✓\n\n3. **Spawn position**: For the I piece, setting `spawnY = -1` positions it so the actual piece blocks start at y=0, the top visible row, with the empty rows above screen.\n\n4. **Game over condition**: When spawning a piece, if it's invalid at y=0 or y=1, we try moving it up with `current.y--`. The actual game over happens when pieces stack up to the top and can't spawn anymore. ✓\n\n5. **DAS timing**: The `dasTimer` accumulates each frame, and once it hits the 133ms threshold, `dasRepeat` starts accumulating. The `while` loop correctly handles cases where a single frame's dt exceeds the repeat period. ✓\n\n6. **Ghost piece rendering**: I'm checking if the ghost's y position matches the current piece's y—if they're the same, there's no point rendering it since they'd overlap.\n\n7. **Lock and spawn flow**: When gravity causes a piece to lock, `lock()` immediately spawns the next piece and updates `this.current`, then the game loop breaks. ✓\n\n8. **Soft and hard drop scoring**: Soft drops award 1 point per row, hard drops award 2 points per row, matching standard Tetris rules. ✓\n\n9. **Level calculation**: Levels increase every 10 lines cleared using `Math.floor(this.lines / 10) + 1`, so lines 0-9 are level 1, 10-19 are level 2, and so on.\n\n10. **Drop speed formula**: The Tetris guideline formula correctly calculates drop intervals—level 1 is 1000ms, level 2 drops to 793ms, level 3 to 618ms, and by level 10 it's down to 64ms. ✓\n\n11. **Board initialization**: `emptyBoard` is called...\n\nActually, I need to reconsider the timing here. Class field initializers in TypeScript run before the constructor body executes, so `this.emptyBoard()` will initialize the board without depending on any other state—that's fine. ✓\n\n12. **Preview drawing**: When the piece type is null, the preview just fills with the background color and exits. ✓\n\n13. **Idle board rendering**: I'm not explicitly calling `draw()` in `drawIdleBoard`, but that's okay because `startGame()` triggers the game loop which handles rendering. However, I'm noticing a potential issue—in `drawIdleBoard` I'm calling `drawCell` with a random piece type `t`, but I need to verify that's actually what I intended there.\n\nThe `drawCell` function correctly uses both `COLORS[type]` and `DARK[type]` for rendering, so that works. ✓\n\nFor the key tracking, using `this.held` to prevent repeated keydown events is the right approach—the browser fires keydown continuously when a key is held, so tracking which keys are active prevents duplicate processing. ✓\n\nThe board stores colors as hex strings, and when rendering locked cells I'm doing a reverse lookup to find the original piece type from the color. Since each type has a unique color, this lookup is reliable. ✓\n\nI could optimize by storing the `PieceType` directly instead of the color, but the current approach works fine for this implementation.\n\nNow I'm checking if the build is still clean after all the changes.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":10935,"cache_read_input_tokens":53973,"cache_creation":{"ephemeral_5m_input_tokens":10935,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"4321bf16-723d-472d-b5dd-4d78766c767f"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01A4LjVYBkqsu2dY2bbKmrTi","type":"message","role":"assistant","content":[{"type":"text","text":"The code looks solid. Let me do a final clean build to confirm everything still compiles:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":10935,"cache_read_input_tokens":53973,"cache_creation":{"ephemeral_5m_input_tokens":10935,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"b98ca105-e781-4781-afa3-82100940ea07"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01A4LjVYBkqsu2dY2bbKmrTi","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01WbJyZUpccyZoKPgYS5SiWn","name":"Bash","input":{"command":"npm run build 2>&1","description":"Final clean TypeScript build"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":10935,"cache_read_input_tokens":53973,"cache_creation":{"ephemeral_5m_input_tokens":10935,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"d8da4fbe-e2dc-4eb6-8d77-a6d3ad16a2a8"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01WbJyZUpccyZoKPgYS5SiWn","type":"tool_result","content":"> loop-bench-6c3p0wr6@1.0.0 build\n> tsc","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"aa4d7fc1-8e88-4afa-8f5c-2433299055cd","timestamp":"2026-04-05T19:38:33.321Z","tool_use_result":{"stdout":"> loop-bench-6c3p0wr6@1.0.0 build\n> tsc","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GtwEnQ3are8CH945QWF1wp","type":"message","role":"assistant","content":[{"type":"text","text":"Zero errors. Let me do a quick sanity check on the final file tree and a spot-check of the compiled output:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1647,"cache_read_input_tokens":64908,"cache_creation":{"ephemeral_5m_input_tokens":1647,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"06530279-8897-4289-8d6c-9c09eb931fc9"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GtwEnQ3are8CH945QWF1wp","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01EYroehprAR3PCjU4qkAPaG","name":"Bash","input":{"command":"find /tmp/loop-bench-6c3p0wr6 -not -path '*/node_modules/*' -not -name '*.map' | sort","description":"List all project files"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1647,"cache_read_input_tokens":64908,"cache_creation":{"ephemeral_5m_input_tokens":1647,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"006af8cf-7ab3-458e-aacf-da1e580b1ff0"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01EYroehprAR3PCjU4qkAPaG","type":"tool_result","content":"/tmp/loop-bench-6c3p0wr6\n/tmp/loop-bench-6c3p0wr6/dist\n/tmp/loop-bench-6c3p0wr6/dist/tetris.js\n/tmp/loop-bench-6c3p0wr6/index.html\n/tmp/loop-bench-6c3p0wr6/node_modules\n/tmp/loop-bench-6c3p0wr6/package.json\n/tmp/loop-bench-6c3p0wr6/package-lock.json\n/tmp/loop-bench-6c3p0wr6/src\n/tmp/loop-bench-6c3p0wr6/src/tetris.ts\n/tmp/loop-bench-6c3p0wr6/style.css\n/tmp/loop-bench-6c3p0wr6/tsconfig.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"8fd23c47-3218-4ec1-a46b-c762cf4546b8","timestamp":"2026-04-05T19:38:36.766Z","tool_use_result":{"stdout":"/tmp/loop-bench-6c3p0wr6\n/tmp/loop-bench-6c3p0wr6/dist\n/tmp/loop-bench-6c3p0wr6/dist/tetris.js\n/tmp/loop-bench-6c3p0wr6/index.html\n/tmp/loop-bench-6c3p0wr6/node_modules\n/tmp/loop-bench-6c3p0wr6/package.json\n/tmp/loop-bench-6c3p0wr6/package-lock.json\n/tmp/loop-bench-6c3p0wr6/src\n/tmp/loop-bench-6c3p0wr6/src/tetris.ts\n/tmp/loop-bench-6c3p0wr6/style.css\n/tmp/loop-bench-6c3p0wr6/tsconfig.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01ANJmjito7eBFJ8aq3CGUKx","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01GSEYkdafhi9auYuAUH5rji","name":"Bash","input":{"command":"head -40 /tmp/loop-bench-6c3p0wr6/dist/tetris.js","description":"Spot-check the compiled JS output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":367,"cache_read_input_tokens":66555,"cache_creation":{"ephemeral_5m_input_tokens":367,"ephemeral_1h_input_tokens":0},"output_tokens":53,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"84bd83ac-df87-45c5-a187-39bc300cdad7"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01GSEYkdafhi9auYuAUH5rji","type":"tool_result","content":"\"use strict\";\n// =============================================================\n// TETRIS – Full browser implementation in TypeScript\n// =============================================================\n// ── Constants ──────────────────────────────────────────────\nconst BOARD_W = 10;\nconst BOARD_H = 20;\nconst CELL = 30; // px per cell on main board\nconst PREVIEW_W = 120; // px wide of hold / next canvas\nconst PREVIEW_H = 120;\n// ── Colours ────────────────────────────────────────────────\nconst COLORS = {\n I: '#00f0f0',\n O: '#f0f000',\n T: '#a020f0',\n S: '#00e000',\n Z: '#f00000',\n J: '#2040f0',\n L: '#f0a000',\n};\n// Slightly darker shade used for 3-D inner shadow\nconst DARK = {\n I: '#009090',\n O: '#909000',\n T: '#601890',\n S: '#008000',\n Z: '#900000',\n J: '#102080',\n L: '#905800',\n};\n// ── Shapes (4 rotations each) ──────────────────────────────\n// 1 = filled, 0 = empty\nconst SHAPES = {\n I: [\n [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]],\n [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]],\n [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]],\n ],\n O: [","is_error":false}]},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"059001ca-ba2c-4056-9a58-793ac6f8a080","timestamp":"2026-04-05T19:38:39.346Z","tool_use_result":{"stdout":"\"use strict\";\n// =============================================================\n// TETRIS – Full browser implementation in TypeScript\n// =============================================================\n// ── Constants ──────────────────────────────────────────────\nconst BOARD_W = 10;\nconst BOARD_H = 20;\nconst CELL = 30; // px per cell on main board\nconst PREVIEW_W = 120; // px wide of hold / next canvas\nconst PREVIEW_H = 120;\n// ── Colours ────────────────────────────────────────────────\nconst COLORS = {\n I: '#00f0f0',\n O: '#f0f000',\n T: '#a020f0',\n S: '#00e000',\n Z: '#f00000',\n J: '#2040f0',\n L: '#f0a000',\n};\n// Slightly darker shade used for 3-D inner shadow\nconst DARK = {\n I: '#009090',\n O: '#909000',\n T: '#601890',\n S: '#008000',\n Z: '#900000',\n J: '#102080',\n L: '#905800',\n};\n// ── Shapes (4 rotations each) ──────────────────────────────\n// 1 = filled, 0 = empty\nconst SHAPES = {\n I: [\n [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]],\n [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]],\n [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]],\n ],\n O: [","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01VpUsz5NzBRU3gVK1TB583o","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Everything looks good. Let me give a comprehensive summary of what was built.","signature":"EooCClsIDBgCKkBGXwk4M6Ww5UsSoT4kVHLQ4CG7Jpnsb8PsfwrH25kqg37+Yt5HpQzvc8aEAhyCa9ysodPSxHmTpw4zj/XXS9l0MhFjbGF1ZGUtc29ubmV0LTQtNjgAEgzEm/BGXgdTHN2ivfAaDPgBSTlFqiA7NMIeBSIwN5VdvlgeHyLlcLxagTf392a5I9P+FqxRHhicQJVQkgRih2cJOiE1haY/jJ9s10J8Kl0m7k1sn0PSnH6kdfH9BhLxzrUPia1ZWfTggQ7Bp52cJSwLuGlxDxwKboVObzpwoxTz/P3IK7mcJAlN06MX6RQ7paI/cDjM+bhmlXtKaK8UL8SipyXGkFwhCc4b/wwYAQ=="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":654,"cache_read_input_tokens":66922,"cache_creation":{"ephemeral_5m_input_tokens":654,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"2c414ebc-0e95-44ff-a263-e1a7753f1e92"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01VpUsz5NzBRU3gVK1TB583o","type":"message","role":"assistant","content":[{"type":"text","text":"Everything compiles cleanly and the output is correct. Here's a summary of everything that was built:\n\n---\n\n## Project structure\n\n```\nindex.html ← Open this in a browser to play\nstyle.css ← Dark neon theme, responsive layout\nsrc/tetris.ts ← Full TypeScript source (~735 lines)\ndist/tetris.js ← Compiled output (loaded by the HTML)\ntsconfig.json ← ES2020, strict mode\npackage.json ← npm build / watch scripts\n```\n\n**To play:** `open index.html` (or serve with any static file server — no backend needed). To rebuild after edits: `npm run build` (or `npm run watch` for live recompilation).\n\n---\n\n## What's implemented\n\n| Feature | Detail |\n|---|---|\n| **All 7 tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces, including the separate I-piece kick table |\n| **7-bag randomiser** | Guarantees each piece appears exactly once per bag — no drought |\n| **Ghost piece** | Translucent outline shows where the piece will land |\n| **Hold piece** | Press **C** to swap the current piece into hold (once per drop) |\n| **Next preview** | Shows the upcoming piece in a small canvas |\n| **Scoring** | Guideline scoring: 100 / 300 / 500 / 800 × level for 1–4 lines; +1 per soft-drop row; +2 per hard-drop row |\n| **Levels & speed** | Level up every 10 lines; speed follows the official guideline formula `(0.8 − 0.007(L−1))^(L−1)` seconds/row |\n| **DAS** | Delayed Auto-Shift (133 ms delay, 50 ms repeat) for smooth left/right movement |\n| **Pause / resume** | **P** or **Esc** toggles pause; overlay shows current state |\n| **Game over** | Detected at spawn time; overlay shows final score |\n| **3-D cell rendering** | Bevel highlight + dark shadow + inner shine per cell |\n\n### Keyboard controls\n\n| Key | Action |\n|---|---|\n| `← →` | Move left / right |\n| `↓` | Soft drop (20× speed) |\n| `Space` | Hard drop |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` | Hold piece |\n| `P` / `Esc` | Pause / resume |"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":654,"cache_read_input_tokens":66922,"cache_creation":{"ephemeral_5m_input_tokens":654,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","uuid":"bfe1464e-d292-43ed-9a54-c69c1eef63e3"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":953979,"duration_api_ms":951531,"num_turns":21,"result":"Everything compiles cleanly and the output is correct. Here's a summary of everything that was built:\n\n---\n\n## Project structure\n\n```\nindex.html ← Open this in a browser to play\nstyle.css ← Dark neon theme, responsive layout\nsrc/tetris.ts ← Full TypeScript source (~735 lines)\ndist/tetris.js ← Compiled output (loaded by the HTML)\ntsconfig.json ← ES2020, strict mode\npackage.json ← npm build / watch scripts\n```\n\n**To play:** `open index.html` (or serve with any static file server — no backend needed). To rebuild after edits: `npm run build` (or `npm run watch` for live recompilation).\n\n---\n\n## What's implemented\n\n| Feature | Detail |\n|---|---|\n| **All 7 tetrominoes** | I, O, T, S, Z, J, L with correct shapes |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces, including the separate I-piece kick table |\n| **7-bag randomiser** | Guarantees each piece appears exactly once per bag — no drought |\n| **Ghost piece** | Translucent outline shows where the piece will land |\n| **Hold piece** | Press **C** to swap the current piece into hold (once per drop) |\n| **Next preview** | Shows the upcoming piece in a small canvas |\n| **Scoring** | Guideline scoring: 100 / 300 / 500 / 800 × level for 1–4 lines; +1 per soft-drop row; +2 per hard-drop row |\n| **Levels & speed** | Level up every 10 lines; speed follows the official guideline formula `(0.8 − 0.007(L−1))^(L−1)` seconds/row |\n| **DAS** | Delayed Auto-Shift (133 ms delay, 50 ms repeat) for smooth left/right movement |\n| **Pause / resume** | **P** or **Esc** toggles pause; overlay shows current state |\n| **Game over** | Detected at spawn time; overlay shows final score |\n| **3-D cell rendering** | Bevel highlight + dark shadow + inner shine per cell |\n\n### Keyboard controls\n\n| Key | Action |\n|---|---|\n| `← →` | Move left / right |\n| `↓` | Soft drop (20× speed) |\n| `Space` | Hard drop |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` | Hold piece |\n| `P` / `Esc` | Pause / resume |","stop_reason":"end_turn","session_id":"3b4bca27-4f3b-4df7-9a9b-b38efefcf5bf","total_cost_usd":1.6425389999999997,"usage":{"input_tokens":28,"cache_creation_input_tokens":68070,"cache_read_input_tokens":972475,"output_tokens":73030,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":68070},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":28,"outputTokens":73030,"cacheReadInputTokens":972475,"cacheCreationInputTokens":68070,"webSearchRequests":0,"costUSD":1.6425389999999997,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"6bf86f7c-c436-458d-a7a9-5d3c15d43ced"} diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_output.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":359869,"duration_api_ms":355437,"num_turns":30,"result":"The Tetris game is complete. Here's a summary of everything built:\n\n---\n\n## Project Structure\n\n```\nindex.html ← The game page (open this in a browser)\nsrc/tetris.ts ← Full TypeScript source (~730 lines)\ndist/tetris.js ← Compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config (ES2020, strict mode)\npackage.json ← npm build script\n```\n\n## How to play\nOpen `index.html` in any modern browser — no server needed. Alternatively rebuild anytime with `npm run build`.\n\n## What's implemented\n\n### Core mechanics\n| Feature | Detail |\n|---|---|\n| **7 tetrominoes** | I, O, T, S, Z, J, L — all standard shapes |\n| **7-bag randomiser** | Guarantees each piece appears once per 7-piece cycle |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces |\n| **Ghost piece** | Semi-transparent preview showing where the piece will land |\n| **Hold queue** | Store one piece (greys out if already used this turn) |\n| **Next preview** | Shows the next 3 upcoming pieces |\n| **Lock delay** | 500 ms grace period + up to 15 moves before a piece locks |\n| **Line clearing** | Clears 1–4 lines; the grid rows collapse correctly |\n| **Scoring** | 100/300/500/800 × level per 1/2/3/4 lines; +1 soft-drop, +2×rows hard-drop |\n| **Increasing speed** | Drops from 1000 ms → 50 ms as level increases (every 10 lines) |\n| **Game over** | Detected on spawn collision |\n| **Particles** | Burst of colourful particles on every line clear |\n\n### Controls\n| Key | Action |\n|---|---|\n| `← / →` | Move left/right (with DAS auto-repeat) |\n| `↓` | Soft drop (+1 pt/row) |\n| `Space` | Hard drop (+2 pts/row) |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` or `Shift` | Hold piece |\n| `P` or `Esc` | Pause / resume |\n| `Enter` | Start / unpause |","stop_reason":"end_turn","session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","total_cost_usd":0.68018355,"usage":{"input_tokens":33,"cache_creation_input_tokens":34885,"cache_read_input_tokens":520386,"output_tokens":26210,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":34885},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":33,"outputTokens":26210,"cacheReadInputTokens":520386,"cacheCreationInputTokens":34885,"webSearchRequests":0,"costUSD":0.68018355,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"1b817903-1fc2-4678-baee-f862f9ac078d"} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_stderr.log b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/claude_stderr.log diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/eval_results.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/eval_results.json @@ -0,0 +1,132 @@ +{ + "structural": { + "pass": true, + "checks": [ + { + "name": "entry_point_exists", + "pass": true, + "detail": "index.html found" + }, + { + "name": "package_json_exists", + "pass": true, + "detail": "package.json found" + }, + { + "name": "build_succeeds", + "pass": true, + "detail": "npm run build completed successfully" + }, + { + "name": "typescript_compiles", + "pass": true, + "detail": "tsc --noEmit passed" + } + ], + "score": 1.0 + }, + "functional": { + "pass": false, + "error": "playwright eval not yet wired", + "score": 0 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": true + }, + "performance": { + "bundle_size_bytes": 24905, + "size_under_512kb": true + }, + "score": 0.67 + }, + "code_analysis": { + "files": { + "total": 6, + "code": 3, + "docs": 0, + "unnecessary": 0, + "unnecessary_list": [] + }, + "lines_of_code": 1627, + "dependencies": { + "production": 0, + "dev": 5, + "total": 5 + }, + "complexity": "moderate", + "console_logs": 0, + "magic_numbers": { + "count": 40, + "excessive": true + }, + "function_length": { + "count": 90, + "average": 6.1, + "max": 41, + "long_functions": 0 + }, + "max_nesting_depth": 14, + "global_declarations": 20, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 99.7, + "camel_case": 608, + "snake_case": 2 + }, + "error_handling": { + "try_catch_blocks": 0, + "has_error_handling": false + }, + "comments": { + "comment_lines": 85, + "source_lines": 1195, + "ratio_pct": 7.1 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 2, + "files_with_logic": 2, + "files_with_both": 2 + }, + "html_validation": { + "valid": false, + "errors": 5 + }, + "duplication_percentage": 0.0, + "score": 0.85 + }, + "transcript_analysis": { + "total_events": 79, + "tool_calls": { + "total": 29, + "bash": 18, + "write": 0, + "edit": 6, + "read": 5 + }, + "wasted_turns": { + "total": 3, + "docs": 0, + "ascii_art": 3, + "server_starts": 0 + }, + "errors_encountered": 0, + "thinking_blocks": 7, + "text_blocks": 10, + "productivity_ratio": 0.9, + "self_tested": true, + "score": 0.95 + }, + "gameplay_bot": { + "pass": false, + "score": 0, + "error": "Gameplay bot timed out after 180 seconds" + }, + "score": 0.6365 +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/gameplay-bot-report.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/gameplay-bot-report.json @@ -0,0 +1,128 @@ +{ + "implementation": { + "renderer": "canvas", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 33, + "height": 66 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "ArrowUp", + "drop": "Space" + }, + "start_mechanism": "click_canvas", + "score_element_found": true + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": true, + "detail": "started via click_canvas" + }, + { + "name": "auto_drop", + "pass": false, + "detail": "piece did not move in 5 seconds" + }, + { + "name": "move_left", + "pass": false, + "detail": "no change detected after key press" + }, + { + "name": "move_right", + "pass": false, + "detail": "no change detected after key press" + }, + { + "name": "move_down", + "pass": true, + "detail": "grid state changed after key press" + }, + { + "name": "rotate", + "pass": true, + "detail": "piece shape changed after rotate key" + }, + { + "name": "all_pieces_rotate", + "pass": false, + "detail": "could not detect any piece rotations" + }, + { + "name": "hard_drop", + "pass": true, + "detail": "visual change detected after hard drop" + }, + { + "name": "piece_locks", + "pass": false, + "detail": "could not verify piece locking at bottom" + }, + { + "name": "new_piece_spawns", + "pass": true, + "detail": "visual change suggests new piece spawned" + }, + { + "name": "multiple_pieces", + "pass": true, + "detail": "game still responding after 10 piece drops" + }, + { + "name": "line_clear", + "pass": true, + "detail": "line cleared via strategic placement" + }, + { + "name": "score_changes", + "pass": false, + "detail": "score did not increase: [242] -> no change after polling" + }, + { + "name": "game_over", + "pass": false, + "detail": "could not trigger or detect game over" + }, + { + "name": "playable_30s", + "pass": true, + "detail": "played for 30s, placed 79 pieces, no crashes" + } + ], + "summary": { + "total": 16, + "passed": 9, + "failed": 7, + "score": 0.56 + }, + "gameplay": { + "pieces_placed": 189, + "lines_cleared": 1, + "max_score_observed": 222, + "play_duration_seconds": 30, + "errors_during_play": 0 + }, + "performance": { + "load_time_ms": 96 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role", + "canvas without aria-label or role", + "canvas without aria-label or role" + ], + "issue_count": 3, + "pass": false + } +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/meta.json b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/meta.json @@ -0,0 +1,30 @@ +{ + "model": "sonnet", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "off", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "on", + "linter": "on", + "playwright": "on", + "context_file": "none", + "sub_agents": "on", + "web_search": "on", + "max_budget": "low", + "task": "tetris", + "cell_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2", + "run_number": 2, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-05T19:22:56.128186+00:00", + "wall_time_seconds": 360, + "exit_code": 0, + "completed_at": "2026-04-05T19:29:03.407545+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/transcript.jsonl b/results/runs/tetris_context_file=none_effort=high_human_language=en_language=typescript_linter=on_max_budget=low_model=sonnet_playwright=on_prompt_style=simple_sub_agents=on_tool_edit=on_tool_glob=on_tool_grep=on_tool_read=off_tool_write=on_web_search=on_run2/transcript.jsonl @@ -0,0 +1,79 @@ +{"type": "harness", "subtype": "config", "model": "sonnet", "effort": "high", "tools": ["Bash", "Write", "Edit", "Glob", "Grep", "Agent", "WebSearch", "WebFetch"], "max_budget_usd": 2.0, "timeout_seconds": 1200, "task": "tetris", "language": "typescript", "prompt_style": "simple"} +{"type": "user", "subtype": "prompt", "message": {"role": "user", "content": "Build a playable Tetris game that runs in a browser. It should have all the standard mechanics: piece rotation, line clearing, scoring, and increasing speed. Use keyboard controls for movement and rotation.\n\n\nUse TypeScript."}} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-elvty8os","session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"claude-sonnet-4-6","permissionMode":"dontAsk","slash_commands":["update-config","debug","simplify","batch","loop","schedule","claude-api","compact","context","cost","heapdump","init","review","security-review","insights"],"apiKeySource":"apiKeyHelper","claude_code_version":"2.1.92","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan"],"skills":["update-config","debug","simplify","batch","loop","schedule","claude-api"],"plugins":[{"name":"claude-hud","path":"/root/.claude/plugins/marketplaces/claude-hud/","source":"claude-hud@claude-hud"},{"name":"rust-analyzer-lsp","path":"/root/.claude/plugins/marketplaces/claude-plugins-official/plugins/rust-analyzer-lsp","source":"rust-analyzer-lsp@claude-plugins-official"}],"uuid":"02d8f338-f1b0-4684-8f36-ce1d737d1948","fast_mode_state":"off"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Rnn4e3Kh4b9vrcnoQbEaf3","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Let me build a complete Tetris game using TypeScript that runs in a browser. I'll create a well-structured implementation with all the standard Tetris mechanics.\n\nLet me plan the structure:\n1. `index.html` - The main HTML file\n2. `src/tetris.ts` - The main TypeScript file with all game logic\n3. `tsconfig.json` - TypeScript configuration\n\nI'll implement:\n- All 7 Tetris pieces (I, O, T, S, Z, J, L)\n- Piece rotation using rotation matrices or predefined rotations\n\n\n- Line clearing and scoring system similar to classic Tetris\n- Increasing speed as the game progresses\n- Keyboard controls for movement, rotation, and hard drop\n- A visual game board rendered with canvas\n- Next piece preview display\n- Game over detection and start/pause functionality\n\nFor the pieces, I'll use standard colors: cyan for I, yellow for O, purple for T, green for S, red for Z, blue for J, and orange for L. I'll set up a simple TypeScript compilation workflow to handle the build process.\n\nWriting the complete implementation...","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4726,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":4726,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"a2997da2-a2a1-407e-9cc7-23fa7a714a1f"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01Rnn4e3Kh4b9vrcnoQbEaf3","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01DnEC81YLhAXzfZkB4M3iHx","name":"Bash","input":{"command":"node --version && npm --version && which tsc || echo \"tsc not found globally\"","description":"Check Node, npm, and TypeScript versions"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4726,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":4726,"ephemeral_1h_input_tokens":0},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"4255e5ae-5894-4d1f-bac3-6dae73c4dc2b"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01DnEC81YLhAXzfZkB4M3iHx","type":"tool_result","content":"v22.22.0\n11.9.0\n/usr/bin/tsc","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"91fb1e9a-8635-4f54-b27a-735225658bfe","timestamp":"2026-04-05T19:23:12.146Z","tool_use_result":{"stdout":"v22.22.0\n11.9.0\n/usr/bin/tsc","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01WdkkPBbbwmpoait2vfnLC1","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Ur4cpKk281ZXCM4qAYM1CC","name":"Bash","input":{"command":"ls /tmp/loop-bench-elvty8os","description":"List current working directory contents"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":532,"cache_read_input_tokens":4726,"cache_creation":{"ephemeral_5m_input_tokens":532,"ephemeral_1h_input_tokens":0},"output_tokens":40,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"9db400cf-da0d-4b5e-8c6b-30e2ccef72e3"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Ur4cpKk281ZXCM4qAYM1CC","type":"tool_result","content":"node_modules\npackage.json\npackage-lock.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"af436750-d849-4987-891c-728fb87fc701","timestamp":"2026-04-05T19:23:13.842Z","tool_use_result":{"stdout":"node_modules\npackage.json\npackage-lock.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GCaSZbouukrEFhwhnomgxF","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01YEWDKy7phAZkgpkcmuVmv3","name":"Read","input":{"file_path":"/tmp/loop-bench-elvty8os/package.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":641,"cache_read_input_tokens":4726,"cache_creation":{"ephemeral_5m_input_tokens":641,"ephemeral_1h_input_tokens":0},"output_tokens":58,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"c7ec48d9-7fcd-4422-9cb5-78953cb467bf"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01YEWDKy7phAZkgpkcmuVmv3","type":"tool_result","content":"1\t{\n2\t \"name\": \"loop-bench-elvty8os\",\n3\t \"version\": \"1.0.0\",\n4\t \"description\": \"\",\n5\t \"main\": \"index.js\",\n6\t \"scripts\": {\n7\t \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n8\t },\n9\t \"keywords\": [],\n10\t \"author\": \"\",\n11\t \"license\": \"ISC\",\n12\t \"type\": \"commonjs\",\n13\t \"devDependencies\": {\n14\t \"@eslint/js\": \"^10.0.1\",\n15\t \"@playwright/test\": \"^1.59.1\",\n16\t \"@types/node\": \"^25.5.2\",\n17\t \"eslint\": \"^10.2.0\",\n18\t \"typescript\": \"^6.0.2\"\n19\t }\n20\t}\n21\t"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"7064f3b7-8462-44c5-82a3-e30e89e7b1ab","timestamp":"2026-04-05T19:23:15.271Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-elvty8os/package.json","content":"{\n \"name\": \"loop-bench-elvty8os\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@playwright/test\": \"^1.59.1\",\n \"@types/node\": \"^25.5.2\",\n \"eslint\": \"^10.2.0\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","numLines":21,"startLine":1,"totalLines":21}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01KMJUkSMKSmjUZqBYk7gEDE","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Good, TypeScript is available. Now let me build the Tetris game. I'll use a simple approach:\n1. Write the TypeScript source\n2. Compile it with tsc\n3. Create an HTML file that uses the compiled JS\n\nLet me create the structure:\n- `src/tetris.ts` - Main game logic\n- `tsconfig.json` - TypeScript config\n- `index.html` - HTML file\n\nI'll write a comprehensive Tetris implementation. Let me plan it carefully:\n\n**Game Board**: 10 columns × 20 rows (standard Tetris)\n\n**Pieces** (Tetrominos):\n\n\nI've got all seven tetromino shapes defined as 2D arrays, and I'll handle rotation using matrix transpose and reverse operations.\n\n**Scoring**: I'm implementing classic Tetris scoring where clearing multiple lines at once gives exponentially higher points—100 for a single line up to 800 for a Tetris (four lines), all multiplied by the current level.\n\n**Gameplay mechanics**: The level increases every 10 lines cleared, which also speeds up the gravity. Controls include arrow keys for movement, up arrow or X for clockwise rotation, Z for counter-clockwise, down for soft drop, space for hard drop, and P to pause.\n\n**Rendering and features**: I'm building this with HTML5 Canvas and planning to add a ghost piece preview, next piece display, and possibly a hold mechanic, plus some nice visual styling.\n\nWriting the TypeScript implementation... Defining the tetromino shapes and setting up the Super Rotation System wall kicks for piece rotation mechanics... Defining wall kick offset tables... Setting up the game class with canvas contexts for the main board, next piece preview, and hold piece display, then initializing the board state and piece tracking variables. Setting up the canvas elements and their 2D contexts for the main game board, next piece preview, and hold piece display, then initializing an empty board and event listeners before rendering the initial state.\n\nNow I'm implementing the piece randomization system using a bag algorithm with Fisher-Yates shuffle to ensure fair distribution of tetrominoes, and then creating new pieces with proper positioning and rotation state.\n\nImplementing rotation logic... Writing game logic... Writing the line-clearing logic... Now I'm setting up the game over overlay by populating it with the final score and a restart button, then updating the UI elements to display the current score, level, and lines cleared.\n\nSetting up event listeners... Writing the piece movement logic... Writing rotation logic... Writing game logic... Setting up the game loop with animation frames, checking if the piece can drop based on the level's drop interval, and handling the collision detection when it hits the ground.\n\nNow I'm handling the piece locking mechanism—when a piece lands, I start a lock timer that gives the player a brief window to move or rotate before it permanently locks into place, and I'm also setting up the render cycle to update the display.\n\nWriting rendering code... Finishing the ghost piece rendering, then drawing the active piece on top. If the game is paused, I'm overlaying a semi-transparent dark screen with centered \"PAUSED\" text. Now I'm moving into the grid drawing function...\n\nDrawing the grid lines... Finishing the cell drawing with shadow effects on the bottom and right edges, then moving into the piece drawing logic that iterates through the tetromino matrix to render each block...\n\nNow I'm setting up the next piece preview canvas by clearing it and calculating the dimensions needed to center the upcoming tetromino piece. Finishing the hold piece rendering logic and initializing the game...","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":311,"cache_read_input_tokens":5367,"cache_creation":{"ephemeral_5m_input_tokens":311,"ephemeral_1h_input_tokens":0},"output_tokens":39,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"e8211719-b7d2-414a-98f0-c0bb32d6a28a"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MdeScAPBFxZHUWdjzoQw5e","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Good. I have TypeScript available. Let me create the Tetris game. I'll structure it as follows:\n\n1. `src/tetris.ts` - The main TypeScript game logic\n2. `index.html` - The HTML page\n3. `tsconfig.json` - TypeScript configuration\n4. Update `package.json` to add a build script\n\nI'll use the Canvas API for rendering. Let me write a complete, well-structured Tetris implementation.\n\nLet me design the full game:\n\n**Pieces (Tetrominoes):**\n- I: `[[1,1,1,1]]`\n\n\n- O: `[[1,1],[1,1]]`\n- T: `[[0,1,0],[1,1,1]]`\n- S: `[[0,1,1],[1,1,0]]`\n- Z: `[[1,1,0],[0,1,1]]`\n- J: `[[1,0,0],[1,1,1]]`\n- L: `[[0,0,1],[1,1,1]]`\n\nI'll implement rotation using the SRS (Super Rotation System) or just simple matrix rotation. For scoring, I'll award points based on lines cleared and implement increasing difficulty as the player progresses.\n\nNow I'm setting up the game mechanics: controls for movement and rotation, a drop speed that accelerates with each level, and a pause feature. I'll build this with TypeScript and a clean HTML setup that loads the compiled JavaScript.","signature":"Ep0LClsIDBgCKkAbRm4vzJquenC6JHZBcF3c0xjcwBFEkMHpd1hkwXHX0wyhgMAEyLFFzAKdrpauEFeGxOuZUFUWaiDQLGUMEyvrMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgz3B76Y/wR5HhSEtfsaDE+zN3SlOAi/0JLqWCIwOHBjNtEvPv0QPD8mpQu6c+UuSTWAmhGgdZ6v4+JWIP42J+hqlqbSUDSfwwxubB8SKu8JLvUmBt0XrPIZCBCerf2EjLaDptnaK6MIbizhW2X/JNkuOM3ZRNHzpbGmk4cb71gn0UJALbTZMRNE2+5WiGmNEjPJEzRLrlltoBmhUiR5NltbCBy0G7QKqia5Jb1nKnUPUQxfv1kaV1qzbEPCaE/HUiOq0V1/EQNYrv1KunCDq1nmQW9WD6WJXcGMpJlQoCDOYx/Wf1vdVvxuuT42WJjQJy5bDrhePUlvOP6ZIq6qSG/p372yGD8/PJy8miST0Z40Z2fC97Jwg5B6afotIj01ID0mbmoWqb4BeXrQ1FP+g0LpUig/miTXcDIT6hn8i6B8vmDJeRoXEf3pk97zXBR7kv8CEbSxtV1SdPIx2E6xvs1E9bSStw/GLXfiAZRHzIvfH63tCDZu5Ssu2c/V46cLL5iw0n3PhiTgjTBFHd5igkFE0jrq/YERu1zJy9t9oIRUr6nlBXamslzu3bd+d4jstbrhCl8a4kuSt4rRbl3j33MLUYQ6mXgjzr8Q+bMjG2Ue6MlB+OvTGZGmJC1CS/YXHiN+M9b8wX+lMcG0uuXMjrD3FC80zpeD/p5SCuiiW0EoAi9A+ap57A4VtL4w/dbaEjMTPuQZZD1FSt6yjhP89QRgcpnVZwIg0NGHF+HHBuBHti6gXEnM0Fq5EvPJiFTCvo5NVwgwsabyOaPM6vkwoYXleW+AP5YH4nq03/1kxXlP0hsXQvLadjKvEn3g/ibJZYWhFSb2wQ6am3UU91dxJMkHBoRHcTzklVs2uE+yyg5xSpkrolRiVB4wpDxgnIROfvVIkQzLX93y6odu9OidjCzR7AexwdI2T0vMaYMhpJEmW8WSkkysSSTMh2nBYW0cPCWGB6GXivctB4uzLGJK/mYLF6sAOY0zaCWbMh5g8mR79p3g2L1OaPmoomUoSrlhwBw3lGA9TS4kutrWPaFcut94V0FrmEPptWa1b8wfs2DO6SBsYaX8A/iFTv8q8OlskWukie2LCBeGvkEJorKBH7j0TDPB0146XhUmonctke5xiWju2qL7vE+dlUUEQzUhocmbi9bJzC0rbGsZ3NJacq7X8OpUMW83urIH7sK7a/odTQPMcXsuZBY2v/Fvo8aH/0K/KaXyzh3BEc4BrEmn9BcjfIIxB+LoF5kbuRTVBdadcSEt8FMD2v56pM8Lx1HG767AbX3e41I8TkU6zXvOorsTMpd3ehlup169IrX9Vj2+N7JkkAFFlNFxwgGyGtgGKgCFiT+Mt15fmibO4QYuyBUa2Kfd1LBoEYt8dqk65BgnZPb0I7lUktLNzgcvS5W8lKdxGiDUK/MSx0vWnqMrXS/aosPXvXO4yETpl/+l/8xPGOml3suUcTwniwUkK43NhOAVIyAglRTmwVoKemNpQE3D3M+EtbdzuqDsyUOz5LNUGkQQEhWc8gWxrTfAdXJORmdln+Bj43Rn5i1a3hKW7wyCskOU+QM+jbh3mFdoJRxxAilGAO7C88QejrnfvFtg/NKlIYbav+UsjHHL60EoMzFNjDycWbcXvWkN0xUqligygs9fJIu2G00Ol/Obxvv3EKny+oQO+HKV75mwmbO1HtFwsSt1bOJ2++PKJ36tVAxf2EVJMlW7C+BK+cE3QC+7fvPfcFZVA4MiveTIW6Tz1i6PW9ljhB3DReo0uArNVF1MwamlruVl50RHP5XYC1XWGAE="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":5678,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":36,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"fe832689-4096-499c-b4ba-8789dad111f7"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MdeScAPBFxZHUWdjzoQw5e","type":"message","role":"assistant","content":[{"type":"text","text":"Good — TypeScript 6 and Node 22 are ready. Let me build the full Tetris game now."}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":5678,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":36,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"70802368-fb16-46a5-9d20-f1fbc5839ebf"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MdeScAPBFxZHUWdjzoQw5e","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_016toQesG7vNRdZ22bm2srAc","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-elvty8os/src","description":"Create src directory"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":5678,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":36,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"7b1a7c54-0fa8-430e-a93d-15c2c72ddffc"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_016toQesG7vNRdZ22bm2srAc","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"3b3983b6-9391-484d-a15f-7dbe8634c8d6","timestamp":"2026-04-05T19:24:56.055Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":true}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015VBxyTKfG4ZmcwKfniZMeB","type":"message","role":"assistant","content":[{"type":"text","text":"Now I'll write all the files. Let's start with the TypeScript source:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":589,"cache_read_input_tokens":5678,"cache_creation":{"ephemeral_5m_input_tokens":589,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"0e2b773b-22ad-4c30-b4ef-f7662bfbd95b"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015VBxyTKfG4ZmcwKfniZMeB","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01JxBh8jmjnjXxNWsd7UGdam","name":"Bash","input":{"command":"cat > /tmp/loop-bench-elvty8os/src/tetris.ts << 'TYPESCRIPT_EOF'\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Matrix = number[][];\ntype Color = string;\n\ninterface Piece {\n matrix: Matrix;\n color: Color;\n x: number;\n y: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n color: string;\n size: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px per cell\nconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\nconst TOTAL_ROWS = ROWS + HIDDEN;\n\nconst COLORS: Record<string, Color> = {\n I: \"#00d4ff\",\n O: \"#ffd700\",\n T: \"#bf5fff\",\n S: \"#39d353\",\n Z: \"#ff4d4d\",\n J: \"#4d79ff\",\n L: \"#ff9900\",\n};\n\nconst TETROMINOES: Record<string, Matrix> = {\n I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n O: [[1,1],[1,1]],\n T: [[0,1,0],[1,1,1],[0,0,0]],\n S: [[0,1,1],[1,1,0],[0,0,0]],\n Z: [[1,1,0],[0,1,1],[0,0,0]],\n J: [[1,0,0],[1,1,1],[0,0,0]],\n L: [[0,0,1],[1,1,1],[0,0,0]],\n};\n\n// Scoring per lines cleared (multiplied by level)\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n\n// Drop interval in ms at each level (capped at level 20)\nfunction levelInterval(level: number): number {\n return Math.max(50, 1000 - (level - 1) * 47);\n}\n\n// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n\n// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\nconst KICKS_JLSTZ: [number,number][][] = [\n // 0→1\n [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n // 1→2\n [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n // 2→3\n [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n // 3→0\n [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n];\n\n// Kick table for I piece\nconst KICKS_I: [number,number][][] = [\n // 0→1\n [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n // 1→2\n [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n // 2→3\n [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n // 3→0\n [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n];\n\n// ─── Utility ──────────────────────────────────────────────────────────────────\n\nfunction rotateCW(m: Matrix): Matrix {\n const rows = m.length, cols = m[0].length;\n return Array.from({ length: cols }, (_, c) =>\n Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n );\n}\n\nfunction rotateCCW(m: Matrix): Matrix {\n return rotateCW(rotateCW(rotateCW(m)));\n}\n\n// ─── Board ────────────────────────────────────────────────────────────────────\n\nclass Board {\n grid: Color[][];\n\n constructor() {\n this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n }\n\n isValid(piece: Piece): boolean {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const x = piece.x + c;\n const y = piece.y + r;\n if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n if (y >= 0 && this.grid[y][x]) return false;\n }\n }\n return true;\n }\n\n lock(piece: Piece): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const y = piece.y + r;\n const x = piece.x + c;\n if (y >= 0) this.grid[y][x] = piece.color;\n }\n }\n }\n\n clearLines(): number {\n const cleared: number[] = [];\n for (let r = 0; r < TOTAL_ROWS; r++) {\n if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n }\n for (const r of cleared) {\n this.grid.splice(r, 1);\n this.grid.unshift(Array(COLS).fill(\"\"));\n }\n return cleared.length;\n }\n\n getGhostY(piece: Piece): number {\n let gy = piece.y;\n while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n return gy;\n }\n}\n\n// ─── Random Bag ──────────────────────────────────────────────────────────────\n\nclass Bag {\n private queue: string[] = [];\n\n private refill(): void {\n const keys = Object.keys(TETROMINOES);\n for (let i = keys.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [keys[i], keys[j]] = [keys[j], keys[i]];\n }\n this.queue.push(...keys);\n }\n\n next(): string {\n if (this.queue.length < 5) this.refill();\n return this.queue.shift()!;\n }\n\n peek(n: number): string[] {\n while (this.queue.length < n + 5) this.refill();\n return this.queue.slice(0, n);\n }\n}\n\n// ─── Tetris Game ─────────────────────────────────────────────────────────────\n\nclass Tetris {\n // Canvases\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private holdCanvas: HTMLCanvasElement;\n private holdCtx: CanvasRenderingContext2D;\n\n // Game state\n private board: Board;\n private bag: Bag;\n private current!: Piece;\n private holdKey: string | null = null;\n private holdUsed: boolean = false;\n private rotation: number = 0; // 0..3\n private score: number = 0;\n private lines: number = 0;\n private level: number = 1;\n private gameOver: boolean = false;\n private paused: boolean = false;\n private started: boolean = false;\n\n // Timers\n private dropTimer: number = 0;\n private lastTime: number = 0;\n private rafId: number = 0;\n\n // Lock-delay\n private lockTimer: number = 0;\n private lockDelay: number = 500; // ms\n private lockMoves: number = 0;\n private maxLockMoves: number = 15;\n private onGround: boolean = false;\n\n // Particles\n private particles: Particle[] = [];\n\n // DOM\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitle: HTMLElement;\n private overlayMsg: HTMLElement;\n\n constructor() {\n this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n this.ctx = this.canvas.getContext(\"2d\")!;\n this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n\n this.canvas.width = COLS * BLOCK;\n this.canvas.height = ROWS * BLOCK;\n\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitle = document.getElementById(\"overlay-title\")!;\n this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n\n this.board = new Board();\n this.bag = new Bag();\n\n this.bindKeys();\n this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n }\n\n // ── Spawn ────────────────────────────────────────────────────────────────\n\n private spawn(key: string): Piece {\n const matrix = TETROMINOES[key].map(r => [...r]);\n const color = COLORS[key];\n const x = Math.floor((COLS - matrix[0].length) / 2);\n const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n return { matrix, color, x, y };\n }\n\n private spawnNext(): void {\n const key = this.bag.next();\n this.current = this.spawn(key);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n\n if (!this.board.isValid(this.current)) {\n this.endGame();\n }\n }\n\n // ── Movement & Rotation ──────────────────────────────────────────────────\n\n private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }\n\n private rotate(dir: 1 | -1): void {\n const fromRot = this.rotation;\n const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n\n const isI = this.current.matrix.length === 4;\n const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n const kickIdx = dir === 1 ? fromRot : toRot;\n const kickSet = kicks[kickIdx];\n\n for (const [kx, ky] of kickSet) {\n const nx = this.current.x + (dir === 1 ? kx : -kx);\n const ny = this.current.y + (dir === 1 ? ky : -ky);\n const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n if (this.board.isValid(candidate)) {\n this.current = candidate;\n this.rotation = toRot;\n this.resetLockDelay();\n return;\n }\n }\n }\n\n private hardDrop(): void {\n const gy = this.board.getGhostY(this.current);\n const dropped = gy - this.current.y;\n this.score += dropped * 2;\n this.current = { ...this.current, y: gy };\n this.lockPiece();\n }\n\n private hold(): void {\n if (this.holdUsed) return;\n this.holdUsed = true;\n if (this.holdKey === null) {\n // Infer key by matching the color\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n this.holdKey = key;\n this.spawnNext();\n } else {\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n const prev = this.holdKey;\n this.holdKey = key;\n this.current = this.spawn(prev);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n }\n this.drawHold();\n }\n\n // ── Lock Delay ───────────────────────────────────────────────────────────\n\n private resetLockDelay(): void {\n if (this.onGround && this.lockMoves < this.maxLockMoves) {\n this.lockTimer = 0;\n this.lockMoves++;\n }\n }\n\n private lockPiece(): void {\n this.board.lock(this.current);\n const cleared = this.board.clearLines();\n\n if (cleared > 0) {\n this.spawnLineClearParticles(cleared);\n this.score += LINE_SCORES[cleared] * this.level;\n this.lines += cleared;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) this.level = newLevel;\n }\n\n this.holdUsed = false;\n this.updateHUD();\n this.spawnNext();\n }\n\n // ── Particles ────────────────────────────────────────────────────────────\n\n private spawnLineClearParticles(_count: number): void {\n const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n for (let i = 0; i < 80; i++) {\n this.particles.push({\n x: Math.random() * this.canvas.width,\n y: Math.random() * this.canvas.height,\n vx: (Math.random() - 0.5) * 6,\n vy: (Math.random() - 0.5) * 6,\n alpha: 1,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: Math.random() * 5 + 2,\n });\n }\n }\n\n // ── Game Loop ────────────────────────────────────────────────────────────\n\n private loop(time: number): void {\n const dt = Math.min(time - this.lastTime, 100);\n this.lastTime = time;\n\n if (!this.paused && !this.gameOver) {\n this.dropTimer += dt;\n\n const interval = levelInterval(this.level);\n if (this.dropTimer >= interval) {\n this.dropTimer = 0;\n const moved = this.move(0, 1);\n if (!moved) {\n this.onGround = true;\n }\n }\n\n // Lock delay\n const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n if (landedNow) {\n this.onGround = true;\n this.lockTimer += dt;\n if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n this.lockPiece();\n }\n } else {\n this.onGround = false;\n this.lockTimer = 0;\n }\n\n // Update particles\n this.particles = this.particles.filter(p => p.alpha > 0.02);\n for (const p of this.particles) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.15;\n p.alpha *= 0.93;\n }\n }\n\n this.draw();\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Start / Pause / End ──────────────────────────────────────────────────\n\n start(): void {\n if (this.started && !this.gameOver) {\n this.togglePause();\n return;\n }\n this.board = new Board();\n this.bag = new Bag();\n this.holdKey = null;\n this.holdUsed = false;\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.gameOver = false;\n this.paused = false;\n this.started = true;\n this.particles = [];\n this.spawnNext();\n this.updateHUD();\n this.hideOverlay();\n this.lastTime = performance.now();\n this.dropTimer = 0;\n cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n private togglePause(): void {\n this.paused = !this.paused;\n if (this.paused) {\n this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n } else {\n this.hideOverlay();\n this.lastTime = performance.now();\n }\n }\n\n private endGame(): void {\n this.gameOver = true;\n this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n }\n\n // ── Draw ─────────────────────────────────────────────────────────────────\n\n private draw(): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBackground();\n this.drawBoard();\n this.drawGhost();\n this.drawPiece(ctx, this.current, -HIDDEN);\n this.drawParticles();\n this.drawNext();\n this.drawHold();\n }\n\n private drawBackground(): void {\n const ctx = this.ctx;\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n ctx.lineWidth = 1;\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, this.canvas.height);\n ctx.stroke();\n }\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(this.canvas.width, r * BLOCK);\n ctx.stroke();\n }\n }\n\n private drawBoard(): void {\n const ctx = this.ctx;\n for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n const color = this.board.grid[r][c];\n if (color) {\n this.drawBlock(ctx, c, r - HIDDEN, color);\n }\n }\n }\n }\n\n private drawGhost(): void {\n const gy = this.board.getGhostY(this.current);\n if (gy === this.current.y) return;\n const ctx = this.ctx;\n ctx.globalAlpha = 0.25;\n const ghost: Piece = { ...this.current, y: gy };\n this.drawPiece(ctx, ghost, -HIDDEN);\n ctx.globalAlpha = 1;\n }\n\n private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const px = piece.x + c;\n const py = piece.y + r + yOffset;\n if (py < 0) continue;\n this.drawBlock(ctx, px, py, piece.color);\n }\n }\n }\n\n private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n const px = x * size;\n const py = y * size;\n const pad = size * 0.05;\n\n // Base fill\n ctx.fillStyle = color;\n ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n\n // Highlight (top-left)\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n\n // Shadow (bottom-right)\n ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n }\n\n private drawParticles(): void {\n const ctx = this.ctx;\n for (const p of this.particles) {\n ctx.globalAlpha = p.alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n\n private drawNext(): void {\n const ctx = this.nextCtx;\n const next3 = this.bag.peek(3);\n const cellW = 4;\n const cellH = 3;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n next3.forEach((key, idx) => {\n const matrix = TETROMINOES[key];\n const color = COLORS[key];\n const offX = Math.floor((cellW - matrix[0].length) / 2);\n const offY = Math.floor((cellH - matrix.length) / 2);\n const baseY = idx * cellH;\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n }\n }\n });\n }\n\n private drawHold(): void {\n const ctx = this.holdCtx;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n\n if (!this.holdKey) return;\n const matrix = TETROMINOES[this.holdKey];\n const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n const offX = Math.floor((4 - matrix[0].length) / 2);\n const offY = Math.floor((3 - matrix.length) / 2);\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n }\n }\n }\n\n // ── HUD ──────────────────────────────────────────────────────────────────\n\n private updateHUD(): void {\n this.scoreEl.textContent = this.score.toLocaleString();\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitle.textContent = title;\n this.overlayMsg.textContent = msg;\n this.overlayEl.classList.remove(\"hidden\");\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add(\"hidden\");\n }\n\n // ── Key Bindings ─────────────────────────────────────────────────────────\n\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n }, DAS_DELAY) as unknown as NodeJS.Timeout,\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {\n if (!dasState[key]) return;\n clearTimeout(dasState[key].timer!);\n clearInterval(dasState[key].interval!);\n dasState[key].active = false;\n };\n\n window.addEventListener(\"keydown\", (e) => {\n if (!this.started || this.gameOver) {\n if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n return;\n }\n\n switch (e.code) {\n case \"ArrowLeft\":\n e.preventDefault();\n startDAS(\"left\", () => {\n if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowRight\":\n e.preventDefault();\n startDAS(\"right\", () => {\n if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"KeyZ\":\n e.preventDefault();\n if (!this.paused) { this.rotate(-1); }\n break;\n case \"KeyX\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"Space\":\n e.preventDefault();\n if (this.paused) { this.togglePause(); return; }\n this.hardDrop();\n break;\n case \"KeyC\":\n case \"ShiftLeft\":\n case \"ShiftRight\":\n e.preventDefault();\n if (!this.paused) this.hold();\n break;\n case \"KeyP\":\n case \"Escape\":\n e.preventDefault();\n this.togglePause();\n break;\n case \"Enter\":\n e.preventDefault();\n if (this.paused) this.togglePause();\n break;\n }\n });\n\n window.addEventListener(\"keyup\", (e) => {\n if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n if (e.code === \"ArrowRight\") stopDAS(\"right\");\n if (e.code === \"ArrowDown\") stopDAS(\"down\");\n });\n }\n}\n\n// ─── Bootstrap ───────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new Tetris();\n});\nTYPESCRIPT_EOF","description":"Write the main Tetris TypeScript source file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":589,"cache_read_input_tokens":5678,"cache_creation":{"ephemeral_5m_input_tokens":589,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"fbb6ed4b-03fe-4a45-bd49-9d4d8f18f7dd"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01JxBh8jmjnjXxNWsd7UGdam","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"2cf9cc71-a383-4137-92a7-a7770c25e8dd","timestamp":"2026-04-05T19:26:30.203Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_0147J5szqxPDz51Urxd6aKR5","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01QnX3eRw8aGcxGMRp2DSve8","name":"Bash","input":{"command":"cat > /tmp/loop-bench-elvty8os/tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"outDir\": \"./dist\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"skipLibCheck\": true\n },\n \"include\": [\"src/**/*.ts\"]\n}\nEOF","description":"Write tsconfig.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":7892,"cache_read_input_tokens":6267,"cache_creation":{"ephemeral_5m_input_tokens":7892,"ephemeral_1h_input_tokens":0},"output_tokens":36,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"aecb9d4d-3259-4eee-9be9-47f600dcf7ec"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01QnX3eRw8aGcxGMRp2DSve8","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"72349681-e24e-4e89-8382-74ad280de402","timestamp":"2026-04-05T19:26:33.818Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01TksEUxZxBJkeMCEj4ah6pF","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01T3yXq1tFDKx3tq9n9pBryX","name":"Bash","input":{"command":"npx tsc --noEmit 2>&1","description":"Type-check the TypeScript source"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":231,"cache_read_input_tokens":14159,"cache_creation":{"ephemeral_5m_input_tokens":231,"ephemeral_1h_input_tokens":0},"output_tokens":60,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"e91fd5db-72fa-435c-83cc-e788895e2829"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\nsrc/tetris.ts(643,62): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(643,95): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(651,76): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(652,37): error TS2503: Cannot find namespace 'NodeJS'.","is_error":true,"tool_use_id":"toolu_01T3yXq1tFDKx3tq9n9pBryX"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"593b0304-d752-4670-a921-9ace51d6c250","timestamp":"2026-04-05T19:26:35.985Z","tool_use_result":"Error: Exit code 2\nsrc/tetris.ts(643,62): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(643,95): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(651,76): error TS2503: Cannot find namespace 'NodeJS'.\nsrc/tetris.ts(652,37): error TS2503: Cannot find namespace 'NodeJS'."} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015yEJk4e31GujX7uXVGSKFi","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"I need to fix the NodeJS.Timeout types. Since this is a browser environment, I should use `ReturnType<typeof setTimeout>` and `ReturnType<typeof setInterval>` instead.","signature":"EuUCClsIDBgCKkBO6kPMIJVcvb+yRuS3D8jphDLoMZI7a4Hjn5yqURWeCzM/eNjZacn3iGGbPbUnUxVaVlTBFqMmCnIRmS9x/m6fMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgzbnoL6krUdXhLB294aDErDLYHUFQbERGVstCIw0Vx7htBkrQupzXKEbyYMDwCu2btxwVpI+YtWgfjDXWzS01yqoU9D6ekjiuITDo7WKrcBbyL3XGyEPGC79632XhENpiVBwt6WyfhDRI8YPk7nVAJjGdiZPWttZkglpKZLWgq00SjNvGYVOuV2BFdTZxRcENjBh3osjQYBTdDMn0ElbHlffX8Cn3CcSdpLLsM7werO7drpg1bTjIlC/ggOc4BkGkOa2rQB414T/xDzX/O3ajz+IfhTaUB77VgNz0irNPyAWRODRUteShAdbrGPxSPCbNuVHugcRV+QMWFQuJMCsqChfKoEgatqGAE="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":214,"cache_read_input_tokens":14390,"cache_creation":{"ephemeral_5m_input_tokens":214,"ephemeral_1h_input_tokens":0},"output_tokens":30,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"ad39efba-fb8d-47a3-9237-8828de8f384c"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_015yEJk4e31GujX7uXVGSKFi","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_013QmU78bALnYGLC2zZAru4t","name":"Read","input":{"file_path":"/tmp/loop-bench-elvty8os/src/tetris.ts","offset":638,"limit":20},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":214,"cache_read_input_tokens":14390,"cache_creation":{"ephemeral_5m_input_tokens":214,"ephemeral_1h_input_tokens":0},"output_tokens":30,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"e204e7e5-2060-4e7f-a91a-5dd1c8904a0f"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_013QmU78bALnYGLC2zZAru4t","type":"tool_result","content":"638\t\n639\t private bindKeys(): void {\n640\t // DAS (Delayed Auto Shift) state\n641\t const DAS_DELAY = 170;\n642\t const DAS_RATE = 50;\n643\t const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n644\t\n645\t const startDAS = (key: string, fn: () => void) => {\n646\t if (dasState[key]?.active) return;\n647\t fn();\n648\t dasState[key] = {\n649\t active: true,\n650\t timer: setTimeout(() => {\n651\t dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n652\t }, DAS_DELAY) as unknown as NodeJS.Timeout,\n653\t interval: null,\n654\t };\n655\t };\n656\t\n657\t const stopDAS = (key: string) => {"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"c01067a1-ec06-4fe1-80b8-4b92bec5d17a","timestamp":"2026-04-05T19:26:38.427Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-elvty8os/src/tetris.ts","content":"\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n }, DAS_DELAY) as unknown as NodeJS.Timeout,\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {","numLines":20,"startLine":638,"totalLines":737}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01TsBMU6mLdVvzsuY2ooQwRj","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01JsADHBsnYTVWyV9xUn1GRB","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/src/tetris.ts","old_string":" const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n }, DAS_DELAY) as unknown as NodeJS.Timeout,\n interval: null,\n };\n };","new_string":" const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE);\n }, DAS_DELAY),\n interval: null,\n };\n };"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":435,"cache_read_input_tokens":14604,"cache_creation":{"ephemeral_5m_input_tokens":435,"ephemeral_1h_input_tokens":0},"output_tokens":63,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"78151b46-9476-476a-915a-c31b7439e108"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01JsADHBsnYTVWyV9xUn1GRB","type":"tool_result","content":"The file /tmp/loop-bench-elvty8os/src/tetris.ts has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"357b5f41-d452-40e7-b845-792dcef9dbfb","timestamp":"2026-04-05T19:26:43.125Z","tool_use_result":{"filePath":"/tmp/loop-bench-elvty8os/src/tetris.ts","oldString":" const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n }, DAS_DELAY) as unknown as NodeJS.Timeout,\n interval: null,\n };\n };","newString":" const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE);\n }, DAS_DELAY),\n interval: null,\n };\n };","originalFile":"// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Matrix = number[][];\ntype Color = string;\n\ninterface Piece {\n matrix: Matrix;\n color: Color;\n x: number;\n y: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n color: string;\n size: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px per cell\nconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\nconst TOTAL_ROWS = ROWS + HIDDEN;\n\nconst COLORS: Record<string, Color> = {\n I: \"#00d4ff\",\n O: \"#ffd700\",\n T: \"#bf5fff\",\n S: \"#39d353\",\n Z: \"#ff4d4d\",\n J: \"#4d79ff\",\n L: \"#ff9900\",\n};\n\nconst TETROMINOES: Record<string, Matrix> = {\n I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n O: [[1,1],[1,1]],\n T: [[0,1,0],[1,1,1],[0,0,0]],\n S: [[0,1,1],[1,1,0],[0,0,0]],\n Z: [[1,1,0],[0,1,1],[0,0,0]],\n J: [[1,0,0],[1,1,1],[0,0,0]],\n L: [[0,0,1],[1,1,1],[0,0,0]],\n};\n\n// Scoring per lines cleared (multiplied by level)\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n\n// Drop interval in ms at each level (capped at level 20)\nfunction levelInterval(level: number): number {\n return Math.max(50, 1000 - (level - 1) * 47);\n}\n\n// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n\n// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\nconst KICKS_JLSTZ: [number,number][][] = [\n // 0→1\n [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n // 1→2\n [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n // 2→3\n [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n // 3→0\n [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n];\n\n// Kick table for I piece\nconst KICKS_I: [number,number][][] = [\n // 0→1\n [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n // 1→2\n [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n // 2→3\n [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n // 3→0\n [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n];\n\n// ─── Utility ──────────────────────────────────────────────────────────────────\n\nfunction rotateCW(m: Matrix): Matrix {\n const rows = m.length, cols = m[0].length;\n return Array.from({ length: cols }, (_, c) =>\n Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n );\n}\n\nfunction rotateCCW(m: Matrix): Matrix {\n return rotateCW(rotateCW(rotateCW(m)));\n}\n\n// ─── Board ────────────────────────────────────────────────────────────────────\n\nclass Board {\n grid: Color[][];\n\n constructor() {\n this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n }\n\n isValid(piece: Piece): boolean {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const x = piece.x + c;\n const y = piece.y + r;\n if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n if (y >= 0 && this.grid[y][x]) return false;\n }\n }\n return true;\n }\n\n lock(piece: Piece): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const y = piece.y + r;\n const x = piece.x + c;\n if (y >= 0) this.grid[y][x] = piece.color;\n }\n }\n }\n\n clearLines(): number {\n const cleared: number[] = [];\n for (let r = 0; r < TOTAL_ROWS; r++) {\n if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n }\n for (const r of cleared) {\n this.grid.splice(r, 1);\n this.grid.unshift(Array(COLS).fill(\"\"));\n }\n return cleared.length;\n }\n\n getGhostY(piece: Piece): number {\n let gy = piece.y;\n while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n return gy;\n }\n}\n\n// ─── Random Bag ──────────────────────────────────────────────────────────────\n\nclass Bag {\n private queue: string[] = [];\n\n private refill(): void {\n const keys = Object.keys(TETROMINOES);\n for (let i = keys.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [keys[i], keys[j]] = [keys[j], keys[i]];\n }\n this.queue.push(...keys);\n }\n\n next(): string {\n if (this.queue.length < 5) this.refill();\n return this.queue.shift()!;\n }\n\n peek(n: number): string[] {\n while (this.queue.length < n + 5) this.refill();\n return this.queue.slice(0, n);\n }\n}\n\n// ─── Tetris Game ─────────────────────────────────────────────────────────────\n\nclass Tetris {\n // Canvases\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private holdCanvas: HTMLCanvasElement;\n private holdCtx: CanvasRenderingContext2D;\n\n // Game state\n private board: Board;\n private bag: Bag;\n private current!: Piece;\n private holdKey: string | null = null;\n private holdUsed: boolean = false;\n private rotation: number = 0; // 0..3\n private score: number = 0;\n private lines: number = 0;\n private level: number = 1;\n private gameOver: boolean = false;\n private paused: boolean = false;\n private started: boolean = false;\n\n // Timers\n private dropTimer: number = 0;\n private lastTime: number = 0;\n private rafId: number = 0;\n\n // Lock-delay\n private lockTimer: number = 0;\n private lockDelay: number = 500; // ms\n private lockMoves: number = 0;\n private maxLockMoves: number = 15;\n private onGround: boolean = false;\n\n // Particles\n private particles: Particle[] = [];\n\n // DOM\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitle: HTMLElement;\n private overlayMsg: HTMLElement;\n\n constructor() {\n this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n this.ctx = this.canvas.getContext(\"2d\")!;\n this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n\n this.canvas.width = COLS * BLOCK;\n this.canvas.height = ROWS * BLOCK;\n\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitle = document.getElementById(\"overlay-title\")!;\n this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n\n this.board = new Board();\n this.bag = new Bag();\n\n this.bindKeys();\n this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n }\n\n // ── Spawn ────────────────────────────────────────────────────────────────\n\n private spawn(key: string): Piece {\n const matrix = TETROMINOES[key].map(r => [...r]);\n const color = COLORS[key];\n const x = Math.floor((COLS - matrix[0].length) / 2);\n const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n return { matrix, color, x, y };\n }\n\n private spawnNext(): void {\n const key = this.bag.next();\n this.current = this.spawn(key);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n\n if (!this.board.isValid(this.current)) {\n this.endGame();\n }\n }\n\n // ── Movement & Rotation ──────────────────────────────────────────────────\n\n private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }\n\n private rotate(dir: 1 | -1): void {\n const fromRot = this.rotation;\n const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n\n const isI = this.current.matrix.length === 4;\n const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n const kickIdx = dir === 1 ? fromRot : toRot;\n const kickSet = kicks[kickIdx];\n\n for (const [kx, ky] of kickSet) {\n const nx = this.current.x + (dir === 1 ? kx : -kx);\n const ny = this.current.y + (dir === 1 ? ky : -ky);\n const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n if (this.board.isValid(candidate)) {\n this.current = candidate;\n this.rotation = toRot;\n this.resetLockDelay();\n return;\n }\n }\n }\n\n private hardDrop(): void {\n const gy = this.board.getGhostY(this.current);\n const dropped = gy - this.current.y;\n this.score += dropped * 2;\n this.current = { ...this.current, y: gy };\n this.lockPiece();\n }\n\n private hold(): void {\n if (this.holdUsed) return;\n this.holdUsed = true;\n if (this.holdKey === null) {\n // Infer key by matching the color\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n this.holdKey = key;\n this.spawnNext();\n } else {\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n const prev = this.holdKey;\n this.holdKey = key;\n this.current = this.spawn(prev);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n }\n this.drawHold();\n }\n\n // ── Lock Delay ───────────────────────────────────────────────────────────\n\n private resetLockDelay(): void {\n if (this.onGround && this.lockMoves < this.maxLockMoves) {\n this.lockTimer = 0;\n this.lockMoves++;\n }\n }\n\n private lockPiece(): void {\n this.board.lock(this.current);\n const cleared = this.board.clearLines();\n\n if (cleared > 0) {\n this.spawnLineClearParticles(cleared);\n this.score += LINE_SCORES[cleared] * this.level;\n this.lines += cleared;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) this.level = newLevel;\n }\n\n this.holdUsed = false;\n this.updateHUD();\n this.spawnNext();\n }\n\n // ── Particles ────────────────────────────────────────────────────────────\n\n private spawnLineClearParticles(_count: number): void {\n const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n for (let i = 0; i < 80; i++) {\n this.particles.push({\n x: Math.random() * this.canvas.width,\n y: Math.random() * this.canvas.height,\n vx: (Math.random() - 0.5) * 6,\n vy: (Math.random() - 0.5) * 6,\n alpha: 1,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: Math.random() * 5 + 2,\n });\n }\n }\n\n // ── Game Loop ────────────────────────────────────────────────────────────\n\n private loop(time: number): void {\n const dt = Math.min(time - this.lastTime, 100);\n this.lastTime = time;\n\n if (!this.paused && !this.gameOver) {\n this.dropTimer += dt;\n\n const interval = levelInterval(this.level);\n if (this.dropTimer >= interval) {\n this.dropTimer = 0;\n const moved = this.move(0, 1);\n if (!moved) {\n this.onGround = true;\n }\n }\n\n // Lock delay\n const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n if (landedNow) {\n this.onGround = true;\n this.lockTimer += dt;\n if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n this.lockPiece();\n }\n } else {\n this.onGround = false;\n this.lockTimer = 0;\n }\n\n // Update particles\n this.particles = this.particles.filter(p => p.alpha > 0.02);\n for (const p of this.particles) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.15;\n p.alpha *= 0.93;\n }\n }\n\n this.draw();\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Start / Pause / End ──────────────────────────────────────────────────\n\n start(): void {\n if (this.started && !this.gameOver) {\n this.togglePause();\n return;\n }\n this.board = new Board();\n this.bag = new Bag();\n this.holdKey = null;\n this.holdUsed = false;\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.gameOver = false;\n this.paused = false;\n this.started = true;\n this.particles = [];\n this.spawnNext();\n this.updateHUD();\n this.hideOverlay();\n this.lastTime = performance.now();\n this.dropTimer = 0;\n cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n private togglePause(): void {\n this.paused = !this.paused;\n if (this.paused) {\n this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n } else {\n this.hideOverlay();\n this.lastTime = performance.now();\n }\n }\n\n private endGame(): void {\n this.gameOver = true;\n this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n }\n\n // ── Draw ─────────────────────────────────────────────────────────────────\n\n private draw(): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBackground();\n this.drawBoard();\n this.drawGhost();\n this.drawPiece(ctx, this.current, -HIDDEN);\n this.drawParticles();\n this.drawNext();\n this.drawHold();\n }\n\n private drawBackground(): void {\n const ctx = this.ctx;\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n ctx.lineWidth = 1;\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, this.canvas.height);\n ctx.stroke();\n }\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(this.canvas.width, r * BLOCK);\n ctx.stroke();\n }\n }\n\n private drawBoard(): void {\n const ctx = this.ctx;\n for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n const color = this.board.grid[r][c];\n if (color) {\n this.drawBlock(ctx, c, r - HIDDEN, color);\n }\n }\n }\n }\n\n private drawGhost(): void {\n const gy = this.board.getGhostY(this.current);\n if (gy === this.current.y) return;\n const ctx = this.ctx;\n ctx.globalAlpha = 0.25;\n const ghost: Piece = { ...this.current, y: gy };\n this.drawPiece(ctx, ghost, -HIDDEN);\n ctx.globalAlpha = 1;\n }\n\n private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const px = piece.x + c;\n const py = piece.y + r + yOffset;\n if (py < 0) continue;\n this.drawBlock(ctx, px, py, piece.color);\n }\n }\n }\n\n private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n const px = x * size;\n const py = y * size;\n const pad = size * 0.05;\n\n // Base fill\n ctx.fillStyle = color;\n ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n\n // Highlight (top-left)\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n\n // Shadow (bottom-right)\n ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n }\n\n private drawParticles(): void {\n const ctx = this.ctx;\n for (const p of this.particles) {\n ctx.globalAlpha = p.alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n\n private drawNext(): void {\n const ctx = this.nextCtx;\n const next3 = this.bag.peek(3);\n const cellW = 4;\n const cellH = 3;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n next3.forEach((key, idx) => {\n const matrix = TETROMINOES[key];\n const color = COLORS[key];\n const offX = Math.floor((cellW - matrix[0].length) / 2);\n const offY = Math.floor((cellH - matrix.length) / 2);\n const baseY = idx * cellH;\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n }\n }\n });\n }\n\n private drawHold(): void {\n const ctx = this.holdCtx;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n\n if (!this.holdKey) return;\n const matrix = TETROMINOES[this.holdKey];\n const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n const offX = Math.floor((4 - matrix[0].length) / 2);\n const offY = Math.floor((3 - matrix.length) / 2);\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n }\n }\n }\n\n // ── HUD ──────────────────────────────────────────────────────────────────\n\n private updateHUD(): void {\n this.scoreEl.textContent = this.score.toLocaleString();\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitle.textContent = title;\n this.overlayMsg.textContent = msg;\n this.overlayEl.classList.remove(\"hidden\");\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add(\"hidden\");\n }\n\n // ── Key Bindings ─────────────────────────────────────────────────────────\n\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;\n }, DAS_DELAY) as unknown as NodeJS.Timeout,\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {\n if (!dasState[key]) return;\n clearTimeout(dasState[key].timer!);\n clearInterval(dasState[key].interval!);\n dasState[key].active = false;\n };\n\n window.addEventListener(\"keydown\", (e) => {\n if (!this.started || this.gameOver) {\n if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n return;\n }\n\n switch (e.code) {\n case \"ArrowLeft\":\n e.preventDefault();\n startDAS(\"left\", () => {\n if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowRight\":\n e.preventDefault();\n startDAS(\"right\", () => {\n if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"KeyZ\":\n e.preventDefault();\n if (!this.paused) { this.rotate(-1); }\n break;\n case \"KeyX\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"Space\":\n e.preventDefault();\n if (this.paused) { this.togglePause(); return; }\n this.hardDrop();\n break;\n case \"KeyC\":\n case \"ShiftLeft\":\n case \"ShiftRight\":\n e.preventDefault();\n if (!this.paused) this.hold();\n break;\n case \"KeyP\":\n case \"Escape\":\n e.preventDefault();\n this.togglePause();\n break;\n case \"Enter\":\n e.preventDefault();\n if (this.paused) this.togglePause();\n break;\n }\n });\n\n window.addEventListener(\"keyup\", (e) => {\n if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n if (e.code === \"ArrowRight\") stopDAS(\"right\");\n if (e.code === \"ArrowDown\") stopDAS(\"down\");\n });\n }\n}\n\n// ─── Bootstrap ───────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new Tetris();\n});\n","structuredPatch":[{"oldStart":640,"oldLines":7,"newStart":640,"newLines":7,"lines":[" // DAS (Delayed Auto Shift) state"," const DAS_DELAY = 170;"," const DAS_RATE = 50;","- const dasState: Record<string, { active: boolean; timer: NodeJS.Timeout | null; interval: NodeJS.Timeout | null }> = {};","+ const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};"," "," const startDAS = (key: string, fn: () => void) => {"," if (dasState[key]?.active) return;"]},{"oldStart":648,"oldLines":8,"newStart":648,"newLines":8,"lines":[" dasState[key] = {"," active: true,"," timer: setTimeout(() => {","- dasState[key].interval = setInterval(fn, DAS_RATE) as unknown as NodeJS.Timeout;","- }, DAS_DELAY) as unknown as NodeJS.Timeout,","+ dasState[key].interval = setInterval(fn, DAS_RATE);","+ }, DAS_DELAY),"," interval: null,"," };"," };"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01BZMwnUQuXBcz9rqYhJeGDh","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XSGzZQmCCzjFsgtJv5bzgV","name":"Bash","input":{"command":"npx tsc --noEmit 2>&1","description":"Re-run type check"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":462,"cache_read_input_tokens":15039,"cache_creation":{"ephemeral_5m_input_tokens":462,"ephemeral_1h_input_tokens":0},"output_tokens":56,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"7f1cce98-6e3a-4c0b-ab80-1a5b7b8ef6c5"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01XSGzZQmCCzjFsgtJv5bzgV","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"871e5cbc-076d-426e-af60-2ee562129188","timestamp":"2026-04-05T19:26:45.214Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_019xmpa1TQAySKpyJC5rLghr","type":"message","role":"assistant","content":[{"type":"text","text":"Type-check passes. Now compile to JS and build the HTML:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":564,"cache_read_input_tokens":15039,"cache_creation":{"ephemeral_5m_input_tokens":564,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"1fffd8ec-9c48-48fc-a1c1-1d6d1189bf51"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_019xmpa1TQAySKpyJC5rLghr","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XCjvGXxT24nfnQ2TEoBXuo","name":"Bash","input":{"command":"mkdir -p /tmp/loop-bench-elvty8os/dist && npx tsc 2>&1","description":"Compile TypeScript to dist/"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":564,"cache_read_input_tokens":15039,"cache_creation":{"ephemeral_5m_input_tokens":564,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"6639b357-c64f-4271-bf4e-d51f9884dd3e"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\ntsconfig.json(9,5): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.\n Visit https://aka.ms/ts6 for migration information.","is_error":true,"tool_use_id":"toolu_01XCjvGXxT24nfnQ2TEoBXuo"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"4f8632ad-db94-4cae-8a39-52253e67f0e0","timestamp":"2026-04-05T19:26:47.927Z","tool_use_result":"Error: Exit code 2\ntsconfig.json(9,5): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.\n Visit https://aka.ms/ts6 for migration information."} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01WsBvqXWZUrbogP2qf5Ego5","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01PULSuKpybbQWskntUm2KX3","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/tsconfig.json","old_string":" \"outDir\": \"./dist\",","new_string":" \"outDir\": \"./dist\",\n \"rootDir\": \"./src\","},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":209,"cache_read_input_tokens":15603,"cache_creation":{"ephemeral_5m_input_tokens":209,"ephemeral_1h_input_tokens":0},"output_tokens":52,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"de47677a-32f0-44d5-8d7f-afb1cea6cec5"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>","is_error":true,"tool_use_id":"toolu_01PULSuKpybbQWskntUm2KX3"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"8451d38e-0fde-487e-a947-b13945b697fe","timestamp":"2026-04-05T19:26:49.993Z","tool_use_result":"Error: File has not been read yet. Read it first before writing to it."} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01BYi9P9xjwxDTjXqs4edNG1","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01VJWtBJFGTr6Br1bHDjCtwX","name":"Read","input":{"file_path":"/tmp/loop-bench-elvty8os/tsconfig.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":194,"cache_read_input_tokens":15812,"cache_creation":{"ephemeral_5m_input_tokens":194,"ephemeral_1h_input_tokens":0},"output_tokens":59,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"4eacd45b-f07b-40e7-a771-cd199241e94a"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01VJWtBJFGTr6Br1bHDjCtwX","type":"tool_result","content":"1\t{\n2\t \"compilerOptions\": {\n3\t \"target\": \"ES2020\",\n4\t \"module\": \"ESNext\",\n5\t \"moduleResolution\": \"bundler\",\n6\t \"strict\": true,\n7\t \"noUnusedLocals\": true,\n8\t \"noUnusedParameters\": true,\n9\t \"outDir\": \"./dist\",\n10\t \"lib\": [\"ES2020\", \"DOM\"],\n11\t \"skipLibCheck\": true\n12\t },\n13\t \"include\": [\"src/**/*.ts\"]\n14\t}\n15\t"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"be6ed41c-40d7-4bde-a96a-a59980db74bb","timestamp":"2026-04-05T19:26:52.150Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-elvty8os/tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"outDir\": \"./dist\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"skipLibCheck\": true\n },\n \"include\": [\"src/**/*.ts\"]\n}\n","numLines":15,"startLine":1,"totalLines":15}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_013GjcyJaFCxEwUv1DVAU1aQ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01PDSyk3T5tr6qihXvZiSAwt","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/tsconfig.json","old_string":" \"outDir\": \"./dist\",","new_string":" \"rootDir\": \"./src\",\n \"outDir\": \"./dist\","},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":226,"cache_read_input_tokens":16006,"cache_creation":{"ephemeral_5m_input_tokens":226,"ephemeral_1h_input_tokens":0},"output_tokens":62,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"573d026f-ad52-4a37-90b5-38a7440ed318"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01PDSyk3T5tr6qihXvZiSAwt","type":"tool_result","content":"The file /tmp/loop-bench-elvty8os/tsconfig.json has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"be32b81d-1aaf-4406-96b0-46e63bdbd66f","timestamp":"2026-04-05T19:26:53.891Z","tool_use_result":{"filePath":"/tmp/loop-bench-elvty8os/tsconfig.json","oldString":" \"outDir\": \"./dist\",","newString":" \"rootDir\": \"./src\",\n \"outDir\": \"./dist\",","originalFile":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"outDir\": \"./dist\",\n \"lib\": [\"ES2020\", \"DOM\"],\n \"skipLibCheck\": true\n },\n \"include\": [\"src/**/*.ts\"]\n}\n","structuredPatch":[{"oldStart":6,"oldLines":6,"newStart":6,"newLines":7,"lines":[" \"strict\": true,"," \"noUnusedLocals\": true,"," \"noUnusedParameters\": true,","+ \"rootDir\": \"./src\","," \"outDir\": \"./dist\","," \"lib\": [\"ES2020\", \"DOM\"],"," \"skipLibCheck\": true"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01VQQe9SPcXv4HK2K68xtPR6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Ma3AN16Xz41EV2Nx3pxZvD","name":"Bash","input":{"command":"npx tsc 2>&1 && ls /tmp/loop-bench-elvty8os/dist/","description":"Compile TypeScript and verify output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":182,"cache_read_input_tokens":16232,"cache_creation":{"ephemeral_5m_input_tokens":182,"ephemeral_1h_input_tokens":0},"output_tokens":41,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"4d846618-6fbd-49ad-b4b7-bb339a4ce48d"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Ma3AN16Xz41EV2Nx3pxZvD","type":"tool_result","content":"src\ntetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"a72df39a-02ea-4e48-81fe-944ef5f69c20","timestamp":"2026-04-05T19:26:56.164Z","tool_use_result":{"stdout":"src\ntetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01AMUWVPEjGZAAA4FJu6z8s3","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Hmm, it's creating `dist/src/tetris.js` instead of `dist/tetris.js`. Let me check the output path.","signature":"Ep8CClsIDBgCKkAB1gtkK48RCycdMhMC6zdwhGnHsLt6jQ3TM+KuUzIObrNJ2c5n942SCqvHrDABh4dsJR03x7NogKNidimxCI4IMhFjbGF1ZGUtc29ubmV0LTQtNjgAEgxcRThBrpM5K0boUjsaDN+bKw6WF4ib+fv1GiIwWQvzl4/Tlo/tE/ALqDoKdyiijpkLdN72OcqR+RL0L0AkYNUS+npdkhtI8mBKXW83KnKlf8a4TmxyD/+LsKErm6vD5py4ttCJ5H4P9ndGUpc5KgvLiukDdsUdLvmwMoKep4gz/g7ww7nsPQOUKCfy+r4u354HJpJjqD7qIbt+2yOnE8mBzZbmSGALWWorZ96YhvAzPwNQhLe9zk6ZsLElqDQEvH8YAQ=="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":117,"cache_read_input_tokens":16414,"cache_creation":{"ephemeral_5m_input_tokens":117,"ephemeral_1h_input_tokens":0},"output_tokens":48,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"526e70f8-266c-4961-aabc-5c7b3be95d0f"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01AMUWVPEjGZAAA4FJu6z8s3","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01GGVZ5qr3CqAZ2eU7yo7WVZ","name":"Bash","input":{"command":"find /tmp/loop-bench-elvty8os/dist -type f","description":"Find compiled output file"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":117,"cache_read_input_tokens":16414,"cache_creation":{"ephemeral_5m_input_tokens":117,"ephemeral_1h_input_tokens":0},"output_tokens":48,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"58bc6119-8e2a-4425-a569-51fd69bb5eff"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01GGVZ5qr3CqAZ2eU7yo7WVZ","type":"tool_result","content":"/tmp/loop-bench-elvty8os/dist/src/tetris.js\n/tmp/loop-bench-elvty8os/dist/tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"84f03af0-ccf6-4b90-949b-f3b86192c7d8","timestamp":"2026-04-05T19:26:58.511Z","tool_use_result":{"stdout":"/tmp/loop-bench-elvty8os/dist/src/tetris.js\n/tmp/loop-bench-elvty8os/dist/tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01L3MSMSVrVrWnEs6zXTjKG7","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Seems it compiled to both? Actually there might be an issue. Let me check:\n\nActually wait, the output file is at `dist/tetris.js` because I added `rootDir: ./src`. But there's also `dist/src/tetris.js`. Let me look at this more carefully. Actually, there seem to be two output files. One from a previous compilation (before I set rootDir) and one from the latest compilation. Let me just use the correct path and write the HTML to use `dist/tetris.js`.\n\nActually, looking at this again:\n\n\nI see what happened—the first `tsc` run failed with a rootDir error but still partially compiled, creating `dist/src/tetris.js`. After I updated the tsconfig and ran it again, I ended up with both files. The correct one is `dist/tetris.js`, so I should clean up the old output and verify the build is working properly.","signature":"Eu8HClsIDBgCKkAZjQ57v1MCQEFGsQqRtbF/xZKtAUN4itLlzq53VR6lluADeguB0n4Cb54zp/lcRl8sUT2BsPKS3vU1tTGi44o0MhFjbGF1ZGUtc29ubmV0LTQtNjgAEgyqLWu6ht1lJo0uvf8aDJRQvknRDVwhWYNFTSIwJ2R3hoBS29D6EaDnMsbY6of5t/IrmBWNGTzXRQmmBUxNZh9byDSmWKuJqkRM4xkXKsEGyYekBMc08ZD839oxaaC6puhsJn0dn36nMDO1YH9bKRp4CADgs3p2+uYWSEqgVpaYEuB4bxypVSCQr4+5xDIpH9v71DUjRPnF3oBlR6s3PwjJ/mlgKSwwlZ1M3K5eMRMCrLO3suRKDLGfbcczzPrHTblwj1pNOUaTl6q18wvmoZdoXpXlLA+v95Y/V2WiMToH1Z9hosAK2tflNtKGE7jXzxdByry5YZOWsFCYl47Z/GA8WnMpXmFgluikNho1q3AT1t/KyGvzYnZrygxhkJAqwpbWaKYrEi/pFC/jVpmffwkK8qt9z6B7+NgZtm9XeAQr++cZs9aiJAU7EPdrJjI544ZsGSEMLzkoBOBeVDqtsHEq7jtX1x9vkeH5/v5c3Mxbyb2vmVqjqlkqWZ6CRqv/qMKyJrX0yJBG0GP9syKH3e12So+hCzFOrqLmPmiR+K3+Fm/ht4jPBjeQrfQfcF8ppc+DBaoQxGe8dZ/PdWjOpx0relb2f08tLLfMYsXDQQxlfJKwqQ3VB06ZDlKOKpY4Kfl/OZSGJNPTUpb5aJgZj3bg18eb3Gl3JCtYwRndJzQqHjEIQZsW/Y1BA+V5+IADANKwue1kysW4ILU/2wYcLw6hYyE8E15RyELteimSfb8SlcVg1l87fANP37U7PZzrMlURpXHPsVwk7JNdf5cjC4xvYc5lga121+HsldFQG/5y8GzcgeafW21YsELkfGH2P4VaWf47R4f7znBHd8+4R21xzYwVax0m6HDaS8N2MepTJdSkEmMfJDKB3A0PdPX1h+EjEbua7a1pa8mtlT3mLxxPjcJ2sVaHscn6LWzeXNniwTDH/kS2B8776CNQC4ZZsYws8n8FE3D6ualT197lES+8574pPDw3BLprfsmg5+zVvLA9pmU3iQ2E9qcQB04mXtvpCbWZOftU6Umv/EuG9wjXwfueviOWqvA6UeKB/zfJPAbLK2gq9Eulk/ZeboQlWuGCern6JMMJmVcCV22X90O8bP7KDNkvLVT3TWjZe4Im4ZRFg0V0NyUGMO4MPwmzioGP3J8ektShRVWdZ0W24kS3OXOk2YyysoJNej/ukd7n1BKm1bcThw6BoyumcpmjOeQYAQ=="}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":187,"cache_read_input_tokens":16531,"cache_creation":{"ephemeral_5m_input_tokens":187,"ephemeral_1h_input_tokens":0},"output_tokens":9,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"aded08bd-ab0a-423a-af87-ba71d6db84ff"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01L3MSMSVrVrWnEs6zXTjKG7","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01RZzo6GiTfN2bHVG5My1tpN","name":"Bash","input":{"command":"rm -rf /tmp/loop-bench-elvty8os/dist && npx tsc 2>&1 && find /tmp/loop-bench-elvty8os/dist -type f","description":"Clean dist and recompile"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":187,"cache_read_input_tokens":16531,"cache_creation":{"ephemeral_5m_input_tokens":187,"ephemeral_1h_input_tokens":0},"output_tokens":9,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"655523fc-fab5-4f13-93de-4e2c8f4b2ad1"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01RZzo6GiTfN2bHVG5My1tpN","type":"tool_result","content":"/tmp/loop-bench-elvty8os/dist/tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"6656c51c-72eb-4cca-9c36-e0408b7bc6c7","timestamp":"2026-04-05T19:27:05.264Z","tool_use_result":{"stdout":"/tmp/loop-bench-elvty8os/dist/tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_014Mu5vXMPtXHeUSaFza4p3C","type":"message","role":"assistant","content":[{"type":"text","text":"Now write the HTML page:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":385,"cache_read_input_tokens":16718,"cache_creation":{"ephemeral_5m_input_tokens":385,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"82277f4c-6170-46d1-86f3-0eaf98a4d170"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_014Mu5vXMPtXHeUSaFza4p3C","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01LxumFU5J1eoKjHgoyskjsE","name":"Bash","input":{"command":"cat > /tmp/loop-bench-elvty8os/index.html << 'HTML_EOF'\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Tetris</title>\n <style>\n /* ── Reset & base ─────────────────────────────────────────────── */\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n body {\n background: #060610;\n color: #e0e0f0;\n font-family: \"Segoe UI\", system-ui, sans-serif;\n display: flex;\n flex-direction: column;\n align-items: center;\n min-height: 100vh;\n padding: 24px 16px;\n user-select: none;\n }\n\n h1 {\n font-size: 2.4rem;\n font-weight: 900;\n letter-spacing: 0.18em;\n text-transform: uppercase;\n background: linear-gradient(135deg, #00d4ff 0%, #bf5fff 50%, #ff9900 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 20px;\n }\n\n /* ── Layout ───────────────────────────────────────────────────── */\n .game-area {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n }\n\n /* ── Side panels ──────────────────────────────────────────────── */\n .side-panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 96px;\n }\n\n .panel-box {\n background: #12122a;\n border: 1px solid #2a2a50;\n border-radius: 10px;\n padding: 10px 12px;\n }\n\n .panel-label {\n font-size: 0.65rem;\n font-weight: 700;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: #7070a0;\n margin-bottom: 6px;\n }\n\n .panel-value {\n font-size: 1.45rem;\n font-weight: 800;\n color: #ffffff;\n letter-spacing: 0.04em;\n }\n\n canvas.preview {\n display: block;\n background: #0e0e1a;\n border-radius: 6px;\n image-rendering: pixelated;\n }\n\n /* ── Board wrapper ────────────────────────────────────────────── */\n .board-wrap {\n position: relative;\n border: 2px solid #2a2a50;\n border-radius: 8px;\n overflow: hidden;\n box-shadow:\n 0 0 0 1px #1a1a3a,\n 0 0 40px rgba(0, 212, 255, 0.08),\n 0 0 80px rgba(191, 95, 255, 0.05);\n }\n\n #board {\n display: block;\n image-rendering: pixelated;\n }\n\n /* ── Overlay ──────────────────────────────────────────────────── */\n #overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: rgba(6, 6, 20, 0.82);\n backdrop-filter: blur(4px);\n gap: 12px;\n text-align: center;\n padding: 24px;\n transition: opacity 0.15s;\n }\n\n #overlay.hidden {\n display: none;\n }\n\n #overlay-title {\n font-size: 2.8rem;\n font-weight: 900;\n letter-spacing: 0.14em;\n background: linear-gradient(90deg, #00d4ff, #bf5fff);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n }\n\n #overlay-msg {\n font-size: 0.9rem;\n color: #a0a0c0;\n white-space: pre-line;\n line-height: 1.6;\n }\n\n .start-btn {\n margin-top: 8px;\n padding: 10px 28px;\n font-size: 0.95rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n background: linear-gradient(135deg, #00d4ff, #bf5fff);\n color: #fff;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: transform 0.1s, box-shadow 0.1s;\n }\n\n .start-btn:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 20px rgba(0, 212, 255, 0.4);\n }\n\n .start-btn:active { transform: translateY(0); }\n\n /* ── Controls legend ──────────────────────────────────────────── */\n .controls {\n margin-top: 18px;\n display: grid;\n grid-template-columns: auto auto;\n column-gap: 20px;\n row-gap: 4px;\n font-size: 0.72rem;\n color: #6060a0;\n text-align: left;\n }\n\n .controls .key {\n font-family: monospace;\n background: #1e1e3a;\n border: 1px solid #2e2e50;\n border-radius: 4px;\n padding: 1px 6px;\n color: #a0a0d0;\n justify-self: end;\n }\n </style>\n</head>\n<body>\n <h1>Tetris</h1>\n\n <div class=\"game-area\">\n\n <!-- Left panel: Hold + Stats -->\n <div class=\"side-panel\" style=\"align-items: flex-end;\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Hold</div>\n <canvas id=\"hold\" class=\"preview\" width=\"88\" height=\"66\"></canvas>\n </div>\n <div class=\"panel-box\">\n <div class=\"panel-label\">Score</div>\n <div class=\"panel-value\" id=\"score\">0</div>\n </div>\n <div class=\"panel-box\">\n <div class=\"panel-label\">Lines</div>\n <div class=\"panel-value\" id=\"lines\">0</div>\n </div>\n <div class=\"panel-box\">\n <div class=\"panel-label\">Level</div>\n <div class=\"panel-value\" id=\"level\">1</div>\n </div>\n </div>\n\n <!-- Board -->\n <div class=\"board-wrap\">\n <canvas id=\"board\"></canvas>\n <div id=\"overlay\">\n <div id=\"overlay-title\">TETRIS</div>\n <div id=\"overlay-msg\">Press Space or Enter to start</div>\n <button class=\"start-btn\" id=\"start-btn\">Start Game</button>\n </div>\n </div>\n\n <!-- Right panel: Next -->\n <div class=\"side-panel\">\n <div class=\"panel-box\">\n <div class=\"panel-label\">Next</div>\n <canvas id=\"next\" class=\"preview\" width=\"88\" height=\"198\"></canvas>\n </div>\n\n <div class=\"panel-box\">\n <div class=\"panel-label\" style=\"margin-bottom:10px;\">Controls</div>\n <div class=\"controls\">\n <span class=\"key\">← →</span><span>Move</span>\n <span class=\"key\">↓</span><span>Soft drop</span>\n <span class=\"key\">Space</span><span>Hard drop</span>\n <span class=\"key\">↑ / X</span><span>Rotate CW</span>\n <span class=\"key\">Z</span><span>Rotate CCW</span>\n <span class=\"key\">C / ⇧</span><span>Hold</span>\n <span class=\"key\">P / Esc</span><span>Pause</span>\n </div>\n </div>\n </div>\n\n </div>\n\n <script type=\"module\" src=\"dist/tetris.js\"></script>\n <script>\n // Wire up the overlay start button\n document.getElementById(\"start-btn\").addEventListener(\"click\", () => {\n window.dispatchEvent(new KeyboardEvent(\"keydown\", { code: \"Space\", bubbles: true }));\n });\n </script>\n</body>\n</html>\nHTML_EOF","description":"Write the HTML page with full layout and styling"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":385,"cache_read_input_tokens":16718,"cache_creation":{"ephemeral_5m_input_tokens":385,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"0e5b5d7c-b14b-4541-bc98-230671f1a259"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01LxumFU5J1eoKjHgoyskjsE","type":"tool_result","content":"(Bash completed with no output)","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"a782fa82-01a7-40b6-84af-373aee006fe7","timestamp":"2026-04-05T19:27:34.091Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01QuhYUPNWVefBaPajXbELdi","type":"message","role":"assistant","content":[{"type":"text","text":"Now add a `build` script and verify the compiled JS looks correct:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":2429,"cache_read_input_tokens":17103,"cache_creation":{"ephemeral_5m_input_tokens":2429,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"91edd47e-ce53-4dd0-b2c4-1db4b1f17d82"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01QuhYUPNWVefBaPajXbELdi","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01QoiaBuv6BrJcj148uiBQts","name":"Read","input":{"file_path":"/tmp/loop-bench-elvty8os/package.json"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":2429,"cache_read_input_tokens":17103,"cache_creation":{"ephemeral_5m_input_tokens":2429,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"9eba6936-0045-4362-8c4b-50cd0598b59e"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01QoiaBuv6BrJcj148uiBQts","type":"tool_result","content":"File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"5d193f0a-4f2f-4c3d-9af6-dd60c6a4056b","timestamp":"2026-04-05T19:27:37.577Z","tool_use_result":{"type":"file_unchanged","file":{"filePath":"/tmp/loop-bench-elvty8os/package.json"}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_016s7VwWYYW1JXAYGhgrui4w","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_015NEuSBPDABXHQZmVFDWYGT","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/package.json","old_string":" \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","new_string":" \"scripts\": {\n \"build\": \"tsc\",\n \"watch\": \"tsc --watch\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":125,"cache_read_input_tokens":19532,"cache_creation":{"ephemeral_5m_input_tokens":125,"ephemeral_1h_input_tokens":0},"output_tokens":59,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"0760a93d-8b64-4f84-8d97-3ed3a8ef532a"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_015NEuSBPDABXHQZmVFDWYGT","type":"tool_result","content":"The file /tmp/loop-bench-elvty8os/package.json has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"58d48a3d-c341-4547-be52-697898ce955f","timestamp":"2026-04-05T19:27:40.075Z","tool_use_result":{"filePath":"/tmp/loop-bench-elvty8os/package.json","oldString":" \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","newString":" \"scripts\": {\n \"build\": \"tsc\",\n \"watch\": \"tsc --watch\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },","originalFile":"{\n \"name\": \"loop-bench-elvty8os\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"devDependencies\": {\n \"@eslint/js\": \"^10.0.1\",\n \"@playwright/test\": \"^1.59.1\",\n \"@types/node\": \"^25.5.2\",\n \"eslint\": \"^10.2.0\",\n \"typescript\": \"^6.0.2\"\n }\n}\n","structuredPatch":[{"oldStart":4,"oldLines":6,"newStart":4,"newLines":8,"lines":[" \"description\": \"\","," \"main\": \"index.js\","," \"scripts\": {","+ \"build\": \"tsc\",","+ \"watch\": \"tsc --watch\","," \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\""," },"," \"keywords\": [],"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01UsMZrFCrsUrMc9YrU4ivWD","type":"message","role":"assistant","content":[{"type":"text","text":"Let's do a final end-to-end sanity check — recompile from scratch and verify key pieces of the output:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":229,"cache_read_input_tokens":19657,"cache_creation":{"ephemeral_5m_input_tokens":229,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"cc06e7b9-055a-4cba-a241-a3b7a7799480"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01UsMZrFCrsUrMc9YrU4ivWD","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01PXgU5RsKpQBq1MRPvugkCL","name":"Bash","input":{"command":"rm -rf dist && npx tsc && wc -l dist/tetris.js && head -5 dist/tetris.js","description":"Clean build and inspect output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":229,"cache_read_input_tokens":19657,"cache_creation":{"ephemeral_5m_input_tokens":229,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"ac0947d2-d422-4ecc-adf7-2cc90a8eb29d"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01PXgU5RsKpQBq1MRPvugkCL","type":"tool_result","content":"646 dist/tetris.js\n\"use strict\";\n// ─── Types ───────────────────────────────────────────────────────────────────\n// ─── Constants ────────────────────────────────────────────────────────────────\nconst COLS = 10;\nconst ROWS = 20;","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"18979035-fefa-4254-907d-c8d7a6642019","timestamp":"2026-04-05T19:27:43.401Z","tool_use_result":{"stdout":"646 dist/tetris.js\n\"use strict\";\n// ─── Types ───────────────────────────────────────────────────────────────────\n// ─── Constants ────────────────────────────────────────────────────────────────\nconst COLS = 10;\nconst ROWS = 20;","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01MN1SuLqxAQoCfJQBoZA83n","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01XbmTWPfE4FvaMGLaNnWn8y","name":"Bash","input":{"command":"# Check the key functions are present in output\nfor sym in rotateCW rotateCCW Board Bag Tetris; do\n grep -c \"class $sym\\|function $sym\\|const $sym\" dist/tetris.js && echo \"$sym ✓\" || echo \"$sym MISSING\"\ndone","description":"Verify key symbols exist in compiled output"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":218,"cache_read_input_tokens":19886,"cache_creation":{"ephemeral_5m_input_tokens":218,"ephemeral_1h_input_tokens":0},"output_tokens":38,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"23777bde-ca2b-4219-9ab6-dccdc5e990b1"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01XbmTWPfE4FvaMGLaNnWn8y","type":"tool_result","content":"1\nrotateCW ✓\n1\nrotateCCW ✓\n1\nBoard ✓\n1\nBag ✓\n1\nTetris ✓","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"6ae8617d-4cfa-466e-97d6-95ec02482b37","timestamp":"2026-04-05T19:27:47.687Z","tool_use_result":{"stdout":"1\nrotateCW ✓\n1\nrotateCCW ✓\n1\nBoard ✓\n1\nBag ✓\n1\nTetris ✓","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NX49QZv5aoaEL2FQnKkfiU","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_0165nfuGhUahx5DXVikrhndZ","name":"Bash","input":{"command":"# Verify the full file structure looks right\nls -la /tmp/loop-bench-elvty8os/\nls -la /tmp/loop-bench-elvty8os/src/\nls -la /tmp/loop-bench-elvty8os/dist/","description":"Verify all project files are in place"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":204,"cache_read_input_tokens":20104,"cache_creation":{"ephemeral_5m_input_tokens":204,"ephemeral_1h_input_tokens":0},"output_tokens":40,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"71a2aeac-ed47-406d-a4cc-1297dfdfb91f"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_0165nfuGhUahx5DXVikrhndZ","type":"tool_result","content":"total 116\ndrwx------ 5 root root 4096 Apr 5 21:27 .\ndrwxrwxrwt 43 root root 45056 Apr 5 21:27 ..\ndrwxr-xr-x 2 root root 4096 Apr 5 21:27 dist\n-rw-r--r-- 1 root root 7082 Apr 5 21:27 index.html\ndrwxr-xr-x 66 root root 4096 Apr 5 21:23 node_modules\n-rw-r--r-- 1 root root 477 Apr 5 21:27 package.json\n-rw-r--r-- 1 root root 34409 Apr 5 21:23 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 5 21:26 src\n-rw-r--r-- 1 root root 327 Apr 5 21:26 tsconfig.json\ntotal 32\ndrwxr-xr-x 2 root root 4096 Apr 5 21:26 .\ndrwx------ 5 root root 4096 Apr 5 21:27 ..\n-rw-r--r-- 1 root root 23705 Apr 5 21:26 tetris.ts\ntotal 36\ndrwxr-xr-x 2 root root 4096 Apr 5 21:27 .\ndrwx------ 5 root root 4096 Apr 5 21:27 ..\n-rw-r--r-- 1 root root 24873 Apr 5 21:27 tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"331e4251-0cc5-4516-b1e1-8919d68d4a8c","timestamp":"2026-04-05T19:27:50.268Z","tool_use_result":{"stdout":"total 116\ndrwx------ 5 root root 4096 Apr 5 21:27 .\ndrwxrwxrwt 43 root root 45056 Apr 5 21:27 ..\ndrwxr-xr-x 2 root root 4096 Apr 5 21:27 dist\n-rw-r--r-- 1 root root 7082 Apr 5 21:27 index.html\ndrwxr-xr-x 66 root root 4096 Apr 5 21:23 node_modules\n-rw-r--r-- 1 root root 477 Apr 5 21:27 package.json\n-rw-r--r-- 1 root root 34409 Apr 5 21:23 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 5 21:26 src\n-rw-r--r-- 1 root root 327 Apr 5 21:26 tsconfig.json\ntotal 32\ndrwxr-xr-x 2 root root 4096 Apr 5 21:26 .\ndrwx------ 5 root root 4096 Apr 5 21:27 ..\n-rw-r--r-- 1 root root 23705 Apr 5 21:26 tetris.ts\ntotal 36\ndrwxr-xr-x 2 root root 4096 Apr 5 21:27 .\ndrwx------ 5 root root 4096 Apr 5 21:27 ..\n-rw-r--r-- 1 root root 24873 Apr 5 21:27 tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_016L7f4RzgBqNB6L7yNbMb2R","type":"message","role":"assistant","content":[{"type":"text","text":"Everything compiles cleanly. Let me do one final review of the full TypeScript source to make sure all mechanics are solid:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":577,"cache_read_input_tokens":20308,"cache_creation":{"ephemeral_5m_input_tokens":577,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"28daaed5-dd6c-4cbb-965f-1c39b452af58"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_016L7f4RzgBqNB6L7yNbMb2R","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01DkU5iP5JVbQy8YzD1iiaT4","name":"Read","input":{"file_path":"/tmp/loop-bench-elvty8os/src/tetris.ts"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":577,"cache_read_input_tokens":20308,"cache_creation":{"ephemeral_5m_input_tokens":577,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"5d181242-f0cd-4743-8d4a-244642d6b96c"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01DkU5iP5JVbQy8YzD1iiaT4","type":"tool_result","content":"1\t// ─── Types ───────────────────────────────────────────────────────────────────\n2\t\n3\ttype Matrix = number[][];\n4\ttype Color = string;\n5\t\n6\tinterface Piece {\n7\t matrix: Matrix;\n8\t color: Color;\n9\t x: number;\n10\t y: number;\n11\t}\n12\t\n13\tinterface Particle {\n14\t x: number;\n15\t y: number;\n16\t vx: number;\n17\t vy: number;\n18\t alpha: number;\n19\t color: string;\n20\t size: number;\n21\t}\n22\t\n23\t// ─── Constants ────────────────────────────────────────────────────────────────\n24\t\n25\tconst COLS = 10;\n26\tconst ROWS = 20;\n27\tconst BLOCK = 32; // px per cell\n28\tconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\n29\tconst TOTAL_ROWS = ROWS + HIDDEN;\n30\t\n31\tconst COLORS: Record<string, Color> = {\n32\t I: \"#00d4ff\",\n33\t O: \"#ffd700\",\n34\t T: \"#bf5fff\",\n35\t S: \"#39d353\",\n36\t Z: \"#ff4d4d\",\n37\t J: \"#4d79ff\",\n38\t L: \"#ff9900\",\n39\t};\n40\t\n41\tconst TETROMINOES: Record<string, Matrix> = {\n42\t I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n43\t O: [[1,1],[1,1]],\n44\t T: [[0,1,0],[1,1,1],[0,0,0]],\n45\t S: [[0,1,1],[1,1,0],[0,0,0]],\n46\t Z: [[1,1,0],[0,1,1],[0,0,0]],\n47\t J: [[1,0,0],[1,1,1],[0,0,0]],\n48\t L: [[0,0,1],[1,1,1],[0,0,0]],\n49\t};\n50\t\n51\t// Scoring per lines cleared (multiplied by level)\n52\tconst LINE_SCORES = [0, 100, 300, 500, 800];\n53\t\n54\t// Drop interval in ms at each level (capped at level 20)\n55\tfunction levelInterval(level: number): number {\n56\t return Math.max(50, 1000 - (level - 1) * 47);\n57\t}\n58\t\n59\t// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n60\t\n61\t// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\n62\tconst KICKS_JLSTZ: [number,number][][] = [\n63\t // 0→1\n64\t [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n65\t // 1→2\n66\t [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n67\t // 2→3\n68\t [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n69\t // 3→0\n70\t [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n71\t];\n72\t\n73\t// Kick table for I piece\n74\tconst KICKS_I: [number,number][][] = [\n75\t // 0→1\n76\t [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n77\t // 1→2\n78\t [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n79\t // 2→3\n80\t [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n81\t // 3→0\n82\t [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n83\t];\n84\t\n85\t// ─── Utility ──────────────────────────────────────────────────────────────────\n86\t\n87\tfunction rotateCW(m: Matrix): Matrix {\n88\t const rows = m.length, cols = m[0].length;\n89\t return Array.from({ length: cols }, (_, c) =>\n90\t Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n91\t );\n92\t}\n93\t\n94\tfunction rotateCCW(m: Matrix): Matrix {\n95\t return rotateCW(rotateCW(rotateCW(m)));\n96\t}\n97\t\n98\t// ─── Board ────────────────────────────────────────────────────────────────────\n99\t\n100\tclass Board {\n101\t grid: Color[][];\n102\t\n103\t constructor() {\n104\t this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n105\t }\n106\t\n107\t isValid(piece: Piece): boolean {\n108\t for (let r = 0; r < piece.matrix.length; r++) {\n109\t for (let c = 0; c < piece.matrix[r].length; c++) {\n110\t if (!piece.matrix[r][c]) continue;\n111\t const x = piece.x + c;\n112\t const y = piece.y + r;\n113\t if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n114\t if (y >= 0 && this.grid[y][x]) return false;\n115\t }\n116\t }\n117\t return true;\n118\t }\n119\t\n120\t lock(piece: Piece): void {\n121\t for (let r = 0; r < piece.matrix.length; r++) {\n122\t for (let c = 0; c < piece.matrix[r].length; c++) {\n123\t if (!piece.matrix[r][c]) continue;\n124\t const y = piece.y + r;\n125\t const x = piece.x + c;\n126\t if (y >= 0) this.grid[y][x] = piece.color;\n127\t }\n128\t }\n129\t }\n130\t\n131\t clearLines(): number {\n132\t const cleared: number[] = [];\n133\t for (let r = 0; r < TOTAL_ROWS; r++) {\n134\t if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n135\t }\n136\t for (const r of cleared) {\n137\t this.grid.splice(r, 1);\n138\t this.grid.unshift(Array(COLS).fill(\"\"));\n139\t }\n140\t return cleared.length;\n141\t }\n142\t\n143\t getGhostY(piece: Piece): number {\n144\t let gy = piece.y;\n145\t while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n146\t return gy;\n147\t }\n148\t}\n149\t\n150\t// ─── Random Bag ──────────────────────────────────────────────────────────────\n151\t\n152\tclass Bag {\n153\t private queue: string[] = [];\n154\t\n155\t private refill(): void {\n156\t const keys = Object.keys(TETROMINOES);\n157\t for (let i = keys.length - 1; i > 0; i--) {\n158\t const j = Math.floor(Math.random() * (i + 1));\n159\t [keys[i], keys[j]] = [keys[j], keys[i]];\n160\t }\n161\t this.queue.push(...keys);\n162\t }\n163\t\n164\t next(): string {\n165\t if (this.queue.length < 5) this.refill();\n166\t return this.queue.shift()!;\n167\t }\n168\t\n169\t peek(n: number): string[] {\n170\t while (this.queue.length < n + 5) this.refill();\n171\t return this.queue.slice(0, n);\n172\t }\n173\t}\n174\t\n175\t// ─── Tetris Game ─────────────────────────────────────────────────────────────\n176\t\n177\tclass Tetris {\n178\t // Canvases\n179\t private canvas: HTMLCanvasElement;\n180\t private ctx: CanvasRenderingContext2D;\n181\t private nextCanvas: HTMLCanvasElement;\n182\t private nextCtx: CanvasRenderingContext2D;\n183\t private holdCanvas: HTMLCanvasElement;\n184\t private holdCtx: CanvasRenderingContext2D;\n185\t\n186\t // Game state\n187\t private board: Board;\n188\t private bag: Bag;\n189\t private current!: Piece;\n190\t private holdKey: string | null = null;\n191\t private holdUsed: boolean = false;\n192\t private rotation: number = 0; // 0..3\n193\t private score: number = 0;\n194\t private lines: number = 0;\n195\t private level: number = 1;\n196\t private gameOver: boolean = false;\n197\t private paused: boolean = false;\n198\t private started: boolean = false;\n199\t\n200\t // Timers\n201\t private dropTimer: number = 0;\n202\t private lastTime: number = 0;\n203\t private rafId: number = 0;\n204\t\n205\t // Lock-delay\n206\t private lockTimer: number = 0;\n207\t private lockDelay: number = 500; // ms\n208\t private lockMoves: number = 0;\n209\t private maxLockMoves: number = 15;\n210\t private onGround: boolean = false;\n211\t\n212\t // Particles\n213\t private particles: Particle[] = [];\n214\t\n215\t // DOM\n216\t private scoreEl: HTMLElement;\n217\t private linesEl: HTMLElement;\n218\t private levelEl: HTMLElement;\n219\t private overlayEl: HTMLElement;\n220\t private overlayTitle: HTMLElement;\n221\t private overlayMsg: HTMLElement;\n222\t\n223\t constructor() {\n224\t this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n225\t this.ctx = this.canvas.getContext(\"2d\")!;\n226\t this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n227\t this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n228\t this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n229\t this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n230\t\n231\t this.canvas.width = COLS * BLOCK;\n232\t this.canvas.height = ROWS * BLOCK;\n233\t\n234\t this.scoreEl = document.getElementById(\"score\")!;\n235\t this.linesEl = document.getElementById(\"lines\")!;\n236\t this.levelEl = document.getElementById(\"level\")!;\n237\t this.overlayEl = document.getElementById(\"overlay\")!;\n238\t this.overlayTitle = document.getElementById(\"overlay-title\")!;\n239\t this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n240\t\n241\t this.board = new Board();\n242\t this.bag = new Bag();\n243\t\n244\t this.bindKeys();\n245\t this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n246\t }\n247\t\n248\t // ── Spawn ────────────────────────────────────────────────────────────────\n249\t\n250\t private spawn(key: string): Piece {\n251\t const matrix = TETROMINOES[key].map(r => [...r]);\n252\t const color = COLORS[key];\n253\t const x = Math.floor((COLS - matrix[0].length) / 2);\n254\t const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n255\t return { matrix, color, x, y };\n256\t }\n257\t\n258\t private spawnNext(): void {\n259\t const key = this.bag.next();\n260\t this.current = this.spawn(key);\n261\t this.rotation = 0;\n262\t this.lockTimer = 0;\n263\t this.lockMoves = 0;\n264\t this.onGround = false;\n265\t\n266\t if (!this.board.isValid(this.current)) {\n267\t this.endGame();\n268\t }\n269\t }\n270\t\n271\t // ── Movement & Rotation ──────────────────────────────────────────────────\n272\t\n273\t private move(dx: number, dy: number): boolean {\n274\t const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n275\t if (!this.board.isValid(next)) return false;\n276\t this.current = next;\n277\t if (dy > 0 && this.score > 0 && dx === 0) {\n278\t // soft drop bonus\n279\t this.score += 1;\n280\t this.updateHUD();\n281\t }\n282\t return true;\n283\t }\n284\t\n285\t private rotate(dir: 1 | -1): void {\n286\t const fromRot = this.rotation;\n287\t const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n288\t const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n289\t\n290\t const isI = this.current.matrix.length === 4;\n291\t const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n292\t const kickIdx = dir === 1 ? fromRot : toRot;\n293\t const kickSet = kicks[kickIdx];\n294\t\n295\t for (const [kx, ky] of kickSet) {\n296\t const nx = this.current.x + (dir === 1 ? kx : -kx);\n297\t const ny = this.current.y + (dir === 1 ? ky : -ky);\n298\t const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n299\t if (this.board.isValid(candidate)) {\n300\t this.current = candidate;\n301\t this.rotation = toRot;\n302\t this.resetLockDelay();\n303\t return;\n304\t }\n305\t }\n306\t }\n307\t\n308\t private hardDrop(): void {\n309\t const gy = this.board.getGhostY(this.current);\n310\t const dropped = gy - this.current.y;\n311\t this.score += dropped * 2;\n312\t this.current = { ...this.current, y: gy };\n313\t this.lockPiece();\n314\t }\n315\t\n316\t private hold(): void {\n317\t if (this.holdUsed) return;\n318\t this.holdUsed = true;\n319\t if (this.holdKey === null) {\n320\t // Infer key by matching the color\n321\t const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n322\t this.holdKey = key;\n323\t this.spawnNext();\n324\t } else {\n325\t const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n326\t const prev = this.holdKey;\n327\t this.holdKey = key;\n328\t this.current = this.spawn(prev);\n329\t this.rotation = 0;\n330\t this.lockTimer = 0;\n331\t this.lockMoves = 0;\n332\t this.onGround = false;\n333\t }\n334\t this.drawHold();\n335\t }\n336\t\n337\t // ── Lock Delay ───────────────────────────────────────────────────────────\n338\t\n339\t private resetLockDelay(): void {\n340\t if (this.onGround && this.lockMoves < this.maxLockMoves) {\n341\t this.lockTimer = 0;\n342\t this.lockMoves++;\n343\t }\n344\t }\n345\t\n346\t private lockPiece(): void {\n347\t this.board.lock(this.current);\n348\t const cleared = this.board.clearLines();\n349\t\n350\t if (cleared > 0) {\n351\t this.spawnLineClearParticles(cleared);\n352\t this.score += LINE_SCORES[cleared] * this.level;\n353\t this.lines += cleared;\n354\t const newLevel = Math.floor(this.lines / 10) + 1;\n355\t if (newLevel > this.level) this.level = newLevel;\n356\t }\n357\t\n358\t this.holdUsed = false;\n359\t this.updateHUD();\n360\t this.spawnNext();\n361\t }\n362\t\n363\t // ── Particles ────────────────────────────────────────────────────────────\n364\t\n365\t private spawnLineClearParticles(_count: number): void {\n366\t const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n367\t for (let i = 0; i < 80; i++) {\n368\t this.particles.push({\n369\t x: Math.random() * this.canvas.width,\n370\t y: Math.random() * this.canvas.height,\n371\t vx: (Math.random() - 0.5) * 6,\n372\t vy: (Math.random() - 0.5) * 6,\n373\t alpha: 1,\n374\t color: colors[Math.floor(Math.random() * colors.length)],\n375\t size: Math.random() * 5 + 2,\n376\t });\n377\t }\n378\t }\n379\t\n380\t // ── Game Loop ────────────────────────────────────────────────────────────\n381\t\n382\t private loop(time: number): void {\n383\t const dt = Math.min(time - this.lastTime, 100);\n384\t this.lastTime = time;\n385\t\n386\t if (!this.paused && !this.gameOver) {\n387\t this.dropTimer += dt;\n388\t\n389\t const interval = levelInterval(this.level);\n390\t if (this.dropTimer >= interval) {\n391\t this.dropTimer = 0;\n392\t const moved = this.move(0, 1);\n393\t if (!moved) {\n394\t this.onGround = true;\n395\t }\n396\t }\n397\t\n398\t // Lock delay\n399\t const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n400\t if (landedNow) {\n401\t this.onGround = true;\n402\t this.lockTimer += dt;\n403\t if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n404\t this.lockPiece();\n405\t }\n406\t } else {\n407\t this.onGround = false;\n408\t this.lockTimer = 0;\n409\t }\n410\t\n411\t // Update particles\n412\t this.particles = this.particles.filter(p => p.alpha > 0.02);\n413\t for (const p of this.particles) {\n414\t p.x += p.vx;\n415\t p.y += p.vy;\n416\t p.vy += 0.15;\n417\t p.alpha *= 0.93;\n418\t }\n419\t }\n420\t\n421\t this.draw();\n422\t this.rafId = requestAnimationFrame(t => this.loop(t));\n423\t }\n424\t\n425\t // ── Start / Pause / End ──────────────────────────────────────────────────\n426\t\n427\t start(): void {\n428\t if (this.started && !this.gameOver) {\n429\t this.togglePause();\n430\t return;\n431\t }\n432\t this.board = new Board();\n433\t this.bag = new Bag();\n434\t this.holdKey = null;\n435\t this.holdUsed = false;\n436\t this.score = 0;\n437\t this.lines = 0;\n438\t this.level = 1;\n439\t this.gameOver = false;\n440\t this.paused = false;\n441\t this.started = true;\n442\t this.particles = [];\n443\t this.spawnNext();\n444\t this.updateHUD();\n445\t this.hideOverlay();\n446\t this.lastTime = performance.now();\n447\t this.dropTimer = 0;\n448\t cancelAnimationFrame(this.rafId);\n449\t this.rafId = requestAnimationFrame(t => this.loop(t));\n450\t }\n451\t\n452\t private togglePause(): void {\n453\t this.paused = !this.paused;\n454\t if (this.paused) {\n455\t this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n456\t } else {\n457\t this.hideOverlay();\n458\t this.lastTime = performance.now();\n459\t }\n460\t }\n461\t\n462\t private endGame(): void {\n463\t this.gameOver = true;\n464\t this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n465\t }\n466\t\n467\t // ── Draw ─────────────────────────────────────────────────────────────────\n468\t\n469\t private draw(): void {\n470\t const ctx = this.ctx;\n471\t ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n472\t\n473\t this.drawBackground();\n474\t this.drawBoard();\n475\t this.drawGhost();\n476\t this.drawPiece(ctx, this.current, -HIDDEN);\n477\t this.drawParticles();\n478\t this.drawNext();\n479\t this.drawHold();\n480\t }\n481\t\n482\t private drawBackground(): void {\n483\t const ctx = this.ctx;\n484\t ctx.fillStyle = \"#0e0e1a\";\n485\t ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n486\t\n487\t // Grid lines\n488\t ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n489\t ctx.lineWidth = 1;\n490\t for (let c = 0; c <= COLS; c++) {\n491\t ctx.beginPath();\n492\t ctx.moveTo(c * BLOCK, 0);\n493\t ctx.lineTo(c * BLOCK, this.canvas.height);\n494\t ctx.stroke();\n495\t }\n496\t for (let r = 0; r <= ROWS; r++) {\n497\t ctx.beginPath();\n498\t ctx.moveTo(0, r * BLOCK);\n499\t ctx.lineTo(this.canvas.width, r * BLOCK);\n500\t ctx.stroke();\n501\t }\n502\t }\n503\t\n504\t private drawBoard(): void {\n505\t const ctx = this.ctx;\n506\t for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n507\t for (let c = 0; c < COLS; c++) {\n508\t const color = this.board.grid[r][c];\n509\t if (color) {\n510\t this.drawBlock(ctx, c, r - HIDDEN, color);\n511\t }\n512\t }\n513\t }\n514\t }\n515\t\n516\t private drawGhost(): void {\n517\t const gy = this.board.getGhostY(this.current);\n518\t if (gy === this.current.y) return;\n519\t const ctx = this.ctx;\n520\t ctx.globalAlpha = 0.25;\n521\t const ghost: Piece = { ...this.current, y: gy };\n522\t this.drawPiece(ctx, ghost, -HIDDEN);\n523\t ctx.globalAlpha = 1;\n524\t }\n525\t\n526\t private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n527\t for (let r = 0; r < piece.matrix.length; r++) {\n528\t for (let c = 0; c < piece.matrix[r].length; c++) {\n529\t if (!piece.matrix[r][c]) continue;\n530\t const px = piece.x + c;\n531\t const py = piece.y + r + yOffset;\n532\t if (py < 0) continue;\n533\t this.drawBlock(ctx, px, py, piece.color);\n534\t }\n535\t }\n536\t }\n537\t\n538\t private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n539\t const px = x * size;\n540\t const py = y * size;\n541\t const pad = size * 0.05;\n542\t\n543\t // Base fill\n544\t ctx.fillStyle = color;\n545\t ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n546\t\n547\t // Highlight (top-left)\n548\t ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n549\t ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n550\t ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n551\t\n552\t // Shadow (bottom-right)\n553\t ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n554\t ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n555\t ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n556\t }\n557\t\n558\t private drawParticles(): void {\n559\t const ctx = this.ctx;\n560\t for (const p of this.particles) {\n561\t ctx.globalAlpha = p.alpha;\n562\t ctx.fillStyle = p.color;\n563\t ctx.beginPath();\n564\t ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n565\t ctx.fill();\n566\t }\n567\t ctx.globalAlpha = 1;\n568\t }\n569\t\n570\t private drawNext(): void {\n571\t const ctx = this.nextCtx;\n572\t const next3 = this.bag.peek(3);\n573\t const cellW = 4;\n574\t const cellH = 3;\n575\t const bSize = 22;\n576\t\n577\t ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n578\t ctx.fillStyle = \"#0e0e1a\";\n579\t ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n580\t\n581\t next3.forEach((key, idx) => {\n582\t const matrix = TETROMINOES[key];\n583\t const color = COLORS[key];\n584\t const offX = Math.floor((cellW - matrix[0].length) / 2);\n585\t const offY = Math.floor((cellH - matrix.length) / 2);\n586\t const baseY = idx * cellH;\n587\t\n588\t for (let r = 0; r < matrix.length; r++) {\n589\t for (let c = 0; c < matrix[r].length; c++) {\n590\t if (!matrix[r][c]) continue;\n591\t this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n592\t }\n593\t }\n594\t });\n595\t }\n596\t\n597\t private drawHold(): void {\n598\t const ctx = this.holdCtx;\n599\t const bSize = 22;\n600\t\n601\t ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n602\t ctx.fillStyle = \"#0e0e1a\";\n603\t ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n604\t\n605\t if (!this.holdKey) return;\n606\t const matrix = TETROMINOES[this.holdKey];\n607\t const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n608\t const offX = Math.floor((4 - matrix[0].length) / 2);\n609\t const offY = Math.floor((3 - matrix.length) / 2);\n610\t\n611\t for (let r = 0; r < matrix.length; r++) {\n612\t for (let c = 0; c < matrix[r].length; c++) {\n613\t if (!matrix[r][c]) continue;\n614\t this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n615\t }\n616\t }\n617\t }\n618\t\n619\t // ── HUD ──────────────────────────────────────────────────────────────────\n620\t\n621\t private updateHUD(): void {\n622\t this.scoreEl.textContent = this.score.toLocaleString();\n623\t this.linesEl.textContent = String(this.lines);\n624\t this.levelEl.textContent = String(this.level);\n625\t }\n626\t\n627\t private showOverlay(title: string, msg: string): void {\n628\t this.overlayTitle.textContent = title;\n629\t this.overlayMsg.textContent = msg;\n630\t this.overlayEl.classList.remove(\"hidden\");\n631\t }\n632\t\n633\t private hideOverlay(): void {\n634\t this.overlayEl.classList.add(\"hidden\");\n635\t }\n636\t\n637\t // ── Key Bindings ─────────────────────────────────────────────────────────\n638\t\n639\t private bindKeys(): void {\n640\t // DAS (Delayed Auto Shift) state\n641\t const DAS_DELAY = 170;\n642\t const DAS_RATE = 50;\n643\t const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n644\t\n645\t const startDAS = (key: string, fn: () => void) => {\n646\t if (dasState[key]?.active) return;\n647\t fn();\n648\t dasState[key] = {\n649\t active: true,\n650\t timer: setTimeout(() => {\n651\t dasState[key].interval = setInterval(fn, DAS_RATE);\n652\t }, DAS_DELAY),\n653\t interval: null,\n654\t };\n655\t };\n656\t\n657\t const stopDAS = (key: string) => {\n658\t if (!dasState[key]) return;\n659\t clearTimeout(dasState[key].timer!);\n660\t clearInterval(dasState[key].interval!);\n661\t dasState[key].active = false;\n662\t };\n663\t\n664\t window.addEventListener(\"keydown\", (e) => {\n665\t if (!this.started || this.gameOver) {\n666\t if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n667\t return;\n668\t }\n669\t\n670\t switch (e.code) {\n671\t case \"ArrowLeft\":\n672\t e.preventDefault();\n673\t startDAS(\"left\", () => {\n674\t if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n675\t });\n676\t break;\n677\t case \"ArrowRight\":\n678\t e.preventDefault();\n679\t startDAS(\"right\", () => {\n680\t if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n681\t });\n682\t break;\n683\t case \"ArrowDown\":\n684\t e.preventDefault();\n685\t startDAS(\"down\", () => {\n686\t if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n687\t });\n688\t break;\n689\t case \"ArrowUp\":\n690\t e.preventDefault();\n691\t if (!this.paused) { this.rotate(1); }\n692\t break;\n693\t case \"KeyZ\":\n694\t e.preventDefault();\n695\t if (!this.paused) { this.rotate(-1); }\n696\t break;\n697\t case \"KeyX\":\n698\t e.preventDefault();\n699\t if (!this.paused) { this.rotate(1); }\n700\t break;\n701\t case \"Space\":\n702\t e.preventDefault();\n703\t if (this.paused) { this.togglePause(); return; }\n704\t this.hardDrop();\n705\t break;\n706\t case \"KeyC\":\n707\t case \"ShiftLeft\":\n708\t case \"ShiftRight\":\n709\t e.preventDefault();\n710\t if (!this.paused) this.hold();\n711\t break;\n712\t case \"KeyP\":\n713\t case \"Escape\":\n714\t e.preventDefault();\n715\t this.togglePause();\n716\t break;\n717\t case \"Enter\":\n718\t e.preventDefault();\n719\t if (this.paused) this.togglePause();\n720\t break;\n721\t }\n722\t });\n723\t\n724\t window.addEventListener(\"keyup\", (e) => {\n725\t if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n726\t if (e.code === \"ArrowRight\") stopDAS(\"right\");\n727\t if (e.code === \"ArrowDown\") stopDAS(\"down\");\n728\t });\n729\t }\n730\t}\n731\t\n732\t// ─── Bootstrap ───────────────────────────────────────────────────────────────\n733\t\n734\twindow.addEventListener(\"DOMContentLoaded\", () => {\n735\t new Tetris();\n736\t});\n737\t"}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"9debf74a-4e75-49ef-89a1-8ad542ffac2b","timestamp":"2026-04-05T19:27:52.619Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-elvty8os/src/tetris.ts","content":"// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Matrix = number[][];\ntype Color = string;\n\ninterface Piece {\n matrix: Matrix;\n color: Color;\n x: number;\n y: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n color: string;\n size: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px per cell\nconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\nconst TOTAL_ROWS = ROWS + HIDDEN;\n\nconst COLORS: Record<string, Color> = {\n I: \"#00d4ff\",\n O: \"#ffd700\",\n T: \"#bf5fff\",\n S: \"#39d353\",\n Z: \"#ff4d4d\",\n J: \"#4d79ff\",\n L: \"#ff9900\",\n};\n\nconst TETROMINOES: Record<string, Matrix> = {\n I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n O: [[1,1],[1,1]],\n T: [[0,1,0],[1,1,1],[0,0,0]],\n S: [[0,1,1],[1,1,0],[0,0,0]],\n Z: [[1,1,0],[0,1,1],[0,0,0]],\n J: [[1,0,0],[1,1,1],[0,0,0]],\n L: [[0,0,1],[1,1,1],[0,0,0]],\n};\n\n// Scoring per lines cleared (multiplied by level)\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n\n// Drop interval in ms at each level (capped at level 20)\nfunction levelInterval(level: number): number {\n return Math.max(50, 1000 - (level - 1) * 47);\n}\n\n// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n\n// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\nconst KICKS_JLSTZ: [number,number][][] = [\n // 0→1\n [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n // 1→2\n [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n // 2→3\n [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n // 3→0\n [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n];\n\n// Kick table for I piece\nconst KICKS_I: [number,number][][] = [\n // 0→1\n [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n // 1→2\n [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n // 2→3\n [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n // 3→0\n [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n];\n\n// ─── Utility ──────────────────────────────────────────────────────────────────\n\nfunction rotateCW(m: Matrix): Matrix {\n const rows = m.length, cols = m[0].length;\n return Array.from({ length: cols }, (_, c) =>\n Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n );\n}\n\nfunction rotateCCW(m: Matrix): Matrix {\n return rotateCW(rotateCW(rotateCW(m)));\n}\n\n// ─── Board ────────────────────────────────────────────────────────────────────\n\nclass Board {\n grid: Color[][];\n\n constructor() {\n this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n }\n\n isValid(piece: Piece): boolean {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const x = piece.x + c;\n const y = piece.y + r;\n if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n if (y >= 0 && this.grid[y][x]) return false;\n }\n }\n return true;\n }\n\n lock(piece: Piece): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const y = piece.y + r;\n const x = piece.x + c;\n if (y >= 0) this.grid[y][x] = piece.color;\n }\n }\n }\n\n clearLines(): number {\n const cleared: number[] = [];\n for (let r = 0; r < TOTAL_ROWS; r++) {\n if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n }\n for (const r of cleared) {\n this.grid.splice(r, 1);\n this.grid.unshift(Array(COLS).fill(\"\"));\n }\n return cleared.length;\n }\n\n getGhostY(piece: Piece): number {\n let gy = piece.y;\n while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n return gy;\n }\n}\n\n// ─── Random Bag ──────────────────────────────────────────────────────────────\n\nclass Bag {\n private queue: string[] = [];\n\n private refill(): void {\n const keys = Object.keys(TETROMINOES);\n for (let i = keys.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [keys[i], keys[j]] = [keys[j], keys[i]];\n }\n this.queue.push(...keys);\n }\n\n next(): string {\n if (this.queue.length < 5) this.refill();\n return this.queue.shift()!;\n }\n\n peek(n: number): string[] {\n while (this.queue.length < n + 5) this.refill();\n return this.queue.slice(0, n);\n }\n}\n\n// ─── Tetris Game ─────────────────────────────────────────────────────────────\n\nclass Tetris {\n // Canvases\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private holdCanvas: HTMLCanvasElement;\n private holdCtx: CanvasRenderingContext2D;\n\n // Game state\n private board: Board;\n private bag: Bag;\n private current!: Piece;\n private holdKey: string | null = null;\n private holdUsed: boolean = false;\n private rotation: number = 0; // 0..3\n private score: number = 0;\n private lines: number = 0;\n private level: number = 1;\n private gameOver: boolean = false;\n private paused: boolean = false;\n private started: boolean = false;\n\n // Timers\n private dropTimer: number = 0;\n private lastTime: number = 0;\n private rafId: number = 0;\n\n // Lock-delay\n private lockTimer: number = 0;\n private lockDelay: number = 500; // ms\n private lockMoves: number = 0;\n private maxLockMoves: number = 15;\n private onGround: boolean = false;\n\n // Particles\n private particles: Particle[] = [];\n\n // DOM\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitle: HTMLElement;\n private overlayMsg: HTMLElement;\n\n constructor() {\n this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n this.ctx = this.canvas.getContext(\"2d\")!;\n this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n\n this.canvas.width = COLS * BLOCK;\n this.canvas.height = ROWS * BLOCK;\n\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitle = document.getElementById(\"overlay-title\")!;\n this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n\n this.board = new Board();\n this.bag = new Bag();\n\n this.bindKeys();\n this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n }\n\n // ── Spawn ────────────────────────────────────────────────────────────────\n\n private spawn(key: string): Piece {\n const matrix = TETROMINOES[key].map(r => [...r]);\n const color = COLORS[key];\n const x = Math.floor((COLS - matrix[0].length) / 2);\n const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n return { matrix, color, x, y };\n }\n\n private spawnNext(): void {\n const key = this.bag.next();\n this.current = this.spawn(key);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n\n if (!this.board.isValid(this.current)) {\n this.endGame();\n }\n }\n\n // ── Movement & Rotation ──────────────────────────────────────────────────\n\n private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }\n\n private rotate(dir: 1 | -1): void {\n const fromRot = this.rotation;\n const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n\n const isI = this.current.matrix.length === 4;\n const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n const kickIdx = dir === 1 ? fromRot : toRot;\n const kickSet = kicks[kickIdx];\n\n for (const [kx, ky] of kickSet) {\n const nx = this.current.x + (dir === 1 ? kx : -kx);\n const ny = this.current.y + (dir === 1 ? ky : -ky);\n const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n if (this.board.isValid(candidate)) {\n this.current = candidate;\n this.rotation = toRot;\n this.resetLockDelay();\n return;\n }\n }\n }\n\n private hardDrop(): void {\n const gy = this.board.getGhostY(this.current);\n const dropped = gy - this.current.y;\n this.score += dropped * 2;\n this.current = { ...this.current, y: gy };\n this.lockPiece();\n }\n\n private hold(): void {\n if (this.holdUsed) return;\n this.holdUsed = true;\n if (this.holdKey === null) {\n // Infer key by matching the color\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n this.holdKey = key;\n this.spawnNext();\n } else {\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n const prev = this.holdKey;\n this.holdKey = key;\n this.current = this.spawn(prev);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n }\n this.drawHold();\n }\n\n // ── Lock Delay ───────────────────────────────────────────────────────────\n\n private resetLockDelay(): void {\n if (this.onGround && this.lockMoves < this.maxLockMoves) {\n this.lockTimer = 0;\n this.lockMoves++;\n }\n }\n\n private lockPiece(): void {\n this.board.lock(this.current);\n const cleared = this.board.clearLines();\n\n if (cleared > 0) {\n this.spawnLineClearParticles(cleared);\n this.score += LINE_SCORES[cleared] * this.level;\n this.lines += cleared;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) this.level = newLevel;\n }\n\n this.holdUsed = false;\n this.updateHUD();\n this.spawnNext();\n }\n\n // ── Particles ────────────────────────────────────────────────────────────\n\n private spawnLineClearParticles(_count: number): void {\n const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n for (let i = 0; i < 80; i++) {\n this.particles.push({\n x: Math.random() * this.canvas.width,\n y: Math.random() * this.canvas.height,\n vx: (Math.random() - 0.5) * 6,\n vy: (Math.random() - 0.5) * 6,\n alpha: 1,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: Math.random() * 5 + 2,\n });\n }\n }\n\n // ── Game Loop ────────────────────────────────────────────────────────────\n\n private loop(time: number): void {\n const dt = Math.min(time - this.lastTime, 100);\n this.lastTime = time;\n\n if (!this.paused && !this.gameOver) {\n this.dropTimer += dt;\n\n const interval = levelInterval(this.level);\n if (this.dropTimer >= interval) {\n this.dropTimer = 0;\n const moved = this.move(0, 1);\n if (!moved) {\n this.onGround = true;\n }\n }\n\n // Lock delay\n const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n if (landedNow) {\n this.onGround = true;\n this.lockTimer += dt;\n if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n this.lockPiece();\n }\n } else {\n this.onGround = false;\n this.lockTimer = 0;\n }\n\n // Update particles\n this.particles = this.particles.filter(p => p.alpha > 0.02);\n for (const p of this.particles) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.15;\n p.alpha *= 0.93;\n }\n }\n\n this.draw();\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Start / Pause / End ──────────────────────────────────────────────────\n\n start(): void {\n if (this.started && !this.gameOver) {\n this.togglePause();\n return;\n }\n this.board = new Board();\n this.bag = new Bag();\n this.holdKey = null;\n this.holdUsed = false;\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.gameOver = false;\n this.paused = false;\n this.started = true;\n this.particles = [];\n this.spawnNext();\n this.updateHUD();\n this.hideOverlay();\n this.lastTime = performance.now();\n this.dropTimer = 0;\n cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n private togglePause(): void {\n this.paused = !this.paused;\n if (this.paused) {\n this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n } else {\n this.hideOverlay();\n this.lastTime = performance.now();\n }\n }\n\n private endGame(): void {\n this.gameOver = true;\n this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n }\n\n // ── Draw ─────────────────────────────────────────────────────────────────\n\n private draw(): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBackground();\n this.drawBoard();\n this.drawGhost();\n this.drawPiece(ctx, this.current, -HIDDEN);\n this.drawParticles();\n this.drawNext();\n this.drawHold();\n }\n\n private drawBackground(): void {\n const ctx = this.ctx;\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n ctx.lineWidth = 1;\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, this.canvas.height);\n ctx.stroke();\n }\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(this.canvas.width, r * BLOCK);\n ctx.stroke();\n }\n }\n\n private drawBoard(): void {\n const ctx = this.ctx;\n for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n const color = this.board.grid[r][c];\n if (color) {\n this.drawBlock(ctx, c, r - HIDDEN, color);\n }\n }\n }\n }\n\n private drawGhost(): void {\n const gy = this.board.getGhostY(this.current);\n if (gy === this.current.y) return;\n const ctx = this.ctx;\n ctx.globalAlpha = 0.25;\n const ghost: Piece = { ...this.current, y: gy };\n this.drawPiece(ctx, ghost, -HIDDEN);\n ctx.globalAlpha = 1;\n }\n\n private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const px = piece.x + c;\n const py = piece.y + r + yOffset;\n if (py < 0) continue;\n this.drawBlock(ctx, px, py, piece.color);\n }\n }\n }\n\n private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n const px = x * size;\n const py = y * size;\n const pad = size * 0.05;\n\n // Base fill\n ctx.fillStyle = color;\n ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n\n // Highlight (top-left)\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n\n // Shadow (bottom-right)\n ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n }\n\n private drawParticles(): void {\n const ctx = this.ctx;\n for (const p of this.particles) {\n ctx.globalAlpha = p.alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n\n private drawNext(): void {\n const ctx = this.nextCtx;\n const next3 = this.bag.peek(3);\n const cellW = 4;\n const cellH = 3;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n next3.forEach((key, idx) => {\n const matrix = TETROMINOES[key];\n const color = COLORS[key];\n const offX = Math.floor((cellW - matrix[0].length) / 2);\n const offY = Math.floor((cellH - matrix.length) / 2);\n const baseY = idx * cellH;\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n }\n }\n });\n }\n\n private drawHold(): void {\n const ctx = this.holdCtx;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n\n if (!this.holdKey) return;\n const matrix = TETROMINOES[this.holdKey];\n const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n const offX = Math.floor((4 - matrix[0].length) / 2);\n const offY = Math.floor((3 - matrix.length) / 2);\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n }\n }\n }\n\n // ── HUD ──────────────────────────────────────────────────────────────────\n\n private updateHUD(): void {\n this.scoreEl.textContent = this.score.toLocaleString();\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitle.textContent = title;\n this.overlayMsg.textContent = msg;\n this.overlayEl.classList.remove(\"hidden\");\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add(\"hidden\");\n }\n\n // ── Key Bindings ─────────────────────────────────────────────────────────\n\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE);\n }, DAS_DELAY),\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {\n if (!dasState[key]) return;\n clearTimeout(dasState[key].timer!);\n clearInterval(dasState[key].interval!);\n dasState[key].active = false;\n };\n\n window.addEventListener(\"keydown\", (e) => {\n if (!this.started || this.gameOver) {\n if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n return;\n }\n\n switch (e.code) {\n case \"ArrowLeft\":\n e.preventDefault();\n startDAS(\"left\", () => {\n if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowRight\":\n e.preventDefault();\n startDAS(\"right\", () => {\n if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"KeyZ\":\n e.preventDefault();\n if (!this.paused) { this.rotate(-1); }\n break;\n case \"KeyX\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"Space\":\n e.preventDefault();\n if (this.paused) { this.togglePause(); return; }\n this.hardDrop();\n break;\n case \"KeyC\":\n case \"ShiftLeft\":\n case \"ShiftRight\":\n e.preventDefault();\n if (!this.paused) this.hold();\n break;\n case \"KeyP\":\n case \"Escape\":\n e.preventDefault();\n this.togglePause();\n break;\n case \"Enter\":\n e.preventDefault();\n if (this.paused) this.togglePause();\n break;\n }\n });\n\n window.addEventListener(\"keyup\", (e) => {\n if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n if (e.code === \"ArrowRight\") stopDAS(\"right\");\n if (e.code === \"ArrowDown\") stopDAS(\"down\");\n });\n }\n}\n\n// ─── Bootstrap ───────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new Tetris();\n});\n","numLines":737,"startLine":1,"totalLines":737}}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011cQc61iPvFmUqArov7Abyq","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The code looks correct and comprehensive. Let me also check the `draw` method when `started` is false - when the game hasn't started yet, `this.current` is uninitialized (it's typed as `Piece` with `!`). The draw loop only starts after `start()` is called which calls `spawnNext()` first, so that's fine.\n\nLet me also double-check the `clearLines` method. There's a subtle bug - when I remove a line and unshift, the indices of subsequent lines change. Let me trace through:\n\nFor example, if lines 5 and 10 are full:\n\n\n- `cleared = [5, 10]`\n- First iteration: `r = 5`, splice(5, 1), unshift → now what was row 10 is now row 11 (after removing row 5 and prepending an empty row, all indices shift down by 1, then back up by 1, so it stays at 10... actually, let me reconsider)\n\nWhen I splice row 5 and unshift a new row, the grid length stays the same, but the indices of all rows below row 5 shift up by 1. So what was at index 10 is now at index 9. But I'm iterating through `cleared = [5, 10]` in order, so when I process the second element (10), I'm actually removing the wrong row. I'm tracing through the array mutations more carefully now. After removing the row at index 5, the original row 10 shifts down to index 9. Then when I unshift an empty row at the beginning, everything shifts again—the original row 10 ends up at index 10, and I need to account for how the second removal at index 10 will affect the positions. So the pattern holds generally: when I process row r1 before r2, the splice reduces r2's index by 1, then the unshift increases it back by 1, so r2 stays at its original index—this is why the algorithm works correctly despite the shifting indices.\n\nNow I'm verifying that the `draw` method handles uninitialized state safely. The `draw` method calls several rendering functions including one that uses `this.current`, but since `draw` is only invoked from the game loop which starts after `spawnNext()` initializes the current piece, there's no risk of accessing an uninitialized property.\n\nLooking at the soft drop bonus logic, there's a condition checking `this.score > 0` before awarding points, which seems like it might be a bug since standard Tetris rules award soft drop bonuses from the start of the game rather than only after the first score.\n\nThe real issue is that both player-initiated soft drops and gravity-driven drops call the same `move(0, 1)` function, so they'd both trigger the score bonus when only player soft drops should award points. I need to separate these two paths so gravity drops don't incorrectly add to the score. I realize the soft drop bonus issue isn't critical since gravity drops and player input are on separate timers anyway, but I should still fix it properly by adding an `isSoftDrop` parameter to distinguish between the two. Looking at how both the gravity loop and the key handler call `move()`, I need to pass this flag through so only intentional soft drops award points.","signature":"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"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":9418,"cache_read_input_tokens":20885,"cache_creation":{"ephemeral_5m_input_tokens":9418,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"6c3d7ff7-c406-4426-bf7f-2ddf05b92b11"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011cQc61iPvFmUqArov7Abyq","type":"message","role":"assistant","content":[{"type":"text","text":"Let me also fix a minor mechanics issue — the `move()` method currently gives soft-drop points even for gravity ticks. I'll split them properly:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":9418,"cache_read_input_tokens":20885,"cache_creation":{"ephemeral_5m_input_tokens":9418,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"173b94a3-579a-48bd-84ab-9d9d3343879e"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011cQc61iPvFmUqArov7Abyq","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_011uP4e2Y3Jutr582SGoCaEQ","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/src/tetris.ts","old_string":" private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }","new_string":" private move(dx: number, dy: number, softDrop = false): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (softDrop && dy > 0) {\n // +1 per row for player-initiated soft drop\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":9418,"cache_read_input_tokens":20885,"cache_creation":{"ephemeral_5m_input_tokens":9418,"ephemeral_1h_input_tokens":0},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"e3101577-b1c5-4b2a-b938-1dbc41f31f21"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_011uP4e2Y3Jutr582SGoCaEQ","type":"tool_result","content":"The file /tmp/loop-bench-elvty8os/src/tetris.ts has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"29ee9b97-c910-4f6e-abd2-8fde72e97ba1","timestamp":"2026-04-05T19:28:39.681Z","tool_use_result":{"filePath":"/tmp/loop-bench-elvty8os/src/tetris.ts","oldString":" private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }","newString":" private move(dx: number, dy: number, softDrop = false): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (softDrop && dy > 0) {\n // +1 per row for player-initiated soft drop\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }","originalFile":"// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Matrix = number[][];\ntype Color = string;\n\ninterface Piece {\n matrix: Matrix;\n color: Color;\n x: number;\n y: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n color: string;\n size: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px per cell\nconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\nconst TOTAL_ROWS = ROWS + HIDDEN;\n\nconst COLORS: Record<string, Color> = {\n I: \"#00d4ff\",\n O: \"#ffd700\",\n T: \"#bf5fff\",\n S: \"#39d353\",\n Z: \"#ff4d4d\",\n J: \"#4d79ff\",\n L: \"#ff9900\",\n};\n\nconst TETROMINOES: Record<string, Matrix> = {\n I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n O: [[1,1],[1,1]],\n T: [[0,1,0],[1,1,1],[0,0,0]],\n S: [[0,1,1],[1,1,0],[0,0,0]],\n Z: [[1,1,0],[0,1,1],[0,0,0]],\n J: [[1,0,0],[1,1,1],[0,0,0]],\n L: [[0,0,1],[1,1,1],[0,0,0]],\n};\n\n// Scoring per lines cleared (multiplied by level)\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n\n// Drop interval in ms at each level (capped at level 20)\nfunction levelInterval(level: number): number {\n return Math.max(50, 1000 - (level - 1) * 47);\n}\n\n// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n\n// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\nconst KICKS_JLSTZ: [number,number][][] = [\n // 0→1\n [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n // 1→2\n [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n // 2→3\n [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n // 3→0\n [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n];\n\n// Kick table for I piece\nconst KICKS_I: [number,number][][] = [\n // 0→1\n [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n // 1→2\n [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n // 2→3\n [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n // 3→0\n [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n];\n\n// ─── Utility ──────────────────────────────────────────────────────────────────\n\nfunction rotateCW(m: Matrix): Matrix {\n const rows = m.length, cols = m[0].length;\n return Array.from({ length: cols }, (_, c) =>\n Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n );\n}\n\nfunction rotateCCW(m: Matrix): Matrix {\n return rotateCW(rotateCW(rotateCW(m)));\n}\n\n// ─── Board ────────────────────────────────────────────────────────────────────\n\nclass Board {\n grid: Color[][];\n\n constructor() {\n this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n }\n\n isValid(piece: Piece): boolean {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const x = piece.x + c;\n const y = piece.y + r;\n if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n if (y >= 0 && this.grid[y][x]) return false;\n }\n }\n return true;\n }\n\n lock(piece: Piece): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const y = piece.y + r;\n const x = piece.x + c;\n if (y >= 0) this.grid[y][x] = piece.color;\n }\n }\n }\n\n clearLines(): number {\n const cleared: number[] = [];\n for (let r = 0; r < TOTAL_ROWS; r++) {\n if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n }\n for (const r of cleared) {\n this.grid.splice(r, 1);\n this.grid.unshift(Array(COLS).fill(\"\"));\n }\n return cleared.length;\n }\n\n getGhostY(piece: Piece): number {\n let gy = piece.y;\n while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n return gy;\n }\n}\n\n// ─── Random Bag ──────────────────────────────────────────────────────────────\n\nclass Bag {\n private queue: string[] = [];\n\n private refill(): void {\n const keys = Object.keys(TETROMINOES);\n for (let i = keys.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [keys[i], keys[j]] = [keys[j], keys[i]];\n }\n this.queue.push(...keys);\n }\n\n next(): string {\n if (this.queue.length < 5) this.refill();\n return this.queue.shift()!;\n }\n\n peek(n: number): string[] {\n while (this.queue.length < n + 5) this.refill();\n return this.queue.slice(0, n);\n }\n}\n\n// ─── Tetris Game ─────────────────────────────────────────────────────────────\n\nclass Tetris {\n // Canvases\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private holdCanvas: HTMLCanvasElement;\n private holdCtx: CanvasRenderingContext2D;\n\n // Game state\n private board: Board;\n private bag: Bag;\n private current!: Piece;\n private holdKey: string | null = null;\n private holdUsed: boolean = false;\n private rotation: number = 0; // 0..3\n private score: number = 0;\n private lines: number = 0;\n private level: number = 1;\n private gameOver: boolean = false;\n private paused: boolean = false;\n private started: boolean = false;\n\n // Timers\n private dropTimer: number = 0;\n private lastTime: number = 0;\n private rafId: number = 0;\n\n // Lock-delay\n private lockTimer: number = 0;\n private lockDelay: number = 500; // ms\n private lockMoves: number = 0;\n private maxLockMoves: number = 15;\n private onGround: boolean = false;\n\n // Particles\n private particles: Particle[] = [];\n\n // DOM\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitle: HTMLElement;\n private overlayMsg: HTMLElement;\n\n constructor() {\n this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n this.ctx = this.canvas.getContext(\"2d\")!;\n this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n\n this.canvas.width = COLS * BLOCK;\n this.canvas.height = ROWS * BLOCK;\n\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitle = document.getElementById(\"overlay-title\")!;\n this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n\n this.board = new Board();\n this.bag = new Bag();\n\n this.bindKeys();\n this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n }\n\n // ── Spawn ────────────────────────────────────────────────────────────────\n\n private spawn(key: string): Piece {\n const matrix = TETROMINOES[key].map(r => [...r]);\n const color = COLORS[key];\n const x = Math.floor((COLS - matrix[0].length) / 2);\n const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n return { matrix, color, x, y };\n }\n\n private spawnNext(): void {\n const key = this.bag.next();\n this.current = this.spawn(key);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n\n if (!this.board.isValid(this.current)) {\n this.endGame();\n }\n }\n\n // ── Movement & Rotation ──────────────────────────────────────────────────\n\n private move(dx: number, dy: number): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (dy > 0 && this.score > 0 && dx === 0) {\n // soft drop bonus\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }\n\n private rotate(dir: 1 | -1): void {\n const fromRot = this.rotation;\n const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n\n const isI = this.current.matrix.length === 4;\n const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n const kickIdx = dir === 1 ? fromRot : toRot;\n const kickSet = kicks[kickIdx];\n\n for (const [kx, ky] of kickSet) {\n const nx = this.current.x + (dir === 1 ? kx : -kx);\n const ny = this.current.y + (dir === 1 ? ky : -ky);\n const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n if (this.board.isValid(candidate)) {\n this.current = candidate;\n this.rotation = toRot;\n this.resetLockDelay();\n return;\n }\n }\n }\n\n private hardDrop(): void {\n const gy = this.board.getGhostY(this.current);\n const dropped = gy - this.current.y;\n this.score += dropped * 2;\n this.current = { ...this.current, y: gy };\n this.lockPiece();\n }\n\n private hold(): void {\n if (this.holdUsed) return;\n this.holdUsed = true;\n if (this.holdKey === null) {\n // Infer key by matching the color\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n this.holdKey = key;\n this.spawnNext();\n } else {\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n const prev = this.holdKey;\n this.holdKey = key;\n this.current = this.spawn(prev);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n }\n this.drawHold();\n }\n\n // ── Lock Delay ───────────────────────────────────────────────────────────\n\n private resetLockDelay(): void {\n if (this.onGround && this.lockMoves < this.maxLockMoves) {\n this.lockTimer = 0;\n this.lockMoves++;\n }\n }\n\n private lockPiece(): void {\n this.board.lock(this.current);\n const cleared = this.board.clearLines();\n\n if (cleared > 0) {\n this.spawnLineClearParticles(cleared);\n this.score += LINE_SCORES[cleared] * this.level;\n this.lines += cleared;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) this.level = newLevel;\n }\n\n this.holdUsed = false;\n this.updateHUD();\n this.spawnNext();\n }\n\n // ── Particles ────────────────────────────────────────────────────────────\n\n private spawnLineClearParticles(_count: number): void {\n const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n for (let i = 0; i < 80; i++) {\n this.particles.push({\n x: Math.random() * this.canvas.width,\n y: Math.random() * this.canvas.height,\n vx: (Math.random() - 0.5) * 6,\n vy: (Math.random() - 0.5) * 6,\n alpha: 1,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: Math.random() * 5 + 2,\n });\n }\n }\n\n // ── Game Loop ────────────────────────────────────────────────────────────\n\n private loop(time: number): void {\n const dt = Math.min(time - this.lastTime, 100);\n this.lastTime = time;\n\n if (!this.paused && !this.gameOver) {\n this.dropTimer += dt;\n\n const interval = levelInterval(this.level);\n if (this.dropTimer >= interval) {\n this.dropTimer = 0;\n const moved = this.move(0, 1);\n if (!moved) {\n this.onGround = true;\n }\n }\n\n // Lock delay\n const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n if (landedNow) {\n this.onGround = true;\n this.lockTimer += dt;\n if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n this.lockPiece();\n }\n } else {\n this.onGround = false;\n this.lockTimer = 0;\n }\n\n // Update particles\n this.particles = this.particles.filter(p => p.alpha > 0.02);\n for (const p of this.particles) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.15;\n p.alpha *= 0.93;\n }\n }\n\n this.draw();\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Start / Pause / End ──────────────────────────────────────────────────\n\n start(): void {\n if (this.started && !this.gameOver) {\n this.togglePause();\n return;\n }\n this.board = new Board();\n this.bag = new Bag();\n this.holdKey = null;\n this.holdUsed = false;\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.gameOver = false;\n this.paused = false;\n this.started = true;\n this.particles = [];\n this.spawnNext();\n this.updateHUD();\n this.hideOverlay();\n this.lastTime = performance.now();\n this.dropTimer = 0;\n cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n private togglePause(): void {\n this.paused = !this.paused;\n if (this.paused) {\n this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n } else {\n this.hideOverlay();\n this.lastTime = performance.now();\n }\n }\n\n private endGame(): void {\n this.gameOver = true;\n this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n }\n\n // ── Draw ─────────────────────────────────────────────────────────────────\n\n private draw(): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBackground();\n this.drawBoard();\n this.drawGhost();\n this.drawPiece(ctx, this.current, -HIDDEN);\n this.drawParticles();\n this.drawNext();\n this.drawHold();\n }\n\n private drawBackground(): void {\n const ctx = this.ctx;\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n ctx.lineWidth = 1;\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, this.canvas.height);\n ctx.stroke();\n }\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(this.canvas.width, r * BLOCK);\n ctx.stroke();\n }\n }\n\n private drawBoard(): void {\n const ctx = this.ctx;\n for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n const color = this.board.grid[r][c];\n if (color) {\n this.drawBlock(ctx, c, r - HIDDEN, color);\n }\n }\n }\n }\n\n private drawGhost(): void {\n const gy = this.board.getGhostY(this.current);\n if (gy === this.current.y) return;\n const ctx = this.ctx;\n ctx.globalAlpha = 0.25;\n const ghost: Piece = { ...this.current, y: gy };\n this.drawPiece(ctx, ghost, -HIDDEN);\n ctx.globalAlpha = 1;\n }\n\n private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const px = piece.x + c;\n const py = piece.y + r + yOffset;\n if (py < 0) continue;\n this.drawBlock(ctx, px, py, piece.color);\n }\n }\n }\n\n private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n const px = x * size;\n const py = y * size;\n const pad = size * 0.05;\n\n // Base fill\n ctx.fillStyle = color;\n ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n\n // Highlight (top-left)\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n\n // Shadow (bottom-right)\n ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n }\n\n private drawParticles(): void {\n const ctx = this.ctx;\n for (const p of this.particles) {\n ctx.globalAlpha = p.alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n\n private drawNext(): void {\n const ctx = this.nextCtx;\n const next3 = this.bag.peek(3);\n const cellW = 4;\n const cellH = 3;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n next3.forEach((key, idx) => {\n const matrix = TETROMINOES[key];\n const color = COLORS[key];\n const offX = Math.floor((cellW - matrix[0].length) / 2);\n const offY = Math.floor((cellH - matrix.length) / 2);\n const baseY = idx * cellH;\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n }\n }\n });\n }\n\n private drawHold(): void {\n const ctx = this.holdCtx;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n\n if (!this.holdKey) return;\n const matrix = TETROMINOES[this.holdKey];\n const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n const offX = Math.floor((4 - matrix[0].length) / 2);\n const offY = Math.floor((3 - matrix.length) / 2);\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n }\n }\n }\n\n // ── HUD ──────────────────────────────────────────────────────────────────\n\n private updateHUD(): void {\n this.scoreEl.textContent = this.score.toLocaleString();\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitle.textContent = title;\n this.overlayMsg.textContent = msg;\n this.overlayEl.classList.remove(\"hidden\");\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add(\"hidden\");\n }\n\n // ── Key Bindings ─────────────────────────────────────────────────────────\n\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE);\n }, DAS_DELAY),\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {\n if (!dasState[key]) return;\n clearTimeout(dasState[key].timer!);\n clearInterval(dasState[key].interval!);\n dasState[key].active = false;\n };\n\n window.addEventListener(\"keydown\", (e) => {\n if (!this.started || this.gameOver) {\n if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n return;\n }\n\n switch (e.code) {\n case \"ArrowLeft\":\n e.preventDefault();\n startDAS(\"left\", () => {\n if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowRight\":\n e.preventDefault();\n startDAS(\"right\", () => {\n if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"KeyZ\":\n e.preventDefault();\n if (!this.paused) { this.rotate(-1); }\n break;\n case \"KeyX\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"Space\":\n e.preventDefault();\n if (this.paused) { this.togglePause(); return; }\n this.hardDrop();\n break;\n case \"KeyC\":\n case \"ShiftLeft\":\n case \"ShiftRight\":\n e.preventDefault();\n if (!this.paused) this.hold();\n break;\n case \"KeyP\":\n case \"Escape\":\n e.preventDefault();\n this.togglePause();\n break;\n case \"Enter\":\n e.preventDefault();\n if (this.paused) this.togglePause();\n break;\n }\n });\n\n window.addEventListener(\"keyup\", (e) => {\n if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n if (e.code === \"ArrowRight\") stopDAS(\"right\");\n if (e.code === \"ArrowDown\") stopDAS(\"down\");\n });\n }\n}\n\n// ─── Bootstrap ───────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new Tetris();\n});\n","structuredPatch":[{"oldStart":270,"oldLines":12,"newStart":270,"newLines":12,"lines":[" "," // ── Movement & Rotation ──────────────────────────────────────────────────"," ","- private move(dx: number, dy: number): boolean {","+ private move(dx: number, dy: number, softDrop = false): boolean {"," const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };"," if (!this.board.isValid(next)) return false;"," this.current = next;","- if (dy > 0 && this.score > 0 && dx === 0) {","- // soft drop bonus","+ if (softDrop && dy > 0) {","+ // +1 per row for player-initiated soft drop"," this.score += 1;"," this.updateHUD();"," }"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01GCzybhgLurf6uLA5jxLMgh","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01KMAzRgmWwBYVmKFnbn6R6M","name":"Edit","input":{"replace_all":false,"file_path":"/tmp/loop-bench-elvty8os/src/tetris.ts","old_string":" case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });","new_string":" case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1, true); this.resetLockDelay(); }\n });"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":2802,"cache_read_input_tokens":30303,"cache_creation":{"ephemeral_5m_input_tokens":2802,"ephemeral_1h_input_tokens":0},"output_tokens":61,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"7e01f540-1790-4316-bba7-8cbb705c82ec"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01KMAzRgmWwBYVmKFnbn6R6M","type":"tool_result","content":"The file /tmp/loop-bench-elvty8os/src/tetris.ts has been updated successfully."}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"3b53fca8-5e5e-4578-b90f-f3717f0fc3bb","timestamp":"2026-04-05T19:28:42.708Z","tool_use_result":{"filePath":"/tmp/loop-bench-elvty8os/src/tetris.ts","oldString":" case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });","newString":" case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1, true); this.resetLockDelay(); }\n });","originalFile":"// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Matrix = number[][];\ntype Color = string;\n\ninterface Piece {\n matrix: Matrix;\n color: Color;\n x: number;\n y: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n alpha: number;\n color: string;\n size: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK = 32; // px per cell\nconst HIDDEN = 2; // hidden rows above visible area (spawn buffer)\nconst TOTAL_ROWS = ROWS + HIDDEN;\n\nconst COLORS: Record<string, Color> = {\n I: \"#00d4ff\",\n O: \"#ffd700\",\n T: \"#bf5fff\",\n S: \"#39d353\",\n Z: \"#ff4d4d\",\n J: \"#4d79ff\",\n L: \"#ff9900\",\n};\n\nconst TETROMINOES: Record<string, Matrix> = {\n I: [[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]],\n O: [[1,1],[1,1]],\n T: [[0,1,0],[1,1,1],[0,0,0]],\n S: [[0,1,1],[1,1,0],[0,0,0]],\n Z: [[1,1,0],[0,1,1],[0,0,0]],\n J: [[1,0,0],[1,1,1],[0,0,0]],\n L: [[0,0,1],[1,1,1],[0,0,0]],\n};\n\n// Scoring per lines cleared (multiplied by level)\nconst LINE_SCORES = [0, 100, 300, 500, 800];\n\n// Drop interval in ms at each level (capped at level 20)\nfunction levelInterval(level: number): number {\n return Math.max(50, 1000 - (level - 1) * 47);\n}\n\n// ─── SRS Wall-Kick Data ───────────────────────────────────────────────────────\n\n// Kick table: [from_rotation][0..3] for J,L,S,T,Z pieces\nconst KICKS_JLSTZ: [number,number][][] = [\n // 0→1\n [[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],\n // 1→2\n [[0,0],[1,0],[1,-1],[0,2],[1,2]],\n // 2→3\n [[0,0],[1,0],[1,1],[0,-2],[1,-2]],\n // 3→0\n [[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],\n];\n\n// Kick table for I piece\nconst KICKS_I: [number,number][][] = [\n // 0→1\n [[0,0],[-2,0],[1,0],[-2,-1],[1,2]],\n // 1→2\n [[0,0],[-1,0],[2,0],[-1,2],[2,-1]],\n // 2→3\n [[0,0],[2,0],[-1,0],[2,1],[-1,-2]],\n // 3→0\n [[0,0],[1,0],[-2,0],[1,-2],[-2,1]],\n];\n\n// ─── Utility ──────────────────────────────────────────────────────────────────\n\nfunction rotateCW(m: Matrix): Matrix {\n const rows = m.length, cols = m[0].length;\n return Array.from({ length: cols }, (_, c) =>\n Array.from({ length: rows }, (_, r) => m[rows - 1 - r][c])\n );\n}\n\nfunction rotateCCW(m: Matrix): Matrix {\n return rotateCW(rotateCW(rotateCW(m)));\n}\n\n// ─── Board ────────────────────────────────────────────────────────────────────\n\nclass Board {\n grid: Color[][];\n\n constructor() {\n this.grid = Array.from({ length: TOTAL_ROWS }, () => Array(COLS).fill(\"\"));\n }\n\n isValid(piece: Piece): boolean {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const x = piece.x + c;\n const y = piece.y + r;\n if (x < 0 || x >= COLS || y >= TOTAL_ROWS) return false;\n if (y >= 0 && this.grid[y][x]) return false;\n }\n }\n return true;\n }\n\n lock(piece: Piece): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const y = piece.y + r;\n const x = piece.x + c;\n if (y >= 0) this.grid[y][x] = piece.color;\n }\n }\n }\n\n clearLines(): number {\n const cleared: number[] = [];\n for (let r = 0; r < TOTAL_ROWS; r++) {\n if (this.grid[r].every(cell => cell !== \"\")) cleared.push(r);\n }\n for (const r of cleared) {\n this.grid.splice(r, 1);\n this.grid.unshift(Array(COLS).fill(\"\"));\n }\n return cleared.length;\n }\n\n getGhostY(piece: Piece): number {\n let gy = piece.y;\n while (this.isValid({ ...piece, y: gy + 1 })) gy++;\n return gy;\n }\n}\n\n// ─── Random Bag ──────────────────────────────────────────────────────────────\n\nclass Bag {\n private queue: string[] = [];\n\n private refill(): void {\n const keys = Object.keys(TETROMINOES);\n for (let i = keys.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [keys[i], keys[j]] = [keys[j], keys[i]];\n }\n this.queue.push(...keys);\n }\n\n next(): string {\n if (this.queue.length < 5) this.refill();\n return this.queue.shift()!;\n }\n\n peek(n: number): string[] {\n while (this.queue.length < n + 5) this.refill();\n return this.queue.slice(0, n);\n }\n}\n\n// ─── Tetris Game ─────────────────────────────────────────────────────────────\n\nclass Tetris {\n // Canvases\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private holdCanvas: HTMLCanvasElement;\n private holdCtx: CanvasRenderingContext2D;\n\n // Game state\n private board: Board;\n private bag: Bag;\n private current!: Piece;\n private holdKey: string | null = null;\n private holdUsed: boolean = false;\n private rotation: number = 0; // 0..3\n private score: number = 0;\n private lines: number = 0;\n private level: number = 1;\n private gameOver: boolean = false;\n private paused: boolean = false;\n private started: boolean = false;\n\n // Timers\n private dropTimer: number = 0;\n private lastTime: number = 0;\n private rafId: number = 0;\n\n // Lock-delay\n private lockTimer: number = 0;\n private lockDelay: number = 500; // ms\n private lockMoves: number = 0;\n private maxLockMoves: number = 15;\n private onGround: boolean = false;\n\n // Particles\n private particles: Particle[] = [];\n\n // DOM\n private scoreEl: HTMLElement;\n private linesEl: HTMLElement;\n private levelEl: HTMLElement;\n private overlayEl: HTMLElement;\n private overlayTitle: HTMLElement;\n private overlayMsg: HTMLElement;\n\n constructor() {\n this.canvas = document.getElementById(\"board\") as HTMLCanvasElement;\n this.ctx = this.canvas.getContext(\"2d\")!;\n this.nextCanvas = document.getElementById(\"next\") as HTMLCanvasElement;\n this.nextCtx = this.nextCanvas.getContext(\"2d\")!;\n this.holdCanvas = document.getElementById(\"hold\") as HTMLCanvasElement;\n this.holdCtx = this.holdCanvas.getContext(\"2d\")!;\n\n this.canvas.width = COLS * BLOCK;\n this.canvas.height = ROWS * BLOCK;\n\n this.scoreEl = document.getElementById(\"score\")!;\n this.linesEl = document.getElementById(\"lines\")!;\n this.levelEl = document.getElementById(\"level\")!;\n this.overlayEl = document.getElementById(\"overlay\")!;\n this.overlayTitle = document.getElementById(\"overlay-title\")!;\n this.overlayMsg = document.getElementById(\"overlay-msg\")!;\n\n this.board = new Board();\n this.bag = new Bag();\n\n this.bindKeys();\n this.showOverlay(\"TETRIS\", \"Press Space or Enter to start\");\n }\n\n // ── Spawn ────────────────────────────────────────────────────────────────\n\n private spawn(key: string): Piece {\n const matrix = TETROMINOES[key].map(r => [...r]);\n const color = COLORS[key];\n const x = Math.floor((COLS - matrix[0].length) / 2);\n const y = key === \"I\" ? HIDDEN - 2 : HIDDEN - 1;\n return { matrix, color, x, y };\n }\n\n private spawnNext(): void {\n const key = this.bag.next();\n this.current = this.spawn(key);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n\n if (!this.board.isValid(this.current)) {\n this.endGame();\n }\n }\n\n // ── Movement & Rotation ──────────────────────────────────────────────────\n\n private move(dx: number, dy: number, softDrop = false): boolean {\n const next = { ...this.current, x: this.current.x + dx, y: this.current.y + dy };\n if (!this.board.isValid(next)) return false;\n this.current = next;\n if (softDrop && dy > 0) {\n // +1 per row for player-initiated soft drop\n this.score += 1;\n this.updateHUD();\n }\n return true;\n }\n\n private rotate(dir: 1 | -1): void {\n const fromRot = this.rotation;\n const toRot = (fromRot + (dir === 1 ? 1 : 3)) % 4;\n const newMatrix = dir === 1 ? rotateCW(this.current.matrix) : rotateCCW(this.current.matrix);\n\n const isI = this.current.matrix.length === 4;\n const kicks = isI ? KICKS_I : KICKS_JLSTZ;\n const kickIdx = dir === 1 ? fromRot : toRot;\n const kickSet = kicks[kickIdx];\n\n for (const [kx, ky] of kickSet) {\n const nx = this.current.x + (dir === 1 ? kx : -kx);\n const ny = this.current.y + (dir === 1 ? ky : -ky);\n const candidate: Piece = { ...this.current, matrix: newMatrix, x: nx, y: ny };\n if (this.board.isValid(candidate)) {\n this.current = candidate;\n this.rotation = toRot;\n this.resetLockDelay();\n return;\n }\n }\n }\n\n private hardDrop(): void {\n const gy = this.board.getGhostY(this.current);\n const dropped = gy - this.current.y;\n this.score += dropped * 2;\n this.current = { ...this.current, y: gy };\n this.lockPiece();\n }\n\n private hold(): void {\n if (this.holdUsed) return;\n this.holdUsed = true;\n if (this.holdKey === null) {\n // Infer key by matching the color\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n this.holdKey = key;\n this.spawnNext();\n } else {\n const key = Object.keys(COLORS).find(k => COLORS[k] === this.current.color)!;\n const prev = this.holdKey;\n this.holdKey = key;\n this.current = this.spawn(prev);\n this.rotation = 0;\n this.lockTimer = 0;\n this.lockMoves = 0;\n this.onGround = false;\n }\n this.drawHold();\n }\n\n // ── Lock Delay ───────────────────────────────────────────────────────────\n\n private resetLockDelay(): void {\n if (this.onGround && this.lockMoves < this.maxLockMoves) {\n this.lockTimer = 0;\n this.lockMoves++;\n }\n }\n\n private lockPiece(): void {\n this.board.lock(this.current);\n const cleared = this.board.clearLines();\n\n if (cleared > 0) {\n this.spawnLineClearParticles(cleared);\n this.score += LINE_SCORES[cleared] * this.level;\n this.lines += cleared;\n const newLevel = Math.floor(this.lines / 10) + 1;\n if (newLevel > this.level) this.level = newLevel;\n }\n\n this.holdUsed = false;\n this.updateHUD();\n this.spawnNext();\n }\n\n // ── Particles ────────────────────────────────────────────────────────────\n\n private spawnLineClearParticles(_count: number): void {\n const colors = [\"#fff\", \"#ffd700\", \"#ff9900\", \"#39d353\", \"#00d4ff\", \"#bf5fff\"];\n for (let i = 0; i < 80; i++) {\n this.particles.push({\n x: Math.random() * this.canvas.width,\n y: Math.random() * this.canvas.height,\n vx: (Math.random() - 0.5) * 6,\n vy: (Math.random() - 0.5) * 6,\n alpha: 1,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: Math.random() * 5 + 2,\n });\n }\n }\n\n // ── Game Loop ────────────────────────────────────────────────────────────\n\n private loop(time: number): void {\n const dt = Math.min(time - this.lastTime, 100);\n this.lastTime = time;\n\n if (!this.paused && !this.gameOver) {\n this.dropTimer += dt;\n\n const interval = levelInterval(this.level);\n if (this.dropTimer >= interval) {\n this.dropTimer = 0;\n const moved = this.move(0, 1);\n if (!moved) {\n this.onGround = true;\n }\n }\n\n // Lock delay\n const landedNow = !this.board.isValid({ ...this.current, y: this.current.y + 1 });\n if (landedNow) {\n this.onGround = true;\n this.lockTimer += dt;\n if (this.lockTimer >= this.lockDelay || this.lockMoves >= this.maxLockMoves) {\n this.lockPiece();\n }\n } else {\n this.onGround = false;\n this.lockTimer = 0;\n }\n\n // Update particles\n this.particles = this.particles.filter(p => p.alpha > 0.02);\n for (const p of this.particles) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.15;\n p.alpha *= 0.93;\n }\n }\n\n this.draw();\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n // ── Start / Pause / End ──────────────────────────────────────────────────\n\n start(): void {\n if (this.started && !this.gameOver) {\n this.togglePause();\n return;\n }\n this.board = new Board();\n this.bag = new Bag();\n this.holdKey = null;\n this.holdUsed = false;\n this.score = 0;\n this.lines = 0;\n this.level = 1;\n this.gameOver = false;\n this.paused = false;\n this.started = true;\n this.particles = [];\n this.spawnNext();\n this.updateHUD();\n this.hideOverlay();\n this.lastTime = performance.now();\n this.dropTimer = 0;\n cancelAnimationFrame(this.rafId);\n this.rafId = requestAnimationFrame(t => this.loop(t));\n }\n\n private togglePause(): void {\n this.paused = !this.paused;\n if (this.paused) {\n this.showOverlay(\"PAUSED\", \"Press P or Space to resume\");\n } else {\n this.hideOverlay();\n this.lastTime = performance.now();\n }\n }\n\n private endGame(): void {\n this.gameOver = true;\n this.showOverlay(\"GAME OVER\", `Score: ${this.score.toLocaleString()}\\nPress Space or Enter to restart`);\n }\n\n // ── Draw ─────────────────────────────────────────────────────────────────\n\n private draw(): void {\n const ctx = this.ctx;\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBackground();\n this.drawBoard();\n this.drawGhost();\n this.drawPiece(ctx, this.current, -HIDDEN);\n this.drawParticles();\n this.drawNext();\n this.drawHold();\n }\n\n private drawBackground(): void {\n const ctx = this.ctx;\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Grid lines\n ctx.strokeStyle = \"rgba(255,255,255,0.04)\";\n ctx.lineWidth = 1;\n for (let c = 0; c <= COLS; c++) {\n ctx.beginPath();\n ctx.moveTo(c * BLOCK, 0);\n ctx.lineTo(c * BLOCK, this.canvas.height);\n ctx.stroke();\n }\n for (let r = 0; r <= ROWS; r++) {\n ctx.beginPath();\n ctx.moveTo(0, r * BLOCK);\n ctx.lineTo(this.canvas.width, r * BLOCK);\n ctx.stroke();\n }\n }\n\n private drawBoard(): void {\n const ctx = this.ctx;\n for (let r = HIDDEN; r < TOTAL_ROWS; r++) {\n for (let c = 0; c < COLS; c++) {\n const color = this.board.grid[r][c];\n if (color) {\n this.drawBlock(ctx, c, r - HIDDEN, color);\n }\n }\n }\n }\n\n private drawGhost(): void {\n const gy = this.board.getGhostY(this.current);\n if (gy === this.current.y) return;\n const ctx = this.ctx;\n ctx.globalAlpha = 0.25;\n const ghost: Piece = { ...this.current, y: gy };\n this.drawPiece(ctx, ghost, -HIDDEN);\n ctx.globalAlpha = 1;\n }\n\n private drawPiece(ctx: CanvasRenderingContext2D, piece: Piece, yOffset: number): void {\n for (let r = 0; r < piece.matrix.length; r++) {\n for (let c = 0; c < piece.matrix[r].length; c++) {\n if (!piece.matrix[r][c]) continue;\n const px = piece.x + c;\n const py = piece.y + r + yOffset;\n if (py < 0) continue;\n this.drawBlock(ctx, px, py, piece.color);\n }\n }\n }\n\n private drawBlock(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number = BLOCK): void {\n const px = x * size;\n const py = y * size;\n const pad = size * 0.05;\n\n // Base fill\n ctx.fillStyle = color;\n ctx.fillRect(px + pad, py + pad, size - pad * 2, size - pad * 2);\n\n // Highlight (top-left)\n ctx.fillStyle = \"rgba(255,255,255,0.35)\";\n ctx.fillRect(px + pad, py + pad, size - pad * 2, pad * 2);\n ctx.fillRect(px + pad, py + pad, pad * 2, size - pad * 2);\n\n // Shadow (bottom-right)\n ctx.fillStyle = \"rgba(0,0,0,0.3)\";\n ctx.fillRect(px + pad, py + size - pad * 3, size - pad * 2, pad * 2);\n ctx.fillRect(px + size - pad * 3, py + pad, pad * 2, size - pad * 2);\n }\n\n private drawParticles(): void {\n const ctx = this.ctx;\n for (const p of this.particles) {\n ctx.globalAlpha = p.alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n\n private drawNext(): void {\n const ctx = this.nextCtx;\n const next3 = this.bag.peek(3);\n const cellW = 4;\n const cellH = 3;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n next3.forEach((key, idx) => {\n const matrix = TETROMINOES[key];\n const color = COLORS[key];\n const offX = Math.floor((cellW - matrix[0].length) / 2);\n const offY = Math.floor((cellH - matrix.length) / 2);\n const baseY = idx * cellH;\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, baseY + offY + r, color, bSize);\n }\n }\n });\n }\n\n private drawHold(): void {\n const ctx = this.holdCtx;\n const bSize = 22;\n\n ctx.clearRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n ctx.fillStyle = \"#0e0e1a\";\n ctx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);\n\n if (!this.holdKey) return;\n const matrix = TETROMINOES[this.holdKey];\n const color = this.holdUsed ? \"#555\" : COLORS[this.holdKey];\n const offX = Math.floor((4 - matrix[0].length) / 2);\n const offY = Math.floor((3 - matrix.length) / 2);\n\n for (let r = 0; r < matrix.length; r++) {\n for (let c = 0; c < matrix[r].length; c++) {\n if (!matrix[r][c]) continue;\n this.drawBlock(ctx, offX + c, offY + r, color, bSize);\n }\n }\n }\n\n // ── HUD ──────────────────────────────────────────────────────────────────\n\n private updateHUD(): void {\n this.scoreEl.textContent = this.score.toLocaleString();\n this.linesEl.textContent = String(this.lines);\n this.levelEl.textContent = String(this.level);\n }\n\n private showOverlay(title: string, msg: string): void {\n this.overlayTitle.textContent = title;\n this.overlayMsg.textContent = msg;\n this.overlayEl.classList.remove(\"hidden\");\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add(\"hidden\");\n }\n\n // ── Key Bindings ─────────────────────────────────────────────────────────\n\n private bindKeys(): void {\n // DAS (Delayed Auto Shift) state\n const DAS_DELAY = 170;\n const DAS_RATE = 50;\n const dasState: Record<string, { active: boolean; timer: ReturnType<typeof setTimeout> | null; interval: ReturnType<typeof setInterval> | null }> = {};\n\n const startDAS = (key: string, fn: () => void) => {\n if (dasState[key]?.active) return;\n fn();\n dasState[key] = {\n active: true,\n timer: setTimeout(() => {\n dasState[key].interval = setInterval(fn, DAS_RATE);\n }, DAS_DELAY),\n interval: null,\n };\n };\n\n const stopDAS = (key: string) => {\n if (!dasState[key]) return;\n clearTimeout(dasState[key].timer!);\n clearInterval(dasState[key].interval!);\n dasState[key].active = false;\n };\n\n window.addEventListener(\"keydown\", (e) => {\n if (!this.started || this.gameOver) {\n if (e.code === \"Space\" || e.code === \"Enter\") this.start();\n return;\n }\n\n switch (e.code) {\n case \"ArrowLeft\":\n e.preventDefault();\n startDAS(\"left\", () => {\n if (!this.paused) { this.move(-1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowRight\":\n e.preventDefault();\n startDAS(\"right\", () => {\n if (!this.paused) { this.move(1, 0); this.resetLockDelay(); }\n });\n break;\n case \"ArrowDown\":\n e.preventDefault();\n startDAS(\"down\", () => {\n if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }\n });\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"KeyZ\":\n e.preventDefault();\n if (!this.paused) { this.rotate(-1); }\n break;\n case \"KeyX\":\n e.preventDefault();\n if (!this.paused) { this.rotate(1); }\n break;\n case \"Space\":\n e.preventDefault();\n if (this.paused) { this.togglePause(); return; }\n this.hardDrop();\n break;\n case \"KeyC\":\n case \"ShiftLeft\":\n case \"ShiftRight\":\n e.preventDefault();\n if (!this.paused) this.hold();\n break;\n case \"KeyP\":\n case \"Escape\":\n e.preventDefault();\n this.togglePause();\n break;\n case \"Enter\":\n e.preventDefault();\n if (this.paused) this.togglePause();\n break;\n }\n });\n\n window.addEventListener(\"keyup\", (e) => {\n if (e.code === \"ArrowLeft\") stopDAS(\"left\");\n if (e.code === \"ArrowRight\") stopDAS(\"right\");\n if (e.code === \"ArrowDown\") stopDAS(\"down\");\n });\n }\n}\n\n// ─── Bootstrap ───────────────────────────────────────────────────────────────\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n new Tetris();\n});\n","structuredPatch":[{"oldStart":683,"oldLines":7,"newStart":683,"newLines":7,"lines":[" case \"ArrowDown\":"," e.preventDefault();"," startDAS(\"down\", () => {","- if (!this.paused) { this.move(0, 1); this.resetLockDelay(); }","+ if (!this.paused) { this.move(0, 1, true); this.resetLockDelay(); }"," });"," break;"," case \"ArrowUp\":"]}],"userModified":false,"replaceAll":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01HjXyTbwtM5mKwz9M34a8KC","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01VaJYgTp3kKCdCA4mKzKEip","name":"Bash","input":{"command":"npx tsc --noEmit 2>&1 && echo \"✓ No errors\"","description":"Final type-check"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":273,"cache_read_input_tokens":33105,"cache_creation":{"ephemeral_5m_input_tokens":273,"ephemeral_1h_input_tokens":0},"output_tokens":55,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"14e7e132-89f0-444c-adb0-2c32834726e4"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01VaJYgTp3kKCdCA4mKzKEip","type":"tool_result","content":"✓ No errors","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"cb93a5ee-96aa-425c-82a9-42c9e80a8cfa","timestamp":"2026-04-05T19:28:45.337Z","tool_use_result":{"stdout":"✓ No errors","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_011WRhWwu6t24AcgiLr8AiQc","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_012wzZstyBNAdfFmJt6cpqe5","name":"Bash","input":{"command":"rm -rf /tmp/loop-bench-elvty8os/dist && npx tsc && echo \"✓ Compiled successfully\" && ls -lh dist/","description":"Final clean build"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":110,"cache_read_input_tokens":33378,"cache_creation":{"ephemeral_5m_input_tokens":110,"ephemeral_1h_input_tokens":0},"output_tokens":51,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"bd023c29-8633-4774-9ba9-81f3d8c03424"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_012wzZstyBNAdfFmJt6cpqe5","type":"tool_result","content":"✓ Compiled successfully\ntotal 28K\n-rw-r--r-- 1 root root 25K Apr 5 21:28 tetris.js","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"af79ef3d-4be3-4961-8db9-4c96d6804da3","timestamp":"2026-04-05T19:28:48.784Z","tool_use_result":{"stdout":"✓ Compiled successfully\ntotal 28K\n-rw-r--r-- 1 root root 25K Apr 5 21:28 tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_013S5b7276voaKm1Q8VnTSam","type":"message","role":"assistant","content":[{"type":"text","text":"All good. Let me verify the final project structure one more time:"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":160,"cache_read_input_tokens":33488,"cache_creation":{"ephemeral_5m_input_tokens":160,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"23e0fd06-290d-4d77-ab62-0452ae32d27f"} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_013S5b7276voaKm1Q8VnTSam","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01X3jznDGsp82KqcUUDE9nvJ","name":"Bash","input":{"command":"find /tmp/loop-bench-elvty8os -not -path '*/node_modules/*' -not -path '*/.git/*' -type f | sort","description":"List all project files (excluding node_modules)"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":160,"cache_read_input_tokens":33488,"cache_creation":{"ephemeral_5m_input_tokens":160,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"0bdbb29b-09d6-4905-8cd6-073a31d90d4b"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01X3jznDGsp82KqcUUDE9nvJ","type":"tool_result","content":"/tmp/loop-bench-elvty8os/dist/tetris.js\n/tmp/loop-bench-elvty8os/index.html\n/tmp/loop-bench-elvty8os/package.json\n/tmp/loop-bench-elvty8os/package-lock.json\n/tmp/loop-bench-elvty8os/src/tetris.ts\n/tmp/loop-bench-elvty8os/tsconfig.json","is_error":false}]},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"16f11293-0592-477e-b856-7fa3dd27b42c","timestamp":"2026-04-05T19:28:50.881Z","tool_use_result":{"stdout":"/tmp/loop-bench-elvty8os/dist/tetris.js\n/tmp/loop-bench-elvty8os/index.html\n/tmp/loop-bench-elvty8os/package.json\n/tmp/loop-bench-elvty8os/package-lock.json\n/tmp/loop-bench-elvty8os/src/tetris.ts\n/tmp/loop-bench-elvty8os/tsconfig.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01NNE4FeoW5aGaqpN5TaHRFk","type":"message","role":"assistant","content":[{"type":"text","text":"The Tetris game is complete. Here's a summary of everything built:\n\n---\n\n## Project Structure\n\n```\nindex.html ← The game page (open this in a browser)\nsrc/tetris.ts ← Full TypeScript source (~730 lines)\ndist/tetris.js ← Compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config (ES2020, strict mode)\npackage.json ← npm build script\n```\n\n## How to play\nOpen `index.html` in any modern browser — no server needed. Alternatively rebuild anytime with `npm run build`.\n\n## What's implemented\n\n### Core mechanics\n| Feature | Detail |\n|---|---|\n| **7 tetrominoes** | I, O, T, S, Z, J, L — all standard shapes |\n| **7-bag randomiser** | Guarantees each piece appears once per 7-piece cycle |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces |\n| **Ghost piece** | Semi-transparent preview showing where the piece will land |\n| **Hold queue** | Store one piece (greys out if already used this turn) |\n| **Next preview** | Shows the next 3 upcoming pieces |\n| **Lock delay** | 500 ms grace period + up to 15 moves before a piece locks |\n| **Line clearing** | Clears 1–4 lines; the grid rows collapse correctly |\n| **Scoring** | 100/300/500/800 × level per 1/2/3/4 lines; +1 soft-drop, +2×rows hard-drop |\n| **Increasing speed** | Drops from 1000 ms → 50 ms as level increases (every 10 lines) |\n| **Game over** | Detected on spawn collision |\n| **Particles** | Burst of colourful particles on every line clear |\n\n### Controls\n| Key | Action |\n|---|---|\n| `← / →` | Move left/right (with DAS auto-repeat) |\n| `↓` | Soft drop (+1 pt/row) |\n| `Space` | Hard drop (+2 pts/row) |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` or `Shift` | Hold piece |\n| `P` or `Esc` | Pause / resume |\n| `Enter` | Start / unpause |"}],"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":243,"cache_read_input_tokens":33648,"cache_creation":{"ephemeral_5m_input_tokens":243,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","uuid":"d07ea374-285b-49ca-a29a-980ff5db5eff"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":359869,"duration_api_ms":355437,"num_turns":30,"result":"The Tetris game is complete. Here's a summary of everything built:\n\n---\n\n## Project Structure\n\n```\nindex.html ← The game page (open this in a browser)\nsrc/tetris.ts ← Full TypeScript source (~730 lines)\ndist/tetris.js ← Compiled output (loaded by index.html)\ntsconfig.json ← TypeScript config (ES2020, strict mode)\npackage.json ← npm build script\n```\n\n## How to play\nOpen `index.html` in any modern browser — no server needed. Alternatively rebuild anytime with `npm run build`.\n\n## What's implemented\n\n### Core mechanics\n| Feature | Detail |\n|---|---|\n| **7 tetrominoes** | I, O, T, S, Z, J, L — all standard shapes |\n| **7-bag randomiser** | Guarantees each piece appears once per 7-piece cycle |\n| **SRS rotation** | Full Super Rotation System wall-kick tables for all pieces |\n| **Ghost piece** | Semi-transparent preview showing where the piece will land |\n| **Hold queue** | Store one piece (greys out if already used this turn) |\n| **Next preview** | Shows the next 3 upcoming pieces |\n| **Lock delay** | 500 ms grace period + up to 15 moves before a piece locks |\n| **Line clearing** | Clears 1–4 lines; the grid rows collapse correctly |\n| **Scoring** | 100/300/500/800 × level per 1/2/3/4 lines; +1 soft-drop, +2×rows hard-drop |\n| **Increasing speed** | Drops from 1000 ms → 50 ms as level increases (every 10 lines) |\n| **Game over** | Detected on spawn collision |\n| **Particles** | Burst of colourful particles on every line clear |\n\n### Controls\n| Key | Action |\n|---|---|\n| `← / →` | Move left/right (with DAS auto-repeat) |\n| `↓` | Soft drop (+1 pt/row) |\n| `Space` | Hard drop (+2 pts/row) |\n| `↑` or `X` | Rotate clockwise |\n| `Z` | Rotate counter-clockwise |\n| `C` or `Shift` | Hold piece |\n| `P` or `Esc` | Pause / resume |\n| `Enter` | Start / unpause |","stop_reason":"end_turn","session_id":"2fdcd06b-7925-460c-b703-4f9dca96c49d","total_cost_usd":0.68018355,"usage":{"input_tokens":33,"cache_creation_input_tokens":34885,"cache_read_input_tokens":520386,"output_tokens":26210,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":34885},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":33,"outputTokens":26210,"cacheReadInputTokens":520386,"cacheCreationInputTokens":34885,"webSearchRequests":0,"costUSD":0.68018355,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"1b817903-1fc2-4678-baee-f862f9ac078d"}

Impressum · Datenschutz