diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 5e93070..6506ed9 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,7 +1,7 @@ # Graph Report - juzi (2026-10-13) ## Corpus Check -- 118 files · ~4,910,388 words +- 118 files · ~4,910,480 words - Verdict: corpus is large enough that graph structure adds value. ## Summary @@ -10,7 +10,7 @@ - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `e71368db` +- Built from commit: `73813061` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). diff --git a/graphify-out/graph.json b/graphify-out/graph.json index 78287dd..01b1c0e 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -22291,7 +22291,7 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "h5/test/scan-placeholder.mjs", - "source_location": "L76", + "source_location": "L80", "weight": 1.0, "_origin": "ast", "source": "h5_test_scan_placeholder", @@ -51725,5 +51725,5 @@ } ], "hyperedges": [], - "built_at_commit": "e71368db6d5f23e06cd13457b63f54540b267a53" + "built_at_commit": "7381306139392bc4575c5331951df2076c9854f1" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 8cd5b3d..ee0faaa 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -140,8 +140,8 @@ "semantic_hash": "" }, "h5/index.html": { - "mtime": 1791885347.4210553, - "ast_hash": "663942bdfbce6304130bb23712875653", + "mtime": 1791885786.4010859, + "ast_hash": "2a9b884da4be536708d26bf69f4a9f12", "semantic_hash": "" }, "h5/vendor/faceapi/README.md": { @@ -1930,8 +1930,8 @@ "semantic_hash": "" }, "h5/test/scan-placeholder.mjs": { - "mtime": 1791815038.0590124, - "ast_hash": "bb8566ee5f3ad2a6bf95aafafb7145ba", + "mtime": 1791885786.4050858, + "ast_hash": "98f0327cec6167ceb0a435240f763e4c", "semantic_hash": "" }, "tools/optimize_delivery_images.py": { @@ -2015,8 +2015,8 @@ "semantic_hash": "" }, "docs/\u76f8\u673a\u7ffb\u8f6c\u6027\u80fd\u4f18\u5316-2026-10-13.md": { - "mtime": 1791881165.8330255, - "ast_hash": "bb925d4f64c3d8275262b8241adc4c1b", + "mtime": 1791885450.2930646, + "ast_hash": "5d45e9c3fdde5ef718721caf5dbc88a7", "semantic_hash": "" }, "h5/test/splash-brand-browser.mjs": { @@ -2025,8 +2025,8 @@ "semantic_hash": "" }, "docs/\u62cd\u6444\u89d2\u5ea6\u4e0d\u5408\u683c\u9707\u52a8\u63d0\u9192-2026-10-13.md": { - "mtime": 1791884945.1610558, - "ast_hash": "a02d1db13bb8aa8e76e58e78fb6b82b7", + "mtime": 1791885450.2930646, + "ast_hash": "fcbbc5db7241f97579efaf14eaa5135e", "semantic_hash": "" } } \ No newline at end of file diff --git a/h5/css/ui-20261012.css b/h5/css/ui-20261012.css index 4bcb0e3..2231519 100644 --- a/h5/css/ui-20261012.css +++ b/h5/css/ui-20261012.css @@ -86,6 +86,10 @@ .scan-stage { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(100vw, 480px, calc(100dvh * 1080 / 2091)); height: min(100dvh, calc(min(100vw, 480px) * 2091 / 1080)); } @supports not (height: 100dvh) { .scan-stage { width: min(100vw, 480px, calc(100vh * 1080 / 2091)); height: min(100vh, calc(min(100vw, 480px) * 2091 / 1080)); } } .scan-artwork { width: 100%; height: 100%; object-fit: contain; } +/* Cover the old flip icon baked into the PSD raster (843,1846–921,1924). + Share the camera's replacement asset; decorative only, never a control. */ +.scan-flip-icon { position:absolute; left:77.314815%; top:87.900526%; width:8.888889%; height:4.591105%; background:#000; display:flex; align-items:center; justify-content:center; pointer-events:none; } +.scan-flip-icon img { width:83.333333%; height:83.333333%; object-fit:contain; } .scan-face { position: absolute; inset: 0; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; overflow: hidden; } .scan-beam { position: absolute; left: 0; right: 0; top: 20%; height: 18%; background: linear-gradient(to bottom, #F5F078 0%, #F5F078 35%, rgba(245,240,120,0) 100%); } #p-analyzing:not(.scan-artwork-ready) .scan-stage { visibility: hidden; } diff --git a/h5/index.html b/h5/index.html index 8c5f31b..b0478b8 100644 --- a/h5/index.html +++ b/h5/index.html @@ -460,6 +460,7 @@

检测中…

diff --git a/h5/test/scan-placeholder.mjs b/h5/test/scan-placeholder.mjs index 1faa497..8f18a78 100644 --- a/h5/test/scan-placeholder.mjs +++ b/h5/test/scan-placeholder.mjs @@ -64,6 +64,10 @@ try { assert.equal(await page.locator('#scan-photo').count(), 0, 'no user photo element'); await capture(); await page.waitForSelector('#p-analyzing.scan-artwork-ready'); + await page.waitForFunction(() => { const i = document.querySelector('.scan-flip-icon img'); return i.complete && i.naturalWidth === 80 && i.naturalHeight === 80; }); + assert.equal(await page.locator('.scan-flip-icon img').getAttribute('src'), await page.locator('.cam-flip img').getAttribute('src'), 'scan and camera share replacement icon'); + assert.equal(await page.locator('.scan-flip-icon').evaluate(el => getComputedStyle(el).pointerEvents), 'none'); + assert.equal(await page.locator('.scan-flip-icon [data-action], button.scan-flip-icon').count(), 0, 'scan flip stays decorative'); assert((await page.locator('#scan-face').evaluate(el => getComputedStyle(el).maskImage)).includes('scan-face-mask.png')); assert.equal(await page.locator('.scan-beam').evaluate(el => getComputedStyle(el).animationName), 'report-scan'); const pixels = await page.locator('#scan-artwork').evaluate(image => { @@ -75,6 +79,9 @@ try { for (const [width, height] of [[320, 726], [375, 726], [390, 844], [414, 896], [480, 726], [375, 440]]) { await page.setViewportSize({ width, height }); const art = await page.locator('#scan-artwork').boundingBox(); + const icon = await page.locator('.scan-flip-icon img').boundingBox(); + assert(Math.abs(icon.width / art.width - 80 / 1080) < .001, 'icon scales with PSD stage'); + assert(Math.abs(icon.height - icon.width) < 1, 'replacement remains square'); assert(art.width <= width + 1 && art.height <= height + 1); assert(Math.abs(art.width / art.height - 1080 / 2091) < .001, 'PSD is contained without cropping'); assert(Math.abs(art.x - (width - art.width) / 2) < 1 && Math.abs(art.y - (height - art.height) / 2) < 1);