> numberswipe-main@1.0.0 check > npm run build && npm test && npm run smoke > numberswipe-main@1.0.0 build > node build.mjs Built campaign-200-r2: 200 levels > numberswipe-main@1.0.0 test > node --test *.test.mjs ✔ 手机没有浏览器音频接口时,原生播放器仍能播放全部 36 步和六类反馈音 (8.9435ms) ✔ 关闭音效停止播放;再次开启会试听并保存偏好;后台中断停止所有播放器 (1.1639ms) ✔ 延迟通关音在静音或进入后台时取消,不在返回后突然播放 (47.0186ms) ✔ 音频错误可诊断,不再静默吞掉 (0.8142ms) ✔ 所有音频均为非静音 PCM;原版第13步比第1步高一个八度 (49.8985ms) ✔ 教学和组合规则用具体动作及奇偶例子解释,没有未解释的术语 (39.0574ms) ✔ 过关提示同步使用实际播放起点,非请求时间 (1.1057ms) ✔ 过关短句使用用户提供的3秒WAV,不与旧和弦叠加 (7.5766ms) ✔ jingle end, cancellation and playback error restore BGM without restarting (6.6654ms) ✔ muted effects never duck BGM and unrelated effect errors cannot end jingle ducking (0.5332ms) ✔ hide and music preference do not revive playback through a late jingle callback (0.5819ms) ✔ BGMB is absent from the runtime manifest and music package (0.9783ms) ✔ merged irregular outlines retain holes and never draw internal unit edges (187.7866ms) ✔ all 200 boards fit four screen budgets with stable safe anchors and real shared entrances (1687.1491ms) ✔ guides through every irregular block stay inside its occupied shape (67.4851ms) ✔ visited, conflicting and hinted category cells retain their material identity (15.4878ms) ✔ five font subsets match their manifest and fit the package budget (6.3089ms) ✔ upstream adapter fails closed if the inspected render seams change (4.4174ms) ✔ procedural cushion pixels preserve holes and light the upper bevel without a border (39.8189ms) ✔ visible glyph bounds are centered independently of font ascent and side bearings (2.0616ms) ✔ stage with zero depth casts alpha shadows without painting a solid backing (12.7032ms) ✔ native width-only TextMetrics still centers the rasterized glyph ink (5.3524ms) ✔ fixed channels remain anchored at their block centers after number enlargement (2251.9192ms) ✔ checkpoint ribbons trigger on correct arrival only and never duplicate per frame (7.9589ms) ✔ checkpoint pulse is small, centered in time and settles without looping (0.8892ms) ✔ event batches preserve every landing and sequence but commit only highest audio and haptic (8.628ms) ✔ completion waits at most 120ms and ignores late audio callbacks (0.7635ms) ✔ light haptics are limited, checkpoint replaces light, and completion adds only one delayed short pulse (0.9155ms) ✔ unsupported graded haptic falls back to one short pulse, never long vibration (4.573ms) ✔ haptic disable, preview and lifecycle cancellation suppress delayed or expired work (1.2133ms) ✔ late failed haptic requests cannot revive old pulses and ungraded completion falls back once (16.0315ms) ✔ rectangles, concave shapes and hexagons require geometric inward distance without treating internal seams as walls (58.0774ms) ✔ one high-speed native move records all intermediate cells and completion without duplicate final node (333.9406ms) ✔ legal but off-solution moves use public rules, while invalid clues only produce error (513.6096ms) ✔ drag near a previous-block boundary cannot undo; deeper entry can, and undo button remains immediate (263.342ms) ✔ tutorial, redraw, hint and restored saved routes do not generate player feedback (316.5441ms) ✔ pressure and rebound have bounded amplitude and duration (0.7293ms) ✔ interpolation cannot duplicate the same failed-cell event within one native movement (0.4654ms) ✔ nodes are driven by explicit events even when multiple arrive before rendering; at most two ribbons survive (54.316ms) ✔ audio fast moves merge to latest pitch and completion stops the whole four-channel pool (4.2573ms) ✔ settings persist haptic preference independently and chapter cards always use three columns (196.5803ms) ✔ original audio is preserved and high pitches lose energy rather than growing sharper (20.3321ms) ✔ empty, partial and wrong routes reveal the first incomplete full segment (8.1753ms) ✔ completion hides the hint; repeat clicks cannot skip; undo and restart return to earlier segments (1.1961ms) ✔ all 200 levels reveal consecutive segments without changing the player path (3772.7025ms) ✔ hint draws skip player edges and mask visited cells on their own layer; compositing is restored (3.0586ms) ✔ parity is a segment anchor; colour is not; flow moves continuously across cells (2.7027ms) ✔ soft teaching ribbon preserves visited masks without arrows in reduced motion (3.0311ms) ✔ hint rounds shared guide junctions and keeps separate runs disconnected (2.0014ms) ✔ 实际教学关动画:basic (5.7751ms) ✔ 实际教学关动画:walls (1.3457ms) ✔ 实际教学关动画:straight (3.5357ms) ✔ 实际教学关动画:vertical (5.928ms) ✔ 实际教学关动画:corner (2.104ms) ✔ 实际教学关动画:colour (1.229ms) ✔ 实际教学关动画:parity (0.7272ms) ✔ 实际教学关动画:rhythm-door (2.0488ms) ✔ 实际教学关动画:hex (16.839ms) ✔ 实际教学关动画:unknown-start (8.1501ms) ✔ 200关的组合规则均能找到对应真实教学关 (146.9163ms) ✔ 教学减速,结束停留1秒后自动循环 (3.789ms) ✔ music loops independently, persists mute and cancels in background (2.5341ms) ✔ old arrows retain distance, rush to endpoint and fresh arrows move at base speed (1.0276ms) ✔ settings have exactly three independent preferences, and hint has its own cue (531.0682ms) ✔ actual fixed numeric node uses checkpoint pitch, final cell uses complete chord (357.6796ms) ✔ selected menu and BGMA loop are stereo PCM WAV with complete musical durations (12.9153ms) ✔ selected runtime WAVs retain the original durations after sample-rate adaptation (46.8893ms) ✔ gameplay ambient uses lower scene volume and keeps independent mute and resume behavior (0.7041ms) ✔ all 200 levels: valid numeric, parity and direction arrivals play checkpoint pitch; final arrival only completes (53800.1232ms) ✔ drag back and undo button both vibrate lightly; disabling vibration suppresses both (82.8582ms) ✔ haptic cadence is approximately 15 percent denser without changing light or medium grades (3.0517ms) ✔ regular and special scale settle at 90ms with a larger special peak (0.3485ms) ✔ rendered undo target and nonnumeric checkpoint animate immediately without adding ribbons (9.0174ms) ✔ quick undo cancels removed node rebound, including last-step removal (3.4522ms) ✔ navigation buttons use the same selection cue and settings include uniform colons (63.494ms) ✔ early next during confetti cancels warming; settled ceremony reuses its background (285.4005ms) ✔ font corpus includes every settings label including music le glyph (1.8083ms) ✔ first launch goes directly to gameplay (493.2614ms) ✔ resume unfinished route after exit from gameplay (615.7597ms) ✔ resume unfinished route after exit from selection (504.8706ms) ✔ completed level resumes next unfinished, including leaving from cleared screen (183.7206ms) ✔ replaying a cleared level does not replace the unfinished save (188.5401ms) ✔ legacy saves, malformed data and full completion have valid startup targets (219.7827ms) ✔ selection pages expose fifteen cards and fit phone safe areas (514.0614ms) ✔ hint-only frames reuse static UI, and player input invalidates it (151.9144ms) ✔ hint curves are cached and distance lookup is stable at boundaries (2.1228ms) ✔ new-mechanic lesson reuses the board while the continuous cursor advances (130.4526ms) ✔ BGMA stays continuous across level changes and completion redraws (2.7072ms) ✔ subpackage completion never plays a stale scene after hiding, muting, or clearing (0.6587ms) ✔ music load failure is silent and one real resume can retry; muted pending loads stay silent (0.6025ms) ✔ runtime uses supplied WAV hashes and ships music as a subpackage with a small main bundle (266.2246ms) ✔ title is centered and selection settings share the progress and level-range row (925.6168ms) ✔ completion ducks BGMA until jingle ends and next level never restarts it (252.8562ms) ✔ title artwork is a transparent, high resolution PNG packaged locally (12.136ms) ✔ asynchronous native image load requests a repaint and draws the artwork without a font substitute (1.315ms) ✔ artwork stays above progress pills and clear of settings; fifteen cards still fit all phone sizes (1184.7768ms) ✔ A3 width, one wide patch and brighter body preserve original design proportions (7.0053ms) ✔ ribbon caches its body, draws source-atop only offscreen and starts each frame clean (13.5722ms) ✔ one patch travels at 60px/s on the full route and does not restart when player advances (0.5319ms) ✔ reduced motion and missing canvas use a static ribbon without main-board compositing (0.6184ms) ✔ real target contours and smoothed routes stay attached to actual 200-level geometry (2580.5724ms) ✔ live target breath uses cached board layers, arrival and background stop obsolete visuals (273.3177ms) ✔ undo button reverses seven played steps as 7,6,5,4,3,2,1 (723.4609ms) ✔ drag reverses seven played steps as 7,6,5,4,3,2,1 (316.3682ms) ✔ completion amplitude is reduced 15 percent while node, undo and restart volumes stay unchanged (2.476ms) ✔ fast reverse coalesces to the latest descending pitch and cannot replay an old forward note (2.3642ms) ✔ all prepared routes match the immutable level hash and public rules (32.8606ms) ✔ entering next level draws the live board once and preserves the running BGMA player (2786.6811ms) ✔ next-board warming advances one item per frame and cancels on deadline, replacement or hide (0.8861ms) ✔ idle material warming never changes the player path or emits sound and vibration (113.63ms) ℹ tests 110 ℹ suites 0 ℹ pass 110 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 54956.9338 > numberswipe-main@1.0.0 smoke > node smoke.mjs PASS 200/200: r2源文件哈希一致、唯一解、微信发布包触摸通关、撤销/重开/指路、存档/音效设置恢复、前后台切换。