diff --git a/aiAssets/arr_mip_grhpl_easylevelprogression_01_real_nougc_noseason_en_full_na_al.html b/aiAssets/arr_mip_grhpl_easylevelprogression_01_real_nougc_noseason_en_full_na_al.html deleted file mode 100644 index 52d623d..0000000 --- a/aiAssets/arr_mip_grhpl_easylevelprogression_01_real_nougc_noseason_en_full_na_al.html +++ /dev/null @@ -1,6381 +0,0 @@ - - - - - - Arrow Puzzle - - - - - - - diff --git a/aiAssets/wrd_mip_grhpl_simplegameplaysounddark_01_real_nougc_noseason_en_full_na_al.html b/aiAssets/wrd_mip_grhpl_simplegameplaysounddark_01_real_nougc_noseason_en_full_na_al.html deleted file mode 100644 index 6022461..0000000 --- a/aiAssets/wrd_mip_grhpl_simplegameplaysounddark_01_real_nougc_noseason_en_full_na_al.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - Wordle - - - - - - - - - - \ No newline at end of file diff --git a/manifest.json b/data/manifest.json similarity index 100% rename from manifest.json rename to data/manifest.json diff --git a/build.ps1 b/scripts/build.ps1 similarity index 100% rename from build.ps1 rename to scripts/build.ps1 diff --git a/scripts/check-dogcat3-playwright.mjs b/scripts/check-dogcat3-playwright.mjs deleted file mode 100644 index 367f730..0000000 --- a/scripts/check-dogcat3-playwright.mjs +++ /dev/null @@ -1,177 +0,0 @@ -import { chromium } from 'playwright'; -import { createServer } from 'node:http'; -import { execFileSync } from 'node:child_process'; -import { mkdtemp, readdir, readFile, rm } from 'node:fs/promises'; -import { existsSync } from 'node:fs'; -import { tmpdir } from 'node:os'; -import path from 'node:path'; - -const root = process.cwd(); -const dogCatRoot = process.env.DOGCAT_ROOT || path.join(root, 'aiAssets', 'DogCat3'); -const waitMs = Number(process.env.RUNTIME_WAIT_MS || 9000); - -const mraidStub = ` -window.mraid = window.mraid || { - getState: function(){ return 'default'; }, - isViewable: function(){ return true; }, - addEventListener: function(name, cb){ if (name === 'ready') setTimeout(cb, 0); }, - removeEventListener: function(){}, - open: function(url){ console.log('[stub mraid.open]', url); }, - close: function(){ console.log('[stub mraid.close]'); }, - supports: function(){ return false; } -}; -`; - -const exitApiStub = ` -window.ExitApi = window.ExitApi || { - exit: function(){ console.log('[stub ExitApi.exit]'); } -}; -`; - -async function collectCases(tempDir) { - const cases = []; - const networkFolders = [ - 'Applovin', - 'Facebook', - 'Ironsource', - 'Moloco', - 'Unity', - 'GoogleAds', - 'Mintegral', - 'Vungle', - ]; - for (const name of networkFolders) { - const dir = path.join(dogCatRoot, name); - if (!existsSync(dir)) continue; - const entries = await readdir(dir); - const htmlName = entries.find((entry) => /\.html?$/i.test(entry)); - if (htmlName) { - cases.push([name, await readFile(path.join(dir, htmlName))]); - continue; - } - const zipName = entries.find((entry) => /\.zip$/i.test(entry)); - if (!zipName) continue; - const zip = path.join(dir, zipName); - const out = path.join(tempDir, name); - execFileSync('powershell', [ - '-NoProfile', - '-Command', - `Expand-Archive -LiteralPath '${zip.replaceAll("'", "''")}' -DestinationPath '${out.replaceAll("'", "''")}' -Force`, - ], { stdio: 'ignore' }); - const expanded = await readdir(out); - const indexName = expanded.find((entry) => entry.toLowerCase() === 'index.html'); - if (indexName) cases.push([name, await readFile(path.join(out, indexName))]); - } - return cases; -} - -async function startServer(cases) { - const html = new Map(cases.map(([name, body]) => [`/${name}/index.html`, body])); - const server = createServer((req, res) => { - const url = new URL(req.url || '/', 'http://127.0.0.1'); - if (url.pathname.endsWith('/mraid.js')) { - res.writeHead(200, { 'content-type': 'application/javascript' }); - res.end(mraidStub); - return; - } - if (url.pathname.endsWith('/exitapi.js')) { - res.writeHead(200, { 'content-type': 'application/javascript' }); - res.end(exitApiStub); - return; - } - const body = html.get(url.pathname); - if (body) { - res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }); - res.end(body); - return; - } - res.writeHead(404, { 'content-type': 'text/plain' }); - res.end('not found'); - }); - await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); - return { - baseUrl: `http://127.0.0.1:${server.address().port}`, - close: () => new Promise((resolve) => server.close(resolve)), - }; -} - -function simplifyUrl(url) { - return url.replace(/^https?:\/\/127\.0\.0\.1:\d+\//, '/'); -} - -async function runCase(browser, baseUrl, name) { - const page = await browser.newPage({ viewport: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true }); - const issues = []; - - page.on('pageerror', (error) => { - issues.push({ type: 'pageerror', text: error.stack || error.message }); - }); - page.on('console', (message) => { - if (['error', 'assert'].includes(message.type())) { - const location = message.location(); - const suffix = location.url ? ` @ ${simplifyUrl(location.url)}:${location.lineNumber}:${location.columnNumber}` : ''; - issues.push({ type: `console.${message.type()}`, text: `${message.text()}${suffix}` }); - } - }); - page.on('requestfailed', (request) => { - issues.push({ - type: 'requestfailed', - text: `${simplifyUrl(request.url())} :: ${request.failure()?.errorText || 'failed'}`, - }); - }); - page.on('response', (response) => { - if (response.status() >= 400) { - issues.push({ - type: `http.${response.status()}`, - text: simplifyUrl(response.url()), - }); - } - }); - - await page.goto(`${baseUrl}/${name}/index.html`, { waitUntil: 'domcontentloaded', timeout: 20000 }); - await page.waitForTimeout(waitMs); - - const bodyText = await page.locator('body').evaluate((body) => body.innerText.slice(0, 2000)).catch(() => ''); - const canvasCount = await page.locator('canvas').count().catch(() => 0); - const title = await page.title().catch(() => ''); - await page.close(); - - return { issues, canvasCount, title, bodyText }; -} - -async function main() { - const tempDir = await mkdtemp(path.join(tmpdir(), 'dogcat3-playwright-')); - let server; - let browser; - try { - const cases = await collectCases(tempDir); - server = await startServer(cases); - browser = await chromium.launch({ channel: 'msedge', headless: true }); - - for (const [name] of cases) { - const result = await runCase(browser, server.baseUrl, name); - console.log(`\n## ${name}`); - console.log(`canvas=${result.canvasCount}`); - if (result.title) console.log(`title=${result.title}`); - if (!result.issues.length) { - console.log('No page errors, console errors, failed requests, or HTTP 4xx/5xx responses captured.'); - } else { - for (const issue of result.issues) { - console.log(`- ${issue.type}: ${issue.text.replace(/\s+/g, ' ').slice(0, 700)}`); - } - } - if (result.bodyText && /error|exception|cannot|failed/i.test(result.bodyText)) { - console.log(`body_error_text=${result.bodyText.replace(/\s+/g, ' ').slice(0, 700)}`); - } - } - } finally { - if (browser) await browser.close(); - if (server) await server.close(); - await rm(tempDir, { recursive: true, force: true }); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/run-standalone.ps1 b/scripts/run-standalone.ps1 similarity index 100% rename from run-standalone.ps1 rename to scripts/run-standalone.ps1