LyoKICogQ29weXJpZ2h0IChjKSAyMDE0LTIwMTUsIDIwMTcgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIAogIFxmaWxlICB3bGFuX3FjdF9wYWxfcGFja2V0LmMKICAKICBcYnJpZWYgSW1wbGVtZW50YXRpb24gZm9yIFBBTCBwYWNrZXQuIHdwdCA9IChXbGFuIFBhbCBUeXBlKSB3cGFsID0gKFdsYW4gUEFMKQogICAgICAgICAgICAgICAKICAgRGVmaW5pdGlvbnMgZm9yIHBsYXRmb3JtIHdpdGggVk9TUyBwYWNrZXQgc3VwcG9ydCBhbmQgTEEuCiAgCiAgCiAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfcGFja2V0LmgiCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfYXBpLmgiCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfdHJhY2UuaCIKI2luY2x1ZGUgIndsYW5fcWN0X29zX3N0YXR1cy5oIgojaW5jbHVkZSAidm9zX3BhY2tldC5oIgojaW5jbHVkZSAidm9zX3RyYWNlLmgiCiNpbmNsdWRlICJ2b3NfbGlzdC5oIgojaW5jbHVkZSAidm9zX2FwaS5oIgoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSAiZG1hLW1hcHBpbmcuaCIKI2luY2x1ZGUgPGxpbnV4L3djbnNzX3dsYW4uaD4KCi8qUGVyIHNwZWMgZGVmaW5pdGlvbiovCiNkZWZpbmUgV1BBTF9FVEhFUk5FVF9QQUtDRVRfSEVBREVSX1NJWkUgICAgIDE0CgovKlBlciBzcGVjIGRlZmluaXRpb24gLSBub3QgaW5jbHVkaW5nIFFPUyBmaWVsZCovCiNkZWZpbmUgV1BBTF84MDJfMTFfUEFDS0VUX0hFQURFUl9TSVpFICAgIDI0IAoKLypwIGlzIGEgcG9pbnRlciB0byB3cHRfcGFja2V0Ki8KI2RlZmluZSBXUEFMX1RPX1ZPU19QS1QocCkgKCh2b3NfcGt0X3QgKikocCkpCgoKdHlwZWRlZiBzdHJ1Y3QKewogIHZvaWQqICAgICAgcFBoeUFkZHI7CiAgd3B0X3VpbnQzMiB1TGVuOwp9d3B0X2l0ZXJhdG9yX2luZm87CgovKiBTdG9yYWdlIGZvciBEWEUgQ0IgZnVuY3Rpb24gcG9pbnRlciAqLwpzdGF0aWMgd3BhbFBhY2tldExvd1BhY2tldENCIHdwYWxQYWNrZXRBdmFpbGFibGVDQjsKCi8qIFRlbXAgc3RvcmFnZSBmb3IgdHJhbnNwb3J0IGNoYW5uZWwgRElBRy9MT0cgaW5mb3JtYXRpb24KICogRWFjaCBjaGFubmVsIHdpbGwgdXBkYXRlIGluZm9ybWF0aW9uIHdpdGggZGlmZmVyZW50IGNvbnRleHQKICogQmVmb3JlIHNlbmQgc3RvcmVkIGRhdGUgdG8gRElBRywKICogdGVtcG9yYXJ5IGl0IHNob3VsZCBiZSBzdG9yZWQgKi8Kc3RhdGljIHdwdF9sb2dfZGF0YV9zdGFsbF90eXBlIHdwYWxUcmFzcG9ydFN0YWxsSW5mbzsKCi8qCiAgIHdwYWxQYWNrZXRJbml0IGlzIG5vLW9wIGZvciBWT1NTLXN1cHBvcnQgd3B0X3BhY2tldAoqLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRJbml0KHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCgovKgogICB3cGFsUGFja2V0Q2xvc2UgaXMgbm8tb3AgZm9yIFZPU1Mtc3VwcG9ydCB3cHRfcGFja2V0CiovCndwdF9zdGF0dXMgd3BhbFBhY2tldENsb3NlKHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCIJYgUlggUkFXIHBhY2tlciBDQiBmdW5jdGlvbgogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBBdmFpbGFibGUgUlggcGFja2V0CiAgICAgICAgdXNlckRhdGEgLSBQQUwgQ2xpZW50IENvbnRleHQsIERYRQogICAgUmV0dXJuOgogICAgICAgIFN0YXR1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIHdwYWxQYWNrZXRSWExvd1Jlc291cmNlQ0Iodm9zX3BrdF90ICpwUGFja2V0LCB2X1ZPSURfdCAqdXNlckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB2b2lkKiAgICAgICAgcERhdGEgICAgID0gTlVMTDsKCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAiR2V0IG5ldyBSWCBQQUwgcGFja2V0IGZhaWwiKTsKICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB9CiAgIHZvc1N0YXR1cyA9IHZvc19wa3RfcmVzZXJ2ZV9oZWFkX2Zhc3QoIHBQYWNrZXQsICZwRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVlBLVF9TSVpFX0JVRkZFUiApOwogICBpZihWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIlByZXBhcmUgUlggcGFja2V0IGZvciBEWEUgZmFpbCIpOwogICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgIH0KCiAgIGlmKChOVUxMID09IHdwYWxQYWNrZXRBdmFpbGFibGVDQikgfHwgKE5VTEwgPT0gdXNlckRhdGEpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIkludmFsaWQgQVJHIGZvciBuZXcgUlggcGFja2V0Iik7CiAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgfQoKICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCKCAod3B0X3BhY2tldCAqKXBQYWNrZXQsIHVzZXJEYXRhICk7CgogICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEFsbG9jIJYgQWxsb2NhdGUgYSB3cHRfcGFja2V0IGZyb20gUEFMLgogICAgUGFyYW06IAogICAgICAgIHBrdFR5cGUgliBzcGVjaWZ5IHRoZSB0eXBlIG9mIHdwdF9wYWNrZXQgdG8gYWxsb2NhdGUKICAgICAgICBuUGt0U2l6ZSAtIHBhY2tldCBzaXplCiAgICBSZXR1cm46CiAgICAgICAgQSBwb2ludGVyIHRvIHRoZSB3cHRfcGFja2V0LiBOVUxMIG1lYW5zIGZhaWwuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9wYWNrZXQgKiB3cGFsUGFja2V0QWxsb2Mod3B0X3BhY2tldF90eXBlIHBrdFR5cGUsIHdwdF91aW50MzIgblBrdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3BhbFBhY2tldExvd1BhY2tldENCIHJ4TG93Q0IsIHZvaWQgKnVzckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB3cHRfcGFja2V0KiAgcFBrdCAgICAgID0gTlVMTDsKICAgdm9zX3BrdF90KiAgIHBWb3NQa3QgICA9IE5VTEw7CiAgIHZvaWQqICAgICAgICBwRGF0YSAgICAgPSBOVUxMOwogICB2X1UxNl90ICAgICAgYWxsb2NMZW47CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICBzd2l0Y2ggKHBrdFR5cGUpCiAgIHsKICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHZvc1N0YXR1cyA9IHZvc19wa3RfZ2V0X3BhY2tldCgmcFZvc1BrdCwgVk9TX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuUGt0U2l6ZSwgMSwgVk9TX0ZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCAvKm5vIGNhbGxiYWNrKi8pOwogICAgICBicmVhazsKCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVzoKICAgICAgLyogU2V0IHRoZSB3cGFsUGFja2V0QXZhaWxhYmxlQ0IgYmVmb3JlIHdlIHRyeSB0byBnZXQgYSBWT1MKICAgICAgICogcGFja2V0IGZyb20gdGhlICdmcmVlIGxpc3QnIGFuZCByZXNldCBpdCBpZiB2b3NfcGt0X2dldF9wYWNrZXQoKQogICAgICAgKiByZXR1cm5zIGEgdmFsaWQgcGFja2V0LiBUaGlzIG9yZGVyIGlzIHJlcXVpcmVkIHRvIGF2b2lkIHRoZQogICAgICAgKiByYWNlIGNvbmRpdGlvbjoKICAgICAgICogMS4gVGhlIGJlbG93IGNhbGwgdG8gdm9zX3BrdF9nZXRfcGFja2V0KCkgaW4gUlhfVGhyZWFkIGRldGVybWluZXMKICAgICAgICogICAgdGhhdCBubyBtb3JlIHBhY2tldHMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgJ2ZyZWUgbGlzdCcgYW5kIHNldHMKICAgICAgICogICAgdGhlIGxvdyByZXNvdXJjZSBjYWxsYmFja3MuCiAgICAgICAqIDIuIGluIHBhcmFsbGVsIHZvc19wa3RfcmV0dXJuX3BhY2tldCgpIGlzIGNhbGxlZCBpbiBNQ19UaHJlYWQgZm9yIGEKICAgICAgICogICAgTWFuYWdlbWVudCBmcmFtZSBiZWZvcmUgd3BhbFBhY2tldEFsbG9jKCkgZ2V0cyBhIGNoYW5jZSB0byBzZXQKICAgICAgICogICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCIGFuZCBzaW5jZSB0aGUgJ2xvdyByZXNvdXJjZSBjYWxsYmFja3MnCiAgICAgICAqICAgIGFyZSBzZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIC0gd3BhbFBhY2tldFJYTG93UmVzb3VyY2VDQiBpcwogICAgICAgKiAgICBleGVjdXRlZCxidXQgc2luY2Ugd3BhbFBhY2tldEF2YWlsYWJsZUNCIGlzIHN0aWxsIE5VTEwgdGhlIGxvdwogICAgICAgKiAgICByZXNvdXJjZSByZWNvdmVyeSBmYWlscy4KICAgICAgICovCiAgICAgIHdwYWxQYWNrZXRBdmFpbGFibGVDQiA9IHJ4TG93Q0I7CgogICAgICB2b3NTdGF0dXMgPSB2b3NfcGt0X2dldF9wYWNrZXQoJnBWb3NQa3QsIFZPU19QS1RfVFlQRV9SWF9SQVcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Qa3RTaXplLCAxLCBWT1NfRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCLCB1c3JEYXRhKTsKCiAgICAgIC8qIFJlc2VydmUgdGhlIGVudGlyZSByYXcgcnggYnVmZmVyIGZvciBEWEUgKi8KICAgICAgaWYoIHZvc1N0YXR1cyA9PSBWT1NfU1RBVFVTX1NVQ0NFU1MgKQogICAgICB7CiAgICAgICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCID0gTlVMTDsKICAgICAgICB2b3NTdGF0dXMgPSAgdm9zX3BrdF9yZXNlcnZlX2hlYWRfZmFzdCggcFZvc1BrdCwgJnBEYXRhLCBuUGt0U2l6ZSApOyAKICAgICAgfQoKICAgICAgaWYoKE5VTEwgIT0gcFZvc1BrdCkgJiYgKFZPU19TVEFUVVNfRV9SRVNPVVJDRVMgIT0gdm9zU3RhdHVzKSkKICAgICAgewogICAgICAgICB2b3NfcGt0X2dldF9wYWNrZXRfbGVuZ3RoKHBWb3NQa3QsICZhbGxvY0xlbik7CiAgICAgICAgIGlmIChuUGt0U2l6ZSAhPSBhbGxvY0xlbikKICAgICAgICAgewogICAgICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAiUlggcGFja2V0IGFsbG9jIGhhcyBwcm9ibGVtLCBkaXNjYXJkIHRoaXMgZnJhbWUsIExlbiAlZCIsIGFsbG9jTGVuKTsKICAgICAgICAgICAgdm9zX3BrdF9yZXR1cm5fcGFja2V0KHBWb3NQa3QpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAiIHRyeSB0byBhbGxvY2F0ZSB1bnN1cHBvcnRlZCBwYWNrZXQgdHlwZSAoJWQpIiwgcGt0VHlwZSk7CiAgICAgIGJyZWFrOwogICB9CgogICBpZihWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgewogICAgICBwUGt0ID0gKHdwdF9wYWNrZXQgKilwVm9zUGt0OwogICB9CgoKICAgcmV0dXJuIHBQa3Q7Cn0vKndwYWxQYWNrZXRBbGxvYyovCgoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0RnJlZSCWIEZyZWUgYSB3cHRfcGFja2V0IGNoYWluIGZvciBvbmUgcGFydGljdWxhciB0eXBlLgogICAgRm9yIG91ciBsZWdhY3kgVU1BQywgaXQgaXMgbm90IG5lZWRlZCBiZWNhdXNlIHZvc19wYWNrZXQgY29udGFpbnMgcGFsX3BhY2tldC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IJYgcG9pbnRlciB0byBhIHdwdF9wYWNrZXQKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgLSBzdWNjZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldEZyZWUod3B0X3BhY2tldCAqcFBrdCkKewogICBWT1NfU1RBVFVTIHZvc1N0YXR1czsKCiAgIGlmKE5VTEwgIT0gcFBrdC0+cEludGVybmFsRGF0YSkKICAgewogICAgICB3cGFsTWVtb3J5RnJlZShwUGt0LT5wSW50ZXJuYWxEYXRhKTsKICAgfQogICB2b3NTdGF0dXMgPSB2b3NfcGt0X3JldHVybl9wYWNrZXQoV1BBTF9UT19WT1NfUEtUKHBQa3QpKTsKCiAgIC8vV2l0aCBWT1NTIHN1cHBvcnQsIHdlIGNhbiBjYXN0IGJldHdlZW4gd3B0X3N0YXR1cyBhbmQgVk9TX1NUQVRVUwogICByZXR1cm4gKHdwdF9zdGF0dXMpdm9zU3RhdHVzOwp9Lyp3cGFsUGFja2V0RnJlZSovCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRHZXRMZW5ndGggliBHZXQgbnVtYmVyIG9mIGJ5dGVzIGluIGEgd3B0X3BhY2tldC4gSXQgaW5jbHVkZSB0aGUgCiAgICBieXRlcyBpbiBhIEJEIGlmIGl0IGV4aXN0LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgcGFja2V0IHRvIGJlIGZyZWVkLgogICAgUmV0dXJuOgogICAgICAgIExlbmd0aCBvZiB0aGUgZGF0YSBpbmNsdWRlIGxheWVyLTIgaGVhZGVycy4gRm9yIGV4YW1wbGUsIGlmIHRoZSBmcmFtZQogICAgICAgIGlzIDgwMi4zLCB0aGUgbGVuZ3RoIGluY2x1ZGVzIHRoZSBldGhlcm5ldCBoZWFkZXIuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF91aW50MzIgd3BhbFBhY2tldEdldExlbmd0aCh3cHRfcGFja2V0ICpwUGt0KQp7CiAgIHZfVTE2X3QgbGVuID0gMCwgcGt0TGVuID0gMDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgoKICAgaWYoIFdQQUxfUEFDS0VUX0dFVF9CRF9QT0lOVEVSKHBQa3QpICkKICAgewogICAgICBsZW4gPSBXUEFMX1BBQ0tFVF9HRVRfQkRfTEVOR1RIKHBQa3QpOwogICB9CiAgIGlmKCBWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zX3BrdF9nZXRfcGFja2V0X2xlbmd0aChXUEFMX1RPX1ZPU19QS1QocFBrdCksICZwa3RMZW4pKSApCiAgIHsKICAgICAgbGVuICs9IHBrdExlbjsKICAgfQogICBlbHNlCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsICIlcyAgZmFpbGVkIiwKICAgICAgICAgX19mdW5jX18pOwogICB9CgogICByZXR1cm4gKCh3cHRfdWludDMyKWxlbik7Cn0vKndwYWxQYWNrZXRHZXRMZW5ndGgqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UmF3VHJpbUhlYWQgliBNb3ZlIHRoZSBzdGFydGluZyBvZmZzZXQgYW5kIHJldHVybiB0aGUgaGVhZCBwb2ludGVyCiAgICAgICAgICBiZWZvcmUgdGhlIG1vdmluZy4gVGhlIGZ1bmN0aW9uIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCByYXcgcGFja2V0cywKICAgICAgICAgIHdob3NlIGJ1ZmZlciBpcyBvbmUgcGllY2UgYW5kIGFsbG9jYXRlZCBieSBXTEFOIGRyaXZlci4gVGhpcyBhbHNvCiAgICAgICAgICByZWR1Y2UgdGhlIGxlbmd0aCBvZiB0aGUgcGFja2V0LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgd3B0X3BhY2tldC4KICAgICAgICBzaXplIJYgbnVtYmVyIG9mIGJ5dGVzIHRvIHRha2Ugb2ZmIHRoZSBoZWFkLgogICAgUmV0dXJuOgogICAgICAgIEEgcG9pbnRlciB0byB0aGUgb3JpZ2luYWwgYnVmZmVyIGhlYWQgYmVmb3JlIHRoZSB0cmltbWluZy4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsUGFja2V0UmF3VHJpbUhlYWQod3B0X3BhY2tldCAqcFBrdCwgd3B0X3VpbnQzMiBzaXplKQp7CiAgIHdwdF9zdGF0dXMgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGt0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgcGFja2V0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmICgoZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSB8fAogICAgICAgICAgICAgICAoZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVyA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkpCiAgIHsKICAgICAgIC8vIENvbnRpbnVlIHRvIHRyaW0gdGhlIHBhY2tldAogICB9CiAgIGVsc2UKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IG5laXRoZXIgODAyMTEgbWFuYWdtZW50IHBhY2tldCBub3IgUkFXIHBhY2tldCIsIF9fZnVuY19fKTsKICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgaWYoICFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zX3BrdF90cmltX2hlYWQoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAodl9TSVpFX3Qpc2l6ZSkpICkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgIiVzICBJbnZhbGlkIHRyaW0oJWQpIiwKICAgICAgICAgX19mdW5jX18sIHNpemUpOwogICAgICBzdGF0dXMgPSBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHJldHVybiBzdGF0dXM7Cn0vKndwYWxQYWNrZXRSYXdUcmltSGVhZCovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldFJhd1RyaW1UYWlsIJYgcmVkdWNlIHRoZSBsZW5ndGggb2YgdGhlIHBhY2tldC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHdwdF9wYWNrZXQuCiAgICAgICAgc2l6ZSCWIG51bWJlciBvZiBieXRlcyB0byB0YWtlIG9mIHRoZSBwYWNrZXQgbGVuZ3RoCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIJYgc3VjY2Vzcy4gT3RoZXJ3aXNlIGZhaWwuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldFJhd1RyaW1UYWlsKHdwdF9wYWNrZXQgKnBQa3QsIHdwdF91aW50MzIgc2l6ZSkKewogICB3cHRfc3RhdHVzIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBpZiAoKGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkgfHwKICAgICAgICAgICAgICAgKGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVcgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpKQogICB7CiAgICAgICAvLyBDb250aW51ZSB0byB0cmltIHRoZSBwYWNrZXQKICAgfQogICBlbHNlCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBuZWl0aGVyIDgwMjExIG1hbmFnbWVudCBwYWNrZXQgbm9yIFJBVyBwYWNrZXQiLCBfX2Z1bmNfXyk7CiAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmKCAhVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfdHJpbV90YWlsKFdQQUxfVE9fVk9TX1BLVChwUGt0KSwgKHZfU0laRV90KXNpemUpKSApCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsICIlcyAgSW52YWxpZCB0cmltKCVkKSIsCiAgICAgICAgIF9fZnVuY19fLCBzaXplKTsKICAgICAgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICByZXR1cm4gc3RhdHVzOwp9Lyp3cGFsUGFja2V0UmF3VHJpbVRhaWwqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0R2V0UmF3QnVmIJYgUmV0dXJuIHRoZSBzdGFydGluZyBidWZmZXIgdmlydHVhbCBhZGRyZXNzIGZvciB0aGUgUkFXIGZsYXQgYnVmZmVyCiAgICBJdCBpcyBpbmxpbmUgaW4gaG9wZSBvZiBmYXN0ZXIgaW1wbGVtZW50YXRpb24gZm9yIGNlcnRhaW4gcGxhdGZvcm0uIEZvciBXaW54cCwgaXQgCiAgICB3aWxsIGJlIHNsb3cuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgUmV0dXJuOgogICAgICAgIE5VTEwgLSBmYWlsLgogICAgICAgIE90aGVyd2lzZSB0aGUgYWRkcmVzcyBvZiB0aGUgc3RhcnRpbmcgb2YgdGhlIGJ1ZmZlcgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfdWludDggKndwYWxQYWNrZXRHZXRSYXdCdWYod3B0X3BhY2tldCAqcFBrdCkKewogICB3cHRfdWludDggKnBSZXQgPSBOVUxMOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGt0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgcGFja2V0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBOVUxMOwogICB9CgogICAvL1NpbmNlIGl0IGlzIGEgZmxhdCBidWZmZXIsIGFsbCB3ZSBuZWVkIGlzIHRvIGdldCBvbmUgYnl0ZSBvZiBvZmZzZXQgMAogICBpZiggKGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVcgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAoZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSApCiAgIHsKICAgICAgdm9zX3BrdF9wZWVrX2RhdGEoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAwLCAodl9WT0lEX3QqKikmcFJldCwgMSk7CiAgICAgIFdQQUxfQVNTRVJUKE5VTEwgIT0gcFJldCk7CiAgIH0gICAgICAgICAgICAKCiAgIHJldHVybiBwUmV0Owp9Lyp3cGFsUGFja2V0R2V0UmF3QnVmKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldFNldFJ4TGVuZ3RoIJYgU2V0IHRoZSB2YWxpZCBkYXRhIGxlbmd0aCBvbiBhIFJYIHBhY2tldC4gVGhpcyBmdW5jdGlvbiBtdXN0IAogICAgYmUgY2FsbGVkIG9uY2UgcGVyIFJYIHBhY2tldCBwZXIgcmVjZWl2aW5nLiBJdCBpbmRpY2F0ZXMgdGhlIGF2YWlsYWJsZSBkYXRhIGxlbmd0aCBmcm9tCiAgICB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlci4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHdwdF9wYWNrZXQuCiAgICBSZXR1cm46CiAgICAgICAgTlVMTCAtIGZhaWwuCiAgICAgICAgT3RoZXJ3aXNlIHRoZSBhZGRyZXNzIG9mIHRoZSBzdGFydGluZyBvZiB0aGUgYnVmZmVyCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldFNldFJ4TGVuZ3RoKHdwdF9wYWNrZXQgKnBQa3QsIHdwdF91aW50MzIgbGVuKQp7CiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICAvKk9ubHkgYWxsb3dlZCBmb3IgUlggUmF3IHBhY2tldHMgKi8KICAgaWYoIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXICE9IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSkKICAgewogICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICIlcyAgSW52YWxpZCBwYWNrZXQgdHlwZSglZCkiLCAgX19mdW5jX18sCiAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSk7CiAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgaWYoVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3Rfc2V0X3J4X2xlbmd0aChXUEFMX1RPX1ZPU19QS1QocFBrdCksIGxlbikpKQogICB7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIH0KICAgZWxzZQogICB7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KfS8qd3BhbFBhY2tldFNldFJ4TGVuZ3RoKi8KCnZvaWQgd3BhbFJlY292ZXJUYWlsKHdwdF9wYWNrZXQgKnBGcmFtZSkKewogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBGcmFtZSkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm47CiAgIH0KCiAgIHJldHVybiB2b3NfcmVjb3Zlcl90YWlsKFdQQUxfVE9fVk9TX1BLVChwRnJhbWUpKTsKfQoKdm9pZCogd3BhbEdldE9TUGt0SGVhZCh3cHRfcGFja2V0ICpwRnJhbWUpCnsKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwRnJhbWUpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIE5VTEw7CiAgIH0KCiAgIHJldHVybiB2b3NfZ2V0X3BrdF9oZWFkKFdQQUxfVE9fVk9TX1BLVChwRnJhbWUpKTsKfQoKdm9pZCogd3BhbEdldE9TUGt0ZW5kKHdwdF9wYWNrZXQgKnBGcmFtZSkKewogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBGcmFtZSkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gMDsKICAgfQoKICAgcmV0dXJuIHZvc19nZXRfcGt0X2VuZChXUEFMX1RPX1ZPU19QS1QocEZyYW1lKSk7Cn0KCi8qCiAgU2V0IG9mIGhlbHBlciBmdW5jdGlvbnMgdGhhdCB3aWxsIHByZXBhcmUgcGFja2V0IGZvciBETUEgdHJhbnNmZXIsCiAgYmFzZWQgb24gdGhlIHR5cGUgb2YgdHJhbnNmZXIgOiAtIHRvIGFuZCBmcm9tIHRoZSBkZXZpY2UKICAtIGZvbGxvd2luZyB0aGVzZSBjYWxscyB0aGUgcGFja2V0IHdpbGwgYmUgbG9ja2VkIGZvciBETUEgb25seSwKICBDUFUgd2lsbCBub3QgYmUgYWJsZSB0byBtb2RpZnkgaXQgPT4gdGhlIHBhY2tldCBtdXN0IGJlIGV4cGxpY2l0bHkgcmV0dXJuZWQgdG8KICB0aGUgQ1BVIG9uY2UgdGhlIERNQSB0cmFuc2ZlciBpcyBjb21wbGV0ZQoqLwpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCogaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHdwdF9wYWNrZXQgKnBQYWNrZXQgKQp7CiAgIHN0cnVjdCBza19idWZmICpza2I7CiAgIHN0cnVjdCBkZXZpY2UgKndjbnNzX2RldmljZSA9IChzdHJ1Y3QgZGV2aWNlICopZ0NvbnRleHQuZGV2SGFuZGxlOwogICAvKi0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICBpZiAoIFZPU19TVEFUVVNfU1VDQ0VTUyAhPSAKICAgICAgICB2b3NfcGt0X2dldF9vc19wYWNrZXQoV1BBTF9UT19WT1NfUEtUKHBQYWNrZXQpLCAodm9pZCoqKSZza2IsIFZPU19GQUxTRSApKQogICB7CiAgICAgcmV0dXJuIE5VTEw7CiAgIH0KICAgZWxzZQogICB7CiAgICAgLypNYXAgc2tiIGRhdGEgaW50byBkbWEtYWJsZSBtZW1vcnkgCiAgICAgICAoY2hhbmdlcyB3aWxsIGJlIGNvbW1pdGVkIGZyb20gY2FjaGUpICovCiAgICAgcmV0dXJuICh2b2lkKilkbWFfbWFwX3NpbmdsZSggd2Nuc3NfZGV2aWNlLCBza2ItPmRhdGEsIHNrYi0+bGVuLCBETUFfVE9fREVWSUNFICk7CiAgIH0KfS8qaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UqLwoKV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQqIGl0R2V0T1NQa3RBZGRyRnJvbURldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCApCnsKICAgc3RydWN0IHNrX2J1ZmYgKnNrYjsKICAgc3RydWN0IGRldmljZSAqd2Nuc3NfZGV2aWNlID0gKHN0cnVjdCBkZXZpY2UgKilnQ29udGV4dC5kZXZIYW5kbGU7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gKi8KCiAgIGlmICggVk9TX1NUQVRVU19TVUNDRVNTICE9IAogICAgICAgIHZvc19wa3RfZ2V0X29zX3BhY2tldChXUEFMX1RPX1ZPU19QS1QocFBhY2tldCksICh2b2lkKiopJnNrYiwgVk9TX0ZBTFNFICkpCiAgIHsKICAgICByZXR1cm4gTlVMTDsKICAgfQogICBlbHNlCiAgIHsKICAgICBpZigodWludHB0cl90KXNrYi0+ZGF0YSA9PSAodWludHB0cl90KXNrYi0+dGFpbCkKICAgICB7CiNpZmRlZiBXTEFOX0JVR19PTl9TS0JfRVJST1IKICAgICAgIHdwYWxEZXZpY2VQYW5pYygpOwojZWxzZQogICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRkFUQUwsCiAgICAgICAgICAgICAgICAiJXM6IHNrYi0+ZGF0YSA9PSBza2ItPnRhaWwuIEF0dGVtcHRpbmcgcmVjb3ZlcnkgIgogICAgICAgICAgICAgICAgInNrYjolcEssIGhlYWQ6JXBLLCB0YWlsOiVwSywgZGF0YTolcEsiLAogICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgc2tiLCBza2ItPmhlYWQsIHNrYi0+dGFpbCwgc2tiLT5kYXRhKTsKCiAgICAgIHNrYi0+ZGF0YSA9IHNrYi0+aGVhZDsKI2VuZGlmCiAgICAgfQogICAgIC8qTWFwIHNrYiBkYXRhIGludG8gZG1hLWFibGUgbWVtb3J5IAogICAgICAgKGNoYW5nZXMgd2lsbCBiZSBjb21taXRlZCBmcm9tIGNhY2hlKSAqLwogICAgIHJldHVybiAodm9pZCopZG1hX21hcF9zaW5nbGUoIHdjbnNzX2RldmljZSwgc2tiLT5kYXRhLCBza2ItPmxlbiwgRE1BX0ZST01fREVWSUNFICk7CiAgIH0KfS8qaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKi8KCi8qCiAgU2V0IG9mIGhlbHBlciBmdW5jdGlvbnMgdGhhdCB3aWxsIHJldHVybiBhIERNQS1lZCBwYWNrZXQgdG8gdGhlIENQVSwKICBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0cmFuc2ZlciA6IC0gdG8gYW5kIGZyb20gdGhlIGRldmljZQoqLwpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCBpdFJldHVybk9TUGt0QWRkckZvckRldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCwgIHZvaWQqIGFkZHIsIHdwdF91aW50MzIgc2l6ZSApCnsKICAgc3RydWN0IGRldmljZSAqd2Nuc3NfZGV2aWNlID0gKHN0cnVjdCBkZXZpY2UgKilnQ29udGV4dC5kZXZIYW5kbGU7CgogICBkbWFfdW5tYXBfc2luZ2xlKCB3Y25zc19kZXZpY2UsIChkbWFfYWRkcl90KWFkZHIsIHNpemUsIERNQV9UT19ERVZJQ0UgKTsKfQoKV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQgaXRSZXR1cm5PU1BrdEFkZHJGcm9tRGV2aWNlKCB3cHRfcGFja2V0ICpwUGFja2V0LCB2b2lkKiBhZGRyLCB3cHRfdWludDMyIHNpemUgICkKewogICBzdHJ1Y3QgZGV2aWNlICp3Y25zc19kZXZpY2UgPSAoc3RydWN0IGRldmljZSAqKWdDb250ZXh0LmRldkhhbmRsZTsKCiAgIGRtYV91bm1hcF9zaW5nbGUoIHdjbnNzX2RldmljZSwgKGRtYV9hZGRyX3QpYWRkciwgc2l6ZSwgRE1BX0ZST01fREVWSUNFICk7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbEl0ZXJhdG9ySW5pdCCWIEluaXRpYWxpemUgYW4gaW50ZXJhdG9yIGJ5IHVwZGF0aW5nIHBDdXIgdG8gZmlyc3QgaXRlbS4KICAgIFBhcmFtOiAKICAgICAgICBwSXRlciCWIHBvaW50ZXIgdG8gYSBjYWxsZXIgYWxsb2NhdGVkIHdwdF9pdGVyYXRvcgogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyAtIHN1Y2Nlc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsSXRlcmF0b3JJbml0KHdwdF9pdGVyYXRvciAqcEl0ZXIsIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKICAgd3B0X3N0YXR1cyAgICAgICAgIHN0YXR1cyAgICAgPSBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwQ3VySW5mbyAgID0gTlVMTDsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBOZXh0SW5mbyAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcFBrdEluZm8gICA9IE5VTEw7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseSgoTlVMTCA9PSBwUGFja2V0KXx8KE5VTEw9PXBJdGVyKSkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXJzICVwSyAlcEsiLCBfX2Z1bmNfXywgcFBhY2tldCwgcEl0ZXIpOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwUGt0SW5mbyA9ICh3cHRfaXRlcmF0b3JfaW5mbyopcFBhY2tldC0+cEludGVybmFsRGF0YTsKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogSW52YWxpZCBQYWNrZXQgSW5mbyIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgLy8gaWYgdGhlcmUgaXMgTk8gQkQgb24gdGhpcyBmcmFtZSwgdGhlbiBpbml0aWFsaXplIHRoZSBuZXh0IHBvaW50ZXIgdG8KICAgLy8gcG9pbnQgdGhlIGZpcnN0IGZyYWdtZW50LgogICBpZiAoIE5VTEwgPT0gV1BBTF9QQUNLRVRfR0VUX0JEX1BIWVMocFBhY2tldCkgKQogICB7CiAgICAgcEN1ckluZm8gICA9IHBQa3RJbmZvOwogICAgIHBOZXh0SW5mbyAgICAgICAgICAgPSBOVUxMOwogICB9CiAgIGVsc2UKICAgewogICAgIC8qQWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgY3VycmVudCBpbmZvKi8KICAgICBwQ3VySW5mbyA9IHdwYWxNZW1vcnlBbGxvY2F0ZSggc2l6ZW9mKHdwdF9pdGVyYXRvcl9pbmZvKSApOwoKICAgICAvLyBWYWxpZGF0ZSB0aGUgbWVtb3J5IGFsbG9jYXRpb24KICAgICBpZiAodW5saWtlbHkoTlVMTCA9PSBwQ3VySW5mbykpCiAgICAgewogICAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgICAiJXMgOiBGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5ICIsIF9fZnVuY19fKTsKICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICAgIH0KCiAgICAgcEN1ckluZm8tPnBQaHlBZGRyID0gV1BBTF9QQUNLRVRfR0VUX0JEX1BIWVMocFBhY2tldCk7CiAgICAgcEN1ckluZm8tPnVMZW4gICAgID0gV1BBTF9QQUNLRVRfR0VUX0JEX0xFTkdUSChwUGFja2V0KTsKCiAgICAgcE5leHRJbmZvICAgICAgICAgICA9IHBQa3RJbmZvOwogICB9ICAgICAgCgogICBwSXRlci0+cEN1ciAgICAgPSAodm9pZCopcEN1ckluZm87IAogICBwSXRlci0+cE5leHQgICAgPSAodm9pZCopcE5leHRJbmZvOwogICBwSXRlci0+cENvbnRleHQgPSBOVUxMOwoKICAgcmV0dXJuIHN0YXR1czsKfS8qd3BhbEl0ZXJhdG9ySW5pdCovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbEl0ZXJhdG9yTmV4dCCWIEdldCB0aGUgYWRkcmVzcyBmb3IgdGhlIG5leHQgaXRlbQogICAgUGFyYW06IAogICAgICAgIHBJdGVyIJYgcG9pbnRlciB0byBhIGNhbGxlciBhbGxvY2F0ZWQgd3B0X2l0ZXJhdG9yCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICAgICAgcHBBZGRyIJYgQ2FsbGVyIGFsbG9jYXRlZCBwb2ludGVyIHRvIHJldHVybiB0aGUgYWRkcmVzcyBvZiB0aGUgaXRlbS4KICAgICAgICBGb3IgRE1BLWFibGUgZGV2aWNlcywgdGhpcyBpcyB0aGUgcGh5c2ljYWwgYWRkcmVzcyBvZiB0aGUgaXRlbS4KICAgICAgICBwTGVuIJYgVG8gcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGl0ZW0uCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxJdGVyYXRvck5leHQod3B0X2l0ZXJhdG9yICpwSXRlciwgd3B0X3BhY2tldCAqcFBhY2tldCwgdm9pZCAqKnBwQWRkciwgd3B0X3VpbnQzMiAqcExlbikKewogICB3cHRfaXRlcmF0b3JfaW5mbyogcEN1ckluZm8gID0gTlVMTDsKICAgLyotIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSovCiAgIAogICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBTYW5pdHkgY2hlY2sKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgIGlmICh1bmxpa2VseSgoIE5VTEwgPT0gcEl0ZXIgKXx8KCBOVUxMID09IHBQYWNrZXQgKSB8fCAKICAgICAgKCBOVUxMID09IHBwQWRkciApIHx8ICggTlVMTCA9PSBwTGVuICkpKQogICB7CiAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgIiVzICBJbnZhbGlkIGlucHV0IHBhcmFtZXRlcnMiLCAgX19mdW5jX18gKTsKICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwQ3VySW5mbyA9ICh3cHRfaXRlcmF0b3JfaW5mbyopcEl0ZXItPnBDdXI7IAogICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBJZiBjdXJyZW50IHBvaW50ZXIgaXMgTlVMTCAtIHRoZXJlIGlzIG5vIGRhdGEgaW4gdGhlIHBhY2tldCAtIHJldHVybgogICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KICAgaWYoIHBJdGVyLT5wQ3VyID09IE5VTEwgKQogICB7CiAgICAgICpwcEFkZHIgPSBOVUxMOyAKICAgICAgKnBMZW4gICA9IDA7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIH0KCiAgIC8qQWRkcmVzcyBhbmQgbGVuZ3RoIGFyZSBrZXB0IGluIHRoZSBjdXJyZW50IGZpZWxkKi8KICAgKnBwQWRkciA9IHBDdXJJbmZvLT5wUGh5QWRkcjsgCiAgICpwTGVuICAgPSBwQ3VySW5mby0+dUxlbjsKICAgIAogICBpZiggTlVMTCA9PSBwSXRlci0+cE5leHQgKQogICB7CiAgICAgLypTYXZlIHRoZSBpdGVyYXRvciBmb3IgY2xlYW51cCovCiAgICAgcFBhY2tldC0+cEludGVybmFsRGF0YSA9IHBJdGVyLT5wQ3VyOyAKICAgICBwSXRlci0+cEN1ciAgICAgICAgICAgID0gTlVMTDsgCiAgIH0KICAgZWxzZQogICB7CiAgICAgLypSZWxlYXNlIHRoZSBtZW1vcnkgc2F2ZWQgZm9yIHN0b3JpbmcgdGhlIEJEIGluZm9ybWF0aW9uKi8KICAgICB3cGFsTWVtb3J5RnJlZShwQ3VySW5mbyk7IAogIAogICAgIC8qRm9yIExBIC0gdGhlIHBhY2tldCBpcyByZXByZXNlbnRlZCBieSBtYXhpbXVtIDIgZmllbGRzIG9mIGRhdGEgCiAgICAgICAtIEJEIGFuZCBhY3R1YWwgZGF0YSBmcm9tIHNrIGJ1ZmYgKi8KICAgICBwSXRlci0+cEN1ciAgICAgPSBwSXRlci0+cE5leHQ7CiAgICAgcEl0ZXItPnBOZXh0ICAgID0gTlVMTDsKICAgfQogICAKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIgliBNYXAgdGhlIGRhdGEgYnVmZmVyIGZyb20gZG1hIHNvIHRoYXQgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhIGlzIGNvbW1pdGVkIGZyb20gY2FjaGUgYW5kIHRoZSBjcHUgcmVsaW5xdWlzaGVzCiAgICAgICAgICAgICAgICAgICAgICAgICBvd25lcnNoaXAgb2YgdGhlIGJ1ZmZlcgogCiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgLSBzdWNjZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbExvY2tQYWNrZXRGb3JUcmFuc2Zlciggd3B0X3BhY2tldCAqcFBhY2tldCkKewogICB2b2lkKiAgICAgICAgICAgICAgcFBoeURhdGEgICA9IE5VTEw7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwSW5mbyAgICAgID0gTlVMTDsKICAgdl9VMTZfdCAgICAgICAgICAgIHVMZW5EYXRhICAgPSAwOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGFja2V0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgc3dpdGNoKFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQYWNrZXQpKQogICB7CiAgICAgIC8qIEZvciBtYW5hZ2VtZW50IGZyYW1lcywgQkQgaXMgYWxsb2NhdGVkIGJ5IFdESSwgaGVhZGVyIGlzIGluIHJhdyBidWZmZXIsCiAgICAgICAgIHJlc3Qgb2YgdGhlIGZyYW1lIGlzIGFsc28gaW4gcmF3IGJ1ZmZlciAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVDoKICAgICAgewogICAgICAgICAvKlRYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgdG8gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBwUGh5RGF0YSA9ICh2b2lkKilpdEdldE9TUGt0QWRkckZvckRldmljZSggcFBhY2tldCApOyAgIAogICAgICB9CiAgICAgIGJyZWFrOwogICAgICAgICAvKiBEYXRhIHBhY2tldHMgLSBCRCAoYWxsb2NhdGVkIGJ5IFdESSksIGhlYWRlciAoaW4gVk9TUyBoZWFkZXIpLAogICAgICAgICAgICByZXN0IG9mIHRoZSBwYWNrZXQgKERTTSBpdGVtcykgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX0RBVEE6CiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8zX0RBVEE6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHBQYWNrZXQgKTsKICAgICAgfQogICAgICBicmVhazsKCiAgICAgIC8qIEZvciBSYXcgUlgsIEJEICsgaGVhZGVyICsgcmVzdCBvZiB0aGUgcGFja2V0IGlzIGFsbCBjb250YWluZWQgaW4gdGhlIHJhdwogICAgICAgICBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXOgogICAgICB7CiAgICAgICAgIC8qUlggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCBmcm9tIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKCBwUGFja2V0ICk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICBkZWZhdWx0OgogICAgICB7CiAgICAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgICAiIFdMQU5fUEFMOiAlczogSW52YWxpZCBwYWNrZXQgdHlwZSAlZCEiLCAgX19mdW5jX18sIAogICAgICAgICAgICAgICAgICAgIFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQYWNrZXQpICk7IAogICAgICAgICBXUEFMX0FTU0VSVCgwKTsgCiAgICAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgfQogICB9CgogICAvKkdldCBwYWNrZXQgbGVuZ3RoKi8KICAgdm9zX3BrdF9nZXRfcGFja2V0X2xlbmd0aChXUEFMX1RPX1ZPU19QS1QocFBhY2tldCksJnVMZW5EYXRhKTsKCiAgICAvKkFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGN1cnJlbnQgaW5mbyovCiAgIHBJbmZvID0gd3BhbE1lbW9yeUFsbG9jYXRlKCBzaXplb2Yod3B0X2l0ZXJhdG9yX2luZm8pICk7CgogICAvLyBWYWxpZGF0ZSB0aGUgbWVtb3J5IGFsbG9jYXRpb24KICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSAiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHBJbmZvLT5wUGh5QWRkciA9IHBQaHlEYXRhOwogICBwSW5mby0+dUxlbiAgICAgPSB1TGVuRGF0YTsKCiAgIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBwSW5mbzsKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbExvY2tQYWNrZXRGb3JUcmFuc2ZlciovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFVubG9ja1BhY2tldCCWIFVubWFwIHRoZSBkYXRhIGJ1ZmZlciBmcm9tIGRtYSBzbyB0aGF0IGNwdSBjYW4gcmVnYWluCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJzaGlwIG9uIGl0CiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MgLSBzdWNjZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFVubG9ja1BhY2tldCggd3B0X3BhY2tldCAqcFBhY2tldCkKewoKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBJbmZvOwoKICAgLy8gVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwUGFja2V0KSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlciBwUGFja2V0IiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwSW5mbyAgPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBQYWNrZXQtPnBJbnRlcm5hbERhdGE7CgogICAvLyBWYWxpZGF0ZSBwSW5mbwogICBpZiAodW5saWtlbHkoTlVMTCA9PSBwSW5mbykpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRkFUQUwsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIgcEluZm8iLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHN3aXRjaChXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSkKICAgewogICAgICAvKiBGb3IgbWFuYWdlbWVudCBmcmFtZXMsIEJEIGlzIGFsbG9jYXRlZCBieSBXREksIGhlYWRlciBpcyBpbiByYXcgYnVmZmVyLAogICAgICAgICByZXN0IG9mIHRoZSBmcmFtZSBpcyBhbHNvIGluIHJhdyBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICBpdFJldHVybk9TUGt0QWRkckZvckRldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgfQogICAgICBicmVhazsKICAgICAgICAgLyogRGF0YSBwYWNrZXRzIC0gQkQgKGFsbG9jYXRlZCBieSBXREkpLCBoZWFkZXIgKGluIFZPU1MgaGVhZGVyKSwKICAgICAgICAgICAgcmVzdCBvZiB0aGUgcGFja2V0IChEU00gaXRlbXMpICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9EQVRBOgogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfM19EQVRBOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIGl0UmV0dXJuT1NQa3RBZGRyRm9yRGV2aWNlKHBQYWNrZXQsIHBJbmZvLT5wUGh5QWRkciwgcEluZm8tPnVMZW4pOyAgIAogICAgICB9CiAgICAgIGJyZWFrOwoKICAgICAgLyogRm9yIFJhdyBSWCwgQkQgKyBoZWFkZXIgKyByZXN0IG9mIHRoZSBwYWNrZXQgaXMgYWxsIGNvbnRhaW5lZCBpbiB0aGUgcmF3CiAgICAgICAgIGJ1ZmZlciAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVc6CiAgICAgIHsKICAgICAgICAgLypSWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIGZyb20gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBpZihOVUxMID09IHBJbmZvLT5wUGh5QWRkcikKICAgICAgICAgewogICAgICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IFJYIGZyYW1lIHdhcyBub3QgbG9ja2VkIHByb3Blcmx5IiwgIF9fZnVuY19fKTsgCiAgICAgICAgIH0KICAgICAgICAgZWxzZQogICAgICAgICB7CiAgICAgICAgICAgIGl0UmV0dXJuT1NQa3RBZGRyRnJvbURldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgewogICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IEludmFsaWQgcGFja2V0IHR5cGUgJWQhIiwgIF9fZnVuY19fLCAKICAgICAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSApOyAKICAgICAgICAgV1BBTF9BU1NFUlQoMCk7IAogICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgIH0KICAgfQoKICB3cGFsTWVtb3J5RnJlZShwSW5mbyk7CiAgcFBhY2tldC0+cEludGVybmFsRGF0YSA9IE5VTEw7CiAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbFVubG9ja1BhY2tldCovCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbElzUGFja2V0TG9ja2VkIJYgIENoZWNrIHdoZXRoZXIgdGhlIFBhY2tldCBpcyBsb2NrZWQgZm9yIERNQS4KICAgIFBhcmFtOiAKICAgICAgICBwUGFja2V0IJYgcG9pbnRlciB0byBhIHdwdF9wYWNrZXQKIAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUwogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfRV9GQUlMVVJFCiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbElzUGFja2V0TG9ja2VkKCB3cHRfcGFja2V0ICpwUGFja2V0KQp7CgogICB3cHRfaXRlcmF0b3JfaW5mbyogcEluZm87CgogICAvKiBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzICovCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfV0FSTiwKICAgICAgICAgICAgICAgICIlcyA6IE5VTEwgaW5wdXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgLyogVmFsaWRhdGUgcEludGVybmFsRGF0YSAqLwogICBwSW5mbyAgPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBQYWNrZXQtPnBJbnRlcm5hbERhdGE7CiAgIHJldHVybiAoTlVMTCA9PSBwSW5mbyk/IGVXTEFOX1BBTF9TVEFUVVNfRV9GQUlMVVJFIDogCiAgICAgICAgICAgICAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwp9Lyp3cGFsSXNQYWNrZXRMb2NrZWQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgd3BhbEdldE51bVJ4UmF3UGFja2V0ICAgUXVlcnkgYXZhaWxhYmxlIFJYIFJBVyB0b3RhbCBidWZmZXIgY291bnQKICAgcGFyYW06CiAgICAgICBudW1SeFJlc291cmNlICBwb2ludGVyIG9mIHF1ZXJpZWQgdmFsdWUKCiAgIHJldHVybjoKICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxHZXROdW1SeFJhd1BhY2tldCh3cHRfdWludDMyICpudW1SeFJlc291cmNlKQp7CiAgICpudW1SeFJlc291cmNlID0gKHdwdF91aW50MzIpdm9zX3BrdF9nZXRfbnVtX29mX3J4X3Jhd19wa3RzKCk7CgogICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICB3cGFsR2V0TnVtUnhQYWNrZXRBbGxvY0ZhaWx1cmVzICAgR2V0IG51bWJlciBvZiB0aW1lcyBwYWNrZXQgYWxsb2MgZmFpbGVkCiAgICAgICBudW1SeFJlc291cmNlICBwb2ludGVyIG9mIHF1ZXJpZWQgdmFsdWUKCiAgIHJldHVybjoKICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxHZXROdW1SeFBhY2tldEFsbG9jRmFpbHVyZXMod3B0X3VpbnQzMiAqbnVtUnhSZXNvdXJjZSkKewogICAqbnVtUnhSZXNvdXJjZSA9ICh3cHRfdWludDMyKXZvc19wa3RfZ2V0X251bV9vZl9yeF9wa3RfYWxsb2NfZmFpbHVyZXMoKTsKCiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgd3BhbEdldE51bVJ4RnJlZVBhY2tldCAgIFF1ZXJ5IGF2YWlsYWJsZSBSWCBGcmVlIGJ1ZmZlciBjb3VudAogICBwYXJhbToKICAgICAgIG51bVJ4UmVzb3VyY2UgIHBvaW50ZXIgb2YgcXVlcmllZCB2YWx1ZQoKICAgcmV0dXJuOgogICAgICAgV1BUX1NUQVRVUwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxHZXROdW1SeEZyZWVQYWNrZXQod3B0X3VpbnQzMiAqbnVtUnhSZXNvdXJjZSkKewogICBWT1NfU1RBVFVTIHN0YXR1czsKCiAgIHN0YXR1cyA9IHZvc19wa3RfZ2V0X2F2YWlsYWJsZV9idWZmZXJfcG9vbChWT1NfUEtUX1RZUEVfUlhfUkFXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfU0laRV90ICopbnVtUnhSZXNvdXJjZSk7CgogICByZXR1cm4gV1BBTF9WT1NfVE9fV1BBTF9TVEFUVVMoc3RhdHVzKTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTdGFsbFVwZGF0ZUluZm8gliBVcGRhdGUgZWFjaCBjaGFubmVsIGluZm9ybWF0aW9uIHdoZW4gc3RhbGwKICAgICAgIGRldGVjdGVkLCBhbHNvIHBvd2VyIHN0YXRlIGFuZCBmcmVlIHJlc291cmNlIGNvdW50CgogICAgUGFyYW06CiAgICAgICBwb3dlclN0YXRlICA/IFdMQU4gc3lzdGVtIHBvd2VyIHN0YXRlIHdoZW4gc3RhbGwgZGV0ZWN0ZWQKICAgICAgIG51bUZyZWVCZCAgID8gTnVtYmVyIG9mIGZyZWUgcmVzb3VyY2UgY291bnQgaW4gSFcKICAgICAgIGNoYW5uZWxJbmZvID8gRWFjaCBjaGFubmVsIHNwZWNpZmljIGluZm9ybWF0aW9uIHdoZW4gc3RhbGwgaGFwcGVuCiAgICAgICBjaGFubmVsTnVtICA/IENoYW5uZWwgbnVtYmVyIHVwZGF0ZSBpbmZvcm1hdGlvbgoKICAgIFJldHVybjoKICAgICAgIE5PTkUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgd3BhbFBhY2tldFN0YWxsVXBkYXRlSW5mbwooCiAgIHZfVTMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgKnBvd2VyU3RhdGUsCiAgIHZfVTMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgKm51bUZyZWVCZCwKICAgd3B0X2xvZ19kYXRhX3N0YWxsX2NoYW5uZWxfdHlwZSAqY2hhbm5lbEluZm8sCiAgIHZfVThfdCAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxOdW0KKQp7CiAgIC8qIFVwZGF0ZSBwb3dlciBzdGF0ZSB3aGVuIHN0YWxsIGRldGVjdGVkICovCiAgIGlmKE5VTEwgIT0gcG93ZXJTdGF0ZSkKICAgewogICAgICB3cGFsVHJhc3BvcnRTdGFsbEluZm8uUG93ZXJTdGF0ZSA9ICpwb3dlclN0YXRlOwogICB9CgogICAvKiBVcGRhdGUgSFcgZnJlZSByZXNvdXJjZSBjb3VudCAqLwogICBpZihOVUxMICE9IG51bUZyZWVCZCkKICAgewogICAgICB3cGFsVHJhc3BvcnRTdGFsbEluZm8ubnVtRnJlZUJkICA9ICpudW1GcmVlQmQ7CiAgIH0KCiAgIC8qIFVwZGF0ZSBjaGFubmVsIGluZm9ybWF0aW9uICovCiAgIGlmKE5VTEwgIT0gY2hhbm5lbEluZm8pCiAgIHsKICAgICAgd3BhbE1lbW9yeUNvcHkoJndwYWxUcmFzcG9ydFN0YWxsSW5mby5keGVDaGFubmVsSW5mb1tjaGFubmVsTnVtXSwKICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZih3cHRfbG9nX2RhdGFfc3RhbGxfY2hhbm5lbF90eXBlKSk7CiAgIH0KCiAgIHJldHVybjsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9ESUFHX1NVUFBPUlQKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTdGFsbER1bXBMb2cgliBUcmlnZ2VyIHRvIHNlbmQgbG9nIHBhY2tldCB0byBESUFHCiAgICAgICBVcGRhdGVkIHRyYW5zcG9ydCBzeXN0ZW0gaW5mb3JtYXRpb24gd2lsbCBiZSBzZW50IHRvIERJQUcKCiAgICBQYXJhbToKICAgICAgICBOT05FCgogICAgUmV0dXJuOgogICAgICAgIE5PTkUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgd3BhbFBhY2tldFN0YWxsRHVtcExvZwooCiAgIHZvaWQKKQp7CiAgIHZvc19sb2dfZGF0YV9zdGFsbF90eXBlICAqbG9nX3B0ciA9IE5VTEw7CgogICBXTEFOX1ZPU19ESUFHX0xPR19BTExPQyhsb2dfcHRyLCB2b3NfbG9nX2RhdGFfc3RhbGxfdHlwZSwgTE9HX1RSU1BfREFUQV9TVEFMTF9DKTsKICAgaWYobG9nX3B0cikKICAgewogICAgICBsb2dfcHRyLT5Qb3dlclN0YXRlID0gd3BhbFRyYXNwb3J0U3RhbGxJbmZvLlBvd2VyU3RhdGU7CiAgICAgIGxvZ19wdHItPm51bUZyZWVCZCAgPSB3cGFsVHJhc3BvcnRTdGFsbEluZm8ubnVtRnJlZUJkOwogICAgICB3cGFsTWVtb3J5Q29weSgmbG9nX3B0ci0+ZHhlQ2hhbm5lbEluZm9bMF0sCiAgICAgICAgICAgICAgICAgICAgICZ3cGFsVHJhc3BvcnRTdGFsbEluZm8uZHhlQ2hhbm5lbEluZm9bMF0sCiAgICAgICAgICAgICAgICAgICAgIFdQVF9OVU1fVFJQVF9DSEFOTkVMICogc2l6ZW9mKHZvc19sb2dfZGF0YV9zdGFsbF9jaGFubmVsX3R5cGUpKTsKICAgICAgcHJfaW5mbygiU3RhbGwgbG9nIGR1bXAiKTsKICAgICAgV0xBTl9WT1NfRElBR19MT0dfUkVQT1JUKGxvZ19wdHIpOwogICB9CgogICByZXR1cm47Cn0KI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9ESUFHX1NVUFBPUlQgKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsTG9nUGt0U2VyaWFsaXplIC0gU2VyaWFsaXplIExvZ2dpbmcgZGF0YSB0byBsb2dnZXIgdGhyZWFkCgogICAgUGFyYW06CiAgICB3cHRfcGFja2V0IHBGcmFtZSAtIFRoZSBwYWNrZXQgd2hpY2ggY29udGFpbnMgdGhlIGxvZ2dpbmcgZGF0YS4KICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBwYWNrZXQgaGFzIHRvIGJlIGEgVkFMSUQgcGFja2V0LCBhcyB0aGlzCiAgICAgICAgICAgICAgICAgICAgICAgIEFQSSB3aWxsIG5vdCBkbyBhbnkgY2hlY2tzIG9uIHRoZSB2YWxpZGl0eSBvZgogICAgICAgICAgICAgICAgICAgICAgICB0aGUgcGFja2V0LgoKICAgIFJldHVybjoKICAgICAgICBOT05FCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIHdwYWxMb2dQa3RTZXJpYWxpemUKKAogICB3cHRfcGFja2V0ICpwRnJhbWUKKQp7CiAgIFdESV9EU19SeE1ldGFJbmZvVHlwZSAqcFJ4TWV0YWRhdGE7CiAgIHZvaWQgICAgICAgICAgICAgICAgICAqcEJ1ZmZlcjsKICAgVk9TX1NUQVRVUyAgICAgICAgICAgICB2b3NTdGF0dXM7CgogICB2b3NTdGF0dXMgPSB2b3NfcGt0X3BlZWtfZGF0YShXUEFMX1RPX1ZPU19QS1QocEZyYW1lKSwgMCwgJnBCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdESV9EU19MT0dfUEtUX1RZUEVfTEVOKTsKCiAgIGlmIChWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgewogICAgICAvLyBhIFZBTElEIHBhY2tldCBpbXBsaWVzIG5vbiBOVUxMIG1ldGEtZGF0YQogICAgICBwUnhNZXRhZGF0YSA9IFdESV9EU19FeHRyYWN0UnhNZXRhRGF0YShwRnJhbWUpOwogICAgICBwUnhNZXRhZGF0YS0+bG9nZ2luZ0RhdGEgPSAqKCh3cHRfdWludDMyICopcEJ1ZmZlcik7CgogICAgICB3cGFsUGFja2V0UmF3VHJpbUhlYWQocEZyYW1lLCBXRElfRFNfTE9HX1BLVF9UWVBFX0xFTik7CgogICAgICB2b3NfbG9nZ2VyX3BrdF9zZXJpYWxpemUoV1BBTF9UT19WT1NfUEtUKHBGcmFtZSksIHBSeE1ldGFkYXRhLT5sb2dnaW5nRGF0YSk7CiAgIH0KICAgZWxzZQogICB7CiAgICAgIHZvc19wa3RfcmV0dXJuX3BhY2tldChXUEFMX1RPX1ZPU19QS1QocEZyYW1lKSk7CiAgIH0KfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxGd0xvZ1BrdFNlcmlhbGl6ZSAtIFNlcmlhbGl6ZSBMb2dnaW5nIGRhdGEgdG8gbG9nZ2VyIHRocmVhZAoKICAgIFBhcmFtOgogICAgd3B0X3BhY2tldCBwRnJhbWUgLSBUaGUgcGFja2V0IHdoaWNoIGNvbnRhaW5zIHRoZSBsb2dnaW5nIGRhdGEuCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgcGFja2V0IGhhcyB0byBiZSBhIFZBTElEIHBhY2tldCwgYXMgdGhpcwogICAgICAgICAgICAgICAgICAgICAgICBBUEkgd2lsbCBub3QgZG8gYW55IGNoZWNrcyBvbiB0aGUgdmFsaWRpdHkgb2YKICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHBhY2tldC4KCiAgICBSZXR1cm46CiAgICAgICAgTk9ORQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCB3cGFsRndMb2dQa3RTZXJpYWxpemUKKAogICB3cHRfcGFja2V0ICpwRnJhbWUsIHdwdF91aW50MzIgcGt0VHlwZQopCnsKICAgIHZvc19sb2dnZXJfcGt0X3NlcmlhbGl6ZShXUEFMX1RPX1ZPU19QS1QocEZyYW1lKSwgcGt0VHlwZSk7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBlclBrdFNlcmlhbGl6ZSAtIFNlcmlhbGl6ZSBwZXJwa3QgZGF0YSB0byBsb2dnZXIgdGhyZWFkCgogICAgUGFyYW06CgoKICAgIFJldHVybjoKICAgICAgICBOT05FCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIHdwYWxQZXJQa3RTZXJpYWxpemUKKAogICB2b2lkICpwZXJQa3RTdGF0CikKewogICB2b3NfcGVyX3BrdF9zdGF0c190b191c2VyKHBlclBrdFN0YXQpOwp9Cg==