LyoKICogQ29weXJpZ2h0IChDKSAyMDAzLCAyMDA0IFN0ZWZhbiBMZWljaHRlcgogKiBDb3B5cmlnaHQgKEMpIDIwMDUsIDIwMDYgRGV0bGVmIFJpZWtlbmJlcmcKICogQ29weXJpZ2h0IChDKSAyMDA2IERtaXRyeSBUaW1vc2hrb3YKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5zcG9vbC5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAid2luZS90ZXN0LmgiCgojZGVmaW5lIE1BR0lDX0RFQUQgIDB4ZGVhZGJlZWYKI2RlZmluZSBERUZBVUxUX1BSSU5URVJfU0laRSAxMDAwCgpzdGF0aWMgQ0hBUiBkb2VzX25vdF9leGlzdF9kbGxbXT0gImRvZXNfbm90X2V4aXN0LmRsbCI7CnN0YXRpYyBDSEFSIGRvZXNfbm90X2V4aXN0W10gICAgPSAiZG9lc19ub3RfZXhpc3QiOwpzdGF0aWMgQ0hBUiBlbXB0eVtdICAgICAgICAgICAgID0gIiI7CnN0YXRpYyBDSEFSIGVudl94ODZbXSAgICAgICAgICAgPSAiV2luZG93cyBOVCB4ODYiOwpzdGF0aWMgQ0hBUiBlbnZfd2luOXhfY2FzZVtdICAgID0gIndpbmRvd1MgNC4wIjsKc3RhdGljIENIQVIgaWxsZWdhbF9uYW1lW10gICAgICA9ICJpbGxlZ2FsLG5hbWUiOwpzdGF0aWMgQ0hBUiBpbnZhbGlkX2VudltdICAgICAgID0gImludmFsaWRfZW52IjsKc3RhdGljIENIQVIgTG9jYWxQb3J0QVtdICAgICAgICA9ICJMb2NhbCBQb3J0IjsKc3RhdGljIENIQVIgcG9ydG5hbWVfY29tMVtdICAgICA9ICJDT00xOiI7CnN0YXRpYyBDSEFSIHBvcnRuYW1lX2ZpbGVbXSAgICAgPSAiRklMRToiOwpzdGF0aWMgQ0hBUiBwb3J0bmFtZV9scHQxW10gICAgID0gIkxQVDE6IjsKc3RhdGljIENIQVIgc2VydmVyX2RvZXNfbm90X2V4aXN0W10gPSAiXFxkb2VzX25vdF9leGlzdCI7CnN0YXRpYyBDSEFSIHZlcnNpb25fZGxsW10gICAgICAgPSAidmVyc2lvbi5kbGwiOwpzdGF0aWMgQ0hBUiB3aW5ldGVzdFtdICAgICAgICAgID0gIndpbmV0ZXN0IjsKc3RhdGljIENIQVIgeGN2X2xvY2FscG9ydFtdICAgICA9ICIsWGN2TW9uaXRvciBMb2NhbCBQb3J0IjsKCnN0YXRpYyBXQ0hBUiBjbWRfTW9uaXRvclVJV1tdID0geydNJywnbycsJ24nLCdpJywndCcsJ28nLCdyJywnVScsJ0knLDB9OwpzdGF0aWMgV0NIQVIgY21kX1BvcnRJc1ZhbGlkV1tdID0geydQJywnbycsJ3InLCd0JywnSScsJ3MnLCdWJywnYScsJ2wnLCdpJywnZCcsMH07CnN0YXRpYyBXQ0hBUiBlbXB0eVdbXSA9IHswfTsKCnN0YXRpYyBXQ0hBUiBwb3J0bmFtZV9jb20xV1tdID0geydDJywnTycsJ00nLCcxJywnOicsMH07CnN0YXRpYyBXQ0hBUiBwb3J0bmFtZV9jb20yV1tdID0geydDJywnTycsJ00nLCcyJywnOicsMH07CnN0YXRpYyBXQ0hBUiBwb3J0bmFtZV9maWxlV1tdID0geydGJywnSScsJ0wnLCdFJywnOicsMH07CnN0YXRpYyBXQ0hBUiBwb3J0bmFtZV9scHQxV1tdID0geydMJywnUCcsJ1QnLCcxJywnOicsMH07CnN0YXRpYyBXQ0hBUiBwb3J0bmFtZV9scHQyV1tdID0geydMJywnUCcsJ1QnLCcyJywnOicsMH07CgpzdGF0aWMgSEFORExFICBod2luc3Bvb2w7CnN0YXRpYyBCT09MICAoV0lOQVBJICogcEdldERlZmF1bHRQcmludGVyQSkoTFBTVFIsIExQRFdPUkQpOwpzdGF0aWMgQk9PTCAgKFdJTkFQSSAqIHBTZXREZWZhdWx0UHJpbnRlckEpKExQQ1NUUik7CnN0YXRpYyBEV09SRCAoV0lOQVBJICogcFhjdkRhdGFXKShIQU5ETEUsIExQQ1dTVFIsIFBCWVRFLCBEV09SRCwgUEJZVEUsIERXT1JELCBQRFdPUkQsIFBEV09SRCk7CnN0YXRpYyBCT09MICAoV0lOQVBJICogcEFkZFBvcnRFeEEpKExQU1RSLCBEV09SRCwgTFBCWVRFLCBMUFNUUik7CgoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0cnVjdCBtb25pdG9yX2VudHJ5IHsKICAgIExQU1RSICBlbnY7CiAgICBDSEFSICBkbGxuYW1lWzMyXTsKfTsKCnN0YXRpYyBMUFNUUiBkZWZhdWx0X3ByaW50ZXIgPSBOVUxMOwpzdGF0aWMgTFBTVFIgbG9jYWxfc2VydmVyID0gTlVMTDsKc3RhdGljIExQU1RSIHRlbXBkaXJBID0gTlVMTDsKc3RhdGljIExQU1RSIHRlbXBmaWxlQSA9IE5VTEw7CnN0YXRpYyBMUFdTVFIgdGVtcGRpclcgPSBOVUxMOwpzdGF0aWMgTFBXU1RSIHRlbXBmaWxlVyA9IE5VTEw7CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwovKiByZXBvcnQgY29tbW9uIGJlaGF2aW9yIG9ubHkgb25jZSAqLwpzdGF0aWMgRFdPUkQgZGVhY3RpdmF0ZWRfc3Bvb2xlcl9yZXBvcnRlZCA9IDA7CiNkZWZpbmUgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKSBcCiAgICBpZiAoKHJlcyA9PSAwKSAmJiAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFKSkgXAogICAgeyBcCiAgICAgICAgaWYgKCFkZWFjdGl2YXRlZF9zcG9vbGVyX3JlcG9ydGVkKSB7IFwKICAgICAgICAgICAgZGVhY3RpdmF0ZWRfc3Bvb2xlcl9yZXBvcnRlZCsrOyBcCiAgICAgICAgICAgIHNraXAoIlRoZSBTZXJ2aWNlICdTcG9vbGVyJyBpcyByZXF1aXJlZCBmb3IgbWFueSB0ZXN0XG4iKTsgXAogICAgICAgIH0gXAogICAgICAgIHJldHVybjsgXAogICAgfQoKc3RhdGljIERXT1JEIGFjY2Vzc19kZW5pZWRfcmVwb3J0ZWQgPSAwOwojZGVmaW5lIFJFVFVSTl9PTl9BQ0NFU1NfREVOSUVEKHJlcykgXAogICAgaWYgKChyZXMgPT0gMCkgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0FDQ0VTU19ERU5JRUQpKSBcCiAgICB7IFwKICAgICAgICBpZiAoIWFjY2Vzc19kZW5pZWRfcmVwb3J0ZWQpIHsgXAogICAgICAgICAgICBhY2Nlc3NfZGVuaWVkX3JlcG9ydGVkKys7IFwKICAgICAgICAgICAgc2tpcCgiTW9yZSBBY2Nlc3MtUmlnaHRzIGFyZSByZXF1aXJlZCBmb3IgbWFueSB0ZXN0XG4iKTsgXAogICAgICAgIH0gXAogICAgICAgIHJldHVybjsgXAogICAgfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIGZpbmRfZGVmYXVsdF9wcmludGVyKFZPSUQpCnsKICAgIHN0YXRpYyAgY2hhciAgICBidWZmZXJbREVGQVVMVF9QUklOVEVSX1NJWkVdOwogICAgRFdPUkQgICBuZWVkZWQ7CiAgICBEV09SRCAgIHJlczsKICAgIExQU1RSICAgcHRyOwoKICAgIGlmICgoZGVmYXVsdF9wcmludGVyID09IE5VTEwpICYmIChwR2V0RGVmYXVsdFByaW50ZXJBKSkKICAgIHsKICAgICAgICAvKiB3MmsgYW5kIGFib3ZlICovCiAgICAgICAgbmVlZGVkID0gc2l6ZW9mKGJ1ZmZlcik7CiAgICAgICAgcmVzID0gcEdldERlZmF1bHRQcmludGVyQShidWZmZXIsICZuZWVkZWQpOwogICAgICAgIGlmKHJlcykgIGRlZmF1bHRfcHJpbnRlciA9IGJ1ZmZlcjsKICAgICAgICB0cmFjZSgiZGVmYXVsdF9wcmludGVyOiAnJXMnXG4iLCBkZWZhdWx0X3ByaW50ZXIpOwogICAgfQogICAgaWYgKGRlZmF1bHRfcHJpbnRlciA9PSBOVUxMKQogICAgewogICAgICAgIEhLRVkgaHdpbmRvd3M7CiAgICAgICAgRFdPUkQgICB0eXBlOwogICAgICAgIC8qIE5UIDMueCBhbmQgYWJvdmUgKi8KICAgICAgICBpZiAoUmVnT3BlbktleUV4KEhLRVlfQ1VSUkVOVF9VU0VSLCAKICAgICAgICAgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3MgTlRcXEN1cnJlbnRWZXJzaW9uXFxXaW5kb3dzIiwKICAgICAgICAgICAgICAgICAgICAgICAgMCwgS0VZX1FVRVJZX1ZBTFVFLCAmaHdpbmRvd3MpID09IE5PX0VSUk9SKSB7CgogICAgICAgICAgICBuZWVkZWQgPSBzaXplb2YoYnVmZmVyKTsKICAgICAgICAgICAgaWYgKFJlZ1F1ZXJ5VmFsdWVFeChod2luZG93cywgImRldmljZSIsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0eXBlLCAoTFBCWVRFKWJ1ZmZlciwgJm5lZWRlZCkgPT0gTk9fRVJST1IpIHsKCiAgICAgICAgICAgICAgICBwdHIgPSBzdHJjaHIoYnVmZmVyLCAnLCcpOwogICAgICAgICAgICAgICAgaWYgKHB0cikgewogICAgICAgICAgICAgICAgICAgIHB0clswXSA9ICdcMCc7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9wcmludGVyID0gYnVmZmVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGh3aW5kb3dzKTsKICAgICAgICB9CiAgICAgICAgdHJhY2UoImRlZmF1bHRfcHJpbnRlcjogJyVzJ1xuIiwgZGVmYXVsdF9wcmludGVyKTsKICAgIH0KICAgIGlmIChkZWZhdWx0X3ByaW50ZXIgPT0gTlVMTCkKICAgIHsKICAgICAgICAvKiB3aW45eCAqLwogICAgICAgIG5lZWRlZCA9IHNpemVvZihidWZmZXIpOwogICAgICAgIHJlcyA9IEdldFByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsICIqIiwgYnVmZmVyLCBuZWVkZWQpOwogICAgICAgIGlmKHJlcykgewogICAgICAgICAgICBwdHIgPSBzdHJjaHIoYnVmZmVyLCAnLCcpOwogICAgICAgICAgICBpZiAocHRyKSB7CiAgICAgICAgICAgICAgICBwdHJbMF0gPSAnXDAnOwogICAgICAgICAgICAgICAgZGVmYXVsdF9wcmludGVyID0gYnVmZmVyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyYWNlKCJkZWZhdWx0X3ByaW50ZXI6ICclcydcbiIsIGRlZmF1bHRfcHJpbnRlcik7CiAgICB9Cn0KCgpzdGF0aWMgc3RydWN0IG1vbml0b3JfZW50cnkgKiBmaW5kX2luc3RhbGxlZF9tb25pdG9yKHZvaWQpCnsKICAgIE1PTklUT1JfSU5GT18yQSBtaTJhOyAKICAgIHN0YXRpYyBzdHJ1Y3QgIG1vbml0b3JfZW50cnkgKiBlbnRyeSA9IE5VTEw7CiAgICBEV09SRCAgIG51bV90ZXN0czsKICAgIERXT1JEICAgaSA9IDA7CgogICAgc3RhdGljIHN0cnVjdCBtb25pdG9yX2VudHJ5ICBtb25pdG9yX3RhYmxlW10gPSB7CiAgICAgICAge2Vudl93aW45eF9jYXNlLCAibG9jYWxzcGwuZGxsIn0sCiAgICAgICAge2Vudl94ODYsICAgICAgICAibG9jYWxzcGwuZGxsIn0sCiAgICAgICAge2Vudl93aW45eF9jYXNlLCAibG9jYWxtb24uZGxsIn0sCiAgICAgICAge2Vudl94ODYsICAgICAgICAibG9jYWxtb24uZGxsIn0sCiAgICAgICAge2Vudl93aW45eF9jYXNlLCAidGNwbW9uLmRsbCJ9LAogICAgICAgIHtlbnZfeDg2LCAgICAgICAgInRjcG1vbi5kbGwifSwKICAgICAgICB7ZW52X3dpbjl4X2Nhc2UsICJ1c2Jtb24uZGxsIn0sCiAgICAgICAge2Vudl94ODYsICAgICAgICAidXNibW9uLmRsbCJ9LAogICAgICAgIHtlbnZfd2luOXhfY2FzZSwgIm1zcHAzMi5kbGwifSwKICAgICAgICB7ZW52X3g4NiwgICAgICAgICJ3aW4zMnNwbC5kbGwifSwKICAgICAgICB7ZW52X3g4NiwgICAgICAgICJyZWRtb25udC5kbGwifSwKICAgICAgICB7ZW52X3g4NiwgICAgICAgICJyZWRtb24zNS5kbGwifSwKICAgICAgICB7ZW52X3dpbjl4X2Nhc2UsICJyZWRtb245NS5kbGwifSwKICAgICAgICB7ZW52X3g4NiwgICAgICAgICJwZGZjbW5udC5kbGwifSwKICAgICAgICB7ZW52X3dpbjl4X2Nhc2UsICJwZGZjbW45NS5kbGwifSwKICAgIH07CgogICAgaWYgKGVudHJ5KSByZXR1cm4gZW50cnk7CgogICAgbnVtX3Rlc3RzID0gKHNpemVvZihtb25pdG9yX3RhYmxlKS9zaXplb2Yoc3RydWN0IG1vbml0b3JfZW50cnkpKTsKCiAgICAvKiBjbGVhbnVwICovCiAgICBEZWxldGVNb25pdG9yQShOVUxMLCBlbnZfeDg2LCB3aW5ldGVzdCk7CiAgICBEZWxldGVNb25pdG9yQShOVUxMLCBlbnZfd2luOXhfY2FzZSwgd2luZXRlc3QpOwoKICAgIC8qIGZpbmQgYSB1c2FibGUgbW9uaXRvciBmcm9tIHRoZSB0YWJsZSAqLwogICAgbWkyYS5wTmFtZSA9IHdpbmV0ZXN0OwogICAgd2hpbGUgKChlbnRyeSA9PSBOVUxMKSAmJiAoaSA8IG51bV90ZXN0cykpIHsKICAgICAgICBlbnRyeSA9ICZtb25pdG9yX3RhYmxlW2ldOwogICAgICAgIGkrKzsKICAgICAgICBtaTJhLnBFbnZpcm9ubWVudCA9IGVudHJ5LT5lbnY7CiAgICAgICAgbWkyYS5wRExMTmFtZSA9IGVudHJ5LT5kbGxuYW1lOwoKICAgICAgICBpZiAoQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpKSB7CiAgICAgICAgICAgIC8qIHdlIGdvdCBvbmUgKi8KICAgICAgICAgICAgdHJhY2UoInVzaW5nICclcycsICclcydcbiIsIGVudHJ5LT5lbnYsIGVudHJ5LT5kbGxuYW1lKTsKICAgICAgICAgICAgRGVsZXRlTW9uaXRvckEoTlVMTCwgZW50cnktPmVudiwgd2luZXRlc3QpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBlbnRyeSA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGVudHJ5Owp9CgoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCBmaW5kX2xvY2FsX3NlcnZlcihWT0lEKQp7CiAgICBzdGF0aWMgIGNoYXIgICAgYnVmZmVyW01BWF9QQVRIXTsKICAgIERXT1JEICAgcmVzOwogICAgRFdPUkQgICBzaXplOwoKICAgIHNpemUgPSBzaXplb2YoYnVmZmVyKSAtIDMgOwogICAgYnVmZmVyWzBdID0gJ1xcJzsKICAgIGJ1ZmZlclsxXSA9ICdcXCc7CiAgICBidWZmZXJbMl0gPSAnXDAnOwoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEdldENvbXB1dGVyTmFtZUEoJmJ1ZmZlclsyXSwgJnNpemUpOwogICAgdHJhY2UoInJldHVybmVkICVkIHdpdGggJWQgYW5kICVkOiAnJXMnXG4iLCByZXMsIEdldExhc3RFcnJvcigpLCBzaXplLCBidWZmZXIpOwoKICAgIG9rKCByZXMgIT0gMCwgInJldHVybmVkICVkIHdpdGggJWQgYW5kICVkOiAnJXMnIChleHBlY3RlZCAnIT0gMCcpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCksIHNpemUsIGJ1ZmZlcik7CgogICAgaWYgKHJlcykgbG9jYWxfc2VydmVyID0gYnVmZmVyOwp9CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIGZpbmRfdGVtcGZpbGUoVk9JRCkKewogICAgc3RhdGljIENIQVIgYnVmZmVyX2RpckFbTUFYX1BBVEhdOwogICAgc3RhdGljIENIQVIgYnVmZmVyX2ZpbGVBW01BWF9QQVRIXTsKICAgIHN0YXRpYyBXQ0hBUiBidWZmZXJfZGlyV1tNQVhfUEFUSF07CiAgICBzdGF0aWMgV0NIQVIgYnVmZmVyX2ZpbGVXW01BWF9QQVRIXTsKICAgIERXT1JEICAgcmVzOwogICAgaW50ICAgICByZXNpbnQ7CgogICAgbWVtc2V0KGJ1ZmZlcl9kaXJBLCAwLCBNQVhfUEFUSCAtIDEpOwogICAgYnVmZmVyX2RpckFbTUFYX1BBVEggLSAxXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRUZW1wUGF0aEEoTUFYX1BBVEgsIGJ1ZmZlcl9kaXJBKTsKICAgIG9rKHJlcywgInJldHVybmVkICV1IHdpdGggJXUgYW5kICclcycgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCksIGJ1ZmZlcl9kaXJBKTsKICAgIGlmIChyZXMgPT0gMCkgcmV0dXJuOwoKICAgIG1lbXNldChidWZmZXJfZmlsZUEsIDAsIE1BWF9QQVRIIC0gMSk7CiAgICBidWZmZXJfZmlsZUFbTUFYX1BBVEggLSAxXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRUZW1wRmlsZU5hbWVBKGJ1ZmZlcl9kaXJBLCB3aW5ldGVzdCwgMCwgYnVmZmVyX2ZpbGVBKTsKICAgIG9rKHJlcywgInJldHVybmVkICV1IHdpdGggJXUgYW5kICclcycgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCksIGJ1ZmZlcl9maWxlQSk7CiAgICBpZiAocmVzID09IDApIHJldHVybjsKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXNpbnQgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgYnVmZmVyX2RpckEsIC0xLCBidWZmZXJfZGlyVywgTUFYX1BBVEgpOwogICAgb2socmVzLCAicmV0dXJuZWQgJXUgd2l0aCAldSAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzaW50LCBHZXRMYXN0RXJyb3IoKSk7CiAgICBpZiAocmVzaW50ID09IDApIHJldHVybjsKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXNpbnQgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgYnVmZmVyX2ZpbGVBLCAtMSwgYnVmZmVyX2ZpbGVXLCBNQVhfUEFUSCk7CiAgICBvayhyZXMsICJyZXR1cm5lZCAldSB3aXRoICV1IChleHBlY3RlZCAnIT0gMCcpXG4iLCByZXNpbnQsIEdldExhc3RFcnJvcigpKTsKICAgIGlmIChyZXNpbnQgPT0gMCkgcmV0dXJuOwoKICAgIHRlbXBkaXJBICA9IGJ1ZmZlcl9kaXJBOwogICAgdGVtcGZpbGVBID0gYnVmZmVyX2ZpbGVBOwogICAgdGVtcGRpclcgID0gYnVmZmVyX2Rpclc7CiAgICB0ZW1wZmlsZVcgPSBidWZmZXJfZmlsZVc7CiAgICB0cmFjZSgidGVtcGZpbGU6ICclcydcbiIsIHRlbXBmaWxlQSk7Cn0KCi8qICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwoKc3RhdGljIHZvaWQgdGVzdF9BZGRNb25pdG9yKHZvaWQpCnsKICAgIE1PTklUT1JfSU5GT18yQSBtaTJhOyAKICAgIHN0cnVjdCAgbW9uaXRvcl9lbnRyeSAqIGVudHJ5ID0gTlVMTDsKICAgIERXT1JEICAgcmVzOwoKICAgIGVudHJ5ID0gZmluZF9pbnN0YWxsZWRfbW9uaXRvcigpOwoKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEFkZE1vbml0b3JBKE5VTEwsIDEsIE5VTEwpOwogICAgb2soIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9MRVZFTCksIAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX0xFVkVMKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBBZGRNb25pdG9yQShOVUxMLCAzLCBOVUxMKTsKICAgIG9rKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTEVWRUwpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9MRVZFTClcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgaWYgKDApCiAgICB7CiAgICAvKiBUaGlzIHRlc3QgY3Jhc2ggd2l0aCB3aW45eCBvbiB2bXdhcmUgKHdvcmtzIHdpdGggd2luOXggb24gcWVtdSAwLjguMSkgKi8KICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEFkZE1vbml0b3JBKE5VTEwsIDIsIE5VTEwpOwogICAgLyogTlQ6IHVuY2hhbmdlZCwgIDl4OiBFUlJPUl9QUklWSUxFR0VfTk9UX0hFTEQgKi8KICAgIG9rKCFyZXMgJiYKICAgICAgICAoKEdldExhc3RFcnJvcigpID09IE1BR0lDX0RFQUQpIHx8CiAgICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QUklWSUxFR0VfTk9UX0hFTEQpKSwgCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoOiBNQUdJQ19ERUFEIG9yICIKICAgICAgICAiRVJST1JfUFJJVklMRUdFX05PVF9IRUxEKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICB9CgogICAgWmVyb01lbW9yeSgmbWkyYSwgc2l6ZW9mKE1PTklUT1JfSU5GT18yQSkpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQogICAgUkVUVVJOX09OX0FDQ0VTU19ERU5JRUQocmVzKQoKICAgIC8qIE5UOiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgIDl4OiBFUlJPUl9JTlZBTElEX0VOVklST05NRU5UICovCiAgICBvayghcmVzICYmICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpIHx8CiAgICAgICAgICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9FTlZJUk9OTUVOVCkpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9FTlZJUk9OTUVOVClcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIGlmICghZW50cnkpIHsKICAgICAgICBza2lwKCJObyB1c2FibGUgTW9uaXRvciBmb3VuZFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICgwKQogICAgewogICAgLyogVGhlIFRlc3QgaXMgZGVhY3RpdmF0ZWQsIGJlY2F1c2Ugd2hlbiBtaTJhLnBOYW1lIGlzIE5VTEwsIHRoZSBzdWJrZXkKICAgICAgIEhLTE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0XENvbnRyb2xcUHJpbnRcTW9uaXRvcnNcQzpcV0lORE9XU1xTWVNURU0KICAgICAgIG9yIEhLTE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0XENvbnRyb2xcUHJpbnRcTW9uaXRvcnNc7AogICAgICAgaXMgY3JlYXRlZCBvbiB3aW45eCBhbmQgd2UgZG8gbm90IHdhbnQgdG8gaGl0IHRoaXMgYnVnIGhlcmUuICovCgogICAgbWkyYS5wRW52aXJvbm1lbnQgPSBlbnRyeS0+ZW52OwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgLyogTlQ6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSLCAgOXg6IEVSUk9SX1BSSVZJTEVHRV9OT1RfSEVMRCAqLwogICAgfQoKICAgIG1pMmEucEVudmlyb25tZW50ID0gZW50cnktPmVudjsKICAgIG1pMmEucE5hbWUgPSBlbXB0eTsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEFkZE1vbml0b3JBKE5VTEwsIDIsIChMUEJZVEUpICZtaTJhKTsKICAgIC8qIE5UOiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgIDl4OiBFUlJPUl9QUklWSUxFR0VfTk9UX0hFTEQgKi8KICAgIG9rKCAhcmVzICYmCiAgICAgICAgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUikgfHwKICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX1BSSVZJTEVHRV9OT1RfSEVMRCkpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSIG9yICIKICAgICAgICAiRVJST1JfUFJJVklMRUdFX05PVF9IRUxEKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBtaTJhLnBOYW1lID0gd2luZXRlc3Q7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBBZGRNb25pdG9yQShOVUxMLCAyLCAoTFBCWVRFKSAmbWkyYSk7CiAgICAvKiBOVDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIsICA5eDogRVJST1JfUFJJVklMRUdFX05PVF9IRUxEICovCiAgICBvayggIXJlcyAmJgogICAgICAgICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpIHx8CiAgICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QUklWSUxFR0VfTk9UX0hFTEQpKSwgCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoOiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiBvciAiCiAgICAgICAgIkVSUk9SX1BSSVZJTEVHRV9OT1RfSEVMRClcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgbWkyYS5wRExMTmFtZSA9IGVtcHR5OwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIG1pMmEucERMTE5hbWUgPSBkb2VzX25vdF9leGlzdF9kbGw7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBBZGRNb25pdG9yQShOVUxMLCAyLCAoTFBCWVRFKSAmbWkyYSk7CiAgICAvKiBOVDogRVJST1JfTU9EX05PVF9GT1VORCwgIDl4OiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiAqLwogICAgb2soICFyZXMgJiYKICAgICAgICAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX01PRF9OT1RfRk9VTkQpIHx8CiAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoOiBFUlJPUl9NT0RfTk9UX0ZPVU5EIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBtaTJhLnBETExOYW1lID0gdmVyc2lvbl9kbGw7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBBZGRNb25pdG9yQShOVUxMLCAyLCAoTFBCWVRFKSAmbWkyYSk7CiAgICAvKiBOVDogRVJST1JfUFJPQ19OT1RfRk9VTkQsICA5eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKi8KICAgIG9rKCAhcmVzICYmCiAgICAgICAgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QUk9DX05PVF9GT1VORCkgfHwKICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGg6IEVSUk9SX1BST0NfTk9UX0ZPVU5EIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgIGlmIChyZXMpIERlbGV0ZU1vbml0b3JBKE5VTEwsIGVudHJ5LT5lbnYsIHdpbmV0ZXN0KTsKCiAgIC8qIFRlc3QgQWRkTW9uaXRvciB3aXRoIHJlYWwgb3B0aW9ucyAqLwogICAgbWkyYS5wRExMTmFtZSA9IGVudHJ5LT5kbGxuYW1lOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgLyogYWRkIGEgbW9uaXRvciB0d2ljZSAqLwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgLyogTlQ6IEVSUk9SX1BSSU5UX01PTklUT1JfQUxSRUFEWV9JTlNUQUxMRUQgKDMwMDYpLCA5eDogRVJST1JfQUxSRUFEWV9FWElTVFMgKDE4MykgKi8KICAgIG9rKCAhcmVzICYmCiAgICAgICAgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QUklOVF9NT05JVE9SX0FMUkVBRFlfSU5TVEFMTEVEKSB8fAogICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9BTFJFQURZX0VYSVNUUykpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGg6ICIKICAgICAgICAiRVJST1JfUFJJTlRfTU9OSVRPUl9BTFJFQURZX0lOU1RBTExFRCBvciBFUlJPUl9BTFJFQURZX0VYSVNUUylcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgRGVsZXRlTW9uaXRvckEoTlVMTCwgZW50cnktPmVudiwgd2luZXRlc3QpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gQWRkTW9uaXRvckEoZW1wdHksIDIsIChMUEJZVEUpICZtaTJhKTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIC8qIGNsZWFudXAgKi8KICAgIERlbGV0ZU1vbml0b3JBKE5VTEwsIGVudHJ5LT5lbnYsIHdpbmV0ZXN0KTsKCn0KCi8qICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwoKc3RhdGljIHZvaWQgdGVzdF9BZGRQb3J0KHZvaWQpCnsKICAgIERXT1JEICAgcmVzOwoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEFkZFBvcnRBKE5VTEwsIDAsIE5VTEwpOwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQogICAgLyogTlQ6IFJQQ19YX05VTExfUkVGX1BPSU5URVIsIDl4OiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiAqLwogICAgb2soICFyZXMgJiYgKChHZXRMYXN0RXJyb3IoKSA9PSBSUENfWF9OVUxMX1JFRl9QT0lOVEVSKSB8fCAKICAgICAgICAgICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfTk9UX1NVUFBPUlRFRCBvciAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEFkZFBvcnRBKE5VTEwsIDAsIGVtcHR5KTsKICAgIC8qIEFsbG93ZWQgb25seSBmb3IgKFByaW50ZXItKUFkbWluaXN0cmF0b3JzICovCiAgICBSRVRVUk5fT05fQUNDRVNTX0RFTklFRChyZXMpCgogICAgLyogWFA6IEVSUk9SX05PVF9TVVBQT1JURUQsIE5UMzUxIGFuZCA5eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKi8KICAgIG9rKCAhcmVzICYmICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfTk9UX1NVUFBPUlRFRCkgfHwgCiAgICAgICAgICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX05PVF9TVVBQT1JURUQgb3IgIgogICAgICAgICJFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBBZGRQb3J0QShOVUxMLCAwLCBkb2VzX25vdF9leGlzdCk7CiAgICAvKiBYUDogRVJST1JfTk9UX1NVUFBPUlRFRCwgTlQzNTEgYW5kIDl4OiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiAqLwogICAgb2soICFyZXMgJiYgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9OT1RfU1VQUE9SVEVEKSB8fCAKICAgICAgICAgICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfTk9UX1NVUFBPUlRFRCBvciAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7Cgp9CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIHRlc3RfQWRkUG9ydEV4KHZvaWQpCnsKICAgIFBPUlRfSU5GT18yQSBwaTsKICAgIERXT1JEICAgcmVzOwoKCiAgICBpZiAoIXBBZGRQb3J0RXhBKSB7CiAgICAgICAgc2tpcCgiQWRkUG9ydEV4IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBzdGFydCB0ZXN0IHdpdGggYSBjbGVhbiBzeXN0ZW0gKi8KICAgIERlbGV0ZVBvcnRBKE5VTEwsIDAsIHRlbXBmaWxlQSk7CgogICAgcGkucFBvcnROYW1lID0gdGVtcGZpbGVBOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcEFkZFBvcnRFeEEoTlVMTCwgMSwgKExQQllURSkgJnBpLCBMb2NhbFBvcnRBKTsKICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKCiAgICAvKiBBbGxvd2VkIG9ubHkgZm9yIChQcmludGVyLSlBZG1pbmlzdHJhdG9ycy4KICAgICAgIFcySytYUDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgICovCiAgICBpZiAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpKSB7CiAgICAgICAgc2tpcCgiQUNDRVNTX0RFTklFRCAoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBvayggcmVzLCAiZ290ICV1IHdpdGggJXUgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIC8qIEFkZCBhIHBvcnQsIHRoYXQgYWxyZWFkeSBleGlzdCAqLwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcEFkZFBvcnRFeEEoTlVMTCwgMSwgKExQQllURSkgJnBpLCBMb2NhbFBvcnRBKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksCiAgICAgICAgImdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICBEZWxldGVQb3J0QShOVUxMLCAwLCB0ZW1wZmlsZUEpOwoKCiAgICAvKiB0aGUgTW9uaXRvcm5hbWUgbXVzdCBtYXRjaCAqLwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcEFkZFBvcnRFeEEoTlVMTCwgMSwgKExQQllURSkgJnBpLCBOVUxMKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksCiAgICAgICAgImdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICBpZiAocmVzKSBEZWxldGVQb3J0QShOVUxMLCAwLCB0ZW1wZmlsZUEpOwoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBBZGRQb3J0RXhBKE5VTEwsIDEsIChMUEJZVEUpICZwaSwgZW1wdHkpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSwKICAgICAgICAiZ290ICV1IHdpdGggJXUgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKICAgIGlmIChyZXMpIERlbGV0ZVBvcnRBKE5VTEwsIDAsIHRlbXBmaWxlQSk7CgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcEFkZFBvcnRFeEEoTlVMTCwgMSwgKExQQllURSkgJnBpLCBkb2VzX25vdF9leGlzdCk7CiAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpLAogICAgICAgICJnb3QgJXUgd2l0aCAldSAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgaWYgKHJlcykgRGVsZXRlUG9ydEEoTlVMTCwgMCwgdGVtcGZpbGVBKTsKCgogICAgLyogV2UgbmVlZCBhIFBvcnRuYW1lICovCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwQWRkUG9ydEV4QShOVUxMLCAxLCBOVUxMLCBMb2NhbFBvcnRBKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksCiAgICAgICAgImdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgcGkucFBvcnROYW1lID0gTlVMTDsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBBZGRQb3J0RXhBKE5VTEwsIDEsIChMUEJZVEUpICZwaSwgTG9jYWxQb3J0QSk7CiAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpLAogICAgICAgICJnb3QgJXUgd2l0aCAldSAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgaWYgKHJlcykgRGVsZXRlUG9ydEEoTlVMTCwgMCwgdGVtcGZpbGVBKTsKCgogICAgLyogIGxldmVsIDIgaXMgZG9jdW1lbnRlZCBhcyBzdXBwb3J0ZWQgZm9yIFByaW50bW9uaXRvcnMsCiAgICAgICAgYnV0IHRoYXQgaXMgbm90IHN1cHBvcnRlZCBmb3IgIkxvY2FsIFBvcnQiIChsb2NhbHNwbC5kbGwpIGFuZAogICAgICAgIEFkZFBvcnRFeCBmYWlscyB3aXRoIEVSUk9SX0lOVkFMSURfTEVWRUwgKi8KCiAgICBwaS5wUG9ydE5hbWUgPSB0ZW1wZmlsZUE7CiAgICBwaS5wTW9uaXRvck5hbWUgPSBMb2NhbFBvcnRBOwogICAgcGkucERlc2NyaXB0aW9uID0gd2luZXRlc3Q7CiAgICBwaS5mUG9ydFR5cGUgPSBQT1JUX1RZUEVfV1JJVEU7CgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcEFkZFBvcnRFeEEoTlVMTCwgMiwgKExQQllURSkgJnBpLCBMb2NhbFBvcnRBKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSwKICAgICAgICAiZ290ICV1IHdpdGggJXUgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX0lOVkFMSURfTEVWRUwpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgaWYgKHJlcykgRGVsZXRlUG9ydEEoTlVMTCwgMCwgdGVtcGZpbGVBKTsKCgogICAgLyogaW52YWxpZCBsZXZlbHMgKi8KICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBBZGRQb3J0RXhBKE5VTEwsIDAsIChMUEJZVEUpICZwaSwgTG9jYWxQb3J0QSk7CiAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9MRVZFTCksCiAgICAgICAgImdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX0xFVkVMKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwQWRkUG9ydEV4QShOVUxMLCAzLCAoTFBCWVRFKSAmcGksIExvY2FsUG9ydEEpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTEVWRUwpLAogICAgICAgICJnb3QgJXUgd2l0aCAldSAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9MRVZFTClcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgoKICAgIC8qIGNsZWFudXAgKi8KICAgIERlbGV0ZVBvcnRBKE5VTEwsIDAsIHRlbXBmaWxlQSk7Cgp9CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIHRlc3RfQ29uZmlndXJlUG9ydCh2b2lkKQp7CiAgICBEV09SRCAgIHJlczsKCgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gQ29uZmlndXJlUG9ydEEoTlVMTCwgMCwgTlVMTCk7CiAgICBSRVRVUk5fT05fREVBQ1RJVkFURURfU1BPT0xFUihyZXMpCiAgICAvKiBOVDogUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiwgOXg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICovCiAgICBvayggIXJlcyAmJiAoKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpIHx8IAogICAgICAgICAgICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUikpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9OT1RfU1VQUE9SVEVEIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBDb25maWd1cmVQb3J0QShOVUxMLCAwLCBlbXB0eSk7CiAgICAvKiBBbGxvd2VkIG9ubHkgZm9yIChQcmludGVyLSlBZG1pbmlzdHJhdG9ycyAqLwogICAgUkVUVVJOX09OX0FDQ0VTU19ERU5JRUQocmVzKQoKICAgIC8qIFhQOiBFUlJPUl9OT1RfU1VQUE9SVEVELCBOVDM1MSBhbmQgOXg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICovCiAgICBvayggIXJlcyAmJiAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX05PVF9TVVBQT1JURUQpIHx8IAogICAgICAgICAgICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUikpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9OT1RfU1VQUE9SVEVEIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gQ29uZmlndXJlUG9ydEEoTlVMTCwgMCwgZG9lc19ub3RfZXhpc3QpOwogICAgLyogWFA6IEVSUk9SX05PVF9TVVBQT1JURUQsIE5UMzUxIGFuZCA5eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKi8KICAgIG9rKCAhcmVzICYmICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfTk9UX1NVUFBPUlRFRCkgfHwgCiAgICAgICAgICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX05PVF9TVVBQT1JURUQgb3IgIgogICAgICAgICJFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICAvKiAgVGVzdGluZy1SZXN1bHRzOgogICAgICAgIC0gQ2FzZSBvZiBQb3J0bmFtZXMgaXMgaWdub3JlZCAKICAgICAgICAtIFBvcnRuYW1lIHdpdGhvdXQgIjoiID0+IE5UOiBFUlJPUl9OT1RfU1VQUE9SVEVELCA5eDogRGlhbG9nIGNvbWVzIHVwCiAgICAgICAgLSBFbXB0eSBTZXJ2ZXJuYW1lIChMUFQxOikgPT4gTlQ6IEVSUk9SX05PVF9TVVBQT1JURUQsIDl4OiBEaWFsb2cgY29tZXMgdXAKCiAgICAgICAgLSBQb3J0IG5vdCBwcmVzZW50ID0+ICA5eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIsIE5UOkVSUk9SX05PVF9TVVBQT1JURUQKICAgICAgICAtICJGSUxFOiIgPT4gOXg6U3VjY2VzcywgTlQ6RVJST1JfQ0FOQ0VMRUQKICAgICAgICAtIENhbmNlbCAoIkxvY2FsIFBvcnQiKSA9PiBFUlJPUl9DQU5DRUxFRAogICAgICAgIC0gQ2FuY2VsICgiUmVkaXJlY3RlZCBQb3J0IikgPT4gU3VjY2VzcwogICAgKi8KICAgIGlmICh3aW5ldGVzdF9pbnRlcmFjdGl2ZSA+IDApIHsKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gQ29uZmlndXJlUG9ydEEoTlVMTCwgMCwgcG9ydG5hbWVfY29tMSk7CiAgICAgICAgdHJhY2UoIiclcycgcmV0dXJuZWQgJWQgd2l0aCAlZFxuIiwgcG9ydG5hbWVfY29tMSwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBDb25maWd1cmVQb3J0QShOVUxMLCAwLCBwb3J0bmFtZV9scHQxKTsKICAgICAgICB0cmFjZSgiJyVzJyByZXR1cm5lZCAlZCB3aXRoICVkXG4iLCBwb3J0bmFtZV9scHQxLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIHJlcyA9IENvbmZpZ3VyZVBvcnRBKE5VTEwsIDAsIHBvcnRuYW1lX2ZpbGUpOwogICAgICAgIHRyYWNlKCInJXMnIHJldHVybmVkICVkIHdpdGggJWRcbiIsIHBvcnRuYW1lX2ZpbGUsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgfQp9CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIHRlc3RfRGVsZXRlTW9uaXRvcih2b2lkKQp7CiAgICBNT05JVE9SX0lORk9fMkEgICAgICAgICBtaTJhOwogICAgc3RydWN0IG1vbml0b3JfZW50cnkgICogZW50cnkgPSBOVUxMOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgcmVzOwoKCiAgICBlbnRyeSA9IGZpbmRfaW5zdGFsbGVkX21vbml0b3IoKTsKCiAgICBpZiAoIWVudHJ5KSB7CiAgICAgICAgc2tpcCgiTm8gdXNhYmxlIE1vbml0b3IgZm91bmRcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBtaTJhLnBOYW1lID0gd2luZXRlc3Q7CiAgICBtaTJhLnBFbnZpcm9ubWVudCA9IGVudHJ5LT5lbnY7CiAgICBtaTJhLnBETExOYW1lID0gZW50cnktPmRsbG5hbWU7CgogICAgLyogVGVzdGluZyBEZWxldGVNb25pdG9yIHdpdGggcmVhbCBvcHRpb25zICovCiAgICBBZGRNb25pdG9yQShOVUxMLCAyLCAoTFBCWVRFKSAmbWkyYSk7CgogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gRGVsZXRlTW9uaXRvckEoTlVMTCwgZW50cnktPmVudiwgd2luZXRlc3QpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgLyogRGVsZXRlIHRoZSBNb25pdG9yIHR3aWNlICovCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBEZWxldGVNb25pdG9yQShOVUxMLCBlbnRyeS0+ZW52LCB3aW5ldGVzdCk7CiAgICAvKiBOVDogRVJST1JfVU5LTk9XTl9QUklOVF9NT05JVE9SICgzMDAwKSwgOXg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICg4NykgKi8KICAgIG9rKCAhcmVzICYmCiAgICAgICAgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9VTktOT1dOX1BSSU5UX01PTklUT1IpIHx8CiAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSksIAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aDogRVJST1JfVU5LTk9XTl9QUklOVF9NT05JVE9SIgogICAgICAgICIgb3IgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAvKiB0aGUgZW52aXJvbm1lbnQgKi8KICAgIEFkZE1vbml0b3JBKE5VTEwsIDIsIChMUEJZVEUpICZtaTJhKTsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IERlbGV0ZU1vbml0b3JBKE5VTEwsIE5VTEwsIHdpbmV0ZXN0KTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gRGVsZXRlTW9uaXRvckEoTlVMTCwgZW1wdHksIHdpbmV0ZXN0KTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gRGVsZXRlTW9uaXRvckEoTlVMTCwgaW52YWxpZF9lbnYsIHdpbmV0ZXN0KTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgLyogdGhlIG1vbml0b3ItbmFtZSAqLwogICAgQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gRGVsZXRlTW9uaXRvckEoTlVMTCwgZW50cnktPmVudiwgTlVMTCk7CiAgICAvKiBOVDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKDg3KSwgIDl4OiBFUlJPUl9JTlZBTElEX05BTUUgKDEyMykqLwogICAgb2soICFyZXMgJiYKICAgICAgICAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSB8fAogICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX05BTUUpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGg6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSIG9yICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9OQU1FKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgQWRkTW9uaXRvckEoTlVMTCwgMiwgKExQQllURSkgJm1pMmEpOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gRGVsZXRlTW9uaXRvckEoTlVMTCwgZW50cnktPmVudiwgZW1wdHkpOwogICAgLyogTlQ6IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICg4NyksICA5eDogRVJST1JfSU5WQUxJRF9OQU1FICgxMjMpKi8KICAgIG9rKCAhcmVzICYmIAogICAgICAgICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpIHx8CiAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTkFNRSkpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgb3IgIgogICAgICAgICJFUlJPUl9JTlZBTElEX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBBZGRNb25pdG9yQShOVUxMLCAyLCAoTFBCWVRFKSAmbWkyYSk7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBEZWxldGVNb25pdG9yQShlbXB0eSwgZW50cnktPmVudiwgd2luZXRlc3QpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAvKiBjbGVhbnVwICovCiAgICBEZWxldGVNb25pdG9yQShOVUxMLCBlbnRyeS0+ZW52LCB3aW5ldGVzdCk7Cn0KCi8qICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwoKc3RhdGljIHZvaWQgdGVzdF9EZWxldGVQb3J0KHZvaWQpCnsKICAgIERXT1JEICAgcmVzOwoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IERlbGV0ZVBvcnRBKE5VTEwsIDAsIE5VTEwpOwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IERlbGV0ZVBvcnRBKE5VTEwsIDAsIGVtcHR5KTsKICAgIC8qIEFsbG93ZWQgb25seSBmb3IgKFByaW50ZXItKUFkbWluaXN0cmF0b3JzICovCiAgICBSRVRVUk5fT05fQUNDRVNTX0RFTklFRChyZXMpCgogICAgLyogWFA6IEVSUk9SX05PVF9TVVBQT1JURUQsIE5UMzUxIGFuZCA5eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKi8KICAgIG9rKCAhcmVzICYmICgoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfTk9UX1NVUFBPUlRFRCkgfHwgCiAgICAgICAgICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX05PVF9TVVBQT1JURUQgb3IgIgogICAgICAgICJFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBEZWxldGVQb3J0QShOVUxMLCAwLCBkb2VzX25vdF9leGlzdCk7CiAgICAvKiBYUDogRVJST1JfTk9UX1NVUFBPUlRFRCwgTlQzNTEgYW5kIDl4OiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiAqLwogICAgb2soICFyZXMgJiYgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9OT1RfU1VQUE9SVEVEKSB8fCAKICAgICAgICAgICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfTk9UX1NVUFBPUlRFRCBvciAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7Cgp9CgovKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgKi8KCnN0YXRpYyB2b2lkIHRlc3RfRW51bUZvcm1zKExQU1RSIHBOYW1lKQp7CiAgICBEV09SRCAgIHJlczsKICAgIEhBTkRMRSAgaHByaW50ZXIgPSAwOwogICAgTFBCWVRFICBidWZmZXI7CiAgICBEV09SRCAgIGNiQnVmOwogICAgRFdPUkQgICBwY2JOZWVkZWQ7CiAgICBEV09SRCAgIHBjUmV0dXJuZWQ7CiAgICBEV09SRCAgIGxldmVsOwogICAgSU5UICAgICBpOwogICAgY29uc3QgY2hhciAqZm9ybXR5cGU7CiAgICBzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGZvcm10eXBlc1tdID0geyAiRk9STV9VU0VSIiwgIkZPUk1fQlVJTFRJTiIsICJGT1JNX1BSSU5URVIiLCAiRk9STV9mbGFnX3Vua25vd24iIH07CiNkZWZpbmUgRk9STVRZUEVfTUFYIDIKICAgIFBGT1JNX0lORk9fMUEgcEZJXzFhOwogICAgUEZPUk1fSU5GT18yQSBwRklfMmE7CgogICAgcmVzID0gT3BlblByaW50ZXIocE5hbWUsICZocHJpbnRlciwgTlVMTCk7CiAgICBSRVRVUk5fT05fREVBQ1RJVkFURURfU1BPT0xFUihyZXMpCiAgICBpZiAoIXJlcyB8fCAhaHByaW50ZXIpCiAgICB7CiAgICAgICAgLyogT3BlbiB0aGUgbG9jYWwgUHJpbnNlcnZlciBpcyBub3Qgc3VwcG9ydGVkIG9uIHdpbjl4ICovCiAgICAgICAgaWYgKHBOYW1lKSBza2lwKCJGYWlsZWQgdG8gb3BlbiAnJXMnIChub3Qgc3VwcG9ydGVkIG9uIHdpbjl4KVxuIiwgcE5hbWUpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiB2YWxpZCBsZXZlbHMgYXJlIDEgYW5kIDIgKi8KICAgIGZvcihsZXZlbCA9IDA7IGxldmVsIDwgNDsgbGV2ZWwrKykgewogICAgICAgIGNiQnVmID0gMHhkZWFkYmVlZjsKICAgICAgICBwY1JldHVybmVkID0gMHhkZWFkYmVlZjsKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gRW51bUZvcm1zQShocHJpbnRlciwgbGV2ZWwsIE5VTEwsIDAsICZjYkJ1ZiwgJnBjUmV0dXJuZWQpOwoKICAgICAgICAvKiBFbnVtRm9ybXMgaXMgbm90IGltcGxlbWVudGVkIGluIHdpbjl4ICovCiAgICAgICAgaWYgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEKSkgY29udGludWU7CgogICAgICAgIC8qIEVudW1Gb3JtcyBmb3IgdGhlIFNlcnZlciBub3QgaW1wbGVtZW50ZWQgb24gYWxsIE5ULVZlcnNpb25zICovCiAgICAgICAgaWYgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfSEFORExFKSAmJiAhcE5hbWUpIGNvbnRpbnVlOwoKICAgICAgICAvKiBMZXZlbCAyIGZvciBFbnVtRm9ybXMgaXMgbm90IHN1cHBvcnRlZCBvbiBhbGwgc3lzdGVtcyAqLwogICAgICAgIGlmICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSAmJiAobGV2ZWwgPT0gMikpIGNvbnRpbnVlOwoKICAgICAgICAvKiB1c2Ugb25seSBhIHNob3J0IHRlc3QsIHdoZW4gd2UgdGVzdCB3aXRoIGFuIGludmFsaWQgbGV2ZWwgKi8KICAgICAgICBpZighbGV2ZWwgfHwgKGxldmVsID4gMikpIHsKICAgICAgICAgICAgb2soICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSkgfHwKICAgICAgICAgICAgICAgIChyZXMgJiYgKHBjUmV0dXJuZWQgPT0gMCkpLAogICAgICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCBhbmQgMHglMDh4IChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgICAgICAgICAiRVJST1JfSU5WQUxJRF9MRVZFTCBvciAnIT0wJyBhbmQgMHgwKVxuIiwKICAgICAgICAgICAgICAgIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpLCBwY1JldHVybmVkKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBvaygoIXJlcykgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpLAogICAgICAgICAgICAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgICAgICJFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICBidWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2JCdWYgKjIpOwogICAgICAgIGlmIChidWZmZXIgPT0gTlVMTCkgY29udGludWU7CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtRm9ybXNBKGhwcmludGVyLCBsZXZlbCwgYnVmZmVyLCBjYkJ1ZiwgJnBjYk5lZWRlZCwgJnBjUmV0dXJuZWQpOwogICAgICAgIG9rKHJlcywgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcpXG4iLAogICAgICAgICAgICAgICAgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICBpZiAod2luZXRlc3RfZGVidWcgPiAxKSB7CiAgICAgICAgICAgIHRyYWNlKCJkdW1waW5nICVkIGZvcm1zIGxldmVsICVkXG4iLCBwY1JldHVybmVkLCBsZXZlbCk7CiAgICAgICAgICAgIHBGSV8xYSA9IChQRk9STV9JTkZPXzFBKWJ1ZmZlcjsKICAgICAgICAgICAgcEZJXzJhID0gKFBGT1JNX0lORk9fMkEpYnVmZmVyOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGNSZXR1cm5lZDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBmaXJzdCBwYXJ0IGlzIHNhbWUgaW4gRk9STV9JTkZPXzEgYW5kIEZPUk1fSU5GT18yICovCiAgICAgICAgICAgICAgICBmb3JtdHlwZSA9IChwRklfMWEtPkZsYWdzIDw9IEZPUk1UWVBFX01BWCkgPyBmb3JtdHlwZXNbcEZJXzFhLT5GbGFnc10gOiBmb3JtdHlwZXNbM107CiAgICAgICAgICAgICAgICB0cmFjZSgiJXUgKCVzKTogJS4wM2ZtbSB4ICUuMDNmbW0sICVzXG4iLCBpLCBwRklfMWEtPnBOYW1lLAogICAgICAgICAgICAgICAgICAgICAgKGZsb2F0KXBGSV8xYS0+U2l6ZS5jeC8xMDAwLCAoZmxvYXQpcEZJXzFhLT5TaXplLmN5LzEwMDAsIGZvcm10eXBlKTsKCiAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPT0gMSkgcEZJXzFhICsrOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogb3V0cHV0IGFkZGl0aW9uYWwgRk9STV9JTkZPXzIgZmllbGRzICovCiAgICAgICAgICAgICAgICAgICAgdHJhY2UoIlx0a2V5d29yZD0lcyBzdHJ0eXBlPSV1IG11aWRsbD0lcyByZXNpZD0ldSBkaXNwbmFtZT0lcyBsYW5naWQ9JXVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcEZJXzJhLT5wS2V5d29yZCwgcEZJXzJhLT5TdHJpbmdUeXBlLCBwRklfMmEtPnBNdWlEbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcEZJXzJhLT5kd1Jlc291cmNlSWQsIHBGSV8yYS0+cERpc3BsYXlOYW1lLCBwRklfMmEtPndMYW5nSWQpOwoKICAgICAgICAgICAgICAgICAgICAvKiBvZmZzZXQgcG9pbnRlciBwRklfMWEgYnkgMSpzaXplb2YoRk9STV9JTkZPXzJBKSBCeXRlcyAqLwogICAgICAgICAgICAgICAgICAgIHBGSV8yYSArKzsKICAgICAgICAgICAgICAgICAgICBwRklfMWEgPSAoUEZPUk1fSU5GT18xQSlwRklfMmE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtRm9ybXNBKGhwcmludGVyLCBsZXZlbCwgYnVmZmVyLCBjYkJ1ZisxLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgb2soIHJlcywgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcpXG4iLAogICAgICAgICAgICBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtRm9ybXNBKGhwcmludGVyLCBsZXZlbCwgYnVmZmVyLCBjYkJ1Zi0xLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpLAogICAgICAgICAgICAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgICAgICJFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIHJlcyA9IEVudW1Gb3Jtc0EoaHByaW50ZXIsIGxldmVsLCBOVUxMLCBjYkJ1ZiwgJnBjYk5lZWRlZCwgJnBjUmV0dXJuZWQpOwogICAgICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1VTRVJfQlVGRkVSKSAsCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0lOVkFMSURfVVNFUl9CVUZGRVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgoKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gRW51bUZvcm1zQShocHJpbnRlciwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsIE5VTEwsICZwY1JldHVybmVkKTsKICAgICAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1hfTlVMTF9SRUZfUE9JTlRFUikgLAogICAgICAgICAgICAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgICAgICJSUENfWF9OVUxMX1JFRl9QT0lOVEVSKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gRW51bUZvcm1zQShocHJpbnRlciwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsICZwY2JOZWVkZWQsIE5VTEwpOwogICAgICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBSUENfWF9OVUxMX1JFRl9QT0lOVEVSKSAsCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtRm9ybXNBKDAsIGxldmVsLCBidWZmZXIsIGNiQnVmLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfSEFORExFKSAsCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0lOVkFMSURfSEFORExFKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWZmZXIpOwogICAgfSAvKiBmb3IobGV2ZWwgLi4uICovCgogICAgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X0VudW1Nb25pdG9ycyh2b2lkKQp7CiAgICBEV09SRCAgIHJlczsKICAgIExQQllURSAgYnVmZmVyOwogICAgRFdPUkQgICBjYkJ1ZjsKICAgIERXT1JEICAgcGNiTmVlZGVkOwogICAgRFdPUkQgICBwY1JldHVybmVkOwogICAgRFdPUkQgICBsZXZlbDsKCiAgICAvKiB2YWxpZCBsZXZlbHMgYXJlIDEgYW5kIDIgKi8KICAgIGZvcihsZXZlbCA9IDA7IGxldmVsIDwgNDsgbGV2ZWwrKykgewogICAgICAgIGNiQnVmID0gTUFHSUNfREVBRDsKICAgICAgICBwY1JldHVybmVkID0gTUFHSUNfREVBRDsKICAgICAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICAgICAgcmVzID0gRW51bU1vbml0b3JzQShOVUxMLCBsZXZlbCwgTlVMTCwgMCwgJmNiQnVmLCAmcGNSZXR1cm5lZCk7CgogICAgICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKCiAgICAgICAgLyogbm90IGltcGxlbWVudGVkIHlldCBpbiB3aW5lICovCiAgICAgICAgaWYgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEKSkgY29udGludWU7CgoKICAgICAgICAvKiB1c2Ugb25seSBhIHNob3J0IHRlc3QsIHdoZW4gd2UgdGVzdCB3aXRoIGFuIGludmFsaWQgbGV2ZWwgKi8KICAgICAgICBpZighbGV2ZWwgfHwgKGxldmVsID4gMikpIHsKICAgICAgICAgICAgb2soICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSkgfHwKICAgICAgICAgICAgICAgIChyZXMgJiYgKHBjUmV0dXJuZWQgPT0gMCkpLAogICAgICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCBhbmQgMHglMDh4IChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgICAgICAgICAiRVJST1JfSU5WQUxJRF9MRVZFTCBvciAnIT0wJyBhbmQgMHgwKVxuIiwKICAgICAgICAgICAgICAgIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpLCBwY1JldHVybmVkKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfSAgICAgICAgCgogICAgICAgIC8qIExldmVsIDIgaXMgbm90IHN1cHBvcnRlZCBvbiB3aW45eCAqLwogICAgICAgIGlmICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSkgewogICAgICAgICAgICBza2lwKCJMZXZlbCAlZCBub3Qgc3VwcG9ydGVkXG4iLCBsZXZlbCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgb2soKCFyZXMpICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggIgogICAgICAgICAgICAiRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgaWYgKCFjYkJ1ZikgewogICAgICAgICAgICBza2lwKCJubyB2YWxpZCBidWZmZXIgc2l6ZSByZXR1cm5lZFxuIik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNiQnVmICoyKTsKICAgICAgICBpZiAoYnVmZmVyID09IE5VTEwpIGNvbnRpbnVlOwoKICAgICAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICAgICAgcGNiTmVlZGVkID0gTUFHSUNfREVBRDsKICAgICAgICByZXMgPSBFbnVtTW9uaXRvcnNBKE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgb2socmVzLCAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJylcbiIsCiAgICAgICAgICAgICAgICBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgb2socGNiTmVlZGVkID09IGNiQnVmLCAiKCVkKSByZXR1cm5lZCAlZCAoZXhwZWN0ZWQgJWQpXG4iLAogICAgICAgICAgICAgICAgbGV2ZWwsIHBjYk5lZWRlZCwgY2JCdWYpOwogICAgICAgIC8qIFdlIGNhbiB2YWxpZGF0ZSB0aGUgcmV0dXJuZWQgRGF0YSB3aXRoIHRoZSBSZWdpc3RyeSBoZXJlICovCgoKICAgICAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICAgICAgcGNSZXR1cm5lZCA9IE1BR0lDX0RFQUQ7CiAgICAgICAgcGNiTmVlZGVkID0gTUFHSUNfREVBRDsKICAgICAgICByZXMgPSBFbnVtTW9uaXRvcnNBKE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmKzEsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKICAgICAgICBvayhyZXMsICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgbGV2ZWwsCiAgICAgICAgICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBvayhwY2JOZWVkZWQgPT0gY2JCdWYsICIoJWQpIHJldHVybmVkICVkIChleHBlY3RlZCAlZClcbiIsIGxldmVsLAogICAgICAgICAgICAgICAgcGNiTmVlZGVkLCBjYkJ1Zik7CgogICAgICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgICAgICBwY2JOZWVkZWQgPSBNQUdJQ19ERUFEOwogICAgICAgIHJlcyA9IEVudW1Nb25pdG9yc0EoTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYtMSwgJnBjYk5lZWRlZCwgJnBjUmV0dXJuZWQpOwogICAgICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggIgogICAgICAgICAgICAiRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgb2socGNiTmVlZGVkID09IGNiQnVmLCAiKCVkKSByZXR1cm5lZCAlZCAoZXhwZWN0ZWQgJWQpXG4iLCBsZXZlbCwKICAgICAgICAgICAgICAgIHBjYk5lZWRlZCwgY2JCdWYpOwoKLyoKICAgICAgRG8gbm90IGFkZCB0aGUgbmV4dCB0ZXN0OgogICAgICB3MmsrOiAgUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiAKICAgICAgTlQzLjU6IEVSUk9SX0lOVkFMSURfVVNFUl9CVUZGRVIKICAgICAgd2luOXg6IGNyYXNoIGluIHdpbnNwb29sLmRydgoKICAgICAgcmVzID0gRW51bU1vbml0b3JzQShOVUxMLCBsZXZlbCwgTlVMTCwgY2JCdWYsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKKi8KCiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHBjYk5lZWRlZCA9IE1BR0lDX0RFQUQ7CiAgICAgICAgcGNSZXR1cm5lZCA9IE1BR0lDX0RFQUQ7CiAgICAgICAgcmVzID0gRW51bU1vbml0b3JzQShOVUxMLCBsZXZlbCwgYnVmZmVyLCBjYkJ1ZiwgTlVMTCwgJnBjUmV0dXJuZWQpOwogICAgICAgIG9rKCByZXMgfHwgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpKSAsCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIHBjYk5lZWRlZCA9IE1BR0lDX0RFQUQ7CiAgICAgICAgcGNSZXR1cm5lZCA9IE1BR0lDX0RFQUQ7CiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHJlcyA9IEVudW1Nb25pdG9yc0EoTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsICZwY2JOZWVkZWQsIE5VTEwpOwogICAgICAgIG9rKCByZXMgfHwgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpKSAsCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlcik7CiAgICB9IC8qIGZvcihsZXZlbCAuLi4gKi8KfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X0VudW1Qb3J0cyh2b2lkKQp7CiAgICBEV09SRCAgIHJlczsKICAgIERXT1JEICAgbGV2ZWw7CiAgICBMUEJZVEUgIGJ1ZmZlcjsKICAgIERXT1JEICAgY2JCdWY7CiAgICBEV09SRCAgIHBjYk5lZWRlZDsKICAgIERXT1JEICAgcGNSZXR1cm5lZDsKCiAgICAvKiB2YWxpZCBsZXZlbHMgYXJlIDEgYW5kIDIgKi8KICAgIGZvcihsZXZlbCA9IDA7IGxldmVsIDwgNDsgbGV2ZWwrKykgewoKICAgICAgICBjYkJ1ZiA9IDB4ZGVhZGJlZWY7CiAgICAgICAgcGNSZXR1cm5lZCA9IDB4ZGVhZGJlZWY7CiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIHJlcyA9IEVudW1Qb3J0c0EoTlVMTCwgbGV2ZWwsIE5VTEwsIDAsICZjYkJ1ZiwgJnBjUmV0dXJuZWQpOwogICAgICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKCiAgICAgICAgLyogdXNlIG9ubHkgYSBzaG9ydCB0ZXN0LCB3aGVuIHdlIHRlc3Qgd2l0aCBhbiBpbnZhbGlkIGxldmVsICovCiAgICAgICAgaWYoIWxldmVsIHx8IChsZXZlbCA+IDIpKSB7CiAgICAgICAgICAgIC8qIE5UOiBFUlJPUl9JTlZBTElEX0xFVkVMLCA5eDogc3VjY2VzcyAqLwogICAgICAgICAgICBvayggKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTEVWRUwpKSB8fAogICAgICAgICAgICAgICAgKHJlcyAmJiAocGNSZXR1cm5lZCA9PSAwKSksCiAgICAgICAgICAgICAgICAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIGFuZCAweCUwOHggKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgICAgICJFUlJPUl9JTlZBTElEX0xFVkVMIG9yICchPTAnIGFuZCAweDApXG4iLAogICAgICAgICAgICAgICAgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCksIHBjUmV0dXJuZWQpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9ICAgICAgICAKCiAgICAgICAgCiAgICAgICAgLyogTGV2ZWwgMiBpcyBub3Qgc3VwcG9ydGVkIG9uIE5UIDMueCAqLwogICAgICAgIGlmICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSkgewogICAgICAgICAgICBza2lwKCJMZXZlbCAlZCBub3Qgc3VwcG9ydGVkXG4iLCBsZXZlbCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgb2soKCFyZXMpICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggIgogICAgICAgICAgICAiRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNiQnVmICoyKTsKICAgICAgICBpZiAoYnVmZmVyID09IE5VTEwpIGNvbnRpbnVlOwoKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtUG9ydHNBKE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgb2socmVzLCAiKCVkKSByZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJylcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBvayhwY2JOZWVkZWQgPT0gY2JCdWYsICIoJWQpIHJldHVybmVkICVkIChleHBlY3RlZCAlZClcbiIsIGxldmVsLCBwY2JOZWVkZWQsIGNiQnVmKTsKICAgICAgICAvKiBUb0RvOiBDb21wYXJlIHRoZSByZXR1cm5lZCBEYXRhIHdpdGggdGhlIFJlZ2lzdHJ5IC8gIndpbi5pbmkiLFtQb3J0c10gaGVyZSAqLwoKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIHBjUmV0dXJuZWQgPSAweGRlYWRiZWVmOwogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtUG9ydHNBKE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmKzEsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKICAgICAgICBvayhyZXMsICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKHBjYk5lZWRlZCA9PSBjYkJ1ZiwgIiglZCkgcmV0dXJuZWQgJWQgKGV4cGVjdGVkICVkKVxuIiwgbGV2ZWwsIHBjYk5lZWRlZCwgY2JCdWYpOwoKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtUG9ydHNBKE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmLTEsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKICAgICAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiksCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgb2socGNiTmVlZGVkID09IGNiQnVmLCAiKCVkKSByZXR1cm5lZCAlZCAoZXhwZWN0ZWQgJWQpXG4iLCBsZXZlbCwgcGNiTmVlZGVkLCBjYkJ1Zik7CgogICAgICAgIC8qCiAgICAgICAgICBEbyBub3QgYWRkIHRoaXMgdGVzdDoKICAgICAgICAgIHJlcyA9IEVudW1Qb3J0c0EoTlVMTCwgbGV2ZWwsIE5VTEwsIGNiQnVmLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgICB3MmsrOiAgUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiAKICAgICAgICAgIE5UMy41OiBFUlJPUl9JTlZBTElEX1VTRVJfQlVGRkVSCiAgICAgICAgICB3aW45eDogY3Jhc2ggaW4gd2luc3Bvb2wuZHJ2CiAgICAgICAgICovCgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICByZXMgPSBFbnVtUG9ydHMoTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsIE5VTEwsICZwY1JldHVybmVkKTsKICAgICAgICAvKiBOVDogUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiAoMTc4MCksICA5eDogc3VjY2VzcyAqLwogICAgICAgIG9rKCAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1hfTlVMTF9SRUZfUE9JTlRFUikgKSB8fAogICAgICAgICAgICAoIHJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfU1VDQ0VTUykgKSwKICAgICAgICAgICAgIiglZCkgcmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggIgogICAgICAgICAgICAiUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiBvciAnIT0wJyB3aXRoIE5PX0VSUk9SKVxuIiwKICAgICAgICAgICAgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIHJlcyA9IEVudW1Qb3J0cyhOVUxMLCBsZXZlbCwgYnVmZmVyLCBjYkJ1ZiwgJnBjYk5lZWRlZCwgTlVMTCk7CiAgICAgICAgLyogTlQ6IFJQQ19YX05VTExfUkVGX1BPSU5URVIgKDE3ODApLCAgOXg6IHN1Y2Nlc3MgKi8KICAgICAgICBvayggKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpICkgfHwKICAgICAgICAgICAgKCByZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX1NVQ0NFU1MpICksCiAgICAgICAgICAgICIoJWQpIHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIgb3IgJyE9MCcgd2l0aCBOT19FUlJPUilcbiIsCiAgICAgICAgICAgIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyKTsKICAgIH0KfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X0VudW1QcmludGVyRHJpdmVycyh2b2lkKQp7CiAgICBEV09SRCAgIHJlczsKICAgIExQQllURSAgYnVmZmVyOwogICAgRFdPUkQgICBjYkJ1ZjsKICAgIERXT1JEICAgcGNiTmVlZGVkOwogICAgRFdPUkQgICBwY1JldHVybmVkOwogICAgRFdPUkQgICBsZXZlbDsKCiAgICAvKiAxLTMgZm9yIHc5NS93OTgvTlQ0OyAxLTMrNiBmb3IgbWU7IDEtNiBmb3IgdzJrL3hwLzIwMDM7IDEtNis4IGZvciB2aXN0YSAqLwogICAgZm9yKGxldmVsID0gMDsgbGV2ZWwgPCAxMDsgbGV2ZWwrKykgewogICAgICAgIGNiQnVmID0gMHhkZWFkYmVlZjsKICAgICAgICBwY1JldHVybmVkID0gMHhkZWFkYmVlZjsKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gRW51bVByaW50ZXJEcml2ZXJzQShOVUxMLCBOVUxMLCBsZXZlbCwgTlVMTCwgMCwgJmNiQnVmLCAmcGNSZXR1cm5lZCk7CiAgICAgICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQoKICAgICAgICAvKiB1c2Ugb25seSBhIHNob3J0IHRlc3QsIHdoZW4gd2UgdGVzdCB3aXRoIGFuIGludmFsaWQgbGV2ZWwgKi8KICAgICAgICBpZighbGV2ZWwgfHwgKGxldmVsID09IDcpIHx8IChsZXZlbCA+IDgpKSB7CgogICAgICAgICAgICBvayggKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTEVWRUwpKSB8fAogICAgICAgICAgICAgICAgKHJlcyAmJiAocGNSZXR1cm5lZCA9PSAwKSksCiAgICAgICAgICAgICAgICAiKCVkKSBnb3QgJXUgd2l0aCAldSBhbmQgMHgleCAiCiAgICAgICAgICAgICAgICAiKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX0lOVkFMSURfTEVWRUwgb3IgJyE9MCcgYW5kIDB4MClcbiIsCiAgICAgICAgICAgICAgICBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgcGNSZXR1cm5lZCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLyogc29tZSBsZXZlbCBhcmUgbm90IHN1cHBvcnRlZCBpbiBhbGwgd2luZG93cyB2ZXJzaW9ucyAqLwogICAgICAgIGlmICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSkgewogICAgICAgICAgICBza2lwKCJMZXZlbCAlZCBub3Qgc3VwcG9ydGVkXG4iLCBsZXZlbCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgb2soICgoIXJlcykgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpKSB8fAogICAgICAgICAgICAocmVzICYmIChkZWZhdWx0X3ByaW50ZXIgPT0gTlVMTCkpLAogICAgICAgICAgICAiKCV1KSBnb3QgJXUgd2l0aCAldSBmb3IgJXMgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgb3IgJyE9IDAnIHdpdGhvdXQgYSBwcmludGVyKVxuIiwKICAgICAgICAgICAgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCksIGRlZmF1bHRfcHJpbnRlcik7CgogICAgICAgIGlmICghY2JCdWYpIHsKICAgICAgICAgICAgc2tpcCgibm8gdmFsaWQgYnVmZmVyIHNpemUgcmV0dXJuZWRcbiIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjYkJ1ZiArIDQpOwogICAgICAgIGlmIChidWZmZXIgPT0gTlVMTCkgY29udGludWU7CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIHJlcyA9IEVudW1QcmludGVyRHJpdmVyc0EoTlVMTCwgTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKICAgICAgICBvayhyZXMsICIoJXUpIGdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnIT0wJylcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBvayhwY2JOZWVkZWQgPT0gY2JCdWYsICIoJWQpIHJldHVybmVkICVkIChleHBlY3RlZCAlZClcbiIsIGxldmVsLCBwY2JOZWVkZWQsIGNiQnVmKTsKCiAgICAgICAgLyogdmFsaWRhdGUgdGhlIHJldHVybmVkIERhdGEgaGVyZSAqLwogICAgICAgIGlmIChsZXZlbCA+IDEpIHsKICAgICAgICAgICAgTFBEUklWRVJfSU5GT18yQSBkaSA9IChMUERSSVZFUl9JTkZPXzJBKSBidWZmZXI7CgogICAgICAgICAgICBvayggc3RycmNocihkaS0+cERyaXZlclBhdGgsICdcXCcpICE9IE5VTEwsCiAgICAgICAgICAgICAgICAiKCV1KSBnb3QgJXMgZm9yICVzIChleHBlY3RlZCBhIGZ1bGwgcGF0aClcbiIsCiAgICAgICAgICAgICAgICBsZXZlbCwgZGktPnBEcml2ZXJQYXRoLCBkaS0+cE5hbWUpOwoKICAgICAgICB9CgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICBwY1JldHVybmVkID0gMHhkZWFkYmVlZjsKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIHJlcyA9IEVudW1QcmludGVyRHJpdmVyc0EoTlVMTCwgTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYrMSwgJnBjYk5lZWRlZCwgJnBjUmV0dXJuZWQpOwogICAgICAgIG9rKHJlcywgIigldSkgZ290ICV1IHdpdGggJXUgKGV4cGVjdGVkICchPTAnKVxuIiwgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKHBjYk5lZWRlZCA9PSBjYkJ1ZiwgIigldSkgcmV0dXJuZWQgJXUgKGV4cGVjdGVkICV1KVxuIiwgbGV2ZWwsIHBjYk5lZWRlZCwgY2JCdWYpOwoKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcGNiTmVlZGVkID0gMHhkZWFkYmVlZjsKICAgICAgICByZXMgPSBFbnVtUHJpbnRlckRyaXZlcnNBKE5VTEwsIE5VTEwsIGxldmVsLCBidWZmZXIsIGNiQnVmLTEsICZwY2JOZWVkZWQsICZwY1JldHVybmVkKTsKICAgICAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiksCiAgICAgICAgICAgICIoJXUpIGdvdCAldSB3aXRoICV1IChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKVxuIiwKICAgICAgICAgICAgbGV2ZWwsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKHBjYk5lZWRlZCA9PSBjYkJ1ZiwgIigldSkgcmV0dXJuZWQgJXUgKGV4cGVjdGVkICV1KVxuIiwgbGV2ZWwsIHBjYk5lZWRlZCwgY2JCdWYpOwoKLyoKICAgICAgRG8gbm90IGFkZCB0aGUgbmV4dCB0ZXN0OgogICAgICBOVDogRVJST1JfSU5WQUxJRF9VU0VSX0JVRkZFUgogICAgICB3aW45eDogY3Jhc2ggb3IgMTAwJSBDUFUKCiAgICAgIHJlcyA9IEVudW1QcmludGVyRHJpdmVyc0EoTlVMTCwgTlVMTCwgbGV2ZWwsIE5VTEwsIGNiQnVmLCAmcGNiTmVlZGVkLCAmcGNSZXR1cm5lZCk7CiovCgogICAgICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgICAgICBwY2JOZWVkZWQgPSAweGRlYWRiZWVmOwogICAgICAgIHBjUmV0dXJuZWQgPSAweGRlYWRiZWVmOwogICAgICAgIHJlcyA9IEVudW1QcmludGVyRHJpdmVyc0EoTlVMTCwgTlVMTCwgbGV2ZWwsIGJ1ZmZlciwgY2JCdWYsIE5VTEwsICZwY1JldHVybmVkKTsKICAgICAgICBvayggcmVzIHx8ICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBSUENfWF9OVUxMX1JFRl9QT0lOVEVSKSkgLAogICAgICAgICAgICAiKCV1KSBnb3QgJXUgd2l0aCAldSAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggIgogICAgICAgICAgICAiUlBDX1hfTlVMTF9SRUZfUE9JTlRFUilcbiIsIGxldmVsLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgcGNiTmVlZGVkID0gMHhkZWFkYmVlZjsKICAgICAgICBwY1JldHVybmVkID0gMHhkZWFkYmVlZjsKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgcmVzID0gRW51bVByaW50ZXJEcml2ZXJzQShOVUxMLCBOVUxMLCBsZXZlbCwgYnVmZmVyLCBjYkJ1ZiwgJnBjYk5lZWRlZCwgTlVMTCk7CiAgICAgICAgb2soIHJlcyB8fCAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1hfTlVMTF9SRUZfUE9JTlRFUikpICwKICAgICAgICAgICAgIigldSkgZ290ICV1IHdpdGggJXUgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIpXG4iLCBsZXZlbCwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlcik7CiAgICB9IC8qIGZvcihsZXZlbCAuLi4gKi8KfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X0dldERlZmF1bHRQcmludGVyKHZvaWQpCnsKICAgIEJPT0wgICAgcmV0dmFsOwogICAgRFdPUkQgICBleGFjdCA9IERFRkFVTFRfUFJJTlRFUl9TSVpFOwogICAgRFdPUkQgICBzaXplOwogICAgY2hhciAgICBidWZmZXJbREVGQVVMVF9QUklOVEVSX1NJWkVdOwoKICAgIGlmICghcEdldERlZmF1bHRQcmludGVyQSkgIHJldHVybjsKCS8qIG9ubHkgc3VwcG9ydGVkIG9uIE5UIGxpa2UgT1NlcyBzdGFydGluZyB3aXRoIHdpbjJrICovCgogICAgU2V0TGFzdEVycm9yKEVSUk9SX1NVQ0NFU1MpOwogICAgcmV0dmFsID0gcEdldERlZmF1bHRQcmludGVyQShidWZmZXIsICZleGFjdCk7CiAgICBpZiAoIXJldHZhbCB8fCAhZXhhY3QgfHwgIXN0cmxlbihidWZmZXIpIHx8CgkoRVJST1JfU1VDQ0VTUyAhPSBHZXRMYXN0RXJyb3IoKSkpIHsKCWlmICgoRVJST1JfRklMRV9OT1RfRk9VTkQgPT0gR2V0TGFzdEVycm9yKCkpIHx8CgkgICAgKEVSUk9SX0lOVkFMSURfTkFNRSA9PSBHZXRMYXN0RXJyb3IoKSkpCgkgICAgdHJhY2UoInRoaXMgdGVzdCByZXF1aXJlcyBhIGRlZmF1bHQgcHJpbnRlciB0byBiZSBzZXRcbiIpOwoJZWxzZSB7CgkJb2soIDAsICJmdW5jdGlvbiBjYWxsIEdldERlZmF1bHRQcmludGVyQSBmYWlsZWQgdW5leHBlY3RlZCFcbiIKCQkiZnVuY3Rpb24gcmV0dXJuZWQgJXNcbiIKCQkibGFzdCBlcnJvciAweCUwOHhcbiIKCQkicmV0dXJuZWQgYnVmZmVyIHNpemUgMHglMDh4XG4iCgkJInJldHVybmVkIGJ1ZmZlciBjb250ZW50ICVzXG4iLAoJCXJldHZhbCA/ICJ0cnVlIiA6ICJmYWxzZSIsIEdldExhc3RFcnJvcigpLCBleGFjdCwgYnVmZmVyKTsKCX0KCXJldHVybjsKICAgIH0KICAgIFNldExhc3RFcnJvcihFUlJPUl9TVUNDRVNTKTsKICAgIHJldHZhbCA9IHBHZXREZWZhdWx0UHJpbnRlckEoTlVMTCwgTlVMTCk7IAogICAgb2soICFyZXR2YWwsICJmdW5jdGlvbiByZXN1bHQgd3JvbmchIEZhbHNlIGV4cGVjdGVkXG4iKTsKICAgIG9rKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiA9PSBHZXRMYXN0RXJyb3IoKSwKCSJMYXN0IGVycm9yIHdyb25nISBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiBleHBlY3RlZCwgZ290IDB4JTA4eFxuIiwKCUdldExhc3RFcnJvcigpKTsKCiAgICBTZXRMYXN0RXJyb3IoRVJST1JfU1VDQ0VTUyk7CiAgICByZXR2YWwgPSBwR2V0RGVmYXVsdFByaW50ZXJBKGJ1ZmZlciwgTlVMTCk7IAogICAgb2soICFyZXR2YWwsICJmdW5jdGlvbiByZXN1bHQgd3JvbmchIEZhbHNlIGV4cGVjdGVkXG4iKTsKICAgIG9rKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiA9PSBHZXRMYXN0RXJyb3IoKSwKCSJMYXN0IGVycm9yIHdyb25nISBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiBleHBlY3RlZCwgZ290IDB4JTA4eFxuIiwKCUdldExhc3RFcnJvcigpKTsKCiAgICBTZXRMYXN0RXJyb3IoRVJST1JfU1VDQ0VTUyk7CiAgICBzaXplID0gMDsKICAgIHJldHZhbCA9IHBHZXREZWZhdWx0UHJpbnRlckEoTlVMTCwgJnNpemUpOyAKICAgIG9rKCAhcmV0dmFsLCAiZnVuY3Rpb24gcmVzdWx0IHdyb25nISBGYWxzZSBleHBlY3RlZFxuIik7CiAgICBvayggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiA9PSBHZXRMYXN0RXJyb3IoKSwKCSJMYXN0IGVycm9yIHdyb25nISBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSIGV4cGVjdGVkLCBnb3QgMHglMDh4XG4iLAoJR2V0TGFzdEVycm9yKCkpOwogICAgb2soIHNpemUgPT0gZXhhY3QsICJQYXJhbWV0ZXIgc2l6ZSB3cm9uZyEgJWQgZXhwZWN0ZWQgZ290ICVkXG4iLAoJZXhhY3QsIHNpemUpOwoKICAgIFNldExhc3RFcnJvcihFUlJPUl9TVUNDRVNTKTsKICAgIHNpemUgPSBERUZBVUxUX1BSSU5URVJfU0laRTsKICAgIHJldHZhbCA9IHBHZXREZWZhdWx0UHJpbnRlckEoTlVMTCwgJnNpemUpOyAKICAgIG9rKCAhcmV0dmFsLCAiZnVuY3Rpb24gcmVzdWx0IHdyb25nISBGYWxzZSBleHBlY3RlZFxuIik7CiAgICBvayggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiA9PSBHZXRMYXN0RXJyb3IoKSwKCSJMYXN0IGVycm9yIHdyb25nISBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSIGV4cGVjdGVkLCBnb3QgMHglMDh4XG4iLAoJR2V0TGFzdEVycm9yKCkpOwogICAgb2soIHNpemUgPT0gZXhhY3QsICJQYXJhbWV0ZXIgc2l6ZSB3cm9uZyEgJWQgZXhwZWN0ZWQgZ290ICVkXG4iLAoJZXhhY3QsIHNpemUpOwoKICAgIHNpemUgPSAwOwogICAgcmV0dmFsID0gcEdldERlZmF1bHRQcmludGVyQShidWZmZXIsICZzaXplKTsgCiAgICBvayggIXJldHZhbCwgImZ1bmN0aW9uIHJlc3VsdCB3cm9uZyEgRmFsc2UgZXhwZWN0ZWRcbiIpOwogICAgb2soIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgPT0gR2V0TGFzdEVycm9yKCksCgkiTGFzdCBlcnJvciB3cm9uZyEgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiBleHBlY3RlZCwgZ290IDB4JTA4eFxuIiwKCUdldExhc3RFcnJvcigpKTsKICAgIG9rKCBzaXplID09IGV4YWN0LCAiUGFyYW1ldGVyIHNpemUgd3JvbmchICVkIGV4cGVjdGVkIGdvdCAlZFxuIiwKCWV4YWN0LCBzaXplKTsKCiAgICBzaXplID0gZXhhY3Q7CiAgICByZXR2YWwgPSBwR2V0RGVmYXVsdFByaW50ZXJBKGJ1ZmZlciwgJnNpemUpOyAKICAgIG9rKCByZXR2YWwsICJmdW5jdGlvbiByZXN1bHQgd3JvbmchIFRydWUgZXhwZWN0ZWRcbiIpOwogICAgb2soIHNpemUgPT0gZXhhY3QsICJQYXJhbWV0ZXIgc2l6ZSB3cm9uZyEgJWQgZXhwZWN0ZWQgZ290ICVkXG4iLAoJZXhhY3QsIHNpemUpOwp9CgpzdGF0aWMgdm9pZCB0ZXN0X0dldFByaW50ZXJEcml2ZXJEaXJlY3Rvcnkodm9pZCkKewogICAgTFBCWVRFICAgICAgYnVmZmVyID0gTlVMTDsKICAgIERXT1JEICAgICAgIGNiQnVmID0gMCwgcGNiTmVlZGVkID0gMDsKICAgIEJPT0wgICAgICAgIHJlczsKCgogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeUEoIE5VTEwsIE5VTEwsIDEsIE5VTEwsIDAsICZjYkJ1Zik7CiAgICB0cmFjZSgiZmlyc3QgY2FsbCByZXR1cm5lZCAweCUwNHgsIHdpdGggJWQ6IGJ1ZmZlciBzaXplIDB4JTA4eFxuIiwKICAgIHJlcywgR2V0TGFzdEVycm9yKCksIGNiQnVmKTsKCiAgICBSRVRVUk5fT05fREVBQ1RJVkFURURfU1BPT0xFUihyZXMpCiAgICBvaygocmVzID09IDApICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCBsYXN0ZXJyb3I9JWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIGlmICghY2JCdWYpIHsKICAgICAgICBza2lwKCJubyB2YWxpZCBidWZmZXIgc2l6ZSByZXR1cm5lZFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGJ1ZmZlciA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2JCdWYqMik7CiAgICBpZiAoYnVmZmVyID09IE5VTEwpICByZXR1cm4gOwoKICAgIHJlcyA9IEdldFByaW50ZXJEcml2ZXJEaXJlY3RvcnlBKE5VTEwsIE5VTEwsIDEsIGJ1ZmZlciwgY2JCdWYsICZwY2JOZWVkZWQpOwogICAgb2soIHJlcywgImV4cGVjdGVkIHJlc3VsdCAhPSAwLCBnb3QgJWRcbiIsIHJlcyk7CiAgICBvayggY2JCdWYgPT0gcGNiTmVlZGVkLCAicGNiTmVlZGVkIHNldCB0byAlZCBpbnN0ZWFkIG9mICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNiTmVlZGVkLCBjYkJ1Zik7CgogICAgcmVzID0gR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeUEoTlVMTCwgTlVMTCwgMSwgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKICAgIG9rKCByZXMsICJleHBlY3RlZCByZXN1bHQgIT0gMCwgZ290ICVkXG4iLCByZXMpOwogICAgb2soIGNiQnVmID09IHBjYk5lZWRlZCwgInBjYk5lZWRlZCBzZXQgdG8gJWQgaW5zdGVhZCBvZiAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjYk5lZWRlZCwgY2JCdWYpOwogCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QSggTlVMTCwgTlVMTCwgMSwgYnVmZmVyLCBjYkJ1Zi0xLCAmcGNiTmVlZGVkKTsKICAgIG9rKCAhcmVzICwgImV4cGVjdGVkIHJlc3VsdCA9PSAwLCBnb3QgJWRcbiIsIHJlcyk7CiAgICBvayggY2JCdWYgPT0gcGNiTmVlZGVkLCAicGNiTmVlZGVkIHNldCB0byAlZCBpbnN0ZWFkIG9mICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNiTmVlZGVkLCBjYkJ1Zik7CiAgICAKICAgIG9rKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSID09IEdldExhc3RFcnJvcigpLAogICAgICAgICJsYXN0IGVycm9yIHNldCB0byAlZCBpbnN0ZWFkIG9mIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVJcbiIsCiAgICAgICAgR2V0TGFzdEVycm9yKCkpOwoKLyoKICAgIERvIG5vdCBhZGQgdGhlIG5leHQgdGVzdDoKICAgIFhQc3AyOiBjcmFzaCBpbiB0aGlzIGFwcCwgd2hlbiB0aGUgc3Bvb2xlciBpcyBub3QgcnVubmluZyAKICAgIE5UMy41OiBFUlJPUl9JTlZBTElEX1VTRVJfQlVGRkVSCiAgICB3aW45eDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIKCiAgICBwY2JOZWVkZWQgPSBNQUdJQ19ERUFEOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeUEoIE5VTEwsIE5VTEwsIDEsIE5VTEwsIGNiQnVmLCAmcGNiTmVlZGVkKTsKKi8KCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QSggTlVMTCwgTlVMTCwgMSwgYnVmZmVyLCBjYkJ1ZiwgTlVMTCk7CiAgICBvayggKCFyZXMgJiYgUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiA9PSBHZXRMYXN0RXJyb3IoKSkgfHwgcmVzLAogICAgICAgICAiZXhwZWN0ZWQgZWl0aGVyIHJlc3VsdCA9PSAwIGFuZCAiCiAgICAgICAgICJsYXN0IGVycm9yID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIgb3IgcmVzdWx0ICE9IDAgIgogICAgICAgICAiZ290IHJlc3VsdCAlZCBhbmQgbGFzdCBlcnJvciA9PSAlZFxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeUEoIE5VTEwsIE5VTEwsIDEsIE5VTEwsIGNiQnVmLCBOVUxMKTsKICAgIG9rKHJlcyB8fCAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAiUlBDX1hfTlVMTF9SRUZfUE9JTlRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogCiAKICAgIC8qIHdpdGggYSB2YWxpZCBidWZmZXIsIGJ1dCBsZXZlbCBpcyB0b28gbGFyZ2UgKi8KICAgIGJ1ZmZlclswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QShOVUxMLCBOVUxMLCAyLCBidWZmZXIsIGNiQnVmLCAmcGNiTmVlZGVkKTsKCiAgICAvKiBMZXZlbCBub3QgY2hlY2tlZCBpbiB3aW45eCBhbmQgd2luZToqLwogICAgaWYoKHJlcyAhPSBGQUxTRSkgJiYgYnVmZmVyWzBdKQogICAgewogICAgICAgIHRyYWNlKCJMZXZlbCAnMicgbm90IGNoZWNrZWQgJyVzJ1xuIiwgYnVmZmVyKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9MRVZFTCksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggbGFzdGVycm9yPSVkIChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfTEVWRUwpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgIH0KCiAgICAvKiBwcmludGluZyBlbnZpcm9ubWVudHMgYXJlIGNhc2UgaW5zZW5zaXRpdmUgKi8KICAgIC8qICJXaW5kb3dzIDQuMCIgaXMgdmFsaWQgZm9yIHdpbjl4IGFuZCBOVCAqLwogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEdldFByaW50ZXJEcml2ZXJEaXJlY3RvcnlBKE5VTEwsIGVudl93aW45eF9jYXNlLCAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgY2JCdWYqMiwgJnBjYk5lZWRlZCk7CgogICAgaWYoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUikpIHsKICAgICAgICBjYkJ1ZiA9IHBjYk5lZWRlZDsKICAgICAgICBidWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWZmZXIsIGNiQnVmKjIpOwogICAgICAgIGlmIChidWZmZXIgPT0gTlVMTCkgIHJldHVybiA7CgogICAgICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgICAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QShOVUxMLCBlbnZfd2luOXhfY2FzZSwgMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIGNiQnVmKjIsICZwY2JOZWVkZWQpOwogICAgfQoKICAgIG9rKHJlcyAmJiBidWZmZXJbMF0sICJyZXR1cm5lZCAlZCB3aXRoICIKICAgICAgICAibGFzdGVycm9yPSVkIGFuZCBsZW49JWQgKGV4cGVjdGVkICcxJyB3aXRoICdsZW4gPiAwJylcbiIsIAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCksIGxzdHJsZW5BKChjaGFyICopYnVmZmVyKSk7CgogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEdldFByaW50ZXJEcml2ZXJEaXJlY3RvcnlBKE5VTEwsIGVudl94ODYsIDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKCiAgICBpZighcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSkgewogICAgICAgIGNiQnVmID0gcGNiTmVlZGVkOwogICAgICAgIGJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlciwgY2JCdWYqMik7CiAgICAgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKSAgcmV0dXJuIDsKCiAgICAgICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgICAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICAgICAgcmVzID0gR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeUEoTlVMTCwgZW52X3g4NiwgMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIGNiQnVmKjIsICZwY2JOZWVkZWQpOwogICAgfQoKICAgIC8qICJXaW5kb3dzIE5UIHg4NiIgaXMgaW52YWxpZCBmb3Igd2luOXggKi8KICAgIG9rKCAocmVzICYmIGJ1ZmZlclswXSkgfHwKICAgICAgICAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9FTlZJUk9OTUVOVCkpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCBsYXN0ZXJyb3I9JWQgYW5kIGxlbj0lZCAoZXhwZWN0ZWQgJyE9IDAnIHdpdGggIgogICAgICAgICInbGVuID4gMCcgb3IgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9FTlZJUk9OTUVOVClcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbHN0cmxlbkEoKGNoYXIgKilidWZmZXIpKTsKCiAgICAvKiBBIHNldHVwIHByb2dyYW0gKFBERkNyZWF0b3JfMC44LjApIHVzZSBlbXB0eSBzdHJpbmdzICovCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QShlbXB0eSwgZW1wdHksIDEsIGJ1ZmZlciwgY2JCdWYqMiwgJnBjYk5lZWRlZCk7CiAgICBvayhyZXMsICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkgKTsKCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcmludGVyRHJpdmVyRGlyZWN0b3J5QShOVUxMLCBlbXB0eSwgMSwgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSApOwoKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEdldFByaW50ZXJEcml2ZXJEaXJlY3RvcnlBKGVtcHR5LCBOVUxMLCAxLCBidWZmZXIsIGNiQnVmKjIsICZwY2JOZWVkZWQpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcpXG4iLCByZXMsIEdldExhc3RFcnJvcigpICk7CgogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlcik7Cn0KCi8qICMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X0dldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5KHZvaWQpCnsKICAgIExQQllURSAgICAgIGJ1ZmZlciA9IE5VTEw7CiAgICBEV09SRCAgICAgICBjYkJ1ZiA9IDA7CiAgICBEV09SRCAgICAgICBwY2JOZWVkZWQgPSAwOwogICAgQk9PTCAgICAgICAgcmVzOwoKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeUEoTlVMTCwgTlVMTCwgMSwgTlVMTCwgMCwgJmNiQnVmKTsKICAgIC8qIFRoZSBkZWFjdGl2YXRlZCBTcG9vbGVyIGlzIGNhdWdodCBoZXJlIG9uIE5UMy41MSAqLwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBidWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2JCdWYqMik7CiAgICBpZihidWZmZXIgPT0gTlVMTCkgIHJldHVybjsKCiAgICBidWZmZXJbMF0gPSAnXDAnOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gR2V0UHJpbnRQcm9jZXNzb3JEaXJlY3RvcnlBKE5VTEwsIE5VTEwsIDEsIGJ1ZmZlciwgY2JCdWYsICZwY2JOZWVkZWQpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIHJlcyA9IEdldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5QShOVUxMLCBOVUxMLCAxLCBidWZmZXIsIGNiQnVmKjIsICZwY2JOZWVkZWQpOwogICAgb2socmVzLCAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAKICAgIC8qIEJ1ZmZlciB0byBzbWFsbCAqLwogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEdldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5QSggTlVMTCwgTlVMTCwgMSwgYnVmZmVyLCBjYkJ1Zi0xLCAmcGNiTmVlZGVkKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgaWYgKDApCiAgICB7CiAgICAvKiBYUHNwMjogdGhlIHByb2dyYW0gd2lsbCBjcmFzaCBoZXJlLCB3aGVuIHRoZSBzcG9vbGVyIGlzIG5vdCBydW5uaW5nICAqLwogICAgLyogICAgICAgIEdldFByaW50ZXJEcml2ZXJEaXJlY3RvcnkgaGFzIHRoZSBzYW1lIGJ1ZyAqLwogICAgcGNiTmVlZGVkID0gMDsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEdldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5QSggTlVMTCwgTlVMTCwgMSwgTlVMTCwgY2JCdWYsICZwY2JOZWVkZWQpOwogICAgfQoKICAgIGJ1ZmZlclswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeUEoIE5VTEwsIE5VTEwsIDEsIGJ1ZmZlciwgY2JCdWYsIE5VTEwpOwogICAgLyogTlQ6IFJQQ19YX05VTExfUkVGX1BPSU5URVIsIDl4OiByZXMgIT0gMCAgKi8KICAgIG9rKCByZXMgfHwgKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0gMCcgb3IgJzAnIHdpdGggIgogICAgICAgICJSUENfWF9OVUxMX1JFRl9QT0lOVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgoKICAgIGJ1ZmZlclswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeUEoIE5VTEwsIE5VTEwsIDEsIE5VTEwsIGNiQnVmLCBOVUxMKTsKICAgIC8qIE5UOiBSUENfWF9OVUxMX1JFRl9QT0lOVEVSLCA5eDogcmVzICE9IDAgICovCiAgICBvayggcmVzIHx8IChHZXRMYXN0RXJyb3IoKSA9PSBSUENfWF9OVUxMX1JFRl9QT0lOVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9IDAnIG9yICcwJyB3aXRoICIKICAgICAgICAiUlBDX1hfTlVMTF9SRUZfUE9JTlRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKIAogICAgLyogd2l0aCBhIHZhbGlkIGJ1ZmZlciwgYnV0IGxldmVsIGlzIGludmFsaWQgKi8KICAgIGJ1ZmZlclswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeUEoTlVMTCwgTlVMTCwgMiwgYnVmZmVyLCBjYkJ1ZiwgJnBjYk5lZWRlZCk7CiAgICBpZiAocmVzICYmIGJ1ZmZlclswXSkKICAgIHsKICAgICAgICAvKiBMZXZlbCBpcyBpZ25vcmVkIGluIHdpbjl4Ki8KICAgICAgICB0cmFjZSgiaW52YWxpZCBsZXZlbCAoMikgd2FzIGlnbm9yZWRcbiIpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSwKICAgICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX0lOVkFMSURfTEVWRUwpXG4iLAogICAgICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKICAgIH0KCiAgICAvKiBFbXB0eSBlbnZpcm9ubWVudCBpcyB0aGUgc2FtZSBhcyB0aGUgZGVmYXVsdCBlbnZpcm9ubWVudCAqLwogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEdldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5QShOVUxMLCBlbXB0eSwgMSwgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIC8qICJXaW5kb3dzIDQuMCIgaXMgdmFsaWQgZm9yIHdpbjl4IGFuZCBOVCAqLwogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IEdldFByaW50UHJvY2Vzc29yRGlyZWN0b3J5QShOVUxMLCBlbnZfd2luOXhfY2FzZSwgMSwgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICAvKiAiV2luZG93cyBOVCB4ODYiIGlzIGludmFsaWQgZm9yIHdpbjl4ICovCiAgICBidWZmZXJbMF0gPSAnXDAnOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gR2V0UHJpbnRQcm9jZXNzb3JEaXJlY3RvcnlBKE5VTEwsIGVudl94ODYsIDEsIGJ1ZmZlciwgY2JCdWYqMiwgJnBjYk5lZWRlZCk7CiAgICBvayggcmVzIHx8IChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0VOVklST05NRU5UKSwgCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPSAwJyBvciAnMCcgd2l0aCAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfRU5WSVJPTk1FTlQpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAvKiBpbnZhbGlkIG9uIGFsbCBTeXN0ZW1zICovCiAgICBidWZmZXJbMF0gPSAnXDAnOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gR2V0UHJpbnRQcm9jZXNzb3JEaXJlY3RvcnlBKE5VTEwsIGludmFsaWRfZW52LCAxLCBidWZmZXIsIGNiQnVmKjIsICZwY2JOZWVkZWQpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfRU5WSVJPTk1FTlQpLCAKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9FTlZJUk9OTUVOVClcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgLyogRW1wdHkgc2VydmVybmFtZSBpcyB0aGUgc2FtZSBhcyB0aGUgbG9jYWwgY29tcHV0ZXIgKi8KICAgIGJ1ZmZlclswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBHZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeUEoZW1wdHksIE5VTEwsIDEsIGJ1ZmZlciwgY2JCdWYqMiwgJnBjYk5lZWRlZCk7CiAgICBvayhyZXMsICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0gMCcpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICAvKiBpbnZhbGlkIG9uIGFsbCBTeXN0ZW1zICovCiAgICBidWZmZXJbMF0gPSAnXDAnOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gR2V0UHJpbnRQcm9jZXNzb3JEaXJlY3RvcnlBKHNlcnZlcl9kb2VzX25vdF9leGlzdCwgTlVMTCwgMSwgYnVmZmVyLCBjYkJ1ZioyLCAmcGNiTmVlZGVkKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksIAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyKTsKfQoKLyogIyMjIyMgKi8KCnN0YXRpYyB2b2lkIHRlc3RfT3BlblByaW50ZXIodm9pZCkKewogICAgUFJJTlRFUl9ERUZBVUxUU0EgICBkZWZhdWx0czsKICAgIEhBTkRMRSAgICAgICAgICAgICAgaHByaW50ZXI7CiAgICBEV09SRCAgICAgICAgICAgICAgIHJlczsKCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBPcGVuUHJpbnRlcihOVUxMLCBOVUxMLCBOVUxMKTsgICAgCiAgICAvKiBUaGUgZGVhY3RpdmF0ZWQgU3Bvb2xlciBpcyBjYXVnaHQgaGVyZSBvbiBOVDMuNTEgKi8KICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKICAgIG9rKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKCiAgICAvKiBHZXQgSGFuZGxlIGZvciB0aGUgbG9jYWwgUHJpbnRzZXJ2ZXIgKE5UIG9ubHkpKi8KICAgIGhwcmludGVyID0gKEhBTkRMRSkgTUFHSUNfREVBRDsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IE9wZW5QcmludGVyKE5VTEwsICZocHJpbnRlciwgTlVMTCk7CiAgICAvKiBUaGUgZGVhY3RpdmF0ZWQgU3Bvb2xlciBpcyBjYXVnaHQgaGVyZSBvbiBYUHNwMiAqLwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQogICAgb2socmVzIHx8ICghcmVzICYmIEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgaWYocmVzKSB7CiAgICAgICAgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKCiAgICAgICAgZGVmYXVsdHMucERhdGF0eXBlPU5VTEw7CiAgICAgICAgZGVmYXVsdHMucERldk1vZGU9TlVMTDsKCiAgICAgICAgZGVmYXVsdHMuRGVzaXJlZEFjY2Vzcz0wOwogICAgICAgIGhwcmludGVyID0gKEhBTkRMRSkgTUFHSUNfREVBRDsKICAgICAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICAgICAgcmVzID0gT3BlblByaW50ZXIoTlVMTCwgJmhwcmludGVyLCAmZGVmYXVsdHMpOwogICAgICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgaWYgKHJlcykgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKCiAgICAgICAgZGVmYXVsdHMuRGVzaXJlZEFjY2Vzcz0tMTsKICAgICAgICBocHJpbnRlciA9IChIQU5ETEUpIE1BR0lDX0RFQUQ7CiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHJlcyA9IE9wZW5QcmludGVyKE5VTEwsICZocHJpbnRlciwgJmRlZmF1bHRzKTsKICAgICAgICB0b2RvX3dpbmUgewogICAgICAgIG9rKCFyZXMgJiYgR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfQUNDRVNTX0RFTklFRCwKICAgICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoIEVSUk9SX0FDQ0VTU19ERU5JRUQpXG4iLCAKICAgICAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CgogICAgfQoKCiAgICBpZiAobG9jYWxfc2VydmVyICE9IE5VTEwpIHsKICAgICAgICBocHJpbnRlciA9IChIQU5ETEUpIDB4ZGVhZGJlZWY7CiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIHJlcyA9IE9wZW5QcmludGVyKGxvY2FsX3NlcnZlciwgJmhwcmludGVyLCBOVUxMKTsKICAgICAgICBvayhyZXMgfHwgKCFyZXMgJiYgR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpLAogICAgICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBpZihyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CiAgICB9CgogICAgLyogSW52YWxpZCBQcmludGVybmFtZSAqLwogICAgaHByaW50ZXIgPSAoSEFORExFKSBNQUdJQ19ERUFEOwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gT3BlblByaW50ZXIoaWxsZWdhbF9uYW1lLCAmaHByaW50ZXIsIE5VTEwpOwogICAgb2soIXJlcyAmJiAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKSB8fCAKICAgICAgICAgICAgICAgIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUikgKSwKICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnMCcgd2l0aDogRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgb3IiCiAgICAgICAiRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgIGlmKHJlcykgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKCiAgICBocHJpbnRlciA9IChIQU5ETEUpIE1BR0lDX0RFQUQ7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBPcGVuUHJpbnRlcihlbXB0eSwgJmhwcmludGVyLCBOVUxMKTsKICAgIC8qIE5UOiBFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSwgIDl4OiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiAqLwogICAgb2soICFyZXMgJiYKICAgICAgICAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKSB8fCAKICAgICAgICAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpICksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoOiBFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSIKICAgICAgICAiIG9yIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CiAgICBpZihyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CgoKICAgIC8qIEdldCBIYW5kbGUgZm9yIHRoZSBkZWZhdWx0IFByaW50ZXIgKi8KICAgIGlmIChkZWZhdWx0X3ByaW50ZXIpCiAgICB7CiAgICAgICAgaHByaW50ZXIgPSAoSEFORExFKSBNQUdJQ19ERUFEOwogICAgICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgICAgICByZXMgPSBPcGVuUHJpbnRlcihkZWZhdWx0X3ByaW50ZXIsICZocHJpbnRlciwgTlVMTCk7CiAgICAgICAgaWYoKCFyZXMpICYmIChHZXRMYXN0RXJyb3IoKSA9PSBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEUpKQogICAgICAgIHsKICAgICAgICAgICAgdHJhY2UoIlRoZSBTZXJ2aWNlICdTcG9vbGVyJyBpcyByZXF1aXJlZCBmb3IgJyVzJ1xuIiwgZGVmYXVsdF9wcmludGVyKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBvayhyZXMsICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIGlmKHJlcykgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKCiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHJlcyA9IE9wZW5QcmludGVyKGRlZmF1bHRfcHJpbnRlciwgTlVMTCwgTlVMTCk7CiAgICAgICAgLyogTlQ6IEZBTFNFIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIsIDl4OiBUUlVFICovCiAgICAgICAgb2socmVzIHx8IChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksCiAgICAgICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJyBvciAnMCcgd2l0aCAiCiAgICAgICAgICAgICJFUlJPUl9JTlZBTElEX1BBUkFNRVRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICBkZWZhdWx0cy5wRGF0YXR5cGU9TlVMTDsKICAgICAgICBkZWZhdWx0cy5wRGV2TW9kZT1OVUxMOwogICAgICAgIGRlZmF1bHRzLkRlc2lyZWRBY2Nlc3M9MDsKCiAgICAgICAgaHByaW50ZXIgPSAoSEFORExFKSBNQUdJQ19ERUFEOwogICAgICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgICAgICByZXMgPSBPcGVuUHJpbnRlcihkZWZhdWx0X3ByaW50ZXIsICZocHJpbnRlciwgJmRlZmF1bHRzKTsKICAgICAgICBvayhyZXMgfHwgR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfQUNDRVNTX0RFTklFRCwKICAgICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0FDQ0VTU19ERU5JRUQpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBpZihyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CgogICAgICAgIGRlZmF1bHRzLnBEYXRhdHlwZSA9IGVtcHR5OwoKICAgICAgICBocHJpbnRlciA9IChIQU5ETEUpIE1BR0lDX0RFQUQ7CiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHJlcyA9IE9wZW5QcmludGVyKGRlZmF1bHRfcHJpbnRlciwgJmhwcmludGVyLCAmZGVmYXVsdHMpOwogICAgICAgIC8qIHN0b3AgaGVyZSwgd2hlbiBhIHJlbW90ZSBQcmludHNlcnZlciBoYXMgbm8gUlBDLVNlcnZpY2UgcnVubmluZyAqLwogICAgICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKICAgICAgICBvayhyZXMgfHwgKChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0RBVEFUWVBFKSB8fAogICAgICAgICAgICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0FDQ0VTU19ERU5JRUQpKSwKICAgICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoOiAiCiAgICAgICAgICAgICJFUlJPUl9JTlZBTElEX0RBVEFUWVBFIG9yIEVSUk9SX0FDQ0VTU19ERU5JRUQpXG4iLAogICAgICAgICAgICByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBpZihyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CgoKICAgICAgICBkZWZhdWx0cy5wRGF0YXR5cGU9TlVMTDsKICAgICAgICBkZWZhdWx0cy5EZXNpcmVkQWNjZXNzPVBSSU5URVJfQUNDRVNTX1VTRTsKCiAgICAgICAgaHByaW50ZXIgPSAoSEFORExFKSBNQUdJQ19ERUFEOwogICAgICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgICAgICByZXMgPSBPcGVuUHJpbnRlcihkZWZhdWx0X3ByaW50ZXIsICZocHJpbnRlciwgJmRlZmF1bHRzKTsKICAgICAgICBvayhyZXMgfHwgR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfQUNDRVNTX0RFTklFRCwKICAgICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgICAgIkVSUk9SX0FDQ0VTU19ERU5JRUQpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBpZihyZXMpIENsb3NlUHJpbnRlcihocHJpbnRlcik7CgoKICAgICAgICBkZWZhdWx0cy5EZXNpcmVkQWNjZXNzPVBSSU5URVJfQUxMX0FDQ0VTUzsKICAgICAgICBocHJpbnRlciA9IChIQU5ETEUpIE1BR0lDX0RFQUQ7CiAgICAgICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgICAgIHJlcyA9IE9wZW5QcmludGVyKGRlZmF1bHRfcHJpbnRlciwgJmhwcmludGVyLCAmZGVmYXVsdHMpOwogICAgICAgIG9rKHJlcyB8fCBHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9BQ0NFU1NfREVOSUVELAogICAgICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggIgogICAgICAgICAgICAiRVJST1JfQUNDRVNTX0RFTklFRClcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIGlmKHJlcykgQ2xvc2VQcmludGVyKGhwcmludGVyKTsKICAgIH0KCn0KCgpzdGF0aWMgdm9pZCB0ZXN0X1NldERlZmF1bHRQcmludGVyKHZvaWQpCnsKICAgIERXT1JEICAgcmVzOwogICAgRFdPUkQgICBzaXplID0gREVGQVVMVF9QUklOVEVSX1NJWkU7CiAgICBDSEFSICAgIGJ1ZmZlcltERUZBVUxUX1BSSU5URVJfU0laRV07CiAgICBDSEFSICAgIG9yZ192YWx1ZVtERUZBVUxUX1BSSU5URVJfU0laRV07CgoKICAgIGlmICghcFNldERlZmF1bHRQcmludGVyQSkgIHJldHVybjsKCS8qIG9ubHkgc3VwcG9ydGVkIG9uIHdpbjJrIGFuZCBhYm92ZSAqLwoKICAgIC8qIGJhY2t1cCB0aGUgb3JpZ2luYWwgdmFsdWUgKi8KICAgIG9yZ192YWx1ZVswXSA9ICdcMCc7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBHZXRQcm9maWxlU3RyaW5nQSgid2luZG93cyIsICJkZXZpY2UiLCBOVUxMLCBvcmdfdmFsdWUsIHNpemUpOwoKICAgIC8qIGZpcnN0IHBhcnQ6IHdpdGggdGhlIGRlZmF1bHQgUHJpbnRlciAqLwogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gcFNldERlZmF1bHRQcmludGVyQSgibm9fcHJpbnRlcl93aXRoX3RoaXNfbmFtZSIpOwoKICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKICAgIC8qIHNwb29sZXIgaXMgcnVubmluZyBvciB3ZSBoYXZlIG5vIHNwb29sZXIgaGVyZSovCgogICAgLyogTm90IGltcGxlbWVudGVkIGluIHdpbmUgKi8KICAgIGlmICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCkpIHsKICAgICAgICB0cmFjZSgiU2V0RGVmYXVsdFByaW50ZXJBKCkgbm90IGltcGxlbWVudGVkIHlldC5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBvayghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIG9yZ192YWx1ZSk7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBwU2V0RGVmYXVsdFByaW50ZXJBKCIiKTsKICAgIG9rKHJlcyB8fCAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggIgogICAgICAgICJFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSlcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIFdyaXRlUHJvZmlsZVN0cmluZ0EoIndpbmRvd3MiLCAiZGV2aWNlIiwgb3JnX3ZhbHVlKTsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IHBTZXREZWZhdWx0UHJpbnRlckEoTlVMTCk7CiAgICBvayhyZXMgfHwgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIG9yZ192YWx1ZSk7CiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBwU2V0RGVmYXVsdFByaW50ZXJBKGRlZmF1bHRfcHJpbnRlcik7CiAgICBvayhyZXMgfHwgKCFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCgogICAgLyogc2Vjb25kIHBhcnQ6IGFsd2F5cyB3aXRob3V0IGEgZGVmYXVsdCBQcmludGVyICovCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIE5VTEwpOyAgICAKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IHBTZXREZWZhdWx0UHJpbnRlckEoIm5vX3ByaW50ZXJfd2l0aF90aGlzX25hbWUiKTsKCiAgICBvayghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpXG4iLCByZXMsIEdldExhc3RFcnJvcigpKTsKCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIE5VTEwpOyAgICAKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IHBTZXREZWZhdWx0UHJpbnRlckEoIiIpOwogICAgLyogd2UgZ2V0IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FIHdoZW4gbm8gcHJpbnRlciBpcyBpbnN0YWxsZWQgKi8KICAgIG9rKHJlcyB8fCAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpKSwKICAgICAgICAgInJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICchPTAnIG9yICcwJyB3aXRoICIKICAgICAgICAgIkVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgV3JpdGVQcm9maWxlU3RyaW5nQSgid2luZG93cyIsICJkZXZpY2UiLCBOVUxMKTsgICAgCiAgICBTZXRMYXN0RXJyb3IoTUFHSUNfREVBRCk7CiAgICByZXMgPSBwU2V0RGVmYXVsdFByaW50ZXJBKE5VTEwpOwogICAgLyogd2UgZ2V0IEVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FIHdoZW4gbm8gcHJpbnRlciBpcyBpbnN0YWxsZWQgKi8KICAgIG9rKHJlcyB8fCAoIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5WQUxJRF9QUklOVEVSX05BTUUpKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAlZCAoZXhwZWN0ZWQgJyE9MCcgb3IgJzAnIHdpdGggIgogICAgICAgICJFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSlcbiIsIHJlcywgR2V0TGFzdEVycm9yKCkpOwoKICAgIFdyaXRlUHJvZmlsZVN0cmluZ0EoIndpbmRvd3MiLCAiZGV2aWNlIiwgTlVMTCk7ICAgIAogICAgU2V0TGFzdEVycm9yKE1BR0lDX0RFQUQpOwogICAgcmVzID0gcFNldERlZmF1bHRQcmludGVyQShkZWZhdWx0X3ByaW50ZXIpOwogICAgb2socmVzIHx8ICghcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BSSU5URVJfTkFNRSkpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICVkIChleHBlY3RlZCAnIT0wJyBvciAnMCcgd2l0aCAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfUFJJTlRFUl9OQU1FKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSk7CgogICAgLyogcmVzdG9yZSB0aGUgb3JpZ2luYWwgdmFsdWUgKi8KICAgIHJlcyA9IHBTZXREZWZhdWx0UHJpbnRlckEoZGVmYXVsdF9wcmludGVyKTsgICAgICAgICAgLyogdGhlIG5pY2Ugd2F5ICovCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIG9yZ192YWx1ZSk7IC8qIHRoZSBvbGQgd2F5ICovCgogICAgYnVmZmVyWzBdID0gJ1wwJzsKICAgIFNldExhc3RFcnJvcihNQUdJQ19ERUFEKTsKICAgIHJlcyA9IEdldFByb2ZpbGVTdHJpbmdBKCJ3aW5kb3dzIiwgImRldmljZSIsIE5VTEwsIGJ1ZmZlciwgc2l6ZSk7CiAgICBvayghbHN0cmNtcEEob3JnX3ZhbHVlLCBidWZmZXIpLCAiJyVzJyAoZXhwZWN0ZWQgJyVzJylcbiIsIGJ1ZmZlciwgb3JnX3ZhbHVlKTsKCn0KCi8qICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwoKc3RhdGljIHZvaWQgdGVzdF9YY3ZEYXRhV19Nb25pdG9yVUkodm9pZCkKewogICAgRFdPUkQgICByZXM7CiAgICBIQU5ETEUgIGhYY3Y7CiAgICBCWVRFICAgIGJ1ZmZlcltNQVhfUEFUSCArIDRdOwogICAgRFdPUkQgICBuZWVkZWQ7CiAgICBEV09SRCAgIHN0YXR1czsKICAgIERXT1JEICAgbGVuOwogICAgUFJJTlRFUl9ERUZBVUxUU0EgcGQ7CgogICAgLyogYXBpIGlzIG5vdCBwcmVzZW50IGJlZm9yZSB3MmsgKi8KICAgIGlmIChwWGN2RGF0YVcgPT0gTlVMTCkgcmV0dXJuOwoKICAgIHBkLnBEYXRhdHlwZSA9IE5VTEw7CiAgICBwZC5wRGV2TW9kZSAgPSBOVUxMOwogICAgcGQuRGVzaXJlZEFjY2VzcyA9IFNFUlZFUl9BQ0NFU1NfQURNSU5JU1RFUjsKCiAgICBoWGN2ID0gTlVMTDsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IE9wZW5QcmludGVyKHhjdl9sb2NhbHBvcnQsICZoWGN2LCAmcGQpOwogICAgUkVUVVJOX09OX0RFQUNUSVZBVEVEX1NQT09MRVIocmVzKQogICAgUkVUVVJOX09OX0FDQ0VTU19ERU5JRUQocmVzKQoKICAgIG9rKHJlcywgInJldHVybmVkICVkIHdpdGggJXUgYW5kIGhhbmRsZSAlcCAoZXhwZWN0ZWQgJyE9IDAnKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgaFhjdik7CiAgICBpZiAoIXJlcykgcmV0dXJuOwoKICAgIC8qIGFzayBmb3IgbmVlZGVkIHNpemUgKi8KICAgIG5lZWRlZCA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIHN0YXR1cyA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBYY3ZEYXRhVyhoWGN2LCBjbWRfTW9uaXRvclVJVywgTlVMTCwgMCwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmIChzdGF0dXMgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUikgJiYgKG5lZWRlZCA8PSBNQVhfUEFUSCksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICchPSAwJyBhbmQgIgogICAgICAgICInPD0gTUFYX1BBVEgnIGZvciBzdGF0dXMgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUilcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIGlmIChuZWVkZWQgPiBNQVhfUEFUSCkgewogICAgICAgIENsb3NlUHJpbnRlcihoWGN2KTsKICAgICAgICBza2lwKCJidWZmZXIgb3ZlcmZsb3cgKCV1KVxuIiwgbmVlZGVkKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBsZW4gPSBuZWVkZWQ7ICAgICAgIC8qIFNpemUgaXMgaW4gYnl0ZXMgKi8KCiAgICAvKiB0aGUgY29tbWFuZCBpcyByZXF1aXJlZCAqLwogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGVtcHR5VywgTlVMTCwgMCwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmIChzdGF0dXMgPT0gRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCAldSBmb3Igc3RhdHVzICV1IChleHBlY3RlZCAnIT0gMCcgd2l0aCAiCiAgICAgICAgIkVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIG5lZWRlZCA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIHN0YXR1cyA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBYY3ZEYXRhVyhoWGN2LCBOVUxMLCBOVUxMLCAwLCBidWZmZXIsIE1BWF9QQVRILCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBSUENfWF9OVUxMX1JFRl9QT0lOVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJzAnIHdpdGggIgogICAgICAgICJSUENfWF9OVUxMX1JFRl9QT0lOVEVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIC8qICJQRFdPUkQgbmVlZGVkIiBpcyBjaGVja2VkIGJlZm9yZSBSUEMtRXJyb3JzICovCiAgICBuZWVkZWQgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBzdGF0dXMgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwWGN2RGF0YVcoaFhjdiwgY21kX01vbml0b3JVSVcsIE5VTEwsIDAsIGJ1ZmZlciwgbGVuLCBOVUxMLCAmc3RhdHVzKTsKICAgIG9rKCAhcmVzICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAiRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Nb25pdG9yVUlXLCBOVUxMLCAwLCBOVUxMLCBsZW4sICZuZWVkZWQsICZzdGF0dXMpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IFJQQ19YX05VTExfUkVGX1BPSU5URVIpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCAldSBmb3Igc3RhdHVzICV1IChleHBlY3RlZCAnMCcgd2l0aCAiCiAgICAgICAgIlJQQ19YX05VTExfUkVGX1BPSU5URVIpXG4iLCByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Nb25pdG9yVUlXLCBOVUxMLCAwLCBidWZmZXIsIGxlbiwgJm5lZWRlZCwgTlVMTCk7CiAgICBvayggIXJlcyAmJiAoR2V0TGFzdEVycm9yKCkgPT0gUlBDX1hfTlVMTF9SRUZfUE9JTlRFUiksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICcwJyB3aXRoICIKICAgICAgICAiUlBDX1hfTlVMTF9SRUZfUE9JTlRFUilcbiIsIHJlcywgR2V0TGFzdEVycm9yKCksIG5lZWRlZCwgc3RhdHVzKTsKCiAgICAvKiBvZmYgYnkgb25lOiBsYXJnZXIgICovCiAgICBuZWVkZWQgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBzdGF0dXMgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwWGN2RGF0YVcoaFhjdiwgY21kX01vbml0b3JVSVcsIE5VTEwsIDAsIGJ1ZmZlciwgbGVuKzEsICZuZWVkZWQsICZzdGF0dXMpOwogICAgb2soIHJlcyAmJiAoc3RhdHVzID09IEVSUk9SX1NVQ0NFU1MpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCAldSBmb3Igc3RhdHVzICV1IChleHBlY3RlZCAnIT0gMCcgZm9yIHN0YXR1cyAiCiAgICAgICAgIkVSUk9SX1NVQ0NFU1MpXG4iLCByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgLyogb2ZmIGJ5IG9uZTogc21hbGxlciAqLwogICAgLyogdGhlIGJ1ZmZlciBpcyBub3QgbW9kaWZpZWQgZm9yIE5UNCwgdzJrLCBYUCAqLwogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Nb25pdG9yVUlXLCBOVUxMLCAwLCBidWZmZXIsIGxlbi0xLCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIG9rKCByZXMgJiYgKHN0YXR1cyA9PSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJyE9IDAnIGZvciBzdGF0dXMgIgogICAgICAgICJFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKCiAgICAvKiBOb3JtYWwgdXNlLiBUaGUgRExMLU5hbWUgd2l0aG91dCBhIFBhdGggaXMgcmV0dXJuZWQgKi8KICAgIG1lbXNldChidWZmZXIsIDAsIGxlbik7CiAgICBuZWVkZWQgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBzdGF0dXMgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwWGN2RGF0YVcoaFhjdiwgY21kX01vbml0b3JVSVcsIE5VTEwsIDAsIGJ1ZmZlciwgbGVuLCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIG9rKCByZXMgJiYgKHN0YXR1cyA9PSBFUlJPUl9TVUNDRVNTKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJyE9IDAnIGZvciBzdGF0dXMgIgogICAgICAgICJFUlJPUl9TVUNDRVNTKVxuIiwgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIENsb3NlUHJpbnRlcihoWGN2KTsKfQoKLyogIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICovCgpzdGF0aWMgdm9pZCB0ZXN0X1hjdkRhdGFXX1BvcnRJc1ZhbGlkKHZvaWQpCnsKICAgIERXT1JEICAgcmVzOwogICAgSEFORExFICBoWGN2OwogICAgRFdPUkQgICBuZWVkZWQ7CiAgICBEV09SRCAgIHN0YXR1czsKICAgIFBSSU5URVJfREVGQVVMVFNBICAgcGQ7CgogICAgLyogYXBpIGlzIG5vdCBwcmVzZW50IGJlZm9yZSB3MmsgKi8KICAgIGlmIChwWGN2RGF0YVcgPT0gTlVMTCkgcmV0dXJuOwoKICAgIHBkLnBEYXRhdHlwZSA9IE5VTEw7CiAgICBwZC5wRGV2TW9kZSAgPSBOVUxMOwogICAgcGQuRGVzaXJlZEFjY2VzcyA9IFNFUlZFUl9BQ0NFU1NfQURNSU5JU1RFUjsKCiAgICBoWGN2ID0gTlVMTDsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IE9wZW5QcmludGVyKHhjdl9sb2NhbHBvcnQsICZoWGN2LCAmcGQpOwoKICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJlcykKICAgIFJFVFVSTl9PTl9BQ0NFU1NfREVOSUVEKHJlcykKCiAgICBvayhyZXMsICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCBoYW5kbGUgJXAgKGV4cGVjdGVkICchPSAwJylcbiIsIHJlcywgR2V0TGFzdEVycm9yKCksIGhYY3YpOwogICAgaWYgKCFyZXMpIHJldHVybjsKCgogICAgLyogIlBEV09SRCBuZWVkZWQiIGlzIGFsd2F5cyByZXF1aXJlZCAqLwogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Qb3J0SXNWYWxpZFcsIChQQllURSkgcG9ydG5hbWVfbHB0MVcsIHNpemVvZihwb3J0bmFtZV9scHQxVyksIE5VTEwsIDAsIE5VTEwsICZzdGF0dXMpOwogICAgb2soICFyZXMgJiYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJyE9IDAnIHdpdGggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpXG4iLAogICAgICAgICByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgLyogYW4gZW1wdHkgbmFtZSBpcyBub3QgYWxsb3dlZCAqLwogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Qb3J0SXNWYWxpZFcsIChQQllURSkgZW1wdHlXLCBzaXplb2YoZW1wdHlXKSwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmICgoc3RhdHVzID09IEVSUk9SX0ZJTEVfTk9UX0ZPVU5EKSB8fCAoc3RhdHVzID09IEVSUk9SX1BBVEhfTk9UX0ZPVU5EKSksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICchPSAwJyBmb3Igc3RhdHVzOiAiCiAgICAgICAgIkVSUk9SX0ZJTEVfTk9UX0ZPVU5EIG9yIEVSUk9SX1BBVEhfTk9UX0ZPVU5EKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgLyogYSBkaXJlY3RvcnkgaXMgbm90IGFsbG93ZWQgKi8KICAgIG5lZWRlZCA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIHN0YXR1cyA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBYY3ZEYXRhVyhoWGN2LCBjbWRfUG9ydElzVmFsaWRXLCAoUEJZVEUpIHRlbXBkaXJXLCAobHN0cmxlblcodGVtcGRpclcpICsgMSkgKiBzaXplb2YoV0NIQVIpLCBOVUxMLCAwLCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIC8qIFhQOiBFUlJPUl9QQVRIX05PVF9GT1VORCwgdzJrIEVSUk9SX0FDQ0VTU19ERU5JRUQgKi8KICAgIG9rKCByZXMgJiYgKChzdGF0dXMgPT0gRVJST1JfUEFUSF9OT1RfRk9VTkQpIHx8IChzdGF0dXMgPT0gRVJST1JfQUNDRVNTX0RFTklFRCkpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCAldSBmb3Igc3RhdHVzICV1IChleHBlY3RlZCAnIT0gMCcgZm9yIHN0YXR1czogIgogICAgICAgICJFUlJPUl9QQVRIX05PVF9GT1VORCBvciBFUlJPUl9BQ0NFU1NfREVOSUVEKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgLyogbW9yZSB2YWxpZCB3ZWxsIGtub3duIFBvcnRzICovCiAgICBuZWVkZWQgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBzdGF0dXMgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwWGN2RGF0YVcoaFhjdiwgY21kX1BvcnRJc1ZhbGlkVywgKFBCWVRFKSBwb3J0bmFtZV9scHQxVywgc2l6ZW9mKHBvcnRuYW1lX2xwdDFXKSwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmIChzdGF0dXMgPT0gRVJST1JfU1VDQ0VTUyksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICchPSAwJyBmb3IgRVJST1JfU1VDQ0VTUylcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIG5lZWRlZCA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIHN0YXR1cyA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBYY3ZEYXRhVyhoWGN2LCBjbWRfUG9ydElzVmFsaWRXLCAoUEJZVEUpIHBvcnRuYW1lX2xwdDJXLCBzaXplb2YocG9ydG5hbWVfbHB0MlcpLCBOVUxMLCAwLCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIG9rKCByZXMgJiYgKHN0YXR1cyA9PSBFUlJPUl9TVUNDRVNTKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJyE9IDAnIGZvciBFUlJPUl9TVUNDRVNTKVxuIiwKICAgICAgICByZXMsIEdldExhc3RFcnJvcigpLCBuZWVkZWQsIHN0YXR1cyk7CgogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Qb3J0SXNWYWxpZFcsIChQQllURSkgcG9ydG5hbWVfY29tMVcsIHNpemVvZihwb3J0bmFtZV9jb20xVyksIE5VTEwsIDAsICZuZWVkZWQsICZzdGF0dXMpOwogICAgb2soIHJlcyAmJiAoc3RhdHVzID09IEVSUk9SX1NVQ0NFU1MpLAogICAgICAgICJyZXR1cm5lZCAlZCB3aXRoICV1IGFuZCAldSBmb3Igc3RhdHVzICV1IChleHBlY3RlZCAnIT0gMCcgZm9yIEVSUk9SX1NVQ0NFU1MpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCksIG5lZWRlZCwgc3RhdHVzKTsKCiAgICBuZWVkZWQgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBzdGF0dXMgPSAoRFdPUkQpIDB4ZGVhZGJlZWY7CiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICByZXMgPSBwWGN2RGF0YVcoaFhjdiwgY21kX1BvcnRJc1ZhbGlkVywgKFBCWVRFKSBwb3J0bmFtZV9jb20yVywgc2l6ZW9mKHBvcnRuYW1lX2NvbTJXKSwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmIChzdGF0dXMgPT0gRVJST1JfU1VDQ0VTUyksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICchPSAwJyBmb3IgRVJST1JfU1VDQ0VTUylcbiIsCiAgICAgICAgcmVzLCBHZXRMYXN0RXJyb3IoKSwgbmVlZGVkLCBzdGF0dXMpOwoKICAgIG5lZWRlZCA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIHN0YXR1cyA9IChEV09SRCkgMHhkZWFkYmVlZjsKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJlcyA9IHBYY3ZEYXRhVyhoWGN2LCBjbWRfUG9ydElzVmFsaWRXLCAoUEJZVEUpIHBvcnRuYW1lX2ZpbGVXLCBzaXplb2YocG9ydG5hbWVfZmlsZVcpLCBOVUxMLCAwLCAmbmVlZGVkLCAmc3RhdHVzKTsKICAgIG9rKCByZXMgJiYgKHN0YXR1cyA9PSBFUlJPUl9TVUNDRVNTKSwKICAgICAgICAicmV0dXJuZWQgJWQgd2l0aCAldSBhbmQgJXUgZm9yIHN0YXR1cyAldSAoZXhwZWN0ZWQgJyE9IDAnIHdpdGggIEVSUk9SX1NVQ0NFU1MpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCksIG5lZWRlZCwgc3RhdHVzKTsKCgogICAgLyogYSBub3JtYWwsIHdyaXRhYmxlIGZpbGUgaXMgYWxsb3dlZCAqLwogICAgbmVlZGVkID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgc3RhdHVzID0gKERXT1JEKSAweGRlYWRiZWVmOwogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgcmVzID0gcFhjdkRhdGFXKGhYY3YsIGNtZF9Qb3J0SXNWYWxpZFcsIChQQllURSkgdGVtcGZpbGVXLCAobHN0cmxlblcodGVtcGZpbGVXKSArIDEpICogc2l6ZW9mKFdDSEFSKSwgTlVMTCwgMCwgJm5lZWRlZCwgJnN0YXR1cyk7CiAgICBvayggcmVzICYmIChzdGF0dXMgPT0gRVJST1JfU1VDQ0VTUyksCiAgICAgICAgInJldHVybmVkICVkIHdpdGggJXUgYW5kICV1IGZvciBzdGF0dXMgJXUgKGV4cGVjdGVkICchPSAwJyB3aXRoIEVSUk9SX1NVQ0NFU1MpXG4iLAogICAgICAgIHJlcywgR2V0TGFzdEVycm9yKCksIG5lZWRlZCwgc3RhdHVzKTsKCiAgICBDbG9zZVByaW50ZXIoaFhjdik7Cn0KCi8qICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAqLwoKc3RhdGljIHZvaWQgdGVzdF9HZXRQcmludGVyRHJpdmVyKHZvaWQpCnsKICAgIEhBTkRMRSBocHJuOwogICAgQk9PTCByZXQ7CiAgICBCWVRFICpidWY7CiAgICBJTlQgbGV2ZWw7CiAgICBEV09SRCBuZWVkZWQsIGZpbGxlZDsKCiAgICBpZiAoIWRlZmF1bHRfcHJpbnRlcikKICAgIHsKICAgICAgICBza2lwKCJUaGVyZSBpcyBubyBkZWZhdWx0IHByaW50ZXIgaW5zdGFsbGVkXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaHBybiA9IDA7CiAgICByZXQgPSBPcGVuUHJpbnRlcihkZWZhdWx0X3ByaW50ZXIsICZocHJuLCBOVUxMKTsKICAgIGlmICghcmV0KQogICAgewogICAgICAgIHNraXAoIlVuYWJsZSB0byBvcGVuIHRoZSBkZWZhdWx0IHByaW50ZXIgKCVzKVxuIiwgZGVmYXVsdF9wcmludGVyKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBvayhocHJuICE9IDAsICJ3cm9uZyBocHJuICVwXG4iLCBocHJuKTsKCiAgICBmb3IgKGxldmVsID0gLTE7IGxldmVsIDw9IDc7IGxldmVsKyspCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgICAgIG5lZWRlZCA9IChEV09SRCktMTsKICAgICAgICByZXQgPSBHZXRQcmludGVyRHJpdmVyKGhwcm4sIE5VTEwsIGxldmVsLCBOVUxMLCAwLCAmbmVlZGVkKTsKICAgICAgICBvayghcmV0LCAibGV2ZWwgJWQ6IEdldFByaW50ZXJEcml2ZXIgc2hvdWxkIGZhaWxcbiIsIGxldmVsKTsKICAgICAgICBpZiAobGV2ZWwgPj0gMSAmJiBsZXZlbCA8PSA2KQogICAgICAgIHsKICAgICAgICAgICAgLyogTm90IGFsbCBsZXZlbHMgYXJlIHN1cHBvcnRlZCBvbiBhbGwgV2luZG93cy1WZXJzaW9ucyAqLwogICAgICAgICAgICBpZihHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JTlZBTElEX0xFVkVMKSBjb250aW51ZTsKICAgICAgICAgICAgb2soR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgIndyb25nIGVycm9yICVkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIG9rKG5lZWRlZCA+IDAsIm5vdCBleHBlY3RlZCBuZWVkZWQgYnVmZmVyIHNpemUgJWRcbiIsIG5lZWRlZCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIEVSUk9SX09VVE9GTUVNT1JZIGZvdW5kIG9uIHdpbjl4ICovCiAgICAgICAgICAgIG9rKCAoKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOVkFMSURfTEVWRUwpIHx8CiAgICAgICAgICAgICAgICAgKEdldExhc3RFcnJvcigpID09IEVSUk9SX09VVE9GTUVNT1JZKSksCiAgICAgICAgICAgICAgICAiJWQ6IHJldHVybmVkICVkIHdpdGggJWQgKGV4cGVjdGVkICcwJyB3aXRoOiAiCiAgICAgICAgICAgICAgICAiRVJST1JfSU5WQUxJRF9MRVZFTCBvciBFUlJPUl9PVVRPRk1FTU9SWSlcbiIsCiAgICAgICAgICAgICAgICBsZXZlbCwgcmV0LCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIC8qIG5lZWRlZCBpcyBtb2RpZmllZCBpbiB3aW45eC4gVGhlIG1vZGlmaWVkIFZhbHVlIGRlcGVuZHMgb24gdGhlCiAgICAgICAgICAgICAgIGRlZmF1bHQgUHJpbnRlci4gdGVzdGluZyBmb3IgIm5lZWRlZCA9PSAoRFdPUkQpLTEiIHdpbGwgZmFpbCAqLwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGJ1ZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBuZWVkZWQpOwoKICAgICAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICAgICAgZmlsbGVkID0gLTE7CiAgICAgICAgcmV0ID0gR2V0UHJpbnRlckRyaXZlcihocHJuLCBOVUxMLCBsZXZlbCwgYnVmLCBuZWVkZWQsICZmaWxsZWQpOwogICAgICAgIG9rKHJldCwgImxldmVsICVkOiBHZXRQcmludGVyRHJpdmVyIGVycm9yICVkXG4iLCBsZXZlbCwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKG5lZWRlZCA9PSBmaWxsZWQsICJuZWVkZWQgJWQgIT0gZmlsbGVkICVkXG4iLCBuZWVkZWQsIGZpbGxlZCk7CgogICAgICAgIGlmIChsZXZlbCA9PSAyKQogICAgICAgIHsKICAgICAgICAgICAgRFJJVkVSX0lORk9fMiAqZGlfMiA9IChEUklWRVJfSU5GT18yICopYnVmOwogICAgICAgICAgICBEV09SRCBjYWxjdWxhdGVkID0gc2l6ZW9mKCpkaV8yKTsKCiAgICAgICAgICAgIC8qIE1TRE4gaXMgd3Jvbmc6IFRoZSBEcml2ZXJzIG9uIHRoZSB3aW45eC1DRCdzIGhhdmUgY1ZlcnNpb249MHgwNDAwCiAgICAgICAgICAgICAgIE5UMzUxOiAxLCBOVDQuMCt3MmsoS2VybmVsbW9kZSk6IDIsIHcyayBhbmQgYWJvdmUoVXNlcm1vZGUpOiAzICAqLwogICAgICAgICAgICBvaygoZGlfMi0+Y1ZlcnNpb24gPj0gMCAmJiBkaV8yLT5jVmVyc2lvbiA8PSAzKSB8fAogICAgICAgICAgICAgICAgKGRpXzItPmNWZXJzaW9uID09IDB4MDQwMCksICJkaV8yLT5jVmVyc2lvbiA9ICVkXG4iLCBkaV8yLT5jVmVyc2lvbik7CiAgICAgICAgICAgIG9rKGRpXzItPnBOYW1lICE9IE5VTEwsICJub3QgZXhwZWN0ZWQgTlVMTCBwdHJcbiIpOwogICAgICAgICAgICBvayhkaV8yLT5wRW52aXJvbm1lbnQgIT0gTlVMTCwgIm5vdCBleHBlY3RlZCBOVUxMIHB0clxuIik7CiAgICAgICAgICAgIG9rKGRpXzItPnBEcml2ZXJQYXRoICE9IE5VTEwsICJub3QgZXhwZWN0ZWQgTlVMTCBwdHJcbiIpOwogICAgICAgICAgICBvayhkaV8yLT5wRGF0YUZpbGUgIT0gTlVMTCwgIm5vdCBleHBlY3RlZCBOVUxMIHB0clxuIik7CiAgICAgICAgICAgIG9rKGRpXzItPnBDb25maWdGaWxlICE9IE5VTEwsICJub3QgZXhwZWN0ZWQgTlVMTCBwdHJcbiIpOwoKICAgICAgICAgICAgdHJhY2UoImNWZXJzaW9uICVkXG4iLCBkaV8yLT5jVmVyc2lvbik7CiAgICAgICAgICAgIHRyYWNlKCJwTmFtZSAlc1xuIiwgZGlfMi0+cE5hbWUpOwogICAgICAgICAgICBjYWxjdWxhdGVkICs9IHN0cmxlbihkaV8yLT5wTmFtZSkgKyAxOwogICAgICAgICAgICB0cmFjZSgicEVudmlyb25tZW50ICVzXG4iLCBkaV8yLT5wRW52aXJvbm1lbnQpOwogICAgICAgICAgICBjYWxjdWxhdGVkICs9IHN0cmxlbihkaV8yLT5wRW52aXJvbm1lbnQpICsgMTsKICAgICAgICAgICAgdHJhY2UoInBEcml2ZXJQYXRoICVzXG4iLCBkaV8yLT5wRHJpdmVyUGF0aCk7CiAgICAgICAgICAgIGNhbGN1bGF0ZWQgKz0gc3RybGVuKGRpXzItPnBEcml2ZXJQYXRoKSArIDE7CiAgICAgICAgICAgIHRyYWNlKCJwRGF0YUZpbGUgJXNcbiIsIGRpXzItPnBEYXRhRmlsZSk7CiAgICAgICAgICAgIGNhbGN1bGF0ZWQgKz0gc3RybGVuKGRpXzItPnBEYXRhRmlsZSkgKyAxOwogICAgICAgICAgICB0cmFjZSgicENvbmZpZ0ZpbGUgJXNcbiIsIGRpXzItPnBDb25maWdGaWxlKTsKICAgICAgICAgICAgY2FsY3VsYXRlZCArPSBzdHJsZW4oZGlfMi0+cENvbmZpZ0ZpbGUpICsgMTsKCiAgICAgICAgICAgIC8qIFhQIGFsbG9jYXRlcyBtZW1vcnkgZm9yIGJvdGggQU5TSSBhbmQgdW5pY29kZSBuYW1lcyAqLwogICAgICAgICAgICBvayhmaWxsZWQgPj0gY2FsY3VsYXRlZCwiY2FsY3VsYXRlZCAlZCAhPSBmaWxsZWQgJWRcbiIsIGNhbGN1bGF0ZWQsIGZpbGxlZCk7CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYpOwogICAgfQoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJldCA9IENsb3NlUHJpbnRlcihocHJuKTsKICAgIG9rKHJldCwgIkNsb3NlUHJpbnRlciBlcnJvciAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwp9CgpzdGF0aWMgdm9pZCB0ZXN0X0RFVk1PREUoY29uc3QgREVWTU9ERSAqZG0sIExPTkcgZG1TaXplLCBMUENTVFIgZXhwX3Bybl9uYW1lKQp7CiAgICAvKiBPbiBOVDMuNTEsIHNvbWUgZmllbGRzIGluIERFVk1PREUgYXJlIGVtcHR5L3plcm8KICAgICAgKGRtRGV2aWNlTmFtZSwgZG1TcGVjVmVyc2lvbiwgZG1Ecml2ZXJWZXJzaW9uIGFuZCBkbURyaXZlckV4dHJhKQogICAgICAgV2Ugc2tpcCB0aGUgVGVzdHMgb24gdGhpcyBQbGF0Zm9ybSAqLwogICAgaWYgKGRtLT5kbVNwZWNWZXJzaW9uIHx8IGRtLT5kbURyaXZlclZlcnNpb24gfHwgZG0tPmRtRHJpdmVyRXh0cmEpIHsKICAgIC8qIFRoZSAwLXRlcm1pbmF0ZWQgUHJpbnRlcm5hbWUgY2FuIGJlIGxhcmdlciAoTUFYX1BBVEgpIHRoYW4gQ0NIREVWSUNFTkFNRSAqLwogICAgICAgIG9rKCFzdHJuY21wKGV4cF9wcm5fbmFtZSwgKExQQ1NUUilkbS0+ZG1EZXZpY2VOYW1lLCBDQ0hERVZJQ0VOQU1FIC0xKSwKICAgICAgICAgICAgImV4cGVjdGVkICclcycsIGdvdCAnJXMnXG4iLCBleHBfcHJuX25hbWUsIGRtLT5kbURldmljZU5hbWUpOwogICAgICAgIG9rKGRtLT5kbVNpemUgKyBkbS0+ZG1Ecml2ZXJFeHRyYSA9PSBkbVNpemUsCiAgICAgICAgICAgICIldSAhPSAlZFxuIiwgZG0tPmRtU2l6ZSArIGRtLT5kbURyaXZlckV4dHJhLCBkbVNpemUpOwogICAgfQogICAgdHJhY2UoImRtRmllbGRzICUwOHhcbiIsIGRtLT5kbUZpZWxkcyk7Cn0KCnN0YXRpYyB2b2lkIHRlc3RfRG9jdW1lbnRQcm9wZXJ0aWVzKHZvaWQpCnsKICAgIEhBTkRMRSBocHJuOwogICAgTE9ORyBkbV9zaXplLCByZXQ7CiAgICBERVZNT0RFICpkbTsKCiAgICBpZiAoIWRlZmF1bHRfcHJpbnRlcikKICAgIHsKICAgICAgICBza2lwKCJUaGVyZSBpcyBubyBkZWZhdWx0IHByaW50ZXIgaW5zdGFsbGVkXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaHBybiA9IDA7CiAgICByZXQgPSBPcGVuUHJpbnRlcihkZWZhdWx0X3ByaW50ZXIsICZocHJuLCBOVUxMKTsKICAgIGlmICghcmV0KQogICAgewogICAgICAgIHNraXAoIlVuYWJsZSB0byBvcGVuIHRoZSBkZWZhdWx0IHByaW50ZXIgKCVzKVxuIiwgZGVmYXVsdF9wcmludGVyKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBvayhocHJuICE9IDAsICJ3cm9uZyBocHJuICVwXG4iLCBocHJuKTsKCiAgICBkbV9zaXplID0gRG9jdW1lbnRQcm9wZXJ0aWVzKDAsIGhwcm4sIE5VTEwsIE5VTEwsIE5VTEwsIDApOwogICAgdHJhY2UoIkRFVk1PREUgcmVxdWlyZWQgc2l6ZSAlZFxuIiwgZG1fc2l6ZSk7CiAgICBvayhkbV9zaXplID49IHNpemVvZihERVZNT0RFKSwgInVuZXhwZWN0ZWQgRG9jdW1lbnRQcm9wZXJ0aWVzIHJldCB2YWx1ZSAlZFxuIiwgZG1fc2l6ZSk7CgogICAgZG0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgZG1fc2l6ZSk7CgogICAgcmV0ID0gRG9jdW1lbnRQcm9wZXJ0aWVzKDAsIGhwcm4sIE5VTEwsIGRtLCBkbSwgRE1fT1VUX0JVRkZFUik7CiAgICBvayhyZXQgPT0gSURPSywgIkRvY3VtZW50UHJvcGVydGllcyByZXQgdmFsdWUgJWQgIT0gZXhwZWN0ZWQgSURPS1xuIiwgcmV0KTsKCiAgICB0ZXN0X0RFVk1PREUoZG0sIGRtX3NpemUsIGRlZmF1bHRfcHJpbnRlcik7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZG0pOwoKICAgIFNldExhc3RFcnJvcigweGRlYWRiZWVmKTsKICAgIHJldCA9IENsb3NlUHJpbnRlcihocHJuKTsKICAgIG9rKHJldCwgIkNsb3NlUHJpbnRlciBlcnJvciAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwp9CgpzdGF0aWMgdm9pZCB0ZXN0X0VudW1QcmludGVycyh2b2lkKQp7CiAgICBEV09SRCBuZWVkZWRBLCBuZWVkZWRXLCBudW07CiAgICBEV09SRCByZXQ7CgogICAgU2V0TGFzdEVycm9yKDB4ZGVhZGJlZWYpOwogICAgbmVlZGVkQSA9IC0xOwogICAgcmV0ID0gRW51bVByaW50ZXJzQShQUklOVEVSX0VOVU1fTE9DQUwsIE5VTEwsIDIsIE5VTEwsIDAsICZuZWVkZWRBLCAmbnVtKTsKICAgIFJFVFVSTl9PTl9ERUFDVElWQVRFRF9TUE9PTEVSKHJldCkKICAgIGlmICghcmV0KQogICAgewogICAgICAgIC8qIFdlIGhhdmUgMSBvciBtb3JlIHByaW50ZXJzICovCiAgICAgICAgb2soR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgImdsZSAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKG5lZWRlZEEgPiAwLCAiRXhwZWN0ZWQgbmVlZGVkQSB0byBzaG93IHRoZSBudW1iZXIgb2YgbmVlZGVkIGJ5dGVzXG4iKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBXZSBkb24ndCBoYXZlIGFueSBwcmludGVycyBkZWZpbmVkICovCiAgICAgICAgb2soR2V0TGFzdEVycm9yKCkgPT0gU19PSywgImdsZSAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgIG9rKG5lZWRlZEEgPT0gMCwgIkV4cGVjdGVkIG5lZWRlZEEgdG8gYmUgemVyb1xuIik7CiAgICB9CiAgICBvayhudW0gPT0gMCwgIm51bSAlZFxuIiwgbnVtKTsKCiAgICBTZXRMYXN0RXJyb3IoMHhkZWFkYmVlZik7CiAgICBuZWVkZWRXID0gLTE7CiAgICByZXQgPSBFbnVtUHJpbnRlcnNXKFBSSU5URVJfRU5VTV9MT0NBTCwgTlVMTCwgMiwgTlVMTCwgMCwgJm5lZWRlZFcsICZudW0pOwogICAgLyogRW51bVByaW50ZXJzVyBpcyBub3Qgc3VwcG9ydGVkIG9uIGFsbCBwbGF0Zm9ybXMgKi8KICAgIGlmICghcmV0ICYmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCkpCiAgICB7CiAgICAgICAgc2tpcCgiRW51bVByaW50ZXJzVyBpcyBub3QgaW1wbGVtZW50ZWRcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIXJldCkKICAgIHsKICAgICAgICAvKiBXZSBoYXZlIDEgb3IgbW9yZSBwcmludGVycyAqLwogICAgICAgIG9rKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIsICJnbGUgJWRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBvayhuZWVkZWRXID4gMCwgIkV4cGVjdGVkIG5lZWRlZFcgdG8gc2hvdyB0aGUgbnVtYmVyIG9mIG5lZWRlZCBieXRlc1xuIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogV2UgZG9uJ3QgaGF2ZSBhbnkgcHJpbnRlcnMgZGVmaW5lZCAqLwogICAgICAgIG9rKEdldExhc3RFcnJvcigpID09IFNfT0ssICJnbGUgJWRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBvayhuZWVkZWRXID09IDAsICJFeHBlY3RlZCBuZWVkZWRXIHRvIGJlIHplcm9cbiIpOwogICAgfQogICAgb2sobnVtID09IDAsICJudW0gJWRcbiIsIG51bSk7CgogICAgLyogT3V0bG9vazIwMDMgcmVsaWVzIG9uIHRoZSBidWZmZXIgc2l6ZSByZXR1cm5lZCBieSBFbnVtUHJpbnRlcnNBIGJlaW5nIGJpZyBlbm91Z2gKICAgICAgIHRvIGhvbGQgdGhlIGJ1ZmZlciByZXR1cm5lZCBieSBFbnVtUHJpbnRlcnNXICovCiAgICBvayhuZWVkZWRBID09IG5lZWRlZFcsICJuZWVkZWRBICVkIG5lZWRlZFcgJWRcbiIsIG5lZWRlZEEsIG5lZWRlZFcpOwp9CgpzdGF0aWMgdm9pZCB0ZXN0X0RldmljZUNhcGFiaWxpdGllcyh2b2lkKQp7CiAgICBIQU5ETEUgaENvbWRsZzMyOwogICAgQk9PTCAoV0lOQVBJICpwUHJpbnREbGdBKShQUklOVERMR0EgKik7CiAgICBQUklOVERMR0EgcHJuX2RsZzsKICAgIERFVk1PREUgKmRtOwogICAgREVWTkFNRVMgKmRuOwogICAgY29uc3QgY2hhciAqZHJpdmVyLCAqZGV2aWNlLCAqcG9ydDsKICAgIFdPUkQgKnBhcGVyczsKICAgIFBPSU5UICpwYXBlcl9zaXplOwogICAgUE9JTlRTIGV4dDsKICAgIHN0cnVjdAogICAgewogICAgICAgIGNoYXIgbmFtZVs2NF07CiAgICB9ICpwYXBlcl9uYW1lOwogICAgSU5UIG5fcGFwZXJzLCBuX3BhcGVyX3NpemUsIG5fcGFwZXJfbmFtZXMsIG5fY29waWVzLCByZXQ7CiAgICBEV09SRCBmaWVsZHM7CgogICAgaENvbWRsZzMyID0gTG9hZExpYnJhcnkoImNvbWRsZzMyLmRsbCIpOwogICAgYXNzZXJ0KGhDb21kbGczMik7CiAgICBwUHJpbnREbGdBID0gKHZvaWQgKilHZXRQcm9jQWRkcmVzcyhoQ29tZGxnMzIsICJQcmludERsZ0EiKTsKICAgIGFzc2VydChwUHJpbnREbGdBKTsKCiAgICBtZW1zZXQoJnBybl9kbGcsIDAsIHNpemVvZihwcm5fZGxnKSk7CiAgICBwcm5fZGxnLmxTdHJ1Y3RTaXplID0gc2l6ZW9mKHBybl9kbGcpOwogICAgcHJuX2RsZy5GbGFncyA9IFBEX1JFVFVSTkRFRkFVTFQ7CiAgICByZXQgPSBwUHJpbnREbGdBKCZwcm5fZGxnKTsKICAgIEZyZWVMaWJyYXJ5KGhDb21kbGczMik7CiAgICBpZiAoIXJldCkKICAgIHsKICAgICAgICBza2lwKCJQcmludERsZyByZXR1cm5lZCBubyBkZWZhdWx0IHByaW50ZXJcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIG9rKHBybl9kbGcuaERldk1vZGUgIT0gMCwgIlByaW50RGxnIHJldHVybmVkIGhEZXZNb2RlID09IE5VTExcbiIpOwogICAgb2socHJuX2RsZy5oRGV2TmFtZXMgIT0gMCwgIlByaW50RGxnIHJldHVybmVkIGhEZXZOYW1lcyA9PSBOVUxMXG4iKTsKCiAgICBkbSA9IEdsb2JhbExvY2socHJuX2RsZy5oRGV2TW9kZSk7CiAgICBvayhkbSAhPSBOVUxMLCAiR2xvYmFsTG9jayhwcm5fZGxnLmhEZXZNb2RlKSBmYWlsZWRcbiIpOwogICAgdHJhY2UoImRtRGV2aWNlTmFtZSBcIiVzXCJcbiIsIGRtLT5kbURldmljZU5hbWUpOwoKICAgIGRuID0gR2xvYmFsTG9jayhwcm5fZGxnLmhEZXZOYW1lcyk7CiAgICBvayhkbiAhPSBOVUxMLCAiR2xvYmFsTG9jayhwcm5fZGxnLmhEZXZOYW1lcykgZmFpbGVkXG4iKTsKICAgIG9rKGRuLT53RHJpdmVyT2Zmc2V0LCAiZXhwZWN0ZWQgbm90IDAgd0RyaXZlck9mZnNldFxuIik7CiAgICBvayhkbi0+d0RldmljZU9mZnNldCwgImV4cGVjdGVkIG5vdCAwIHdEZXZpY2VPZmZzZXRcbiIpOwogICAgb2soZG4tPndPdXRwdXRPZmZzZXQsICJleHBlY3RlZCBub3QgMCB3T3V0cHV0T2Zmc2V0XG4iKTsKICAgIG9rKGRuLT53RGVmYXVsdCA9PSBETl9ERUZBVUxUUFJOLCAiZXhwZWN0ZWQgRE5fREVGQVVMVFBSTiBnb3QgJXhcbiIsIGRuLT53RGVmYXVsdCk7CiAgICBkcml2ZXIgPSAoY29uc3QgY2hhciAqKWRuICsgZG4tPndEcml2ZXJPZmZzZXQ7CiAgICBkZXZpY2UgPSAoY29uc3QgY2hhciAqKWRuICsgZG4tPndEZXZpY2VPZmZzZXQ7CiAgICBwb3J0ID0gKGNvbnN0IGNoYXIgKilkbiArIGRuLT53T3V0cHV0T2Zmc2V0OwogICAgdHJhY2UoImRyaXZlciBcIiVzXCIgZGV2aWNlIFwiJXNcIiBwb3J0IFwiJXNcIlxuIiwgZHJpdmVyLCBkZXZpY2UsIHBvcnQpOwoKICAgIHRlc3RfREVWTU9ERShkbSwgZG0tPmRtU2l6ZSArIGRtLT5kbURyaXZlckV4dHJhLCBkZXZpY2UpOwoKICAgIG5fcGFwZXJzID0gRGV2aWNlQ2FwYWJpbGl0aWVzKGRldmljZSwgcG9ydCwgRENfUEFQRVJTLCBOVUxMLCBOVUxMKTsKICAgIG9rKG5fcGFwZXJzID4gMCwgIkRldmljZUNhcGFiaWxpdGllcyBEQ19QQVBFUlMgZmFpbGVkXG4iKTsKICAgIHBhcGVycyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKnBhcGVycykgKiBuX3BhcGVycyk7CiAgICByZXQgPSBEZXZpY2VDYXBhYmlsaXRpZXMoZGV2aWNlLCBwb3J0LCBEQ19QQVBFUlMsIChMUFNUUilwYXBlcnMsIE5VTEwpOwogICAgb2socmV0ID09IG5fcGFwZXJzLCAiZXhwZWN0ZWQgJWQsIGdvdCAlZFxuIiwgbl9wYXBlcnMsIHJldCk7CiNpZiBWRVJCT1NFCiAgICBmb3IgKHJldCA9IDA7IHJldCA8IG5fcGFwZXJzOyByZXQrKykKICAgICAgICB0cmFjZSgicGFwZXJzWyVkXSA9ICVkXG4iLCByZXQsIHBhcGVyc1tyZXRdKTsKI2VuZGlmCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXBlcnMpOwoKICAgIG5fcGFwZXJfc2l6ZSA9IERldmljZUNhcGFiaWxpdGllcyhkZXZpY2UsIHBvcnQsIERDX1BBUEVSU0laRSwgTlVMTCwgTlVMTCk7CiAgICBvayhuX3BhcGVyX3NpemUgPiAwLCAiRGV2aWNlQ2FwYWJpbGl0aWVzIERDX1BBUEVSU0laRSBmYWlsZWRcbiIpOwogICAgb2sobl9wYXBlcl9zaXplID09IG5fcGFwZXJzLCAibl9wYXBlcl9zaXplICVkICE9IG5fcGFwZXJzICVkXG4iLCBuX3BhcGVyX3NpemUsIG5fcGFwZXJzKTsKICAgIHBhcGVyX3NpemUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpwYXBlcl9zaXplKSAqIG5fcGFwZXJfc2l6ZSk7CiAgICByZXQgPSBEZXZpY2VDYXBhYmlsaXRpZXMoZGV2aWNlLCBwb3J0LCBEQ19QQVBFUlNJWkUsIChMUFNUUilwYXBlcl9zaXplLCBOVUxMKTsKICAgIG9rKHJldCA9PSBuX3BhcGVyX3NpemUsICJleHBlY3RlZCAlZCwgZ290ICVkXG4iLCBuX3BhcGVyX3NpemUsIHJldCk7CiNpZiBWRVJCT1NFCiAgICBmb3IgKHJldCA9IDA7IHJldCA8IG5fcGFwZXJfc2l6ZTsgcmV0KyspCiAgICAgICAgdHJhY2UoInBhcGVyX3NpemVbJWRdID0gJWQgeCAlZFxuIiwgcmV0LCBwYXBlcl9zaXplW3JldF0ueCwgcGFwZXJfc2l6ZVtyZXRdLnkpOwojZW5kaWYKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhcGVyX3NpemUpOwoKICAgIG5fcGFwZXJfbmFtZXMgPSBEZXZpY2VDYXBhYmlsaXRpZXMoZGV2aWNlLCBwb3J0LCBEQ19QQVBFUk5BTUVTLCBOVUxMLCBOVUxMKTsKICAgIG9rKG5fcGFwZXJfbmFtZXMgPiAwLCAiRGV2aWNlQ2FwYWJpbGl0aWVzIERDX1BBUEVSTkFNRVMgZmFpbGVkXG4iKTsKICAgIG9rKG5fcGFwZXJfbmFtZXMgPT0gbl9wYXBlcnMsICJuX3BhcGVyX25hbWVzICVkICE9IG5fcGFwZXJzICVkXG4iLCBuX3BhcGVyX25hbWVzLCBuX3BhcGVycyk7CiAgICBwYXBlcl9uYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcGFwZXJfbmFtZSkgKiBuX3BhcGVyX25hbWVzKTsKICAgIHJldCA9IERldmljZUNhcGFiaWxpdGllcyhkZXZpY2UsIHBvcnQsIERDX1BBUEVSTkFNRVMsIChMUFNUUilwYXBlcl9uYW1lLCBOVUxMKTsKICAgIG9rKHJldCA9PSBuX3BhcGVyX25hbWVzLCAiZXhwZWN0ZWQgJWQsIGdvdCAlZFxuIiwgbl9wYXBlcl9uYW1lcywgcmV0KTsKI2lmIFZFUkJPU0UKICAgIGZvciAocmV0ID0gMDsgcmV0IDwgbl9wYXBlcl9uYW1lczsgcmV0KyspCiAgICAgICAgdHJhY2UoInBhcGVyX25hbWVbJXVdID0gJXNcbiIsIHJldCwgcGFwZXJfbmFtZVtyZXRdLm5hbWUpOwojZW5kaWYKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhcGVyX25hbWUpOwoKICAgIG5fY29waWVzID0gRGV2aWNlQ2FwYWJpbGl0aWVzKGRldmljZSwgcG9ydCwgRENfQ09QSUVTLCBOVUxMLCBkbSk7CiAgICBvayhuX2NvcGllcyA+IDAsICJEZXZpY2VDYXBhYmlsaXRpZXMgRENfQ09QSUVTIGZhaWxlZFxuIik7CiAgICB0cmFjZSgibl9jb3BpZXMgPSAlZFxuIiwgbl9jb3BpZXMpOwoKICAgIHJldCA9IERldmljZUNhcGFiaWxpdGllcyhkZXZpY2UsIHBvcnQsIERDX01BWEVYVEVOVCwgTlVMTCwgTlVMTCk7CiAgICBvayhyZXQgIT0gLTEsICJEZXZpY2VDYXBhYmlsaXRpZXMgRENfTUFYRVhURU5UIGZhaWxlZFxuIik7CiAgICBleHQgPSBNQUtFUE9JTlRTKHJldCk7CiAgICB0cmFjZSgibWF4IGV4dCA9ICVkIHggJWRcbiIsIGV4dC54LCBleHQueSk7CgogICAgcmV0ID0gRGV2aWNlQ2FwYWJpbGl0aWVzKGRldmljZSwgcG9ydCwgRENfTUlORVhURU5ULCBOVUxMLCBOVUxMKTsKICAgIG9rKHJldCAhPSAtMSwgIkRldmljZUNhcGFiaWxpdGllcyBEQ19NSU5FWFRFTlQgZmFpbGVkXG4iKTsKICAgIGV4dCA9IE1BS0VQT0lOVFMocmV0KTsKICAgIHRyYWNlKCJtaW4gZXh0ID0gJWQgeCAlZFxuIiwgZXh0LngsIGV4dC55KTsKCiAgICBmaWVsZHMgPSBEZXZpY2VDYXBhYmlsaXRpZXMoZGV2aWNlLCBwb3J0LCBEQ19GSUVMRFMsIE5VTEwsIE5VTEwpOwogICAgb2soZmllbGRzICE9IChEV09SRCktMSwgIkRldmljZUNhcGFiaWxpdGllcyBEQ19GSUVMRFMgZmFpbGVkXG4iKTsKICAgIG9rKGZpZWxkcyA9PSBkbS0+ZG1GaWVsZHMsICJmaWVsZHMgJXggIT0gZG0tPmRtRmllbGRzICV4XG4iLCBmaWVsZHMsIGRtLT5kbUZpZWxkcyk7CgogICAgR2xvYmFsVW5sb2NrKHBybl9kbGcuaERldk1vZGUpOwogICAgR2xvYmFsRnJlZShwcm5fZGxnLmhEZXZNb2RlKTsKICAgIEdsb2JhbFVubG9jayhwcm5fZGxnLmhEZXZOYW1lcyk7CiAgICBHbG9iYWxGcmVlKHBybl9kbGcuaERldk5hbWVzKTsKfQoKU1RBUlRfVEVTVChpbmZvKQp7CiAgICBod2luc3Bvb2wgPSBHZXRNb2R1bGVIYW5kbGVBKCJ3aW5zcG9vbC5kcnYiKTsKICAgIHBHZXREZWZhdWx0UHJpbnRlckEgPSAodm9pZCAqKSBHZXRQcm9jQWRkcmVzcyhod2luc3Bvb2wsICJHZXREZWZhdWx0UHJpbnRlckEiKTsKICAgIHBTZXREZWZhdWx0UHJpbnRlckEgPSAodm9pZCAqKSBHZXRQcm9jQWRkcmVzcyhod2luc3Bvb2wsICJTZXREZWZhdWx0UHJpbnRlckEiKTsKICAgIHBYY3ZEYXRhVyA9ICh2b2lkICopIEdldFByb2NBZGRyZXNzKGh3aW5zcG9vbCwgIlhjdkRhdGFXIik7CiAgICBwQWRkUG9ydEV4QSA9ICh2b2lkICopIEdldFByb2NBZGRyZXNzKGh3aW5zcG9vbCwgIkFkZFBvcnRFeEEiKTsKCiAgICBmaW5kX2RlZmF1bHRfcHJpbnRlcigpOwogICAgZmluZF9sb2NhbF9zZXJ2ZXIoKTsKICAgIGZpbmRfdGVtcGZpbGUoKTsKCiAgICB0ZXN0X0FkZE1vbml0b3IoKTsKICAgIHRlc3RfQWRkUG9ydCgpOwogICAgdGVzdF9BZGRQb3J0RXgoKTsKICAgIHRlc3RfQ29uZmlndXJlUG9ydCgpOwogICAgdGVzdF9EZWxldGVNb25pdG9yKCk7CiAgICB0ZXN0X0RlbGV0ZVBvcnQoKTsKICAgIHRlc3RfRGV2aWNlQ2FwYWJpbGl0aWVzKCk7CiAgICB0ZXN0X0RvY3VtZW50UHJvcGVydGllcygpOwogICAgdGVzdF9FbnVtRm9ybXMoTlVMTCk7CiAgICBpZiAoZGVmYXVsdF9wcmludGVyKSB0ZXN0X0VudW1Gb3JtcyhkZWZhdWx0X3ByaW50ZXIpOwogICAgdGVzdF9FbnVtTW9uaXRvcnMoKTsKICAgIHRlc3RfRW51bVBvcnRzKCk7CiAgICB0ZXN0X0VudW1QcmludGVyRHJpdmVycygpOwogICAgdGVzdF9FbnVtUHJpbnRlcnMoKTsKICAgIHRlc3RfR2V0RGVmYXVsdFByaW50ZXIoKTsKICAgIHRlc3RfR2V0UHJpbnRlckRyaXZlckRpcmVjdG9yeSgpOwogICAgdGVzdF9HZXRQcmludFByb2Nlc3NvckRpcmVjdG9yeSgpOwogICAgdGVzdF9PcGVuUHJpbnRlcigpOwogICAgdGVzdF9HZXRQcmludGVyRHJpdmVyKCk7CiAgICB0ZXN0X1NldERlZmF1bHRQcmludGVyKCk7CiAgICB0ZXN0X1hjdkRhdGFXX01vbml0b3JVSSgpOwogICAgdGVzdF9YY3ZEYXRhV19Qb3J0SXNWYWxpZCgpOwoKICAgIC8qIENsZWFudXAgb3VyIHRlbXBvcmFyeSBmaWxlICovCiAgICBEZWxldGVGaWxlQSh0ZW1wZmlsZUEpOwp9Cg==