LyoKICogQ29weXJpZ2h0IChDKSAyMDA3IFN0ZWZhbiBE9nNpbmdlcihmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCi8qIFNlZSBjb21tZW50IGluIGRsbHMvZDNkOS90ZXN0cy92aXN1YWwuYyBmb3IgZ2VuZXJhbCBndWlkZWxpbmVzICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlICJ3aW5lL3Rlc3QuaCIKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCkhXTkQgd2luZG93OwpJRGlyZWN0RHJhdzcgICAgICAgICpEaXJlY3REcmF3ID0gTlVMTDsKSURpcmVjdERyYXdTdXJmYWNlNyAqU3VyZmFjZTsKSURpcmVjdDNENyAgICAgICAgICAqRGlyZWN0M0QgPSBOVUxMOwpJRGlyZWN0M0REZXZpY2U3ICAgICpEaXJlY3QzRERldmljZSA9IE5VTEw7CgpzdGF0aWMgSFJFU1VMVCAoV0lOQVBJICpwRGlyZWN0RHJhd0NyZWF0ZUV4KShMUEdVSUQsTFBWT0lEKixSRUZJSUQsTFBVTktOT1dOKTsKCnN0YXRpYyBCT09MIGNyZWF0ZU9iamVjdHModm9pZCkKewogICAgSFJFU1VMVCBocjsKICAgIEhNT0RVTEUgaG1vZCA9IEdldE1vZHVsZUhhbmRsZUEoImRkcmF3LmRsbCIpOwogICAgV05EQ0xBU1Mgd2MgPSB7MH07CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwoKCiAgICBpZighaG1vZCkgcmV0dXJuIEZBTFNFOwogICAgcERpcmVjdERyYXdDcmVhdGVFeCA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhobW9kLCAiRGlyZWN0RHJhd0NyZWF0ZUV4Iik7CiAgICBpZighcERpcmVjdERyYXdDcmVhdGVFeCkgcmV0dXJuIEZBTFNFOwoKICAgIGhyID0gcERpcmVjdERyYXdDcmVhdGVFeChOVUxMLCAodm9pZCAqKikgJkRpcmVjdERyYXcsICZJSURfSURpcmVjdERyYXc3LCBOVUxMKTsKICAgIG9rKGhyPT1ERF9PSyB8fCBocj09RERFUlJfTk9ESVJFQ1REUkFXU1VQUE9SVCwgIkRpcmVjdERyYXdDcmVhdGVFeCByZXR1cm5lZDogJXhcbiIsIGhyKTsKICAgIGlmKCFEaXJlY3REcmF3KSBnb3RvIGVycjsKCiAgICB3Yy5scGZuV25kUHJvYyA9ICZEZWZXaW5kb3dQcm9jOwogICAgd2MubHBzekNsYXNzTmFtZSA9ICJkM2Q3X3Rlc3Rfd2MiOwogICAgUmVnaXN0ZXJDbGFzcygmd2MpOwogICAgd2luZG93ID0gQ3JlYXRlV2luZG93KCJkM2Q3X3Rlc3Rfd2MiLCAiZDNkN190ZXN0IiwgV1NfTUFYSU1JWkUgfCBXU19WSVNJQkxFIHwgV1NfQ0FQVElPTiAsIDAsIDAsIDY0MCwgNDgwLCAwLCAwLCAwLCAwKTsKCiAgICBociA9IElEaXJlY3REcmF3N19TZXRDb29wZXJhdGl2ZUxldmVsKERpcmVjdERyYXcsIHdpbmRvdywgRERTQ0xfRVhDTFVTSVZFIHwgRERTQ0xfRlVMTFNDUkVFTik7CiAgICBvayhociA9PSBERF9PSywgIklEaXJlY3REcmF3N19TZXRDb29wZXJhdGl2ZUxldmVsIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgIGlmKEZBSUxFRChocikpIGdvdG8gZXJyOwogICAgaHIgPSBJRGlyZWN0RHJhdzdfU2V0RGlzcGxheU1vZGUoRGlyZWN0RHJhdywgNjQwLCA0ODAsIDMyLCAwLCAwKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICAvKiAyNCBiaXQgaXMgZmluZSB0b28gKi8KICAgICAgICBociA9IElEaXJlY3REcmF3N19TZXREaXNwbGF5TW9kZShEaXJlY3REcmF3LCA2NDAsIDQ4MCwgMjQsIDAsIDApOwoKICAgIH0KICAgIG9rKGhyID09IEREX09LIHx8IGhyID09IERERVJSX1VOU1VQUE9SVEVELCAiSURpcmVjdERyYXc3X1NldERpc3BsYXlNb2RlIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICAvKiB1c2UgdHJhY2UsIHRoZSBjYWxsZXIgY2FsbHMgc2tpcCgpICovCiAgICAgICAgdHJhY2UoIlNldERpc3BsYXlNb2RlIGZhaWxlZFxuIik7CiAgICAgICAgZ290byBlcnI7CiAgICB9CgogICAgaHIgPSBJRGlyZWN0RHJhdzdfUXVlcnlJbnRlcmZhY2UoRGlyZWN0RHJhdywgJklJRF9JRGlyZWN0M0Q3LCAodm9pZCoqKSAmRGlyZWN0M0QpOwogICAgaWYgKGhyID09IEVfTk9JTlRFUkZBQ0UpIGdvdG8gZXJyOwogICAgb2soaHI9PUREX09LLCAiUXVlcnlJbnRlcmZhY2UgcmV0dXJuZWQ6ICUwOHhcbiIsIGhyKTsKCiAgICAvKiBEaXJlY3REcmF3IEZsaXBwaW5nIGJlaGF2aW9yIGRvZXNuJ3Qgc2VlbSB0aGF0IHdlbGwtZGVmaW5lZC4gVGhlIHJlZmVyZW5jZSByYXN0ZXJpemVyIGJlaGF2ZXMgZGlmZmVyZW50bHkKICAgICAqIHRoYW4gaGFyZHdhcmUgaW1wbGVtZW50YXRpb25zLiBSZXF1ZXN0IHNpbmdsZSBidWZmZXJpbmcsIHRoYXQgc2VlbXMgdG8gd29yayBldmVyeXdoZXJlCiAgICAgKi8KICAgIG1lbXNldCgmZGRzZCwgMCwgc2l6ZW9mKGRkc2QpKTsKICAgIGRkc2QuZHdTaXplID0gc2l6ZW9mKGRkc2QpOwogICAgZGRzZC5kd0ZsYWdzID0gRERTRF9DQVBTOwogICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTXzNEREVWSUNFOwogICAgZGRzZC5kd0JhY2tCdWZmZXJDb3VudCA9IDE7CiAgICBociA9IElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKERpcmVjdERyYXcsICZkZHNkLCAmU3VyZmFjZSwgTlVMTCk7CiAgICBvayhocj09RERfT0ssICJDcmVhdGVTdXJmYWNlIHJldHVybmVkOiAlMDh4XG4iLCBocik7CiAgICBpZighU3VyZmFjZSkgZ290byBlcnI7CgogICAgaHIgPSBJRGlyZWN0M0Q3X0NyZWF0ZURldmljZShEaXJlY3QzRCwgJklJRF9JRGlyZWN0M0RUbkxIYWxEZXZpY2UsIFN1cmZhY2UsICZEaXJlY3QzRERldmljZSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIHRyYWNlKCJDcmVhdGluZyBhIFRuTEhhbCBEZXZpY2UgZmFpbGVkLCB0cnlpbmcgSEFMXG4iKTsKICAgICAgICBociA9IElEaXJlY3QzRDdfQ3JlYXRlRGV2aWNlKERpcmVjdDNELCAmSUlEX0lEaXJlY3QzREhBTERldmljZSwgU3VyZmFjZSwgJkRpcmVjdDNERGV2aWNlKTsKICAgICAgICBpZihGQUlMRUQoaHIpKQogICAgICAgIHsKICAgICAgICAgICAgdHJhY2UoIkNyZWF0aW5nIGEgSEFMIGRldmljZSBmYWlsZWQsIHRyeWluZyBSZWZcbiIpOwogICAgICAgICAgICBociA9IElEaXJlY3QzRDdfQ3JlYXRlRGV2aWNlKERpcmVjdDNELCAmSUlEX0lEaXJlY3QzRFJlZkRldmljZSwgU3VyZmFjZSwgJkRpcmVjdDNERGV2aWNlKTsKICAgICAgICB9CiAgICB9CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0Q3X0NyZWF0ZURldmljZSBmYWlsZWQgd2l0aCAlMDh4XG4iLCBocik7CiAgICBpZighRGlyZWN0M0REZXZpY2UpIGdvdG8gZXJyOwogICAgcmV0dXJuIFRSVUU7CgogICAgZXJyOgogICAgaWYoRGlyZWN0RHJhdykgSURpcmVjdERyYXc3X1JlbGVhc2UoRGlyZWN0RHJhdyk7CiAgICBpZihTdXJmYWNlKSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoU3VyZmFjZSk7CiAgICBpZihEaXJlY3QzRCkgSURpcmVjdDNEN19SZWxlYXNlKERpcmVjdDNEKTsKICAgIGlmKERpcmVjdDNERGV2aWNlKSBJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoRGlyZWN0M0REZXZpY2UpOwogICAgaWYod2luZG93KSBEZXN0cm95V2luZG93KHdpbmRvdyk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyB2b2lkIHJlbGVhc2VPYmplY3RzKHZvaWQpCnsKICAgIElEaXJlY3QzRERldmljZTdfUmVsZWFzZShEaXJlY3QzRERldmljZSk7CiAgICBJRGlyZWN0M0Q3X1JlbGVhc2UoRGlyZWN0M0QpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKFN1cmZhY2UpOwogICAgSURpcmVjdERyYXc3X1JlbGVhc2UoRGlyZWN0RHJhdyk7CiAgICBEZXN0cm95V2luZG93KHdpbmRvdyk7Cn0KCnN0YXRpYyBEV09SRCBnZXRQaXhlbENvbG9yKElEaXJlY3QzRERldmljZTcgKmRldmljZSwgVUlOVCB4LCBVSU5UIHkpCnsKICAgIERXT1JEIHJldDsKICAgIEhSRVNVTFQgaHI7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwogICAgUkVDVCByZWN0VG9Mb2NrID0ge3gsIHksIHgrMSwgeSsxfTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYgPSBOVUxMOwoKICAgIC8qIFNvbWUgaW1wbGVtZW50YXRpb25zIHNlZW0gdG8gZGlzbGlrZSBkaXJlY3QgbG9ja2luZyBvbiB0aGUgZnJvbnQgYnVmZmVyLiBUaHVzIGNvcHkgdGhlIGZyb250IGJ1ZmZlcgogICAgICogdG8gYW4gb2Zmc2NyZWVuIHN1cmZhY2UgYW5kIGxvY2sgaXQgaW5zdGVhZCBvZiB0aGUgZnJvbnQgYnVmZmVyCiAgICAgKi8KICAgIG1lbXNldCgmZGRzZCwgMCwgc2l6ZW9mKGRkc2QpKTsKICAgIGRkc2QuZHdTaXplID0gc2l6ZW9mKGRkc2QpOwogICAgVTQoZGRzZCkuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQpOwogICAgZGRzZC5kd0ZsYWdzID0gRERTRF9XSURUSCB8IEREU0RfSEVJR0hUIHwgRERTRF9DQVBTOwogICAgZGRzZC5kd1dpZHRoID0gNjQwOwogICAgZGRzZC5kd0hlaWdodCA9IDQ4MDsKICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX09GRlNDUkVFTlBMQUlOIHwgRERTQ0FQU19TWVNURU1NRU1PUlk7CiAgICBociA9IElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKERpcmVjdERyYXcsICZkZHNkLCAmc3VyZiwgTlVMTCk7CiAgICBvayhociA9PSBERF9PSywgIklEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgIGlmKCFzdXJmKQogICAgewogICAgICAgIHRyYWNlKCJjYW5ub3QgY3JlYXRlIGhlbHBlciBzdXJmYWNlXG4iKTsKICAgICAgICByZXR1cm4gMHhkZWFkYmVlZjsKICAgIH0KCiAgICBtZW1zZXQoJmRkc2QsIDAsIHNpemVvZihkZHNkKSk7CiAgICBkZHNkLmR3U2l6ZSA9IHNpemVvZihkZHNkKTsKICAgIFU0KGRkc2QpLmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoVTQoZGRzZCkuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZV9CbHRGYXN0KHN1cmYsIDAsIDAsIFN1cmZhY2UsIE5VTEwsIDApOwogICAgb2soaHIgPT0gRERfT0ssICJJRGlyZWN0RHJhd1N1cmZhY2U3X0JsdEZhc3QgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICB0cmFjZSgiQ2Fubm90IGJsaXRcbiIpOwogICAgICAgIHJldCA9IDB4ZGVhZGJlZTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfTG9jayhzdXJmLCAmcmVjdFRvTG9jaywgJmRkc2QsIERETE9DS19SRUFET05MWSB8IERETE9DS19XQUlULCBOVUxMKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgdHJhY2UoIkNhbid0IGxvY2sgdGhlIG9mZnNjcmVlbiBzdXJmYWNlLCBocj0lMDh4XG4iLCBocik7CiAgICAgICAgcmV0ID0gMHhkZWFkYmVlYzsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICAvKiBSZW1vdmUgdGhlIFggY2hhbm5lbCBmb3Igbm93LiBEaXJlY3RYIGFuZCBPcGVuR0wgaGF2ZSBkaWZmZXJlbnQgaWRlYXMgaG93IHRvIHRyZWF0IGl0IGFwcGFyZW50bHksIGFuZCBpdCBpc24ndAogICAgICogcmVhbGx5IGltcG9ydGFudCBmb3IgdGhlc2UgdGVzdHMKICAgICAqLwogICAgcmV0ID0gKChEV09SRCAqKSBkZHNkLmxwU3VyZmFjZSlbMF0gJiAweDAwZmZmZmZmOwogICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X1VubG9jayhzdXJmLCAmcmVjdFRvTG9jayk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIHRyYWNlKCJDYW4ndCB1bmxvY2sgdGhlIG9mZnNjcmVlbiBzdXJmYWNlLCBocj0lMDh4XG4iLCBocik7CiAgICB9CgpvdXQ6CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7CiAgICByZXR1cm4gcmV0Owp9CgpzdHJ1Y3QgdmVydGV4CnsKICAgIGZsb2F0IHgsIHksIHo7CiAgICBEV09SRCBkaWZmdXNlOwp9OwoKc3RydWN0IG52ZXJ0ZXgKewogICAgZmxvYXQgeCwgeSwgejsKICAgIGZsb2F0IG54LCBueSwgbno7CiAgICBEV09SRCBkaWZmdXNlOwp9OwoKc3RhdGljIHZvaWQgbGlnaHRpbmdfdGVzdChJRGlyZWN0M0REZXZpY2U3ICpkZXZpY2UpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBEV09SRCBmdmYgPSBEM0RGVkZfWFlaIHwgRDNERlZGX0RJRkZVU0U7CiAgICBEV09SRCBuZnZmID0gRDNERlZGX1hZWiB8IEQzREZWRl9ESUZGVVNFIHwgRDNERlZGX05PUk1BTDsKICAgIERXT1JEIGNvbG9yOwoKICAgIGZsb2F0IG1hdFsxNl0gPSB7IDEuMGYsIDAuMGYsIDAuMGYsIDAuMGYsCiAgICAgICAgICAgICAgICAgICAgICAwLjBmLCAxLjBmLCAwLjBmLCAwLjBmLAogICAgICAgICAgICAgICAgICAgICAgMC4wZiwgMC4wZiwgMS4wZiwgMC4wZiwKICAgICAgICAgICAgICAgICAgICAgIDAuMGYsIDAuMGYsIDAuMGYsIDEuMGYgfTsKCiAgICBzdHJ1Y3QgdmVydGV4IHVubGl0cXVhZFtdID0KICAgIHsKICAgICAgICB7LTEuMGYsIC0xLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGZmZmYwMDAwfSwKICAgICAgICB7LTEuMGYsICAwLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGZmZmYwMDAwfSwKICAgICAgICB7IDAuMGYsICAwLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGZmZmYwMDAwfSwKICAgICAgICB7IDAuMGYsIC0xLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGZmZmYwMDAwfSwKICAgIH07CiAgICBzdHJ1Y3QgdmVydGV4IGxpdHF1YWRbXSA9CiAgICB7CiAgICAgICAgey0xLjBmLCAgMC4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZjAwZmYwMH0sCiAgICAgICAgey0xLjBmLCAgMS4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZjAwZmYwMH0sCiAgICAgICAgeyAwLjBmLCAgMS4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZjAwZmYwMH0sCiAgICAgICAgeyAwLjBmLCAgMC4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmZjAwZmYwMH0sCiAgICB9OwogICAgc3RydWN0IG52ZXJ0ZXggdW5saXRucXVhZFtdID0KICAgIHsKICAgICAgICB7IDAuMGYsIC0xLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmMDAwMGZmfSwKICAgICAgICB7IDAuMGYsICAwLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmMDAwMGZmfSwKICAgICAgICB7IDEuMGYsICAwLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmMDAwMGZmfSwKICAgICAgICB7IDEuMGYsIC0xLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmMDAwMGZmfSwKICAgIH07CiAgICBzdHJ1Y3QgbnZlcnRleCBsaXRucXVhZFtdID0KICAgIHsKICAgICAgICB7IDAuMGYsICAwLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmZmZmZjAwfSwKICAgICAgICB7IDAuMGYsICAxLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmZmZmZjAwfSwKICAgICAgICB7IDEuMGYsICAxLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmZmZmZjAwfSwKICAgICAgICB7IDEuMGYsICAwLjBmLCAgIDAuMWYsICAxLjBmLCAgIDEuMGYsICAgMS4wZiwgICAweGZmZmZmZjAwfSwKICAgIH07CiAgICBXT1JEIEluZGljZXNbXSA9IHswLCAxLCAyLCAyLCAzLCAwfTsKCiAgICBociA9IElEaXJlY3QzRERldmljZTdfQ2xlYXIoZGV2aWNlLCAwLCBOVUxMLCBEM0RDTEVBUl9UQVJHRVQsIDB4ZmZmZmZmZmYsIDAuMCwgMCk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X0NsZWFyIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKCiAgICAvKiBTZXR1cCBzb21lIHN0YXRlcyB0aGF0IG1heSBjYXVzZSBpc3N1ZXMgKi8KICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUcmFuc2Zvcm0oZGV2aWNlLCBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRCwgKEQzRE1BVFJJWCAqKSBtYXQpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRUcmFuc2Zvcm0gcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRyYW5zZm9ybShkZXZpY2UsIEQzRFRSQU5TRk9STVNUQVRFX1ZJRVcsIChEM0RNQVRSSVggKiltYXQpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRUcmFuc2Zvcm0gcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRyYW5zZm9ybShkZXZpY2UsIEQzRFRSQU5TRk9STVNUQVRFX1BST0pFQ1RJT04sIChEM0RNQVRSSVggKikgbWF0KTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0VHJhbnNmb3JtIHJldHVybmVkICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0NMSVBQSU5HLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIHJldHVybmVkICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX1pFTkFCTEUsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfRk9HRU5BQkxFLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIHJldHVybmVkICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX1NURU5DSUxFTkFCTEUsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfQUxQSEFURVNURU5BQkxFLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIHJldHVybmVkICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0FMUEhBQkxFTkRFTkFCTEUsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfQ1VMTE1PREUsIEQzRENVTExfTk9ORSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKCiAgICBociA9IElEaXJlY3QzRERldmljZTdfQmVnaW5TY2VuZShkZXZpY2UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19CZWdpblNjZW5lIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgIGlmKGhyID09IEQzRF9PSykKICAgIHsKICAgICAgICAvKiBObyBsaWdodHMgYXJlIGRlZmluZWQuLi4gVGhhdCBtZWFucywgbGl0IHZlcnRpY2VzIHNob3VsZCBiZSBlbnRpcmVseSBibGFjayAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0xJR0hUSU5HLCBGQUxTRSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlMDh4XG4iLCBocik7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0RyYXdJbmRleGVkUHJpbWl0aXZlKGRldmljZSwgRDNEUFRfVFJJQU5HTEVMSVNULCBmdmYsIHVubGl0cXVhZCwgNCAvKiBOdW1WZXJ0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsIDYgLyogSW5kZXhjb3VudCAqLywgMCAvKiBmbGFncyAqLyk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZVVQIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfTElHSFRJTkcsIFRSVUUpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgZnZmLCBsaXRxdWFkLCA0IC8qIE51bVZlcnRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWNlcywgNiAvKiBJbmRleGNvdW50ICovLCAwIC8qIGZsYWdzICovKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X0RyYXdJbmRleGVkUHJpbWl0aXZlVVAgZmFpbGVkIHdpdGggJTA4eFxuIiwgaHIpOwoKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9MSUdIVElORywgRkFMU0UpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgbmZ2ZiwgdW5saXRucXVhZCwgNCAvKiBOdW1WZXJ0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsIDYgLyogSW5kZXhjb3VudCAqLywgMCAvKiBmbGFncyAqLyk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZVVQIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfTElHSFRJTkcsIFRSVUUpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgbmZ2ZiwgbGl0bnF1YWQsIDQgLyogTnVtVmVydHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRpY2VzLCA2IC8qIEluZGV4Y291bnQgKi8sIDAgLyogZmxhZ3MgKi8pOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmVVUCBmYWlsZWQgd2l0aCAlMDh4XG4iLCBocik7CgogICAgICAgIElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoZGV2aWNlKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X0VuZFNjZW5lIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgIH0KCiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDM2MCk7IC8qIGxvd2VyIGxlZnQgcXVhZCAtIHVubGl0IHdpdGhvdXQgbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMGZmMDAwMCwgIlVubGl0IHF1YWQgd2l0aG91dCBub3JtYWxzIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDEyMCk7IC8qIHVwcGVyIGxlZnQgcXVhZCAtIGxpdCB3aXRob3V0IG5vcm1hbHMgKi8KICAgIG9rKGNvbG9yID09IDB4MDAwMDAwMDAsICJMaXQgcXVhZCB3aXRob3V0IG5vcm1hbHMgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMzYwKTsgLyogbG93ZXIgbGVmdCBxdWFkIC0gdW5saXQgd2lkdGggbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMDAwMDBmZiwgIlVubGl0IHF1YWQgd2lkdGggbm9ybWFscyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgNDgwLCAxMjApOyAvKiB1cHBlciBsZWZ0IHF1YWQgLSBsaXQgd2lkdGggbm9ybWFscyAqLwogICAgb2soY29sb3IgPT0gMHgwMDAwMDAwMCwgIkxpdCBxdWFkIHdpZHRoIG5vcm1hbHMgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKCiAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9MSUdIVElORywgRkFMU0UpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSByZXR1cm5lZCAlMDh4XG4iLCBocik7Cn0KCnN0YXRpYyB2b2lkIGNsZWFyX3Rlc3QoSURpcmVjdDNERGV2aWNlNyAqZGV2aWNlKQp7CiAgICAvKiBUZXN0cyB0aGUgY29ycmVjdG5lc3Mgb2YgY2xlYXJpbmcgcGFyYW1ldGVycyAqLwogICAgSFJFU1VMVCBocjsKICAgIEQzRFJFQ1QgcmVjdFsyXTsKICAgIEQzRFJFQ1QgcmVjdF9uZWduZWc7CiAgICBEV09SRCBjb2xvcjsKCiAgICBociA9IElEaXJlY3QzRERldmljZTdfQ2xlYXIoZGV2aWNlLCAwLCBOVUxMLCBEM0RDTEVBUl9UQVJHRVQsIDB4ZmZmZmZmZmYsIDAuMCwgMCk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X0NsZWFyIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKCiAgICAvKiBQb3NpdGl2ZSB4LCBuZWdhdGl2ZSB5ICovCiAgICBVMShyZWN0WzBdKS54MSA9IDA7CiAgICBVMihyZWN0WzBdKS55MSA9IDQ4MDsKICAgIFUzKHJlY3RbMF0pLngyID0gMzIwOwogICAgVTQocmVjdFswXSkueTIgPSAyNDA7CgogICAgLyogUG9zaXRpdmUgeCwgcG9zaXRpdmUgeSAqLwogICAgVTEocmVjdFsxXSkueDEgPSAwOwogICAgVTIocmVjdFsxXSkueTEgPSAwOwogICAgVTMocmVjdFsxXSkueDIgPSAzMjA7CiAgICBVNChyZWN0WzFdKS55MiA9IDI0MDsKICAgIC8qIENsZWFyIDIgcmVjdGFuZ2xlcyB3aXRoIG9uZSBjYWxsLiBTaG93cyB0aGF0IGEgcG9zaXRpdmUgdmFsdWUgaXMgcmV0dXJuZWQsIGJ1dCB0aGUgbmVnYXRpdmUgcmVjdGFuZ2xlCiAgICAgKiBpcyBpZ25vcmVkLCB0aGUgcG9zaXRpdmUgaXMgc3RpbGwgY2xlYXJlZCBhZnRlcndhcmRzCiAgICAgKi8KICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19DbGVhcihkZXZpY2UsIDIsIHJlY3QsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDAwMCwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfQ2xlYXIgZmFpbGVkIHdpdGggJTA4eFxuIiwgaHIpOwoKICAgIC8qIG5lZ2F0aXZlIHgsIG5lZ2F0aXZlIHkgKi8KICAgIFUxKHJlY3RfbmVnbmVnKS54MSA9IDY0MDsKICAgIFUyKHJlY3RfbmVnbmVnKS55MSA9IDI0MDsKICAgIFUzKHJlY3RfbmVnbmVnKS54MiA9IDMyMDsKICAgIFU0KHJlY3RfbmVnbmVnKS55MiA9IDA7CiAgICBociA9IElEaXJlY3QzRERldmljZTdfQ2xlYXIoZGV2aWNlLCAxLCAmcmVjdF9uZWduZWcsIEQzRENMRUFSX1RBUkdFVCwgMHhmZjAwZmYwMCwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfQ2xlYXIgZmFpbGVkIHdpdGggJTA4eFxuIiwgaHIpOwoKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDE2MCwgMzYwKTsgLyogbG93ZXIgbGVmdCBxdWFkICovCiAgICBvayhjb2xvciA9PSAweDAwZmZmZmZmLCAiQ2xlYXIgcmVjdGFuZ2xlIDMocG9zLCBuZWcpIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDEyMCk7IC8qIHVwcGVyIGxlZnQgcXVhZCAqLwogICAgb2soY29sb3IgPT0gMHgwMGZmMDAwMCwgIkNsZWFyIHJlY3RhbmdsZSAxKHBvcywgcG9zKSBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgNDgwLCAzNjApOyAvKiBsb3dlciByaWdodCBxdWFkICAqLwogICAgb2soY29sb3IgPT0gMHgwMGZmZmZmZiwgIkNsZWFyIHJlY3RhbmdsZSA0KE5VTEwpIGhhcyBjb2xvciAlMDh4XG4iLCBjb2xvcik7CiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCA0ODAsIDEyMCk7IC8qIHVwcGVyIHJpZ2h0IHF1YWQgKi8KICAgIG9rKGNvbG9yID09IDB4MDBmZmZmZmYsICJDbGVhciByZWN0YW5nbGUgNChuZWcsIG5lZykgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKfQoKc3RydWN0IHNWZXJ0ZXggewogICAgZmxvYXQgeCwgeSwgejsKICAgIERXT1JEIGRpZmZ1c2U7CiAgICBEV09SRCBzcGVjdWxhcjsKfTsKCnN0cnVjdCBzVmVydGV4VCB7CiAgICBmbG9hdCB4LCB5LCB6LCByaHc7CiAgICBEV09SRCBkaWZmdXNlOwogICAgRFdPUkQgc3BlY3VsYXI7Cn07CgpzdGF0aWMgdm9pZCBmb2dfdGVzdChJRGlyZWN0M0REZXZpY2U3ICpkZXZpY2UpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBEV09SRCBjb2xvcjsKICAgIGZsb2F0IHN0YXJ0ID0gMC4wLCBlbmQgPSAxLjA7CiAgICBEM0RERVZJQ0VERVNDNyBjYXBzOwoKICAgIC8qIEdldHMgZnVsbCB6IGJhc2VkIGZvZyB3aXRoIGxpbmVhciBmb2csIG5vIGZvZyB3aXRoIHNwZWN1bGFyIGNvbG9yICovCiAgICBzdHJ1Y3Qgc1ZlcnRleCB1bnN0cmFuc2Zvcm1lZF8xW10gPSB7CiAgICAgICAgey0xLCAgICAtMSwgICAwLjFmLCAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHstMSwgICAgIDAsICAgMC4xZiwgICAgICAgICAweEZGRkYwMDAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7IDAsICAgICAwLCAgIDAuMWYsICAgICAgICAgMHhGRkZGMDAwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgeyAwLCAgICAtMSwgICAwLjFmLCAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgfTsKICAgIC8qIE9rLCBJIGFtIHRvbyBsYXp5IHRvIGRlYWwgd2l0aCB0cmFuc2Zvcm0gbWF0cmljZXMgKi8KICAgIHN0cnVjdCBzVmVydGV4IHVuc3RyYW5zZm9ybWVkXzJbXSA9IHsKICAgICAgICB7LTEsICAgICAwLCAgIDEuMGYsICAgICAgICAgMHhGRkZGMDAwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgey0xLCAgICAgMSwgICAxLjBmLCAgICAgICAgIDB4RkZGRjAwMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHsgMCwgICAgIDEsICAgMS4wZiwgICAgICAgICAweEZGRkYwMDAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7IDAsICAgICAwLCAgIDEuMGYsICAgICAgICAgMHhGRkZGMDAwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICB9OwogICAgLyogVW50cmFuc2Zvcm1lZCBvbmVzLiBHaXZlIHRoZW0gYSBkaWZmZXJlbnQgZGlmZnVzZSBjb2xvciB0byBtYWtlIHRoZSB0ZXN0IGxvb2sKICAgICAqIG5pY2VyLiBJdCBhbHNvIG1ha2VzIG1ha2luZyBzdXJlIHRoYXQgdGhleSBhcmUgZHJhd24gY29ycmVjdGx5IGVhc2llci4KICAgICAqLwogICAgc3RydWN0IHNWZXJ0ZXhUIHRyYW5zZm9ybWVkXzFbXSA9IHsKICAgICAgICB7MzIwLCAgICAwLCAgIDEuMGYsIDEuMGYsICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgezY0MCwgICAgMCwgICAxLjBmLCAxLjBmLCAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHs2NDAsICAyNDAsICAgMS4wZiwgMS4wZiwgICAweEZGRkZGRjAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7MzIwLCAgMjQwLCAgIDEuMGYsIDEuMGYsICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICB9OwogICAgc3RydWN0IHNWZXJ0ZXhUIHRyYW5zZm9ybWVkXzJbXSA9IHsKICAgICAgICB7MzIwLCAgMjQwLCAgIDEuMGYsIDEuMGYsICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICAgICAgezY0MCwgIDI0MCwgICAxLjBmLCAxLjBmLCAgIDB4RkZGRkZGMDAsICAgICAweEZGMDAwMDAwICB9LAogICAgICAgIHs2NDAsICA0ODAsICAgMS4wZiwgMS4wZiwgICAweEZGRkZGRjAwLCAgICAgMHhGRjAwMDAwMCAgfSwKICAgICAgICB7MzIwLCAgNDgwLCAgIDEuMGYsIDEuMGYsICAgMHhGRkZGRkYwMCwgICAgIDB4RkYwMDAwMDAgIH0sCiAgICB9OwogICAgV09SRCBJbmRpY2VzW10gPSB7MCwgMSwgMiwgMiwgMywgMH07CgogICAgbWVtc2V0KCZjYXBzLCAwLCBzaXplb2YoY2FwcykpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0dldENhcHMoZGV2aWNlLCAmY2Fwcyk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X0dldENhcHMgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0NsZWFyKGRldmljZSwgMCwgTlVMTCwgRDNEQ0xFQVJfVEFSR0VULCAweGZmZmYwMGZmLCAwLjAsIDApOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19DbGVhciByZXR1cm5lZCAlMDh4XG4iLCBocik7CgogICAgLyogU2V0dXAgaW5pdGlhbCBzdGF0ZXM6IE5vIGxpZ2h0aW5nLCBmb2cgb24sIGZvZyBjb2xvciAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfTElHSFRJTkcsIEZBTFNFKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb2ZmIGxpZ2h0aW5nIHJldHVybmVkICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0ZPR0VOQUJMRSwgVFJVRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9uIGZvZyBjYWxjdWxhdGlvbnMgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfRk9HQ09MT1IsIDB4RkYwMEZGMDAgLyogQSBuaWNlIGdyZWVuICovKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb24gZm9nIGNhbGN1bGF0aW9ucyByZXR1cm5lZCAlMDh4XG4iLCBocik7CgogICAgLyogRmlyc3QgdGVzdDogQm90aCB0YWJsZSBmb2cgYW5kIHZlcnRleCBmb2cgb2ZmICovCiAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9GT0dUQUJMRU1PREUsIEQzREZPR19OT05FKTsKICAgIG9rKGhyID09IEQzRF9PSywgIlR1cm5pbmcgb2ZmIHRhYmxlIGZvZyByZXR1cm5lZCAlMDh4XG4iLCBocik7CiAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9GT0dWRVJURVhNT0RFLCBEM0RGT0dfTk9ORSk7CiAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9mZiB0YWJsZSBmb2cgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwoKICAgIC8qIFN0YXJ0ID0gMCwgZW5kID0gMS4gU2hvdWxkIGJlIGRlZmF1bHQsIGJ1dCBzZXQgdGhlbSAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfRk9HU1RBUlQsICooKERXT1JEICopICZzdGFydCkpOwogICAgb2soaHIgPT0gRDNEX09LLCAiU2V0dGluZyBmb2cgc3RhcnQgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfRk9HRU5ELCAqKChEV09SRCAqKSAmZW5kKSk7CiAgICBvayhociA9PSBEM0RfT0ssICJTZXR0aW5nIGZvZyBzdGFydCByZXR1cm5lZCAlMDh4XG4iLCBocik7CgogICAgaWYoSURpcmVjdDNERGV2aWNlN19CZWdpblNjZW5lKGRldmljZSkgPT0gRDNEX09LKQogICAgewogICAgICAgIC8qIFVudHJhbnNmb3JtZWQsIHZlcnRleCBmb2cgPSBOT05FLCB0YWJsZSBmb2cgPSBOT05FOiBSZWFkIHRoZSBmb2cgd2VpZ2h0aW5nIGZyb20gdGhlIHNwZWN1bGFyIGNvbG9yICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0RyYXdJbmRleGVkUHJpbWl0aXZlKGRldmljZSwgRDNEUFRfVFJJQU5HTEVMSVNULCBEM0RGVkZfWFlaIHwgRDNERlZGX0RJRkZVU0UgfCBEM0RGVkZfU1BFQ1VMQVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc3RyYW5zZm9ybWVkXzEsIDQsIEluZGljZXMsIDYsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkRyYXdJbmRleGVkUHJpbWl0aXZlIHJldHVybmVkICUwOHhcbiIsIGhyKTsKCiAgICAgICAgLyogVGhhdCBtYWtlcyBpdCB1c2UgdGhlIFogdmFsdWUgKi8KICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9GT0dWRVJURVhNT0RFLCBEM0RGT0dfTElORUFSKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9mZiB0YWJsZSBmb2cgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgICAgIC8qIFVudHJhbnNmb3JtZWQsIHZlcnRleCBmb2cgIT0gbm9uZSAob3IgdGFibGUgZm9nICE9IG5vbmUpOgogICAgICAgICAqIFVzZSB0aGUgWiB2YWx1ZSBhcyBpbnB1dCBpbnRvIHRoZSBlcXVhdGlvbgogICAgICAgICAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFTElTVCwgRDNERlZGX1hZWiB8IEQzREZWRl9ESUZGVVNFIHwgRDNERlZGX1NQRUNVTEFSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnN0cmFuc2Zvcm1lZF8yLCA0LCBJbmRpY2VzLCA2LCAwKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJEcmF3SW5kZXhlZFByaW1pdGl2ZSByZXR1cm5lZCAlMDh4XG4iLCBocik7CgogICAgICAgIC8qIHRyYW5zZm9ybWVkIHZlcnRzICovCiAgICAgICAgb2soIGhyID09IEQzRF9PSywgIlNldEZWRiByZXR1cm5lZCAlMDh4XG4iLCBocik7CiAgICAgICAgLyogVHJhbnNmb3JtZWQsIHZlcnRleCBmb2cgIT0gTk9ORSwgcGl4ZWwgZm9nID09IE5PTkU6IFVzZSBzcGVjdWxhciBjb2xvciBhbHBoYSBjb21wb25lbnQgKi8KICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmUoZGV2aWNlLCBEM0RQVF9UUklBTkdMRUxJU1QsIEQzREZWRl9YWVpSSFcgfCBEM0RGVkZfRElGRlVTRSB8IEQzREZWRl9TUEVDVUxBUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRfMSwgNCwgSW5kaWNlcywgNiwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRHJhd0luZGV4ZWRQcmltaXRpdmUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwoKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9GT0dUQUJMRU1PREUsIEQzREZPR19MSU5FQVIpOwogICAgICAgIG9rKCBociA9PSBEM0RfT0ssICJTZXR0aW5nIGZvZyB0YWJsZSBtb2RlIHRvIEQzREZPR19MSU5FQVIgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwogICAgICAgIC8qIFRyYW5zZm9ybWVkLCB0YWJsZSBmb2cgIT0gbm9uZSwgdmVydGV4IGFueXRoaW5nOiBVc2UgWiB2YWx1ZSBhcyBpbnB1dCB0byB0aGUgZm9nCiAgICAgICAgICogZXF1YXRpb24KICAgICAgICAgKi8KICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmUoZGV2aWNlLCBEM0RQVF9UUklBTkdMRUxJU1QsIEQzREZWRl9YWVpSSFcgfCBEM0RGVkZfRElGRlVTRSB8IEQzREZWRl9TUEVDVUxBUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRfMiwgNCwgSW5kaWNlcywgNiwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRHJhd0luZGV4ZWRQcmltaXRpdmUgcmV0dXJuZWQgJTA4eFxuIiwgaHIpOwoKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoZGV2aWNlKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJFbmRTY2VuZSByZXR1cm5lZCAlMDh4XG4iLCBocik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgb2soRkFMU0UsICJCZWdpblNjZW5lIGZhaWxlZFxuIik7CiAgICB9CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMTYwLCAzNjApOwogICAgb2soY29sb3IgPT0gMHgwMEZGMDAwMCwgIlVudHJhbnNmb3JtZWQgdmVydGV4IHdpdGggbm8gdGFibGUgb3IgdmVydGV4IGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMTYwLCAxMjApOwogICAgb2soY29sb3IgPT0gMHgwMDAwRkYwMCwgIlVudHJhbnNmb3JtZWQgdmVydGV4IHdpdGggbGluZWFyIHZlcnRleCBmb2cgaGFzIGNvbG9yICUwOHhcbiIsIGNvbG9yKTsKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMTIwKTsKICAgIG9rKGNvbG9yID09IDB4MDBGRkZGMDAsICJUcmFuc2Zvcm1lZCB2ZXJ0ZXggd2l0aCBsaW5lYXIgdmVydGV4IGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgaWYoY2Fwcy5kcGNUcmlDYXBzLmR3UmFzdGVyQ2FwcyAmIEQzRFBSQVNURVJDQVBTX0ZPR1RBQkxFKQogICAgewogICAgICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMzYwKTsKICAgICAgICBvayhjb2xvciA9PSAweDAwMDBGRjAwLCAiVHJhbnNmb3JtZWQgdmVydGV4IHdpdGggbGluZWFyIHRhYmxlIGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIFdpdGhvdXQgZm9nIHRhYmxlIHN1cHBvcnQgdGhlIHZlcnRleCBmb2cgaXMgc3RpbGwgYXBwbGllZCwgZXZlbiB0aG91Z2ggdGFibGUgZm9nIGlzIHR1cm5lZCBvbi4KICAgICAgICAgKiBUaGUgc2V0dGluZ3MgYWJvdmUgcmVzdWx0IGluIG5vIGZvZ2dpbmcgd2l0aCB2ZXJ0ZXggZm9nCiAgICAgICAgICovCiAgICAgICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgNDgwLCAxMjApOwogICAgICAgIG9rKGNvbG9yID09IDB4MDBGRkZGMDAsICJUcmFuc2Zvcm1lZCB2ZXJ0ZXggd2l0aCBsaW5lYXIgdmVydGV4IGZvZyBoYXMgY29sb3IgJTA4eFxuIiwgY29sb3IpOwogICAgICAgIHRyYWNlKCJJbmZvOiBUYWJsZSBmb2cgbm90IHN1cHBvcnRlZCBieSB0aGlzIGRldmljZVxuIik7CiAgICB9CgogICAgLyogVHVybiBvZmYgdGhlIGZvZyBtYXN0ZXIgc3dpdGNoIHRvIGF2b2lkIGNvbmZ1c2luZyBvdGhlciB0ZXN0cyAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfRk9HRU5BQkxFLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJUdXJuaW5nIG9mZiBmb2cgY2FsY3VsYXRpb25zIHJldHVybmVkICUwOHhcbiIsIGhyKTsKfQoKc3RhdGljIHZvaWQgb2Zmc2NyZWVuX3Rlc3QoSURpcmVjdDNERGV2aWNlNyAqZGV2aWNlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqYmFja2J1ZmZlciA9IE5VTEwsICpvZmZzY3JlZW4gPSBOVUxMOwogICAgRFdPUkQgY29sb3I7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwoKICAgIHN0YXRpYyBjb25zdCBmbG9hdCBxdWFkW11bNV0gPSB7CiAgICAgICAgey0wLjVmLCAtMC41ZiwgMC4xZiwgMC4wZiwgMC4wZn0sCiAgICAgICAgey0wLjVmLCAgMC41ZiwgMC4xZiwgMC4wZiwgMS4wZn0sCiAgICAgICAgeyAwLjVmLCAtMC41ZiwgMC4xZiwgMS4wZiwgMC4wZn0sCiAgICAgICAgeyAwLjVmLCAgMC41ZiwgMC4xZiwgMS4wZiwgMS4wZn0sCiAgICB9OwoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19DbGVhcihkZXZpY2UsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDAwMCwgMC4wLCAwKTsKICAgIG9rKGhyID09IEQzRF9PSywgIkNsZWFyIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CgogICAgbWVtc2V0KCZkZHNkLCAwLCBzaXplb2YoZGRzZCkpOwogICAgZGRzZC5kd1NpemUgPSBzaXplb2YoZGRzZCk7CiAgICBVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKFU0KGRkc2QpLmRkcGZQaXhlbEZvcm1hdCk7CiAgICBkZHNkLmR3RmxhZ3MgPSBERFNEX1dJRFRIIHwgRERTRF9IRUlHSFQgfCBERFNEX0NBUFM7CiAgICBkZHNkLmR3V2lkdGggPSAxMjg7CiAgICBkZHNkLmR3SGVpZ2h0ID0gMTI4OwogICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfVEVYVFVSRSB8IEREU0NBUFNfM0RERVZJQ0U7CiAgICBociA9IElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKERpcmVjdERyYXcsICZkZHNkLCAmb2Zmc2NyZWVuLCBOVUxMKTsKICAgIG9rKGhyID09IEQzRF9PSywgIkNyZWF0aW5nIHRoZSBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldCBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaWYoIW9mZnNjcmVlbikgewogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19HZXRSZW5kZXJUYXJnZXQoZGV2aWNlLCAmYmFja2J1ZmZlcik7CiAgICBvayhociA9PSBEM0RfT0ssICJDYW4ndCBnZXQgYmFjayBidWZmZXIsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaWYoIWJhY2tidWZmZXIpIHsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0VGV4dHVyZVN0YWdlU3RhdGUoZGV2aWNlLCAwLCBEM0RUU1NfQ09MT1JPUCwgRDNEVE9QX1NFTEVDVEFSRzEpOwogICAgb2soaHIgPT0gRDNEX09LLCAiU2V0VGV4dHVyZVN0YWdlU3RhdGUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShkZXZpY2UsIDAsIEQzRFRTU19DT0xPUkFSRzEsIEQzRFRBX1RFWFRVUkUpOwogICAgb2soaHIgPT0gRDNEX09LLCAiU2V0VGV4dHVyZVN0YWdlU3RhdGUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShkZXZpY2UsIDAsIEQzRFRTU19NSU5GSUxURVIsIEQzREZJTFRFUl9ORUFSRVNUKTsKICAgIG9rKFNVQ0NFRURFRChociksICJTZXRUZXh0dXJlU3RhZ2VTdGF0ZSBEM0RTQU1QX01JTkZJTFRFUiBmYWlsZWQgKDB4JTA4eClcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShkZXZpY2UsIDAsIEQzRFRTU19NQUdGSUxURVIsIEQzREZJTFRFUl9ORUFSRVNUKTsKICAgIG9rKFNVQ0NFRURFRChociksICJTZXRUZXh0dXJlU3RhZ2VTdGF0ZSBEM0RTQU1QX01BR0ZJTFRFUiBmYWlsZWQgKDB4JTA4eClcbiIsIGhyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0xJR0hUSU5HLCBGQUxTRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIHJldHVybmVkIGhyID0gJTA4eFxuIiwgaHIpOwoKICAgIGlmKElEaXJlY3QzRERldmljZTdfQmVnaW5TY2VuZShkZXZpY2UpID09IEQzRF9PSykgewogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJUYXJnZXQoZGV2aWNlLCBvZmZzY3JlZW4sIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIlNldFJlbmRlclRhcmdldCBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19DbGVhcihkZXZpY2UsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDBmZiwgMC4wLCAwKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJDbGVhciBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwoKICAgICAgICAvKiBEcmF3IHdpdGhvdXQgdGV4dHVyZXMgLSBTaG91bGQgcmVzdXQgaW4gYSB3aGl0ZSBxdWFkICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0RyYXdQcmltaXRpdmUoZGV2aWNlLCBEM0RQVF9UUklBTkdMRVNUUklQLCBEM0RGVkZfWFlaIHwgRDNERlZGX1RFWDEsIHF1YWQsIDQsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkRyYXdQcmltaXRpdmUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclRhcmdldChkZXZpY2UsIGJhY2tidWZmZXIsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIlNldFJlbmRlclRhcmdldCBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlKGRldmljZSwgMCwgb2Zmc2NyZWVuKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJTZXRUZXh0dXJlIGZhaWxlZCwgJTA4eFxuIiwgaHIpOwoKICAgICAgICAvKiBUaGlzIHRpbWUgd2l0aCB0aGUgdGV4dHVyZSAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKGRldmljZSwgRDNEUFRfVFJJQU5HTEVTVFJJUCwgRDNERlZGX1hZWiB8IEQzREZWRl9URVgxLCBxdWFkLCA0LCAwKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJEcmF3UHJpbWl0aXZlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CgogICAgICAgIElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoZGV2aWNlKTsKICAgIH0KCiAgICAvKiBDZW50ZXIgcXVhZCAtIHNob3VsZCBiZSB3aGl0ZSAqLwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMzIwLCAyNDApOwogICAgb2soY29sb3IgPT0gMHgwMGZmZmZmZiwgIk9mZnNjcmVlbiBmYWlsZWQ6IEdvdCBjb2xvciAweCUwOHgsIGV4cGVjdGVkIDB4MDBmZmZmZmYuXG4iLCBjb2xvcik7CiAgICAvKiBTb21lIHF1YWQgaW4gdGhlIGNsZWFyZWQgcGFydCBvZiB0aGUgdGV4dHVyZSAqLwogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMTcwLCAyNDApOwogICAgb2soY29sb3IgPT0gMHgwMGZmMDBmZiwgIk9mZnNjcmVlbiBmYWlsZWQ6IEdvdCBjb2xvciAweCUwOHgsIGV4cGVjdGVkIDB4MDBmZjAwZmYuXG4iLCBjb2xvcik7CiAgICAvKiBQYXJ0IG9mIHRoZSBvcmlnaW5hbGx5IGNsZWFyZWQgYmFjayBidWZmZXIgKi8KICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDEwLCAxMCk7CiAgICBvayhjb2xvciA9PSAweDAwZmYwMDAwLCAiT2Zmc2NyZWVuIGZhaWxlZDogR290IGNvbG9yIDB4JTA4eCwgZXhwZWN0ZWQgMHgwMGZmMDAwMC5cbiIsIGNvbG9yKTsKICAgIGlmKDApIHsKICAgICAgICAvKiBMb3dlciBsZWZ0IGNvcm5lciBvZiB0aGUgc2NyZWVuLCB3aGVyZSBiYWNrIGJ1ZmZlciBvZmZzY3JlZW4gcmVuZGVyaW5nIGRyYXdzIHRoZSBvZmZzY3JlZW4gdGV4dHVyZS4KICAgICAgICAgKiBJdCBzaG91bGQgYmUgcmVkLCBidXQgdGhlIG9mZnNjcmVlbiB0ZXh0dXJlIG1heSBsZWF2ZSBzb21lIGp1bmsgdGhlcmUuIE5vdCB0ZXN0ZWQgeWV0LiBEZXBlbmRpbmcgb24KICAgICAgICAgKiB0aGUgb2Zmc2NyZWVuIHJlbmRlcmluZyBtb2RlIHRoaXMgdGVzdCB3b3VsZCBzdWNjZWVkIG9yIGZhaWwKICAgICAgICAgKi8KICAgICAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxMCwgNDcwKTsKICAgICAgICBvayhjb2xvciA9PSAweDAwZmYwMDAwLCAiT2Zmc2NyZWVuIGZhaWxlZDogR290IGNvbG9yIDB4JTA4eCwgZXhwZWN0ZWQgMHgwMGZmMDAwMC5cbiIsIGNvbG9yKTsKICAgIH0KCm91dDoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlKGRldmljZSwgMCwgTlVMTCk7CgogICAgLyogcmVzdG9yZSB0aGluZ3MgKi8KICAgIGlmKGJhY2tidWZmZXIpIHsKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyVGFyZ2V0KGRldmljZSwgYmFja2J1ZmZlciwgMCk7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGJhY2tidWZmZXIpOwogICAgfQogICAgaWYob2Zmc2NyZWVuKSB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKG9mZnNjcmVlbik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGFscGhhX3Rlc3QoSURpcmVjdDNERGV2aWNlNyAqZGV2aWNlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqYmFja2J1ZmZlciA9IE5VTEwsICpvZmZzY3JlZW4gPSBOVUxMOwogICAgRFdPUkQgY29sb3IsIHJlZCwgZ3JlZW4sIGJsdWU7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwoKICAgIHN0cnVjdCB2ZXJ0ZXggcXVhZDFbXSA9CiAgICB7CiAgICAgICAgey0xLjBmLCAtMS4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAwZmYwMH0sCiAgICAgICAgey0xLjBmLCAgMC4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAwZmYwMH0sCiAgICAgICAgeyAxLjBmLCAtMS4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAwZmYwMH0sCiAgICAgICAgeyAxLjBmLCAgMC4wZiwgICAwLjFmLCAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MDAwZmYwMH0sCiAgICB9OwogICAgc3RydWN0IHZlcnRleCBxdWFkMltdID0KICAgIHsKICAgICAgICB7LTEuMGYsICAwLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGMwMDAwMGZmfSwKICAgICAgICB7LTEuMGYsICAxLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGMwMDAwMGZmfSwKICAgICAgICB7IDEuMGYsICAwLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGMwMDAwMGZmfSwKICAgICAgICB7IDEuMGYsICAxLjBmLCAgIDAuMWYsICAgICAgICAgICAgICAgICAgICAgICAgICAweGMwMDAwMGZmfSwKICAgIH07CiAgICBzdGF0aWMgY29uc3QgZmxvYXQgY29tcG9zaXRlX3F1YWRbXVs1XSA9IHsKICAgICAgICB7IDAuMGYsIC0xLjBmLCAwLjFmLCAwLjBmLCAxLjBmfSwKICAgICAgICB7IDAuMGYsICAxLjBmLCAwLjFmLCAwLjBmLCAwLjBmfSwKICAgICAgICB7IDEuMGYsIC0xLjBmLCAwLjFmLCAxLjBmLCAxLjBmfSwKICAgICAgICB7IDEuMGYsICAxLjBmLCAwLjFmLCAxLjBmLCAwLjBmfSwKICAgIH07CgogICAgLyogQ2xlYXIgdGhlIHJlbmRlciB0YXJnZXQgd2l0aCBhbHBoYSA9IDAuNSAqLwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0NsZWFyKGRldmljZSwgMCwgTlVMTCwgRDNEQ0xFQVJfVEFSR0VULCAweDgwZmYwMDAwLCAwLjAsIDApOwogICAgb2soaHIgPT0gRDNEX09LLCAiQ2xlYXIgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICBtZW1zZXQoJmRkc2QsIDAsIHNpemVvZihkZHNkKSk7CiAgICBkZHNkLmR3U2l6ZSA9IHNpemVvZihkZHNkKTsKICAgIGRkc2QuZHdGbGFncyA9IEREU0RfV0lEVEggfCBERFNEX0hFSUdIVCB8IEREU0RfQ0FQUyB8IEREU0RfUElYRUxGT1JNQVQ7CiAgICBkZHNkLmR3V2lkdGggPSAxMjg7CiAgICBkZHNkLmR3SGVpZ2h0ID0gMTI4OwogICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfVEVYVFVSRSB8IEREU0NBUFNfM0RERVZJQ0U7CiAgICBVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQuZHdGbGFncyA9IEREUEZfUkdCIHwgRERQRl9BTFBIQVBJWEVMUzsKICAgIFUxKFU0KGRkc2QpLmRkcGZQaXhlbEZvcm1hdCkuZHdSR0JCaXRDb3VudCAgICAgID0gMzI7CiAgICBVMihVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQpLmR3UkJpdE1hc2sgICAgICAgICA9IDB4MDBmZjAwMDA7CiAgICBVMyhVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQpLmR3R0JpdE1hc2sgICAgICAgICA9IDB4MDAwMGZmMDA7CiAgICBVNChVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQpLmR3QkJpdE1hc2sgICAgICAgICA9IDB4MDAwMDAwZmY7CiAgICBVNShVNChkZHNkKS5kZHBmUGl4ZWxGb3JtYXQpLmR3UkdCQWxwaGFCaXRNYXNrICA9IDB4ZmYwMDAwMDA7CiAgICBociA9IElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKERpcmVjdERyYXcsICZkZHNkLCAmb2Zmc2NyZWVuLCBOVUxMKTsKICAgIG9rKGhyID09IEQzRF9PSywgIkNyZWF0aW5nIHRoZSBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldCBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaWYoIW9mZnNjcmVlbikgewogICAgICAgIGdvdG8gb3V0OwogICAgfQogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0dldFJlbmRlclRhcmdldChkZXZpY2UsICZiYWNrYnVmZmVyKTsKICAgIG9rKGhyID09IEQzRF9PSywgIkNhbid0IGdldCBiYWNrIGJ1ZmZlciwgaHIgPSAlMDh4XG4iLCBocik7CiAgICBpZighYmFja2J1ZmZlcikgewogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShkZXZpY2UsIDAsIEQzRFRTU19DT0xPUk9QLCBEM0RUT1BfU0VMRUNUQVJHMSk7CiAgICBvayhociA9PSBEM0RfT0ssICJTZXRUZXh0dXJlU3RhZ2VTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRleHR1cmVTdGFnZVN0YXRlKGRldmljZSwgMCwgRDNEVFNTX0NPTE9SQVJHMSwgRDNEVEFfVEVYVFVSRSk7CiAgICBvayhociA9PSBEM0RfT0ssICJTZXRUZXh0dXJlU3RhZ2VTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRleHR1cmVTdGFnZVN0YXRlKGRldmljZSwgMCwgRDNEVFNTX01JTkZJTFRFUiwgRDNERklMVEVSX05FQVJFU1QpOwogICAgb2soU1VDQ0VFREVEKGhyKSwgIlNldFRleHR1cmVTdGFnZVN0YXRlIEQzRFNBTVBfTUlORklMVEVSIGZhaWxlZCAoMHglMDh4KVxuIiwgaHIpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRleHR1cmVTdGFnZVN0YXRlKGRldmljZSwgMCwgRDNEVFNTX01BR0ZJTFRFUiwgRDNERklMVEVSX05FQVJFU1QpOwogICAgb2soU1VDQ0VFREVEKGhyKSwgIlNldFRleHR1cmVTdGFnZVN0YXRlIEQzRFNBTVBfTUFHRklMVEVSIGZhaWxlZCAoMHglMDh4KVxuIiwgaHIpOwoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0FMUEhBQkxFTkRFTkFCTEUsIFRSVUUpOwogICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgaWYoSURpcmVjdDNERGV2aWNlN19CZWdpblNjZW5lKGRldmljZSkgPT0gRDNEX09LKSB7CgogICAgICAgIC8qIERyYXcgdHdvIHF1YWRzLCBvbmUgd2l0aCBzcmMgYWxwaGEgYmxlbmRpbmcsIG9uZSB3aXRoIGRlc3QgYWxwaGEgYmxlbmRpbmcuIFRoZQogICAgICAgICAqIFNSQ0FMUEhBIC8gSU5WU1JDQUxQSEEgYmxlbmQgZG9lc24ndCBnaXZlIGFueSBzdXJwcmlzZXMuIENvbG9ycyBhcmUgYmxlbmRlZCBiYXNlZCBvbgogICAgICAgICAqIHRoZSBpbnB1dCBhbHBoYQogICAgICAgICAqCiAgICAgICAgICogVGhlIERFU1RBTFBIQSAvIElOVkRFU1RBTFBIQSBkbyBub3QgIndvcmsiIG9uIHRoZSByZWd1bGFyIGJ1ZmZlciBiZWNhdXNlIHRoZXJlIGlzIG5vIGFscGhhLgogICAgICAgICAqIFRoZXkgZ2l2ZSBlc3NlbnRpYWxseSBaRVJPIGFuZCBPTkUgYmxlbmQgZmFjdG9ycwogICAgICAgICAqLwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX1NSQ0JMRU5ELCBEM0RCTEVORF9TUkNBTFBIQSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0RFU1RCTEVORCwgRDNEQkxFTkRfSU5WU1JDQUxQSEEpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFU1RSSVAsIEQzREZWRl9YWVogfCBEM0RGVkZfRElGRlVTRSwgcXVhZDEsIDQsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkRyYXdQcmltaXRpdmUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfU1JDQkxFTkQsIEQzREJMRU5EX0RFU1RBTFBIQSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShkZXZpY2UsIEQzRFJFTkRFUlNUQVRFX0RFU1RCTEVORCwgRDNEQkxFTkRfSU5WREVTVEFMUEhBKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0RyYXdQcmltaXRpdmUoZGV2aWNlLCBEM0RQVF9UUklBTkdMRVNUUklQLCBEM0RGVkZfWFlaIHwgRDNERlZGX0RJRkZVU0UsIHF1YWQyLCA0LCAwKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJEcmF3UHJpbWl0aXZlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CgogICAgICAgIC8qIFN3aXRjaCB0byB0aGUgb2Zmc2NyZWVuIGJ1ZmZlciwgYW5kIHJlZG8gdGhlIHRlc3RpbmcuIFNSQ0FMUEhBIGFuZCBERVNUQUxQSEEuIFRoZSBvZmZzY3JlZW4gYnVmZmVyCiAgICAgICAgICogaGFzIGEgYWxwaGEgY2hhbm5lbCBvbiBpdHMgb3duLiBDbGVhciB0aGUgb2Zmc2NyZWVuIGJ1ZmZlciB3aXRoIGFscGhhID0gMC41IGFnYWluLCB0aGVuIGRyYXcgdGhlCiAgICAgICAgICogcXVhZHMgYWdhaW4uIFRoZSBTUkNBTFBIQS9JTlZTUkNBTFBIQSBkb2Vzbid0IGdpdmUgYW55IHN1cnByaXNlcywgYnV0IHRoZSBERVNUQUxQSEEvSU5WREVTVEFMUEhBCiAgICAgICAgICogYmxlbmRpbmcgd29ya3MgYXMgc3VwcG9zZWQgbm93IC0gYmxlbmQgZmFjdG9yIGlzIDAuNSBpbiBib3RoIGNhc2VzLCBub3QgMC43NSBhcyBmcm9tIHRoZSBpbnB1dAogICAgICAgICAqIHZlcnRpY2VzCiAgICAgICAgICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclRhcmdldChkZXZpY2UsIG9mZnNjcmVlbiwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiQ2FuJ3QgZ2V0IGJhY2sgYnVmZmVyLCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfQ2xlYXIoZGV2aWNlLCAwLCBOVUxMLCBEM0RDTEVBUl9UQVJHRVQsIDB4ODBmZjAwMDAsIDAuMCwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiQ2xlYXIgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfU1JDQkxFTkQsIEQzREJMRU5EX1NSQ0FMUEhBKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfREVTVEJMRU5ELCBEM0RCTEVORF9JTlZTUkNBTFBIQSk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKGRldmljZSwgRDNEUFRfVFJJQU5HTEVTVFJJUCwgRDNERlZGX1hZWiB8IEQzREZWRl9ESUZGVVNFLCBxdWFkMSwgNCwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRHJhd1ByaW1pdGl2ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwoKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoZGV2aWNlLCBEM0RSRU5ERVJTVEFURV9TUkNCTEVORCwgRDNEQkxFTkRfREVTVEFMUEhBKTsKICAgICAgICBvayhociA9PSBEM0RfT0ssICJJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfREVTVEJMRU5ELCBEM0RCTEVORF9JTlZERVNUQUxQSEEpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZShkZXZpY2UsIEQzRFBUX1RSSUFOR0xFU1RSSVAsIEQzREZWRl9YWVogfCBEM0RGVkZfRElGRlVTRSwgcXVhZDIsIDQsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkRyYXdQcmltaXRpdmUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclRhcmdldChkZXZpY2UsIGJhY2tidWZmZXIsIDApOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIkNhbid0IGdldCBiYWNrIGJ1ZmZlciwgaHIgPSAlMDh4XG4iLCBocik7CgogICAgICAgIC8qIFJlbmRlciB0aGUgb2Zmc2NyZWVuIHRleHR1cmUgb250byB0aGUgZnJhbWUgYnVmZmVyIHRvIGJlIGFibGUgdG8gY29tcGFyZSBpdCByZWd1bGFybHkuCiAgICAgICAgICogRGlzYWJsZSBhbHBoYSBibGVuZGluZyBmb3IgdGhlIGZpbmFsIGNvbXBvc2l0aW9uCiAgICAgICAgICovCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKGRldmljZSwgRDNEUkVOREVSU1RBVEVfQUxQSEFCTEVOREVOQUJMRSwgRkFMU0UpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFRleHR1cmUoZGV2aWNlLCAwLCBvZmZzY3JlZW4pOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfU2V0VGV4dHVyZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKGRldmljZSwgRDNEUFRfVFJJQU5HTEVTVFJJUCwgRDNERlZGX1hZWiB8IEQzREZWRl9URVgxLCBjb21wb3NpdGVfcXVhZCwgNCwgMCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiRHJhd1ByaW1pdGl2ZSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlKGRldmljZSwgMCwgTlVMTCk7CiAgICAgICAgb2soaHIgPT0gRDNEX09LLCAiSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CgogICAgICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19FbmRTY2VuZShkZXZpY2UpOwogICAgICAgIG9rKGhyID09IEQzRF9PSywgIklEaXJlY3QzRERldmljZTdfRW5kU2NlbmUgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgIH0KCiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCAxNjAsIDM2MCk7CiAgICByZWQgPSAgIChjb2xvciAmIDB4MDBmZjAwMDApID4+IDE2OwogICAgZ3JlZW4gPSAoY29sb3IgJiAweDAwMDBmZjAwKSA+PiAgODsKICAgIGJsdWUgPSAgKGNvbG9yICYgMHgwMDAwMDBmZik7CiAgICBvayhyZWQgPj0gMHhiZSAmJiByZWQgPD0gMHhjMCAmJiBncmVlbiA+PSAweDM5ICYmIGdyZWVuIDw9IDB4NDEgJiYgYmx1ZSA9PSAweDAwLAogICAgICAgIlNSQ0FMUEhBIG9uIGZyYW1lIGJ1ZmZlciByZXR1cm5lZCBjb2xvciAlMDh4LCBleHBlY3RlZCAweDAwYmY0MDAwXG4iLCBjb2xvcik7CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKGRldmljZSwgMTYwLCAxMjApOwogICAgcmVkID0gICAoY29sb3IgJiAweDAwZmYwMDAwKSA+PiAxNjsKICAgIGdyZWVuID0gKGNvbG9yICYgMHgwMDAwZmYwMCkgPj4gIDg7CiAgICBibHVlID0gIChjb2xvciAmIDB4MDAwMDAwZmYpOwogICAgb2socmVkID09IDB4MDAgJiYgZ3JlZW4gPT0gMHgwMCAmJiBibHVlID49IDB4ZmUgJiYgYmx1ZSA8PSAweGZmICwKICAgICAgICJEU1RBTFBIQSBvbiBmcmFtZSBidWZmZXIgcmV0dXJuZWQgY29sb3IgJTA4eCwgZXhwZWN0ZWQgMHgwMGZmMDAwMFxuIiwgY29sb3IpOwoKICAgIGNvbG9yID0gZ2V0UGl4ZWxDb2xvcihkZXZpY2UsIDQ4MCwgMzYwKTsKICAgIHJlZCA9ICAgKGNvbG9yICYgMHgwMGZmMDAwMCkgPj4gMTY7CiAgICBncmVlbiA9IChjb2xvciAmIDB4MDAwMGZmMDApID4+ICA4OwogICAgYmx1ZSA9ICAoY29sb3IgJiAweDAwMDAwMGZmKTsKICAgIG9rKHJlZCA+PSAweGJlICYmIHJlZCA8PSAweGMwICYmIGdyZWVuID49IDB4MzkgJiYgZ3JlZW4gPD0gMHg0MSAmJiBibHVlID09IDB4MDAsCiAgICAgICAiU1JDQUxQSEEgb24gdGV4dHVyZSByZXR1cm5lZCBjb2xvciAlMDh4LCBleHBlY3RlZCBiYXJcbiIsIGNvbG9yKTsKCiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoZGV2aWNlLCA0ODAsIDEyMCk7CiAgICByZWQgPSAgIChjb2xvciAmIDB4MDBmZjAwMDApID4+IDE2OwogICAgZ3JlZW4gPSAoY29sb3IgJiAweDAwMDBmZjAwKSA+PiAgODsKICAgIGJsdWUgPSAgKGNvbG9yICYgMHgwMDAwMDBmZik7CiAgICBvayhyZWQgPj0gMHg3ZSAmJiByZWQgPD0gMHg4MSAmJiBncmVlbiA9PSAweDAwICYmIGJsdWUgPj0gMHg3ZSAmJiBibHVlIDw9IDB4ODEsCiAgICAgICAiRFNUQUxQSEEgb24gdGV4dHVyZSByZXR1cm5lZCBjb2xvciAlMDh4LCBleHBlY3RlZCBmb29cbiIsIGNvbG9yKTsKCiAgICBvdXQ6CiAgICBpZihvZmZzY3JlZW4pIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShvZmZzY3JlZW4pOwogICAgaWYoYmFja2J1ZmZlcikgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGJhY2tidWZmZXIpOwp9CgpTVEFSVF9URVNUKHZpc3VhbCkKewogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIGNvbG9yOwogICAgaWYoIWNyZWF0ZU9iamVjdHMoKSkKICAgIHsKICAgICAgICBza2lwKCJDYW5ub3QgaW5pdGlhbGl6ZSBEaXJlY3REcmF3IGFuZCBEaXJlY3QzRCwgc2tpcHBpbmdcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBDaGVjayBmb3IgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSByZXR1cm5lZCBkYXRhICovCiAgICBociA9IElEaXJlY3QzRERldmljZTdfQ2xlYXIoRGlyZWN0M0REZXZpY2UsIDAsIE5VTEwsIEQzRENMRUFSX1RBUkdFVCwgMHhmZmZmMDAwMCwgMC4wLCAwKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgdHJhY2UoIkNsZWFyIGZhaWxlZCwgY2FuJ3QgYXNzdXJlIGNvcnJlY3RuZXNzIG9mIHRoZSB0ZXN0IHJlc3VsdHMsIHNraXBwaW5nXG4iKTsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CgogICAgY29sb3IgPSBnZXRQaXhlbENvbG9yKERpcmVjdDNERGV2aWNlLCAxLCAxKTsKICAgIGlmKGNvbG9yICE9MHgwMGZmMDAwMCkKICAgIHsKICAgICAgICB0cmFjZSgiU2FuaXR5IGNoZWNrIHJldHVybmVkIGFuIGluY29ycmVjdCBjb2xvciglMDh4KSwgY2FuJ3QgYXNzdXJlIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUgdGVzdHMsIHNraXBwaW5nXG4iLCBjb2xvcik7CiAgICAgICAgZ290byBjbGVhbnVwOwogICAgfQoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19DbGVhcihEaXJlY3QzRERldmljZSwgMCwgTlVMTCwgRDNEQ0xFQVJfVEFSR0VULCAweGZmMDBkZGVlLCAwLjAsIDApOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICB0cmFjZSgiQ2xlYXIgZmFpbGVkLCBjYW4ndCBhc3N1cmUgY29ycmVjdG5lc3Mgb2YgdGhlIHRlc3QgcmVzdWx0cywgc2tpcHBpbmdcbiIpOwogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KCiAgICBjb2xvciA9IGdldFBpeGVsQ29sb3IoRGlyZWN0M0REZXZpY2UsIDYzOSwgNDc5KTsKICAgIGlmKGNvbG9yICE9IDB4MDAwMGRkZWUpCiAgICB7CiAgICAgICAgdHJhY2UoIlNhbml0eSBjaGVjayByZXR1cm5lZCBhbiBpbmNvcnJlY3QgY29sb3IoJTA4eCksIGNhbid0IGFzc3VyZSB0aGUgY29ycmVjdG5lc3Mgb2YgdGhlIHRlc3RzLCBza2lwcGluZ1xuIiwgY29sb3IpOwogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KCiAgICAvKiBOb3cgcnVuIHRoZSB0ZXN0cyAqLwogICAgbGlnaHRpbmdfdGVzdChEaXJlY3QzRERldmljZSk7CiAgICBjbGVhcl90ZXN0KERpcmVjdDNERGV2aWNlKTsKICAgIGZvZ190ZXN0KERpcmVjdDNERGV2aWNlKTsKICAgIG9mZnNjcmVlbl90ZXN0KERpcmVjdDNERGV2aWNlKTsKICAgIGFscGhhX3Rlc3QoRGlyZWN0M0REZXZpY2UpOwoKY2xlYW51cDoKICAgIHJlbGVhc2VPYmplY3RzKCk7Cn0K