> 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 步和六类反馈音 (3.9885ms) ✔ 关闭音效停止播放;再次开启会试听并保存偏好;后台中断停止所有播放器 (0.7226ms) ✔ 延迟通关音在静音或进入后台时取消,不在返回后突然播放 (43.816ms) ✔ 音频错误可诊断,不再静默吞掉 (0.4879ms) ✔ 所有音频均为非静音 PCM;原版第13步比第1步高一个八度 (17.705ms) ✔ 教学和组合规则用具体动作及奇偶例子解释,没有未解释的术语 (10.1978ms) ✔ 过关提示同步使用实际播放起点,非请求时间 (0.67ms) ✔ 过关和弦收尾持续衰减,不在后半段重新起音 (2.9896ms) ✔ merged irregular outlines retain holes and never draw internal unit edges (47.5019ms) ✔ all 200 boards fit four screen budgets with stable safe anchors and real shared entrances (610.3905ms) ✔ guides through every irregular block stay inside its occupied shape (29.4299ms) ✔ visited, conflicting and hinted category cells retain their material identity (10.7152ms) ✔ five font subsets match their manifest and fit the package budget (3.8633ms) ✔ upstream adapter fails closed if the inspected render seams change (0.7606ms) ✔ procedural cushion pixels preserve holes and light the upper bevel without a border (18.2888ms) ✔ visible glyph bounds are centered independently of font ascent and side bearings (1.8222ms) ✔ stage with zero depth casts alpha shadows without painting a solid backing (8.1804ms) ✔ native width-only TextMetrics still centers the rasterized glyph ink (2.6229ms) ✔ fixed channels remain anchored at their block centers after number enlargement (781.7528ms) ✔ checkpoint ribbons trigger on correct arrival only and never duplicate per frame (4.1184ms) ✔ checkpoint pulse is small, centered in time and settles without looping (0.3466ms) ✔ event batches preserve every landing and sequence but commit only highest audio and haptic (2.9218ms) ✔ completion waits at most 120ms and ignores late audio callbacks (0.5196ms) ✔ light haptics are limited, checkpoint replaces light, and completion adds only one delayed short pulse (0.4533ms) ✔ unsupported graded haptic falls back to one short pulse, never long vibration (0.3297ms) ✔ haptic disable, preview and lifecycle cancellation suppress delayed or expired work (0.5018ms) ✔ late failed haptic requests cannot revive old pulses and ungraded completion falls back once (0.3539ms) ✔ rectangles, concave shapes and hexagons require geometric inward distance without treating internal seams as walls (1.3157ms) ✔ one high-speed native move records all intermediate cells and completion without duplicate final node (121.2167ms) ✔ legal but off-solution moves use public rules, while invalid clues only produce error (60.7207ms) ✔ drag near a previous-block boundary cannot undo; deeper entry can, and undo button remains immediate (44.9951ms) ✔ tutorial, redraw, hint and restored saved routes do not generate player feedback (78.4011ms) ✔ pressure and rebound have bounded amplitude and duration (0.3839ms) ✔ interpolation cannot duplicate the same failed-cell event within one native movement (0.2255ms) ✔ nodes are driven by explicit events even when multiple arrive before rendering; at most two ribbons survive (18.5497ms) ✔ audio fast moves merge to latest pitch and completion stops the whole four-channel pool (1.2874ms) ✔ settings persist haptic preference independently and chapter cards always use three columns (75.56ms) ✔ original audio is preserved and high pitches lose energy rather than growing sharper (7.6609ms) ✔ empty, partial and wrong routes reveal the first incomplete full segment (3.5196ms) ✔ completion hides the hint; repeat clicks cannot skip; undo and restart return to earlier segments (0.5284ms) ✔ all 200 levels reveal consecutive segments without changing the player path (1330.6071ms) ✔ hint draws skip player edges and mask visited cells on their own layer; compositing is restored (0.8237ms) ✔ parity is a segment anchor; colour is not; flow moves continuously across cells (0.3012ms) ✔ coral teaching ribbon preserves visited masks and offers direction in reduced motion (1.3822ms) ✔ hint rounds shared guide junctions and keeps separate runs disconnected (0.2984ms) ✔ 实际教学关动画:basic (4.1589ms) ✔ 实际教学关动画:walls (0.8719ms) ✔ 实际教学关动画:straight (1.9467ms) ✔ 实际教学关动画:vertical (2.6791ms) ✔ 实际教学关动画:corner (1.1548ms) ✔ 实际教学关动画:colour (0.5767ms) ✔ 实际教学关动画:parity (0.515ms) ✔ 实际教学关动画:rhythm-door (0.704ms) ✔ 实际教学关动画:hex (0.6488ms) ✔ 实际教学关动画:unknown-start (1.7224ms) ✔ 200关的组合规则均能找到对应真实教学关 (91.9189ms) ✔ 教学减速,结束停留1秒后自动循环 (4.4562ms) ✔ music loops independently, persists mute and cancels in background (1.613ms) ✔ old arrows retain distance, rush to endpoint and fresh arrows move at base speed (0.7279ms) ✔ settings have exactly three independent preferences, and hint has its own cue (124.8702ms) ✔ actual fixed numeric node uses checkpoint pitch, final cell uses complete chord (107.024ms) ✔ two original music loops are quiet, nonempty and have a smooth loop seam (1.5419ms) ✔ all 200 levels: valid numeric, parity and direction arrivals play checkpoint pitch; final arrival only completes (24773.4619ms) ✔ drag back and undo button both vibrate lightly; disabling vibration suppresses both (50.2723ms) ✔ haptic cadence is approximately 15 percent denser without changing light or medium grades (1.4843ms) ✔ regular and special scale settle at 90ms with a larger special peak (0.3ms) ✔ rendered undo target and nonnumeric checkpoint animate immediately without adding ribbons (6.1374ms) ✔ quick undo cancels removed node rebound, including last-step removal (1.9203ms) ✔ first launch goes directly to gameplay (86.9461ms) ✔ resume unfinished route after exit from gameplay (105.339ms) ✔ resume unfinished route after exit from selection (89.2179ms) ✔ completed level resumes next unfinished, including leaving from cleared screen (75.952ms) ✔ replaying a cleared level does not replace the unfinished save (79.5395ms) ✔ legacy saves, malformed data and full completion have valid startup targets (56.1729ms) ✔ selection pages expose fifteen cards and fit phone safe areas (247.9721ms) ✔ hint-only frames reuse static UI, and player input invalidates it (46.1472ms) ✔ hint curves are cached and distance lookup is stable at boundaries (1.1599ms) ✔ new-mechanic lesson reuses the board while the continuous cursor advances (39.2951ms) ℹ tests 78 ℹ suites 0 ℹ pass 78 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 25049.2178 > numberswipe-main@1.0.0 smoke > node smoke.mjs PASS 200/200: r2源文件哈希一致、唯一解、微信发布包触摸通关、撤销/重开/指路、存档/音效设置恢复、前后台切换。