import fs from 'node:fs' import path from 'node:path' import { parse } from '@babel/parser' import traverseModule from '@babel/traverse' import postcss from 'postcss' const traverse=traverseModule.default??traverseModule, evidence=JSON.parse(fs.readFileSync('.tmp/rea-runtime-scripts.json','utf8')),cache=new Map() function source(base){return evidence.items.find((item)=>item.file_path.endsWith(base))?.source.artifact.text} function ast(base){if(!cache.has(base))cache.set(base,parse(source(base),{sourceType:'module'}));return cache.get(base)} const context='contexts-BMeWSUHk.js',staticValue=(node)=>!node?undefined:node.type==='TemplateLiteral'&&!node.expressions.length?node.quasis[0].value.cooked:node.type==='StringLiteral'||node.type==='NumericLiteral'?node.value:undefined function object(node){return Object.fromEntries(node.properties.filter((prop)=>prop.type==='ObjectProperty').map((prop)=>[prop.key.name??prop.key.value,staticValue(prop.value)]))} let tabs,groups traverse(ast(context),{AssignmentExpression(p){if(p.node.left.name==='DC')tabs=p.node.right.elements.map(object);if(p.node.left.name==='cXe')groups=p.node.right.elements.map(object)}}) const labels={};traverse(ast('zh-cn-Dfzn8myY.js'),{ObjectProperty(p){const key=p.node.key.value;if(typeof key==='string'&&/^(settings\.nav\.|settings\.search\.)/.test(key)){const value=staticValue(p.node.value);if(typeof value==='string')labels[key]=value}}}) const names={settings:'Hee',account:'ute',subscriptionUsage:'Ute',appearance:'qre',personalization:'bne',memory:'Na',extensions:'Une',models:'ModelNavIcon',claw:'ClawSettingsIcon',laboratory:'wre',deviceConnections:'MobileConnectIcon',dataManagement:'Kte',keyboardShortcuts:'Qne',buddyApps:'_ne',securityCenter:'Vte',systemPermissions:'$a',softwareConfig:'ro',helpFeedback:'co',getHelp:'One'} function resolve(base,name,depth=0){ if(depth>8)return null let imported,decl traverse(ast(base),{ImportDeclaration(p){for(const spec of p.node.specifiers)if(spec.local.name===name&&spec.type==='ImportSpecifier')imported={base:p.node.source.value.replace('./',''),member:spec.imported.name}},FunctionDeclaration(p){if(p.node.id?.name===name)decl=p},AssignmentExpression(p){if(p.node.left.name===name)decl=p},VariableDeclarator(p){if(p.node.id?.name===name&&p.node.init)decl=p}}) if(imported&&source(imported.base)){let local;traverse(ast(imported.base),{ExportNamedDeclaration(p){for(const spec of p.node.specifiers)if(spec.exported.name===imported.member)local=spec.local.name}});if(local)return resolve(imported.base,local,depth+1)} if(!decl)return null const right=decl.node.right??decl.node.init if(right?.type==='CallExpression'&&typeof staticValue(right.arguments[0])==='string'&&right.arguments[1]?.type==='Identifier') { let nodes;traverse(ast(base),{AssignmentExpression(p){if(p.node.left.name===right.arguments[1].name&&p.node.right.type==='ArrayExpression')nodes=p.node.right.elements}}) if(nodes){let defaults={};traverse(ast('createLucideIcon-1goKJVIH.js'),{AssignmentExpression(p){if(p.node.left.name==='i'&&p.node.right.type==='ObjectExpression')defaults=object(p.node.right)}});return{props:defaults,children:nodes.map((entry)=>({tag:staticValue(entry.elements[0]),props:object(entry.elements[1])}))}} } if(right?.type==='CallExpression'&&right.arguments[0]?.type==='Identifier')return resolve(base,right.arguments[0].name,depth+1) let svg=null,paths=[],next decl.traverse({CallExpression(p){const tag=p.node.arguments[0];if(tag?.type==='Identifier'){next=tag.name;return}const kind=staticValue(tag);if(!['svg','path','circle','rect','line','polyline','polygon','ellipse'].includes(kind))return;const props={};for(const prop of p.node.arguments[1]?.properties??[]){if(prop.type!=='ObjectProperty')continue;const value=staticValue(prop.value);if(value!==undefined)props[prop.key.name??prop.key.value]=value}if(kind==='svg')svg=props;else paths.push({tag:kind,props})}}) if(svg&&paths.length)return{props:svg,children:paths} return next?resolve(base,next,depth+1):null } const icons={};for(const[id,name]of Object.entries(names)){const svg=resolve(context,name);if(svg)icons[id]=svg} fs.writeFileSync('src/renderer/src/components/source-settings-navigation-reference.ts','// REA '+evidence.evidence_id+'; SettingsNavigation/DC/cXe and source SVG geometry only.\nexport const sourceSettingsTabs = '+JSON.stringify(tabs,null,2)+'\nexport const sourceSettingsGroups = '+JSON.stringify(groups,null,2)+'\nexport const sourceSettingsIcons: Record;children:{tag:string;props:Record}[]}> = '+JSON.stringify(icons,null,2)+'\nconst labels:Record = '+JSON.stringify(labels,null,2)+'\nexport const sourceSettingsLabel=(key:string):string=>labels[key]??key\n') const root=postcss.parse(fs.readFileSync('.tmp/rea-css-recovered/contexts-BkjwYSZT.css','utf8')),css=[] root.walkRules((rule)=>{if(!/\.settings-(?:navigation|search)/.test(rule.selector))return;let copy=rule.clone();copy.selectors=copy.selectors.map((s)=>'.source-settings-navigation '+s);let tree=copy;for(let parent=rule.parent;parent?.type==='atrule';parent=parent.parent){const wrap=parent.clone({nodes:[]});wrap.append(tree);tree=wrap}css.push(tree.toString())}) const variables=new Set();const collect=(text)=>{for(const match of text.matchAll(/var\((--[\w-]+)/g))variables.add(match[1])};collect(css.join(''));const tokenRules=[];postcss.parse(fs.readFileSync('.tmp/rea-css-recovered/tokens-Df-i-zsO.css','utf8')).walkRules((rule)=>tokenRules.push(rule));for(let pass=0;pass<10;pass++)for(const rule of tokenRules)rule.walkDecls((decl)=>{if(variables.has(decl.prop))collect(decl.value)});const light=new Map(),dark=new Map();for(const rule of tokenRules){const target=rule.selector.includes('dark')?dark:rule.selector.includes(':root')?light:null;if(target)rule.walkDecls((decl)=>{if(variables.has(decl.prop))target.set(decl.prop,decl.value)})}const serialize=(map)=>[...map].map(([key,value])=>key+':'+value).join(';');css.unshift('.source-settings-navigation{'+serialize(light)+'}',':root[data-theme=dark] .source-settings-navigation{'+serialize(dark)+'}'); fs.writeFileSync('src/renderer/src/components/source-settings-navigation-recovered.css','/* REA ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94; media conditions retained. */\n'+css.join('\n')+'\n') console.log(JSON.stringify({tabs:tabs.length,groups:groups.length,icons:Object.keys(icons),unknownIcons:Object.keys(names).filter((key)=>!icons[key]),rules:css.length}))