serve-sim 0.0.0
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.
- package/bin/serve-sim-bin +0 -0
- package/dist/middleware.cjs +2 -0
- package/dist/middleware.js +7 -0
- package/dist/serve-sim.js +40 -0
- package/package.json +40 -0
- package/src/middleware.ts +147 -0
- package/src/state.ts +26 -0
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{readdirSync as J,readFileSync as P}from"fs";import{spawn as j}from"child_process";import{tmpdir as k}from"os";import{join as H}from"path";var F=H(k(),"serve-sim");function Z(){let U;try{U=J(F).filter((G)=>G.startsWith("server-")&&G.endsWith(".json"))}catch{return[]}let B=[];for(let G of U)try{let z=JSON.parse(P(H(F,G),"utf-8"));try{process.kill(z.pid,0),B.push(z)}catch{}}catch{}return B}var $=null;function D(){if(!$)$=Buffer.from("PCFkb2N0eXBlIGh0bWw+CjxodG1sPjxoZWFkPgo8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsaW5pdGlhbC1zY2FsZT0xIj4KPHRpdGxlPlNpbXVsYXRvciBQcmV2aWV3PC90aXRsZT4KPHN0eWxlPiosKjo6YmVmb3JlLCo6OmFmdGVye2JveC1zaXppbmc6Ym9yZGVyLWJveH1odG1sLGJvZHl7bWFyZ2luOjA7aGVpZ2h0OjEwMCU7b3ZlcmZsb3c6aGlkZGVufTwvc3R5bGU+CjwvaGVhZD48Ym9keT4KPGRpdiBpZD0icm9vdCI+PC9kaXY+CjwhLS1fX1NJTV9QUkVWSUVXX0NPTkZJR19fLS0+CjxzY3JpcHQgdHlwZT0ibW9kdWxlIj52YXIgYjAsUCxiNCxqNSxLMCx3NCxwNCx2NCxYNCxDMCxVMCxqNCxLNCxZNCxaNCxSNCx3MD17fSxTMD1bXSxSNT0vYWNpdHxleCg/OnN8Z3xufHB8JCl8cnBofGdyaWR8b3dzfG1uY3xudHd8aW5lW2NoXXx6b298Xm9yZHxpdGVyYS9pLEEwPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24gWDAoWCxZKXtmb3IodmFyIFogaW4gWSlYW1pdPVlbWl07cmV0dXJuIFh9ZnVuY3Rpb24gUTQoWCl7WCYmWC5wYXJlbnROb2RlJiZYLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoWCl9ZnVuY3Rpb24gWTAoWCxZLFope3ZhciBKLHEsSyxRPXt9O2ZvcihLIGluIFkpSz09ImtleSI/Sj1ZW0tdOks9PSJyZWYiP3E9WVtLXTpRW0tdPVlbS107aWYoYXJndW1lbnRzLmxlbmd0aD4yJiYoUS5jaGlsZHJlbj1hcmd1bWVudHMubGVuZ3RoPjM/YjAuY2FsbChhcmd1bWVudHMsMik6WiksdHlwZW9mIFg9PSJmdW5jdGlvbiImJlguZGVmYXVsdFByb3BzIT1udWxsKWZvcihLIGluIFguZGVmYXVsdFByb3BzKVFbS109PT12b2lkIDAmJihRW0tdPVguZGVmYXVsdFByb3BzW0tdKTtyZXR1cm4gRTAoWCxRLEoscSxudWxsKX1mdW5jdGlvbiBFMChYLFksWixKLHEpe3ZhciBLPXt0eXBlOlgscHJvcHM6WSxrZXk6WixyZWY6SixfX2s6bnVsbCxfXzpudWxsLF9fYjowLF9fZTpudWxsLF9fYzpudWxsLGNvbnN0cnVjdG9yOnZvaWQgMCxfX3Y6cT09bnVsbD8rK2I0OnEsX19pOi0xLF9fdTowfTtyZXR1cm4gcT09bnVsbCYmUC52bm9kZSE9bnVsbCYmUC52bm9kZShLKSxLfWZ1bmN0aW9uIHgoWCl7cmV0dXJuIFguY2hpbGRyZW59ZnVuY3Rpb24gZyhYLFkpe3RoaXMucHJvcHM9WCx0aGlzLmNvbnRleHQ9WX1mdW5jdGlvbiBMMChYLFkpe2lmKFk9PW51bGwpcmV0dXJuIFguX18/TDAoWC5fXyxYLl9faSsxKTpudWxsO2Zvcih2YXIgWjtZPFguX19rLmxlbmd0aDtZKyspaWYoKFo9WC5fX2tbWV0pIT1udWxsJiZaLl9fZSE9bnVsbClyZXR1cm4gWi5fX2U7cmV0dXJuIHR5cGVvZiBYLnR5cGU9PSJmdW5jdGlvbiI/TDAoWCk6bnVsbH1mdW5jdGlvbiB5NShYKXtpZihYLl9fUCYmWC5fX2Qpe3ZhciBZPVguX192LFo9WS5fX2UsSj1bXSxxPVtdLEs9WDAoe30sWSk7Sy5fX3Y9WS5fX3YrMSxQLnZub2RlJiZQLnZub2RlKEspLCQ0KFguX19QLEssWSxYLl9fbixYLl9fUC5uYW1lc3BhY2VVUkksMzImWS5fX3U/W1pdOm51bGwsSixaPT1udWxsP0wwKFkpOlosISEoMzImWS5fX3UpLHEpLEsuX192PVkuX192LEsuX18uX19rW0suX19pXT1LLGQ0KEosSyxxKSxZLl9fZT1ZLl9fPW51bGwsSy5fX2UhPVomJnk0KEspfX1mdW5jdGlvbiB5NChYKXtpZigoWD1YLl9fKSE9bnVsbCYmWC5fX2MhPW51bGwpcmV0dXJuIFguX19lPVguX19jLmJhc2U9bnVsbCxYLl9fay5zb21lKGZ1bmN0aW9uKFkpe2lmKFkhPW51bGwmJlkuX19lIT1udWxsKXJldHVybiBYLl9fZT1YLl9fYy5iYXNlPVkuX19lfSkseTQoWCl9ZnVuY3Rpb24gSjQoWCl7KCFYLl9fZCYmKFguX19kPSEwKSYmSzAucHVzaChYKSYmIVQwLl9fcisrfHx3NCE9UC5kZWJvdW5jZVJlbmRlcmluZykmJigodzQ9UC5kZWJvdW5jZVJlbmRlcmluZyl8fHA0KShUMCl9ZnVuY3Rpb24gVDAoKXt0cnl7Zm9yKHZhciBYLFk9MTtLMC5sZW5ndGg7KUswLmxlbmd0aD5ZJiZLMC5zb3J0KHY0KSxYPUswLnNoaWZ0KCksWT1LMC5sZW5ndGgseTUoWCl9ZmluYWxseXtLMC5sZW5ndGg9VDAuX19yPTB9fWZ1bmN0aW9uIGc0KFgsWSxaLEoscSxLLFEseixHLEwsRCl7dmFyIFcsTyxVLGssXyxDLE0sRj1KJiZKLl9fa3x8UzAsRT1ZLmxlbmd0aDtmb3IoRz1nNShaLFksRixHLEUpLFc9MDtXPEU7VysrKShVPVouX19rW1ddKSE9bnVsbCYmKE89VS5fX2khPS0xJiZGW1UuX19pXXx8dzAsVS5fX2k9VyxDPSQ0KFgsVSxPLHEsSyxRLHosRyxMLEQpLGs9VS5fX2UsVS5yZWYmJk8ucmVmIT1VLnJlZiYmKE8ucmVmJiZXNChPLnJlZixudWxsLFUpLEQucHVzaChVLnJlZixVLl9fY3x8ayxVKSksXz09bnVsbCYmayE9bnVsbCYmKF89ayksKE09ISEoNCZVLl9fdSkpfHxPLl9faz09PVUuX19rPyhHPXg0KFUsRyxYLE0pLE0mJk8uX19lJiYoTy5fX2U9bnVsbCkpOnR5cGVvZiBVLnR5cGU9PSJmdW5jdGlvbiImJkMhPT12b2lkIDA/Rz1DOmsmJihHPWsubmV4dFNpYmxpbmcpLFUuX191Jj0tNyk7cmV0dXJuIFouX19lPV8sR31mdW5jdGlvbiBnNShYLFksWixKLHEpe3ZhciBLLFEseixHLEwsRD1aLmxlbmd0aCxXPUQsTz0wO2ZvcihYLl9faz1BcnJheShxKSxLPTA7SzxxO0srKykoUT1ZW0tdKSE9bnVsbCYmdHlwZW9mIFEhPSJib29sZWFuIiYmdHlwZW9mIFEhPSJmdW5jdGlvbiI/KHR5cGVvZiBRPT0ic3RyaW5nInx8dHlwZW9mIFE9PSJudW1iZXIifHx0eXBlb2YgUT09ImJpZ2ludCJ8fFEuY29uc3RydWN0b3I9PVN0cmluZz9RPVguX19rW0tdPUUwKG51bGwsUSxudWxsLG51bGwsbnVsbCk6QTAoUSk/UT1YLl9fa1tLXT1FMCh4LHtjaGlsZHJlbjpRfSxudWxsLG51bGwsbnVsbCk6US5jb25zdHJ1Y3Rvcj09PXZvaWQgMCYmUS5fX2I+MD9RPVguX19rW0tdPUUwKFEudHlwZSxRLnByb3BzLFEua2V5LFEucmVmP1EucmVmOm51bGwsUS5fX3YpOlguX19rW0tdPVEsRz1LK08sUS5fXz1YLFEuX19iPVguX19iKzEsej1udWxsLChMPVEuX19pPXg1KFEsWixHLFcpKSE9LTEmJihXLS0sKHo9WltMXSkmJih6Ll9fdXw9MikpLHo9PW51bGx8fHouX192PT1udWxsPyhMPT0tMSYmKHE+RD9PLS06cTxEJiZPKyspLHR5cGVvZiBRLnR5cGUhPSJmdW5jdGlvbiImJihRLl9fdXw9NCkpOkwhPUcmJihMPT1HLTE/Ty0tOkw9PUcrMT9PKys6KEw+Rz9PLS06TysrLFEuX191fD00KSkpOlguX19rW0tdPW51bGw7aWYoVylmb3IoSz0wO0s8RDtLKyspKHo9WltLXSkhPW51bGwmJigyJnouX191KT09MCYmKHouX19lPT1KJiYoSj1MMCh6KSksaDQoeix6KSk7cmV0dXJuIEp9ZnVuY3Rpb24geDQoWCxZLFosSil7dmFyIHEsSztpZih0eXBlb2YgWC50eXBlPT0iZnVuY3Rpb24iKXtmb3IocT1YLl9fayxLPTA7cSYmSzxxLmxlbmd0aDtLKyspcVtLXSYmKHFbS10uX189WCxZPXg0KHFbS10sWSxaLEopKTtyZXR1cm4gWX1YLl9fZSE9WSYmKEomJihZJiZYLnR5cGUmJiFZLnBhcmVudE5vZGUmJihZPUwwKFgpKSxaLmluc2VydEJlZm9yZShYLl9fZSxZfHxudWxsKSksWT1YLl9fZSk7ZG8gWT1ZJiZZLm5leHRTaWJsaW5nO3doaWxlKFkhPW51bGwmJlkubm9kZVR5cGU9PTgpO3JldHVybiBZfWZ1bmN0aW9uIFowKFgsWSl7cmV0dXJuIFk9WXx8W10sWD09bnVsbHx8dHlwZW9mIFg9PSJib29sZWFuInx8KEEwKFgpP1guc29tZShmdW5jdGlvbihaKXtaMChaLFkpfSk6WS5wdXNoKFgpKSxZfWZ1bmN0aW9uIHg1KFgsWSxaLEope3ZhciBxLEssUSx6PVgua2V5LEc9WC50eXBlLEw9WVtaXSxEPUwhPW51bGwmJigyJkwuX191KT09MDtpZihMPT09bnVsbCYmej09bnVsbHx8RCYmej09TC5rZXkmJkc9PUwudHlwZSlyZXR1cm4gWjtpZihKPihEPzE6MCkpe2ZvcihxPVotMSxLPVorMTtxPj0wfHxLPFkubGVuZ3RoOylpZigoTD1ZW1E9cT49MD9xLS06SysrXSkhPW51bGwmJigyJkwuX191KT09MCYmej09TC5rZXkmJkc9PUwudHlwZSlyZXR1cm4gUX1yZXR1cm4tMX1mdW5jdGlvbiBTNChYLFksWil7WVswXT09Ii0iP1guc2V0UHJvcGVydHkoWSxaPT1udWxsPyIiOlopOlhbWV09Wj09bnVsbD8iIjp0eXBlb2YgWiE9Im51bWJlciJ8fFI1LnRlc3QoWSk/WjpaKyJweCJ9ZnVuY3Rpb24gTTAoWCxZLFosSixxKXt2YXIgSyxRO1g6aWYoWT09InN0eWxlIilpZih0eXBlb2YgWj09InN0cmluZyIpWC5zdHlsZS5jc3NUZXh0PVo7ZWxzZXtpZih0eXBlb2YgSj09InN0cmluZyImJihYLnN0eWxlLmNzc1RleHQ9Sj0iIiksSilmb3IoWSBpbiBKKVomJlkgaW4gWnx8UzQoWC5zdHlsZSxZLCIiKTtpZihaKWZvcihZIGluIFopSiYmWltZXT09SltZXXx8UzQoWC5zdHlsZSxZLFpbWV0pfWVsc2UgaWYoWVswXT09Im8iJiZZWzFdPT0ibiIpSz1ZIT0oWT1ZLnJlcGxhY2UoajQsIiQxIikpLFE9WS50b0xvd2VyQ2FzZSgpLFk9USBpbiBYfHxZPT0ib25Gb2N1c091dCJ8fFk9PSJvbkZvY3VzSW4iP1Euc2xpY2UoMik6WS5zbGljZSgyKSxYLmx8fChYLmw9e30pLFgubFtZK0tdPVosWj9KP1pbVTBdPUpbVTBdOihaW1UwXT1LNCxYLmFkZEV2ZW50TGlzdGVuZXIoWSxLP1o0Olk0LEspKTpYLnJlbW92ZUV2ZW50TGlzdGVuZXIoWSxLP1o0Olk0LEspO2Vsc2V7aWYocT09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIilZPVkucmVwbGFjZSgveGxpbmsoSHw6aCkvLCJoIikucmVwbGFjZSgvc05hbWUkLywicyIpO2Vsc2UgaWYoWSE9IndpZHRoIiYmWSE9ImhlaWdodCImJlkhPSJocmVmIiYmWSE9Imxpc3QiJiZZIT0iZm9ybSImJlkhPSJ0YWJJbmRleCImJlkhPSJkb3dubG9hZCImJlkhPSJyb3dTcGFuIiYmWSE9ImNvbFNwYW4iJiZZIT0icm9sZSImJlkhPSJwb3BvdmVyIiYmWSBpbiBYKXRyeXtYW1ldPVo9PW51bGw/IiI6WjticmVhayBYfWNhdGNoKHope310eXBlb2YgWj09ImZ1bmN0aW9uInx8KFo9PW51bGx8fFo9PT0hMSYmWVs0XSE9Ii0iP1gucmVtb3ZlQXR0cmlidXRlKFkpOlguc2V0QXR0cmlidXRlKFksWT09InBvcG92ZXIiJiZaPT0xPyIiOlopKX19ZnVuY3Rpb24gVDQoWCl7cmV0dXJuIGZ1bmN0aW9uKFkpe2lmKHRoaXMubCl7dmFyIFo9dGhpcy5sW1kudHlwZStYXTtpZihZW0MwXT09bnVsbClZW0MwXT1LNCsrO2Vsc2UgaWYoWVtDMF08WltVMF0pcmV0dXJuO3JldHVybiBaKFAuZXZlbnQ/UC5ldmVudChZKTpZKX19fWZ1bmN0aW9uICQ0KFgsWSxaLEoscSxLLFEseixHLEwpe3ZhciBELFcsTyxVLGssXyxDLE0sRixFLEksdixyLGYsaSx5PVkudHlwZTtpZihZLmNvbnN0cnVjdG9yIT09dm9pZCAwKXJldHVybiBudWxsOzEyOCZaLl9fdSYmKEc9ISEoMzImWi5fX3UpLEs9W3o9WS5fX2U9Wi5fX2VdKSwoRD1QLl9fYikmJkQoWSk7WDppZih0eXBlb2YgeT09ImZ1bmN0aW9uIil0cnl7aWYoTT1ZLnByb3BzLEY9eS5wcm90b3R5cGUmJnkucHJvdG90eXBlLnJlbmRlcixFPShEPXkuY29udGV4dFR5cGUpJiZKW0QuX19jXSxJPUQ/RT9FLnByb3BzLnZhbHVlOkQuX186SixaLl9fYz9DPShXPVkuX19jPVouX19jKS5fXz1XLl9fRTooRj9ZLl9fYz1XPW5ldyB5KE0sSSk6KFkuX19jPVc9bmV3IGcoTSxJKSxXLmNvbnN0cnVjdG9yPXksVy5yZW5kZXI9bTUpLEUmJkUuc3ViKFcpLFcuc3RhdGV8fChXLnN0YXRlPXt9KSxXLl9fbj1KLE89Vy5fX2Q9ITAsVy5fX2g9W10sVy5fc2I9W10pLEYmJlcuX19zPT1udWxsJiYoVy5fX3M9Vy5zdGF0ZSksRiYmeS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMhPW51bGwmJihXLl9fcz09Vy5zdGF0ZSYmKFcuX19zPVgwKHt9LFcuX19zKSksWDAoVy5fX3MseS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoTSxXLl9fcykpKSxVPVcucHJvcHMsaz1XLnN0YXRlLFcuX192PVksTylGJiZ5LmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcz09bnVsbCYmVy5jb21wb25lbnRXaWxsTW91bnQhPW51bGwmJlcuY29tcG9uZW50V2lsbE1vdW50KCksRiYmVy5jb21wb25lbnREaWRNb3VudCE9bnVsbCYmVy5fX2gucHVzaChXLmNvbXBvbmVudERpZE1vdW50KTtlbHNle2lmKEYmJnkuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzPT1udWxsJiZNIT09VSYmVy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIT1udWxsJiZXLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoTSxJKSxZLl9fdj09Wi5fX3Z8fCFXLl9fZSYmVy5zaG91bGRDb21wb25lbnRVcGRhdGUhPW51bGwmJlcuc2hvdWxkQ29tcG9uZW50VXBkYXRlKE0sVy5fX3MsSSk9PT0hMSl7WS5fX3YhPVouX192JiYoVy5wcm9wcz1NLFcuc3RhdGU9Vy5fX3MsVy5fX2Q9ITEpLFkuX19lPVouX19lLFkuX19rPVouX19rLFkuX19rLnNvbWUoZnVuY3Rpb24obSl7bSYmKG0uX189WSl9KSxTMC5wdXNoLmFwcGx5KFcuX19oLFcuX3NiKSxXLl9zYj1bXSxXLl9faC5sZW5ndGgmJlEucHVzaChXKTticmVhayBYfVcuY29tcG9uZW50V2lsbFVwZGF0ZSE9bnVsbCYmVy5jb21wb25lbnRXaWxsVXBkYXRlKE0sVy5fX3MsSSksRiYmVy5jb21wb25lbnREaWRVcGRhdGUhPW51bGwmJlcuX19oLnB1c2goZnVuY3Rpb24oKXtXLmNvbXBvbmVudERpZFVwZGF0ZShVLGssXyl9KX1pZihXLmNvbnRleHQ9SSxXLnByb3BzPU0sVy5fX1A9WCxXLl9fZT0hMSx2PVAuX19yLHI9MCxGKVcuc3RhdGU9Vy5fX3MsVy5fX2Q9ITEsdiYmdihZKSxEPVcucmVuZGVyKFcucHJvcHMsVy5zdGF0ZSxXLmNvbnRleHQpLFMwLnB1c2guYXBwbHkoVy5fX2gsVy5fc2IpLFcuX3NiPVtdO2Vsc2UgZG8gVy5fX2Q9ITEsdiYmdihZKSxEPVcucmVuZGVyKFcucHJvcHMsVy5zdGF0ZSxXLmNvbnRleHQpLFcuc3RhdGU9Vy5fX3M7d2hpbGUoVy5fX2QmJisrcjwyNSk7Vy5zdGF0ZT1XLl9fcyxXLmdldENoaWxkQ29udGV4dCE9bnVsbCYmKEo9WDAoWDAoe30sSiksVy5nZXRDaGlsZENvbnRleHQoKSkpLEYmJiFPJiZXLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlIT1udWxsJiYoXz1XLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlKFUsaykpLGY9RCE9bnVsbCYmRC50eXBlPT09eCYmRC5rZXk9PW51bGw/bTQoRC5wcm9wcy5jaGlsZHJlbik6RCx6PWc0KFgsQTAoZik/ZjpbZl0sWSxaLEoscSxLLFEseixHLEwpLFcuYmFzZT1ZLl9fZSxZLl9fdSY9LTE2MSxXLl9faC5sZW5ndGgmJlEucHVzaChXKSxDJiYoVy5fX0U9Vy5fXz1udWxsKX1jYXRjaChtKXtpZihZLl9fdj1udWxsLEd8fEshPW51bGwpaWYobS50aGVuKXtmb3IoWS5fX3V8PUc/MTYwOjEyODt6JiZ6Lm5vZGVUeXBlPT04JiZ6Lm5leHRTaWJsaW5nOyl6PXoubmV4dFNpYmxpbmc7S1tLLmluZGV4T2YoeildPW51bGwsWS5fX2U9en1lbHNle2ZvcihpPUsubGVuZ3RoO2ktLTspUTQoS1tpXSk7cTQoWSl9ZWxzZSBZLl9fZT1aLl9fZSxZLl9faz1aLl9fayxtLnRoZW58fHE0KFkpO1AuX19lKG0sWSxaKX1lbHNlIEs9PW51bGwmJlkuX192PT1aLl9fdj8oWS5fX2s9Wi5fX2ssWS5fX2U9Wi5fX2UpOno9WS5fX2U9ZDUoWi5fX2UsWSxaLEoscSxLLFEsRyxMKTtyZXR1cm4oRD1QLmRpZmZlZCkmJkQoWSksMTI4JlkuX191P3ZvaWQgMDp6fWZ1bmN0aW9uIHE0KFgpe1gmJihYLl9fYyYmKFguX19jLl9fZT0hMCksWC5fX2smJlguX19rLnNvbWUocTQpKX1mdW5jdGlvbiBkNChYLFksWil7Zm9yKHZhciBKPTA7SjxaLmxlbmd0aDtKKyspVzQoWltKXSxaWysrSl0sWlsrK0pdKTtQLl9fYyYmUC5fX2MoWSxYKSxYLnNvbWUoZnVuY3Rpb24ocSl7dHJ5e1g9cS5fX2gscS5fX2g9W10sWC5zb21lKGZ1bmN0aW9uKEspe0suY2FsbChxKX0pfWNhdGNoKEspe1AuX19lKEsscS5fX3YpfX0pfWZ1bmN0aW9uIG00KFgpe3JldHVybiB0eXBlb2YgWCE9Im9iamVjdCJ8fFg9PW51bGx8fFguX19iPjA/WDpBMChYKT9YLm1hcChtNCk6WDAoe30sWCl9ZnVuY3Rpb24gZDUoWCxZLFosSixxLEssUSx6LEcpe3ZhciBMLEQsVyxPLFUsayxfLEM9Wi5wcm9wc3x8dzAsTT1ZLnByb3BzLEY9WS50eXBlO2lmKEY9PSJzdmciP3E9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIjpGPT0ibWF0aCI/cT0iaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCI6cXx8KHE9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiKSxLIT1udWxsKXtmb3IoTD0wO0w8Sy5sZW5ndGg7TCsrKWlmKChVPUtbTF0pJiYic2V0QXR0cmlidXRlImluIFU9PSEhRiYmKEY/VS5sb2NhbE5hbWU9PUY6VS5ub2RlVHlwZT09Mykpe1g9VSxLW0xdPW51bGw7YnJlYWt9fWlmKFg9PW51bGwpe2lmKEY9PW51bGwpcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKE0pO1g9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHEsRixNLmlzJiZNKSx6JiYoUC5fX20mJlAuX19tKFksSyksej0hMSksSz1udWxsfWlmKEY9PW51bGwpQz09PU18fHomJlguZGF0YT09TXx8KFguZGF0YT1NKTtlbHNle2lmKEs9SyYmYjAuY2FsbChYLmNoaWxkTm9kZXMpLCF6JiZLIT1udWxsKWZvcihDPXt9LEw9MDtMPFguYXR0cmlidXRlcy5sZW5ndGg7TCsrKUNbKFU9WC5hdHRyaWJ1dGVzW0xdKS5uYW1lXT1VLnZhbHVlO2ZvcihMIGluIEMpVT1DW0xdLEw9PSJkYW5nZXJvdXNseVNldElubmVySFRNTCI/Vz1VOkw9PSJjaGlsZHJlbiJ8fChMIGluIE0pfHxMPT0idmFsdWUiJiYoImRlZmF1bHRWYWx1ZSJpbiBNKXx8TD09ImNoZWNrZWQiJiYoImRlZmF1bHRDaGVja2VkImluIE0pfHxNMChYLEwsbnVsbCxVLHEpO2ZvcihMIGluIE0pVT1NW0xdLEw9PSJjaGlsZHJlbiI/Tz1VOkw9PSJkYW5nZXJvdXNseVNldElubmVySFRNTCI/RD1VOkw9PSJ2YWx1ZSI/az1VOkw9PSJjaGVja2VkIj9fPVU6eiYmdHlwZW9mIFUhPSJmdW5jdGlvbiJ8fENbTF09PT1VfHxNMChYLEwsVSxDW0xdLHEpO2lmKEQpenx8VyYmKEQuX19odG1sPT1XLl9faHRtbHx8RC5fX2h0bWw9PVguaW5uZXJIVE1MKXx8KFguaW5uZXJIVE1MPUQuX19odG1sKSxZLl9faz1bXTtlbHNlIGlmKFcmJihYLmlubmVySFRNTD0iIiksZzQoWS50eXBlPT0idGVtcGxhdGUiP1guY29udGVudDpYLEEwKE8pP086W09dLFksWixKLEY9PSJmb3JlaWduT2JqZWN0Ij8iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI6cSxLLFEsSz9LWzBdOlouX19rJiZMMChaLDApLHosRyksSyE9bnVsbClmb3IoTD1LLmxlbmd0aDtMLS07KVE0KEtbTF0pO3p8fChMPSJ2YWx1ZSIsRj09InByb2dyZXNzIiYmaz09bnVsbD9YLnJlbW92ZUF0dHJpYnV0ZSgidmFsdWUiKTprIT1udWxsJiYoayE9PVhbTF18fEY9PSJwcm9ncmVzcyImJiFrfHxGPT0ib3B0aW9uIiYmayE9Q1tMXSkmJk0wKFgsTCxrLENbTF0scSksTD0iY2hlY2tlZCIsXyE9bnVsbCYmXyE9WFtMXSYmTTAoWCxMLF8sQ1tMXSxxKSl9cmV0dXJuIFh9ZnVuY3Rpb24gVzQoWCxZLFope3RyeXtpZih0eXBlb2YgWD09ImZ1bmN0aW9uIil7dmFyIEo9dHlwZW9mIFguX191PT0iZnVuY3Rpb24iO0omJlguX191KCksSiYmWT09bnVsbHx8KFguX191PVgoWSkpfWVsc2UgWC5jdXJyZW50PVl9Y2F0Y2gocSl7UC5fX2UocSxaKX19ZnVuY3Rpb24gaDQoWCxZLFope3ZhciBKLHE7aWYoUC51bm1vdW50JiZQLnVubW91bnQoWCksKEo9WC5yZWYpJiYoSi5jdXJyZW50JiZKLmN1cnJlbnQhPVguX19lfHxXNChKLG51bGwsWSkpLChKPVguX19jKSE9bnVsbCl7aWYoSi5jb21wb25lbnRXaWxsVW5tb3VudCl0cnl7Si5jb21wb25lbnRXaWxsVW5tb3VudCgpfWNhdGNoKEspe1AuX19lKEssWSl9Si5iYXNlPUouX19QPW51bGx9aWYoSj1YLl9faylmb3IocT0wO3E8Si5sZW5ndGg7cSsrKUpbcV0mJmg0KEpbcV0sWSxafHx0eXBlb2YgWC50eXBlIT0iZnVuY3Rpb24iKTtafHxRNChYLl9fZSksWC5fX2M9WC5fXz1YLl9fZT12b2lkIDB9ZnVuY3Rpb24gbTUoWCxZLFope3JldHVybiB0aGlzLmNvbnN0cnVjdG9yKFgsWil9ZnVuY3Rpb24gcDAoWCxZLFope3ZhciBKLHEsSyxRO1k9PWRvY3VtZW50JiYoWT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLFAuX18mJlAuX18oWCxZKSxxPShKPXR5cGVvZiBaPT0iZnVuY3Rpb24iKT9udWxsOlomJlouX19rfHxZLl9fayxLPVtdLFE9W10sJDQoWSxYPSghSiYmWnx8WSkuX19rPVkwKHgsbnVsbCxbWF0pLHF8fHcwLHcwLFkubmFtZXNwYWNlVVJJLCFKJiZaP1taXTpxP251bGw6WS5maXJzdENoaWxkP2IwLmNhbGwoWS5jaGlsZE5vZGVzKTpudWxsLEssIUomJlo/WjpxP3EuX19lOlkuZmlyc3RDaGlsZCxKLFEpLGQ0KEssWCxRKX1mdW5jdGlvbiB6MChYKXtmdW5jdGlvbiBZKFope3ZhciBKLHE7cmV0dXJuIHRoaXMuZ2V0Q2hpbGRDb250ZXh0fHwoSj1uZXcgU2V0LChxPXt9KVtZLl9fY109dGhpcyx0aGlzLmdldENoaWxkQ29udGV4dD1mdW5jdGlvbigpe3JldHVybiBxfSx0aGlzLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7Sj1udWxsfSx0aGlzLnNob3VsZENvbXBvbmVudFVwZGF0ZT1mdW5jdGlvbihLKXt0aGlzLnByb3BzLnZhbHVlIT1LLnZhbHVlJiZKLmZvckVhY2goZnVuY3Rpb24oUSl7US5fX2U9ITAsSjQoUSl9KX0sdGhpcy5zdWI9ZnVuY3Rpb24oSyl7Si5hZGQoSyk7dmFyIFE9Sy5jb21wb25lbnRXaWxsVW5tb3VudDtLLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7SiYmSi5kZWxldGUoSyksUSYmUS5jYWxsKEspfX0pLFouY2hpbGRyZW59cmV0dXJuIFkuX19jPSJfX2NDIitSNCsrLFkuX189WCxZLlByb3ZpZGVyPVkuX19sPShZLkNvbnN1bWVyPWZ1bmN0aW9uKFosSil7cmV0dXJuIFouY2hpbGRyZW4oSil9KS5jb250ZXh0VHlwZT1ZLFl9YjA9UzAuc2xpY2UsUD17X19lOmZ1bmN0aW9uKFgsWSxaLEope2Zvcih2YXIgcSxLLFE7WT1ZLl9fOylpZigocT1ZLl9fYykmJiFxLl9fKXRyeXtpZigoSz1xLmNvbnN0cnVjdG9yKSYmSy5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IhPW51bGwmJihxLnNldFN0YXRlKEsuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKFgpKSxRPXEuX19kKSxxLmNvbXBvbmVudERpZENhdGNoIT1udWxsJiYocS5jb21wb25lbnREaWRDYXRjaChYLEp8fHt9KSxRPXEuX19kKSxRKXJldHVybiBxLl9fRT1xfWNhdGNoKHope1g9en10aHJvdyBYfX0sYjQ9MCxqNT1mdW5jdGlvbihYKXtyZXR1cm4gWCE9bnVsbCYmWC5jb25zdHJ1Y3Rvcj09PXZvaWQgMH0sZy5wcm90b3R5cGUuc2V0U3RhdGU9ZnVuY3Rpb24oWCxZKXt2YXIgWjtaPXRoaXMuX19zIT1udWxsJiZ0aGlzLl9fcyE9dGhpcy5zdGF0ZT90aGlzLl9fczp0aGlzLl9fcz1YMCh7fSx0aGlzLnN0YXRlKSx0eXBlb2YgWD09ImZ1bmN0aW9uIiYmKFg9WChYMCh7fSxaKSx0aGlzLnByb3BzKSksWCYmWDAoWixYKSxYIT1udWxsJiZ0aGlzLl9fdiYmKFkmJnRoaXMuX3NiLnB1c2goWSksSjQodGhpcykpfSxnLnByb3RvdHlwZS5mb3JjZVVwZGF0ZT1mdW5jdGlvbihYKXt0aGlzLl9fdiYmKHRoaXMuX19lPSEwLFgmJnRoaXMuX19oLnB1c2goWCksSjQodGhpcykpfSxnLnByb3RvdHlwZS5yZW5kZXI9eCxLMD1bXSxwND10eXBlb2YgUHJvbWlzZT09ImZ1bmN0aW9uIj9Qcm9taXNlLnByb3RvdHlwZS50aGVuLmJpbmQoUHJvbWlzZS5yZXNvbHZlKCkpOnNldFRpbWVvdXQsdjQ9ZnVuY3Rpb24oWCxZKXtyZXR1cm4gWC5fX3YuX19iLVkuX192Ll9fYn0sVDAuX19yPTAsWDQ9TWF0aC5yYW5kb20oKS50b1N0cmluZyg4KSxDMD0iX19kIitYNCxVMD0iX19hIitYNCxqND0vKFBvaW50ZXJDYXB0dXJlKSR8Q2FwdHVyZSQvaSxLND0wLFk0PVQ0KCExKSxaND1UNCghMCksUjQ9MDt2YXIgTjAsVCxMNCxmNCxEMD0wLHI0PVtdLGI9UCxhND1iLl9fYixjND1iLl9fcixsND1iLmRpZmZlZCxpND1iLl9fYyxzND1iLnVubW91bnQsbzQ9Yi5fXztmdW5jdGlvbiBqMChYLFkpe2IuX19oJiZiLl9faChULFgsRDB8fFkpLEQwPTA7dmFyIFo9VC5fX0h8fChULl9fSD17X186W10sX19oOltdfSk7cmV0dXJuIFg+PVouX18ubGVuZ3RoJiZaLl9fLnB1c2goe30pLFouX19bWF19ZnVuY3Rpb24gcChYKXtyZXR1cm4gRDA9MSxONChuNCxYKX1mdW5jdGlvbiBONChYLFksWil7dmFyIEo9ajAoTjArKywyKTtpZihKLnQ9WCwhSi5fX2MmJihKLl9fPVtaP1ooWSk6bjQodm9pZCAwLFkpLGZ1bmN0aW9uKHope3ZhciBHPUouX19OP0ouX19OWzBdOkouX19bMF0sTD1KLnQoRyx6KTtHIT09TCYmKEouX19OPVtMLEouX19bMV1dLEouX19jLnNldFN0YXRlKHt9KSl9XSxKLl9fYz1ULCFULl9fZikpe3ZhciBxPWZ1bmN0aW9uKHosRyxMKXtpZighSi5fX2MuX19IKXJldHVybiEwO3ZhciBEPUouX19jLl9fSC5fXy5maWx0ZXIoZnVuY3Rpb24oTyl7cmV0dXJuIE8uX19jfSk7aWYoRC5ldmVyeShmdW5jdGlvbihPKXtyZXR1cm4hTy5fX059KSlyZXR1cm4hS3x8Sy5jYWxsKHRoaXMseixHLEwpO3ZhciBXPUouX19jLnByb3BzIT09ejtyZXR1cm4gRC5zb21lKGZ1bmN0aW9uKE8pe2lmKE8uX19OKXt2YXIgVT1PLl9fWzBdO08uX189Ty5fX04sTy5fX049dm9pZCAwLFUhPT1PLl9fWzBdJiYoVz0hMCl9fSksSyYmSy5jYWxsKHRoaXMseixHLEwpfHxXfTtULl9fZj0hMDt2YXJ7c2hvdWxkQ29tcG9uZW50VXBkYXRlOkssY29tcG9uZW50V2lsbFVwZGF0ZTpRfT1UO1QuY29tcG9uZW50V2lsbFVwZGF0ZT1mdW5jdGlvbih6LEcsTCl7aWYodGhpcy5fX2Upe3ZhciBEPUs7Sz12b2lkIDAscSh6LEcsTCksSz1EfVEmJlEuY2FsbCh0aGlzLHosRyxMKX0sVC5zaG91bGRDb21wb25lbnRVcGRhdGU9cX1yZXR1cm4gSi5fX058fEouX199ZnVuY3Rpb24gZChYLFkpe3ZhciBaPWowKE4wKyssMyk7IWIuX19zJiZ0NChaLl9fSCxZKSYmKFouX189WCxaLnU9WSxULl9fSC5fX2gucHVzaChaKSl9ZnVuY3Rpb24gdyhYKXtyZXR1cm4gRDA9NSxSMChmdW5jdGlvbigpe3JldHVybntjdXJyZW50Olh9fSxbXSl9ZnVuY3Rpb24gUjAoWCxZKXt2YXIgWj1qMChOMCsrLDcpO3JldHVybiB0NChaLl9fSCxZKSYmKFouX189WCgpLFouX19IPVksWi5fX2g9WCksWi5fX31mdW5jdGlvbiBqKFgsWSl7cmV0dXJuIEQwPTgsUjAoZnVuY3Rpb24oKXtyZXR1cm4gWH0sWSl9ZnVuY3Rpb24gUDAoWCl7dmFyIFk9VC5jb250ZXh0W1guX19jXSxaPWowKE4wKyssOSk7cmV0dXJuIFouYz1YLFk/KFouX189PW51bGwmJihaLl9fPSEwLFkuc3ViKFQpKSxZLnByb3BzLnZhbHVlKTpYLl9ffWZ1bmN0aW9uIGg1KCl7Zm9yKHZhciBYO1g9cjQuc2hpZnQoKTspe3ZhciBZPVguX19IO2lmKFguX19QJiZZKXRyeXtZLl9faC5zb21lKHYwKSxZLl9faC5zb21lKHo0KSxZLl9faD1bXX1jYXRjaChaKXtZLl9faD1bXSxiLl9fZShaLFguX192KX19fWIuX19iPWZ1bmN0aW9uKFgpe1Q9bnVsbCxhNCYmYTQoWCl9LGIuX189ZnVuY3Rpb24oWCxZKXtYJiZZLl9fayYmWS5fX2suX19tJiYoWC5fX209WS5fX2suX19tKSxvNCYmbzQoWCxZKX0sYi5fX3I9ZnVuY3Rpb24oWCl7YzQmJmM0KFgpLE4wPTA7dmFyIFk9KFQ9WC5fX2MpLl9fSDtZJiYoTDQ9PT1UPyhZLl9faD1bXSxULl9faD1bXSxZLl9fLnNvbWUoZnVuY3Rpb24oWil7Wi5fX04mJihaLl9fPVouX19OKSxaLnU9Wi5fX049dm9pZCAwfSkpOihZLl9faC5zb21lKHYwKSxZLl9faC5zb21lKHo0KSxZLl9faD1bXSxOMD0wKSksTDQ9VH0sYi5kaWZmZWQ9ZnVuY3Rpb24oWCl7bDQmJmw0KFgpO3ZhciBZPVguX19jO1kmJlkuX19IJiYoWS5fX0guX19oLmxlbmd0aCYmKHI0LnB1c2goWSkhPT0xJiZmND09PWIucmVxdWVzdEFuaW1hdGlvbkZyYW1lfHwoKGY0PWIucmVxdWVzdEFuaW1hdGlvbkZyYW1lKXx8ZjUpKGg1KSksWS5fX0guX18uc29tZShmdW5jdGlvbihaKXtaLnUmJihaLl9fSD1aLnUpLFoudT12b2lkIDB9KSksTDQ9VD1udWxsfSxiLl9fYz1mdW5jdGlvbihYLFkpe1kuc29tZShmdW5jdGlvbihaKXt0cnl7Wi5fX2guc29tZSh2MCksWi5fX2g9Wi5fX2guZmlsdGVyKGZ1bmN0aW9uKEope3JldHVybiFKLl9ffHx6NChKKX0pfWNhdGNoKEope1kuc29tZShmdW5jdGlvbihxKXtxLl9faCYmKHEuX19oPVtdKX0pLFk9W10sYi5fX2UoSixaLl9fdil9fSksaTQmJmk0KFgsWSl9LGIudW5tb3VudD1mdW5jdGlvbihYKXtzNCYmczQoWCk7dmFyIFksWj1YLl9fYztaJiZaLl9fSCYmKFouX19ILl9fLnNvbWUoZnVuY3Rpb24oSil7dHJ5e3YwKEopfWNhdGNoKHEpe1k9cX19KSxaLl9fSD12b2lkIDAsWSYmYi5fX2UoWSxaLl9fdikpfTt2YXIgdTQ9dHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZT09ImZ1bmN0aW9uIjtmdW5jdGlvbiBmNShYKXt2YXIgWSxaPWZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KEopLHU0JiZjYW5jZWxBbmltYXRpb25GcmFtZShZKSxzZXRUaW1lb3V0KFgpfSxKPXNldFRpbWVvdXQoWiwzNSk7dTQmJihZPXJlcXVlc3RBbmltYXRpb25GcmFtZShaKSl9ZnVuY3Rpb24gdjAoWCl7dmFyIFk9VCxaPVguX19jO3R5cGVvZiBaPT0iZnVuY3Rpb24iJiYoWC5fX2M9dm9pZCAwLFooKSksVD1ZfWZ1bmN0aW9uIHo0KFgpe3ZhciBZPVQ7WC5fX2M9WC5fXygpLFQ9WX1mdW5jdGlvbiB0NChYLFkpe3JldHVybiFYfHxYLmxlbmd0aCE9PVkubGVuZ3RofHxZLnNvbWUoZnVuY3Rpb24oWixKKXtyZXR1cm4gWiE9PVhbSl19KX1mdW5jdGlvbiBuNChYLFkpe3JldHVybiB0eXBlb2YgWT09ImZ1bmN0aW9uIj9ZKFgpOll9ZnVuY3Rpb24gdTUoWCxZKXtmb3IodmFyIFogaW4gWSlYW1pdPVlbWl07cmV0dXJuIFh9ZnVuY3Rpb24gZTQoWCxZKXtmb3IodmFyIFogaW4gWClpZihaIT09Il9fc291cmNlIiYmIShaIGluIFkpKXJldHVybiEwO2Zvcih2YXIgSiBpbiBZKWlmKEohPT0iX19zb3VyY2UiJiZYW0pdIT09WVtKXSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiBYNShYLFkpe3RoaXMucHJvcHM9WCx0aGlzLmNvbnRleHQ9WX0oWDUucHJvdG90eXBlPW5ldyBnKS5pc1B1cmVSZWFjdENvbXBvbmVudD0hMCxYNS5wcm90b3R5cGUuc2hvdWxkQ29tcG9uZW50VXBkYXRlPWZ1bmN0aW9uKFgsWSl7cmV0dXJuIGU0KHRoaXMucHJvcHMsWCl8fGU0KHRoaXMuc3RhdGUsWSl9O3ZhciBZNT1QLl9fYjtQLl9fYj1mdW5jdGlvbihYKXtYLnR5cGUmJlgudHlwZS5fX2YmJlgucmVmJiYoWC5wcm9wcy5yZWY9WC5yZWYsWC5yZWY9bnVsbCksWTUmJlk1KFgpfTt2YXIgcjU9UC5fX2U7UC5fX2U9ZnVuY3Rpb24oWCxZLFosSil7aWYoWC50aGVuKXtmb3IodmFyIHEsSz1ZO0s9Sy5fXzspaWYoKHE9Sy5fX2MpJiZxLl9fYylyZXR1cm4gWS5fX2U9PW51bGwmJihZLl9fZT1aLl9fZSxZLl9faz1aLl9faykscS5fX2MoWCxZKX1yNShYLFksWixKKX07dmFyIFo1PVAudW5tb3VudDtmdW5jdGlvbiBXNShYLFksWil7cmV0dXJuIFgmJihYLl9fYyYmWC5fX2MuX19IJiYoWC5fX2MuX19ILl9fLmZvckVhY2goZnVuY3Rpb24oSil7dHlwZW9mIEouX19jPT0iZnVuY3Rpb24iJiZKLl9fYygpfSksWC5fX2MuX19IPW51bGwpLChYPXU1KHt9LFgpKS5fX2MhPW51bGwmJihYLl9fYy5fX1A9PT1aJiYoWC5fX2MuX19QPVkpLFguX19jLl9fZT0hMCxYLl9fYz1udWxsKSxYLl9faz1YLl9fayYmWC5fX2subWFwKGZ1bmN0aW9uKEope3JldHVybiBXNShKLFksWil9KSksWH1mdW5jdGlvbiBMNShYLFksWil7cmV0dXJuIFgmJlomJihYLl9fdj1udWxsLFguX19rPVguX19rJiZYLl9fay5tYXAoZnVuY3Rpb24oSil7cmV0dXJuIEw1KEosWSxaKX0pLFguX19jJiZYLl9fYy5fX1A9PT1ZJiYoWC5fX2UmJlouYXBwZW5kQ2hpbGQoWC5fX2UpLFguX19jLl9fZT0hMCxYLl9fYy5fX1A9WikpLFh9ZnVuY3Rpb24gRzQoKXt0aGlzLl9fdT0wLHRoaXMubz1udWxsLHRoaXMuX19iPW51bGx9ZnVuY3Rpb24gejUoWCl7dmFyIFk9WC5fXyYmWC5fXy5fX2M7cmV0dXJuIFkmJlkuX19hJiZZLl9fYShYKX1mdW5jdGlvbiB5MCgpe3RoaXMuaT1udWxsLHRoaXMubD1udWxsfVAudW5tb3VudD1mdW5jdGlvbihYKXt2YXIgWT1YLl9fYztZJiYoWS5fX3o9ITApLFkmJlkuX19SJiZZLl9fUigpLFkmJjMyJlguX191JiYoWC50eXBlPW51bGwpLFo1JiZaNShYKX0sKEc0LnByb3RvdHlwZT1uZXcgZykuX19jPWZ1bmN0aW9uKFgsWSl7dmFyIFo9WS5fX2MsSj10aGlzO0oubz09bnVsbCYmKEoubz1bXSksSi5vLnB1c2goWik7dmFyIHE9ejUoSi5fX3YpLEs9ITEsUT1mdW5jdGlvbigpe0t8fEouX196fHwoSz0hMCxaLl9fUj1udWxsLHE/cShHKTpHKCkpfTtaLl9fUj1RO3ZhciB6PVouX19QO1ouX19QPW51bGw7dmFyIEc9ZnVuY3Rpb24oKXtpZighLS1KLl9fdSl7aWYoSi5zdGF0ZS5fX2Epe3ZhciBMPUouc3RhdGUuX19hO0ouX192Ll9fa1swXT1MNShMLEwuX19jLl9fUCxMLl9fYy5fX08pfXZhciBEO2ZvcihKLnNldFN0YXRlKHtfX2E6Si5fX2I9bnVsbH0pO0Q9Si5vLnBvcCgpOylELl9fUD16LEQuZm9yY2VVcGRhdGUoKX19O0ouX191Kyt8fDMyJlkuX191fHxKLnNldFN0YXRlKHtfX2E6Si5fX2I9Si5fX3YuX19rWzBdfSksWC50aGVuKFEsUSl9LEc0LnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudD1mdW5jdGlvbigpe3RoaXMubz1bXX0sRzQucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbihYLFkpe2lmKHRoaXMuX19iKXtpZih0aGlzLl9fdi5fX2spe3ZhciBaPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpLEo9dGhpcy5fX3YuX19rWzBdLl9fYzt0aGlzLl9fdi5fX2tbMF09VzUodGhpcy5fX2IsWixKLl9fTz1KLl9fUCl9dGhpcy5fX2I9bnVsbH12YXIgcT1ZLl9fYSYmWTAoeCxudWxsLFguZmFsbGJhY2spO3JldHVybiBxJiYocS5fX3UmPS0zMyksW1kwKHgsbnVsbCxZLl9fYT9udWxsOlguY2hpbGRyZW4pLHFdfTt2YXIgSjU9ZnVuY3Rpb24oWCxZLFope2lmKCsrWlsxXT09PVpbMF0mJlgubC5kZWxldGUoWSksWC5wcm9wcy5yZXZlYWxPcmRlciYmKFgucHJvcHMucmV2ZWFsT3JkZXJbMF0hPT0idCJ8fCFYLmwuc2l6ZSkpZm9yKFo9WC5pO1o7KXtmb3IoO1oubGVuZ3RoPjM7KVoucG9wKCkoKTtpZihaWzFdPFpbMF0pYnJlYWs7WC5pPVo9WlsyXX19Oyh5MC5wcm90b3R5cGU9bmV3IGcpLl9fYT1mdW5jdGlvbihYKXt2YXIgWT10aGlzLFo9ejUoWS5fX3YpLEo9WS5sLmdldChYKTtyZXR1cm4gSlswXSsrLGZ1bmN0aW9uKHEpe3ZhciBLPWZ1bmN0aW9uKCl7WS5wcm9wcy5yZXZlYWxPcmRlcj8oSi5wdXNoKHEpLEo1KFksWCxKKSk6cSgpfTtaP1ooSyk6SygpfX0seTAucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbihYKXt0aGlzLmk9bnVsbCx0aGlzLmw9bmV3IE1hcDt2YXIgWT1aMChYLmNoaWxkcmVuKTtYLnJldmVhbE9yZGVyJiZYLnJldmVhbE9yZGVyWzBdPT09ImIiJiZZLnJldmVyc2UoKTtmb3IodmFyIFo9WS5sZW5ndGg7Wi0tOyl0aGlzLmwuc2V0KFlbWl0sdGhpcy5pPVsxLDAsdGhpcy5pXSk7cmV0dXJuIFguY2hpbGRyZW59LHkwLnByb3RvdHlwZS5jb21wb25lbnREaWRVcGRhdGU9eTAucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50PWZ1bmN0aW9uKCl7dmFyIFg9dGhpczt0aGlzLmwuZm9yRWFjaChmdW5jdGlvbihZLFope0o1KFgsWixZKX0pfTt2YXIgdDU9dHlwZW9mIFN5bWJvbDwidSImJlN5bWJvbC5mb3ImJlN5bWJvbC5mb3IoInJlYWN0LmVsZW1lbnQiKXx8NjAxMDMsbjU9L14oPzphY2NlbnR8YWxpZ25tZW50fGFyYWJpY3xiYXNlbGluZXxjYXB8Y2xpcCg/IVBhdGhVKXxjb2xvcnxkb21pbmFudHxmaWxsfGZsb29kfGZvbnR8Z2x5cGgoPyFSKXxob3JpenxpbWFnZSghUyl8bGV0dGVyfGxpZ2h0aW5nfG1hcmtlcig/IUh8V3xVKXxvdmVybGluZXxwYWludHxwb2ludGVyfHNoYXBlfHN0b3B8c3RyaWtldGhyb3VnaHxzdHJva2V8dGV4dCg/IUwpfHRyYW5zZm9ybXx1bmRlcmxpbmV8dW5pY29kZXx1bml0c3x2fHZlY3Rvcnx2ZXJ0fHdvcmR8d3JpdGluZ3x4KD8hQykpW0EtWl0vLGU1PS9eb24oQW5pfFRyYXxUb3V8QmVmb3JlSW5wfENvbXBvKS8sWDY9L1tBLVowLTldL2csWTY9dHlwZW9mIGRvY3VtZW50PCJ1IixaNj1mdW5jdGlvbihYKXtyZXR1cm4odHlwZW9mIFN5bWJvbDwidSImJnR5cGVvZiBTeW1ib2woKT09InN5bWJvbCI/L2ZpbHxjaGV8cmFkLzovZmlsfGNoZXxyYS8pLnRlc3QoWCl9O2Z1bmN0aW9uIE41KFgsWSxaKXtyZXR1cm4gWS5fX2s9PW51bGwmJihZLnRleHRDb250ZW50PSIiKSxwMChYLFkpLHR5cGVvZiBaPT0iZnVuY3Rpb24iJiZaKCksWD9YLl9fYzpudWxsfWcucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9ITAsWyJjb21wb25lbnRXaWxsTW91bnQiLCJjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIiwiY29tcG9uZW50V2lsbFVwZGF0ZSJdLmZvckVhY2goZnVuY3Rpb24oWCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGcucHJvdG90eXBlLFgse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1siVU5TQUZFXyIrWF19LHNldDpmdW5jdGlvbihZKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxYLHtjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6WX0pfX0pfSk7dmFyIHE1PVAuZXZlbnQ7UC5ldmVudD1mdW5jdGlvbihYKXtyZXR1cm4gcTUmJihYPXE1KFgpKSxYLnBlcnNpc3Q9ZnVuY3Rpb24oKXt9LFguaXNQcm9wYWdhdGlvblN0b3BwZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jYW5jZWxCdWJibGV9LFguaXNEZWZhdWx0UHJldmVudGVkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGVmYXVsdFByZXZlbnRlZH0sWC5uYXRpdmVFdmVudD1YfTt2YXIgRzUsSjY9e2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jbGFzc319LEs1PVAudm5vZGU7UC52bm9kZT1mdW5jdGlvbihYKXt0eXBlb2YgWC50eXBlPT0ic3RyaW5nIiYmZnVuY3Rpb24oWSl7dmFye3Byb3BzOlosdHlwZTpKfT1ZLHE9e30sSz1KLmluZGV4T2YoIi0iKT09LTE7Zm9yKHZhciBRIGluIFope3ZhciB6PVpbUV07aWYoIShRPT09InZhbHVlIiYmKCJkZWZhdWx0VmFsdWUiaW4gWikmJno9PW51bGx8fFk2JiZRPT09ImNoaWxkcmVuIiYmSj09PSJub3NjcmlwdCJ8fFE9PT0iY2xhc3MifHxRPT09ImNsYXNzTmFtZSIpKXt2YXIgRz1RLnRvTG93ZXJDYXNlKCk7UT09PSJkZWZhdWx0VmFsdWUiJiYidmFsdWUiaW4gWiYmWi52YWx1ZT09bnVsbD9RPSJ2YWx1ZSI6UT09PSJkb3dubG9hZCImJno9PT0hMD96PSIiOkc9PT0idHJhbnNsYXRlIiYmej09PSJubyI/ej0hMTpHWzBdPT09Im8iJiZHWzFdPT09Im4iP0c9PT0ib25kb3VibGVjbGljayI/UT0ib25kYmxjbGljayI6RyE9PSJvbmNoYW5nZSJ8fEohPT0iaW5wdXQiJiZKIT09InRleHRhcmVhInx8WjYoWi50eXBlKT9HPT09Im9uZm9jdXMiP1E9Im9uZm9jdXNpbiI6Rz09PSJvbmJsdXIiP1E9Im9uZm9jdXNvdXQiOmU1LnRlc3QoUSkmJihRPUcpOkc9UT0ib25pbnB1dCI6SyYmbjUudGVzdChRKT9RPVEucmVwbGFjZShYNiwiLSQmIikudG9Mb3dlckNhc2UoKTp6PT09bnVsbCYmKHo9dm9pZCAwKSxHPT09Im9uaW5wdXQiJiZxW1E9R10mJihRPSJvbmlucHV0Q2FwdHVyZSIpLHFbUV09en19Sj09InNlbGVjdCImJihxLm11bHRpcGxlJiZBcnJheS5pc0FycmF5KHEudmFsdWUpJiYocS52YWx1ZT1aMChaLmNoaWxkcmVuKS5mb3JFYWNoKGZ1bmN0aW9uKEwpe0wucHJvcHMuc2VsZWN0ZWQ9cS52YWx1ZS5pbmRleE9mKEwucHJvcHMudmFsdWUpIT0tMX0pKSxxLmRlZmF1bHRWYWx1ZSE9bnVsbCYmKHEudmFsdWU9WjAoWi5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbihMKXtMLnByb3BzLnNlbGVjdGVkPXEubXVsdGlwbGU/cS5kZWZhdWx0VmFsdWUuaW5kZXhPZihMLnByb3BzLnZhbHVlKSE9LTE6cS5kZWZhdWx0VmFsdWU9PUwucHJvcHMudmFsdWV9KSkpLFouY2xhc3MmJiFaLmNsYXNzTmFtZT8ocS5jbGFzcz1aLmNsYXNzLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLCJjbGFzc05hbWUiLEo2KSk6Wi5jbGFzc05hbWUmJihxLmNsYXNzPXEuY2xhc3NOYW1lPVouY2xhc3NOYW1lKSxZLnByb3BzPXF9KFgpLFguJCR0eXBlb2Y9dDUsSzUmJks1KFgpfTt2YXIgUTU9UC5fX3I7UC5fX3I9ZnVuY3Rpb24oWCl7UTUmJlE1KFgpLEc1PVguX19jfTt2YXIgJDU9UC5kaWZmZWQ7UC5kaWZmZWQ9ZnVuY3Rpb24oWCl7JDUmJiQ1KFgpO3Zhcntwcm9wczpZLF9fZTpafT1YO1ohPW51bGwmJlgudHlwZT09PSJ0ZXh0YXJlYSImJiJ2YWx1ZSJpbiBZJiZZLnZhbHVlIT09Wi52YWx1ZSYmKFoudmFsdWU9WS52YWx1ZT09bnVsbD8iIjpZLnZhbHVlKSxHNT1udWxsfTtmdW5jdGlvbiBWNShYKXtyZXR1cm4hIVguX19rJiYocDAobnVsbCxYKSwhMCl9ZnVuY3Rpb24gSDUoWCl7cmV0dXJue3JlbmRlcjpmdW5jdGlvbihZKXtONShZLFgpfSx1bm1vdW50OmZ1bmN0aW9uKCl7VjUoWCl9fX1mdW5jdGlvbiBJNShYLFkpe2Zvcih2YXIgWiBpbiBZKVhbWl09WVtaXTtyZXR1cm4gWH1mdW5jdGlvbiBPNShYLFkpe2Zvcih2YXIgWiBpbiBYKWlmKFohPT0iX19zb3VyY2UiJiYhKFogaW4gWSkpcmV0dXJuITA7Zm9yKHZhciBKIGluIFkpaWYoSiE9PSJfX3NvdXJjZSImJlhbSl0hPT1ZW0pdKXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIFU1KFgsWSl7dGhpcy5wcm9wcz1YLHRoaXMuY29udGV4dD1ZfShVNS5wcm90b3R5cGU9bmV3IGcpLmlzUHVyZVJlYWN0Q29tcG9uZW50PSEwLFU1LnByb3RvdHlwZS5zaG91bGRDb21wb25lbnRVcGRhdGU9ZnVuY3Rpb24oWCxZKXtyZXR1cm4gTzUodGhpcy5wcm9wcyxYKXx8TzUodGhpcy5zdGF0ZSxZKX07dmFyIEE1PVAuX19iO1AuX19iPWZ1bmN0aW9uKFgpe1gudHlwZSYmWC50eXBlLl9fZiYmWC5yZWYmJihYLnByb3BzLnJlZj1YLnJlZixYLnJlZj1udWxsKSxBNSYmQTUoWCl9O3ZhciBxNj10eXBlb2YgU3ltYm9sPCJ1IiYmU3ltYm9sLmZvciYmU3ltYm9sLmZvcigicmVhY3QuZm9yd2FyZF9yZWYiKXx8MzkxMTtmdW5jdGlvbiBHMChYKXtmdW5jdGlvbiBZKFope3ZhciBKPUk1KHt9LFopO3JldHVybiBkZWxldGUgSi5yZWYsWChKLFoucmVmfHxudWxsKX1yZXR1cm4gWS4kJHR5cGVvZj1xNixZLnJlbmRlcj1YLFkucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9WS5fX2Y9ITAsWS5kaXNwbGF5TmFtZT0iRm9yd2FyZFJlZigiKyhYLmRpc3BsYXlOYW1lfHxYLm5hbWUpKyIpIixZfXZhciBLNj1QLl9fZTtQLl9fZT1mdW5jdGlvbihYLFksWixKKXtpZihYLnRoZW4pe2Zvcih2YXIgcSxLPVk7Sz1LLl9fOylpZigocT1LLl9fYykmJnEuX19jKXJldHVybiBZLl9fZT09bnVsbCYmKFkuX19lPVouX19lLFkuX19rPVouX19rKSxxLl9fYyhYLFkpfUs2KFgsWSxaLEopfTt2YXIgRDU9UC51bm1vdW50O2Z1bmN0aW9uIE01KFgsWSxaKXtyZXR1cm4gWCYmKFguX19jJiZYLl9fYy5fX0gmJihYLl9fYy5fX0guX18uZm9yRWFjaChmdW5jdGlvbihKKXt0eXBlb2YgSi5fX2M9PSJmdW5jdGlvbiImJkouX19jKCl9KSxYLl9fYy5fX0g9bnVsbCksKFg9STUoe30sWCkpLl9fYyE9bnVsbCYmKFguX19jLl9fUD09PVomJihYLl9fYy5fX1A9WSksWC5fX2MuX19lPSEwLFguX19jPW51bGwpLFguX19rPVguX19rJiZYLl9fay5tYXAoZnVuY3Rpb24oSil7cmV0dXJuIE01KEosWSxaKX0pKSxYfWZ1bmN0aW9uIEM1KFgsWSxaKXtyZXR1cm4gWCYmWiYmKFguX192PW51bGwsWC5fX2s9WC5fX2smJlguX19rLm1hcChmdW5jdGlvbihKKXtyZXR1cm4gQzUoSixZLFopfSksWC5fX2MmJlguX19jLl9fUD09PVkmJihYLl9fZSYmWi5hcHBlbmRDaGlsZChYLl9fZSksWC5fX2MuX19lPSEwLFguX19jLl9fUD1aKSksWH1mdW5jdGlvbiBINCgpe3RoaXMuX191PTAsdGhpcy5vPW51bGwsdGhpcy5fX2I9bnVsbH1mdW5jdGlvbiBFNShYKXt2YXIgWT1YLl9fJiZYLl9fLl9fYztyZXR1cm4gWSYmWS5fX2EmJlkuX19hKFgpfWZ1bmN0aW9uIGcwKCl7dGhpcy5pPW51bGwsdGhpcy5sPW51bGx9UC51bm1vdW50PWZ1bmN0aW9uKFgpe3ZhciBZPVguX19jO1kmJihZLl9fej0hMCksWSYmWS5fX1ImJlkuX19SKCksWSYmMzImWC5fX3UmJihYLnR5cGU9bnVsbCksRDUmJkQ1KFgpfSwoSDQucHJvdG90eXBlPW5ldyBnKS5fX2M9ZnVuY3Rpb24oWCxZKXt2YXIgWj1ZLl9fYyxKPXRoaXM7Si5vPT1udWxsJiYoSi5vPVtdKSxKLm8ucHVzaChaKTt2YXIgcT1FNShKLl9fdiksSz0hMSxRPWZ1bmN0aW9uKCl7S3x8Si5fX3p8fChLPSEwLFouX19SPW51bGwscT9xKEcpOkcoKSl9O1ouX19SPVE7dmFyIHo9Wi5fX1A7Wi5fX1A9bnVsbDt2YXIgRz1mdW5jdGlvbigpe2lmKCEtLUouX191KXtpZihKLnN0YXRlLl9fYSl7dmFyIEw9Si5zdGF0ZS5fX2E7Si5fX3YuX19rWzBdPUM1KEwsTC5fX2MuX19QLEwuX19jLl9fTyl9dmFyIEQ7Zm9yKEouc2V0U3RhdGUoe19fYTpKLl9fYj1udWxsfSk7RD1KLm8ucG9wKCk7KUQuX19QPXosRC5mb3JjZVVwZGF0ZSgpfX07Si5fX3UrK3x8MzImWS5fX3V8fEouc2V0U3RhdGUoe19fYTpKLl9fYj1KLl9fdi5fX2tbMF19KSxYLnRoZW4oUSxRKX0sSDQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7dGhpcy5vPVtdfSxINC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKFgsWSl7aWYodGhpcy5fX2Ipe2lmKHRoaXMuX192Ll9fayl7dmFyIFo9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IiksSj10aGlzLl9fdi5fX2tbMF0uX19jO3RoaXMuX192Ll9fa1swXT1NNSh0aGlzLl9fYixaLEouX19PPUouX19QKX10aGlzLl9fYj1udWxsfXZhciBxPVkuX19hJiZZMCh4LG51bGwsWC5mYWxsYmFjayk7cmV0dXJuIHEmJihxLl9fdSY9LTMzKSxbWTAoeCxudWxsLFkuX19hP251bGw6WC5jaGlsZHJlbikscV19O3ZhciBQNT1mdW5jdGlvbihYLFksWil7aWYoKytaWzFdPT09WlswXSYmWC5sLmRlbGV0ZShZKSxYLnByb3BzLnJldmVhbE9yZGVyJiYoWC5wcm9wcy5yZXZlYWxPcmRlclswXSE9PSJ0Inx8IVgubC5zaXplKSlmb3IoWj1YLmk7Wjspe2Zvcig7Wi5sZW5ndGg+MzspWi5wb3AoKSgpO2lmKFpbMV08WlswXSlicmVhaztYLmk9Wj1aWzJdfX07KGcwLnByb3RvdHlwZT1uZXcgZykuX19hPWZ1bmN0aW9uKFgpe3ZhciBZPXRoaXMsWj1FNShZLl9fdiksSj1ZLmwuZ2V0KFgpO3JldHVybiBKWzBdKyssZnVuY3Rpb24ocSl7dmFyIEs9ZnVuY3Rpb24oKXtZLnByb3BzLnJldmVhbE9yZGVyPyhKLnB1c2gocSksUDUoWSxYLEopKTpxKCl9O1o/WihLKTpLKCl9fSxnMC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKFgpe3RoaXMuaT1udWxsLHRoaXMubD1uZXcgTWFwO3ZhciBZPVowKFguY2hpbGRyZW4pO1gucmV2ZWFsT3JkZXImJlgucmV2ZWFsT3JkZXJbMF09PT0iYiImJlkucmV2ZXJzZSgpO2Zvcih2YXIgWj1ZLmxlbmd0aDtaLS07KXRoaXMubC5zZXQoWVtaXSx0aGlzLmk9WzEsMCx0aGlzLmldKTtyZXR1cm4gWC5jaGlsZHJlbn0sZzAucHJvdG90eXBlLmNvbXBvbmVudERpZFVwZGF0ZT1nMC5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQ9ZnVuY3Rpb24oKXt2YXIgWD10aGlzO3RoaXMubC5mb3JFYWNoKGZ1bmN0aW9uKFksWil7UDUoWCxaLFkpfSl9O3ZhciBRNj10eXBlb2YgU3ltYm9sPCJ1IiYmU3ltYm9sLmZvciYmU3ltYm9sLmZvcigicmVhY3QuZWxlbWVudCIpfHw2MDEwMywkNj0vXig/OmFjY2VudHxhbGlnbm1lbnR8YXJhYmljfGJhc2VsaW5lfGNhcHxjbGlwKD8hUGF0aFUpfGNvbG9yfGRvbWluYW50fGZpbGx8Zmxvb2R8Zm9udHxnbHlwaCg/IVIpfGhvcml6fGltYWdlKCFTKXxsZXR0ZXJ8bGlnaHRpbmd8bWFya2VyKD8hSHxXfFUpfG92ZXJsaW5lfHBhaW50fHBvaW50ZXJ8c2hhcGV8c3RvcHxzdHJpa2V0aHJvdWdofHN0cm9rZXx0ZXh0KD8hTCl8dHJhbnNmb3JtfHVuZGVybGluZXx1bmljb2RlfHVuaXRzfHZ8dmVjdG9yfHZlcnR8d29yZHx3cml0aW5nfHgoPyFDKSlbQS1aXS8sVzY9L15vbihBbml8VHJhfFRvdXxCZWZvcmVJbnB8Q29tcG8pLyxMNj0vW0EtWjAtOV0vZyx6Nj10eXBlb2YgZG9jdW1lbnQ8InUiLE42PWZ1bmN0aW9uKFgpe3JldHVybih0eXBlb2YgU3ltYm9sPCJ1IiYmdHlwZW9mIFN5bWJvbCgpPT0ic3ltYm9sIj8vZmlsfGNoZXxyYWQvOi9maWx8Y2hlfHJhLykudGVzdChYKX07Zy5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudD0hMCxbImNvbXBvbmVudFdpbGxNb3VudCIsImNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMiLCJjb21wb25lbnRXaWxsVXBkYXRlIl0uZm9yRWFjaChmdW5jdGlvbihYKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoZy5wcm90b3R5cGUsWCx7Y29uZmlndXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzWyJVTlNBRkVfIitYXX0sc2V0OmZ1bmN0aW9uKFkpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFgse2NvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTpZfSl9fSl9KTt2YXIgQjU9UC5ldmVudDtQLmV2ZW50PWZ1bmN0aW9uKFgpe3JldHVybiBCNSYmKFg9QjUoWCkpLFgucGVyc2lzdD1mdW5jdGlvbigpe30sWC5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmNhbmNlbEJ1YmJsZX0sWC5pc0RlZmF1bHRQcmV2ZW50ZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kZWZhdWx0UHJldmVudGVkfSxYLm5hdGl2ZUV2ZW50PVh9O3ZhciB3NSxHNj17Y29uZmlndXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmNsYXNzfX0sXzU9UC52bm9kZTtQLnZub2RlPWZ1bmN0aW9uKFgpe3R5cGVvZiBYLnR5cGU9PSJzdHJpbmciJiZmdW5jdGlvbihZKXt2YXJ7cHJvcHM6Wix0eXBlOkp9PVkscT17fSxLPUouaW5kZXhPZigiLSIpPT0tMTtmb3IodmFyIFEgaW4gWil7dmFyIHo9WltRXTtpZighKFE9PT0idmFsdWUiJiYoImRlZmF1bHRWYWx1ZSJpbiBaKSYmej09bnVsbHx8ejYmJlE9PT0iY2hpbGRyZW4iJiZKPT09Im5vc2NyaXB0Inx8UT09PSJjbGFzcyJ8fFE9PT0iY2xhc3NOYW1lIikpe3ZhciBHPVEudG9Mb3dlckNhc2UoKTtRPT09ImRlZmF1bHRWYWx1ZSImJiJ2YWx1ZSJpbiBaJiZaLnZhbHVlPT1udWxsP1E9InZhbHVlIjpRPT09ImRvd25sb2FkIiYmej09PSEwP3o9IiI6Rz09PSJ0cmFuc2xhdGUiJiZ6PT09Im5vIj96PSExOkdbMF09PT0ibyImJkdbMV09PT0ibiI/Rz09PSJvbmRvdWJsZWNsaWNrIj9RPSJvbmRibGNsaWNrIjpHIT09Im9uY2hhbmdlInx8SiE9PSJpbnB1dCImJkohPT0idGV4dGFyZWEifHxONihaLnR5cGUpP0c9PT0ib25mb2N1cyI/UT0ib25mb2N1c2luIjpHPT09Im9uYmx1ciI/UT0ib25mb2N1c291dCI6VzYudGVzdChRKSYmKFE9Ryk6Rz1RPSJvbmlucHV0IjpLJiYkNi50ZXN0KFEpP1E9US5yZXBsYWNlKEw2LCItJCYiKS50b0xvd2VyQ2FzZSgpOno9PT1udWxsJiYoej12b2lkIDApLEc9PT0ib25pbnB1dCImJnFbUT1HXSYmKFE9Im9uaW5wdXRDYXB0dXJlIikscVtRXT16fX1KPT0ic2VsZWN0IiYmKHEubXVsdGlwbGUmJkFycmF5LmlzQXJyYXkocS52YWx1ZSkmJihxLnZhbHVlPVowKFouY2hpbGRyZW4pLmZvckVhY2goZnVuY3Rpb24oTCl7TC5wcm9wcy5zZWxlY3RlZD1xLnZhbHVlLmluZGV4T2YoTC5wcm9wcy52YWx1ZSkhPS0xfSkpLHEuZGVmYXVsdFZhbHVlIT1udWxsJiYocS52YWx1ZT1aMChaLmNoaWxkcmVuKS5mb3JFYWNoKGZ1bmN0aW9uKEwpe0wucHJvcHMuc2VsZWN0ZWQ9cS5tdWx0aXBsZT9xLmRlZmF1bHRWYWx1ZS5pbmRleE9mKEwucHJvcHMudmFsdWUpIT0tMTpxLmRlZmF1bHRWYWx1ZT09TC5wcm9wcy52YWx1ZX0pKSksWi5jbGFzcyYmIVouY2xhc3NOYW1lPyhxLmNsYXNzPVouY2xhc3MsT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsImNsYXNzTmFtZSIsRzYpKTpaLmNsYXNzTmFtZSYmKHEuY2xhc3M9cS5jbGFzc05hbWU9Wi5jbGFzc05hbWUpLFkucHJvcHM9cX0oWCksWC4kJHR5cGVvZj1RNixfNSYmXzUoWCl9O3ZhciBGNT1QLl9fcjtQLl9fcj1mdW5jdGlvbihYKXtGNSYmRjUoWCksdzU9WC5fX2N9O3ZhciBrNT1QLmRpZmZlZDtQLmRpZmZlZD1mdW5jdGlvbihYKXtrNSYmazUoWCk7dmFye3Byb3BzOlksX19lOlp9PVg7WiE9bnVsbCYmWC50eXBlPT09InRleHRhcmVhIiYmInZhbHVlImluIFkmJlkudmFsdWUhPT1aLnZhbHVlJiYoWi52YWx1ZT1ZLnZhbHVlPT1udWxsPyIiOlkudmFsdWUpLHc1PW51bGx9O3ZhciBWNj0wO2Z1bmN0aW9uICQoWCxZLFosSixxLEspe1l8fChZPXt9KTt2YXIgUSx6LEc9WTtpZigicmVmImluIEcpZm9yKHogaW4gRz17fSxZKXo9PSJyZWYiP1E9WVt6XTpHW3pdPVlbel07dmFyIEw9e3R5cGU6WCxwcm9wczpHLGtleTpaLHJlZjpRLF9fazpudWxsLF9fOm51bGwsX19iOjAsX19lOm51bGwsX19jOm51bGwsY29uc3RydWN0b3I6dm9pZCAwLF9fdjotLVY2LF9faTotMSxfX3U6MCxfX3NvdXJjZTpxLF9fc2VsZjpLfTtpZih0eXBlb2YgWD09ImZ1bmN0aW9uIiYmKFE9WC5kZWZhdWx0UHJvcHMpKWZvcih6IGluIFEpR1t6XT09PXZvaWQgMCYmKEdbel09UVt6XSk7cmV0dXJuIFAudm5vZGUmJlAudm5vZGUoTCksTH12YXIgTzQ9YHVybCgiZGF0YTppbWFnZS9zdmcreG1sLCUzQ3N2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyMCcgaGVpZ2h0PScyMCclM0UlM0NjaXJjbGUgY3g9JzEwJyBjeT0nMTAnIHI9JzknIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsMC40KScgc3Ryb2tlPSdyZ2JhKDI1NSwyNTUsMjU1LDAuNyknIHN0cm9rZS13aWR0aD0nMScvJTNFJTNDL3N2ZyUzRSIpIDEwIDEwLCBwb2ludGVyYCxINj0zLE82PTQsVTY9NTtmdW5jdGlvbiB4MCh7dXJsOlgsd3NVcmw6WSxzdHlsZTpaLGltYWdlU3R5bGU6SixjbGFzc05hbWU6cSxvbkhvbWVQcmVzczpLLG9uU3RyZWFtVG91Y2g6USxvblN0cmVhbU11bHRpVG91Y2g6eixvblN0cmVhbUJ1dHRvbjpHLHN1YnNjcmliZUZyYW1lOkwsc3RyZWFtRnJhbWU6RCxzdHJlYW1Db25maWc6VyxoaWRlQ29udHJvbHM6TyxvblN0cmVhbWluZ0NoYW5nZTpVLGNvbm5lY3Rpb25RdWFsaXR5Omt9KXtsZXQgXz0hIVEsQz13KG51bGwpLE09dyhudWxsKSxGPXcobnVsbCksW0UsSV09cCghMSksW3Yscl09cChudWxsKSxbZixpXT1wKG51bGwpLHk9dyhudWxsKSxbbSxjMF09cChudWxsKTtkKCgpPT57bGV0IFY9eS5jdXJyZW50O2lmKCFWfHx0eXBlb2YgUmVzaXplT2JzZXJ2ZXI+InUiKXJldHVybjtsZXQgSD1uZXcgUmVzaXplT2JzZXJ2ZXIoKE4pPT57bGV0IEE9TlswXT8uY29udGVudFJlY3Q7aWYoQSljMCh7d2lkdGg6QS53aWR0aCxoZWlnaHQ6QS5oZWlnaHR9KX0pO3JldHVybiBILm9ic2VydmUoViksKCk9PkguZGlzY29ubmVjdCgpfSxbXSk7bGV0W0Q0LFA0XT1wKDApLFcwPXcoMCksW3A1LGwwXT1wKCExKSx0PXcobnVsbCk7ZCgoKT0+e2lmKGs9PT0icG9vciIpe2lmKGwwKCEwKSx0LmN1cnJlbnQpY2xlYXJUaW1lb3V0KHQuY3VycmVudCk7dC5jdXJyZW50PXNldFRpbWVvdXQoKCk9PntsMCghMSksdC5jdXJyZW50PW51bGx9LDMwMDApfWVsc2UgaWYobDAoITEpLHQuY3VycmVudCljbGVhclRpbWVvdXQodC5jdXJyZW50KSx0LmN1cnJlbnQ9bnVsbDtyZXR1cm4oKT0+e2lmKHQuY3VycmVudCljbGVhclRpbWVvdXQodC5jdXJyZW50KX19LFtrXSk7bGV0IGkwPWAke1h9L3N0cmVhbS5tanBlZ2AsQjQ9dyhVKTtCNC5jdXJyZW50PVUsZCgoKT0+e0I0LmN1cnJlbnQ/LihFKX0sW0VdKSxkKCgpPT57aWYoXyYmVylpKFcpfSxbXyxXXSk7bGV0IF80PXcoITEpO180LmN1cnJlbnQ9RTtsZXQgczA9dyhudWxsKTtkKCgpPT57aWYoIV98fCFMKXJldHVybjtyZXR1cm4gTCgoVik9PntXMC5jdXJyZW50Kys7bGV0IEg9TS5jdXJyZW50O2lmKEgpe2lmKHMwLmN1cnJlbnQpVVJMLnJldm9rZU9iamVjdFVSTChzMC5jdXJyZW50KTtzMC5jdXJyZW50PVYsSC5zcmM9Vn1pZighXzQuY3VycmVudCljb25zb2xlLmxvZygiW3NlcnZlLXNpbV0gZmlyc3QgZnJhbWUgcmVjZWl2ZWQsIHJlbmRlcmluZyIpLEkoITApLHIobnVsbCl9KX0sW18sTF0pO2xldCBjPWooKFYpPT57aWYoXyl7UT8uKFYpO3JldHVybn1sZXQgSD1GLmN1cnJlbnQ7aWYoIUh8fEgucmVhZHlTdGF0ZSE9PVdlYlNvY2tldC5PUEVOKXJldHVybjtsZXQgTj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoVikpLEE9bmV3IFVpbnQ4QXJyYXkoMStOLmxlbmd0aCk7QVswXT1INixBLnNldChOLDEpLEguc2VuZChBKX0sW18sUV0pLG8wPWooKFYpPT57aWYoXyl7Rz8uKFYpO3JldHVybn1sZXQgSD1GLmN1cnJlbnQ7aWYoIUh8fEgucmVhZHlTdGF0ZSE9PVdlYlNvY2tldC5PUEVOKXJldHVybjtsZXQgTj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoe2J1dHRvbjpWfSkpLEE9bmV3IFVpbnQ4QXJyYXkoMStOLmxlbmd0aCk7QVswXT1PNixBLnNldChOLDEpLEguc2VuZChBKX0sW18sR10pLG49aigoVik9PntpZihfKXt6Py4oVik7cmV0dXJufWxldCBIPUYuY3VycmVudDtpZighSHx8SC5yZWFkeVN0YXRlIT09V2ViU29ja2V0Lk9QRU4pcmV0dXJuO2xldCBOPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShKU09OLnN0cmluZ2lmeShWKSksQT1uZXcgVWludDhBcnJheSgxK04ubGVuZ3RoKTtBWzBdPVU2LEEuc2V0KE4sMSksSC5zZW5kKEEpfSxbXyx6XSk7ZCgoKT0+e2lmKF8pcmV0dXJuO2ZldGNoKGAke1h9L2NvbmZpZ2ApLnRoZW4oKEIpPT5CLmpzb24oKSkudGhlbigoQik9PntpZihCLndpZHRoPjAmJkIuaGVpZ2h0PjApaShCKX0pLmNhdGNoKCgpPT57fSk7bGV0IFY9WT8/WC5yZXBsYWNlKC9eaHR0cC8sIndzIikrIi93cyIsSD1uZXcgV2ViU29ja2V0KFYpO0guYmluYXJ5VHlwZT0iYXJyYXlidWZmZXIiLEYuY3VycmVudD1ILEgub25vcGVuPSgpPT57SSghMCkscihudWxsKX0sSC5vbmNsb3NlPSgpPT57SSghMSl9LEgub25lcnJvcj0oKT0+e3IoIldlYlNvY2tldCBjb25uZWN0aW9uIGZhaWxlZCIpLEkoITEpfTtsZXQgTj1uZXcgQWJvcnRDb250cm9sbGVyLEE9c2V0SW50ZXJ2YWwoKCk9PntQNChXMC5jdXJyZW50KSxXMC5jdXJyZW50PTB9LDEwMDApO3JldHVybihhc3luYygpPT57dHJ5e2xldCBTPShhd2FpdCBmZXRjaChpMCx7c2lnbmFsOk4uc2lnbmFsfSkpLmJvZHk/LmdldFJlYWRlcigpO2lmKCFTKXJldHVybjtsZXQgaD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoIi0tZnJhbWUiKTt3aGlsZSghMCl7bGV0e2RvbmU6bCx2YWx1ZTp1fT1hd2FpdCBTLnJlYWQoKTtpZihsKWJyZWFrO2lmKHUpZm9yKGxldCBlMD0wO2UwPD11Lmxlbmd0aC1oLmxlbmd0aDtlMCsrKXtsZXQgRTQ9ITA7Zm9yKGxldCBJMD0wO0kwPGgubGVuZ3RoO0kwKyspaWYodVtlMCtJMF0hPT1oW0kwXSl7RTQ9ITE7YnJlYWt9aWYoRTQpVzAuY3VycmVudCsrfX19Y2F0Y2h7fX0pKCksKCk9PntOLmFib3J0KCksY2xlYXJJbnRlcnZhbChBKSxILmNsb3NlKCksRi5jdXJyZW50PW51bGx9fSxbWCxpMCxfXSksZCgoKT0+e2lmKCFfKXJldHVybjtsZXQgVj1zZXRJbnRlcnZhbCgoKT0+e1A0KFcwLmN1cnJlbnQpLFcwLmN1cnJlbnQ9MH0sMTAwMCk7cmV0dXJuKCk9PmNsZWFySW50ZXJ2YWwoVil9LFtfXSk7bGV0IGU9aigoKT0+e3JldHVybiBfP00uY3VycmVudDpDLmN1cnJlbnR9LFtfXSksQjA9aigoVixIKT0+e2xldCBOPWUoKTtpZighTilyZXR1cm47bGV0IEE9Ti5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxCPShILmNsaWVudFgtQS5sZWZ0KS9BLndpZHRoLFM9KEguY2xpZW50WS1BLnRvcCkvQS5oZWlnaHQ7Yyh7dHlwZTpWLHg6Qix5OlN9KX0sW2NdKSxRMD0zLGE9dyghMSksbz13KCExKSx1MD13KCExKSxyMD13KHtkeDowLGR5OjB9KSxWMD13KCExKSxbdDAsRjRdPXAoITEpLGs0PXcoe3g6MC41LHk6MC41fSksW3EwLHNdPXAobnVsbCk7ZCgoKT0+e2xldCBWPShOKT0+e2lmKE4ua2V5PT09IkFsdCIpRjQoITApfSxIPShOKT0+e2lmKE4ua2V5PT09IkFsdCIpe2lmKEY0KCExKSwhby5jdXJyZW50KXMobnVsbCl9fTtyZXR1cm4gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImtleWRvd24iLFYpLHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJrZXl1cCIsSCksKCk9Pnt3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigia2V5ZG93biIsViksd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoImtleXVwIixIKX19LFtdKSxkKCgpPT57aWYodDAmJiFvLmN1cnJlbnQpe2xldCBWPWs0LmN1cnJlbnQ7cyh7eDE6Vi54LHkxOlYueSx4MjoxLVYueCx5MjoxLVYueX0pfWVsc2UgaWYoIXQwJiYhby5jdXJyZW50KXMobnVsbCl9LFt0MF0pO2xldCBfMD13KG51bGwpLG4wPXcoITEpLEgwPXcoMCksSTQ9aigoVixIKT0+e24wLmN1cnJlbnQ9ITA7bGV0IE49XzAuY3VycmVudDtpZihOKWNhbmNlbEFuaW1hdGlvbkZyYW1lKEgwLmN1cnJlbnQpLEgwLmN1cnJlbnQ9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpPT57Ti5zdHlsZS5sZWZ0PWAke1YqMTAwfSVgLE4uc3R5bGUudG9wPWAke0gqMTAwfSVgLE4uc3R5bGUuZGlzcGxheT0iYmxvY2sifSl9LFtdKSxNND1qKChWLEgpPT57aWYoIW4wLmN1cnJlbnQpcmV0dXJuO2xldCBOPV8wLmN1cnJlbnQ7aWYoTiljYW5jZWxBbmltYXRpb25GcmFtZShIMC5jdXJyZW50KSxIMC5jdXJyZW50PXJlcXVlc3RBbmltYXRpb25GcmFtZSgoKT0+e04uc3R5bGUubGVmdD1gJHtWKjEwMH0lYCxOLnN0eWxlLnRvcD1gJHtIKjEwMH0lYH0pfSxbXSksRjA9aigoKT0+e24wLmN1cnJlbnQ9ITE7bGV0IFY9XzAuY3VycmVudDtpZihWKWNhbmNlbEFuaW1hdGlvbkZyYW1lKEgwLmN1cnJlbnQpLFYuc3R5bGUuZGlzcGxheT0ibm9uZSJ9LFtdKSxDND13KDApLE8wPXcobnVsbCksdjU9aigoKT0+e2xldCBWPURhdGUubm93KCksSD1WLUM0LmN1cnJlbnQ7aWYoQzQuY3VycmVudD1WLEg8MzAwKXtpZihPMC5jdXJyZW50KWNsZWFyVGltZW91dChPMC5jdXJyZW50KSxPMC5jdXJyZW50PW51bGw7aWYoSylLKCk7ZWxzZSBvMCgiYXBwX3N3aXRjaGVyIil9ZWxzZSBPMC5jdXJyZW50PXNldFRpbWVvdXQoKCk9PntpZihLKUsoKTtlbHNlIG8wKCJob21lIik7TzAuY3VycmVudD1udWxsfSwzMDApfSxbbzAsS10pLGswPSgoKT0+e2lmKCFmfHwhbSlyZXR1cm4gbnVsbDtpZihtLndpZHRoPT09MHx8bS5oZWlnaHQ9PT0wKXJldHVybiBudWxsO2xldCBWPU1hdGgubWluKG0ud2lkdGgvZi53aWR0aCxtLmhlaWdodC9mLmhlaWdodCk7cmV0dXJue3dpZHRoOmYud2lkdGgqVixoZWlnaHQ6Zi5oZWlnaHQqVn19KSgpO3JldHVybiAkKCJkaXYiLHtzdHlsZTp7ZGlzcGxheToiZmxleCIsZmxleERpcmVjdGlvbjoiY29sdW1uIixmbGV4OjEsLi4uTz97fTp7Ym9yZGVyOiIxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjEyKSJ9LG92ZXJmbG93OiJoaWRkZW4iLG1pbldpZHRoOjAsbWluSGVpZ2h0OjAsLi4uWn0sY2xhc3NOYW1lOnEsY2hpbGRyZW46WyQoImRpdiIse3JlZjp5LHN0eWxlOntwb3NpdGlvbjoicmVsYXRpdmUiLGZsZXg6MSxtaW5IZWlnaHQ6MCxtaW5XaWR0aDowLGRpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsanVzdGlmeUNvbnRlbnQ6ImNlbnRlciJ9LGNoaWxkcmVuOiQoImRpdiIse3N0eWxlOntwb3NpdGlvbjoicmVsYXRpdmUiLHdpZHRoOmswP2Ake2swLndpZHRofXB4YDoiMTAwJSIsaGVpZ2h0OmswP2Ake2swLmhlaWdodH1weGA6IjEwMCUifSxjaGlsZHJlbjpbJCgiaW1nIix7cmVmOkMsc3JjOl8/dm9pZCAwOmkwLGRyYWdnYWJsZTohMSxvbkxvYWQ6KFYpPT57bGV0IEg9Vi5jdXJyZW50VGFyZ2V0O2lmKEgubmF0dXJhbFdpZHRoPjAmJkgubmF0dXJhbEhlaWdodD4wKWkoKE4pPT5OJiZOLndpZHRoPT09SC5uYXR1cmFsV2lkdGgmJk4uaGVpZ2h0PT09SC5uYXR1cmFsSGVpZ2h0P046e3dpZHRoOkgubmF0dXJhbFdpZHRoLGhlaWdodDpILm5hdHVyYWxIZWlnaHR9KX0sc3R5bGU6Xz97ZGlzcGxheToibm9uZSJ9Ontwb3NpdGlvbjoiYWJzb2x1dGUiLGluc2V0OjAsd2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsY3Vyc29yOk80LGRpc3BsYXk6ImJsb2NrIix1c2VyU2VsZWN0OiJub25lIixXZWJraXRVc2VyU2VsZWN0OiJub25lIix0b3VjaEFjdGlvbjoibm9uZSIsLi4uSn19KSxfJiYkKCJpbWciLHtyZWY6TSxkcmFnZ2FibGU6ITEsb25Mb2FkOihWKT0+e2xldCBIPVYuY3VycmVudFRhcmdldDtpZihILm5hdHVyYWxXaWR0aD4wJiZILm5hdHVyYWxIZWlnaHQ+MClpKChOKT0+TiYmTi53aWR0aD09PUgubmF0dXJhbFdpZHRoJiZOLmhlaWdodD09PUgubmF0dXJhbEhlaWdodD9OOnt3aWR0aDpILm5hdHVyYWxXaWR0aCxoZWlnaHQ6SC5uYXR1cmFsSGVpZ2h0fSl9LHN0eWxlOntwb3NpdGlvbjoiYWJzb2x1dGUiLGluc2V0OjAsd2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsY3Vyc29yOk80LGRpc3BsYXk6ImJsb2NrIix1c2VyU2VsZWN0OiJub25lIixXZWJraXRVc2VyU2VsZWN0OiJub25lIix0b3VjaEFjdGlvbjoibm9uZSIsLi4uSn19KSwkKCJkaXYiLHtzdHlsZTp7cG9zaXRpb246ImFic29sdXRlIixpbnNldDowLGN1cnNvcjpPNCx0b3VjaEFjdGlvbjoibm9uZSJ9LG9uTW91c2VEb3duOihWKT0+e1YucHJldmVudERlZmF1bHQoKTtsZXQgSD1lKCk7aWYoIUgpcmV0dXJuO2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKFYuYWx0S2V5KXtvLmN1cnJlbnQ9ITAsdTAuY3VycmVudD1WLnNoaWZ0S2V5O2xldCBTPXt4MTpBLHkxOkIseDI6MS1BLHkyOjEtQn07cjAuY3VycmVudD17ZHg6MS1BLUEsZHk6MS1CLUJ9LHMoUyksbih7dHlwZToiYmVnaW4iLC4uLlN9KTtyZXR1cm59aWYoSTQoQSxCKSxCPjAuODgpYS5jdXJyZW50PSEwLGMoe3R5cGU6ImJlZ2luIix4OkEseTpCLGVkZ2U6UTB9KTtlbHNlIGEuY3VycmVudD0hMSxCMCgiYmVnaW4iLFYpfSxvbk1vdXNlTW92ZTooVik9PntsZXQgSD1lKCk7aWYoIUgpcmV0dXJuO2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKGs0LmN1cnJlbnQ9e3g6QSx5OkJ9LFYuYnV0dG9ucz09PTApe2lmKFYuYWx0S2V5KXMoe3gxOkEseTE6Qix4MjoxLUEseTI6MS1CfSk7cmV0dXJufWlmKG8uY3VycmVudCl7bGV0IFM7aWYodTAuY3VycmVudCl7bGV0IGg9cjAuY3VycmVudDtTPXt4MTpBLHkxOkIseDI6QStoLmR4LHkyOkIraC5keX19ZWxzZSBTPXt4MTpBLHkxOkIseDI6MS1BLHkyOjEtQn07cyhTKSxuKHt0eXBlOiJtb3ZlIiwuLi5TfSk7cmV0dXJufWlmKE00KEEsQiksYS5jdXJyZW50KWMoe3R5cGU6Im1vdmUiLHg6QSx5OkIsZWRnZTpRMH0pO2Vsc2UgQjAoIm1vdmUiLFYpfSxvbk1vdXNlVXA6KFYpPT57aWYoby5jdXJyZW50KXtsZXQgSD1lKCk7aWYoSCl7bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxBPShWLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLEI9KFYuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYodTAuY3VycmVudCl7bGV0IFM9cjAuY3VycmVudDtuKHt0eXBlOiJlbmQiLHgxOkEseTE6Qix4MjpBK1MuZHgseTI6QitTLmR5fSl9ZWxzZSBuKHt0eXBlOiJlbmQiLHgxOkEseTE6Qix4MjoxLUEseTI6MS1CfSl9aWYoby5jdXJyZW50PSExLCFWLmFsdEtleSlzKG51bGwpO3JldHVybn1pZihGMCgpLGEuY3VycmVudCl7bGV0IEg9ZSgpO2lmKEgpe2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2Moe3R5cGU6ImVuZCIseDpBLHk6QixlZGdlOlEwfSl9YS5jdXJyZW50PSExO3JldHVybn1CMCgiZW5kIixWKX0sb25Nb3VzZUxlYXZlOihWKT0+e2lmKG8uY3VycmVudCl7aWYocTApbih7dHlwZToiZW5kIiwuLi5xMH0pO28uY3VycmVudD0hMSxzKG51bGwpO3JldHVybn1pZihGMCgpLGEuY3VycmVudCl7bGV0IEg9ZSgpO2lmKEgpe2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2Moe3R5cGU6ImVuZCIseDpBLHk6QixlZGdlOlEwfSl9YS5jdXJyZW50PSExO3JldHVybn1pZihWLmJ1dHRvbnM+MClCMCgiZW5kIixWKTtzKG51bGwpfSxvblRvdWNoU3RhcnQ6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWLnRvdWNoZXMubGVuZ3RoPj0yKXtGMCgpO2xldCBoPVYudG91Y2hlc1swXSxsPVYudG91Y2hlc1sxXSx1PXt4MTooaC5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCx5MTooaC5jbGllbnRZLU4udG9wKS9OLmhlaWdodCx4MjoobC5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCx5MjoobC5jbGllbnRZLU4udG9wKS9OLmhlaWdodH07aWYoIVYwLmN1cnJlbnQmJiFhLmN1cnJlbnQpYyh7dHlwZToiZW5kIix4OnUueDEseTp1LnkxfSk7VjAuY3VycmVudD0hMCxvLmN1cnJlbnQ9ITAsYS5jdXJyZW50PSExLHModSksbih7dHlwZToiYmVnaW4iLC4uLnV9KTtyZXR1cm59bGV0IEE9Vi50b3VjaGVzWzBdO2lmKCFBKXJldHVybjtsZXQgQj0oQS5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxTPShBLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKEk0KEIsUyksUz4wLjg4KWEuY3VycmVudD0hMCxjKHt0eXBlOiJiZWdpbiIseDpCLHk6UyxlZGdlOlEwfSk7ZWxzZSBhLmN1cnJlbnQ9ITEsYyh7dHlwZToiYmVnaW4iLHg6Qix5OlN9KX0sb25Ub3VjaE1vdmU6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWMC5jdXJyZW50JiZWLnRvdWNoZXMubGVuZ3RoPj0yKXtsZXQgaD1WLnRvdWNoZXNbMF0sbD1WLnRvdWNoZXNbMV0sdT17eDE6KGguY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTE6KGguY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQseDI6KGwuY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTI6KGwuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHR9O3ModSksbih7dHlwZToibW92ZSIsLi4udX0pO3JldHVybn1sZXQgQT1WLnRvdWNoZXNbMF07aWYoIUEpcmV0dXJuO2xldCBCPShBLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLFM9KEEuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYoTTQoQixTKSxhLmN1cnJlbnQpYyh7dHlwZToibW92ZSIseDpCLHk6UyxlZGdlOlEwfSk7ZWxzZSBjKHt0eXBlOiJtb3ZlIix4OkIseTpTfSl9LG9uVG91Y2hFbmQ6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWMC5jdXJyZW50KXtpZihWLnRvdWNoZXMubGVuZ3RoPDIpe2xldCBoPVYuY2hhbmdlZFRvdWNoZXNbMF0sbD1xMDtpZihoJiZsKW4oe3R5cGU6ImVuZCIseDE6KGguY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTE6KGguY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQseDI6bC54Mix5MjpsLnkyfSk7ZWxzZSBpZihsKW4oe3R5cGU6ImVuZCIsLi4ubH0pO1YwLmN1cnJlbnQ9ITEsby5jdXJyZW50PSExLHMobnVsbCl9cmV0dXJufWxldCBBPVYuY2hhbmdlZFRvdWNoZXNbMF07aWYoIUEpcmV0dXJuO2xldCBCPShBLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLFM9KEEuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYoRjAoKSxhLmN1cnJlbnQpYyh7dHlwZToiZW5kIix4OkIseTpTLGVkZ2U6UTB9KSxhLmN1cnJlbnQ9ITE7ZWxzZSBjKHt0eXBlOiJlbmQiLHg6Qix5OlN9KX19KSwkKCJkaXYiLHtyZWY6XzAsImRhdGEtdGVzdGlkIjoidG91Y2gtaW5kaWNhdG9yIixzdHlsZTp7cG9zaXRpb246ImFic29sdXRlIixkaXNwbGF5OiJub25lIix3aWR0aDoyNCxoZWlnaHQ6MjQsYm9yZGVyUmFkaXVzOiI1MCUiLGJhY2tncm91bmQ6InJnYmEoNTksMTMwLDI0NiwwLjUpIixib3hTaGFkb3c6IjAgMCA4cHggcmdiYSg1OSwxMzAsMjQ2LDAuMykiLHRyYW5zZm9ybToidHJhbnNsYXRlKC01MCUsIC01MCUpIixwb2ludGVyRXZlbnRzOiJub25lIn19KSxxMCYmJCh4LHtjaGlsZHJlbjpbJCgiZGl2Iix7ImRhdGEtdGVzdGlkIjoiZmluZ2VyLWRvdCIsc3R5bGU6YjUocTAueDEscTAueTEpfSksJCgiZGl2Iix7ImRhdGEtdGVzdGlkIjoiZmluZ2VyLWRvdCIsc3R5bGU6YjUocTAueDIscTAueTIpfSldfSksIUUmJiF2JiYkKCJkaXYiLHtzdHlsZTpTNSxjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6e2NvbG9yOiIjODg4Iixmb250U2l6ZToxNH0sY2hpbGRyZW46IkNvbm5lY3RpbmcuLi4ifSl9KSx2JiYkKCJkaXYiLHtzdHlsZTpTNSxjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6e2NvbG9yOiIjZjQ0Iixmb250U2l6ZToxNCxwYWRkaW5nOjIwLHRleHRBbGlnbjoiY2VudGVyIn0sY2hpbGRyZW46dn0pfSkscDUmJiQoImRpdiIse3N0eWxlOkE2LGNoaWxkcmVuOiQoInNwYW4iLHtzdHlsZTp7Y29sb3I6IiNmYmJmMjQiLGZvbnRTaXplOjEzLGZvbnRGYW1pbHk6Im1vbm9zcGFjZSJ9LGNoaWxkcmVuOiJTbG93IGNvbm5lY3Rpb24ifSl9KV19KX0pLCFPJiYkKCJkaXYiLHtzdHlsZTp7ZGlzcGxheToiZmxleCIsYWxpZ25JdGVtczoiY2VudGVyIixqdXN0aWZ5Q29udGVudDoic3BhY2UtYmV0d2VlbiIscGFkZGluZzoiNHB4IDhweCIsYm9yZGVyVG9wOiIxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjEyKSJ9LGNoaWxkcmVuOlskKCJidXR0b24iLHtvbkNsaWNrOnY1LHN0eWxlOntiYWNrZ3JvdW5kOiJub25lIixib3JkZXI6IjFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMikiLGNvbG9yOiIjYWFhIixmb250U2l6ZToxMSxmb250RmFtaWx5OiJtb25vc3BhY2UiLHBhZGRpbmc6IjJweCAxMHB4IixjdXJzb3I6InBvaW50ZXIiLGJvcmRlclJhZGl1czo0fSxjaGlsZHJlbjoiSG9tZSJ9KSwkKCJzcGFuIix7c3R5bGU6e2NvbG9yOkQ0PjA/IiM0ZjQiOiIjODg4Iixmb250U2l6ZToxMixmb250RmFtaWx5OiJtb25vc3BhY2UiLGRpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjZ9LGNoaWxkcmVuOltrJiYkKCJzcGFuIix7ImRhdGEtdGVzdGlkIjoicXVhbGl0eS1kb3QiLHN0eWxlOnt3aWR0aDo4LGhlaWdodDo4LGJvcmRlclJhZGl1czoiNTAlIixkaXNwbGF5OiJpbmxpbmUtYmxvY2siLGJhY2tncm91bmQ6az09PSJnb29kIj8iIzRhZGU4MCI6az09PSJkZWdyYWRlZCI/IiNmYWNjMTUiOiIjZWY0NDQ0In19KSxENCwiIGZwcyJdfSldfSldfSl9dmFyIEE2PXtwb3NpdGlvbjoiYWJzb2x1dGUiLHRvcDo4LGxlZnQ6IjUwJSIsdHJhbnNmb3JtOiJ0cmFuc2xhdGVYKC01MCUpIixiYWNrZ3JvdW5kOiJyZ2JhKDAsMCwwLDAuNykiLGJvcmRlclJhZGl1czo2LHBhZGRpbmc6IjRweCAxMnB4Iixwb2ludGVyRXZlbnRzOiJub25lIn0sUzU9e3Bvc2l0aW9uOiJhYnNvbHV0ZSIsaW5zZXQ6MCxkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGp1c3RpZnlDb250ZW50OiJjZW50ZXIiLGJhY2tncm91bmQ6InJnYmEoMCwwLDAsMC44KSJ9LFQ1PTIwO2Z1bmN0aW9uIGI1KFgsWSl7cmV0dXJue3Bvc2l0aW9uOiJhYnNvbHV0ZSIsbGVmdDpgJHtYKjEwMH0lYCx0b3A6YCR7WSoxMDB9JWAsd2lkdGg6VDUsaGVpZ2h0OlQ1LGJvcmRlclJhZGl1czoiNTAlIixiYWNrZ3JvdW5kOiJyZ2JhKDI1NSwyNTUsMjU1LDAuNCkiLGJvcmRlcjoiMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC43KSIsdHJhbnNmb3JtOiJ0cmFuc2xhdGUoLTUwJSwgLTUwJSkiLHBvaW50ZXJFdmVudHM6Im5vbmUifX1mdW5jdGlvbiBkMChYKXtpZighWClyZXR1cm4iaXBob25lIjtsZXQgWT1YLnRvTG93ZXJDYXNlKCk7aWYoWS5pbmNsdWRlcygiaXBhZCIpKXJldHVybiJpcGFkIjtpZihZLmluY2x1ZGVzKCJ3YXRjaCIpKXJldHVybiJ3YXRjaCI7aWYoWS5pbmNsdWRlcygidmlzaW9uIikpcmV0dXJuInZpc2lvbiI7cmV0dXJuImlwaG9uZSJ9dmFyIFI9e2lwaG9uZTp7d2lkdGg6NDI3LGhlaWdodDo4ODEsYmV6ZWxYOjE4LGJlemVsWToxOCxpbm5lclJhZGl1czo1NX0saXBhZDp7d2lkdGg6NDMwLGhlaWdodDo2MDUsYmV6ZWxYOjE2LGJlemVsWToxNixpbm5lclJhZGl1czoxMn0sd2F0Y2g6e3dpZHRoOjI3NCxoZWlnaHQ6MzIyLGJlemVsWDoxMixiZXplbFk6MTIsaW5uZXJSYWRpdXM6Nzl9LHZpc2lvbjp7d2lkdGg6NjQwLGhlaWdodDo0MDAsYmV6ZWxYOjEyLGJlemVsWToxMixpbm5lclJhZGl1czozMn19LFU3PVIuaXBob25lLndpZHRoLEE3PVIuaXBob25lLmhlaWdodCxENz1SLmlwaG9uZS5iZXplbFgsUDc9Ui5pcGhvbmUuYmV6ZWxZLEI3PVIuaXBob25lLmlubmVyUmFkaXVzO2Z1bmN0aW9uIFU0KFg9ImlwaG9uZSIpe2xldCBZPVJbWF07cmV0dXJue3RvcDpgJHtZLmJlemVsWS9ZLmhlaWdodCoxMDB9JWAsbGVmdDpgJHtZLmJlemVsWC9ZLndpZHRoKjEwMH0lYCxyaWdodDpgJHtZLmJlemVsWC9ZLndpZHRoKjEwMH0lYCxib3R0b206YCR7WS5iZXplbFkvWS5oZWlnaHQqMTAwfSVgfX1mdW5jdGlvbiBtMChYPSJpcGhvbmUiKXtsZXQgWT1SW1hdLFo9WS53aWR0aC0yKlkuYmV6ZWxYLEo9WS5oZWlnaHQtMipZLmJlemVsWTtyZXR1cm5gJHtZLmlubmVyUmFkaXVzL1oqMTAwfSUgLyAke1kuaW5uZXJSYWRpdXMvSioxMDB9JWB9ZnVuY3Rpb24gaDAoe3R5cGU6WD0iaXBob25lIixzdHJlYW1pbmc6WT0hMX0pe3N3aXRjaChYKXtjYXNlImlwYWQiOnJldHVybiAkKEI2LHtzdHJlYW1pbmc6WX0pO2Nhc2Uid2F0Y2giOnJldHVybiAkKF82LHtzdHJlYW1pbmc6WX0pO2Nhc2UidmlzaW9uIjpyZXR1cm4gJChGNix7c3RyZWFtaW5nOll9KTtkZWZhdWx0OnJldHVybiAkKFA2LHtzdHJlYW1pbmc6WX0pfX1mdW5jdGlvbiBQNih7c3RyZWFtaW5nOlg9ITF9KXtyZXR1cm4gJCgic3ZnIix7dmlld0JveDoiMCAwIDQyNyA4ODEiLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIn0sZmlsbDoibm9uZSIseG1sbnM6Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIixjaGlsZHJlbjpbJCgiZGVmcyIse2NoaWxkcmVuOlskKCJmaWx0ZXIiLHtpZDoiY2hyb21lLWZpbHRlcjAiLHg6Ii0wLjE2Njk5MiIseToiMC4xNjY1MDQiLHdpZHRoOiI0MjciLGhlaWdodDoiODgwLjY2NyIsZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjUiLHJlc3VsdDoiZWZmZWN0MV9mb3JlZ3JvdW5kQmx1ciJ9KV19KSwkKCJmaWx0ZXIiLHtpZDoiY2hyb21lLWZpbHRlcjEiLHg6IjYuMzMyMzYiLHk6IjYuMzMzODIiLHdpZHRoOiI0MTQiLGhlaWdodDoiODY4IixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuMzMzMzMzIixyZXN1bHQ6ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXIifSldfSldfSksJCgicmVjdCIse3g6IjMuODMyNjgiLHk6IjMuODMzNjYiLHdpZHRoOiI0MTkiLGhlaWdodDoiODczIixyeDoiNjYuMTY2NyIsc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiNC4zMzMzMyJ9KSwkKCJyZWN0Iix7eDoiMC44MzMzMzMiLHk6IjAuODMzMzMzIix3aWR0aDoiNDI1IixoZWlnaHQ6Ijg3OSIscng6IjY5LjE2NjciLHN0cm9rZToiIzM3MzczYSIsc3Ryb2tlV2lkdGg6IjEuNjY2NjcifSksJCgiZyIse29wYWNpdHk6IjAuOSIsZmlsdGVyOiJ1cmwoI2Nocm9tZS1maWx0ZXIwKSIsY2hpbGRyZW46JCgicmVjdCIse3g6IjEuNjY2MDIiLHk6IjIiLHdpZHRoOiI0MjMuMzMzIixoZWlnaHQ6Ijg3NyIscng6IjY4LjY2NjciLHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEuNjY2NjcifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjY2hyb21lLWZpbHRlcjEpIixjaGlsZHJlbjokKCJyZWN0Iix7eDoiNy4zMzI2OCIseToiNy4zMzM2NiIsd2lkdGg6IjQxMiIsaGVpZ2h0OiI4NjYiLHJ4OiI2Mi42NjY3IixzdHJva2U6IiM2NDY0NjQiLHN0cm9rZVdpZHRoOiIwLjY2NjY2NyJ9KX0pLCQoInJlY3QiLHt4OiIxNTEuNjY2Iix5OiIzMS42NjciLHdpZHRoOiIxMjMuMzMzIixoZWlnaHQ6IjM2IixyeDoiMTgiLGZpbGw6ImJsYWNrIixzdHlsZTp7b3BhY2l0eTpYPzA6MSx0cmFuc2l0aW9uOiJvcGFjaXR5IDAuM3MgZWFzZSJ9fSldfSl9ZnVuY3Rpb24gQjYoe3N0cmVhbWluZzpYPSExfSl7bGV0IFk9Ui5pcGFkLndpZHRoLFo9Ui5pcGFkLmhlaWdodCxKPTMwLHE9MjY7cmV0dXJuICQoInN2ZyIse3ZpZXdCb3g6YDAgMCAke1l9ICR7Wn1gLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIn0sZmlsbDoibm9uZSIseG1sbnM6Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIixjaGlsZHJlbjpbJCgiZGVmcyIse2NoaWxkcmVuOlskKCJmaWx0ZXIiLHtpZDoiaXBhZC1nbG93MCIseDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuNSIscmVzdWx0OiJibHVyIn0pXX0pLCQoImZpbHRlciIse2lkOiJpcGFkLWdsb3cxIix4OiI1Iix5OiI1Iix3aWR0aDpZLTEwLGhlaWdodDpaLTEwLGZpbHRlclVuaXRzOiJ1c2VyU3BhY2VPblVzZSIsY29sb3JJbnRlcnBvbGF0aW9uRmlsdGVyczoic1JHQiIsY2hpbGRyZW46WyQoImZlRmxvb2QiLHtmbG9vZE9wYWNpdHk6IjAiLHJlc3VsdDoiQmFja2dyb3VuZEltYWdlRml4In0pLCQoImZlQmxlbmQiLHttb2RlOiJub3JtYWwiLGluOiJTb3VyY2VHcmFwaGljIixpbjI6IkJhY2tncm91bmRJbWFnZUZpeCIscmVzdWx0OiJzaGFwZSJ9KSwkKCJmZUdhdXNzaWFuQmx1ciIse3N0ZERldmlhdGlvbjoiMC4zMzMzMzMiLHJlc3VsdDoiYmx1ciJ9KV19KV19KSwkKCJyZWN0Iix7eDoiMy41Iix5OiIzLjUiLHdpZHRoOlktNyxoZWlnaHQ6Wi03LHJ4OjI2LHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjQifSksJCgicmVjdCIse3g6IjAuODMzIix5OiIwLjgzMyIsd2lkdGg6WS0xLjY2NixoZWlnaHQ6Wi0xLjY2NixyeDozMCxzdHJva2U6IiMzNzM3M2EiLHN0cm9rZVdpZHRoOiIxLjY2NiJ9KSwkKCJnIix7b3BhY2l0eToiMC45IixmaWx0ZXI6InVybCgjaXBhZC1nbG93MCkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiIxLjUiLHk6IjEuNSIsd2lkdGg6WS0zLGhlaWdodDpaLTMscng6Mjksc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiMS42NjYifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjaXBhZC1nbG93MSkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiI2Iix5OiI2Iix3aWR0aDpZLTEyLGhlaWdodDpaLTEyLHJ4OjI0LHN0cm9rZToiIzY0NjQ2NCIsc3Ryb2tlV2lkdGg6IjAuNjY2In0pfSksJCgiY2lyY2xlIix7Y3g6WS8yLGN5OlIuaXBhZC5iZXplbFkvMisxLHI6IjMiLGZpbGw6IiMxYTFhMWEiLHN0eWxlOntvcGFjaXR5Olg/MDowLjgsdHJhbnNpdGlvbjoib3BhY2l0eSAwLjNzIGVhc2UifX0pLCQoInJlY3QiLHt4OihZLTEyMCkvMix5OlotUi5pcGFkLmJlemVsWS8yLTIuNSx3aWR0aDoiMTIwIixoZWlnaHQ6IjUiLHJ4OiIyLjUiLGZpbGw6IndoaXRlIixzdHlsZTp7b3BhY2l0eTpYPzA6MC4zNSxtaXhCbGVuZE1vZGU6ImRpZmZlcmVuY2UiLHRyYW5zaXRpb246Im9wYWNpdHkgMC4zcyBlYXNlIn19KV19KX1mdW5jdGlvbiBfNih7c3RyZWFtaW5nOlg9ITF9KXtsZXQgWT1SLndhdGNoLndpZHRoLFo9Ui53YXRjaC5oZWlnaHQsSj04OCxxPTgyLEs9OCxRPTM2LHo9Wi8yLTE4LTE2LEc9MjIsTD1aLzItMTErMTY7cmV0dXJuICQoInN2ZyIse3ZpZXdCb3g6YDAgMCAke1l9ICR7Wn1gLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIixvdmVyZmxvdzoidmlzaWJsZSJ9LGZpbGw6Im5vbmUiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46WyQoImRlZnMiLHtjaGlsZHJlbjokKCJmaWx0ZXIiLHtpZDoid2F0Y2gtZ2xvdzAiLHg6IjAiLHk6IjAiLHdpZHRoOlkrMTIsaGVpZ2h0OlosZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjUiLHJlc3VsdDoiYmx1ciJ9KV19KX0pLCQoInJlY3QiLHt4OlktMix5Onosd2lkdGg6OCxoZWlnaHQ6MzYscng6IjMiLGZpbGw6IiMyYTJhMmMiLHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEifSksJCgicmVjdCIse3g6WS0xLHk6TCx3aWR0aDo2LGhlaWdodDoyMixyeDoiMi41IixmaWxsOiIjMmEyYTJjIixzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIwLjgifSksJCgicmVjdCIse3g6IjMuNSIseToiMy41Iix3aWR0aDpZLTcsaGVpZ2h0OlotNyxyeDo4MixzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIzLjUifSksJCgicmVjdCIse3g6IjAuODMzIix5OiIwLjgzMyIsd2lkdGg6WS0xLjY2NixoZWlnaHQ6Wi0xLjY2NixyeDo4OCxzdHJva2U6IiMzNzM3M2EiLHN0cm9rZVdpZHRoOiIxLjY2NiJ9KSwkKCJnIix7b3BhY2l0eToiMC45IixmaWx0ZXI6InVybCgjd2F0Y2gtZ2xvdzApIixjaGlsZHJlbjokKCJyZWN0Iix7eDoiMS41Iix5OiIxLjUiLHdpZHRoOlktMyxoZWlnaHQ6Wi0zLHJ4Ojg3LHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEuNjY2In0pfSldfSl9ZnVuY3Rpb24gRjYoe3N0cmVhbWluZzpYPSExfSl7bGV0IFk9Ui52aXNpb24ud2lkdGgsWj1SLnZpc2lvbi5oZWlnaHQsSj00MCxxPTM0O3JldHVybiAkKCJzdmciLHt2aWV3Qm94OmAwIDAgJHtZfSAke1p9YCxzdHlsZTp7d2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSJ9LGZpbGw6Im5vbmUiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46WyQoImRlZnMiLHtjaGlsZHJlbjpbJCgiZmlsdGVyIix7aWQ6InZpc2lvbi1nbG93MCIseDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuNSIscmVzdWx0OiJibHVyIn0pXX0pLCQoImZpbHRlciIse2lkOiJ2aXNpb24tZ2xvdzEiLHg6IjUiLHk6IjUiLHdpZHRoOlktMTAsaGVpZ2h0OlotMTAsZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjMzMyIscmVzdWx0OiJibHVyIn0pXX0pLCQoImxpbmVhckdyYWRpZW50Iix7aWQ6InZpc2lvbi1nbGFzcyIseDE6IjAiLHkxOiIwIix4MjoiMCIseTI6IjEiLGNoaWxkcmVuOlskKCJzdG9wIix7b2Zmc2V0OiIwJSIsc3RvcENvbG9yOiIjNTU1NTU4IixzdG9wT3BhY2l0eToiMC4zIn0pLCQoInN0b3AiLHtvZmZzZXQ6IjEwMCUiLHN0b3BDb2xvcjoiIzNhM2EzZCIsc3RvcE9wYWNpdHk6IjAuMSJ9KV19KV19KSwkKCJyZWN0Iix7eDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixyeDo0MCxmaWxsOiJ1cmwoI3Zpc2lvbi1nbGFzcykifSksJCgicmVjdCIse3g6IjMuNSIseToiMy41Iix3aWR0aDpZLTcsaGVpZ2h0OlotNyxyeDozNCxzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIzIn0pLCQoInJlY3QiLHt4OiIwLjgzMyIseToiMC44MzMiLHdpZHRoOlktMS42NjYsaGVpZ2h0OlotMS42NjYscng6NDAsc3Ryb2tlOiIjMzczNzNhIixzdHJva2VXaWR0aDoiMS42NjYifSksJCgiZyIse29wYWNpdHk6IjAuOSIsZmlsdGVyOiJ1cmwoI3Zpc2lvbi1nbG93MCkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiIxLjUiLHk6IjEuNSIsd2lkdGg6WS0zLGhlaWdodDpaLTMscng6Mzksc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiMS42NjYifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjdmlzaW9uLWdsb3cxKSIsY2hpbGRyZW46JCgicmVjdCIse3g6IjYiLHk6IjYiLHdpZHRoOlktMTIsaGVpZ2h0OlotMTIscng6MzIsc3Ryb2tlOiIjNjQ2NDY0IixzdHJva2VXaWR0aDoiMC42NjYifSl9KSwkKCJlbGxpcHNlIix7Y3g6WS8yLGN5OlovMixyeDpZLzItMzAscnk6Wi8yLTI0LHN0cm9rZToiIzRhNGE0ZCIsc3Ryb2tlV2lkdGg6IjAuNSIsb3BhY2l0eToiMC4zIixzdHlsZTp7b3BhY2l0eTpYPzA6MC4zLHRyYW5zaXRpb246Im9wYWNpdHkgMC4zcyBlYXNlIn19KV19KX12YXIgQTQ9ejAobnVsbCk7ZnVuY3Rpb24gZjAoWCl7bGV0IFk9UDAoQTQpO2lmKCFZKXRocm93IEVycm9yKGA8U2ltdWxhdG9yVG9vbGJhci4ke1h9PiBtdXN0IGJlIHJlbmRlcmVkIGluc2lkZSA8U2ltdWxhdG9yVG9vbGJhcj5gKTtyZXR1cm4gWX12YXIgTTY9e2Rpc3BsYXk6ImZsZXgiLGZsZXhXcmFwOiJ3cmFwIixhbGlnbkl0ZW1zOiJjZW50ZXIiLGp1c3RpZnlDb250ZW50OiJzcGFjZS1iZXR3ZWVuIixnYXA6IjRweCAxMnB4IixwYWRkaW5nOiI4cHggMTJweCIsYm9yZGVyUmFkaXVzOjI0LGJhY2tncm91bmQ6IiMxYzFjMWUiLGJvcmRlcjoiMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4xKSIsYm94U2hhZG93OiIwIDFweCAycHggcmdiYSgwLDAsMCwwLjIpIixtaW5XaWR0aDoyNDAsd2lkdGg6IjEwMCUifTtmdW5jdGlvbiBDNih7ZXhlYzpYLGRldmljZVVkaWQ6WSxkZXZpY2VOYW1lOlosZGV2aWNlUnVudGltZTpKLHN0cmVhbWluZzpxPSExLGRpc2FibGVkOks9ITEsY2hpbGRyZW46USxzdHlsZTp6LC4uLkd9KXtsZXQgTD1kMChaKSxXPXtleGVjOlgsZGV2aWNlVWRpZDpZLGRldmljZU5hbWU6WixkZXZpY2VSdW50aW1lOkosZGV2aWNlVHlwZTpMLHN0cmVhbWluZzpxLGRpc2FibGVkOkt8fCFZfHwhcX07cmV0dXJuICQoQTQuUHJvdmlkZXIse3ZhbHVlOlcsY2hpbGRyZW46JCgiZGl2Iix7ImRhdGEtc2ltdWxhdG9yLXRvb2xiYXIiOiEwLHN0eWxlOnsuLi5NNiwuLi56fSwuLi5HLGNoaWxkcmVuOlF9KX0pfXZhciBFNj17ZGlzcGxheToiZmxleCIsZmxleERpcmVjdGlvbjoiY29sdW1uIixhbGlnbkl0ZW1zOiJmbGV4LXN0YXJ0Iix0ZXh0QWxpZ246ImxlZnQiLGJhY2tncm91bmQ6InRyYW5zcGFyZW50Iixib3JkZXI6Im5vbmUiLGNvbG9yOiIjZmZmIixwYWRkaW5nOiIycHggNHB4IixtYXJnaW46Ii0ycHggLTRweCIsYm9yZGVyUmFkaXVzOjYsY3Vyc29yOiJwb2ludGVyIixtaW5XaWR0aDowLG1heFdpZHRoOiIxMDAlIixsaW5lSGVpZ2h0OjEuMixmb250RmFtaWx5OiJpbmhlcml0In0sdzY9RzAoZnVuY3Rpb24oe25hbWU6WSxzdWJ0aXRsZTpaLGhpZGVDaGV2cm9uOkosc3R5bGU6cSxvbk1vdXNlRW50ZXI6Syxvbk1vdXNlTGVhdmU6USwuLi56fSxHKXtsZXQgTD1mMCgiVGl0bGUiKSxbRCxXXT1wKCExKSxPPVk/P0wuZGV2aWNlTmFtZT8/Ik5vIHNpbXVsYXRvciIsVT1aPz8oTC5kZXZpY2VSdW50aW1lP0wuZGV2aWNlUnVudGltZS5yZXBsYWNlKC9cLi8sIiAiKToi4oCUIik7cmV0dXJuICQoImJ1dHRvbiIse3JlZjpHLHR5cGU6ImJ1dHRvbiIsImRhdGEtc2ltdWxhdG9yLXRvb2xiYXItdGl0bGUiOiEwLG9uTW91c2VFbnRlcjooayk9PntXKCEwKSxLPy4oayl9LG9uTW91c2VMZWF2ZTooayk9PntXKCExKSxRPy4oayl9LHN0eWxlOnsuLi5FNixiYWNrZ3JvdW5kOkQ/InJnYmEoMjU1LDI1NSwyNTUsMC4xKSI6InRyYW5zcGFyZW50IiwuLi5xfSwuLi56LGNoaWxkcmVuOlskKCJzcGFuIix7c3R5bGU6e2Rpc3BsYXk6ImlubGluZS1mbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDo0LGZvbnRTaXplOjEyLGZvbnRXZWlnaHQ6NjAwLGNvbG9yOiIjZmZmIixtYXhXaWR0aDoiMTAwJSIsb3ZlcmZsb3c6ImhpZGRlbiIsdGV4dE92ZXJmbG93OiJlbGxpcHNpcyIsd2hpdGVTcGFjZToibm93cmFwIn0sY2hpbGRyZW46W08sIUomJiQoInN2ZyIse3dpZHRoOiIxMCIsaGVpZ2h0OiIxMCIsdmlld0JveDoiMCAwIDI0IDI0IixmaWxsOiJub25lIixzdHJva2U6ImN1cnJlbnRDb2xvciIsc3Ryb2tlV2lkdGg6IjIuNSIsc3Ryb2tlTGluZWNhcDoicm91bmQiLHN0cm9rZUxpbmVqb2luOiJyb3VuZCIsc3R5bGU6e2NvbG9yOiJyZ2JhKDI1NSwyNTUsMjU1LDAuNikiLGZsZXhTaHJpbms6MH0sY2hpbGRyZW46JCgicG9seWxpbmUiLHtwb2ludHM6IjYgOSAxMiAxNSAxOCA5In0pfSldfSksJCgic3BhbiIse3N0eWxlOntmb250U2l6ZToxMCxjb2xvcjoicmdiYSgyNTUsMjU1LDI1NSwwLjUpIixtYXhXaWR0aDoiMTAwJSIsb3ZlcmZsb3c6ImhpZGRlbiIsdGV4dE92ZXJmbG93OiJlbGxpcHNpcyIsd2hpdGVTcGFjZToibm93cmFwIn0sY2hpbGRyZW46VX0pXX0pfSksUzY9e2Rpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjQsZmxleFNocmluazowfTtmdW5jdGlvbiBUNih7c3R5bGU6WCwuLi5ZfSl7cmV0dXJuICQoImRpdiIse3N0eWxlOnsuLi5TNiwuLi5YfSwuLi5ZfSl9dmFyIGI2PXtiYWNrZ3JvdW5kOiJ0cmFuc3BhcmVudCIsYm9yZGVyOiJub25lIixwYWRkaW5nOjYsYm9yZGVyUmFkaXVzOjYsY3Vyc29yOiJwb2ludGVyIixkaXNwbGF5OiJpbmxpbmUtZmxleCIsYWxpZ25JdGVtczoiY2VudGVyIixqdXN0aWZ5Q29udGVudDoiY2VudGVyIixjb2xvcjoicmdiYSgyNTUsMjU1LDI1NSwwLjgpIix0cmFuc2l0aW9uOiJiYWNrZ3JvdW5kLWNvbG9yIDAuMTVzLCBjb2xvciAwLjE1cyJ9LGEwPUcwKGZ1bmN0aW9uKHtmb3JjZURpc2FibGVkOlksc3R5bGU6WixkaXNhYmxlZDpKLG9uTW91c2VFbnRlcjpxLG9uTW91c2VMZWF2ZTpLLGNoaWxkcmVuOlEsLi4uen0sRyl7bGV0IEw9UDAoQTQpLEQ9Snx8WXx8TD8uZGlzYWJsZWQsW1csT109cCghMSk7cmV0dXJuICQoImJ1dHRvbiIse3JlZjpHLHR5cGU6ImJ1dHRvbiIsZGlzYWJsZWQ6RCxvbk1vdXNlRW50ZXI6KFUpPT57TyghMCkscT8uKFUpfSxvbk1vdXNlTGVhdmU6KFUpPT57TyghMSksSz8uKFUpfSxzdHlsZTp7Li4uYjYsY29sb3I6RD8icmdiYSgyNTUsMjU1LDI1NSwwLjI1KSI6InJnYmEoMjU1LDI1NSwyNTUsMC44KSIsYmFja2dyb3VuZDpXJiYhRD8icmdiYSgyNTUsMjU1LDI1NSwwLjEpIjoidHJhbnNwYXJlbnQiLGN1cnNvcjpEPyJub3QtYWxsb3dlZCI6InBvaW50ZXIiLC4uLlp9LC4uLnosY2hpbGRyZW46UX0pfSk7ZnVuY3Rpb24gcDYoKXtyZXR1cm5bJ3RlbGwgYXBwbGljYXRpb24gIlN5c3RlbSBFdmVudHMiIHRvIHRlbGwgcHJvY2VzcyAiU2ltdWxhdG9yIiB0byBzZXQgZnJvbnRtb3N0IHRvIHRydWUnLCd0ZWxsIGFwcGxpY2F0aW9uICJTeXN0ZW0gRXZlbnRzIiB0byB0ZWxsIHByb2Nlc3MgIlNpbXVsYXRvciIgdG8gcGVyZm9ybSBhY3Rpb24gIkFYUmFpc2UiIG9mIChmaXJzdCB3aW5kb3cgd2hvc2UgbmFtZSBjb250YWlucyAid2F0Y2hPUyIpJywndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8gdGVsbCBwcm9jZXNzICJTaW11bGF0b3IiIHRvIGNsaWNrIG1lbnUgaXRlbSAiSG9tZSIgb2YgbWVudSAiRGV2aWNlIiBvZiBtZW51IGJhciBpdGVtICJEZXZpY2UiIG9mIG1lbnUgYmFyIDEnXS5tYXAoKFkpPT5gLWUgJyR7WX0nYCkucmVkdWNlKChZLFopPT5gJHtZfSAke1p9YCwib3Nhc2NyaXB0Iil9dmFyIHY2PSQoInN2ZyIse3dpZHRoOiIxOCIsaGVpZ2h0OiIxOCIsdmlld0JveDoiMCAwIDI0IDI0IixmaWxsOiJub25lIixzdHJva2U6ImN1cnJlbnRDb2xvciIsc3Ryb2tlV2lkdGg6IjIiLHN0cm9rZUxpbmVjYXA6InJvdW5kIixzdHJva2VMaW5lam9pbjoicm91bmQiLGNoaWxkcmVuOiQoInBhdGgiLHtkOiJNMyAxMC41IDEyIDNsOSA3LjVWMjBhMSAxIDAgMCAxLTEgMWgtNXYtN2gtNnY3SDRhMSAxIDAgMCAxLTEtMXoifSl9KSxqNj0kKCJzdmciLHt3aWR0aDoiMTgiLGhlaWdodDoiMTgiLHZpZXdCb3g6IjAgMCAyNCAyNCIsZmlsbDoibm9uZSIsc3Ryb2tlOiJjdXJyZW50Q29sb3IiLHN0cm9rZVdpZHRoOiIyIixzdHJva2VMaW5lY2FwOiJyb3VuZCIsc3Ryb2tlTGluZWpvaW46InJvdW5kIixjaGlsZHJlbjpbJCgicGF0aCIse2Q6Ik0xNC41IDRoLTVMNyA3SDRhMiAyIDAgMCAwLTIgMnY5YTIgMiAwIDAgMCAyIDJoMTZhMiAyIDAgMCAwIDItMlY5YTIgMiAwIDAgMC0yLTJoLTN6In0pLCQoImNpcmNsZSIse2N4OiIxMiIsY3k6IjEzIixyOiI0In0pXX0pLFI2PSQoInN2ZyIse3dpZHRoOiIxOCIsaGVpZ2h0OiIxOCIsdmlld0JveDoiMCAwIDEyIDEzIixmaWxsOiJjdXJyZW50Q29sb3IiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46JCgicGF0aCIse2Q6Ik0xMC4yMzA1IDEyLjgwNzdINC40MjM4M0MzLjkyMzgzIDEyLjgwNzcgMy41NDY4OCAxMi42ODQ2IDMuMjkyOTcgMTIuNDM4NUMzLjA0Mjk3IDEyLjE5NjMgMi45MTc5NyAxMS44MTk0IDIuOTE3OTcgMTEuMzA3N1Y1LjUxMjc0QzIuOTE3OTcgNC45OTcxMSAzLjA0Mjk3IDQuNjE4MjEgMy4yOTI5NyA0LjM3NjAyQzMuNTQ2ODggNC4xMjk5MyAzLjkyMzgzIDQuMDA2ODggNC40MjM4MyA0LjAwNjg4SDEwLjIzMDVDMTAuNzM0NCA0LjAwNjg4IDExLjExMTMgNC4xMjk5MyAxMS4zNjEzIDQuMzc2MDJDMTEuNjExMyA0LjYxODIxIDExLjczNjMgNC45OTcxMSAxMS43MzYzIDUuNTEyNzRWMTEuMzA3N0MxMS43MzYzIDExLjgxOTQgMTEuNjExMyAxMi4xOTYzIDExLjM2MTMgMTIuNDM4NUMxMS4xMTEzIDEyLjY4NDYgMTAuNzM0NCAxMi44MDc3IDEwLjIzMDUgMTIuODA3N1pNMTAuMjEyOSAxMS44NjQzQzEwLjQxNiAxMS44NjQzIDEwLjU2MjUgMTEuODE5NCAxMC42NTIzIDExLjcyOTVDMTAuNzQ2MSAxMS42NDM2IDEwLjc5MyAxMS40OTcxIDEwLjc5MyAxMS4yOTAxVjUuNTI0NDZDMTAuNzkzIDUuMzE3NDMgMTAuNzQ2MSA1LjE3MDk0IDEwLjY1MjMgNS4wODUwMUMxMC41NjI1IDQuOTk1MTYgMTAuNDE2IDQuOTUwMjQgMTAuMjEyOSA0Ljk1MDI0SDQuNDQxNDFDNC4yNDIxOSA0Ljk1MDI0IDQuMDk1NyA0Ljk5NTE2IDQuMDAxOTUgNS4wODUwMUMzLjkwODIgNS4xNzA5NCAzLjg2MTMzIDUuMzE3NDMgMy44NjEzMyA1LjUyNDQ2VjExLjI5MDFDMy44NjEzMyAxMS40OTcxIDMuOTA4MiAxMS42NDM2IDQuMDAxOTUgMTEuNzI5NUM0LjA5NTcgMTEuODE5NCA0LjI0MjE5IDExLjg2NDMgNC40NDE0MSAxMS44NjQzSDEwLjIxMjlaTTIuOTE3OTcgMi41ODMwNVYwLjQxNTA4M0MyLjkxNzk3IDAuMjAwMjQgMi45ODYzMyAwLjA2OTM4MDMgMy4xMjMwNSAwLjAyMjUwNTNDMy4yNTk3NyAtMC4wMjgyNzU5IDMuNDEwMTYgMC4wMDY4ODAzMyAzLjU3NDIyIDAuMTI3OTc0TDUuMDUwNzggMS4yMTE5NkM1LjE3NTc4IDEuMzA1NzEgNS4yMzgyOCAxLjQwMTQxIDUuMjM4MjggMS40OTkwN0M1LjIzODI4IDEuNTk2NzIgNS4xNzU3OCAxLjY5MjQzIDUuMDUwNzggMS43ODYxOEwzLjU3NDIyIDIuODY0M0MzLjQxMDE2IDIuOTg1NCAzLjI1OTc3IDMuMDIyNTEgMy4xMjMwNSAyLjk3NTYzQzIuOTg2MzMgMi45MjQ4NSAyLjkxNzk3IDIuNzkzOTkgMi45MTc5NyAyLjU4MzA1Wk0zLjUzMzIgMS4xNTMzNkMzLjYyNjk1IDEuMTUzMzYgMy43MDcwMyAxLjE4NjU3IDMuNzczNDQgMS4yNTI5N0MzLjg0Mzc1IDEuMzE5MzggMy44Nzg5MSAxLjM5NzUxIDMuODc4OTEgMS40ODczNUMzLjg3ODkxIDEuNTgxMSAzLjg0Mzc1IDEuNjYzMTMgMy43NzM0NCAxLjczMzQ0QzMuNzA3MDMgMS43OTk4NSAzLjYyNjk1IDEuODMzMDUgMy41MzMyIDEuODMzMDVIMi44MDY2NEMyLjM4MDg2IDEuODMzMDUgMi4wMTE3MiAxLjkyNDg1IDEuNjk5MjIgMi4xMDg0NEMxLjM5MDYyIDIuMjg4MTMgMS4xNTIzNCAyLjUzODEzIDAuOTg0Mzc1IDIuODU4NDRDMC44MTY0MDYgMy4xNzg3NiAwLjczMjQyMiAzLjU0NTk0IDAuNzMyNDIyIDMuOTYwMDFWNC44Mzg5MUMwLjczMjQyMiA0LjkzNjU3IDAuNjk3MjY2IDUuMDIyNTEgMC42MjY5NTMgNS4wOTY3MkMwLjU1MjczNCA1LjE2NzA0IDAuNDY0ODQ0IDUuMjAyMTkgMC4zNjMyODEgNS4yMDIxOUMwLjI2NTYyNSA1LjIwMjE5IDAuMTgxNjQxIDUuMTY3MDQgMC4xMTEzMjggNS4wOTY3MkMwLjAzNzEwOTQgNS4wMjI1MSAwIDQuOTM2NTcgMCA0LjgzODkxVjMuOTYwMDFDMCAzLjQwMTQxIDAuMTE3MTg4IDIuOTExMTggMC4zNTE1NjIgMi40ODkzQzAuNTgyMDMxIDIuMDY3NDMgMC45MDgyMDMgMS43MzkzIDEuMzMwMDggMS41MDQ5M0MxLjc0ODA1IDEuMjcwNTUgMi4yMzgyOCAxLjE1MzM2IDIuODAwNzggMS4xNTMzNkgzLjUzMzJaIn0pfSkseTY9RzAoZnVuY3Rpb24oe29uQ2xpY2s6WSwuLi5afSxKKXtsZXQgcT1mMCgiSG9tZUJ1dHRvbiIpO3JldHVybiAkKGEwLHtyZWY6SiwiYXJpYS1sYWJlbCI6IkhvbWUiLG9uQ2xpY2s6KEspPT57aWYoWT8uKEspLEsuZGVmYXVsdFByZXZlbnRlZClyZXR1cm47aWYocS5kZXZpY2VUeXBlPT09IndhdGNoIilxLmV4ZWMocDYoKSk7ZWxzZSBxLmV4ZWMoInNlcnZlLXNpbSBidXR0b24gaG9tZSIpfSwuLi5aLGNoaWxkcmVuOnY2fSl9KSxnNj1HMChmdW5jdGlvbih7b25DbGljazpZLC4uLlp9LEope2xldCBxPWYwKCJTY3JlZW5zaG90QnV0dG9uIik7cmV0dXJuICQoYTAse3JlZjpKLCJhcmlhLWxhYmVsIjoiU2NyZWVuc2hvdCIsb25DbGljazooSyk9PntpZihZPy4oSyksSy5kZWZhdWx0UHJldmVudGVkKXJldHVybjtpZihxLmRldmljZVVkaWQpcS5leGVjKGB4Y3J1biBzaW1jdGwgaW8gJHtxLmRldmljZVVkaWR9IHNjcmVlbnNob3Qgfi9EZXNrdG9wL2hhdGNoLXNjcmVlbnNob3QtJChkYXRlICslcykucG5nYCl9LC4uLlosY2hpbGRyZW46ajZ9KX0pLHg2PUcwKGZ1bmN0aW9uKHtvbkNsaWNrOlksLi4uWn0sSil7bGV0IHE9ZjAoIlJvdGF0ZUJ1dHRvbiIpO3JldHVybiAkKGEwLHtyZWY6SiwiYXJpYS1sYWJlbCI6IlJvdGF0ZSBkZXZpY2UiLG9uQ2xpY2s6KEspPT57aWYoWT8uKEspLEsuZGVmYXVsdFByZXZlbnRlZClyZXR1cm47aWYocS5kZXZpY2VVZGlkKXEuZXhlYyhgb3Nhc2NyaXB0IC1lICd0ZWxsIGFwcGxpY2F0aW9uICJTaW11bGF0b3IiIHRvIGFjdGl2YXRlJyAtZSAndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8ga2V5IGNvZGUgMTI0IHVzaW5nIHtjb21tYW5kIGRvd259J2ApfSwuLi5aLGNoaWxkcmVuOlI2fSl9KSwkMD1DNjskMC5UaXRsZT13NjskMC5BY3Rpb25zPVQ2OyQwLkJ1dHRvbj1hMDskMC5Ib21lQnV0dG9uPXk2OyQwLlNjcmVlbnNob3RCdXR0b249ZzY7JDAuUm90YXRlQnV0dG9uPXg2O2Z1bmN0aW9uIGQ2KFgpe2xldFtZLFpdPXAobnVsbCksSj13KG5ldyBTZXQpLFtxLEtdPXAobnVsbCksUT1qKCh6KT0+e3JldHVybiBKLmN1cnJlbnQuYWRkKHopLCgpPT57Si5jdXJyZW50LmRlbGV0ZSh6KX19LFtdKTtyZXR1cm4gZCgoKT0+e2lmKCFYKXJldHVybjtsZXQgej1uZXcgQWJvcnRDb250cm9sbGVyLEc9WC5yZXBsYWNlKC9cL3N0cmVhbVwubWpwZWckLywiIik7cmV0dXJuIGZldGNoKGAke0d9L2NvbmZpZ2Ase3NpZ25hbDp6LnNpZ25hbH0pLnRoZW4oKEwpPT5MLmpzb24oKSkudGhlbigoTCk9PntpZihMLndpZHRoPjAmJkwuaGVpZ2h0PjApWihMKX0pLmNhdGNoKCgpPT57fSksKGFzeW5jKCk9Pnt0cnl7bGV0IEQ9KGF3YWl0IGZldGNoKFgse3NpZ25hbDp6LnNpZ25hbH0pKS5ib2R5Py5nZXRSZWFkZXIoKTtpZighRClyZXR1cm47bGV0IFc9bmV3IFVpbnQ4QXJyYXkoMCk7d2hpbGUoITApe2xldHtkb25lOk8sdmFsdWU6VX09YXdhaXQgRC5yZWFkKCk7aWYoTylicmVhaztsZXQgaz1uZXcgVWludDhBcnJheShXLmxlbmd0aCtVLmxlbmd0aCk7ay5zZXQoVyksay5zZXQoVSxXLmxlbmd0aCksVz1rO3doaWxlKCEwKXtsZXQgXz0tMTtmb3IobGV0IEk9MDtJPFcubGVuZ3RoLTE7SSsrKWlmKFdbSV09PT0yNTUmJldbSSsxXT09PTIxNil7Xz1JO2JyZWFrfWlmKF89PT0tMSlicmVhaztsZXQgQz0tMTtmb3IobGV0IEk9XysyO0k8Vy5sZW5ndGgtMTtJKyspaWYoV1tJXT09PTI1NSYmV1tJKzFdPT09MjE3KXtDPUkrMjticmVha31pZihDPT09LTEpYnJlYWs7bGV0IE09Vy5zbGljZShfLEMpO1c9Vy5zbGljZShDKTtsZXQgRj1uZXcgQmxvYihbTV0se3R5cGU6ImltYWdlL2pwZWcifSksRT1VUkwuY3JlYXRlT2JqZWN0VVJMKEYpO0soRSk7Zm9yKGxldCBJIG9mIEouY3VycmVudClJKEUpfX19Y2F0Y2h7fX0pKCksKCk9PnouYWJvcnQoKX0sW1hdKSx7c3Vic2NyaWJlRnJhbWU6USxmcmFtZTpxLGNvbmZpZzpZfX1mdW5jdGlvbiBtNigpe2xldCBYPXdpbmRvdy5fX1NJTV9QUkVWSUVXX18sW1ksWl09cCghMSk7aWYoZCgoKT0+e2lmKCFYPy5sb2dzRW5kcG9pbnQpcmV0dXJuO2xldCBPPW5ldyBFdmVudFNvdXJjZShYLmxvZ3NFbmRwb2ludCksVT1uZXcgTWFwLGs9WyIjOGJlOWZkIiwiIzUwZmE3YiIsIiNmZmI4NmMiLCIjZmY3OWM2IiwiI2JkOTNmOSIsIiNmMWZhOGMiLCIjNjI3MmE0IiwiI2ZmNTU1NSIsIiM2OWZmOTQiLCIjZDZhY2ZmIiwiI2ZmZmZhNSIsIiNhNGZmZmYiLCIjZmY2ZTZlIiwiI2NhYTlmYSIsIiM1YWY3OGUiXTtmdW5jdGlvbiBfKEYpe2xldCBFPVUuZ2V0KEYpO2lmKCFFKXtsZXQgST0wO2ZvcihsZXQgdj0wO3Y8Ri5sZW5ndGg7disrKUk9KEk8PDUpLUkrRi5jaGFyQ29kZUF0KHYpfDA7RT1rW01hdGguYWJzKEkpJWsubGVuZ3RoXSxVLnNldChGLEUpfXJldHVybiBFfWxldCBDPSIiLE09ITE7cmV0dXJuIE8ub25tZXNzYWdlPShGKT0+e3RyeXtsZXQgRT1KU09OLnBhcnNlKEYuZGF0YSksST1FLnByb2Nlc3NJbWFnZVBhdGg/LnNwbGl0KCIvIikucG9wKCk/P0Uuc2VuZGVySW1hZ2VQYXRoPy5zcGxpdCgiLyIpLnBvcCgpPz8iIix2PUUuc3Vic3lzdGVtPz8iIixyPUUuY2F0ZWdvcnk/PyIiLGY9RS5ldmVudE1lc3NhZ2U/PyIiO2lmKCFmKXJldHVybjtpZihJIT09Qyl7aWYoTSljb25zb2xlLmdyb3VwRW5kKCk7bGV0IGMwPV8oSSk7Y29uc29sZS5ncm91cENvbGxhcHNlZChgJWMke0l9JHt2P2AgJWMke3Z9JHtyPyI6IityOiIifWA6IiJ9YCxgY29sb3I6JHtjMH07Zm9udC13ZWlnaHQ6Ym9sZGAsLi4udj9bImNvbG9yOiM4ODg7Zm9udC13ZWlnaHQ6bm9ybWFsIl06W10pLE09ITAsQz1JfWxldCBpPShFLm1lc3NhZ2VUeXBlPz8iIikudG9Mb3dlckNhc2UoKSx5PXYmJkk9PT1DP2AlYyR7cnx8dn0lYyBgOiIiLG09eT9bImNvbG9yOiM4ODg7Zm9udC1zdHlsZTppdGFsaWMiLCJjb2xvcjppbmhlcml0Il06W107aWYoaT09PSJmYXVsdCJ8fGk9PT0iZXJyb3IiKWNvbnNvbGUubG9nKGAke3l9JWMke2Z9YCwuLi5tLCJjb2xvcjojZmY1NTU1Iik7ZWxzZSBpZihpPT09ImRlYnVnIiljb25zb2xlLmxvZyhgJHt5fSVjJHtmfWAsLi4ubSwiY29sb3I6IzYyNzJhNCIpO2Vsc2UgY29uc29sZS5sb2coYCR7eX0lYyR7Zn1gLC4uLm0sImNvbG9yOmluaGVyaXQiKX1jYXRjaHt9fSwoKT0+e2lmKE0pY29uc29sZS5ncm91cEVuZCgpO08uY2xvc2UoKX19LFtYPy5sb2dzRW5kcG9pbnRdKSwhWClyZXR1cm4gJCgiZGl2Iix7c3R5bGU6SjAucGFnZSxjaGlsZHJlbjokKCJkaXYiLHtzdHlsZTpKMC5lbXB0eSxjaGlsZHJlbjpbJCgiaDEiLHtzdHlsZTpKMC5lbXB0eVRpdGxlLGNoaWxkcmVuOiJObyBzZXJ2ZS1zaW0gc3RyZWFtIHJ1bm5pbmcifSksJCgicCIse3N0eWxlOkowLmVtcHR5SGludCxjaGlsZHJlbjpbIkJvb3QgYW4gaU9TIHNpbXVsYXRvciBhbmQgc3RhcnQgYSBIYXRjaCBzdHJlYW0gd2l0aCIsIiAiLCQoImNvZGUiLHtzdHlsZTpKMC5jb2RlLGNoaWxkcmVuOiJidW54IHNlcnZlLXNpbSAtLWRldGFjaCJ9KSwiLCB0aGVuIHJlbG9hZC4iXX0pXX0pfSk7bGV0IEo9Ui5pcGhvbmUscT1VNCgiaXBob25lIiksSz1tMCgiaXBob25lIiksUT1kNihYLnN0cmVhbVVybCksej13KG51bGwpO2QoKCk9PntsZXQgTz1uZXcgV2ViU29ja2V0KFgud3NVcmwpO3JldHVybiBPLmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix6LmN1cnJlbnQ9TywoKT0+e08uY2xvc2UoKSx6LmN1cnJlbnQ9bnVsbH19LFtYLndzVXJsXSk7bGV0IEc9aigoTyxVKT0+e2xldCBrPXouY3VycmVudDtpZigha3x8ay5yZWFkeVN0YXRlIT09V2ViU29ja2V0Lk9QRU4pcmV0dXJuO2xldCBfPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShKU09OLnN0cmluZ2lmeShVKSksQz1uZXcgVWludDhBcnJheSgxK18ubGVuZ3RoKTtDWzBdPU8sQy5zZXQoXywxKSxrLnNlbmQoQyl9LFtdKSxMPWooKE8pPT5HKDMsTyksW0ddKSxEPWooKE8pPT5HKDUsTyksW0ddKSxXPWooKE8pPT5HKDQse2J1dHRvbjpPfSksW0ddKTtyZXR1cm4gJCgiZGl2Iix7c3R5bGU6SjAucGFnZSxjaGlsZHJlbjpbJCgiZGl2Iix7c3R5bGU6e3Bvc2l0aW9uOiJyZWxhdGl2ZSIsbWF4V2lkdGg6MzIwLHdpZHRoOiIxMDAlIixhc3BlY3RSYXRpbzpgJHtKLndpZHRofSAvICR7Si5oZWlnaHR9YH0sY2hpbGRyZW46WyQoImRpdiIse3N0eWxlOntwb3NpdGlvbjoiYWJzb2x1dGUiLC4uLnF9LGNoaWxkcmVuOiQoeDAse3VybDpYLnVybCxzdHlsZTp7d2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsYm9yZGVyOiJub25lIn0saW1hZ2VTdHlsZTp7Ym9yZGVyUmFkaXVzOkssY29ybmVyU2hhcGU6InN1cGVyZWxsaXBzZSgxLjMpIn0saGlkZUNvbnRyb2xzOiEwLG9uU3RyZWFtaW5nQ2hhbmdlOlosb25TdHJlYW1Ub3VjaDpMLG9uU3RyZWFtTXVsdGlUb3VjaDpELG9uU3RyZWFtQnV0dG9uOlcsc3Vic2NyaWJlRnJhbWU6US5zdWJzY3JpYmVGcmFtZSxzdHJlYW1GcmFtZTpRLmZyYW1lLHN0cmVhbUNvbmZpZzpRLmNvbmZpZ30pfSksJCgiZGl2Iix7c3R5bGU6e3Bvc2l0aW9uOiJhYnNvbHV0ZSIsaW5zZXQ6MCxwb2ludGVyRXZlbnRzOiJub25lIix6SW5kZXg6MTB9LGNoaWxkcmVuOiQoaDAse3R5cGU6ImlwaG9uZSIsc3RyZWFtaW5nOll9KX0pXX0pLCQoImRpdiIse3N0eWxlOkowLmJhcixjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6ey4uLkowLmxpdmUsY29sb3I6WT8iIzRhZGU4MCI6IiM2NjYifSxjaGlsZHJlbjpbJCgic3BhbiIse3N0eWxlOnsuLi5KMC5kb3QsYmFja2dyb3VuZDpZPyIjNGFkZTgwIjoiIzY2NiJ9fSksWT8ibGl2ZSI6ImNvbm5lY3RpbmciXX0pfSldfSl9dmFyIEowPXtwYWdlOntkaXNwbGF5OiJmbGV4IixmbGV4RGlyZWN0aW9uOiJjb2x1bW4iLGFsaWduSXRlbXM6ImNlbnRlciIsanVzdGlmeUNvbnRlbnQ6ImNlbnRlciIsaGVpZ2h0OiIxMDB2aCIsYmFja2dyb3VuZDoiIzBhMGEwYSIscGFkZGluZzoyNCxnYXA6MTIsZm9udEZhbWlseToiLWFwcGxlLXN5c3RlbSwgc3lzdGVtLXVpLCBzYW5zLXNlcmlmIn0sYmFyOntkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDoxMCxmb250U2l6ZToxMixmb250RmFtaWx5OiJ1aS1tb25vc3BhY2UsIG1vbm9zcGFjZSIsY29sb3I6IiM2NjYifSxsaXZlOntkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDo1LHRyYW5zaXRpb246ImNvbG9yIDAuM3MifSxkb3Q6e3dpZHRoOjYsaGVpZ2h0OjYsYm9yZGVyUmFkaXVzOiI1MCUiLHRyYW5zaXRpb246ImJhY2tncm91bmQgMC4zcyJ9LGVtcHR5OntkaXNwbGF5OiJmbGV4IixmbGV4RGlyZWN0aW9uOiJjb2x1bW4iLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjEyLHRleHRBbGlnbjoiY2VudGVyIn0sZW1wdHlUaXRsZTp7Zm9udFNpemU6MTgsbWFyZ2luOjAsY29sb3I6IiNlZWUifSxlbXB0eUhpbnQ6e2NvbG9yOiIjODg4Iixmb250U2l6ZToxNCxtYXhXaWR0aDo0ODB9LGNvZGU6e2JhY2tncm91bmQ6IiMyMjIiLHBhZGRpbmc6IjJweCA2cHgiLGJvcmRlclJhZGl1czo0LGZvbnRTaXplOjEzfX07SDUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJvb3QiKSkucmVuZGVyKCQobTYse30pKTsKPC9zY3JpcHQ+CjwvYm9keT48L2h0bWw+","base64").toString("utf-8");return $}function y(U){let B=(U?.basePath??"/.sim").replace(/\/+$/,"");return(G,z,w)=>{let M=G.url??"";if(M===B||M===B+"/"){let V=Z()[0]??null,K=D();if(V){let X=`<script>window.__SIM_PREVIEW__=${JSON.stringify({...V,logsEndpoint:B+"/logs"})}</script>`;K=K.replace("<!--__SIM_PREVIEW_CONFIG__-->",X)}z.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),z.end(K);return}if(M===B+"/api"){let Q=Z();z.writeHead(200,{"Content-Type":"application/json","Cache-Control":"no-store"}),z.end(JSON.stringify(Q[0]||null));return}if(M===B+"/logs"||M.startsWith(B+"/logs?")){let Q=Z();if(Q.length===0){z.writeHead(404),z.end("No serve-sim device");return}let V=Q[0].device;z.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}),z.write(`:
|
|
3
|
+
|
|
4
|
+
`);let K=j("xcrun",["simctl","spawn",V,"log","stream","--style","ndjson","--level","info"],{stdio:["ignore","pipe","ignore"]}),L="";K.stdout.on("data",(X)=>{L+=X.toString();let Y;while((Y=L.indexOf(`
|
|
5
|
+
`))!==-1){let C=L.slice(0,Y).trim();if(L=L.slice(Y+1),C)z.write("data: "+C+`
|
|
6
|
+
|
|
7
|
+
`)}}),K.on("close",()=>z.end()),G.on("close",()=>K.kill());return}if(w)w()}}export{y as simMiddleware};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
var $e=Object.defineProperty;var ye=(e,_)=>{for(var t in _)$e(e,t,{get:_[t],enumerable:!0,configurable:!0,set:(C)=>_[t]=()=>C})};var ce=(e,_)=>()=>(e&&(_=e(e=0)),_);var U={};ye(U,{simMiddleware:()=>ge});import{readdirSync as pe,readFileSync as He}from"fs";import{spawn as Te}from"child_process";import{tmpdir as ue}from"os";import{join as P}from"path";function N(){let e;try{e=pe(k).filter((t)=>t.startsWith("server-")&&t.endsWith(".json"))}catch{return[]}let _=[];for(let t of e)try{let C=JSON.parse(He(P(k,t),"utf-8"));try{process.kill(C.pid,0),_.push(C)}catch{}}catch{}return _}function le(){if(!V)V=Buffer.from("PCFkb2N0eXBlIGh0bWw+CjxodG1sPjxoZWFkPgo8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsaW5pdGlhbC1zY2FsZT0xIj4KPHRpdGxlPlNpbXVsYXRvciBQcmV2aWV3PC90aXRsZT4KPHN0eWxlPiosKjo6YmVmb3JlLCo6OmFmdGVye2JveC1zaXppbmc6Ym9yZGVyLWJveH1odG1sLGJvZHl7bWFyZ2luOjA7aGVpZ2h0OjEwMCU7b3ZlcmZsb3c6aGlkZGVufTwvc3R5bGU+CjwvaGVhZD48Ym9keT4KPGRpdiBpZD0icm9vdCI+PC9kaXY+CjwhLS1fX1NJTV9QUkVWSUVXX0NPTkZJR19fLS0+CjxzY3JpcHQgdHlwZT0ibW9kdWxlIj52YXIgYjAsUCxiNCxqNSxLMCx3NCxwNCx2NCxYNCxDMCxVMCxqNCxLNCxZNCxaNCxSNCx3MD17fSxTMD1bXSxSNT0vYWNpdHxleCg/OnN8Z3xufHB8JCl8cnBofGdyaWR8b3dzfG1uY3xudHd8aW5lW2NoXXx6b298Xm9yZHxpdGVyYS9pLEEwPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24gWDAoWCxZKXtmb3IodmFyIFogaW4gWSlYW1pdPVlbWl07cmV0dXJuIFh9ZnVuY3Rpb24gUTQoWCl7WCYmWC5wYXJlbnROb2RlJiZYLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoWCl9ZnVuY3Rpb24gWTAoWCxZLFope3ZhciBKLHEsSyxRPXt9O2ZvcihLIGluIFkpSz09ImtleSI/Sj1ZW0tdOks9PSJyZWYiP3E9WVtLXTpRW0tdPVlbS107aWYoYXJndW1lbnRzLmxlbmd0aD4yJiYoUS5jaGlsZHJlbj1hcmd1bWVudHMubGVuZ3RoPjM/YjAuY2FsbChhcmd1bWVudHMsMik6WiksdHlwZW9mIFg9PSJmdW5jdGlvbiImJlguZGVmYXVsdFByb3BzIT1udWxsKWZvcihLIGluIFguZGVmYXVsdFByb3BzKVFbS109PT12b2lkIDAmJihRW0tdPVguZGVmYXVsdFByb3BzW0tdKTtyZXR1cm4gRTAoWCxRLEoscSxudWxsKX1mdW5jdGlvbiBFMChYLFksWixKLHEpe3ZhciBLPXt0eXBlOlgscHJvcHM6WSxrZXk6WixyZWY6SixfX2s6bnVsbCxfXzpudWxsLF9fYjowLF9fZTpudWxsLF9fYzpudWxsLGNvbnN0cnVjdG9yOnZvaWQgMCxfX3Y6cT09bnVsbD8rK2I0OnEsX19pOi0xLF9fdTowfTtyZXR1cm4gcT09bnVsbCYmUC52bm9kZSE9bnVsbCYmUC52bm9kZShLKSxLfWZ1bmN0aW9uIHgoWCl7cmV0dXJuIFguY2hpbGRyZW59ZnVuY3Rpb24gZyhYLFkpe3RoaXMucHJvcHM9WCx0aGlzLmNvbnRleHQ9WX1mdW5jdGlvbiBMMChYLFkpe2lmKFk9PW51bGwpcmV0dXJuIFguX18/TDAoWC5fXyxYLl9faSsxKTpudWxsO2Zvcih2YXIgWjtZPFguX19rLmxlbmd0aDtZKyspaWYoKFo9WC5fX2tbWV0pIT1udWxsJiZaLl9fZSE9bnVsbClyZXR1cm4gWi5fX2U7cmV0dXJuIHR5cGVvZiBYLnR5cGU9PSJmdW5jdGlvbiI/TDAoWCk6bnVsbH1mdW5jdGlvbiB5NShYKXtpZihYLl9fUCYmWC5fX2Qpe3ZhciBZPVguX192LFo9WS5fX2UsSj1bXSxxPVtdLEs9WDAoe30sWSk7Sy5fX3Y9WS5fX3YrMSxQLnZub2RlJiZQLnZub2RlKEspLCQ0KFguX19QLEssWSxYLl9fbixYLl9fUC5uYW1lc3BhY2VVUkksMzImWS5fX3U/W1pdOm51bGwsSixaPT1udWxsP0wwKFkpOlosISEoMzImWS5fX3UpLHEpLEsuX192PVkuX192LEsuX18uX19rW0suX19pXT1LLGQ0KEosSyxxKSxZLl9fZT1ZLl9fPW51bGwsSy5fX2UhPVomJnk0KEspfX1mdW5jdGlvbiB5NChYKXtpZigoWD1YLl9fKSE9bnVsbCYmWC5fX2MhPW51bGwpcmV0dXJuIFguX19lPVguX19jLmJhc2U9bnVsbCxYLl9fay5zb21lKGZ1bmN0aW9uKFkpe2lmKFkhPW51bGwmJlkuX19lIT1udWxsKXJldHVybiBYLl9fZT1YLl9fYy5iYXNlPVkuX19lfSkseTQoWCl9ZnVuY3Rpb24gSjQoWCl7KCFYLl9fZCYmKFguX19kPSEwKSYmSzAucHVzaChYKSYmIVQwLl9fcisrfHx3NCE9UC5kZWJvdW5jZVJlbmRlcmluZykmJigodzQ9UC5kZWJvdW5jZVJlbmRlcmluZyl8fHA0KShUMCl9ZnVuY3Rpb24gVDAoKXt0cnl7Zm9yKHZhciBYLFk9MTtLMC5sZW5ndGg7KUswLmxlbmd0aD5ZJiZLMC5zb3J0KHY0KSxYPUswLnNoaWZ0KCksWT1LMC5sZW5ndGgseTUoWCl9ZmluYWxseXtLMC5sZW5ndGg9VDAuX19yPTB9fWZ1bmN0aW9uIGc0KFgsWSxaLEoscSxLLFEseixHLEwsRCl7dmFyIFcsTyxVLGssXyxDLE0sRj1KJiZKLl9fa3x8UzAsRT1ZLmxlbmd0aDtmb3IoRz1nNShaLFksRixHLEUpLFc9MDtXPEU7VysrKShVPVouX19rW1ddKSE9bnVsbCYmKE89VS5fX2khPS0xJiZGW1UuX19pXXx8dzAsVS5fX2k9VyxDPSQ0KFgsVSxPLHEsSyxRLHosRyxMLEQpLGs9VS5fX2UsVS5yZWYmJk8ucmVmIT1VLnJlZiYmKE8ucmVmJiZXNChPLnJlZixudWxsLFUpLEQucHVzaChVLnJlZixVLl9fY3x8ayxVKSksXz09bnVsbCYmayE9bnVsbCYmKF89ayksKE09ISEoNCZVLl9fdSkpfHxPLl9faz09PVUuX19rPyhHPXg0KFUsRyxYLE0pLE0mJk8uX19lJiYoTy5fX2U9bnVsbCkpOnR5cGVvZiBVLnR5cGU9PSJmdW5jdGlvbiImJkMhPT12b2lkIDA/Rz1DOmsmJihHPWsubmV4dFNpYmxpbmcpLFUuX191Jj0tNyk7cmV0dXJuIFouX19lPV8sR31mdW5jdGlvbiBnNShYLFksWixKLHEpe3ZhciBLLFEseixHLEwsRD1aLmxlbmd0aCxXPUQsTz0wO2ZvcihYLl9faz1BcnJheShxKSxLPTA7SzxxO0srKykoUT1ZW0tdKSE9bnVsbCYmdHlwZW9mIFEhPSJib29sZWFuIiYmdHlwZW9mIFEhPSJmdW5jdGlvbiI/KHR5cGVvZiBRPT0ic3RyaW5nInx8dHlwZW9mIFE9PSJudW1iZXIifHx0eXBlb2YgUT09ImJpZ2ludCJ8fFEuY29uc3RydWN0b3I9PVN0cmluZz9RPVguX19rW0tdPUUwKG51bGwsUSxudWxsLG51bGwsbnVsbCk6QTAoUSk/UT1YLl9fa1tLXT1FMCh4LHtjaGlsZHJlbjpRfSxudWxsLG51bGwsbnVsbCk6US5jb25zdHJ1Y3Rvcj09PXZvaWQgMCYmUS5fX2I+MD9RPVguX19rW0tdPUUwKFEudHlwZSxRLnByb3BzLFEua2V5LFEucmVmP1EucmVmOm51bGwsUS5fX3YpOlguX19rW0tdPVEsRz1LK08sUS5fXz1YLFEuX19iPVguX19iKzEsej1udWxsLChMPVEuX19pPXg1KFEsWixHLFcpKSE9LTEmJihXLS0sKHo9WltMXSkmJih6Ll9fdXw9MikpLHo9PW51bGx8fHouX192PT1udWxsPyhMPT0tMSYmKHE+RD9PLS06cTxEJiZPKyspLHR5cGVvZiBRLnR5cGUhPSJmdW5jdGlvbiImJihRLl9fdXw9NCkpOkwhPUcmJihMPT1HLTE/Ty0tOkw9PUcrMT9PKys6KEw+Rz9PLS06TysrLFEuX191fD00KSkpOlguX19rW0tdPW51bGw7aWYoVylmb3IoSz0wO0s8RDtLKyspKHo9WltLXSkhPW51bGwmJigyJnouX191KT09MCYmKHouX19lPT1KJiYoSj1MMCh6KSksaDQoeix6KSk7cmV0dXJuIEp9ZnVuY3Rpb24geDQoWCxZLFosSil7dmFyIHEsSztpZih0eXBlb2YgWC50eXBlPT0iZnVuY3Rpb24iKXtmb3IocT1YLl9fayxLPTA7cSYmSzxxLmxlbmd0aDtLKyspcVtLXSYmKHFbS10uX189WCxZPXg0KHFbS10sWSxaLEopKTtyZXR1cm4gWX1YLl9fZSE9WSYmKEomJihZJiZYLnR5cGUmJiFZLnBhcmVudE5vZGUmJihZPUwwKFgpKSxaLmluc2VydEJlZm9yZShYLl9fZSxZfHxudWxsKSksWT1YLl9fZSk7ZG8gWT1ZJiZZLm5leHRTaWJsaW5nO3doaWxlKFkhPW51bGwmJlkubm9kZVR5cGU9PTgpO3JldHVybiBZfWZ1bmN0aW9uIFowKFgsWSl7cmV0dXJuIFk9WXx8W10sWD09bnVsbHx8dHlwZW9mIFg9PSJib29sZWFuInx8KEEwKFgpP1guc29tZShmdW5jdGlvbihaKXtaMChaLFkpfSk6WS5wdXNoKFgpKSxZfWZ1bmN0aW9uIHg1KFgsWSxaLEope3ZhciBxLEssUSx6PVgua2V5LEc9WC50eXBlLEw9WVtaXSxEPUwhPW51bGwmJigyJkwuX191KT09MDtpZihMPT09bnVsbCYmej09bnVsbHx8RCYmej09TC5rZXkmJkc9PUwudHlwZSlyZXR1cm4gWjtpZihKPihEPzE6MCkpe2ZvcihxPVotMSxLPVorMTtxPj0wfHxLPFkubGVuZ3RoOylpZigoTD1ZW1E9cT49MD9xLS06SysrXSkhPW51bGwmJigyJkwuX191KT09MCYmej09TC5rZXkmJkc9PUwudHlwZSlyZXR1cm4gUX1yZXR1cm4tMX1mdW5jdGlvbiBTNChYLFksWil7WVswXT09Ii0iP1guc2V0UHJvcGVydHkoWSxaPT1udWxsPyIiOlopOlhbWV09Wj09bnVsbD8iIjp0eXBlb2YgWiE9Im51bWJlciJ8fFI1LnRlc3QoWSk/WjpaKyJweCJ9ZnVuY3Rpb24gTTAoWCxZLFosSixxKXt2YXIgSyxRO1g6aWYoWT09InN0eWxlIilpZih0eXBlb2YgWj09InN0cmluZyIpWC5zdHlsZS5jc3NUZXh0PVo7ZWxzZXtpZih0eXBlb2YgSj09InN0cmluZyImJihYLnN0eWxlLmNzc1RleHQ9Sj0iIiksSilmb3IoWSBpbiBKKVomJlkgaW4gWnx8UzQoWC5zdHlsZSxZLCIiKTtpZihaKWZvcihZIGluIFopSiYmWltZXT09SltZXXx8UzQoWC5zdHlsZSxZLFpbWV0pfWVsc2UgaWYoWVswXT09Im8iJiZZWzFdPT0ibiIpSz1ZIT0oWT1ZLnJlcGxhY2UoajQsIiQxIikpLFE9WS50b0xvd2VyQ2FzZSgpLFk9USBpbiBYfHxZPT0ib25Gb2N1c091dCJ8fFk9PSJvbkZvY3VzSW4iP1Euc2xpY2UoMik6WS5zbGljZSgyKSxYLmx8fChYLmw9e30pLFgubFtZK0tdPVosWj9KP1pbVTBdPUpbVTBdOihaW1UwXT1LNCxYLmFkZEV2ZW50TGlzdGVuZXIoWSxLP1o0Olk0LEspKTpYLnJlbW92ZUV2ZW50TGlzdGVuZXIoWSxLP1o0Olk0LEspO2Vsc2V7aWYocT09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIilZPVkucmVwbGFjZSgveGxpbmsoSHw6aCkvLCJoIikucmVwbGFjZSgvc05hbWUkLywicyIpO2Vsc2UgaWYoWSE9IndpZHRoIiYmWSE9ImhlaWdodCImJlkhPSJocmVmIiYmWSE9Imxpc3QiJiZZIT0iZm9ybSImJlkhPSJ0YWJJbmRleCImJlkhPSJkb3dubG9hZCImJlkhPSJyb3dTcGFuIiYmWSE9ImNvbFNwYW4iJiZZIT0icm9sZSImJlkhPSJwb3BvdmVyIiYmWSBpbiBYKXRyeXtYW1ldPVo9PW51bGw/IiI6WjticmVhayBYfWNhdGNoKHope310eXBlb2YgWj09ImZ1bmN0aW9uInx8KFo9PW51bGx8fFo9PT0hMSYmWVs0XSE9Ii0iP1gucmVtb3ZlQXR0cmlidXRlKFkpOlguc2V0QXR0cmlidXRlKFksWT09InBvcG92ZXIiJiZaPT0xPyIiOlopKX19ZnVuY3Rpb24gVDQoWCl7cmV0dXJuIGZ1bmN0aW9uKFkpe2lmKHRoaXMubCl7dmFyIFo9dGhpcy5sW1kudHlwZStYXTtpZihZW0MwXT09bnVsbClZW0MwXT1LNCsrO2Vsc2UgaWYoWVtDMF08WltVMF0pcmV0dXJuO3JldHVybiBaKFAuZXZlbnQ/UC5ldmVudChZKTpZKX19fWZ1bmN0aW9uICQ0KFgsWSxaLEoscSxLLFEseixHLEwpe3ZhciBELFcsTyxVLGssXyxDLE0sRixFLEksdixyLGYsaSx5PVkudHlwZTtpZihZLmNvbnN0cnVjdG9yIT09dm9pZCAwKXJldHVybiBudWxsOzEyOCZaLl9fdSYmKEc9ISEoMzImWi5fX3UpLEs9W3o9WS5fX2U9Wi5fX2VdKSwoRD1QLl9fYikmJkQoWSk7WDppZih0eXBlb2YgeT09ImZ1bmN0aW9uIil0cnl7aWYoTT1ZLnByb3BzLEY9eS5wcm90b3R5cGUmJnkucHJvdG90eXBlLnJlbmRlcixFPShEPXkuY29udGV4dFR5cGUpJiZKW0QuX19jXSxJPUQ/RT9FLnByb3BzLnZhbHVlOkQuX186SixaLl9fYz9DPShXPVkuX19jPVouX19jKS5fXz1XLl9fRTooRj9ZLl9fYz1XPW5ldyB5KE0sSSk6KFkuX19jPVc9bmV3IGcoTSxJKSxXLmNvbnN0cnVjdG9yPXksVy5yZW5kZXI9bTUpLEUmJkUuc3ViKFcpLFcuc3RhdGV8fChXLnN0YXRlPXt9KSxXLl9fbj1KLE89Vy5fX2Q9ITAsVy5fX2g9W10sVy5fc2I9W10pLEYmJlcuX19zPT1udWxsJiYoVy5fX3M9Vy5zdGF0ZSksRiYmeS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMhPW51bGwmJihXLl9fcz09Vy5zdGF0ZSYmKFcuX19zPVgwKHt9LFcuX19zKSksWDAoVy5fX3MseS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoTSxXLl9fcykpKSxVPVcucHJvcHMsaz1XLnN0YXRlLFcuX192PVksTylGJiZ5LmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcz09bnVsbCYmVy5jb21wb25lbnRXaWxsTW91bnQhPW51bGwmJlcuY29tcG9uZW50V2lsbE1vdW50KCksRiYmVy5jb21wb25lbnREaWRNb3VudCE9bnVsbCYmVy5fX2gucHVzaChXLmNvbXBvbmVudERpZE1vdW50KTtlbHNle2lmKEYmJnkuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzPT1udWxsJiZNIT09VSYmVy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIT1udWxsJiZXLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoTSxJKSxZLl9fdj09Wi5fX3Z8fCFXLl9fZSYmVy5zaG91bGRDb21wb25lbnRVcGRhdGUhPW51bGwmJlcuc2hvdWxkQ29tcG9uZW50VXBkYXRlKE0sVy5fX3MsSSk9PT0hMSl7WS5fX3YhPVouX192JiYoVy5wcm9wcz1NLFcuc3RhdGU9Vy5fX3MsVy5fX2Q9ITEpLFkuX19lPVouX19lLFkuX19rPVouX19rLFkuX19rLnNvbWUoZnVuY3Rpb24obSl7bSYmKG0uX189WSl9KSxTMC5wdXNoLmFwcGx5KFcuX19oLFcuX3NiKSxXLl9zYj1bXSxXLl9faC5sZW5ndGgmJlEucHVzaChXKTticmVhayBYfVcuY29tcG9uZW50V2lsbFVwZGF0ZSE9bnVsbCYmVy5jb21wb25lbnRXaWxsVXBkYXRlKE0sVy5fX3MsSSksRiYmVy5jb21wb25lbnREaWRVcGRhdGUhPW51bGwmJlcuX19oLnB1c2goZnVuY3Rpb24oKXtXLmNvbXBvbmVudERpZFVwZGF0ZShVLGssXyl9KX1pZihXLmNvbnRleHQ9SSxXLnByb3BzPU0sVy5fX1A9WCxXLl9fZT0hMSx2PVAuX19yLHI9MCxGKVcuc3RhdGU9Vy5fX3MsVy5fX2Q9ITEsdiYmdihZKSxEPVcucmVuZGVyKFcucHJvcHMsVy5zdGF0ZSxXLmNvbnRleHQpLFMwLnB1c2guYXBwbHkoVy5fX2gsVy5fc2IpLFcuX3NiPVtdO2Vsc2UgZG8gVy5fX2Q9ITEsdiYmdihZKSxEPVcucmVuZGVyKFcucHJvcHMsVy5zdGF0ZSxXLmNvbnRleHQpLFcuc3RhdGU9Vy5fX3M7d2hpbGUoVy5fX2QmJisrcjwyNSk7Vy5zdGF0ZT1XLl9fcyxXLmdldENoaWxkQ29udGV4dCE9bnVsbCYmKEo9WDAoWDAoe30sSiksVy5nZXRDaGlsZENvbnRleHQoKSkpLEYmJiFPJiZXLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlIT1udWxsJiYoXz1XLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlKFUsaykpLGY9RCE9bnVsbCYmRC50eXBlPT09eCYmRC5rZXk9PW51bGw/bTQoRC5wcm9wcy5jaGlsZHJlbik6RCx6PWc0KFgsQTAoZik/ZjpbZl0sWSxaLEoscSxLLFEseixHLEwpLFcuYmFzZT1ZLl9fZSxZLl9fdSY9LTE2MSxXLl9faC5sZW5ndGgmJlEucHVzaChXKSxDJiYoVy5fX0U9Vy5fXz1udWxsKX1jYXRjaChtKXtpZihZLl9fdj1udWxsLEd8fEshPW51bGwpaWYobS50aGVuKXtmb3IoWS5fX3V8PUc/MTYwOjEyODt6JiZ6Lm5vZGVUeXBlPT04JiZ6Lm5leHRTaWJsaW5nOyl6PXoubmV4dFNpYmxpbmc7S1tLLmluZGV4T2YoeildPW51bGwsWS5fX2U9en1lbHNle2ZvcihpPUsubGVuZ3RoO2ktLTspUTQoS1tpXSk7cTQoWSl9ZWxzZSBZLl9fZT1aLl9fZSxZLl9faz1aLl9fayxtLnRoZW58fHE0KFkpO1AuX19lKG0sWSxaKX1lbHNlIEs9PW51bGwmJlkuX192PT1aLl9fdj8oWS5fX2s9Wi5fX2ssWS5fX2U9Wi5fX2UpOno9WS5fX2U9ZDUoWi5fX2UsWSxaLEoscSxLLFEsRyxMKTtyZXR1cm4oRD1QLmRpZmZlZCkmJkQoWSksMTI4JlkuX191P3ZvaWQgMDp6fWZ1bmN0aW9uIHE0KFgpe1gmJihYLl9fYyYmKFguX19jLl9fZT0hMCksWC5fX2smJlguX19rLnNvbWUocTQpKX1mdW5jdGlvbiBkNChYLFksWil7Zm9yKHZhciBKPTA7SjxaLmxlbmd0aDtKKyspVzQoWltKXSxaWysrSl0sWlsrK0pdKTtQLl9fYyYmUC5fX2MoWSxYKSxYLnNvbWUoZnVuY3Rpb24ocSl7dHJ5e1g9cS5fX2gscS5fX2g9W10sWC5zb21lKGZ1bmN0aW9uKEspe0suY2FsbChxKX0pfWNhdGNoKEspe1AuX19lKEsscS5fX3YpfX0pfWZ1bmN0aW9uIG00KFgpe3JldHVybiB0eXBlb2YgWCE9Im9iamVjdCJ8fFg9PW51bGx8fFguX19iPjA/WDpBMChYKT9YLm1hcChtNCk6WDAoe30sWCl9ZnVuY3Rpb24gZDUoWCxZLFosSixxLEssUSx6LEcpe3ZhciBMLEQsVyxPLFUsayxfLEM9Wi5wcm9wc3x8dzAsTT1ZLnByb3BzLEY9WS50eXBlO2lmKEY9PSJzdmciP3E9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIjpGPT0ibWF0aCI/cT0iaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCI6cXx8KHE9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiKSxLIT1udWxsKXtmb3IoTD0wO0w8Sy5sZW5ndGg7TCsrKWlmKChVPUtbTF0pJiYic2V0QXR0cmlidXRlImluIFU9PSEhRiYmKEY/VS5sb2NhbE5hbWU9PUY6VS5ub2RlVHlwZT09Mykpe1g9VSxLW0xdPW51bGw7YnJlYWt9fWlmKFg9PW51bGwpe2lmKEY9PW51bGwpcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKE0pO1g9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHEsRixNLmlzJiZNKSx6JiYoUC5fX20mJlAuX19tKFksSyksej0hMSksSz1udWxsfWlmKEY9PW51bGwpQz09PU18fHomJlguZGF0YT09TXx8KFguZGF0YT1NKTtlbHNle2lmKEs9SyYmYjAuY2FsbChYLmNoaWxkTm9kZXMpLCF6JiZLIT1udWxsKWZvcihDPXt9LEw9MDtMPFguYXR0cmlidXRlcy5sZW5ndGg7TCsrKUNbKFU9WC5hdHRyaWJ1dGVzW0xdKS5uYW1lXT1VLnZhbHVlO2ZvcihMIGluIEMpVT1DW0xdLEw9PSJkYW5nZXJvdXNseVNldElubmVySFRNTCI/Vz1VOkw9PSJjaGlsZHJlbiJ8fChMIGluIE0pfHxMPT0idmFsdWUiJiYoImRlZmF1bHRWYWx1ZSJpbiBNKXx8TD09ImNoZWNrZWQiJiYoImRlZmF1bHRDaGVja2VkImluIE0pfHxNMChYLEwsbnVsbCxVLHEpO2ZvcihMIGluIE0pVT1NW0xdLEw9PSJjaGlsZHJlbiI/Tz1VOkw9PSJkYW5nZXJvdXNseVNldElubmVySFRNTCI/RD1VOkw9PSJ2YWx1ZSI/az1VOkw9PSJjaGVja2VkIj9fPVU6eiYmdHlwZW9mIFUhPSJmdW5jdGlvbiJ8fENbTF09PT1VfHxNMChYLEwsVSxDW0xdLHEpO2lmKEQpenx8VyYmKEQuX19odG1sPT1XLl9faHRtbHx8RC5fX2h0bWw9PVguaW5uZXJIVE1MKXx8KFguaW5uZXJIVE1MPUQuX19odG1sKSxZLl9faz1bXTtlbHNlIGlmKFcmJihYLmlubmVySFRNTD0iIiksZzQoWS50eXBlPT0idGVtcGxhdGUiP1guY29udGVudDpYLEEwKE8pP086W09dLFksWixKLEY9PSJmb3JlaWduT2JqZWN0Ij8iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI6cSxLLFEsSz9LWzBdOlouX19rJiZMMChaLDApLHosRyksSyE9bnVsbClmb3IoTD1LLmxlbmd0aDtMLS07KVE0KEtbTF0pO3p8fChMPSJ2YWx1ZSIsRj09InByb2dyZXNzIiYmaz09bnVsbD9YLnJlbW92ZUF0dHJpYnV0ZSgidmFsdWUiKTprIT1udWxsJiYoayE9PVhbTF18fEY9PSJwcm9ncmVzcyImJiFrfHxGPT0ib3B0aW9uIiYmayE9Q1tMXSkmJk0wKFgsTCxrLENbTF0scSksTD0iY2hlY2tlZCIsXyE9bnVsbCYmXyE9WFtMXSYmTTAoWCxMLF8sQ1tMXSxxKSl9cmV0dXJuIFh9ZnVuY3Rpb24gVzQoWCxZLFope3RyeXtpZih0eXBlb2YgWD09ImZ1bmN0aW9uIil7dmFyIEo9dHlwZW9mIFguX191PT0iZnVuY3Rpb24iO0omJlguX191KCksSiYmWT09bnVsbHx8KFguX191PVgoWSkpfWVsc2UgWC5jdXJyZW50PVl9Y2F0Y2gocSl7UC5fX2UocSxaKX19ZnVuY3Rpb24gaDQoWCxZLFope3ZhciBKLHE7aWYoUC51bm1vdW50JiZQLnVubW91bnQoWCksKEo9WC5yZWYpJiYoSi5jdXJyZW50JiZKLmN1cnJlbnQhPVguX19lfHxXNChKLG51bGwsWSkpLChKPVguX19jKSE9bnVsbCl7aWYoSi5jb21wb25lbnRXaWxsVW5tb3VudCl0cnl7Si5jb21wb25lbnRXaWxsVW5tb3VudCgpfWNhdGNoKEspe1AuX19lKEssWSl9Si5iYXNlPUouX19QPW51bGx9aWYoSj1YLl9faylmb3IocT0wO3E8Si5sZW5ndGg7cSsrKUpbcV0mJmg0KEpbcV0sWSxafHx0eXBlb2YgWC50eXBlIT0iZnVuY3Rpb24iKTtafHxRNChYLl9fZSksWC5fX2M9WC5fXz1YLl9fZT12b2lkIDB9ZnVuY3Rpb24gbTUoWCxZLFope3JldHVybiB0aGlzLmNvbnN0cnVjdG9yKFgsWil9ZnVuY3Rpb24gcDAoWCxZLFope3ZhciBKLHEsSyxRO1k9PWRvY3VtZW50JiYoWT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLFAuX18mJlAuX18oWCxZKSxxPShKPXR5cGVvZiBaPT0iZnVuY3Rpb24iKT9udWxsOlomJlouX19rfHxZLl9fayxLPVtdLFE9W10sJDQoWSxYPSghSiYmWnx8WSkuX19rPVkwKHgsbnVsbCxbWF0pLHF8fHcwLHcwLFkubmFtZXNwYWNlVVJJLCFKJiZaP1taXTpxP251bGw6WS5maXJzdENoaWxkP2IwLmNhbGwoWS5jaGlsZE5vZGVzKTpudWxsLEssIUomJlo/WjpxP3EuX19lOlkuZmlyc3RDaGlsZCxKLFEpLGQ0KEssWCxRKX1mdW5jdGlvbiB6MChYKXtmdW5jdGlvbiBZKFope3ZhciBKLHE7cmV0dXJuIHRoaXMuZ2V0Q2hpbGRDb250ZXh0fHwoSj1uZXcgU2V0LChxPXt9KVtZLl9fY109dGhpcyx0aGlzLmdldENoaWxkQ29udGV4dD1mdW5jdGlvbigpe3JldHVybiBxfSx0aGlzLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7Sj1udWxsfSx0aGlzLnNob3VsZENvbXBvbmVudFVwZGF0ZT1mdW5jdGlvbihLKXt0aGlzLnByb3BzLnZhbHVlIT1LLnZhbHVlJiZKLmZvckVhY2goZnVuY3Rpb24oUSl7US5fX2U9ITAsSjQoUSl9KX0sdGhpcy5zdWI9ZnVuY3Rpb24oSyl7Si5hZGQoSyk7dmFyIFE9Sy5jb21wb25lbnRXaWxsVW5tb3VudDtLLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7SiYmSi5kZWxldGUoSyksUSYmUS5jYWxsKEspfX0pLFouY2hpbGRyZW59cmV0dXJuIFkuX19jPSJfX2NDIitSNCsrLFkuX189WCxZLlByb3ZpZGVyPVkuX19sPShZLkNvbnN1bWVyPWZ1bmN0aW9uKFosSil7cmV0dXJuIFouY2hpbGRyZW4oSil9KS5jb250ZXh0VHlwZT1ZLFl9YjA9UzAuc2xpY2UsUD17X19lOmZ1bmN0aW9uKFgsWSxaLEope2Zvcih2YXIgcSxLLFE7WT1ZLl9fOylpZigocT1ZLl9fYykmJiFxLl9fKXRyeXtpZigoSz1xLmNvbnN0cnVjdG9yKSYmSy5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IhPW51bGwmJihxLnNldFN0YXRlKEsuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKFgpKSxRPXEuX19kKSxxLmNvbXBvbmVudERpZENhdGNoIT1udWxsJiYocS5jb21wb25lbnREaWRDYXRjaChYLEp8fHt9KSxRPXEuX19kKSxRKXJldHVybiBxLl9fRT1xfWNhdGNoKHope1g9en10aHJvdyBYfX0sYjQ9MCxqNT1mdW5jdGlvbihYKXtyZXR1cm4gWCE9bnVsbCYmWC5jb25zdHJ1Y3Rvcj09PXZvaWQgMH0sZy5wcm90b3R5cGUuc2V0U3RhdGU9ZnVuY3Rpb24oWCxZKXt2YXIgWjtaPXRoaXMuX19zIT1udWxsJiZ0aGlzLl9fcyE9dGhpcy5zdGF0ZT90aGlzLl9fczp0aGlzLl9fcz1YMCh7fSx0aGlzLnN0YXRlKSx0eXBlb2YgWD09ImZ1bmN0aW9uIiYmKFg9WChYMCh7fSxaKSx0aGlzLnByb3BzKSksWCYmWDAoWixYKSxYIT1udWxsJiZ0aGlzLl9fdiYmKFkmJnRoaXMuX3NiLnB1c2goWSksSjQodGhpcykpfSxnLnByb3RvdHlwZS5mb3JjZVVwZGF0ZT1mdW5jdGlvbihYKXt0aGlzLl9fdiYmKHRoaXMuX19lPSEwLFgmJnRoaXMuX19oLnB1c2goWCksSjQodGhpcykpfSxnLnByb3RvdHlwZS5yZW5kZXI9eCxLMD1bXSxwND10eXBlb2YgUHJvbWlzZT09ImZ1bmN0aW9uIj9Qcm9taXNlLnByb3RvdHlwZS50aGVuLmJpbmQoUHJvbWlzZS5yZXNvbHZlKCkpOnNldFRpbWVvdXQsdjQ9ZnVuY3Rpb24oWCxZKXtyZXR1cm4gWC5fX3YuX19iLVkuX192Ll9fYn0sVDAuX19yPTAsWDQ9TWF0aC5yYW5kb20oKS50b1N0cmluZyg4KSxDMD0iX19kIitYNCxVMD0iX19hIitYNCxqND0vKFBvaW50ZXJDYXB0dXJlKSR8Q2FwdHVyZSQvaSxLND0wLFk0PVQ0KCExKSxaND1UNCghMCksUjQ9MDt2YXIgTjAsVCxMNCxmNCxEMD0wLHI0PVtdLGI9UCxhND1iLl9fYixjND1iLl9fcixsND1iLmRpZmZlZCxpND1iLl9fYyxzND1iLnVubW91bnQsbzQ9Yi5fXztmdW5jdGlvbiBqMChYLFkpe2IuX19oJiZiLl9faChULFgsRDB8fFkpLEQwPTA7dmFyIFo9VC5fX0h8fChULl9fSD17X186W10sX19oOltdfSk7cmV0dXJuIFg+PVouX18ubGVuZ3RoJiZaLl9fLnB1c2goe30pLFouX19bWF19ZnVuY3Rpb24gcChYKXtyZXR1cm4gRDA9MSxONChuNCxYKX1mdW5jdGlvbiBONChYLFksWil7dmFyIEo9ajAoTjArKywyKTtpZihKLnQ9WCwhSi5fX2MmJihKLl9fPVtaP1ooWSk6bjQodm9pZCAwLFkpLGZ1bmN0aW9uKHope3ZhciBHPUouX19OP0ouX19OWzBdOkouX19bMF0sTD1KLnQoRyx6KTtHIT09TCYmKEouX19OPVtMLEouX19bMV1dLEouX19jLnNldFN0YXRlKHt9KSl9XSxKLl9fYz1ULCFULl9fZikpe3ZhciBxPWZ1bmN0aW9uKHosRyxMKXtpZighSi5fX2MuX19IKXJldHVybiEwO3ZhciBEPUouX19jLl9fSC5fXy5maWx0ZXIoZnVuY3Rpb24oTyl7cmV0dXJuIE8uX19jfSk7aWYoRC5ldmVyeShmdW5jdGlvbihPKXtyZXR1cm4hTy5fX059KSlyZXR1cm4hS3x8Sy5jYWxsKHRoaXMseixHLEwpO3ZhciBXPUouX19jLnByb3BzIT09ejtyZXR1cm4gRC5zb21lKGZ1bmN0aW9uKE8pe2lmKE8uX19OKXt2YXIgVT1PLl9fWzBdO08uX189Ty5fX04sTy5fX049dm9pZCAwLFUhPT1PLl9fWzBdJiYoVz0hMCl9fSksSyYmSy5jYWxsKHRoaXMseixHLEwpfHxXfTtULl9fZj0hMDt2YXJ7c2hvdWxkQ29tcG9uZW50VXBkYXRlOkssY29tcG9uZW50V2lsbFVwZGF0ZTpRfT1UO1QuY29tcG9uZW50V2lsbFVwZGF0ZT1mdW5jdGlvbih6LEcsTCl7aWYodGhpcy5fX2Upe3ZhciBEPUs7Sz12b2lkIDAscSh6LEcsTCksSz1EfVEmJlEuY2FsbCh0aGlzLHosRyxMKX0sVC5zaG91bGRDb21wb25lbnRVcGRhdGU9cX1yZXR1cm4gSi5fX058fEouX199ZnVuY3Rpb24gZChYLFkpe3ZhciBaPWowKE4wKyssMyk7IWIuX19zJiZ0NChaLl9fSCxZKSYmKFouX189WCxaLnU9WSxULl9fSC5fX2gucHVzaChaKSl9ZnVuY3Rpb24gdyhYKXtyZXR1cm4gRDA9NSxSMChmdW5jdGlvbigpe3JldHVybntjdXJyZW50Olh9fSxbXSl9ZnVuY3Rpb24gUjAoWCxZKXt2YXIgWj1qMChOMCsrLDcpO3JldHVybiB0NChaLl9fSCxZKSYmKFouX189WCgpLFouX19IPVksWi5fX2g9WCksWi5fX31mdW5jdGlvbiBqKFgsWSl7cmV0dXJuIEQwPTgsUjAoZnVuY3Rpb24oKXtyZXR1cm4gWH0sWSl9ZnVuY3Rpb24gUDAoWCl7dmFyIFk9VC5jb250ZXh0W1guX19jXSxaPWowKE4wKyssOSk7cmV0dXJuIFouYz1YLFk/KFouX189PW51bGwmJihaLl9fPSEwLFkuc3ViKFQpKSxZLnByb3BzLnZhbHVlKTpYLl9ffWZ1bmN0aW9uIGg1KCl7Zm9yKHZhciBYO1g9cjQuc2hpZnQoKTspe3ZhciBZPVguX19IO2lmKFguX19QJiZZKXRyeXtZLl9faC5zb21lKHYwKSxZLl9faC5zb21lKHo0KSxZLl9faD1bXX1jYXRjaChaKXtZLl9faD1bXSxiLl9fZShaLFguX192KX19fWIuX19iPWZ1bmN0aW9uKFgpe1Q9bnVsbCxhNCYmYTQoWCl9LGIuX189ZnVuY3Rpb24oWCxZKXtYJiZZLl9fayYmWS5fX2suX19tJiYoWC5fX209WS5fX2suX19tKSxvNCYmbzQoWCxZKX0sYi5fX3I9ZnVuY3Rpb24oWCl7YzQmJmM0KFgpLE4wPTA7dmFyIFk9KFQ9WC5fX2MpLl9fSDtZJiYoTDQ9PT1UPyhZLl9faD1bXSxULl9faD1bXSxZLl9fLnNvbWUoZnVuY3Rpb24oWil7Wi5fX04mJihaLl9fPVouX19OKSxaLnU9Wi5fX049dm9pZCAwfSkpOihZLl9faC5zb21lKHYwKSxZLl9faC5zb21lKHo0KSxZLl9faD1bXSxOMD0wKSksTDQ9VH0sYi5kaWZmZWQ9ZnVuY3Rpb24oWCl7bDQmJmw0KFgpO3ZhciBZPVguX19jO1kmJlkuX19IJiYoWS5fX0guX19oLmxlbmd0aCYmKHI0LnB1c2goWSkhPT0xJiZmND09PWIucmVxdWVzdEFuaW1hdGlvbkZyYW1lfHwoKGY0PWIucmVxdWVzdEFuaW1hdGlvbkZyYW1lKXx8ZjUpKGg1KSksWS5fX0guX18uc29tZShmdW5jdGlvbihaKXtaLnUmJihaLl9fSD1aLnUpLFoudT12b2lkIDB9KSksTDQ9VD1udWxsfSxiLl9fYz1mdW5jdGlvbihYLFkpe1kuc29tZShmdW5jdGlvbihaKXt0cnl7Wi5fX2guc29tZSh2MCksWi5fX2g9Wi5fX2guZmlsdGVyKGZ1bmN0aW9uKEope3JldHVybiFKLl9ffHx6NChKKX0pfWNhdGNoKEope1kuc29tZShmdW5jdGlvbihxKXtxLl9faCYmKHEuX19oPVtdKX0pLFk9W10sYi5fX2UoSixaLl9fdil9fSksaTQmJmk0KFgsWSl9LGIudW5tb3VudD1mdW5jdGlvbihYKXtzNCYmczQoWCk7dmFyIFksWj1YLl9fYztaJiZaLl9fSCYmKFouX19ILl9fLnNvbWUoZnVuY3Rpb24oSil7dHJ5e3YwKEopfWNhdGNoKHEpe1k9cX19KSxaLl9fSD12b2lkIDAsWSYmYi5fX2UoWSxaLl9fdikpfTt2YXIgdTQ9dHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZT09ImZ1bmN0aW9uIjtmdW5jdGlvbiBmNShYKXt2YXIgWSxaPWZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KEopLHU0JiZjYW5jZWxBbmltYXRpb25GcmFtZShZKSxzZXRUaW1lb3V0KFgpfSxKPXNldFRpbWVvdXQoWiwzNSk7dTQmJihZPXJlcXVlc3RBbmltYXRpb25GcmFtZShaKSl9ZnVuY3Rpb24gdjAoWCl7dmFyIFk9VCxaPVguX19jO3R5cGVvZiBaPT0iZnVuY3Rpb24iJiYoWC5fX2M9dm9pZCAwLFooKSksVD1ZfWZ1bmN0aW9uIHo0KFgpe3ZhciBZPVQ7WC5fX2M9WC5fXygpLFQ9WX1mdW5jdGlvbiB0NChYLFkpe3JldHVybiFYfHxYLmxlbmd0aCE9PVkubGVuZ3RofHxZLnNvbWUoZnVuY3Rpb24oWixKKXtyZXR1cm4gWiE9PVhbSl19KX1mdW5jdGlvbiBuNChYLFkpe3JldHVybiB0eXBlb2YgWT09ImZ1bmN0aW9uIj9ZKFgpOll9ZnVuY3Rpb24gdTUoWCxZKXtmb3IodmFyIFogaW4gWSlYW1pdPVlbWl07cmV0dXJuIFh9ZnVuY3Rpb24gZTQoWCxZKXtmb3IodmFyIFogaW4gWClpZihaIT09Il9fc291cmNlIiYmIShaIGluIFkpKXJldHVybiEwO2Zvcih2YXIgSiBpbiBZKWlmKEohPT0iX19zb3VyY2UiJiZYW0pdIT09WVtKXSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiBYNShYLFkpe3RoaXMucHJvcHM9WCx0aGlzLmNvbnRleHQ9WX0oWDUucHJvdG90eXBlPW5ldyBnKS5pc1B1cmVSZWFjdENvbXBvbmVudD0hMCxYNS5wcm90b3R5cGUuc2hvdWxkQ29tcG9uZW50VXBkYXRlPWZ1bmN0aW9uKFgsWSl7cmV0dXJuIGU0KHRoaXMucHJvcHMsWCl8fGU0KHRoaXMuc3RhdGUsWSl9O3ZhciBZNT1QLl9fYjtQLl9fYj1mdW5jdGlvbihYKXtYLnR5cGUmJlgudHlwZS5fX2YmJlgucmVmJiYoWC5wcm9wcy5yZWY9WC5yZWYsWC5yZWY9bnVsbCksWTUmJlk1KFgpfTt2YXIgcjU9UC5fX2U7UC5fX2U9ZnVuY3Rpb24oWCxZLFosSil7aWYoWC50aGVuKXtmb3IodmFyIHEsSz1ZO0s9Sy5fXzspaWYoKHE9Sy5fX2MpJiZxLl9fYylyZXR1cm4gWS5fX2U9PW51bGwmJihZLl9fZT1aLl9fZSxZLl9faz1aLl9faykscS5fX2MoWCxZKX1yNShYLFksWixKKX07dmFyIFo1PVAudW5tb3VudDtmdW5jdGlvbiBXNShYLFksWil7cmV0dXJuIFgmJihYLl9fYyYmWC5fX2MuX19IJiYoWC5fX2MuX19ILl9fLmZvckVhY2goZnVuY3Rpb24oSil7dHlwZW9mIEouX19jPT0iZnVuY3Rpb24iJiZKLl9fYygpfSksWC5fX2MuX19IPW51bGwpLChYPXU1KHt9LFgpKS5fX2MhPW51bGwmJihYLl9fYy5fX1A9PT1aJiYoWC5fX2MuX19QPVkpLFguX19jLl9fZT0hMCxYLl9fYz1udWxsKSxYLl9faz1YLl9fayYmWC5fX2subWFwKGZ1bmN0aW9uKEope3JldHVybiBXNShKLFksWil9KSksWH1mdW5jdGlvbiBMNShYLFksWil7cmV0dXJuIFgmJlomJihYLl9fdj1udWxsLFguX19rPVguX19rJiZYLl9fay5tYXAoZnVuY3Rpb24oSil7cmV0dXJuIEw1KEosWSxaKX0pLFguX19jJiZYLl9fYy5fX1A9PT1ZJiYoWC5fX2UmJlouYXBwZW5kQ2hpbGQoWC5fX2UpLFguX19jLl9fZT0hMCxYLl9fYy5fX1A9WikpLFh9ZnVuY3Rpb24gRzQoKXt0aGlzLl9fdT0wLHRoaXMubz1udWxsLHRoaXMuX19iPW51bGx9ZnVuY3Rpb24gejUoWCl7dmFyIFk9WC5fXyYmWC5fXy5fX2M7cmV0dXJuIFkmJlkuX19hJiZZLl9fYShYKX1mdW5jdGlvbiB5MCgpe3RoaXMuaT1udWxsLHRoaXMubD1udWxsfVAudW5tb3VudD1mdW5jdGlvbihYKXt2YXIgWT1YLl9fYztZJiYoWS5fX3o9ITApLFkmJlkuX19SJiZZLl9fUigpLFkmJjMyJlguX191JiYoWC50eXBlPW51bGwpLFo1JiZaNShYKX0sKEc0LnByb3RvdHlwZT1uZXcgZykuX19jPWZ1bmN0aW9uKFgsWSl7dmFyIFo9WS5fX2MsSj10aGlzO0oubz09bnVsbCYmKEoubz1bXSksSi5vLnB1c2goWik7dmFyIHE9ejUoSi5fX3YpLEs9ITEsUT1mdW5jdGlvbigpe0t8fEouX196fHwoSz0hMCxaLl9fUj1udWxsLHE/cShHKTpHKCkpfTtaLl9fUj1RO3ZhciB6PVouX19QO1ouX19QPW51bGw7dmFyIEc9ZnVuY3Rpb24oKXtpZighLS1KLl9fdSl7aWYoSi5zdGF0ZS5fX2Epe3ZhciBMPUouc3RhdGUuX19hO0ouX192Ll9fa1swXT1MNShMLEwuX19jLl9fUCxMLl9fYy5fX08pfXZhciBEO2ZvcihKLnNldFN0YXRlKHtfX2E6Si5fX2I9bnVsbH0pO0Q9Si5vLnBvcCgpOylELl9fUD16LEQuZm9yY2VVcGRhdGUoKX19O0ouX191Kyt8fDMyJlkuX191fHxKLnNldFN0YXRlKHtfX2E6Si5fX2I9Si5fX3YuX19rWzBdfSksWC50aGVuKFEsUSl9LEc0LnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudD1mdW5jdGlvbigpe3RoaXMubz1bXX0sRzQucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbihYLFkpe2lmKHRoaXMuX19iKXtpZih0aGlzLl9fdi5fX2spe3ZhciBaPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpLEo9dGhpcy5fX3YuX19rWzBdLl9fYzt0aGlzLl9fdi5fX2tbMF09VzUodGhpcy5fX2IsWixKLl9fTz1KLl9fUCl9dGhpcy5fX2I9bnVsbH12YXIgcT1ZLl9fYSYmWTAoeCxudWxsLFguZmFsbGJhY2spO3JldHVybiBxJiYocS5fX3UmPS0zMyksW1kwKHgsbnVsbCxZLl9fYT9udWxsOlguY2hpbGRyZW4pLHFdfTt2YXIgSjU9ZnVuY3Rpb24oWCxZLFope2lmKCsrWlsxXT09PVpbMF0mJlgubC5kZWxldGUoWSksWC5wcm9wcy5yZXZlYWxPcmRlciYmKFgucHJvcHMucmV2ZWFsT3JkZXJbMF0hPT0idCJ8fCFYLmwuc2l6ZSkpZm9yKFo9WC5pO1o7KXtmb3IoO1oubGVuZ3RoPjM7KVoucG9wKCkoKTtpZihaWzFdPFpbMF0pYnJlYWs7WC5pPVo9WlsyXX19Oyh5MC5wcm90b3R5cGU9bmV3IGcpLl9fYT1mdW5jdGlvbihYKXt2YXIgWT10aGlzLFo9ejUoWS5fX3YpLEo9WS5sLmdldChYKTtyZXR1cm4gSlswXSsrLGZ1bmN0aW9uKHEpe3ZhciBLPWZ1bmN0aW9uKCl7WS5wcm9wcy5yZXZlYWxPcmRlcj8oSi5wdXNoKHEpLEo1KFksWCxKKSk6cSgpfTtaP1ooSyk6SygpfX0seTAucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbihYKXt0aGlzLmk9bnVsbCx0aGlzLmw9bmV3IE1hcDt2YXIgWT1aMChYLmNoaWxkcmVuKTtYLnJldmVhbE9yZGVyJiZYLnJldmVhbE9yZGVyWzBdPT09ImIiJiZZLnJldmVyc2UoKTtmb3IodmFyIFo9WS5sZW5ndGg7Wi0tOyl0aGlzLmwuc2V0KFlbWl0sdGhpcy5pPVsxLDAsdGhpcy5pXSk7cmV0dXJuIFguY2hpbGRyZW59LHkwLnByb3RvdHlwZS5jb21wb25lbnREaWRVcGRhdGU9eTAucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50PWZ1bmN0aW9uKCl7dmFyIFg9dGhpczt0aGlzLmwuZm9yRWFjaChmdW5jdGlvbihZLFope0o1KFgsWixZKX0pfTt2YXIgdDU9dHlwZW9mIFN5bWJvbDwidSImJlN5bWJvbC5mb3ImJlN5bWJvbC5mb3IoInJlYWN0LmVsZW1lbnQiKXx8NjAxMDMsbjU9L14oPzphY2NlbnR8YWxpZ25tZW50fGFyYWJpY3xiYXNlbGluZXxjYXB8Y2xpcCg/IVBhdGhVKXxjb2xvcnxkb21pbmFudHxmaWxsfGZsb29kfGZvbnR8Z2x5cGgoPyFSKXxob3JpenxpbWFnZSghUyl8bGV0dGVyfGxpZ2h0aW5nfG1hcmtlcig/IUh8V3xVKXxvdmVybGluZXxwYWludHxwb2ludGVyfHNoYXBlfHN0b3B8c3RyaWtldGhyb3VnaHxzdHJva2V8dGV4dCg/IUwpfHRyYW5zZm9ybXx1bmRlcmxpbmV8dW5pY29kZXx1bml0c3x2fHZlY3Rvcnx2ZXJ0fHdvcmR8d3JpdGluZ3x4KD8hQykpW0EtWl0vLGU1PS9eb24oQW5pfFRyYXxUb3V8QmVmb3JlSW5wfENvbXBvKS8sWDY9L1tBLVowLTldL2csWTY9dHlwZW9mIGRvY3VtZW50PCJ1IixaNj1mdW5jdGlvbihYKXtyZXR1cm4odHlwZW9mIFN5bWJvbDwidSImJnR5cGVvZiBTeW1ib2woKT09InN5bWJvbCI/L2ZpbHxjaGV8cmFkLzovZmlsfGNoZXxyYS8pLnRlc3QoWCl9O2Z1bmN0aW9uIE41KFgsWSxaKXtyZXR1cm4gWS5fX2s9PW51bGwmJihZLnRleHRDb250ZW50PSIiKSxwMChYLFkpLHR5cGVvZiBaPT0iZnVuY3Rpb24iJiZaKCksWD9YLl9fYzpudWxsfWcucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9ITAsWyJjb21wb25lbnRXaWxsTW91bnQiLCJjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIiwiY29tcG9uZW50V2lsbFVwZGF0ZSJdLmZvckVhY2goZnVuY3Rpb24oWCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGcucHJvdG90eXBlLFgse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1siVU5TQUZFXyIrWF19LHNldDpmdW5jdGlvbihZKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxYLHtjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6WX0pfX0pfSk7dmFyIHE1PVAuZXZlbnQ7UC5ldmVudD1mdW5jdGlvbihYKXtyZXR1cm4gcTUmJihYPXE1KFgpKSxYLnBlcnNpc3Q9ZnVuY3Rpb24oKXt9LFguaXNQcm9wYWdhdGlvblN0b3BwZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jYW5jZWxCdWJibGV9LFguaXNEZWZhdWx0UHJldmVudGVkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGVmYXVsdFByZXZlbnRlZH0sWC5uYXRpdmVFdmVudD1YfTt2YXIgRzUsSjY9e2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jbGFzc319LEs1PVAudm5vZGU7UC52bm9kZT1mdW5jdGlvbihYKXt0eXBlb2YgWC50eXBlPT0ic3RyaW5nIiYmZnVuY3Rpb24oWSl7dmFye3Byb3BzOlosdHlwZTpKfT1ZLHE9e30sSz1KLmluZGV4T2YoIi0iKT09LTE7Zm9yKHZhciBRIGluIFope3ZhciB6PVpbUV07aWYoIShRPT09InZhbHVlIiYmKCJkZWZhdWx0VmFsdWUiaW4gWikmJno9PW51bGx8fFk2JiZRPT09ImNoaWxkcmVuIiYmSj09PSJub3NjcmlwdCJ8fFE9PT0iY2xhc3MifHxRPT09ImNsYXNzTmFtZSIpKXt2YXIgRz1RLnRvTG93ZXJDYXNlKCk7UT09PSJkZWZhdWx0VmFsdWUiJiYidmFsdWUiaW4gWiYmWi52YWx1ZT09bnVsbD9RPSJ2YWx1ZSI6UT09PSJkb3dubG9hZCImJno9PT0hMD96PSIiOkc9PT0idHJhbnNsYXRlIiYmej09PSJubyI/ej0hMTpHWzBdPT09Im8iJiZHWzFdPT09Im4iP0c9PT0ib25kb3VibGVjbGljayI/UT0ib25kYmxjbGljayI6RyE9PSJvbmNoYW5nZSJ8fEohPT0iaW5wdXQiJiZKIT09InRleHRhcmVhInx8WjYoWi50eXBlKT9HPT09Im9uZm9jdXMiP1E9Im9uZm9jdXNpbiI6Rz09PSJvbmJsdXIiP1E9Im9uZm9jdXNvdXQiOmU1LnRlc3QoUSkmJihRPUcpOkc9UT0ib25pbnB1dCI6SyYmbjUudGVzdChRKT9RPVEucmVwbGFjZShYNiwiLSQmIikudG9Mb3dlckNhc2UoKTp6PT09bnVsbCYmKHo9dm9pZCAwKSxHPT09Im9uaW5wdXQiJiZxW1E9R10mJihRPSJvbmlucHV0Q2FwdHVyZSIpLHFbUV09en19Sj09InNlbGVjdCImJihxLm11bHRpcGxlJiZBcnJheS5pc0FycmF5KHEudmFsdWUpJiYocS52YWx1ZT1aMChaLmNoaWxkcmVuKS5mb3JFYWNoKGZ1bmN0aW9uKEwpe0wucHJvcHMuc2VsZWN0ZWQ9cS52YWx1ZS5pbmRleE9mKEwucHJvcHMudmFsdWUpIT0tMX0pKSxxLmRlZmF1bHRWYWx1ZSE9bnVsbCYmKHEudmFsdWU9WjAoWi5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbihMKXtMLnByb3BzLnNlbGVjdGVkPXEubXVsdGlwbGU/cS5kZWZhdWx0VmFsdWUuaW5kZXhPZihMLnByb3BzLnZhbHVlKSE9LTE6cS5kZWZhdWx0VmFsdWU9PUwucHJvcHMudmFsdWV9KSkpLFouY2xhc3MmJiFaLmNsYXNzTmFtZT8ocS5jbGFzcz1aLmNsYXNzLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLCJjbGFzc05hbWUiLEo2KSk6Wi5jbGFzc05hbWUmJihxLmNsYXNzPXEuY2xhc3NOYW1lPVouY2xhc3NOYW1lKSxZLnByb3BzPXF9KFgpLFguJCR0eXBlb2Y9dDUsSzUmJks1KFgpfTt2YXIgUTU9UC5fX3I7UC5fX3I9ZnVuY3Rpb24oWCl7UTUmJlE1KFgpLEc1PVguX19jfTt2YXIgJDU9UC5kaWZmZWQ7UC5kaWZmZWQ9ZnVuY3Rpb24oWCl7JDUmJiQ1KFgpO3Zhcntwcm9wczpZLF9fZTpafT1YO1ohPW51bGwmJlgudHlwZT09PSJ0ZXh0YXJlYSImJiJ2YWx1ZSJpbiBZJiZZLnZhbHVlIT09Wi52YWx1ZSYmKFoudmFsdWU9WS52YWx1ZT09bnVsbD8iIjpZLnZhbHVlKSxHNT1udWxsfTtmdW5jdGlvbiBWNShYKXtyZXR1cm4hIVguX19rJiYocDAobnVsbCxYKSwhMCl9ZnVuY3Rpb24gSDUoWCl7cmV0dXJue3JlbmRlcjpmdW5jdGlvbihZKXtONShZLFgpfSx1bm1vdW50OmZ1bmN0aW9uKCl7VjUoWCl9fX1mdW5jdGlvbiBJNShYLFkpe2Zvcih2YXIgWiBpbiBZKVhbWl09WVtaXTtyZXR1cm4gWH1mdW5jdGlvbiBPNShYLFkpe2Zvcih2YXIgWiBpbiBYKWlmKFohPT0iX19zb3VyY2UiJiYhKFogaW4gWSkpcmV0dXJuITA7Zm9yKHZhciBKIGluIFkpaWYoSiE9PSJfX3NvdXJjZSImJlhbSl0hPT1ZW0pdKXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIFU1KFgsWSl7dGhpcy5wcm9wcz1YLHRoaXMuY29udGV4dD1ZfShVNS5wcm90b3R5cGU9bmV3IGcpLmlzUHVyZVJlYWN0Q29tcG9uZW50PSEwLFU1LnByb3RvdHlwZS5zaG91bGRDb21wb25lbnRVcGRhdGU9ZnVuY3Rpb24oWCxZKXtyZXR1cm4gTzUodGhpcy5wcm9wcyxYKXx8TzUodGhpcy5zdGF0ZSxZKX07dmFyIEE1PVAuX19iO1AuX19iPWZ1bmN0aW9uKFgpe1gudHlwZSYmWC50eXBlLl9fZiYmWC5yZWYmJihYLnByb3BzLnJlZj1YLnJlZixYLnJlZj1udWxsKSxBNSYmQTUoWCl9O3ZhciBxNj10eXBlb2YgU3ltYm9sPCJ1IiYmU3ltYm9sLmZvciYmU3ltYm9sLmZvcigicmVhY3QuZm9yd2FyZF9yZWYiKXx8MzkxMTtmdW5jdGlvbiBHMChYKXtmdW5jdGlvbiBZKFope3ZhciBKPUk1KHt9LFopO3JldHVybiBkZWxldGUgSi5yZWYsWChKLFoucmVmfHxudWxsKX1yZXR1cm4gWS4kJHR5cGVvZj1xNixZLnJlbmRlcj1YLFkucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9WS5fX2Y9ITAsWS5kaXNwbGF5TmFtZT0iRm9yd2FyZFJlZigiKyhYLmRpc3BsYXlOYW1lfHxYLm5hbWUpKyIpIixZfXZhciBLNj1QLl9fZTtQLl9fZT1mdW5jdGlvbihYLFksWixKKXtpZihYLnRoZW4pe2Zvcih2YXIgcSxLPVk7Sz1LLl9fOylpZigocT1LLl9fYykmJnEuX19jKXJldHVybiBZLl9fZT09bnVsbCYmKFkuX19lPVouX19lLFkuX19rPVouX19rKSxxLl9fYyhYLFkpfUs2KFgsWSxaLEopfTt2YXIgRDU9UC51bm1vdW50O2Z1bmN0aW9uIE01KFgsWSxaKXtyZXR1cm4gWCYmKFguX19jJiZYLl9fYy5fX0gmJihYLl9fYy5fX0guX18uZm9yRWFjaChmdW5jdGlvbihKKXt0eXBlb2YgSi5fX2M9PSJmdW5jdGlvbiImJkouX19jKCl9KSxYLl9fYy5fX0g9bnVsbCksKFg9STUoe30sWCkpLl9fYyE9bnVsbCYmKFguX19jLl9fUD09PVomJihYLl9fYy5fX1A9WSksWC5fX2MuX19lPSEwLFguX19jPW51bGwpLFguX19rPVguX19rJiZYLl9fay5tYXAoZnVuY3Rpb24oSil7cmV0dXJuIE01KEosWSxaKX0pKSxYfWZ1bmN0aW9uIEM1KFgsWSxaKXtyZXR1cm4gWCYmWiYmKFguX192PW51bGwsWC5fX2s9WC5fX2smJlguX19rLm1hcChmdW5jdGlvbihKKXtyZXR1cm4gQzUoSixZLFopfSksWC5fX2MmJlguX19jLl9fUD09PVkmJihYLl9fZSYmWi5hcHBlbmRDaGlsZChYLl9fZSksWC5fX2MuX19lPSEwLFguX19jLl9fUD1aKSksWH1mdW5jdGlvbiBINCgpe3RoaXMuX191PTAsdGhpcy5vPW51bGwsdGhpcy5fX2I9bnVsbH1mdW5jdGlvbiBFNShYKXt2YXIgWT1YLl9fJiZYLl9fLl9fYztyZXR1cm4gWSYmWS5fX2EmJlkuX19hKFgpfWZ1bmN0aW9uIGcwKCl7dGhpcy5pPW51bGwsdGhpcy5sPW51bGx9UC51bm1vdW50PWZ1bmN0aW9uKFgpe3ZhciBZPVguX19jO1kmJihZLl9fej0hMCksWSYmWS5fX1ImJlkuX19SKCksWSYmMzImWC5fX3UmJihYLnR5cGU9bnVsbCksRDUmJkQ1KFgpfSwoSDQucHJvdG90eXBlPW5ldyBnKS5fX2M9ZnVuY3Rpb24oWCxZKXt2YXIgWj1ZLl9fYyxKPXRoaXM7Si5vPT1udWxsJiYoSi5vPVtdKSxKLm8ucHVzaChaKTt2YXIgcT1FNShKLl9fdiksSz0hMSxRPWZ1bmN0aW9uKCl7S3x8Si5fX3p8fChLPSEwLFouX19SPW51bGwscT9xKEcpOkcoKSl9O1ouX19SPVE7dmFyIHo9Wi5fX1A7Wi5fX1A9bnVsbDt2YXIgRz1mdW5jdGlvbigpe2lmKCEtLUouX191KXtpZihKLnN0YXRlLl9fYSl7dmFyIEw9Si5zdGF0ZS5fX2E7Si5fX3YuX19rWzBdPUM1KEwsTC5fX2MuX19QLEwuX19jLl9fTyl9dmFyIEQ7Zm9yKEouc2V0U3RhdGUoe19fYTpKLl9fYj1udWxsfSk7RD1KLm8ucG9wKCk7KUQuX19QPXosRC5mb3JjZVVwZGF0ZSgpfX07Si5fX3UrK3x8MzImWS5fX3V8fEouc2V0U3RhdGUoe19fYTpKLl9fYj1KLl9fdi5fX2tbMF19KSxYLnRoZW4oUSxRKX0sSDQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7dGhpcy5vPVtdfSxINC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKFgsWSl7aWYodGhpcy5fX2Ipe2lmKHRoaXMuX192Ll9fayl7dmFyIFo9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IiksSj10aGlzLl9fdi5fX2tbMF0uX19jO3RoaXMuX192Ll9fa1swXT1NNSh0aGlzLl9fYixaLEouX19PPUouX19QKX10aGlzLl9fYj1udWxsfXZhciBxPVkuX19hJiZZMCh4LG51bGwsWC5mYWxsYmFjayk7cmV0dXJuIHEmJihxLl9fdSY9LTMzKSxbWTAoeCxudWxsLFkuX19hP251bGw6WC5jaGlsZHJlbikscV19O3ZhciBQNT1mdW5jdGlvbihYLFksWil7aWYoKytaWzFdPT09WlswXSYmWC5sLmRlbGV0ZShZKSxYLnByb3BzLnJldmVhbE9yZGVyJiYoWC5wcm9wcy5yZXZlYWxPcmRlclswXSE9PSJ0Inx8IVgubC5zaXplKSlmb3IoWj1YLmk7Wjspe2Zvcig7Wi5sZW5ndGg+MzspWi5wb3AoKSgpO2lmKFpbMV08WlswXSlicmVhaztYLmk9Wj1aWzJdfX07KGcwLnByb3RvdHlwZT1uZXcgZykuX19hPWZ1bmN0aW9uKFgpe3ZhciBZPXRoaXMsWj1FNShZLl9fdiksSj1ZLmwuZ2V0KFgpO3JldHVybiBKWzBdKyssZnVuY3Rpb24ocSl7dmFyIEs9ZnVuY3Rpb24oKXtZLnByb3BzLnJldmVhbE9yZGVyPyhKLnB1c2gocSksUDUoWSxYLEopKTpxKCl9O1o/WihLKTpLKCl9fSxnMC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKFgpe3RoaXMuaT1udWxsLHRoaXMubD1uZXcgTWFwO3ZhciBZPVowKFguY2hpbGRyZW4pO1gucmV2ZWFsT3JkZXImJlgucmV2ZWFsT3JkZXJbMF09PT0iYiImJlkucmV2ZXJzZSgpO2Zvcih2YXIgWj1ZLmxlbmd0aDtaLS07KXRoaXMubC5zZXQoWVtaXSx0aGlzLmk9WzEsMCx0aGlzLmldKTtyZXR1cm4gWC5jaGlsZHJlbn0sZzAucHJvdG90eXBlLmNvbXBvbmVudERpZFVwZGF0ZT1nMC5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQ9ZnVuY3Rpb24oKXt2YXIgWD10aGlzO3RoaXMubC5mb3JFYWNoKGZ1bmN0aW9uKFksWil7UDUoWCxaLFkpfSl9O3ZhciBRNj10eXBlb2YgU3ltYm9sPCJ1IiYmU3ltYm9sLmZvciYmU3ltYm9sLmZvcigicmVhY3QuZWxlbWVudCIpfHw2MDEwMywkNj0vXig/OmFjY2VudHxhbGlnbm1lbnR8YXJhYmljfGJhc2VsaW5lfGNhcHxjbGlwKD8hUGF0aFUpfGNvbG9yfGRvbWluYW50fGZpbGx8Zmxvb2R8Zm9udHxnbHlwaCg/IVIpfGhvcml6fGltYWdlKCFTKXxsZXR0ZXJ8bGlnaHRpbmd8bWFya2VyKD8hSHxXfFUpfG92ZXJsaW5lfHBhaW50fHBvaW50ZXJ8c2hhcGV8c3RvcHxzdHJpa2V0aHJvdWdofHN0cm9rZXx0ZXh0KD8hTCl8dHJhbnNmb3JtfHVuZGVybGluZXx1bmljb2RlfHVuaXRzfHZ8dmVjdG9yfHZlcnR8d29yZHx3cml0aW5nfHgoPyFDKSlbQS1aXS8sVzY9L15vbihBbml8VHJhfFRvdXxCZWZvcmVJbnB8Q29tcG8pLyxMNj0vW0EtWjAtOV0vZyx6Nj10eXBlb2YgZG9jdW1lbnQ8InUiLE42PWZ1bmN0aW9uKFgpe3JldHVybih0eXBlb2YgU3ltYm9sPCJ1IiYmdHlwZW9mIFN5bWJvbCgpPT0ic3ltYm9sIj8vZmlsfGNoZXxyYWQvOi9maWx8Y2hlfHJhLykudGVzdChYKX07Zy5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudD0hMCxbImNvbXBvbmVudFdpbGxNb3VudCIsImNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMiLCJjb21wb25lbnRXaWxsVXBkYXRlIl0uZm9yRWFjaChmdW5jdGlvbihYKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoZy5wcm90b3R5cGUsWCx7Y29uZmlndXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzWyJVTlNBRkVfIitYXX0sc2V0OmZ1bmN0aW9uKFkpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFgse2NvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTpZfSl9fSl9KTt2YXIgQjU9UC5ldmVudDtQLmV2ZW50PWZ1bmN0aW9uKFgpe3JldHVybiBCNSYmKFg9QjUoWCkpLFgucGVyc2lzdD1mdW5jdGlvbigpe30sWC5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmNhbmNlbEJ1YmJsZX0sWC5pc0RlZmF1bHRQcmV2ZW50ZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kZWZhdWx0UHJldmVudGVkfSxYLm5hdGl2ZUV2ZW50PVh9O3ZhciB3NSxHNj17Y29uZmlndXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmNsYXNzfX0sXzU9UC52bm9kZTtQLnZub2RlPWZ1bmN0aW9uKFgpe3R5cGVvZiBYLnR5cGU9PSJzdHJpbmciJiZmdW5jdGlvbihZKXt2YXJ7cHJvcHM6Wix0eXBlOkp9PVkscT17fSxLPUouaW5kZXhPZigiLSIpPT0tMTtmb3IodmFyIFEgaW4gWil7dmFyIHo9WltRXTtpZighKFE9PT0idmFsdWUiJiYoImRlZmF1bHRWYWx1ZSJpbiBaKSYmej09bnVsbHx8ejYmJlE9PT0iY2hpbGRyZW4iJiZKPT09Im5vc2NyaXB0Inx8UT09PSJjbGFzcyJ8fFE9PT0iY2xhc3NOYW1lIikpe3ZhciBHPVEudG9Mb3dlckNhc2UoKTtRPT09ImRlZmF1bHRWYWx1ZSImJiJ2YWx1ZSJpbiBaJiZaLnZhbHVlPT1udWxsP1E9InZhbHVlIjpRPT09ImRvd25sb2FkIiYmej09PSEwP3o9IiI6Rz09PSJ0cmFuc2xhdGUiJiZ6PT09Im5vIj96PSExOkdbMF09PT0ibyImJkdbMV09PT0ibiI/Rz09PSJvbmRvdWJsZWNsaWNrIj9RPSJvbmRibGNsaWNrIjpHIT09Im9uY2hhbmdlInx8SiE9PSJpbnB1dCImJkohPT0idGV4dGFyZWEifHxONihaLnR5cGUpP0c9PT0ib25mb2N1cyI/UT0ib25mb2N1c2luIjpHPT09Im9uYmx1ciI/UT0ib25mb2N1c291dCI6VzYudGVzdChRKSYmKFE9Ryk6Rz1RPSJvbmlucHV0IjpLJiYkNi50ZXN0KFEpP1E9US5yZXBsYWNlKEw2LCItJCYiKS50b0xvd2VyQ2FzZSgpOno9PT1udWxsJiYoej12b2lkIDApLEc9PT0ib25pbnB1dCImJnFbUT1HXSYmKFE9Im9uaW5wdXRDYXB0dXJlIikscVtRXT16fX1KPT0ic2VsZWN0IiYmKHEubXVsdGlwbGUmJkFycmF5LmlzQXJyYXkocS52YWx1ZSkmJihxLnZhbHVlPVowKFouY2hpbGRyZW4pLmZvckVhY2goZnVuY3Rpb24oTCl7TC5wcm9wcy5zZWxlY3RlZD1xLnZhbHVlLmluZGV4T2YoTC5wcm9wcy52YWx1ZSkhPS0xfSkpLHEuZGVmYXVsdFZhbHVlIT1udWxsJiYocS52YWx1ZT1aMChaLmNoaWxkcmVuKS5mb3JFYWNoKGZ1bmN0aW9uKEwpe0wucHJvcHMuc2VsZWN0ZWQ9cS5tdWx0aXBsZT9xLmRlZmF1bHRWYWx1ZS5pbmRleE9mKEwucHJvcHMudmFsdWUpIT0tMTpxLmRlZmF1bHRWYWx1ZT09TC5wcm9wcy52YWx1ZX0pKSksWi5jbGFzcyYmIVouY2xhc3NOYW1lPyhxLmNsYXNzPVouY2xhc3MsT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsImNsYXNzTmFtZSIsRzYpKTpaLmNsYXNzTmFtZSYmKHEuY2xhc3M9cS5jbGFzc05hbWU9Wi5jbGFzc05hbWUpLFkucHJvcHM9cX0oWCksWC4kJHR5cGVvZj1RNixfNSYmXzUoWCl9O3ZhciBGNT1QLl9fcjtQLl9fcj1mdW5jdGlvbihYKXtGNSYmRjUoWCksdzU9WC5fX2N9O3ZhciBrNT1QLmRpZmZlZDtQLmRpZmZlZD1mdW5jdGlvbihYKXtrNSYmazUoWCk7dmFye3Byb3BzOlksX19lOlp9PVg7WiE9bnVsbCYmWC50eXBlPT09InRleHRhcmVhIiYmInZhbHVlImluIFkmJlkudmFsdWUhPT1aLnZhbHVlJiYoWi52YWx1ZT1ZLnZhbHVlPT1udWxsPyIiOlkudmFsdWUpLHc1PW51bGx9O3ZhciBWNj0wO2Z1bmN0aW9uICQoWCxZLFosSixxLEspe1l8fChZPXt9KTt2YXIgUSx6LEc9WTtpZigicmVmImluIEcpZm9yKHogaW4gRz17fSxZKXo9PSJyZWYiP1E9WVt6XTpHW3pdPVlbel07dmFyIEw9e3R5cGU6WCxwcm9wczpHLGtleTpaLHJlZjpRLF9fazpudWxsLF9fOm51bGwsX19iOjAsX19lOm51bGwsX19jOm51bGwsY29uc3RydWN0b3I6dm9pZCAwLF9fdjotLVY2LF9faTotMSxfX3U6MCxfX3NvdXJjZTpxLF9fc2VsZjpLfTtpZih0eXBlb2YgWD09ImZ1bmN0aW9uIiYmKFE9WC5kZWZhdWx0UHJvcHMpKWZvcih6IGluIFEpR1t6XT09PXZvaWQgMCYmKEdbel09UVt6XSk7cmV0dXJuIFAudm5vZGUmJlAudm5vZGUoTCksTH12YXIgTzQ9YHVybCgiZGF0YTppbWFnZS9zdmcreG1sLCUzQ3N2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyMCcgaGVpZ2h0PScyMCclM0UlM0NjaXJjbGUgY3g9JzEwJyBjeT0nMTAnIHI9JzknIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsMC40KScgc3Ryb2tlPSdyZ2JhKDI1NSwyNTUsMjU1LDAuNyknIHN0cm9rZS13aWR0aD0nMScvJTNFJTNDL3N2ZyUzRSIpIDEwIDEwLCBwb2ludGVyYCxINj0zLE82PTQsVTY9NTtmdW5jdGlvbiB4MCh7dXJsOlgsd3NVcmw6WSxzdHlsZTpaLGltYWdlU3R5bGU6SixjbGFzc05hbWU6cSxvbkhvbWVQcmVzczpLLG9uU3RyZWFtVG91Y2g6USxvblN0cmVhbU11bHRpVG91Y2g6eixvblN0cmVhbUJ1dHRvbjpHLHN1YnNjcmliZUZyYW1lOkwsc3RyZWFtRnJhbWU6RCxzdHJlYW1Db25maWc6VyxoaWRlQ29udHJvbHM6TyxvblN0cmVhbWluZ0NoYW5nZTpVLGNvbm5lY3Rpb25RdWFsaXR5Omt9KXtsZXQgXz0hIVEsQz13KG51bGwpLE09dyhudWxsKSxGPXcobnVsbCksW0UsSV09cCghMSksW3Yscl09cChudWxsKSxbZixpXT1wKG51bGwpLHk9dyhudWxsKSxbbSxjMF09cChudWxsKTtkKCgpPT57bGV0IFY9eS5jdXJyZW50O2lmKCFWfHx0eXBlb2YgUmVzaXplT2JzZXJ2ZXI+InUiKXJldHVybjtsZXQgSD1uZXcgUmVzaXplT2JzZXJ2ZXIoKE4pPT57bGV0IEE9TlswXT8uY29udGVudFJlY3Q7aWYoQSljMCh7d2lkdGg6QS53aWR0aCxoZWlnaHQ6QS5oZWlnaHR9KX0pO3JldHVybiBILm9ic2VydmUoViksKCk9PkguZGlzY29ubmVjdCgpfSxbXSk7bGV0W0Q0LFA0XT1wKDApLFcwPXcoMCksW3A1LGwwXT1wKCExKSx0PXcobnVsbCk7ZCgoKT0+e2lmKGs9PT0icG9vciIpe2lmKGwwKCEwKSx0LmN1cnJlbnQpY2xlYXJUaW1lb3V0KHQuY3VycmVudCk7dC5jdXJyZW50PXNldFRpbWVvdXQoKCk9PntsMCghMSksdC5jdXJyZW50PW51bGx9LDMwMDApfWVsc2UgaWYobDAoITEpLHQuY3VycmVudCljbGVhclRpbWVvdXQodC5jdXJyZW50KSx0LmN1cnJlbnQ9bnVsbDtyZXR1cm4oKT0+e2lmKHQuY3VycmVudCljbGVhclRpbWVvdXQodC5jdXJyZW50KX19LFtrXSk7bGV0IGkwPWAke1h9L3N0cmVhbS5tanBlZ2AsQjQ9dyhVKTtCNC5jdXJyZW50PVUsZCgoKT0+e0I0LmN1cnJlbnQ/LihFKX0sW0VdKSxkKCgpPT57aWYoXyYmVylpKFcpfSxbXyxXXSk7bGV0IF80PXcoITEpO180LmN1cnJlbnQ9RTtsZXQgczA9dyhudWxsKTtkKCgpPT57aWYoIV98fCFMKXJldHVybjtyZXR1cm4gTCgoVik9PntXMC5jdXJyZW50Kys7bGV0IEg9TS5jdXJyZW50O2lmKEgpe2lmKHMwLmN1cnJlbnQpVVJMLnJldm9rZU9iamVjdFVSTChzMC5jdXJyZW50KTtzMC5jdXJyZW50PVYsSC5zcmM9Vn1pZighXzQuY3VycmVudCljb25zb2xlLmxvZygiW3NlcnZlLXNpbV0gZmlyc3QgZnJhbWUgcmVjZWl2ZWQsIHJlbmRlcmluZyIpLEkoITApLHIobnVsbCl9KX0sW18sTF0pO2xldCBjPWooKFYpPT57aWYoXyl7UT8uKFYpO3JldHVybn1sZXQgSD1GLmN1cnJlbnQ7aWYoIUh8fEgucmVhZHlTdGF0ZSE9PVdlYlNvY2tldC5PUEVOKXJldHVybjtsZXQgTj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoVikpLEE9bmV3IFVpbnQ4QXJyYXkoMStOLmxlbmd0aCk7QVswXT1INixBLnNldChOLDEpLEguc2VuZChBKX0sW18sUV0pLG8wPWooKFYpPT57aWYoXyl7Rz8uKFYpO3JldHVybn1sZXQgSD1GLmN1cnJlbnQ7aWYoIUh8fEgucmVhZHlTdGF0ZSE9PVdlYlNvY2tldC5PUEVOKXJldHVybjtsZXQgTj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoSlNPTi5zdHJpbmdpZnkoe2J1dHRvbjpWfSkpLEE9bmV3IFVpbnQ4QXJyYXkoMStOLmxlbmd0aCk7QVswXT1PNixBLnNldChOLDEpLEguc2VuZChBKX0sW18sR10pLG49aigoVik9PntpZihfKXt6Py4oVik7cmV0dXJufWxldCBIPUYuY3VycmVudDtpZighSHx8SC5yZWFkeVN0YXRlIT09V2ViU29ja2V0Lk9QRU4pcmV0dXJuO2xldCBOPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShKU09OLnN0cmluZ2lmeShWKSksQT1uZXcgVWludDhBcnJheSgxK04ubGVuZ3RoKTtBWzBdPVU2LEEuc2V0KE4sMSksSC5zZW5kKEEpfSxbXyx6XSk7ZCgoKT0+e2lmKF8pcmV0dXJuO2ZldGNoKGAke1h9L2NvbmZpZ2ApLnRoZW4oKEIpPT5CLmpzb24oKSkudGhlbigoQik9PntpZihCLndpZHRoPjAmJkIuaGVpZ2h0PjApaShCKX0pLmNhdGNoKCgpPT57fSk7bGV0IFY9WT8/WC5yZXBsYWNlKC9eaHR0cC8sIndzIikrIi93cyIsSD1uZXcgV2ViU29ja2V0KFYpO0guYmluYXJ5VHlwZT0iYXJyYXlidWZmZXIiLEYuY3VycmVudD1ILEgub25vcGVuPSgpPT57SSghMCkscihudWxsKX0sSC5vbmNsb3NlPSgpPT57SSghMSl9LEgub25lcnJvcj0oKT0+e3IoIldlYlNvY2tldCBjb25uZWN0aW9uIGZhaWxlZCIpLEkoITEpfTtsZXQgTj1uZXcgQWJvcnRDb250cm9sbGVyLEE9c2V0SW50ZXJ2YWwoKCk9PntQNChXMC5jdXJyZW50KSxXMC5jdXJyZW50PTB9LDEwMDApO3JldHVybihhc3luYygpPT57dHJ5e2xldCBTPShhd2FpdCBmZXRjaChpMCx7c2lnbmFsOk4uc2lnbmFsfSkpLmJvZHk/LmdldFJlYWRlcigpO2lmKCFTKXJldHVybjtsZXQgaD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoIi0tZnJhbWUiKTt3aGlsZSghMCl7bGV0e2RvbmU6bCx2YWx1ZTp1fT1hd2FpdCBTLnJlYWQoKTtpZihsKWJyZWFrO2lmKHUpZm9yKGxldCBlMD0wO2UwPD11Lmxlbmd0aC1oLmxlbmd0aDtlMCsrKXtsZXQgRTQ9ITA7Zm9yKGxldCBJMD0wO0kwPGgubGVuZ3RoO0kwKyspaWYodVtlMCtJMF0hPT1oW0kwXSl7RTQ9ITE7YnJlYWt9aWYoRTQpVzAuY3VycmVudCsrfX19Y2F0Y2h7fX0pKCksKCk9PntOLmFib3J0KCksY2xlYXJJbnRlcnZhbChBKSxILmNsb3NlKCksRi5jdXJyZW50PW51bGx9fSxbWCxpMCxfXSksZCgoKT0+e2lmKCFfKXJldHVybjtsZXQgVj1zZXRJbnRlcnZhbCgoKT0+e1A0KFcwLmN1cnJlbnQpLFcwLmN1cnJlbnQ9MH0sMTAwMCk7cmV0dXJuKCk9PmNsZWFySW50ZXJ2YWwoVil9LFtfXSk7bGV0IGU9aigoKT0+e3JldHVybiBfP00uY3VycmVudDpDLmN1cnJlbnR9LFtfXSksQjA9aigoVixIKT0+e2xldCBOPWUoKTtpZighTilyZXR1cm47bGV0IEE9Ti5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxCPShILmNsaWVudFgtQS5sZWZ0KS9BLndpZHRoLFM9KEguY2xpZW50WS1BLnRvcCkvQS5oZWlnaHQ7Yyh7dHlwZTpWLHg6Qix5OlN9KX0sW2NdKSxRMD0zLGE9dyghMSksbz13KCExKSx1MD13KCExKSxyMD13KHtkeDowLGR5OjB9KSxWMD13KCExKSxbdDAsRjRdPXAoITEpLGs0PXcoe3g6MC41LHk6MC41fSksW3EwLHNdPXAobnVsbCk7ZCgoKT0+e2xldCBWPShOKT0+e2lmKE4ua2V5PT09IkFsdCIpRjQoITApfSxIPShOKT0+e2lmKE4ua2V5PT09IkFsdCIpe2lmKEY0KCExKSwhby5jdXJyZW50KXMobnVsbCl9fTtyZXR1cm4gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImtleWRvd24iLFYpLHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJrZXl1cCIsSCksKCk9Pnt3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigia2V5ZG93biIsViksd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoImtleXVwIixIKX19LFtdKSxkKCgpPT57aWYodDAmJiFvLmN1cnJlbnQpe2xldCBWPWs0LmN1cnJlbnQ7cyh7eDE6Vi54LHkxOlYueSx4MjoxLVYueCx5MjoxLVYueX0pfWVsc2UgaWYoIXQwJiYhby5jdXJyZW50KXMobnVsbCl9LFt0MF0pO2xldCBfMD13KG51bGwpLG4wPXcoITEpLEgwPXcoMCksSTQ9aigoVixIKT0+e24wLmN1cnJlbnQ9ITA7bGV0IE49XzAuY3VycmVudDtpZihOKWNhbmNlbEFuaW1hdGlvbkZyYW1lKEgwLmN1cnJlbnQpLEgwLmN1cnJlbnQ9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpPT57Ti5zdHlsZS5sZWZ0PWAke1YqMTAwfSVgLE4uc3R5bGUudG9wPWAke0gqMTAwfSVgLE4uc3R5bGUuZGlzcGxheT0iYmxvY2sifSl9LFtdKSxNND1qKChWLEgpPT57aWYoIW4wLmN1cnJlbnQpcmV0dXJuO2xldCBOPV8wLmN1cnJlbnQ7aWYoTiljYW5jZWxBbmltYXRpb25GcmFtZShIMC5jdXJyZW50KSxIMC5jdXJyZW50PXJlcXVlc3RBbmltYXRpb25GcmFtZSgoKT0+e04uc3R5bGUubGVmdD1gJHtWKjEwMH0lYCxOLnN0eWxlLnRvcD1gJHtIKjEwMH0lYH0pfSxbXSksRjA9aigoKT0+e24wLmN1cnJlbnQ9ITE7bGV0IFY9XzAuY3VycmVudDtpZihWKWNhbmNlbEFuaW1hdGlvbkZyYW1lKEgwLmN1cnJlbnQpLFYuc3R5bGUuZGlzcGxheT0ibm9uZSJ9LFtdKSxDND13KDApLE8wPXcobnVsbCksdjU9aigoKT0+e2xldCBWPURhdGUubm93KCksSD1WLUM0LmN1cnJlbnQ7aWYoQzQuY3VycmVudD1WLEg8MzAwKXtpZihPMC5jdXJyZW50KWNsZWFyVGltZW91dChPMC5jdXJyZW50KSxPMC5jdXJyZW50PW51bGw7aWYoSylLKCk7ZWxzZSBvMCgiYXBwX3N3aXRjaGVyIil9ZWxzZSBPMC5jdXJyZW50PXNldFRpbWVvdXQoKCk9PntpZihLKUsoKTtlbHNlIG8wKCJob21lIik7TzAuY3VycmVudD1udWxsfSwzMDApfSxbbzAsS10pLGswPSgoKT0+e2lmKCFmfHwhbSlyZXR1cm4gbnVsbDtpZihtLndpZHRoPT09MHx8bS5oZWlnaHQ9PT0wKXJldHVybiBudWxsO2xldCBWPU1hdGgubWluKG0ud2lkdGgvZi53aWR0aCxtLmhlaWdodC9mLmhlaWdodCk7cmV0dXJue3dpZHRoOmYud2lkdGgqVixoZWlnaHQ6Zi5oZWlnaHQqVn19KSgpO3JldHVybiAkKCJkaXYiLHtzdHlsZTp7ZGlzcGxheToiZmxleCIsZmxleERpcmVjdGlvbjoiY29sdW1uIixmbGV4OjEsLi4uTz97fTp7Ym9yZGVyOiIxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjEyKSJ9LG92ZXJmbG93OiJoaWRkZW4iLG1pbldpZHRoOjAsbWluSGVpZ2h0OjAsLi4uWn0sY2xhc3NOYW1lOnEsY2hpbGRyZW46WyQoImRpdiIse3JlZjp5LHN0eWxlOntwb3NpdGlvbjoicmVsYXRpdmUiLGZsZXg6MSxtaW5IZWlnaHQ6MCxtaW5XaWR0aDowLGRpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsanVzdGlmeUNvbnRlbnQ6ImNlbnRlciJ9LGNoaWxkcmVuOiQoImRpdiIse3N0eWxlOntwb3NpdGlvbjoicmVsYXRpdmUiLHdpZHRoOmswP2Ake2swLndpZHRofXB4YDoiMTAwJSIsaGVpZ2h0OmswP2Ake2swLmhlaWdodH1weGA6IjEwMCUifSxjaGlsZHJlbjpbJCgiaW1nIix7cmVmOkMsc3JjOl8/dm9pZCAwOmkwLGRyYWdnYWJsZTohMSxvbkxvYWQ6KFYpPT57bGV0IEg9Vi5jdXJyZW50VGFyZ2V0O2lmKEgubmF0dXJhbFdpZHRoPjAmJkgubmF0dXJhbEhlaWdodD4wKWkoKE4pPT5OJiZOLndpZHRoPT09SC5uYXR1cmFsV2lkdGgmJk4uaGVpZ2h0PT09SC5uYXR1cmFsSGVpZ2h0P046e3dpZHRoOkgubmF0dXJhbFdpZHRoLGhlaWdodDpILm5hdHVyYWxIZWlnaHR9KX0sc3R5bGU6Xz97ZGlzcGxheToibm9uZSJ9Ontwb3NpdGlvbjoiYWJzb2x1dGUiLGluc2V0OjAsd2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsY3Vyc29yOk80LGRpc3BsYXk6ImJsb2NrIix1c2VyU2VsZWN0OiJub25lIixXZWJraXRVc2VyU2VsZWN0OiJub25lIix0b3VjaEFjdGlvbjoibm9uZSIsLi4uSn19KSxfJiYkKCJpbWciLHtyZWY6TSxkcmFnZ2FibGU6ITEsb25Mb2FkOihWKT0+e2xldCBIPVYuY3VycmVudFRhcmdldDtpZihILm5hdHVyYWxXaWR0aD4wJiZILm5hdHVyYWxIZWlnaHQ+MClpKChOKT0+TiYmTi53aWR0aD09PUgubmF0dXJhbFdpZHRoJiZOLmhlaWdodD09PUgubmF0dXJhbEhlaWdodD9OOnt3aWR0aDpILm5hdHVyYWxXaWR0aCxoZWlnaHQ6SC5uYXR1cmFsSGVpZ2h0fSl9LHN0eWxlOntwb3NpdGlvbjoiYWJzb2x1dGUiLGluc2V0OjAsd2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsY3Vyc29yOk80LGRpc3BsYXk6ImJsb2NrIix1c2VyU2VsZWN0OiJub25lIixXZWJraXRVc2VyU2VsZWN0OiJub25lIix0b3VjaEFjdGlvbjoibm9uZSIsLi4uSn19KSwkKCJkaXYiLHtzdHlsZTp7cG9zaXRpb246ImFic29sdXRlIixpbnNldDowLGN1cnNvcjpPNCx0b3VjaEFjdGlvbjoibm9uZSJ9LG9uTW91c2VEb3duOihWKT0+e1YucHJldmVudERlZmF1bHQoKTtsZXQgSD1lKCk7aWYoIUgpcmV0dXJuO2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKFYuYWx0S2V5KXtvLmN1cnJlbnQ9ITAsdTAuY3VycmVudD1WLnNoaWZ0S2V5O2xldCBTPXt4MTpBLHkxOkIseDI6MS1BLHkyOjEtQn07cjAuY3VycmVudD17ZHg6MS1BLUEsZHk6MS1CLUJ9LHMoUyksbih7dHlwZToiYmVnaW4iLC4uLlN9KTtyZXR1cm59aWYoSTQoQSxCKSxCPjAuODgpYS5jdXJyZW50PSEwLGMoe3R5cGU6ImJlZ2luIix4OkEseTpCLGVkZ2U6UTB9KTtlbHNlIGEuY3VycmVudD0hMSxCMCgiYmVnaW4iLFYpfSxvbk1vdXNlTW92ZTooVik9PntsZXQgSD1lKCk7aWYoIUgpcmV0dXJuO2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKGs0LmN1cnJlbnQ9e3g6QSx5OkJ9LFYuYnV0dG9ucz09PTApe2lmKFYuYWx0S2V5KXMoe3gxOkEseTE6Qix4MjoxLUEseTI6MS1CfSk7cmV0dXJufWlmKG8uY3VycmVudCl7bGV0IFM7aWYodTAuY3VycmVudCl7bGV0IGg9cjAuY3VycmVudDtTPXt4MTpBLHkxOkIseDI6QStoLmR4LHkyOkIraC5keX19ZWxzZSBTPXt4MTpBLHkxOkIseDI6MS1BLHkyOjEtQn07cyhTKSxuKHt0eXBlOiJtb3ZlIiwuLi5TfSk7cmV0dXJufWlmKE00KEEsQiksYS5jdXJyZW50KWMoe3R5cGU6Im1vdmUiLHg6QSx5OkIsZWRnZTpRMH0pO2Vsc2UgQjAoIm1vdmUiLFYpfSxvbk1vdXNlVXA6KFYpPT57aWYoby5jdXJyZW50KXtsZXQgSD1lKCk7aWYoSCl7bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxBPShWLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLEI9KFYuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYodTAuY3VycmVudCl7bGV0IFM9cjAuY3VycmVudDtuKHt0eXBlOiJlbmQiLHgxOkEseTE6Qix4MjpBK1MuZHgseTI6QitTLmR5fSl9ZWxzZSBuKHt0eXBlOiJlbmQiLHgxOkEseTE6Qix4MjoxLUEseTI6MS1CfSl9aWYoby5jdXJyZW50PSExLCFWLmFsdEtleSlzKG51bGwpO3JldHVybn1pZihGMCgpLGEuY3VycmVudCl7bGV0IEg9ZSgpO2lmKEgpe2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2Moe3R5cGU6ImVuZCIseDpBLHk6QixlZGdlOlEwfSl9YS5jdXJyZW50PSExO3JldHVybn1CMCgiZW5kIixWKX0sb25Nb3VzZUxlYXZlOihWKT0+e2lmKG8uY3VycmVudCl7aWYocTApbih7dHlwZToiZW5kIiwuLi5xMH0pO28uY3VycmVudD0hMSxzKG51bGwpO3JldHVybn1pZihGMCgpLGEuY3VycmVudCl7bGV0IEg9ZSgpO2lmKEgpe2xldCBOPUguZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksQT0oVi5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxCPShWLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2Moe3R5cGU6ImVuZCIseDpBLHk6QixlZGdlOlEwfSl9YS5jdXJyZW50PSExO3JldHVybn1pZihWLmJ1dHRvbnM+MClCMCgiZW5kIixWKTtzKG51bGwpfSxvblRvdWNoU3RhcnQ6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWLnRvdWNoZXMubGVuZ3RoPj0yKXtGMCgpO2xldCBoPVYudG91Y2hlc1swXSxsPVYudG91Y2hlc1sxXSx1PXt4MTooaC5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCx5MTooaC5jbGllbnRZLU4udG9wKS9OLmhlaWdodCx4MjoobC5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCx5MjoobC5jbGllbnRZLU4udG9wKS9OLmhlaWdodH07aWYoIVYwLmN1cnJlbnQmJiFhLmN1cnJlbnQpYyh7dHlwZToiZW5kIix4OnUueDEseTp1LnkxfSk7VjAuY3VycmVudD0hMCxvLmN1cnJlbnQ9ITAsYS5jdXJyZW50PSExLHModSksbih7dHlwZToiYmVnaW4iLC4uLnV9KTtyZXR1cm59bGV0IEE9Vi50b3VjaGVzWzBdO2lmKCFBKXJldHVybjtsZXQgQj0oQS5jbGllbnRYLU4ubGVmdCkvTi53aWR0aCxTPShBLmNsaWVudFktTi50b3ApL04uaGVpZ2h0O2lmKEk0KEIsUyksUz4wLjg4KWEuY3VycmVudD0hMCxjKHt0eXBlOiJiZWdpbiIseDpCLHk6UyxlZGdlOlEwfSk7ZWxzZSBhLmN1cnJlbnQ9ITEsYyh7dHlwZToiYmVnaW4iLHg6Qix5OlN9KX0sb25Ub3VjaE1vdmU6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWMC5jdXJyZW50JiZWLnRvdWNoZXMubGVuZ3RoPj0yKXtsZXQgaD1WLnRvdWNoZXNbMF0sbD1WLnRvdWNoZXNbMV0sdT17eDE6KGguY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTE6KGguY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQseDI6KGwuY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTI6KGwuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHR9O3ModSksbih7dHlwZToibW92ZSIsLi4udX0pO3JldHVybn1sZXQgQT1WLnRvdWNoZXNbMF07aWYoIUEpcmV0dXJuO2xldCBCPShBLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLFM9KEEuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYoTTQoQixTKSxhLmN1cnJlbnQpYyh7dHlwZToibW92ZSIseDpCLHk6UyxlZGdlOlEwfSk7ZWxzZSBjKHt0eXBlOiJtb3ZlIix4OkIseTpTfSl9LG9uVG91Y2hFbmQ6KFYpPT57Vi5wcmV2ZW50RGVmYXVsdCgpO2xldCBIPWUoKTtpZighSClyZXR1cm47bGV0IE49SC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZihWMC5jdXJyZW50KXtpZihWLnRvdWNoZXMubGVuZ3RoPDIpe2xldCBoPVYuY2hhbmdlZFRvdWNoZXNbMF0sbD1xMDtpZihoJiZsKW4oe3R5cGU6ImVuZCIseDE6KGguY2xpZW50WC1OLmxlZnQpL04ud2lkdGgseTE6KGguY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQseDI6bC54Mix5MjpsLnkyfSk7ZWxzZSBpZihsKW4oe3R5cGU6ImVuZCIsLi4ubH0pO1YwLmN1cnJlbnQ9ITEsby5jdXJyZW50PSExLHMobnVsbCl9cmV0dXJufWxldCBBPVYuY2hhbmdlZFRvdWNoZXNbMF07aWYoIUEpcmV0dXJuO2xldCBCPShBLmNsaWVudFgtTi5sZWZ0KS9OLndpZHRoLFM9KEEuY2xpZW50WS1OLnRvcCkvTi5oZWlnaHQ7aWYoRjAoKSxhLmN1cnJlbnQpYyh7dHlwZToiZW5kIix4OkIseTpTLGVkZ2U6UTB9KSxhLmN1cnJlbnQ9ITE7ZWxzZSBjKHt0eXBlOiJlbmQiLHg6Qix5OlN9KX19KSwkKCJkaXYiLHtyZWY6XzAsImRhdGEtdGVzdGlkIjoidG91Y2gtaW5kaWNhdG9yIixzdHlsZTp7cG9zaXRpb246ImFic29sdXRlIixkaXNwbGF5OiJub25lIix3aWR0aDoyNCxoZWlnaHQ6MjQsYm9yZGVyUmFkaXVzOiI1MCUiLGJhY2tncm91bmQ6InJnYmEoNTksMTMwLDI0NiwwLjUpIixib3hTaGFkb3c6IjAgMCA4cHggcmdiYSg1OSwxMzAsMjQ2LDAuMykiLHRyYW5zZm9ybToidHJhbnNsYXRlKC01MCUsIC01MCUpIixwb2ludGVyRXZlbnRzOiJub25lIn19KSxxMCYmJCh4LHtjaGlsZHJlbjpbJCgiZGl2Iix7ImRhdGEtdGVzdGlkIjoiZmluZ2VyLWRvdCIsc3R5bGU6YjUocTAueDEscTAueTEpfSksJCgiZGl2Iix7ImRhdGEtdGVzdGlkIjoiZmluZ2VyLWRvdCIsc3R5bGU6YjUocTAueDIscTAueTIpfSldfSksIUUmJiF2JiYkKCJkaXYiLHtzdHlsZTpTNSxjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6e2NvbG9yOiIjODg4Iixmb250U2l6ZToxNH0sY2hpbGRyZW46IkNvbm5lY3RpbmcuLi4ifSl9KSx2JiYkKCJkaXYiLHtzdHlsZTpTNSxjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6e2NvbG9yOiIjZjQ0Iixmb250U2l6ZToxNCxwYWRkaW5nOjIwLHRleHRBbGlnbjoiY2VudGVyIn0sY2hpbGRyZW46dn0pfSkscDUmJiQoImRpdiIse3N0eWxlOkE2LGNoaWxkcmVuOiQoInNwYW4iLHtzdHlsZTp7Y29sb3I6IiNmYmJmMjQiLGZvbnRTaXplOjEzLGZvbnRGYW1pbHk6Im1vbm9zcGFjZSJ9LGNoaWxkcmVuOiJTbG93IGNvbm5lY3Rpb24ifSl9KV19KX0pLCFPJiYkKCJkaXYiLHtzdHlsZTp7ZGlzcGxheToiZmxleCIsYWxpZ25JdGVtczoiY2VudGVyIixqdXN0aWZ5Q29udGVudDoic3BhY2UtYmV0d2VlbiIscGFkZGluZzoiNHB4IDhweCIsYm9yZGVyVG9wOiIxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjEyKSJ9LGNoaWxkcmVuOlskKCJidXR0b24iLHtvbkNsaWNrOnY1LHN0eWxlOntiYWNrZ3JvdW5kOiJub25lIixib3JkZXI6IjFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMikiLGNvbG9yOiIjYWFhIixmb250U2l6ZToxMSxmb250RmFtaWx5OiJtb25vc3BhY2UiLHBhZGRpbmc6IjJweCAxMHB4IixjdXJzb3I6InBvaW50ZXIiLGJvcmRlclJhZGl1czo0fSxjaGlsZHJlbjoiSG9tZSJ9KSwkKCJzcGFuIix7c3R5bGU6e2NvbG9yOkQ0PjA/IiM0ZjQiOiIjODg4Iixmb250U2l6ZToxMixmb250RmFtaWx5OiJtb25vc3BhY2UiLGRpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjZ9LGNoaWxkcmVuOltrJiYkKCJzcGFuIix7ImRhdGEtdGVzdGlkIjoicXVhbGl0eS1kb3QiLHN0eWxlOnt3aWR0aDo4LGhlaWdodDo4LGJvcmRlclJhZGl1czoiNTAlIixkaXNwbGF5OiJpbmxpbmUtYmxvY2siLGJhY2tncm91bmQ6az09PSJnb29kIj8iIzRhZGU4MCI6az09PSJkZWdyYWRlZCI/IiNmYWNjMTUiOiIjZWY0NDQ0In19KSxENCwiIGZwcyJdfSldfSldfSl9dmFyIEE2PXtwb3NpdGlvbjoiYWJzb2x1dGUiLHRvcDo4LGxlZnQ6IjUwJSIsdHJhbnNmb3JtOiJ0cmFuc2xhdGVYKC01MCUpIixiYWNrZ3JvdW5kOiJyZ2JhKDAsMCwwLDAuNykiLGJvcmRlclJhZGl1czo2LHBhZGRpbmc6IjRweCAxMnB4Iixwb2ludGVyRXZlbnRzOiJub25lIn0sUzU9e3Bvc2l0aW9uOiJhYnNvbHV0ZSIsaW5zZXQ6MCxkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGp1c3RpZnlDb250ZW50OiJjZW50ZXIiLGJhY2tncm91bmQ6InJnYmEoMCwwLDAsMC44KSJ9LFQ1PTIwO2Z1bmN0aW9uIGI1KFgsWSl7cmV0dXJue3Bvc2l0aW9uOiJhYnNvbHV0ZSIsbGVmdDpgJHtYKjEwMH0lYCx0b3A6YCR7WSoxMDB9JWAsd2lkdGg6VDUsaGVpZ2h0OlQ1LGJvcmRlclJhZGl1czoiNTAlIixiYWNrZ3JvdW5kOiJyZ2JhKDI1NSwyNTUsMjU1LDAuNCkiLGJvcmRlcjoiMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC43KSIsdHJhbnNmb3JtOiJ0cmFuc2xhdGUoLTUwJSwgLTUwJSkiLHBvaW50ZXJFdmVudHM6Im5vbmUifX1mdW5jdGlvbiBkMChYKXtpZighWClyZXR1cm4iaXBob25lIjtsZXQgWT1YLnRvTG93ZXJDYXNlKCk7aWYoWS5pbmNsdWRlcygiaXBhZCIpKXJldHVybiJpcGFkIjtpZihZLmluY2x1ZGVzKCJ3YXRjaCIpKXJldHVybiJ3YXRjaCI7aWYoWS5pbmNsdWRlcygidmlzaW9uIikpcmV0dXJuInZpc2lvbiI7cmV0dXJuImlwaG9uZSJ9dmFyIFI9e2lwaG9uZTp7d2lkdGg6NDI3LGhlaWdodDo4ODEsYmV6ZWxYOjE4LGJlemVsWToxOCxpbm5lclJhZGl1czo1NX0saXBhZDp7d2lkdGg6NDMwLGhlaWdodDo2MDUsYmV6ZWxYOjE2LGJlemVsWToxNixpbm5lclJhZGl1czoxMn0sd2F0Y2g6e3dpZHRoOjI3NCxoZWlnaHQ6MzIyLGJlemVsWDoxMixiZXplbFk6MTIsaW5uZXJSYWRpdXM6Nzl9LHZpc2lvbjp7d2lkdGg6NjQwLGhlaWdodDo0MDAsYmV6ZWxYOjEyLGJlemVsWToxMixpbm5lclJhZGl1czozMn19LFU3PVIuaXBob25lLndpZHRoLEE3PVIuaXBob25lLmhlaWdodCxENz1SLmlwaG9uZS5iZXplbFgsUDc9Ui5pcGhvbmUuYmV6ZWxZLEI3PVIuaXBob25lLmlubmVyUmFkaXVzO2Z1bmN0aW9uIFU0KFg9ImlwaG9uZSIpe2xldCBZPVJbWF07cmV0dXJue3RvcDpgJHtZLmJlemVsWS9ZLmhlaWdodCoxMDB9JWAsbGVmdDpgJHtZLmJlemVsWC9ZLndpZHRoKjEwMH0lYCxyaWdodDpgJHtZLmJlemVsWC9ZLndpZHRoKjEwMH0lYCxib3R0b206YCR7WS5iZXplbFkvWS5oZWlnaHQqMTAwfSVgfX1mdW5jdGlvbiBtMChYPSJpcGhvbmUiKXtsZXQgWT1SW1hdLFo9WS53aWR0aC0yKlkuYmV6ZWxYLEo9WS5oZWlnaHQtMipZLmJlemVsWTtyZXR1cm5gJHtZLmlubmVyUmFkaXVzL1oqMTAwfSUgLyAke1kuaW5uZXJSYWRpdXMvSioxMDB9JWB9ZnVuY3Rpb24gaDAoe3R5cGU6WD0iaXBob25lIixzdHJlYW1pbmc6WT0hMX0pe3N3aXRjaChYKXtjYXNlImlwYWQiOnJldHVybiAkKEI2LHtzdHJlYW1pbmc6WX0pO2Nhc2Uid2F0Y2giOnJldHVybiAkKF82LHtzdHJlYW1pbmc6WX0pO2Nhc2UidmlzaW9uIjpyZXR1cm4gJChGNix7c3RyZWFtaW5nOll9KTtkZWZhdWx0OnJldHVybiAkKFA2LHtzdHJlYW1pbmc6WX0pfX1mdW5jdGlvbiBQNih7c3RyZWFtaW5nOlg9ITF9KXtyZXR1cm4gJCgic3ZnIix7dmlld0JveDoiMCAwIDQyNyA4ODEiLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIn0sZmlsbDoibm9uZSIseG1sbnM6Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIixjaGlsZHJlbjpbJCgiZGVmcyIse2NoaWxkcmVuOlskKCJmaWx0ZXIiLHtpZDoiY2hyb21lLWZpbHRlcjAiLHg6Ii0wLjE2Njk5MiIseToiMC4xNjY1MDQiLHdpZHRoOiI0MjciLGhlaWdodDoiODgwLjY2NyIsZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjUiLHJlc3VsdDoiZWZmZWN0MV9mb3JlZ3JvdW5kQmx1ciJ9KV19KSwkKCJmaWx0ZXIiLHtpZDoiY2hyb21lLWZpbHRlcjEiLHg6IjYuMzMyMzYiLHk6IjYuMzMzODIiLHdpZHRoOiI0MTQiLGhlaWdodDoiODY4IixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuMzMzMzMzIixyZXN1bHQ6ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXIifSldfSldfSksJCgicmVjdCIse3g6IjMuODMyNjgiLHk6IjMuODMzNjYiLHdpZHRoOiI0MTkiLGhlaWdodDoiODczIixyeDoiNjYuMTY2NyIsc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiNC4zMzMzMyJ9KSwkKCJyZWN0Iix7eDoiMC44MzMzMzMiLHk6IjAuODMzMzMzIix3aWR0aDoiNDI1IixoZWlnaHQ6Ijg3OSIscng6IjY5LjE2NjciLHN0cm9rZToiIzM3MzczYSIsc3Ryb2tlV2lkdGg6IjEuNjY2NjcifSksJCgiZyIse29wYWNpdHk6IjAuOSIsZmlsdGVyOiJ1cmwoI2Nocm9tZS1maWx0ZXIwKSIsY2hpbGRyZW46JCgicmVjdCIse3g6IjEuNjY2MDIiLHk6IjIiLHdpZHRoOiI0MjMuMzMzIixoZWlnaHQ6Ijg3NyIscng6IjY4LjY2NjciLHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEuNjY2NjcifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjY2hyb21lLWZpbHRlcjEpIixjaGlsZHJlbjokKCJyZWN0Iix7eDoiNy4zMzI2OCIseToiNy4zMzM2NiIsd2lkdGg6IjQxMiIsaGVpZ2h0OiI4NjYiLHJ4OiI2Mi42NjY3IixzdHJva2U6IiM2NDY0NjQiLHN0cm9rZVdpZHRoOiIwLjY2NjY2NyJ9KX0pLCQoInJlY3QiLHt4OiIxNTEuNjY2Iix5OiIzMS42NjciLHdpZHRoOiIxMjMuMzMzIixoZWlnaHQ6IjM2IixyeDoiMTgiLGZpbGw6ImJsYWNrIixzdHlsZTp7b3BhY2l0eTpYPzA6MSx0cmFuc2l0aW9uOiJvcGFjaXR5IDAuM3MgZWFzZSJ9fSldfSl9ZnVuY3Rpb24gQjYoe3N0cmVhbWluZzpYPSExfSl7bGV0IFk9Ui5pcGFkLndpZHRoLFo9Ui5pcGFkLmhlaWdodCxKPTMwLHE9MjY7cmV0dXJuICQoInN2ZyIse3ZpZXdCb3g6YDAgMCAke1l9ICR7Wn1gLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIn0sZmlsbDoibm9uZSIseG1sbnM6Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIixjaGlsZHJlbjpbJCgiZGVmcyIse2NoaWxkcmVuOlskKCJmaWx0ZXIiLHtpZDoiaXBhZC1nbG93MCIseDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuNSIscmVzdWx0OiJibHVyIn0pXX0pLCQoImZpbHRlciIse2lkOiJpcGFkLWdsb3cxIix4OiI1Iix5OiI1Iix3aWR0aDpZLTEwLGhlaWdodDpaLTEwLGZpbHRlclVuaXRzOiJ1c2VyU3BhY2VPblVzZSIsY29sb3JJbnRlcnBvbGF0aW9uRmlsdGVyczoic1JHQiIsY2hpbGRyZW46WyQoImZlRmxvb2QiLHtmbG9vZE9wYWNpdHk6IjAiLHJlc3VsdDoiQmFja2dyb3VuZEltYWdlRml4In0pLCQoImZlQmxlbmQiLHttb2RlOiJub3JtYWwiLGluOiJTb3VyY2VHcmFwaGljIixpbjI6IkJhY2tncm91bmRJbWFnZUZpeCIscmVzdWx0OiJzaGFwZSJ9KSwkKCJmZUdhdXNzaWFuQmx1ciIse3N0ZERldmlhdGlvbjoiMC4zMzMzMzMiLHJlc3VsdDoiYmx1ciJ9KV19KV19KSwkKCJyZWN0Iix7eDoiMy41Iix5OiIzLjUiLHdpZHRoOlktNyxoZWlnaHQ6Wi03LHJ4OjI2LHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjQifSksJCgicmVjdCIse3g6IjAuODMzIix5OiIwLjgzMyIsd2lkdGg6WS0xLjY2NixoZWlnaHQ6Wi0xLjY2NixyeDozMCxzdHJva2U6IiMzNzM3M2EiLHN0cm9rZVdpZHRoOiIxLjY2NiJ9KSwkKCJnIix7b3BhY2l0eToiMC45IixmaWx0ZXI6InVybCgjaXBhZC1nbG93MCkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiIxLjUiLHk6IjEuNSIsd2lkdGg6WS0zLGhlaWdodDpaLTMscng6Mjksc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiMS42NjYifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjaXBhZC1nbG93MSkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiI2Iix5OiI2Iix3aWR0aDpZLTEyLGhlaWdodDpaLTEyLHJ4OjI0LHN0cm9rZToiIzY0NjQ2NCIsc3Ryb2tlV2lkdGg6IjAuNjY2In0pfSksJCgiY2lyY2xlIix7Y3g6WS8yLGN5OlIuaXBhZC5iZXplbFkvMisxLHI6IjMiLGZpbGw6IiMxYTFhMWEiLHN0eWxlOntvcGFjaXR5Olg/MDowLjgsdHJhbnNpdGlvbjoib3BhY2l0eSAwLjNzIGVhc2UifX0pLCQoInJlY3QiLHt4OihZLTEyMCkvMix5OlotUi5pcGFkLmJlemVsWS8yLTIuNSx3aWR0aDoiMTIwIixoZWlnaHQ6IjUiLHJ4OiIyLjUiLGZpbGw6IndoaXRlIixzdHlsZTp7b3BhY2l0eTpYPzA6MC4zNSxtaXhCbGVuZE1vZGU6ImRpZmZlcmVuY2UiLHRyYW5zaXRpb246Im9wYWNpdHkgMC4zcyBlYXNlIn19KV19KX1mdW5jdGlvbiBfNih7c3RyZWFtaW5nOlg9ITF9KXtsZXQgWT1SLndhdGNoLndpZHRoLFo9Ui53YXRjaC5oZWlnaHQsSj04OCxxPTgyLEs9OCxRPTM2LHo9Wi8yLTE4LTE2LEc9MjIsTD1aLzItMTErMTY7cmV0dXJuICQoInN2ZyIse3ZpZXdCb3g6YDAgMCAke1l9ICR7Wn1gLHN0eWxlOnt3aWR0aDoiMTAwJSIsaGVpZ2h0OiIxMDAlIixvdmVyZmxvdzoidmlzaWJsZSJ9LGZpbGw6Im5vbmUiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46WyQoImRlZnMiLHtjaGlsZHJlbjokKCJmaWx0ZXIiLHtpZDoid2F0Y2gtZ2xvdzAiLHg6IjAiLHk6IjAiLHdpZHRoOlkrMTIsaGVpZ2h0OlosZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjUiLHJlc3VsdDoiYmx1ciJ9KV19KX0pLCQoInJlY3QiLHt4OlktMix5Onosd2lkdGg6OCxoZWlnaHQ6MzYscng6IjMiLGZpbGw6IiMyYTJhMmMiLHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEifSksJCgicmVjdCIse3g6WS0xLHk6TCx3aWR0aDo2LGhlaWdodDoyMixyeDoiMi41IixmaWxsOiIjMmEyYTJjIixzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIwLjgifSksJCgicmVjdCIse3g6IjMuNSIseToiMy41Iix3aWR0aDpZLTcsaGVpZ2h0OlotNyxyeDo4MixzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIzLjUifSksJCgicmVjdCIse3g6IjAuODMzIix5OiIwLjgzMyIsd2lkdGg6WS0xLjY2NixoZWlnaHQ6Wi0xLjY2NixyeDo4OCxzdHJva2U6IiMzNzM3M2EiLHN0cm9rZVdpZHRoOiIxLjY2NiJ9KSwkKCJnIix7b3BhY2l0eToiMC45IixmaWx0ZXI6InVybCgjd2F0Y2gtZ2xvdzApIixjaGlsZHJlbjokKCJyZWN0Iix7eDoiMS41Iix5OiIxLjUiLHdpZHRoOlktMyxoZWlnaHQ6Wi0zLHJ4Ojg3LHN0cm9rZToiIzQ1NDU0OCIsc3Ryb2tlV2lkdGg6IjEuNjY2In0pfSldfSl9ZnVuY3Rpb24gRjYoe3N0cmVhbWluZzpYPSExfSl7bGV0IFk9Ui52aXNpb24ud2lkdGgsWj1SLnZpc2lvbi5oZWlnaHQsSj00MCxxPTM0O3JldHVybiAkKCJzdmciLHt2aWV3Qm94OmAwIDAgJHtZfSAke1p9YCxzdHlsZTp7d2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSJ9LGZpbGw6Im5vbmUiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46WyQoImRlZnMiLHtjaGlsZHJlbjpbJCgiZmlsdGVyIix7aWQ6InZpc2lvbi1nbG93MCIseDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixmaWx0ZXJVbml0czoidXNlclNwYWNlT25Vc2UiLGNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnM6InNSR0IiLGNoaWxkcmVuOlskKCJmZUZsb29kIix7Zmxvb2RPcGFjaXR5OiIwIixyZXN1bHQ6IkJhY2tncm91bmRJbWFnZUZpeCJ9KSwkKCJmZUJsZW5kIix7bW9kZToibm9ybWFsIixpbjoiU291cmNlR3JhcGhpYyIsaW4yOiJCYWNrZ3JvdW5kSW1hZ2VGaXgiLHJlc3VsdDoic2hhcGUifSksJCgiZmVHYXVzc2lhbkJsdXIiLHtzdGREZXZpYXRpb246IjAuNSIscmVzdWx0OiJibHVyIn0pXX0pLCQoImZpbHRlciIse2lkOiJ2aXNpb24tZ2xvdzEiLHg6IjUiLHk6IjUiLHdpZHRoOlktMTAsaGVpZ2h0OlotMTAsZmlsdGVyVW5pdHM6InVzZXJTcGFjZU9uVXNlIixjb2xvckludGVycG9sYXRpb25GaWx0ZXJzOiJzUkdCIixjaGlsZHJlbjpbJCgiZmVGbG9vZCIse2Zsb29kT3BhY2l0eToiMCIscmVzdWx0OiJCYWNrZ3JvdW5kSW1hZ2VGaXgifSksJCgiZmVCbGVuZCIse21vZGU6Im5vcm1hbCIsaW46IlNvdXJjZUdyYXBoaWMiLGluMjoiQmFja2dyb3VuZEltYWdlRml4IixyZXN1bHQ6InNoYXBlIn0pLCQoImZlR2F1c3NpYW5CbHVyIix7c3RkRGV2aWF0aW9uOiIwLjMzMyIscmVzdWx0OiJibHVyIn0pXX0pLCQoImxpbmVhckdyYWRpZW50Iix7aWQ6InZpc2lvbi1nbGFzcyIseDE6IjAiLHkxOiIwIix4MjoiMCIseTI6IjEiLGNoaWxkcmVuOlskKCJzdG9wIix7b2Zmc2V0OiIwJSIsc3RvcENvbG9yOiIjNTU1NTU4IixzdG9wT3BhY2l0eToiMC4zIn0pLCQoInN0b3AiLHtvZmZzZXQ6IjEwMCUiLHN0b3BDb2xvcjoiIzNhM2EzZCIsc3RvcE9wYWNpdHk6IjAuMSJ9KV19KV19KSwkKCJyZWN0Iix7eDoiMCIseToiMCIsd2lkdGg6WSxoZWlnaHQ6WixyeDo0MCxmaWxsOiJ1cmwoI3Zpc2lvbi1nbGFzcykifSksJCgicmVjdCIse3g6IjMuNSIseToiMy41Iix3aWR0aDpZLTcsaGVpZ2h0OlotNyxyeDozNCxzdHJva2U6IiM0NTQ1NDgiLHN0cm9rZVdpZHRoOiIzIn0pLCQoInJlY3QiLHt4OiIwLjgzMyIseToiMC44MzMiLHdpZHRoOlktMS42NjYsaGVpZ2h0OlotMS42NjYscng6NDAsc3Ryb2tlOiIjMzczNzNhIixzdHJva2VXaWR0aDoiMS42NjYifSksJCgiZyIse29wYWNpdHk6IjAuOSIsZmlsdGVyOiJ1cmwoI3Zpc2lvbi1nbG93MCkiLGNoaWxkcmVuOiQoInJlY3QiLHt4OiIxLjUiLHk6IjEuNSIsd2lkdGg6WS0zLGhlaWdodDpaLTMscng6Mzksc3Ryb2tlOiIjNDU0NTQ4IixzdHJva2VXaWR0aDoiMS42NjYifSl9KSwkKCJnIix7b3BhY2l0eToiMC44IixmaWx0ZXI6InVybCgjdmlzaW9uLWdsb3cxKSIsY2hpbGRyZW46JCgicmVjdCIse3g6IjYiLHk6IjYiLHdpZHRoOlktMTIsaGVpZ2h0OlotMTIscng6MzIsc3Ryb2tlOiIjNjQ2NDY0IixzdHJva2VXaWR0aDoiMC42NjYifSl9KSwkKCJlbGxpcHNlIix7Y3g6WS8yLGN5OlovMixyeDpZLzItMzAscnk6Wi8yLTI0LHN0cm9rZToiIzRhNGE0ZCIsc3Ryb2tlV2lkdGg6IjAuNSIsb3BhY2l0eToiMC4zIixzdHlsZTp7b3BhY2l0eTpYPzA6MC4zLHRyYW5zaXRpb246Im9wYWNpdHkgMC4zcyBlYXNlIn19KV19KX12YXIgQTQ9ejAobnVsbCk7ZnVuY3Rpb24gZjAoWCl7bGV0IFk9UDAoQTQpO2lmKCFZKXRocm93IEVycm9yKGA8U2ltdWxhdG9yVG9vbGJhci4ke1h9PiBtdXN0IGJlIHJlbmRlcmVkIGluc2lkZSA8U2ltdWxhdG9yVG9vbGJhcj5gKTtyZXR1cm4gWX12YXIgTTY9e2Rpc3BsYXk6ImZsZXgiLGZsZXhXcmFwOiJ3cmFwIixhbGlnbkl0ZW1zOiJjZW50ZXIiLGp1c3RpZnlDb250ZW50OiJzcGFjZS1iZXR3ZWVuIixnYXA6IjRweCAxMnB4IixwYWRkaW5nOiI4cHggMTJweCIsYm9yZGVyUmFkaXVzOjI0LGJhY2tncm91bmQ6IiMxYzFjMWUiLGJvcmRlcjoiMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4xKSIsYm94U2hhZG93OiIwIDFweCAycHggcmdiYSgwLDAsMCwwLjIpIixtaW5XaWR0aDoyNDAsd2lkdGg6IjEwMCUifTtmdW5jdGlvbiBDNih7ZXhlYzpYLGRldmljZVVkaWQ6WSxkZXZpY2VOYW1lOlosZGV2aWNlUnVudGltZTpKLHN0cmVhbWluZzpxPSExLGRpc2FibGVkOks9ITEsY2hpbGRyZW46USxzdHlsZTp6LC4uLkd9KXtsZXQgTD1kMChaKSxXPXtleGVjOlgsZGV2aWNlVWRpZDpZLGRldmljZU5hbWU6WixkZXZpY2VSdW50aW1lOkosZGV2aWNlVHlwZTpMLHN0cmVhbWluZzpxLGRpc2FibGVkOkt8fCFZfHwhcX07cmV0dXJuICQoQTQuUHJvdmlkZXIse3ZhbHVlOlcsY2hpbGRyZW46JCgiZGl2Iix7ImRhdGEtc2ltdWxhdG9yLXRvb2xiYXIiOiEwLHN0eWxlOnsuLi5NNiwuLi56fSwuLi5HLGNoaWxkcmVuOlF9KX0pfXZhciBFNj17ZGlzcGxheToiZmxleCIsZmxleERpcmVjdGlvbjoiY29sdW1uIixhbGlnbkl0ZW1zOiJmbGV4LXN0YXJ0Iix0ZXh0QWxpZ246ImxlZnQiLGJhY2tncm91bmQ6InRyYW5zcGFyZW50Iixib3JkZXI6Im5vbmUiLGNvbG9yOiIjZmZmIixwYWRkaW5nOiIycHggNHB4IixtYXJnaW46Ii0ycHggLTRweCIsYm9yZGVyUmFkaXVzOjYsY3Vyc29yOiJwb2ludGVyIixtaW5XaWR0aDowLG1heFdpZHRoOiIxMDAlIixsaW5lSGVpZ2h0OjEuMixmb250RmFtaWx5OiJpbmhlcml0In0sdzY9RzAoZnVuY3Rpb24oe25hbWU6WSxzdWJ0aXRsZTpaLGhpZGVDaGV2cm9uOkosc3R5bGU6cSxvbk1vdXNlRW50ZXI6Syxvbk1vdXNlTGVhdmU6USwuLi56fSxHKXtsZXQgTD1mMCgiVGl0bGUiKSxbRCxXXT1wKCExKSxPPVk/P0wuZGV2aWNlTmFtZT8/Ik5vIHNpbXVsYXRvciIsVT1aPz8oTC5kZXZpY2VSdW50aW1lP0wuZGV2aWNlUnVudGltZS5yZXBsYWNlKC9cLi8sIiAiKToi4oCUIik7cmV0dXJuICQoImJ1dHRvbiIse3JlZjpHLHR5cGU6ImJ1dHRvbiIsImRhdGEtc2ltdWxhdG9yLXRvb2xiYXItdGl0bGUiOiEwLG9uTW91c2VFbnRlcjooayk9PntXKCEwKSxLPy4oayl9LG9uTW91c2VMZWF2ZTooayk9PntXKCExKSxRPy4oayl9LHN0eWxlOnsuLi5FNixiYWNrZ3JvdW5kOkQ/InJnYmEoMjU1LDI1NSwyNTUsMC4xKSI6InRyYW5zcGFyZW50IiwuLi5xfSwuLi56LGNoaWxkcmVuOlskKCJzcGFuIix7c3R5bGU6e2Rpc3BsYXk6ImlubGluZS1mbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDo0LGZvbnRTaXplOjEyLGZvbnRXZWlnaHQ6NjAwLGNvbG9yOiIjZmZmIixtYXhXaWR0aDoiMTAwJSIsb3ZlcmZsb3c6ImhpZGRlbiIsdGV4dE92ZXJmbG93OiJlbGxpcHNpcyIsd2hpdGVTcGFjZToibm93cmFwIn0sY2hpbGRyZW46W08sIUomJiQoInN2ZyIse3dpZHRoOiIxMCIsaGVpZ2h0OiIxMCIsdmlld0JveDoiMCAwIDI0IDI0IixmaWxsOiJub25lIixzdHJva2U6ImN1cnJlbnRDb2xvciIsc3Ryb2tlV2lkdGg6IjIuNSIsc3Ryb2tlTGluZWNhcDoicm91bmQiLHN0cm9rZUxpbmVqb2luOiJyb3VuZCIsc3R5bGU6e2NvbG9yOiJyZ2JhKDI1NSwyNTUsMjU1LDAuNikiLGZsZXhTaHJpbms6MH0sY2hpbGRyZW46JCgicG9seWxpbmUiLHtwb2ludHM6IjYgOSAxMiAxNSAxOCA5In0pfSldfSksJCgic3BhbiIse3N0eWxlOntmb250U2l6ZToxMCxjb2xvcjoicmdiYSgyNTUsMjU1LDI1NSwwLjUpIixtYXhXaWR0aDoiMTAwJSIsb3ZlcmZsb3c6ImhpZGRlbiIsdGV4dE92ZXJmbG93OiJlbGxpcHNpcyIsd2hpdGVTcGFjZToibm93cmFwIn0sY2hpbGRyZW46VX0pXX0pfSksUzY9e2Rpc3BsYXk6ImZsZXgiLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjQsZmxleFNocmluazowfTtmdW5jdGlvbiBUNih7c3R5bGU6WCwuLi5ZfSl7cmV0dXJuICQoImRpdiIse3N0eWxlOnsuLi5TNiwuLi5YfSwuLi5ZfSl9dmFyIGI2PXtiYWNrZ3JvdW5kOiJ0cmFuc3BhcmVudCIsYm9yZGVyOiJub25lIixwYWRkaW5nOjYsYm9yZGVyUmFkaXVzOjYsY3Vyc29yOiJwb2ludGVyIixkaXNwbGF5OiJpbmxpbmUtZmxleCIsYWxpZ25JdGVtczoiY2VudGVyIixqdXN0aWZ5Q29udGVudDoiY2VudGVyIixjb2xvcjoicmdiYSgyNTUsMjU1LDI1NSwwLjgpIix0cmFuc2l0aW9uOiJiYWNrZ3JvdW5kLWNvbG9yIDAuMTVzLCBjb2xvciAwLjE1cyJ9LGEwPUcwKGZ1bmN0aW9uKHtmb3JjZURpc2FibGVkOlksc3R5bGU6WixkaXNhYmxlZDpKLG9uTW91c2VFbnRlcjpxLG9uTW91c2VMZWF2ZTpLLGNoaWxkcmVuOlEsLi4uen0sRyl7bGV0IEw9UDAoQTQpLEQ9Snx8WXx8TD8uZGlzYWJsZWQsW1csT109cCghMSk7cmV0dXJuICQoImJ1dHRvbiIse3JlZjpHLHR5cGU6ImJ1dHRvbiIsZGlzYWJsZWQ6RCxvbk1vdXNlRW50ZXI6KFUpPT57TyghMCkscT8uKFUpfSxvbk1vdXNlTGVhdmU6KFUpPT57TyghMSksSz8uKFUpfSxzdHlsZTp7Li4uYjYsY29sb3I6RD8icmdiYSgyNTUsMjU1LDI1NSwwLjI1KSI6InJnYmEoMjU1LDI1NSwyNTUsMC44KSIsYmFja2dyb3VuZDpXJiYhRD8icmdiYSgyNTUsMjU1LDI1NSwwLjEpIjoidHJhbnNwYXJlbnQiLGN1cnNvcjpEPyJub3QtYWxsb3dlZCI6InBvaW50ZXIiLC4uLlp9LC4uLnosY2hpbGRyZW46UX0pfSk7ZnVuY3Rpb24gcDYoKXtyZXR1cm5bJ3RlbGwgYXBwbGljYXRpb24gIlN5c3RlbSBFdmVudHMiIHRvIHRlbGwgcHJvY2VzcyAiU2ltdWxhdG9yIiB0byBzZXQgZnJvbnRtb3N0IHRvIHRydWUnLCd0ZWxsIGFwcGxpY2F0aW9uICJTeXN0ZW0gRXZlbnRzIiB0byB0ZWxsIHByb2Nlc3MgIlNpbXVsYXRvciIgdG8gcGVyZm9ybSBhY3Rpb24gIkFYUmFpc2UiIG9mIChmaXJzdCB3aW5kb3cgd2hvc2UgbmFtZSBjb250YWlucyAid2F0Y2hPUyIpJywndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8gdGVsbCBwcm9jZXNzICJTaW11bGF0b3IiIHRvIGNsaWNrIG1lbnUgaXRlbSAiSG9tZSIgb2YgbWVudSAiRGV2aWNlIiBvZiBtZW51IGJhciBpdGVtICJEZXZpY2UiIG9mIG1lbnUgYmFyIDEnXS5tYXAoKFkpPT5gLWUgJyR7WX0nYCkucmVkdWNlKChZLFopPT5gJHtZfSAke1p9YCwib3Nhc2NyaXB0Iil9dmFyIHY2PSQoInN2ZyIse3dpZHRoOiIxOCIsaGVpZ2h0OiIxOCIsdmlld0JveDoiMCAwIDI0IDI0IixmaWxsOiJub25lIixzdHJva2U6ImN1cnJlbnRDb2xvciIsc3Ryb2tlV2lkdGg6IjIiLHN0cm9rZUxpbmVjYXA6InJvdW5kIixzdHJva2VMaW5lam9pbjoicm91bmQiLGNoaWxkcmVuOiQoInBhdGgiLHtkOiJNMyAxMC41IDEyIDNsOSA3LjVWMjBhMSAxIDAgMCAxLTEgMWgtNXYtN2gtNnY3SDRhMSAxIDAgMCAxLTEtMXoifSl9KSxqNj0kKCJzdmciLHt3aWR0aDoiMTgiLGhlaWdodDoiMTgiLHZpZXdCb3g6IjAgMCAyNCAyNCIsZmlsbDoibm9uZSIsc3Ryb2tlOiJjdXJyZW50Q29sb3IiLHN0cm9rZVdpZHRoOiIyIixzdHJva2VMaW5lY2FwOiJyb3VuZCIsc3Ryb2tlTGluZWpvaW46InJvdW5kIixjaGlsZHJlbjpbJCgicGF0aCIse2Q6Ik0xNC41IDRoLTVMNyA3SDRhMiAyIDAgMCAwLTIgMnY5YTIgMiAwIDAgMCAyIDJoMTZhMiAyIDAgMCAwIDItMlY5YTIgMiAwIDAgMC0yLTJoLTN6In0pLCQoImNpcmNsZSIse2N4OiIxMiIsY3k6IjEzIixyOiI0In0pXX0pLFI2PSQoInN2ZyIse3dpZHRoOiIxOCIsaGVpZ2h0OiIxOCIsdmlld0JveDoiMCAwIDEyIDEzIixmaWxsOiJjdXJyZW50Q29sb3IiLHhtbG5zOiJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIsY2hpbGRyZW46JCgicGF0aCIse2Q6Ik0xMC4yMzA1IDEyLjgwNzdINC40MjM4M0MzLjkyMzgzIDEyLjgwNzcgMy41NDY4OCAxMi42ODQ2IDMuMjkyOTcgMTIuNDM4NUMzLjA0Mjk3IDEyLjE5NjMgMi45MTc5NyAxMS44MTk0IDIuOTE3OTcgMTEuMzA3N1Y1LjUxMjc0QzIuOTE3OTcgNC45OTcxMSAzLjA0Mjk3IDQuNjE4MjEgMy4yOTI5NyA0LjM3NjAyQzMuNTQ2ODggNC4xMjk5MyAzLjkyMzgzIDQuMDA2ODggNC40MjM4MyA0LjAwNjg4SDEwLjIzMDVDMTAuNzM0NCA0LjAwNjg4IDExLjExMTMgNC4xMjk5MyAxMS4zNjEzIDQuMzc2MDJDMTEuNjExMyA0LjYxODIxIDExLjczNjMgNC45OTcxMSAxMS43MzYzIDUuNTEyNzRWMTEuMzA3N0MxMS43MzYzIDExLjgxOTQgMTEuNjExMyAxMi4xOTYzIDExLjM2MTMgMTIuNDM4NUMxMS4xMTEzIDEyLjY4NDYgMTAuNzM0NCAxMi44MDc3IDEwLjIzMDUgMTIuODA3N1pNMTAuMjEyOSAxMS44NjQzQzEwLjQxNiAxMS44NjQzIDEwLjU2MjUgMTEuODE5NCAxMC42NTIzIDExLjcyOTVDMTAuNzQ2MSAxMS42NDM2IDEwLjc5MyAxMS40OTcxIDEwLjc5MyAxMS4yOTAxVjUuNTI0NDZDMTAuNzkzIDUuMzE3NDMgMTAuNzQ2MSA1LjE3MDk0IDEwLjY1MjMgNS4wODUwMUMxMC41NjI1IDQuOTk1MTYgMTAuNDE2IDQuOTUwMjQgMTAuMjEyOSA0Ljk1MDI0SDQuNDQxNDFDNC4yNDIxOSA0Ljk1MDI0IDQuMDk1NyA0Ljk5NTE2IDQuMDAxOTUgNS4wODUwMUMzLjkwODIgNS4xNzA5NCAzLjg2MTMzIDUuMzE3NDMgMy44NjEzMyA1LjUyNDQ2VjExLjI5MDFDMy44NjEzMyAxMS40OTcxIDMuOTA4MiAxMS42NDM2IDQuMDAxOTUgMTEuNzI5NUM0LjA5NTcgMTEuODE5NCA0LjI0MjE5IDExLjg2NDMgNC40NDE0MSAxMS44NjQzSDEwLjIxMjlaTTIuOTE3OTcgMi41ODMwNVYwLjQxNTA4M0MyLjkxNzk3IDAuMjAwMjQgMi45ODYzMyAwLjA2OTM4MDMgMy4xMjMwNSAwLjAyMjUwNTNDMy4yNTk3NyAtMC4wMjgyNzU5IDMuNDEwMTYgMC4wMDY4ODAzMyAzLjU3NDIyIDAuMTI3OTc0TDUuMDUwNzggMS4yMTE5NkM1LjE3NTc4IDEuMzA1NzEgNS4yMzgyOCAxLjQwMTQxIDUuMjM4MjggMS40OTkwN0M1LjIzODI4IDEuNTk2NzIgNS4xNzU3OCAxLjY5MjQzIDUuMDUwNzggMS43ODYxOEwzLjU3NDIyIDIuODY0M0MzLjQxMDE2IDIuOTg1NCAzLjI1OTc3IDMuMDIyNTEgMy4xMjMwNSAyLjk3NTYzQzIuOTg2MzMgMi45MjQ4NSAyLjkxNzk3IDIuNzkzOTkgMi45MTc5NyAyLjU4MzA1Wk0zLjUzMzIgMS4xNTMzNkMzLjYyNjk1IDEuMTUzMzYgMy43MDcwMyAxLjE4NjU3IDMuNzczNDQgMS4yNTI5N0MzLjg0Mzc1IDEuMzE5MzggMy44Nzg5MSAxLjM5NzUxIDMuODc4OTEgMS40ODczNUMzLjg3ODkxIDEuNTgxMSAzLjg0Mzc1IDEuNjYzMTMgMy43NzM0NCAxLjczMzQ0QzMuNzA3MDMgMS43OTk4NSAzLjYyNjk1IDEuODMzMDUgMy41MzMyIDEuODMzMDVIMi44MDY2NEMyLjM4MDg2IDEuODMzMDUgMi4wMTE3MiAxLjkyNDg1IDEuNjk5MjIgMi4xMDg0NEMxLjM5MDYyIDIuMjg4MTMgMS4xNTIzNCAyLjUzODEzIDAuOTg0Mzc1IDIuODU4NDRDMC44MTY0MDYgMy4xNzg3NiAwLjczMjQyMiAzLjU0NTk0IDAuNzMyNDIyIDMuOTYwMDFWNC44Mzg5MUMwLjczMjQyMiA0LjkzNjU3IDAuNjk3MjY2IDUuMDIyNTEgMC42MjY5NTMgNS4wOTY3MkMwLjU1MjczNCA1LjE2NzA0IDAuNDY0ODQ0IDUuMjAyMTkgMC4zNjMyODEgNS4yMDIxOUMwLjI2NTYyNSA1LjIwMjE5IDAuMTgxNjQxIDUuMTY3MDQgMC4xMTEzMjggNS4wOTY3MkMwLjAzNzEwOTQgNS4wMjI1MSAwIDQuOTM2NTcgMCA0LjgzODkxVjMuOTYwMDFDMCAzLjQwMTQxIDAuMTE3MTg4IDIuOTExMTggMC4zNTE1NjIgMi40ODkzQzAuNTgyMDMxIDIuMDY3NDMgMC45MDgyMDMgMS43MzkzIDEuMzMwMDggMS41MDQ5M0MxLjc0ODA1IDEuMjcwNTUgMi4yMzgyOCAxLjE1MzM2IDIuODAwNzggMS4xNTMzNkgzLjUzMzJaIn0pfSkseTY9RzAoZnVuY3Rpb24oe29uQ2xpY2s6WSwuLi5afSxKKXtsZXQgcT1mMCgiSG9tZUJ1dHRvbiIpO3JldHVybiAkKGEwLHtyZWY6SiwiYXJpYS1sYWJlbCI6IkhvbWUiLG9uQ2xpY2s6KEspPT57aWYoWT8uKEspLEsuZGVmYXVsdFByZXZlbnRlZClyZXR1cm47aWYocS5kZXZpY2VUeXBlPT09IndhdGNoIilxLmV4ZWMocDYoKSk7ZWxzZSBxLmV4ZWMoInNlcnZlLXNpbSBidXR0b24gaG9tZSIpfSwuLi5aLGNoaWxkcmVuOnY2fSl9KSxnNj1HMChmdW5jdGlvbih7b25DbGljazpZLC4uLlp9LEope2xldCBxPWYwKCJTY3JlZW5zaG90QnV0dG9uIik7cmV0dXJuICQoYTAse3JlZjpKLCJhcmlhLWxhYmVsIjoiU2NyZWVuc2hvdCIsb25DbGljazooSyk9PntpZihZPy4oSyksSy5kZWZhdWx0UHJldmVudGVkKXJldHVybjtpZihxLmRldmljZVVkaWQpcS5leGVjKGB4Y3J1biBzaW1jdGwgaW8gJHtxLmRldmljZVVkaWR9IHNjcmVlbnNob3Qgfi9EZXNrdG9wL2hhdGNoLXNjcmVlbnNob3QtJChkYXRlICslcykucG5nYCl9LC4uLlosY2hpbGRyZW46ajZ9KX0pLHg2PUcwKGZ1bmN0aW9uKHtvbkNsaWNrOlksLi4uWn0sSil7bGV0IHE9ZjAoIlJvdGF0ZUJ1dHRvbiIpO3JldHVybiAkKGEwLHtyZWY6SiwiYXJpYS1sYWJlbCI6IlJvdGF0ZSBkZXZpY2UiLG9uQ2xpY2s6KEspPT57aWYoWT8uKEspLEsuZGVmYXVsdFByZXZlbnRlZClyZXR1cm47aWYocS5kZXZpY2VVZGlkKXEuZXhlYyhgb3Nhc2NyaXB0IC1lICd0ZWxsIGFwcGxpY2F0aW9uICJTaW11bGF0b3IiIHRvIGFjdGl2YXRlJyAtZSAndGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIgdG8ga2V5IGNvZGUgMTI0IHVzaW5nIHtjb21tYW5kIGRvd259J2ApfSwuLi5aLGNoaWxkcmVuOlI2fSl9KSwkMD1DNjskMC5UaXRsZT13NjskMC5BY3Rpb25zPVQ2OyQwLkJ1dHRvbj1hMDskMC5Ib21lQnV0dG9uPXk2OyQwLlNjcmVlbnNob3RCdXR0b249ZzY7JDAuUm90YXRlQnV0dG9uPXg2O2Z1bmN0aW9uIGQ2KFgpe2xldFtZLFpdPXAobnVsbCksSj13KG5ldyBTZXQpLFtxLEtdPXAobnVsbCksUT1qKCh6KT0+e3JldHVybiBKLmN1cnJlbnQuYWRkKHopLCgpPT57Si5jdXJyZW50LmRlbGV0ZSh6KX19LFtdKTtyZXR1cm4gZCgoKT0+e2lmKCFYKXJldHVybjtsZXQgej1uZXcgQWJvcnRDb250cm9sbGVyLEc9WC5yZXBsYWNlKC9cL3N0cmVhbVwubWpwZWckLywiIik7cmV0dXJuIGZldGNoKGAke0d9L2NvbmZpZ2Ase3NpZ25hbDp6LnNpZ25hbH0pLnRoZW4oKEwpPT5MLmpzb24oKSkudGhlbigoTCk9PntpZihMLndpZHRoPjAmJkwuaGVpZ2h0PjApWihMKX0pLmNhdGNoKCgpPT57fSksKGFzeW5jKCk9Pnt0cnl7bGV0IEQ9KGF3YWl0IGZldGNoKFgse3NpZ25hbDp6LnNpZ25hbH0pKS5ib2R5Py5nZXRSZWFkZXIoKTtpZighRClyZXR1cm47bGV0IFc9bmV3IFVpbnQ4QXJyYXkoMCk7d2hpbGUoITApe2xldHtkb25lOk8sdmFsdWU6VX09YXdhaXQgRC5yZWFkKCk7aWYoTylicmVhaztsZXQgaz1uZXcgVWludDhBcnJheShXLmxlbmd0aCtVLmxlbmd0aCk7ay5zZXQoVyksay5zZXQoVSxXLmxlbmd0aCksVz1rO3doaWxlKCEwKXtsZXQgXz0tMTtmb3IobGV0IEk9MDtJPFcubGVuZ3RoLTE7SSsrKWlmKFdbSV09PT0yNTUmJldbSSsxXT09PTIxNil7Xz1JO2JyZWFrfWlmKF89PT0tMSlicmVhaztsZXQgQz0tMTtmb3IobGV0IEk9XysyO0k8Vy5sZW5ndGgtMTtJKyspaWYoV1tJXT09PTI1NSYmV1tJKzFdPT09MjE3KXtDPUkrMjticmVha31pZihDPT09LTEpYnJlYWs7bGV0IE09Vy5zbGljZShfLEMpO1c9Vy5zbGljZShDKTtsZXQgRj1uZXcgQmxvYihbTV0se3R5cGU6ImltYWdlL2pwZWcifSksRT1VUkwuY3JlYXRlT2JqZWN0VVJMKEYpO0soRSk7Zm9yKGxldCBJIG9mIEouY3VycmVudClJKEUpfX19Y2F0Y2h7fX0pKCksKCk9PnouYWJvcnQoKX0sW1hdKSx7c3Vic2NyaWJlRnJhbWU6USxmcmFtZTpxLGNvbmZpZzpZfX1mdW5jdGlvbiBtNigpe2xldCBYPXdpbmRvdy5fX1NJTV9QUkVWSUVXX18sW1ksWl09cCghMSk7aWYoZCgoKT0+e2lmKCFYPy5sb2dzRW5kcG9pbnQpcmV0dXJuO2xldCBPPW5ldyBFdmVudFNvdXJjZShYLmxvZ3NFbmRwb2ludCksVT1uZXcgTWFwLGs9WyIjOGJlOWZkIiwiIzUwZmE3YiIsIiNmZmI4NmMiLCIjZmY3OWM2IiwiI2JkOTNmOSIsIiNmMWZhOGMiLCIjNjI3MmE0IiwiI2ZmNTU1NSIsIiM2OWZmOTQiLCIjZDZhY2ZmIiwiI2ZmZmZhNSIsIiNhNGZmZmYiLCIjZmY2ZTZlIiwiI2NhYTlmYSIsIiM1YWY3OGUiXTtmdW5jdGlvbiBfKEYpe2xldCBFPVUuZ2V0KEYpO2lmKCFFKXtsZXQgST0wO2ZvcihsZXQgdj0wO3Y8Ri5sZW5ndGg7disrKUk9KEk8PDUpLUkrRi5jaGFyQ29kZUF0KHYpfDA7RT1rW01hdGguYWJzKEkpJWsubGVuZ3RoXSxVLnNldChGLEUpfXJldHVybiBFfWxldCBDPSIiLE09ITE7cmV0dXJuIE8ub25tZXNzYWdlPShGKT0+e3RyeXtsZXQgRT1KU09OLnBhcnNlKEYuZGF0YSksST1FLnByb2Nlc3NJbWFnZVBhdGg/LnNwbGl0KCIvIikucG9wKCk/P0Uuc2VuZGVySW1hZ2VQYXRoPy5zcGxpdCgiLyIpLnBvcCgpPz8iIix2PUUuc3Vic3lzdGVtPz8iIixyPUUuY2F0ZWdvcnk/PyIiLGY9RS5ldmVudE1lc3NhZ2U/PyIiO2lmKCFmKXJldHVybjtpZihJIT09Qyl7aWYoTSljb25zb2xlLmdyb3VwRW5kKCk7bGV0IGMwPV8oSSk7Y29uc29sZS5ncm91cENvbGxhcHNlZChgJWMke0l9JHt2P2AgJWMke3Z9JHtyPyI6IityOiIifWA6IiJ9YCxgY29sb3I6JHtjMH07Zm9udC13ZWlnaHQ6Ym9sZGAsLi4udj9bImNvbG9yOiM4ODg7Zm9udC13ZWlnaHQ6bm9ybWFsIl06W10pLE09ITAsQz1JfWxldCBpPShFLm1lc3NhZ2VUeXBlPz8iIikudG9Mb3dlckNhc2UoKSx5PXYmJkk9PT1DP2AlYyR7cnx8dn0lYyBgOiIiLG09eT9bImNvbG9yOiM4ODg7Zm9udC1zdHlsZTppdGFsaWMiLCJjb2xvcjppbmhlcml0Il06W107aWYoaT09PSJmYXVsdCJ8fGk9PT0iZXJyb3IiKWNvbnNvbGUubG9nKGAke3l9JWMke2Z9YCwuLi5tLCJjb2xvcjojZmY1NTU1Iik7ZWxzZSBpZihpPT09ImRlYnVnIiljb25zb2xlLmxvZyhgJHt5fSVjJHtmfWAsLi4ubSwiY29sb3I6IzYyNzJhNCIpO2Vsc2UgY29uc29sZS5sb2coYCR7eX0lYyR7Zn1gLC4uLm0sImNvbG9yOmluaGVyaXQiKX1jYXRjaHt9fSwoKT0+e2lmKE0pY29uc29sZS5ncm91cEVuZCgpO08uY2xvc2UoKX19LFtYPy5sb2dzRW5kcG9pbnRdKSwhWClyZXR1cm4gJCgiZGl2Iix7c3R5bGU6SjAucGFnZSxjaGlsZHJlbjokKCJkaXYiLHtzdHlsZTpKMC5lbXB0eSxjaGlsZHJlbjpbJCgiaDEiLHtzdHlsZTpKMC5lbXB0eVRpdGxlLGNoaWxkcmVuOiJObyBzZXJ2ZS1zaW0gc3RyZWFtIHJ1bm5pbmcifSksJCgicCIse3N0eWxlOkowLmVtcHR5SGludCxjaGlsZHJlbjpbIkJvb3QgYW4gaU9TIHNpbXVsYXRvciBhbmQgc3RhcnQgYSBIYXRjaCBzdHJlYW0gd2l0aCIsIiAiLCQoImNvZGUiLHtzdHlsZTpKMC5jb2RlLGNoaWxkcmVuOiJidW54IHNlcnZlLXNpbSAtLWRldGFjaCJ9KSwiLCB0aGVuIHJlbG9hZC4iXX0pXX0pfSk7bGV0IEo9Ui5pcGhvbmUscT1VNCgiaXBob25lIiksSz1tMCgiaXBob25lIiksUT1kNihYLnN0cmVhbVVybCksej13KG51bGwpO2QoKCk9PntsZXQgTz1uZXcgV2ViU29ja2V0KFgud3NVcmwpO3JldHVybiBPLmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix6LmN1cnJlbnQ9TywoKT0+e08uY2xvc2UoKSx6LmN1cnJlbnQ9bnVsbH19LFtYLndzVXJsXSk7bGV0IEc9aigoTyxVKT0+e2xldCBrPXouY3VycmVudDtpZigha3x8ay5yZWFkeVN0YXRlIT09V2ViU29ja2V0Lk9QRU4pcmV0dXJuO2xldCBfPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShKU09OLnN0cmluZ2lmeShVKSksQz1uZXcgVWludDhBcnJheSgxK18ubGVuZ3RoKTtDWzBdPU8sQy5zZXQoXywxKSxrLnNlbmQoQyl9LFtdKSxMPWooKE8pPT5HKDMsTyksW0ddKSxEPWooKE8pPT5HKDUsTyksW0ddKSxXPWooKE8pPT5HKDQse2J1dHRvbjpPfSksW0ddKTtyZXR1cm4gJCgiZGl2Iix7c3R5bGU6SjAucGFnZSxjaGlsZHJlbjpbJCgiZGl2Iix7c3R5bGU6e3Bvc2l0aW9uOiJyZWxhdGl2ZSIsbWF4V2lkdGg6MzIwLHdpZHRoOiIxMDAlIixhc3BlY3RSYXRpbzpgJHtKLndpZHRofSAvICR7Si5oZWlnaHR9YH0sY2hpbGRyZW46WyQoImRpdiIse3N0eWxlOntwb3NpdGlvbjoiYWJzb2x1dGUiLC4uLnF9LGNoaWxkcmVuOiQoeDAse3VybDpYLnVybCxzdHlsZTp7d2lkdGg6IjEwMCUiLGhlaWdodDoiMTAwJSIsYm9yZGVyOiJub25lIn0saW1hZ2VTdHlsZTp7Ym9yZGVyUmFkaXVzOkssY29ybmVyU2hhcGU6InN1cGVyZWxsaXBzZSgxLjMpIn0saGlkZUNvbnRyb2xzOiEwLG9uU3RyZWFtaW5nQ2hhbmdlOlosb25TdHJlYW1Ub3VjaDpMLG9uU3RyZWFtTXVsdGlUb3VjaDpELG9uU3RyZWFtQnV0dG9uOlcsc3Vic2NyaWJlRnJhbWU6US5zdWJzY3JpYmVGcmFtZSxzdHJlYW1GcmFtZTpRLmZyYW1lLHN0cmVhbUNvbmZpZzpRLmNvbmZpZ30pfSksJCgiZGl2Iix7c3R5bGU6e3Bvc2l0aW9uOiJhYnNvbHV0ZSIsaW5zZXQ6MCxwb2ludGVyRXZlbnRzOiJub25lIix6SW5kZXg6MTB9LGNoaWxkcmVuOiQoaDAse3R5cGU6ImlwaG9uZSIsc3RyZWFtaW5nOll9KX0pXX0pLCQoImRpdiIse3N0eWxlOkowLmJhcixjaGlsZHJlbjokKCJzcGFuIix7c3R5bGU6ey4uLkowLmxpdmUsY29sb3I6WT8iIzRhZGU4MCI6IiM2NjYifSxjaGlsZHJlbjpbJCgic3BhbiIse3N0eWxlOnsuLi5KMC5kb3QsYmFja2dyb3VuZDpZPyIjNGFkZTgwIjoiIzY2NiJ9fSksWT8ibGl2ZSI6ImNvbm5lY3RpbmciXX0pfSldfSl9dmFyIEowPXtwYWdlOntkaXNwbGF5OiJmbGV4IixmbGV4RGlyZWN0aW9uOiJjb2x1bW4iLGFsaWduSXRlbXM6ImNlbnRlciIsanVzdGlmeUNvbnRlbnQ6ImNlbnRlciIsaGVpZ2h0OiIxMDB2aCIsYmFja2dyb3VuZDoiIzBhMGEwYSIscGFkZGluZzoyNCxnYXA6MTIsZm9udEZhbWlseToiLWFwcGxlLXN5c3RlbSwgc3lzdGVtLXVpLCBzYW5zLXNlcmlmIn0sYmFyOntkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDoxMCxmb250U2l6ZToxMixmb250RmFtaWx5OiJ1aS1tb25vc3BhY2UsIG1vbm9zcGFjZSIsY29sb3I6IiM2NjYifSxsaXZlOntkaXNwbGF5OiJmbGV4IixhbGlnbkl0ZW1zOiJjZW50ZXIiLGdhcDo1LHRyYW5zaXRpb246ImNvbG9yIDAuM3MifSxkb3Q6e3dpZHRoOjYsaGVpZ2h0OjYsYm9yZGVyUmFkaXVzOiI1MCUiLHRyYW5zaXRpb246ImJhY2tncm91bmQgMC4zcyJ9LGVtcHR5OntkaXNwbGF5OiJmbGV4IixmbGV4RGlyZWN0aW9uOiJjb2x1bW4iLGFsaWduSXRlbXM6ImNlbnRlciIsZ2FwOjEyLHRleHRBbGlnbjoiY2VudGVyIn0sZW1wdHlUaXRsZTp7Zm9udFNpemU6MTgsbWFyZ2luOjAsY29sb3I6IiNlZWUifSxlbXB0eUhpbnQ6e2NvbG9yOiIjODg4Iixmb250U2l6ZToxNCxtYXhXaWR0aDo0ODB9LGNvZGU6e2JhY2tncm91bmQ6IiMyMjIiLHBhZGRpbmc6IjJweCA2cHgiLGJvcmRlclJhZGl1czo0LGZvbnRTaXplOjEzfX07SDUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJvb3QiKSkucmVuZGVyKCQobTYse30pKTsKPC9zY3JpcHQ+CjwvYm9keT48L2h0bWw+","base64").toString("utf-8");return V}function ge(e){let _=(e?.basePath??"/.sim").replace(/\/+$/,"");return(t,C,S)=>{let A=t.url??"";if(A===_||A===_+"/"){let i=N()[0]??null,r=le();if(i){let R=`<script>window.__SIM_PREVIEW__=${JSON.stringify({...i,logsEndpoint:_+"/logs"})}</script>`;r=r.replace("<!--__SIM_PREVIEW_CONFIG__-->",R)}C.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),C.end(r);return}if(A===_+"/api"){let B=N();C.writeHead(200,{"Content-Type":"application/json","Cache-Control":"no-store"}),C.end(JSON.stringify(B[0]||null));return}if(A===_+"/logs"||A.startsWith(_+"/logs?")){let B=N();if(B.length===0){C.writeHead(404),C.end("No serve-sim device");return}let i=B[0].device;C.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}),C.write(`:
|
|
4
|
+
|
|
5
|
+
`);let r=Te("xcrun",["simctl","spawn",i,"log","stream","--style","ndjson","--level","info"],{stdio:["ignore","pipe","ignore"]}),s="";r.stdout.on("data",(R)=>{s+=R.toString();let D;while((D=s.indexOf(`
|
|
6
|
+
`))!==-1){let o=s.slice(0,D).trim();if(s=s.slice(D+1),o)C.write("data: "+o+`
|
|
7
|
+
|
|
8
|
+
`)}}),r.on("close",()=>C.end()),t.on("close",()=>r.kill());return}if(S)S()}}var k,V=null;var K=ce(()=>{k=P(ue(),"serve-sim")});import{execSync as y,spawn as x}from"child_process";import{chmodSync as Fe,existsSync as u,mkdirSync as j,openSync as J,closeSync as Q,readFileSync as v,unlinkSync as L,writeFileSync as Z}from"fs";import{createHash as de}from"crypto";import{homedir as we,networkInterfaces as Oe}from"os";import{join as ve,resolve as W}from"path";import{tmpdir as be}from"os";import{join as g}from"path";import{readdirSync as he}from"fs";var b=g(be(),"serve-sim"),Ze=g(b,"server.json");function F(e){return g(b,`server-${e}.json`)}function d(){try{return he(b).filter((e)=>e.startsWith("server-")&&e.endsWith(".json")).map((e)=>g(b,e))}catch{return[]}}var T="./serve-sim-bin-pwrv9qme.";function q(){if(!u(b))j(b,{recursive:!0})}function p(e){if(e)return M(F(e));for(let _ of d()){let t=M(_);if(t)return t}return null}function M(e){try{if(!u(e))return null;let _=JSON.parse(v(e,"utf-8"));try{return process.kill(_.pid,0),_}catch{return L(e),null}}catch{return null}}function m(){let e=[];for(let _ of d()){let t=M(_);if(t)e.push(t)}return e}function X(e){q(),Z(F(e.device),JSON.stringify(e,null,2))}function l(e){if(e)try{L(F(e))}catch{}else for(let _ of d())try{L(_)}catch{}}function me(){let e=T.startsWith("/$bunfs/");if(!e&&u(T))return T;if(!e){let A=W(import.meta.dir,"../bin/serve-sim-bin");if(u(A))return A;throw Error(`serve-sim-bin not found. Run 'bun run build:swift' first.
|
|
9
|
+
Checked: ${T}, ${A}`)}let _=v(T),t=de("sha256").update(_).digest("hex").slice(0,16),C=W(we(),"Library/Caches/serve-sim");j(C,{recursive:!0});let S=W(C,`serve-sim-bin-${t}`);if(!u(S)){Z(S,_),Fe(S,493);try{y(`codesign -s - -f ${JSON.stringify(S)}`,{stdio:"ignore"})}catch{}}return S}function Y(){try{let e=y("xcrun simctl list devices booted -j",{encoding:"utf-8"}),_=JSON.parse(e);for(let t of Object.values(_.devices))for(let C of t)if(C.state==="Booted")return C.udid}catch{}return null}function z(e){try{let _=y("xcrun simctl list devices -j",{encoding:"utf-8"}),t=JSON.parse(_);for(let C of Object.values(t.devices))for(let S of C)if(S.udid===e)return S.name}catch{}return null}function E(e){if(/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i.test(e))return e;try{let _=y("xcrun simctl list devices -j",{encoding:"utf-8"}),t=JSON.parse(_);for(let C of Object.values(t.devices))for(let S of C)if(S.name.toLowerCase()===e.toLowerCase())return S.udid}catch{}console.error(`Could not resolve device: ${e}`),process.exit(1)}function ee(e){try{let _=y("xcrun simctl list devices -j",{encoding:"utf-8"}),t=JSON.parse(_);for(let C of Object.values(t.devices))for(let S of C)if(S.udid===e)return S.state==="Booted"}catch{}return!1}function I(e){try{return process.kill(e,0),!0}catch{return!1}}function G(e){try{process.kill(e,"SIGTERM")}catch{return}let _=Date.now()+500;while(Date.now()<_)try{process.kill(e,0),Bun.sleepSync(25)}catch{return}try{process.kill(e,"SIGKILL")}catch{}let t=Date.now()+500;while(Date.now()<t)try{process.kill(e,0),Bun.sleepSync(25)}catch{return}}function Ee(e){try{let _=y(`lsof -ti tcp:${e}`,{encoding:"utf-8",stdio:"pipe"}).trim();if(!_)return[];let t=process.pid;return _.split(`
|
|
10
|
+
`).map((C)=>parseInt(C,10)).filter((C)=>Number.isFinite(C)&&C!==t)}catch{return[]}}function Ne(e){let _=Ee(e);if(_.length===0)return;console.log(`\x1B[90mPort ${e} busy, killing holder pid(s): ${_.join(", ")}\x1B[0m`);for(let t of _)try{process.kill(t,"SIGKILL")}catch{}Bun.sleepSync(100)}function Ve(e){if(!ee(e))try{y(`xcrun simctl boot ${e}`,{encoding:"utf-8",stdio:"pipe"})}catch(_){let t=(_.stderr??_.message??"").toLowerCase();if(!t.includes("booted")&&!t.includes("current state"))throw Error(`Failed to boot device ${e}: ${_.stderr||_.message}`)}try{y("open -ga Simulator",{encoding:"utf-8",stdio:"pipe",timeout:3000})}catch{}}function We(){let e=Oe();for(let _ of Object.values(e))for(let t of _??[])if(t.family==="IPv4"&&!t.internal)return t.address;return null}async function _e(e){let _=new Set(m().map((t)=>t.port));for(let t=e;t<e+100;t++){if(_.has(t))continue;try{return Bun.serve({port:t,fetch:()=>new Response("ok")}).stop(!0),t}catch{continue}}throw Error(`No available port found in range ${e}-${e+99}`)}async function Le(e){Ve(e);try{y(`xcrun simctl bootstatus ${e} -b`,{encoding:"utf-8",stdio:"pipe",timeout:60000})}catch(_){if(!ee(e))console.error(`Device ${e} failed to reach booted state: ${_.stderr||_.message}`),process.exit(1)}}async function te(e,_,t,C){let S=!1;for(let B=0;B<30;B++){if(!C())break;try{if((await fetch(`${_}/health`)).ok){S=!0;break}}catch{}await new Promise((i)=>setTimeout(i,100))}if(S){let B=Date.now()+8000;while(Date.now()<B){if(await new Promise((i)=>setTimeout(i,200)),!C()){S=!1;break}try{if(v(t,"utf-8").includes("Capture started"))break}catch{}}}let A="";try{A=v(t,"utf-8").trim()}catch{}return{ready:S,log:A}}async function Me(e){let{helperPath:_,udid:t,port:C,host:S,logFile:A}=e,B=`http://${S}:${C}`;q();let i=J(A,"w"),r=x(_,[t,"--port",String(C)],{detached:!0,stdio:["ignore",i,i]});r.unref(),Q(i);let s=r.pid,R=!1;r.once("exit",()=>{R=!0});let{ready:D,log:o}=await te(s,B,A,()=>!R&&I(s));return{ready:D,pid:s,exited:R||!I(s),log:o}}async function Ie(e){let{helperPath:_,udid:t,port:C,host:S,logFile:A}=e,B=`http://${S}:${C}`;q();let i=J(A,"w"),r=x(_,[t,"--port",String(C)],{detached:!1,stdio:["ignore",i,i]});Q(i);let s=r.pid,R=!1;r.once("exit",()=>{R=!0});let{ready:D,log:o}=await te(s,B,A,()=>!R&&I(s));return{ready:D,child:r,log:o}}async function Ce(e,_,t){await Le(e);let C="127.0.0.1",S=me(),A=ve(b,`server-${e}.log`),B={helperPath:S,udid:e,port:_,host:C,logFile:A},i="",r=2;for(let R=1;R<=r;R++){if(Ne(_),t.detach){let D=await Me(B);if(D.ready){let o={pid:D.pid,port:_,device:e,url:`http://${C}:${_}`,streamUrl:`http://${C}:${_}/stream.mjpeg`,wsUrl:`ws://${C}:${_}/ws`};return X(o),{pid:D.pid}}G(D.pid),i=D.log}else{let D=await Ie(B);if(D.ready){let o={pid:D.child.pid,port:_,device:e,url:`http://${C}:${_}`,streamUrl:`http://${C}:${_}/stream.mjpeg`,wsUrl:`ws://${C}:${_}/ws`};return X(o),{pid:D.child.pid,child:D.child}}G(D.child.pid),i=D.log}if(R<r)await new Promise((D)=>setTimeout(D,500))}let s=i?`Helper failed:
|
|
11
|
+
${i}`:"Helper process failed to start";console.error(s),process.exit(1)}async function Ge(e,_,t){let C=e.length>0?e.map(E):(()=>{let s=Y();if(!s)console.error("No device specified and no booted simulator found."),process.exit(1);return[s]})(),S=new Map,A=[],B=_;for(let s of C){let R=p(s);if(R){if(!t){let c=z(s)??s;if(C.length>1)console.log(`
|
|
12
|
+
==> ${c} (${s}) <==`);console.log(` Already running on port ${R.port}`),console.log(` Stream: ${R.streamUrl}`),console.log(` WebSocket: ${R.wsUrl}`)}A.push(R);continue}B=await _e(B);let{pid:D,child:o}=await Ce(s,B,{detach:!1});if(o)S.set(s,o);let H="127.0.0.1",h={pid:D,port:B,device:s,url:`http://${H}:${B}`,streamUrl:`http://${H}:${B}/stream.mjpeg`,wsUrl:`ws://${H}:${B}/ws`};if(A.push(h),!t){let c=z(s)??s;if(C.length>1)console.log(`
|
|
13
|
+
==> ${c} (${s}) <==`);console.log(` Stream: ${h.streamUrl}`),console.log(` WebSocket: ${h.wsUrl}`),console.log(` Port: ${B}`)}B++}if(A.length===1){let s=A[0];console.log(JSON.stringify({url:s.url,streamUrl:s.streamUrl,wsUrl:s.wsUrl,port:s.port,device:s.device}))}else console.log(JSON.stringify({devices:A.map((s)=>({url:s.url,streamUrl:s.streamUrl,wsUrl:s.wsUrl,port:s.port,device:s.device}))}));if(S.size===0)return;let i=!1,r=(s)=>{if(i)return;if(i=!0,!t)console.log(`
|
|
14
|
+
Shutting down...`);for(let[R,D]of S){let o=D.pid;if(o)G(o);l(R)}S.clear(),process.exit(s)};for(let[s,R]of S)R.on("exit",(D)=>{if(i)return;if(!t)console.error(`[${s}] Helper exited (code ${D})`);if(l(s),S.delete(s),S.size===0)r(D??1)});process.on("SIGINT",()=>r(0)),process.on("SIGTERM",()=>r(0)),process.on("SIGHUP",()=>r(0)),process.on("exit",()=>{for(let[s,R]of S){try{if(R.pid)process.kill(R.pid,"SIGTERM")}catch{}try{l(s)}catch{}}}),await new Promise(()=>{})}async function se(e,_){let t=e.length>0?e.map(E):(()=>{let A=Y();if(!A)console.error("No device specified and no booted simulator found."),process.exit(1);return[A]})(),C=[],S=_;for(let A of t){let B=p(A);if(B){C.push(B);continue}S=await _e(S),await Ce(A,S,{detach:!0});let i="127.0.0.1";C.push({pid:p(A).pid,port:S,device:A,url:`http://${i}:${S}`,streamUrl:`http://${i}:${S}/stream.mjpeg`,wsUrl:`ws://${i}:${S}/ws`}),S++}return C}function qe(e){if(e.length===1){let _=e[0];console.log(JSON.stringify({url:_.url,streamUrl:_.streamUrl,wsUrl:_.wsUrl,port:_.port,device:_.device}))}else console.log(JSON.stringify({devices:e.map((_)=>({url:_.url,streamUrl:_.streamUrl,wsUrl:_.wsUrl,port:_.port,device:_.device}))}))}function ke(e){if(e){let t=E(e),C=p(t);if(!C)console.log(JSON.stringify({running:!1,device:t}));else console.log(JSON.stringify({running:!0,url:C.url,streamUrl:C.streamUrl,wsUrl:C.wsUrl,port:C.port,device:C.device,pid:C.pid}));return}let _=m();if(_.length===0)console.log(JSON.stringify({running:!1}));else if(_.length===1){let t=_[0];console.log(JSON.stringify({running:!0,url:t.url,streamUrl:t.streamUrl,wsUrl:t.wsUrl,port:t.port,device:t.device,pid:t.pid}))}else console.log(JSON.stringify({running:!0,streams:_.map((t)=>({url:t.url,streamUrl:t.streamUrl,wsUrl:t.wsUrl,port:t.port,device:t.device,pid:t.pid}))}))}function Pe(e){if(e){let _=E(e),t=p(_);if(!t){console.log(JSON.stringify({disconnected:!0,device:_}));return}try{process.kill(t.pid,"SIGTERM")}catch{}l(_),console.log(JSON.stringify({disconnected:!0,device:t.device}))}else{let _=m();if(_.length===0){console.log(JSON.stringify({disconnected:!0,devices:[]}));return}let t=[];for(let C of _){try{process.kill(C.pid,"SIGTERM")}catch{}t.push(C.device)}l(),console.log(JSON.stringify({disconnected:!0,devices:t}))}}async function Ue(e){let _,t=[];for(let B=0;B<e.length;B++)if(e[B]==="--device"||e[B]==="-d")_=e[++B];else t.push(e[B]);let C=p(_);if(!C)console.error("No serve-sim server running. Run `serve-sim` first."),process.exit(1);let S=t[0];if(!S)console.error("Usage: serve-sim gesture '<json>'"),console.error(`Example: serve-sim gesture '{"type":"begin","x":0.5,"y":0.5}'`),process.exit(1);let A;try{A=JSON.parse(S)}catch{console.error("Invalid JSON:",S),process.exit(1)}return new Promise((B,i)=>{let r=new WebSocket(C.wsUrl);r.binaryType="arraybuffer",r.onopen=()=>{let s=new TextEncoder().encode(JSON.stringify(A)),R=new Uint8Array(1+s.length);R[0]=3,R.set(s,1),r.send(R),setTimeout(()=>{r.close(),B()},50)},r.onerror=()=>{console.error("Failed to connect to serve-sim server at",C.wsUrl),i(Error("WebSocket connection failed"))}})}async function Ke(e){let _,t=[];for(let A=0;A<e.length;A++)if(e[A]==="--device"||e[A]==="-d")_=e[++A];else t.push(e[A]);let C=p(_);if(!C)console.error("No serve-sim server running. Run `serve-sim` first."),process.exit(1);let S=t[0]??"home";return new Promise((A,B)=>{let i=new WebSocket(C.wsUrl);i.binaryType="arraybuffer",i.onopen=()=>{let r=new TextEncoder().encode(JSON.stringify({button:S})),s=new Uint8Array(1+r.length);s[0]=4,s.set(r,1),i.send(s),setTimeout(()=>{i.close(),A()},50)},i.onerror=()=>{console.error("Failed to connect to serve-sim server at",C.wsUrl),B(Error("WebSocket connection failed"))}})}async function Xe(e,_){if(m().length===0)console.log("Starting simulator stream..."),await se(_,3100);let{simMiddleware:C}=await Promise.resolve().then(() => (K(),U)),S=C({basePath:"/"});Bun.serve({port:e,idleTimeout:255,async fetch(B){return new Promise((i)=>{let r=new URL(B.url),s={url:r.pathname+r.search,method:B.method,headers:Object.fromEntries(B.headers.entries()),on(n,$){}},R=[];s.on=(n,$)=>{if(n==="close")R.push($)},B.signal.addEventListener("abort",()=>{for(let n of R)n()});let D=200,o=new Headers,H=[],h=!1,c=null;S(s,{writeHead(n,$){if(D=n,$)for(let[f,ae]of Object.entries($))o.set(f,ae)},setHeader(n,$){o.set(n,$)},get statusCode(){return D},set statusCode(n){D=n},write(n){if(!h){h=!0;let $=new ReadableStream({start(f){c=f}});i(new Response($,{status:D,headers:o}))}try{c?.enqueue(typeof n==="string"?new TextEncoder().encode(n):n)}catch{}},end(n){if(h){if(n)try{c?.enqueue(typeof n==="string"?new TextEncoder().encode(n):n)}catch{}try{c?.close()}catch{}}else{if(n)H.push(n);let $=H.map((f)=>typeof f==="string"?f:new TextDecoder().decode(f)).join("");i(new Response($,{status:D,headers:o}))}}},()=>{i(new Response("Not found",{status:404}))})})}});let A=We();if(console.log(""),console.log(` - Local: http://localhost:${e}`),A)console.log(` - Network: http://${A}:${e}`);console.log(""),process.on("SIGINT",()=>process.exit(0)),process.on("SIGTERM",()=>process.exit(0)),await new Promise(()=>{})}function Se(){console.log(`
|
|
15
|
+
serve-sim - Stream iOS Simulator to the browser
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
serve-sim [device...] Start preview server (default: localhost:3200)
|
|
19
|
+
serve-sim --no-preview [device...] Stream in foreground without a preview server
|
|
20
|
+
serve-sim gesture '<json>' [-d udid] Send a touch gesture
|
|
21
|
+
serve-sim button [name] [-d udid] Send a button press (default: home)
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
-p, --port <port> Starting port (preview default: 3200, stream default: 3100)
|
|
25
|
+
-d, --detach Spawn helper and exit (daemon mode)
|
|
26
|
+
-q, --quiet Suppress human-readable output, JSON only
|
|
27
|
+
--no-preview Skip the web preview server; stream in foreground only
|
|
28
|
+
--list [device] List running streams
|
|
29
|
+
--kill [device] Kill running stream(s)
|
|
30
|
+
-h, --help Show this help
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
serve-sim Open simulator preview at localhost:3200
|
|
34
|
+
serve-sim -p 8080 Preview on a custom port
|
|
35
|
+
serve-sim --no-preview Auto-detect booted sim, stream in foreground
|
|
36
|
+
serve-sim --no-preview "iPhone 16 Pro" Stream a specific device (no preview)
|
|
37
|
+
serve-sim --detach Start streaming in background (daemon)
|
|
38
|
+
serve-sim --list Show all running streams
|
|
39
|
+
serve-sim --kill Stop all streams
|
|
40
|
+
`)}var a=process.argv.slice(2);if(a[0]==="gesture")await Ue(a.slice(1)),process.exit(0);if(a[0]==="button")await Ke(a.slice(1)),process.exit(0);var w,Ae=!1,Be=!1,ie=!1,re=!1,De=!1,Re=!1,O=[],oe,ne;for(let e=0;e<a.length;e++){let _=a[e];switch(_){case"--port":case"-p":w=parseInt(a[++e]??"3100",10);break;case"--detach":case"-d":Ae=!0;break;case"--quiet":case"-q":Be=!0;break;case"--no-preview":Re=!0;break;case"--list":case"-l":if(ie=!0,a[e+1]&&!a[e+1].startsWith("-"))oe=a[++e];break;case"--kill":case"-k":if(re=!0,a[e+1]&&!a[e+1].startsWith("-"))ne=a[++e];break;case"--help":case"-h":case"help":De=!0;break;default:if(!_.startsWith("-"))O.push(_);else console.error(`Unknown flag: ${_}`),Se(),process.exit(1)}}if(De)Se(),process.exit(0);if(ie)ke(oe),process.exit(0);if(re)Pe(ne),process.exit(0);if(Ae){let e=await se(O,w??3100);qe(e)}else if(Re)await Ge(O,w??3100,Be);else await Xe(w??3200,O);
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "serve-sim",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"serve-sim": "dist/serve-sim.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist/serve-sim.js",
|
|
10
|
+
"dist/middleware.js",
|
|
11
|
+
"dist/middleware.cjs",
|
|
12
|
+
"src/middleware.ts",
|
|
13
|
+
"src/state.ts",
|
|
14
|
+
"bin/serve-sim-bin"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
"./middleware": {
|
|
18
|
+
"require": "./dist/middleware.cjs",
|
|
19
|
+
"import": "./dist/middleware.js",
|
|
20
|
+
"types": "./src/middleware.ts"
|
|
21
|
+
},
|
|
22
|
+
"./state": {
|
|
23
|
+
"import": "./src/state.ts",
|
|
24
|
+
"types": "./src/state.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "bun run build.ts",
|
|
29
|
+
"build:swift": "./build.sh",
|
|
30
|
+
"dev": "bun run dev.ts"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/bun": "latest",
|
|
34
|
+
"mac-mini-client": "workspace:*",
|
|
35
|
+
"preact": "^10.29.1",
|
|
36
|
+
"react": "^19.0.0",
|
|
37
|
+
"react-dom": "^19.0.0",
|
|
38
|
+
"typescript": "^5.7.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "fs";
|
|
2
|
+
import { spawn, type ChildProcess } from "child_process";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
|
|
6
|
+
// Injected at build time as a base64-encoded string via `define`
|
|
7
|
+
declare const __PREVIEW_HTML_B64__: string;
|
|
8
|
+
const STATE_DIR = join(tmpdir(), "serve-sim");
|
|
9
|
+
|
|
10
|
+
interface ServeSimState {
|
|
11
|
+
pid: number;
|
|
12
|
+
port: number;
|
|
13
|
+
device: string;
|
|
14
|
+
url: string;
|
|
15
|
+
streamUrl: string;
|
|
16
|
+
wsUrl: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function readServeSimStates(): ServeSimState[] {
|
|
20
|
+
let files: string[];
|
|
21
|
+
try {
|
|
22
|
+
files = readdirSync(STATE_DIR).filter(
|
|
23
|
+
(f) => f.startsWith("server-") && f.endsWith(".json"),
|
|
24
|
+
);
|
|
25
|
+
} catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const states: ServeSimState[] = [];
|
|
29
|
+
for (const f of files) {
|
|
30
|
+
try {
|
|
31
|
+
const state: ServeSimState = JSON.parse(readFileSync(join(STATE_DIR, f), "utf-8"));
|
|
32
|
+
try {
|
|
33
|
+
process.kill(state.pid, 0);
|
|
34
|
+
states.push(state);
|
|
35
|
+
} catch {}
|
|
36
|
+
} catch {}
|
|
37
|
+
}
|
|
38
|
+
return states;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let _html: string | null = null;
|
|
42
|
+
function loadHtml(): string {
|
|
43
|
+
if (!_html) {
|
|
44
|
+
_html = Buffer.from(__PREVIEW_HTML_B64__, "base64").toString("utf-8");
|
|
45
|
+
}
|
|
46
|
+
return _html;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface SimMiddlewareOptions {
|
|
50
|
+
/** Base path to serve the preview at. Default: "/.sim" */
|
|
51
|
+
basePath?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Connect-style middleware that serves the simulator preview UI.
|
|
56
|
+
*
|
|
57
|
+
* Routes handled under `basePath` (default `/.sim`):
|
|
58
|
+
* GET {basePath} — the preview HTML page
|
|
59
|
+
* GET {basePath}/api — serve-sim state JSON
|
|
60
|
+
* GET {basePath}/logs — SSE stream of simctl logs
|
|
61
|
+
*/
|
|
62
|
+
export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
63
|
+
const base = (options?.basePath ?? "/.sim").replace(/\/+$/, "");
|
|
64
|
+
|
|
65
|
+
return (req: any, res: any, next?: () => void) => {
|
|
66
|
+
const url: string = req.url ?? "";
|
|
67
|
+
|
|
68
|
+
// Serve the preview page
|
|
69
|
+
if (url === base || url === base + "/") {
|
|
70
|
+
const states = readServeSimStates();
|
|
71
|
+
const state = states[0] ?? null;
|
|
72
|
+
let html = loadHtml();
|
|
73
|
+
|
|
74
|
+
if (state) {
|
|
75
|
+
// Pass real serve-sim URLs directly. The client parses the MJPEG
|
|
76
|
+
// stream via fetch() (CORS is fine — serve-sim sends Access-Control-Allow-Origin: *)
|
|
77
|
+
// and connects to the WS directly (WS has no CORS).
|
|
78
|
+
const config = JSON.stringify({
|
|
79
|
+
...state,
|
|
80
|
+
logsEndpoint: base + "/logs",
|
|
81
|
+
});
|
|
82
|
+
const configScript = `<script>window.__SIM_PREVIEW__=${config}</script>`;
|
|
83
|
+
html = html.replace("<!--__SIM_PREVIEW_CONFIG__-->", configScript);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
res.writeHead(200, {
|
|
87
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
88
|
+
"Cache-Control": "no-store",
|
|
89
|
+
});
|
|
90
|
+
res.end(html);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// JSON API: serve-sim state
|
|
95
|
+
if (url === base + "/api") {
|
|
96
|
+
const states = readServeSimStates();
|
|
97
|
+
res.writeHead(200, {
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
"Cache-Control": "no-store",
|
|
100
|
+
});
|
|
101
|
+
res.end(JSON.stringify(states[0] || null));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// SSE: simctl log stream
|
|
106
|
+
if (url === base + "/logs" || url.startsWith(base + "/logs?")) {
|
|
107
|
+
const states = readServeSimStates();
|
|
108
|
+
if (states.length === 0) {
|
|
109
|
+
res.writeHead(404);
|
|
110
|
+
res.end("No serve-sim device");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const udid = states[0].device;
|
|
114
|
+
res.writeHead(200, {
|
|
115
|
+
"Content-Type": "text/event-stream",
|
|
116
|
+
"Cache-Control": "no-cache",
|
|
117
|
+
Connection: "keep-alive",
|
|
118
|
+
"X-Accel-Buffering": "no",
|
|
119
|
+
});
|
|
120
|
+
res.write(":\n\n");
|
|
121
|
+
|
|
122
|
+
const child: ChildProcess = spawn("xcrun", [
|
|
123
|
+
"simctl", "spawn", udid, "log", "stream",
|
|
124
|
+
"--style", "ndjson",
|
|
125
|
+
"--level", "info",
|
|
126
|
+
], { stdio: ["ignore", "pipe", "ignore"] });
|
|
127
|
+
|
|
128
|
+
let buf = "";
|
|
129
|
+
child.stdout!.on("data", (chunk: Buffer) => {
|
|
130
|
+
buf += chunk.toString();
|
|
131
|
+
let nl: number;
|
|
132
|
+
while ((nl = buf.indexOf("\n")) !== -1) {
|
|
133
|
+
const line = buf.slice(0, nl).trim();
|
|
134
|
+
buf = buf.slice(nl + 1);
|
|
135
|
+
if (line) res.write("data: " + line + "\n\n");
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
child.on("close", () => res.end());
|
|
140
|
+
req.on("close", () => child.kill());
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Not ours — pass through
|
|
145
|
+
if (next) next();
|
|
146
|
+
};
|
|
147
|
+
}
|
package/src/state.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { tmpdir } from "os";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { readdirSync } from "fs";
|
|
4
|
+
|
|
5
|
+
/** Directory where serve-sim stores runtime state. */
|
|
6
|
+
export const STATE_DIR = join(tmpdir(), "serve-sim");
|
|
7
|
+
|
|
8
|
+
/** Path to the serve-sim server state file (JSON with pid, port, URLs).
|
|
9
|
+
* @deprecated Use `stateFileForDevice(udid)` for multi-device support. Kept for backward compat. */
|
|
10
|
+
export const STATE_FILE = join(STATE_DIR, "server.json");
|
|
11
|
+
|
|
12
|
+
/** Per-device state file: `/tmp/serve-sim/server-{udid}.json` */
|
|
13
|
+
export function stateFileForDevice(udid: string): string {
|
|
14
|
+
return join(STATE_DIR, `server-${udid}.json`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** List all per-device state files in the state directory. */
|
|
18
|
+
export function listStateFiles(): string[] {
|
|
19
|
+
try {
|
|
20
|
+
return readdirSync(STATE_DIR)
|
|
21
|
+
.filter((f) => f.startsWith("server-") && f.endsWith(".json"))
|
|
22
|
+
.map((f) => join(STATE_DIR, f));
|
|
23
|
+
} catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|