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 a581eb64b6ee2f4ae51713167e36114abe29c336
parent 7cad71376c1153a15b0ef0e87176d2c5ee230578
Author: Brian Graham <brian@buildingbetterteams.de>
Date:   Tue,  7 Apr 2026 10:52:12 +0200

Checkpoint: 30 runs (240 total)

Diffstat:
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/README.md | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.js | 387+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.ts | 504+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/index.html | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package-lock.json | 2519+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package.json | 21+++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/styles.css | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/playwright.config.ts | 13+++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/tetris.spec.ts | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/playwright.config.ts | 13+++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/tetris.spec.ts | 474+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tsconfig.json | 14++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/README.md | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/index.html | 42++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package-lock.json | 2519+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package.json | 27+++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/styles.css | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/playwright.config.ts | 13+++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/tetris.spec.ts | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/playwright.config.ts | 13+++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/tetris.spec.ts | 474+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.js | 361+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aartifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.ts | 463+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mresults/analysis/main_effects_build_quality.json | 174++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_code_quality.json | 222++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_cost.json | 206++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_gameplay.json | 224++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_score.json | 226++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_sonarqube.json | 242++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_structural.json | 192++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_transcript.json | 184++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_turns.json | 226++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/analysis/main_effects_wall_time.json | 204++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mresults/index.jsonl | 2++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_output.json | 2++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_stderr.log | 0
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/eval_results.json | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/meta.json | 41+++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/transcript.jsonl | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_output.json | 2++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_stderr.log | 0
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/eval_results.json | 275+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/gameplay-bot-report.json | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/meta.json | 41+++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/transcript.jsonl | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/claude_stderr.log | 0
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/meta.json | 38++++++++++++++++++++++++++++++++++++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/transcript.jsonl | 4++++
Aresults/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run2/meta.json | 38++++++++++++++++++++++++++++++++++++++
49 files changed, 10428 insertions(+), 1050 deletions(-)

diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/README.md b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/README.md @@ -0,0 +1,59 @@ +# Tetris Game + +A fully playable Tetris game built with TypeScript, HTML5 Canvas, and CSS3. + +## Features + +- All standard Tetris mechanics + - 7 Tetromino shapes (I, O, T, S, Z, J, L) + - Piece rotation with wall kicks + - Line clearing with scoring + - Increasing speed/level progression +- Ghost piece preview +- Next piece display +- Score, level, and lines tracking +- Pause functionality + +## Controls + +| Key | Action | +|-----|--------| +| ← / → | Move left/right | +| ↑ | Rotate piece | +| ↓ | Soft drop (faster fall + points) | +| Space | Hard drop (instant drop + points) | +| P | Pause/Resume game | + +## Scoring + +- Soft drop: 1 point per cell +- Hard drop: 2 points per cell +- Line clears: + - 1 line: 100 × level + - 2 lines: 300 × level + - 3 lines: 500 × level + - 4 lines (Tetris): 800 × level + +## How to Play + +1. Open the game in a web browser by visiting `http://localhost:8080` +2. Click the START button to begin +3. Use the keyboard controls to manipulate pieces +4. Clear lines to score points and advance levels +5. Game speeds up every 10 lines cleared +6. Try to get the highest score possible! + +## Files + +- `index.html` - Main game HTML structure +- `styles.css` - Game styling and animations +- `game.ts` - TypeScript game logic +- `game.js` - Compiled JavaScript (generated) +- `tsconfig.json` - TypeScript configuration + +To rebuild the JavaScript after modifying `game.ts`: +```bash +npx tsc +``` + +Then refresh your browser. diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.js b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.js @@ -0,0 +1,387 @@ +"use strict"; +const COLS = 10; +const ROWS = 20; +const BLOCK_SIZE = 30; +const TETROMINOES = [ + { shape: [[1, 1, 1, 1]], color: '#00f0f0', id: 1 }, // I + { shape: [[1, 1], [1, 1]], color: '#f0f000', id: 2 }, // O + { shape: [[0, 1, 0], [1, 1, 1]], color: '#a000f0', id: 3 }, // T + { shape: [[0, 1, 1], [1, 1, 0]], color: '#00f000', id: 4 }, // S + { shape: [[1, 1, 0], [0, 1, 1]], color: '#f00000', id: 5 }, // Z + { shape: [[1, 0, 0], [1, 1, 1]], color: '#0000f0', id: 6 }, // J + { shape: [[0, 0, 1], [1, 1, 1]], color: '#f0a000', id: 7 }, // L +]; +class Tetris { + constructor() { + this.canvas = document.getElementById('game'); + this.ctx = this.canvas.getContext('2d'); + this.nextCanvas = document.getElementById('next'); + this.nextCtx = this.nextCanvas.getContext('2d'); + this.startBtn = document.getElementById('start-btn'); + this.restartBtn = document.getElementById('restart-btn'); + this.gameOverEl = document.getElementById('game-over'); + this.scoreEl = document.getElementById('score'); + this.levelEl = document.getElementById('level'); + this.linesEl = document.getElementById('lines'); + this.finalScoreEl = document.getElementById('final-score'); + this.state = this.createInitialState(); + this.dropInterval = 1000; + this.lastDropTime = 0; + this.animationId = 0; + this.init(); + } + createInitialState() { + return { + board: Array.from({ length: ROWS }, () => Array(COLS).fill(null)), + currentPiece: null, + nextPiece: null, + score: 0, + level: 1, + lines: 0, + isGameOver: false, + isPaused: false, + isPlaying: false, + }; + } + init() { + this.startBtn.addEventListener('click', () => this.startGame()); + this.restartBtn.addEventListener('click', () => this.startGame()); + document.addEventListener('keydown', (e) => this.handleKeyPress(e)); + this.drawEmptyBoard(); + } + startGame() { + this.state = this.createInitialState(); + this.state.isPlaying = true; + this.state.nextPiece = this.getRandomPiece(); + this.spawnNewPiece(); + this.dropInterval = 1000; + this.lastDropTime = performance.now(); + this.gameOverEl.classList.add('hidden'); + this.startBtn.classList.add('hidden'); + this.restartBtn.classList.add('hidden'); + this.updateDisplay(); + this.gameLoop(); + } + gameLoop(timestamp = 0) { + if (!this.state.isPlaying) + return; + if (!this.state.isPaused) { + if (timestamp - this.lastDropTime > this.dropInterval) { + this.drop(); + this.lastDropTime = timestamp; + } + this.draw(); + this.drawNextPiece(); + } + this.animationId = requestAnimationFrame((ts) => this.gameLoop(ts)); + } + getRandomPiece() { + const randomIndex = Math.floor(Math.random() * TETROMINOES.length); + return Object.assign({}, TETROMINOES[randomIndex]); + } + spawnNewPiece() { + const piece = this.state.nextPiece || this.getRandomPiece(); + const shape = piece.shape.map(row => [...row]); + this.state.currentPiece = { + shape, + color: piece.color, + id: piece.id, + x: Math.floor((COLS - shape[0].length) / 2), + y: 0, + }; + this.state.nextPiece = this.getRandomPiece(); + if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) { + this.gameOver(); + } + } + checkCollision(x, y, shape) { + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const newX = x + col; + const newY = y + row; + if (newX < 0 || newX >= COLS || newY >= ROWS) { + return true; + } + if (newY >= 0 && this.state.board[newY][newX]) { + return true; + } + } + } + } + return false; + } + move(dx, dy) { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) + return; + const newX = this.state.currentPiece.x + dx; + const newY = this.state.currentPiece.y + dy; + if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) { + this.state.currentPiece.x = newX; + this.state.currentPiece.y = newY; + } + else if (dy > 0) { + this.lockPiece(); + } + } + rotate() { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) + return; + const shape = this.state.currentPiece.shape; + const rows = shape.length; + const cols = shape[0].length; + const rotated = Array.from({ length: cols }, () => Array(rows).fill(0)); + for (let row = 0; row < rows; row++) { + for (let col = 0; col < cols; col++) { + rotated[col][rows - 1 - row] = shape[row][col]; + } + } + // Wall kick - try to adjust position if rotation causes collision + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) { + this.state.currentPiece.shape = rotated; + this.state.currentPiece.x += kick; + return; + } + } + } + hardDrop() { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) + return; + while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) { + this.state.currentPiece.y++; + this.state.score += 2; // Bonus points for hard drop + } + this.lockPiece(); + } + drop() { + this.move(0, 1); + } + lockPiece() { + if (!this.state.currentPiece) + return; + const { shape, color, x, y } = this.state.currentPiece; + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const boardY = y + row; + const boardX = x + col; + if (boardY >= 0 && boardY < ROWS && boardX >= 0 && boardX < COLS) { + this.state.board[boardY][boardX] = color; + } + } + } + } + this.clearLines(); + this.spawnNewPiece(); + this.updateDisplay(); + } + clearLines() { + let linesCleared = 0; + for (let row = ROWS - 1; row >= 0; row--) { + if (this.state.board[row].every(cell => cell !== null)) { + this.state.board.splice(row, 1); + this.state.board.unshift(Array(COLS).fill(null)); + linesCleared++; + row++; // Check the same row again + } + } + if (linesCleared > 0) { + const points = [0, 100, 300, 500, 800]; + this.state.score += points[linesCleared] * this.state.level; + this.state.lines += linesCleared; + // Level up every 10 lines + const newLevel = Math.floor(this.state.lines / 10) + 1; + if (newLevel > this.state.level) { + this.state.level = newLevel; + // Increase speed (decrease drop interval) + this.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100); + } + } + } + gameOver() { + this.state.isGameOver = true; + this.state.isPlaying = false; + cancelAnimationFrame(this.animationId); + this.finalScoreEl.textContent = `Final Score: ${this.state.score}`; + this.gameOverEl.classList.remove('hidden'); + this.restartBtn.classList.remove('hidden'); + } + handleKeyPress(e) { + if (!this.state.isPlaying || this.state.isGameOver) + return; + switch (e.key) { + case 'ArrowLeft': + e.preventDefault(); + this.move(-1, 0); + break; + case 'ArrowRight': + e.preventDefault(); + this.move(1, 0); + break; + case 'ArrowDown': + e.preventDefault(); + this.move(0, 1); + this.state.score += 1; // Soft drop bonus + this.updateDisplay(); + break; + case 'ArrowUp': + e.preventDefault(); + this.rotate(); + break; + case ' ': + e.preventDefault(); + this.hardDrop(); + break; + case 'p': + case 'P': + e.preventDefault(); + this.state.isPaused = !this.state.isPaused; + if (!this.state.isPaused) { + this.lastDropTime = performance.now(); + } + break; + } + } + draw() { + this.ctx.fillStyle = '#0a0a0a'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + // Draw grid + this.ctx.strokeStyle = '#1a1a1a'; + this.ctx.lineWidth = 1; + for (let x = 0; x <= COLS; x++) { + this.ctx.beginPath(); + this.ctx.moveTo(x * BLOCK_SIZE, 0); + this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE); + this.ctx.stroke(); + } + for (let y = 0; y <= ROWS; y++) { + this.ctx.beginPath(); + this.ctx.moveTo(0, y * BLOCK_SIZE); + this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE); + this.ctx.stroke(); + } + // Draw board + for (let row = 0; row < ROWS; row++) { + for (let col = 0; col < COLS; col++) { + if (this.state.board[row][col]) { + this.drawBlock(col, row, this.state.board[row][col]); + } + } + } + // Draw ghost piece + if (this.state.currentPiece) { + const ghostY = this.getGhostY(); + this.ctx.globalAlpha = 0.3; + for (let row = 0; row < this.state.currentPiece.shape.length; row++) { + for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) { + if (this.state.currentPiece.shape[row][col]) { + this.drawBlock(this.state.currentPiece.x + col, ghostY + row, this.state.currentPiece.color); + } + } + } + this.ctx.globalAlpha = 1; + } + // Draw current piece + if (this.state.currentPiece) { + for (let row = 0; row < this.state.currentPiece.shape.length; row++) { + for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) { + if (this.state.currentPiece.shape[row][col]) { + this.drawBlock(this.state.currentPiece.x + col, this.state.currentPiece.y + row, this.state.currentPiece.color); + } + } + } + } + // Draw pause overlay + if (this.state.isPaused) { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.fillStyle = '#fff'; + this.ctx.font = 'bold 36px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('PAUSED', this.canvas.width / 2, this.canvas.height / 2); + } + } + getGhostY() { + if (!this.state.currentPiece) + return 0; + let ghostY = this.state.currentPiece.y; + while (!this.checkCollision(this.state.currentPiece.x, ghostY + 1, this.state.currentPiece.shape)) { + ghostY++; + } + return ghostY; + } + drawBlock(x, y, color) { + const px = x * BLOCK_SIZE; + const py = y * BLOCK_SIZE; + // Main block + this.ctx.fillStyle = color; + this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2); + // Highlight + this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, 4); + this.ctx.fillRect(px + 1, py + 1, 4, BLOCK_SIZE - 2); + // Shadow + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.ctx.fillRect(px + 1, py + BLOCK_SIZE - 5, BLOCK_SIZE - 2, 4); + this.ctx.fillRect(px + BLOCK_SIZE - 5, py + 1, 4, BLOCK_SIZE - 2); + } + drawNextPiece() { + this.nextCtx.fillStyle = '#0a0a0a'; + this.nextCtx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height); + if (!this.state.nextPiece) + return; + const piece = this.state.nextPiece; + const blockSize = 20; + const offsetX = (this.nextCanvas.width - piece.shape[0].length * blockSize) / 2; + const offsetY = (this.nextCanvas.height - piece.shape.length * blockSize) / 2; + for (let row = 0; row < piece.shape.length; row++) { + for (let col = 0; col < piece.shape[row].length; col++) { + if (piece.shape[row][col]) { + const px = offsetX + col * blockSize; + const py = offsetY + row * blockSize; + this.nextCtx.fillStyle = piece.color; + this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, blockSize - 2); + this.nextCtx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, 3); + this.nextCtx.fillRect(px + 1, py + 1, 3, blockSize - 2); + this.nextCtx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.nextCtx.fillRect(px + 1, py + blockSize - 4, blockSize - 2, 3); + this.nextCtx.fillRect(px + blockSize - 4, py + 1, 3, blockSize - 2); + } + } + } + } + drawEmptyBoard() { + this.ctx.fillStyle = '#0a0a0a'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.strokeStyle = '#1a1a1a'; + this.ctx.lineWidth = 1; + for (let x = 0; x <= COLS; x++) { + this.ctx.beginPath(); + this.ctx.moveTo(x * BLOCK_SIZE, 0); + this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE); + this.ctx.stroke(); + } + for (let y = 0; y <= ROWS; y++) { + this.ctx.beginPath(); + this.ctx.moveTo(0, y * BLOCK_SIZE); + this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE); + this.ctx.stroke(); + } + this.ctx.fillStyle = '#fff'; + this.ctx.font = 'bold 24px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('Press START', this.canvas.width / 2, this.canvas.height / 2); + } + updateDisplay() { + this.scoreEl.textContent = this.state.score.toString(); + this.levelEl.textContent = this.state.level.toString(); + this.linesEl.textContent = this.state.lines.toString(); + } +} +// Initialize game when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + new Tetris(); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/game.ts @@ -0,0 +1,504 @@ +// Tetromino shapes and their colors +interface Tetromino { + shape: number[][]; + color: string; + id: number; +} + +interface GameState { + board: (string | null)[][]; + currentPiece: { + shape: number[][]; + color: string; + id: number; + x: number; + y: number; + } | null; + nextPiece: { + shape: number[][]; + color: string; + id: number; + } | null; + score: number; + level: number; + lines: number; + isGameOver: boolean; + isPaused: boolean; + isPlaying: boolean; +} + +const COLS = 10; +const ROWS = 20; +const BLOCK_SIZE = 30; + +const TETROMINOES: Tetromino[] = [ + { shape: [[1, 1, 1, 1]], color: '#00f0f0', id: 1 }, // I + { shape: [[1, 1], [1, 1]], color: '#f0f000', id: 2 }, // O + { shape: [[0, 1, 0], [1, 1, 1]], color: '#a000f0', id: 3 }, // T + { shape: [[0, 1, 1], [1, 1, 0]], color: '#00f000', id: 4 }, // S + { shape: [[1, 1, 0], [0, 1, 1]], color: '#f00000', id: 5 }, // Z + { shape: [[1, 0, 0], [1, 1, 1]], color: '#0000f0', id: 6 }, // J + { shape: [[0, 0, 1], [1, 1, 1]], color: '#f0a000', id: 7 }, // L +]; + +class Tetris { + private canvas: HTMLCanvasElement; + private ctx: CanvasRenderingContext2D; + private nextCanvas: HTMLCanvasElement; + private nextCtx: CanvasRenderingContext2D; + private startBtn: HTMLButtonElement; + private restartBtn: HTMLButtonElement; + private gameOverEl: HTMLElement; + private scoreEl: HTMLElement; + private levelEl: HTMLElement; + private linesEl: HTMLElement; + private finalScoreEl: HTMLElement; + + private state: GameState; + private dropInterval: number; + private lastDropTime: number; + private animationId: number; + + constructor() { + this.canvas = document.getElementById('game') as HTMLCanvasElement; + this.ctx = this.canvas.getContext('2d')!; + this.nextCanvas = document.getElementById('next') as HTMLCanvasElement; + this.nextCtx = this.nextCanvas.getContext('2d')!; + + this.startBtn = document.getElementById('start-btn') as HTMLButtonElement; + this.restartBtn = document.getElementById('restart-btn') as HTMLButtonElement; + this.gameOverEl = document.getElementById('game-over') as HTMLElement; + this.scoreEl = document.getElementById('score') as HTMLElement; + this.levelEl = document.getElementById('level') as HTMLElement; + this.linesEl = document.getElementById('lines') as HTMLElement; + this.finalScoreEl = document.getElementById('final-score') as HTMLElement; + + this.state = this.createInitialState(); + this.dropInterval = 1000; + this.lastDropTime = 0; + this.animationId = 0; + + this.init(); + } + + private createInitialState(): GameState { + return { + board: Array.from({ length: ROWS }, () => Array(COLS).fill(null)), + currentPiece: null, + nextPiece: null, + score: 0, + level: 1, + lines: 0, + isGameOver: false, + isPaused: false, + isPlaying: false, + }; + } + + private init(): void { + this.startBtn.addEventListener('click', () => this.startGame()); + this.restartBtn.addEventListener('click', () => this.startGame()); + + document.addEventListener('keydown', (e) => this.handleKeyPress(e)); + + this.drawEmptyBoard(); + } + + private startGame(): void { + this.state = this.createInitialState(); + this.state.isPlaying = true; + this.state.nextPiece = this.getRandomPiece(); + this.spawnNewPiece(); + this.dropInterval = 1000; + this.lastDropTime = performance.now(); + + this.gameOverEl.classList.add('hidden'); + this.startBtn.classList.add('hidden'); + this.restartBtn.classList.add('hidden'); + + this.updateDisplay(); + this.gameLoop(); + } + + private gameLoop(timestamp: number = 0): void { + if (!this.state.isPlaying) return; + + if (!this.state.isPaused) { + if (timestamp - this.lastDropTime > this.dropInterval) { + this.drop(); + this.lastDropTime = timestamp; + } + + this.draw(); + this.drawNextPiece(); + } + + this.animationId = requestAnimationFrame((ts) => this.gameLoop(ts)); + } + + private getRandomPiece(): Tetromino { + const randomIndex = Math.floor(Math.random() * TETROMINOES.length); + return { ...TETROMINOES[randomIndex] }; + } + + private spawnNewPiece(): void { + const piece = this.state.nextPiece || this.getRandomPiece(); + const shape = piece.shape.map(row => [...row]); + + this.state.currentPiece = { + shape, + color: piece.color, + id: piece.id, + x: Math.floor((COLS - shape[0].length) / 2), + y: 0, + }; + + this.state.nextPiece = this.getRandomPiece(); + + if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) { + this.gameOver(); + } + } + + private checkCollision(x: number, y: number, shape: number[][]): boolean { + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const newX = x + col; + const newY = y + row; + + if (newX < 0 || newX >= COLS || newY >= ROWS) { + return true; + } + + if (newY >= 0 && this.state.board[newY][newX]) { + return true; + } + } + } + } + return false; + } + + private move(dx: number, dy: number): void { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return; + + const newX = this.state.currentPiece.x + dx; + const newY = this.state.currentPiece.y + dy; + + if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) { + this.state.currentPiece.x = newX; + this.state.currentPiece.y = newY; + } else if (dy > 0) { + this.lockPiece(); + } + } + + private rotate(): void { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return; + + const shape = this.state.currentPiece.shape; + const rows = shape.length; + const cols = shape[0].length; + + const rotated = Array.from({ length: cols }, () => Array(rows).fill(0)); + + for (let row = 0; row < rows; row++) { + for (let col = 0; col < cols; col++) { + rotated[col][rows - 1 - row] = shape[row][col]; + } + } + + // Wall kick - try to adjust position if rotation causes collision + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) { + this.state.currentPiece.shape = rotated; + this.state.currentPiece.x += kick; + return; + } + } + } + + private hardDrop(): void { + if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return; + + while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) { + this.state.currentPiece.y++; + this.state.score += 2; // Bonus points for hard drop + } + + this.lockPiece(); + } + + private drop(): void { + this.move(0, 1); + } + + private lockPiece(): void { + if (!this.state.currentPiece) return; + + const { shape, color, x, y } = this.state.currentPiece; + + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const boardY = y + row; + const boardX = x + col; + + if (boardY >= 0 && boardY < ROWS && boardX >= 0 && boardX < COLS) { + this.state.board[boardY][boardX] = color; + } + } + } + } + + this.clearLines(); + this.spawnNewPiece(); + this.updateDisplay(); + } + + private clearLines(): void { + let linesCleared = 0; + + for (let row = ROWS - 1; row >= 0; row--) { + if (this.state.board[row].every(cell => cell !== null)) { + this.state.board.splice(row, 1); + this.state.board.unshift(Array(COLS).fill(null)); + linesCleared++; + row++; // Check the same row again + } + } + + if (linesCleared > 0) { + const points = [0, 100, 300, 500, 800]; + this.state.score += points[linesCleared] * this.state.level; + this.state.lines += linesCleared; + + // Level up every 10 lines + const newLevel = Math.floor(this.state.lines / 10) + 1; + if (newLevel > this.state.level) { + this.state.level = newLevel; + // Increase speed (decrease drop interval) + this.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100); + } + } + } + + private gameOver(): void { + this.state.isGameOver = true; + this.state.isPlaying = false; + cancelAnimationFrame(this.animationId); + + this.finalScoreEl.textContent = `Final Score: ${this.state.score}`; + this.gameOverEl.classList.remove('hidden'); + this.restartBtn.classList.remove('hidden'); + } + + private handleKeyPress(e: KeyboardEvent): void { + if (!this.state.isPlaying || this.state.isGameOver) return; + + switch (e.key) { + case 'ArrowLeft': + e.preventDefault(); + this.move(-1, 0); + break; + case 'ArrowRight': + e.preventDefault(); + this.move(1, 0); + break; + case 'ArrowDown': + e.preventDefault(); + this.move(0, 1); + this.state.score += 1; // Soft drop bonus + this.updateDisplay(); + break; + case 'ArrowUp': + e.preventDefault(); + this.rotate(); + break; + case ' ': + e.preventDefault(); + this.hardDrop(); + break; + case 'p': + case 'P': + e.preventDefault(); + this.state.isPaused = !this.state.isPaused; + if (!this.state.isPaused) { + this.lastDropTime = performance.now(); + } + break; + } + } + + private draw(): void { + this.ctx.fillStyle = '#0a0a0a'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + // Draw grid + this.ctx.strokeStyle = '#1a1a1a'; + this.ctx.lineWidth = 1; + for (let x = 0; x <= COLS; x++) { + this.ctx.beginPath(); + this.ctx.moveTo(x * BLOCK_SIZE, 0); + this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE); + this.ctx.stroke(); + } + for (let y = 0; y <= ROWS; y++) { + this.ctx.beginPath(); + this.ctx.moveTo(0, y * BLOCK_SIZE); + this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE); + this.ctx.stroke(); + } + + // Draw board + for (let row = 0; row < ROWS; row++) { + for (let col = 0; col < COLS; col++) { + if (this.state.board[row][col]) { + this.drawBlock(col, row, this.state.board[row][col]!); + } + } + } + + // Draw ghost piece + if (this.state.currentPiece) { + const ghostY = this.getGhostY(); + this.ctx.globalAlpha = 0.3; + for (let row = 0; row < this.state.currentPiece.shape.length; row++) { + for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) { + if (this.state.currentPiece.shape[row][col]) { + this.drawBlock( + this.state.currentPiece.x + col, + ghostY + row, + this.state.currentPiece.color + ); + } + } + } + this.ctx.globalAlpha = 1; + } + + // Draw current piece + if (this.state.currentPiece) { + for (let row = 0; row < this.state.currentPiece.shape.length; row++) { + for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) { + if (this.state.currentPiece.shape[row][col]) { + this.drawBlock( + this.state.currentPiece.x + col, + this.state.currentPiece.y + row, + this.state.currentPiece.color + ); + } + } + } + } + + // Draw pause overlay + if (this.state.isPaused) { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.fillStyle = '#fff'; + this.ctx.font = 'bold 36px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('PAUSED', this.canvas.width / 2, this.canvas.height / 2); + } + } + + private getGhostY(): number { + if (!this.state.currentPiece) return 0; + + let ghostY = this.state.currentPiece.y; + while (!this.checkCollision(this.state.currentPiece.x, ghostY + 1, this.state.currentPiece.shape)) { + ghostY++; + } + return ghostY; + } + + private drawBlock(x: number, y: number, color: string): void { + const px = x * BLOCK_SIZE; + const py = y * BLOCK_SIZE; + + // Main block + this.ctx.fillStyle = color; + this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2); + + // Highlight + this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, 4); + this.ctx.fillRect(px + 1, py + 1, 4, BLOCK_SIZE - 2); + + // Shadow + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.ctx.fillRect(px + 1, py + BLOCK_SIZE - 5, BLOCK_SIZE - 2, 4); + this.ctx.fillRect(px + BLOCK_SIZE - 5, py + 1, 4, BLOCK_SIZE - 2); + } + + private drawNextPiece(): void { + this.nextCtx.fillStyle = '#0a0a0a'; + this.nextCtx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height); + + if (!this.state.nextPiece) return; + + const piece = this.state.nextPiece; + const blockSize = 20; + const offsetX = (this.nextCanvas.width - piece.shape[0].length * blockSize) / 2; + const offsetY = (this.nextCanvas.height - piece.shape.length * blockSize) / 2; + + for (let row = 0; row < piece.shape.length; row++) { + for (let col = 0; col < piece.shape[row].length; col++) { + if (piece.shape[row][col]) { + const px = offsetX + col * blockSize; + const py = offsetY + row * blockSize; + + this.nextCtx.fillStyle = piece.color; + this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, blockSize - 2); + + this.nextCtx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, 3); + this.nextCtx.fillRect(px + 1, py + 1, 3, blockSize - 2); + + this.nextCtx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.nextCtx.fillRect(px + 1, py + blockSize - 4, blockSize - 2, 3); + this.nextCtx.fillRect(px + blockSize - 4, py + 1, 3, blockSize - 2); + } + } + } + } + + private drawEmptyBoard(): void { + this.ctx.fillStyle = '#0a0a0a'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + this.ctx.strokeStyle = '#1a1a1a'; + this.ctx.lineWidth = 1; + for (let x = 0; x <= COLS; x++) { + this.ctx.beginPath(); + this.ctx.moveTo(x * BLOCK_SIZE, 0); + this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE); + this.ctx.stroke(); + } + for (let y = 0; y <= ROWS; y++) { + this.ctx.beginPath(); + this.ctx.moveTo(0, y * BLOCK_SIZE); + this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE); + this.ctx.stroke(); + } + + this.ctx.fillStyle = '#fff'; + this.ctx.font = 'bold 24px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('Press START', this.canvas.width / 2, this.canvas.height / 2); + } + + private updateDisplay(): void { + this.scoreEl.textContent = this.state.score.toString(); + this.levelEl.textContent = this.state.level.toString(); + this.linesEl.textContent = this.state.lines.toString(); + } +} + +// Initialize game when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + new Tetris(); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/index.html b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/index.html @@ -0,0 +1,52 @@ +<!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="styles.css"> +</head> +<body> + <div class="container"> + <div class="game-container"> + <canvas id="game" width="300" height="600"></canvas> + </div> + <div class="sidebar"> + <h1>TETRIS</h1> + <div class="score-display"> + <div class="score-label">SCORE</div> + <div id="score" class="score-value">0</div> + </div> + <div class="score-display"> + <div class="score-label">LEVEL</div> + <div id="level" class="score-value">1</div> + </div> + <div class="score-display"> + <div class="score-label">LINES</div> + <div id="lines" class="score-value">0</div> + </div> + <div class="next-piece"> + <div class="score-label">NEXT</div> + <canvas id="next" width="100" height="100"></canvas> + </div> + <div class="controls"> + <div class="score-label">CONTROLS</div> + <div class="control-item">← → : Move</div> + <div class="control-item">↑ : Rotate</div> + <div class="control-item">↓ : Soft Drop</div> + <div class="control-item">SPACE : Hard Drop</div> + <div class="control-item">P : Pause</div> + </div> + <button id="start-btn" class="btn">START</button> + <button id="restart-btn" class="btn hidden">RESTART</button> + </div> + </div> + <div id="game-over" class="game-over hidden"> + <div class="game-over-content"> + <h2>GAME OVER</h2> + <p id="final-score">Final Score: 0</p> + </div> + </div> + <script src="game.js"></script> +</body> +</html> diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package-lock.json b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package-lock.json @@ -0,0 +1,2519 @@ +{ + "name": "loop-bench-n6dz6e8u", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-n6dz6e8u", + "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.3.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.2.tgz", + "integrity": "sha512-wgWa6FWQ3QRRJbIjbsldRJZxdxYngT/dO0I5Ynmlnin8qy7tC6xYzbcJjtN4wHLXtkbVwHzk0C+OejVw1XM+DQ==", + "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/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package.json b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/package.json @@ -0,0 +1,21 @@ +{ + "name": "loop-bench-n6dz6e8u", + "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/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/styles.css b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/styles.css @@ -0,0 +1,177 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Arial', sans-serif; + background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + color: #fff; +} + +.container { + display: flex; + gap: 40px; + align-items: flex-start; + padding: 40px; + background: rgba(0, 0, 0, 0.3); + border-radius: 20px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); +} + +.game-container { + border: 4px solid #e94560; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 0 20px rgba(233, 69, 96, 0.5); +} + +#game { + display: block; + background: #0a0a0a; +} + +.sidebar { + display: flex; + flex-direction: column; + gap: 20px; + min-width: 200px; +} + +h1 { + font-size: 36px; + text-align: center; + background: linear-gradient(135deg, #e94560, #ff6b6b); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-shadow: 0 0 20px rgba(233, 69, 96, 0.3); +} + +.score-display { + background: rgba(233, 69, 96, 0.1); + border: 2px solid #e94560; + border-radius: 10px; + padding: 15px; + text-align: center; +} + +.score-label { + font-size: 12px; + color: #e94560; + margin-bottom: 5px; + letter-spacing: 2px; +} + +.score-value { + font-size: 28px; + font-weight: bold; + text-shadow: 0 0 10px rgba(233, 69, 96, 0.5); +} + +.next-piece { + background: rgba(233, 69, 96, 0.1); + border: 2px solid #e94560; + border-radius: 10px; + padding: 15px; + text-align: center; +} + +#next { + display: block; + margin: 0 auto; + background: #0a0a0a; + border-radius: 5px; +} + +.controls { + background: rgba(233, 69, 96, 0.1); + border: 2px solid #e94560; + border-radius: 10px; + padding: 15px; +} + +.control-item { + font-size: 12px; + padding: 5px 0; + color: #ccc; +} + +.btn { + background: linear-gradient(135deg, #e94560, #ff6b6b); + border: none; + border-radius: 10px; + padding: 15px 30px; + font-size: 16px; + font-weight: bold; + color: #fff; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 5px 20px rgba(233, 69, 96, 0.4); +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 7px 25px rgba(233, 69, 96, 0.6); +} + +.btn:active { + transform: translateY(0); +} + +.btn.hidden { + display: none; +} + +.game-over { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.game-over.hidden { + display: none; +} + +.game-over-content { + background: linear-gradient(135deg, #1a1a2e, #16213e); + border: 4px solid #e94560; + border-radius: 20px; + padding: 50px; + text-align: center; + box-shadow: 0 0 50px rgba(233, 69, 96, 0.5); + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { + box-shadow: 0 0 50px rgba(233, 69, 96, 0.5); + } + 50% { + box-shadow: 0 0 80px rgba(233, 69, 96, 0.8); + } +} + +.game-over h2 { + font-size: 48px; + margin-bottom: 20px; + color: #e94560; + text-shadow: 0 0 20px rgba(233, 69, 96, 0.8); +} + +.game-over p { + font-size: 24px; + color: #fff; +} diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/playwright.config.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/playwright.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "@playwright/test"; + +export default defineConfig({ + testDir: ".", + timeout: 30_000, + retries: 0, + workers: 1, + use: { + baseURL: "http://localhost:3000", + headless: true, + viewport: { width: 1280, height: 720 }, + }, +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/tetris.spec.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-few/tetris.spec.ts @@ -0,0 +1,96 @@ +import { test, expect, type Page } from "@playwright/test"; + +// Try common entry points until one loads successfully. +async function loadGame(page: Page) { + const candidates = [ + "/", + "/index.html", + "/dist/index.html", + "/public/index.html", + "/build/index.html", + ]; + + for (const path of candidates) { + try { + const resp = await page.goto(path, { timeout: 5000 }); + if (resp?.ok()) return; + } catch { + continue; + } + } +} + +test.describe("Tetris Game", () => { + test.beforeEach(async ({ page }) => { + await loadGame(page); + await page.waitForLoadState("domcontentloaded"); + }); + + test("page loads without console errors", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Give the page a moment to finish initializing + await page.waitForTimeout(2000); + + expect(errors).toEqual([]); + }); + + test("game board is visible", async ({ page }) => { + // A Tetris game should render either a <canvas> or a grid of DOM elements + const canvas = page.locator("canvas"); + const gridContainer = page.locator( + [ + '[class*="board"]', + '[class*="grid"]', + '[class*="game"]', + '[class*="field"]', + '[id*="board"]', + '[id*="grid"]', + '[id*="game"]', + '[id*="field"]', + "table", + ].join(", ") + ); + + const canvasCount = await canvas.count(); + const gridCount = await gridContainer.count(); + + expect( + canvasCount + gridCount, + "Expected a <canvas> or a container with board/grid/game/field in its class or id" + ).toBeGreaterThan(0); + }); + + test("keyboard input does not crash the game", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Press every key a Tetris game should handle + const keys = [ + "ArrowLeft", + "ArrowRight", + "ArrowDown", + "ArrowUp", + "Space", + ]; + for (const key of keys) { + await page.keyboard.press(key); + await page.waitForTimeout(150); + } + + expect(errors).toEqual([]); + }); + + test("game state changes over time", async ({ page }) => { + // If the game is running, the visual output should change as pieces fall + const shot1 = await page.screenshot(); + await page.waitForTimeout(3000); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected the page to visually change over 3 seconds (pieces should be falling)" + ).toBe(false); + }); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/playwright.config.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/playwright.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "@playwright/test"; + +export default defineConfig({ + testDir: ".", + timeout: 60_000, + retries: 0, + workers: 1, + use: { + baseURL: "http://localhost:3000", + headless: true, + viewport: { width: 1280, height: 720 }, + }, +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/tetris.spec.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tests-full/tetris.spec.ts @@ -0,0 +1,474 @@ +import { test, expect, type Page } from "@playwright/test"; + +// Try common entry points until one loads successfully. +async function loadGame(page: Page) { + const candidates = [ + "/", + "/index.html", + "/dist/index.html", + "/public/index.html", + "/build/index.html", + ]; + + for (const path of candidates) { + try { + const resp = await page.goto(path, { timeout: 5000 }); + if (resp?.ok()) return; + } catch { + continue; + } + } +} + +// Find the game surface: canvas or a grid-like DOM container. +function gameBoard(page: Page) { + return page.locator( + [ + "canvas", + '[class*="board"]', + '[class*="grid"]', + '[class*="game-area"]', + '[class*="field"]', + '[id*="board"]', + '[id*="grid"]', + '[id*="game"]', + '[id*="field"]', + "table", + ].join(", ") + ); +} + +// Click the board area to make sure it has focus, then try common +// start interactions in case the game waits for user action. +async function ensureGameStarted(page: Page) { + const board = gameBoard(page); + const count = await board.count(); + if (count > 0) { + try { + await board.first().click({ timeout: 2000 }); + } catch { + // click failed, continue anyway + } + } + + // Some games need a key press or button click to start + const startButton = page.locator( + 'button:has-text("start"), button:has-text("Start"), button:has-text("play"), button:has-text("Play"), [class*="start"], [id*="start"]' + ); + if ((await startButton.count()) > 0) { + try { + await startButton.first().click({ timeout: 2000 }); + } catch { + // ignore + } + } + + // Press Enter/Space as a fallback start trigger + await page.keyboard.press("Enter"); + await page.waitForTimeout(300); + await page.keyboard.press("Space"); + await page.waitForTimeout(500); +} + +test.describe("Tetris Game", () => { + test.beforeEach(async ({ page }) => { + await loadGame(page); + await page.waitForLoadState("domcontentloaded"); + await page.waitForTimeout(1000); + await ensureGameStarted(page); + }); + + // ---- 1. Page loads without errors ---- + test("page loads without console errors", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + await page.waitForTimeout(2000); + expect(errors).toEqual([]); + }); + + // ---- 2. Game board is visible ---- + test("game board is visible", async ({ page }) => { + const board = gameBoard(page); + const count = await board.count(); + + expect( + count, + "Expected a <canvas> or a container with board/grid/game/field in its class or id" + ).toBeGreaterThan(0); + + // The board element should have meaningful dimensions + const box = await board.first().boundingBox(); + expect(box, "Game board should be visible on screen").not.toBeNull(); + expect(box!.width).toBeGreaterThan(50); + expect(box!.height).toBeGreaterThan(50); + }); + + // ---- 3. Game starts automatically or via interaction ---- + test("game starts", async ({ page }) => { + // After beforeEach, the game should be running. Verify by checking that + // the page is not static: take two screenshots separated by time. + const shot1 = await page.screenshot(); + await page.waitForTimeout(2500); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected the game to show visual activity after starting" + ).toBe(false); + }); + + // ---- 4. Piece falls automatically (auto-drop) ---- + test("piece falls automatically", async ({ page }) => { + // Take screenshots at intervals without pressing any keys. + // A falling piece should cause visual changes. + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot3 = await page.screenshot(); + + const buf1 = Buffer.from(shot1); + const buf2 = Buffer.from(shot2); + const buf3 = Buffer.from(shot3); + + // At least one pair should differ (piece is moving down) + const changed = !buf1.equals(buf2) || !buf2.equals(buf3); + expect(changed, "Expected piece to fall over time without input").toBe( + true + ); + }); + + // ---- 5. Left arrow moves piece left ---- + test("left arrow moves piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + // The piece should have moved, so the screenshots should differ + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing left arrow" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 6. Right arrow moves piece right ---- + test("right arrow moves piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing right arrow" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 7. Down arrow moves piece down faster ---- + test("down arrow accelerates piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + for (let i = 0; i < 10; i++) { + await page.keyboard.press("ArrowDown"); + await page.waitForTimeout(50); + } + await page.waitForTimeout(200); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing down arrow repeatedly" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 8. Up arrow (or Z) rotates piece ---- + test("rotation changes the piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowUp"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing rotate key" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 9. Space bar hard-drops piece ---- + test("space bar hard-drops piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("Space"); + await page.waitForTimeout(500); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing space (hard drop)" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 10. Pieces lock at the bottom ---- + test("pieces lock at the bottom", async ({ page }) => { + // Hard-drop several pieces and check that the bottom of the board + // accumulates filled cells (the visual should change cumulatively). + const shots: Buffer[] = []; + + shots.push(Buffer.from(await page.screenshot())); + + for (let i = 0; i < 3; i++) { + await page.keyboard.press("Space"); + await page.waitForTimeout(800); + } + + shots.push(Buffer.from(await page.screenshot())); + + // After 3 hard drops, the board should look different from the start + // because pieces have stacked up at the bottom. + expect( + shots[0].equals(shots[1]), + "Expected pieces to stack up at the bottom after hard drops" + ).toBe(false); + }); + + // ---- 11. New piece spawns after lock ---- + test("new piece spawns after locking", async ({ page }) => { + // Hard-drop to lock a piece, then wait and verify the game is still + // showing activity (a new piece should be falling). + await page.keyboard.press("Space"); + await page.waitForTimeout(1000); + + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + + // If a new piece spawned and is falling, the screen should change + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected a new piece to spawn and fall after the previous one locked" + ).toBe(false); + }); + + // ---- 12. Multiple different pieces appear ---- + test("multiple different pieces appear", async ({ page }) => { + // Play through several pieces and capture screenshots. Different piece + // shapes should produce visually distinct patterns. + const shots: Buffer[] = []; + + for (let i = 0; i < 6; i++) { + // Move each piece to a different column so they don't overlap identically + if (i % 2 === 0) { + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(100); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(100); + } else { + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(100); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(100); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(600); + shots.push(Buffer.from(await page.screenshot())); + } + + // At least some consecutive screenshots should differ (different piece shapes) + let differences = 0; + for (let i = 1; i < shots.length; i++) { + if (!shots[i - 1].equals(shots[i])) differences++; + } + + expect( + differences, + "Expected to see visual differences between consecutive pieces (different shapes)" + ).toBeGreaterThanOrEqual(2); + }); + + // ---- 13. Completed line clears ---- + test("completed line clears", async ({ page }) => { + // Fill a row by dropping many pieces. Observe whether any row disappears. + // We can detect this by tracking the total filled area -- after a line clear, + // the board should have less filled content than just before the clear. + const pageText = async () => + (await page.evaluate(() => document.body.innerText)) || ""; + + // Drop many pieces rapidly to fill rows + for (let i = 0; i < 30; i++) { + // Vary positions to try to complete a row + const moves = (i % 5) - 2; // -2, -1, 0, 1, 2 + for (let m = 0; m < Math.abs(moves); m++) { + await page.keyboard.press( + moves < 0 ? "ArrowLeft" : "ArrowRight" + ); + await page.waitForTimeout(50); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(300); + } + + // Check if a score or lines counter changed (common indicators of line clears) + const text = await pageText(); + const numbers = (text.match(/\d+/g) || []).map(Number); + const hasNonZero = numbers.some((n) => n > 0); + + // Also check visual: the board should not be completely static + const shot1 = await page.screenshot(); + await page.waitForTimeout(1000); + const shot2 = await page.screenshot(); + + // Either: score/lines increased, or game is still active (meaning lines cleared + // and made room for more pieces instead of game over) + const stillActive = !Buffer.from(shot1).equals(Buffer.from(shot2)); + + expect( + hasNonZero || stillActive, + "Expected evidence of line clearing (score > 0 or game still active after many drops)" + ).toBe(true); + }); + + // ---- 14. Score increases during play ---- + test("score increases during play", async ({ page }) => { + // Look for a score display on the page + const getNumbers = async () => { + const text = (await page.evaluate(() => document.body.innerText)) || ""; + return (text.match(/\d+/g) || []).map(Number); + }; + + const numbersBefore = await getNumbers(); + + // Play for a while: drop several pieces + for (let i = 0; i < 15; i++) { + const offset = (i % 5) - 2; + for (let m = 0; m < Math.abs(offset); m++) { + await page.keyboard.press(offset < 0 ? "ArrowLeft" : "ArrowRight"); + await page.waitForTimeout(50); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(300); + } + + const numbersAfter = await getNumbers(); + + // At least one number on the page should have increased + // (score, lines counter, level, etc.) + let anyIncreased = false; + const maxLen = Math.min(numbersBefore.length, numbersAfter.length); + for (let i = 0; i < maxLen; i++) { + if (numbersAfter[i] > numbersBefore[i]) { + anyIncreased = true; + break; + } + } + + // Also accept if new numbers appeared + if (!anyIncreased && numbersAfter.length > numbersBefore.length) { + anyIncreased = true; + } + + // Also accept if the max number increased + if (!anyIncreased) { + const maxBefore = numbersBefore.length > 0 ? Math.max(...numbersBefore) : 0; + const maxAfter = numbersAfter.length > 0 ? Math.max(...numbersAfter) : 0; + if (maxAfter > maxBefore) anyIncreased = true; + } + + expect( + anyIncreased, + "Expected at least one numeric value on the page to increase during play (score, lines, level)" + ).toBe(true); + }); + + // ---- 15. Game over when pieces reach top ---- + test("game over when pieces reach top", async ({ page }) => { + // Stack pieces in the center until the game ends. + // Drop as many pieces as possible straight down. + for (let i = 0; i < 50; i++) { + await page.keyboard.press("Space"); + await page.waitForTimeout(200); + } + + await page.waitForTimeout(2000); + + // After stacking to overflow, the game should show some game-over indicator: + // - text saying "game over", "you lose", "try again", "restart", "end" + // - or the game stops updating (static screen) + const text = ((await page.evaluate(() => document.body.innerText)) || "").toLowerCase(); + const gameOverText = + text.includes("game over") || + text.includes("gameover") || + text.includes("you lose") || + text.includes("try again") || + text.includes("restart") || + text.includes("play again") || + text.includes("ended"); + + // Check if the game stopped (screen is static) + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + const isStatic = Buffer.from(shot1).equals(Buffer.from(shot2)); + + expect( + gameOverText || isStatic, + "Expected game-over text or the game to stop after stacking pieces to the top" + ).toBe(true); + }); + + // ---- 16. Game runs for 30 seconds without crashing ---- + test("game runs for 30 seconds without crashing", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Simulate varied gameplay for 30 seconds + const keys = [ + "ArrowLeft", + "ArrowRight", + "ArrowDown", + "ArrowUp", + "Space", + ]; + const start = Date.now(); + + while (Date.now() - start < 30_000) { + const key = keys[Math.floor(Math.random() * keys.length)]; + await page.keyboard.press(key); + await page.waitForTimeout(150 + Math.random() * 200); + } + + // The page should still be alive (not crashed, not blank) + const text = await page.evaluate(() => document.body.innerText); + expect(text, "Page body should not be empty after 30s of play").toBeTruthy(); + expect( + errors.length, + `Expected no console errors during 30s of play, got: ${errors.join("; ")}` + ).toBe(0); + }); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tsconfig.json b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2015", + "module": "none", + "outFile": "game.js", + "strict": true, + "noImplicitAny": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "ignoreDeprecations": "6.0" + }, + "include": ["game.ts"] +} diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/README.md b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/README.md @@ -0,0 +1,65 @@ +# Tetris Game + +A fully functional Tetris game built with TypeScript and HTML5 Canvas. + +## Features + +- **All 7 Tetrominos**: I, O, T, S, Z, J, and L pieces +- **Piece Rotation**: Clockwise rotation with wall kick support +- **Line Clearing**: Clear complete lines to score points +- **Scoring System**: Points scale with level and lines cleared +- **Level Progression**: Game speed increases every 10 lines cleared +- **Ghost Piece**: Shows where the piece will land +- **Pause/Resume**: Pause the game at any time + +## Controls + +| Key | Action | +|-----|--------| +| ← → | Move left/right | +| ↑ | Rotate piece | +| ↓ | Soft drop (move down faster) | +| Space | Hard drop (instant drop) | +| P | Pause/Resume | + +## Scoring + +- 1 line: 100 × level +- 2 lines: 300 × level +- 3 lines: 500 × level +- 4 lines (Tetris): 800 × level + +## Level Progression + +- Level increases every 10 lines cleared +- Drop speed decreases by 100ms per level (minimum 100ms) + +## Running the Game + +1. **Compile TypeScript (if needed):** + ```bash + npm run build + ``` + +2. **Start a local server:** + ```bash + npm start + ``` + +3. **Open in browser:** + Navigate to `http://localhost:8000` + +## Files + +- `index.html` - Game HTML structure +- `styles.css` - Game styling +- `tetris.ts` - TypeScript game logic +- `tetris.js` - Compiled JavaScript (auto-generated) +- `package.json` - Project configuration + +## Development + +To watch for TypeScript changes and auto-compile: +```bash +npm run watch +``` diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/index.html b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/index.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Tetris Game</title> + <link rel="stylesheet" href="styles.css"> +</head> +<body> + <div class="game-container"> + <h1>Tetris</h1> + <div class="game-info"> + <div class="info-panel"> + <h3>Score</h3> + <p id="score">0</p> + </div> + <div class="info-panel"> + <h3>Level</h3> + <p id="level">1</p> + </div> + <div class="info-panel"> + <h3>Lines</h3> + <p id="lines">0</p> + </div> + </div> + <div class="game-board-container"> + <canvas id="tetris" width="240" height="400"></canvas> + </div> + <div class="controls-info"> + <h3>Controls</h3> + <p>← → : Move</p> + <p>↑ : Rotate</p> + <p>↓ : Soft Drop</p> + <p>Space : Hard Drop</p> + <p>P : Pause</p> + </div> + <button id="startBtn">Start Game</button> + <button id="pauseBtn" disabled>Pause</button> + </div> + <script src="tetris.js"></script> +</body> +</html> diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package-lock.json b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package-lock.json @@ -0,0 +1,2519 @@ +{ + "name": "loop-bench-dps90bem", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loop-bench-dps90bem", + "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.3.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.2.tgz", + "integrity": "sha512-wgWa6FWQ3QRRJbIjbsldRJZxdxYngT/dO0I5Ynmlnin8qy7tC6xYzbcJjtN4wHLXtkbVwHzk0C+OejVw1XM+DQ==", + "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/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package.json b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/package.json @@ -0,0 +1,27 @@ +{ + "name": "loop-bench-dps90bem", + "version": "1.0.0", + "description": "Tetris game built with TypeScript", + "main": "index.js", + "scripts": { + "build": "tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir .", + "watch": "tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir . --watch", + "start": "python3 -m http.server 8000" + }, + "keywords": [ + "tetris", + "game", + "typescript" + ], + "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/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/styles.css b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/styles.css @@ -0,0 +1,118 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Arial', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + color: white; +} + +.game-container { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + text-align: center; +} + +h1 { + font-size: 2.5rem; + margin-bottom: 20px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); +} + +.game-info { + display: flex; + justify-content: space-around; + margin-bottom: 20px; +} + +.info-panel { + background: rgba(255, 255, 255, 0.2); + padding: 15px 25px; + border-radius: 10px; + min-width: 100px; +} + +.info-panel h3 { + font-size: 1rem; + margin-bottom: 5px; + opacity: 0.8; +} + +.info-panel p { + font-size: 1.8rem; + font-weight: bold; +} + +.game-board-container { + display: flex; + justify-content: center; + margin-bottom: 20px; +} + +#tetris { + border: 4px solid rgba(255, 255, 255, 0.3); + border-radius: 5px; + background: rgba(0, 0, 0, 0.3); +} + +.controls-info { + background: rgba(255, 255, 255, 0.2); + padding: 15px; + border-radius: 10px; + margin-bottom: 20px; +} + +.controls-info h3 { + margin-bottom: 10px; +} + +.controls-info p { + margin: 5px 0; + font-size: 0.9rem; +} + +button { + padding: 12px 30px; + font-size: 1.1rem; + border: none; + border-radius: 25px; + cursor: pointer; + transition: all 0.3s ease; + margin: 5px; +} + +#startBtn { + background: #4CAF50; + color: white; +} + +#startBtn:hover { + background: #45a049; + transform: translateY(-2px); +} + +#pauseBtn { + background: #ff9800; + color: white; +} + +#pauseBtn:hover { + background: #f57c00; + transform: translateY(-2px); +} + +button:disabled { + background: #ccc; + cursor: not-allowed; + transform: none; +} diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/playwright.config.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/playwright.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "@playwright/test"; + +export default defineConfig({ + testDir: ".", + timeout: 30_000, + retries: 0, + workers: 1, + use: { + baseURL: "http://localhost:3000", + headless: true, + viewport: { width: 1280, height: 720 }, + }, +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/tetris.spec.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-few/tetris.spec.ts @@ -0,0 +1,96 @@ +import { test, expect, type Page } from "@playwright/test"; + +// Try common entry points until one loads successfully. +async function loadGame(page: Page) { + const candidates = [ + "/", + "/index.html", + "/dist/index.html", + "/public/index.html", + "/build/index.html", + ]; + + for (const path of candidates) { + try { + const resp = await page.goto(path, { timeout: 5000 }); + if (resp?.ok()) return; + } catch { + continue; + } + } +} + +test.describe("Tetris Game", () => { + test.beforeEach(async ({ page }) => { + await loadGame(page); + await page.waitForLoadState("domcontentloaded"); + }); + + test("page loads without console errors", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Give the page a moment to finish initializing + await page.waitForTimeout(2000); + + expect(errors).toEqual([]); + }); + + test("game board is visible", async ({ page }) => { + // A Tetris game should render either a <canvas> or a grid of DOM elements + const canvas = page.locator("canvas"); + const gridContainer = page.locator( + [ + '[class*="board"]', + '[class*="grid"]', + '[class*="game"]', + '[class*="field"]', + '[id*="board"]', + '[id*="grid"]', + '[id*="game"]', + '[id*="field"]', + "table", + ].join(", ") + ); + + const canvasCount = await canvas.count(); + const gridCount = await gridContainer.count(); + + expect( + canvasCount + gridCount, + "Expected a <canvas> or a container with board/grid/game/field in its class or id" + ).toBeGreaterThan(0); + }); + + test("keyboard input does not crash the game", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Press every key a Tetris game should handle + const keys = [ + "ArrowLeft", + "ArrowRight", + "ArrowDown", + "ArrowUp", + "Space", + ]; + for (const key of keys) { + await page.keyboard.press(key); + await page.waitForTimeout(150); + } + + expect(errors).toEqual([]); + }); + + test("game state changes over time", async ({ page }) => { + // If the game is running, the visual output should change as pieces fall + const shot1 = await page.screenshot(); + await page.waitForTimeout(3000); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected the page to visually change over 3 seconds (pieces should be falling)" + ).toBe(false); + }); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/playwright.config.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/playwright.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "@playwright/test"; + +export default defineConfig({ + testDir: ".", + timeout: 60_000, + retries: 0, + workers: 1, + use: { + baseURL: "http://localhost:3000", + headless: true, + viewport: { width: 1280, height: 720 }, + }, +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/tetris.spec.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tests-full/tetris.spec.ts @@ -0,0 +1,474 @@ +import { test, expect, type Page } from "@playwright/test"; + +// Try common entry points until one loads successfully. +async function loadGame(page: Page) { + const candidates = [ + "/", + "/index.html", + "/dist/index.html", + "/public/index.html", + "/build/index.html", + ]; + + for (const path of candidates) { + try { + const resp = await page.goto(path, { timeout: 5000 }); + if (resp?.ok()) return; + } catch { + continue; + } + } +} + +// Find the game surface: canvas or a grid-like DOM container. +function gameBoard(page: Page) { + return page.locator( + [ + "canvas", + '[class*="board"]', + '[class*="grid"]', + '[class*="game-area"]', + '[class*="field"]', + '[id*="board"]', + '[id*="grid"]', + '[id*="game"]', + '[id*="field"]', + "table", + ].join(", ") + ); +} + +// Click the board area to make sure it has focus, then try common +// start interactions in case the game waits for user action. +async function ensureGameStarted(page: Page) { + const board = gameBoard(page); + const count = await board.count(); + if (count > 0) { + try { + await board.first().click({ timeout: 2000 }); + } catch { + // click failed, continue anyway + } + } + + // Some games need a key press or button click to start + const startButton = page.locator( + 'button:has-text("start"), button:has-text("Start"), button:has-text("play"), button:has-text("Play"), [class*="start"], [id*="start"]' + ); + if ((await startButton.count()) > 0) { + try { + await startButton.first().click({ timeout: 2000 }); + } catch { + // ignore + } + } + + // Press Enter/Space as a fallback start trigger + await page.keyboard.press("Enter"); + await page.waitForTimeout(300); + await page.keyboard.press("Space"); + await page.waitForTimeout(500); +} + +test.describe("Tetris Game", () => { + test.beforeEach(async ({ page }) => { + await loadGame(page); + await page.waitForLoadState("domcontentloaded"); + await page.waitForTimeout(1000); + await ensureGameStarted(page); + }); + + // ---- 1. Page loads without errors ---- + test("page loads without console errors", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + await page.waitForTimeout(2000); + expect(errors).toEqual([]); + }); + + // ---- 2. Game board is visible ---- + test("game board is visible", async ({ page }) => { + const board = gameBoard(page); + const count = await board.count(); + + expect( + count, + "Expected a <canvas> or a container with board/grid/game/field in its class or id" + ).toBeGreaterThan(0); + + // The board element should have meaningful dimensions + const box = await board.first().boundingBox(); + expect(box, "Game board should be visible on screen").not.toBeNull(); + expect(box!.width).toBeGreaterThan(50); + expect(box!.height).toBeGreaterThan(50); + }); + + // ---- 3. Game starts automatically or via interaction ---- + test("game starts", async ({ page }) => { + // After beforeEach, the game should be running. Verify by checking that + // the page is not static: take two screenshots separated by time. + const shot1 = await page.screenshot(); + await page.waitForTimeout(2500); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected the game to show visual activity after starting" + ).toBe(false); + }); + + // ---- 4. Piece falls automatically (auto-drop) ---- + test("piece falls automatically", async ({ page }) => { + // Take screenshots at intervals without pressing any keys. + // A falling piece should cause visual changes. + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot3 = await page.screenshot(); + + const buf1 = Buffer.from(shot1); + const buf2 = Buffer.from(shot2); + const buf3 = Buffer.from(shot3); + + // At least one pair should differ (piece is moving down) + const changed = !buf1.equals(buf2) || !buf2.equals(buf3); + expect(changed, "Expected piece to fall over time without input").toBe( + true + ); + }); + + // ---- 5. Left arrow moves piece left ---- + test("left arrow moves piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + // The piece should have moved, so the screenshots should differ + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing left arrow" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 6. Right arrow moves piece right ---- + test("right arrow moves piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(200); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing right arrow" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 7. Down arrow moves piece down faster ---- + test("down arrow accelerates piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + for (let i = 0; i < 10; i++) { + await page.keyboard.press("ArrowDown"); + await page.waitForTimeout(50); + } + await page.waitForTimeout(200); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing down arrow repeatedly" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 8. Up arrow (or Z) rotates piece ---- + test("rotation changes the piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("ArrowUp"); + await page.waitForTimeout(300); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing rotate key" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 9. Space bar hard-drops piece ---- + test("space bar hard-drops piece", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + const shot1 = await page.screenshot(); + await page.keyboard.press("Space"); + await page.waitForTimeout(500); + const shot2 = await page.screenshot(); + + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected visual change after pressing space (hard drop)" + ).toBe(false); + expect(errors).toEqual([]); + }); + + // ---- 10. Pieces lock at the bottom ---- + test("pieces lock at the bottom", async ({ page }) => { + // Hard-drop several pieces and check that the bottom of the board + // accumulates filled cells (the visual should change cumulatively). + const shots: Buffer[] = []; + + shots.push(Buffer.from(await page.screenshot())); + + for (let i = 0; i < 3; i++) { + await page.keyboard.press("Space"); + await page.waitForTimeout(800); + } + + shots.push(Buffer.from(await page.screenshot())); + + // After 3 hard drops, the board should look different from the start + // because pieces have stacked up at the bottom. + expect( + shots[0].equals(shots[1]), + "Expected pieces to stack up at the bottom after hard drops" + ).toBe(false); + }); + + // ---- 11. New piece spawns after lock ---- + test("new piece spawns after locking", async ({ page }) => { + // Hard-drop to lock a piece, then wait and verify the game is still + // showing activity (a new piece should be falling). + await page.keyboard.press("Space"); + await page.waitForTimeout(1000); + + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + + // If a new piece spawned and is falling, the screen should change + expect( + Buffer.from(shot1).equals(Buffer.from(shot2)), + "Expected a new piece to spawn and fall after the previous one locked" + ).toBe(false); + }); + + // ---- 12. Multiple different pieces appear ---- + test("multiple different pieces appear", async ({ page }) => { + // Play through several pieces and capture screenshots. Different piece + // shapes should produce visually distinct patterns. + const shots: Buffer[] = []; + + for (let i = 0; i < 6; i++) { + // Move each piece to a different column so they don't overlap identically + if (i % 2 === 0) { + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(100); + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(100); + } else { + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(100); + await page.keyboard.press("ArrowRight"); + await page.waitForTimeout(100); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(600); + shots.push(Buffer.from(await page.screenshot())); + } + + // At least some consecutive screenshots should differ (different piece shapes) + let differences = 0; + for (let i = 1; i < shots.length; i++) { + if (!shots[i - 1].equals(shots[i])) differences++; + } + + expect( + differences, + "Expected to see visual differences between consecutive pieces (different shapes)" + ).toBeGreaterThanOrEqual(2); + }); + + // ---- 13. Completed line clears ---- + test("completed line clears", async ({ page }) => { + // Fill a row by dropping many pieces. Observe whether any row disappears. + // We can detect this by tracking the total filled area -- after a line clear, + // the board should have less filled content than just before the clear. + const pageText = async () => + (await page.evaluate(() => document.body.innerText)) || ""; + + // Drop many pieces rapidly to fill rows + for (let i = 0; i < 30; i++) { + // Vary positions to try to complete a row + const moves = (i % 5) - 2; // -2, -1, 0, 1, 2 + for (let m = 0; m < Math.abs(moves); m++) { + await page.keyboard.press( + moves < 0 ? "ArrowLeft" : "ArrowRight" + ); + await page.waitForTimeout(50); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(300); + } + + // Check if a score or lines counter changed (common indicators of line clears) + const text = await pageText(); + const numbers = (text.match(/\d+/g) || []).map(Number); + const hasNonZero = numbers.some((n) => n > 0); + + // Also check visual: the board should not be completely static + const shot1 = await page.screenshot(); + await page.waitForTimeout(1000); + const shot2 = await page.screenshot(); + + // Either: score/lines increased, or game is still active (meaning lines cleared + // and made room for more pieces instead of game over) + const stillActive = !Buffer.from(shot1).equals(Buffer.from(shot2)); + + expect( + hasNonZero || stillActive, + "Expected evidence of line clearing (score > 0 or game still active after many drops)" + ).toBe(true); + }); + + // ---- 14. Score increases during play ---- + test("score increases during play", async ({ page }) => { + // Look for a score display on the page + const getNumbers = async () => { + const text = (await page.evaluate(() => document.body.innerText)) || ""; + return (text.match(/\d+/g) || []).map(Number); + }; + + const numbersBefore = await getNumbers(); + + // Play for a while: drop several pieces + for (let i = 0; i < 15; i++) { + const offset = (i % 5) - 2; + for (let m = 0; m < Math.abs(offset); m++) { + await page.keyboard.press(offset < 0 ? "ArrowLeft" : "ArrowRight"); + await page.waitForTimeout(50); + } + await page.keyboard.press("Space"); + await page.waitForTimeout(300); + } + + const numbersAfter = await getNumbers(); + + // At least one number on the page should have increased + // (score, lines counter, level, etc.) + let anyIncreased = false; + const maxLen = Math.min(numbersBefore.length, numbersAfter.length); + for (let i = 0; i < maxLen; i++) { + if (numbersAfter[i] > numbersBefore[i]) { + anyIncreased = true; + break; + } + } + + // Also accept if new numbers appeared + if (!anyIncreased && numbersAfter.length > numbersBefore.length) { + anyIncreased = true; + } + + // Also accept if the max number increased + if (!anyIncreased) { + const maxBefore = numbersBefore.length > 0 ? Math.max(...numbersBefore) : 0; + const maxAfter = numbersAfter.length > 0 ? Math.max(...numbersAfter) : 0; + if (maxAfter > maxBefore) anyIncreased = true; + } + + expect( + anyIncreased, + "Expected at least one numeric value on the page to increase during play (score, lines, level)" + ).toBe(true); + }); + + // ---- 15. Game over when pieces reach top ---- + test("game over when pieces reach top", async ({ page }) => { + // Stack pieces in the center until the game ends. + // Drop as many pieces as possible straight down. + for (let i = 0; i < 50; i++) { + await page.keyboard.press("Space"); + await page.waitForTimeout(200); + } + + await page.waitForTimeout(2000); + + // After stacking to overflow, the game should show some game-over indicator: + // - text saying "game over", "you lose", "try again", "restart", "end" + // - or the game stops updating (static screen) + const text = ((await page.evaluate(() => document.body.innerText)) || "").toLowerCase(); + const gameOverText = + text.includes("game over") || + text.includes("gameover") || + text.includes("you lose") || + text.includes("try again") || + text.includes("restart") || + text.includes("play again") || + text.includes("ended"); + + // Check if the game stopped (screen is static) + const shot1 = await page.screenshot(); + await page.waitForTimeout(2000); + const shot2 = await page.screenshot(); + const isStatic = Buffer.from(shot1).equals(Buffer.from(shot2)); + + expect( + gameOverText || isStatic, + "Expected game-over text or the game to stop after stacking pieces to the top" + ).toBe(true); + }); + + // ---- 16. Game runs for 30 seconds without crashing ---- + test("game runs for 30 seconds without crashing", async ({ page }) => { + const errors: string[] = []; + page.on("pageerror", (err) => errors.push(err.message)); + + // Simulate varied gameplay for 30 seconds + const keys = [ + "ArrowLeft", + "ArrowRight", + "ArrowDown", + "ArrowUp", + "Space", + ]; + const start = Date.now(); + + while (Date.now() - start < 30_000) { + const key = keys[Math.floor(Math.random() * keys.length)]; + await page.keyboard.press(key); + await page.waitForTimeout(150 + Math.random() * 200); + } + + // The page should still be alive (not crashed, not blank) + const text = await page.evaluate(() => document.body.innerText); + expect(text, "Page body should not be empty after 30s of play").toBeTruthy(); + expect( + errors.length, + `Expected no console errors during 30s of play, got: ${errors.join("; ")}` + ).toBe(0); + }); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.js b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.js @@ -0,0 +1,361 @@ +"use strict"; +// Tetris Game in TypeScript +// Game constants +const COLS = 10; +const ROWS = 20; +const BLOCK_SIZE = 24; +// Tetromino shapes and their colors +const TETROMINOES = { + I: { + shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], + color: '#00f5ff' + }, + O: { + shape: [[1, 1], [1, 1]], + color: '#ffff00' + }, + T: { + shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]], + color: '#a020f0' + }, + S: { + shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]], + color: '#00ff00' + }, + Z: { + shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]], + color: '#ff0000' + }, + J: { + shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]], + color: '#0000ff' + }, + L: { + shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]], + color: '#ff7f00' + } +}; +class TetrisGame { + constructor() { + this.lastTime = 0; + this.dropCounter = 0; + this.animationId = null; + this.canvas = document.getElementById('tetris'); + this.ctx = this.canvas.getContext('2d'); + this.state = this.getInitialState(); + this.setupEventListeners(); + this.draw(); + } + getInitialState() { + return { + board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)), + score: 0, + level: 1, + lines: 0, + gameOver: false, + paused: false, + currentPiece: null, + nextPiece: null, + dropInterval: 1000 + }; + } + setupEventListeners() { + const startBtn = document.getElementById('startBtn'); + const pauseBtn = document.getElementById('pauseBtn'); + startBtn.addEventListener('click', () => this.startGame()); + pauseBtn.addEventListener('click', () => this.togglePause()); + document.addEventListener('keydown', (e) => this.handleKeyPress(e)); + } + handleKeyPress(e) { + if (this.state.gameOver || this.state.paused) { + return; + } + switch (e.key) { + case 'ArrowLeft': + e.preventDefault(); + this.movePiece(-1, 0); + break; + case 'ArrowRight': + e.preventDefault(); + this.movePiece(1, 0); + break; + case 'ArrowDown': + e.preventDefault(); + this.movePiece(0, 1); + break; + case 'ArrowUp': + e.preventDefault(); + this.rotatePiece(); + break; + case ' ': + e.preventDefault(); + this.hardDrop(); + break; + case 'p': + case 'P': + e.preventDefault(); + this.togglePause(); + break; + } + } + startGame() { + const startBtn = document.getElementById('startBtn'); + const pauseBtn = document.getElementById('pauseBtn'); + this.state = this.getInitialState(); + this.spawnPiece(); + startBtn.disabled = true; + pauseBtn.disabled = false; + this.updateDisplay(); + this.gameLoop(); + } + togglePause() { + if (this.state.gameOver) { + return; + } + this.state.paused = !this.state.paused; + const pauseBtn = document.getElementById('pauseBtn'); + pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause'; + if (!this.state.paused) { + this.lastTime = performance.now(); + this.gameLoop(); + } + } + gameLoop(time = 0) { + if (this.state.paused || this.state.gameOver) { + return; + } + const deltaTime = time - this.lastTime; + this.lastTime = time; + this.dropCounter += deltaTime; + if (this.dropCounter > this.state.dropInterval) { + this.dropPiece(); + this.dropCounter = 0; + } + this.draw(); + this.animationId = requestAnimationFrame((t) => this.gameLoop(t)); + } + spawnPiece() { + const types = Object.keys(TETROMINOES); + const randomType = types[Math.floor(Math.random() * types.length)]; + const tetromino = TETROMINOES[randomType]; + this.state.currentPiece = this.state.nextPiece || { + shape: tetromino.shape.map((row) => [...row]), + color: tetromino.color, + x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2), + y: 0, + type: randomType + }; + // Generate next piece + const nextType = types[Math.floor(Math.random() * types.length)]; + const nextTetromino = TETROMINOES[nextType]; + this.state.nextPiece = { + shape: nextTetromino.shape.map((row) => [...row]), + color: nextTetromino.color, + x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2), + y: 0, + type: nextType + }; + // Check if game over + if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) { + this.state.gameOver = true; + const startBtn = document.getElementById('startBtn'); + const pauseBtn = document.getElementById('pauseBtn'); + startBtn.disabled = false; + pauseBtn.disabled = true; + pauseBtn.textContent = 'Pause'; + if (this.animationId !== null) { + cancelAnimationFrame(this.animationId); + } + this.drawGameOver(); + } + } + movePiece(dx, dy) { + if (!this.state.currentPiece) + return; + const newX = this.state.currentPiece.x + dx; + const newY = this.state.currentPiece.y + dy; + if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) { + this.state.currentPiece.x = newX; + this.state.currentPiece.y = newY; + this.draw(); + } + else if (dy > 0) { + this.lockPiece(); + } + } + dropPiece() { + this.movePiece(0, 1); + } + hardDrop() { + if (!this.state.currentPiece) + return; + while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) { + this.state.currentPiece.y++; + } + this.lockPiece(); + } + rotatePiece() { + if (!this.state.currentPiece) + return; + const rotated = this.rotateMatrix(this.state.currentPiece.shape); + // Wall kick - try different positions if rotation causes collision + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) { + this.state.currentPiece.x += kick; + this.state.currentPiece.shape = rotated; + this.draw(); + return; + } + } + } + rotateMatrix(matrix) { + const n = matrix.length; + const rotated = []; + for (let i = 0; i < n; i++) { + rotated[i] = []; + for (let j = 0; j < n; j++) { + rotated[i][j] = matrix[n - 1 - j][i]; + } + } + return rotated; + } + checkCollision(x, y, shape) { + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const newX = x + col; + const newY = y + row; + if (newX < 0 || newX >= COLS || newY >= ROWS) { + return true; + } + if (newY >= 0 && this.state.board[newY][newX]) { + return true; + } + } + } + } + return false; + } + lockPiece() { + if (!this.state.currentPiece) + return; + const { shape, x, y } = this.state.currentPiece; + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const boardY = y + row; + const boardX = x + col; + if (boardY >= 0) { + this.state.board[boardY][boardX] = 1; + } + } + } + } + this.clearLines(); + this.spawnPiece(); + } + clearLines() { + let linesCleared = 0; + for (let row = ROWS - 1; row >= 0; row--) { + if (this.state.board[row].every(cell => cell === 1)) { + this.state.board.splice(row, 1); + this.state.board.unshift(Array(COLS).fill(0)); + linesCleared++; + row++; // Check the same row again + } + } + if (linesCleared > 0) { + this.updateScore(linesCleared); + } + } + updateScore(linesCleared) { + // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris) + const points = [0, 100, 300, 500, 800]; + this.state.score += points[linesCleared] * this.state.level; + this.state.lines += linesCleared; + // Level up every 10 lines + this.state.level = Math.floor(this.state.lines / 10) + 1; + // Increase speed (decrease drop interval) + this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100); + this.updateDisplay(); + } + updateDisplay() { + document.getElementById('score').textContent = this.state.score.toString(); + document.getElementById('level').textContent = this.state.level.toString(); + document.getElementById('lines').textContent = this.state.lines.toString(); + } + draw() { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + this.drawBoard(); + this.drawCurrentPiece(); + this.drawGhostPiece(); + } + drawBoard() { + for (let row = 0; row < ROWS; row++) { + for (let col = 0; col < COLS; col++) { + if (this.state.board[row][col]) { + this.drawBlock(col, row, '#ffffff'); + } + } + } + } + drawCurrentPiece() { + if (!this.state.currentPiece) + return; + const { shape, x, y, color } = this.state.currentPiece; + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + this.drawBlock(x + col, y + row, color); + } + } + } + } + drawGhostPiece() { + if (!this.state.currentPiece) + return; + const { shape, x, y, color } = this.state.currentPiece; + let ghostY = y; + // Find where the ghost piece would land + while (!this.checkCollision(x, ghostY + 1, shape)) { + ghostY++; + } + // Draw ghost piece (semi-transparent) + this.ctx.globalAlpha = 0.3; + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + this.drawBlock(x + col, ghostY + row, color); + } + } + } + this.ctx.globalAlpha = 1.0; + } + drawBlock(x, y, color) { + const padding = 1; + this.ctx.fillStyle = color; + this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, BLOCK_SIZE - padding * 2); + // Add a slight 3D effect + this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, 4); + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + BLOCK_SIZE - padding - 4, BLOCK_SIZE - padding * 2, 4); + } + drawGameOver() { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.fillStyle = '#ffffff'; + this.ctx.font = 'bold 24px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20); + this.ctx.font = '16px Arial'; + this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20); + this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50); + } +} +// Initialize game when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + new TetrisGame(); +}); diff --git a/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.ts b/artifacts/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/tetris.ts @@ -0,0 +1,463 @@ +// Tetris Game in TypeScript + +// Game constants +const COLS = 10; +const ROWS = 20; +const BLOCK_SIZE = 24; + +// Tetromino shapes and their colors +const TETROMINOES: Record<string, { shape: number[][]; color: string }> = { + I: { + shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], + color: '#00f5ff' + }, + O: { + shape: [[1, 1], [1, 1]], + color: '#ffff00' + }, + T: { + shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]], + color: '#a020f0' + }, + S: { + shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]], + color: '#00ff00' + }, + Z: { + shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]], + color: '#ff0000' + }, + J: { + shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]], + color: '#0000ff' + }, + L: { + shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]], + color: '#ff7f00' + } +}; + +// Game state +interface GameState { + board: number[][]; + score: number; + level: number; + lines: number; + gameOver: boolean; + paused: boolean; + currentPiece: Tetromino | null; + nextPiece: Tetromino | null; + dropInterval: number; +} + +interface Tetromino { + shape: number[][]; + color: string; + x: number; + y: number; + type: string; +} + +class TetrisGame { + private canvas: HTMLCanvasElement; + private ctx: CanvasRenderingContext2D; + private state: GameState; + private lastTime: number = 0; + private dropCounter: number = 0; + private animationId: number | null = null; + + constructor() { + this.canvas = document.getElementById('tetris') as HTMLCanvasElement; + this.ctx = this.canvas.getContext('2d')!; + + this.state = this.getInitialState(); + + this.setupEventListeners(); + this.draw(); + } + + private getInitialState(): GameState { + return { + board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)), + score: 0, + level: 1, + lines: 0, + gameOver: false, + paused: false, + currentPiece: null, + nextPiece: null, + dropInterval: 1000 + }; + } + + private setupEventListeners(): void { + const startBtn = document.getElementById('startBtn') as HTMLButtonElement; + const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement; + + startBtn.addEventListener('click', () => this.startGame()); + pauseBtn.addEventListener('click', () => this.togglePause()); + + document.addEventListener('keydown', (e) => this.handleKeyPress(e)); + } + + private handleKeyPress(e: KeyboardEvent): void { + if (this.state.gameOver || this.state.paused) { + return; + } + + switch (e.key) { + case 'ArrowLeft': + e.preventDefault(); + this.movePiece(-1, 0); + break; + case 'ArrowRight': + e.preventDefault(); + this.movePiece(1, 0); + break; + case 'ArrowDown': + e.preventDefault(); + this.movePiece(0, 1); + break; + case 'ArrowUp': + e.preventDefault(); + this.rotatePiece(); + break; + case ' ': + e.preventDefault(); + this.hardDrop(); + break; + case 'p': + case 'P': + e.preventDefault(); + this.togglePause(); + break; + } + } + + private startGame(): void { + const startBtn = document.getElementById('startBtn') as HTMLButtonElement; + const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement; + + this.state = this.getInitialState(); + this.spawnPiece(); + + startBtn.disabled = true; + pauseBtn.disabled = false; + + this.updateDisplay(); + this.gameLoop(); + } + + private togglePause(): void { + if (this.state.gameOver) { + return; + } + + this.state.paused = !this.state.paused; + const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement; + pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause'; + + if (!this.state.paused) { + this.lastTime = performance.now(); + this.gameLoop(); + } + } + + private gameLoop(time: number = 0): void { + if (this.state.paused || this.state.gameOver) { + return; + } + + const deltaTime = time - this.lastTime; + this.lastTime = time; + this.dropCounter += deltaTime; + + if (this.dropCounter > this.state.dropInterval) { + this.dropPiece(); + this.dropCounter = 0; + } + + this.draw(); + this.animationId = requestAnimationFrame((t) => this.gameLoop(t)); + } + + private spawnPiece(): void { + const types = Object.keys(TETROMINOES); + const randomType = types[Math.floor(Math.random() * types.length)]; + const tetromino = TETROMINOES[randomType]; + + this.state.currentPiece = this.state.nextPiece || { + shape: tetromino.shape.map((row: number[]) => [...row]), + color: tetromino.color, + x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2), + y: 0, + type: randomType + }; + + // Generate next piece + const nextType = types[Math.floor(Math.random() * types.length)]; + const nextTetromino = TETROMINOES[nextType]; + this.state.nextPiece = { + shape: nextTetromino.shape.map((row: number[]) => [...row]), + color: nextTetromino.color, + x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2), + y: 0, + type: nextType + }; + + // Check if game over + if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) { + this.state.gameOver = true; + const startBtn = document.getElementById('startBtn') as HTMLButtonElement; + const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement; + startBtn.disabled = false; + pauseBtn.disabled = true; + pauseBtn.textContent = 'Pause'; + + if (this.animationId !== null) { + cancelAnimationFrame(this.animationId); + } + + this.drawGameOver(); + } + } + + private movePiece(dx: number, dy: number): void { + if (!this.state.currentPiece) return; + + const newX = this.state.currentPiece.x + dx; + const newY = this.state.currentPiece.y + dy; + + if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) { + this.state.currentPiece.x = newX; + this.state.currentPiece.y = newY; + this.draw(); + } else if (dy > 0) { + this.lockPiece(); + } + } + + private dropPiece(): void { + this.movePiece(0, 1); + } + + private hardDrop(): void { + if (!this.state.currentPiece) return; + + while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) { + this.state.currentPiece.y++; + } + this.lockPiece(); + } + + private rotatePiece(): void { + if (!this.state.currentPiece) return; + + const rotated = this.rotateMatrix(this.state.currentPiece.shape); + + // Wall kick - try different positions if rotation causes collision + const kicks = [0, -1, 1, -2, 2]; + for (const kick of kicks) { + if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) { + this.state.currentPiece.x += kick; + this.state.currentPiece.shape = rotated; + this.draw(); + return; + } + } + } + + private rotateMatrix(matrix: number[][]): number[][] { + const n = matrix.length; + const rotated: number[][] = []; + + for (let i = 0; i < n; i++) { + rotated[i] = []; + for (let j = 0; j < n; j++) { + rotated[i][j] = matrix[n - 1 - j][i]; + } + } + + return rotated; + } + + private checkCollision(x: number, y: number, shape: number[][]): boolean { + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const newX = x + col; + const newY = y + row; + + if (newX < 0 || newX >= COLS || newY >= ROWS) { + return true; + } + + if (newY >= 0 && this.state.board[newY][newX]) { + return true; + } + } + } + } + return false; + } + + private lockPiece(): void { + if (!this.state.currentPiece) return; + + const { shape, x, y } = this.state.currentPiece; + + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + const boardY = y + row; + const boardX = x + col; + if (boardY >= 0) { + this.state.board[boardY][boardX] = 1; + } + } + } + } + + this.clearLines(); + this.spawnPiece(); + } + + private clearLines(): void { + let linesCleared = 0; + + for (let row = ROWS - 1; row >= 0; row--) { + if (this.state.board[row].every(cell => cell === 1)) { + this.state.board.splice(row, 1); + this.state.board.unshift(Array(COLS).fill(0)); + linesCleared++; + row++; // Check the same row again + } + } + + if (linesCleared > 0) { + this.updateScore(linesCleared); + } + } + + private updateScore(linesCleared: number): void { + // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris) + const points = [0, 100, 300, 500, 800]; + this.state.score += points[linesCleared] * this.state.level; + this.state.lines += linesCleared; + + // Level up every 10 lines + this.state.level = Math.floor(this.state.lines / 10) + 1; + + // Increase speed (decrease drop interval) + this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100); + + this.updateDisplay(); + } + + private updateDisplay(): void { + document.getElementById('score')!.textContent = this.state.score.toString(); + document.getElementById('level')!.textContent = this.state.level.toString(); + document.getElementById('lines')!.textContent = this.state.lines.toString(); + } + + private draw(): void { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + this.drawBoard(); + this.drawCurrentPiece(); + this.drawGhostPiece(); + } + + private drawBoard(): void { + for (let row = 0; row < ROWS; row++) { + for (let col = 0; col < COLS; col++) { + if (this.state.board[row][col]) { + this.drawBlock(col, row, '#ffffff'); + } + } + } + } + + private drawCurrentPiece(): void { + if (!this.state.currentPiece) return; + + const { shape, x, y, color } = this.state.currentPiece; + + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + this.drawBlock(x + col, y + row, color); + } + } + } + } + + private drawGhostPiece(): void { + if (!this.state.currentPiece) return; + + const { shape, x, y, color } = this.state.currentPiece; + let ghostY = y; + + // Find where the ghost piece would land + while (!this.checkCollision(x, ghostY + 1, shape)) { + ghostY++; + } + + // Draw ghost piece (semi-transparent) + this.ctx.globalAlpha = 0.3; + for (let row = 0; row < shape.length; row++) { + for (let col = 0; col < shape[row].length; col++) { + if (shape[row][col]) { + this.drawBlock(x + col, ghostY + row, color); + } + } + } + this.ctx.globalAlpha = 1.0; + } + + private drawBlock(x: number, y: number, color: string): void { + const padding = 1; + this.ctx.fillStyle = color; + this.ctx.fillRect( + x * BLOCK_SIZE + padding, + y * BLOCK_SIZE + padding, + BLOCK_SIZE - padding * 2, + BLOCK_SIZE - padding * 2 + ); + + // Add a slight 3D effect + this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; + this.ctx.fillRect( + x * BLOCK_SIZE + padding, + y * BLOCK_SIZE + padding, + BLOCK_SIZE - padding * 2, + 4 + ); + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; + this.ctx.fillRect( + x * BLOCK_SIZE + padding, + y * BLOCK_SIZE + BLOCK_SIZE - padding - 4, + BLOCK_SIZE - padding * 2, + 4 + ); + } + + private drawGameOver(): void { + this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'; + this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); + + this.ctx.fillStyle = '#ffffff'; + this.ctx.font = 'bold 24px Arial'; + this.ctx.textAlign = 'center'; + this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20); + this.ctx.font = '16px Arial'; + this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20); + this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50); + } +} + +// Initialize game when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + new TetrisGame(); +}); diff --git a/results/analysis/main_effects_build_quality.json b/results/analysis/main_effects_build_quality.json @@ -3,17 +3,17 @@ "values": { "javascript": { "mean": 1.0, - "effect": 0.1258, + "effect": 0.1262, "n": 11 }, "typescript": { - "mean": 0.8792, - "effect": 0.005, - "n": 213 + "mean": 0.8787, + "effect": 0.0049, + "n": 215 }, "unspecified": { "mean": 0.67, - "effect": -0.2042, + "effect": -0.2038, "n": 12 } }, @@ -23,32 +23,32 @@ "values": { "glm-4.5-air": { "mean": 0.7208, - "effect": -0.1534, + "effect": -0.1531, "n": 13 }, "glm-4.7": { - "mean": 0.8573, - "effect": -0.0169, - "n": 37 + "mean": 0.8562, + "effect": -0.0177, + "n": 39 }, "glm-5.1": { "mean": 0.8167, - "effect": -0.0575, + "effect": -0.0572, "n": 9 }, "haiku": { "mean": 0.7993, - "effect": -0.0748, + "effect": -0.0745, "n": 74 }, "opus": { "mean": 0.9676, - "effect": 0.0935, + "effect": 0.0938, "n": 51 }, "sonnet": { "mean": 0.9492, - "effect": 0.0751, + "effect": 0.0754, "n": 52 } }, @@ -58,17 +58,17 @@ "values": { "dom": { "mean": 0.89, - "effect": 0.0158, + "effect": 0.0162, "n": 3 }, "none": { - "mean": 0.8748, + "mean": 0.8745, "effect": 0.0007, - "n": 232 + "n": 234 }, "webgl": { "mean": 0.67, - "effect": -0.2042, + "effect": -0.2038, "n": 1 } }, @@ -78,42 +78,42 @@ "values": { "detailed": { "mean": 0.715, - "effect": -0.1592, + "effect": -0.1588, "n": 22 }, "simple": { - "mean": 0.8905, - "effect": 0.0164, - "n": 214 + "mean": 0.89, + "effect": 0.0162, + "n": 216 } }, - "spread": 0.1755 + "spread": 0.175 }, "strategy": { "values": { "creative_validate": { "mean": 0.78, - "effect": -0.0942, + "effect": -0.0938, "n": 3 }, "iterate": { "mean": 0.78, - "effect": -0.0942, + "effect": -0.0938, "n": 3 }, "none": { - "mean": 0.8261, - "effect": -0.0481, - "n": 74 + "mean": 0.8263, + "effect": -0.0475, + "n": 76 }, "plan_first": { "mean": 0.78, - "effect": -0.0942, + "effect": -0.0938, "n": 3 }, "use_subagents": { "mean": 0.9029, - "effect": 0.0288, + "effect": 0.0291, "n": 153 } }, @@ -123,180 +123,180 @@ "values": { "off": { "mean": 0.7761, - "effect": -0.0981, + "effect": -0.0978, "n": 28 }, "on": { - "mean": 0.8874, - "effect": 0.0132, - "n": 208 + "mean": 0.8869, + "effect": 0.013, + "n": 210 } }, - "spread": 0.1113 + "spread": 0.1108 }, "web_search": { "values": { "off": { "mean": 0.7996, - "effect": -0.0745, + "effect": -0.0742, "n": 28 }, "on": { - "mean": 0.8842, - "effect": 0.01, - "n": 208 + "mean": 0.8837, + "effect": 0.0099, + "n": 210 } }, - "spread": 0.0846 + "spread": 0.0841 }, "tool_read": { "values": { "off": { "mean": 0.7991, - "effect": -0.075, + "effect": -0.0747, "n": 23 }, "on": { - "mean": 0.8823, - "effect": 0.0081, - "n": 213 + "mean": 0.8818, + "effect": 0.008, + "n": 215 } }, - "spread": 0.0832 + "spread": 0.0827 }, "tool_edit": { "values": { "off": { "mean": 0.802, - "effect": -0.0722, + "effect": -0.0718, "n": 25 }, "on": { - "mean": 0.8827, - "effect": 0.0085, - "n": 211 + "mean": 0.8823, + "effect": 0.0084, + "n": 213 } }, - "spread": 0.0807 + "spread": 0.0803 }, "tool_write": { "values": { "off": { "mean": 0.802, - "effect": -0.0722, + "effect": -0.0718, "n": 25 }, "on": { - "mean": 0.8827, - "effect": 0.0085, - "n": 211 + "mean": 0.8823, + "effect": 0.0084, + "n": 213 } }, - "spread": 0.0807 + "spread": 0.0803 }, "tool_grep": { "values": { "off": { "mean": 0.802, - "effect": -0.0722, + "effect": -0.0718, "n": 20 }, "on": { - "mean": 0.8808, - "effect": 0.0067, - "n": 216 + "mean": 0.8804, + "effect": 0.0066, + "n": 218 } }, - "spread": 0.0788 + "spread": 0.0784 }, "human_language": { "values": { "en": { - "mean": 0.8807, - "effect": 0.0066, - "n": 213 + "mean": 0.8803, + "effect": 0.0065, + "n": 215 }, "es": { "mean": 0.8135, - "effect": -0.0607, + "effect": -0.0603, "n": 23 } }, - "spread": 0.0672 + "spread": 0.0668 }, "playwright": { "values": { "available": { "mean": 0.8963, - "effect": 0.0222, + "effect": 0.0225, "n": 156 }, "off": { - "mean": 0.8309, - "effect": -0.0433, - "n": 80 + "mean": 0.831, + "effect": -0.0428, + "n": 82 } }, - "spread": 0.0654 + "spread": 0.0653 }, "effort": { "values": { "high": { - "mean": 0.8713, + "mean": 0.8709, "effect": -0.0029, - "n": 223 + "n": 225 }, "max": { "mean": 0.9238, - "effect": 0.0497, + "effect": 0.05, "n": 13 } }, - "spread": 0.0525 + "spread": 0.0529 }, "context_file": { "values": { "none": { - "mean": 0.8782, + "mean": 0.8778, "effect": 0.004, - "n": 214 + "n": 216 }, "provided": { "mean": 0.835, - "effect": -0.0392, + "effect": -0.0388, "n": 22 } }, - "spread": 0.0432 + "spread": 0.0428 }, "max_budget": { "values": { "high": { "mean": 0.8515, - "effect": -0.0227, + "effect": -0.0223, "n": 20 }, "low": { - "mean": 0.8763, - "effect": 0.0021, - "n": 216 + "mean": 0.8759, + "effect": 0.002, + "n": 218 } }, - "spread": 0.0248 + "spread": 0.0244 }, "tool_glob": { "values": { "off": { - "mean": 0.8533, - "effect": -0.0208, - "n": 18 + "mean": 0.8515, + "effect": -0.0223, + "n": 20 }, "on": { "mean": 0.8759, - "effect": 0.0017, + "effect": 0.002, "n": 218 } }, - "spread": 0.0226 + "spread": 0.0244 } } \ No newline at end of file diff --git a/results/analysis/main_effects_code_quality.json b/results/analysis/main_effects_code_quality.json @@ -3,27 +3,27 @@ "values": { "creative_validate": { "mean": 0.55, - "effect": -0.2337, + "effect": -0.2326, "n": 3 }, "iterate": { "mean": 0.7033, - "effect": -0.0804, + "effect": -0.0793, "n": 3 }, "none": { - "mean": 0.747, - "effect": -0.0367, - "n": 74 + "mean": 0.7445, + "effect": -0.0381, + "n": 76 }, "plan_first": { "mean": 0.65, - "effect": -0.1337, + "effect": -0.1326, "n": 3 }, "use_subagents": { "mean": 0.8103, - "effect": 0.0265, + "effect": 0.0277, "n": 153 } }, @@ -33,32 +33,32 @@ "values": { "glm-4.5-air": { "mean": 0.7077, - "effect": -0.076, + "effect": -0.0749, "n": 13 }, "glm-4.7": { - "mean": 0.7219, - "effect": -0.0618, - "n": 37 + "mean": 0.7182, + "effect": -0.0644, + "n": 39 }, "glm-5.1": { "mean": 0.7667, - "effect": -0.0171, + "effect": -0.0159, "n": 9 }, "haiku": { "mean": 0.7176, - "effect": -0.0662, + "effect": -0.065, "n": 74 }, "opus": { "mean": 0.8647, - "effect": 0.081, + "effect": 0.0821, "n": 51 }, "sonnet": { "mean": 0.8644, - "effect": 0.0807, + "effect": 0.0818, "n": 52 } }, @@ -68,235 +68,235 @@ "values": { "javascript": { "mean": 0.9136, - "effect": 0.1299, + "effect": 0.131, "n": 11 }, "typescript": { - "mean": 0.7695, + "mean": 0.7684, "effect": -0.0142, - "n": 213 + "n": 215 }, "unspecified": { "mean": 0.9167, - "effect": 0.1329, + "effect": 0.1341, "n": 12 } }, - "spread": 0.1472 + "spread": 0.1483 }, "playwright": { "values": { "available": { "mean": 0.8073, - "effect": 0.0236, + "effect": 0.0247, "n": 156 }, "off": { - "mean": 0.7378, - "effect": -0.046, - "n": 80 + "mean": 0.7356, + "effect": -0.047, + "n": 82 } }, - "spread": 0.0695 + "spread": 0.0717 }, "human_language": { "values": { "en": { - "mean": 0.7888, - "effect": 0.0051, - "n": 213 + "mean": 0.7875, + "effect": 0.0049, + "n": 215 }, "es": { "mean": 0.737, - "effect": -0.0468, + "effect": -0.0456, "n": 23 } }, - "spread": 0.0518 + "spread": 0.0505 }, "prompt_style": { "values": { "detailed": { "mean": 0.8227, - "effect": 0.039, + "effect": 0.0401, "n": 22 }, "simple": { - "mean": 0.7797, - "effect": -0.004, - "n": 214 - } - }, - "spread": 0.043 - }, - "effort": { - "values": { - "high": { - "mean": 0.7857, - "effect": 0.002, - "n": 223 - }, - "max": { - "mean": 0.7492, - "effect": -0.0345, - "n": 13 + "mean": 0.7785, + "effect": -0.0041, + "n": 216 } }, - "spread": 0.0365 + "spread": 0.0442 }, "tool_grep": { "values": { "off": { "mean": 0.8155, - "effect": 0.0318, + "effect": 0.0329, "n": 20 }, "on": { - "mean": 0.7808, - "effect": -0.0029, - "n": 216 + "mean": 0.7796, + "effect": -0.003, + "n": 218 } }, - "spread": 0.0347 + "spread": 0.0359 + }, + "effort": { + "values": { + "high": { + "mean": 0.7845, + "effect": 0.0019, + "n": 225 + }, + "max": { + "mean": 0.7492, + "effect": -0.0334, + "n": 13 + } + }, + "spread": 0.0353 }, "renderer": { "values": { "dom": { "mean": 0.7667, - "effect": -0.0171, + "effect": -0.0159, "n": 3 }, "none": { - "mean": 0.7841, - "effect": 0.0004, - "n": 232 + "mean": 0.7829, + "effect": 0.0003, + "n": 234 }, "webgl": { "mean": 0.75, - "effect": -0.0337, + "effect": -0.0326, "n": 1 } }, - "spread": 0.0341 + "spread": 0.0329 }, "context_file": { "values": { "none": { - "mean": 0.7864, - "effect": 0.0027, - "n": 214 + "mean": 0.7851, + "effect": 0.0025, + "n": 216 }, "provided": { "mean": 0.7577, - "effect": -0.026, + "effect": -0.0249, "n": 22 } }, - "spread": 0.0287 + "spread": 0.0274 }, "max_budget": { "values": { "high": { "mean": 0.762, - "effect": -0.0217, + "effect": -0.0206, "n": 20 }, "low": { - "mean": 0.7857, - "effect": 0.002, - "n": 216 + "mean": 0.7845, + "effect": 0.0019, + "n": 218 } }, - "spread": 0.0237 + "spread": 0.0225 + }, + "tool_glob": { + "values": { + "off": { + "mean": 0.765, + "effect": -0.0176, + "n": 20 + }, + "on": { + "mean": 0.7842, + "effect": 0.0016, + "n": 218 + } + }, + "spread": 0.0192 }, "tool_write": { "values": { "off": { "mean": 0.7656, - "effect": -0.0181, + "effect": -0.017, "n": 25 }, "on": { - "mean": 0.7859, - "effect": 0.0021, - "n": 211 + "mean": 0.7846, + "effect": 0.002, + "n": 213 } }, - "spread": 0.0203 + "spread": 0.019 }, "web_search": { "values": { "off": { "mean": 0.7671, - "effect": -0.0166, + "effect": -0.0155, "n": 28 }, "on": { - "mean": 0.786, - "effect": 0.0022, - "n": 208 + "mean": 0.7847, + "effect": 0.0021, + "n": 210 } }, - "spread": 0.0189 + "spread": 0.0176 }, "tool_read": { "values": { "off": { "mean": 0.7957, - "effect": 0.0119, + "effect": 0.013, "n": 23 }, "on": { - "mean": 0.7824, - "effect": -0.0013, - "n": 213 + "mean": 0.7812, + "effect": -0.0014, + "n": 215 } }, - "spread": 0.0133 - }, - "tool_glob": { - "values": { - "off": { - "mean": 0.7778, - "effect": -0.006, - "n": 18 - }, - "on": { - "mean": 0.7842, - "effect": 0.0005, - "n": 218 - } - }, - "spread": 0.0064 + "spread": 0.0145 }, "linter": { "values": { "off": { "mean": 0.7857, - "effect": 0.002, + "effect": 0.0031, "n": 28 }, "on": { - "mean": 0.7835, - "effect": -0.0003, - "n": 208 + "mean": 0.7822, + "effect": -0.0004, + "n": 210 } }, - "spread": 0.0022 + "spread": 0.0035 }, "tool_edit": { "values": { "off": { "mean": 0.7828, - "effect": -0.0009, + "effect": 0.0002, "n": 25 }, "on": { - "mean": 0.7838, - "effect": 0.0001, - "n": 211 + "mean": 0.7826, + "effect": -0.0, + "n": 213 } }, - "spread": 0.001 + "spread": 0.0002 } } \ No newline at end of file diff --git a/results/analysis/main_effects_cost.json b/results/analysis/main_effects_cost.json @@ -3,62 +3,62 @@ "values": { "creative_validate": { "mean": 1.797, - "effect": 1.1732, + "effect": 1.1766, "n": 3 }, "iterate": { "mean": 0.9792, - "effect": 0.3554, + "effect": 0.3588, "n": 3 }, "none": { - "mean": 0.3808, - "effect": -0.243, - "n": 74 + "mean": 0.3766, + "effect": -0.2438, + "n": 76 }, "plan_first": { "mean": 0.5439, - "effect": -0.08, + "effect": -0.0766, "n": 3 }, "use_subagents": { "mean": 0.7129, - "effect": 0.0891, + "effect": 0.0925, "n": 153 } }, - "spread": 1.4162 + "spread": 1.4204 }, "model": { "values": { "glm-4.5-air": { "mean": 0.356, - "effect": -0.2678, + "effect": -0.2644, "n": 13 }, "glm-4.7": { - "mean": 0.4652, - "effect": -0.1586, - "n": 37 + "mean": 0.4527, + "effect": -0.1677, + "n": 39 }, "glm-5.1": { "mean": 0.3543, - "effect": -0.2695, + "effect": -0.2661, "n": 9 }, "haiku": { "mean": 0.266, - "effect": -0.3578, + "effect": -0.3545, "n": 74 }, "opus": { "mean": 0.6385, - "effect": 0.0146, + "effect": 0.018, "n": 51 }, "sonnet": { "mean": 1.3451, - "effect": 0.7213, + "effect": 0.7247, "n": 52 } }, @@ -68,235 +68,235 @@ "values": { "dom": { "mean": 0.3572, - "effect": -0.2666, + "effect": -0.2633, "n": 3 }, "none": { - "mean": 0.6278, - "effect": 0.004, - "n": 232 + "mean": 0.6243, + "effect": 0.0039, + "n": 234 }, "webgl": { "mean": 0.4994, - "effect": -0.1244, + "effect": -0.121, "n": 1 } }, - "spread": 0.2706 + "spread": 0.2671 }, "playwright": { "values": { "available": { "mean": 0.7113, - "effect": 0.0875, + "effect": 0.0909, "n": 156 }, "off": { - "mean": 0.4533, - "effect": -0.1706, - "n": 80 + "mean": 0.4476, + "effect": -0.1728, + "n": 82 } }, - "spread": 0.258 + "spread": 0.2637 }, "tool_edit": { "values": { "off": { "mean": 0.3968, - "effect": -0.227, + "effect": -0.2236, "n": 25 }, "on": { - "mean": 0.6507, - "effect": 0.0269, - "n": 211 + "mean": 0.6467, + "effect": 0.0262, + "n": 213 } }, - "spread": 0.2539 + "spread": 0.2499 }, "linter": { "values": { "off": { "mean": 0.4469, - "effect": -0.1769, + "effect": -0.1735, "n": 28 }, "on": { - "mean": 0.6476, - "effect": 0.0238, - "n": 208 + "mean": 0.6436, + "effect": 0.0231, + "n": 210 + } + }, + "spread": 0.1967 + }, + "tool_glob": { + "values": { + "off": { + "mean": 0.4426, + "effect": -0.1779, + "n": 20 + }, + "on": { + "mean": 0.6368, + "effect": 0.0163, + "n": 218 } }, - "spread": 0.2007 + "spread": 0.1942 }, "max_budget": { "values": { "high": { "mean": 0.443, - "effect": -0.1808, + "effect": -0.1774, "n": 20 }, "low": { - "mean": 0.6406, - "effect": 0.0167, - "n": 216 + "mean": 0.6367, + "effect": 0.0163, + "n": 218 } }, - "spread": 0.1976 + "spread": 0.1937 }, "tool_write": { "values": { "off": { "mean": 0.45, - "effect": -0.1738, + "effect": -0.1705, "n": 25 }, "on": { - "mean": 0.6444, - "effect": 0.0206, - "n": 211 + "mean": 0.6404, + "effect": 0.02, + "n": 213 } }, - "spread": 0.1944 + "spread": 0.1904 }, "effort": { "values": { "high": { - "mean": 0.6136, - "effect": -0.0103, - "n": 223 + "mean": 0.6101, + "effect": -0.0104, + "n": 225 }, "max": { "mean": 0.7998, - "effect": 0.1759, + "effect": 0.1793, "n": 13 } }, - "spread": 0.1862 - }, - "tool_glob": { - "values": { - "off": { - "mean": 0.4672, - "effect": -0.1567, - "n": 18 - }, - "on": { - "mean": 0.6368, - "effect": 0.0129, - "n": 218 - } - }, - "spread": 0.1696 + "spread": 0.1897 }, "tool_read": { "values": { "off": { "mean": 0.4817, - "effect": -0.1422, + "effect": -0.1388, "n": 23 }, "on": { - "mean": 0.6392, - "effect": 0.0154, - "n": 213 + "mean": 0.6353, + "effect": 0.0148, + "n": 215 } }, - "spread": 0.1575 + "spread": 0.1536 }, "tool_grep": { "values": { "off": { "mean": 0.4821, - "effect": -0.1417, + "effect": -0.1383, "n": 20 }, "on": { - "mean": 0.6369, - "effect": 0.0131, - "n": 216 + "mean": 0.6331, + "effect": 0.0127, + "n": 218 } }, - "spread": 0.1548 + "spread": 0.151 }, "human_language": { "values": { "en": { - "mean": 0.6384, - "effect": 0.0146, - "n": 213 + "mean": 0.6345, + "effect": 0.0141, + "n": 215 }, "es": { "mean": 0.4886, - "effect": -0.1352, + "effect": -0.1318, "n": 23 } }, - "spread": 0.1498 + "spread": 0.1459 }, "web_search": { "values": { "off": { "mean": 0.5087, - "effect": -0.1151, + "effect": -0.1117, "n": 28 }, "on": { - "mean": 0.6393, - "effect": 0.0155, - "n": 208 + "mean": 0.6353, + "effect": 0.0149, + "n": 210 } }, - "spread": 0.1306 + "spread": 0.1266 }, "language": { "values": { "javascript": { "mean": 0.5097, - "effect": -0.1142, + "effect": -0.1108, "n": 11 }, "typescript": { - "mean": 0.6345, - "effect": 0.0106, - "n": 213 + "mean": 0.6306, + "effect": 0.0102, + "n": 215 }, "unspecified": { "mean": 0.5395, - "effect": -0.0843, + "effect": -0.0809, "n": 12 } }, - "spread": 0.1248 + "spread": 0.1209 }, "context_file": { "values": { "none": { - "mean": 0.6354, - "effect": 0.0115, - "n": 214 + "mean": 0.6315, + "effect": 0.0111, + "n": 216 }, "provided": { "mean": 0.5115, - "effect": -0.1123, + "effect": -0.1089, "n": 22 } }, - "spread": 0.1239 + "spread": 0.12 }, "prompt_style": { "values": { "detailed": { "mean": 0.5368, - "effect": -0.087, + "effect": -0.0836, "n": 22 }, "simple": { - "mean": 0.6328, - "effect": 0.0089, - "n": 214 + "mean": 0.6289, + "effect": 0.0085, + "n": 216 } }, - "spread": 0.096 + "spread": 0.0921 } } \ No newline at end of file diff --git a/results/analysis/main_effects_gameplay.json b/results/analysis/main_effects_gameplay.json @@ -3,17 +3,17 @@ "values": { "dom": { "mean": 0.75, - "effect": 0.2648, + "effect": 0.2687, "n": 3 }, "none": { - "mean": 0.4828, - "effect": -0.0024, - "n": 232 + "mean": 0.4789, + "effect": -0.0025, + "n": 234 }, "webgl": { "mean": 0.25, - "effect": -0.2352, + "effect": -0.2313, "n": 1 } }, @@ -23,62 +23,62 @@ "values": { "glm-4.5-air": { "mean": 0.3177, - "effect": -0.1675, + "effect": -0.1637, "n": 13 }, "glm-4.7": { - "mean": 0.1935, - "effect": -0.2917, - "n": 37 + "mean": 0.1851, + "effect": -0.2962, + "n": 39 }, "glm-5.1": { "mean": 0.5767, - "effect": 0.0915, + "effect": 0.0953, "n": 9 }, "haiku": { "mean": 0.5473, - "effect": 0.0621, + "effect": 0.066, "n": 74 }, "opus": { "mean": 0.661, - "effect": 0.1758, + "effect": 0.1796, "n": 51 }, "sonnet": { "mean": 0.4579, - "effect": -0.0273, + "effect": -0.0235, "n": 52 } }, - "spread": 0.4675 + "spread": 0.4759 }, "strategy": { "values": { "creative_validate": { "mean": 0.0833, - "effect": -0.4018, + "effect": -0.398, "n": 3 }, "iterate": { "mean": 0.3767, - "effect": -0.1085, + "effect": -0.1047, "n": 3 }, "none": { - "mean": 0.3885, - "effect": -0.0967, - "n": 74 + "mean": 0.3791, + "effect": -0.1023, + "n": 76 }, "plan_first": { "mean": 0.25, - "effect": -0.2352, + "effect": -0.2313, "n": 3 }, "use_subagents": { "mean": 0.5465, - "effect": 0.0614, + "effect": 0.0652, "n": 153 } }, @@ -88,215 +88,215 @@ "values": { "javascript": { "mean": 0.2845, - "effect": -0.2006, + "effect": -0.1968, "n": 11 }, "typescript": { - "mean": 0.515, - "effect": 0.0298, - "n": 213 + "mean": 0.5105, + "effect": 0.0291, + "n": 215 }, "unspecified": { "mean": 0.14, - "effect": -0.3452, + "effect": -0.3413, "n": 12 } }, - "spread": 0.375 - }, - "tool_glob": { - "values": { - "off": { - "mean": 0.7161, - "effect": 0.2309, - "n": 18 - }, - "on": { - "mean": 0.4661, - "effect": -0.0191, - "n": 218 - } - }, - "spread": 0.25 + "spread": 0.3705 }, "context_file": { "values": { "none": { - "mean": 0.4624, - "effect": -0.0227, - "n": 214 + "mean": 0.4584, + "effect": -0.0229, + "n": 216 }, "provided": { "mean": 0.7064, - "effect": 0.2212, + "effect": 0.225, "n": 22 } }, - "spread": 0.244 + "spread": 0.248 }, "playwright": { "values": { "available": { "mean": 0.5549, - "effect": 0.0698, + "effect": 0.0736, "n": 156 }, "off": { - "mean": 0.3491, - "effect": -0.136, - "n": 80 + "mean": 0.3413, + "effect": -0.14, + "n": 82 } }, - "spread": 0.2058 + "spread": 0.2136 }, "max_budget": { "values": { "high": { "mean": 0.6545, - "effect": 0.1693, + "effect": 0.1732, "n": 20 }, "low": { - "mean": 0.4695, - "effect": -0.0157, - "n": 216 + "mean": 0.4655, + "effect": -0.0159, + "n": 218 + } + }, + "spread": 0.189 + }, + "tool_glob": { + "values": { + "off": { + "mean": 0.6475, + "effect": 0.1662, + "n": 20 + }, + "on": { + "mean": 0.4661, + "effect": -0.0152, + "n": 218 } }, - "spread": 0.185 + "spread": 0.1814 }, "tool_grep": { "values": { "off": { "mean": 0.6295, - "effect": 0.1443, + "effect": 0.1482, "n": 20 }, "on": { - "mean": 0.4718, - "effect": -0.0134, - "n": 216 + "mean": 0.4678, + "effect": -0.0136, + "n": 218 } }, - "spread": 0.1577 + "spread": 0.1617 }, "tool_edit": { "values": { "off": { "mean": 0.6164, - "effect": 0.1312, + "effect": 0.1351, "n": 25 }, "on": { - "mean": 0.4696, - "effect": -0.0155, - "n": 211 + "mean": 0.4655, + "effect": -0.0159, + "n": 213 } }, - "spread": 0.1468 + "spread": 0.1509 }, "tool_read": { "values": { "off": { "mean": 0.3896, - "effect": -0.0956, + "effect": -0.0918, "n": 23 }, "on": { - "mean": 0.4955, - "effect": 0.0103, - "n": 213 + "mean": 0.4912, + "effect": 0.0098, + "n": 215 } }, - "spread": 0.1059 + "spread": 0.1016 }, "effort": { "values": { "high": { - "mean": 0.4908, - "effect": 0.0056, - "n": 223 + "mean": 0.4867, + "effect": 0.0053, + "n": 225 }, "max": { "mean": 0.3892, - "effect": -0.0959, + "effect": -0.0921, "n": 13 } }, - "spread": 0.1016 - }, - "human_language": { - "values": { - "en": { - "mean": 0.493, - "effect": 0.0078, - "n": 213 - }, - "es": { - "mean": 0.413, - "effect": -0.0721, - "n": 23 - } - }, - "spread": 0.08 + "spread": 0.0975 }, "tool_write": { "values": { "off": { "mean": 0.5512, - "effect": 0.066, + "effect": 0.0699, "n": 25 }, "on": { - "mean": 0.4773, - "effect": -0.0078, - "n": 211 + "mean": 0.4731, + "effect": -0.0082, + "n": 213 + } + }, + "spread": 0.0781 + }, + "human_language": { + "values": { + "en": { + "mean": 0.4887, + "effect": 0.0073, + "n": 215 + }, + "es": { + "mean": 0.413, + "effect": -0.0683, + "n": 23 } }, - "spread": 0.0739 + "spread": 0.0757 }, "linter": { "values": { "off": { "mean": 0.4582, - "effect": -0.027, + "effect": -0.0231, "n": 28 }, "on": { - "mean": 0.4888, - "effect": 0.0036, - "n": 208 + "mean": 0.4844, + "effect": 0.0031, + "n": 210 } }, - "spread": 0.0306 + "spread": 0.0262 }, "web_search": { "values": { "off": { "mean": 0.5004, - "effect": 0.0152, + "effect": 0.019, "n": 28 }, "on": { - "mean": 0.4831, - "effect": -0.002, - "n": 208 + "mean": 0.4788, + "effect": -0.0025, + "n": 210 } }, - "spread": 0.0173 + "spread": 0.0216 }, "prompt_style": { "values": { "detailed": { "mean": 0.4836, - "effect": -0.0015, + "effect": 0.0023, "n": 22 }, "simple": { - "mean": 0.4853, - "effect": 0.0002, - "n": 214 + "mean": 0.4811, + "effect": -0.0002, + "n": 216 } }, - "spread": 0.0017 + "spread": 0.0025 } } \ No newline at end of file diff --git a/results/analysis/main_effects_score.json b/results/analysis/main_effects_score.json @@ -3,62 +3,62 @@ "values": { "glm-4.5-air": { "mean": 0.3973, - "effect": -0.1357, + "effect": -0.1313, "n": 13 }, "glm-4.7": { - "mean": 0.3484, - "effect": -0.1846, - "n": 37 + "mean": 0.3313, + "effect": -0.1973, + "n": 39 }, "glm-5.1": { "mean": 0.5828, - "effect": 0.0498, + "effect": 0.0542, "n": 9 }, "haiku": { "mean": 0.5502, - "effect": 0.0172, + "effect": 0.0216, "n": 74 }, "opus": { "mean": 0.6692, - "effect": 0.1362, + "effect": 0.1406, "n": 51 }, "sonnet": { "mean": 0.5314, - "effect": -0.0015, + "effect": 0.0028, "n": 52 } }, - "spread": 0.3208 + "spread": 0.3379 }, "strategy": { "values": { "creative_validate": { "mean": 0.2833, - "effect": -0.2496, + "effect": -0.2453, "n": 3 }, "iterate": { "mean": 0.4783, - "effect": -0.0546, + "effect": -0.0503, "n": 3 }, "none": { - "mean": 0.4572, - "effect": -0.0758, - "n": 74 + "mean": 0.4455, + "effect": -0.0831, + "n": 76 }, "plan_first": { "mean": 0.35, - "effect": -0.183, + "effect": -0.1786, "n": 3 }, "use_subagents": { "mean": 0.5792, - "effect": 0.0462, + "effect": 0.0506, "n": 153 } }, @@ -68,17 +68,17 @@ "values": { "dom": { "mean": 0.635, - "effect": 0.102, + "effect": 0.1064, "n": 3 }, "none": { - "mean": 0.5321, - "effect": -0.0009, - "n": 232 + "mean": 0.5276, + "effect": -0.001, + "n": 234 }, "webgl": { "mean": 0.435, - "effect": -0.098, + "effect": -0.0936, "n": 1 } }, @@ -88,215 +88,215 @@ "values": { "available": { "mean": 0.5786, - "effect": 0.0456, + "effect": 0.0499, "n": 156 }, "off": { - "mean": 0.4441, - "effect": -0.0889, - "n": 80 + "mean": 0.4336, + "effect": -0.095, + "n": 82 } }, - "spread": 0.1345 + "spread": 0.145 }, "tool_grep": { "values": { "off": { "mean": 0.6327, - "effect": 0.0998, + "effect": 0.1041, "n": 20 }, "on": { - "mean": 0.5237, - "effect": -0.0092, - "n": 216 + "mean": 0.5191, + "effect": -0.0096, + "n": 218 } }, - "spread": 0.109 + "spread": 0.1136 }, "context_file": { "values": { "none": { - "mean": 0.5235, - "effect": -0.0095, - "n": 214 + "mean": 0.5187, + "effect": -0.0099, + "n": 216 }, "provided": { "mean": 0.6255, - "effect": 0.0925, + "effect": 0.0968, "n": 22 } }, - "spread": 0.102 + "spread": 0.1068 }, "effort": { "values": { "high": { - "mean": 0.538, - "effect": 0.005, - "n": 223 + "mean": 0.5333, + "effect": 0.0047, + "n": 225 }, "max": { "mean": 0.4473, - "effect": -0.0857, + "effect": -0.0813, "n": 13 } }, - "spread": 0.0907 + "spread": 0.086 }, - "tool_glob": { + "max_budget": { "values": { - "off": { - "mean": 0.6164, - "effect": 0.0834, - "n": 18 + "high": { + "mean": 0.5845, + "effect": 0.0559, + "n": 20 }, - "on": { - "mean": 0.5261, - "effect": -0.0069, + "low": { + "mean": 0.5235, + "effect": -0.0051, "n": 218 } }, - "spread": 0.0903 - }, - "human_language": { - "values": { - "en": { - "mean": 0.5386, - "effect": 0.0056, - "n": 213 - }, - "es": { - "mean": 0.4811, - "effect": -0.0519, - "n": 23 - } - }, - "spread": 0.0575 + "spread": 0.061 }, "language": { "values": { "javascript": { "mean": 0.5423, - "effect": 0.0093, + "effect": 0.0137, "n": 11 }, "typescript": { - "mean": 0.5352, - "effect": 0.0022, - "n": 213 + "mean": 0.5303, + "effect": 0.0017, + "n": 215 }, "unspecified": { "mean": 0.485, - "effect": -0.048, + "effect": -0.0436, "n": 12 } }, "spread": 0.0573 }, - "max_budget": { + "human_language": { "values": { - "high": { - "mean": 0.5845, - "effect": 0.0515, - "n": 20 + "en": { + "mean": 0.5337, + "effect": 0.0051, + "n": 215 }, - "low": { - "mean": 0.5282, - "effect": -0.0048, - "n": 216 + "es": { + "mean": 0.4811, + "effect": -0.0475, + "n": 23 + } + }, + "spread": 0.0526 + }, + "tool_edit": { + "values": { + "off": { + "mean": 0.5676, + "effect": 0.039, + "n": 25 + }, + "on": { + "mean": 0.524, + "effect": -0.0046, + "n": 213 } }, - "spread": 0.0563 + "spread": 0.0436 }, "tool_read": { "values": { "off": { "mean": 0.495, - "effect": -0.038, + "effect": -0.0336, "n": 23 }, "on": { - "mean": 0.5371, - "effect": 0.0041, - "n": 213 + "mean": 0.5322, + "effect": 0.0036, + "n": 215 } }, - "spread": 0.0421 + "spread": 0.0372 }, - "tool_edit": { + "tool_glob": { "values": { "off": { - "mean": 0.5676, - "effect": 0.0346, - "n": 25 + "mean": 0.5563, + "effect": 0.0276, + "n": 20 }, "on": { - "mean": 0.5289, - "effect": -0.0041, - "n": 211 + "mean": 0.5261, + "effect": -0.0025, + "n": 218 } }, - "spread": 0.0387 + "spread": 0.0302 }, "prompt_style": { "values": { "detailed": { "mean": 0.5489, - "effect": 0.0159, + "effect": 0.0203, "n": 22 }, "simple": { - "mean": 0.5313, - "effect": -0.0016, - "n": 214 + "mean": 0.5266, + "effect": -0.0021, + "n": 216 } }, - "spread": 0.0176 + "spread": 0.0223 }, "tool_write": { "values": { "off": { "mean": 0.5412, - "effect": 0.0082, + "effect": 0.0126, "n": 25 }, "on": { - "mean": 0.532, - "effect": -0.001, - "n": 211 + "mean": 0.5271, + "effect": -0.0015, + "n": 213 } }, - "spread": 0.0092 + "spread": 0.0141 }, "linter": { "values": { "off": { "mean": 0.5404, - "effect": 0.0074, + "effect": 0.0117, "n": 28 }, "on": { - "mean": 0.532, - "effect": -0.001, - "n": 208 + "mean": 0.527, + "effect": -0.0016, + "n": 210 } }, - "spread": 0.0084 + "spread": 0.0134 }, "web_search": { "values": { "off": { "mean": 0.5387, - "effect": 0.0058, + "effect": 0.0101, "n": 28 }, "on": { - "mean": 0.5322, - "effect": -0.0008, - "n": 208 + "mean": 0.5273, + "effect": -0.0014, + "n": 210 } }, - "spread": 0.0065 + "spread": 0.0114 } } \ No newline at end of file diff --git a/results/analysis/main_effects_sonarqube.json b/results/analysis/main_effects_sonarqube.json @@ -3,52 +3,52 @@ "values": { "javascript": { "mean": 0.8, - "effect": 0.2192, + "effect": 0.2241, "n": 11 }, "typescript": { - "mean": 0.5554, - "effect": -0.0254, - "n": 213 + "mean": 0.5502, + "effect": -0.0256, + "n": 215 }, "unspecified": { "mean": 0.83, - "effect": 0.2492, + "effect": 0.2541, "n": 12 } }, - "spread": 0.2746 + "spread": 0.2798 }, "model": { "values": { "glm-4.5-air": { "mean": 0.4769, - "effect": -0.1038, + "effect": -0.099, "n": 13 }, "glm-4.7": { - "mean": 0.5032, - "effect": -0.0775, - "n": 37 + "mean": 0.4774, + "effect": -0.0984, + "n": 39 }, "glm-5.1": { "mean": 0.5889, - "effect": 0.0081, + "effect": 0.013, "n": 9 }, "haiku": { "mean": 0.5531, - "effect": -0.0277, + "effect": -0.0228, "n": 74 }, "opus": { "mean": 0.6775, - "effect": 0.0967, + "effect": 0.1016, "n": 51 }, "sonnet": { "mean": 0.605, - "effect": 0.0242, + "effect": 0.0291, "n": 52 } }, @@ -58,245 +58,245 @@ "values": { "creative_validate": { "mean": 0.4833, - "effect": -0.0974, + "effect": -0.0925, "n": 3 }, "iterate": { "mean": 0.58, - "effect": -0.0008, + "effect": 0.0041, "n": 3 }, "none": { - "mean": 0.5258, - "effect": -0.055, - "n": 74 + "mean": 0.512, + "effect": -0.0639, + "n": 76 }, "plan_first": { "mean": 0.45, - "effect": -0.1308, + "effect": -0.1259, "n": 3 }, "use_subagents": { "mean": 0.6118, - "effect": 0.0311, + "effect": 0.0359, "n": 153 } }, "spread": 0.1618 }, + "tool_glob": { + "values": { + "off": { + "mean": 0.465, + "effect": -0.1109, + "n": 20 + }, + "on": { + "mean": 0.5861, + "effect": 0.0102, + "n": 218 + } + }, + "spread": 0.1211 + }, "renderer": { "values": { "dom": { "mean": 0.52, - "effect": -0.0608, + "effect": -0.0559, "n": 3 }, "none": { - "mean": 0.5814, - "effect": 0.0006, - "n": 232 + "mean": 0.5764, + "effect": 0.0005, + "n": 234 }, "webgl": { "mean": 0.62, - "effect": 0.0392, + "effect": 0.0441, "n": 1 } }, "spread": 0.1 }, + "playwright": { + "values": { + "available": { + "mean": 0.6022, + "effect": 0.0263, + "n": 156 + }, + "off": { + "mean": 0.5259, + "effect": -0.05, + "n": 82 + } + }, + "spread": 0.0763 + }, "effort": { "values": { "high": { - "mean": 0.5852, - "effect": 0.0044, - "n": 223 + "mean": 0.58, + "effect": 0.0041, + "n": 225 }, "max": { "mean": 0.5054, - "effect": -0.0754, + "effect": -0.0705, "n": 13 } }, - "spread": 0.0798 + "spread": 0.0746 }, "max_budget": { "values": { "high": { "mean": 0.5145, - "effect": -0.0663, + "effect": -0.0614, "n": 20 }, "low": { - "mean": 0.5869, - "effect": 0.0061, - "n": 216 + "mean": 0.5815, + "effect": 0.0056, + "n": 218 } }, - "spread": 0.0724 + "spread": 0.067 }, - "tool_glob": { + "tool_grep": { "values": { "off": { - "mean": 0.5167, - "effect": -0.0641, - "n": 18 + "mean": 0.636, + "effect": 0.0601, + "n": 20 }, "on": { - "mean": 0.5861, - "effect": 0.0053, + "mean": 0.5704, + "effect": -0.0055, "n": 218 } }, - "spread": 0.0694 + "spread": 0.0656 }, "tool_edit": { "values": { "off": { "mean": 0.5188, - "effect": -0.062, + "effect": -0.0571, "n": 25 }, "on": { - "mean": 0.5881, - "effect": 0.0073, - "n": 211 - } - }, - "spread": 0.0693 - }, - "playwright": { - "values": { - "available": { - "mean": 0.6022, - "effect": 0.0214, - "n": 156 - }, - "off": { - "mean": 0.539, - "effect": -0.0418, - "n": 80 + "mean": 0.5826, + "effect": 0.0067, + "n": 213 } }, - "spread": 0.0632 + "spread": 0.0638 }, - "tool_grep": { + "linter": { "values": { "off": { - "mean": 0.636, - "effect": 0.0552, - "n": 20 + "mean": 0.6225, + "effect": 0.0466, + "n": 28 }, "on": { - "mean": 0.5756, - "effect": -0.0051, - "n": 216 + "mean": 0.5697, + "effect": -0.0062, + "n": 210 } }, - "spread": 0.0604 + "spread": 0.0528 }, "tool_write": { "values": { "off": { "mean": 0.5312, - "effect": -0.0496, + "effect": -0.0447, "n": 25 }, "on": { - "mean": 0.5866, - "effect": 0.0059, - "n": 211 + "mean": 0.5811, + "effect": 0.0052, + "n": 213 } }, - "spread": 0.0554 + "spread": 0.0499 }, - "linter": { + "prompt_style": { "values": { - "off": { - "mean": 0.6225, - "effect": 0.0417, - "n": 28 + "detailed": { + "mean": 0.6141, + "effect": 0.0382, + "n": 22 }, - "on": { - "mean": 0.5751, - "effect": -0.0056, - "n": 208 + "simple": { + "mean": 0.572, + "effect": -0.0039, + "n": 216 } }, - "spread": 0.0474 + "spread": 0.0421 }, "context_file": { "values": { "none": { - "mean": 0.5845, - "effect": 0.0037, - "n": 214 + "mean": 0.5791, + "effect": 0.0032, + "n": 216 }, "provided": { "mean": 0.5445, - "effect": -0.0362, + "effect": -0.0313, "n": 22 } }, - "spread": 0.04 - }, - "prompt_style": { - "values": { - "detailed": { - "mean": 0.6141, - "effect": 0.0333, - "n": 22 - }, - "simple": { - "mean": 0.5773, - "effect": -0.0034, - "n": 214 - } - }, - "spread": 0.0368 + "spread": 0.0346 }, "human_language": { "values": { "en": { - "mean": 0.5842, - "effect": 0.0034, - "n": 213 + "mean": 0.5787, + "effect": 0.0029, + "n": 215 }, "es": { "mean": 0.5491, - "effect": -0.0316, + "effect": -0.0268, "n": 23 } }, - "spread": 0.0351 + "spread": 0.0296 }, "tool_read": { "values": { "off": { "mean": 0.6004, - "effect": 0.0197, + "effect": 0.0246, "n": 23 }, "on": { - "mean": 0.5786, - "effect": -0.0021, - "n": 213 + "mean": 0.5733, + "effect": -0.0026, + "n": 215 } }, - "spread": 0.0218 + "spread": 0.0271 }, "web_search": { "values": { "off": { "mean": 0.5771, - "effect": -0.0036, + "effect": 0.0013, "n": 28 }, "on": { - "mean": 0.5813, - "effect": 0.0005, - "n": 208 + "mean": 0.5757, + "effect": -0.0002, + "n": 210 } }, - "spread": 0.0042 + "spread": 0.0014 } } \ No newline at end of file diff --git a/results/analysis/main_effects_structural.json b/results/analysis/main_effects_structural.json @@ -3,52 +3,52 @@ "values": { "dom": { "mean": 0.8333, - "effect": -0.0126, + "effect": -0.0129, "n": 3 }, "none": { - "mean": 0.8476, - "effect": 0.0017, - "n": 232 + "mean": 0.8479, + "effect": 0.0016, + "n": 234 }, "webgl": { "mean": 0.5, - "effect": -0.346, + "effect": -0.3462, "n": 1 } }, - "spread": 0.3476 + "spread": 0.3479 }, "model": { "values": { "glm-4.5-air": { "mean": 0.6285, - "effect": -0.2175, + "effect": -0.2178, "n": 13 }, "glm-4.7": { - "mean": 0.8068, - "effect": -0.0392, - "n": 37 + "mean": 0.8103, + "effect": -0.036, + "n": 39 }, "glm-5.1": { "mean": 0.75, - "effect": -0.096, + "effect": -0.0962, "n": 9 }, "haiku": { "mean": 0.7865, - "effect": -0.0595, + "effect": -0.0597, "n": 74 }, "opus": { "mean": 0.9739, - "effect": 0.1279, + "effect": 0.1277, "n": 51 }, "sonnet": { "mean": 0.904, - "effect": 0.0581, + "effect": 0.0578, "n": 52 } }, @@ -58,27 +58,27 @@ "values": { "creative_validate": { "mean": 0.75, - "effect": -0.096, + "effect": -0.0962, "n": 3 }, "iterate": { "mean": 0.75, - "effect": -0.096, + "effect": -0.0962, "n": 3 }, "none": { - "mean": 0.7819, - "effect": -0.0641, - "n": 74 + "mean": 0.7843, + "effect": -0.0619, + "n": 76 }, "plan_first": { "mean": 0.6667, - "effect": -0.1793, + "effect": -0.1796, "n": 3 }, "use_subagents": { "mean": 0.8842, - "effect": 0.0383, + "effect": 0.038, "n": 153 } }, @@ -88,215 +88,215 @@ "values": { "detailed": { "mean": 0.7282, - "effect": -0.1178, + "effect": -0.118, "n": 22 }, "simple": { - "mean": 0.8581, - "effect": 0.0121, - "n": 214 + "mean": 0.8582, + "effect": 0.012, + "n": 216 } }, - "spread": 0.1299 + "spread": 0.13 }, "linter": { "values": { "off": { "mean": 0.7475, - "effect": -0.0985, + "effect": -0.0987, "n": 28 }, "on": { - "mean": 0.8592, - "effect": 0.0133, - "n": 208 + "mean": 0.8594, + "effect": 0.0132, + "n": 210 } }, - "spread": 0.1117 + "spread": 0.1119 }, "playwright": { "values": { "available": { "mean": 0.8806, - "effect": 0.0346, + "effect": 0.0344, "n": 156 }, "off": { - "mean": 0.7785, - "effect": -0.0675, - "n": 80 + "mean": 0.7809, + "effect": -0.0654, + "n": 82 } }, - "spread": 0.1021 + "spread": 0.0997 }, "language": { "values": { "javascript": { "mean": 0.85, - "effect": 0.004, + "effect": 0.0038, "n": 11 }, "typescript": { - "mean": 0.851, - "effect": 0.0051, - "n": 213 + "mean": 0.8513, + "effect": 0.005, + "n": 215 }, "unspecified": { "mean": 0.7525, - "effect": -0.0935, + "effect": -0.0937, "n": 12 } }, - "spread": 0.0985 + "spread": 0.0988 }, "tool_grep": { "values": { "off": { "mean": 0.763, - "effect": -0.083, + "effect": -0.0832, "n": 20 }, "on": { - "mean": 0.8537, - "effect": 0.0077, - "n": 216 + "mean": 0.8539, + "effect": 0.0076, + "n": 218 } }, - "spread": 0.0907 + "spread": 0.0909 }, "tool_read": { "values": { "off": { "mean": 0.7796, - "effect": -0.0664, + "effect": -0.0667, "n": 23 }, "on": { - "mean": 0.8531, - "effect": 0.0072, - "n": 213 + "mean": 0.8533, + "effect": 0.0071, + "n": 215 } }, - "spread": 0.0735 + "spread": 0.0737 }, "web_search": { "values": { "off": { "mean": 0.7861, - "effect": -0.0599, + "effect": -0.0601, "n": 28 }, "on": { - "mean": 0.854, - "effect": 0.0081, - "n": 208 + "mean": 0.8542, + "effect": 0.008, + "n": 210 } }, - "spread": 0.0679 + "spread": 0.0681 }, "human_language": { "values": { "en": { - "mean": 0.8524, + "mean": 0.8526, "effect": 0.0064, - "n": 213 + "n": 215 }, "es": { "mean": 0.7865, - "effect": -0.0595, + "effect": -0.0597, "n": 23 } }, - "spread": 0.0659 + "spread": 0.0661 }, "effort": { "values": { "high": { - "mean": 0.8426, - "effect": -0.0034, - "n": 223 + "mean": 0.8429, + "effect": -0.0033, + "n": 225 }, "max": { "mean": 0.9038, - "effect": 0.0579, + "effect": 0.0576, "n": 13 } }, - "spread": 0.0612 + "spread": 0.0609 }, "tool_edit": { "values": { "off": { "mean": 0.8104, - "effect": -0.0356, + "effect": -0.0358, "n": 25 }, "on": { - "mean": 0.8502, + "mean": 0.8504, "effect": 0.0042, - "n": 211 + "n": 213 } }, - "spread": 0.0398 + "spread": 0.04 }, - "tool_glob": { + "max_budget": { "values": { - "off": { - "mean": 0.8289, - "effect": -0.0171, - "n": 18 + "high": { + "mean": 0.8295, + "effect": -0.0167, + "n": 20 }, - "on": { - "mean": 0.8474, - "effect": 0.0014, + "low": { + "mean": 0.8478, + "effect": 0.0015, "n": 218 } }, - "spread": 0.0185 + "spread": 0.0183 }, - "max_budget": { + "tool_glob": { "values": { - "high": { - "mean": 0.8295, - "effect": -0.0165, + "off": { + "mean": 0.8335, + "effect": -0.0127, "n": 20 }, - "low": { - "mean": 0.8475, - "effect": 0.0015, - "n": 216 + "on": { + "mean": 0.8474, + "effect": 0.0012, + "n": 218 } }, - "spread": 0.018 + "spread": 0.0139 }, "tool_write": { "values": { "off": { "mean": 0.8368, - "effect": -0.0092, + "effect": -0.0094, "n": 25 }, "on": { - "mean": 0.8471, + "mean": 0.8473, "effect": 0.0011, - "n": 211 + "n": 213 } }, - "spread": 0.0103 + "spread": 0.0105 }, "context_file": { "values": { "none": { - "mean": 0.8469, + "mean": 0.8471, "effect": 0.0009, - "n": 214 + "n": 216 }, "provided": { "mean": 0.8373, - "effect": -0.0087, + "effect": -0.0089, "n": 22 } }, - "spread": 0.0096 + "spread": 0.0098 } } \ No newline at end of file diff --git a/results/analysis/main_effects_transcript.json b/results/analysis/main_effects_transcript.json @@ -3,32 +3,32 @@ "values": { "glm-4.5-air": { "mean": 0.9692, - "effect": 0.0586, + "effect": 0.0587, "n": 13 }, "glm-4.7": { - "mean": 0.8878, - "effect": -0.0228, - "n": 37 + "mean": 0.8885, + "effect": -0.022, + "n": 39 }, "glm-5.1": { "mean": 1.0, - "effect": 0.0894, + "effect": 0.0895, "n": 9 }, "haiku": { "mean": 0.7872, - "effect": -0.1234, + "effect": -0.1233, "n": 74 }, "opus": { "mean": 1.0, - "effect": 0.0894, + "effect": 0.0895, "n": 51 }, "sonnet": { "mean": 0.9846, - "effect": 0.074, + "effect": 0.0741, "n": 52 } }, @@ -38,27 +38,27 @@ "values": { "creative_validate": { "mean": 0.95, - "effect": 0.0394, + "effect": 0.0395, "n": 3 }, "iterate": { "mean": 0.8667, - "effect": -0.0439, + "effect": -0.0438, "n": 3 }, "none": { "mean": 0.902, - "effect": -0.0086, - "n": 74 + "effect": -0.0085, + "n": 76 }, "plan_first": { "mean": 0.8167, - "effect": -0.0939, + "effect": -0.0938, "n": 3 }, "use_subagents": { "mean": 0.9167, - "effect": 0.0061, + "effect": 0.0062, "n": 153 } }, @@ -68,17 +68,17 @@ "values": { "javascript": { "mean": 1.0, - "effect": 0.0894, + "effect": 0.0895, "n": 11 }, "typescript": { "mean": 0.9021, - "effect": -0.0085, - "n": 213 + "effect": -0.0084, + "n": 215 }, "unspecified": { "mean": 0.9792, - "effect": 0.0686, + "effect": 0.0687, "n": 12 } }, @@ -88,198 +88,198 @@ "values": { "dom": { "mean": 1.0, - "effect": 0.0894, + "effect": 0.0895, "n": 3 }, "none": { - "mean": 0.9091, + "mean": 0.909, "effect": -0.0015, - "n": 232 + "n": 234 }, "webgl": { "mean": 1.0, - "effect": 0.0894, + "effect": 0.0895, "n": 1 } }, - "spread": 0.0909 + "spread": 0.091 }, "tool_write": { "values": { "off": { "mean": 0.84, - "effect": -0.0706, + "effect": -0.0705, "n": 25 }, "on": { - "mean": 0.919, - "effect": 0.0084, - "n": 211 - } - }, - "spread": 0.079 - }, - "tool_glob": { - "values": { - "off": { - "mean": 0.8389, - "effect": -0.0717, - "n": 18 - }, - "on": { - "mean": 0.9165, - "effect": 0.0059, - "n": 218 + "mean": 0.9188, + "effect": 0.0083, + "n": 213 } }, - "spread": 0.0776 + "spread": 0.0788 }, "context_file": { "values": { "none": { - "mean": 0.9178, - "effect": 0.0072, - "n": 214 + "mean": 0.9176, + "effect": 0.0071, + "n": 216 }, "provided": { "mean": 0.8409, - "effect": -0.0697, + "effect": -0.0696, "n": 22 } }, - "spread": 0.0769 + "spread": 0.0767 }, "tool_read": { "values": { "off": { "mean": 0.8413, - "effect": -0.0693, + "effect": -0.0692, "n": 23 }, "on": { - "mean": 0.9181, - "effect": 0.0075, - "n": 213 + "mean": 0.9179, + "effect": 0.0074, + "n": 215 } }, - "spread": 0.0768 + "spread": 0.0766 }, "tool_edit": { "values": { "off": { "mean": 0.846, - "effect": -0.0646, + "effect": -0.0645, "n": 25 }, "on": { - "mean": 0.9182, - "effect": 0.0077, - "n": 211 + "mean": 0.9181, + "effect": 0.0076, + "n": 213 + } + }, + "spread": 0.0721 + }, + "tool_glob": { + "values": { + "off": { + "mean": 0.845, + "effect": -0.0655, + "n": 20 + }, + "on": { + "mean": 0.9165, + "effect": 0.006, + "n": 218 } }, - "spread": 0.0722 + "spread": 0.0715 }, "tool_grep": { "values": { "off": { "mean": 0.845, - "effect": -0.0656, + "effect": -0.0655, "n": 20 }, "on": { - "mean": 0.9167, - "effect": 0.0061, - "n": 216 + "mean": 0.9165, + "effect": 0.006, + "n": 218 } }, - "spread": 0.0717 + "spread": 0.0715 }, "human_language": { "values": { "en": { - "mean": 0.9169, - "effect": 0.0063, - "n": 213 + "mean": 0.9167, + "effect": 0.0062, + "n": 215 }, "es": { "mean": 0.8522, - "effect": -0.0584, + "effect": -0.0583, "n": 23 } }, - "spread": 0.0647 + "spread": 0.0645 }, "prompt_style": { "values": { "detailed": { "mean": 0.8614, - "effect": -0.0492, + "effect": -0.0491, "n": 22 }, "simple": { - "mean": 0.9157, - "effect": 0.0051, - "n": 214 + "mean": 0.9155, + "effect": 0.005, + "n": 216 } }, - "spread": 0.0543 + "spread": 0.0541 }, "linter": { "values": { "off": { "mean": 0.8643, - "effect": -0.0463, + "effect": -0.0462, "n": 28 }, "on": { - "mean": 0.9168, + "mean": 0.9167, "effect": 0.0062, - "n": 208 + "n": 210 } }, - "spread": 0.0525 + "spread": 0.0524 }, "web_search": { "values": { "off": { "mean": 0.8679, - "effect": -0.0427, + "effect": -0.0426, "n": 28 }, "on": { - "mean": 0.9163, - "effect": 0.0058, - "n": 208 + "mean": 0.9162, + "effect": 0.0057, + "n": 210 } }, - "spread": 0.0484 + "spread": 0.0483 }, "max_budget": { "values": { "high": { "mean": 0.8675, - "effect": -0.0431, + "effect": -0.043, "n": 20 }, "low": { - "mean": 0.9146, - "effect": 0.004, - "n": 216 + "mean": 0.9144, + "effect": 0.0039, + "n": 218 } }, - "spread": 0.0471 + "spread": 0.0469 }, "playwright": { "values": { "available": { "mean": 0.9154, - "effect": 0.0048, + "effect": 0.0049, "n": 156 }, "off": { "mean": 0.9012, "effect": -0.0093, - "n": 80 + "n": 82 } }, "spread": 0.0142 @@ -287,9 +287,9 @@ "effort": { "values": { "high": { - "mean": 0.911, + "mean": 0.9109, "effect": 0.0004, - "n": 223 + "n": 225 }, "max": { "mean": 0.9038, @@ -297,6 +297,6 @@ "n": 13 } }, - "spread": 0.0072 + "spread": 0.0071 } } \ No newline at end of file diff --git a/results/analysis/main_effects_turns.json b/results/analysis/main_effects_turns.json @@ -3,27 +3,27 @@ "values": { "creative_validate": { "mean": 69.3333, - "effect": 48.8842, + "effect": 49.0476, "n": 3 }, "iterate": { "mean": 1.3333, - "effect": -19.1158, + "effect": -18.9524, "n": 3 }, "none": { - "mean": 16.7973, - "effect": -3.6519, - "n": 74 + "mean": 16.3816, + "effect": -3.9041, + "n": 76 }, "plan_first": { "mean": 1.6667, - "effect": -18.7825, + "effect": -18.619, "n": 3 }, "use_subagents": { "mean": 22.0, - "effect": 1.5508, + "effect": 1.7143, "n": 153 } }, @@ -33,270 +33,270 @@ "values": { "dom": { "mean": 27.0, - "effect": 6.5508, + "effect": 6.7143, "n": 3 }, "none": { - "mean": 20.2845, - "effect": -0.1647, - "n": 232 + "mean": 20.1197, + "effect": -0.1661, + "n": 234 }, "webgl": { "mean": 39.0, - "effect": 18.5508, + "effect": 18.7143, "n": 1 } }, - "spread": 18.7155 + "spread": 18.8803 }, "model": { "values": { "glm-4.5-air": { "mean": 16.5385, - "effect": -3.9107, + "effect": -3.7473, "n": 13 }, "glm-4.7": { - "mean": 11.5676, - "effect": -8.8816, - "n": 37 + "mean": 11.0256, + "effect": -9.2601, + "n": 39 }, "glm-5.1": { "mean": 24.2222, - "effect": 3.7731, + "effect": 3.9365, "n": 9 }, "haiku": { "mean": 26.2838, - "effect": 5.8346, + "effect": 5.9981, "n": 74 }, "opus": { "mean": 19.2549, - "effect": -1.1943, + "effect": -1.0308, "n": 51 }, "sonnet": { "mean": 19.9615, - "effect": -0.4876, + "effect": -0.3242, "n": 52 } }, - "spread": 14.7162 + "spread": 15.2582 }, "language": { "values": { "javascript": { "mean": 7.9091, - "effect": -12.5401, + "effect": -12.3766, "n": 11 }, "typescript": { - "mean": 21.7559, - "effect": 1.3067, - "n": 213 + "mean": 21.5628, + "effect": 1.2771, + "n": 215 }, "unspecified": { "mean": 8.75, - "effect": -11.6992, + "effect": -11.5357, "n": 12 } }, - "spread": 13.8468 + "spread": 13.6537 }, "context_file": { "values": { "none": { - "mean": 19.9346, - "effect": -0.5146, - "n": 214 + "mean": 19.7593, + "effect": -0.5265, + "n": 216 }, "provided": { "mean": 25.4545, - "effect": 5.0054, + "effect": 5.1688, "n": 22 } }, - "spread": 5.5199 - }, - "tool_glob": { - "values": { - "off": { - "mean": 25.3889, - "effect": 4.9397, - "n": 18 - }, - "on": { - "mean": 20.0413, - "effect": -0.4079, - "n": 218 - } - }, - "spread": 5.3476 + "spread": 5.6952 }, "playwright": { "values": { "available": { "mean": 22.0321, - "effect": 1.5829, + "effect": 1.7463, "n": 156 }, "off": { - "mean": 17.3625, - "effect": -3.0867, - "n": 80 + "mean": 16.9634, + "effect": -3.3223, + "n": 82 } }, - "spread": 4.6696 + "spread": 5.0687 }, "web_search": { "values": { "off": { "mean": 24.5, - "effect": 4.0508, + "effect": 4.2143, "n": 28 }, "on": { - "mean": 19.9038, - "effect": -0.5453, - "n": 208 + "mean": 19.7238, + "effect": -0.5619, + "n": 210 } }, - "spread": 4.5962 + "spread": 4.7762 }, "tool_write": { "values": { "off": { "mean": 23.68, - "effect": 3.2308, + "effect": 3.3943, "n": 25 }, "on": { - "mean": 20.0664, - "effect": -0.3828, - "n": 211 + "mean": 19.8873, + "effect": -0.3984, + "n": 213 } }, - "spread": 3.6136 + "spread": 3.7927 }, "tool_grep": { "values": { "off": { "mean": 23.4, - "effect": 2.9508, + "effect": 3.1143, "n": 20 }, "on": { - "mean": 20.1759, - "effect": -0.2732, - "n": 216 + "mean": 20.0, + "effect": -0.2857, + "n": 218 } }, - "spread": 3.2241 + "spread": 3.4 }, "human_language": { "values": { "en": { - "mean": 20.1362, - "effect": -0.313, - "n": 213 + "mean": 19.9581, + "effect": -0.3276, + "n": 215 }, "es": { "mean": 23.3478, - "effect": 2.8987, + "effect": 3.0621, "n": 23 } }, - "spread": 3.2116 + "spread": 3.3897 + }, + "tool_glob": { + "values": { + "off": { + "mean": 22.95, + "effect": 2.6643, + "n": 20 + }, + "on": { + "mean": 20.0413, + "effect": -0.2444, + "n": 218 + } + }, + "spread": 2.9087 }, "tool_read": { "values": { "off": { "mean": 22.7391, - "effect": 2.29, + "effect": 2.4534, "n": 23 }, "on": { - "mean": 20.2019, - "effect": -0.2473, - "n": 213 + "mean": 20.0233, + "effect": -0.2625, + "n": 215 } }, - "spread": 2.5372 + "spread": 2.7158 }, "max_budget": { "values": { "high": { "mean": 22.3, - "effect": 1.8508, + "effect": 2.0143, "n": 20 }, "low": { - "mean": 20.2778, - "effect": -0.1714, - "n": 216 + "mean": 20.1009, + "effect": -0.1848, + "n": 218 } }, - "spread": 2.0222 + "spread": 2.1991 }, "tool_edit": { "values": { "off": { "mean": 22.04, - "effect": 1.5908, + "effect": 1.7543, "n": 25 }, "on": { - "mean": 20.2607, - "effect": -0.1885, - "n": 211 + "mean": 20.0798, + "effect": -0.2059, + "n": 213 } }, - "spread": 1.7793 + "spread": 1.9602 }, "linter": { "values": { "off": { "mean": 21.4286, - "effect": 0.9794, + "effect": 1.1429, "n": 28 }, "on": { - "mean": 20.3173, - "effect": -0.1318, - "n": 208 - } - }, - "spread": 1.1113 - }, - "prompt_style": { - "values": { - "detailed": { - "mean": 19.7273, - "effect": -0.7219, - "n": 22 - }, - "simple": { - "mean": 20.5234, - "effect": 0.0742, - "n": 214 + "mean": 20.1333, + "effect": -0.1524, + "n": 210 } }, - "spread": 0.7961 + "spread": 1.2953 }, "effort": { "values": { "high": { - "mean": 20.4215, - "effect": -0.0276, - "n": 223 + "mean": 20.2489, + "effect": -0.0368, + "n": 225 }, "max": { "mean": 20.9231, - "effect": 0.4739, + "effect": 0.6374, "n": 13 } }, - "spread": 0.5016 + "spread": 0.6742 + }, + "prompt_style": { + "values": { + "detailed": { + "mean": 19.7273, + "effect": -0.5584, + "n": 22 + }, + "simple": { + "mean": 20.3426, + "effect": 0.0569, + "n": 216 + } + }, + "spread": 0.6153 } } \ 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,32 +3,32 @@ "values": { "glm-4.5-air": { "mean": 543.3846, - "effect": 108.1516, + "effect": 107.5275, "n": 13 }, "glm-4.7": { - "mean": 561.6216, - "effect": 126.3886, - "n": 37 + "mean": 558.9487, + "effect": 123.0916, + "n": 39 }, "glm-5.1": { "mean": 572.5556, - "effect": 137.3225, + "effect": 136.6984, "n": 9 }, "haiku": { "mean": 219.973, - "effect": -215.2601, + "effect": -215.8842, "n": 74 }, "opus": { "mean": 224.3529, - "effect": -210.8801, + "effect": -211.5042, "n": 51 }, "sonnet": { "mean": 807.6538, - "effect": 372.4208, + "effect": 371.7967, "n": 52 } }, @@ -38,27 +38,27 @@ "values": { "creative_validate": { "mean": 748.0, - "effect": 312.7669, + "effect": 312.1429, "n": 3 }, "iterate": { "mean": 635.6667, - "effect": 200.4336, + "effect": 199.8095, "n": 3 }, "none": { - "mean": 456.6216, - "effect": 21.3886, - "n": 74 + "mean": 458.0132, + "effect": 22.156, + "n": 76 }, "plan_first": { "mean": 926.0, - "effect": 490.7669, + "effect": 490.1429, "n": 3 }, "use_subagents": { "mean": 405.2026, - "effect": -30.0304, + "effect": -30.6545, "n": 153 } }, @@ -68,235 +68,235 @@ "values": { "dom": { "mean": 560.3333, - "effect": 125.1003, + "effect": 124.4762, "n": 3 }, "none": { - "mean": 431.7802, - "effect": -3.4529, - "n": 232 + "mean": 432.4444, + "effect": -3.4127, + "n": 234 }, "webgl": { "mean": 861.0, - "effect": 425.7669, + "effect": 425.1429, "n": 1 } }, - "spread": 429.2198 - }, - "tool_glob": { - "values": { - "off": { - "mean": 288.9444, - "effect": -146.2886, - "n": 18 - }, - "on": { - "mean": 447.3119, - "effect": 12.0789, - "n": 218 - } - }, - "spread": 158.3675 + "spread": 428.5556 }, "max_budget": { "values": { "high": { "mean": 294.5, - "effect": -140.7331, + "effect": -141.3571, "n": 20 }, "low": { - "mean": 448.2639, - "effect": 13.0308, - "n": 216 + "mean": 448.8257, + "effect": 12.9685, + "n": 218 } }, - "spread": 153.7639 + "spread": 154.3257 }, "tool_edit": { "values": { "off": { "mean": 299.6, - "effect": -135.6331, + "effect": -136.2571, "n": 25 }, "on": { - "mean": 451.3033, - "effect": 16.0703, - "n": 211 + "mean": 451.8498, + "effect": 15.9926, + "n": 213 } }, - "spread": 151.7033 + "spread": 152.2498 }, "effort": { "values": { "high": { - "mean": 427.1121, - "effect": -8.1209, - "n": 223 + "mean": 427.8444, + "effect": -8.0127, + "n": 225 }, "max": { "mean": 574.5385, - "effect": 139.3054, + "effect": 138.6813, "n": 13 } }, - "spread": 147.4264 + "spread": 146.6941 }, "context_file": { "values": { "none": { - "mean": 448.8318, - "effect": 13.5987, - "n": 214 + "mean": 449.3935, + "effect": 13.5364, + "n": 216 }, "provided": { "mean": 302.9545, - "effect": -132.2785, + "effect": -132.9026, "n": 22 } }, - "spread": 145.8773 + "spread": 146.439 }, "tool_grep": { "values": { "off": { "mean": 309.65, - "effect": -125.5831, + "effect": -126.2071, "n": 20 }, "on": { - "mean": 446.8611, - "effect": 11.6281, - "n": 216 + "mean": 447.4358, + "effect": 11.5786, + "n": 218 } }, - "spread": 137.2111 + "spread": 137.7858 + }, + "tool_glob": { + "values": { + "off": { + "mean": 311.0, + "effect": -124.8571, + "n": 20 + }, + "on": { + "mean": 447.3119, + "effect": 11.4548, + "n": 218 + } + }, + "spread": 136.3119 }, "playwright": { "values": { "available": { "mean": 402.0256, - "effect": -33.2074, + "effect": -33.8315, "n": 156 }, "off": { - "mean": 499.9875, - "effect": 64.7544, - "n": 80 + "mean": 500.2195, + "effect": 64.3624, + "n": 82 } }, - "spread": 97.9619 + "spread": 98.1939 }, "language": { "values": { "javascript": { "mean": 351.9091, - "effect": -83.324, + "effect": -83.9481, "n": 11 }, "typescript": { - "mean": 442.7793, - "effect": 7.5463, - "n": 213 + "mean": 443.4, + "effect": 7.5429, + "n": 215 }, "unspecified": { "mean": 377.6667, - "effect": -57.5664, + "effect": -58.1905, "n": 12 } }, - "spread": 90.8702 + "spread": 91.4909 }, "linter": { "values": { "off": { "mean": 356.8571, - "effect": -78.3759, + "effect": -79.0, "n": 28 }, "on": { - "mean": 445.7837, - "effect": 10.5506, - "n": 208 + "mean": 446.3905, + "effect": 10.5333, + "n": 210 } }, - "spread": 88.9266 + "spread": 89.5334 }, "prompt_style": { "values": { "detailed": { "mean": 360.6818, - "effect": -74.5512, + "effect": -75.1753, "n": 22 }, "simple": { - "mean": 442.8972, - "effect": 7.6641, - "n": 214 + "mean": 443.5139, + "effect": 7.6567, + "n": 216 } }, - "spread": 82.2154 + "spread": 82.8321 }, "tool_write": { "values": { "off": { "mean": 375.56, - "effect": -59.6731, + "effect": -60.2971, "n": 25 }, "on": { - "mean": 442.3033, - "effect": 7.0703, - "n": 211 + "mean": 442.9343, + "effect": 7.0771, + "n": 213 } }, - "spread": 66.7433 + "spread": 67.3743 }, "web_search": { "values": { "off": { "mean": 386.7143, - "effect": -48.5188, + "effect": -49.1429, "n": 28 }, "on": { - "mean": 441.7644, - "effect": 6.5314, - "n": 208 + "mean": 442.4095, + "effect": 6.5524, + "n": 210 } }, - "spread": 55.0501 + "spread": 55.6952 }, "human_language": { "values": { "en": { - "mean": 440.3662, - "effect": 5.1331, - "n": 213 + "mean": 441.0093, + "effect": 5.1522, + "n": 215 }, "es": { "mean": 387.6957, - "effect": -47.5374, + "effect": -48.1615, "n": 23 } }, - "spread": 52.6705 + "spread": 53.3136 }, "tool_read": { "values": { "off": { "mean": 400.3043, - "effect": -34.9287, + "effect": -35.5528, "n": 23 }, "on": { - "mean": 439.0047, - "effect": 3.7716, - "n": 213 + "mean": 439.6605, + "effect": 3.8033, + "n": 215 } }, - "spread": 38.7004 + "spread": 39.3562 } } \ No newline at end of file diff --git a/results/index.jsonl b/results/index.jsonl @@ -234,3 +234,5 @@ {"run_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off_run1", "task": "tetris", "model": "haiku", "cell_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off", "short_id": "67825cfa", "short_cell_id": "b0ec2d7c", "completed_at": "2026-04-06T11:07:43.412285+00:00"} {"run_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off_run2", "task": "tetris", "model": "haiku", "cell_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off", "short_id": "ccc32a02", "short_cell_id": "b0ec2d7c", "completed_at": "2026-04-06T11:06:57.859005+00:00"} {"run_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off_run3", "task": "tetris", "model": "haiku", "cell_id": "tetris_arch=none_ctx=provided_noise=clean_dsgn=none_eff=high_echk=none_hlang=es_lang=ts_lint=on_budget=high_model=haiku_pw=off_prompt=simple_rndr=none_strat=usub_tst=none_tedit=off_tglob=on_tgrep=on_tread=on_twrite=off_web=off", "short_id": "edcf7c7c", "short_cell_id": "b0ec2d7c", "completed_at": "2026-04-06T11:04:14.817177+00:00"} +{"run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2", "task": "tetris", "model": "glm-4.7", "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on", "short_id": "fe0ccd52", "short_cell_id": "8205db2d", "completed_at": "2026-04-07T08:48:22.477925+00:00"} +{"run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3", "task": "tetris", "model": "glm-4.7", "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on", "short_id": "65b5c05a", "short_cell_id": "8205db2d", "completed_at": "2026-04-07T08:50:35.391903+00:00"} diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_output.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":5656,"duration_api_ms":442042,"num_turns":1,"result":"The HTTP server is now running successfully. You can play the Tetris game at:\n\n**http://localhost:8080**\n\nJust open that URL in your browser and click the **START** button to begin playing. The game includes all standard Tetris mechanics with keyboard controls, scoring, and increasing difficulty as you progress through levels.","stop_reason":"end_turn","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","total_cost_usd":0.1734975,"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":13335,"output_tokens":111,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":1241,"outputTokens":8398,"cacheReadInputTokens":146015,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.1734975,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"e9d31893-1d62-4e1d-b2ea-5ee22ac129e0"} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_stderr.log b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/claude_stderr.log diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/eval_results.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/eval_results.json @@ -0,0 +1,135 @@ +{ + "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 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": true + }, + "performance": { + "pass": true, + "bundle_size_bytes": 91703, + "size_under_512kb": true + }, + "score": 1.0 + }, + "code_analysis": { + "files": { + "total": 12, + "code": 8, + "docs": 1, + "unnecessary": 1, + "unnecessary_list": [ + "README.md" + ] + }, + "lines_of_code": 1716, + "dependencies": { + "production": 0, + "dev": 4, + "total": 4 + }, + "complexity": "over-engineered", + "console_logs": 0, + "magic_numbers": { + "count": 41, + "excessive": true + }, + "function_length": { + "count": 67, + "average": 6.6, + "max": 21, + "long_functions": 0 + }, + "max_nesting_depth": 14, + "global_declarations": 8, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 100.0, + "camel_case": 756, + "snake_case": 0 + }, + "error_handling": { + "try_catch_blocks": 4, + "has_error_handling": true + }, + "comments": { + "comment_lines": 95, + "source_lines": 1233, + "ratio_pct": 7.7 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 4, + "files_with_logic": 3, + "files_with_both": 3 + }, + "html_validation": { + "valid": false, + "errors": 2 + }, + "duplication_percentage": 0.0, + "score": 0.65 + }, + "transcript_analysis": { + "total_events": 58, + "tool_calls": { + "total": 14, + "bash": 13, + "write": 1, + "edit": 0, + "read": 0 + }, + "wasted_turns": { + "total": 2, + "docs": 1, + "ascii_art": 0, + "server_starts": 1 + }, + "errors_encountered": 0, + "thinking_blocks": 14, + "text_blocks": 8, + "productivity_ratio": 0.86, + "self_tested": false, + "score": 0.9 + }, + "gameplay_bot": { + "pass": false, + "score": 0, + "error": "Gameplay bot timed out after 180 seconds" + }, + "outcome_score": 0.0, + "score": 0.0, + "sonarqube": { + "error": "SonarQube not running at localhost:9000", + "score": 0 + } +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/meta.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/meta.json @@ -0,0 +1,40 @@ +{ + "model": "glm-4.7", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "off", + "tool_grep": "on", + "linter": "on", + "playwright": "off", + "context_file": "none", + "web_search": "on", + "max_budget": "low", + "tests_provided": "none", + "strategy": "none", + "design_guidance": "none", + "architecture": "none", + "error_checking": "none", + "context_noise": "clean", + "renderer": "none", + "provider": "zai", + "task": "tetris", + "actual_model": "glm-4.7", + "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2", + "short_id": "fe0ccd52", + "short_cell_id": "8205db2d", + "run_number": 2, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-07T08:40:52.499440+00:00", + "wall_time_seconds": 446, + "exit_code": 0, + "completed_at": "2026-04-07T08:48:22.477925+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/transcript.jsonl b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run2/transcript.jsonl @@ -0,0 +1,58 @@ +{"type": "harness", "subtype": "config", "model": "glm-4.7", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Grep", "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-n6dz6e8u","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"glm-4.7","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":"4a90e7ba-a04e-4563-aede-f22b441526cf","fast_mode_state":"off"} +{"type":"assistant","message":{"id":"msg_20260407164057ff95ea1c0e454201","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The user wants me to build a playable Tetris game that runs in a browser. They want it to have:\n1. All standard mechanics: piece rotation, line clearing, scoring, increasing speed\n2. Keyboard controls for movement and rotation\n3. Use TypeScript\n\nI'll need to create:\n1. An HTML file for the game structure\n2. TypeScript files for the game logic\n3. CSS for styling\n\nLet me start by creating the project structure and files.\n\nThe game will need:\n- Game board (10x20 grid)\n- 7 tetromino pieces (I, O, T, S, Z, J, L)\n- Piece rotation logic\n- Collision detection\n- Line clearing\n- Scoring system\n- Speed progression\n- Keyboard controls\n\nI'll create a complete implementation with TypeScript.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"01b25ab0-0490-4aba-bf86-b0a669959118"} +{"type":"assistant","message":{"id":"msg_20260407164057ff95ea1c0e454201","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"I'll build a complete Tetris game with TypeScript. Let me create the necessary files."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"56742c55-2836-4652-a8cd-3bd401a31700"} +{"type":"assistant","message":{"id":"msg_20260407164057ff95ea1c0e454201","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_46e2e65c6b8c47c8b8c3ede1","name":"Write","input":{"file_path":"/tmp/loop-bench-n6dz6e8u/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=\"styles.css\">\n</head>\n<body>\n <div class=\"container\">\n <div class=\"game-container\">\n <canvas id=\"game\" width=\"300\" height=\"600\"></canvas>\n </div>\n <div class=\"sidebar\">\n <h1>TETRIS</h1>\n <div class=\"score-display\">\n <div class=\"score-label\">SCORE</div>\n <div id=\"score\" class=\"score-value\">0</div>\n </div>\n <div class=\"score-display\">\n <div class=\"score-label\">LEVEL</div>\n <div id=\"level\" class=\"score-value\">1</div>\n </div>\n <div class=\"score-display\">\n <div class=\"score-label\">LINES</div>\n <div id=\"lines\" class=\"score-value\">0</div>\n </div>\n <div class=\"next-piece\">\n <div class=\"score-label\">NEXT</div>\n <canvas id=\"next\" width=\"100\" height=\"100\"></canvas>\n </div>\n <div class=\"controls\">\n <div class=\"score-label\">CONTROLS</div>\n <div class=\"control-item\">← → : Move</div>\n <div class=\"control-item\">↑ : Rotate</div>\n <div class=\"control-item\">↓ : Soft Drop</div>\n <div class=\"control-item\">SPACE : Hard Drop</div>\n <div class=\"control-item\">P : Pause</div>\n </div>\n <button id=\"start-btn\" class=\"btn\">START</button>\n <button id=\"restart-btn\" class=\"btn hidden\">RESTART</button>\n </div>\n </div>\n <div id=\"game-over\" class=\"game-over hidden\">\n <div class=\"game-over-content\">\n <h2>GAME OVER</h2>\n <p id=\"final-score\">Final Score: 0</p>\n </div>\n </div>\n <script src=\"game.js\"></script>\n</body>\n</html>"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"8d9c3830-212d-44cd-8723-5473acff2844"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"<tool_use_error>Error: No such tool available: Write</tool_use_error>","is_error":true,"tool_use_id":"call_46e2e65c6b8c47c8b8c3ede1"}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"173ddb6f-d1ca-4c73-ba5f-303dd406b162","timestamp":"2026-04-07T08:41:33.579Z","tool_use_result":"Error: No such tool available: Write"} +{"type":"assistant","message":{"id":"msg_202604071641345629d0a1942b434d","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"I made an error - I tried to use a \"Write\" tool but it doesn't exist. I need to use the Bash tool to create files. Let me use bash with echo or other methods to create the files.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"cb61c9fb-e776-434b-8c63-10c4058099ac"} +{"type":"assistant","message":{"id":"msg_202604071641345629d0a1942b434d","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Let me use the correct approach to create the files:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"aec27917-50c3-467f-a60d-ce7dc600ffbf"} +{"type":"assistant","message":{"id":"msg_202604071641345629d0a1942b434d","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_1fb0a60686dc43ab815064cb","name":"Bash","input":{"command":"cat > 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=\"styles.css\">\n</head>\n<body>\n <div class=\"container\">\n <div class=\"game-container\">\n <canvas id=\"game\" width=\"300\" height=\"600\"></canvas>\n </div>\n <div class=\"sidebar\">\n <h1>TETRIS</h1>\n <div class=\"score-display\">\n <div class=\"score-label\">SCORE</div>\n <div id=\"score\" class=\"score-value\">0</div>\n </div>\n <div class=\"score-display\">\n <div class=\"score-label\">LEVEL</div>\n <div id=\"level\" class=\"score-value\">1</div>\n </div>\n <div class=\"score-display\">\n <div class=\"score-label\">LINES</div>\n <div id=\"lines\" class=\"score-value\">0</div>\n </div>\n <div class=\"next-piece\">\n <div class=\"score-label\">NEXT</div>\n <canvas id=\"next\" width=\"100\" height=\"100\"></canvas>\n </div>\n <div class=\"controls\">\n <div class=\"score-label\">CONTROLS</div>\n <div class=\"control-item\">← → : Move</div>\n <div class=\"control-item\">↑ : Rotate</div>\n <div class=\"control-item\">↓ : Soft Drop</div>\n <div class=\"control-item\">SPACE : Hard Drop</div>\n <div class=\"control-item\">P : Pause</div>\n </div>\n <button id=\"start-btn\" class=\"btn\">START</button>\n <button id=\"restart-btn\" class=\"btn hidden\">RESTART</button>\n </div>\n </div>\n <div id=\"game-over\" class=\"game-over hidden\">\n <div class=\"game-over-content\">\n <h2>GAME OVER</h2>\n <p id=\"final-score\">Final Score: 0</p>\n </div>\n </div>\n <script src=\"game.js\"></script>\n</body>\n</html>\nEOF","description":"Create HTML file for Tetris game"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"8e0cbdf0-a40e-40ac-88e5-f630c4717418"} +{"type":"assistant","message":{"id":"msg_202604071641345629d0a1942b434d","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_a043efaa8d38476886223142","name":"Bash","input":{"command":"cat > styles.css << 'EOF'\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Arial', sans-serif;\n background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n color: #fff;\n}\n\n.container {\n display: flex;\n gap: 40px;\n align-items: flex-start;\n padding: 40px;\n background: rgba(0, 0, 0, 0.3);\n border-radius: 20px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);\n}\n\n.game-container {\n border: 4px solid #e94560;\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 0 20px rgba(233, 69, 96, 0.5);\n}\n\n#game {\n display: block;\n background: #0a0a0a;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 20px;\n min-width: 200px;\n}\n\nh1 {\n font-size: 36px;\n text-align: center;\n background: linear-gradient(135deg, #e94560, #ff6b6b);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n text-shadow: 0 0 20px rgba(233, 69, 96, 0.3);\n}\n\n.score-display {\n background: rgba(233, 69, 96, 0.1);\n border: 2px solid #e94560;\n border-radius: 10px;\n padding: 15px;\n text-align: center;\n}\n\n.score-label {\n font-size: 12px;\n color: #e94560;\n margin-bottom: 5px;\n letter-spacing: 2px;\n}\n\n.score-value {\n font-size: 28px;\n font-weight: bold;\n text-shadow: 0 0 10px rgba(233, 69, 96, 0.5);\n}\n\n.next-piece {\n background: rgba(233, 69, 96, 0.1);\n border: 2px solid #e94560;\n border-radius: 10px;\n padding: 15px;\n text-align: center;\n}\n\n#next {\n display: block;\n margin: 0 auto;\n background: #0a0a0a;\n border-radius: 5px;\n}\n\n.controls {\n background: rgba(233, 69, 96, 0.1);\n border: 2px solid #e94560;\n border-radius: 10px;\n padding: 15px;\n}\n\n.control-item {\n font-size: 12px;\n padding: 5px 0;\n color: #ccc;\n}\n\n.btn {\n background: linear-gradient(135deg, #e94560, #ff6b6b);\n border: none;\n border-radius: 10px;\n padding: 15px 30px;\n font-size: 16px;\n font-weight: bold;\n color: #fff;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 5px 20px rgba(233, 69, 96, 0.4);\n}\n\n.btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 7px 25px rgba(233, 69, 96, 0.6);\n}\n\n.btn:active {\n transform: translateY(0);\n}\n\n.btn.hidden {\n display: none;\n}\n\n.game-over {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n\n.game-over.hidden {\n display: none;\n}\n\n.game-over-content {\n background: linear-gradient(135deg, #1a1a2e, #16213e);\n border: 4px solid #e94560;\n border-radius: 20px;\n padding: 50px;\n text-align: center;\n box-shadow: 0 0 50px rgba(233, 69, 96, 0.5);\n animation: pulse 2s infinite;\n}\n\n@keyframes pulse {\n 0%, 100% {\n box-shadow: 0 0 50px rgba(233, 69, 96, 0.5);\n }\n 50% {\n box-shadow: 0 0 80px rgba(233, 69, 96, 0.8);\n }\n}\n\n.game-over h2 {\n font-size: 48px;\n margin-bottom: 20px;\n color: #e94560;\n text-shadow: 0 0 20px rgba(233, 69, 96, 0.8);\n}\n\n.game-over p {\n font-size: 24px;\n color: #fff;\n}\nEOF","description":"Create CSS file for Tetris game"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"ab4b5218-5801-495b-ac37-a9d20edd9097"} +{"type":"assistant","message":{"id":"msg_202604071641345629d0a1942b434d","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_ac176166eb584ca084478212","name":"Bash","input":{"command":"cat > tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2015\",\n \"module\": \"ES2015\",\n \"strict\": true,\n \"noImplicitAny\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true\n },\n \"include\": [\"game.ts\"]\n}\nEOF","description":"Create TypeScript config file"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"a1eb0ab7-568c-4548-bae4-5379cc50641f"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_1fb0a60686dc43ab815064cb","type":"tool_result","content":"[rerun: b1]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"664c88e8-681a-4529-afee-25e00b4c91be","timestamp":"2026-04-07T08:43:39.441Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_a043efaa8d38476886223142","type":"tool_result","content":"[rerun: b2]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"944e72f2-cbb1-404c-ae21-00dd579d05e7","timestamp":"2026-04-07T08:43:39.450Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_ac176166eb584ca084478212","type":"tool_result","content":"[rerun: b3]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"88c40b40-d96a-40e3-9ede-2f2177ca9bf8","timestamp":"2026-04-07T08:43:39.465Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164340172ad27e9b02422e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good, I've created the HTML, CSS, and tsconfig.json files. Now I need to create the main TypeScript file for the game logic. Let me create a comprehensive Tetris game in TypeScript.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"6563d940-fd8c-40c1-993e-7e859ee5e554"} +{"type":"assistant","message":{"id":"msg_20260407164340172ad27e9b02422e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me create the main TypeScript game file:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"9afeeb3d-9706-403e-a187-01bd211434de"} +{"type":"assistant","message":{"id":"msg_20260407164340172ad27e9b02422e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_abb8ff8a316742bda8897975","name":"Bash","input":{"command":"cat > game.ts << 'EOF'\n// Tetromino shapes and their colors\ninterface Tetromino {\n shape: number[][];\n color: string;\n id: number;\n}\n\ninterface GameState {\n board: (string | null)[][];\n currentPiece: {\n shape: number[][];\n color: string;\n id: number;\n x: number;\n y: number;\n } | null;\n nextPiece: {\n shape: number[][];\n color: string;\n id: number;\n } | null;\n score: number;\n level: number;\n lines: number;\n isGameOver: boolean;\n isPaused: boolean;\n isPlaying: boolean;\n}\n\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 30;\n\nconst TETROMINOES: Tetromino[] = [\n { shape: [[1, 1, 1, 1]], color: '#00f0f0', id: 1 }, // I\n { shape: [[1, 1], [1, 1]], color: '#f0f000', id: 2 }, // O\n { shape: [[0, 1, 0], [1, 1, 1]], color: '#a000f0', id: 3 }, // T\n { shape: [[0, 1, 1], [1, 1, 0]], color: '#00f000', id: 4 }, // S\n { shape: [[1, 1, 0], [0, 1, 1]], color: '#f00000', id: 5 }, // Z\n { shape: [[1, 0, 0], [1, 1, 1]], color: '#0000f0', id: 6 }, // J\n { shape: [[0, 0, 1], [1, 1, 1]], color: '#f0a000', id: 7 }, // L\n];\n\nclass Tetris {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private nextCanvas: HTMLCanvasElement;\n private nextCtx: CanvasRenderingContext2D;\n private startBtn: HTMLButtonElement;\n private restartBtn: HTMLButtonElement;\n private gameOverEl: HTMLElement;\n private scoreEl: HTMLElement;\n private levelEl: HTMLElement;\n private linesEl: HTMLElement;\n private finalScoreEl: HTMLElement;\n\n private state: GameState;\n private dropInterval: number;\n private lastDropTime: number;\n private animationId: number;\n\n constructor() {\n this.canvas = document.getElementById('game') 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\n this.startBtn = document.getElementById('start-btn') as HTMLButtonElement;\n this.restartBtn = document.getElementById('restart-btn') as HTMLButtonElement;\n this.gameOverEl = document.getElementById('game-over') as HTMLElement;\n this.scoreEl = document.getElementById('score') as HTMLElement;\n this.levelEl = document.getElementById('level') as HTMLElement;\n this.linesEl = document.getElementById('lines') as HTMLElement;\n this.finalScoreEl = document.getElementById('final-score') as HTMLElement;\n\n this.state = this.createInitialState();\n this.dropInterval = 1000;\n this.lastDropTime = 0;\n this.animationId = 0;\n\n this.init();\n }\n\n private createInitialState(): GameState {\n return {\n board: Array.from({ length: ROWS }, () => Array(COLS).fill(null)),\n currentPiece: null,\n nextPiece: null,\n score: 0,\n level: 1,\n lines: 0,\n isGameOver: false,\n isPaused: false,\n isPlaying: false,\n };\n }\n\n private init(): void {\n this.startBtn.addEventListener('click', () => this.startGame());\n this.restartBtn.addEventListener('click', () => this.startGame());\n\n document.addEventListener('keydown', (e) => this.handleKeyPress(e));\n\n this.drawEmptyBoard();\n }\n\n private startGame(): void {\n this.state = this.createInitialState();\n this.state.isPlaying = true;\n this.state.nextPiece = this.getRandomPiece();\n this.spawnNewPiece();\n this.dropInterval = 1000;\n this.lastDropTime = performance.now();\n\n this.gameOverEl.classList.add('hidden');\n this.startBtn.classList.add('hidden');\n this.restartBtn.classList.add('hidden');\n\n this.updateDisplay();\n this.gameLoop();\n }\n\n private gameLoop(timestamp: number = 0): void {\n if (!this.state.isPlaying) return;\n\n if (!this.state.isPaused) {\n if (timestamp - this.lastDropTime > this.dropInterval) {\n this.drop();\n this.lastDropTime = timestamp;\n }\n\n this.draw();\n this.drawNextPiece();\n }\n\n this.animationId = requestAnimationFrame((ts) => this.gameLoop(ts));\n }\n\n private getRandomPiece(): Tetromino {\n const randomIndex = Math.floor(Math.random() * TETROMINOES.length);\n return { ...TETROMINOES[randomIndex] };\n }\n\n private spawnNewPiece(): void {\n const piece = this.state.nextPiece || this.getRandomPiece();\n const shape = piece.shape.map(row => [...row]);\n\n this.state.currentPiece = {\n shape,\n color: piece.color,\n id: piece.id,\n x: Math.floor((COLS - shape[0].length) / 2),\n y: 0,\n };\n\n this.state.nextPiece = this.getRandomPiece();\n\n if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) {\n this.gameOver();\n }\n }\n\n private checkCollision(x: number, y: number, shape: number[][]): boolean {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n\n if (newX < 0 || newX >= COLS || newY >= ROWS) {\n return true;\n }\n\n if (newY >= 0 && this.state.board[newY][newX]) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n private move(dx: number, dy: number): void {\n if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return;\n\n const newX = this.state.currentPiece.x + dx;\n const newY = this.state.currentPiece.y + dy;\n\n if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) {\n this.state.currentPiece.x = newX;\n this.state.currentPiece.y = newY;\n } else if (dy > 0) {\n this.lockPiece();\n }\n }\n\n private rotate(): void {\n if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return;\n\n const shape = this.state.currentPiece.shape;\n const rows = shape.length;\n const cols = shape[0].length;\n\n const rotated = Array.from({ length: cols }, () => Array(rows).fill(0));\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n rotated[col][rows - 1 - row] = shape[row][col];\n }\n }\n\n // Wall kick - try to adjust position if rotation causes collision\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) {\n this.state.currentPiece.shape = rotated;\n this.state.currentPiece.x += kick;\n return;\n }\n }\n }\n\n private hardDrop(): void {\n if (!this.state.currentPiece || this.state.isPaused || this.state.isGameOver) return;\n\n while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) {\n this.state.currentPiece.y++;\n this.state.score += 2; // Bonus points for hard drop\n }\n\n this.lockPiece();\n }\n\n private drop(): void {\n this.move(0, 1);\n }\n\n private lockPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, color, x, y } = this.state.currentPiece;\n\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = y + row;\n const boardX = x + col;\n\n if (boardY >= 0 && boardY < ROWS && boardX >= 0 && boardX < COLS) {\n this.state.board[boardY][boardX] = color;\n }\n }\n }\n }\n\n this.clearLines();\n this.spawnNewPiece();\n this.updateDisplay();\n }\n\n private clearLines(): void {\n let linesCleared = 0;\n\n for (let row = ROWS - 1; row >= 0; row--) {\n if (this.state.board[row].every(cell => cell !== null)) {\n this.state.board.splice(row, 1);\n this.state.board.unshift(Array(COLS).fill(null));\n linesCleared++;\n row++; // Check the same row again\n }\n }\n\n if (linesCleared > 0) {\n const points = [0, 100, 300, 500, 800];\n this.state.score += points[linesCleared] * this.state.level;\n this.state.lines += linesCleared;\n\n // Level up every 10 lines\n const newLevel = Math.floor(this.state.lines / 10) + 1;\n if (newLevel > this.state.level) {\n this.state.level = newLevel;\n // Increase speed (decrease drop interval)\n this.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100);\n }\n }\n }\n\n private gameOver(): void {\n this.state.isGameOver = true;\n this.state.isPlaying = false;\n cancelAnimationFrame(this.animationId);\n\n this.finalScoreEl.textContent = `Final Score: ${this.state.score}`;\n this.gameOverEl.classList.remove('hidden');\n this.restartBtn.classList.remove('hidden');\n }\n\n private handleKeyPress(e: KeyboardEvent): void {\n if (!this.state.isPlaying || this.state.isGameOver) return;\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault();\n this.move(-1, 0);\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.move(1, 0);\n break;\n case 'ArrowDown':\n e.preventDefault();\n this.move(0, 1);\n this.state.score += 1; // Soft drop bonus\n this.updateDisplay();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.rotate();\n break;\n case ' ':\n e.preventDefault();\n this.hardDrop();\n break;\n case 'p':\n case 'P':\n e.preventDefault();\n this.state.isPaused = !this.state.isPaused;\n if (!this.state.isPaused) {\n this.lastDropTime = performance.now();\n }\n break;\n }\n }\n\n private draw(): void {\n this.ctx.fillStyle = '#0a0a0a';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Draw grid\n this.ctx.strokeStyle = '#1a1a1a';\n this.ctx.lineWidth = 1;\n for (let x = 0; x <= COLS; x++) {\n this.ctx.beginPath();\n this.ctx.moveTo(x * BLOCK_SIZE, 0);\n this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE);\n this.ctx.stroke();\n }\n for (let y = 0; y <= ROWS; y++) {\n this.ctx.beginPath();\n this.ctx.moveTo(0, y * BLOCK_SIZE);\n this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE);\n this.ctx.stroke();\n }\n\n // Draw board\n for (let row = 0; row < ROWS; row++) {\n for (let col = 0; col < COLS; col++) {\n if (this.state.board[row][col]) {\n this.drawBlock(col, row, this.state.board[row][col]!);\n }\n }\n }\n\n // Draw ghost piece\n if (this.state.currentPiece) {\n const ghostY = this.getGhostY();\n this.ctx.globalAlpha = 0.3;\n for (let row = 0; row < this.state.currentPiece.shape.length; row++) {\n for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) {\n if (this.state.currentPiece.shape[row][col]) {\n this.drawBlock(\n this.state.currentPiece.x + col,\n ghostY + row,\n this.state.currentPiece.color\n );\n }\n }\n }\n this.ctx.globalAlpha = 1;\n }\n\n // Draw current piece\n if (this.state.currentPiece) {\n for (let row = 0; row < this.state.currentPiece.shape.length; row++) {\n for (let col = 0; col < this.state.currentPiece.shape[row].length; col++) {\n if (this.state.currentPiece.shape[row][col]) {\n this.drawBlock(\n this.state.currentPiece.x + col,\n this.state.currentPiece.y + row,\n this.state.currentPiece.color\n );\n }\n }\n }\n }\n\n // Draw pause overlay\n if (this.state.isPaused) {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.ctx.fillStyle = '#fff';\n this.ctx.font = 'bold 36px Arial';\n this.ctx.textAlign = 'center';\n this.ctx.fillText('PAUSED', this.canvas.width / 2, this.canvas.height / 2);\n }\n }\n\n private getGhostY(): number {\n if (!this.state.currentPiece) return 0;\n\n let ghostY = this.state.currentPiece.y;\n while (!this.checkCollision(this.state.currentPiece.x, ghostY + 1, this.state.currentPiece.shape)) {\n ghostY++;\n }\n return ghostY;\n }\n\n private drawBlock(x: number, y: number, color: string): void {\n const px = x * BLOCK_SIZE;\n const py = y * BLOCK_SIZE;\n\n // Main block\n this.ctx.fillStyle = color;\n this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2);\n\n // Highlight\n this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n this.ctx.fillRect(px + 1, py + 1, BLOCK_SIZE - 2, 4);\n this.ctx.fillRect(px + 1, py + 1, 4, BLOCK_SIZE - 2);\n\n // Shadow\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n this.ctx.fillRect(px + 1, py + BLOCK_SIZE - 5, BLOCK_SIZE - 2, 4);\n this.ctx.fillRect(px + BLOCK_SIZE - 5, py + 1, 4, BLOCK_SIZE - 2);\n }\n\n private drawNextPiece(): void {\n this.nextCtx.fillStyle = '#0a0a0a';\n this.nextCtx.fillRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);\n\n if (!this.state.nextPiece) return;\n\n const piece = this.state.nextPiece;\n const blockSize = 20;\n const offsetX = (this.nextCanvas.width - piece.shape[0].length * blockSize) / 2;\n const offsetY = (this.nextCanvas.height - piece.shape.length * blockSize) / 2;\n\n for (let row = 0; row < piece.shape.length; row++) {\n for (let col = 0; col < piece.shape[row].length; col++) {\n if (piece.shape[row][col]) {\n const px = offsetX + col * blockSize;\n const py = offsetY + row * blockSize;\n\n this.nextCtx.fillStyle = piece.color;\n this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, blockSize - 2);\n\n this.nextCtx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n this.nextCtx.fillRect(px + 1, py + 1, blockSize - 2, 3);\n this.nextCtx.fillRect(px + 1, py + 1, 3, blockSize - 2);\n\n this.nextCtx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n this.nextCtx.fillRect(px + 1, py + blockSize - 4, blockSize - 2, 3);\n this.nextCtx.fillRect(px + blockSize - 4, py + 1, 3, blockSize - 2);\n }\n }\n }\n }\n\n private drawEmptyBoard(): void {\n this.ctx.fillStyle = '#0a0a0a';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.ctx.strokeStyle = '#1a1a1a';\n this.ctx.lineWidth = 1;\n for (let x = 0; x <= COLS; x++) {\n this.ctx.beginPath();\n this.ctx.moveTo(x * BLOCK_SIZE, 0);\n this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE);\n this.ctx.stroke();\n }\n for (let y = 0; y <= ROWS; y++) {\n this.ctx.beginPath();\n this.ctx.moveTo(0, y * BLOCK_SIZE);\n this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE);\n this.ctx.stroke();\n }\n\n this.ctx.fillStyle = '#fff';\n this.ctx.font = 'bold 24px Arial';\n this.ctx.textAlign = 'center';\n this.ctx.fillText('Press START', this.canvas.width / 2, this.canvas.height / 2);\n }\n\n private updateDisplay(): void {\n this.scoreEl.textContent = this.state.score.toString();\n this.levelEl.textContent = this.state.level.toString();\n this.linesEl.textContent = this.state.lines.toString();\n }\n}\n\n// Initialize game when DOM is loaded\ndocument.addEventListener('DOMContentLoaded', () => {\n new Tetris();\n});\nEOF","description":"Create TypeScript game logic"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"d3054451-0b66-400e-bd1a-b243b7412b96"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_abb8ff8a316742bda8897975","type":"tool_result","content":"[rerun: b4]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"c22fa88b-2bd3-4c8f-82c1-70c8c66965f6","timestamp":"2026-04-07T08:46:03.128Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716460433b71bb2dee94232","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Now I need to compile the TypeScript to JavaScript. Let me install TypeScript (if not available) and compile the game.ts file.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"d2800572-ce25-4a54-9526-a046027a90d3"} +{"type":"assistant","message":{"id":"msg_2026040716460433b71bb2dee94232","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me compile the TypeScript to JavaScript:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"f16dc38a-b2ec-47f6-8dc7-899a98d5cadb"} +{"type":"assistant","message":{"id":"msg_2026040716460433b71bb2dee94232","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_69ae5e4b1a17412ab065567b","name":"Bash","input":{"command":"npx tsc game.ts --target ES2015 --module ES2015 --outFile game.js 2>&1 || npm install -g typescript 2>&1 && npx tsc game.ts --target ES2015 --module ES2015 --outFile game.js","description":"Compile TypeScript to JavaScript"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"b2a97b1f-92fd-4aeb-9dfd-7b39b883ad60"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 1\nerror TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.\n\nchanged 1 package in 394ms\nerror TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.\n[rerun: b5]","is_error":true,"tool_use_id":"call_69ae5e4b1a17412ab065567b"}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"45b2d421-55d4-4548-b4af-db9607a34493","timestamp":"2026-04-07T08:46:21.509Z","tool_use_result":"Error: Exit code 1\nerror TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.\n\nchanged 1 package in 394ms\nerror TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.\n[rerun: b5]"} +{"type":"assistant","message":{"id":"msg_20260407164622e0483c5c4c7e49f1","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"I need to use the --ignoreConfig flag to ignore the tsconfig.json file when running tsc with files specified.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"307fcaf3-2256-4b85-99a8-56a73339f511"} +{"type":"assistant","message":{"id":"msg_20260407164622e0483c5c4c7e49f1","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_0469631712314a9b94fe5ca9","name":"Bash","input":{"command":"npx tsc game.ts --target ES2015 --module ES2015 --outFile game.js --ignoreConfig","description":"Compile TypeScript to JavaScript"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"3f1fd3f4-bfa9-4b5d-a128-93b8b7a55a9b"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\nerror TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\nerror TS6082: Only 'amd' and 'system' modules are supported alongside --outFile.\n[rerun: b6]","is_error":true,"tool_use_id":"call_0469631712314a9b94fe5ca9"}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"2bee9ae5-38bd-4a32-a3de-3134ae9bdc9a","timestamp":"2026-04-07T08:46:36.540Z","tool_use_result":"Error: Exit code 2\nerror TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\nerror TS6082: Only 'amd' and 'system' modules are supported alongside --outFile.\n[rerun: b6]"} +{"type":"assistant","message":{"id":"msg_202604071646370be4f45fcc3c4987","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The issue is that ES2015 module doesn't support outFile. I need to use a different approach. Let me either:\n1. Use no module and compile to a single file\n2. Use a bundler like browserify or webpack\n\nFor simplicity, let me just compile without modules and target ES2015.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"b6327c24-b758-495e-93a1-7130f69c4c13"} +{"type":"assistant","message":{"id":"msg_202604071646370be4f45fcc3c4987","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_c54ebd2887494900b7dfd628","name":"Bash","input":{"command":"npx tsc game.ts --target ES2015 --outFile game.js --ignoreConfig --module none","description":"Compile TypeScript to JavaScript without modules"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"19416738-20b5-44cb-8bcc-c012801e6cda"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\nerror TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\nerror TS5107: Option 'module=None' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\n[rerun: b7]","is_error":true,"tool_use_id":"call_c54ebd2887494900b7dfd628"}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"31372b24-d159-4ba8-8e83-5177f500cdd8","timestamp":"2026-04-07T08:46:43.955Z","tool_use_result":"Error: Exit code 2\nerror TS5101: Option 'outFile' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\nerror TS5107: Option 'module=None' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '\"ignoreDeprecations\": \"6.0\"' to silence this error.\n[rerun: b7]"} +{"type":"assistant","message":{"id":"msg_202604071646457647d5066b6a4630","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Let me try a different approach. I'll compile using tsconfig.json instead of command line arguments, and configure it properly.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"203ce82e-82d1-4c87-b419-ae63ff519ab0"} +{"type":"assistant","message":{"id":"msg_202604071646457647d5066b6a4630","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_12ca248a90e24a27b10e0ede","name":"Bash","input":{"command":"cat > tsconfig.json << 'EOF'\n{\n \"compilerOptions\": {\n \"target\": \"ES2015\",\n \"module\": \"none\",\n \"outFile\": \"game.js\",\n \"strict\": true,\n \"noImplicitAny\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"ignoreDeprecations\": \"6.0\"\n },\n \"include\": [\"game.ts\"]\n}\nEOF","description":"Update tsconfig.json with correct settings"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"824719e7-f330-4fbf-b393-e69540bcb422"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_12ca248a90e24a27b10e0ede","type":"tool_result","content":"[rerun: b8]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"692edaa2-40a4-4bb2-978a-a489d6fccd77","timestamp":"2026-04-07T08:46:59.094Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164701b0f41d27a39f4e38","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good, now let me compile using tsconfig.json.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"a2a7e403-dbd4-4b13-9337-2809ecbaa58f"} +{"type":"assistant","message":{"id":"msg_20260407164701b0f41d27a39f4e38","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_82478f2d4bf344b691115ee2","name":"Bash","input":{"command":"npx tsc","description":"Compile TypeScript using tsconfig.json"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"f30d2ea9-8956-4a84-b62a-379ebb7bde80"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_82478f2d4bf344b691115ee2","type":"tool_result","content":"[rerun: b9]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"0dde37b3-145b-4e39-8323-a30b5d6862be","timestamp":"2026-04-07T08:47:04.643Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071647053d4be36ff2b141e9","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The TypeScript compilation was successful (no error output). Let me verify that the game.js file was created and check the file list.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"82114e26-b248-483b-9c51-bf79c5e072f4"} +{"type":"assistant","message":{"id":"msg_202604071647053d4be36ff2b141e9","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_8c89d1916898450b840c8135","name":"Bash","input":{"command":"ls -la","description":"List files in current directory"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"317f6551-9025-44a4-84b9-355028bde944"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_8c89d1916898450b840c8135","type":"tool_result","content":"total 148\ndrwx------ 5 root root 4096 Apr 7 10:46 .\ndrwxrwxrwt 819 root root 45056 Apr 7 10:47 ..\n-rw-r--r-- 1 root root 15384 Apr 7 10:47 game.js\n-rw-r--r-- 1 root root 17344 Apr 7 10:46 game.ts\n-rw-r--r-- 1 root root 1958 Apr 7 10:43 index.html\ndrwxr-xr-x 63 root root 4096 Apr 7 10:40 node_modules\n-rw-r--r-- 1 root root 394 Apr 7 10:40 package.json\n-rw-r--r-- 1 root root 32398 Apr 7 10:40 package-lock.json\n-rw-r--r-- 1 root root 3294 Apr 7 10:43 styles.css\ndrwxr-xr-x 2 root root 4096 Apr 6 16:05 tests-few\ndrwxr-xr-x 2 root root 4096 Apr 6 16:07 tests-full\n-rw-r--r-- 1 root root 351 Apr 7 10:46 tsconfig.json\n[rerun: b10]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"32c4e35b-1925-4b92-9629-535cf94ae865","timestamp":"2026-04-07T08:47:16.604Z","tool_use_result":{"stdout":"total 148\ndrwx------ 5 root root 4096 Apr 7 10:46 .\ndrwxrwxrwt 819 root root 45056 Apr 7 10:47 ..\n-rw-r--r-- 1 root root 15384 Apr 7 10:47 game.js\n-rw-r--r-- 1 root root 17344 Apr 7 10:46 game.ts\n-rw-r--r-- 1 root root 1958 Apr 7 10:43 index.html\ndrwxr-xr-x 63 root root 4096 Apr 7 10:40 node_modules\n-rw-r--r-- 1 root root 394 Apr 7 10:40 package.json\n-rw-r--r-- 1 root root 32398 Apr 7 10:40 package-lock.json\n-rw-r--r-- 1 root root 3294 Apr 7 10:43 styles.css\ndrwxr-xr-x 2 root root 4096 Apr 6 16:05 tests-few\ndrwxr-xr-x 2 root root 4096 Apr 6 16:07 tests-full\n-rw-r--r-- 1 root root 351 Apr 7 10:46 tsconfig.json","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164718001bd222401742aa","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The game.js file has been created successfully. Now let me start a simple HTTP server to test the game in the browser. I'll use Python's built-in HTTP server or Node.js http-server.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"2dca2de6-8862-4b17-8c1c-9d51db6d92e5"} +{"type":"assistant","message":{"id":"msg_20260407164718001bd222401742aa","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"The game is compiled. Now let me start a simple HTTP server so you can play it:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"6054bce9-db94-44e9-94f2-347c0345d533"} +{"type":"assistant","message":{"id":"msg_20260407164718001bd222401742aa","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_fa19d82948794666b981256a","name":"Bash","input":{"command":"python3 -m http.server 8080 &","description":"Start HTTP server for the game","run_in_background":true}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"e548a749-3903-4ca3-86e7-30c65e451df5"} +{"type":"system","subtype":"task_started","task_id":"bksca8s0x","tool_use_id":"call_fa19d82948794666b981256a","description":"Start HTTP server for the game","task_type":"local_bash","uuid":"921e86bf-6c85-45c6-b385-dc735a144e86","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_fa19d82948794666b981256a","type":"tool_result","content":"Command running in background with ID: bksca8s0x. Output is being written to: /tmp/claude-0/-tmp-loop-bench-n6dz6e8u/70324406-ed0a-4a8c-ace1-c49357d250fe/tasks/bksca8s0x.output\n[rerun: b11]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"2734a69f-6be8-44dd-9bfc-3bf99796d29a","timestamp":"2026-04-07T08:47:21.002Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false,"backgroundTaskId":"bksca8s0x"}} +{"type":"assistant","message":{"id":"msg_202604071647220a3517ba0c6842af","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The HTTP server has been started in the background. Let me verify it's running and provide instructions to the user.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"dd537468-24bb-48b3-99ff-29d9d1ddb6cb"} +{"type":"assistant","message":{"id":"msg_202604071647220a3517ba0c6842af","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_cdae8320bab44026a7d2174d","name":"Bash","input":{"command":"sleep 1 && curl -I http://localhost:8080/ 2>&1 | head -5","description":"Check if HTTP server is running"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"2fee6093-30e3-4900-8c14-d89c4b0274ef"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_cdae8320bab44026a7d2174d","type":"tool_result","content":" % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 1958 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\nHTTP/1.0 200 OK\r\nServer: SimpleHTTP/0.6 Python/3.12.3\n[rerun: b12]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"7c7e09dd-e0d8-47f1-8294-9e65dfbede3d","timestamp":"2026-04-07T08:47:26.869Z","tool_use_result":{"stdout":" % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 1958 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\nHTTP/1.0 200 OK\r\nServer: SimpleHTTP/0.6 Python/3.12.3","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071647278bb6f1a5ff814206","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The server is running. Let me also create a simple README to explain how to use the game.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"63058a6c-7290-4e12-ac33-0f6061552921"} +{"type":"assistant","message":{"id":"msg_202604071647278bb6f1a5ff814206","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"The game is ready. Let me also create a README file with instructions:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"a534cd71-5cf7-45c3-8274-2e5fa673d797"} +{"type":"assistant","message":{"id":"msg_202604071647278bb6f1a5ff814206","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_8184b03eebb7402192b360d8","name":"Bash","input":{"command":"cat > README.md << 'EOF'\n# Tetris Game\n\nA fully playable Tetris game built with TypeScript, HTML5 Canvas, and CSS3.\n\n## Features\n\n- All standard Tetris mechanics\n - 7 Tetromino shapes (I, O, T, S, Z, J, L)\n - Piece rotation with wall kicks\n - Line clearing with scoring\n - Increasing speed/level progression\n- Ghost piece preview\n- Next piece display\n- Score, level, and lines tracking\n- Pause functionality\n\n## Controls\n\n| Key | Action |\n|-----|--------|\n| ← / → | Move left/right |\n| ↑ | Rotate piece |\n| ↓ | Soft drop (faster fall + points) |\n| Space | Hard drop (instant drop + points) |\n| P | Pause/Resume game |\n\n## Scoring\n\n- Soft drop: 1 point per cell\n- Hard drop: 2 points per cell\n- Line clears:\n - 1 line: 100 × level\n - 2 lines: 300 × level\n - 3 lines: 500 × level\n - 4 lines (Tetris): 800 × level\n\n## How to Play\n\n1. Open the game in a web browser by visiting `http://localhost:8080`\n2. Click the START button to begin\n3. Use the keyboard controls to manipulate pieces\n4. Clear lines to score points and advance levels\n5. Game speeds up every 10 lines cleared\n6. Try to get the highest score possible!\n\n## Files\n\n- `index.html` - Main game HTML structure\n- `styles.css` - Game styling and animations\n- `game.ts` - TypeScript game logic\n- `game.js` - Compiled JavaScript (generated)\n- `tsconfig.json` - TypeScript configuration\n\nTo rebuild the JavaScript after modifying `game.ts`:\n```bash\nnpx tsc\n```\n\nThen refresh your browser.\nEOF","description":"Create README file"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"6c53b29e-83ac-4d71-897a-1af839157234"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_8184b03eebb7402192b360d8","type":"tool_result","content":"[rerun: b13]","is_error":false}]},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"012ff8dd-ce88-4f8b-aa45-3af14d2e0506","timestamp":"2026-04-07T08:47:45.139Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164746ae3cb53505e641a6","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"All files have been created. Let me provide a summary of what was built.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"799e6875-ef1b-4692-938f-15cce74e484e"} +{"type":"assistant","message":{"id":"msg_20260407164746ae3cb53505e641a6","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"I've built a fully playable Tetris game with TypeScript. Here's what's included:\n\n## Files Created\n\n1. **index.html** - The main game structure with canvas elements and UI\n2. **styles.css** - Beautiful gradient styling with animations\n3. **game.ts** - Complete TypeScript game logic\n4. **game.js** - Compiled JavaScript (ready to run)\n5. **README.md** - Documentation and controls\n\n## Game Features\n\n- ✅ **All 7 Tetrominoes** (I, O, T, S, Z, J, L) with classic colors\n- ✅ **Piece rotation** with wall-kick support\n- ✅ **Line clearing** with proper scoring\n- ✅ **Level progression** - speed increases every 10 lines\n- ✅ **Ghost piece** preview to see where pieces will land\n- ✅ **Next piece** display\n- ✅ **Pause functionality**\n- ✅ **Game over** detection and restart\n\n## Controls\n\n- **← →** : Move left/right\n- **↑** : Rotate piece\n- **↓** : Soft drop (faster fall + bonus points)\n- **SPACE** : Hard drop (instant drop + bonus points)\n- **P** : Pause/Resume\n\n## Scoring\n\n- 1 line: 100 × level\n- 2 lines: 300 × level\n- 3 lines: 500 × level\n- 4 lines (Tetris): 800 × level\n\n## Play Now\n\nThe game is served on: **http://localhost:8080**\n\nJust open your browser and navigate to that URL, then click **START** to play!"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"9805f90e-cddb-4cc1-8ab9-db283741220b"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":440419,"duration_api_ms":436387,"num_turns":15,"result":"I've built a fully playable Tetris game with TypeScript. Here's what's included:\n\n## Files Created\n\n1. **index.html** - The main game structure with canvas elements and UI\n2. **styles.css** - Beautiful gradient styling with animations\n3. **game.ts** - Complete TypeScript game logic\n4. **game.js** - Compiled JavaScript (ready to run)\n5. **README.md** - Documentation and controls\n\n## Game Features\n\n- ✅ **All 7 Tetrominoes** (I, O, T, S, Z, J, L) with classic colors\n- ✅ **Piece rotation** with wall-kick support\n- ✅ **Line clearing** with proper scoring\n- ✅ **Level progression** - speed increases every 10 lines\n- ✅ **Ghost piece** preview to see where pieces will land\n- ✅ **Next piece** display\n- ✅ **Pause functionality**\n- ✅ **Game over** detection and restart\n\n## Controls\n\n- **← →** : Move left/right\n- **↑** : Rotate piece\n- **↓** : Soft drop (faster fall + bonus points)\n- **SPACE** : Hard drop (instant drop + bonus points)\n- **P** : Pause/Resume\n\n## Scoring\n\n- 1 line: 100 × level\n- 2 lines: 300 × level\n- 3 lines: 500 × level\n- 4 lines (Tetris): 800 × level\n\n## Play Now\n\nThe game is served on: **http://localhost:8080**\n\nJust open your browser and navigate to that URL, then click **START** to play!","stop_reason":"end_turn","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","total_cost_usd":0.167412,"usage":{"input_tokens":1101,"cache_creation_input_tokens":0,"cache_read_input_tokens":132680,"output_tokens":8287,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":1101,"outputTokens":8287,"cacheReadInputTokens":132680,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.167412,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"5d84d972-00d5-44dd-9aa1-3fa807662e63"} +{"type":"system","subtype":"task_notification","task_id":"bksca8s0x","tool_use_id":"call_fa19d82948794666b981256a","status":"completed","output_file":"/tmp/claude-0/-tmp-loop-bench-n6dz6e8u/70324406-ed0a-4a8c-ace1-c49357d250fe/tasks/bksca8s0x.output","summary":"Background command \"Start HTTP server for the game\" completed (exit code 0)","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"bddcbf5e-3541-4459-81dc-336e20bf0ccb"} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-n6dz6e8u","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"glm-4.7","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":"a1e43b43-1513-4bc3-88d8-3ed3ffafce76","fast_mode_state":"off"} +{"type":"assistant","message":{"id":"msg_20260407164817ffd8f903f8ae45dd","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The HTTP server has started successfully. The background task completed with exit code 0, meaning the server is now running. The user should be able to access the game at http://localhost:8080.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"33b96975-828c-48f8-9e66-2e6d3baf386f"} +{"type":"assistant","message":{"id":"msg_20260407164817ffd8f903f8ae45dd","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"The HTTP server is now running successfully. You can play the Tetris game at:\n\n**http://localhost:8080**\n\nJust open that URL in your browser and click the **START** button to begin playing. The game includes all standard Tetris mechanics with keyboard controls, scoring, and increasing difficulty as you progress through levels."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","uuid":"1a9a240f-b791-4edf-bc8c-bd521d877085"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":5656,"duration_api_ms":442042,"num_turns":1,"result":"The HTTP server is now running successfully. You can play the Tetris game at:\n\n**http://localhost:8080**\n\nJust open that URL in your browser and click the **START** button to begin playing. The game includes all standard Tetris mechanics with keyboard controls, scoring, and increasing difficulty as you progress through levels.","stop_reason":"end_turn","session_id":"70324406-ed0a-4a8c-ace1-c49357d250fe","total_cost_usd":0.1734975,"usage":{"input_tokens":140,"cache_creation_input_tokens":0,"cache_read_input_tokens":13335,"output_tokens":111,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":1241,"outputTokens":8398,"cacheReadInputTokens":146015,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.1734975,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"e9d31893-1d62-4e1d-b2ea-5ee22ac129e0"} diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_output.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_output.json @@ -0,0 +1 @@ +{"type":"result","subtype":"success","is_error":false,"duration_ms":29740,"duration_api_ms":567580,"num_turns":1,"result":"The server started successfully! 🎉\n\nYour Tetris game is now live and ready to play at **http://localhost:8000**\n\nThe game includes all the standard Tetris mechanics with a modern, responsive design:\n\n- **Beautiful UI**: Glassmorphism styling with purple gradient background\n- **Smooth gameplay**: RequestAnimationFrame for 60fps rendering\n- **Visual feedback**: Ghost pieces, 3D block effects, and game over screen\n- **Full type safety**: Written in TypeScript with proper interfaces\n\nJust open the URL in your browser and click \"Start Game\" to play!","stop_reason":"end_turn","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","total_cost_usd":0.2686095,"usage":{"input_tokens":141,"cache_creation_input_tokens":0,"cache_read_input_tokens":20197,"output_tokens":183,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":5586,"outputTokens":11004,"cacheReadInputTokens":289305,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.2686095,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"7226aa0b-b0fe-497c-b5bb-95493c408d61"} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_stderr.log b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/claude_stderr.log diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/eval_results.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/eval_results.json @@ -0,0 +1,274 @@ +{ + "structural": { + "pass": false, + "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": false, + "detail": "TypeScript files found but no tsconfig.json" + } + ], + "score": 0.75 + }, + "quality": { + "lint": { + "pass": true, + "errors": 0, + "warnings": 0 + }, + "typecheck": { + "pass": false, + "error": "no tsconfig.json" + }, + "performance": { + "pass": true, + "bundle_size_bytes": 83826, + "size_under_512kb": true + }, + "score": 0.67 + }, + "code_analysis": { + "files": { + "total": 11, + "code": 8, + "docs": 1, + "unnecessary": 1, + "unnecessary_list": [ + "README.md" + ] + }, + "lines_of_code": 1580, + "dependencies": { + "production": 0, + "dev": 4, + "total": 4 + }, + "complexity": "over-engineered", + "console_logs": 0, + "magic_numbers": { + "count": 49, + "excessive": true + }, + "function_length": { + "count": 64, + "average": 6.1, + "max": 27, + "long_functions": 0 + }, + "max_nesting_depth": 12, + "global_declarations": 8, + "naming": { + "dominant_style": "camelCase", + "consistency_pct": 100.0, + "camel_case": 593, + "snake_case": 0 + }, + "error_handling": { + "try_catch_blocks": 4, + "has_error_handling": true + }, + "comments": { + "comment_lines": 97, + "source_lines": 1168, + "ratio_pct": 8.3 + }, + "separation_of_concerns": { + "verdict": "mixed", + "files_with_rendering": 4, + "files_with_logic": 3, + "files_with_both": 3 + }, + "html_validation": { + "valid": false, + "errors": 2 + }, + "duplication_percentage": 0.0, + "score": 0.65 + }, + "transcript_analysis": { + "total_events": 84, + "tool_calls": { + "total": 20, + "bash": 17, + "write": 1, + "edit": 0, + "read": 2 + }, + "wasted_turns": { + "total": 4, + "docs": 1, + "ascii_art": 0, + "server_starts": 3 + }, + "errors_encountered": 0, + "thinking_blocks": 22, + "text_blocks": 14, + "productivity_ratio": 0.8, + "self_tested": true, + "score": 0.9 + }, + "gameplay_bot": { + "pass": false, + "score": 0.06, + "total": 16, + "passed": 1, + "failed": 15, + "report": { + "implementation": { + "renderer": "unknown", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 240, + "height": 400 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "ArrowUp", + "drop": "Space" + }, + "start_mechanism": "unknown", + "score_element_found": true, + "grid_confidence": 1 + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": false, + "detail": "could not start game with any mechanism" + }, + { + "name": "auto_drop", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_left", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_right", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_down", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "rotate", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "all_pieces_rotate", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "hard_drop", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "piece_locks", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "new_piece_spawns", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "multiple_pieces", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "line_clear", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "score_changes", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "game_over", + "pass": false, + "detail": "skipped: gameplay phase not met" + }, + { + "name": "playable_30s", + "pass": false, + "detail": "skipped: gameplay phase not met" + } + ], + "summary": { + "total": 16, + "passed": 1, + "failed": 15, + "score": 0.06 + }, + "gameplay": { + "pieces_placed": 0, + "lines_cleared": 0, + "max_score_observed": 0, + "play_duration_seconds": 0, + "errors_during_play": 0 + }, + "session": { + "frames": 0, + "events_count": 0, + "pieces_spawned": 0, + "pieces_locked": 0, + "lines_cleared": 0, + "piece_types_seen": [], + "grid_read_success_rate": 0 + }, + "performance": { + "load_time_ms": 29 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role" + ], + "issue_count": 1, + "pass": false + } + } + }, + "outcome_score": 0.03, + "score": 0.03, + "sonarqube": { + "error": "SonarQube not running at localhost:9000", + "score": 0 + } +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/gameplay-bot-report.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/gameplay-bot-report.json @@ -0,0 +1,136 @@ +{ + "implementation": { + "renderer": "unknown", + "grid_detected": true, + "grid_bounds": { + "x": 0, + "y": 0, + "width": 240, + "height": 400 + }, + "controls": { + "left": "ArrowLeft", + "right": "ArrowRight", + "down": "ArrowDown", + "rotate": "ArrowUp", + "drop": "Space" + }, + "start_mechanism": "unknown", + "score_element_found": true, + "grid_confidence": 1 + }, + "tests": [ + { + "name": "game_loads", + "pass": true, + "detail": "no console errors" + }, + { + "name": "game_starts", + "pass": false, + "detail": "could not start game with any mechanism" + }, + { + "name": "auto_drop", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_left", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_right", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "move_down", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "rotate", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "all_pieces_rotate", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "hard_drop", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "piece_locks", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "new_piece_spawns", + "pass": false, + "detail": "skipped: game did not start" + }, + { + "name": "multiple_pieces", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "line_clear", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "score_changes", + "pass": false, + "detail": "skipped: mechanics phase not met" + }, + { + "name": "game_over", + "pass": false, + "detail": "skipped: gameplay phase not met" + }, + { + "name": "playable_30s", + "pass": false, + "detail": "skipped: gameplay phase not met" + } + ], + "summary": { + "total": 16, + "passed": 1, + "failed": 15, + "score": 0.06 + }, + "gameplay": { + "pieces_placed": 0, + "lines_cleared": 0, + "max_score_observed": 0, + "play_duration_seconds": 0, + "errors_during_play": 0 + }, + "session": { + "frames": 0, + "events_count": 0, + "pieces_spawned": 0, + "pieces_locked": 0, + "lines_cleared": 0, + "piece_types_seen": [], + "grid_read_success_rate": 0 + }, + "performance": { + "load_time_ms": 29 + }, + "accessibility": { + "issues": [ + "canvas without aria-label or role" + ], + "issue_count": 1, + "pass": false + } +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/meta.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/meta.json @@ -0,0 +1,40 @@ +{ + "model": "glm-4.7", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "off", + "tool_grep": "on", + "linter": "on", + "playwright": "off", + "context_file": "none", + "web_search": "on", + "max_budget": "low", + "tests_provided": "none", + "strategy": "none", + "design_guidance": "none", + "architecture": "none", + "error_checking": "none", + "context_noise": "clean", + "renderer": "none", + "provider": "zai", + "task": "tetris", + "actual_model": "glm-4.7", + "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3", + "short_id": "65b5c05a", + "short_cell_id": "8205db2d", + "run_number": 3, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-07T08:41:00.762349+00:00", + "wall_time_seconds": 573, + "exit_code": 0, + "completed_at": "2026-04-07T08:50:35.391903+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/transcript.jsonl b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=off_tgrep=on_tread=on_twrite=on_web=on_run3/transcript.jsonl @@ -0,0 +1,84 @@ +{"type": "harness", "subtype": "config", "model": "glm-4.7", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Grep", "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-dps90bem","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"glm-4.7","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":"3293fe48-bf69-4bec-8bbc-1b338ab70230","fast_mode_state":"off"} +{"type":"assistant","message":{"id":"msg_20260407164103014e58c7845447f9","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The user wants me to build a playable Tetris game that runs in a browser. Let me break down the requirements:\n\n1. Standard Tetris mechanics:\n - Piece rotation\n - Line clearing\n - Scoring\n - Increasing speed\n \n2. Keyboard controls for movement and rotation\n\n3. Use TypeScript\n\nI'll need to create:\n1. An HTML file for the game display\n2. TypeScript files for the game logic\n3. CSS for styling\n\nLet me start by creating the project structure and files.\n\nFirst, let me check what's in the current directory.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"c45473df-2844-46c6-8381-7963254e7d92"} +{"type":"assistant","message":{"id":"msg_20260407164103014e58c7845447f9","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"I'll create a playable Tetris game with TypeScript. Let me start by setting up the project structure."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"78c33e68-267e-4989-b93b-8b9cce33e4db"} +{"type":"assistant","message":{"id":"msg_20260407164103014e58c7845447f9","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_3e95823a14f34f2d88c44080","name":"Bash","input":{"command":"ls -la","description":"List current directory contents"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"01f5a2b3-45cb-4f42-b296-49ebf6ac4de2"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_3e95823a14f34f2d88c44080","type":"tool_result","content":"total 100\ndrwx------ 5 root root 4096 Apr 7 10:41 .\ndrwxrwxrwt 819 root root 45056 Apr 7 10:41 ..\ndrwxr-xr-x 63 root root 4096 Apr 7 10:41 node_modules\n-rw-r--r-- 1 root root 394 Apr 7 10:41 package.json\n-rw-r--r-- 1 root root 32398 Apr 7 10:41 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 6 16:05 tests-few\ndrwxr-xr-x 2 root root 4096 Apr 6 16:07 tests-full\n[rerun: b1]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"c926e84e-f753-4138-a0d3-1eea70be2135","timestamp":"2026-04-07T08:41:07.272Z","tool_use_result":{"stdout":"total 100\ndrwx------ 5 root root 4096 Apr 7 10:41 .\ndrwxrwxrwt 819 root root 45056 Apr 7 10:41 ..\ndrwxr-xr-x 63 root root 4096 Apr 7 10:41 node_modules\n-rw-r--r-- 1 root root 394 Apr 7 10:41 package.json\n-rw-r--r-- 1 root root 32398 Apr 7 10:41 package-lock.json\ndrwxr-xr-x 2 root root 4096 Apr 6 16:05 tests-few\ndrwxr-xr-x 2 root root 4096 Apr 6 16:07 tests-full","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716410824a1cd34454f4ff7","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good, it seems like there's already a Node.js project set up. Let me check the package.json to see what's there.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"2c1b9e66-bf20-4433-9551-37f77118762d"} +{"type":"assistant","message":{"id":"msg_2026040716410824a1cd34454f4ff7","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_ccaf8aff9a0e445db6f4422c","name":"Read","input":{"file_path":"/tmp/loop-bench-dps90bem/package.json"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a5d13ac0-2f59-4386-9dba-a2a9b8e5410f"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_ccaf8aff9a0e445db6f4422c","type":"tool_result","content":"1\t{\n2\t \"name\": \"loop-bench-dps90bem\",\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":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"2cb0547c-d3a8-45e1-a1fa-a3a25b9b13b6","timestamp":"2026-04-07T08:41:29.046Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-dps90bem/package.json","content":"{\n \"name\": \"loop-bench-dps90bem\",\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":{"id":"msg_2026040716412913a06a9c19d04630","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good, TypeScript is already installed. Now I'll create the Tetris game. I'll need:\n\n1. HTML file for the game display\n2. TypeScript files for game logic\n3. CSS for styling\n4. Setup for compiling TypeScript\n\nLet me create the files:\n\n1. index.html - The main HTML file\n2. tetris.ts - The main game logic\n3. styles.css - Styling\n4. Update package.json with build scripts\n\nLet me start by creating these files.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a72f8f45-fe25-4c96-9e27-d107a967fb03"} +{"type":"assistant","message":{"id":"msg_2026040716412913a06a9c19d04630","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"I'll create a complete Tetris game with TypeScript. Let me set up the project structure."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"f7e50934-fddf-4a78-9278-7a4639106058"} +{"type":"assistant","message":{"id":"msg_2026040716412913a06a9c19d04630","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_14465323fd8f47f18c98e37e","name":"Write","input":{"file_path":"/tmp/loop-bench-dps90bem/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 Game</title>\n <link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n <div class=\"game-container\">\n <h1>Tetris</h1>\n <div class=\"game-info\">\n <div class=\"info-panel\">\n <h3>Score</h3>\n <p id=\"score\">0</p>\n </div>\n <div class=\"info-panel\">\n <h3>Level</h3>\n <p id=\"level\">1</p>\n </div>\n <div class=\"info-panel\">\n <h3>Lines</h3>\n <p id=\"lines\">0</p>\n </div>\n </div>\n <div class=\"game-board-container\">\n <canvas id=\"tetris\" width=\"240\" height=\"400\"></canvas>\n </div>\n <div class=\"controls-info\">\n <h3>Controls</h3>\n <p>← → : Move</p>\n <p>↑ : Rotate</p>\n <p>↓ : Soft Drop</p>\n <p>Space : Hard Drop</p>\n <p>P : Pause</p>\n </div>\n <button id=\"startBtn\">Start Game</button>\n <button id=\"pauseBtn\" disabled>Pause</button>\n </div>\n <script src=\"tetris.js\"></script>\n</body>\n</html>\n"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"42b5ef3d-2c2f-4ccf-a8f8-72d6d8f224c6"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"<tool_use_error>Error: No such tool available: Write</tool_use_error>","is_error":true,"tool_use_id":"call_14465323fd8f47f18c98e37e"}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"f0b273c9-c8e8-48cd-8557-47028ce5b803","timestamp":"2026-04-07T08:41:47.873Z","tool_use_result":"Error: No such tool available: Write"} +{"type":"assistant","message":{"id":"msg_20260407164149443a7ce9d103427e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"It seems the Write tool is not available. Let me use the Edit tool instead, but first I need to create the files. Let me try using Bash to create the files directly.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ee753e8a-d8a9-4d39-a688-154a4c71b20b"} +{"type":"assistant","message":{"id":"msg_20260407164149443a7ce9d103427e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_a1f8231a7d9e4e0e85c17e47","name":"Bash","input":{"command":"cat > 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 Game</title>\n <link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n <div class=\"game-container\">\n <h1>Tetris</h1>\n <div class=\"game-info\">\n <div class=\"info-panel\">\n <h3>Score</h3>\n <p id=\"score\">0</p>\n </div>\n <div class=\"info-panel\">\n <h3>Level</h3>\n <p id=\"level\">1</p>\n </div>\n <div class=\"info-panel\">\n <h3>Lines</h3>\n <p id=\"lines\">0</p>\n </div>\n </div>\n <div class=\"game-board-container\">\n <canvas id=\"tetris\" width=\"240\" height=\"400\"></canvas>\n </div>\n <div class=\"controls-info\">\n <h3>Controls</h3>\n <p>← → : Move</p>\n <p>↑ : Rotate</p>\n <p>↓ : Soft Drop</p>\n <p>Space : Hard Drop</p>\n <p>P : Pause</p>\n </div>\n <button id=\"startBtn\">Start Game</button>\n <button id=\"pauseBtn\" disabled>Pause</button>\n </div>\n <script src=\"tetris.js\"></script>\n</body>\n</html>\nEOF","description":"Create HTML file for Tetris game"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"f308bb05-b9dd-4fd1-80b4-0b08a0850387"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_a1f8231a7d9e4e0e85c17e47","type":"tool_result","content":"[rerun: b2]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"9442e948-f231-4649-84a7-6482381bcb06","timestamp":"2026-04-07T08:42:10.996Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071642122e0ff91e223d4e65","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good! Now let me create the CSS file.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"e485d86f-7fa5-4202-9a41-e244249b671f"} +{"type":"assistant","message":{"id":"msg_202604071642122e0ff91e223d4e65","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_4e28807141e64e6283cd1b7d","name":"Bash","input":{"command":"cat > styles.css << 'EOF'\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Arial', sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n color: white;\n}\n\n.game-container {\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(10px);\n border-radius: 20px;\n padding: 30px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\n text-align: center;\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 20px;\n text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);\n}\n\n.game-info {\n display: flex;\n justify-content: space-around;\n margin-bottom: 20px;\n}\n\n.info-panel {\n background: rgba(255, 255, 255, 0.2);\n padding: 15px 25px;\n border-radius: 10px;\n min-width: 100px;\n}\n\n.info-panel h3 {\n font-size: 1rem;\n margin-bottom: 5px;\n opacity: 0.8;\n}\n\n.info-panel p {\n font-size: 1.8rem;\n font-weight: bold;\n}\n\n.game-board-container {\n display: flex;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n#tetris {\n border: 4px solid rgba(255, 255, 255, 0.3);\n border-radius: 5px;\n background: rgba(0, 0, 0, 0.3);\n}\n\n.controls-info {\n background: rgba(255, 255, 255, 0.2);\n padding: 15px;\n border-radius: 10px;\n margin-bottom: 20px;\n}\n\n.controls-info h3 {\n margin-bottom: 10px;\n}\n\n.controls-info p {\n margin: 5px 0;\n font-size: 0.9rem;\n}\n\nbutton {\n padding: 12px 30px;\n font-size: 1.1rem;\n border: none;\n border-radius: 25px;\n cursor: pointer;\n transition: all 0.3s ease;\n margin: 5px;\n}\n\n#startBtn {\n background: #4CAF50;\n color: white;\n}\n\n#startBtn:hover {\n background: #45a049;\n transform: translateY(-2px);\n}\n\n#pauseBtn {\n background: #ff9800;\n color: white;\n}\n\n#pauseBtn:hover {\n background: #f57c00;\n transform: translateY(-2px);\n}\n\nbutton:disabled {\n background: #ccc;\n cursor: not-allowed;\n transform: none;\n}\nEOF","description":"Create CSS file for Tetris game styling"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"fd2a9961-6189-4dad-a639-61dc57cadf20"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_4e28807141e64e6283cd1b7d","type":"tool_result","content":"[rerun: b3]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"cbcf4b38-5faf-4c8f-8fc5-7f53aa7cc915","timestamp":"2026-04-07T08:42:54.316Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716425542c6827bfb3b4725","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Now let me create the main TypeScript file for the Tetris game logic.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"2d475cb4-a9d6-43bb-be77-e8e9548d0b16"} +{"type":"assistant","message":{"id":"msg_2026040716425542c6827bfb3b4725","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_24dc2e4103fe49209b4f8b6a","name":"Bash","input":{"command":"cat > tetris.ts << 'EOF'\n// Tetris Game in TypeScript\n\n// Game constants\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 24;\n\n// Tetromino shapes and their colors\nconst TETROMINOES = {\n I: {\n shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n color: '#00f5ff'\n },\n O: {\n shape: [[1, 1], [1, 1]],\n color: '#ffff00'\n },\n T: {\n shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]],\n color: '#a020f0'\n },\n S: {\n shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]],\n color: '#00ff00'\n },\n Z: {\n shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]],\n color: '#ff0000'\n },\n J: {\n shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]],\n color: '#0000ff'\n },\n L: {\n shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]],\n color: '#ff7f00'\n }\n};\n\n// Game state\ninterface GameState {\n board: number[][];\n score: number;\n level: number;\n lines: number;\n gameOver: boolean;\n paused: boolean;\n currentPiece: Tetromino | null;\n nextPiece: Tetromino | null;\n dropInterval: number;\n}\n\ninterface Tetromino {\n shape: number[][];\n color: string;\n x: number;\n y: number;\n type: string;\n}\n\nclass TetrisGame {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private state: GameState;\n private lastTime: number = 0;\n private dropCounter: number = 0;\n private animationId: number | null = null;\n\n constructor() {\n this.canvas = document.getElementById('tetris') as HTMLCanvasElement;\n this.ctx = this.canvas.getContext('2d')!;\n \n this.state = this.getInitialState();\n \n this.setupEventListeners();\n this.draw();\n }\n\n private getInitialState(): GameState {\n return {\n board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)),\n score: 0,\n level: 1,\n lines: 0,\n gameOver: false,\n paused: false,\n currentPiece: null,\n nextPiece: null,\n dropInterval: 1000\n };\n }\n\n private setupEventListeners(): void {\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n\n startBtn.addEventListener('click', () => this.startGame());\n pauseBtn.addEventListener('click', () => this.togglePause());\n\n document.addEventListener('keydown', (e) => this.handleKeyPress(e));\n }\n\n private handleKeyPress(e: KeyboardEvent): void {\n if (this.state.gameOver || this.state.paused) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault();\n this.movePiece(-1, 0);\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.movePiece(1, 0);\n break;\n case 'ArrowDown':\n e.preventDefault();\n this.movePiece(0, 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.rotatePiece();\n break;\n case ' ':\n e.preventDefault();\n this.hardDrop();\n break;\n case 'p':\n case 'P':\n e.preventDefault();\n this.togglePause();\n break;\n }\n }\n\n private startGame(): void {\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n\n this.state = this.getInitialState();\n this.spawnPiece();\n \n startBtn.disabled = true;\n pauseBtn.disabled = false;\n \n this.updateDisplay();\n this.gameLoop();\n }\n\n private togglePause(): void {\n if (this.state.gameOver) {\n return;\n }\n\n this.state.paused = !this.state.paused;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause';\n\n if (!this.state.paused) {\n this.lastTime = performance.now();\n this.gameLoop();\n }\n }\n\n private gameLoop(time: number = 0): void {\n if (this.state.paused || this.state.gameOver) {\n return;\n }\n\n const deltaTime = time - this.lastTime;\n this.lastTime = time;\n this.dropCounter += deltaTime;\n\n if (this.dropCounter > this.state.dropInterval) {\n this.dropPiece();\n this.dropCounter = 0;\n }\n\n this.draw();\n this.animationId = requestAnimationFrame((t) => this.gameLoop(t));\n }\n\n private spawnPiece(): void {\n const types = Object.keys(TETROMINOES);\n const randomType = types[Math.floor(Math.random() * types.length)];\n const tetromino = TETROMINOES[randomType];\n\n this.state.currentPiece = this.state.nextPiece || {\n shape: tetromino.shape.map(row => [...row]),\n color: tetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2),\n y: 0,\n type: randomType\n };\n\n // Generate next piece\n const nextType = types[Math.floor(Math.random() * types.length)];\n const nextTetromino = TETROMINOES[nextType];\n this.state.nextPiece = {\n shape: nextTetromino.shape.map(row => [...row]),\n color: nextTetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2),\n y: 0,\n type: nextType\n };\n\n // Check if game over\n if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) {\n this.state.gameOver = true;\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n startBtn.disabled = false;\n pauseBtn.disabled = true;\n pauseBtn.textContent = 'Pause';\n \n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n }\n \n this.drawGameOver();\n }\n }\n\n private movePiece(dx: number, dy: number): void {\n if (!this.state.currentPiece) return;\n\n const newX = this.state.currentPiece.x + dx;\n const newY = this.state.currentPiece.y + dy;\n\n if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) {\n this.state.currentPiece.x = newX;\n this.state.currentPiece.y = newY;\n this.draw();\n } else if (dy > 0) {\n this.lockPiece();\n }\n }\n\n private dropPiece(): void {\n this.movePiece(0, 1);\n }\n\n private hardDrop(): void {\n if (!this.state.currentPiece) return;\n\n while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) {\n this.state.currentPiece.y++;\n }\n this.lockPiece();\n }\n\n private rotatePiece(): void {\n if (!this.state.currentPiece) return;\n\n const rotated = this.rotateMatrix(this.state.currentPiece.shape);\n \n // Wall kick - try different positions if rotation causes collision\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) {\n this.state.currentPiece.x += kick;\n this.state.currentPiece.shape = rotated;\n this.draw();\n return;\n }\n }\n }\n\n private rotateMatrix(matrix: number[][]): number[][] {\n const n = matrix.length;\n const rotated: number[][] = [];\n \n for (let i = 0; i < n; i++) {\n rotated[i] = [];\n for (let j = 0; j < n; j++) {\n rotated[i][j] = matrix[n - 1 - j][i];\n }\n }\n \n return rotated;\n }\n\n private checkCollision(x: number, y: number, shape: number[][]): boolean {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n \n if (newX < 0 || newX >= COLS || newY >= ROWS) {\n return true;\n }\n \n if (newY >= 0 && this.state.board[newY][newX]) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n private lockPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y } = this.state.currentPiece;\n \n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = y + row;\n const boardX = x + col;\n if (boardY >= 0) {\n this.state.board[boardY][boardX] = 1;\n }\n }\n }\n }\n\n this.clearLines();\n this.spawnPiece();\n }\n\n private clearLines(): void {\n let linesCleared = 0;\n \n for (let row = ROWS - 1; row >= 0; row--) {\n if (this.state.board[row].every(cell => cell === 1)) {\n this.state.board.splice(row, 1);\n this.state.board.unshift(Array(COLS).fill(0));\n linesCleared++;\n row++; // Check the same row again\n }\n }\n\n if (linesCleared > 0) {\n this.updateScore(linesCleared);\n }\n }\n\n private updateScore(linesCleared: number): void {\n // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris)\n const points = [0, 100, 300, 500, 800];\n this.state.score += points[linesCleared] * this.state.level;\n this.state.lines += linesCleared;\n \n // Level up every 10 lines\n this.state.level = Math.floor(this.state.lines / 10) + 1;\n \n // Increase speed (decrease drop interval)\n this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100);\n \n this.updateDisplay();\n }\n\n private updateDisplay(): void {\n document.getElementById('score')!.textContent = this.state.score.toString();\n document.getElementById('level')!.textContent = this.state.level.toString();\n document.getElementById('lines')!.textContent = this.state.lines.toString();\n }\n\n private draw(): void {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBoard();\n this.drawCurrentPiece();\n this.drawGhostPiece();\n }\n\n private drawBoard(): void {\n for (let row = 0; row < ROWS; row++) {\n for (let col = 0; col < COLS; col++) {\n if (this.state.board[row][col]) {\n this.drawBlock(col, row, '#ffffff');\n }\n }\n }\n }\n\n private drawCurrentPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y, color } = this.state.currentPiece;\n \n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, y + row, color);\n }\n }\n }\n }\n\n private drawGhostPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y, color } = this.state.currentPiece;\n let ghostY = y;\n\n // Find where the ghost piece would land\n while (!this.checkCollision(x, ghostY + 1, shape)) {\n ghostY++;\n }\n\n // Draw ghost piece (semi-transparent)\n this.ctx.globalAlpha = 0.3;\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, ghostY + row, color);\n }\n }\n }\n this.ctx.globalAlpha = 1.0;\n }\n\n private drawBlock(x: number, y: number, color: string): void {\n const padding = 1;\n this.ctx.fillStyle = color;\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + padding,\n BLOCK_SIZE - padding * 2,\n BLOCK_SIZE - padding * 2\n );\n \n // Add a slight 3D effect\n this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + padding,\n BLOCK_SIZE - padding * 2,\n 4\n );\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + BLOCK_SIZE - padding - 4,\n BLOCK_SIZE - padding * 2,\n 4\n );\n }\n\n private drawGameOver(): void {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n \n this.ctx.fillStyle = '#ffffff';\n this.ctx.font = 'bold 24px Arial';\n this.ctx.textAlign = 'center';\n this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20);\n this.ctx.font = '16px Arial';\n this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20);\n this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50);\n }\n}\n\n// Initialize game when DOM is loaded\ndocument.addEventListener('DOMContentLoaded', () => {\n new TetrisGame();\n});\nEOF","description":"Create TypeScript file for Tetris game logic"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ca7faf62-9695-4e54-8a8a-2c5d9a034659"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_24dc2e4103fe49209b4f8b6a","type":"tool_result","content":"[rerun: b4]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ee5cd1fb-b848-40c9-854c-2b2d12b09773","timestamp":"2026-04-07T08:45:41.223Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071645423084f819c7a2451a","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Now I need to update the package.json to add build scripts for compiling TypeScript. Let me update it.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"b6496241-3398-4db5-8c51-fd1ad799e69a"} +{"type":"assistant","message":{"id":"msg_202604071645423084f819c7a2451a","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me update the package.json to add build scripts:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"bb7a84db-1187-4af0-9d49-70c08a043866"} +{"type":"assistant","message":{"id":"msg_202604071645423084f819c7a2451a","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_9fa8903987bc4ba79346b055","name":"Bash","input":{"command":"cat > package.json << 'EOF'\n{\n \"name\": \"loop-bench-dps90bem\",\n \"version\": \"1.0.0\",\n \"description\": \"Tetris game built with TypeScript\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"build\": \"tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir .\",\n \"watch\": \"tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir . --watch\",\n \"start\": \"python3 -m http.server 8000\"\n },\n \"keywords\": [\"tetris\", \"game\", \"typescript\"],\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}\nEOF","description":"Update package.json with build scripts"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"fe13be7e-ac0a-4152-974c-8f6638c8a468"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_9fa8903987bc4ba79346b055","type":"tool_result","content":"[rerun: b5]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a7b4db6f-4b6b-4991-bb69-6cbcfc37b80a","timestamp":"2026-04-07T08:45:53.878Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071645542886c1f891834878","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Now let me compile the TypeScript file to JavaScript using the TypeScript compiler.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"6251d4db-1f27-4a27-a87f-85d042b50319"} +{"type":"assistant","message":{"id":"msg_202604071645542886c1f891834878","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me compile the TypeScript code:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"3e0cdccc-0b2a-48a5-92ce-bf616302be5c"} +{"type":"assistant","message":{"id":"msg_202604071645542886c1f891834878","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_e12c8ffb9b46484fb0ff17ef","name":"Bash","input":{"command":"npx tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir .","description":"Compile TypeScript to JavaScript"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"5ae2dcdc-d294-4ead-b3ec-f4b4b5c9ff03"} +{"type":"user","message":{"role":"user","content":[{"type":"tool_result","content":"Exit code 2\ntetris.ts(187,27): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\n No index signature with a parameter of type 'string' was found on type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\ntetris.ts(190,40): error TS7006: Parameter 'row' implicitly has an 'any' type.\ntetris.ts(199,31): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\n No index signature with a parameter of type 'string' was found on type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\ntetris.ts(201,44): error TS7006: Parameter 'row' implicitly has an 'any' type.\n[rerun: b6]","is_error":true,"tool_use_id":"call_e12c8ffb9b46484fb0ff17ef"}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"bb0553ef-95f9-41ab-9050-fbafd1dda665","timestamp":"2026-04-07T08:45:57.624Z","tool_use_result":"Error: Exit code 2\ntetris.ts(187,27): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\n No index signature with a parameter of type 'string' was found on type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\ntetris.ts(190,40): error TS7006: Parameter 'row' implicitly has an 'any' type.\ntetris.ts(199,31): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\n No index signature with a parameter of type 'string' was found on type '{ I: { shape: number[][]; color: string; }; O: { shape: number[][]; color: string; }; T: { shape: number[][]; color: string; }; S: { shape: number[][]; color: string; }; Z: { shape: number[][]; color: string; }; J: { shape: number[][]; color: string; }; L: { ...; }; }'.\ntetris.ts(201,44): error TS7006: Parameter 'row' implicitly has an 'any' type.\n[rerun: b6]"} +{"type":"assistant","message":{"id":"msg_20260407164558e60a2877a3b34287","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"I need to fix the TypeScript type errors. The main issues are:\n1. Using string to index TETROMINOES object (needs index signature or type casting)\n2. Implicit 'any' type for the row parameter in map functions\n\nLet me fix these issues.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"00335ae3-64de-49ce-a9ba-a7f80d0e7de7"} +{"type":"assistant","message":{"id":"msg_20260407164558e60a2877a3b34287","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Let me fix the TypeScript errors:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"9c392e2b-a57f-4398-a4b3-4bb4559fe20f"} +{"type":"assistant","message":{"id":"msg_20260407164558e60a2877a3b34287","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_9d145df2fb774f07acf1a28c","name":"Bash","input":{"command":"cat > tetris.ts << 'EOF'\n// Tetris Game in TypeScript\n\n// Game constants\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 24;\n\n// Tetromino shapes and their colors\nconst TETROMINOES: Record<string, { shape: number[][]; color: string }> = {\n I: {\n shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n color: '#00f5ff'\n },\n O: {\n shape: [[1, 1], [1, 1]],\n color: '#ffff00'\n },\n T: {\n shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]],\n color: '#a020f0'\n },\n S: {\n shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]],\n color: '#00ff00'\n },\n Z: {\n shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]],\n color: '#ff0000'\n },\n J: {\n shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]],\n color: '#0000ff'\n },\n L: {\n shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]],\n color: '#ff7f00'\n }\n};\n\n// Game state\ninterface GameState {\n board: number[][];\n score: number;\n level: number;\n lines: number;\n gameOver: boolean;\n paused: boolean;\n currentPiece: Tetromino | null;\n nextPiece: Tetromino | null;\n dropInterval: number;\n}\n\ninterface Tetromino {\n shape: number[][];\n color: string;\n x: number;\n y: number;\n type: string;\n}\n\nclass TetrisGame {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private state: GameState;\n private lastTime: number = 0;\n private dropCounter: number = 0;\n private animationId: number | null = null;\n\n constructor() {\n this.canvas = document.getElementById('tetris') as HTMLCanvasElement;\n this.ctx = this.canvas.getContext('2d')!;\n \n this.state = this.getInitialState();\n \n this.setupEventListeners();\n this.draw();\n }\n\n private getInitialState(): GameState {\n return {\n board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)),\n score: 0,\n level: 1,\n lines: 0,\n gameOver: false,\n paused: false,\n currentPiece: null,\n nextPiece: null,\n dropInterval: 1000\n };\n }\n\n private setupEventListeners(): void {\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n\n startBtn.addEventListener('click', () => this.startGame());\n pauseBtn.addEventListener('click', () => this.togglePause());\n\n document.addEventListener('keydown', (e) => this.handleKeyPress(e));\n }\n\n private handleKeyPress(e: KeyboardEvent): void {\n if (this.state.gameOver || this.state.paused) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault();\n this.movePiece(-1, 0);\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.movePiece(1, 0);\n break;\n case 'ArrowDown':\n e.preventDefault();\n this.movePiece(0, 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.rotatePiece();\n break;\n case ' ':\n e.preventDefault();\n this.hardDrop();\n break;\n case 'p':\n case 'P':\n e.preventDefault();\n this.togglePause();\n break;\n }\n }\n\n private startGame(): void {\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n\n this.state = this.getInitialState();\n this.spawnPiece();\n \n startBtn.disabled = true;\n pauseBtn.disabled = false;\n \n this.updateDisplay();\n this.gameLoop();\n }\n\n private togglePause(): void {\n if (this.state.gameOver) {\n return;\n }\n\n this.state.paused = !this.state.paused;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause';\n\n if (!this.state.paused) {\n this.lastTime = performance.now();\n this.gameLoop();\n }\n }\n\n private gameLoop(time: number = 0): void {\n if (this.state.paused || this.state.gameOver) {\n return;\n }\n\n const deltaTime = time - this.lastTime;\n this.lastTime = time;\n this.dropCounter += deltaTime;\n\n if (this.dropCounter > this.state.dropInterval) {\n this.dropPiece();\n this.dropCounter = 0;\n }\n\n this.draw();\n this.animationId = requestAnimationFrame((t) => this.gameLoop(t));\n }\n\n private spawnPiece(): void {\n const types = Object.keys(TETROMINOES);\n const randomType = types[Math.floor(Math.random() * types.length)];\n const tetromino = TETROMINOES[randomType];\n\n this.state.currentPiece = this.state.nextPiece || {\n shape: tetromino.shape.map((row: number[]) => [...row]),\n color: tetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2),\n y: 0,\n type: randomType\n };\n\n // Generate next piece\n const nextType = types[Math.floor(Math.random() * types.length)];\n const nextTetromino = TETROMINOES[nextType];\n this.state.nextPiece = {\n shape: nextTetromino.shape.map((row: number[]) => [...row]),\n color: nextTetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2),\n y: 0,\n type: nextType\n };\n\n // Check if game over\n if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) {\n this.state.gameOver = true;\n const startBtn = document.getElementById('startBtn') as HTMLButtonElement;\n const pauseBtn = document.getElementById('pauseBtn') as HTMLButtonElement;\n startBtn.disabled = false;\n pauseBtn.disabled = true;\n pauseBtn.textContent = 'Pause';\n \n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n }\n \n this.drawGameOver();\n }\n }\n\n private movePiece(dx: number, dy: number): void {\n if (!this.state.currentPiece) return;\n\n const newX = this.state.currentPiece.x + dx;\n const newY = this.state.currentPiece.y + dy;\n\n if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) {\n this.state.currentPiece.x = newX;\n this.state.currentPiece.y = newY;\n this.draw();\n } else if (dy > 0) {\n this.lockPiece();\n }\n }\n\n private dropPiece(): void {\n this.movePiece(0, 1);\n }\n\n private hardDrop(): void {\n if (!this.state.currentPiece) return;\n\n while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) {\n this.state.currentPiece.y++;\n }\n this.lockPiece();\n }\n\n private rotatePiece(): void {\n if (!this.state.currentPiece) return;\n\n const rotated = this.rotateMatrix(this.state.currentPiece.shape);\n \n // Wall kick - try different positions if rotation causes collision\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) {\n this.state.currentPiece.x += kick;\n this.state.currentPiece.shape = rotated;\n this.draw();\n return;\n }\n }\n }\n\n private rotateMatrix(matrix: number[][]): number[][] {\n const n = matrix.length;\n const rotated: number[][] = [];\n \n for (let i = 0; i < n; i++) {\n rotated[i] = [];\n for (let j = 0; j < n; j++) {\n rotated[i][j] = matrix[n - 1 - j][i];\n }\n }\n \n return rotated;\n }\n\n private checkCollision(x: number, y: number, shape: number[][]): boolean {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n \n if (newX < 0 || newX >= COLS || newY >= ROWS) {\n return true;\n }\n \n if (newY >= 0 && this.state.board[newY][newX]) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n private lockPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y } = this.state.currentPiece;\n \n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = y + row;\n const boardX = x + col;\n if (boardY >= 0) {\n this.state.board[boardY][boardX] = 1;\n }\n }\n }\n }\n\n this.clearLines();\n this.spawnPiece();\n }\n\n private clearLines(): void {\n let linesCleared = 0;\n \n for (let row = ROWS - 1; row >= 0; row--) {\n if (this.state.board[row].every(cell => cell === 1)) {\n this.state.board.splice(row, 1);\n this.state.board.unshift(Array(COLS).fill(0));\n linesCleared++;\n row++; // Check the same row again\n }\n }\n\n if (linesCleared > 0) {\n this.updateScore(linesCleared);\n }\n }\n\n private updateScore(linesCleared: number): void {\n // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris)\n const points = [0, 100, 300, 500, 800];\n this.state.score += points[linesCleared] * this.state.level;\n this.state.lines += linesCleared;\n \n // Level up every 10 lines\n this.state.level = Math.floor(this.state.lines / 10) + 1;\n \n // Increase speed (decrease drop interval)\n this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100);\n \n this.updateDisplay();\n }\n\n private updateDisplay(): void {\n document.getElementById('score')!.textContent = this.state.score.toString();\n document.getElementById('level')!.textContent = this.state.level.toString();\n document.getElementById('lines')!.textContent = this.state.lines.toString();\n }\n\n private draw(): void {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.drawBoard();\n this.drawCurrentPiece();\n this.drawGhostPiece();\n }\n\n private drawBoard(): void {\n for (let row = 0; row < ROWS; row++) {\n for (let col = 0; col < COLS; col++) {\n if (this.state.board[row][col]) {\n this.drawBlock(col, row, '#ffffff');\n }\n }\n }\n }\n\n private drawCurrentPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y, color } = this.state.currentPiece;\n \n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, y + row, color);\n }\n }\n }\n }\n\n private drawGhostPiece(): void {\n if (!this.state.currentPiece) return;\n\n const { shape, x, y, color } = this.state.currentPiece;\n let ghostY = y;\n\n // Find where the ghost piece would land\n while (!this.checkCollision(x, ghostY + 1, shape)) {\n ghostY++;\n }\n\n // Draw ghost piece (semi-transparent)\n this.ctx.globalAlpha = 0.3;\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, ghostY + row, color);\n }\n }\n }\n this.ctx.globalAlpha = 1.0;\n }\n\n private drawBlock(x: number, y: number, color: string): void {\n const padding = 1;\n this.ctx.fillStyle = color;\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + padding,\n BLOCK_SIZE - padding * 2,\n BLOCK_SIZE - padding * 2\n );\n \n // Add a slight 3D effect\n this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + padding,\n BLOCK_SIZE - padding * 2,\n 4\n );\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n this.ctx.fillRect(\n x * BLOCK_SIZE + padding,\n y * BLOCK_SIZE + BLOCK_SIZE - padding - 4,\n BLOCK_SIZE - padding * 2,\n 4\n );\n }\n\n private drawGameOver(): void {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n \n this.ctx.fillStyle = '#ffffff';\n this.ctx.font = 'bold 24px Arial';\n this.ctx.textAlign = 'center';\n this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20);\n this.ctx.font = '16px Arial';\n this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20);\n this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50);\n }\n}\n\n// Initialize game when DOM is loaded\ndocument.addEventListener('DOMContentLoaded', () => {\n new TetrisGame();\n});\nEOF","description":"Fix TypeScript type errors in tetris.ts"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"2c00459b-1a3f-4abb-9b58-eec8accdb155"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_9d145df2fb774f07acf1a28c","type":"tool_result","content":"[rerun: b7]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"12985d64-b394-4327-971c-a7ef3de2918d","timestamp":"2026-04-07T08:48:15.378Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716481730ae2cafdef34f35","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good! Now let me compile the TypeScript again to see if the errors are fixed.","signature":"de067b63118e459a8147afe5"}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":13,"output_tokens":69,"cache_read_input_tokens":14161,"server_tool_use":{"web_search_requests":0},"service_tier":"standard"},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"38743e8a-3f2f-46b8-84f6-000000000000"} +{"type":"assistant","message":{"id":"msg_2026040716481730ae2cafdef34f35","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me compile the TypeScript code again:"}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":13,"output_tokens":69,"cache_read_input_tokens":14161,"server_tool_use":{"web_search_requests":0},"service_tier":"standard"},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"38743e8a-3f2f-46b8-84f6-000000000001"} +{"type":"assistant","message":{"id":"msg_2026040716481730ae2cafdef34f35","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_e03d3ee774c04f46a7a6789c","name":"Bash","input":{"command":"npx tsc tetris.ts --target ES2015 --lib ES2015,DOM --outDir .","description":"Compile TypeScript to JavaScript"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":13,"output_tokens":69,"cache_read_input_tokens":14161,"server_tool_use":{"web_search_requests":0},"service_tier":"standard"},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"38743e8a-3f2f-46b8-84f6-000000000002"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_e03d3ee774c04f46a7a6789c","type":"tool_result","content":"[rerun: b8]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a15108c9-4b44-4044-9c82-e7df5bbd77df","timestamp":"2026-04-07T08:48:21.049Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164822f0e8773e8bc94ec5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Great! The TypeScript compilation succeeded. Let me verify that the JavaScript file was created and check the generated JavaScript file.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"71514d4f-32ad-42db-bf11-afb0bc8797ac"} +{"type":"assistant","message":{"id":"msg_20260407164822f0e8773e8bc94ec5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Let me verify the JavaScript file was created:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"547f0a47-7375-4264-872f-8617d1bc90ef"} +{"type":"assistant","message":{"id":"msg_20260407164822f0e8773e8bc94ec5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_68fe34dd910147e59077e5db","name":"Bash","input":{"command":"ls -la *.js *.html *.css","description":"List game files"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a8cae6ae-8309-4794-84b6-5309be3a153d"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_68fe34dd910147e59077e5db","type":"tool_result","content":"-rw-r--r-- 1 root root 1249 Apr 7 10:42 index.html\n-rw-r--r-- 1 root root 1981 Apr 7 10:42 styles.css\n-rw-r--r-- 1 root root 12710 Apr 7 10:48 tetris.js\n[rerun: b9]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"9d5bacf4-4de2-4c8d-8cb9-cdd6fa9b0071","timestamp":"2026-04-07T08:48:24.717Z","tool_use_result":{"stdout":"-rw-r--r-- 1 root root 1249 Apr 7 10:42 index.html\n-rw-r--r-- 1 root root 1981 Apr 7 10:42 styles.css\n-rw-r--r-- 1 root root 12710 Apr 7 10:48 tetris.js","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716482550e3f48202b848c2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Perfect! All the files have been created. Let me also check the generated JavaScript file to make sure it looks correct.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"acfa8a1f-a50f-43de-8fd0-d05762b1a852"} +{"type":"assistant","message":{"id":"msg_2026040716482550e3f48202b848c2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Let me check the generated JavaScript file:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"61b8ece0-1771-413c-a7f5-5c87dcf33f89"} +{"type":"assistant","message":{"id":"msg_2026040716482550e3f48202b848c2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_9b43f8b62e824e98a757d481","name":"Read","input":{"file_path":"/tmp/loop-bench-dps90bem/tetris.js"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"0601523c-c7d5-4beb-a299-54e5cd037a2c"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_9b43f8b62e824e98a757d481","type":"tool_result","content":"1\t\"use strict\";\n2\t// Tetris Game in TypeScript\n3\t// Game constants\n4\tconst COLS = 10;\n5\tconst ROWS = 20;\n6\tconst BLOCK_SIZE = 24;\n7\t// Tetromino shapes and their colors\n8\tconst TETROMINOES = {\n9\t I: {\n10\t shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n11\t color: '#00f5ff'\n12\t },\n13\t O: {\n14\t shape: [[1, 1], [1, 1]],\n15\t color: '#ffff00'\n16\t },\n17\t T: {\n18\t shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]],\n19\t color: '#a020f0'\n20\t },\n21\t S: {\n22\t shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]],\n23\t color: '#00ff00'\n24\t },\n25\t Z: {\n26\t shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]],\n27\t color: '#ff0000'\n28\t },\n29\t J: {\n30\t shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]],\n31\t color: '#0000ff'\n32\t },\n33\t L: {\n34\t shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]],\n35\t color: '#ff7f00'\n36\t }\n37\t};\n38\tclass TetrisGame {\n39\t constructor() {\n40\t this.lastTime = 0;\n41\t this.dropCounter = 0;\n42\t this.animationId = null;\n43\t this.canvas = document.getElementById('tetris');\n44\t this.ctx = this.canvas.getContext('2d');\n45\t this.state = this.getInitialState();\n46\t this.setupEventListeners();\n47\t this.draw();\n48\t }\n49\t getInitialState() {\n50\t return {\n51\t board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)),\n52\t score: 0,\n53\t level: 1,\n54\t lines: 0,\n55\t gameOver: false,\n56\t paused: false,\n57\t currentPiece: null,\n58\t nextPiece: null,\n59\t dropInterval: 1000\n60\t };\n61\t }\n62\t setupEventListeners() {\n63\t const startBtn = document.getElementById('startBtn');\n64\t const pauseBtn = document.getElementById('pauseBtn');\n65\t startBtn.addEventListener('click', () => this.startGame());\n66\t pauseBtn.addEventListener('click', () => this.togglePause());\n67\t document.addEventListener('keydown', (e) => this.handleKeyPress(e));\n68\t }\n69\t handleKeyPress(e) {\n70\t if (this.state.gameOver || this.state.paused) {\n71\t return;\n72\t }\n73\t switch (e.key) {\n74\t case 'ArrowLeft':\n75\t e.preventDefault();\n76\t this.movePiece(-1, 0);\n77\t break;\n78\t case 'ArrowRight':\n79\t e.preventDefault();\n80\t this.movePiece(1, 0);\n81\t break;\n82\t case 'ArrowDown':\n83\t e.preventDefault();\n84\t this.movePiece(0, 1);\n85\t break;\n86\t case 'ArrowUp':\n87\t e.preventDefault();\n88\t this.rotatePiece();\n89\t break;\n90\t case ' ':\n91\t e.preventDefault();\n92\t this.hardDrop();\n93\t break;\n94\t case 'p':\n95\t case 'P':\n96\t e.preventDefault();\n97\t this.togglePause();\n98\t break;\n99\t }\n100\t }\n101\t startGame() {\n102\t const startBtn = document.getElementById('startBtn');\n103\t const pauseBtn = document.getElementById('pauseBtn');\n104\t this.state = this.getInitialState();\n105\t this.spawnPiece();\n106\t startBtn.disabled = true;\n107\t pauseBtn.disabled = false;\n108\t this.updateDisplay();\n109\t this.gameLoop();\n110\t }\n111\t togglePause() {\n112\t if (this.state.gameOver) {\n113\t return;\n114\t }\n115\t this.state.paused = !this.state.paused;\n116\t const pauseBtn = document.getElementById('pauseBtn');\n117\t pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause';\n118\t if (!this.state.paused) {\n119\t this.lastTime = performance.now();\n120\t this.gameLoop();\n121\t }\n122\t }\n123\t gameLoop(time = 0) {\n124\t if (this.state.paused || this.state.gameOver) {\n125\t return;\n126\t }\n127\t const deltaTime = time - this.lastTime;\n128\t this.lastTime = time;\n129\t this.dropCounter += deltaTime;\n130\t if (this.dropCounter > this.state.dropInterval) {\n131\t this.dropPiece();\n132\t this.dropCounter = 0;\n133\t }\n134\t this.draw();\n135\t this.animationId = requestAnimationFrame((t) => this.gameLoop(t));\n136\t }\n137\t spawnPiece() {\n138\t const types = Object.keys(TETROMINOES);\n139\t const randomType = types[Math.floor(Math.random() * types.length)];\n140\t const tetromino = TETROMINOES[randomType];\n141\t this.state.currentPiece = this.state.nextPiece || {\n142\t shape: tetromino.shape.map((row) => [...row]),\n143\t color: tetromino.color,\n144\t x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2),\n145\t y: 0,\n146\t type: randomType\n147\t };\n148\t // Generate next piece\n149\t const nextType = types[Math.floor(Math.random() * types.length)];\n150\t const nextTetromino = TETROMINOES[nextType];\n151\t this.state.nextPiece = {\n152\t shape: nextTetromino.shape.map((row) => [...row]),\n153\t color: nextTetromino.color,\n154\t x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2),\n155\t y: 0,\n156\t type: nextType\n157\t };\n158\t // Check if game over\n159\t if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) {\n160\t this.state.gameOver = true;\n161\t const startBtn = document.getElementById('startBtn');\n162\t const pauseBtn = document.getElementById('pauseBtn');\n163\t startBtn.disabled = false;\n164\t pauseBtn.disabled = true;\n165\t pauseBtn.textContent = 'Pause';\n166\t if (this.animationId !== null) {\n167\t cancelAnimationFrame(this.animationId);\n168\t }\n169\t this.drawGameOver();\n170\t }\n171\t }\n172\t movePiece(dx, dy) {\n173\t if (!this.state.currentPiece)\n174\t return;\n175\t const newX = this.state.currentPiece.x + dx;\n176\t const newY = this.state.currentPiece.y + dy;\n177\t if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) {\n178\t this.state.currentPiece.x = newX;\n179\t this.state.currentPiece.y = newY;\n180\t this.draw();\n181\t }\n182\t else if (dy > 0) {\n183\t this.lockPiece();\n184\t }\n185\t }\n186\t dropPiece() {\n187\t this.movePiece(0, 1);\n188\t }\n189\t hardDrop() {\n190\t if (!this.state.currentPiece)\n191\t return;\n192\t while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) {\n193\t this.state.currentPiece.y++;\n194\t }\n195\t this.lockPiece();\n196\t }\n197\t rotatePiece() {\n198\t if (!this.state.currentPiece)\n199\t return;\n200\t const rotated = this.rotateMatrix(this.state.currentPiece.shape);\n201\t // Wall kick - try different positions if rotation causes collision\n202\t const kicks = [0, -1, 1, -2, 2];\n203\t for (const kick of kicks) {\n204\t if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) {\n205\t this.state.currentPiece.x += kick;\n206\t this.state.currentPiece.shape = rotated;\n207\t this.draw();\n208\t return;\n209\t }\n210\t }\n211\t }\n212\t rotateMatrix(matrix) {\n213\t const n = matrix.length;\n214\t const rotated = [];\n215\t for (let i = 0; i < n; i++) {\n216\t rotated[i] = [];\n217\t for (let j = 0; j < n; j++) {\n218\t rotated[i][j] = matrix[n - 1 - j][i];\n219\t }\n220\t }\n221\t return rotated;\n222\t }\n223\t checkCollision(x, y, shape) {\n224\t for (let row = 0; row < shape.length; row++) {\n225\t for (let col = 0; col < shape[row].length; col++) {\n226\t if (shape[row][col]) {\n227\t const newX = x + col;\n228\t const newY = y + row;\n229\t if (newX < 0 || newX >= COLS || newY >= ROWS) {\n230\t return true;\n231\t }\n232\t if (newY >= 0 && this.state.board[newY][newX]) {\n233\t return true;\n234\t }\n235\t }\n236\t }\n237\t }\n238\t return false;\n239\t }\n240\t lockPiece() {\n241\t if (!this.state.currentPiece)\n242\t return;\n243\t const { shape, x, y } = this.state.currentPiece;\n244\t for (let row = 0; row < shape.length; row++) {\n245\t for (let col = 0; col < shape[row].length; col++) {\n246\t if (shape[row][col]) {\n247\t const boardY = y + row;\n248\t const boardX = x + col;\n249\t if (boardY >= 0) {\n250\t this.state.board[boardY][boardX] = 1;\n251\t }\n252\t }\n253\t }\n254\t }\n255\t this.clearLines();\n256\t this.spawnPiece();\n257\t }\n258\t clearLines() {\n259\t let linesCleared = 0;\n260\t for (let row = ROWS - 1; row >= 0; row--) {\n261\t if (this.state.board[row].every(cell => cell === 1)) {\n262\t this.state.board.splice(row, 1);\n263\t this.state.board.unshift(Array(COLS).fill(0));\n264\t linesCleared++;\n265\t row++; // Check the same row again\n266\t }\n267\t }\n268\t if (linesCleared > 0) {\n269\t this.updateScore(linesCleared);\n270\t }\n271\t }\n272\t updateScore(linesCleared) {\n273\t // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris)\n274\t const points = [0, 100, 300, 500, 800];\n275\t this.state.score += points[linesCleared] * this.state.level;\n276\t this.state.lines += linesCleared;\n277\t // Level up every 10 lines\n278\t this.state.level = Math.floor(this.state.lines / 10) + 1;\n279\t // Increase speed (decrease drop interval)\n280\t this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100);\n281\t this.updateDisplay();\n282\t }\n283\t updateDisplay() {\n284\t document.getElementById('score').textContent = this.state.score.toString();\n285\t document.getElementById('level').textContent = this.state.level.toString();\n286\t document.getElementById('lines').textContent = this.state.lines.toString();\n287\t }\n288\t draw() {\n289\t this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n290\t this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n291\t this.drawBoard();\n292\t this.drawCurrentPiece();\n293\t this.drawGhostPiece();\n294\t }\n295\t drawBoard() {\n296\t for (let row = 0; row < ROWS; row++) {\n297\t for (let col = 0; col < COLS; col++) {\n298\t if (this.state.board[row][col]) {\n299\t this.drawBlock(col, row, '#ffffff');\n300\t }\n301\t }\n302\t }\n303\t }\n304\t drawCurrentPiece() {\n305\t if (!this.state.currentPiece)\n306\t return;\n307\t const { shape, x, y, color } = this.state.currentPiece;\n308\t for (let row = 0; row < shape.length; row++) {\n309\t for (let col = 0; col < shape[row].length; col++) {\n310\t if (shape[row][col]) {\n311\t this.drawBlock(x + col, y + row, color);\n312\t }\n313\t }\n314\t }\n315\t }\n316\t drawGhostPiece() {\n317\t if (!this.state.currentPiece)\n318\t return;\n319\t const { shape, x, y, color } = this.state.currentPiece;\n320\t let ghostY = y;\n321\t // Find where the ghost piece would land\n322\t while (!this.checkCollision(x, ghostY + 1, shape)) {\n323\t ghostY++;\n324\t }\n325\t // Draw ghost piece (semi-transparent)\n326\t this.ctx.globalAlpha = 0.3;\n327\t for (let row = 0; row < shape.length; row++) {\n328\t for (let col = 0; col < shape[row].length; col++) {\n329\t if (shape[row][col]) {\n330\t this.drawBlock(x + col, ghostY + row, color);\n331\t }\n332\t }\n333\t }\n334\t this.ctx.globalAlpha = 1.0;\n335\t }\n336\t drawBlock(x, y, color) {\n337\t const padding = 1;\n338\t this.ctx.fillStyle = color;\n339\t this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, BLOCK_SIZE - padding * 2);\n340\t // Add a slight 3D effect\n341\t this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n342\t this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, 4);\n343\t this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n344\t this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + BLOCK_SIZE - padding - 4, BLOCK_SIZE - padding * 2, 4);\n345\t }\n346\t drawGameOver() {\n347\t this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n348\t this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n349\t this.ctx.fillStyle = '#ffffff';\n350\t this.ctx.font = 'bold 24px Arial';\n351\t this.ctx.textAlign = 'center';\n352\t this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20);\n353\t this.ctx.font = '16px Arial';\n354\t this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20);\n355\t this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50);\n356\t }\n357\t}\n358\t// Initialize game when DOM is loaded\n359\tdocument.addEventListener('DOMContentLoaded', () => {\n360\t new TetrisGame();\n361\t});\n362\t"}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"fdcbc495-653d-419e-9407-8756f8ebde6a","timestamp":"2026-04-07T08:48:33.490Z","tool_use_result":{"type":"text","file":{"filePath":"/tmp/loop-bench-dps90bem/tetris.js","content":"\"use strict\";\n// Tetris Game in TypeScript\n// Game constants\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 24;\n// Tetromino shapes and their colors\nconst TETROMINOES = {\n I: {\n shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n color: '#00f5ff'\n },\n O: {\n shape: [[1, 1], [1, 1]],\n color: '#ffff00'\n },\n T: {\n shape: [[0, 1, 0], [1, 1, 1], [0, 0, 0]],\n color: '#a020f0'\n },\n S: {\n shape: [[0, 1, 1], [1, 1, 0], [0, 0, 0]],\n color: '#00ff00'\n },\n Z: {\n shape: [[1, 1, 0], [0, 1, 1], [0, 0, 0]],\n color: '#ff0000'\n },\n J: {\n shape: [[1, 0, 0], [1, 1, 1], [0, 0, 0]],\n color: '#0000ff'\n },\n L: {\n shape: [[0, 0, 1], [1, 1, 1], [0, 0, 0]],\n color: '#ff7f00'\n }\n};\nclass TetrisGame {\n constructor() {\n this.lastTime = 0;\n this.dropCounter = 0;\n this.animationId = null;\n this.canvas = document.getElementById('tetris');\n this.ctx = this.canvas.getContext('2d');\n this.state = this.getInitialState();\n this.setupEventListeners();\n this.draw();\n }\n getInitialState() {\n return {\n board: Array.from({ length: ROWS }, () => Array(COLS).fill(0)),\n score: 0,\n level: 1,\n lines: 0,\n gameOver: false,\n paused: false,\n currentPiece: null,\n nextPiece: null,\n dropInterval: 1000\n };\n }\n setupEventListeners() {\n const startBtn = document.getElementById('startBtn');\n const pauseBtn = document.getElementById('pauseBtn');\n startBtn.addEventListener('click', () => this.startGame());\n pauseBtn.addEventListener('click', () => this.togglePause());\n document.addEventListener('keydown', (e) => this.handleKeyPress(e));\n }\n handleKeyPress(e) {\n if (this.state.gameOver || this.state.paused) {\n return;\n }\n switch (e.key) {\n case 'ArrowLeft':\n e.preventDefault();\n this.movePiece(-1, 0);\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.movePiece(1, 0);\n break;\n case 'ArrowDown':\n e.preventDefault();\n this.movePiece(0, 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.rotatePiece();\n break;\n case ' ':\n e.preventDefault();\n this.hardDrop();\n break;\n case 'p':\n case 'P':\n e.preventDefault();\n this.togglePause();\n break;\n }\n }\n startGame() {\n const startBtn = document.getElementById('startBtn');\n const pauseBtn = document.getElementById('pauseBtn');\n this.state = this.getInitialState();\n this.spawnPiece();\n startBtn.disabled = true;\n pauseBtn.disabled = false;\n this.updateDisplay();\n this.gameLoop();\n }\n togglePause() {\n if (this.state.gameOver) {\n return;\n }\n this.state.paused = !this.state.paused;\n const pauseBtn = document.getElementById('pauseBtn');\n pauseBtn.textContent = this.state.paused ? 'Resume' : 'Pause';\n if (!this.state.paused) {\n this.lastTime = performance.now();\n this.gameLoop();\n }\n }\n gameLoop(time = 0) {\n if (this.state.paused || this.state.gameOver) {\n return;\n }\n const deltaTime = time - this.lastTime;\n this.lastTime = time;\n this.dropCounter += deltaTime;\n if (this.dropCounter > this.state.dropInterval) {\n this.dropPiece();\n this.dropCounter = 0;\n }\n this.draw();\n this.animationId = requestAnimationFrame((t) => this.gameLoop(t));\n }\n spawnPiece() {\n const types = Object.keys(TETROMINOES);\n const randomType = types[Math.floor(Math.random() * types.length)];\n const tetromino = TETROMINOES[randomType];\n this.state.currentPiece = this.state.nextPiece || {\n shape: tetromino.shape.map((row) => [...row]),\n color: tetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(tetromino.shape[0].length / 2),\n y: 0,\n type: randomType\n };\n // Generate next piece\n const nextType = types[Math.floor(Math.random() * types.length)];\n const nextTetromino = TETROMINOES[nextType];\n this.state.nextPiece = {\n shape: nextTetromino.shape.map((row) => [...row]),\n color: nextTetromino.color,\n x: Math.floor(COLS / 2) - Math.floor(nextTetromino.shape[0].length / 2),\n y: 0,\n type: nextType\n };\n // Check if game over\n if (this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y, this.state.currentPiece.shape)) {\n this.state.gameOver = true;\n const startBtn = document.getElementById('startBtn');\n const pauseBtn = document.getElementById('pauseBtn');\n startBtn.disabled = false;\n pauseBtn.disabled = true;\n pauseBtn.textContent = 'Pause';\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n }\n this.drawGameOver();\n }\n }\n movePiece(dx, dy) {\n if (!this.state.currentPiece)\n return;\n const newX = this.state.currentPiece.x + dx;\n const newY = this.state.currentPiece.y + dy;\n if (!this.checkCollision(newX, newY, this.state.currentPiece.shape)) {\n this.state.currentPiece.x = newX;\n this.state.currentPiece.y = newY;\n this.draw();\n }\n else if (dy > 0) {\n this.lockPiece();\n }\n }\n dropPiece() {\n this.movePiece(0, 1);\n }\n hardDrop() {\n if (!this.state.currentPiece)\n return;\n while (!this.checkCollision(this.state.currentPiece.x, this.state.currentPiece.y + 1, this.state.currentPiece.shape)) {\n this.state.currentPiece.y++;\n }\n this.lockPiece();\n }\n rotatePiece() {\n if (!this.state.currentPiece)\n return;\n const rotated = this.rotateMatrix(this.state.currentPiece.shape);\n // Wall kick - try different positions if rotation causes collision\n const kicks = [0, -1, 1, -2, 2];\n for (const kick of kicks) {\n if (!this.checkCollision(this.state.currentPiece.x + kick, this.state.currentPiece.y, rotated)) {\n this.state.currentPiece.x += kick;\n this.state.currentPiece.shape = rotated;\n this.draw();\n return;\n }\n }\n }\n rotateMatrix(matrix) {\n const n = matrix.length;\n const rotated = [];\n for (let i = 0; i < n; i++) {\n rotated[i] = [];\n for (let j = 0; j < n; j++) {\n rotated[i][j] = matrix[n - 1 - j][i];\n }\n }\n return rotated;\n }\n checkCollision(x, y, shape) {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n if (newX < 0 || newX >= COLS || newY >= ROWS) {\n return true;\n }\n if (newY >= 0 && this.state.board[newY][newX]) {\n return true;\n }\n }\n }\n }\n return false;\n }\n lockPiece() {\n if (!this.state.currentPiece)\n return;\n const { shape, x, y } = this.state.currentPiece;\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = y + row;\n const boardX = x + col;\n if (boardY >= 0) {\n this.state.board[boardY][boardX] = 1;\n }\n }\n }\n }\n this.clearLines();\n this.spawnPiece();\n }\n clearLines() {\n let linesCleared = 0;\n for (let row = ROWS - 1; row >= 0; row--) {\n if (this.state.board[row].every(cell => cell === 1)) {\n this.state.board.splice(row, 1);\n this.state.board.unshift(Array(COLS).fill(0));\n linesCleared++;\n row++; // Check the same row again\n }\n }\n if (linesCleared > 0) {\n this.updateScore(linesCleared);\n }\n }\n updateScore(linesCleared) {\n // Scoring: 100 for 1 line, 300 for 2, 500 for 3, 800 for 4 (Tetris)\n const points = [0, 100, 300, 500, 800];\n this.state.score += points[linesCleared] * this.state.level;\n this.state.lines += linesCleared;\n // Level up every 10 lines\n this.state.level = Math.floor(this.state.lines / 10) + 1;\n // Increase speed (decrease drop interval)\n this.state.dropInterval = Math.max(100, 1000 - (this.state.level - 1) * 100);\n this.updateDisplay();\n }\n updateDisplay() {\n document.getElementById('score').textContent = this.state.score.toString();\n document.getElementById('level').textContent = this.state.level.toString();\n document.getElementById('lines').textContent = this.state.lines.toString();\n }\n draw() {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.drawBoard();\n this.drawCurrentPiece();\n this.drawGhostPiece();\n }\n drawBoard() {\n for (let row = 0; row < ROWS; row++) {\n for (let col = 0; col < COLS; col++) {\n if (this.state.board[row][col]) {\n this.drawBlock(col, row, '#ffffff');\n }\n }\n }\n }\n drawCurrentPiece() {\n if (!this.state.currentPiece)\n return;\n const { shape, x, y, color } = this.state.currentPiece;\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, y + row, color);\n }\n }\n }\n }\n drawGhostPiece() {\n if (!this.state.currentPiece)\n return;\n const { shape, x, y, color } = this.state.currentPiece;\n let ghostY = y;\n // Find where the ghost piece would land\n while (!this.checkCollision(x, ghostY + 1, shape)) {\n ghostY++;\n }\n // Draw ghost piece (semi-transparent)\n this.ctx.globalAlpha = 0.3;\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n this.drawBlock(x + col, ghostY + row, color);\n }\n }\n }\n this.ctx.globalAlpha = 1.0;\n }\n drawBlock(x, y, color) {\n const padding = 1;\n this.ctx.fillStyle = color;\n this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, BLOCK_SIZE - padding * 2);\n // Add a slight 3D effect\n this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';\n this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + padding, BLOCK_SIZE - padding * 2, 4);\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n this.ctx.fillRect(x * BLOCK_SIZE + padding, y * BLOCK_SIZE + BLOCK_SIZE - padding - 4, BLOCK_SIZE - padding * 2, 4);\n }\n drawGameOver() {\n this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';\n this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.ctx.fillStyle = '#ffffff';\n this.ctx.font = 'bold 24px Arial';\n this.ctx.textAlign = 'center';\n this.ctx.fillText('GAME OVER', this.canvas.width / 2, this.canvas.height / 2 - 20);\n this.ctx.font = '16px Arial';\n this.ctx.fillText(`Score: ${this.state.score}`, this.canvas.width / 2, this.canvas.height / 2 + 20);\n this.ctx.fillText('Click Start to play again', this.canvas.width / 2, this.canvas.height / 2 + 50);\n }\n}\n// Initialize game when DOM is loaded\ndocument.addEventListener('DOMContentLoaded', () => {\n new TetrisGame();\n});\n","numLines":362,"startLine":1,"totalLines":362}}} +{"type":"assistant","message":{"id":"msg_20260407164834c955b64e49c44fd2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Perfect! The JavaScript file was generated correctly. Now let me create a README file to explain how to run the game.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"9f45b435-11b4-4f3d-8e1e-9e7d8f0eb63b"} +{"type":"assistant","message":{"id":"msg_20260407164834c955b64e49c44fd2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Perfect! Now let me create a README file with instructions:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"5f1f2ad1-8907-4eac-9ee8-2755367985f9"} +{"type":"assistant","message":{"id":"msg_20260407164834c955b64e49c44fd2","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_33723a2e32cf496c885fa4d0","name":"Bash","input":{"command":"cat > README.md << 'EOF'\n# Tetris Game\n\nA fully functional Tetris game built with TypeScript and HTML5 Canvas.\n\n## Features\n\n- **All 7 Tetrominos**: I, O, T, S, Z, J, and L pieces\n- **Piece Rotation**: Clockwise rotation with wall kick support\n- **Line Clearing**: Clear complete lines to score points\n- **Scoring System**: Points scale with level and lines cleared\n- **Level Progression**: Game speed increases every 10 lines cleared\n- **Ghost Piece**: Shows where the piece will land\n- **Pause/Resume**: Pause the game at any time\n\n## Controls\n\n| Key | Action |\n|-----|--------|\n| ← → | Move left/right |\n| ↑ | Rotate piece |\n| ↓ | Soft drop (move down faster) |\n| Space | Hard drop (instant drop) |\n| P | Pause/Resume |\n\n## Scoring\n\n- 1 line: 100 × level\n- 2 lines: 300 × level\n- 3 lines: 500 × level\n- 4 lines (Tetris): 800 × level\n\n## Level Progression\n\n- Level increases every 10 lines cleared\n- Drop speed decreases by 100ms per level (minimum 100ms)\n\n## Running the Game\n\n1. **Compile TypeScript (if needed):**\n ```bash\n npm run build\n ```\n\n2. **Start a local server:**\n ```bash\n npm start\n ```\n\n3. **Open in browser:**\n Navigate to `http://localhost:8000`\n\n## Files\n\n- `index.html` - Game HTML structure\n- `styles.css` - Game styling\n- `tetris.ts` - TypeScript game logic\n- `tetris.js` - Compiled JavaScript (auto-generated)\n- `package.json` - Project configuration\n\n## Development\n\nTo watch for TypeScript changes and auto-compile:\n```bash\nnpm run watch\n```\nEOF","description":"Create README with game instructions"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"b914ca6d-65a2-445d-ae28-d0519fd6928f"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_33723a2e32cf496c885fa4d0","type":"tool_result","content":"[rerun: b10]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a611dae9-35cd-4fab-aecd-df49771a3f88","timestamp":"2026-04-07T08:48:56.594Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164857f1159b7f124845cb","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Great! Let me now start a local server to verify the game works. I'll use Python's built-in HTTP server.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"dd2e0cbf-05ea-48e2-8b0c-7578e0ebf9ba"} +{"type":"assistant","message":{"id":"msg_20260407164857f1159b7f124845cb","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Now let me start the game server to test it:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"47960d32-621c-46ab-8c3d-747016d1060c"} +{"type":"assistant","message":{"id":"msg_20260407164857f1159b7f124845cb","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_e546d6046b5f4754a81dd0a0","name":"Bash","input":{"command":"python3 -m http.server 8000 &","description":"Start local HTTP server in background","run_in_background":true}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"260dbc81-b307-491d-a76c-15690c17ce99"} +{"type":"system","subtype":"task_started","task_id":"b79rsbiw4","tool_use_id":"call_e546d6046b5f4754a81dd0a0","description":"Start local HTTP server in background","task_type":"local_bash","uuid":"a4907f58-0259-4cb4-9eab-6228b9d61a5e","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_e546d6046b5f4754a81dd0a0","type":"tool_result","content":"Command running in background with ID: b79rsbiw4. Output is being written to: /tmp/claude-0/-tmp-loop-bench-dps90bem/6d0c2f47-379d-4fb5-ad72-70eea56cb23e/tasks/b79rsbiw4.output\n[rerun: b11]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ea810997-6c65-4fe6-973d-14fe99d7a1cb","timestamp":"2026-04-07T08:49:13.009Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false,"backgroundTaskId":"b79rsbiw4"}} +{"type":"assistant","message":{"id":"msg_202604071649139de26aedef244b4e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Good! The server is running in the background. Let me check the output to make sure it started successfully.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"3ef8b6dd-c8be-49b6-9827-02cf5915f84b"} +{"type":"assistant","message":{"id":"msg_202604071649139de26aedef244b4e","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_fa424589eb844d588ea1236b","name":"Bash","input":{"command":"sleep 2 && cat /tmp/claude-0/-tmp-loop-bench-dps90bem/6d0c2f47-379d-4fb5-ad72-70eea56cb23e/tasks/b79rsbiw4.output","description":"Check server startup status"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"8376e098-7e50-48c8-85a7-9dfa4323a391"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_fa424589eb844d588ea1236b","type":"tool_result","content":"[rerun: b12]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"39a3e747-8876-4108-a2ec-8591dfcaf996","timestamp":"2026-04-07T08:49:19.611Z","tool_use_result":{"stdout":"","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716492067f87cf5da0f40a0","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Let me check if the server is running properly:","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"199eb6ca-2b20-484b-8d00-6e691ebb8023"} +{"type":"assistant","message":{"id":"msg_2026040716492067f87cf5da0f40a0","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_443be7d5ae504582adb3e5d3","name":"Bash","input":{"command":"ps aux | grep \"http.server\" | grep -v grep","description":"Check if HTTP server is running"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"c6a9f5aa-1cf2-400f-a149-2e4decff3193"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_443be7d5ae504582adb3e5d3","type":"tool_result","content":"root 1951154 0.0 0.1 103988 20612 ? S 10:47 0:00 python3 -m http.server 8080\nroot 1951804 0.0 0.1 29232 20176 ? S 10:49 0:00 python3 -m http.server 8000\n[rerun: b13]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"d241ac98-d7de-41f3-b450-40649d516ba8","timestamp":"2026-04-07T08:49:22.740Z","tool_use_result":{"stdout":"root 1951154 0.0 0.1 103988 20612 ? S 10:47 0:00 python3 -m http.server 8080\nroot 1951804 0.0 0.1 29232 20176 ? S 10:49 0:00 python3 -m http.server 8000","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071649238a05226d68f24df6","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The server is running. Let me test the game by making a request to verify the HTML loads correctly.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ddee7aec-8ff8-4a22-8c43-df7261165346"} +{"type":"assistant","message":{"id":"msg_202604071649238a05226d68f24df6","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"The server is running on port 8000. Let me verify the game loads correctly:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"de598b71-b7c5-456e-8e52-859b779d4e6e"} +{"type":"assistant","message":{"id":"msg_202604071649238a05226d68f24df6","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_29283325ee1745f598a1062b","name":"Bash","input":{"command":"curl -s http://localhost:8000/index.html | head -20","description":"Test if game HTML loads correctly"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"96a86cb5-a0b3-4e95-85d5-5c09b76fc852"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_29283325ee1745f598a1062b","type":"tool_result","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 Game</title>\n <link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n <div class=\"game-container\">\n <h1>Tetris</h1>\n <div class=\"game-info\">\n <div class=\"info-panel\">\n <h3>Score</h3>\n <p id=\"score\">0</p>\n </div>\n <div class=\"info-panel\">\n <h3>Level</h3>\n <p id=\"level\">1</p>\n </div>\n[rerun: b14]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"1294002a-c0f7-4a71-bf73-05e28e2d24ed","timestamp":"2026-04-07T08:49:28.550Z","tool_use_result":{"stdout":"<!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 Game</title>\n <link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n <div class=\"game-container\">\n <h1>Tetris</h1>\n <div class=\"game-info\">\n <div class=\"info-panel\">\n <h3>Score</h3>\n <p id=\"score\">0</p>\n </div>\n <div class=\"info-panel\">\n <h3>Level</h3>\n <p id=\"level\">1</p>\n </div>","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164929cb919415e7fd4677","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Great! The game is loading correctly. Let me also verify that the JavaScript and CSS files are accessible.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"3f8e13ce-d0ad-43b3-b892-b6788925d5d2"} +{"type":"assistant","message":{"id":"msg_20260407164929cb919415e7fd4677","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_73f32967ecf04135893be154","name":"Bash","input":{"command":"curl -s http://localhost:8000/tetris.js | head -10","description":"Verify JavaScript file is accessible"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"1d2751c7-05cd-4fbd-8909-92235fb4795e"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_73f32967ecf04135893be154","type":"tool_result","content":"\"use strict\";\n// Tetris Game in TypeScript\n// Game constants\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 24;\n// Tetromino shapes and their colors\nconst TETROMINOES = {\n I: {\n shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],\n[rerun: b15]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"57baaf1c-29d4-42e1-9e42-02313df7e8d9","timestamp":"2026-04-07T08:49:31.373Z","tool_use_result":{"stdout":"\"use strict\";\n// Tetris Game in TypeScript\n// Game constants\nconst COLS = 10;\nconst ROWS = 20;\nconst BLOCK_SIZE = 24;\n// Tetromino shapes and their colors\nconst TETROMINOES = {\n I: {\n shape: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_20260407164932a5845ac6d5a44b83","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"All the files are loading correctly. Let me also check the CSS file and then create a summary of what was created.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"03332f96-1c30-4c21-80f1-d83a4ab4817a"} +{"type":"assistant","message":{"id":"msg_20260407164932a5845ac6d5a44b83","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_9052595a58b441a1b5ddde95","name":"Bash","input":{"command":"curl -s http://localhost:8000/styles.css | head -10","description":"Verify CSS file is accessible"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ffa76371-085a-4cfb-aa97-6545ebdad110"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_9052595a58b441a1b5ddde95","type":"tool_result","content":"* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Arial', sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n display: flex;\n[rerun: b16]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"5e2cbf4f-0034-4fbd-a4fe-e02b5f1a90f9","timestamp":"2026-04-07T08:49:34.212Z","tool_use_result":{"stdout":"* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Arial', sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n display: flex;","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_2026040716493563a066158ea54be5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"Excellent! All files are loading correctly. Let me list all the created files and provide a summary.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"6441d62b-3164-4b79-a509-93f25c3c4b39"} +{"type":"assistant","message":{"id":"msg_2026040716493563a066158ea54be5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Perfect! Let me show you all the created files:"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"c8ad291f-00bd-4680-936d-2f4da5e02969"} +{"type":"assistant","message":{"id":"msg_2026040716493563a066158ea54be5","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"tool_use","id":"call_50d7bac539f54c3da076831f","name":"Bash","input":{"command":"ls -la *.ts *.js *.html *.css *.md 2>/dev/null | awk '{print $9, $5}' | column -t","description":"List all game files with sizes"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"63774176-039f-4840-9bb1-5a103ef94886"} +{"type":"user","message":{"role":"user","content":[{"tool_use_id":"call_50d7bac539f54c3da076831f","type":"tool_result","content":"index.html 1249\nREADME.md 1469\nstyles.css 1981\ntetris.js 12710\ntetris.ts 14263\n[rerun: b17]","is_error":false}]},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"a083a7ea-f3b4-4ece-8c28-76aecf23c196","timestamp":"2026-04-07T08:49:37.743Z","tool_use_result":{"stdout":"index.html 1249\nREADME.md 1469\nstyles.css 1981\ntetris.js 12710\ntetris.ts 14263","stderr":"","interrupted":false,"isImage":false,"noOutputExpected":false}} +{"type":"assistant","message":{"id":"msg_202604071649383cbe2720cb244a72","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The user asked me to build a Tetris game, and I've completed that. Looking at the current state, I've:\n\n1. Created all the necessary files\n2. Compiled the TypeScript successfully\n3. Started a server\n4. Verified the game is loading correctly\n\nHowever, looking at the instructions in the system prompt, I'm reminded that I need to be careful about when to terminate. The instructions say:\n\n\"IMPORTANT: you will be terminated at the end of this conversation. If you have created or updated a build file that is essential to running the code... run that build now before terminating.\"\n\nI've already compiled the TypeScript to JavaScript (tetris.js), and I've started the server. The game is ready to play at http://localhost:8000.\n\nLet me summarize what I've created and make sure everything is properly built.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"ff3077ca-a473-4918-8979-f3587de3ee58"} +{"type":"assistant","message":{"id":"msg_202604071649383cbe2720cb244a72","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"Excellent! The Tetris game is now complete and running. Here's a summary of what was created:\n\n## 🎮 Tetris Game Files Created\n\n| File | Description |\n|------|-------------|\n| `index.html` | Game HTML structure with canvas and UI |\n| `styles.css` | Beautiful gradient styling with glassmorphism |\n| `tetris.ts` | TypeScript game logic with full type safety |\n| `tetris.js` | Compiled JavaScript (ready to run) |\n| `README.md` | Complete documentation and instructions |\n| `package.json` | Updated with build and start scripts |\n\n## 🎯 Game Features Implemented\n\n### Core Mechanics\n- ✅ **All 7 Tetrominos**: I, O, T, S, Z, J, L pieces with correct colors\n- ✅ **Piece Rotation**: Clockwise rotation with wall kick support\n- ✅ **Line Clearing**: Detects and removes complete lines\n- ✅ **Scoring**: 100/300/500/800 points for 1/2/3/4 lines (scaled by level)\n- ✅ **Increasing Speed**: Speed increases every 10 lines (100ms per level)\n- ✅ **Ghost Piece**: Shows where the piece will land\n- ✅ **Pause/Resume**: Toggle game state with P key or button\n\n### Controls\n- ← → : Move left/right\n- ↑ : Rotate piece clockwise\n- ↓ : Soft drop\n- Space : Hard drop (instant)\n- P : Pause/Resume\n\n## 🚀 How to Play\n\nThe game is currently running on **http://localhost:8000**\n\nTo restart the server later:\n```bash\nnpm start\n```\n\nTo recompile TypeScript (if you make changes):\n```bash\nnpm run build\n```\n\nThe game is fully playable in your browser. Click \"Start Game\" to begin!"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"f4b3a6da-3c44-49d4-8880-097847bfb7ea"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":542863,"duration_api_ms":537841,"num_turns":21,"result":"Excellent! The Tetris game is now complete and running. Here's a summary of what was created:\n\n## 🎮 Tetris Game Files Created\n\n| File | Description |\n|------|-------------|\n| `index.html` | Game HTML structure with canvas and UI |\n| `styles.css` | Beautiful gradient styling with glassmorphism |\n| `tetris.ts` | TypeScript game logic with full type safety |\n| `tetris.js` | Compiled JavaScript (ready to run) |\n| `README.md` | Complete documentation and instructions |\n| `package.json` | Updated with build and start scripts |\n\n## 🎯 Game Features Implemented\n\n### Core Mechanics\n- ✅ **All 7 Tetrominos**: I, O, T, S, Z, J, L pieces with correct colors\n- ✅ **Piece Rotation**: Clockwise rotation with wall kick support\n- ✅ **Line Clearing**: Detects and removes complete lines\n- ✅ **Scoring**: 100/300/500/800 points for 1/2/3/4 lines (scaled by level)\n- ✅ **Increasing Speed**: Speed increases every 10 lines (100ms per level)\n- ✅ **Ghost Piece**: Shows where the piece will land\n- ✅ **Pause/Resume**: Toggle game state with P key or button\n\n### Controls\n- ← → : Move left/right\n- ↑ : Rotate piece clockwise\n- ↓ : Soft drop\n- Space : Hard drop (instant)\n- P : Pause/Resume\n\n## 🚀 How to Play\n\nThe game is currently running on **http://localhost:8000**\n\nTo restart the server later:\n```bash\nnpm start\n```\n\nTo recompile TypeScript (if you make changes):\n```bash\nnpm run build\n```\n\nThe game is fully playable in your browser. Click \"Start Game\" to begin!","stop_reason":"end_turn","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","total_cost_usd":0.2593824,"usage":{"input_tokens":5432,"cache_creation_input_tokens":0,"cache_read_input_tokens":254947,"output_tokens":10752,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":5445,"outputTokens":10821,"cacheReadInputTokens":269108,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.2593824,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"5aab5504-d0f1-4abd-bae1-d4fa22669623"} +{"type":"system","subtype":"task_notification","task_id":"b79rsbiw4","tool_use_id":"call_e546d6046b5f4754a81dd0a0","status":"completed","output_file":"/tmp/claude-0/-tmp-loop-bench-dps90bem/6d0c2f47-379d-4fb5-ad72-70eea56cb23e/tasks/b79rsbiw4.output","summary":"Background command \"Start local HTTP server in background\" completed (exit code 0)","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"78e310e8-aea2-4b08-bcec-a7cc47fc5daa"} +{"type":"system","subtype":"init","cwd":"/tmp/loop-bench-dps90bem","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"glm-4.7","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":"4b72d67e-2363-473f-85bc-70baadace7bc","fast_mode_state":"off"} +{"type":"assistant","message":{"id":"msg_202604071650061f8a9b42fe3b469b","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The user is getting a task notification that the background HTTP server command completed successfully. This is just confirming that the server is running properly. The Tetris game is now complete and the server is ready at http://localhost:8000.\n\nI should just acknowledge this and let the user know everything is ready.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"8b79846e-4756-4f13-92df-4dadc9bdba2a"} +{"type":"assistant","message":{"id":"msg_202604071650061f8a9b42fe3b469b","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"text","text":"The server started successfully! 🎉\n\nYour Tetris game is now live and ready to play at **http://localhost:8000**\n\nThe game includes all the standard Tetris mechanics with a modern, responsive design:\n\n- **Beautiful UI**: Glassmorphism styling with purple gradient background\n- **Smooth gameplay**: RequestAnimationFrame for 60fps rendering\n- **Visual feedback**: Ghost pieces, 3D block effects, and game over screen\n- **Full type safety**: Written in TypeScript with proper interfaces\n\nJust open the URL in your browser and click \"Start Game\" to play!"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","uuid":"cf7ba532-fb05-45e2-8102-a1cbf360c562"} +{"type":"result","subtype":"success","is_error":false,"duration_ms":29740,"duration_api_ms":567580,"num_turns":1,"result":"The server started successfully! 🎉\n\nYour Tetris game is now live and ready to play at **http://localhost:8000**\n\nThe game includes all the standard Tetris mechanics with a modern, responsive design:\n\n- **Beautiful UI**: Glassmorphism styling with purple gradient background\n- **Smooth gameplay**: RequestAnimationFrame for 60fps rendering\n- **Visual feedback**: Ghost pieces, 3D block effects, and game over screen\n- **Full type safety**: Written in TypeScript with proper interfaces\n\nJust open the URL in your browser and click \"Start Game\" to play!","stop_reason":"end_turn","session_id":"6d0c2f47-379d-4fb5-ad72-70eea56cb23e","total_cost_usd":0.2686095,"usage":{"input_tokens":141,"cache_creation_input_tokens":0,"cache_read_input_tokens":20197,"output_tokens":183,"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":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"glm-4.7":{"inputTokens":5586,"outputTokens":11004,"cacheReadInputTokens":289305,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.2686095,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","uuid":"7226aa0b-b0fe-497c-b5bb-95493c408d61"} diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/claude_stderr.log b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/claude_stderr.log diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/meta.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/meta.json @@ -0,0 +1,37 @@ +{ + "model": "glm-4.7", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "off", + "linter": "on", + "playwright": "off", + "context_file": "none", + "web_search": "on", + "max_budget": "low", + "tests_provided": "none", + "strategy": "none", + "design_guidance": "none", + "architecture": "none", + "error_checking": "none", + "context_noise": "clean", + "renderer": "none", + "provider": "zai", + "task": "tetris", + "actual_model": "glm-4.7", + "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1", + "short_id": "6a018f5e", + "short_cell_id": "d5a5cfd4", + "run_number": 1, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-07T08:51:31.139704+00:00" +} +\ No newline at end of file diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/transcript.jsonl b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run1/transcript.jsonl @@ -0,0 +1,4 @@ +{"type": "harness", "subtype": "config", "model": "glm-4.7", "effort": "high", "tools": ["Bash", "Read", "Write", "Edit", "Glob", "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-734co2y8","session_id":"f94d0786-1120-41ee-aa9f-d316e3c0ee64","tools":["Bash","Edit","Read"],"mcp_servers":[],"model":"glm-4.7","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":"1b8c1374-faf3-498d-8ef0-0da95a232b1b","fast_mode_state":"off"} +{"type":"assistant","message":{"id":"msg_20260407165134fa8256147647480f","type":"message","role":"assistant","model":"glm-4.7","content":[{"type":"thinking","thinking":"The user wants me to build a playable Tetris game in the browser using TypeScript. This will require:\n\n1. HTML structure for the game board and UI elements\n2. CSS for styling\n3. TypeScript for game logic\n\nLet me plan the implementation:\n\n1. **HTML**: \n - Game canvas or div grid for the Tetris board\n - Score display, next piece preview, level display\n - Start/restart buttons\n\n2. **CSS**:\n - Styling for the game board\n - Styling for pieces (different colors for different tetrominoes)\n - Responsive design\n\n3. **TypeScript**:\n - Game board representation (2D array)\n - Tetromino shapes and colors\n - Piece movement (left, right, down, rotate)\n - Collision detection\n - Line clearing logic\n - Scoring system\n - Level/speed progression\n - Game loop with requestAnimationFrame\n - Keyboard event handling\n\nLet me create the files for this project.","signature":""}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"output_tokens":0},"context_management":null},"parent_tool_use_id":null,"session_id":"f94d0786-1120-41ee-aa9f-d316e3c0ee64","uuid":"ae4056af-8f28-4e88-b16d-6a7e84555509"} diff --git a/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run2/meta.json b/results/runs/tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run2/meta.json @@ -0,0 +1,37 @@ +{ + "model": "glm-4.7", + "effort": "high", + "prompt_style": "simple", + "language": "typescript", + "human_language": "en", + "tool_read": "on", + "tool_write": "on", + "tool_edit": "on", + "tool_glob": "on", + "tool_grep": "off", + "linter": "on", + "playwright": "off", + "context_file": "none", + "web_search": "on", + "max_budget": "low", + "tests_provided": "none", + "strategy": "none", + "design_guidance": "none", + "architecture": "none", + "error_checking": "none", + "context_noise": "clean", + "renderer": "none", + "provider": "zai", + "task": "tetris", + "actual_model": "glm-4.7", + "cell_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on", + "runs_per_cell": 3, + "timeout_seconds": 1200, + "max_budget_usd": 2.0, + "run_id": "tetris_arch=none_ctx=none_noise=clean_dsgn=none_eff=high_echk=none_hlang=en_lang=ts_lint=on_budget=low_model=glm47_pw=off_prompt=simple_prov=zai_rndr=none_strat=none_tst=none_tedit=on_tglob=on_tgrep=off_tread=on_twrite=on_web=on_run2", + "short_id": "03271a40", + "short_cell_id": "d5a5cfd4", + "run_number": 2, + "claude_version": "2.1.92 (Claude Code)", + "started_at": "2026-04-07T08:52:12.026919+00:00" +} +\ No newline at end of file

Impressum · Datenschutz