'use strict'; function developerShortcut(input){return input?.type==='keyDown'&&(input.key==='F12'||((input.control||input.meta)&&input.shift&&!input.alt&&['i','j'].includes(String(input.key).toLowerCase())));} function developerAssetRequestAllowed(details,{ready,policy,tabs}={}){ if(!ready||policy?.browser?.allowDevTools!==true||Date.parse(policy.expiresAt)<=Date.now()||!Number.isSafeInteger(details?.webContentsId))return false; let url;try{url=new URL(details.url);}catch{return false;} if(url.protocol!=='devtools:'||url.hostname!=='devtools'||!url.pathname.startsWith('/bundled/')||url.username||url.password)return false; return tabs?.some(tab=>{if(tab.view.webContents.isDestroyed())return false;const frontend=tab.security?.developerFrontend||tab.view.webContents.devToolsWebContents;return frontend&&!frontend.isDestroyed()&&frontend.id===details.webContentsId;})===true; } function createDeveloperToolsGuard({contents,getContext,isCurrent,audit,createFrontend}={}){ if(!contents||[getContext,isCurrent,audit].some(fn=>typeof fn!=='function'))throw TypeError('Native developer-tools callbacks required'); let opening=false,openedState=false,frontend; const disposeFrontend=()=>{const previous=frontend;frontend=null;if(previous&&!previous.isDestroyed())previous.destroy();}; const close=()=>{openedState=false;if(!contents.isDestroyed())contents.closeDevTools();disposeFrontend();}; const allowed=context=>!!context?.ready&&context.foreground===true&&context.policy?.browser?.allowDevTools===true&&Date.parse(context.policy.expiresAt)>Date.now()&&/^https?:\/\//.test(context.url||'')&&!contents.isDestroyed(); async function toggle(){ if(contents.isDestroyed())return; if(openedState||contents.isDevToolsOpened()){close();await audit('devtools.closed');return;} const context=getContext(); if(!allowed(context)||opening){await audit('devtools.denied');return;} opening=true; try{ // Publication and activation changes across audit persistence invalidate this grant. await audit('devtools.open-requested'); if(!allowed(getContext())||!isCurrent(context)){await audit('devtools.denied');return;} if(createFrontend){frontend=createFrontend();contents.setDevToolsWebContents(frontend.webContents);frontend.once('closed',()=>{if(!contents.isDestroyed()&&(openedState||contents.isDevToolsOpened()))contents.closeDevTools();});} contents.openDevTools({mode:'detach',activate:true,title:'S Browser ยท Privileged developer tools'}); }finally{opening=false;} } const opened=()=>{openedState=true;const context=getContext();if(!allowed(context))close();else {frontend?.show();Promise.resolve(audit('devtools.opened')).catch(close);}}; const closed=()=>{openedState=false;disposeFrontend();}; contents.on('devtools-opened',opened); contents.on('devtools-closed',closed); contents.once('destroyed',disposeFrontend); return {handleInput:(event,input)=>{if(!developerShortcut(input))return false;event.preventDefault();toggle().catch(close);return true;},toggle,close,isOpened:()=>openedState,dispose:()=>{contents.removeListener('devtools-opened',opened);contents.removeListener('devtools-closed',closed);close();}}; } module.exports={createDeveloperToolsGuard,developerShortcut,developerAssetRequestAllowed};