import { readFile, writeFile } from 'node:fs/promises' import { createHash } from 'node:crypto' import { parse } from '@babel/parser' import postcss from 'postcss' const evidence = JSON.parse(await readFile('.tmp/rea-runtime-scripts.json', 'utf8')) if (evidence.evidence_id !== 'ev_717fa5e846e64d67ac19c8925d121bff632c0d3aefb3603b10858559cabb2dcb') throw Error('REA script Evidence changed') const source = evidence.items.find(item => item.file_path.endsWith('media-preview-DMz4TW4q.js'))?.source?.artifact?.text if (!source || createHash('sha256').update(source).digest('hex') !== 'e8c19693ac7d8d06b45b531de405cc23c071fa19ebd5543b483a43dbdfce8111') throw Error('Browser source changed') const names = { BackIcon: 'SourceBrowserBackIcon', ForwardIcon: 'SourceBrowserForwardIcon', RefreshIcon: 'SourceBrowserRefreshIcon', BrowserPlaceholderIcon: 'SourceBrowserPlaceholderIcon' } const found = new Map() const walk = node => { if (!node || typeof node !== 'object') return if (node.type === 'AssignmentExpression' && node.left.type === 'Identifier' && names[node.left.name] && node.right.type === 'ArrowFunctionExpression') { let value = source.slice(node.right.start, node.right.end).replace(/\(0,[A-Za-z0-9_$]+\.(jsx|jsxs)\)/g, ' $1') value = value.replace(/Yr\.icon/g, '"_icon_vnue1_21"') found.set(node.left.name, `const ${names[node.left.name]} = ${value}`) } for (const value of Object.values(node)) if (Array.isArray(value)) value.forEach(walk); else if (value && typeof value === 'object') walk(value) } walk(parse(source, { sourceType: 'module' })) if (found.size !== Object.keys(names).length) throw Error('Browser SVG family missing') const panePath = 'src/renderer/src/workbuddy/workbench/NativeBrowserPane.tsx' const pane = await readFile(panePath, 'utf8') await writeFile(panePath, pane.replace(/\/\/ BEGIN REA BROWSER SVG[\s\S]*?\/\/ END REA BROWSER SVG/, `// BEGIN REA BROWSER SVG\n// Unchanged SVG payloads from ${evidence.evidence_id}, media-preview-DMz4TW4q.js.\n${[...found.values()].join('\n')}\n// END REA BROWSER SVG`)) const css = await readFile('.tmp/rea-css-recovered/media-preview-Dvr0Ekj9.css', 'utf8') if (createHash('sha256').update(css).digest('hex') !== '36758fadd61577145a3b46dd12bcd966c662ea0cfaa4e62dc3e31ba4bf7f5fb8') throw Error('Browser CSS changed') function filter(node) { if (node.type === 'rule') return /_rh4x8_|_x8iy7_|_vnue1_/.test(node.selector) ? node.clone() : null if (node.type !== 'atrule') return null const result = node.clone({ nodes: [] }) for (const child of node.nodes ?? []) { const match = filter(child); if (match) result.append(match) } return result.nodes.length ? result : null } const selected = postcss.root() for (const node of postcss.parse(css).nodes) { const match = filter(node); if (match) selected.append(match) } await writeFile('src/renderer/src/workbuddy/workbench/browser-source.css', `/* REA ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94; exact browser rules with parent conditions. */\n${selected.toString()}\n/* YCode native-surface bindings. */\n.yc-native-browser{--wb-color-border-tertiary:var(--yc-border-tertiary);--wb-color-border-solid:var(--yc-border-primary);--wb-color-border-focus:var(--yc-brand-8);min-height:0;flex:1;position:relative}\n.yc-native-browser button{border:0;background:transparent;padding:0;cursor:pointer}\n.yc-native-browser button:disabled{opacity:.35;cursor:default}\n.yc-native-browser__viewport{flex:1;min-height:0;background:white}\n.yc-native-browser__progress{height:2px;background:var(--yc-brand-8);position:absolute;top:47px;left:0;right:0;z-index:1;opacity:.6}\n:root[data-theme=dark] .yc-native-browser ._icon_vnue1_21{--nt-browser-chrome:#424242;--nt-browser-body:#333}\n`) console.log(`Recovered ${found.size} source browser SVGs and browser toolbar/placeholder CSS`)