LyoKICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTMsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBQcmV2aW91c2x5IGxpY2Vuc2VkIHVuZGVyIHRoZSBJU0MgbGljZW5zZSBieSBRdWFsY29tbSBBdGhlcm9zLCBJbmMuCiAqCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yCiAqIGFueSBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlCiAqIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbAogKiBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwKICogV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRAogKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUgogKiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwovKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBQcmV2aW91c2x5IGxpY2Vuc2VkIHVuZGVyIHRoZSBJU0MgbGljZW5zZSBieSBRdWFsY29tbSBBdGhlcm9zLCBJbmMuCiAqCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yCiAqIGFueSBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlCiAqIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbAogKiBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwKICogV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRAogKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUgogKiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKCgovKio9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgCiAgXGZpbGUgIHdsYW5fcWN0X3BhbF9wYWNrZXQuYwogIAogIFxicmllZiBJbXBsZW1lbnRhdGlvbiBmb3IgUEFMIHBhY2tldC4gd3B0ID0gKFdsYW4gUGFsIFR5cGUpIHdwYWwgPSAoV2xhbiBQQUwpCiAgICAgICAgICAgICAgIAogICBEZWZpbml0aW9ucyBmb3IgcGxhdGZvcm0gd2l0aCBWT1NTIHBhY2tldCBzdXBwb3J0IGFuZCBMQS4KICAKICAgQ29weXJpZ2h0IDIwMTAgKGMpIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQuICBBbGwgUmlnaHRzIFJlc2VydmVkLgogICAKICAgUXVhbGNvbW0gQ29uZmlkZW50aWFsIGFuZCBQcm9wcmlldGFyeS4KICAKICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF9wYWNrZXQuaCIKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF9hcGkuaCIKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF90cmFjZS5oIgojaW5jbHVkZSAidm9zX3BhY2tldC5oIgojaW5jbHVkZSAidm9zX3RyYWNlLmgiCiNpbmNsdWRlICJ2b3NfbGlzdC5oIgoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSAiZG1hLW1hcHBpbmcuaCIKCi8qUGVyIHNwZWMgZGVmaW5pdGlvbiovCiNkZWZpbmUgV1BBTF9FVEhFUk5FVF9QQUtDRVRfSEVBREVSX1NJWkUgICAgIDE0CgovKlBlciBzcGVjIGRlZmluaXRpb24gLSBub3QgaW5jbHVkaW5nIFFPUyBmaWVsZCovCiNkZWZpbmUgV1BBTF84MDJfMTFfUEFDS0VUX0hFQURFUl9TSVpFICAgIDI0IAoKLypwIGlzIGEgcG9pbnRlciB0byB3cHRfcGFja2V0Ki8KI2RlZmluZSBXUEFMX1RPX1ZPU19QS1QocCkgKCh2b3NfcGt0X3QgKikocCkpCgoKdHlwZWRlZiBzdHJ1Y3QKewogIHZvaWQqICAgICAgcFBoeUFkZHI7CiAgd3B0X3VpbnQzMiB1TGVuOwp9d3B0X2l0ZXJhdG9yX2luZm87CgovKiBTdG9yYWdlIGZvciBEWEUgQ0IgZnVuY3Rpb24gcG9pbnRlciAqLwpzdGF0aWMgd3BhbFBhY2tldExvd1BhY2tldENCIHdwYWxQYWNrZXRBdmFpbGFibGVDQjsKCi8qCiAgIHdwYWxQYWNrZXRJbml0IGlzIG5vLW9wIGZvciBWT1NTLXN1cHBvcnQgd3B0X3BhY2tldAoqLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRJbml0KHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCgovKgogICB3cGFsUGFja2V0Q2xvc2UgaXMgbm8tb3AgZm9yIFZPU1Mtc3VwcG9ydCB3cHRfcGFja2V0CiovCndwdF9zdGF0dXMgd3BhbFBhY2tldENsb3NlKHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCIJYgUlggUkFXIHBhY2tlciBDQiBmdW5jdGlvbgogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBBdmFpbGFibGUgUlggcGFja2V0CiAgICAgICAgdXNlckRhdGEgLSBQQUwgQ2xpZW50IENvbnRleHQsIERYRQogICAgUmV0dXJuOgogICAgICAgIFN0YXR1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIHdwYWxQYWNrZXRSWExvd1Jlc291cmNlQ0Iodm9zX3BrdF90ICpwUGFja2V0LCB2X1ZPSURfdCAqdXNlckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB2b2lkKiAgICAgICAgcERhdGEgICAgID0gTlVMTDsKCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAiR2V0IG5ldyBSWCBQQUwgcGFja2V0IGZhaWwiKTsKICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB9CiAgIHZvc1N0YXR1cyA9IHZvc19wa3RfcmVzZXJ2ZV9oZWFkX2Zhc3QoIHBQYWNrZXQsICZwRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVlBLVF9TSVpFX0JVRkZFUiApOwogICBpZihWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIlByZXBhcmUgUlggcGFja2V0IGZvciBEWEUgZmFpbCIpOwogICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgIH0KCiAgIGlmKChOVUxMID09IHdwYWxQYWNrZXRBdmFpbGFibGVDQikgfHwgKE5VTEwgPT0gdXNlckRhdGEpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIkludmFsaWQgQVJHIGZvciBuZXcgUlggcGFja2V0Iik7CiAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgfQoKICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCKCAod3B0X3BhY2tldCAqKXBQYWNrZXQsIHVzZXJEYXRhICk7CiAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0QWxsb2MgliBBbGxvY2F0ZSBhIHdwdF9wYWNrZXQgZnJvbSBQQUwuCiAgICBQYXJhbTogCiAgICAgICAgcGt0VHlwZSCWIHNwZWNpZnkgdGhlIHR5cGUgb2Ygd3B0X3BhY2tldCB0byBhbGxvY2F0ZQogICAgICAgIG5Qa3RTaXplIC0gcGFja2V0IHNpemUKICAgIFJldHVybjoKICAgICAgICBBIHBvaW50ZXIgdG8gdGhlIHdwdF9wYWNrZXQuIE5VTEwgbWVhbnMgZmFpbC4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3BhY2tldCAqIHdwYWxQYWNrZXRBbGxvYyh3cHRfcGFja2V0X3R5cGUgcGt0VHlwZSwgd3B0X3VpbnQzMiBuUGt0U2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cGFsUGFja2V0TG93UGFja2V0Q0IgcnhMb3dDQiwgdm9pZCAqdXNyRGF0YSkKewogICBWT1NfU1RBVFVTICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgIHdwdF9wYWNrZXQqICBwUGt0ICAgICAgPSBOVUxMOwogICB2b3NfcGt0X3QqICAgcFZvc1BrdCAgID0gTlVMTDsKICAgdm9pZCogICAgICAgIHBEYXRhICAgICA9IE5VTEw7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICAvKiBJbml0aWFsaXplIERYRSBDQiBmdW5jdGlvbiBwb2ludGVyIHN0b3JhZ2UgKi8KICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCID0gTlVMTDsKICAgc3dpdGNoIChwa3RUeXBlKQogICB7CiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UOgogICAgICB2b3NTdGF0dXMgPSB2b3NfcGt0X2dldF9wYWNrZXQoJnBWb3NQa3QsIFZPU19QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblBrdFNpemUsIDEsIFZPU19GQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwgLypubyBjYWxsYmFjayovKTsKICAgICAgYnJlYWs7CgogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVc6CiAgICAgIHZvc1N0YXR1cyA9IHZvc19wa3RfZ2V0X3BhY2tldCgmcFZvc1BrdCwgVk9TX1BLVF9UWVBFX1JYX1JBVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblBrdFNpemUsIDEsIFZPU19GQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdwYWxQYWNrZXRSWExvd1Jlc291cmNlQ0IsIHVzckRhdGEpOwoKI2lmbmRlZiBGRUFUVVJFX1IzM0QKICAgICAgLyogUmVzZXJ2ZSB0aGUgZW50aXJlIHJhdyByeCBidWZmZXIgZm9yIERYRSAqLwogICAgICBpZiggdm9zU3RhdHVzID09IFZPU19TVEFUVVNfU1VDQ0VTUyApCiAgICAgIHsKICAgICAgICB2b3NTdGF0dXMgPSAgdm9zX3BrdF9yZXNlcnZlX2hlYWRfZmFzdCggcFZvc1BrdCwgJnBEYXRhLCBuUGt0U2l6ZSApOyAKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICB3cGFsUGFja2V0QXZhaWxhYmxlQ0IgPSByeExvd0NCOwogICAgICB9CiNlbmRpZiAvKiBGRUFUVVJFX1IzM0QgKi8KICAgICAgYnJlYWs7CgogICBkZWZhdWx0OgogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICIgdHJ5IHRvIGFsbG9jYXRlIHVuc3VwcG9ydGVkIHBhY2tldCB0eXBlICglZClcbiIsIHBrdFR5cGUpOwogICAgICBicmVhazsKICAgfQoKICAgaWYoVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgIHsKICAgICAgcFBrdCA9ICh3cHRfcGFja2V0ICopcFZvc1BrdDsKICAgfQoKCiAgIHJldHVybiBwUGt0Owp9Lyp3cGFsUGFja2V0QWxsb2MqLwoKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEZyZWUgliBGcmVlIGEgd3B0X3BhY2tldCBjaGFpbiBmb3Igb25lIHBhcnRpY3VsYXIgdHlwZS4KICAgIEZvciBvdXIgbGVnYWN5IFVNQUMsIGl0IGlzIG5vdCBuZWVkZWQgYmVjYXVzZSB2b3NfcGFja2V0IGNvbnRhaW5zIHBhbF9wYWNrZXQuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRGcmVlKHdwdF9wYWNrZXQgKnBQa3QpCnsKICAgVk9TX1NUQVRVUyB2b3NTdGF0dXM7CgogICBpZihOVUxMICE9IHBQa3QtPnBJbnRlcm5hbERhdGEpCiAgIHsKICAgICAgd3BhbE1lbW9yeUZyZWUocFBrdC0+cEludGVybmFsRGF0YSk7CiAgIH0KICAgdm9zU3RhdHVzID0gdm9zX3BrdF9yZXR1cm5fcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGt0KSk7CgogICAvL1dpdGggVk9TUyBzdXBwb3J0LCB3ZSBjYW4gY2FzdCBiZXR3ZWVuIHdwdF9zdGF0dXMgYW5kIFZPU19TVEFUVVMKICAgcmV0dXJuICh3cHRfc3RhdHVzKXZvc1N0YXR1czsKfS8qd3BhbFBhY2tldEZyZWUqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0R2V0TGVuZ3RoIJYgR2V0IG51bWJlciBvZiBieXRlcyBpbiBhIHdwdF9wYWNrZXQuIEl0IGluY2x1ZGUgdGhlIAogICAgYnl0ZXMgaW4gYSBCRCBpZiBpdCBleGlzdC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHBhY2tldCB0byBiZSBmcmVlZC4KICAgIFJldHVybjoKICAgICAgICBMZW5ndGggb2YgdGhlIGRhdGEgaW5jbHVkZSBsYXllci0yIGhlYWRlcnMuIEZvciBleGFtcGxlLCBpZiB0aGUgZnJhbWUKICAgICAgICBpcyA4MDIuMywgdGhlIGxlbmd0aCBpbmNsdWRlcyB0aGUgZXRoZXJuZXQgaGVhZGVyLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfdWludDMyIHdwYWxQYWNrZXRHZXRMZW5ndGgod3B0X3BhY2tldCAqcFBrdCkKewogICB2X1UxNl90IGxlbiA9IDAsIHBrdExlbiA9IDA7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKCiAgIGlmKCBXUEFMX1BBQ0tFVF9HRVRfQkRfUE9JTlRFUihwUGt0KSApCiAgIHsKICAgICAgbGVuID0gV1BBTF9QQUNLRVRfR0VUX0JEX0xFTkdUSChwUGt0KTsKICAgfQogICBpZiggVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfZ2V0X3BhY2tldF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAmcGt0TGVuKSkgKQogICB7CiAgICAgIGxlbiArPSBwa3RMZW47CiAgIH0KICAgZWxzZQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIGZhaWxlZFxuIiwKICAgICAgICAgX19mdW5jX18pOwogICB9CgogICByZXR1cm4gKCh3cHRfdWludDMyKWxlbik7Cn0vKndwYWxQYWNrZXRHZXRMZW5ndGgqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UmF3VHJpbUhlYWQgliBNb3ZlIHRoZSBzdGFydGluZyBvZmZzZXQgYW5kIHJldHVybiB0aGUgaGVhZCBwb2ludGVyCiAgICAgICAgICBiZWZvcmUgdGhlIG1vdmluZy4gVGhlIGZ1bmN0aW9uIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCByYXcgcGFja2V0cywKICAgICAgICAgIHdob3NlIGJ1ZmZlciBpcyBvbmUgcGllY2UgYW5kIGFsbG9jYXRlZCBieSBXTEFOIGRyaXZlci4gVGhpcyBhbHNvCiAgICAgICAgICByZWR1Y2UgdGhlIGxlbmd0aCBvZiB0aGUgcGFja2V0LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgd3B0X3BhY2tldC4KICAgICAgICBzaXplIJYgbnVtYmVyIG9mIGJ5dGVzIHRvIHRha2Ugb2ZmIHRoZSBoZWFkLgogICAgUmV0dXJuOgogICAgICAgIEEgcG9pbnRlciB0byB0aGUgb3JpZ2luYWwgYnVmZmVyIGhlYWQgYmVmb3JlIHRoZSB0cmltbWluZy4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsUGFja2V0UmF3VHJpbUhlYWQod3B0X3BhY2tldCAqcFBrdCwgd3B0X3VpbnQzMiBzaXplKQp7CiAgIHdwdF9zdGF0dXMgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGt0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgcGFja2V0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIFZPU19BU1NFUlQoIChlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAgICAgICAgIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSApOwoKICAgaWYoICFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zX3BrdF90cmltX2hlYWQoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAodl9TSVpFX3Qpc2l6ZSkpICkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgIiVzICBJbnZhbGlkIHRyaW0oJWQpXG4iLAogICAgICAgICBfX2Z1bmNfXywgc2l6ZSk7CiAgICAgIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcmV0dXJuIHN0YXR1czsKfS8qd3BhbFBhY2tldFJhd1RyaW1IZWFkKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UmF3VHJpbVRhaWwgliByZWR1Y2UgdGhlIGxlbmd0aCBvZiB0aGUgcGFja2V0LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgd3B0X3BhY2tldC4KICAgICAgICBzaXplIJYgbnVtYmVyIG9mIGJ5dGVzIHRvIHRha2Ugb2YgdGhlIHBhY2tldCBsZW5ndGgKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgliBzdWNjZXNzLiBPdGhlcndpc2UgZmFpbC4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsUGFja2V0UmF3VHJpbVRhaWwod3B0X3BhY2tldCAqcFBrdCwgd3B0X3VpbnQzMiBzaXplKQp7CiAgIHdwdF9zdGF0dXMgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGt0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgcGFja2V0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIFZPU19BU1NFUlQoIChlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAgICAgICAgIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSApOwogICBpZiggIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NfcGt0X3RyaW1fdGFpbChXUEFMX1RPX1ZPU19QS1QocFBrdCksICh2X1NJWkVfdClzaXplKSkgKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIEludmFsaWQgdHJpbSglZClcbiIsCiAgICAgICAgIF9fZnVuY19fLCBzaXplKTsKICAgICAgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICByZXR1cm4gc3RhdHVzOwp9Lyp3cGFsUGFja2V0UmF3VHJpbVRhaWwqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0R2V0UmF3QnVmIJYgUmV0dXJuIHRoZSBzdGFydGluZyBidWZmZXIgdmlydHVhbCBhZGRyZXNzIGZvciB0aGUgUkFXIGZsYXQgYnVmZmVyCiAgICBJdCBpcyBpbmxpbmUgaW4gaG9wZSBvZiBmYXN0ZXIgaW1wbGVtZW50YXRpb24gZm9yIGNlcnRhaW4gcGxhdGZvcm0uIEZvciBXaW54cCwgaXQgCiAgICB3aWxsIGJlIHNsb3cuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgUmV0dXJuOgogICAgICAgIE5VTEwgLSBmYWlsLgogICAgICAgIE90aGVyd2lzZSB0aGUgYWRkcmVzcyBvZiB0aGUgc3RhcnRpbmcgb2YgdGhlIGJ1ZmZlcgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfdWludDggKndwYWxQYWNrZXRHZXRSYXdCdWYod3B0X3BhY2tldCAqcFBrdCkKewogICB3cHRfdWludDggKnBSZXQgPSBOVUxMOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGt0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgcGFja2V0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBOVUxMOwogICB9CgogICAvL1NpbmNlIGl0IGlzIGEgZmxhdCBidWZmZXIsIGFsbCB3ZSBuZWVkIGlzIHRvIGdldCBvbmUgYnl0ZSBvZiBvZmZzZXQgMAogICBpZiggKGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVcgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAoZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSApCiAgIHsKICAgICAgdm9zX3BrdF9wZWVrX2RhdGEoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAwLCAodl9WT0lEX3QqKikmcFJldCwgMSk7CiAgICAgIFdQQUxfQVNTRVJUKE5VTEwgIT0gcFJldCk7CiAgIH0gICAgICAgICAgICAKCiAgIHJldHVybiBwUmV0Owp9Lyp3cGFsUGFja2V0R2V0UmF3QnVmKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldFNldFJ4TGVuZ3RoIJYgU2V0IHRoZSB2YWxpZCBkYXRhIGxlbmd0aCBvbiBhIFJYIHBhY2tldC4gVGhpcyBmdW5jdGlvbiBtdXN0IAogICAgYmUgY2FsbGVkIG9uY2UgcGVyIFJYIHBhY2tldCBwZXIgcmVjZWl2aW5nLiBJdCBpbmRpY2F0ZXMgdGhlIGF2YWlsYWJsZSBkYXRhIGxlbmd0aCBmcm9tCiAgICB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlci4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHdwdF9wYWNrZXQuCiAgICBSZXR1cm46CiAgICAgICAgTlVMTCAtIGZhaWwuCiAgICAgICAgT3RoZXJ3aXNlIHRoZSBhZGRyZXNzIG9mIHRoZSBzdGFydGluZyBvZiB0aGUgYnVmZmVyCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldFNldFJ4TGVuZ3RoKHdwdF9wYWNrZXQgKnBQa3QsIHdwdF91aW50MzIgbGVuKQp7CiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICAvKk9ubHkgYWxsb3dlZCBmb3IgUlggUmF3IHBhY2tldHMgKi8KICAgaWYoIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXICE9IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSkKICAgewogICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICIlcyAgSW52YWxpZCBwYWNrZXQgdHlwZSglZClcbiIsICBfX2Z1bmNfXywgCiAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSk7CiAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgaWYoVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3Rfc2V0X3J4X2xlbmd0aChXUEFMX1RPX1ZPU19QS1QocFBrdCksIGxlbikpKQogICB7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIH0KICAgZWxzZQogICB7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KfS8qd3BhbFBhY2tldFNldFJ4TGVuZ3RoKi8KCi8qCiAgU2V0IG9mIGhlbHBlciBmdW5jdGlvbnMgdGhhdCB3aWxsIHByZXBhcmUgcGFja2V0IGZvciBETUEgdHJhbnNmZXIsCiAgYmFzZWQgb24gdGhlIHR5cGUgb2YgdHJhbnNmZXIgOiAtIHRvIGFuZCBmcm9tIHRoZSBkZXZpY2UKICAtIGZvbGxvd2luZyB0aGVzZSBjYWxscyB0aGUgcGFja2V0IHdpbGwgYmUgbG9ja2VkIGZvciBETUEgb25seSwKICBDUFUgd2lsbCBub3QgYmUgYWJsZSB0byBtb2RpZnkgaXQgPT4gdGhlIHBhY2tldCBtdXN0IGJlIGV4cGxpY2l0bHkgcmV0dXJuZWQgdG8KICB0aGUgQ1BVIG9uY2UgdGhlIERNQSB0cmFuc2ZlciBpcyBjb21wbGV0ZQoqLwpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCogaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHdwdF9wYWNrZXQgKnBQYWNrZXQgKQp7CiAgIHN0cnVjdCBza19idWZmICpza2I7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gKi8KICAgaWYgKCBWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gCiAgICAgICAgdm9zX3BrdF9nZXRfb3NfcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGFja2V0KSwgKHZvaWQqKikmc2tiLCBWT1NfRkFMU0UgKSkKICAgewogICAgIHJldHVybiBOVUxMOwogICB9CiAgIGVsc2UKICAgewogICAgIC8qTWFwIHNrYiBkYXRhIGludG8gZG1hLWFibGUgbWVtb3J5IAogICAgICAgKGNoYW5nZXMgd2lsbCBiZSBjb21taXRlZCBmcm9tIGNhY2hlKSAqLwogICAgIHJldHVybiAodm9pZCopZG1hX21hcF9zaW5nbGUoIE5VTEwsIHNrYi0+ZGF0YSwgc2tiLT5sZW4sIERNQV9UT19ERVZJQ0UgKTsKICAgfQp9LyppdEdldE9TUGt0QWRkckZvckRldmljZSovCgpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCogaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKCB3cHRfcGFja2V0ICpwUGFja2V0ICkKewoKICAgc3RydWN0IHNrX2J1ZmYgKnNrYjsKICAgLyotIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAqLwogICBpZiAoIFZPU19TVEFUVVNfU1VDQ0VTUyAhPSAKICAgICAgICB2b3NfcGt0X2dldF9vc19wYWNrZXQoV1BBTF9UT19WT1NfUEtUKHBQYWNrZXQpLCAodm9pZCoqKSZza2IsIFZPU19GQUxTRSApKQogICB7CiAgICAgcmV0dXJuIE5VTEw7CiAgIH0KICAgZWxzZQogICB7CiAgICAgLypNYXAgc2tiIGRhdGEgaW50byBkbWEtYWJsZSBtZW1vcnkgCiAgICAgICAoY2hhbmdlcyB3aWxsIGJlIGNvbW1pdGVkIGZyb20gY2FjaGUpICovCiAgICAgcmV0dXJuICh2b2lkKilkbWFfbWFwX3NpbmdsZSggTlVMTCwgc2tiLT5kYXRhLCBza2ItPmxlbiwgRE1BX0ZST01fREVWSUNFICk7CiAgIH0KfS8qaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKi8KCi8qCiAgU2V0IG9mIGhlbHBlciBmdW5jdGlvbnMgdGhhdCB3aWxsIHJldHVybiBhIERNQS1lZCBwYWNrZXQgdG8gdGhlIENQVSwKICBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0cmFuc2ZlciA6IC0gdG8gYW5kIGZyb20gdGhlIGRldmljZQoqLwpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCBpdFJldHVybk9TUGt0QWRkckZvckRldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCwgIHZvaWQqIGFkZHIsIHdwdF91aW50MzIgc2l6ZSApCnsKIAogICBkbWFfdW5tYXBfc2luZ2xlKCBOVUxMLCAoZG1hX2FkZHJfdClhZGRyLCBzaXplLCBETUFfVE9fREVWSUNFICk7Cn0KCldQVF9TVEFUSUMgV1BUX0lOTElORSB2b2lkIGl0UmV0dXJuT1NQa3RBZGRyRnJvbURldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCwgdm9pZCogYWRkciwgd3B0X3VpbnQzMiBzaXplICApCnsKCiAgIGRtYV91bm1hcF9zaW5nbGUoIE5VTEwsIChkbWFfYWRkcl90KWFkZHIsIHNpemUsIERNQV9GUk9NX0RFVklDRSApOyAKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsSXRlcmF0b3JJbml0IJYgSW5pdGlhbGl6ZSBhbiBpbnRlcmF0b3IgYnkgdXBkYXRpbmcgcEN1ciB0byBmaXJzdCBpdGVtLgogICAgUGFyYW06IAogICAgICAgIHBJdGVyIJYgcG9pbnRlciB0byBhIGNhbGxlciBhbGxvY2F0ZWQgd3B0X2l0ZXJhdG9yCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxJdGVyYXRvckluaXQod3B0X2l0ZXJhdG9yICpwSXRlciwgd3B0X3BhY2tldCAqcFBhY2tldCkKewogICB3cHRfc3RhdHVzICAgICAgICAgc3RhdHVzICAgICA9IGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBDdXJJbmZvICAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcE5leHRJbmZvICA9IE5VTEw7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwUGt0SW5mbyAgID0gTlVMTDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KChOVUxMID09IHBQYWNrZXQpfHwoTlVMTD09cEl0ZXIpKSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlcnMgJXggJXgiLCBfX2Z1bmNfXywgcFBhY2tldCwgcEl0ZXIpOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwUGt0SW5mbyA9ICh3cHRfaXRlcmF0b3JfaW5mbyopcFBhY2tldC0+cEludGVybmFsRGF0YTsKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogSW52YWxpZCBQYWNrZXQgSW5mbyIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgLy8gaWYgdGhlcmUgaXMgTk8gQkQgb24gdGhpcyBmcmFtZSwgdGhlbiBpbml0aWFsaXplIHRoZSBuZXh0IHBvaW50ZXIgdG8KICAgLy8gcG9pbnQgdGhlIGZpcnN0IGZyYWdtZW50LgogICBpZiAoIE5VTEwgPT0gV1BBTF9QQUNLRVRfR0VUX0JEX1BIWVMocFBhY2tldCkgKQogICB7CiAgICAgcEN1ckluZm8gICA9IHBQa3RJbmZvOwogICAgIHBOZXh0SW5mbyAgICAgICAgICAgPSBOVUxMOwogICB9CiAgIGVsc2UKICAgewogICAgIC8qQWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgY3VycmVudCBpbmZvKi8KICAgICBwQ3VySW5mbyA9IHdwYWxNZW1vcnlBbGxvY2F0ZSggc2l6ZW9mKHdwdF9pdGVyYXRvcl9pbmZvKSApOwoKICAgICAvLyBWYWxpZGF0ZSB0aGUgbWVtb3J5IGFsbG9jYXRpb24KICAgICBpZiAodW5saWtlbHkoTlVMTCA9PSBwQ3VySW5mbykpCiAgICAgewogICAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgICAiJXMgOiBGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5ICIsIF9fZnVuY19fKTsKICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICAgIH0KCiAgICAgcEN1ckluZm8tPnBQaHlBZGRyID0gV1BBTF9QQUNLRVRfR0VUX0JEX1BIWVMocFBhY2tldCk7CiAgICAgcEN1ckluZm8tPnVMZW4gICAgID0gV1BBTF9QQUNLRVRfR0VUX0JEX0xFTkdUSChwUGFja2V0KTsKCiAgICAgcE5leHRJbmZvICAgICAgICAgICA9IHBQa3RJbmZvOwogICB9ICAgICAgCgogICBwSXRlci0+cEN1ciAgICAgPSAodm9pZCopcEN1ckluZm87IAogICBwSXRlci0+cE5leHQgICAgPSAodm9pZCopcE5leHRJbmZvOwogICBwSXRlci0+cENvbnRleHQgPSBOVUxMOwoKICAgcmV0dXJuIHN0YXR1czsKfS8qd3BhbEl0ZXJhdG9ySW5pdCovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbEl0ZXJhdG9yTmV4dCCWIEdldCB0aGUgYWRkcmVzcyBmb3IgdGhlIG5leHQgaXRlbQogICAgUGFyYW06IAogICAgICAgIHBJdGVyIJYgcG9pbnRlciB0byBhIGNhbGxlciBhbGxvY2F0ZWQgd3B0X2l0ZXJhdG9yCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICAgICAgcHBBZGRyIJYgQ2FsbGVyIGFsbG9jYXRlZCBwb2ludGVyIHRvIHJldHVybiB0aGUgYWRkcmVzcyBvZiB0aGUgaXRlbS4KICAgICAgICBGb3IgRE1BLWFibGUgZGV2aWNlcywgdGhpcyBpcyB0aGUgcGh5c2ljYWwgYWRkcmVzcyBvZiB0aGUgaXRlbS4KICAgICAgICBwTGVuIJYgVG8gcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGl0ZW0uCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxJdGVyYXRvck5leHQod3B0X2l0ZXJhdG9yICpwSXRlciwgd3B0X3BhY2tldCAqcFBhY2tldCwgdm9pZCAqKnBwQWRkciwgd3B0X3VpbnQzMiAqcExlbikKewogICB3cHRfaXRlcmF0b3JfaW5mbyogcEN1ckluZm8gID0gTlVMTDsKICAgLyotIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSovCiAgIAogICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBTYW5pdHkgY2hlY2sKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgIGlmICh1bmxpa2VseSgoIE5VTEwgPT0gcEl0ZXIgKXx8KCBOVUxMID09IHBQYWNrZXQgKSB8fCAKICAgICAgKCBOVUxMID09IHBwQWRkciApIHx8ICggTlVMTCA9PSBwTGVuICkpKQogICB7CiAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgIiVzICBJbnZhbGlkIGlucHV0IHBhcmFtZXRlcnMgXG4iLCAgX19mdW5jX18gKTsKICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwQ3VySW5mbyA9ICh3cHRfaXRlcmF0b3JfaW5mbyopcEl0ZXItPnBDdXI7IAogICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBJZiBjdXJyZW50IHBvaW50ZXIgaXMgTlVMTCAtIHRoZXJlIGlzIG5vIGRhdGEgaW4gdGhlIHBhY2tldCAtIHJldHVybgogICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KICAgaWYoIHBJdGVyLT5wQ3VyID09IE5VTEwgKQogICB7CiAgICAgICpwcEFkZHIgPSBOVUxMOyAKICAgICAgKnBMZW4gICA9IDA7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIH0KCiAgIC8qQWRkcmVzcyBhbmQgbGVuZ3RoIGFyZSBrZXB0IGluIHRoZSBjdXJyZW50IGZpZWxkKi8KICAgKnBwQWRkciA9IHBDdXJJbmZvLT5wUGh5QWRkcjsgCiAgICpwTGVuICAgPSBwQ3VySW5mby0+dUxlbjsKICAgIAogICBpZiggTlVMTCA9PSBwSXRlci0+cE5leHQgKQogICB7CiAgICAgLypTYXZlIHRoZSBpdGVyYXRvciBmb3IgY2xlYW51cCovCiAgICAgcFBhY2tldC0+cEludGVybmFsRGF0YSA9IHBJdGVyLT5wQ3VyOyAKICAgICBwSXRlci0+cEN1ciAgICAgICAgICAgID0gTlVMTDsgCiAgIH0KICAgZWxzZQogICB7CiAgICAgLypSZWxlYXNlIHRoZSBtZW1vcnkgc2F2ZWQgZm9yIHN0b3JpbmcgdGhlIEJEIGluZm9ybWF0aW9uKi8KICAgICB3cGFsTWVtb3J5RnJlZShwQ3VySW5mbyk7IAogIAogICAgIC8qRm9yIExBIC0gdGhlIHBhY2tldCBpcyByZXByZXNlbnRlZCBieSBtYXhpbXVtIDIgZmllbGRzIG9mIGRhdGEgCiAgICAgICAtIEJEIGFuZCBhY3R1YWwgZGF0YSBmcm9tIHNrIGJ1ZmYgKi8KICAgICBwSXRlci0+cEN1ciAgICAgPSBwSXRlci0+cE5leHQ7CiAgICAgcEl0ZXItPnBOZXh0ICAgID0gTlVMTDsKICAgfQogICAKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIgliBNYXAgdGhlIGRhdGEgYnVmZmVyIGZyb20gZG1hIHNvIHRoYXQgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhIGlzIGNvbW1pdGVkIGZyb20gY2FjaGUgYW5kIHRoZSBjcHUgcmVsaW5xdWlzaGVzCiAgICAgICAgICAgICAgICAgICAgICAgICBvd25lcnNoaXAgb2YgdGhlIGJ1ZmZlcgogCiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgLSBzdWNjZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbExvY2tQYWNrZXRGb3JUcmFuc2Zlciggd3B0X3BhY2tldCAqcFBhY2tldCkKewogICB2b2lkKiAgICAgICAgICAgICAgcFBoeURhdGEgICA9IE5VTEw7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwSW5mbyAgICAgID0gTlVMTDsKICAgdl9VMTZfdCAgICAgICAgICAgIHVMZW5EYXRhICAgPSAwOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGFja2V0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgc3dpdGNoKFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQYWNrZXQpKQogICB7CiAgICAgIC8qIEZvciBtYW5hZ2VtZW50IGZyYW1lcywgQkQgaXMgYWxsb2NhdGVkIGJ5IFdESSwgaGVhZGVyIGlzIGluIHJhdyBidWZmZXIsCiAgICAgICAgIHJlc3Qgb2YgdGhlIGZyYW1lIGlzIGFsc28gaW4gcmF3IGJ1ZmZlciAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVDoKICAgICAgewogICAgICAgICAvKlRYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgdG8gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBwUGh5RGF0YSA9ICh2b2lkKilpdEdldE9TUGt0QWRkckZvckRldmljZSggcFBhY2tldCApOyAgIAogICAgICB9CiAgICAgIGJyZWFrOwogICAgICAgICAvKiBEYXRhIHBhY2tldHMgLSBCRCAoYWxsb2NhdGVkIGJ5IFdESSksIGhlYWRlciAoaW4gVk9TUyBoZWFkZXIpLAogICAgICAgICAgICByZXN0IG9mIHRoZSBwYWNrZXQgKERTTSBpdGVtcykgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX0RBVEE6CiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8zX0RBVEE6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHBQYWNrZXQgKTsKICAgICAgfQogICAgICBicmVhazsKCiAgICAgIC8qIEZvciBSYXcgUlgsIEJEICsgaGVhZGVyICsgcmVzdCBvZiB0aGUgcGFja2V0IGlzIGFsbCBjb250YWluZWQgaW4gdGhlIHJhdwogICAgICAgICBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXOgogICAgICB7CiAgICAgICAgIC8qUlggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCBmcm9tIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKCBwUGFja2V0ICk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICBkZWZhdWx0OgogICAgICB7CiAgICAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgICAiIFdMQU5fUEFMOiAlczogSW52YWxpZCBwYWNrZXQgdHlwZSAlZCEiLCAgX19mdW5jX18sIAogICAgICAgICAgICAgICAgICAgIFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQYWNrZXQpICk7IAogICAgICAgICBXUEFMX0FTU0VSVCgwKTsgCiAgICAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgfQogICB9CgogICAvKkdldCBwYWNrZXQgbGVuZ3RoKi8KICAgdm9zX3BrdF9nZXRfcGFja2V0X2xlbmd0aChXUEFMX1RPX1ZPU19QS1QocFBhY2tldCksJnVMZW5EYXRhKTsKCiAgICAvKkFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGN1cnJlbnQgaW5mbyovCiAgIHBJbmZvID0gd3BhbE1lbW9yeUFsbG9jYXRlKCBzaXplb2Yod3B0X2l0ZXJhdG9yX2luZm8pICk7CgogICAvLyBWYWxpZGF0ZSB0aGUgbWVtb3J5IGFsbG9jYXRpb24KICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSAiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHBJbmZvLT5wUGh5QWRkciA9IHBQaHlEYXRhOwogICBwSW5mby0+dUxlbiAgICAgPSB1TGVuRGF0YTsKCiAgIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBwSW5mbzsKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbExvY2tQYWNrZXRGb3JUcmFuc2ZlciovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFVubG9ja1BhY2tldCCWIFVubWFwIHRoZSBkYXRhIGJ1ZmZlciBmcm9tIGRtYSBzbyB0aGF0IGNwdSBjYW4gcmVnYWluCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJzaGlwIG9uIGl0CiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgLSBzdWNjZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFVubG9ja1BhY2tldCggd3B0X3BhY2tldCAqcFBhY2tldCkKewoKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBJbmZvOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGFja2V0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlciBwUGFja2V0IiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwSW5mbyAgPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBQYWNrZXQtPnBJbnRlcm5hbERhdGE7CgogICAvLyBWYWxpZGF0ZSBwSW5mbwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwSW5mbykpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRkFUQUwsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIgcEluZm8iLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHN3aXRjaChXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSkKICAgewogICAgICAvKiBGb3IgbWFuYWdlbWVudCBmcmFtZXMsIEJEIGlzIGFsbG9jYXRlZCBieSBXREksIGhlYWRlciBpcyBpbiByYXcgYnVmZmVyLAogICAgICAgICByZXN0IG9mIHRoZSBmcmFtZSBpcyBhbHNvIGluIHJhdyBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICBpdFJldHVybk9TUGt0QWRkckZvckRldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgfQogICAgICBicmVhazsKICAgICAgICAgLyogRGF0YSBwYWNrZXRzIC0gQkQgKGFsbG9jYXRlZCBieSBXREkpLCBoZWFkZXIgKGluIFZPU1MgaGVhZGVyKSwKICAgICAgICAgICAgcmVzdCBvZiB0aGUgcGFja2V0IChEU00gaXRlbXMpICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9EQVRBOgogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfM19EQVRBOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIGl0UmV0dXJuT1NQa3RBZGRyRm9yRGV2aWNlKHBQYWNrZXQsIHBJbmZvLT5wUGh5QWRkciwgcEluZm8tPnVMZW4pOyAgIAogICAgICB9CiAgICAgIGJyZWFrOwoKICAgICAgLyogRm9yIFJhdyBSWCwgQkQgKyBoZWFkZXIgKyByZXN0IG9mIHRoZSBwYWNrZXQgaXMgYWxsIGNvbnRhaW5lZCBpbiB0aGUgcmF3CiAgICAgICAgIGJ1ZmZlciAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVc6CiAgICAgIHsKICAgICAgICAgLypSWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIGZyb20gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBpZihOVUxMID09IHBJbmZvLT5wUGh5QWRkcikKICAgICAgICAgewogICAgICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IFJYIGZyYW1lIHdhcyBub3QgbG9ja2VkIHByb3Blcmx5IiwgIF9fZnVuY19fKTsgCiAgICAgICAgIH0KICAgICAgICAgZWxzZQogICAgICAgICB7CiAgICAgICAgICAgIGl0UmV0dXJuT1NQa3RBZGRyRnJvbURldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgewogICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IEludmFsaWQgcGFja2V0IHR5cGUgJWQhIiwgIF9fZnVuY19fLCAKICAgICAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSApOyAKICAgICAgICAgV1BBTF9BU1NFUlQoMCk7IAogICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgIH0KICAgfQoKICB3cGFsTWVtb3J5RnJlZShwSW5mbyk7CiAgcFBhY2tldC0+cEludGVybmFsRGF0YSA9IE5VTEw7CiAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbFVubG9ja1BhY2tldCovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbElzUGFja2V0TG9ja2VkIJYgIENoZWNrIHdoZXRoZXIgdGhlIFBhY2tldCBpcyBsb2NrZWQgZm9yIERNQS4KICAgIFBhcmFtOiAKICAgICAgICBwUGFja2V0IJYgcG9pbnRlciB0byBhIHdwdF9wYWNrZXQKIAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUwogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfRV9GQUlMVVJFCiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbElzUGFja2V0TG9ja2VkKCB3cHRfcGFja2V0ICpwUGFja2V0KQp7CgogICB3cHRfaXRlcmF0b3JfaW5mbyogcEluZm87CgogICAvKiBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzICovCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIC8qIFZhbGlkYXRlIHBJbnRlcm5hbERhdGEgKi8KICAgcEluZm8gID0gKHdwdF9pdGVyYXRvcl9pbmZvKilwUGFja2V0LT5wSW50ZXJuYWxEYXRhOwogICByZXR1cm4gKE5VTEwgPT0gcEluZm8pPyBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRSA6IAogICAgICAgICAgICAgICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbElzUGFja2V0TG9ja2VkKi8KCg==