BNO ILR Continuous Residence Checker
Check whether you meet the 5-year continuous residence requirement to apply for Indefinite Leave to Remain under the Hong Kong BN(O) route.
1
Your BNO Leave Details
📅
e.g. 31/01/2021
📅
e.g. 31/01/2026
Your qualifying period is 5 years from the date your BNO leave was first granted. You can apply up to 28 days before completing 5 years.
2
Travel History (Absences from the UK)
Enter every trip outside the UK during your qualifying period. Include the date you left and the date you returned. Only whole days absent are counted (departure and return days are not counted).
3
Other ILR Requirements
✓
Eligibility Checklist
Residence Timeline
In the UK Absent from the UK
Rolling 12-Month Absence Analysis
The table below shows the maximum number of whole days absent within any rolling 12-month window during your qualifying period. You must not exceed 180 days in any such period.
| 12-Month Window Start | 12-Month Window End | Days Absent | Status |
|---|
Important Disclaimer:
This tool provides a preliminary assessment only and does not constitute legal advice. Immigration Rules are subject to change. For a full eligibility assessment tailored to your individual circumstances, please contact Dual HK UK Legal Services.
KGZ1bmN0aW9uKCkgewoKLy8gPT09PT09PT09PT09PT09PT09PT0gTEFOR1VBR0UgPT09PT09PT09PT09PT09PT09PT0KbGV0IGN1cnJlbnRMYW5nID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKS5nZXQoJ2xhbmcnKSA9PT0gJ3poJyA/ICd6aCcgOiAnZW4nOwoKY29uc3QgTU9OVEhTX0VOID0gWydKYW51YXJ5JywnRmVicnVhcnknLCdNYXJjaCcsJ0FwcmlsJywnTWF5JywnSnVuZScsJ0p1bHknLCdBdWd1c3QnLCdTZXB0ZW1iZXInLCdPY3RvYmVyJywnTm92ZW1iZXInLCdEZWNlbWJlciddOwpjb25zdCBNT05USFNfRU5fU0hPUlQgPSBbJ0phbicsJ0ZlYicsJ01hcicsJ0FwcicsJ01heScsJ0p1bicsJ0p1bCcsJ0F1ZycsJ1NlcCcsJ09jdCcsJ05vdicsJ0RlYyddOwpjb25zdCBNT05USFNfWkggPSBbJzFcdTY3MDgnLCcyXHU2NzA4JywnM1x1NjcwOCcsJzRcdTY3MDgnLCc1XHU2NzA4JywnNlx1NjcwOCcsJzdcdTY3MDgnLCc4XHU2NzA4JywnOVx1NjcwOCcsJzEwXHU2NzA4JywnMTFcdTY3MDgnLCcxMlx1NjcwOCddOwoKZnVuY3Rpb24gc2V0TGFuZyhsYW5nKSB7CiAgY3VycmVudExhbmcgPSBsYW5nOwogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5sYW5nLWJ0bicpLmZvckVhY2goYnRuID0+IGJ0bi5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKSk7CiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmxhbmctYnRuJykuZm9yRWFjaChidG4gPT4gewogICAgaWYgKChsYW5nID09PSAnZW4nICYmIGJ0bi50ZXh0Q29udGVudCA9PT0gJ0VuZ2xpc2gnKSB8fCAobGFuZyA9PT0gJ3poJyAmJiBidG4udGV4dENvbnRlbnQgPT09ICdcdTdlNDFcdTlhZDRcdTRlMmRcdTY1ODcnKSkKICAgICAgYnRuLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpOwogIH0pOwogIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5sYW5nID0gbGFuZyA9PT0gJ3poJyA/ICd6aC1IYW50JyA6ICdlbic7CiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtJyArIGxhbmcgKyAnXScpLmZvckVhY2goZWwgPT4gewogICAgaWYgKGVsLnRhZ05hbWUgPT09ICdPUFRJT04nKSByZXR1cm47CiAgICAvLyBEb24ndCBvdmVyd3JpdGUgZGF0ZSBoaW50IGlmIGl0IGhhcyBzdWNjZXNzL2Vycm9yIHN0YXRlCiAgICBpZiAoZWwuY2xhc3NMaXN0ICYmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ3N1Y2Nlc3MnKSB8fCBlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2Vycm9yJykpKSByZXR1cm47CiAgICBlbC50ZXh0Q29udGVudCA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS0nICsgbGFuZyk7CiAgfSk7CiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc2VsZWN0IG9wdGlvbltkYXRhLScgKyBsYW5nICsgJ10nKS5mb3JFYWNoKG9wdCA9PiB7CiAgICBvcHQudGV4dENvbnRlbnQgPSBvcHQuZ2V0QXR0cmlidXRlKCdkYXRhLScgKyBsYW5nKTsKICB9KTsKCiAgLy8gUmUtdmFsaWRhdGUgZGF0ZSBpbnB1dHMgdG8gdXBkYXRlIGhpbnQgdGV4dCBpbiBuZXcgbGFuZ3VhZ2UKICBbJ2xlYXZlU3RhcnREYXRlJywgJ2FwcGxpY2F0aW9uRGF0ZSddLmZvckVhY2goaWQgPT4gewogICAgY29uc3QgdmFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnZhbHVlOwogICAgaWYgKHZhbCkgewogICAgICBjb25zdCBoaW50RWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCArICdIaW50Jyk7CiAgICAgIGlmIChoaW50RWwpIHsgaGludEVsLmNsYXNzTmFtZSA9ICdkYXRlLWhpbnQgc3VjY2Vzcyc7IGhpbnRFbC50ZXh0Q29udGVudCA9IGZvcm1hdERhdGVEaXNwbGF5KHZhbCk7IH0KICAgIH0KICB9KTsKCiAgcmVuZGVyVHJpcHMoKTsKfQoKZnVuY3Rpb24gdChlbiwgemgpIHsgcmV0dXJuIGN1cnJlbnRMYW5nID09PSAnemgnID8gemggOiBlbjsgfQoKZnVuY3Rpb24gZm9ybWF0RGF0ZURpc3BsYXkoaXNvU3RyKSB7CiAgaWYgKCFpc29TdHIpIHJldHVybiAnJzsKICBjb25zdCBkID0gbmV3IERhdGUoaXNvU3RyICsgJ1QwMDowMDowMCcpOwogIGNvbnN0IG1vbnRocyA9IGN1cnJlbnRMYW5nID09PSAnemgnID8gTU9OVEhTX1pIIDogTU9OVEhTX0VOOwogIGlmIChjdXJyZW50TGFuZyA9PT0gJ3poJykgewogICAgcmV0dXJuIGAke2QuZ2V0RnVsbFllYXIoKX1cdTVlNzQgJHttb250aHNbZC5nZXRNb250aCgpXX0gJHtkLmdldERhdGUoKX1cdTY1ZTVgOwogIH0KICByZXR1cm4gYCR7ZC5nZXREYXRlKCl9ICR7bW9udGhzW2QuZ2V0TW9udGgoKV19ICR7ZC5nZXRGdWxsWWVhcigpfWA7Cn0KCmZ1bmN0aW9uIGZvcm1hdERhdGUoZGF0ZSkgewogIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXRlKTsKICBjb25zdCBtb250aHMgPSBjdXJyZW50TGFuZyA9PT0gJ3poJyA/IE1PTlRIU19aSCA6IE1PTlRIU19FTl9TSE9SVDsKICBpZiAoY3VycmVudExhbmcgPT09ICd6aCcpIHsKICAgIHJldHVybiBgJHtkLmdldEZ1bGxZZWFyKCl9XHU1ZTc0ICR7bW9udGhzW2QuZ2V0TW9udGgoKV19ICR7ZC5nZXREYXRlKCl9XHU2NWU1YDsKICB9CiAgcmV0dXJuIGAke2QuZ2V0RGF0ZSgpfSAke21vbnRoc1tkLmdldE1vbnRoKCldfSAke2QuZ2V0RnVsbFllYXIoKX1gOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PSBBVVRPLUZPUk1BVCBEQVRFIElOUFVUID09PT09PT09PT09PT09PT09PT09CmZ1bmN0aW9uIGdldERheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKSB7CiAgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoICsgMSwgMCkuZ2V0RGF0ZSgpOwp9CgovKioKICogaW5pdERhdGVJbnB1dCBcdTIwMTQgYXR0YWNoIGF1dG8tZm9ybWF0IGJlaGF2aW91ciB0byBhIHRleHQgaW5wdXQuCiAqIEFzIHRoZSB1c2VyIHR5cGVzIGRpZ2l0cyB0aGUgZmllbGQgYXV0by1pbnNlcnRzICIgLyAiIHNlcGFyYXRvcnMKICogc28gdGhlIGRpc3BsYXkgcmVhZHMgIEREIC8gTU0gLyBZWVlZLiAgSXQgd3JpdGVzIHRoZSBJU08gdmFsdWUKICogKFlZWVktTU0tREQpIGludG8gdGhlIHBhaXJlZCBoaWRkZW4gaW5wdXQgYW5kIHNob3dzIGEgaGludC4KICoKICogQHBhcmFtIHtzdHJpbmd9IGlucHV0SWQgIFx1MjAxNCB2aXNpYmxlIHRleHQgaW5wdXQgaWQKICogQHBhcmFtIHtzdHJpbmd9IGhpZGRlbklkIFx1MjAxNCBoaWRkZW4gaW5wdXQgaWQgdGhhdCByZWNlaXZlcyBJU08gdmFsdWUKICogQHBhcmFtIHtzdHJpbmd9IGhpbnRJZCAgIFx1MjAxNCBoaW50IGRpdiBpZAogKi8KZnVuY3Rpb24gaW5pdERhdGVJbnB1dChpbnB1dElkLCBoaWRkZW5JZCwgaGludElkKSB7CiAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpbnB1dElkKTsKICBjb25zdCBoaWRkZW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChoaWRkZW5JZCk7CiAgY29uc3QgaGludCAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGludElkKTsKCiAgLy8gU3RyaXAgbm9uLWRpZ2l0cyBhbmQga2VlcCBvbmx5IHVwIHRvIDggZGlnaXRzCiAgZnVuY3Rpb24gZGlnaXRzT25seShzdHIpIHsgcmV0dXJuIHN0ci5yZXBsYWNlKC9cRC9nLCAnJykuc2xpY2UoMCwgOCk7IH0KCiAgLy8gRm9ybWF0IDggcmF3IGRpZ2l0cyBpbnRvICJERCAvIE1NIC8gWVlZWSIKICBmdW5jdGlvbiBmb3JtYXREaXNwbGF5KGRpZ2l0cykgewogICAgbGV0IG91dCA9ICcnOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWdpdHMubGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKGkgPT09IDIgfHwgaSA9PT0gNCkgb3V0ICs9ICcgLyAnOwogICAgICBvdXQgKz0gZGlnaXRzW2ldOwogICAgfQogICAgcmV0dXJuIG91dDsKICB9CgogIC8vIEdpdmVuIHJhdyBkaWdpdHMsIGZpZ3VyZSBjYXJldCBwb3NpdGlvbiBpbiBmb3JtYXR0ZWQgc3RyaW5nCiAgZnVuY3Rpb24gY2FyZXRGb3JEaWdpdEluZGV4KGlkeCkgewogICAgaWYgKGlkeCA8PSAyKSByZXR1cm4gaWR4OwogICAgaWYgKGlkeCA8PSA0KSByZXR1cm4gaWR4ICsgMzsgLy8gYWZ0ZXIgIiAvICIKICAgIHJldHVybiBpZHggKyA2OyAvLyBhZnRlciB0d28gIiAvICIKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlKGRpZ2l0cykgewogICAgaGlkZGVuLnZhbHVlID0gJyc7CiAgICBpbnB1dC5jbGFzc0xpc3QucmVtb3ZlKCd2YWxpZCcsICdpbnZhbGlkJyk7CiAgICBpZiAoaGludCkgeyBoaW50LmNsYXNzTmFtZSA9ICdkYXRlLWhpbnQnOyBoaW50LnRleHRDb250ZW50ID0gaGludC5nZXRBdHRyaWJ1dGUoJ2RhdGEtJyArIGN1cnJlbnRMYW5nKSB8fCBoaW50LmdldEF0dHJpYnV0ZSgnZGF0YS1lbicpIHx8ICcnOyB9CgogICAgaWYgKGRpZ2l0cy5sZW5ndGggPCA4KSByZXR1cm47CgogICAgY29uc3QgZGQgPSBwYXJzZUludChkaWdpdHMuc2xpY2UoMCwgMiksIDEwKTsKICAgIGNvbnN0IG1tID0gcGFyc2VJbnQoZGlnaXRzLnNsaWNlKDIsIDQpLCAxMCk7CiAgICBjb25zdCB5eXl5ID0gcGFyc2VJbnQoZGlnaXRzLnNsaWNlKDQsIDgpLCAxMCk7CgogICAgaWYgKG1tIDwgMSB8fCBtbSA+IDEyKSB7CiAgICAgIGlucHV0LmNsYXNzTGlzdC5hZGQoJ2ludmFsaWQnKTsKICAgICAgaWYgKGhpbnQpIHsgaGludC5jbGFzc05hbWUgPSAnZGF0ZS1oaW50IGVycm9yJzsgaGludC50ZXh0Q29udGVudCA9IHQoJ0ludmFsaWQgbW9udGgnLCAnXHU2NzA4XHU0ZWZkXHU3MTIxXHU2NTQ4Jyk7IH0KICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgbWF4RGF5ID0gZ2V0RGF5c0luTW9udGgobW0gLSAxLCB5eXl5KTsKICAgIGlmIChkZCA8IDEgfHwgZGQgPiBtYXhEYXkpIHsKICAgICAgaW5wdXQuY2xhc3NMaXN0LmFkZCgnaW52YWxpZCcpOwogICAgICBpZiAoaGludCkgeyBoaW50LmNsYXNzTmFtZSA9ICdkYXRlLWhpbnQgZXJyb3InOyBoaW50LnRleHRDb250ZW50ID0gdCgnSW52YWxpZCBkYXkgZm9yIHRoaXMgbW9udGgnLCAnXHU4YTcyXHU2NzA4XHU0ZWZkXHU3Njg0XHU2NWU1XHU2NzFmXHU3MTIxXHU2NTQ4Jyk7IH0KICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKHl5eXkgPCAyMDE5IHx8IHl5eXkgPiAyMDM2KSB7CiAgICAgIGlucHV0LmNsYXNzTGlzdC5hZGQoJ2ludmFsaWQnKTsKICAgICAgaWYgKGhpbnQpIHsgaGludC5jbGFzc05hbWUgPSAnZGF0ZS1oaW50IGVycm9yJzsgaGludC50ZXh0Q29udGVudCA9IHQoJ1llYXIgbXVzdCBiZSBiZXR3ZWVuIDIwMTkgYW5kIDIwMzYnLCAnXHU1ZTc0XHU0ZWZkXHU5ODA4XHU0ZWNiXHU0ZTRlIDIwMTkgXHU4MWYzIDIwMzYnKTsgfQogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3QgaXNvID0gYCR7eXl5eX0tJHtTdHJpbmcobW0pLnBhZFN0YXJ0KDIsJzAnKX0tJHtTdHJpbmcoZGQpLnBhZFN0YXJ0KDIsJzAnKX1gOwogICAgaGlkZGVuLnZhbHVlID0gaXNvOwogICAgaW5wdXQuY2xhc3NMaXN0LmFkZCgndmFsaWQnKTsKICAgIGlmIChoaW50KSB7IGhpbnQuY2xhc3NOYW1lID0gJ2RhdGUtaGludCBzdWNjZXNzJzsgaGludC50ZXh0Q29udGVudCA9IGZvcm1hdERhdGVEaXNwbGF5KGlzbyk7IH0KICB9CgogIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgZnVuY3Rpb24gKGUpIHsKICAgIGNvbnN0IHJhdyA9IGRpZ2l0c09ubHkodGhpcy52YWx1ZSk7CiAgICBjb25zdCBmb3JtYXR0ZWQgPSBmb3JtYXREaXNwbGF5KHJhdyk7CiAgICB0aGlzLnZhbHVlID0gZm9ybWF0dGVkOwogICAgLy8gUGxhY2UgY2FyZXQgYWZ0ZXIgdGhlIGxhc3QgdHlwZWQgZGlnaXQKICAgIGNvbnN0IHBvcyA9IGNhcmV0Rm9yRGlnaXRJbmRleChyYXcubGVuZ3RoKTsKICAgIHRoaXMuc2V0U2VsZWN0aW9uUmFuZ2UocG9zLCBwb3MpOwogICAgdmFsaWRhdGUocmF3KTsKICB9KTsKCiAgLy8gQWxsb3cgYXJyb3cga2V5cyBhbmQgYmFja3NwYWNlIHRvIHdvcmsgbmF0dXJhbGx5LCBhbmQgaGFuZGxlIHBhc3RlCiAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGZ1bmN0aW9uIChlKSB7CiAgICAvLyBBbGxvdzogYmFja3NwYWNlLCBkZWxldGUsIHRhYiwgZXNjYXBlLCBhcnJvd3MsIGhvbWUsIGVuZCwgc2VsZWN0LWFsbAogICAgaWYgKFs4LDksMjcsNDYsMzUsMzYsMzcsMzgsMzksNDBdLmluY2x1ZGVzKGUua2V5Q29kZSkgfHwgKGUuY3RybEtleSAmJiBlLmtleUNvZGUgPT09IDY1KSB8fCAoZS5tZXRhS2V5ICYmIGUua2V5Q29kZSA9PT0gNjUpKSByZXR1cm47CiAgICAvLyBBbGxvdyBwYXN0ZQogICAgaWYgKChlLmN0cmxLZXkgfHwgZS5tZXRhS2V5KSAmJiAoZS5rZXlDb2RlID09PSA4NiB8fCBlLmtleSA9PT0gJ3YnKSkgcmV0dXJuOwogICAgLy8gQmxvY2sgbm9uLWRpZ2l0IGtleXMKICAgIGlmICghL15cZCQvLnRlc3QoZS5rZXkpKSB7IGUucHJldmVudERlZmF1bHQoKTsgcmV0dXJuOyB9CiAgICAvLyBCbG9jayBpZiBhbHJlYWR5IDggZGlnaXRzCiAgICBjb25zdCByYXcgPSBkaWdpdHNPbmx5KHRoaXMudmFsdWUpOwogICAgaWYgKHJhdy5sZW5ndGggPj0gOCkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH0KICB9KTsKCiAgLy8gSGFuZGxlIHBhc3RlCiAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcigncGFzdGUnLCBmdW5jdGlvbiAoZSkgewogICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgY29uc3QgcGFzdGUgPSAoZS5jbGlwYm9hcmREYXRhIHx8IHdpbmRvdy5jbGlwYm9hcmREYXRhKS5nZXREYXRhKCd0ZXh0Jyk7CiAgICBjb25zdCByYXcgPSBkaWdpdHNPbmx5KHBhc3RlKTsKICAgIGNvbnN0IGZvcm1hdHRlZCA9IGZvcm1hdERpc3BsYXkocmF3KTsKICAgIHRoaXMudmFsdWUgPSBmb3JtYXR0ZWQ7CiAgICBjb25zdCBwb3MgPSBjYXJldEZvckRpZ2l0SW5kZXgocmF3Lmxlbmd0aCk7CiAgICB0aGlzLnNldFNlbGVjdGlvblJhbmdlKHBvcywgcG9zKTsKICAgIHZhbGlkYXRlKHJhdyk7CiAgfSk7CgogIC8vIFByZS1wb3B1bGF0ZSBpZiBoaWRkZW4gaW5wdXQgYWxyZWFkeSBoYXMgYSB2YWx1ZQogIGlmIChoaWRkZW4udmFsdWUpIHsKICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShoaWRkZW4udmFsdWUgKyAnVDAwOjAwOjAwJyk7CiAgICBjb25zdCByYXcgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsJzAnKSArIFN0cmluZyhkLmdldE1vbnRoKCkrMSkucGFkU3RhcnQoMiwnMCcpICsgU3RyaW5nKGQuZ2V0RnVsbFllYXIoKSk7CiAgICBpbnB1dC52YWx1ZSA9IGZvcm1hdERpc3BsYXkocmF3KTsKICAgIHZhbGlkYXRlKHJhdyk7CiAgfQp9CgovLyA9PT09PT09PT09PT09PT09PT09PSBUUklQIE1BTkFHRU1FTlQgPT09PT09PT09PT09PT09PT09PT0KbGV0IHRyaXBzID0gW107CmxldCB0cmlwSWRDb3VudGVyID0gMDsKCmZ1bmN0aW9uIGFkZFRyaXAoKSB7CiAgdHJpcHMucHVzaCh7IGlkOiB0cmlwSWRDb3VudGVyKyssIGRlcGFydHVyZTogJycsIHJldHVybjogJycgfSk7CiAgcmVuZGVyVHJpcHMoKTsKfQoKZnVuY3Rpb24gcmVtb3ZlVHJpcChpZCkgewogIHRyaXBzID0gdHJpcHMuZmlsdGVyKHQgPT4gdC5pZCAhPT0gaWQpOwogIHJlbmRlclRyaXBzKCk7Cn0KCi8vIFRyaXAgZGF0ZSBpbnB1dHMgd3JpdGUgYmFjayBpbnRvIHRoZSB0cmlwcyBhcnJheSB2aWEgYSBjaGFuZ2Ugd2F0Y2hlcgpmdW5jdGlvbiBpbml0VHJpcERhdGVJbnB1dChpbnB1dElkLCBoaWRkZW5JZCwgdHJpcElkLCBmaWVsZCkgewogIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5wdXRJZCk7CiAgY29uc3QgaGlkZGVuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGlkZGVuSWQpOwoKICBmdW5jdGlvbiBkaWdpdHNPbmx5KHN0cikgeyByZXR1cm4gc3RyLnJlcGxhY2UoL1xEL2csICcnKS5zbGljZSgwLCA4KTsgfQoKICBmdW5jdGlvbiBmb3JtYXREaXNwbGF5KGRpZ2l0cykgewogICAgbGV0IG91dCA9ICcnOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWdpdHMubGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKGkgPT09IDIgfHwgaSA9PT0gNCkgb3V0ICs9ICcgLyAnOwogICAgICBvdXQgKz0gZGlnaXRzW2ldOwogICAgfQogICAgcmV0dXJuIG91dDsKICB9CgogIGZ1bmN0aW9uIGNhcmV0Rm9yRGlnaXRJbmRleChpZHgpIHsKICAgIGlmIChpZHggPD0gMikgcmV0dXJuIGlkeDsKICAgIGlmIChpZHggPD0gNCkgcmV0dXJuIGlkeCArIDM7CiAgICByZXR1cm4gaWR4ICsgNjsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlKGRpZ2l0cykgewogICAgaGlkZGVuLnZhbHVlID0gJyc7CiAgICBpbnB1dC5jbGFzc0xpc3QucmVtb3ZlKCd2YWxpZCcsICdpbnZhbGlkJyk7CiAgICBpZiAoZGlnaXRzLmxlbmd0aCA8IDgpIHsgdXBkYXRlVHJpcEZpZWxkKHRyaXBJZCwgZmllbGQsICcnKTsgcmV0dXJuOyB9CiAgICBjb25zdCBkZCA9IHBhcnNlSW50KGRpZ2l0cy5zbGljZSgwLCAyKSwgMTApOwogICAgY29uc3QgbW0gPSBwYXJzZUludChkaWdpdHMuc2xpY2UoMiwgNCksIDEwKTsKICAgIGNvbnN0IHl5eXkgPSBwYXJzZUludChkaWdpdHMuc2xpY2UoNCwgOCksIDEwKTsKICAgIGlmIChtbSA8IDEgfHwgbW0gPiAxMiB8fCB5eXl5IDwgMjAxOSB8fCB5eXl5ID4gMjAzNikgeyBpbnB1dC5jbGFzc0xpc3QuYWRkKCdpbnZhbGlkJyk7IHVwZGF0ZVRyaXBGaWVsZCh0cmlwSWQsIGZpZWxkLCAnJyk7IHJldHVybjsgfQogICAgY29uc3QgbWF4RGF5ID0gZ2V0RGF5c0luTW9udGgobW0gLSAxLCB5eXl5KTsKICAgIGlmIChkZCA8IDEgfHwgZGQgPiBtYXhEYXkpIHsgaW5wdXQuY2xhc3NMaXN0LmFkZCgnaW52YWxpZCcpOyB1cGRhdGVUcmlwRmllbGQodHJpcElkLCBmaWVsZCwgJycpOyByZXR1cm47IH0KICAgIGNvbnN0IGlzbyA9IGAke3l5eXl9LSR7U3RyaW5nKG1tKS5wYWRTdGFydCgyLCcwJyl9LSR7U3RyaW5nKGRkKS5wYWRTdGFydCgyLCcwJyl9YDsKICAgIGhpZGRlbi52YWx1ZSA9IGlzbzsKICAgIGlucHV0LmNsYXNzTGlzdC5hZGQoJ3ZhbGlkJyk7CiAgICB1cGRhdGVUcmlwRmllbGQodHJpcElkLCBmaWVsZCwgaXNvKTsKICB9CgogIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgZnVuY3Rpb24gKCkgewogICAgY29uc3QgcmF3ID0gZGlnaXRzT25seSh0aGlzLnZhbHVlKTsKICAgIHRoaXMudmFsdWUgPSBmb3JtYXREaXNwbGF5KHJhdyk7CiAgICBjb25zdCBwb3MgPSBjYXJldEZvckRpZ2l0SW5kZXgocmF3Lmxlbmd0aCk7CiAgICB0aGlzLnNldFNlbGVjdGlvblJhbmdlKHBvcywgcG9zKTsKICAgIHZhbGlkYXRlKHJhdyk7CiAgfSk7CgogIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkgewogICAgaWYgKFs4LDksMjcsNDYsMzUsMzYsMzcsMzgsMzksNDBdLmluY2x1ZGVzKGUua2V5Q29kZSkgfHwgKGUuY3RybEtleSAmJiBlLmtleUNvZGUgPT09IDY1KSB8fCAoZS5tZXRhS2V5ICYmIGUua2V5Q29kZSA9PT0gNjUpKSByZXR1cm47CiAgICBpZiAoKGUuY3RybEtleSB8fCBlLm1ldGFLZXkpICYmIChlLmtleUNvZGUgPT09IDg2IHx8IGUua2V5ID09PSAndicpKSByZXR1cm47CiAgICBpZiAoIS9eXGQkLy50ZXN0KGUua2V5KSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IHJldHVybjsgfQogICAgaWYgKGRpZ2l0c09ubHkodGhpcy52YWx1ZSkubGVuZ3RoID49IDgpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9CiAgfSk7CgogIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgZnVuY3Rpb24gKGUpIHsKICAgIGUucHJldmVudERlZmF1bHQoKTsKICAgIGNvbnN0IHBhc3RlID0gKGUuY2xpcGJvYXJkRGF0YSB8fCB3aW5kb3cuY2xpcGJvYXJkRGF0YSkuZ2V0RGF0YSgndGV4dCcpOwogICAgY29uc3QgcmF3ID0gZGlnaXRzT25seShwYXN0ZSk7CiAgICB0aGlzLnZhbHVlID0gZm9ybWF0RGlzcGxheShyYXcpOwogICAgY29uc3QgcG9zID0gY2FyZXRGb3JEaWdpdEluZGV4KHJhdy5sZW5ndGgpOwogICAgdGhpcy5zZXRTZWxlY3Rpb25SYW5nZShwb3MsIHBvcyk7CiAgICB2YWxpZGF0ZShyYXcpOwogIH0pOwoKICAvLyBQcmUtcG9wdWxhdGUgZnJvbSB0cmlwIGRhdGEKICBjb25zdCB0cmlwID0gdHJpcHMuZmluZCh0ID0+IHQuaWQgPT09IHRyaXBJZCk7CiAgaWYgKHRyaXAgJiYgdHJpcFtmaWVsZF0pIHsKICAgIGNvbnN0IGQgPSBuZXcgRGF0ZSh0cmlwW2ZpZWxkXSArICdUMDA6MDA6MDAnKTsKICAgIGNvbnN0IHJhdyA9IFN0cmluZyhkLmdldERhdGUoKSkucGFkU3RhcnQoMiwnMCcpICsgU3RyaW5nKGQuZ2V0TW9udGgoKSsxKS5wYWRTdGFydCgyLCcwJykgKyBTdHJpbmcoZC5nZXRGdWxsWWVhcigpKTsKICAgIGlucHV0LnZhbHVlID0gZm9ybWF0RGlzcGxheShyYXcpOwogICAgdmFsaWRhdGUocmF3KTsKICB9Cn0KCmZ1bmN0aW9uIHVwZGF0ZVRyaXBGaWVsZCh0cmlwSWQsIGZpZWxkLCB2YWx1ZSkgewogIGNvbnN0IHRyaXAgPSB0cmlwcy5maW5kKHQgPT4gdC5pZCA9PT0gdHJpcElkKTsKICBpZiAodHJpcCkgewogICAgdHJpcFtmaWVsZF0gPSB2YWx1ZTsKICAgIC8vIFVwZGF0ZSB0aGUgZGF5cyBkaXNwbGF5IGZvciB0aGlzIHRyaXAKICAgIGNvbnN0IGRheXNFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGB0cmlwRGF5c18ke3RyaXBJZH1gKTsKICAgIGlmIChkYXlzRWwpIHsKICAgICAgY29uc3QgZGF5cyA9IGNhbGNXaG9sZURheXModHJpcC5kZXBhcnR1cmUsIHRyaXAucmV0dXJuKTsKICAgICAgZGF5c0VsLmNsYXNzTmFtZSA9ICd0cmlwLWRheXMnICsgKGRheXMgPiAxODAgPyAnIGRhbmdlcicgOiBkYXlzID4gMTUwID8gJyB3YXJuaW5nJyA6ICcnKTsKICAgICAgZGF5c0VsLnRleHRDb250ZW50ID0gZGF5cyA+IDAgPyBkYXlzICsgJyAnICsgdCgnZGF5cycsICdcdTU5MjknKSA6ICctJzsKICAgIH0KICB9Cn0KCmZ1bmN0aW9uIGNhbGNXaG9sZURheXMoZGVwYXJ0dXJlLCByZXR1cm5EYXRlKSB7CiAgaWYgKCFkZXBhcnR1cmUgfHwgIXJldHVybkRhdGUpIHJldHVybiAwOwogIGNvbnN0IGRlcCA9IG5ldyBEYXRlKGRlcGFydHVyZSk7CiAgY29uc3QgcmV0ID0gbmV3IERhdGUocmV0dXJuRGF0ZSk7CiAgaWYgKHJldCA8PSBkZXApIHJldHVybiAwOwogIGNvbnN0IG1zUGVyRGF5ID0gODY0MDAwMDA7CiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGguZmxvb3IoKHJldCAtIGRlcCkgLyBtc1BlckRheSkgLSAxKTsKfQoKZnVuY3Rpb24gcmVuZGVyVHJpcHMoKSB7CiAgY29uc3QgbGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0cmlwTGlzdCcpOwogIGlmICh0cmlwcy5sZW5ndGggPT09IDApIHsKICAgIGxpc3QuaW5uZXJIVE1MID0gJzxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtjb2xvcjojNzE4MDk2O3BhZGRpbmc6MjBweDtmb250LXNpemU6MTRweDsiPicgKwogICAgICB0KCdObyB0cmlwcyBhZGRlZCB5ZXQuIENsaWNrIGJlbG93IHRvIGFkZCB5b3VyIHRyYXZlbCBoaXN0b3J5LicsICdcdTVjMWFcdTY3MmFcdTZkZmJcdTUyYTBcdTg4NGNcdTdhMGJcdTMwMDJcdTllZGVcdTY0Y2FcdTRlMGJcdTY1YjlcdTY1YjBcdTU4OWVcdTYwYThcdTc2ODRcdTY1YzVcdTg4NGNcdThhMThcdTkzMDRcdTMwMDInKSArICc8L3A+JzsKICAgIHJldHVybjsKICB9CgogIGxpc3QuaW5uZXJIVE1MID0gdHJpcHMubWFwKHRyaXAgPT4gewogICAgY29uc3QgZGF5cyA9IGNhbGNXaG9sZURheXModHJpcC5kZXBhcnR1cmUsIHRyaXAucmV0dXJuKTsKICAgIGxldCBkYXlzQ2xhc3MgPSAnJzsKICAgIGlmIChkYXlzID4gMTgwKSBkYXlzQ2xhc3MgPSAnZGFuZ2VyJzsKICAgIGVsc2UgaWYgKGRheXMgPiAxNTApIGRheXNDbGFzcyA9ICd3YXJuaW5nJzsKCiAgICBjb25zdCBkZXBJbnB1dElkID0gYHRyaXBEZXBfJHt0cmlwLmlkfWA7CiAgICBjb25zdCBkZXBIaWRkZW5JZCA9IGB0cmlwRGVwSF8ke3RyaXAuaWR9YDsKICAgIGNvbnN0IHJldElucHV0SWQgPSBgdHJpcFJldF8ke3RyaXAuaWR9YDsKICAgIGNvbnN0IHJldEhpZGRlbklkID0gYHRyaXBSZXRIXyR7dHJpcC5pZH1gOwoKICAgIHJldHVybiBgCiAgICAgIDxkaXYgY2xhc3M9InRyaXAtaXRlbSI+CiAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICA8bGFiZWw+JHt0KCdMZWZ0IFVLJywgJ1x1OTZlMlx1OTU4Ylx1ODJmMVx1NTcwYicpfTwvbGFiZWw+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJkYXRlLWlucHV0LXdyYXAiPgogICAgICAgICAgICA8c3BhbiBjbGFzcz0iZGF0ZS1pbnB1dC1pY29uIj4mIzEyODE5Nzs8L3NwYW4+CiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBjbGFzcz0iZGF0ZS1hdXRvIiBpZD0iJHtkZXBJbnB1dElkfSIgaW5wdXRtb2RlPSJudW1lcmljIiBwbGFjZWhvbGRlcj0iREQgLyBNTSAvIFlZWVkiIG1heGxlbmd0aD0iMTQiIGF1dG9jb21wbGV0ZT0ib2ZmIiBzdHlsZT0iZm9udC1zaXplOjE0cHg7cGFkZGluZzo4cHggMTBweCA4cHggMzRweDttaW4taGVpZ2h0OjM4cHg7Ij4KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgaWQ9IiR7ZGVwSGlkZGVuSWR9Ij4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4KICAgICAgICAgIDxsYWJlbD4ke3QoJ1JldHVybmVkIHRvIFVLJywgJ1x1OGZkNFx1NTZkZVx1ODJmMVx1NTcwYicpfTwvbGFiZWw+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJkYXRlLWlucHV0LXdyYXAiPgogICAgICAgICAgICA8c3BhbiBjbGFzcz0iZGF0ZS1pbnB1dC1pY29uIj4mIzEyODE5Nzs8L3NwYW4+CiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBjbGFzcz0iZGF0ZS1hdXRvIiBpZD0iJHtyZXRJbnB1dElkfSIgaW5wdXRtb2RlPSJudW1lcmljIiBwbGFjZWhvbGRlcj0iREQgLyBNTSAvIFlZWVkiIG1heGxlbmd0aD0iMTQiIGF1dG9jb21wbGV0ZT0ib2ZmIiBzdHlsZT0iZm9udC1zaXplOjE0cHg7cGFkZGluZzo4cHggMTBweCA4cHggMzRweDttaW4taGVpZ2h0OjM4cHg7Ij4KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgaWQ9IiR7cmV0SGlkZGVuSWR9Ij4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJ0cmlwLWRheXMgJHtkYXlzQ2xhc3N9IiBpZD0idHJpcERheXNfJHt0cmlwLmlkfSI+JHtkYXlzID4gMCA/IGRheXMgKyAnICcgKyB0KCdkYXlzJywgJ1x1NTkyOScpIDogJy0nfTwvZGl2PgogICAgICAgIDxidXR0b24gY2xhc3M9ImJ0bi1yZW1vdmUiIG9uY2xpY2s9InJlbW92ZVRyaXAoJHt0cmlwLmlkfSkiIHRpdGxlPSIke3QoJ1JlbW92ZScsICdcdTUyMmFcdTk2NjQnKX0iPiYjMTAwMDU7PC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgYDsKICB9KS5qb2luKCcnKTsKCiAgLy8gSW5pdGlhbGlzZSBhdXRvLWZvcm1hdCBoYW5kbGVycyBmb3IgZWFjaCB0cmlwIHJvdwogIHRyaXBzLmZvckVhY2godHJpcCA9PiB7CiAgICBpbml0VHJpcERhdGVJbnB1dChgdHJpcERlcF8ke3RyaXAuaWR9YCwgYHRyaXBEZXBIXyR7dHJpcC5pZH1gLCB0cmlwLmlkLCAnZGVwYXJ0dXJlJyk7CiAgICBpbml0VHJpcERhdGVJbnB1dChgdHJpcFJldF8ke3RyaXAuaWR9YCwgYHRyaXBSZXRIXyR7dHJpcC5pZH1gLCB0cmlwLmlkLCAncmV0dXJuJyk7CiAgfSk7Cn0KCi8vID09PT09PT09PT09PT09PT09PT09IENBTENVTEFUSU9OID09PT09PT09PT09PT09PT09PT09CmZ1bmN0aW9uIGNhbGN1bGF0ZSgpIHsKICBjb25zdCBsZWF2ZVN0YXJ0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xlYXZlU3RhcnREYXRlJykudmFsdWU7CiAgY29uc3QgYXBwRGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhcHBsaWNhdGlvbkRhdGUnKS52YWx1ZTsKICBjb25zdCBsaWZlVGVzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsaWZlSW5Va1Rlc3QnKS52YWx1ZTsKICBjb25zdCBlbmdMYW5nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2VuZ2xpc2hMYW5nJykudmFsdWU7CiAgY29uc3QgY3JpbWluYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3JpbWluYWxSZWNvcmQnKS52YWx1ZTsKCgogIGlmICghbGVhdmVTdGFydCB8fCAhYXBwRGF0ZSkgewogICAgYWxlcnQodCgnUGxlYXNlIHNlbGVjdCBib3RoIHRoZSBCTk8gbGVhdmUgc3RhcnQgZGF0ZSBhbmQgaW50ZW5kZWQgYXBwbGljYXRpb24gZGF0ZS4nLCAnXHU4YWNiXHU5MDc4XHU2NGM3IEJOTyBcdTdjM2RcdThiNDlcdTk1OGJcdTU5Y2JcdTY1ZTVcdTY3MWZcdTU0OGNcdThhMDhcdTUyODNcdTc1MzNcdThhY2JcdTY1ZTVcdTY3MWZcdTMwMDInKSk7CiAgICByZXR1cm47CiAgfQoKICBjb25zdCBsZWF2ZVN0YXJ0RHQgPSBuZXcgRGF0ZShsZWF2ZVN0YXJ0KTsKICBjb25zdCBhcHBEYXRlRHQgPSBuZXcgRGF0ZShhcHBEYXRlKTsKICBjb25zdCBxdWFsaWZ5aW5nRW5kRHQgPSBuZXcgRGF0ZShsZWF2ZVN0YXJ0RHQpOwogIHF1YWxpZnlpbmdFbmREdC5zZXRGdWxsWWVhcihxdWFsaWZ5aW5nRW5kRHQuZ2V0RnVsbFllYXIoKSArIDUpOwoKICBjb25zdCBtc1BlckRheSA9IDg2NDAwMDAwOwogIGNvbnN0IHRvdGFsRGF5cyA9IE1hdGguZmxvb3IoKGFwcERhdGVEdCAtIGxlYXZlU3RhcnREdCkgLyBtc1BlckRheSk7CiAgY29uc3QgZGF5c1VudGlsUXVhbGlmaWVkID0gTWF0aC5mbG9vcigocXVhbGlmeWluZ0VuZER0IC0gYXBwRGF0ZUR0KSAvIG1zUGVyRGF5KTsKICBjb25zdCBpc092ZXJzdGF5ZXIgPSBkYXlzVW50aWxRdWFsaWZpZWQgPCAwOyAvLyBhcHBsaWNhdGlvbiBkYXRlIGlzIGFmdGVyIGxlYXZlIGV4cGlyZXMKICBjb25zdCBoYXNDb21wbGV0ZWQ1WWVhcnMgPSBkYXlzVW50aWxRdWFsaWZpZWQgPD0gMjggJiYgIWlzT3ZlcnN0YXllcjsKICBjb25zdCBlYXJsaWVzdEFwcERhdGUgPSBuZXcgRGF0ZShxdWFsaWZ5aW5nRW5kRHQuZ2V0VGltZSgpIC0gMjggKiBtc1BlckRheSk7CiAgY29uc3QgaXNUb29FYXJseSA9IGRheXNVbnRpbFF1YWxpZmllZCA+IDI4OwoKICBsZXQgdG90YWxBYnNlbmNlRGF5cyA9IDA7CiAgY29uc3QgdmFsaWRUcmlwcyA9IHRyaXBzLmZpbHRlcih0cmlwID0+IHRyaXAuZGVwYXJ0dXJlICYmIHRyaXAucmV0dXJuKS5tYXAodHJpcCA9PiB7CiAgICBjb25zdCBkZXAgPSBuZXcgRGF0ZSh0cmlwLmRlcGFydHVyZSk7CiAgICBjb25zdCByZXQgPSBuZXcgRGF0ZSh0cmlwLnJldHVybik7CiAgICBjb25zdCBkYXlzID0gY2FsY1dob2xlRGF5cyh0cmlwLmRlcGFydHVyZSwgdHJpcC5yZXR1cm4pOwogICAgLy8gQWJzZW50IGRheXM6IGRheSBhZnRlciBkZXBhcnR1cmUgdG8gZGF5IGJlZm9yZSByZXR1cm4KICAgIGNvbnN0IGFic2VudFN0YXJ0ID0gbmV3IERhdGUoZGVwLmdldFRpbWUoKSArIG1zUGVyRGF5KTsKICAgIGNvbnN0IGFic2VudEVuZCA9IG5ldyBEYXRlKHJldC5nZXRUaW1lKCkgLSBtc1BlckRheSk7CiAgICBjb25zdCBlZmZTdGFydCA9IGFic2VudFN0YXJ0ID4gbGVhdmVTdGFydER0ID8gYWJzZW50U3RhcnQgOiBsZWF2ZVN0YXJ0RHQ7CiAgICBjb25zdCBlZmZFbmQgPSBhYnNlbnRFbmQgPCBhcHBEYXRlRHQgPyBhYnNlbnRFbmQgOiBhcHBEYXRlRHQ7CiAgICBjb25zdCBlZmZlY3RpdmVEYXlzID0gZWZmRW5kID49IGVmZlN0YXJ0ID8gTWF0aC5mbG9vcigoZWZmRW5kIC0gZWZmU3RhcnQpIC8gbXNQZXJEYXkpICsgMSA6IDA7CiAgICByZXR1cm4geyBkZXBhcnR1cmU6IHRyaXAuZGVwYXJ0dXJlLCByZXR1cm46IHRyaXAucmV0dXJuLCB0b3RhbERheXM6IGRheXMsIGVmZmVjdGl2ZURheXMsIGRlcERhdGU6IGRlcCwgcmV0RGF0ZTogcmV0IH07CiAgfSkuc29ydCgoYSwgYikgPT4gYS5kZXBEYXRlIC0gYi5kZXBEYXRlKTsKCiAgdmFsaWRUcmlwcy5mb3JFYWNoKHQgPT4gdG90YWxBYnNlbmNlRGF5cyArPSB0LmVmZmVjdGl2ZURheXMpOwoKICBsZXQgbWF4QWJzZW5jZUluMTJNb250aHMgPSAwOwogIGxldCB3b3JzdFdpbmRvd1N0YXJ0ID0gbnVsbDsKICBsZXQgd29yc3RXaW5kb3dFbmQgPSBudWxsOwoKICBjb25zdCBrZXlEYXRlcyA9IG5ldyBTZXQoKTsKICB2YWxpZFRyaXBzLmZvckVhY2godHJpcCA9PiB7CiAgICBrZXlEYXRlcy5hZGQodHJpcC5kZXBhcnR1cmUpOyBrZXlEYXRlcy5hZGQodHJpcC5yZXR1cm4pOwogICAgY29uc3QgZDEgPSBuZXcgRGF0ZSh0cmlwLmRlcGFydHVyZSk7IGQxLnNldEZ1bGxZZWFyKGQxLmdldEZ1bGxZZWFyKCkgLSAxKTsga2V5RGF0ZXMuYWRkKGQxLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXSk7CiAgICBjb25zdCBkMiA9IG5ldyBEYXRlKHRyaXAucmV0dXJuKTsgZDIuc2V0RnVsbFllYXIoZDIuZ2V0RnVsbFllYXIoKSAtIDEpOyBrZXlEYXRlcy5hZGQoZDIudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdKTsKICAgIGNvbnN0IGQzID0gbmV3IERhdGUodHJpcC5kZXBhcnR1cmUpOyBkMy5zZXRGdWxsWWVhcihkMy5nZXRGdWxsWWVhcigpICsgMSk7IGtleURhdGVzLmFkZChkMy50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0pOwogIH0pOwoKICBjb25zdCBjaGVja0RhdGUgPSBuZXcgRGF0ZShsZWF2ZVN0YXJ0RHQpOwogIHdoaWxlIChjaGVja0RhdGUgPD0gYXBwRGF0ZUR0KSB7IGtleURhdGVzLmFkZChjaGVja0RhdGUudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdKTsgY2hlY2tEYXRlLnNldE1vbnRoKGNoZWNrRGF0ZS5nZXRNb250aCgpICsgMSk7IH0KCiAgZnVuY3Rpb24gY291bnRBYnNlbmNlRGF5c0luV2luZG93KHdpbmRvd1N0YXJ0LCB3aW5kb3dFbmQpIHsKICAgIGxldCBkYXlzID0gMDsKICAgIHZhbGlkVHJpcHMuZm9yRWFjaCh0cmlwID0+IHsKICAgICAgY29uc3QgZGVwRHQgPSBuZXcgRGF0ZSh0cmlwLmRlcGFydHVyZSksIHJldER0ID0gbmV3IERhdGUodHJpcC5yZXR1cm4pOwogICAgICAvLyBQZXJzb24gaXMgYWJzZW50IGZyb20gZGF5IGFmdGVyIGRlcGFydHVyZSB0byBkYXkgYmVmb3JlIHJldHVybgogICAgICBjb25zdCBhYnNlbnRTdGFydCA9IG5ldyBEYXRlKGRlcER0LmdldFRpbWUoKSArIG1zUGVyRGF5KTsKICAgICAgY29uc3QgYWJzZW50RW5kID0gbmV3IERhdGUocmV0RHQuZ2V0VGltZSgpIC0gbXNQZXJEYXkpOwogICAgICBpZiAoYWJzZW50RW5kIDwgYWJzZW50U3RhcnQpIHJldHVybjsgLy8gbmV4dC1kYXkgcmV0dXJuID0gMCBhYnNlbnQgZGF5cwogICAgICBjb25zdCBvUyA9IGFic2VudFN0YXJ0ID4gd2luZG93U3RhcnQgPyBhYnNlbnRTdGFydCA6IHdpbmRvd1N0YXJ0OwogICAgICBjb25zdCBvRSA9IGFic2VudEVuZCA8IHdpbmRvd0VuZCA/IGFic2VudEVuZCA6IHdpbmRvd0VuZDsKICAgICAgaWYgKG9FID49IG9TKSBkYXlzICs9IE1hdGguZmxvb3IoKG9FIC0gb1MpIC8gbXNQZXJEYXkpICsgMTsKICAgIH0pOwogICAgcmV0dXJuIGRheXM7CiAgfQoKICBjb25zdCBjaGVja2VkV2luZG93cyA9IG5ldyBNYXAoKTsKICBBcnJheS5mcm9tKGtleURhdGVzKS5zb3J0KCkuZm9yRWFjaChkYXRlU3RyID0+IHsKICAgIGNvbnN0IHdTID0gbmV3IERhdGUoZGF0ZVN0cik7CiAgICBpZiAod1MgPCBsZWF2ZVN0YXJ0RHQgfHwgd1MgPiBhcHBEYXRlRHQpIHJldHVybjsKICAgIGNvbnN0IHdFID0gbmV3IERhdGUod1MpOyB3RS5zZXRGdWxsWWVhcih3RS5nZXRGdWxsWWVhcigpICsgMSk7CiAgICBpZiAod0UgPiBhcHBEYXRlRHQpIHdFLnNldFRpbWUoYXBwRGF0ZUR0LmdldFRpbWUoKSk7CiAgICBpZiAoY2hlY2tlZFdpbmRvd3MuaGFzKGRhdGVTdHIpKSByZXR1cm47CiAgICBjb25zdCBhYnMgPSBjb3VudEFic2VuY2VEYXlzSW5XaW5kb3cod1MsIHdFKTsKICAgIGNoZWNrZWRXaW5kb3dzLnNldChkYXRlU3RyLCBhYnMpOwogICAgaWYgKGFicyA+IG1heEFic2VuY2VJbjEyTW9udGhzKSB7IG1heEFic2VuY2VJbjEyTW9udGhzID0gYWJzOyB3b3JzdFdpbmRvd1N0YXJ0ID0gbmV3IERhdGUod1MpOyB3b3JzdFdpbmRvd0VuZCA9IG5ldyBEYXRlKHdFKTsgfQogIH0pOwoKICB2YWxpZFRyaXBzLmZvckVhY2godHJpcCA9PiB7CiAgICBbdHJpcC5kZXBhcnR1cmUsIHRyaXAucmV0dXJuXS5mb3JFYWNoKGRhdGVTdHIgPT4gewogICAgICBjb25zdCBkdCA9IG5ldyBEYXRlKGRhdGVTdHIpOwogICAgICBjb25zdCB3UyA9IG5ldyBEYXRlKGR0KTsgd1Muc2V0RnVsbFllYXIod1MuZ2V0RnVsbFllYXIoKSAtIDEpOwogICAgICBpZiAod1MgPCBsZWF2ZVN0YXJ0RHQpIHdTLnNldFRpbWUobGVhdmVTdGFydER0LmdldFRpbWUoKSk7CiAgICAgIGlmIChkdCA8PSBhcHBEYXRlRHQpIHsKICAgICAgICBjb25zdCBhYnMgPSBjb3VudEFic2VuY2VEYXlzSW5XaW5kb3cod1MsIGR0KTsKICAgICAgICBpZiAoYWJzID4gbWF4QWJzZW5jZUluMTJNb250aHMpIHsgbWF4QWJzZW5jZUluMTJNb250aHMgPSBhYnM7IHdvcnN0V2luZG93U3RhcnQgPSBuZXcgRGF0ZSh3Uyk7IHdvcnN0V2luZG93RW5kID0gbmV3IERhdGUoZHQpOyB9CiAgICAgIH0KICAgIH0pOwogIH0pOwoKICBjb25zdCBhYnNlbmNlQnJlYWNoZWQgPSBtYXhBYnNlbmNlSW4xMk1vbnRocyA+IDE4MDsKCiAgY29uc3QgdGFibGVSb3dzID0gW107CiAgaWYgKHZhbGlkVHJpcHMubGVuZ3RoID4gMCkgewogICAgY29uc3Qgc2VlblN0YXJ0cyA9IG5ldyBTZXQoKTsKICAgIGNvbnN0IGNhbmRpZGF0ZVdpbmRvd3MgPSBbXTsKICAgIHZhbGlkVHJpcHMuZm9yRWFjaCh0cmlwID0+IHsKICAgICAgY29uc3Qgd1MxID0gbmV3IERhdGUodHJpcC5yZXR1cm4pOyB3UzEuc2V0RnVsbFllYXIod1MxLmdldEZ1bGxZZWFyKCkgLSAxKTsKICAgICAgaWYgKHdTMSA8IGxlYXZlU3RhcnREdCkgd1MxLnNldFRpbWUobGVhdmVTdGFydER0LmdldFRpbWUoKSk7CiAgICAgIGNvbnN0IHdFMSA9IG5ldyBEYXRlKHRyaXAucmV0dXJuKTsKICAgICAgaWYgKHdFMSA+IGFwcERhdGVEdCkgd0UxLnNldFRpbWUoYXBwRGF0ZUR0LmdldFRpbWUoKSk7CiAgICAgIGNvbnN0IGtleTEgPSB3UzEudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdOwogICAgICBpZiAoIXNlZW5TdGFydHMuaGFzKGtleTEpKSB7CiAgICAgICAgc2VlblN0YXJ0cy5hZGQoa2V5MSk7CiAgICAgICAgY2FuZGlkYXRlV2luZG93cy5wdXNoKHsgc3RhcnQ6IHdTMSwgZW5kOiB3RTEsIGRheXM6IGNvdW50QWJzZW5jZURheXNJbldpbmRvdyh3UzEsIHdFMSksIGlzV29yc3Q6IGZhbHNlIH0pOwogICAgICB9CiAgICAgIGNvbnN0IHdTMiA9IG5ldyBEYXRlKHRyaXAuZGVwYXJ0dXJlKTsKICAgICAgaWYgKHdTMiA8IGxlYXZlU3RhcnREdCkgd1MyLnNldFRpbWUobGVhdmVTdGFydER0LmdldFRpbWUoKSk7CiAgICAgIGNvbnN0IHdFMiA9IG5ldyBEYXRlKHdTMik7IHdFMi5zZXRGdWxsWWVhcih3RTIuZ2V0RnVsbFllYXIoKSArIDEpOwogICAgICBpZiAod0UyID4gYXBwRGF0ZUR0KSB3RTIuc2V0VGltZShhcHBEYXRlRHQuZ2V0VGltZSgpKTsKICAgICAgY29uc3Qga2V5MiA9IHdTMi50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07CiAgICAgIGlmICghc2VlblN0YXJ0cy5oYXMoa2V5MikpIHsKICAgICAgICBzZWVuU3RhcnRzLmFkZChrZXkyKTsKICAgICAgICBjYW5kaWRhdGVXaW5kb3dzLnB1c2goeyBzdGFydDogd1MyLCBlbmQ6IHdFMiwgZGF5czogY291bnRBYnNlbmNlRGF5c0luV2luZG93KHdTMiwgd0UyKSwgaXNXb3JzdDogZmFsc2UgfSk7CiAgICAgIH0KICAgIH0pOwogICAgY2FuZGlkYXRlV2luZG93cy5zb3J0KChhLCBiKSA9PiBiLmRheXMgLSBhLmRheXMpOwogICAgY29uc3QgdG9wV2luZG93cyA9IGNhbmRpZGF0ZVdpbmRvd3Muc2xpY2UoMCwgNik7CiAgICBpZiAod29yc3RXaW5kb3dTdGFydCAmJiB3b3JzdFdpbmRvd0VuZCkgewogICAgICBjb25zdCB3b3JzdEtleSA9IHdvcnN0V2luZG93U3RhcnQudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdOwogICAgICBjb25zdCBleGlzdGluZyA9IHRvcFdpbmRvd3MuZmluZChyID0+IHIuc3RhcnQudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdID09PSB3b3JzdEtleSk7CiAgICAgIGlmIChleGlzdGluZykgeyBleGlzdGluZy5pc1dvcnN0ID0gdHJ1ZTsgfQogICAgICBlbHNlIHsgdG9wV2luZG93cy51bnNoaWZ0KHsgc3RhcnQ6IHdvcnN0V2luZG93U3RhcnQsIGVuZDogd29yc3RXaW5kb3dFbmQsIGRheXM6IG1heEFic2VuY2VJbjEyTW9udGhzLCBpc1dvcnN0OiB0cnVlIH0pOyB9CiAgICB9CiAgICB0b3BXaW5kb3dzLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQgLSBiLnN0YXJ0KTsKICAgIHRvcFdpbmRvd3MuZm9yRWFjaCh3ID0+IHRhYmxlUm93cy5wdXNoKHcpKTsKICB9CgogIGNvbnN0IGNoZWNrcyA9IHsKICAgIGZpdmVZZWFyczogaGFzQ29tcGxldGVkNVllYXJzLCBhYnNlbmNlOiAhYWJzZW5jZUJyZWFjaGVkLAogICAgbGlmZVRlc3Q6IGxpZmVUZXN0ID09PSAncGFzc2VkJyB8fCBsaWZlVGVzdCA9PT0gJ2V4ZW1wdCcsCiAgICBlbmdsaXNoOiBlbmdMYW5nID09PSAnbWV0JywgY2hhcmFjdGVyOiBjcmltaW5hbCA9PT0gJ25vbmUnCiAgfTsKCiAgY29uc3QgYWxsUmVxdWlyZWRNZXQgPSBjaGVja3MuZml2ZVllYXJzICYmIGNoZWNrcy5hYnNlbmNlOwogIGNvbnN0IGFsbE9wdGlvbmFsTWV0ID0gY2hlY2tzLmxpZmVUZXN0ICYmIGNoZWNrcy5lbmdsaXNoICYmIGNoZWNrcy5jaGFyYWN0ZXI7CiAgY29uc3Qgc29tZVVuYW5zd2VyZWQgPSAhbGlmZVRlc3QgfHwgIWVuZ0xhbmcgfHwgIWNyaW1pbmFsOwogIGxldCBvdmVyYWxsU3RhdHVzID0gJ3Bhc3MnOwogIGlmIChpc092ZXJzdGF5ZXIpIG92ZXJhbGxTdGF0dXMgPSAnZmFpbCc7CiAgZWxzZSBpZiAoIWFsbFJlcXVpcmVkTWV0KSBvdmVyYWxsU3RhdHVzID0gJ2ZhaWwnOwogIGVsc2UgaWYgKCFhbGxPcHRpb25hbE1ldCAmJiAhc29tZVVuYW5zd2VyZWQpIG92ZXJhbGxTdGF0dXMgPSAnZmFpbCc7CiAgZWxzZSBpZiAoc29tZVVuYW5zd2VyZWQpIG92ZXJhbGxTdGF0dXMgPSAnd2Fybic7CgogIGNvbnN0IHJlc3VsdHNFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZXN1bHRzJyk7CiAgcmVzdWx0c0VsLmNsYXNzTGlzdC5hZGQoJ3Nob3cnKTsKICBjb25zdCBleHBCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXhwb3J0QnRuQ29udGFpbmVyJyk7CiAgaWYgKGV4cEJ0bikgZXhwQnRuLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwoKICBjb25zdCBiYW5uZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVzdWx0QmFubmVyJyk7CiAgY29uc3QgaWNvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZXN1bHRJY29uJyk7CiAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVzdWx0VGl0bGUnKTsKICBjb25zdCBzdWJ0aXRsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZXN1bHRTdWJ0aXRsZScpOwogIGJhbm5lci5jbGFzc05hbWUgPSAncmVzdWx0LWJhbm5lciAnICsgb3ZlcmFsbFN0YXR1czsKCiAgaWYgKGlzT3ZlcnN0YXllcikgewogICAgaWNvbi5pbm5lckhUTUwgPSAnJiM5ODg4Oyc7IHRpdGxlLnRleHRDb250ZW50ID0gdCgnT1ZFUlNUQVlFUiAtIFlvdXIgQk5PIGxlYXZlIGhhcyBleHBpcmVkJywgJ1x1OTAzZVx1NjcxZlx1NWM0NVx1NzU1OSAtIFx1NjBhOFx1NzY4NCBCTk8gXHU3YzNkXHU4YjQ5XHU1ZGYyXHU5MDRlXHU2NzFmJyk7CiAgICBzdWJ0aXRsZS50ZXh0Q29udGVudCA9IHQoJ1lvdXIgaW50ZW5kZWQgYXBwbGljYXRpb24gZGF0ZSBpcyBhZnRlciB5b3VyIEJOTyBsZWF2ZSBleHBpcmVzLiBZb3UgY2Fubm90IGFwcGx5IGZvciBJTFIgd2l0aG91dCB2YWxpZCBsZWF2ZS4gUGxlYXNlIHNlZWsgbGVnYWwgYWR2aWNlIGltbWVkaWF0ZWx5LicsICdcdTYwYThcdTc2ODRcdThhMDhcdTUyODNcdTc1MzNcdThhY2JcdTY1ZTVcdTY3MWZcdTU3MjggQk5PIFx1N2MzZFx1OGI0OVx1NTIzMFx1NjcxZlx1NGU0Ylx1NWY4Y1x1MzAwMlx1NmM5Mlx1NjcwOVx1NjcwOVx1NjU0OFx1N2MzZFx1OGI0OVx1ZmZmZCBcdWZmZmRcdTZjZDVcdTc1MzNcdThhY2JcdTZjMzhcdTVjNDVcdTMwMDJcdThhY2JcdTdhY2JcdTUzNzNcdTVjMGJcdTZjNDJcdTZjZDVcdTVmOGJcdTVlZmFcdThiNzBcdTMwMDInKTsKICB9IGVsc2UgaWYgKG92ZXJhbGxTdGF0dXMgPT09ICdwYXNzJykgewogICAgaWNvbi5pbm5lckhUTUwgPSAnJiMxMDAwMzsnOyB0aXRsZS50ZXh0Q29udGVudCA9IHQoJ1lvdSBhcHBlYXIgdG8gbWVldCB0aGUgY29udGludW91cyByZXNpZGVuY2UgcmVxdWlyZW1lbnQnLCAnXHU2MGE4XHU0ZjNjXHU0ZTRlXHU3YjI2XHU1NDA4XHU5MDIzXHU3ZThjXHU1YzQ1XHU0ZjRmXHU4OTgxXHU2YzQyJyk7CiAgICBzdWJ0aXRsZS50ZXh0Q29udGVudCA9IHQoJ0Jhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBwcm92aWRlZCwgeW91IG1heSBiZSBlbGlnaWJsZSB0byBhcHBseSBmb3IgSUxSLicsICdcdTY4MzlcdTY0ZGFcdTYyNDBcdTYzZDBcdTRmOWJcdTc2ODRcdThjYzdcdTY1OTlcdWZmMGNcdTYwYThcdTUzZWZcdTgwZmRcdTY3MDlcdThjYzdcdTY4M2NcdTc1MzNcdThhY2JcdTZjMzhcdTRlNDVcdTVjNDVcdTc1NTlcdTMwMDInKTsKICB9IGVsc2UgaWYgKG92ZXJhbGxTdGF0dXMgPT09ICd3YXJuJykgewogICAgaWNvbi5pbm5lckhUTUwgPSAnJiM5ODg4Oyc7IHRpdGxlLnRleHRDb250ZW50ID0gdCgnUmVzaWRlbmNlIHJlcXVpcmVtZW50IGFwcGVhcnMgdG8gYmUgbWV0LCBidXQgc29tZSBpdGVtcyBhcmUgaW5jb21wbGV0ZScsICdcdTVjNDVcdTRmNGZcdTg5ODFcdTZjNDJcdTRmM2NcdTRlNGVcdTVkZjJcdTZlZmZcdThkYjNcdWZmMGNcdTRmNDZcdTkwZThcdTUyMDZcdTk4MDVcdTc2ZWVcdTVjMWFcdTY3MmFcdTU4NmJcdTViZWInKTsKICAgIHN1YnRpdGxlLnRleHRDb250ZW50ID0gdCgnUGxlYXNlIGNvbXBsZXRlIGFsbCBmaWVsZHMgYWJvdmUgZm9yIGEgZnVsbCBhc3Nlc3NtZW50LicsICdcdThhY2JcdTU4NmJcdTViZWJcdTRlZTVcdTRlMGFcdTYyNDBcdTY3MDlcdTZiMDRcdTRmNGRcdTRlZTVcdTczNzJcdTVmOTdcdTViOGNcdTY1NzRcdThhNTVcdTRmMzBcdTMwMDInKTsKICB9IGVsc2UgewogICAgaWNvbi5pbm5lckhUTUwgPSAnJiMxMDAwNzsnOyB0aXRsZS50ZXh0Q29udGVudCA9IHQoJ1lvdSBtYXkgbm90IGN1cnJlbnRseSBtZWV0IHRoZSByZXF1aXJlbWVudHMgZm9yIElMUicsICdcdTYwYThcdTc2ZWVcdTUyNGRcdTUzZWZcdTgwZmRcdTRlMGRcdTdiMjZcdTU0MDhcdTZjMzhcdTVjNDVcdTg5ODFcdTZjNDInKTsKICAgIHN1YnRpdGxlLnRleHRDb250ZW50ID0gdCgnUGxlYXNlIHJldmlldyB0aGUgZGV0YWlscyBiZWxvdyBhbmQgY29uc2lkZXIgc2Vla2luZyBwcm9mZXNzaW9uYWwgYWR2aWNlLicsICdcdThhY2JcdTY3ZTVcdTc3MGJcdTRlZTVcdTRlMGJcdThhNzNcdTdkMzBcdThjYzdcdTY1OTlcdTRlMjZcdTgwMDNcdTYxNmVcdTVjMGJcdTZjNDJcdTVjMDhcdTY5NmRcdTZjZDVcdTVmOGJcdTVlZmFcdThiNzBcdTMwMDInKTsKICB9CgogIGNvbnN0IGRheXNJblVrID0gdG90YWxEYXlzIC0gdG90YWxBYnNlbmNlRGF5czsKICBjb25zdCBwZXJjZW50SW5VayA9IHRvdGFsRGF5cyA+IDAgPyBNYXRoLnJvdW5kKChkYXlzSW5VayAvIHRvdGFsRGF5cykgKiAxMDApIDogMDsKCiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXRzR3JpZCcpLmlubmVySFRNTCA9IGAKICAgIDxkaXYgY2xhc3M9InN0YXQtY2FyZCI+PGRpdiBjbGFzcz0ic3RhdC12YWx1ZSI+JHt0b3RhbERheXN9PC9kaXY+PGRpdiBjbGFzcz0ic3RhdC1sYWJlbCI+JHt0KCdUb3RhbCBkYXlzIGluIHF1YWxpZnlpbmcgcGVyaW9kJywgJ1x1NTQwOFx1OGNjN1x1NjgzY1x1NjcxZlx1OTU5M1x1N2UzZFx1NTkyOVx1NjU3OCcpfTwvZGl2PjwvZGl2PgogICAgPGRpdiBjbGFzcz0ic3RhdC1jYXJkIj48ZGl2IGNsYXNzPSJzdGF0LXZhbHVlIiBzdHlsZT0iY29sb3I6JHt0b3RhbEFic2VuY2VEYXlzID4gMCA/ICcjYzA1NjIxJyA6ICcjMjc2NzQ5J30iPiR7dG90YWxBYnNlbmNlRGF5c308L2Rpdj48ZGl2IGNsYXNzPSJzdGF0LWxhYmVsIj4ke3QoJ1RvdGFsIHdob2xlIGRheXMgYWJzZW50JywgJ1x1N2UzZFx1N2YzYVx1NWUyZFx1NjU3NFx1NTkyOVx1NjU3OCcpfTwvZGl2PjwvZGl2PgogICAgPGRpdiBjbGFzcz0ic3RhdC1jYXJkIj48ZGl2IGNsYXNzPSJzdGF0LXZhbHVlIiBzdHlsZT0iY29sb3I6JHttYXhBYnNlbmNlSW4xMk1vbnRocyA+IDE4MCA/ICcjYzUzMDMwJyA6IG1heEFic2VuY2VJbjEyTW9udGhzID4gMTUwID8gJyNjMDU2MjEnIDogJyMyNzY3NDknfSI+JHttYXhBYnNlbmNlSW4xMk1vbnRoc308L2Rpdj48ZGl2IGNsYXNzPSJzdGF0LWxhYmVsIj4ke3QoJ01heCBkYXlzIGFic2VudCBpbiBhbnkgMTItbW9udGggd2luZG93JywgJ1x1NGVmYlx1NGY1NSAxMiBcdTUwMGJcdTY3MDhcdTdhOTdcdTUzZTNcdTY3MDBcdTU5MjdcdTdmM2FcdTVlMmRcdTU5MjlcdTY1NzgnKX08L2Rpdj48L2Rpdj4KICAgIDxkaXYgY2xhc3M9InN0YXQtY2FyZCI+PGRpdiBjbGFzcz0ic3RhdC12YWx1ZSI+JHtwZXJjZW50SW5Va30lPC9kaXY+PGRpdiBjbGFzcz0ic3RhdC1sYWJlbCI+JHt0KCdUaW1lIHNwZW50IGluIHRoZSBVSycsICdcdTU3MjhcdTgyZjFcdTU3MGJcdTc2ODRcdTY2NDJcdTk1OTMnKX08L2Rpdj48L2Rpdj5gOwoKICBjb25zdCBjaGVja0l0ZW1zID0gWwogICAgeyBzdGF0dXM6IGlzT3ZlcnN0YXllciA/ICdmYWlsJyA6IGNoZWNrcy5maXZlWWVhcnMgPyAncGFzcycgOiAnZmFpbCcsIHRleHQ6IGlzT3ZlcnN0YXllcgogICAgICA/IHQoYE9WRVJTVEFZRVIgV0FSTklORzogWW91ciBCTk8gbGVhdmUgZXhwaXJlZCBvbiAke2Zvcm1hdERhdGUocXVhbGlmeWluZ0VuZER0KX0uIFlvdXIgYXBwbGljYXRpb24gZGF0ZSBpcyAke01hdGguYWJzKGRheXNVbnRpbFF1YWxpZmllZCl9IGRheXMgYWZ0ZXIgeW91ciBsZWF2ZSBleHBpcmVkLiBZb3UgbXVzdCBhcHBseSBiZWZvcmUgeW91ciBsZWF2ZSBleHBpcmVzIG9yIG9idGFpbiBhbiBleHRlbnNpb24uIFNlZWsgbGVnYWwgYWR2aWNlIGltbWVkaWF0ZWx5LmAsIGBcdTkwM2VcdTY3MWZcdTVjNDVcdTc1NTlcdThiNjZcdTU0NGFcdWZmMWFcdTYwYThcdTc2ODQgQk5PIFx1N2MzZFx1OGI0OVx1NWRmMlx1NjViYyAke2Zvcm1hdERhdGUocXVhbGlmeWluZ0VuZER0KX0gXHU1MjMwXHU2NzFmXHUzMDAyXHU2MGE4XHU3Njg0XHU3NTMzXHU4YWNiXHU2NWU1XHU2NzFmXHU2YmQ0XHU3YzNkXHU4YjQ5XHU1MjMwXHU2NzFmXHU2NWU1XHU5MDcyXHU0ZTg2ICR7TWF0aC5hYnMoZGF5c1VudGlsUXVhbGlmaWVkKX0gXHU1OTI5XHUzMDAyXHU2MGE4XHU1ZmM1XHU5ODA4XHU1NzI4XHU3YzNkXHU4YjQ5XHU1MjMwXHU2NzFmXHU1MjRkXHU3NTMzXHU4YWNiXHU2MjE2XHU3MzcyXHU1Zjk3XHU1ZWY2XHU2NzFmXHUzMDAyXHU4YWNiXHU3YWNiXHU1MzczXHU1YzBiXHU2YzQyXHU2Y2Q1XHU1ZjhiXHU1ZWZhXHU4YjcwXHUzMDAyYCkKICAgICAgOiBjaGVja3MuZml2ZVllYXJzCiAgICAgICAgPyB0KGA1LXllYXIgcXVhbGlmeWluZyBwZXJpb2Q6ICR7ZGF5c1VudGlsUXVhbGlmaWVkIDw9IDAgPyAnQ29tcGxldGVkJyA6ICdDb21wbGV0YWJsZSB3aXRoaW4gMjggZGF5cyBvZiBhcHBsaWNhdGlvbiBkYXRlJ31gLCBgNSBcdTVlNzRcdTU0MDhcdThjYzdcdTY4M2NcdTY3MWZcdTk2NTBcdWZmMWEke2RheXNVbnRpbFF1YWxpZmllZCA8PSAwID8gJ1x1NWRmMlx1NWI4Y1x1NjIxMCcgOiAnXHU1M2VmXHU1NzI4XHU3NTMzXHU4YWNiXHU2NWU1XHU2NzFmIDI4IFx1NTkyOVx1NTE2N1x1NWI4Y1x1NjIxMCd9YCkKICAgICAgICA6IHQoYDUteWVhciBxdWFsaWZ5aW5nIHBlcmlvZDogJHtNYXRoLmFicyhkYXlzVW50aWxRdWFsaWZpZWQpfSBkYXlzIHJlbWFpbmluZyAoZWFybGllc3QgYXBwbGljYXRpb246ICR7Zm9ybWF0RGF0ZShlYXJsaWVzdEFwcERhdGUpfSlgLCBgNSBcdTVlNzRcdTU0MDhcdThjYzdcdTY4M2NcdTY3MWZcdTk2NTBcdWZmMWFcdTVjMWFcdTk5MTggJHtNYXRoLmFicyhkYXlzVW50aWxRdWFsaWZpZWQpfSBcdTU5MjlcdWZmMDhcdTY3MDBcdTY1ZTlcdTc1MzNcdThhY2JcdTY1ZTVcdTY3MWZcdWZmMWEke2Zvcm1hdERhdGUoZWFybGllc3RBcHBEYXRlKX1cdWZmMDlgKSB9LAogICAgeyBzdGF0dXM6IGNoZWNrcy5hYnNlbmNlID8gJ3Bhc3MnIDogJ2ZhaWwnLCB0ZXh0OiBjaGVja3MuYWJzZW5jZQogICAgICA/IHQoYEFic2VuY2VzOiBNYXhpbXVtICR7bWF4QWJzZW5jZUluMTJNb250aHN9IGRheXMgaW4gYW55IHJvbGxpbmcgMTItbW9udGggcGVyaW9kIChsaW1pdDogMTgwIGRheXMpYCwgYFx1N2YzYVx1NWUyZFx1ZmYxYVx1NGVmYlx1NGY1NVx1NmVmZVx1NTJkNSAxMiBcdTUwMGJcdTY3MDhcdTY3MWZcdTk1OTNcdTY3MDBcdTU5MWEgJHttYXhBYnNlbmNlSW4xMk1vbnRoc30gXHU1OTI5XHVmZjA4XHU5NjUwXHU1MjM2XHVmZjFhMTgwIFx1NTkyOVx1ZmYwOWApCiAgICAgIDogdChgQWJzZW5jZXM6ICR7bWF4QWJzZW5jZUluMTJNb250aHN9IGRheXMgaW4gYSAxMi1tb250aCBwZXJpb2QgRVhDRUVEUyB0aGUgMTgwLWRheSBsaW1pdGAsIGBcdTdmM2FcdTVlMmRcdWZmMWExMiBcdTUwMGJcdTY3MDhcdTY3MWZcdTk1OTMgJHttYXhBYnNlbmNlSW4xMk1vbnRoc30gXHU1OTI5XHVmZjBjXHU4ZDg1XHU1MWZhIDE4MCBcdTU5MjlcdTk2NTBcdTUyMzZgKSB9LAogICAgeyBzdGF0dXM6ICFsaWZlVGVzdCA/ICduZXV0cmFsJyA6IGNoZWNrcy5saWZlVGVzdCA/ICdwYXNzJyA6ICdmYWlsJywgdGV4dDogIWxpZmVUZXN0ID8gdCgnTGlmZSBpbiB0aGUgVUsgdGVzdDogTm90IGFuc3dlcmVkJywgJ1x1ODJmMVx1NTcwYlx1NzUxZlx1NmQzYlx1NWUzOFx1OGI1OFx1ODAwM1x1OGE2Nlx1ZmYxYVx1NjcyYVx1NTZkZVx1N2I1NCcpIDogY2hlY2tzLmxpZmVUZXN0ID8gdCgnTGlmZSBpbiB0aGUgVUsgdGVzdDogJyArIChsaWZlVGVzdCA9PT0gJ2V4ZW1wdCcgPyAnRXhlbXB0JyA6ICdQYXNzZWQnKSwgJ1x1ODJmMVx1NTcwYlx1NzUxZlx1NmQzYlx1NWUzOFx1OGI1OFx1ODAwM1x1OGE2Nlx1ZmYxYScgKyAobGlmZVRlc3QgPT09ICdleGVtcHQnID8gJ1x1OGM0MVx1NTE0ZCcgOiAnXHU1ZGYyXHU5MDFhXHU5MDRlJykpIDogdCgnTGlmZSBpbiB0aGUgVUsgdGVzdDogTm90IHlldCBwYXNzZWQnLCAnXHU4MmYxXHU1NzBiXHU3NTFmXHU2ZDNiXHU1ZTM4XHU4YjU4XHU4MDAzXHU4YTY2XHVmZjFhXHU1YzFhXHU2NzJhXHU5MDFhXHU5MDRlJykgfSwKICAgIHsgc3RhdHVzOiAhZW5nTGFuZyA/ICduZXV0cmFsJyA6IGNoZWNrcy5lbmdsaXNoID8gJ3Bhc3MnIDogJ2ZhaWwnLCB0ZXh0OiAhZW5nTGFuZyA/IHQoJ0VuZ2xpc2ggbGFuZ3VhZ2U6IE5vdCBhbnN3ZXJlZCcsICdcdTgyZjFcdThhOWVcdThhOWVcdThhMDBcdWZmMWFcdTY3MmFcdTU2ZGVcdTdiNTQnKSA6IGNoZWNrcy5lbmdsaXNoID8gdCgnRW5nbGlzaCBsYW5ndWFnZSByZXF1aXJlbWVudDogU2F0aXNmaWVkJywgJ1x1ODJmMVx1OGE5ZVx1OGE5ZVx1OGEwMFx1ODk4MVx1NmM0Mlx1ZmYxYVx1NWRmMlx1NmVmZlx1OGRiMycpIDogdCgnRW5nbGlzaCBsYW5ndWFnZSByZXF1aXJlbWVudDogTm90IHlldCBzYXRpc2ZpZWQnLCAnXHU4MmYxXHU4YTllXHU4YTllXHU4YTAwXHU4OTgxXHU2YzQyXHVmZjFhXHU1YzFhXHU2NzJhXHU2ZWZmXHU4ZGIzJykgfSwKICAgIHsgc3RhdHVzOiAhY3JpbWluYWwgPyAnbmV1dHJhbCcgOiBjaGVja3MuY2hhcmFjdGVyID8gJ3Bhc3MnIDogJ2ZhaWwnLCB0ZXh0OiAhY3JpbWluYWwgPyB0KCdHb29kIGNoYXJhY3RlcjogTm90IGFuc3dlcmVkJywgJ1x1ODI2Zlx1NTk3ZFx1NTRjMVx1NjgzY1x1ZmYxYVx1NjcyYVx1NTZkZVx1N2I1NCcpIDogY2hlY2tzLmNoYXJhY3RlciA/IHQoJ0dvb2QgY2hhcmFjdGVyOiBObyBjcmltaW5hbCBjb252aWN0aW9ucycsICdcdTgyNmZcdTU5N2RcdTU0YzFcdTY4M2NcdWZmMWFcdTcxMjFcdTUyMTFcdTRlOGJcdTViOWFcdTdmNmEnKSA6IHQoJ0dvb2QgY2hhcmFjdGVyOiBDcmltaW5hbCByZWNvcmQgZGVjbGFyZWQgLSBzZWVrIGxlZ2FsIGFkdmljZScsICdcdTgyNmZcdTU5N2RcdTU0YzFcdTY4M2NcdWZmMWFcdTVkZjJcdTc1MzNcdTU4MzFcdTUyMTFcdTRlOGJcdThhMThcdTkzMDQgLSBcdThhY2JcdTVjMGJcdTZjNDJcdTZjZDVcdTVmOGJcdTVlZmFcdThiNzAnKSB9CiAgXTsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hlY2tsaXN0JykuaW5uZXJIVE1MID0gY2hlY2tJdGVtcy5tYXAoaXRlbSA9PiBgPGxpPjxkaXYgY2xhc3M9ImNoZWNrLWljb24gJHtpdGVtLnN0YXR1c30iPiR7aXRlbS5zdGF0dXMgPT09ICdwYXNzJyA/ICcmIzEwMDAzOycgOiBpdGVtLnN0YXR1cyA9PT0gJ2ZhaWwnID8gJyYjMTAwMDc7JyA6ICc/J308L2Rpdj48ZGl2PiR7aXRlbS50ZXh0fTwvZGl2PjwvbGk+YCkuam9pbignJyk7CgogIC8vIFRpbWVsaW5lCiAgcmVuZGVyVGltZWxpbmUobGVhdmVTdGFydER0LCBhcHBEYXRlRHQsIHZhbGlkVHJpcHMpOwoKICAvLyBSb2xsaW5nIHRhYmxlCiAgY29uc3QgdGJvZHkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncm9sbGluZ1RhYmxlQm9keScpOwogIGlmICh0YWJsZVJvd3MubGVuZ3RoID09PSAwKSB7CiAgICB0Ym9keS5pbm5lckhUTUwgPSBgPHRyPjx0ZCBjb2xzcGFuPSI0IiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6IzcxODA5NjsiPiR7dCgnTm8gYWJzZW5jZXMgcmVjb3JkZWQnLCAnXHU3MTIxXHU3ZjNhXHU1ZTJkXHU4YTE4XHU5MzA0Jyl9PC90ZD48L3RyPmA7CiAgfSBlbHNlIHsKICAgIHRib2R5LmlubmVySFRNTCA9IHRhYmxlUm93cy5tYXAocm93ID0+IHsKICAgICAgbGV0IHNjID0gJ3NhZmUnLCBzdCA9IHQoJ1dpdGhpbiBsaW1pdCcsICdcdTU3MjhcdTk2NTBcdTUyMzZcdTRlNGJcdTUxNjcnKTsKICAgICAgaWYgKHJvdy5kYXlzID4gMTgwKSB7IHNjID0gJ2Rhbmdlcic7IHN0ID0gdCgnRVhDRUVEUyBMSU1JVCcsICdcdThkODVcdTUxZmFcdTk2NTBcdTUyMzYnKTsgfQogICAgICBlbHNlIGlmIChyb3cuZGF5cyA+IDE1MCkgeyBzYyA9ICd3YXJuaW5nJzsgc3QgPSB0KCdBcHByb2FjaGluZyBsaW1pdCcsICdcdTYzYTVcdThmZDFcdTk2NTBcdTUyMzYnKTsgfQogICAgICBjb25zdCBsYWJlbCA9IHJvdy5pc1dvcnN0ID8gYCA8c3Ryb25nPigke3QoJ3dvcnN0IHdpbmRvdycsICdcdTY3MDBcdTVkZWVcdTdhOTdcdTUzZTMnKX0pPC9zdHJvbmc+YCA6ICcnOwogICAgICByZXR1cm4gYDx0cj48dGQ+JHtmb3JtYXREYXRlKHJvdy5zdGFydCl9JHtsYWJlbH08L3RkPjx0ZD4ke2Zvcm1hdERhdGUocm93LmVuZCl9PC90ZD48dGQgY2xhc3M9IiR7c2N9Ij4ke3Jvdy5kYXlzfTwvdGQ+PHRkIGNsYXNzPSIke3NjfSI+JHtzdH08L3RkPjwvdHI+YDsKICAgIH0pLmpvaW4oJycpOwogIH0KCiAgcmVzdWx0c0VsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ3N0YXJ0JyB9KTsKfQoKZnVuY3Rpb24gcmVuZGVyVGltZWxpbmUoc3RhcnREYXRlLCBlbmREYXRlLCB0cmlwcykgewogIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aW1lbGluZScpOwogIGNvbnN0IG1zUGVyRGF5ID0gODY0MDAwMDA7CiAgY29uc3QgdG90YWxEYXlzID0gTWF0aC5mbG9vcigoZW5kRGF0ZSAtIHN0YXJ0RGF0ZSkgLyBtc1BlckRheSk7CiAgaWYgKHRvdGFsRGF5cyA8PSAwKSB7IGNvbnRhaW5lci5pbm5lckhUTUwgPSAnPHAgc3R5bGU9ImNvbG9yOiM3MTgwOTY7dGV4dC1hbGlnbjpjZW50ZXI7Ij5JbnZhbGlkIGRhdGUgcmFuZ2U8L3A+JzsgcmV0dXJuOyB9CgogIGxldCBhYnNlbmNlQmxvY2tzID0gJyc7CiAgdHJpcHMuZm9yRWFjaCh0cmlwID0+IHsKICAgIGNvbnN0IGVmZmVjdGl2ZURlcCA9IHRyaXAuZGVwRGF0ZSA8IHN0YXJ0RGF0ZSA/IHN0YXJ0RGF0ZSA6IHRyaXAuZGVwRGF0ZTsKICAgIGNvbnN0IGVmZmVjdGl2ZVJldCA9IHRyaXAucmV0RGF0ZSA+IGVuZERhdGUgPyBlbmREYXRlIDogdHJpcC5yZXREYXRlOwogICAgaWYgKGVmZmVjdGl2ZVJldCA8PSBlZmZlY3RpdmVEZXApIHJldHVybjsKICAgIGNvbnN0IGxlZnQgPSAoKGVmZmVjdGl2ZURlcCAtIHN0YXJ0RGF0ZSkgLyBtc1BlckRheSkgLyB0b3RhbERheXMgKiAxMDA7CiAgICBjb25zdCB3aWR0aCA9ICgoZWZmZWN0aXZlUmV0IC0gZWZmZWN0aXZlRGVwKSAvIG1zUGVyRGF5KSAvIHRvdGFsRGF5cyAqIDEwMDsKICAgIGFic2VuY2VCbG9ja3MgKz0gYDxkaXYgY2xhc3M9InRpbWVsaW5lLWFic2VuY2UiIHN0eWxlPSJsZWZ0OiR7bGVmdH0lO3dpZHRoOiR7TWF0aC5tYXgod2lkdGgsIDAuNSl9JTsiIHRpdGxlPSIke3RyaXAuZWZmZWN0aXZlRGF5c30gJHt0KCdkYXlzJywgJ1x1NTkyOScpfSI+JHt0cmlwLmVmZmVjdGl2ZURheXMgPiAwICYmIHdpZHRoID4gNCA/IHRyaXAuZWZmZWN0aXZlRGF5cyArICdkJyA6ICcnfTwvZGl2PmA7CiAgfSk7CgogIGxldCB5ZWFyTWFya2VycyA9ICcnOwogIGZvciAobGV0IHkgPSBzdGFydERhdGUuZ2V0RnVsbFllYXIoKSArIDE7IHkgPD0gZW5kRGF0ZS5nZXRGdWxsWWVhcigpOyB5KyspIHsKICAgIGNvbnN0IHlkID0gbmV3IERhdGUoeSwgMCwgMSk7CiAgICBpZiAoeWQgPiBzdGFydERhdGUgJiYgeWQgPCBlbmREYXRlKSB7CiAgICAgIGNvbnN0IHBvcyA9ICgoeWQgLSBzdGFydERhdGUpIC8gbXNQZXJEYXkpIC8gdG90YWxEYXlzICogMTAwOwogICAgICB5ZWFyTWFya2VycyArPSBgPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7bGVmdDoke3Bvc30lO3RvcDowO2hlaWdodDoxMDAlO3dpZHRoOjFweDtiYWNrZ3JvdW5kOnJnYmEoMCwwLDAsMC4xKTsiPjwvZGl2PmA7CiAgICB9CiAgfQoKICBjb250YWluZXIuaW5uZXJIVE1MID0gYAogICAgPGRpdiBjbGFzcz0idGltZWxpbmUtbGFiZWxzIj48c3Bhbj4ke2Zvcm1hdERhdGUoc3RhcnREYXRlKX0gKCR7dCgnTGVhdmUgZ3JhbnRlZCcsICdcdTdjM2RcdThiNDlcdTczNzJcdTYyNzknKX0pPC9zcGFuPjxzcGFuPiR7Zm9ybWF0RGF0ZShlbmREYXRlKX0gKCR7dCgnQXBwbGljYXRpb24nLCAnXHU3NTMzXHU4YWNiJyl9KTwvc3Bhbj48L2Rpdj4KICAgIDxkaXYgY2xhc3M9InRpbWVsaW5lLWJhciI+JHt5ZWFyTWFya2Vyc30ke2Fic2VuY2VCbG9ja3N9PC9kaXY+YDsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT0gSU5JVCA9PT09PT09PT09PT09PT09PT09PQppbml0RGF0ZUlucHV0KCdsZWF2ZVN0YXJ0RGF0ZUlucHV0JywgJ2xlYXZlU3RhcnREYXRlJywgJ2xlYXZlU3RhcnREYXRlSGludCcpOwppbml0RGF0ZUlucHV0KCdhcHBsaWNhdGlvbkRhdGVJbnB1dCcsICdhcHBsaWNhdGlvbkRhdGUnLCAnYXBwbGljYXRpb25EYXRlSGludCcpOwphZGRUcmlwKCk7CgovLyBFeHBvc2UgZnVuY3Rpb25zIGdsb2JhbGx5IGZvciBvbmNsaWNrIGhhbmRsZXJzCgpmdW5jdGlvbiBsb2FkU2NyaXB0KHNyYykgewogIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc2NyaXB0W3NyYz0iJyArIHNyYyArICciXScpKSB7IHJlc29sdmUoKTsgcmV0dXJuOyB9CiAgICBjb25zdCBzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CiAgICBzLnNyYyA9IHNyYzsKICAgIHMub25sb2FkID0gcmVzb2x2ZTsKICAgIHMub25lcnJvciA9IHJlamVjdDsKICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQocyk7CiAgfSk7Cn0KCmFzeW5jIGZ1bmN0aW9uIGV4cG9ydFBERigpIHsKICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYnRuLWV4cG9ydCcpOwogIGNvbnN0IG9yaWdUZXh0ID0gYnRuLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKS50ZXh0Q29udGVudDsKICBidG4uZGlzYWJsZWQgPSB0cnVlOwogIGJ0bi5xdWVyeVNlbGVjdG9yKCdzcGFuJykudGV4dENvbnRlbnQgPSBjdXJyZW50TGFuZyA9PT0gJ3poJyA/ICdcdTZiNjNcdTU3MjhcdTc1MWZcdTYyMTAgUERGLi4uJyA6ICdHZW5lcmF0aW5nIFBERi4uLic7CgogIHRyeSB7CiAgICBhd2FpdCBsb2FkU2NyaXB0KCdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9odG1sMmNhbnZhcy8xLjQuMS9odG1sMmNhbnZhcy5taW4uanMnKTsKICAgIGF3YWl0IGxvYWRTY3JpcHQoJ2h0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2pzcGRmLzIuNS4xL2pzcGRmLnVtZC5taW4uanMnKTsKCiAgICBjb25zdCB7IGpzUERGIH0gPSB3aW5kb3cuanNwZGY7CiAgICBjb25zdCBwZGYgPSBuZXcganNQREYoJ3AnLCAnbW0nLCAnYTQnKTsKICAgIGNvbnN0IHBhZ2VXID0gMjEwOwogICAgY29uc3QgcGFnZUggPSAyOTc7CiAgICBjb25zdCBtYXJnaW4gPSAxNTsKICAgIGNvbnN0IGNvbnRlbnRXID0gcGFnZVcgLSBtYXJnaW4gKiAyOwoKICAgIC8vIEJ1aWxkIGV2ZXJ5dGhpbmcgYXMgSFRNTCBmb3IgaHRtbDJjYW52YXMgKGZpeGVzIENKSyBmb250IGlzc3VlKQogICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICBjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9ICdwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi05OTk5cHg7dG9wOjA7d2lkdGg6ODYwcHg7YmFja2dyb3VuZDp3aGl0ZTtwYWRkaW5nOjA7JzsKCiAgICAvLyBIZWFkZXIgYXMgSFRNTAogICAgY29uc3QgaGVhZGVyVGl0bGUgPSBjdXJyZW50TGFuZyA9PT0gJ3poJyA/ICdCTk8gXHU2YzM4XHU0ZTQ1XHU1YzQ1XHU3NTU5XHU5MDIzXHU3ZThjXHU1YzQ1XHU0ZjRmXHU2YWEyXHU2N2U1XHU1NjY4JyA6ICdCTk8gSUxSIENvbnRpbnVvdXMgUmVzaWRlbmNlIENoZWNrZXInOwogICAgY29uc3QgYmV0YVRleHQgPSBjdXJyZW50TGFuZyA9PT0gJ3poJyA/ICdcdTZlMmNcdThhNjZcdTcyNDgnIDogJ0JldGEnOwogICAgY29uc3QgcmVwb3J0TGFiZWwgPSBjdXJyZW50TGFuZyA9PT0gJ3poJyA/ICdcdTU4MzFcdTU0NGFcdTY1ZTVcdTY3MWYnIDogJ1JlcG9ydCBkYXRlJzsKICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKS50b0xvY2FsZURhdGVTdHJpbmcoY3VycmVudExhbmcgPT09ICd6aCcgPyAnemgtSEsnIDogJ2VuLUdCJyk7CiAgICBjb25zdCBkaXNjbGFpbWVyVGV4dCA9IGN1cnJlbnRMYW5nID09PSAnemgnID8gJ1x1NmI2NFx1NTgzMVx1NTQ0YVx1NTBjNVx1NGY5Ylx1NTNjM1x1ODAwM1x1ZmYwY1x1NGUwZFx1NjljYlx1NjIxMFx1NmNkNVx1NWY4Ylx1NjEwZlx1ODk4Ylx1MzAwMicgOiAnVGhpcyByZXBvcnQgaXMgZm9yIHJlZmVyZW5jZSBvbmx5IGFuZCBkb2VzIG5vdCBjb25zdGl0dXRlIGxlZ2FsIGFkdmljZS4nOwoKICAgIGNvbnN0IGhlYWRlckVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICBoZWFkZXJFbC5zdHlsZS5jc3NUZXh0ID0gJ2JhY2tncm91bmQ6IzFhMzY1ZDtjb2xvcjp3aGl0ZTtwYWRkaW5nOjIwcHggMjRweCAxNnB4O21hcmdpbi1ib3R0b206MjBweDtmb250LWZhbWlseTpJbnRlcixzeXN0ZW0tdWksc2Fucy1zZXJpZjsnOwogICAgaGVhZGVyRWwuaW5uZXJIVE1MID0gJzxkaXYgc3R5bGU9ImRpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjthbGlnbi1pdGVtczpmbGV4LXN0YXJ0OyI+JyArCiAgICAgICc8ZGl2PjxkaXYgc3R5bGU9ImNvbG9yOiNlOGM4NzI7Zm9udC1zaXplOjIwcHg7Zm9udC13ZWlnaHQ6NzAwO21hcmdpbi1ib3R0b206NHB4OyI+JyArIGhlYWRlclRpdGxlICsKICAgICAgJyA8c3BhbiBzdHlsZT0iZm9udC1zaXplOjExcHg7YmFja2dyb3VuZDojZThjODcyO2NvbG9yOiMxYTM2NWQ7cGFkZGluZzoycHggNnB4O2JvcmRlci1yYWRpdXM6M3B4O21hcmdpbi1sZWZ0OjZweDt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7Ij4nICsgYmV0YVRleHQgKyAnPC9zcGFuPjwvZGl2PicgKwogICAgICAnPGRpdiBzdHlsZT0iZm9udC1zaXplOjEycHg7b3BhY2l0eTowLjg1OyI+RHVhbCBISyBVSyBMZWdhbCBTZXJ2aWNlcyB8IGR1YWxoa3VrbGVnYWwuY28udWs8L2Rpdj48L2Rpdj4nICsKICAgICAgJzxkaXYgc3R5bGU9InRleHQtYWxpZ246cmlnaHQ7Zm9udC1zaXplOjExcHg7b3BhY2l0eTowLjg7Ij4nICsgcmVwb3J0TGFiZWwgKyAnPGJyPjxzdHJvbmc+JyArIHRvZGF5ICsgJzwvc3Ryb25nPjwvZGl2PjwvZGl2Pic7CiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaGVhZGVyRWwpOwoKICAgIC8vIENsb25lIGlucHV0IGNhcmRzIChmaXJzdCAzKQogICAgY29uc3QgY2FyZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjYm5vLWlsci1jaGVja2VyIC5tYWluID4gLmNhcmQnKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5taW4oMywgY2FyZHMubGVuZ3RoKTsgaSsrKSB7CiAgICAgIGNvbnN0IGNsb25lID0gY2FyZHNbaV0uY2xvbmVOb2RlKHRydWUpOwogICAgICBjbG9uZS5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnMTJweCc7CiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjbG9uZSk7CiAgICB9CgogICAgLy8gQ2xvbmUgcmVzdWx0cyBzZWN0aW9uCiAgICBjb25zdCByZXN1bHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Jlc3VsdHMnKTsKICAgIGNvbnN0IHJlc3VsdHNDbG9uZSA9IHJlc3VsdHMuY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgZXhwb3J0QnRuQ2xvbmUgPSByZXN1bHRzQ2xvbmUucXVlcnlTZWxlY3RvcignI2V4cG9ydEJ0bkNvbnRhaW5lcicpOwogICAgaWYgKGV4cG9ydEJ0bkNsb25lKSBleHBvcnRCdG5DbG9uZS5yZW1vdmUoKTsKICAgIHJlc3VsdHNDbG9uZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsKICAgIHJlc3VsdHNDbG9uZS5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7CiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQocmVzdWx0c0Nsb25lKTsKCiAgICAvLyBGb290ZXIgYXMgSFRNTAogICAgY29uc3QgZm9vdGVyRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgIGZvb3RlckVsLnN0eWxlLmNzc1RleHQgPSAnbWFyZ2luLXRvcDoyMHB4O3BhZGRpbmc6MTJweCAyNHB4O2JvcmRlci10b3A6MXB4IHNvbGlkICNkZGQ7Zm9udC1zaXplOjEwcHg7Y29sb3I6Izk5OTtmb250LWZhbWlseTpJbnRlcixzeXN0ZW0tdWksc2Fucy1zZXJpZjtkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47JzsKICAgIGZvb3RlckVsLmlubmVySFRNTCA9ICc8c3Bhbj4nICsgZGlzY2xhaW1lclRleHQgKyAnPC9zcGFuPjxzcGFuPkR1YWwgSEsgVUsgTGVnYWwgU2VydmljZXM8L3NwYW4+JzsKICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChmb290ZXJFbCk7CgogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjb250YWluZXIpOwoKICAgIGNvbnN0IGNhbnZhcyA9IGF3YWl0IGh0bWwyY2FudmFzKGNvbnRhaW5lciwgewogICAgICBzY2FsZTogMiwKICAgICAgdXNlQ09SUzogdHJ1ZSwKICAgICAgYmFja2dyb3VuZENvbG9yOiAnI2ZmZmZmZicsCiAgICAgIGxvZ2dpbmc6IGZhbHNlLAogICAgICBvbmNsb25lOiBmdW5jdGlvbihjbG9uZWREb2MpIHsKICAgICAgICB2YXIgbGFuZ0tleSA9ICdkYXRhLScgKyBjdXJyZW50TGFuZzsKICAgICAgICBjbG9uZWREb2MucXVlcnlTZWxlY3RvckFsbCgnWycgKyBsYW5nS2V5ICsgJ10nKS5mb3JFYWNoKGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ09QVElPTicpIHJldHVybjsKICAgICAgICAgIGlmIChlbC5jbGFzc0xpc3QgJiYgKGVsLmNsYXNzTGlzdC5jb250YWlucygnc3VjY2VzcycpIHx8IGVsLmNsYXNzTGlzdC5jb250YWlucygnZXJyb3InKSkpIHJldHVybjsKICAgICAgICAgIGVsLnRleHRDb250ZW50ID0gZWwuZ2V0QXR0cmlidXRlKGxhbmdLZXkpOwogICAgICAgIH0pOwogICAgICAgIGNsb25lZERvYy5xdWVyeVNlbGVjdG9yQWxsKCdzZWxlY3Qgb3B0aW9uWycgKyBsYW5nS2V5ICsgJ10nKS5mb3JFYWNoKGZ1bmN0aW9uKG9wdCkgewogICAgICAgICAgb3B0LnRleHRDb250ZW50ID0gb3B0LmdldEF0dHJpYnV0ZShsYW5nS2V5KTsKICAgICAgICB9KTsKICAgICAgfQogICAgfSk7CgogICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChjb250YWluZXIpOwoKICAgIGNvbnN0IGltZ1cgPSBjb250ZW50VzsKICAgIGNvbnN0IHB4UGVyTW0gPSBjYW52YXMud2lkdGggLyBjb250ZW50VzsKICAgIGxldCBzcmNZID0gMDsKICAgIGNvbnN0IHNyY1RvdGFsSCA9IGNhbnZhcy5oZWlnaHQ7CiAgICBsZXQgZmlyc3RQYWdlID0gdHJ1ZTsKCiAgICB3aGlsZSAoc3JjWSA8IHNyY1RvdGFsSCkgewogICAgICBpZiAoIWZpcnN0UGFnZSkgcGRmLmFkZFBhZ2UoKTsKICAgICAgY29uc3QgYXZhaWxIID0gcGFnZUggLSBtYXJnaW4gKiAyOwogICAgICBjb25zdCBzbGljZVB4ID0gTWF0aC5taW4oYXZhaWxIICogcHhQZXJNbSwgc3JjVG90YWxIIC0gc3JjWSk7CiAgICAgIGNvbnN0IHNsaWNlSCA9IHNsaWNlUHggLyBweFBlck1tOwoKICAgICAgY29uc3Qgc2xpY2VDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsKICAgICAgc2xpY2VDYW52YXMud2lkdGggPSBjYW52YXMud2lkdGg7CiAgICAgIHNsaWNlQ2FudmFzLmhlaWdodCA9IE1hdGguY2VpbChzbGljZVB4KTsKICAgICAgY29uc3QgY3R4ID0gc2xpY2VDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTsKICAgICAgY3R4LmRyYXdJbWFnZShjYW52YXMsIDAsIHNyY1ksIGNhbnZhcy53aWR0aCwgc2xpY2VQeCwgMCwgMCwgY2FudmFzLndpZHRoLCBzbGljZVB4KTsKCiAgICAgIGNvbnN0IHNsaWNlRGF0YSA9IHNsaWNlQ2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvanBlZycsIDAuOTUpOwogICAgICBwZGYuYWRkSW1hZ2Uoc2xpY2VEYXRhLCAnSlBFRycsIG1hcmdpbiwgbWFyZ2luLCBjb250ZW50Vywgc2xpY2VIKTsKCiAgICAgIHNyY1kgKz0gc2xpY2VQeDsKICAgICAgZmlyc3RQYWdlID0gZmFsc2U7CiAgICB9CgogICAgY29uc3QgZmlsZW5hbWUgPSAnQk5PLUlMUi1SZXNpZGVuY2UtQ2hlY2stJyArIG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zbGljZSgwLDEwKSArICcucGRmJzsKICAgIHBkZi5zYXZlKGZpbGVuYW1lKTsKCiAgfSBjYXRjaCAoZXJyKSB7CiAgICBjb25zb2xlLmVycm9yKCdQREYgZXhwb3J0IGVycm9yOicsIGVycik7CiAgICBhbGVydChjdXJyZW50TGFuZyA9PT0gJ3poJyA/ICdQREYgXHU1MzJmXHU1MWZhXHU1OTMxXHU2NTU3XHVmZjBjXHU4YWNiXHU1MThkXHU4YTY2XHU0ZTAwXHU2YjIxXHUzMDAyJyA6ICdQREYgZXhwb3J0IGZhaWxlZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTsKICB9IGZpbmFsbHkgewogICAgYnRuLmRpc2FibGVkID0gZmFsc2U7CiAgICBidG4ucXVlcnlTZWxlY3Rvcignc3BhbicpLnRleHRDb250ZW50ID0gb3JpZ1RleHQ7CiAgfQp9Cgp3aW5kb3cuc2V0TGFuZyA9IHNldExhbmc7CndpbmRvdy5hZGRUcmlwID0gYWRkVHJpcDsKd2luZG93LnJlbW92ZVRyaXAgPSByZW1vdmVUcmlwOwp3aW5kb3cuY2FsY3VsYXRlID0gY2FsY3VsYXRlOwp3aW5kb3cuZXhwb3J0UERGID0gZXhwb3J0UERGOwoKc2V0TGFuZyhjdXJyZW50TGFuZyk7Cn0pKCk7Cg==
