LyoKICogQ29weXJpZ2h0IChDKSAyMDA1IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IChDKSAyMDA3IFN0ZWZhbiBE9nNpbmdlcihmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCi8qIFNlZSBjb21tZW50IGluIGRsbHMvZDNkOS90ZXN0cy92aXN1YWwuYyBmb3IgZ2VuZXJhbCBndWlkZWxpbmVzICovCgojZGVmaW5lIENPQkpNQUNST1MKI2luY2x1ZGUgPGQzZDguaD4KI2luY2x1ZGUgPGR4ZXJyOC5oPgojaW5jbHVkZSAid2luZS90ZXN0LmgiCgpzdGF0aWMgSE1PRFVMRSBkM2Q4X2hhbmRsZSA9IDA7CgpzdGF0aWMgSFdORCBjcmVhdGVfd2luZG93KHZvaWQpCnsKICAgIFdORENMQVNTIHdjID0gezB9OwogICAgSFdORCByZXQ7CiAgICB3Yy5scGZuV25kUHJvYyA9ICZEZWZXaW5kb3dQcm9jOwogICAgd2MubHBzekNsYXNzTmFtZSA9ICJkM2Q4X3Rlc3Rfd2MiOwogICAgUmVnaXN0ZXJDbGFzcygmd2MpOwoKICAgIHJldCA9IENyZWF0ZVdpbmRvdygiZDNkOF90ZXN0X3djIiwgImQzZDhfdGVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgIFdTX01BWElNSVpFIHwgV1NfVklTSUJMRSB8IFdTX0NBUFRJT04gLCAwLCAwLCA2NDAsIDQ4MCwgMCwgMCwgMCwgMCk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRFdPUkQgZ2V0UGl4ZWxDb2xvcihJRGlyZWN0M0REZXZpY2U4ICpkZXZpY2UsIFVJTlQgeCwgVUlOVCB5KQp7CiAgICBEV09SRCByZXQ7CiAgICBJRGlyZWN0M0RTdXJmYWNlOCAqc3VyZjsKICAgIElEaXJlY3QzRFRleHR1cmU4ICp0ZXg7CiAgICBIUkVTVUxUIGhyOwogICAgRDNETE9DS0VEX1JFQ1QgbG9ja2VkUmVjdDsKICAgIFJFQ1QgcmVjdFRvTG9jayA9IHt4LCB5LCB4KzEsIHkrMX07CgogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0NyZWF0ZVRleHR1cmUoZGV2aWNlLCA2NDAsIDQ4MCwgMSAvKiBMZXZlbHMgKi8sIDAgLyogdXNhZ2UgKi8sIEQzREZNVF9BOFI4RzhCOCwgRDNEUE9PTF9TWVNURU1NRU0sICZ0ZXgpOwogICAgaWYoRkFJTEVEKGhyKSB8fCAhdGV4ICkgIC8qIFRoaXMgaXMgbm90IGEgdGVzdCAqLwogICAgewogICAgICAgIHRyYWNlKCJDYW4ndCBjcmVhdGUgYW4gb2Zmc2NyZWVuIHBsYWluIHN1cmZhY2UgdG8gcmVhZCB0aGUgcmVuZGVyIHRhcmdldCBkYXRhLCBocj0lc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgICAgICByZXR1cm4gMHhkZWFkYmVlZjsKICAgIH0KICAgIGhyID0gSURpcmVjdDNEVGV4dHVyZThfR2V0U3VyZmFjZUxldmVsKHRleCwgMCwgJnN1cmYpOwogICAgaWYoRkFJTEVEKGhyKSB8fCAhdGV4ICkgIC8qIFRoaXMgaXMgbm90IGEgdGVzdCAqLwogICAgewogICAgICAgIHRyYWNlKCJDYW4ndCBnZXQgc3VyZmFjZSBmcm9tIHRleHR1cmUsIGhyPSVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgICAgIHJldCA9IDB4ZGVhZGJlZWU7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0dldEZyb250QnVmZmVyKGRldmljZSwgc3VyZik7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIHRyYWNlKCJDYW4ndCByZWFkIHRoZSBmcm9udCBidWZmZXIgZGF0YSwgaHI9JXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICAgICAgcmV0ID0gMHhkZWFkYmVlZDsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBociA9IElEaXJlY3QzRFN1cmZhY2U4X0xvY2tSZWN0KHN1cmYsICZsb2NrZWRSZWN0LCAmcmVjdFRvTG9jaywgRDNETE9DS19SRUFET05MWSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIHRyYWNlKCJDYW4ndCBsb2NrIHRoZSBvZmZzY3JlZW4gc3VyZmFjZSwgaHI9JXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICAgICAgcmV0ID0gMHhkZWFkYmVlYzsKICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIC8qIFJlbW92ZSB0aGUgWCBjaGFubmVsIGZvciBub3cuIERpcmVjdFggYW5kIE9wZW5HTCBoYXZlIGRpZmZlcmVudCBpZGVhcyBob3cgdG8gdHJlYXQgaXQgYXBwYXJlbnRseSwgYW5kIGl0IGlzbid0CiAgICAgKiByZWFsbHkgaW1wb3J0YW50IGZvciB0aGVzZSB0ZXN0cwogICAgICovCiAgICByZXQgPSAoKERXT1JEICopIGxvY2tlZFJlY3QucEJpdHMpWzBdICYgMHgwMGZmZmZmZjsKICAgIGhyID0gSURpcmVjdDNEU3VyZmFjZThfVW5sb2NrUmVjdChzdXJmKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgdHJhY2UoIkNhbid0IHVubG9jayB0aGUgb2Zmc2NyZWVuIHN1cmZhY2UsIGhyPSVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgfQoKb3V0OgogICAgaWYoc3VyZikgSURpcmVjdDNEU3VyZmFjZThfUmVsZWFzZShzdXJmKTsKICAgIGlmKHRleCkgSURpcmVjdDNEVGV4dHVyZThfUmVsZWFzZSh0ZXgpOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIElEaXJlY3QzRERldmljZTggKmluaXRfZDNkOCh2b2lkKQp7CiAgICBJRGlyZWN0M0Q4ICogKF9fc3RkY2FsbCAqIGQzZDhfY3JlYXRlKShVSU5UIFNES1ZlcnNpb24pID0gMDsKICAgIElEaXJlY3QzRDggKmQzZDhfcHRyID0gMDsKICAgIElEaXJlY3QzRERldmljZTggKmRldmljZV9wdHIgPSAwOwogICAgRDNEUFJFU0VOVF9QQVJBTUVURVJTIHByZXNlbnRfcGFyYW1ldGVyczsKICAgIEhSRVNVTFQgaHI7CgogICAgZDNkOF9jcmVhdGUgPSAodm9pZCAqKUdldFByb2NBZGRyZXNzKGQzZDhfaGFuZGxlLCAiRGlyZWN0M0RDcmVhdGU4Iik7CiAgICBvayhkM2Q4X2NyZWF0ZSAhPSBOVUxMLCAiRmFpbGVkIHRvIGdldCBhZGRyZXNzIG9mIERpcmVjdDNEQ3JlYXRlOFxuIik7CiAgICBpZiAoIWQzZDhfY3JlYXRlKSByZXR1cm4gTlVMTDsKCiAgICBkM2Q4X3B0ciA9IGQzZDhfY3JlYXRlKEQzRF9TREtfVkVSU0lPTik7CiAgICBvayhkM2Q4X3B0ciAhPSBOVUxMLCAiRmFpbGVkIHRvIGNyZWF0ZSBJRGlyZWN0M0Q4IG9iamVjdFxuIik7CiAgICBpZiAoIWQzZDhfcHRyKSByZXR1cm4gTlVMTDsKCiAgICBaZXJvTWVtb3J5KCZwcmVzZW50X3BhcmFtZXRlcnMsIHNpemVvZihwcmVzZW50X3BhcmFtZXRlcnMpKTsKICAgIHByZXNlbnRfcGFyYW1ldGVycy5XaW5kb3dlZCA9IEZBTFNFOwogICAgcHJlc2VudF9wYXJhbWV0ZXJzLmhEZXZpY2VXaW5kb3cgPSBjcmVhdGVfd2luZG93KCk7CiAgICBwcmVzZW50X3BhcmFtZXRlcnMuU3dhcEVmZmVjdCA9IEQzRFNXQVBFRkZFQ1RfRElTQ0FSRDsKICAgIHByZXNlbnRfcGFyYW1ldGVycy5CYWNrQnVmZmVyV2lkdGggPSA2NDA7CiAgICBwcmVzZW50X3BhcmFtZXRlcnMuQmFja0J1ZmZlckhlaWdodCA9IDQ4MDsKICAgIHByZXNlbnRfcGFyYW1ldGVycy5CYWNrQnVmZmVyRm9ybWF0ID0gRDNERk1UX1g4UjhHOEI4OwoKICAgIGhyID0gSURpcmVjdDNEOF9DcmVhdGVEZXZpY2UoZDNkOF9wdHIsIEQzREFEQVBURVJfREVGQVVMVCwgRDNEREVWVFlQRV9IQUwsIHByZXNlbnRfcGFyYW1ldGVycy5oRGV2aWNlV2luZG93LCBEM0RDUkVBVEVfU09GVFdBUkVfVkVSVEVYUFJPQ0VTU0lORywgJnByZXNlbnRfcGFyYW1ldGVycywgJmRldmljZV9wdHIpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNEX0NyZWF0ZURldmljZSByZXR1cm5lZDogJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgcmV0dXJuIGRldmljZV9wdHI7Cn0KCnN0cnVjdCB2ZXJ0ZXgKewogICAgZmxvYXQgeCwgeSwgejsKICAgIERXT1JEIGRpZmZ1c2U7Cn07CgpzdHJ1Y3QgbnZlcnRleAp7CiAgICBmbG9hdCB4LCB5LCB6OwogICAgZmxvYXQgbngsIG55LCBuejsKICAgIERXT1JEIGRpZmZ1c2U7Cn07CgpzdGF0aWMgdm9pZCBsaWdodGluZ190ZXN0KElEaXJlY3QzRERldmljZTggKmRldmljZSkKewogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIGZ2ZiA9IEQzREZWRl9YWVogfCBEM0RGVkZfRElGRlVTRTsKICAgIERXT1JEIG5mdmYgPSBEM0RGVkZfWFlaIHwgRDNERlZGX0RJRkZVU0UgfCBEM0RGVkZfTk9STUFMOwogICAgRFdPUkQgY29sb3I7CgogICAgZmxvYXQgbWF0WzE2XSA9IHsgMS4wLCAwLjAsIDAuMCwgMC4wLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAxLjAsIDAuMCwgMC4wLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjAsIDEuMCwgMC4wLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjAsIDAuMCwgMS4wIH07CgogICAgc3RydWN0IHZlcnRleCB1bmxpdHF1YWRbXSA9CiAgICB7CiAgICAgICAgey0xLjAsICAtMS4wLCAgICAwLjEsICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZmZmMDAwMH0sCiAgICAgICAgey0xLjAsICAgMC4wLCAgICAwLjEsICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZmZmMDAwMH0sCiAgICAgICAgeyAwLjAsICAgMC4wLCAgICAwLjEsICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZmZmMDAwMH0sCiAgICAgICAgeyAwLjAsICAtMS4wLCAgICAwLjEsICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZmZmMDAwMH0sCiAgICB9OwogICAgc3RydWN0IHZlcnRleCBsaXRxdWFkW10gPQogICAgewogICAgICAgIHstMS4wLCAgIDAuMCwgICAgMC4xLCAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZmYwMGZmMDB9LAogICAgICAgIHstMS4wLCAgIDEuMCwgICAgMC4xLCAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZmYwMGZmMDB9LAogICAgICAgIHsgMC4wLCAgIDEuMCwgICAgMC4xLCAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZmYwMGZmMDB9LAogICAgICAgIHsgMC4wLCAgIDAuMCwgICAgMC4xLCAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZmYwMGZmMDB9LAogICAgfTsKICAgIHN0cnVjdCBudmVydGV4IHVubGl0bnF1YWRbXSA9CiAgICB7CiAgICAgICAgeyAwLjAsICAtMS4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZjAwMDBmZn0sCiAgICAgICAgeyAwLjAsICAgMC4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZjAwMDBmZn0sCiAgICAgICAgeyAxLjAsICAgMC4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZjAwMDBmZn0sCiAgICAgICAgeyAxLjAsICAtMS4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZjAwMDBmZn0sCiAgICB9OwogICAgc3RydWN0IG52ZXJ0ZXggbGl0bnF1YWRbXSA9CiAgICB7CiAgICAgICAgeyAwLjAsICAgMC4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZmZmZmYwMH0sCiAgICAgICAgeyAwLjAsICAgMS4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZmZmZmYwMH0sCiAgICAgICAgeyAxLjAsICAgMS4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZmZmZmYwMH0sCiAgICAgICAgeyAxLjAsICAgMC4wLCAgICAwLjEsICAgMS4wLCAgICAxLjAsICAgIDEuMCwgICAgMHhmZmZmZmYwMH0sCiAgICB9OwogICAgV09SRCBJbmRpY2VzW10gPSB7MCwgMSwgMiwgMiwgMywgMH07CgogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0NsZWFyKGRldmljZSwgMCwgTlVMTCwgRDNEQ0xFQVJfVEFSR0VULCAweGZmZmZmZmZmLCAwLjAsIDApOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9DbGVhciBmYWlsZWQgd2l0aCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAvKiBTZXR1cCBzb21lIHN0YXRlcyB0aGF0IG1heSBjYXVzZSBpc3N1ZXMgKi8KICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRUcmFuc2Zvcm0oZGV2aWNlLCBEM0RUU19XT1JMRE1BVFJJWCgwKSwgKEQzRE1BVFJJWCAqKSBtYXQpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9TZXRUcmFuc2Zvcm0gcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0VHJhbnNmb3JtKGRldmljZSwgRDNEVFNfVklFVywgKEQzRE1BVFJJWCAqKW1hdCk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFRyYW5zZm9ybSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRUcmFuc2Zvcm0oZGV2aWNlLCBEM0RUU19QUk9KRUNUSU9OLCAoRDNETUFUUklYICopIG1hdCk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFRyYW5zZm9ybSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0NMSVBQSU5HLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfWkVOQUJMRSwgRkFMU0UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR0VOQUJMRSwgRkFMU0UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX1NURU5DSUxFTkFCTEUsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19BTFBIQVRFU1RFTkFCTEUsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19BTFBIQUJMRU5ERU5BQkxFLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfQ1VMTE1PREUsIEQzRENVTExfTk9ORSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlIGZhaWxlZCB3aXRoICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfQ09MT1JXUklURUVOQUJMRSwgRDNEQ09MT1JXUklURUVOQUJMRURfUkVEIHwgRDNEQ09MT1JXUklURUVOQUJMRURfR1JFRU4gfCBEM0RDT0xPUldSSVRFRU5BQkxFRF9CTFVFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUgZmFpbGVkIHdpdGggJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFZlcnRleFNoYWRlcihkZXZpY2UsIGZ2Zik7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFZlcnRleFNoYWRlciByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICBociA9IElEaXJlY3QzRERldmljZThfQmVnaW5TY2VuZShkZXZpY2UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9CZWdpblNjZW5lIGZhaWxlZCB3aXRoICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaWYoaHIgPT0gRDNEX09LKQogICAgewogICAgICAgIC8qIE5vIGxpZ2h0cyBhcmUgZGVmaW5lZC4uLiBUaGF0IG1lYW5zLCBsaXQgdmVydGljZXMgc2hvdWxkIGJlIGVudGlyZWx5IGJsYWNrICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfTElHSFRJTkcsIEZBTFNFKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKGRldmljZSwgRDNEUFRfVFJJQU5HTEVMSVNULCAwIC8qIE1pbkluZGV4ICovLCA0IC8qIE51bVZlcnRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiAvKlByaW1Db3VudCAqLywgSW5kaWNlcywgRDNERk1UX0lOREVYMTYsIHVubGl0cXVhZCwgc2l6ZW9mKHVubGl0cXVhZFswXSkpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfRHJhd0luZGV4ZWRQcmltaXRpdmVVUCBmYWlsZWQgd2l0aCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfTElHSFRJTkcsIFRSVUUpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0RyYXdJbmRleGVkUHJpbWl0aXZlVVAoZGV2aWNlLCBEM0RQVF9UUklBTkdMRUxJU1QsIDAgLyogTWluSW5kZXggKi8sIDQgLyogTnVtVmVydHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyIC8qUHJpbUNvdW50ICovLCBJbmRpY2VzLCBEM0RGTVRfSU5ERVgxNiwgbGl0cXVhZCwgc2l6ZW9mKGxpdHF1YWRbMF0pKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X0RyYXdJbmRleGVkUHJpbWl0aXZlVVAgZmFpbGVkIHdpdGggJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRWZXJ0ZXhTaGFkZXIoZGV2aWNlLCBuZnZmKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFZlcnRleFNoYWRlciBmYWlsZWQgd2l0aCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfTElHSFRJTkcsIEZBTFNFKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKGRldmljZSwgRDNEUFRfVFJJQU5HTEVMSVNULCAwIC8qIE1pbkluZGV4ICovLCA0IC8qIE51bVZlcnRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiAvKlByaW1Db3VudCAqLywgSW5kaWNlcywgRDNERk1UX0lOREVYMTYsIHVubGl0bnF1YWQsIHNpemVvZih1bmxpdG5xdWFkWzBdKSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQIGZhaWxlZCB3aXRoICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwoKICAgICAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19MSUdIVElORywgVFJVRSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgICAgICBociA9IElEaXJlY3QzRERldmljZThfRHJhd0luZGV4ZWRQcmltaXRpdmVVUChkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgMCAvKiBNaW5JbmRleCAqLywgNCAvKiBOdW1WZXJ0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgLypQcmltQ291bnQgKi8sIEluZGljZXMsIEQzREZNVF9JTkRFWDE2LCBsaXRucXVhZCwgc2l6ZW9mKGxpdG5xdWFkWzBdKSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQIGZhaWxlZCB3aXRoICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwoKICAgICAgICBJRGlyZWN0M0REZXZpY2U4X0VuZFNjZW5lKGRldmljZSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9FbmRTY2VuZSBmYWlsZWQgd2l0aCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIH0KCiAgICBJRGlyZWN0M0REZXZpY2U4X1ByZXNlbnQoZGV2aWNlLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKCiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDM2MCk7IC8qIGxvd2VyIGxlZnQgcXVhZCAtIHVubGl0IHdpdGhvdXQgbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMGZmMDAwMCwgIlVubGl0IHF1YWQgd2l0aG91dCBub3JtYWxzIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDEyMCk7IC8qIHVwcGVyIGxlZnQgcXVhZCAtIGxpdCB3aXRob3V0IG5vcm1hbHMgKi8KICAgIG9rKGNvbG9yID09IDB4MDAwMDAwMDAsICJMaXQgcXVhZCB3aXRob3V0IG5vcm1hbHMgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMzYwKTsgLyogbG93ZXIgbGVmdCBxdWFkIC0gdW5saXQgd2lkdGggbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMDAwMDBmZiwgIlVubGl0IHF1YWQgd2lkdGggbm9ybWFscyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgNDgwLCAxMjApOyAvKiB1cHBlciBsZWZ0IHF1YWQgLSBsaXQgd2lkdGggbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMDAwMDAwMCwgIkxpdCBxdWFkIHdpZHRoIG5vcm1hbHMgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKCiAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19MSUdIVElORywgRkFMU0UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKfQoKc3RhdGljIHZvaWQgY2xlYXJfdGVzdChJRGlyZWN0M0REZXZpY2U4ICpkZXZpY2UpCnsKICAgIC8qIFRlc3RzIHRoZSBjb3JyZWN0bmVzcyBvZiBjbGVhcmluZyBwYXJhbWV0ZXJzICovCiAgICBIUkVTVUxUIGhyOwogICAgRDNEUkVDVCByZWN0WzJdOwogICAgRDNEUkVDVCByZWN0X25lZ25lZzsKICAgIERXT1JEIGNvbG9yOwoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9DbGVhcihkZXZpY2UsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmZmZmZiwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfQ2xlYXIgZmFpbGVkIHdpdGggJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgLyogUG9zaXRpdmUgeCwgbmVnYXRpdmUgeSAqLwogICAgcmVjdFswXS54MSA9IDA7CiAgICByZWN0WzBdLnkxID0gNDgwOwogICAgcmVjdFswXS54MiA9IDMyMDsKICAgIHJlY3RbMF0ueTIgPSAyNDA7CgogICAgLyogUG9zaXRpdmUgeCwgcG9zaXRpdmUgeSAqLwogICAgcmVjdFsxXS54MSA9IDA7CiAgICByZWN0WzFdLnkxID0gMDsKICAgIHJlY3RbMV0ueDIgPSAzMjA7CiAgICByZWN0WzFdLnkyID0gMjQwOwogICAgLyogQ2xlYXIgMiByZWN0YW5nbGVzIHdpdGggb25lIGNhbGwuIFNob3dzIHRoYXQgYSBwb3NpdGl2ZSB2YWx1ZSBpcyByZXR1cm5lZCwgYnV0IHRoZSBuZWdhdGl2ZSByZWN0YW5nbGUKICAgICAqIGlzIGlnbm9yZWQsIHRoZSBwb3NpdGl2ZSBpcyBzdGlsbCBjbGVhcmVkIGFmdGVyd2FyZHMKICAgICAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0NsZWFyKGRldmljZSwgMiwgcmVjdCwgRDNEQ0xFQVJfVEFSR0VULCAweGZmZmYwMDAwLCAwLjAsIDApOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlOF9DbGVhciBmYWlsZWQgd2l0aCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAvKiBuZWdhdGl2ZSB4LCBuZWdhdGl2ZSB5ICovCiAgICByZWN0X25lZ25lZy54MSA9IDY0MDsKICAgIHJlY3RfbmVnbmVnLngxID0gMjQwOwogICAgcmVjdF9uZWduZWcueDIgPSAzMjA7CiAgICByZWN0X25lZ25lZy55MiA9IDA7CiAgICBociA9IElEaXJlY3QzRERldmljZThfQ2xlYXIoZGV2aWNlLCAxLCAmcmVjdF9uZWduZWcsIEQzRENMRUFSX1RBUkdFVCwgMHhmZjAwZmYwMCwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfQ2xlYXIgZmFpbGVkIHdpdGggJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgSURpcmVjdDNERGV2aWNlOF9QcmVzZW50KGRldmljZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMTYwLCAzNjApOyAvKiBsb3dlciBsZWZ0IHF1YWQgKi8KICAgIG9rKGNvbG9yID09IDB4MDBmZmZmZmYsICJDbGVhciByZWN0YW5nbGUgMyhwb3MsIG5lZykgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDE2MCwgMTIwKTsgLyogdXBwZXIgbGVmdCBxdWFkICovCiAgICBvayhjb2xvciA9PSAweDAwZmYwMDAwLCAiQ2xlYXIgcmVjdGFuZ2xlIDEocG9zLCBwb3MpIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCA0ODAsIDM2MCk7IC8qIGxvd2VyIHJpZ2h0IHF1YWQgICovCiAgICBvayhjb2xvciA9PSAweDAwZmZmZmZmLCAiQ2xlYXIgcmVjdGFuZ2xlIDQoTlVMTCkgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMTIwKTsgLyogdXBwZXIgcmlnaHQgcXVhZCAqLwogICAgb2soY29sb3IgPT0gMHgwMGZmZmZmZiwgIkNsZWFyIHJlY3RhbmdsZSA0KG5lZywgbmVnKSBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwp9CgpzdHJ1Y3Qgc1ZlcnRleCB7CiAgICBmbG9hdCB4LCB5LCB6OwogICAgRFdPUkQgZGlmZnVzZTsKICAgIERXT1JEIHNwZWN1bGFyOwp9OwoKc3RydWN0IHNWZXJ0ZXhUIHsKICAgIGZsb2F0IHgsIHksIHosIHJodzsKICAgIERXT1JEIGRpZmZ1c2U7CiAgICBEV09SRCBzcGVjdWxhcjsKfTsKCnN0YXRpYyB2b2lkIGZvZ190ZXN0KElEaXJlY3QzRERldmljZTggKmRldmljZSkKewogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIGNvbG9yOwogICAgZmxvYXQgc3RhcnQgPSAwLjAsIGVuZCA9IDEuMDsKCiAgICAvKiBHZXRzIGZ1bGwgeiBiYXNlZCBmb2cgd2l0aCBsaW5lYXIgZm9nLCBubyBmb2cgd2l0aCBzcGVjdWxhciBjb2xvciAqLwogICAgc3RydWN0IHNWZXJ0ZXggdW5zdHJhbnNmb3JtZWRfMVtdID0gewogICAgICAgIHstMSwgICAgLTEsICAgMC4xLCAgICAgICAgICAweEZGRkYwMDAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7LTEsICAgICAwLCAgIDAuMSwgICAgICAgICAgMHhGRkZGMDAwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgeyAwLCAgICAgMCwgICAwLjEsICAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHsgMCwgICAgLTEsICAgMC4xLCAgICAgICAgICAweEZGRkYwMDAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgIH07CiAgICAvKiBPaywgSSBhbSB0b28gbGF6eSB0byBkZWFsIHdpdGggdHJhbnNmb3JtIG1hdHJpY2VzICovCiAgICBzdHJ1Y3Qgc1ZlcnRleCB1bnN0cmFuc2Zvcm1lZF8yW10gPSB7CiAgICAgICAgey0xLCAgICAgMCwgICAxLjAsICAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHstMSwgICAgIDEsICAgMS4wLCAgICAgICAgICAweEZGRkYwMDAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7IDAsICAgICAxLCAgIDEuMCwgICAgICAgICAgMHhGRkZGMDAwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgeyAwLCAgICAgMCwgICAxLjAsICAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgfTsKICAgIC8qIFVudHJhbnNmb3JtZWQgb25lcy4gR2l2ZSB0aGVtIGEgZGlmZmVyZW50IGRpZmZ1c2UgY29sb3IgdG8gbWFrZSB0aGUgdGVzdCBsb29rCiAgICAgKiBuaWNlci4gSXQgYWxzbyBtYWtlcyBtYWtpbmcgc3VyZSB0aGF0IHRoZXkgYXJlIGRyYXduIGNvcnJlY3RseSBlYXNpZXIuCiAgICAgKi8KICAgIHN0cnVjdCBzVmVydGV4VCB0cmFuc2Zvcm1lZF8xW10gPSB7CiAgICAgICAgezMyMCwgICAgMCwgICAxLjAsICAxLjAsICAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHs2NDAsICAgIDAsICAgMS4wLCAgMS4wLCAgICAweEZGRkZGRjAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7NjQwLCAgMjQwLCAgIDEuMCwgIDEuMCwgICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgezMyMCwgIDI0MCwgICAxLjAsICAxLjAsICAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgfTsKICAgIHN0cnVjdCBzVmVydGV4VCB0cmFuc2Zvcm1lZF8yW10gPSB7CiAgICAgICAgezMyMCwgIDI0MCwgICAxLjAsICAxLjAsICAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHs2NDAsICAyNDAsICAgMS4wLCAgMS4wLCAgICAweEZGRkZGRjAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7NjQwLCAgNDgwLCAgIDEuMCwgIDEuMCwgICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgezMyMCwgIDQ4MCwgICAxLjAsICAxLjAsICAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgfTsKICAgIFdPUkQgSW5kaWNlc1tdID0gezAsIDEsIDIsIDIsIDMsIDB9OwoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9DbGVhcihkZXZpY2UsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDBmZiwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZThfQ2xlYXIgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgLyogU2V0dXAgaW5pdGlhbCBzdGF0ZXM6IE5vIGxpZ2h0aW5nLCBmb2cgb24sIGZvZyBjb2xvciAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfTElHSFRJTkcsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb2ZmIGxpZ2h0aW5nIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfRk9HRU5BQkxFLCBUUlVFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb24gZm9nIGNhbGN1bGF0aW9ucyByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR0NPTE9SLCAweEZGMDBGRjAwIC8qIEEgbmljZSBncmVlbiAqLyk7CiAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9uIGZvZyBjYWxjdWxhdGlvbnMgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgLyogRmlyc3QgdGVzdDogQm90aCB0YWJsZSBmb2cgYW5kIHZlcnRleCBmb2cgb2ZmICovCiAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19GT0dUQUJMRU1PREUsIEQzREZPR19OT05FKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb2ZmIHRhYmxlIGZvZyByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR1ZFUlRFWE1PREUsIEQzREZPR19OT05FKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb2ZmIHRhYmxlIGZvZyByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAvKiBTdGFydCA9IDAsIGVuZCA9IDEuIFNob3VsZCBiZSBkZWZhdWx0LCBidXQgc2V0IHRoZW0gKi8KICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR1NUQVJULCAqKChEV09SRCAqKSAmc3RhcnQpKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlNldHRpbmcgZm9nIHN0YXJ0IHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUlNfRk9HRU5ELCAqKChEV09SRCAqKSAmZW5kKSk7CiAgICBvayhociA9PSBEM0RfT0ssICJTZXR0aW5nIGZvZyBzdGFydCByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICBpZihJRGlyZWN0M0REZXZpY2U4X0JlZ2luU2NlbmUoZGV2aWNlKSA9PSBEM0RfT0spCiAgICB7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X1NldFZlcnRleFNoYWRlcihkZXZpY2UsIEQzREZWRl9YWVogfCBEM0RGVkZfRElGRlVTRSB8IEQzREZWRl9TUEVDVUxBUik7CiAgICAgICAgb2soIGhyID09IEQzRF9PSywgIlNldFZlcnRleFNoYWRlciByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgICAgICAvKiBVbnRyYW5zZm9ybWVkLCB2ZXJ0ZXggZm9nID0gTk9ORSwgdGFibGUgZm9nID0gTk9ORTogUmVhZCB0aGUgZm9nIHdlaWdodGluZyBmcm9tIHRoZSBzcGVjdWxhciBjb2xvciAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKGRldmljZSwgRDNEUFRfVFJJQU5HTEVMSVNULCAwIC8qIE1pbkluZGV4ICovLCA0IC8qIE51bVZlcnRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgLypQcmltQ291bnQgKi8sIEluZGljZXMsIEQzREZNVF9JTkRFWDE2LCB1bnN0cmFuc2Zvcm1lZF8xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih1bnN0cmFuc2Zvcm1lZF8xWzBdKSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRHJhd0luZGV4ZWRQcmltaXRpdmVVUCByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKCiAgICAgICAgLyogVGhhdCBtYWtlcyBpdCB1c2UgdGhlIFogdmFsdWUgKi8KICAgICAgICBociA9IElEaXJlY3QzRERldmljZThfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSU19GT0dWRVJURVhNT0RFLCBEM0RGT0dfTElORUFSKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9mZiB0YWJsZSBmb2cgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICAgICAgLyogVW50cmFuc2Zvcm1lZCwgdmVydGV4IGZvZyAhPSBub25lIChvciB0YWJsZSBmb2cgIT0gbm9uZSk6CiAgICAgICAgICogVXNlIHRoZSBaIHZhbHVlIGFzIGlucHV0IGludG8gdGhlIGVxdWF0aW9uCiAgICAgICAgICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0RyYXdJbmRleGVkUHJpbWl0aXZlVVAoZGV2aWNlLCBEM0RQVF9UUklBTkdMRUxJU1QsIDAgLyogTWluSW5kZXggKi8sIDQgLyogTnVtVmVydHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiAvKlByaW1Db3VudCAqLywgSW5kaWNlcywgRDNERk1UX0lOREVYMTYsIHVuc3RyYW5zZm9ybWVkXzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHVuc3RyYW5zZm9ybWVkXzFbMF0pKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJEcmF3SW5kZXhlZFByaW1pdGl2ZVVQIHJldHVybmVkICVzXG4iLCBEWEdldEVycm9yU3RyaW5nOChocikpOwoKICAgICAgICAvKiB0cmFuc2Zvcm1lZCB2ZXJ0cyAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRWZXJ0ZXhTaGFkZXIoZGV2aWNlLCBEM0RGVkZfWFlaUkhXIHwgRDNERlZGX0RJRkZVU0UgfCBEM0RGVkZfU1BFQ1VMQVIpOwogICAgICAgIG9rKCBociA9PSBEM0RfT0ssICJTZXRWZXJ0ZXhTaGFkZXIgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICAgICAgLyogVHJhbnNmb3JtZWQsIHZlcnRleCBmb2cgIT0gTk9ORSwgcGl4ZWwgZm9nID09IE5PTkU6IFVzZSBzcGVjdWxhciBjb2xvciBhbHBoYSBjb21wb25lbnQgKi8KICAgICAgICBociA9IElEaXJlY3QzRERldmljZThfRHJhd0luZGV4ZWRQcmltaXRpdmVVUChkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgMCAvKiBNaW5JbmRleCAqLywgNCAvKiBOdW1WZXJ0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyIC8qUHJpbUNvdW50ICovLCBJbmRpY2VzLCBEM0RGTVRfSU5ERVgxNiwgdHJhbnNmb3JtZWRfMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodHJhbnNmb3JtZWRfMVswXSkpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkRyYXdJbmRleGVkUHJpbWl0aXZlVVAgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CgogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR1RBQkxFTU9ERSwgRDNERk9HX0xJTkVBUik7CiAgICAgICAgb2soIGhyID09IEQzRF9PSywgIlNldHRpbmcgZm9nIHRhYmxlIG1vZGUgdG8gRDNERk9HX0xJTkVBUiByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKICAgICAgICAvKiBUcmFuc2Zvcm1lZCwgdGFibGUgZm9nICE9IG5vbmUsIHZlcnRleCBhbnl0aGluZzogVXNlIFogdmFsdWUgYXMgaW5wdXQgdG8gdGhlIGZvZwogICAgICAgICAqIGVxdWF0aW9uCiAgICAgICAgICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0RyYXdJbmRleGVkUHJpbWl0aXZlVVAoZGV2aWNlLCBEM0RQVF9UUklBTkdMRUxJU1QsIDAgLyogTWluSW5kZXggKi8sIDQgLyogTnVtVmVydHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiAvKlByaW1Db3VudCAqLywgSW5kaWNlcywgRDNERk1UX0lOREVYMTYsIHRyYW5zZm9ybWVkXzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRyYW5zZm9ybWVkXzJbMF0pKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0VuZFNjZW5lKGRldmljZSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRW5kU2NlbmUgcmV0dXJuZWQgJXNcbiIsIERYR2V0RXJyb3JTdHJpbmc4KGhyKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgb2soRkFMU0UsICJCZWdpblNjZW5lIGZhaWxlZFxuIik7CiAgICB9CgogICAgSURpcmVjdDNERGV2aWNlOF9QcmVzZW50KGRldmljZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDM2MCk7CiAgICBvayhjb2xvciA9PSAweDAwRkYwMDAwLCAiVW50cmFuc2Zvcm1lZCB2ZXJ0ZXggd2l0aCBubyB0YWJsZSBvciB2ZXJ0ZXggZm9nIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDEyMCk7CiAgICBvayhjb2xvciA9PSAweDAwMDBGRjAwLCAiVW50cmFuc2Zvcm1lZCB2ZXJ0ZXggd2l0aCBsaW5lYXIgdmVydGV4IGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgNDgwLCAxMjApOwogICAgb2soY29sb3IgPT0gMHgwMEZGRkYwMCwgIlRyYW5zZm9ybWVkIHZlcnRleCB3aXRoIGxpbmVhciB2ZXJ0ZXggZm9nIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCA0ODAsIDM2MCk7CiAgICBvayhjb2xvciA9PSAweDAwMDBGRjAwLCAiVHJhbnNmb3JtZWQgdmVydGV4IHdpdGggbGluZWFyIHRhYmxlIGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwoKICAgIC8qIFR1cm4gb2ZmIHRoZSBmb2cgbWFzdGVyIHN3aXRjaCB0byBhdm9pZCBjb25mdXNpbmcgb3RoZXIgdGVzdHMgKi8KICAgIGhyID0gSURpcmVjdDNERGV2aWNlOF9TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJTX0ZPR0VOQUJMRSwgRkFMU0UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiVHVybmluZyBvZmYgZm9nIGNhbGN1bGF0aW9ucyByZXR1cm5lZCAlc1xuIiwgRFhHZXRFcnJvclN0cmluZzgoaHIpKTsKfQoKU1RBUlRfVEVTVCh2aXN1YWwpCnsKICAgIElEaXJlY3QzRERldmljZTggKmRldmljZV9wdHI7CiAgICBIUkVTVUxUIGhyOwogICAgRFdPUkQgY29sb3I7CgogICAgZDNkOF9oYW5kbGUgPSBMb2FkTGlicmFyeUEoImQzZDguZGxsIik7CiAgICBpZiAoIWQzZDhfaGFuZGxlKQogICAgewogICAgICAgIHNraXAoIkNvdWxkIG5vdCBsb2FkIGQzZDguZGxsXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZGV2aWNlX3B0ciA9IGluaXRfZDNkOCgpOwogICAgaWYgKCFkZXZpY2VfcHRyKSByZXR1cm47CgogICAgLyogQ2hlY2sgZm9yIHRoZSByZWxpYWJpbGl0eSBvZiB0aGUgcmV0dXJuZWQgZGF0YSAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0NsZWFyKGRldmljZV9wdHIsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDAwMCwgMC4wLCAwKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgdHJhY2UoIkNsZWFyIGZhaWxlZCwgY2FuJ3QgYXNzdXJlIGNvcnJlY3RuZXNzIG9mIHRoZSB0ZXN0IHJlc3VsdHMsIHNraXBwaW5nXG4iKTsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CiAgICBJRGlyZWN0M0REZXZpY2U4X1ByZXNlbnQoZGV2aWNlX3B0ciwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZV9wdHIsIDEsIDEpOwogICAgaWYoY29sb3IgIT0weDAwZmYwMDAwKQogICAgewogICAgICAgIHRyYWNlKCJTYW5pdHkgY2hlY2sgcmV0dXJuZWQgYW4gaW5jb3JyZWN0IGNvbG9yKCUwOHgpLCBjYW4ndCBhc3N1cmUgdGhlIGNvcnJlY3RuZXNzIG9mIHRoZSB0ZXN0cywgc2tpcHBpbmdcbiIsIGNvbG9yKTsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CgogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U4X0NsZWFyKGRldmljZV9wdHIsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZjAwZGRlZSwgMC4wLCAwKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgdHJhY2UoIkNsZWFyIGZhaWxlZCwgY2FuJ3QgYXNzdXJlIGNvcnJlY3RuZXNzIG9mIHRoZSB0ZXN0IHJlc3VsdHMsIHNraXBwaW5nXG4iKTsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CiAgICBJRGlyZWN0M0REZXZpY2U4X1ByZXNlbnQoZGV2aWNlX3B0ciwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZV9wdHIsIDYzOSwgNDc5KTsKICAgIGlmKGNvbG9yICE9IDB4MDAwMGRkZWUpCiAgICB7CiAgICAgICAgdHJhY2UoIlNhbml0eSBjaGVjayByZXR1cm5lZCBhbiBpbmNvcnJlY3QgY29sb3IoJTA4eCksIGNhbid0IGFzc3VyZSB0aGUgY29ycmVjdG5lc3Mgb2YgdGhlIHRlc3RzLCBza2lwcGluZ1xuIiwgY29sb3IpOwogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KCiAgICAvKiBOb3cgcnVuIHRoZSByZWFsIHRlc3QgKi8KICAgIGxpZ2h0aW5nX3Rlc3QoZGV2aWNlX3B0cik7CiAgICBjbGVhcl90ZXN0KGRldmljZV9wdHIpOwogICAgZm9nX3Rlc3QoZGV2aWNlX3B0cik7CgpjbGVhbnVwOgogICAgaWYoZGV2aWNlX3B0cikgSURpcmVjdDNERGV2aWNlOF9SZWxlYXNlKGRldmljZV9wdHIpOwp9Cg==