You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 line
69 KiB
Plaintext
1 line
69 KiB
Plaintext
{"version":3,"sources":["message.ts","components/BreakPoint.tsx","utils.ts","components/FlowPreview.tsx","components/EditFlow.tsx","components/ViewFlow.tsx","flow.ts","App.tsx","reportWebVitals.ts","index.tsx"],"names":["MessageType","BreakPoint","props","state","show","rule","method","url","action","haveRules","handleClose","bind","handleShow","handleSave","this","setState","rules","push","onSave","length","variant","Button","size","onClick","Modal","onHide","Header","closeButton","Title","Body","Form","Group","as","Row","Label","column","sm","Col","Control","value","onChange","e","target","parseInt","Footer","React","Component","isTextBody","payload","header","test","join","getSize","len","isNaN","toFixed","arrayBufferToBase64","buf","binary","bytes","Uint8Array","byteLength","i","String","fromCharCode","btoa","bufHexView","str","viewStr","toString","padStart","FlowPreview","nextProps","isSelected","objA","objB","keysA","Object","keys","keysB","key","undefined","shallowEqual","flow","fp","classNames","waitIntercept","className","onShowDetail","no","host","path","contentType","statusCode","costTime","Flow","msg","id","request","response","_size","headerContentLengthExist","startTime","Date","now","endTime","status","REQUEST","_isTextRequest","_isTextResponse","_requestBody","_hexviewRequestBody","_responseBody","_previewResponseBody","_previewRequestBody","_hexviewResponseBody","curNo","content","URL","pathname","search","REQUEST_BODY","body","RESPONSE","split","includes","RESPONSE_BODY","isTextRequest","TextDecoder","decode","isTextResponse","startsWith","type","data","responseBody","requestBody","hexviewRequestBody","SendMessageType","allMessageBytes","buildMessageEdit","messageType","DROP_REQUEST","DROP_RESPONSE","view","set","TextEncoder","encode","CHANGE_REQUEST","CHANGE_RESPONSE","Error","ArrayBuffer","bodyLen","headerBytes","JSON","stringify","view2","DataView","setUint32","EditFlow","alertMsg","firstLine","headerLines","map","valstr","bodyLines","stringifyRequest","stringifyResponse","when","firstIndex","indexOf","slice","secondIndex","vals","proto","parseRequest","showAlert","onChangeRequest","parseResponse","onChangeResponse","msgType","onMessage","rows","Alert","ViewFlow","flowTab","copied","requestBodyViewTab","responseBodyLineBreak","style","color","pv","previewResponseBody","src","keyStyle","stringStyle","valueStyle","booleanStyle","previewRequestBody","hexviewResponseBody","searchItems","searchParams","forEach","onClose","onReRenderFlows","padding","disabled","curl","fetchToCurl","headers","reduce","obj","copy","setTimeout","marginBottom","requestBodyPreview","FormCheck","inline","checked","label","whiteSpace","preview","hexview","FlowManager","items","_map","filterText","filterTimer","num","max","Map","text","trim","endsWith","reg","RegExp","filter","item","err","oldest","shift","delete","get","callback","clearTimeout","App","flowMgr","ws","pageBottom","autoScore","flows","showList","initWs","close","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","meta","Int8Array","resp","contentStr","parse","parseMessage","add","scrollIntoView","behavior","addRequestBody","addResponse","addResponseBody","error","onerror","watcher","scrollMonitor","create","enterViewport","exitViewport","clear","placeholder","changeFilterLazy","CHANGE_BREAK_POINT_RULES","rulesBytes","buildMessageMeta","send","Table","striped","bordered","tableLayout","width","f","ref","el","initScrollMonitor","height","visibility","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"2JAEYA,E,sKC+HGC,E,kDAvGb,WAAYC,GAAgB,IAAD,8BACzB,cAAMA,IAEDC,MAAQ,CACXC,MAAM,EAENC,KAAM,CACJC,OAAQ,MACRC,IAAK,GACLC,OAAQ,GAGVC,WAAW,GAGb,EAAKC,YAAc,EAAKA,YAAYC,KAAjB,gBACnB,EAAKC,WAAa,EAAKA,WAAWD,KAAhB,gBAClB,EAAKE,WAAa,EAAKA,WAAWF,KAAhB,gBAjBO,E,+CAoB3B,WACEG,KAAKC,SAAS,CAAEX,MAAM,M,wBAGxB,WACEU,KAAKC,SAAS,CAAEX,MAAM,M,wBAGxB,WAAc,IACJC,EAASS,KAAKX,MAAdE,KACFW,EAAiB,GACnBX,EAAKE,KACPS,EAAMC,KAAK,CACTX,OAAwB,QAAhBD,EAAKC,OAAmB,GAAKD,EAAKC,OAC1CC,IAAKF,EAAKE,IACVC,OAAQH,EAAKG,SAIjBM,KAAKZ,MAAMgB,OAAOF,GAClBF,KAAKJ,cAELI,KAAKC,SAAS,CAAEN,YAAWO,EAAMG,W,oBAGnC,WAAU,IAAD,SACqBL,KAAKX,MAAzBE,EADD,EACCA,KACFe,EAFC,EACOX,UACc,UAAY,UAExC,OACE,gCACE,cAACY,EAAA,EAAD,CAAQD,QAASA,EAASE,KAAK,KAAKC,QAAST,KAAKF,WAAlD,wBAEA,eAACY,EAAA,EAAD,CAAOpB,KAAMU,KAAKX,MAAMC,KAAMqB,OAAQX,KAAKJ,YAA3C,UACE,cAACc,EAAA,EAAME,OAAP,CAAcC,aAAW,EAAzB,SACE,cAACH,EAAA,EAAMI,MAAP,+BAGF,eAACJ,EAAA,EAAMK,KAAP,WACE,eAACC,EAAA,EAAKC,MAAN,CAAYC,GAAIC,IAAhB,UACE,cAACH,EAAA,EAAKI,MAAN,CAAYC,QAAM,EAACC,GAAI,EAAvB,oBACA,cAACC,EAAA,EAAD,CAAKD,GAAI,GAAT,SACE,eAACN,EAAA,EAAKQ,QAAN,CAAcN,GAAG,SAASO,MAAOlC,EAAKC,OAAQkC,SAAU,SAAAC,GAAO,EAAK1B,SAAS,CAAEV,KAAK,2BAAMA,GAAP,IAAaC,OAAQmC,EAAEC,OAAOH,WAAjH,UACE,yCACA,yCACA,0CACA,yCACA,oDAKN,eAACT,EAAA,EAAKC,MAAN,CAAYC,GAAIC,IAAhB,UACE,cAACH,EAAA,EAAKI,MAAN,CAAYC,QAAM,EAACC,GAAI,EAAvB,iBACA,cAACC,EAAA,EAAD,CAAKD,GAAI,GAAT,SAAa,cAACN,EAAA,EAAKQ,QAAN,CAAcC,MAAOlC,EAAKE,IAAKiC,SAAU,SAAAC,GAAO,EAAK1B,SAAS,CAAEV,KAAK,2BAAMA,GAAP,IAAaE,IAAKkC,EAAEC,OAAOH,kBAG9G,eAACT,EAAA,EAAKC,MAAN,CAAYC,GAAIC,IAAhB,UACE,cAACH,EAAA,EAAKI,MAAN,CAAYC,QAAM,EAACC,GAAI,EAAvB,oBACA,cAACC,EAAA,EAAD,CAAKD,GAAI,GAAT,SACE,eAACN,EAAA,EAAKQ,QAAN,CAAcN,GAAG,SAASO,MAAOlC,EAAKG,OAAQgC,SAAU,SAAAC,GAAO,EAAK1B,SAAS,CAAEV,KAAK,2BAAMA,GAAP,IAAaG,OAAQmC,SAASF,EAAEC,OAAOH,YAA1H,UACE,wBAAQA,MAAM,IAAd,qBACA,wBAAQA,MAAM,IAAd,sBACA,wBAAQA,MAAM,IAAd,6BAMR,eAACf,EAAA,EAAMoB,OAAP,WACE,cAACvB,EAAA,EAAD,CAAQD,QAAQ,YAAYG,QAAST,KAAKJ,YAA1C,mBAGA,cAACW,EAAA,EAAD,CAAQD,QAAQ,UAAUG,QAAST,KAAKD,WAAxC,+B,GA9FagC,IAAMC,WCvBlBC,EAAa,SAACC,GACzB,QAAKA,MACAA,EAAQC,WACRD,EAAQC,OAAO,iBAEb,2DAA2DC,KAAKF,EAAQC,OAAO,gBAAgBE,KAAK,QAGhGC,EAAU,SAACC,GACtB,OAAKA,EACDC,MAAMD,IACNA,GAAO,EADY,IAGnBA,EAAM,KAAY,GAAN,OAAUA,EAAV,MACZA,EAAM,QAAmB,GAAN,QAAWA,EAAM,MAAME,QAAQ,GAA/B,OACjB,GAAN,QAAWF,EAAG,SAAkBE,QAAQ,GAAxC,OANiB,KAuBNC,EAAsB,SAACC,GAIlC,IAHA,IAAIC,EAAS,GACPC,EAAQ,IAAIC,WAAWH,GACvBJ,EAAMM,EAAME,WACTC,EAAI,EAAGA,EAAIT,EAAKS,IACvBJ,GAAUK,OAAOC,aAAaL,EAAMG,IAEtC,OAAOG,KAAKP,IAGDQ,EAAa,SAACT,GACzB,IAAIU,EAAM,GACJR,EAAQ,IAAIC,WAAWH,GACvBJ,EAAMM,EAAME,WAEdO,EAAU,GAEdD,GAAO,cACP,IAAK,IAAIL,EAAI,EAAGA,EAAIT,EAAKS,IACvBK,GAAOR,EAAMG,GAAGO,SAAS,IAAIC,SAAS,EAAG,KAAO,IAE5CX,EAAMG,IAAM,IAAMH,EAAMG,IAAM,IAChCM,GAAWL,OAAOC,aAAaL,EAAMG,IAErCM,GAAW,KAGRN,EAAI,GAAK,KAAO,GACnBK,GAAO,MAAQC,EACfA,EAAU,GACVD,GAAG,aAAUL,EAAI,GAAGO,SAAS,IAAIC,SAAS,EAAG,KAA1C,SACOR,EAAI,GAAK,IAAM,IACzBK,GAAO,MAKX,GAAIC,EAAQjD,OAAS,EAAG,CACtB,IAAK,IAAI2C,EAAIM,EAAQjD,OAAQ2C,EAAI,GAAIA,IACnCK,GAAO,OACFL,EAAI,GAAK,IAAM,IAAGK,GAAO,MAEhCA,GAAO,IAAMC,EAGf,OAAOD,GCnCMI,E,2KAjCb,SAAsBC,GACpB,OAAIA,EAAUC,aAAe3D,KAAKZ,MAAMuE,aDQhB,SAACC,EAAWC,GACtC,GAAID,IAASC,EAAM,OAAO,EAE1B,IAAMC,EAAQC,OAAOC,KAAKJ,GACpBK,EAAQF,OAAOC,KAAKH,GAC1B,GAAIC,EAAMzD,SAAW4D,EAAM5D,OAAQ,OAAO,EAE1C,IAAK,IAAI2C,EAAI,EAAGA,EAAIc,EAAMzD,OAAQ2C,IAAK,CACrC,IAAMkB,EAAMJ,EAAMd,GAClB,QAAkBmB,IAAdN,EAAKK,IAAsBN,EAAKM,KAASL,EAAKK,GAAM,OAAO,EAEjE,OAAO,ECnBiDE,CAAaV,EAAUW,KAAMrE,KAAKZ,MAAMiF,Q,oBAMhG,WAAU,IAAD,OACDC,EAAKtE,KAAKZ,MAAMiF,KAEhBE,EAAa,GAInB,OAHIvE,KAAKZ,MAAMuE,YAAYY,EAAWpE,KAAK,eACvCmE,EAAGE,eAAeD,EAAWpE,KAAK,qBAGpC,qBAAIsE,UAAWF,EAAWlE,OAASkE,EAAWlC,KAAK,UAAO8B,EACxD1D,QAAS,WACP,EAAKrB,MAAMsF,gBAFf,UAKE,6BAAKJ,EAAGK,KACR,6BAAKL,EAAG9E,SACR,6BAAK8E,EAAGM,OACR,6BAAKN,EAAGO,OACR,6BAAKP,EAAGQ,cACR,6BAAKR,EAAGS,aACR,6BAAKT,EAAG9D,OACR,6BAAK8D,EAAGU,kB,GA5BUjD,IAAMC,W,mGHRpB9C,O,qBAAAA,I,+BAAAA,I,uBAAAA,I,kCAAAA,M,KAgDL,IAAM+F,EAAb,WAgCE,WAAYC,GAAgB,yBA/BrBP,QA+BoB,OA9BpBQ,QA8BoB,OA7BpBX,mBA6BoB,OA5BpBY,aA4BoB,OA3BpBC,SAA6B,KA2BT,KAzBpB5F,SAyBoB,OAxBnBoF,UAwBmB,OAvBnBS,MAAQ,EAuBW,KAtBnB9E,KAAO,IAsBY,KArBnB+E,0BAA2B,EAqBR,KApBnBT,YAAc,GAoBK,KAlBnBU,UAAYC,KAAKC,MAkBE,KAjBnBC,QAAU,EAiBS,KAhBnBX,SAAW,YAgBQ,KAZnBY,OAAsB1G,EAAY2G,QAYf,KAVnBC,oBAUmB,OATnBC,qBASmB,OARnBC,kBAQmB,OAPnBC,oBAAqC,KAOlB,KANnBC,mBAMmB,OAJnBC,qBAA4C,KAIzB,KAHnBC,oBAA2C,KAGxB,KAFnBC,qBAAsC,KAG5CrG,KAAK2E,KAAOM,EAAKqB,MACjBtG,KAAKmF,GAAKD,EAAIC,GACdnF,KAAKwE,cAAgBU,EAAIV,cACzBxE,KAAKoF,QAAUF,EAAIqB,QAEnBvG,KAAKP,IAAM,IAAI+G,IAAIxG,KAAKoF,QAAQ3F,KAChCO,KAAK6E,KAAO7E,KAAKP,IAAIgH,SAAWzG,KAAKP,IAAIiH,OAEzC1G,KAAK8F,eAAiB,KACtB9F,KAAK+F,gBAAkB,KACvB/F,KAAKgG,aAAe,KACpBhG,KAAKkG,cAAgB,KA5CzB,kDA+CE,SAAsBhB,GAIpB,OAHAlF,KAAK4F,OAAS1G,EAAYyH,aAC1B3G,KAAKwE,cAAgBU,EAAIV,cACzBxE,KAAKoF,QAAQwB,KAAO1B,EAAIqB,QACjBvG,OAnDX,yBAsDE,SAAmBkF,GAiBjB,OAhBAlF,KAAK4F,OAAS1G,EAAY2H,SAC1B7G,KAAKwE,cAAgBU,EAAIV,cACzBxE,KAAKqF,SAAWH,EAAIqB,QAEhBvG,KAAKqF,UAAYrF,KAAKqF,SAASlD,SACW,MAAxCnC,KAAKqF,SAASlD,OAAO,kBACvBnC,KAAK8E,YAAc9E,KAAKqF,SAASlD,OAAO,gBAAgB,GAAG2E,MAAM,KAAK,GAClE9G,KAAK8E,YAAYiC,SAAS,gBAAe/G,KAAK8E,YAAc,eAEpB,MAA1C9E,KAAKqF,SAASlD,OAAO,oBACvBnC,KAAKuF,0BAA2B,EAChCvF,KAAKsF,MAAQzD,SAAS7B,KAAKqF,SAASlD,OAAO,kBAAkB,IAC7DnC,KAAKQ,KAAO8B,EAAQtC,KAAKsF,SAItBtF,OAvEX,6BA0EE,SAAuBkF,GAWrB,OAVAlF,KAAK4F,OAAS1G,EAAY8H,cAC1BhH,KAAKwE,cAAgBU,EAAIV,cACrBxE,KAAKqF,WAAUrF,KAAKqF,SAASuB,KAAO1B,EAAIqB,SAC5CvG,KAAK2F,QAAUF,KAAKC,MACpB1F,KAAKgF,SAAW/B,OAAOjD,KAAK2F,QAAU3F,KAAKwF,WAAa,OAEnDxF,KAAKuF,0BAA4BvF,KAAKqF,UAAYrF,KAAKqF,SAASuB,OACnE5G,KAAKsF,MAAQtF,KAAKqF,SAASuB,KAAK7D,WAChC/C,KAAKQ,KAAO8B,EAAQtC,KAAKsF,QAEpBtF,OArFX,qBAwFE,WACE,MAAO,CACL2E,GAAI3E,KAAK2E,GACTQ,GAAInF,KAAKmF,GACTX,cAAexE,KAAKwE,cACpBI,KAAM5E,KAAKP,IAAImF,KACfC,KAAM7E,KAAK6E,KACXrF,OAAQQ,KAAKoF,QAAQ5F,OACrBuF,WAAY/E,KAAKqF,SAAWpC,OAAOjD,KAAKqF,SAASN,YAAc,YAC/DvE,KAAMR,KAAKQ,KACXwE,SAAUhF,KAAKgF,SACfF,YAAa9E,KAAK8E,eAnGxB,2BAuGE,WACE,OAA4B,OAAxB9E,KAAK8F,iBACT9F,KAAK8F,eAAiB7D,EAAWjC,KAAKoF,UADGpF,KAAK8F,iBAxGlD,yBA6GE,WACE,OAA0B,OAAtB9F,KAAKgG,aAA8BhG,KAAKgG,aACvChG,KAAKiH,gBAINjH,KAAK4F,OAAS1G,EAAYyH,aAAqB,IACnD3G,KAAKgG,cAAe,IAAIkB,aAAcC,OAAOnH,KAAKoF,QAAQwB,MACnD5G,KAAKgG,eALVhG,KAAKgG,aAAe,GACbhG,KAAKgG,gBAjHlB,gCAwHE,WAA4C,IAAD,IACzC,OAAiC,OAA7BhG,KAAKiG,oBAAqCjG,KAAKiG,oBAC/CjG,KAAK4F,OAAS1G,EAAYyH,aAAqB,MAC/C,UAAE3G,KAAKoF,eAAP,iBAAE,EAAcwB,YAAhB,aAAE,EAAoB7D,aAE1B/C,KAAKiG,oBAAsB7C,EAAWpD,KAAKoF,QAAQwB,MAC5C5G,KAAKiG,qBAHkC,OA3HlD,4BAiIE,WACE,OAAIjG,KAAK4F,OAAS1G,EAAY2H,SAAiB,MAClB,OAAzB7G,KAAK+F,kBACT/F,KAAK+F,gBAAkB9D,EAAWjC,KAAKqF,WADGrF,KAAK+F,mBAnInD,0BAwIE,WAA+B,IAAD,EAC5B,OAA2B,OAAvB/F,KAAKkG,cAA+BlG,KAAKkG,cACzClG,KAAK4F,OAAS1G,EAAY2H,SAAiB,GAC1C7G,KAAKoH,iBAINpH,KAAK4F,OAAS1G,EAAY8H,cAAsB,IACpDhH,KAAKkG,eAAgB,IAAIgB,aAAcC,OAAlB,UAAyBnH,KAAKqF,gBAA9B,aAAyB,EAAeuB,MACtD5G,KAAKkG,gBALVlG,KAAKkG,cAAgB,GACdlG,KAAKkG,iBA7IlB,iCAoJE,WAAmD,IAAD,IAM5CpB,EALJ,OAAI9E,KAAKmG,qBAA6BnG,KAAKmG,qBAEvCnG,KAAK4F,OAAS1G,EAAY8H,cAAsB,MAChD,UAAEhH,KAAKqF,gBAAP,iBAAE,EAAeuB,YAAjB,aAAE,EAAqB7D,aAGvB/C,KAAKqF,SAASlD,OAAO,kBAAiB2C,EAAc9E,KAAKqF,SAASlD,OAAO,gBAAgB,IACxF2C,GAEDA,EAAYuC,WAAW,UACzBrH,KAAKmG,qBAAuB,CAC1BmB,KAAM,QACNC,KAAM7E,EAAoB1C,KAAKqF,SAASuB,OAGnC9B,EAAYiC,SAAS,sBAC5B/G,KAAKmG,qBAAuB,CAC1BmB,KAAM,OACNC,KAAMvH,KAAKwH,iBAIRxH,KAAKmG,sBAfa,MAJsB,OAxJnD,gCA8KE,WAAkD,IAAD,EAC/C,OAAInG,KAAKoG,oBAA4BpG,KAAKoG,oBAEtCpG,KAAK4F,OAAS1G,EAAYyH,aAAqB,MAC/C,UAAE3G,KAAKoF,QAAQwB,YAAf,aAAE,EAAmB7D,aAEpB/C,KAAKiH,gBAKC,OAAO7E,KAAKpC,KAAKoF,QAAQjD,OAAO,gBAAgBE,KAAK,OAC9DrC,KAAKoG,oBAAsB,CACzBkB,KAAM,OACNC,KAAMvH,KAAKyH,gBAPbzH,KAAKoG,oBAAsB,CACzBkB,KAAM,SACNC,KAAMvH,KAAK0H,sBASR1H,KAAKoG,qBAdiC,OAlLjD,iCAmME,WAA6C,IAAD,IAC1C,OAAkC,OAA9BpG,KAAKqG,qBAAsCrG,KAAKqG,qBAEhDrG,KAAK4F,OAAS1G,EAAY8H,cAAsB,MAChD,UAAEhH,KAAKqF,gBAAP,iBAAE,EAAeuB,YAAjB,aAAE,EAAqB7D,aAE3B/C,KAAKqG,qBAAuBjD,EAAWpD,KAAKqF,SAASuB,MAC9C5G,KAAKqG,sBAHmC,SAvMnD,KAAapB,EAkBGqB,MAAQ,EA4LxB,IA6CYqB,EA7CNC,EAAkB,CACtB1I,EAAY2G,QACZ3G,EAAYyH,aACZzH,EAAY2H,SACZ3H,EAAY8H,gB,SAyCFW,O,oCAAAA,I,sCAAAA,I,gCAAAA,I,kCAAAA,I,yDAAAA,M,KAWL,IAAME,EAAmB,SAACC,EAA8BzD,GAC7D,GAAIyD,IAAgBH,EAAgBI,cAAgBD,IAAgBH,EAAgBK,cAAe,CACjG,IAAMC,EAAO,IAAInF,WAAW,IAI5B,OAHAmF,EAAK,GAAK,EACVA,EAAK,GAAKH,EACVG,EAAKC,KAAI,IAAIC,aAAcC,OAAO/D,EAAKc,IAAK,GACrC8C,EAGT,IAAI9F,EACAyE,EAEJ,GAAIkB,IAAgBH,EAAgBU,eAAgB,CAAC,IAAD,EAC3BhE,EAAKe,QAAzBwB,EAD+C,EAC/CA,KAASzE,EADsC,4BAE7C,IAAI2F,IAAgBH,EAAgBW,gBAGzC,MAAM,IAAIC,MAAM,wBAH2C,IAAD,EACnClE,EAAKgB,SAAzBuB,EADuD,EACvDA,KAASzE,EAD8C,wBAMxDyE,aAAgB4B,cAAa5B,EAAO,IAAI9D,WAAW8D,IACvD,IAAM6B,EAAW7B,GAAQA,EAAK7D,WAAc6D,EAAK7D,WAAa,EAE1D,qBAAsBZ,EAAOA,eAAeA,EAAOA,OAAO,oBAC1D,sBAAuBA,EAAOA,eAAeA,EAAOA,OAAO,qBAC/DA,EAAOA,OAAO,kBAAoB,CAACc,OAAOwF,IAE1C,IAAMC,GAAc,IAAIP,aAAcC,OAAOO,KAAKC,UAAUzG,IACtDI,EAAM,GAAamG,EAAY3F,WAAa,EAAI0F,EAChDlB,EAAO,IAAIiB,YAAYjG,GACvB0F,EAAO,IAAInF,WAAWyE,GAC5BU,EAAK,GAAK,EACVA,EAAK,GAAKH,EACVG,EAAKC,KAAI,IAAIC,aAAcC,OAAO/D,EAAKc,IAAK,GAC5C8C,EAAKC,IAAIQ,EAAa,IAClBD,GAASR,EAAKC,IAAItB,EAAoB,GAAa8B,EAAY3F,WAAa,GAEhF,IAAM8F,EAAQ,IAAIC,SAASvB,GAI3B,OAHAsB,EAAME,UAAU,GAAQL,EAAY3F,YACpC8F,EAAME,UAAU,GAAaL,EAAY3F,WAAY0F,GAE9CR,GI5HMe,E,kDAtHb,WAAY5J,GAAgB,IAAD,8BACzB,cAAMA,IAEDC,MAAQ,CACXC,MAAM,EACN2J,SAAU,GACV1C,QAAS,IAGX,EAAK3G,YAAc,EAAKA,YAAYC,KAAjB,gBACnB,EAAKC,WAAa,EAAKA,WAAWD,KAAhB,gBAClB,EAAKE,WAAa,EAAKA,WAAWF,KAAhB,gBAXO,E,6CAc3B,SAAUqF,GACRlF,KAAKC,SAAS,CAAEgJ,SAAU/D,M,yBAG5B,WACElF,KAAKC,SAAS,CAAEX,MAAM,M,wBAGxB,WAAc,IACJ+E,EAASrE,KAAKZ,MAAdiF,KAGJkC,EAAU,GAEZA,EADW,aAHAlC,EAAKgB,SAAW,WAAa,WA7HrB,SAACD,GACxB,IAAM8D,EAAS,UAAM9D,EAAQ5F,OAAd,YAAwB4F,EAAQ3F,KACzC0J,EAAcpF,OAAOC,KAAKoB,EAAQjD,QAAQiH,KAAI,SAAAlF,GAClD,IAAMmF,EAASjE,EAAQjD,OAAO+B,GAAK7B,KAAK,QACxC,MAAM,GAAN,OAAU6B,EAAV,aAAkBmF,MACjBhH,KAAK,MAEJiH,EAAY,GAGhB,OAFIlE,EAAQwB,MAAQ3E,EAAWmD,KAAUkE,GAAY,IAAIpC,aAAcC,OAAO/B,EAAQwB,OAEhF,GAAN,OAAUsC,EAAV,eAA0BC,EAA1B,eAA4CG,GAuH9BC,CAAiBlF,EAAKe,SArFZ,SAACC,GACzB,IAAM6D,EAAS,UAAM7D,EAASN,YACxBoE,EAAcpF,OAAOC,KAAKqB,EAASlD,QAAQiH,KAAI,SAAAlF,GACnD,IAAMmF,EAAShE,EAASlD,OAAO+B,GAAK7B,KAAK,QACzC,MAAM,GAAN,OAAU6B,EAAV,aAAkBmF,MACjBhH,KAAK,MAEJiH,EAAY,GAGhB,OAFIjE,EAASuB,MAAQ3E,EAAWoD,KAAWiE,GAAY,IAAIpC,aAAcC,OAAO9B,EAASuB,OAEnF,GAAN,OAAUsC,EAAV,eAA0BC,EAA1B,eAA4CG,GA6E9BE,CAAkBnF,EAAKgB,UAGnCrF,KAAKC,SAAS,CAAEX,MAAM,EAAM2J,SAAU,GAAI1C,c,wBAG5C,WAAc,IAENkD,EADWzJ,KAAKZ,MAAdiF,KACUgB,SAAW,WAAa,UAElCkB,EAAYvG,KAAKX,MAAjBkH,QAER,GAAa,YAATkD,EAAoB,CACtB,IAAMrE,EAnIS,SAACmB,GACpB,IAAMmD,EAAanD,EAAQoD,QAAQ,QACnC,KAAID,GAAc,GAAlB,CAEA,IAJ8D,EAI5CnD,EAAQqD,MAAM,EAAGF,GACH5C,MAAM,KALwB,mBAKvDtH,EALuD,KAK/CC,EAL+C,KAM9D,GAAKD,GAAWC,EAAhB,CAEA,IAAMoK,EAActD,EAAQoD,QAAQ,OAAQD,EAAa,GACzD,KAAIG,GAAe,GAAnB,CACA,IAV8D,EAUxDV,EAAc5C,EAAQqD,MAAMF,EAAa,EAAGG,GAC5C1H,EAAiB,GAXuC,cAY3CgH,EAAYrC,MAAM,OAZyB,IAY9D,2BAA4C,CAAC,IAAD,UACjBA,MAAM,MADW,mBACnC5C,EADmC,KAC9B4F,EAD8B,KAE1C,IAAK5F,IAAQ4F,EAAM,OACnB3H,EAAO+B,GAAO4F,EAAKhD,MAAM,SAfmC,8BAkB9D,IACIF,EADE0C,EAAY/C,EAAQqD,MAAMC,EAAc,GAI9C,OAFIP,IAAW1C,GAAO,IAAIuB,aAAcC,OAAOkB,IAExC,CACL9J,SACAC,MACAsK,MAAO,GACP5H,SACAyE,WAwGkBoD,CAAazD,GAC7B,IAAKnB,EAEH,YADApF,KAAKiK,UAAU,eAIjBjK,KAAKZ,MAAM8K,gBAAgB9E,GAC3BpF,KAAKJ,kBACA,CACL,IAAMyF,EAhGU,SAACkB,GACrB,IAAMmD,EAAanD,EAAQoD,QAAQ,QACnC,KAAID,GAAc,GAAlB,CAEA,IAAMR,EAAY3C,EAAQqD,MAAM,EAAGF,GAC7B3E,EAAalD,SAASqH,GAC5B,IAAI1G,MAAMuC,GAAV,CAEA,IAAM8E,EAActD,EAAQoD,QAAQ,OAAQD,EAAa,GACzD,KAAIG,GAAe,GAAnB,CACA,IAVgE,EAU1DV,EAAc5C,EAAQqD,MAAMF,EAAa,EAAGG,GAC5C1H,EAAiB,GAXyC,cAY7CgH,EAAYrC,MAAM,OAZ2B,IAYhE,2BAA4C,CAAC,IAAD,UACjBA,MAAM,MADW,mBACnC5C,EADmC,KAC9B4F,EAD8B,KAE1C,IAAK5F,IAAQ4F,EAAM,OACnB3H,EAAO+B,GAAO4F,EAAKhD,MAAM,SAfqC,8BAkBhE,IACIF,EADE0C,EAAY/C,EAAQqD,MAAMC,EAAc,GAI9C,OAFIP,IAAW1C,GAAO,IAAIuB,aAAcC,OAAOkB,IAExC,CACLvE,aACA5C,SACAyE,WAuEmBuD,CAAc5D,GAC/B,IAAKlB,EAEH,YADArF,KAAKiK,UAAU,eAIjBjK,KAAKZ,MAAMgL,iBAAiB/E,GAC5BrF,KAAKJ,iB,oBAIT,WAAU,IAAD,OACCyE,EAASrE,KAAKZ,MAAdiF,KACR,IAAKA,EAAKG,cAAe,OAAO,KAFzB,IAICyE,EAAajJ,KAAKX,MAAlB4J,SAEFQ,EAAOpF,EAAKgB,SAAW,WAAa,UAE1C,OACE,sBAAKZ,UAAU,iBAAf,UAEE,cAAClE,EAAA,EAAD,CAAQC,KAAK,KAAKC,QAAST,KAAKF,WAAhC,kBAEA,cAACS,EAAA,EAAD,CAAQC,KAAK,KAAKC,QAAS,WACzB,IAAM4J,EAAmB,aAATZ,EAAsB9B,EAAgBW,gBAAkBX,EAAgBU,eAClFnD,EAAM2C,EAAiBwC,EAAShG,GACtC,EAAKjF,MAAMkL,UAAUpF,IAHvB,sBAMA,cAAC3E,EAAA,EAAD,CAAQC,KAAK,KAAKC,QAAS,WACzB,IAAM4J,EAAmB,aAATZ,EAAsB9B,EAAgBK,cAAgBL,EAAgBI,aAChF7C,EAAM2C,EAAiBwC,EAAShG,GACtC,EAAKjF,MAAMkL,UAAUpF,IAHvB,kBAOA,eAACxE,EAAA,EAAD,CAAOF,KAAK,KAAKlB,KAAMU,KAAKX,MAAMC,KAAMqB,OAAQX,KAAKJ,YAArD,UACE,cAACc,EAAA,EAAME,OAAP,CAAcC,aAAW,EAAzB,SACE,eAACH,EAAA,EAAMI,MAAP,mBAA4B,YAAT2I,EAAqB,UAAY,gBAGtD,eAAC/I,EAAA,EAAMK,KAAP,WACE,cAACC,EAAA,EAAKC,MAAN,UACE,cAACD,EAAA,EAAKQ,QAAN,CAAcN,GAAG,WAAWqJ,KAAM,GAAI9I,MAAOzB,KAAKX,MAAMkH,QAAS7E,SAAU,SAAAC,GAAO,EAAK1B,SAAS,CAAEsG,QAAS5E,EAAEC,OAAOH,aAGnHwH,EAAkB,cAACuB,EAAA,EAAD,CAAOlK,QAAQ,SAAf,SAAyB2I,IAAhC,QAIhB,eAACvI,EAAA,EAAMoB,OAAP,WACE,cAACvB,EAAA,EAAD,CAAQD,QAAQ,YAAYG,QAAST,KAAKJ,YAA1C,mBAGA,cAACW,EAAA,EAAD,CAAQD,QAAQ,UAAUG,QAAST,KAAKD,WAAxC,+B,GA5GWgC,IAAMC,WCoLdyI,E,kDAxQb,WAAYrL,GAAgB,IAAD,8BACzB,cAAMA,IAEDC,MAAQ,CACXqL,QAAS,UACTC,QAAQ,EACRC,mBAAoB,MACpBC,uBAAuB,GAPA,E,2CAW3B,WAAW,IACDxG,EAASrE,KAAKZ,MAAdiF,KACR,IAAKA,EAAM,OAAO,KAClB,IAAMgB,EAAWhB,EAAKgB,SACtB,IAAKA,EAAU,OAAO,KAEtB,IAAMA,EAASuB,OAAQvB,EAASuB,KAAK7D,WACnC,OAAO,qBAAK+H,MAAO,CAAEC,MAAO,QAArB,yBAGT,IAAMC,EAAK3G,EAAK4G,sBAChB,OAAKD,EAEW,UAAZA,EAAG1D,KACE,qBAAK4D,IAAG,gCAA2BF,EAAGzD,QAE1B,SAAZyD,EAAG1D,KACH,8BAAK,cAAC,IAAD,CAAYC,KAAMyD,EAAGzD,KAAM4D,SAAU,0BAA2BC,YAAa,yBAA0BC,WAAY,wBAAyBC,aAAc,8BAGjK,qBAAKR,MAAO,CAAEC,MAAO,QAArB,iCATS,qBAAKD,MAAO,CAAEC,MAAO,QAArB,mC,gCAYlB,WAAsB,IACZ1G,EAASrE,KAAKZ,MAAdiF,KACR,IAAKA,EAAM,OAAO,KAElB,IAAM2G,EAAK3G,EAAKkH,qBAChB,OAAKP,EAEW,SAAZA,EAAG1D,KACE,8BAAK,cAAC,IAAD,CAAYC,KAAMyD,EAAGzD,KAAM4D,SAAU,0BAA2BC,YAAa,yBAA0BC,WAAY,wBAAyBC,aAAc,8BAEnJ,WAAZN,EAAG1D,KACH,8BAAK,8BAAM0D,EAAGzD,SAGhB,qBAAKuD,MAAO,CAAEC,MAAO,QAArB,iCATS,qBAAKD,MAAO,CAAEC,MAAO,QAArB,mC,qBAYlB,WAAW,IACD1G,EAASrE,KAAKZ,MAAdiF,KACR,IAAKA,EAAM,OAAO,KAClB,IAAMgB,EAAWhB,EAAKgB,SACtB,OAAKA,EAECA,EAASuB,MAAQvB,EAASuB,KAAK7D,WAI9B,8BAAMsB,EAAKmH,wBAHT,qBAAKV,MAAO,CAAEC,MAAO,QAArB,yBAHa,O,oBASxB,WAAU,IAAD,OACP,IAAK/K,KAAKZ,MAAMiF,KAAM,OAAO,KAE7B,IAAMA,EAAOrE,KAAKZ,MAAMiF,KAClBqG,EAAU1K,KAAKX,MAAMqL,QAErBtF,EAAUf,EAAKe,QACfC,EAAuBhB,EAAKgB,UAAY,GAGxCoG,EAAqD,GAO3D,OANIpH,EAAK5E,KAAO4E,EAAK5E,IAAIiH,QACvBrC,EAAK5E,IAAIiM,aAAaC,SAAQ,SAAClK,EAAOyC,GACpCuH,EAAYtL,KAAK,CAAE+D,MAAKzC,aAK1B,sBAAKgD,UAAU,cAAf,UACE,sBAAKA,UAAU,cAAf,UACE,sBAAMhE,QAAS,WAAQ,EAAKrB,MAAMwM,WAAlC,eACA,sBAAMnH,UAAuB,YAAZiG,EAAwB,gBAAavG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAEyK,QAAS,aAA3G,qBACA,sBAAMjG,UAAuB,YAAZiG,EAAwB,gBAAavG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAEyK,QAAS,aAA3G,qBACA,sBAAMjG,UAAuB,aAAZiG,EAAyB,gBAAavG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAEyK,QAAS,cAA5G,sBACA,sBAAMjG,UAAuB,YAAZiG,EAAwB,gBAAavG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAEyK,QAAS,aAA3G,qBAEA,cAAC,EAAD,CACErG,KAAMA,EACN6F,gBAAiB,SAAA9E,GACff,EAAKe,QAAQ5F,OAAS4F,EAAQ5F,OAC9B6E,EAAKe,QAAQ3F,IAAM2F,EAAQ3F,IAC3B4E,EAAKe,QAAQjD,OAASiD,EAAQjD,OAC1BF,EAAWoC,EAAKe,WAAUf,EAAKe,QAAQwB,KAAOxB,EAAQwB,MAC1D,EAAKxH,MAAMyM,mBAEbzB,iBAAkB,SAAA/E,GACXhB,EAAKgB,WAAUhB,EAAKgB,SAAW,IAEpChB,EAAKgB,SAASN,WAAaM,EAASN,WACpCV,EAAKgB,SAASlD,OAASkD,EAASlD,OAC5BF,EAAWoC,EAAKgB,YAAWhB,EAAKgB,SAASuB,KAAOvB,EAASuB,MAC7D,EAAKxH,MAAMyM,mBAEbvB,UAAW,SAAApF,GACT,EAAK9F,MAAMkL,UAAUpF,GACrBb,EAAKG,eAAgB,EACrB,EAAKpF,MAAMyM,wBAMjB,sBAAKf,MAAO,CAAEgB,QAAS,QAAvB,UAEkB,YAAZpB,EAAyB,KACzB,gCACE,4BAAG,cAACnK,EAAA,EAAD,CAAQC,KAAK,KAAKF,QAASN,KAAKX,MAAMsL,OAAS,UAAY,UAAWoB,SAAU/L,KAAKX,MAAMsL,OAAQlK,QAAS,WAC7G,IAAMuL,EAAOC,IAAY,CACvBxM,IAAK4E,EAAKe,QAAQ3F,IAClBD,OAAQ6E,EAAKe,QAAQ5F,OACrB0M,QAASnI,OAAOC,KAAKK,EAAKe,QAAQjD,QAAQgK,QAAO,SAACC,EAAUlI,GAE1D,OADAkI,EAAIlI,GAAOG,EAAKe,QAAQjD,OAAO+B,GAAK,GAC7BkI,IACN,IACHxF,KAAMvC,EAAKoD,gBAEb4E,IAAKL,GAEL,EAAK/L,SAAS,CAAE0K,QAAQ,IAAQ,WAC9B2B,YAAW,WACT,EAAKrM,SAAS,CAAE0K,QAAQ,MACvB,SAfJ,SAkBC3K,KAAKX,MAAMsL,OAAS,SAAW,mBAEnC,sBAAKlG,UAAU,eAAf,UACE,wCACA,sBAAKA,UAAU,uBAAf,UACE,8CAAiBW,EAAQ3F,OACzB,iDAAoB2F,EAAQ5F,UAC5B,wDAAoB6F,EAASN,YAAc,sBAK3CM,EAASlD,OACT,sBAAKsC,UAAU,eAAf,UACE,iDACA,qBAAKA,UAAU,uBAAf,SAEIV,OAAOC,KAAKqB,EAASlD,QAAQiH,KAAI,SAAAlF,GAC/B,OACE,8BAAcA,EAAd,KAAqBmB,EAASlD,OAAO+B,GAAK7B,KAAK,OAAvC6B,WAPC,KAevB,sBAAKO,UAAU,eAAf,UACE,gDACA,qBAAKA,UAAU,uBAAf,SAEMW,EAAQjD,OACR4B,OAAOC,KAAKoB,EAAQjD,QAAQiH,KAAI,SAAAlF,GAC9B,OACE,8BAAcA,EAAd,KAAqBkB,EAAQjD,OAAO+B,GAAK7B,KAAK,OAAtC6B,MAHM,UAWtBuH,EAAYpL,OACZ,sBAAKoE,UAAU,eAAf,UACE,wDACA,qBAAKA,UAAU,uBAAf,SAEIgH,EAAYrC,KAAI,YAAqB,IAAlBlF,EAAiB,EAAjBA,IAAKzC,EAAY,EAAZA,MACtB,OACE,8BAAcyC,EAAd,KAAqBzC,IAAbyC,WAPI,KAgBtBkB,EAAQwB,MAAQxB,EAAQwB,KAAK7D,WAC7B,sBAAK0B,UAAU,eAAf,UACE,6CACA,qBAAKA,UAAU,uBAAf,SACE,gCACE,sBAAKA,UAAU,sBAAsBqG,MAAO,CAAEyB,aAAc,QAA5D,UACE,sBAAM9H,UAA6C,QAAlCzE,KAAKX,MAAMuL,mBAA+B,gBAAazG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAE2K,mBAAoB,SAAxI,iBACA,sBAAMnG,UAA6C,YAAlCzE,KAAKX,MAAMuL,mBAAmC,gBAAazG,EAAW1D,QAAS,WAAQ,EAAKR,SAAS,CAAE2K,mBAAoB,aAA5I,wBAIoC,QAAlC5K,KAAKX,MAAMuL,mBAAgC,KAC3C,8BAEMvG,EAAK4C,gBAA6E5C,EAAKoD,cAA/D,sBAAMqD,MAAO,CAAEC,MAAO,QAAtB,gCAMI,YAAlC/K,KAAKX,MAAMuL,mBAAoC,KAC/C,8BAAM5K,KAAKwM,+BArBsB,QAgCrC,aAAZ9B,EAA0B,KACxBrF,EAASuB,MAAQvB,EAASuB,KAAK7D,WAC7BsB,EAAK+C,iBACL,gCACE,qBAAK0D,MAAO,CAAEyB,aAAc,QAA5B,SACE,cAACE,EAAA,EAAD,CACEC,QAAM,EACNpF,KAAK,WACLqF,QAAS3M,KAAKX,MAAMwL,sBACpBnJ,SAAU,SAAAC,GACR,EAAK1B,SAAS,CAAE4K,sBAAuBlJ,EAAEC,OAAO+K,WAElDC,MAAM,+BAEV,qBAAK9B,MAAO,CAAE+B,WAAY7M,KAAKX,MAAMwL,sBAAwB,WAAa,OAA1E,SACGxG,EAAKmD,oBAbe,qBAAKsD,MAAO,CAAEC,MAAO,QAArB,+BADkB,qBAAKD,MAAO,CAAEC,MAAO,QAArB,yBAoBnC,YAAZL,EAAyB,KACzB,8BAAM1K,KAAK8M,YAIC,YAAZpC,EAAyB,KACzB,8BAAM1K,KAAK+M,sB,GAhQFhL,IAAMC,WCvBhBgL,EAAb,WAQE,aAAe,yBAPPC,WAOM,OANNC,UAMM,OALNC,gBAKM,OAJNC,iBAIM,OAHNC,SAGM,OAFNC,SAEM,EACZtN,KAAKiN,MAAQ,GACbjN,KAAKkN,KAAO,IAAIK,IAChBvN,KAAKmN,WAAa,GAClBnN,KAAKoN,YAAc,KACnBpN,KAAKqN,IAAM,EAEXrN,KAAKsN,IAAM,IAff,4CAkBE,WACE,IAAIE,EAAOxN,KAAKmN,WAEhB,GADIK,IAAMA,EAAOA,EAAKC,SACjBD,EAAM,OAAOxN,KAAKiN,MAGvB,GAAIO,EAAKnG,WAAW,MAAQmG,EAAKE,SAAS,KAAM,CAE9C,KADAF,EAAOA,EAAK5D,MAAM,EAAG4D,EAAKnN,OAAS,GAAGoN,QAC3B,OAAOzN,KAAKiN,MACvB,IACE,IAAMU,EAAM,IAAIC,OAAOJ,GACvB,OAAOxN,KAAKiN,MAAMY,QAAO,SAAAC,GACvB,OAAOH,EAAIvL,KAAK0L,EAAK1I,QAAQ3F,QAE/B,MAAOsO,GACP,OAAO/N,KAAKiN,OAIhB,OAAOjN,KAAKiN,MAAMY,QAAO,SAAAC,GACvB,OAAOA,EAAK1I,QAAQ3F,IAAIsH,SAASyG,QAtCvC,iBA0CE,SAAIM,GAKF,GAJAA,EAAKnJ,KAAO3E,KAAKqN,IACjBrN,KAAKiN,MAAM9M,KAAK2N,GAChB9N,KAAKkN,KAAKhF,IAAI4F,EAAK3I,GAAI2I,GAEnB9N,KAAKiN,MAAM5M,OAASL,KAAKsN,IAAK,CAChC,IAAMU,EAAShO,KAAKiN,MAAMgB,QACtBD,GAAQhO,KAAKkN,KAAKgB,OAAOF,EAAO7I,OAjD1C,iBAqDE,SAAIA,GACF,OAAOnF,KAAKkN,KAAKiB,IAAIhJ,KAtDzB,0BAyDE,SAAaqI,GACXxN,KAAKmN,WAAaK,IA1DtB,8BA6DE,SAAiBA,EAAcY,GAAuB,IAAD,OAC/CpO,KAAKoN,cACPiB,aAAarO,KAAKoN,aAClBpN,KAAKoN,YAAc,MAGrBpN,KAAKoN,YAAcd,YAAW,WAC5B,EAAKa,WAAaK,EAClBY,MACC,OAtEP,mBAyEE,WACEpO,KAAKiN,MAAQ,GACbjN,KAAKkN,KAAO,IAAIK,QA3EpB,KCiMee,E,kDAxKb,WAAYlP,GAAa,IAAD,8BACtB,cAAMA,IAPAmP,aAMgB,IALhBC,QAKgB,IAHhBC,gBAGgB,IAFhBC,WAAY,EAKlB,EAAKH,QAAU,IAAIvB,EAEnB,EAAK3N,MAAQ,CACXsP,MAAO,EAAKJ,QAAQK,WACpBvK,KAAM,KAENqG,QAAS,WAGX,EAAK8D,GAAK,KACV,EAAKC,WAAa,KAbI,E,qDAgBxB,WACEzO,KAAK6O,W,kCAGP,WACM7O,KAAKwO,IACPxO,KAAKwO,GAAGM,U,oBAIZ,WAAU,IAGJlK,EAHG,OACH5E,KAAKwO,KAMP5J,EAAO,IAAI4B,IAAIuI,SAASvI,KAAK5B,KAE/B5E,KAAKwO,GAAK,IAAIQ,UAAJ,eAAsBpK,EAAtB,UACV5E,KAAKwO,GAAGS,WAAa,cACrBjP,KAAKwO,GAAGU,OAAS,WAAQC,QAAQC,IAAI,SACrCpP,KAAKwO,GAAGa,QAAU,WAAQF,QAAQC,IAAI,UACtCpP,KAAKwO,GAAGc,UAAY,SAAAC,GAClB,IAAMrK,EPwMgB,SAACqC,GAC3B,GAAIA,EAAKxE,WAAa,GAAI,OAAO,KACjC,IAAMyM,EAAO,IAAIC,UAAUlI,EAAKqC,MAAM,EAAG,KAEzC,GAAgB,IADA4F,EAAK,GACF,OAAO,KAC1B,IAAMlI,EAAOkI,EAAK,GAClB,IAAK5H,EAAgBb,SAASO,GAAO,OAAO,KAC5C,IAGMoI,EAAiB,CACrBpI,OACAnC,IALS,IAAI+B,aAAcC,OAAOI,EAAKqC,MAAM,EAAG,KAMhDpF,cALiC,IAAbgL,EAAK,KAO3B,GAAwB,KAApBjI,EAAKxE,WAAmB,OAAO2M,EACnC,GAAIpI,IAASpI,EAAYyH,cAAgBW,IAASpI,EAAY8H,cAE5D,OADA0I,EAAKnJ,QAAUgB,EAAKqC,MAAM,IACnB8F,EAGT,IACInJ,EADEoJ,GAAa,IAAIzI,aAAcC,OAAOI,EAAKqC,MAAM,KAEvD,IACErD,EAAUoC,KAAKiH,MAAMD,GACrB,MAAO5B,GACP,OAAO,KAIT,OADA2B,EAAKnJ,QAAUA,EACRmJ,EOtOSG,CAAaN,EAAIhI,MAC7B,GAAKrC,GAML,GAAIA,EAAIoC,OAASpI,EAAY2G,QAAS,CACpC,IAAMxB,EAAO,IAAIY,EAAKC,GACtB,EAAKqJ,QAAQuB,IAAIzL,GACjB,EAAKpE,SAAS,CAAE0O,MAAO,EAAKJ,QAAQK,aAAc,WAC5C,EAAKH,YAAc,EAAKC,WAAW,EAAKD,WAAWsB,eAAe,CAAEC,SAAU,iBAGjF,GAAI9K,EAAIoC,OAASpI,EAAYyH,aAAc,CAC9C,IAAMtC,EAAO,EAAKkK,QAAQJ,IAAIjJ,EAAIC,IAClC,IAAKd,EAAM,OACXA,EAAK4L,eAAe/K,GACpB,EAAKjF,SAAS,CAAE0O,MAAO,EAAKtP,MAAMsP,aAE/B,GAAIzJ,EAAIoC,OAASpI,EAAY2H,SAAU,CAC1C,IAAMxC,EAAO,EAAKkK,QAAQJ,IAAIjJ,EAAIC,IAClC,IAAKd,EAAM,OACXA,EAAK6L,YAAYhL,GACjB,EAAKjF,SAAS,CAAE0O,MAAO,EAAKtP,MAAMsP,aAE/B,GAAIzJ,EAAIoC,OAASpI,EAAY8H,cAAe,CAC/C,IAAM3C,EAAO,EAAKkK,QAAQJ,IAAIjJ,EAAIC,IAClC,IAAKd,IAASA,EAAKgB,SAAU,OAC7BhB,EAAK8L,gBAAgBjL,GACrB,EAAKjF,SAAS,CAAE0O,MAAO,EAAKtP,MAAMsP,cA5BlCQ,QAAQiB,MAAM,eAAgBb,EAAIhI,OA+BtCvH,KAAKwO,GAAG6B,QAAU,SAAAd,GAChBJ,QAAQC,IAAI,SAAUG,O,+BAI1B,WAAqB,IAAD,OAClB,GAAKvP,KAAKyO,WAAV,CAEA,IAAM6B,EAAUC,IAAcC,OAAOxQ,KAAKyO,YAC1C6B,EAAQG,eAAc,WACpB,EAAK/B,WAAY,KAEnB4B,EAAQI,cAAa,WACnB,EAAKhC,WAAY,Q,oBAIrB,WAAU,IAAD,OACCC,EAAU3O,KAAKX,MAAfsP,MACR,OACE,sBAAKlK,UAAU,kBAAf,UACE,sBAAKA,UAAU,cAAf,UACE,8BAAK,cAAClE,EAAA,EAAD,CAAQC,KAAK,KAAKC,QAAS,WAC9B,EAAK8N,QAAQoC,QACb,EAAK1Q,SAAS,CAAE0O,MAAO,EAAKJ,QAAQK,WAAYvK,KAAM,QAFnD,qBAIL,8BACE,cAACrD,EAAA,EAAKQ,QAAN,CACEhB,KAAK,KAAKoQ,YAAY,SACtBlP,SAAU,SAACC,GACT,IAAMF,EAAQE,EAAEC,OAAOH,MACvB,EAAK8M,QAAQsC,iBAAiBpP,GAAO,WACnC,EAAKxB,SAAS,CAAE0O,MAAO,EAAKJ,QAAQK,qBAO5C,cAAC,EAAD,CAAYxO,OAAQ,SAAAF,GAClB,IAAMgF,EP4Nc,SAAC4C,EAA8B5H,GAC7D,GAAI4H,IAAgBH,EAAgBmJ,yBAClC,MAAM,IAAIvI,MAAM,wBAGlB,IAAMwI,GAAa,IAAI5I,aAAcC,OAAOO,KAAKC,UAAU1I,IACrD+H,EAAO,IAAInF,WAAW,EAAIiO,EAAWhO,YAK3C,OAJAkF,EAAK,GAAK,EACVA,EAAK,GAAKH,EACVG,EAAKC,IAAI6I,EAAY,GAEd9I,EOvOe+I,CAAiBrJ,EAAgBmJ,yBAA0B5Q,GACnE,EAAKsO,IAAI,EAAKA,GAAGyC,KAAK/L,SAI9B,eAACgM,EAAA,EAAD,CAAOC,SAAO,EAACC,UAAQ,EAAC5Q,KAAK,KAAKsK,MAAO,CAAEuG,YAAa,SAAxD,UACE,gCACE,+BACE,oBAAIvG,MAAO,CAAEwG,MAAO,QAApB,gBACA,oBAAIxG,MAAO,CAAEwG,MAAO,QAApB,oBACA,oBAAIxG,MAAO,CAAEwG,MAAO,SAApB,kBACA,oBAAIxG,MAAO,CAAEwG,MAAO,SAApB,kBACA,oBAAIxG,MAAO,CAAEwG,MAAO,SAApB,kBACA,oBAAIxG,MAAO,CAAEwG,MAAO,QAApB,oBACA,oBAAIxG,MAAO,CAAEwG,MAAO,QAApB,kBACA,oBAAIxG,MAAO,CAAEwG,MAAO,QAApB,uBAGJ,gCAEI3C,EAAMvF,KAAI,SAAAmI,GACR,IAAMjN,EAAKiN,EAAEzE,UAEb,OACE,cAAC,EAAD,CAEEzI,KAAMC,EACNX,cAAa,EAAKtE,MAAMgF,MAAQ,EAAKhF,MAAMgF,KAAKc,KAAOb,EAAGa,IAC1DT,aAAc,WACZ,EAAKzE,SAAS,CAAEoE,KAAMkN,MAJnBjN,EAAGa,YAapB,cAAC,EAAD,CACEd,KAAMrE,KAAKX,MAAMgF,KACjBuH,QAAS,WAAQ,EAAK3L,SAAS,CAAEoE,KAAM,QACvCwH,gBAAiB,WAAQ,EAAK5L,SAAS,CAAE0O,MAAO,EAAKtP,MAAMsP,SAC3DrE,UAAW,SAAApF,GAAa,EAAKsJ,IAAI,EAAKA,GAAGyC,KAAK/L,MAGhD,qBAAKsM,IAAK,SAAAC,GACJ,EAAKhD,aACT,EAAKA,WAAagD,EAClB,EAAKC,sBACJ5G,MAAO,CAAE6G,OAAQ,MAAOC,WAAY,UAJvC,2B,GArKU7P,IAAMC,WCNT6P,EAZS,SAACC,GACnBA,GAAeA,aAAuBC,UACxC,6BAAqBC,MAAK,YAAkD,IAA/CC,EAA8C,EAA9CA,OAAQC,EAAsC,EAAtCA,OAAQC,EAA8B,EAA9BA,OAAQC,EAAsB,EAAtBA,OAAQC,EAAc,EAAdA,QAC3DJ,EAAOH,GACPI,EAAOJ,GACPK,EAAOL,GACPM,EAAON,GACPO,EAAQP,OCHdQ,IAASC,OACP,cAAC,IAAMC,WAAP,UACE,cAAC,EAAD,MAEFzD,SAAS0D,eAAe,SAM1BZ,M","file":"static/js/main.6bbef4b6.chunk.js","sourcesContent":["import { arrayBufferToBase64, bufHexView, getSize, isTextBody } from './utils'\n\nexport enum MessageType {\n REQUEST = 1,\n REQUEST_BODY = 2,\n RESPONSE = 3,\n RESPONSE_BODY = 4,\n}\n\nexport type Header = Record<string, string[]>\n\nexport interface IRequest {\n method: string\n url: string\n proto: string\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IResponse {\n statusCode: number\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IMessage {\n type: MessageType\n id: string\n waitIntercept: boolean\n content?: ArrayBuffer | IRequest | IResponse\n}\n\nexport interface IFlowPreview {\n no: number\n id: string\n waitIntercept: boolean\n host: string\n path: string\n method: string\n statusCode: string\n size: string\n costTime: string\n contentType: string\n}\n\ninterface IPreviewBody {\n type: 'image' | 'json' | 'binary'\n data: string | null\n}\n\nexport class Flow {\n public no: number\n public id: string\n public waitIntercept: boolean\n public request: IRequest\n public response: IResponse | null = null\n\n public url: URL\n private path: string\n private _size = 0\n private size = '0'\n private headerContentLengthExist = false\n private contentType = ''\n\n private startTime = Date.now()\n private endTime = 0\n private costTime = '(pending)'\n\n public static curNo = 0\n\n private status: MessageType = MessageType.REQUEST\n\n private _isTextRequest: boolean | null\n private _isTextResponse: boolean | null\n private _requestBody: string | null\n private _hexviewRequestBody: string | null = null\n private _responseBody: string | null\n\n private _previewResponseBody: IPreviewBody | null = null\n private _previewRequestBody: IPreviewBody | null = null\n private _hexviewResponseBody: string | null = null\n\n constructor(msg: IMessage) {\n this.no = ++Flow.curNo\n this.id = msg.id\n this.waitIntercept = msg.waitIntercept\n this.request = msg.content as IRequest\n\n this.url = new URL(this.request.url)\n this.path = this.url.pathname + this.url.search\n\n this._isTextRequest = null\n this._isTextResponse = null\n this._requestBody = null\n this._responseBody = null\n }\n\n public addRequestBody(msg: IMessage): Flow {\n this.status = MessageType.REQUEST_BODY\n this.waitIntercept = msg.waitIntercept\n this.request.body = msg.content as ArrayBuffer\n return this\n }\n\n public addResponse(msg: IMessage): Flow {\n this.status = MessageType.RESPONSE\n this.waitIntercept = msg.waitIntercept\n this.response = msg.content as IResponse\n\n if (this.response && this.response.header) {\n if (this.response.header['Content-Type'] != null) {\n this.contentType = this.response.header['Content-Type'][0].split(';')[0]\n if (this.contentType.includes('javascript')) this.contentType = 'javascript'\n }\n if (this.response.header['Content-Length'] != null) {\n this.headerContentLengthExist = true\n this._size = parseInt(this.response.header['Content-Length'][0])\n this.size = getSize(this._size)\n }\n }\n\n return this\n }\n\n public addResponseBody(msg: IMessage): Flow {\n this.status = MessageType.RESPONSE_BODY\n this.waitIntercept = msg.waitIntercept\n if (this.response) this.response.body = msg.content as ArrayBuffer\n this.endTime = Date.now()\n this.costTime = String(this.endTime - this.startTime) + ' ms'\n\n if (!this.headerContentLengthExist && this.response && this.response.body) {\n this._size = this.response.body.byteLength\n this.size = getSize(this._size)\n }\n return this\n }\n\n public preview(): IFlowPreview {\n return {\n no: this.no,\n id: this.id,\n waitIntercept: this.waitIntercept,\n host: this.url.host,\n path: this.path,\n method: this.request.method,\n statusCode: this.response ? String(this.response.statusCode) : '(pending)',\n size: this.size,\n costTime: this.costTime,\n contentType: this.contentType,\n }\n }\n\n public isTextRequest(): boolean {\n if (this._isTextRequest !== null) return this._isTextRequest\n this._isTextRequest = isTextBody(this.request)\n return this._isTextRequest\n }\n\n public requestBody(): string {\n if (this._requestBody !== null) return this._requestBody\n if (!this.isTextRequest()) {\n this._requestBody = ''\n return this._requestBody\n }\n if (this.status < MessageType.REQUEST_BODY) return ''\n this._requestBody = new TextDecoder().decode(this.request.body)\n return this._requestBody\n }\n\n public hexviewRequestBody(): string | null {\n if (this._hexviewRequestBody !== null) return this._hexviewRequestBody\n if (this.status < MessageType.REQUEST_BODY) return null\n if (!(this.request?.body?.byteLength)) return null\n\n this._hexviewRequestBody = bufHexView(this.request.body)\n return this._hexviewRequestBody\n }\n\n public isTextResponse(): boolean | null {\n if (this.status < MessageType.RESPONSE) return null\n if (this._isTextResponse !== null) return this._isTextResponse\n this._isTextResponse = isTextBody(this.response as IResponse)\n return this._isTextResponse\n }\n\n public responseBody(): string {\n if (this._responseBody !== null) return this._responseBody\n if (this.status < MessageType.RESPONSE) return ''\n if (!this.isTextResponse()) {\n this._responseBody = ''\n return this._responseBody\n }\n if (this.status < MessageType.RESPONSE_BODY) return ''\n this._responseBody = new TextDecoder().decode(this.response?.body)\n return this._responseBody\n }\n\n public previewResponseBody(): IPreviewBody | null {\n if (this._previewResponseBody) return this._previewResponseBody\n\n if (this.status < MessageType.RESPONSE_BODY) return null\n if (!(this.response?.body?.byteLength)) return null\n\n let contentType: string | undefined\n if (this.response.header['Content-Type']) contentType = this.response.header['Content-Type'][0]\n if (!contentType) return null\n\n if (contentType.startsWith('image/')) {\n this._previewResponseBody = {\n type: 'image',\n data: arrayBufferToBase64(this.response.body),\n }\n }\n else if (contentType.includes('application/json')) {\n this._previewResponseBody = {\n type: 'json',\n data: this.responseBody(),\n }\n }\n\n return this._previewResponseBody\n }\n\n public previewRequestBody(): IPreviewBody | null {\n if (this._previewRequestBody) return this._previewRequestBody\n\n if (this.status < MessageType.REQUEST_BODY) return null\n if (!(this.request.body?.byteLength)) return null\n\n if (!this.isTextRequest()) {\n this._previewRequestBody = {\n type: 'binary',\n data: this.hexviewRequestBody(),\n }\n } else if (/json/.test(this.request.header['Content-Type'].join(''))) {\n this._previewRequestBody = {\n type: 'json',\n data: this.requestBody(),\n }\n }\n\n return this._previewRequestBody\n }\n\n public hexviewResponseBody(): string | null {\n if (this._hexviewResponseBody !== null) return this._hexviewResponseBody\n\n if (this.status < MessageType.RESPONSE_BODY) return null\n if (!(this.response?.body?.byteLength)) return null\n\n this._hexviewResponseBody = bufHexView(this.response.body)\n return this._hexviewResponseBody\n }\n}\n\nconst allMessageBytes = [\n MessageType.REQUEST,\n MessageType.REQUEST_BODY,\n MessageType.RESPONSE,\n MessageType.RESPONSE_BODY,\n]\n\n\n// type: 1/2/3/4\n// messageFlow\n// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes\nexport const parseMessage = (data: ArrayBuffer): IMessage | null => {\n if (data.byteLength < 39) return null\n const meta = new Int8Array(data.slice(0, 39))\n const version = meta[0]\n if (version !== 1) return null\n const type = meta[1] as MessageType\n if (!allMessageBytes.includes(type)) return null\n const id = new TextDecoder().decode(data.slice(2, 38))\n const waitIntercept = meta[38] === 1\n\n const resp: IMessage = {\n type,\n id,\n waitIntercept,\n }\n if (data.byteLength === 39) return resp\n if (type === MessageType.REQUEST_BODY || type === MessageType.RESPONSE_BODY) {\n resp.content = data.slice(39)\n return resp\n }\n\n const contentStr = new TextDecoder().decode(data.slice(39))\n let content: any\n try {\n content = JSON.parse(contentStr)\n } catch (err) {\n return null\n }\n\n resp.content = content\n return resp\n}\n\n\nexport enum SendMessageType {\n CHANGE_REQUEST = 11,\n CHANGE_RESPONSE = 12,\n DROP_REQUEST = 13,\n DROP_RESPONSE = 14,\n CHANGE_BREAK_POINT_RULES = 21,\n}\n\n// type: 11/12/13/14\n// messageEdit\n// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes]\nexport const buildMessageEdit = (messageType: SendMessageType, flow: Flow) => {\n if (messageType === SendMessageType.DROP_REQUEST || messageType === SendMessageType.DROP_RESPONSE) {\n const view = new Uint8Array(38)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n return view\n }\n\n let header: Omit<IRequest, 'body'> | Omit<IResponse, 'body'>\n let body: ArrayBuffer | Uint8Array | undefined\n\n if (messageType === SendMessageType.CHANGE_REQUEST) {\n ({ body, ...header } = flow.request)\n } else if (messageType === SendMessageType.CHANGE_RESPONSE) {\n ({ body, ...header } = flow.response as IResponse)\n } else {\n throw new Error('invalid message type')\n }\n\n if (body instanceof ArrayBuffer) body = new Uint8Array(body)\n const bodyLen = (body && body.byteLength) ? body.byteLength : 0\n\n if ('Content-Encoding' in header.header) delete header.header['Content-Encoding']\n if ('Transfer-Encoding' in header.header) delete header.header['Transfer-Encoding']\n header.header['Content-Length'] = [String(bodyLen)]\n\n const headerBytes = new TextEncoder().encode(JSON.stringify(header))\n const len = 2 + 36 + 4 + headerBytes.byteLength + 4 + bodyLen\n const data = new ArrayBuffer(len)\n const view = new Uint8Array(data)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n view.set(headerBytes, 2 + 36 + 4)\n if (bodyLen) view.set(body as Uint8Array, 2 + 36 + 4 + headerBytes.byteLength + 4)\n\n const view2 = new DataView(data)\n view2.setUint32(2 + 36, headerBytes.byteLength)\n view2.setUint32(2 + 36 + 4 + headerBytes.byteLength, bodyLen)\n\n return view\n}\n\n\n// type: 21\n// messageMeta\n// version 1 byte + type 1 byte + content left bytes\nexport const buildMessageMeta = (messageType: SendMessageType, rules: any) => {\n if (messageType !== SendMessageType.CHANGE_BREAK_POINT_RULES) {\n throw new Error('invalid message type')\n }\n\n const rulesBytes = new TextEncoder().encode(JSON.stringify(rules))\n const view = new Uint8Array(2 + rulesBytes.byteLength)\n view[0] = 1\n view[1] = messageType\n view.set(rulesBytes, 2)\n\n return view\n}\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Row from 'react-bootstrap/Row'\nimport Col from 'react-bootstrap/Col'\n\ntype Method = 'ALL' | 'GET' | 'POST' | 'PUT' | 'DELETE' | ''\ntype Action = 1 | 2 | 3\ninterface IRule {\n method: Method\n url: string\n action: Action\n}\n\ninterface IState {\n show: boolean\n rule: IRule\n haveRules: boolean\n}\n\ninterface IProps {\n onSave: (rules: IRule[]) => void\n}\n\nclass BreakPoint extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n\n rule: {\n method: 'ALL',\n url: '',\n action: 1,\n },\n\n haveRules: false,\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n this.setState({ show: true })\n }\n\n handleSave() {\n const { rule } = this.state\n const rules: IRule[] = []\n if (rule.url) {\n rules.push({\n method: rule.method === 'ALL' ? '' : rule.method,\n url: rule.url,\n action: rule.action,\n })\n }\n\n this.props.onSave(rules)\n this.handleClose()\n\n this.setState({ haveRules: rules.length ? true : false })\n }\n\n render() {\n const { rule, haveRules } = this.state\n const variant = haveRules ? 'success' : 'primary'\n\n return (\n <div>\n <Button variant={variant} size=\"sm\" onClick={this.handleShow}>BreakPoint</Button>\n\n <Modal show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Set BreakPoint</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Method</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.method} onChange={e => { this.setState({ rule: { ...rule, method: e.target.value as Method } }) }}>\n <option>ALL</option>\n <option>GET</option>\n <option>POST</option>\n <option>PUT</option>\n <option>DELETE</option>\n </Form.Control>\n </Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>URL</Form.Label>\n <Col sm={10}><Form.Control value={rule.url} onChange={e => { this.setState({ rule: { ...rule, url: e.target.value } }) }} /></Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Action</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.action} onChange={e => { this.setState({ rule: { ...rule, action: parseInt(e.target.value) as Action } }) }}>\n <option value=\"1\">Request</option>\n <option value=\"2\">Response</option>\n <option value=\"3\">Both</option>\n </Form.Control>\n </Col>\n </Form.Group>\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n </div>\n )\n }\n}\n\nexport default BreakPoint\n","import { IRequest, IResponse } from './message'\n\nexport const isTextBody = (payload: IRequest | IResponse) => {\n if (!payload) return false\n if (!payload.header) return false\n if (!payload.header['Content-Type']) return false\n\n return /text|javascript|json|x-www-form-urlencoded|xml|form-data/.test(payload.header['Content-Type'].join(''))\n}\n\nexport const getSize = (len: number) => {\n if (!len) return '0'\n if (isNaN(len)) return '0'\n if (len <= 0) return '0'\n\n if (len < 1024) return `${len} B`\n if (len < 1024 * 1024) return `${(len / 1024).toFixed(2)} KB`\n return `${(len / (1024 * 1024)).toFixed(2)} MB`\n}\n\nexport const shallowEqual = (objA: any, objB: any) => {\n if (objA === objB) return true\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n if (keysA.length !== keysB.length) return false\n\n for (let i = 0; i < keysA.length; i++) {\n const key = keysA[i]\n if (objB[key] === undefined || objA[key] !== objB[key]) return false\n }\n return true\n}\n\nexport const arrayBufferToBase64 = (buf: ArrayBuffer) => {\n let binary = ''\n const bytes = new Uint8Array(buf)\n const len = bytes.byteLength\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i])\n }\n return btoa(binary)\n}\n\nexport const bufHexView = (buf: ArrayBuffer) => {\n let str = ''\n const bytes = new Uint8Array(buf)\n const len = bytes.byteLength\n\n let viewStr = ''\n\n str += '00000000: '\n for (let i = 0; i < len; i++) {\n str += bytes[i].toString(16).padStart(2, '0') + ' '\n\n if (bytes[i] >= 32 && bytes[i] <= 126) {\n viewStr += String.fromCharCode(bytes[i])\n } else {\n viewStr += '.'\n }\n\n if ((i + 1) % 16 === 0) {\n str += ' ' + viewStr\n viewStr = ''\n str += `\\n${(i + 1).toString(16).padStart(8, '0')}: `\n } else if ((i + 1) % 8 === 0) {\n str += ' '\n }\n }\n\n // 补充最后一行的空白\n if (viewStr.length > 0) {\n for (let i = viewStr.length; i < 16; i++) {\n str += ' ' + ' '\n if ((i + 1) % 8 === 0) str += ' '\n }\n str += ' ' + viewStr\n }\n\n return str\n}\n","import React from 'react'\nimport { IFlowPreview } from '../message'\nimport { shallowEqual } from '../utils'\n\ninterface IProps {\n flow: IFlowPreview\n isSelected: boolean\n onShowDetail: () => void\n}\n\nclass FlowPreview extends React.Component<IProps> {\n shouldComponentUpdate(nextProps: IProps) {\n if (nextProps.isSelected === this.props.isSelected && shallowEqual(nextProps.flow, this.props.flow)) {\n return false\n }\n return true\n }\n\n render() {\n const fp = this.props.flow\n\n const classNames = []\n if (this.props.isSelected) classNames.push('tr-selected')\n if (fp.waitIntercept) classNames.push('tr-wait-intercept')\n\n return (\n <tr className={classNames.length ? classNames.join(' ') : undefined}\n onClick={() => {\n this.props.onShowDetail()\n }}\n >\n <td>{fp.no}</td>\n <td>{fp.method}</td>\n <td>{fp.host}</td>\n <td>{fp.path}</td>\n <td>{fp.contentType}</td>\n <td>{fp.statusCode}</td>\n <td>{fp.size}</td>\n <td>{fp.costTime}</td>\n </tr>\n )\n }\n}\n\nexport default FlowPreview\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Alert from 'react-bootstrap/Alert'\n\nimport { SendMessageType, buildMessageEdit, IRequest, IResponse, Header, Flow } from '../message'\nimport { isTextBody } from '../utils'\n\n\nconst stringifyRequest = (request: IRequest) => {\n const firstLine = `${request.method} ${request.url}`\n const headerLines = Object.keys(request.header).map(key => {\n const valstr = request.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (request.body && isTextBody(request)) bodyLines = new TextDecoder().decode(request.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseRequest = (content: string): IRequest | undefined => {\n const firstIndex = content.indexOf('\\n\\n')\n if (firstIndex <= 0) return\n\n const firstLine = content.slice(0, firstIndex)\n const [method, url] = firstLine.split(' ')\n if (!method || !url) return\n\n const secondIndex = content.indexOf('\\n\\n', firstIndex + 2)\n if (secondIndex <= 0) return\n const headerLines = content.slice(firstIndex + 2, secondIndex)\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n const bodyLines = content.slice(secondIndex + 2)\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n method,\n url,\n proto: '',\n header,\n body,\n }\n}\n\nconst stringifyResponse = (response: IResponse) => {\n const firstLine = `${response.statusCode}`\n const headerLines = Object.keys(response.header).map(key => {\n const valstr = response.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (response.body && isTextBody(response)) bodyLines = new TextDecoder().decode(response.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseResponse = (content: string): IResponse | undefined => {\n const firstIndex = content.indexOf('\\n\\n')\n if (firstIndex <= 0) return\n\n const firstLine = content.slice(0, firstIndex)\n const statusCode = parseInt(firstLine)\n if (isNaN(statusCode)) return\n\n const secondIndex = content.indexOf('\\n\\n', firstIndex + 2)\n if (secondIndex <= 0) return\n const headerLines = content.slice(firstIndex + 2, secondIndex)\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n const bodyLines = content.slice(secondIndex + 2)\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n statusCode,\n header,\n body,\n }\n}\n\n\ninterface IProps {\n flow: Flow\n onChangeRequest: (request: IRequest) => void\n onChangeResponse: (response: IResponse) => void\n onMessage: (msg: ArrayBufferLike) => void\n}\n\ninterface IState {\n show: boolean\n alertMsg: string\n content: string\n}\n\nclass EditFlow extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n alertMsg: '',\n content: '',\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n showAlert(msg: string) {\n this.setState({ alertMsg: msg })\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n let content = ''\n if (when === 'request') {\n content = stringifyRequest(flow.request)\n } else {\n content = stringifyResponse(flow.response as IResponse)\n }\n\n this.setState({ show: true, alertMsg: '', content })\n }\n\n handleSave() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n const { content } = this.state\n\n if (when === 'request') {\n const request = parseRequest(content)\n if (!request) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeRequest(request)\n this.handleClose()\n } else {\n const response = parseResponse(content)\n if (!response) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeResponse(response)\n this.handleClose()\n }\n }\n\n render() {\n const { flow } = this.props\n if (!flow.waitIntercept) return null\n\n const { alertMsg } = this.state\n\n const when = flow.response ? 'response' : 'request'\n\n return (\n <div className=\"flow-wait-area\">\n\n <Button size=\"sm\" onClick={this.handleShow}>Edit</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.CHANGE_RESPONSE : SendMessageType.CHANGE_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Continue</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.DROP_RESPONSE : SendMessageType.DROP_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Drop</Button>\n\n\n <Modal size=\"lg\" show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Edit {when === 'request' ? 'Request' : 'Response'}</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group>\n <Form.Control as=\"textarea\" rows={10} value={this.state.content} onChange={e => { this.setState({ content: e.target.value }) }} />\n </Form.Group>\n {\n !alertMsg ? null : <Alert variant=\"danger\">{alertMsg}</Alert>\n }\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n\n </div>\n )\n }\n}\n\nexport default EditFlow\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport FormCheck from 'react-bootstrap/FormCheck'\nimport fetchToCurl from 'fetch-to-curl'\nimport copy from 'copy-to-clipboard'\nimport JSONPretty from 'react-json-pretty'\nimport { Flow, IResponse } from '../message'\nimport { isTextBody } from '../utils'\n\nimport EditFlow from './EditFlow'\n\ninterface Iprops {\n flow: Flow | null\n onClose: () => void\n onReRenderFlows: () => void\n onMessage: (msg: ArrayBufferLike) => void\n}\n\ninterface IState {\n flowTab: 'Headers' | 'Preview' | 'Response' | 'Hexview'\n copied: boolean\n requestBodyViewTab: 'Raw' | 'Preview'\n responseBodyLineBreak: boolean\n}\n\nclass ViewFlow extends React.Component<Iprops, IState> {\n constructor(props: Iprops) {\n super(props)\n\n this.state = {\n flowTab: 'Headers',\n copied: false,\n requestBodyViewTab: 'Raw',\n responseBodyLineBreak: false,\n }\n }\n\n preview() {\n const { flow } = this.props\n if (!flow) return null\n const response = flow.response\n if (!response) return null\n\n if (!(response.body && response.body.byteLength)) {\n return <div style={{ color: 'gray' }}>No response</div>\n }\n\n const pv = flow.previewResponseBody()\n if (!pv) return <div style={{ color: 'gray' }}>Not support preview</div>\n\n if (pv.type === 'image') {\n return <img src={`data:image/png;base64,${pv.data}`} />\n }\n else if (pv.type === 'json') {\n return <div><JSONPretty data={pv.data} keyStyle={'color: rgb(130,40,144);'} stringStyle={'color: rgb(153,68,60);'} valueStyle={'color: rgb(25,1,199);'} booleanStyle={'color: rgb(94,105,192);'} /></div>\n }\n\n return <div style={{ color: 'gray' }}>Not support preview</div>\n }\n\n requestBodyPreview() {\n const { flow } = this.props\n if (!flow) return null\n\n const pv = flow.previewRequestBody()\n if (!pv) return <div style={{ color: 'gray' }}>Not support preview</div>\n\n if (pv.type === 'json') {\n return <div><JSONPretty data={pv.data} keyStyle={'color: rgb(130,40,144);'} stringStyle={'color: rgb(153,68,60);'} valueStyle={'color: rgb(25,1,199);'} booleanStyle={'color: rgb(94,105,192);'} /></div>\n }\n else if (pv.type === 'binary') {\n return <div><pre>{pv.data}</pre></div>\n }\n\n return <div style={{ color: 'gray' }}>Not support preview</div>\n }\n\n hexview() {\n const { flow } = this.props\n if (!flow) return null\n const response = flow.response\n if (!response) return null\n\n if (!(response.body && response.body.byteLength)) {\n return <div style={{ color: 'gray' }}>No response</div>\n }\n\n return <pre>{flow.hexviewResponseBody()}</pre>\n }\n\n render() {\n if (!this.props.flow) return null\n\n const flow = this.props.flow\n const flowTab = this.state.flowTab\n\n const request = flow.request\n const response: IResponse = (flow.response || {}) as any\n\n // Query String Parameters\n const searchItems: Array<{ key: string; value: string }> = []\n if (flow.url && flow.url.search) {\n flow.url.searchParams.forEach((value, key) => {\n searchItems.push({ key, value })\n })\n }\n\n return (\n <div className=\"flow-detail\">\n <div className=\"header-tabs\">\n <span onClick={() => { this.props.onClose() }}>x</span>\n <span className={flowTab === 'Headers' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Headers' }) }}>Headers</span>\n <span className={flowTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Preview' }) }}>Preview</span>\n <span className={flowTab === 'Response' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Response' }) }}>Response</span>\n <span className={flowTab === 'Hexview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Hexview' }) }}>Hexview</span>\n\n <EditFlow\n flow={flow}\n onChangeRequest={request => {\n flow.request.method = request.method\n flow.request.url = request.url\n flow.request.header = request.header\n if (isTextBody(flow.request)) flow.request.body = request.body\n this.props.onReRenderFlows()\n }}\n onChangeResponse={response => {\n if (!flow.response) flow.response = {} as IResponse\n\n flow.response.statusCode = response.statusCode\n flow.response.header = response.header\n if (isTextBody(flow.response)) flow.response.body = response.body\n this.props.onReRenderFlows()\n }}\n onMessage={msg => {\n this.props.onMessage(msg)\n flow.waitIntercept = false\n this.props.onReRenderFlows()\n }}\n />\n\n </div>\n\n <div style={{ padding: '20px' }}>\n {\n !(flowTab === 'Headers') ? null :\n <div>\n <p><Button size=\"sm\" variant={this.state.copied ? 'success' : 'primary'} disabled={this.state.copied} onClick={() => {\n const curl = fetchToCurl({\n url: flow.request.url,\n method: flow.request.method,\n headers: Object.keys(flow.request.header).reduce((obj: any, key: string) => {\n obj[key] = flow.request.header[key][0]\n return obj\n }, {}),\n body: flow.requestBody(),\n })\n copy(curl)\n\n this.setState({ copied: true }, () => {\n setTimeout(() => {\n this.setState({ copied: false })\n }, 1000)\n })\n\n }}>{this.state.copied ? 'Copied' : 'Copy as cURL'}</Button></p>\n\n <div className=\"header-block\">\n <p>General</p>\n <div className=\"header-block-content\">\n <p>Request URL: {request.url}</p>\n <p>Request Method: {request.method}</p>\n <p>Status Code: {`${response.statusCode || '(pending)'}`}</p>\n </div>\n </div>\n\n {\n !(response.header) ? null :\n <div className=\"header-block\">\n <p>Response Headers</p>\n <div className=\"header-block-content\">\n {\n Object.keys(response.header).map(key => {\n return (\n <p key={key}>{key}: {response.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n }\n\n <div className=\"header-block\">\n <p>Request Headers</p>\n <div className=\"header-block-content\">\n {\n !(request.header) ? null :\n Object.keys(request.header).map(key => {\n return (\n <p key={key}>{key}: {request.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n\n {\n !(searchItems.length) ? null :\n <div className=\"header-block\">\n <p>Query String Parameters</p>\n <div className=\"header-block-content\">\n {\n searchItems.map(({ key, value }) => {\n return (\n <p key={key}>{key}: {value}</p>\n )\n })\n }\n </div>\n </div>\n }\n\n {\n !(request.body && request.body.byteLength) ? null :\n <div className=\"header-block\">\n <p>Request Body</p>\n <div className=\"header-block-content\">\n <div>\n <div className=\"request-body-detail\" style={{ marginBottom: '15px' }}>\n <span className={this.state.requestBodyViewTab === 'Raw' ? 'selected' : undefined} onClick={() => { this.setState({ requestBodyViewTab: 'Raw' }) }}>Raw</span>\n <span className={this.state.requestBodyViewTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ requestBodyViewTab: 'Preview' }) }}>Preview</span>\n </div>\n\n {\n !(this.state.requestBodyViewTab === 'Raw') ? null :\n <div>\n {\n !(flow.isTextRequest()) ? <span style={{ color: 'gray' }}>Not text Request</span> : flow.requestBody()\n }\n </div>\n }\n\n {\n !(this.state.requestBodyViewTab === 'Preview') ? null :\n <div>{this.requestBodyPreview()}</div>\n }\n </div>\n </div>\n </div>\n }\n\n </div>\n }\n\n {\n !(flowTab === 'Response') ? null :\n !(response.body && response.body.byteLength) ? <div style={{ color: 'gray' }}>No response</div> :\n !(flow.isTextResponse()) ? <div style={{ color: 'gray' }}>Not text response</div> :\n <div>\n <div style={{ marginBottom: '20px' }}>\n <FormCheck\n inline\n type=\"checkbox\"\n checked={this.state.responseBodyLineBreak}\n onChange={e => {\n this.setState({ responseBodyLineBreak: e.target.checked })\n }}\n label=\"自动换行\"></FormCheck>\n </div>\n <div style={{ whiteSpace: this.state.responseBodyLineBreak ? 'pre-wrap' : 'pre' }}>\n {flow.responseBody()}\n </div>\n </div>\n }\n\n {\n !(flowTab === 'Preview') ? null :\n <div>{this.preview()}</div>\n }\n\n {\n !(flowTab === 'Hexview') ? null :\n <div>{this.hexview()}</div>\n }\n </div>\n\n </div>\n )\n }\n}\n\nexport default ViewFlow\n","import { Flow } from './message'\n\nexport class FlowManager {\n private items: Flow[]\n private _map: Map<string, Flow>\n private filterText: string\n private filterTimer: number | null\n private num: number\n private max: number\n\n constructor() {\n this.items = []\n this._map = new Map()\n this.filterText = ''\n this.filterTimer = null\n this.num = 0\n\n this.max = 1000\n }\n\n showList() {\n let text = this.filterText\n if (text) text = text.trim()\n if (!text) return this.items\n\n // regexp\n if (text.startsWith('/') && text.endsWith('/')) {\n text = text.slice(1, text.length - 1).trim()\n if (!text) return this.items\n try {\n const reg = new RegExp(text)\n return this.items.filter(item => {\n return reg.test(item.request.url)\n })\n } catch (err) {\n return this.items\n }\n }\n\n return this.items.filter(item => {\n return item.request.url.includes(text)\n })\n }\n\n add(item: Flow) {\n item.no = ++this.num\n this.items.push(item)\n this._map.set(item.id, item)\n\n if (this.items.length > this.max) {\n const oldest = this.items.shift()\n if (oldest) this._map.delete(oldest.id)\n }\n }\n\n get(id: string) {\n return this._map.get(id)\n }\n\n changeFilter(text: string) {\n this.filterText = text\n }\n\n changeFilterLazy(text: string, callback: () => void) {\n if (this.filterTimer) {\n clearTimeout(this.filterTimer)\n this.filterTimer = null\n }\n\n this.filterTimer = setTimeout(() => {\n this.filterText = text\n callback()\n }, 300) as any\n }\n\n clear() {\n this.items = []\n this._map = new Map()\n }\n}\n","import React from 'react'\nimport Table from 'react-bootstrap/Table'\nimport Form from 'react-bootstrap/Form'\nimport Button from 'react-bootstrap/Button'\nimport scrollMonitor from 'scrollmonitor'\nimport './App.css'\n\nimport BreakPoint from './components/BreakPoint'\nimport FlowPreview from './components/FlowPreview'\nimport ViewFlow from './components/ViewFlow'\n\nimport { FlowManager } from './flow'\nimport { parseMessage, SendMessageType, buildMessageMeta, Flow, MessageType } from './message'\n\ninterface IState {\n flows: Flow[]\n flow: Flow | null\n flowTab: 'Headers' | 'Preview' | 'Response'\n}\n\nclass App extends React.Component<any, IState> {\n private flowMgr: FlowManager\n private ws: WebSocket | null\n\n private pageBottom: HTMLDivElement | null\n private autoScore = false\n\n constructor(props: any) {\n super(props)\n\n this.flowMgr = new FlowManager()\n\n this.state = {\n flows: this.flowMgr.showList(),\n flow: null,\n\n flowTab: 'Headers', // Headers, Preview, Response\n }\n\n this.ws = null\n this.pageBottom = null\n }\n\n componentDidMount() {\n this.initWs()\n }\n\n componentWillUnmount() {\n if (this.ws) {\n this.ws.close()\n }\n }\n\n initWs() {\n if (this.ws) return\n\n let host\n if (process.env.NODE_ENV === 'development') {\n host = 'localhost:9081'\n } else {\n host = new URL(document.URL).host\n }\n this.ws = new WebSocket(`ws://${host}/echo`)\n this.ws.binaryType = 'arraybuffer'\n this.ws.onopen = () => { console.log('OPEN') }\n this.ws.onclose = () => { console.log('CLOSE') }\n this.ws.onmessage = evt => {\n const msg = parseMessage(evt.data)\n if (!msg) {\n console.error('parse error:', evt.data)\n return\n }\n // console.log('msg:', msg)\n\n if (msg.type === MessageType.REQUEST) {\n const flow = new Flow(msg)\n this.flowMgr.add(flow)\n this.setState({ flows: this.flowMgr.showList() }, () => {\n if (this.pageBottom && this.autoScore) this.pageBottom.scrollIntoView({ behavior: 'auto' })\n })\n }\n else if (msg.type === MessageType.REQUEST_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.addRequestBody(msg)\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.addResponse(msg)\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow || !flow.response) return\n flow.addResponseBody(msg)\n this.setState({ flows: this.state.flows })\n }\n }\n this.ws.onerror = evt => {\n console.log('ERROR:', evt)\n }\n }\n\n initScrollMonitor() {\n if (!this.pageBottom) return\n\n const watcher = scrollMonitor.create(this.pageBottom)\n watcher.enterViewport(() => {\n this.autoScore = true\n })\n watcher.exitViewport(() => {\n this.autoScore = false\n })\n }\n\n render() {\n const { flows } = this.state\n return (\n <div className=\"main-table-wrap\">\n <div className=\"top-control\">\n <div><Button size=\"sm\" onClick={() => {\n this.flowMgr.clear()\n this.setState({ flows: this.flowMgr.showList(), flow: null })\n }}>Clear</Button></div>\n <div>\n <Form.Control\n size=\"sm\" placeholder=\"Filter\"\n onChange={(e) => {\n const value = e.target.value\n this.flowMgr.changeFilterLazy(value, () => {\n this.setState({ flows: this.flowMgr.showList() })\n })\n }}\n >\n </Form.Control>\n </div>\n\n <BreakPoint onSave={rules => {\n const msg = buildMessageMeta(SendMessageType.CHANGE_BREAK_POINT_RULES, rules)\n if (this.ws) this.ws.send(msg)\n }} />\n </div>\n\n <Table striped bordered size=\"sm\" style={{ tableLayout: 'fixed' }}>\n <thead>\n <tr>\n <th style={{ width: '50px' }}>No</th>\n <th style={{ width: '80px' }}>Method</th>\n <th style={{ width: '200px' }}>Host</th>\n <th style={{ width: '600px' }}>Path</th>\n <th style={{ width: '150px' }}>Type</th>\n <th style={{ width: '80px' }}>Status</th>\n <th style={{ width: '90px' }}>Size</th>\n <th style={{ width: '90px' }}>Time</th>\n </tr>\n </thead>\n <tbody>\n {\n flows.map(f => {\n const fp = f.preview()\n\n return (\n <FlowPreview\n key={fp.id}\n flow={fp}\n isSelected={(this.state.flow && this.state.flow.id === fp.id) ? true : false}\n onShowDetail={() => {\n this.setState({ flow: f })\n }}\n />\n )\n })\n }\n </tbody>\n </Table>\n\n <ViewFlow\n flow={this.state.flow}\n onClose={() => { this.setState({ flow: null }) }}\n onReRenderFlows={() => { this.setState({ flows: this.state.flows }) }}\n onMessage={msg => { if (this.ws) this.ws.send(msg) }}\n />\n\n <div ref={el => {\n if (this.pageBottom) return\n this.pageBottom = el\n this.initScrollMonitor()\n }} style={{ height: '0px', visibility: 'hidden' }}>bottom</div>\n </div>\n )\n }\n}\n\nexport default App\n","import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry)\n getFID(onPerfEntry)\n getFCP(onPerfEntry)\n getLCP(onPerfEntry)\n getTTFB(onPerfEntry)\n })\n }\n}\n\nexport default reportWebVitals\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport 'bootstrap/dist/css/bootstrap.min.css'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals()\n"],"sourceRoot":""} |