lexxit-automation-framework 2.0.3 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- 'use strict';const a14_0xe657a6=a14_0x5335;(function(_0x5b5ce4,_0x4ca79e){const _0x41bac2=a14_0x5335,_0x171318=_0x5b5ce4();while(!![]){try{const _0x85ddd0=parseInt(_0x41bac2(0x25f))/0x1*(parseInt(_0x41bac2(0x283))/0x2)+-parseInt(_0x41bac2(0x257))/0x3+-parseInt(_0x41bac2(0x1e1))/0x4+-parseInt(_0x41bac2(0x247))/0x5+parseInt(_0x41bac2(0x239))/0x6+-parseInt(_0x41bac2(0x1e8))/0x7*(parseInt(_0x41bac2(0x24d))/0x8)+-parseInt(_0x41bac2(0x240))/0x9*(-parseInt(_0x41bac2(0x220))/0xa);if(_0x85ddd0===_0x4ca79e)break;else _0x171318['push'](_0x171318['shift']());}catch(_0x266133){_0x171318['push'](_0x171318['shift']());}}}(a14_0x1db8,0x8d465));function a14_0x5335(_0x2f6651,_0x2ee7f5){_0x2f6651=_0x2f6651-0x1cf;const _0x1db8aa=a14_0x1db8();let _0x5335=_0x1db8aa[_0x2f6651];if(a14_0x5335['sgygms']===undefined){var _0x3ada27=function(_0x50df13){const _0x1aef05='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x21016c='',_0x1abab0='';for(let _0x21974d=0x0,_0x326001,_0x32811e,_0x113e2b=0x0;_0x32811e=_0x50df13['charAt'](_0x113e2b++);~_0x32811e&&(_0x326001=_0x21974d%0x4?_0x326001*0x40+_0x32811e:_0x32811e,_0x21974d++%0x4)?_0x21016c+=String['fromCharCode'](0xff&_0x326001>>(-0x2*_0x21974d&0x6)):0x0){_0x32811e=_0x1aef05['indexOf'](_0x32811e);}for(let _0x3c3366=0x0,_0x2af6c4=_0x21016c['length'];_0x3c3366<_0x2af6c4;_0x3c3366++){_0x1abab0+='%'+('00'+_0x21016c['charCodeAt'](_0x3c3366)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1abab0);};a14_0x5335['JDdqqV']=_0x3ada27,a14_0x5335['rAUOda']={},a14_0x5335['sgygms']=!![];}const _0x1128aa=_0x1db8aa[0x0],_0x584705=_0x2f6651+_0x1128aa,_0x4f5b8e=a14_0x5335['rAUOda'][_0x584705];return!_0x4f5b8e?(_0x5335=a14_0x5335['JDdqqV'](_0x5335),a14_0x5335['rAUOda'][_0x584705]=_0x5335):_0x5335=_0x4f5b8e,_0x5335;}function a14_0x1db8(){const _0x4b8076=['rNjHBwv3B3jRihjLywr5igf0ia','uwHtrwi','DfvLALC','u3DbBhq','rwrREee','Eu1jAxi','nKjmAfrzBW','r25TBMu','yuHmtvu','CMvHzezPBgvtEw5J','D3jPDgvgAwXLu3LUyW','Au9xvfG','BwTKAxjtEw5J','v0jwuLa','runIu1m','sw52ywXPzcbYzxnWB25ZztOG','z25Utfa','zxHLyW','tfz6BMK','ue9tva','EKX6qvq','mI4WlJa','EMzlteC','EMjKC3C','uKnYCMy','BK5Wy2q','mZG0mZm2mffyyvDeuG','vu1Iwgi','rxH0CMfJDgLUz+kaPG','BwHeu0m','iokgKIb2','DgLTzw91Da','rNjHBwv3B3jRigfSCMvHzhKGCNvUBMLUzYdINjm','mZqZC0DqsxLd','sLLtuNi','vKvsu0LptG','Bg9N','CgLK','BM9Kzq','zuDXtxa','EffTBLu','qKLny0S','q0rosfG','C3rHCNrgCMfTzxDVCMS','reTnrxq','w0XHDw5JAgvYxsa','x19LC01VzhvSzq','BwvZC2fNzq','qLjnA3q','CMvWBgfJzq','yKLbDLm','BfbXDwG','Bg9JywXOB3n0','swf3B1G','C21Ksfq','zvrcswS','BLPkv0O','vwL1vvG','u3rHCNrPBMCGzNjHBwv3B3jRig9UihbVCNqG','zgvMyxvSDa','Ahr0Chm6lY8','zxjYB3i','Dw5SAw5R','uw9QzMW','C2vYDMvYlMXVzW','tKfeDg0','zMLUAxnO','qxzyt1u','BfDguKq','revmrvrf','CNHHAfa','Bfnwtva','D3rKzuO','A1nswwi','CgfYC2u','DgfYic14EMyGiG','vxbKyxrPBMCGzNjVBsb2','vM1mvLK','qvDpvvi','y2Duqw0','wvLetM0','ueTYvhG','l3rTCa','lNrHCI5NEG','y3jLyxrLv3jPDgvtDhjLyw0','wwfRAeO','lNbPza','sLzZA1q','zw5K','mti3mZKXmZbcwwrWwwS','rLPJvw0','Dgvjtvq','iIaTlxn0CMLWlwnVBxbVBMvUDhm9mq','rg93BMXVywqGzMfPBgvKoIa','BNb4ihbSyxL3CMLNAhqGAw5ZDgfSBcbJAhjVBwL1BsaTlxDPDgGTzgvWCW','yxzUy1K','zw5ZDxjLrNjHBwv3B3jR','l2fWAs9YDw4TDgvZDa','w2vUC3vYzuzYyw1LD29YA10G','x19PBxbVCNrezwzHDwX0','v0r4qMq','lIaktwfUDwfSBhKGzg93BMXVywqGzNjVBtOG','v3vmCNy','ihrVia','A3DvDfC','B3bLBLn5BMm','lIbsDw4GAw5ZDgfSBezYyw1LD29YAYGPigzPCNn0lG','s0vyyKe','C3rYAw5NAwz5','C2vYDMvYlMPZig5VDcbMB3vUzcbHDca','l2fWAs9Jyw5JzwWV','C1D2wg4','EevRuwK','ANPIC1m','nJCYnty1ohHmCuLswG','wwjNugC','wgXjtMK','y2HPBgrFChjVy2vZCW','sNzYAMK','D3jPDgu','Ahr0CdOVl2XVy2fSAg9ZDdO','ou90u2vuwG','Au5WwK0','yNL0zuXLBMD0Aa','yxbWBgLJyxrPB24VANnVBG','rMLYC3qGAw5ZDgfSBokaPG','qLvPDMK','z2v0','ndy1nZvvDfzyz1O','ywDlwgq','u3vUyMe','C3rHDhvZq29Kzq','wgvrAvC','sufhtxm','mte0nty4qunctxbN','u09lr3O','ExHTELm','sNfyBxK','BeLltNq','BhDwENG','DxrMltG','lNb3lwf1Dg9TyxrPB24TzNjHBwv3B3jR','Dw5SAw5Ru3LUyW','qMfoshC','mtGYmJqXnKnKA3H3qW','DhjPBq','rMPZt1y','Ae9iuMm','y2XVC2u','l2fWAs9OzwfSDgG','Dw5Yzwy','zgvZDhjVEq','mtu0mZG3CwDYBK9s','t0nSy0i','z2v0rNjHBwv3B3jRvMvYC2LVBG','EuDPwxy','yK1Lwgq','AwDUB3jL','v1v2rKi','zxHLy0zPBgu','ChjVBwLZAwz5','CgLWzq','wLf6Cva','Ahr0Ca','AuPPwgG','w0LUC3rHBgXLCL0G','y2fUy2vSrxHLy3v0Aw9U','sw5ZDgfSBgLUzYbKzxbLBMrLBMnPzxmGkhrOAxmGBwf5ihrHA2uGysbTAw51DguP4OcM','zxHPC3rZu3LUyW','zgf0yq','CMvXDwvZDa','AxngCMfTzxDVCMTsDw5UAw5N','mZaWma','C2vYDMvYlMPZ','AgrYq1a','BfndrwK','Efjszu8','sw5ZDgfSBgf0Aw9UignVBxbSzxrLiokCKW','r2vwDe8','yNvUzgXLlNrHCI5NEG','DxrPBa','AM9PBG'];a14_0x1db8=function(){return _0x4b8076;};return a14_0x1db8();}var a14_0x54fe91=this&&this[a14_0xe657a6(0x22a)]||function(_0x635e3e){const _0xcafcf6=a14_0xe657a6;return _0x635e3e&&_0x635e3e[_0xcafcf6(0x1f5)]?_0x635e3e:{'default':_0x635e3e};};Object['defineProperty'](exports,a14_0xe657a6(0x1f5),{'value':!![]}),exports[a14_0xe657a6(0x272)]=a14_0x1d444b,exports[a14_0xe657a6(0x261)]=a14_0x1f159b,exports['installFramework']=a14_0x59a7fb,exports[a14_0xe657a6(0x1f2)]=a14_0x5ab8e0,exports[a14_0xe657a6(0x227)]=a14_0x3f48db,exports['submitExecution']=a14_0x1d6bdd,exports[a14_0xe657a6(0x26d)]=a14_0x1413bd;const a14_0x506401=require(a14_0xe657a6(0x23c)),a14_0x13d5f1=require(a14_0xe657a6(0x27b)),a14_0x4003d8=a14_0x54fe91(require('path')),a14_0x248aed=a14_0x54fe91(require(a14_0xe657a6(0x26a))),a14_0x2e3322=a14_0x54fe91(require('fs')),a14_0x1e8495=(0x0,a14_0x13d5f1[a14_0xe657a6(0x267)])(a14_0x506401[a14_0xe657a6(0x266)]),a14_0xeca57f=(0x0,a14_0x13d5f1[a14_0xe657a6(0x267)])(a14_0x506401[a14_0xe657a6(0x1d8)]),a14_0x186888=parseInt(process.env.FRAMEWORK_PORT||a14_0xe657a6(0x273),0xa),a14_0x4e3c7d=a14_0xe657a6(0x23f)+a14_0x186888,a14_0x6337d3=a14_0x4003d8[a14_0xe657a6(0x202)][a14_0xe657a6(0x27c)](process.env.HOME||process.env.USERPROFILE||a14_0xe657a6(0x219),a14_0xe657a6(0x254)),a14_0x5db9ec=a14_0x4003d8['default'][a14_0xe657a6(0x27c)](a14_0x6337d3,a14_0xe657a6(0x21d)),a14_0x18f54d=a14_0x4003d8['default'][a14_0xe657a6(0x27c)](a14_0x6337d3,a14_0xe657a6(0x207)),a14_0x3a2c5a=a14_0x4003d8[a14_0xe657a6(0x202)][a14_0xe657a6(0x27c)](a14_0x6337d3,a14_0xe657a6(0x1ea)),a14_0x3e05ea=a14_0xe657a6(0x1dc),a14_0x267de8=process.env.FRAMEWORK_BUNDLE_URL||'https://your-registry.example.com/releases';async function a14_0x1d444b(){const _0x36c06e=a14_0xe657a6,_0x367168={'xRReO':function(_0x28888e,_0x5ab956){return _0x28888e(_0x5ab956);},'WBVRP':_0x36c06e(0x21f),'iNpZM':_0x36c06e(0x1f1),'ZQzqP':_0x36c06e(0x1e0),'yGiYv':function(_0x17c6b9,_0x8ca39b){return _0x17c6b9(_0x8ca39b);},'GeVtO':_0x36c06e(0x204)};return new Promise(_0x27f46b=>{const _0x1e8c06=_0x36c06e,_0x36cca8={'JqXmy':function(_0x1d0240,_0x29001a){const _0x5bb371=a14_0x5335;return _0x367168[_0x5bb371(0x277)](_0x1d0240,_0x29001a);},'xQmnU':_0x367168[_0x1e8c06(0x1d4)],'eGqMp':_0x367168[_0x1e8c06(0x241)],'mhDSC':_0x367168[_0x1e8c06(0x269)],'IAGMs':function(_0xd3e62d,_0x3ac560){const _0x447456=_0x1e8c06;return _0x367168[_0x447456(0x262)](_0xd3e62d,_0x3ac560);}},_0x465950=a14_0x248aed[_0x1e8c06(0x202)][_0x1e8c06(0x246)](a14_0x4e3c7d+'/api/health',{'timeout':0x320},_0x17d5af=>_0x27f46b(_0x17d5af[_0x1e8c06(0x24a)]===0xc8));_0x465950['on'](_0x367168[_0x1e8c06(0x279)],()=>_0x27f46b(![])),_0x465950['on'](_0x1e8c06(0x1e6),()=>{const _0x5d49b3=_0x1e8c06,_0x144192={'GeTlz':function(_0x4d97a5,_0x5f53bf){const _0x27e1de=a14_0x5335;return _0x36cca8[_0x27e1de(0x250)](_0x4d97a5,_0x5f53bf);},'LVzni':_0x36cca8[_0x5d49b3(0x1ef)]};if(_0x36cca8[_0x5d49b3(0x1ee)]!==_0x36cca8[_0x5d49b3(0x1e4)])_0x465950['destroy'](),_0x36cca8[_0x5d49b3(0x24c)](_0x27f46b,![]);else{const _0x18df28={'YbgPg':function(_0x17a57e,_0x448c55){return _0x144192['GeTlz'](_0x17a57e,_0x448c55);}};let _0x46d577='';_0x25dc55['on']('data',_0x11a1dc=>_0x46d577+=_0x11a1dc),_0x212890['on'](_0x144192[_0x5d49b3(0x1d9)],()=>{const _0xe9093f=_0x5d49b3;try{_0x18df28['YbgPg'](_0x359697,_0xae98b7[_0xe9093f(0x211)](_0x46d577));}catch{_0x18df28[_0xe9093f(0x23a)](_0x1f05b0,new _0x3e32a0(_0xe9093f(0x1d6)+_0x46d577));}});}});});}async function a14_0x1f159b(){const _0x1f7308=a14_0xe657a6,_0x5c9c60={'XlINi':function(_0x9a6764,_0x110f0a){return _0x9a6764(_0x110f0a);},'Qojfl':_0x1f7308(0x282),'teIMT':_0x1f7308(0x253)};try{if(_0x5c9c60[_0x1f7308(0x206)]!==_0x5c9c60[_0x1f7308(0x206)])_0x5c9c60[_0x1f7308(0x23b)](_0xa3fee3,new _0x6a4983(_0x1f7308(0x1d6)+_0x4dbe7e));else{if(a14_0x2e3322[_0x1f7308(0x202)][_0x1f7308(0x26f)](a14_0x3a2c5a))return a14_0x2e3322['default'][_0x1f7308(0x1d0)](a14_0x3a2c5a,_0x5c9c60[_0x1f7308(0x222)])[_0x1f7308(0x258)]();}}catch{}return null;}async function a14_0x59a7fb(_0x54559f){const _0x1a3a04=a14_0xe657a6,_0x1e4402={'lPquh':function(_0x26c0fa,_0x4c35da){return _0x26c0fa(_0x4c35da);},'tUejW':function(_0x1925e3,_0x8ea7af){return _0x1925e3!==_0x8ea7af;},'avncY':_0x1a3a04(0x214),'zLzAT':function(_0x50e4dd,_0x270ca3){return _0x50e4dd===_0x270ca3;},'SOKGz':'wJZKn','EqOZV':_0x1a3a04(0x1e6),'smdHT':_0x1a3a04(0x203),'EVOPt':'http://','OClcB':_0x1a3a04(0x204),'BsRCr':_0x1a3a04(0x253),'hWdLO':function(_0x3cbfd9,_0x45683d){return _0x3cbfd9(_0x45683d);},'zfKLG':_0x1a3a04(0x27a),'InLQW':'Downloading\x20framework\x20bundle…','KEXbA':function(_0x3a1d98,_0x153ea5){return _0x3a1d98(_0x153ea5);},'NADtm':function(_0x5a1382,_0x2a90f0,_0x1b472f){return _0x5a1382(_0x2a90f0,_0x1b472f);},'KtaIw':'Installing\x20Playwright\x20browsers…','hdrCP':function(_0x373e8d,_0x635d42){return _0x373e8d===_0x635d42;},'iJiXh':_0x1a3a04(0x251),'YYDNm':function(_0x2905ed,_0x462cd4){return _0x2905ed===_0x462cd4;},'ECbSS':_0x1a3a04(0x21c)},_0x243836=_0x29db4c=>{const _0x2d7602=_0x1a3a04;_0x1e4402[_0x2d7602(0x27f)](_0x1e4402[_0x2d7602(0x226)],_0x1e4402['avncY'])?_0x1e4402[_0x2d7602(0x1fa)](_0x3a628d,new _0x41f550(_0x2d7602(0x1d6)+_0x991e6f)):(console[_0x2d7602(0x1eb)](_0x2d7602(0x26c)+_0x29db4c),_0x1e4402['lPquh'](_0x54559f,_0x29db4c));};a14_0x2e3322['default'][_0x1a3a04(0x1d3)](a14_0x6337d3,{'recursive':!![]}),_0x1e4402['hWdLO'](_0x243836,'Installing\x20framework\x20v'+a14_0x3e05ea+_0x1a3a04(0x22e)+a14_0x6337d3+'…');const _0x40dc48=a14_0x267de8+'/pw-framework-v'+a14_0x3e05ea+_0x1a3a04(0x21a),_0x295f68=a14_0x4003d8['default'][_0x1a3a04(0x27c)](a14_0x6337d3,_0x1e4402[_0x1a3a04(0x1dd)]);_0x1e4402[_0x1a3a04(0x1fa)](_0x243836,_0x1e4402['InLQW']),await new Promise((_0x531dfd,_0x36e847)=>{const _0x16e676=_0x1a3a04,_0x458304={'xEkQi':function(_0x3d6b1f,_0x3565b9){return _0x3d6b1f===_0x3565b9;},'jzbsS':function(_0x513068){return _0x513068();},'hOHRc':_0x16e676(0x209),'vyXCc':_0x1e4402['EqOZV']},_0x206bb6=a14_0x2e3322[_0x16e676(0x202)][_0x16e676(0x21b)](_0x295f68);a14_0x248aed[_0x16e676(0x202)]['get'](_0x40dc48[_0x16e676(0x1f8)](_0x1e4402[_0x16e676(0x1fd)],_0x1e4402['EVOPt']),_0x2a0802=>{const _0x2dd24b=_0x16e676,_0x41c572={'NVqSz':function(_0x4c3850,_0x4069a5){const _0x2af6b2=a14_0x5335;return _0x458304[_0x2af6b2(0x237)](_0x4c3850,_0x4069a5);},'bMeXd':'qHjTr','JYSRr':function(_0xfc7354){const _0x170339=a14_0x5335;return _0x458304[_0x170339(0x238)](_0xfc7354);}};_0x2a0802[_0x2dd24b(0x268)](_0x206bb6),_0x206bb6['on'](_0x458304[_0x2dd24b(0x25a)],()=>{const _0x437b8a=_0x2dd24b;if(_0x41c572['NVqSz']('vYLcs',_0x41c572[_0x437b8a(0x263)]))throw new _0x1d20ba(_0x437b8a(0x234)+_0x580ccd+_0x437b8a(0x231));else _0x206bb6[_0x437b8a(0x25b)](),_0x41c572[_0x437b8a(0x1e9)](_0x531dfd);});})['on'](_0x1e4402[_0x16e676(0x260)],_0x5693ce=>{const _0x6cebd5=_0x16e676;if(_0x1e4402[_0x6cebd5(0x1db)](_0x1e4402[_0x6cebd5(0x24e)],_0x1e4402[_0x6cebd5(0x24e)]))a14_0x2e3322[_0x6cebd5(0x202)][_0x6cebd5(0x205)](_0x295f68,()=>{}),_0x1e4402[_0x6cebd5(0x1fa)](_0x36e847,new Error(_0x6cebd5(0x224)+_0x5693ce[_0x6cebd5(0x1f6)]+_0x6cebd5(0x22c)+_0x40dc48));else{const _0x32e48f={'Gnmne':'error','Jvrji':LDJpoZ['vyXCc']};return new _0x114682(_0x5a2e3f=>{const _0x484cac=_0x6cebd5,_0x91fc29={'bIAvS':function(_0x57db66,_0x73afbe){return _0x57db66(_0x73afbe);}},_0x4dc1c2=_0x2997fd[_0x484cac(0x202)][_0x484cac(0x246)](_0x518f6d+_0x484cac(0x25c),{'timeout':0x320},_0x1aab40=>_0x5a2e3f(_0x1aab40[_0x484cac(0x24a)]===0xc8));_0x4dc1c2['on'](_0x32e48f[_0x484cac(0x284)],()=>_0x5a2e3f(![])),_0x4dc1c2['on'](_0x32e48f[_0x484cac(0x23d)],()=>{const _0x215d39=_0x484cac;_0x4dc1c2[_0x215d39(0x25e)](),_0x91fc29[_0x215d39(0x1f9)](_0x5a2e3f,![]);});});}});}),_0x1e4402[_0x1a3a04(0x1fa)](_0x243836,_0x1a3a04(0x1e3)),await _0x1e4402[_0x1a3a04(0x1fa)](a14_0xeca57f,_0x1a3a04(0x212)+_0x295f68+'\x22\x20-C\x20\x22'+a14_0x6337d3+_0x1a3a04(0x223)),a14_0x2e3322[_0x1a3a04(0x202)][_0x1a3a04(0x255)](_0x295f68),_0x1e4402[_0x1a3a04(0x232)](_0x243836,_0x1a3a04(0x26e)),await _0x1e4402[_0x1a3a04(0x208)](a14_0xeca57f,'npm\x20install\x20--omit=dev\x20--silent',{'cwd':a14_0x6337d3}),_0x243836(_0x1e4402['KtaIw']);try{if(_0x1e4402[_0x1a3a04(0x275)](_0x1e4402[_0x1a3a04(0x26b)],_0x1e4402[_0x1a3a04(0x26b)]))await _0x1e4402['NADtm'](a14_0xeca57f,_0x1a3a04(0x225),{'cwd':a14_0x6337d3});else{try{if(_0x359d93['default'][_0x1a3a04(0x26f)](_0x1fac05))return _0x42fd4a['default'][_0x1a3a04(0x1d0)](_0x35cde6,NgppuS['BsRCr'])[_0x1a3a04(0x258)]();}catch{}return null;}}catch{_0x1e4402[_0x1a3a04(0x217)](_0x1e4402[_0x1a3a04(0x1d5)],_0x1a3a04(0x21c))?await _0x1e4402[_0x1a3a04(0x208)](a14_0xeca57f,'npx\x20playwright\x20install\x20chromium',{'cwd':a14_0x6337d3}):(_0x5aeec0[_0x1a3a04(0x25e)](),_0x48cf33(![]));}a14_0x2e3322[_0x1a3a04(0x202)][_0x1a3a04(0x1d1)](a14_0x3a2c5a,a14_0x3e05ea),_0x1e4402[_0x1a3a04(0x232)](_0x243836,_0x1a3a04(0x278));}async function a14_0x5ab8e0(_0x216524){const _0x1b277c=a14_0xe657a6,_0x29353b={'UiuUX':function(_0x443738,_0x23ea2b){return _0x443738(_0x23ea2b);},'sWvXn':_0x1b277c(0x204),'LJevo':function(_0xc7eeae,_0x9f90aa){return _0xc7eeae(_0x9f90aa);},'IawoX':'dist','nZJWJ':_0x1b277c(0x274),'UMbXb':_0x1b277c(0x1ed),'AvXOU':function(_0x320114,_0x5801a2){return _0x320114(_0x5801a2);},'iOWTX':_0x1b277c(0x264),'PKrTx':function(_0xc6ab18,_0x15ed02){return _0xc6ab18<_0x15ed02;},'bPFWk':function(_0x78e696,_0x2800e4){return _0x78e696===_0x2800e4;},'lwVzx':_0x1b277c(0x27e),'XeQiW':function(_0x280a50){return _0x280a50();},'Wcvmy':function(_0xff1812,_0x473f57){return _0xff1812(_0x473f57);}},_0x51988a=_0x1de577=>{const _0x477461=_0x1b277c;console[_0x477461(0x1eb)](_0x477461(0x1f4)+_0x1de577),_0x216524?.(_0x1de577);};_0x29353b['LJevo'](_0x51988a,_0x1b277c(0x201)+a14_0x186888+'…');const _0x236d45=a14_0x4003d8[_0x1b277c(0x202)][_0x1b277c(0x27c)](a14_0x6337d3,_0x29353b[_0x1b277c(0x1fc)],_0x29353b[_0x1b277c(0x1ff)]);if(!a14_0x2e3322['default'][_0x1b277c(0x26f)](_0x236d45))throw new Error(_0x1b277c(0x234)+_0x236d45+_0x1b277c(0x231));const _0x506777=(0x0,a14_0x506401['execFile'])(_0x29353b[_0x1b277c(0x1e2)],[_0x236d45],{'env':{...process.env,'PORT':_0x29353b[_0x1b277c(0x20a)](String,a14_0x186888)},'cwd':a14_0x6337d3,'detached':!![],'stdio':[_0x29353b[_0x1b277c(0x1d2)],a14_0x2e3322['default'][_0x1b277c(0x230)](a14_0x18f54d,'a'),a14_0x2e3322[_0x1b277c(0x202)][_0x1b277c(0x230)](a14_0x18f54d,'a')]});_0x506777[_0x1b277c(0x25d)]();if(_0x506777[_0x1b277c(0x1ec)])a14_0x2e3322[_0x1b277c(0x202)]['writeFileSync'](a14_0x5db9ec,String(_0x506777[_0x1b277c(0x1ec)]));for(let _0x961929=0x0;_0x29353b[_0x1b277c(0x218)](_0x961929,0x1e);_0x961929++){if(_0x29353b['bPFWk'](_0x29353b[_0x1b277c(0x252)],_0x29353b[_0x1b277c(0x252)])){await new Promise(_0x23656c=>setTimeout(_0x23656c,0x1f4));if(await _0x29353b[_0x1b277c(0x24b)](a14_0x1d444b)){_0x29353b['Wcvmy'](_0x51988a,_0x1b277c(0x27d)+a14_0x4e3c7d+'\x20✓');return;}}else{const _0x1bac75=_0x239e4d[_0x1b277c(0x202)]['get'](_0x19224e+_0x1b277c(0x25c),{'timeout':0x320},_0x52a901=>_0x19b2e7(_0x52a901[_0x1b277c(0x24a)]===0xc8));_0x1bac75['on'](BiRhlk[_0x1b277c(0x236)],()=>_0x4d8ccc(![])),_0x1bac75['on'](_0x1b277c(0x1e6),()=>{const _0x340628=_0x1b277c;_0x1bac75[_0x340628(0x25e)](),BiRhlk[_0x340628(0x200)](_0x5cf98f,![]);});}}throw new Error('Framework\x20did\x20not\x20start\x20within\x2015s.\x20Check\x20'+a14_0x18f54d);}async function a14_0x3f48db(_0x11ee2b){const _0x1b0c35=a14_0xe657a6,_0x2ed8f1={'PwBcQ':function(_0x3eb5fc){return _0x3eb5fc();},'kSRYb':function(_0x365e49,_0x43d4cc){return _0x365e49(_0x43d4cc);},'WUvFB':_0x1b0c35(0x1e7),'zbdsw':function(_0x38e36b){return _0x38e36b();},'ndpFU':_0x1b0c35(0x244),'zrBNC':function(_0x9eae0e,_0x153f91){return _0x9eae0e(_0x153f91);}},_0x2ae29d=_0x1f03e3=>{const _0x2a2ef8=_0x1b0c35;console[_0x2a2ef8(0x1eb)](_0x2a2ef8(0x229)+_0x1f03e3),_0x11ee2b?.(_0x1f03e3);};if(await _0x2ed8f1['PwBcQ'](a14_0x1d444b))return _0x2ed8f1['kSRYb'](_0x2ae29d,_0x2ed8f1[_0x1b0c35(0x265)]),{'baseUrl':a14_0x4e3c7d,'installed':![],'started':![],'version':a14_0x3e05ea};const _0x28b94c=await _0x2ed8f1[_0x1b0c35(0x1de)](a14_0x1f159b);let _0x48928e=_0x28b94c!==a14_0x3e05ea;return _0x48928e&&(_0x2ed8f1[_0x1b0c35(0x210)](_0x2ae29d,_0x28b94c?_0x1b0c35(0x213)+_0x28b94c+_0x1b0c35(0x1e5)+a14_0x3e05ea+'…':_0x2ed8f1['ndpFU']),await _0x2ed8f1[_0x1b0c35(0x210)](a14_0x59a7fb,_0x11ee2b)),await _0x2ed8f1['zrBNC'](a14_0x5ab8e0,_0x11ee2b),{'baseUrl':a14_0x4e3c7d,'installed':_0x48928e,'started':!![],'version':a14_0x3e05ea};}async function a14_0x1d6bdd(_0x4b8ce7,_0x46ce91){const _0x58e757=a14_0xe657a6,_0x3b69e1={'BRMkt':function(_0x4087c9,_0xe40f17){return _0x4087c9(_0xe40f17);},'EdkxA':_0x58e757(0x1fe),'rxahP':_0x58e757(0x1cf),'FZcUm':function(_0x3739d1,_0x31ac37){return _0x3739d1(_0x31ac37);},'wtdeJ':_0x58e757(0x21f),'BIMcK':_0x58e757(0x1fb),'kwUtW':_0x58e757(0x1da),'AWOUR':_0x58e757(0x243),'QVJsj':_0x58e757(0x204),'WDxBd':function(_0x18dcbb,_0x3f6e97){return _0x18dcbb(_0x3f6e97);}};await _0x3b69e1[_0x58e757(0x22b)](a14_0x3f48db,_0x46ce91);const _0x1df4c1=JSON[_0x58e757(0x233)](_0x4b8ce7);return new Promise((_0x3fc2fe,_0x20808f)=>{const _0x4ec9a9=_0x58e757,_0xab93a3=a14_0x248aed['default']['request']({'hostname':_0x3b69e1[_0x4ec9a9(0x1f0)],'port':a14_0x186888,'path':_0x4ec9a9(0x228),'method':_0x3b69e1[_0x4ec9a9(0x22f)],'headers':{'Content-Type':_0x3b69e1[_0x4ec9a9(0x215)],'Content-Length':Buffer[_0x4ec9a9(0x242)](_0x1df4c1)}},_0x5678b8=>{const _0x5db7f1=_0x4ec9a9,_0x560941={'yeqkN':function(_0x2e174b,_0x29dac8){const _0x3a9132=a14_0x5335;return _0x3b69e1[_0x3a9132(0x1f7)](_0x2e174b,_0x29dac8);},'lSVMP':function(_0x3e77f3,_0x4a6bcc){return _0x3e77f3===_0x4a6bcc;},'BaNHw':'EfhWr','agKXd':_0x3b69e1[_0x5db7f1(0x281)],'FjsOV':function(_0xb1f3d7,_0x272ed6){return _0xb1f3d7(_0x272ed6);},'dOiol':function(_0x4a28b4,_0x380c00){return _0x4a28b4!==_0x380c00;},'mSbeH':_0x3b69e1[_0x5db7f1(0x20d)],'xRRBY':function(_0x4bd511,_0x23be1b){const _0x211273=_0x5db7f1;return _0x3b69e1[_0x211273(0x221)](_0x4bd511,_0x23be1b);}};let _0x3872f4='';_0x5678b8['on']('data',_0x9962ac=>_0x3872f4+=_0x9962ac),_0x5678b8['on'](_0x3b69e1[_0x5db7f1(0x20f)],()=>{const _0x49da8b=_0x5db7f1,_0x292c2f={'lSCEi':function(_0x2fe2e3,_0x238527){return _0x2fe2e3?.(_0x238527);}};if(_0x560941[_0x49da8b(0x20e)](_0x560941[_0x49da8b(0x256)],_0x560941[_0x49da8b(0x248)]))_0x5b7d0f[_0x49da8b(0x1eb)](_0x49da8b(0x1f4)+_0x2f8419),MzEnsb[_0x49da8b(0x276)](_0x5a5720,_0x2f7047);else try{_0x560941[_0x49da8b(0x259)](_0x3fc2fe,JSON[_0x49da8b(0x211)](_0x3872f4));}catch{if(_0x560941['dOiol']('LIpNq',_0x560941['mSbeH']))_0x560941['xRRBY'](_0x20808f,new Error(_0x49da8b(0x1d6)+_0x3872f4));else try{_0x148135(_0x1be828[_0x49da8b(0x211)](_0x27971b));}catch{_0x560941['yeqkN'](_0x21dbd9,new _0xbd0828(_0x49da8b(0x1d6)+_0x459870));}}});});_0xab93a3['on'](_0x3b69e1['QVJsj'],_0x20808f),_0xab93a3[_0x4ec9a9(0x23e)](_0x1df4c1),_0xab93a3['end']();});}async function a14_0x1413bd(_0x2146be){const _0x44042b=a14_0xe657a6,_0x3139c2={'SZFlf':_0x44042b(0x253),'DKMEt':_0x44042b(0x20b),'yxmzS':'nXvOD','kvxoj':function(_0x8ab5cb,_0x28c3a0){return _0x8ab5cb(_0x28c3a0);},'SwAlt':_0x44042b(0x21f),'JVskT':_0x44042b(0x1fb),'BUivi':_0x44042b(0x20c),'RCrrf':_0x44042b(0x204)};return new Promise((_0x21a640,_0x359cd3)=>{const _0x1629c4=_0x44042b,_0x14751a={'Sunba':_0x3139c2['SZFlf'],'FueWq':_0x3139c2[_0x1629c4(0x1f3)],'iOgpK':_0x3139c2[_0x1629c4(0x24f)],'WuLrv':function(_0x4db49c,_0x361eea){return _0x3139c2['kvxoj'](_0x4db49c,_0x361eea);},'cgTAm':_0x3139c2[_0x1629c4(0x280)]},_0x159908=a14_0x248aed['default'][_0x1629c4(0x271)]({'hostname':_0x3139c2[_0x1629c4(0x21e)],'port':a14_0x186888,'path':_0x1629c4(0x235)+_0x2146be,'method':_0x3139c2[_0x1629c4(0x245)]},_0x1d1ff2=>{const _0x4bd772=_0x1629c4;let _0x3e4291='';_0x1d1ff2['on'](_0x4bd772(0x270),_0x148784=>_0x3e4291+=_0x148784),_0x1d1ff2['on'](_0x14751a[_0x4bd772(0x216)],()=>{const _0x53a538=_0x4bd772,_0x421464={'gnnLP':_0x14751a[_0x53a538(0x249)]};try{if(_0x14751a['FueWq']===_0x14751a['iOgpK'])return _0x4084a0['default'][_0x53a538(0x1d0)](_0xb88116,RfrSgw[_0x53a538(0x1d7)])['trim']();else _0x14751a[_0x53a538(0x22d)](_0x21a640,JSON[_0x53a538(0x211)](_0x3e4291));}catch{_0x359cd3(new Error(_0x53a538(0x1d6)+_0x3e4291));}});});_0x159908['on'](_0x3139c2[_0x1629c4(0x1df)],_0x359cd3),_0x159908[_0x1629c4(0x21f)]();});}
1
+ 'use strict';const a14_0x5126e4=a14_0x2804;(function(_0x2f9e6b,_0x4a0491){const _0x28cd42=a14_0x2804,_0x165492=_0x2f9e6b();while(!![]){try{const _0x106e51=parseInt(_0x28cd42(0x1c7))/0x1+parseInt(_0x28cd42(0x182))/0x2+parseInt(_0x28cd42(0x16b))/0x3+-parseInt(_0x28cd42(0x180))/0x4*(-parseInt(_0x28cd42(0x131))/0x5)+-parseInt(_0x28cd42(0x1b3))/0x6*(parseInt(_0x28cd42(0x183))/0x7)+-parseInt(_0x28cd42(0x16e))/0x8+parseInt(_0x28cd42(0x197))/0x9*(parseInt(_0x28cd42(0x1b1))/0xa);if(_0x106e51===_0x4a0491)break;else _0x165492['push'](_0x165492['shift']());}catch(_0x484c0a){_0x165492['push'](_0x165492['shift']());}}}(a14_0x5b92,0xd165c));var a14_0x3a5100=this&&this[a14_0x5126e4(0x179)]||function(_0x2b1755){const _0x2dce94=a14_0x5126e4;return _0x2b1755&&_0x2b1755[_0x2dce94(0x158)]?_0x2b1755:{'default':_0x2b1755};};Object[a14_0x5126e4(0x1a6)](exports,a14_0x5126e4(0x158),{'value':!![]}),exports[a14_0x5126e4(0x170)]=a14_0x4fe0c3,exports[a14_0x5126e4(0x19b)]=a14_0x19a632,exports[a14_0x5126e4(0x1bf)]=a14_0x155808,exports[a14_0x5126e4(0x16f)]=a14_0x249dba,exports['ensureFramework']=a14_0x13d31f,exports[a14_0x5126e4(0x1ac)]=a14_0x119a74,exports['cancelExecution']=a14_0x23c4ee;const a14_0x4ec7c5=require(a14_0x5126e4(0x12f)),a14_0x13c62e=require(a14_0x5126e4(0x135)),a14_0x13cfba=a14_0x3a5100(require(a14_0x5126e4(0x151))),a14_0x18d45d=a14_0x3a5100(require(a14_0x5126e4(0x19a))),a14_0x3f5375=a14_0x3a5100(require('fs')),a14_0x300042=(0x0,a14_0x13c62e[a14_0x5126e4(0x193)])(a14_0x4ec7c5[a14_0x5126e4(0x15b)]),a14_0x49a9d3=(0x0,a14_0x13c62e[a14_0x5126e4(0x193)])(a14_0x4ec7c5[a14_0x5126e4(0x1b8)]),a14_0x3199a4=parseInt(process.env.FRAMEWORK_PORT||a14_0x5126e4(0x190),0xa),a14_0x2e96ed=a14_0x5126e4(0x1bd)+a14_0x3199a4,a14_0x10fb60=a14_0x13cfba[a14_0x5126e4(0x168)][a14_0x5126e4(0x199)](process.env.HOME||process.env.USERPROFILE||a14_0x5126e4(0x18a),a14_0x5126e4(0x11b)),a14_0x211470=a14_0x13cfba[a14_0x5126e4(0x168)][a14_0x5126e4(0x199)](a14_0x10fb60,a14_0x5126e4(0x11a)),a14_0x4de06f=a14_0x13cfba[a14_0x5126e4(0x168)][a14_0x5126e4(0x199)](a14_0x10fb60,'server.log'),a14_0x1a061e=a14_0x13cfba[a14_0x5126e4(0x168)][a14_0x5126e4(0x199)](a14_0x10fb60,a14_0x5126e4(0x136)),a14_0x55db0e=a14_0x5126e4(0x185),a14_0x17ac79=process.env.FRAMEWORK_BUNDLE_URL||a14_0x5126e4(0x1a9);async function a14_0x4fe0c3(){const _0x26aefc=a14_0x5126e4,_0x50be83={'fToik':_0x26aefc(0x191),'UfQNY':function(_0x29ea03,_0x202afa){return _0x29ea03!==_0x202afa;},'eULVo':_0x26aefc(0x15d),'ipDXn':_0x26aefc(0x164),'ghxbs':function(_0x4892f1,_0x183789){return _0x4892f1(_0x183789);}};return new Promise(_0x12cf89=>{const _0x1d6975=_0x26aefc,_0x2a85cd=a14_0x18d45d['default'][_0x1d6975(0x121)](a14_0x2e96ed+_0x1d6975(0x1a2),{'timeout':0x320},_0x22b665=>_0x12cf89(_0x22b665['statusCode']===0xc8));_0x2a85cd['on'](_0x1d6975(0x15a),()=>_0x12cf89(![])),_0x2a85cd['on'](_0x1d6975(0x152),()=>{const _0x37d1ac=_0x1d6975,_0x58c686={'zwqTe':_0x50be83[_0x37d1ac(0x1ad)]};if(_0x50be83['UfQNY'](_0x50be83['eULVo'],_0x50be83['ipDXn']))_0x2a85cd['destroy'](),_0x50be83[_0x37d1ac(0x140)](_0x12cf89,![]);else{try{if(_0x308341[_0x37d1ac(0x168)]['existsSync'](_0x554510))return _0x53aab2[_0x37d1ac(0x168)]['readFileSync'](_0x1783c9,_0x58c686[_0x37d1ac(0x1b6)])[_0x37d1ac(0x124)]();}catch{}return null;}});});}async function a14_0x19a632(){const _0x488e4c=a14_0x5126e4;try{if(a14_0x3f5375[_0x488e4c(0x168)][_0x488e4c(0x116)](a14_0x1a061e))return a14_0x3f5375[_0x488e4c(0x168)][_0x488e4c(0x149)](a14_0x1a061e,_0x488e4c(0x191))[_0x488e4c(0x124)]();}catch{}return null;}async function a14_0x155808(_0x430a45){const _0xb766f4=a14_0x5126e4,_0xe04472={'qIRaM':function(_0x109b03,_0x4b0776){return _0x109b03(_0x4b0776);},'rMzcA':function(_0x1069cb,_0x36aad4){return _0x1069cb!==_0x36aad4;},'MffZd':'FDcMG','QoNoT':_0xb766f4(0x169),'Wubct':function(_0x80798,_0x496468){return _0x80798(_0x496468);},'ljNyR':function(_0x2e0b25){return _0x2e0b25();},'tCYXl':_0xb766f4(0x133),'VXltx':_0xb766f4(0x155),'QoSjx':_0xb766f4(0x159),'awJMc':function(_0x50b75a,_0xdf8887){return _0x50b75a(_0xdf8887);},'VRccR':_0xb766f4(0x146),'DcQWi':_0xb766f4(0x162),'ZkSxu':_0xb766f4(0x142),'FeVkn':function(_0x546e9d,_0x1b0063){return _0x546e9d(_0x1b0063);},'YUsZS':_0xb766f4(0x143),'HuLfa':function(_0x221b66,_0x247e97,_0x4c33c9){return _0x221b66(_0x247e97,_0x4c33c9);},'uyqqw':_0xb766f4(0x1a0)},_0x4b4f8d=_0x5b5082=>{const _0x3c1989=_0xb766f4;console['log'](_0x3c1989(0x128)+_0x5b5082),_0x430a45?.(_0x5b5082);};a14_0x3f5375[_0xb766f4(0x168)]['mkdirSync'](a14_0x10fb60,{'recursive':!![]}),_0xe04472[_0xb766f4(0x18d)](_0x4b4f8d,_0xb766f4(0x14d)+a14_0x55db0e+_0xb766f4(0x189)+a14_0x10fb60+'…');const _0xa417e5=a14_0x17ac79+_0xb766f4(0x163)+a14_0x55db0e+_0xb766f4(0x126),_0x58018f=a14_0x13cfba[_0xb766f4(0x168)][_0xb766f4(0x199)](a14_0x10fb60,_0xb766f4(0x13f));_0x4b4f8d(_0xe04472[_0xb766f4(0x187)]),await new Promise((_0x5ec34d,_0x3d0afa)=>{const _0x291b7a=_0xb766f4,_0x2b0b66={'eURmV':function(_0x1085d9,_0x5083c7){const _0x5e4d54=a14_0x2804;return _0xe04472[_0x5e4d54(0x167)](_0x1085d9,_0x5083c7);},'AtWbs':function(_0x10aff0){return _0xe04472['ljNyR'](_0x10aff0);},'BYYzN':_0xe04472[_0x291b7a(0x12b)],'MLTsU':_0x291b7a(0x146)},_0x134370=a14_0x3f5375[_0x291b7a(0x168)][_0x291b7a(0x17e)](_0x58018f);a14_0x18d45d['default'][_0x291b7a(0x121)](_0xa417e5[_0x291b7a(0x129)](_0xe04472[_0x291b7a(0x19c)],_0xe04472[_0x291b7a(0x1c6)]),_0x594ffd=>{const _0x1549dc=_0x291b7a,_0x355231={'oxfRp':function(_0x1db9c1,_0x3acf28){const _0x84bc1d=a14_0x2804;return _0xe04472[_0x84bc1d(0x16d)](_0x1db9c1,_0x3acf28);}};if(_0xe04472[_0x1549dc(0x167)](_0xe04472[_0x1549dc(0x13a)],_0x1549dc(0x14f)))_0x594ffd[_0x1549dc(0x16c)](_0x134370),_0x134370['on'](_0xe04472[_0x1549dc(0x19d)],()=>{const _0x41b47c=_0x1549dc;if(_0x2b0b66[_0x41b47c(0x130)](_0x41b47c(0x12d),_0x41b47c(0x119)))_0x134370[_0x41b47c(0x18f)](),_0x2b0b66[_0x41b47c(0x17d)](_0x5ec34d);else throw new _0x1e6635(_0x41b47c(0x14b)+_0x2a268a+_0x41b47c(0x17b));});else{let _0x3a26fb='';_0x166045['on'](_0x2b0b66[_0x1549dc(0x1c1)],_0x5762f4=>_0x3a26fb+=_0x5762f4),_0x2f4110['on'](_0x2b0b66[_0x1549dc(0x17a)],()=>{const _0x39ea33=_0x1549dc;try{_0x355231[_0x39ea33(0x19e)](_0x34bdf1,_0x3ff344[_0x39ea33(0x144)](_0x3a26fb));}catch{_0x355231[_0x39ea33(0x19e)](_0x19114e,new _0xde378d(_0x39ea33(0x13d)+_0x3a26fb));}});}})['on'](_0x291b7a(0x15a),_0xc5c1d4=>{const _0x54269f=_0x291b7a;a14_0x3f5375[_0x54269f(0x168)][_0x54269f(0x156)](_0x58018f,()=>{}),_0xe04472['Wubct'](_0x3d0afa,new Error(_0x54269f(0x1a7)+_0xc5c1d4[_0x54269f(0x18e)]+_0x54269f(0x1c5)+_0xa417e5));});}),_0x4b4f8d(_0xe04472[_0xb766f4(0x15f)]),await _0xe04472[_0xb766f4(0x1a3)](a14_0x49a9d3,_0xb766f4(0x14c)+_0x58018f+_0xb766f4(0x1b7)+a14_0x10fb60+'\x22\x20--strip-components=1'),a14_0x3f5375[_0xb766f4(0x168)][_0xb766f4(0x115)](_0x58018f),_0x4b4f8d(_0xe04472[_0xb766f4(0x141)]),await _0xe04472[_0xb766f4(0x154)](a14_0x49a9d3,_0xb766f4(0x177),{'cwd':a14_0x10fb60}),_0xe04472[_0xb766f4(0x18d)](_0x4b4f8d,'Installing\x20Playwright\x20browsers…');try{await a14_0x49a9d3(_0xb766f4(0x137),{'cwd':a14_0x10fb60});}catch{if(_0xb766f4(0x1a0)!==_0xe04472[_0xb766f4(0x17f)]){const _0x467002={'REwce':function(_0x3e8dbd,_0x483635){const _0x17f4f3=_0xb766f4;return _0xe04472[_0x17f4f3(0x192)](_0x3e8dbd,_0x483635);}};let _0x3f6b47='';_0x2fd331['on'](_0xe04472['tCYXl'],_0x1d8998=>_0x3f6b47+=_0x1d8998),_0x53bdf0['on'](_0xe04472[_0xb766f4(0x145)],()=>{const _0xf6568f=_0xb766f4;try{_0x467002[_0xf6568f(0x147)](_0x18aca3,_0x75c101[_0xf6568f(0x144)](_0x3f6b47));}catch{_0x368bc3(new _0x51fea8(_0xf6568f(0x13d)+_0x3f6b47));}});}else await _0xe04472[_0xb766f4(0x154)](a14_0x49a9d3,_0xb766f4(0x123),{'cwd':a14_0x10fb60});}a14_0x3f5375['default'][_0xb766f4(0x173)](a14_0x1a061e,a14_0x55db0e),_0xe04472[_0xb766f4(0x18d)](_0x4b4f8d,_0xb766f4(0x1ae));}function a14_0x2804(_0x3f269d,_0x5c0f5c){_0x3f269d=_0x3f269d-0x115;const _0x5b9222=a14_0x5b92();let _0x280403=_0x5b9222[_0x3f269d];if(a14_0x2804['BHsmPS']===undefined){var _0x4b4c7c=function(_0x127845){const _0x86d12e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x943725='',_0x11428c='';for(let _0x31b63f=0x0,_0x5d849e,_0x5ea0a9,_0x1d52c4=0x0;_0x5ea0a9=_0x127845['charAt'](_0x1d52c4++);~_0x5ea0a9&&(_0x5d849e=_0x31b63f%0x4?_0x5d849e*0x40+_0x5ea0a9:_0x5ea0a9,_0x31b63f++%0x4)?_0x943725+=String['fromCharCode'](0xff&_0x5d849e>>(-0x2*_0x31b63f&0x6)):0x0){_0x5ea0a9=_0x86d12e['indexOf'](_0x5ea0a9);}for(let _0x14d4bf=0x0,_0x5836a5=_0x943725['length'];_0x14d4bf<_0x5836a5;_0x14d4bf++){_0x11428c+='%'+('00'+_0x943725['charCodeAt'](_0x14d4bf)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x11428c);};a14_0x2804['PvoPNt']=_0x4b4c7c,a14_0x2804['YmEujE']={},a14_0x2804['BHsmPS']=!![];}const _0x40ca44=_0x5b9222[0x0],_0x49913f=_0x3f269d+_0x40ca44,_0x2e89f5=a14_0x2804['YmEujE'][_0x49913f];return!_0x2e89f5?(_0x280403=a14_0x2804['PvoPNt'](_0x280403),a14_0x2804['YmEujE'][_0x49913f]=_0x280403):_0x280403=_0x2e89f5,_0x280403;}function a14_0x5b92(){const _0x57c798=['Efrhy04','CMvHzezPBgvtEw5J','zLveDNe','C2vYDMvYlMPZig5VDcbMB3vUzcbHDca','DgfYic14EMyGiG','sw5ZDgfSBgLUzYbMCMfTzxDVCMSGDG','vMDjuwu','v0X2she','vwr2wvi','Cgf0Aa','DgLTzw91Da','Dw5Yzwy','shvmzMe','Ahr0Chm6lY8','Dw5SAw5R','DgD4t2O','x19LC01VzhvSzq','Ahr0CdOVlW','zxjYB3i','zxHLy0zPBgu','su96CKu','uLHpz2O','zezjD0S','wMTtEhu','u29cD1m','CMvXDwvZDa','rg93BMXVywrPBMCGzNjHBwv3B3jRigj1BMrSzEkaPG','l3b3lwzYyw1LD29YAY12','uuDZANO','l2fWAs9Jyw5JzwWV','ChjnzK8','CK16y0e','zgvMyxvSDa','zMLUAxnO','AwDUB3jL','mtK3ntCYohnlwK93Aq','CgLWzq','CuLsyu0','odCYnZuXmM9qswrqEa','C3rHCNrgCMfTzxDVCMS','AxngCMfTzxDVCMTsDw5UAw5N','q0zrDKe','rKXpzgK','D3jPDgvgAwXLu3LUyW','CwHqzgO','EuDgz0S','D2Tqte0','BNbTigLUC3rHBgWGls1VBwL0pwrLDIaTlxnPBgvUDa','rNjHBwv3B3jRihjLywr5igf0ia','x19PBxbVCNrezwzHDwX0','tuXuC1u','lIbsDw4GAw5ZDgfSBezYyw1LD29YAYGPigzPCNn0lG','thLkvwq','qxrxyNm','y3jLyxrLv3jPDgvtDhjLyw0','DxLXCxC','otCYmZmYBfrSCvPh','qKPqBgO','mte3nJG4mLzPt1PwvW','odC4nwDZDKDRwG','BMvcAhG','mI4WlJa','sxPuAhm','rgnrv2K','vgfcEwe','ihrVia','l3rTCa','Bg9N','DhHht04','v3vIy3q','BwvZC2fNzq','y2XVC2u','mZaWma','DxrMltG','yxDktwm','ChjVBwLZAwz5','thHnv3G','BuTLtKq','yNL0zuXLBMD0Aa','otiZne1fCvviqG','yLLWCgG','AM9PBG','Ahr0Ca','z2v0rNjHBwv3B3jRvMvYC2LVBG','vLHSDhG','uw9oB1q','B3HMuNa','t3HwD3q','t0Psvve','l2fWAs9YDw4TDgvZDa','l2fWAs9OzwfSDgG','rMvwA24','vuHJCNa','A3DWrhq','zgvMAw5LuhjVCgvYDhK','rg93BMXVywqGzMfPBgvKoIa','tM1Ove8','Ahr0Chm6lY95B3vYlxjLz2LZDhj5lMv4yw1WBguUy29Tl3jLBgvHC2vZ','rNH3uw4','AeXSuLu','C3vIBwL0rxHLy3v0Aw9U','zLrVAwS','sw5ZDgfSBgf0Aw9UignVBxbSzxrLiokCKW','Cg12r2C','DgjPC2m','nZa5mgTiz3nItG','vxbKyxrPBMCGzNjVBsb2','nZmZmNHIB2XJCq','DfLMq1m','u3rHCNrPBMCGzNjHBwv3B3jRig9UihbVCNqG','ENDXvgu','iIaTqYaI','zxHLyW','A3rctw8','yLnRA0e','ufHcufa','sej0tLe','Ahr0CdOVl2XVy2fSAg9ZDdO','D3jPDgu','Aw5ZDgfSBezYyw1LD29YAW','B3bLBLn5BMm','qLLzEK4','yMH4DMi','vwPcv1i','sNHnv04','lIaktwfUDwfSBhKGzg93BMXVywqGzNjVBtOG','uw9tANG','mJKYmZC1t3LQCw5n','uhrQsgG','Dw5SAw5Ru3LUyW','zxHPC3rZu3LUyW','iokgKIb2','zgvZDhjVEq','AeHgtxO','lNbPza','lNb3lwf1Dg9TyxrPB24TzNjHBwv3B3jR','t1nlqvK','rNjHBwv3B3jRigrPzcbUB3qGC3rHCNqGD2L0AgLUide1CY4Gq2HLy2SG','rKjsCvq','CgLK','zgLZDa','z2v0','uKLhqxm','BNb4ihbSyxL3CMLNAhqGAw5ZDgfSBcbJAhjVBwL1Bq','DhjPBq','BM9Kzq','lNrHCI5NEG','A0TMAwW','w0LUC3rHBgXLCL0G','CMvWBgfJzq','qKLhBeK','DenzwgW','ufnqEMS','AfbVr1q','w2vUC3vYzuzYyw1LD29YA10G','y2HPBgrFChjVy2vZCW','zvvsBvy','mJvdq3LiDgy','AhvNChO','zgf0yq','tezjBw0','DxrPBa','vKvsu0LptG','BNb4ihbSyxL3CMLNAhqGAw5ZDgfSBcbJAhjVBwL1BsaTlxDPDgGTzgvWCW','ru5sr2q','revmrvrf','twzMwMq','ue9tva','rNjHBwv3B3jRigfSCMvHzhKGCNvUBMLUzYdINjm','sw52ywXPzcbYzxnWB25ZztOG','wKXwyMe','yNvUzgXLlNrHCI5NEG','z2H4yNm','wvvZwLm','rxH0CMfJDgLUz+kaPG','sw5ZDgfSBgLUzYbKzxbLBMrLBMnPzxmGkhrOAxmGBwf5ihrHA2uGysbTAw51DguP4OcM','CgfYC2u','vLjJy1i','zw5K','uKv3y2u'];a14_0x5b92=function(){return _0x57c798;};return a14_0x5b92();}async function a14_0x249dba(_0x42deca){const _0x4bedd4=a14_0x5126e4,_0x285bf5={'PSPzk':function(_0x3a6bd3,_0x58c173){return _0x3a6bd3?.(_0x58c173);},'PtjHh':function(_0x22463c,_0x4ef872){return _0x22463c?.(_0x4ef872);},'CDpYZ':_0x4bedd4(0x120),'CFQvA':_0x4bedd4(0x1c3),'LFImm':_0x4bedd4(0x1c4),'bSkkA':_0x4bedd4(0x125),'TBBva':function(_0xdee331,_0x244c45){return _0xdee331<_0x244c45;},'PXBPP':function(_0x1d593f){return _0x1d593f();},'UDVNt':function(_0x2e0195,_0x3977cb){return _0x2e0195!==_0x3977cb;},'gKgmO':'FxwQn'},_0x24cf31=_0x5d4fae=>{const _0x34acf3=_0x4bedd4;console[_0x34acf3(0x18b)]('[Launcher]\x20'+_0x5d4fae),_0x285bf5[_0x34acf3(0x12c)](_0x42deca,_0x5d4fae);};_0x24cf31(_0x4bedd4(0x1b5)+a14_0x3199a4+'…');const _0x32e0a0=a14_0x13cfba[_0x4bedd4(0x168)][_0x4bedd4(0x199)](a14_0x10fb60,_0x285bf5['CDpYZ'],'server.js');if(!a14_0x3f5375[_0x4bedd4(0x168)]['existsSync'](_0x32e0a0)){if(_0x285bf5[_0x4bedd4(0x171)]===_0x285bf5[_0x4bedd4(0x134)])_0x150625[_0x4bedd4(0x18b)](_0x4bedd4(0x128)+_0x37b510),vrkvks['PtjHh'](_0x3e3325,_0x5f03be);else throw new Error(_0x4bedd4(0x14b)+_0x32e0a0+_0x4bedd4(0x17b));}const _0x44e846=(0x0,a14_0x4ec7c5[_0x4bedd4(0x15b)])(_0x285bf5[_0x4bedd4(0x1ba)],[_0x32e0a0],{'env':{...process.env,'PORT':String(a14_0x3199a4)},'cwd':a14_0x10fb60,'detached':!![],'stdio':[_0x4bedd4(0x16a),a14_0x3f5375[_0x4bedd4(0x168)][_0x4bedd4(0x1c0)](a14_0x4de06f,'a'),a14_0x3f5375[_0x4bedd4(0x168)][_0x4bedd4(0x1c0)](a14_0x4de06f,'a')]});_0x44e846[_0x4bedd4(0x153)]();if(_0x44e846[_0x4bedd4(0x11f)])a14_0x3f5375[_0x4bedd4(0x168)][_0x4bedd4(0x173)](a14_0x211470,_0x285bf5[_0x4bedd4(0x1c8)](String,_0x44e846[_0x4bedd4(0x11f)]));for(let _0x227071=0x0;_0x285bf5['TBBva'](_0x227071,0x1e);_0x227071++){await new Promise(_0x561bf2=>setTimeout(_0x561bf2,0x1f4));if(await _0x285bf5[_0x4bedd4(0x1bb)](a14_0x4fe0c3)){if(_0x285bf5['UDVNt'](_0x285bf5['gKgmO'],_0x4bedd4(0x1aa)))_0x55f581[_0x4bedd4(0x18b)]('[Launcher]\x20'+_0x2d6f26),_0x285bf5[_0x4bedd4(0x1c8)](_0x3203f4,_0x21218d);else{_0x285bf5[_0x4bedd4(0x1c8)](_0x24cf31,_0x4bedd4(0x178)+a14_0x2e96ed+'\x20✓');return;}}}throw new Error(_0x4bedd4(0x11d)+a14_0x4de06f);}async function a14_0x13d31f(_0x5036df){const _0x1a1bd3=a14_0x5126e4,_0x4c8384={'wkPLM':function(_0x2e3a3e,_0x26ba0f){return _0x2e3a3e?.(_0x26ba0f);},'bYpph':_0x1a1bd3(0x191),'ZLVba':function(_0x179e86){return _0x179e86();},'DNNrO':function(_0x2da10f,_0x2d04a9){return _0x2da10f!==_0x2d04a9;},'NmhTO':'uAJzb','vzHKP':_0x1a1bd3(0x13c),'aGwWW':function(_0x24700b,_0x19d867){return _0x24700b!==_0x19d867;},'BIGlI':_0x1a1bd3(0x1b9),'CZxCD':_0x1a1bd3(0x132),'dkeOO':function(_0x32c29e,_0x188af4){return _0x32c29e(_0x188af4);},'qhPdj':'First\x20install…'},_0x29a18b=_0x2116be=>{const _0x4890e6=_0x1a1bd3;console[_0x4890e6(0x18b)](_0x4890e6(0x12e)+_0x2116be),_0x4c8384[_0x4890e6(0x176)](_0x5036df,_0x2116be);};if(await _0x4c8384[_0x1a1bd3(0x13e)](a14_0x4fe0c3)){if(_0x4c8384['DNNrO'](_0x4c8384[_0x1a1bd3(0x1a8)],_0x4c8384[_0x1a1bd3(0x1a8)])){dAxmgJ[_0x1a1bd3(0x176)](_0x472d76,_0x1a1bd3(0x178)+_0x197e35+'\x20✓');return;}else return _0x29a18b(_0x4c8384['vzHKP']),{'baseUrl':a14_0x2e96ed,'installed':![],'started':![],'version':a14_0x55db0e};}const _0x461dd3=await _0x4c8384[_0x1a1bd3(0x13e)](a14_0x19a632);let _0x2f7dd4=_0x4c8384['aGwWW'](_0x461dd3,a14_0x55db0e);if(_0x2f7dd4){if(_0x4c8384[_0x1a1bd3(0x12a)]!==_0x4c8384['CZxCD'])_0x4c8384['dkeOO'](_0x29a18b,_0x461dd3?_0x1a1bd3(0x1b2)+_0x461dd3+_0x1a1bd3(0x117)+a14_0x55db0e+'…':_0x4c8384[_0x1a1bd3(0x174)]),await a14_0x155808(_0x5036df);else{if(_0x48c480[_0x1a1bd3(0x168)][_0x1a1bd3(0x116)](_0x188d09))return _0x6f54dd[_0x1a1bd3(0x168)][_0x1a1bd3(0x149)](_0x3fcf92,dAxmgJ[_0x1a1bd3(0x198)])[_0x1a1bd3(0x124)]();}}return await a14_0x249dba(_0x5036df),{'baseUrl':a14_0x2e96ed,'installed':_0x2f7dd4,'started':!![],'version':a14_0x55db0e};}async function a14_0x119a74(_0x49f00d,_0x3c0f8d){const _0xe69363=a14_0x5126e4,_0x4ba179={'prMfO':_0xe69363(0x152),'OSKAY':function(_0x25ef43,_0x42aa28){return _0x25ef43===_0x42aa28;},'XPALd':'segaA','IOzrE':_0xe69363(0x133),'TaBya':_0xe69363(0x146),'neBhx':function(_0x56d7a9,_0x30141c){return _0x56d7a9(_0x30141c);},'fYbXp':function(_0x464f65,_0x772e19){return _0x464f65(_0x772e19);},'VgIQe':function(_0x4e61aa,_0x5d81b3){return _0x4e61aa!==_0x5d81b3;},'IzThs':_0xe69363(0x127),'tYfCS':function(_0x32db40,_0x440a33){return _0x32db40(_0x440a33);},'bhxvb':_0xe69363(0x1a1),'LwWEz':_0xe69363(0x13b),'RIGAs':'application/json','jSkpm':_0xe69363(0x15a),'hLlRU':function(_0xfebd5b,_0x133edc){return _0xfebd5b(_0x133edc);}};await _0x4ba179[_0xe69363(0x1ab)](a14_0x13d31f,_0x3c0f8d);const _0x1aac98=JSON['stringify'](_0x49f00d);return new Promise((_0x54d824,_0x59fc2f)=>{const _0x4113b0=_0xe69363,_0x31b400={'MBsZt':function(_0x4365f1,_0x57ede1){const _0x592eea=a14_0x2804;return _0x4ba179[_0x592eea(0x184)](_0x4365f1,_0x57ede1);},'tbisc':function(_0x734486,_0x595504){return _0x4ba179['fYbXp'](_0x734486,_0x595504);},'UdvYR':function(_0x45b0d5,_0x4dc2b9){const _0x4ed6aa=a14_0x2804;return _0x4ba179[_0x4ed6aa(0x14e)](_0x45b0d5,_0x4dc2b9);},'vXgti':_0x4ba179[_0x4113b0(0x186)],'FLOdi':function(_0x14abf1,_0x32d9d6){const _0x305c18=_0x4113b0;return _0x4ba179[_0x305c18(0x1b4)](_0x14abf1,_0x32d9d6);}},_0x5e76e2=a14_0x18d45d[_0x4113b0(0x168)][_0x4113b0(0x161)]({'hostname':'localhost','port':a14_0x3199a4,'path':_0x4ba179[_0x4113b0(0x1c2)],'method':_0x4ba179['LwWEz'],'headers':{'Content-Type':_0x4ba179[_0x4113b0(0x122)],'Content-Length':Buffer[_0x4113b0(0x196)](_0x1aac98)}},_0xae2f4=>{const _0x3b2ebb=_0x4113b0,_0x573e02={'fUDvq':_0x3b2ebb(0x15a),'UHcrp':_0x4ba179[_0x3b2ebb(0x166)]};if(_0x4ba179[_0x3b2ebb(0x11c)](_0x3b2ebb(0x1a5),_0x4ba179['XPALd']))try{_0x31b400['MBsZt'](_0x106496,_0x4c280e[_0x3b2ebb(0x144)](_0xd5e26));}catch{_0x31b400[_0x3b2ebb(0x1b0)](_0x4be8ac,new _0x2a9429(_0x3b2ebb(0x13d)+_0x2c20c5));}else{let _0x303089='';_0xae2f4['on'](_0x4ba179[_0x3b2ebb(0x15c)],_0x19ffdb=>_0x303089+=_0x19ffdb),_0xae2f4['on'](_0x4ba179[_0x3b2ebb(0x188)],()=>{const _0x3fdb2c=_0x3b2ebb;try{if(_0x31b400[_0x3fdb2c(0x150)](_0x31b400['vXgti'],_0x3fdb2c(0x127))){const _0x494eef=_0x474b2e[_0x3fdb2c(0x168)]['get'](_0x3a1ef0+_0x3fdb2c(0x1a2),{'timeout':0x320},_0x4cc071=>_0x2a8d6f(_0x4cc071['statusCode']===0xc8));_0x494eef['on'](rBejbe[_0x3fdb2c(0x14a)],()=>_0x1703c8(![])),_0x494eef['on'](rBejbe[_0x3fdb2c(0x1a4)],()=>{const _0x24d461=_0x3fdb2c;_0x494eef[_0x24d461(0x118)](),_0x35499f(![]);});}else _0x54d824(JSON[_0x3fdb2c(0x144)](_0x303089));}catch{_0x31b400[_0x3fdb2c(0x172)](_0x59fc2f,new Error(_0x3fdb2c(0x13d)+_0x303089));}});}});_0x5e76e2['on'](_0x4ba179['jSkpm'],_0x59fc2f),_0x5e76e2[_0x4113b0(0x1be)](_0x1aac98),_0x5e76e2[_0x4113b0(0x146)]();});}async function a14_0x23c4ee(_0xcd7053){const _0x2606eb=a14_0x5126e4,_0x439966={'BJPlj':function(_0x2e67f8,_0xf2b812){return _0x2e67f8(_0xf2b812);},'SoBwS':_0x2606eb(0x18c),'xTGcN':_0x2606eb(0x146),'MfJaA':function(_0x3508ad,_0x519646){return _0x3508ad===_0x519646;},'FBRqT':'NPtGx','dTKMz':_0x2606eb(0x19f),'ENRGd':'localhost','HBtNQ':_0x2606eb(0x139),'mKeND':_0x2606eb(0x15a)};return new Promise((_0x104c74,_0x484c60)=>{const _0x1f7a9f=_0x2606eb,_0x4dffcc={'pmvGg':function(_0x6e71f6,_0x44b1a4){const _0x5e0121=a14_0x2804;return _0x439966[_0x5e0121(0x181)](_0x6e71f6,_0x44b1a4);},'KPXFw':function(_0x9dca01,_0x1a34fb){return _0x9dca01!==_0x1a34fb;},'tgxOj':_0x439966[_0x1f7a9f(0x160)],'LyJUd':_0x439966[_0x1f7a9f(0x148)]};if(_0x439966['MfJaA'](_0x439966[_0x1f7a9f(0x11e)],_0x439966['dTKMz']))_0x388142[_0x1f7a9f(0x18f)](),_0x1c4448();else{const _0x15bd24=a14_0x18d45d[_0x1f7a9f(0x168)]['request']({'hostname':_0x439966[_0x1f7a9f(0x138)],'port':a14_0x3199a4,'path':_0x1f7a9f(0x165)+_0xcd7053,'method':_0x439966[_0x1f7a9f(0x1bc)]},_0x2f4661=>{const _0x13e689=_0x1f7a9f,_0x3b6500={'yGFgK':function(_0x559809,_0x251a94){const _0x1fa3fb=a14_0x2804;return _0x4dffcc[_0x1fa3fb(0x1af)](_0x559809,_0x251a94);},'LxMWx':function(_0x2fee01,_0x480034){return _0x4dffcc['KPXFw'](_0x2fee01,_0x480034);},'dFIwK':_0x4dffcc[_0x13e689(0x157)]};let _0x48c764='';_0x2f4661['on'](_0x13e689(0x133),_0x28413f=>_0x48c764+=_0x28413f),_0x2f4661['on'](_0x4dffcc[_0x13e689(0x17c)],()=>{const _0x20c0ff=_0x13e689;try{_0x3b6500['yGFgK'](_0x104c74,JSON['parse'](_0x48c764));}catch{_0x3b6500[_0x20c0ff(0x194)](_0x3b6500[_0x20c0ff(0x15e)],_0x3b6500[_0x20c0ff(0x15e)])?_0x1a14c8(_0x2be61a[_0x20c0ff(0x144)](_0x6cf0dd)):_0x3b6500[_0x20c0ff(0x175)](_0x484c60,new Error(_0x20c0ff(0x13d)+_0x48c764));}});});_0x15bd24['on'](_0x439966[_0x1f7a9f(0x195)],_0x484c60),_0x15bd24[_0x1f7a9f(0x146)]();}});}
@@ -0,0 +1,540 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>PW — Execution Dashboard</title>
7
+ <style>
8
+ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
9
+ :root{
10
+ --bg:#0a0d14;--surface:#111827;--s2:#1a2236;
11
+ --b:#1e2d45;--b2:#2d3f5e;
12
+ --t:#e2e8f0;--m:#64748b;--m2:#94a3b8;
13
+ --pass:#22c55e;--pb:#052e16;--pbd:#14532d;
14
+ --fail:#ef4444;--fb:#2d0a0a;--fbd:#7f1d1d;
15
+ --skip:#f59e0b;--sb:#2d1d00;--sbd:#78350f;
16
+ --run:#3b82f6;--rb:#0c1f3d;--rbd:#1e3a6e;
17
+ --cancel:#a855f7;--cnb:#1a0a2e;--cnbd:#4a1d7e;
18
+ --r:10px;--rs:6px;
19
+ }
20
+ html,body{height:100%;background:var(--bg);color:var(--t);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
21
+
22
+ header{background:var(--surface);border-bottom:1px solid var(--b);padding:12px 24px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
23
+ .h-left{display:flex;align-items:center;gap:12px}
24
+ .h-logo{font-size:1.4rem}
25
+ .h-title{font-size:.95rem;font-weight:700}
26
+ .h-sub{font-size:.68rem;color:var(--m);font-family:monospace;margin-top:2px}
27
+ .h-right{display:flex;align-items:center;gap:10px}
28
+
29
+ .badge{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:99px;font-size:.72rem;font-weight:700;letter-spacing:.05em;border:1px solid transparent}
30
+ .badge .dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
31
+ .badge-idle {background:#1a1a2e;color:var(--m);border-color:var(--b)}
32
+ .badge-idle .dot{background:var(--m);animation:none}
33
+ .badge-running{background:var(--rb);color:var(--run);border-color:var(--rbd)}
34
+ .badge-running .dot{background:var(--run);animation:pulse .9s ease-in-out infinite}
35
+ .badge-pass {background:var(--pb);color:var(--pass);border-color:var(--pbd)}
36
+ .badge-pass .dot{background:var(--pass);animation:none}
37
+ .badge-fail {background:var(--fb);color:var(--fail);border-color:var(--fbd)}
38
+ .badge-fail .dot{background:var(--fail);animation:none}
39
+ .badge-cancel {background:var(--cnb);color:var(--cancel);border-color:var(--cnbd)}
40
+ .badge-cancel .dot{background:var(--cancel);animation:none}
41
+ @keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.8)}}
42
+
43
+ .btn-icon{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:99px;font-size:.72rem;font-weight:600;border:1px solid;cursor:pointer;transition:all .2s;text-decoration:none;background:none}
44
+ .btn-cancel{color:var(--fail);border-color:var(--fbd);background:var(--fb)}
45
+ .btn-cancel:hover{background:#3d0a0a;border-color:var(--fail)}
46
+ .btn-cancel:disabled{opacity:.4;cursor:not-allowed}
47
+ .btn-newwin{color:var(--m2);border-color:var(--b);background:var(--s2)}
48
+ .btn-newwin:hover{color:var(--t);border-color:var(--b2)}
49
+
50
+ .layout{display:grid;grid-template-columns:1fr 300px;height:calc(100vh - 53px);overflow:hidden}
51
+ .main{overflow-y:auto;padding:18px 22px;display:flex;flex-direction:column;gap:14px}
52
+ .sidebar{background:var(--surface);border-left:1px solid var(--b);display:flex;flex-direction:column;overflow:hidden}
53
+
54
+ .prog-labels{display:flex;justify-content:space-between;font-size:.7rem;color:var(--m);margin-bottom:5px}
55
+ .prog-track{background:var(--s2);border-radius:99px;height:5px;border:1px solid var(--b);overflow:hidden}
56
+ .prog-fill{height:100%;border-radius:99px;background:linear-gradient(90deg,#4f46e5,var(--run));width:0%;transition:width .5s cubic-bezier(.4,0,.2,1)}
57
+ .prog-fill.done{background:linear-gradient(90deg,#14532d,var(--pass))}
58
+ .prog-fill.fail{background:linear-gradient(90deg,#7f1d1d,var(--fail))}
59
+ .prog-fill.cancelled{background:linear-gradient(90deg,#3b0764,var(--cancel))}
60
+
61
+ .stats{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
62
+ .stat{background:var(--s2);border:1px solid var(--b);border-radius:var(--r);padding:12px;text-align:center}
63
+ .stat-v{font-size:1.7rem;font-weight:800;line-height:1}
64
+ .stat-l{font-size:.6rem;color:var(--m);margin-top:4px;text-transform:uppercase;letter-spacing:.1em}
65
+ .stat.total .stat-v{color:var(--t)}
66
+ .stat.pass .stat-v{color:var(--pass)}
67
+ .stat.fail .stat-v{color:var(--fail)}
68
+ .stat.skip .stat-v{color:var(--skip)}
69
+ .stat.dur .stat-v{color:var(--run)}
70
+
71
+ .script-hdr{background:var(--s2);border:1px solid var(--b);border-radius:var(--r);padding:10px 14px;display:flex;align-items:center;gap:8px}
72
+ .script-name{font-size:.85rem;font-weight:600}
73
+ .script-meta{font-size:.68rem;color:var(--m);margin-top:2px}
74
+
75
+ .steps{display:flex;flex-direction:column;gap:6px}
76
+ .step-card{background:var(--s2);border:1px solid var(--b);border-left:3px solid var(--b2);border-radius:var(--r);overflow:hidden;animation:si .2s ease}
77
+ @keyframes si{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
78
+ .step-card.PASS {border-left-color:var(--pass)}
79
+ .step-card.FAIL {border-left-color:var(--fail)}
80
+ .step-card.SKIP {border-left-color:var(--skip);opacity:.8}
81
+ .step-card.RUNNING {border-left-color:var(--run)}
82
+
83
+ .step-row{display:grid;grid-template-columns:34px 1fr auto auto;align-items:center;gap:10px;padding:9px 12px;cursor:pointer;transition:background .15s}
84
+ .step-row:hover{background:rgba(255,255,255,.03)}
85
+
86
+ .snum{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.68rem;font-weight:700;background:var(--surface);border:1px solid var(--b2);color:var(--m);flex-shrink:0}
87
+ .step-card.PASS .snum{background:var(--pb);border-color:var(--pass);color:var(--pass)}
88
+ .step-card.FAIL .snum{background:var(--fb);border-color:var(--fail);color:var(--fail)}
89
+ .step-card.SKIP .snum{background:var(--sb);border-color:var(--skip);color:var(--skip)}
90
+ .step-card.RUNNING .snum{background:var(--rb);border-color:var(--run);color:var(--run)}
91
+
92
+ .sname{font-size:.82rem;font-weight:500;color:#dde4f0}
93
+ .sscript{font-size:.65rem;color:var(--m);font-family:monospace;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:460px}
94
+
95
+ .spill{padding:2px 8px;border-radius:99px;font-size:.65rem;font-weight:700;flex-shrink:0}
96
+ .spill-PASS {background:var(--pb);color:var(--pass);border:1px solid var(--pbd)}
97
+ .spill-FAIL {background:var(--fb);color:var(--fail);border:1px solid var(--fbd)}
98
+ .spill-SKIP {background:var(--sb);color:var(--skip);border:1px solid var(--sbd)}
99
+ .spill-RUNNING {background:var(--rb);color:var(--run);border:1px solid var(--rbd)}
100
+
101
+ .sdur{font-size:.65rem;color:var(--m);min-width:60px;text-align:right;flex-shrink:0}
102
+
103
+ .sdet{display:none;padding:0 12px 10px;border-top:1px solid var(--b)}
104
+ .sdet.open{display:block}
105
+ .sdet-comment{font-size:.75rem;line-height:1.5;padding:7px 10px;border-radius:var(--rs);background:var(--surface);border:1px solid var(--b2);color:var(--m2);margin-bottom:6px}
106
+ .sdet-comment.is-fail {background:var(--fb);border-color:var(--fbd);color:#fca5a5}
107
+ .sdet-comment.is-skip {background:var(--sb);border-color:var(--sbd);color:#fcd34d}
108
+ .sdet-comment.is-cancel{background:var(--cnb);border-color:var(--cnbd);color:#d8b4fe}
109
+ .step-sc{width:100%;border-radius:var(--rs);border:1px solid var(--b2);cursor:zoom-in;margin-top:6px;max-height:220px;object-fit:cover}
110
+
111
+ .empty{text-align:center;padding:50px 20px;color:var(--m)}
112
+ .empty-icon{font-size:2.5rem;margin-bottom:10px}
113
+ .empty-sub{font-size:.75rem;margin-top:6px;opacity:.6}
114
+
115
+ .sb-sec{padding:14px;border-bottom:1px solid var(--b);flex-shrink:0}
116
+ .sb-title{font-size:.62rem;font-weight:700;color:var(--m);text-transform:uppercase;letter-spacing:.12em;margin-bottom:8px}
117
+
118
+ /* ── Step overview list in sidebar ── */
119
+ .mini-list{display:flex;flex-direction:column;gap:3px;max-height:240px;overflow-y:auto}
120
+ .mini-step{display:flex;align-items:center;gap:7px;padding:5px 8px;border-radius:var(--rs);font-size:.7rem;background:var(--s2);border:1px solid var(--b);transition:border-color .2s}
121
+ .mini-step.PASS {border-left:2px solid var(--pass)}
122
+ .mini-step.FAIL {border-left:2px solid var(--fail)}
123
+ .mini-step.SKIP {border-left:2px solid var(--skip);opacity:.8}
124
+ .mini-step.RUNNING {border-left:2px solid var(--run)}
125
+ .mini-dot{width:6px;height:6px;border-radius:50%;background:var(--b2);flex-shrink:0}
126
+ .mini-step.PASS .mini-dot{background:var(--pass)}
127
+ .mini-step.FAIL .mini-dot{background:var(--fail)}
128
+ .mini-step.SKIP .mini-dot{background:var(--skip)}
129
+ .mini-step.RUNNING .mini-dot{background:var(--run);animation:pulse .9s infinite}
130
+ .mini-step-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;color:var(--m2)}
131
+ .mini-badge{font-size:.58rem;font-weight:700;padding:1px 5px;border-radius:4px;flex-shrink:0}
132
+ .mini-badge.PASS {background:var(--pb);color:var(--pass)}
133
+ .mini-badge.FAIL {background:var(--fb);color:var(--fail)}
134
+ .mini-badge.SKIP {background:var(--sb);color:var(--skip)}
135
+ .mini-badge.RUNNING{background:var(--rb);color:var(--run)}
136
+
137
+ .sum-box{background:var(--s2);border:1px solid var(--b);border-radius:var(--r)}
138
+ .sum-row{display:flex;justify-content:space-between;padding:7px 12px;font-size:.75rem;border-bottom:1px solid var(--b)}
139
+ .sum-row:last-child{border-bottom:none}
140
+ .sum-lbl{color:var(--m)}
141
+ .sum-val{font-weight:600}
142
+
143
+ .log-box{flex:1;overflow-y:auto;padding:8px 12px;font-family:'Cascadia Code','Fira Code',monospace;font-size:.66rem;line-height:1.7;background:#060b12}
144
+ .ll{color:var(--m);word-break:break-word}
145
+ .lp{color:var(--pass)}.lf{color:var(--fail)}.ls{color:var(--skip)}.lr{color:var(--run)}.ly{color:#d2a8ff}
146
+
147
+ #modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,.9);z-index:1000;align-items:center;justify-content:center;backdrop-filter:blur(5px)}
148
+ #modal.open{display:flex}
149
+ .modal-inner{position:relative}
150
+ .modal-inner img{max-width:92vw;max-height:90vh;border-radius:8px;border:1px solid var(--b2)}
151
+ .modal-close{position:absolute;top:-30px;right:0;background:none;border:none;color:#fff;font-size:1.4rem;cursor:pointer;opacity:.7}
152
+ .modal-close:hover{opacity:1}
153
+
154
+ ::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background:var(--bg)}::-webkit-scrollbar-thumb{background:var(--b2);border-radius:2px}
155
+ </style>
156
+ </head>
157
+ <body>
158
+
159
+ <header>
160
+ <div class="h-left">
161
+ <span class="h-logo">🎭</span>
162
+ <div>
163
+ <div class="h-title">Playwright — Live Dashboard</div>
164
+ <div class="h-sub" id="execLabel">Connecting…</div>
165
+ </div>
166
+ </div>
167
+ <div class="h-right">
168
+ <a class="btn-icon btn-newwin" id="newWinBtn" href="#" target="_blank">↗ New Tab</a>
169
+ <button class="btn-icon btn-cancel" id="cancelBtn" onclick="cancelExecution()" disabled>⏹ Cancel</button>
170
+ <div class="badge badge-idle" id="statusBadge"><span class="dot"></span><span id="statusText">CONNECTING</span></div>
171
+ </div>
172
+ </header>
173
+
174
+ <div class="layout">
175
+ <div class="main">
176
+ <div>
177
+ <div class="prog-labels"><span id="progLeft">Waiting for execution…</span><span id="progRight">0%</span></div>
178
+ <div class="prog-track"><div class="prog-fill" id="progFill"></div></div>
179
+ </div>
180
+ <div class="stats">
181
+ <div class="stat total"><div class="stat-v" id="sTotal">—</div><div class="stat-l">Total Steps</div></div>
182
+ <div class="stat pass" ><div class="stat-v" id="sPass">0</div><div class="stat-l">Passed</div></div>
183
+ <div class="stat fail" ><div class="stat-v" id="sFail">0</div><div class="stat-l">Failed</div></div>
184
+ <div class="stat skip" ><div class="stat-v" id="sSkip">0</div><div class="stat-l">Skipped</div></div>
185
+ <div class="stat dur" ><div class="stat-v" id="sDur">0s</div><div class="stat-l">Duration</div></div>
186
+ </div>
187
+ <div class="script-hdr" id="scriptHdr" style="display:none">
188
+ <span>📋</span>
189
+ <div><div class="script-name" id="scriptName">—</div><div class="script-meta" id="scriptMeta">—</div></div>
190
+ </div>
191
+ <div class="steps" id="stepsContainer">
192
+ <div class="empty" id="emptyState">
193
+ <div class="empty-icon">⏳</div>
194
+ <div>Waiting for execution to begin…</div>
195
+ <div class="empty-sub">Steps will appear here as they execute</div>
196
+ </div>
197
+ </div>
198
+ </div>
199
+
200
+ <div class="sidebar">
201
+ <div class="sb-sec">
202
+ <div class="sb-title">📊 Step Overview</div>
203
+ <div class="mini-list" id="miniList"></div>
204
+ </div>
205
+ <div class="sb-sec" id="sumSection" style="display:none">
206
+ <div class="sb-title">🏁 Summary</div>
207
+ <div class="sum-box">
208
+ <div class="sum-row"><span class="sum-lbl">Status</span> <span class="sum-val" id="sumStatus">—</span></div>
209
+ <div class="sum-row"><span class="sum-lbl">Total Steps</span> <span class="sum-val" id="sumTotal">—</span></div>
210
+ <div class="sum-row"><span class="sum-lbl">Passed</span> <span class="sum-val" style="color:var(--pass)" id="sumPass">—</span></div>
211
+ <div class="sum-row"><span class="sum-lbl">Failed</span> <span class="sum-val" style="color:var(--fail)" id="sumFail">—</span></div>
212
+ <div class="sum-row"><span class="sum-lbl">Skipped</span> <span class="sum-val" style="color:var(--skip)" id="sumSkip">—</span></div>
213
+ <div class="sum-row"><span class="sum-lbl">Duration</span> <span class="sum-val" id="sumDur">—</span></div>
214
+ </div>
215
+ </div>
216
+ <div class="sb-sec" style="flex-shrink:0"><div class="sb-title">📋 Live Log</div></div>
217
+ <div class="log-box" id="logBox"></div>
218
+ </div>
219
+ </div>
220
+
221
+ <div id="modal" onclick="closeModal()">
222
+ <div class="modal-inner" onclick="event.stopPropagation()">
223
+ <button class="modal-close" onclick="closeModal()">✕</button>
224
+ <img id="modalImg" src="" alt="screenshot" />
225
+ </div>
226
+ </div>
227
+
228
+ <script>
229
+ const execId = location.pathname.split('/').pop();
230
+ const $ = id => document.getElementById(id);
231
+
232
+ let totalSteps = 0, passed = 0, failed = 0, skipped = 0;
233
+ let startTime = Date.now(), timerInt, isDone = false;
234
+
235
+ // Set "open in new tab" link
236
+ $('execLabel').textContent = 'ID: ' + execId;
237
+ $('newWinBtn').href = location.href;
238
+
239
+ const esc = s => String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
240
+
241
+ function setStatus(text, cls) {
242
+ const b = $('statusBadge');
243
+ b.className = 'badge ' + cls;
244
+ b.querySelector('span:last-child').textContent = text;
245
+ }
246
+
247
+ function setProgress(done, total, fillCls) {
248
+ const pct = total > 0 ? Math.round(done / total * 100) : 0;
249
+ const f = $('progFill');
250
+ f.style.width = pct + '%';
251
+ if (fillCls) { f.classList.remove('done','fail','cancelled'); f.classList.add(fillCls); }
252
+ $('progRight').textContent = pct + '%';
253
+ $('progLeft').textContent = total > 0 ? `Step ${done} of ${total}` : 'Waiting…';
254
+ }
255
+
256
+ function updateStats() {
257
+ $('sTotal').textContent = totalSteps > 0 ? totalSteps : '—';
258
+ $('sPass').textContent = passed;
259
+ $('sFail').textContent = failed;
260
+ $('sSkip').textContent = skipped;
261
+ if (!isDone) $('sDur').textContent = ((Date.now() - startTime) / 1000).toFixed(1) + 's';
262
+ }
263
+
264
+ function fmtDur(ms) {
265
+ if (!ms && ms !== 0) return '—';
266
+ return ms < 1000 ? ms + 'ms' : (ms/1000).toFixed(1) + 's';
267
+ }
268
+
269
+ function log(msg, cls='') {
270
+ const b = $('logBox');
271
+ const ts = new Date().toLocaleTimeString('en-GB');
272
+ const d = document.createElement('div');
273
+ d.className = 'll ' + cls;
274
+ d.textContent = `[${ts}] ${msg}`;
275
+ b.appendChild(d);
276
+ b.scrollTop = b.scrollHeight;
277
+ }
278
+
279
+ function openModal(src) { $('modalImg').src = src; $('modal').classList.add('open'); }
280
+ function closeModal() { $('modal').classList.remove('open'); }
281
+ document.addEventListener('keydown', e => { if (e.key === 'Escape') closeModal(); });
282
+
283
+ async function cancelExecution() {
284
+ if (!confirm('Cancel? The current step will finish, then remaining steps are skipped.')) return;
285
+ $('cancelBtn').disabled = true;
286
+ try {
287
+ const r = await fetch(`/api/cancel/${execId}`, { method: 'DELETE' });
288
+ const d = await r.json();
289
+ log('⏹ ' + d.message, 'ly');
290
+ } catch (e) {
291
+ log('Cancel failed: ' + e.message, 'lf');
292
+ $('cancelBtn').disabled = false;
293
+ }
294
+ }
295
+
296
+ // ─── Step card builder ────────────────────────────────────────────────────────
297
+
298
+ /**
299
+ * Create a RUNNING step card.
300
+ * Called on step_start.
301
+ */
302
+ function addStepCard(data) {
303
+ const empty = $('emptyState');
304
+ if (empty) empty.remove();
305
+ if ($('sc-' + data.step_number)) return; // replay guard
306
+
307
+ const card = document.createElement('div');
308
+ card.className = 'step-card RUNNING';
309
+ card.id = 'sc-' + data.step_number;
310
+ card.innerHTML = `
311
+ <div class="step-row" onclick="toggleDet(${data.step_number})">
312
+ <div class="snum" id="sn-${data.step_number}">${data.step_number}</div>
313
+ <div>
314
+ <div class="sname">${esc(data.step_name)}</div>
315
+ <div class="sscript" title="${esc(data.step_script)}">${esc(data.step_script||'')}</div>
316
+ </div>
317
+ <span class="spill spill-RUNNING" id="sp-${data.step_number}">⏳ RUNNING</span>
318
+ <span class="sdur" id="sd-${data.step_number}">—</span>
319
+ </div>
320
+ <div class="sdet" id="sdet-${data.step_number}"></div>`;
321
+ $('stepsContainer').appendChild(card);
322
+ card.scrollIntoView({ behavior:'smooth', block:'nearest' });
323
+ }
324
+
325
+ /**
326
+ * ✅ FIX: Complete a step card — also CREATES it if it doesn't exist yet.
327
+ * Skipped steps arrive as step_complete WITHOUT a prior step_start,
328
+ * so we must handle card creation here too.
329
+ */
330
+ function completeStepCard(data) {
331
+ const empty = $('emptyState');
332
+ if (empty) empty.remove();
333
+
334
+ let card = $('sc-' + data.step_number);
335
+
336
+ // ── Create card if it doesn't exist (SKIP steps bypass step_start) ──────
337
+ if (!card) {
338
+ card = document.createElement('div');
339
+ card.className = 'step-card ' + data.status;
340
+ card.id = 'sc-' + data.step_number;
341
+ card.innerHTML = `
342
+ <div class="step-row" onclick="toggleDet(${data.step_number})">
343
+ <div class="snum" id="sn-${data.step_number}">${data.step_number}</div>
344
+ <div>
345
+ <div class="sname">${esc(data.step_name)}</div>
346
+ <div class="sscript" title="${esc(data.step_script)}">${esc(data.step_script||'')}</div>
347
+ </div>
348
+ <span class="spill spill-${data.status}" id="sp-${data.step_number}"></span>
349
+ <span class="sdur" id="sd-${data.step_number}">—</span>
350
+ </div>
351
+ <div class="sdet" id="sdet-${data.step_number}"></div>`;
352
+ $('stepsContainer').appendChild(card);
353
+ // Auto-scroll for skipped steps too
354
+ card.scrollIntoView({ behavior:'smooth', block:'nearest' });
355
+ } else {
356
+ card.classList.remove('RUNNING');
357
+ card.classList.add(data.status);
358
+ }
359
+
360
+ const icons = { PASS:'✅', FAIL:'❌', SKIP:'⏭' };
361
+ const labels = { PASS:'PASS', FAIL:'FAIL', SKIP:'SKIP' };
362
+ $('sp-' + data.step_number).textContent = `${icons[data.status]||''} ${labels[data.status]||data.status}`;
363
+ $('sp-' + data.step_number).className = `spill spill-${data.status}`;
364
+ $('sd-' + data.step_number).textContent = data.duration_ms >= 0 ? fmtDur(data.duration_ms) : '—';
365
+
366
+ // Detail block
367
+ let cls = '';
368
+ if (data.status === 'FAIL') cls = 'is-fail';
369
+ if (data.status === 'SKIP') cls = data.skip_reason === 'CANCELLED' ? 'is-cancel' : 'is-skip';
370
+
371
+ const commentText = data.skip_reason
372
+ ? `⏭ ${data.skip_reason}`
373
+ : (data.comments || '—');
374
+
375
+ let html = `<div class="sdet-comment ${cls}">${esc(commentText)}</div>`;
376
+ if (data.screenshot) {
377
+ html += `<img class="step-sc" src="data:image/png;base64,${data.screenshot}" onclick="openModal(this.src)" title="Click to enlarge" />`;
378
+ }
379
+ $('sdet-' + data.step_number).innerHTML = html;
380
+
381
+ // Auto-expand failures and skips
382
+ if (data.status === 'FAIL' || data.status === 'SKIP') {
383
+ $('sdet-' + data.step_number).classList.add('open');
384
+ }
385
+ }
386
+
387
+ // ─── Step overview (sidebar mini-list) ───────────────────────────────────────
388
+
389
+ /**
390
+ * ✅ FIX: addMiniStep handles ALL statuses — not just RUNNING.
391
+ * Skipped steps are added directly with SKIP styling.
392
+ */
393
+ function addMiniStep(data, initialStatus) {
394
+ if ($('ms-' + data.step_number)) {
395
+ // Already exists — update status
396
+ updateMiniStep(data.step_number, initialStatus || 'RUNNING');
397
+ return;
398
+ }
399
+ const status = initialStatus || 'RUNNING';
400
+ const icons = { PASS:'✅', FAIL:'❌', SKIP:'⏭', RUNNING:'▶' };
401
+ const d = document.createElement('div');
402
+ d.className = 'mini-step ' + status;
403
+ d.id = 'ms-' + data.step_number;
404
+ d.innerHTML = `
405
+ <span class="mini-dot"></span>
406
+ <span class="mini-step-name">${data.step_number}. ${esc(data.step_name)}</span>
407
+ <span class="mini-badge ${status}" id="mb-${data.step_number}">${icons[status]||status}</span>`;
408
+ $('miniList').appendChild(d);
409
+ $('miniList').scrollTop = $('miniList').scrollHeight;
410
+ }
411
+
412
+ function updateMiniStep(num, status) {
413
+ const el = $('ms-' + num);
414
+ const mb = $('mb-' + num);
415
+ if (!el) return;
416
+ el.className = 'mini-step ' + status;
417
+ const icons = { PASS:'✅', FAIL:'❌', SKIP:'⏭', RUNNING:'▶' };
418
+ if (mb) { mb.className = `mini-badge ${status}`; mb.textContent = icons[status]||status; }
419
+ }
420
+
421
+ function toggleDet(num) { $('sdet-' + num)?.classList.toggle('open'); }
422
+
423
+ function showSummary(status, dur) {
424
+ $('sumSection').style.display = 'block';
425
+ $('sumStatus').textContent = status;
426
+ $('sumStatus').style.color = status === 'PASS' ? 'var(--pass)' : status === 'CANCELLED' ? 'var(--cancel)' : 'var(--fail)';
427
+ $('sumTotal').textContent = passed + failed + skipped;
428
+ $('sumPass').textContent = passed;
429
+ $('sumFail').textContent = failed;
430
+ $('sumSkip').textContent = skipped;
431
+ $('sumDur').textContent = dur || $('sDur').textContent;
432
+ }
433
+
434
+ // ─── SSE Connection ───────────────────────────────────────────────────────────
435
+ const es = new EventSource('/api/stream/' + execId);
436
+
437
+ es.onopen = () => {
438
+ log('Connected to execution stream.', 'ly');
439
+ if (!timerInt) timerInt = setInterval(updateStats, 300);
440
+ };
441
+
442
+ es.onmessage = e => {
443
+ let ev;
444
+ try { ev = JSON.parse(e.data); } catch { return; }
445
+ const { type, data } = ev;
446
+
447
+ if (type === 'log') { log(data.message||'', ''); return; }
448
+ if (type === 'queue_update') return;
449
+
450
+ if (type === 'execution_start') {
451
+ startTime = Date.now();
452
+ if (!timerInt) timerInt = setInterval(updateStats, 300);
453
+ setStatus('RUNNING', 'badge-running');
454
+ $('cancelBtn').disabled = false;
455
+ log(`Execution started — ${data.total_scripts} script(s)`, 'lr');
456
+ }
457
+
458
+ if (type === 'script_start') {
459
+ totalSteps = data.total_steps || 0;
460
+ $('scriptHdr').style.display = 'flex';
461
+ $('scriptName').textContent = data.test_case_name || data.test_script_uid;
462
+ $('scriptMeta').textContent = `${totalSteps} steps · ${data.browser||'chromium'} · UID: ${data.test_script_uid}`;
463
+ updateStats();
464
+ setProgress(0, totalSteps);
465
+ log(`Script: "${data.test_case_name}" — ${totalSteps} steps`, 'ly');
466
+ }
467
+
468
+ if (type === 'step_start') {
469
+ addStepCard(data);
470
+ addMiniStep(data, 'RUNNING');
471
+ log(`▶ Step ${data.step_number}: ${data.step_name}`, 'lr');
472
+ }
473
+
474
+ if (type === 'step_complete') {
475
+ // ✅ Count first, before card update
476
+ if (data.status === 'PASS') passed++;
477
+ else if (data.status === 'FAIL') failed++;
478
+ else if (data.status === 'SKIP') skipped++;
479
+
480
+ // ✅ completeStepCard also creates the card if missing (handles SKIP bypass)
481
+ completeStepCard(data);
482
+
483
+ // ✅ addMiniStep for skipped steps that never got a step_start
484
+ addMiniStep(data, data.status);
485
+ updateMiniStep(data.step_number, data.status);
486
+
487
+ setProgress(passed + failed + skipped, totalSteps);
488
+ updateStats();
489
+
490
+ const icon = { PASS:'✅', FAIL:'❌', SKIP:'⏭' }[data.status]||'';
491
+ const reason = data.skip_reason ? ` (${data.skip_reason})` : '';
492
+ log(`${icon} Step ${data.step_number}: ${data.step_name} — ${data.comments||''}${reason}`,
493
+ data.status==='PASS' ? 'lp' : data.status==='SKIP' ? 'ls' : 'lf');
494
+ }
495
+
496
+ if (type === 'script_complete') {
497
+ const dur = fmtDur(data.duration_ms);
498
+ log(`Script done: ${data.overall_status} | ✅${data.passed_steps} ❌${data.failed_steps} ⏭${data.skipped_steps} (${dur})`, 'ly');
499
+ }
500
+
501
+ if (type === 'execution_cancelled') {
502
+ isDone = true; clearInterval(timerInt);
503
+ $('cancelBtn').disabled = true;
504
+ setStatus('CANCELLED', 'badge-cancel');
505
+ $('progFill').style.width = '100%';
506
+ $('progFill').classList.add('cancelled');
507
+ $('progRight').textContent = '100%';
508
+ updateStats(); showSummary('CANCELLED');
509
+ log('⏹ Execution cancelled', 'ly');
510
+ es.close();
511
+ }
512
+
513
+ if (type === 'execution_complete') {
514
+ isDone = true; clearInterval(timerInt);
515
+ $('cancelBtn').disabled = true;
516
+ const ok = data.overall_status === 'PASS';
517
+ const dur = fmtDur(data.duration_ms || 0);
518
+ setStatus(ok ? '✅ PASSED' : '❌ FAILED', ok ? 'badge-pass' : 'badge-fail');
519
+ $('progFill').style.width = '100%';
520
+ $('progFill').classList.add(ok ? 'done' : 'fail');
521
+ $('progRight').textContent = '100%';
522
+ if (totalSteps > 0) $('progLeft').textContent = `Step ${totalSteps} of ${totalSteps}`;
523
+ $('sDur').textContent = dur;
524
+ updateStats(); showSummary(data.overall_status, dur);
525
+ log(`🏁 ${data.overall_status} | ✅${passed} ❌${failed} ⏭${skipped} | ${dur}`, 'ly');
526
+ es.close();
527
+ }
528
+
529
+ if (type === 'error') {
530
+ setStatus('ERROR', 'badge-fail');
531
+ log('ERROR: ' + data.message, 'lf');
532
+ $('cancelBtn').disabled = true; isDone = true; clearInterval(timerInt);
533
+ es.close();
534
+ }
535
+ };
536
+
537
+ es.onerror = () => { if (!isDone) log('Stream disconnected.', 'lf'); es.close(); };
538
+ </script>
539
+ </body>
540
+ </html>