9104064e8c
The #moveCursorToTarget() method recursively schedules itself via requestAnimationFrame, creating a continuous animation loop for the AI cursor. However, dispose() only removes the DOM wrapper element without stopping this loop, causing: - CPU waste: rAF callback continues executing every frame (~60fps) after the mask is disposed, performing unnecessary calculations on a detached cursor element. - Resource leak: Each SimulatorMask instance creates an unrecoverable animation loop that persists for the lifetime of the page. - Console noise: style assignments to removed DOM nodes may produce browser warnings. Fix: Add a #disposed boolean flag, checked at the top of #moveCursorToTarget() to short-circuit the recursion. Set the flag to true in dispose() before removing DOM elements. Changes: - Add #disposed field (default false) - Guard #moveCursorToTarget() with early return when #disposed - Set #disposed = true in dispose() before cleanup