Lyogb2JqLWV2YXguYyAtIEVWQVggKG9wZW5WTVMvQWxwaGEpIG9iamVjdCBmaWxlIGZvcm1hdC4KICAgQ29weXJpZ2h0IChDKSAxOTk2LTIwMTYgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCiAgIENvbnRyaWJ1dGVkIGJ5IEtsYXVzIEvkbXBmIChra2FlbXBmQHByb2dpcy5kZSkgb2YKICAgICBwcm9HSVMgU29mdHdhcmUsIEFhY2hlbiwgR2VybWFueS4KICAgRXh0ZW5zaXZlbHkgZW5oYW5jZWQgYnkgRG91Z2xhcyBSdXBwIG9mIEFkYUNvcmUuCgogICBUaGlzIGZpbGUgaXMgcGFydCBvZiBHQVMsIHRoZSBHTlUgQXNzZW1ibGVyCgogICBHQVMgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzLCBvciAoYXQgeW91ciBvcHRpb24pCiAgIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgR0FTIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgIGFsb25nIHdpdGggR0FTOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwgd3JpdGUgdG8KICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgNTEgRnJhbmtsaW4gU3RyZWV0IC0gRmlmdGggRmxvb3IsIEJvc3RvbiwKICAgTUEgMDIxMTAtMTMwMSwgVVNBLiAgKi8KCiNkZWZpbmUgT0JKX0hFQURFUiAib2JqLWV2YXguaCIKCiNpbmNsdWRlICJhcy5oIgojaW5jbHVkZSAiYmZkLmgiCiNpbmNsdWRlICJ2bXMuaCIKI2luY2x1ZGUgInN1YnNlZ3MuaCIKI2luY2x1ZGUgInN0cnVjLXN5bWJvbC5oIgojaW5jbHVkZSAic2FmZS1jdHlwZS5oIgoKc3RhdGljIHZvaWQgc19ldmF4X3dlYWsgKGludCk7CnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzIgKHVuc2lnbmVkIGNoYXIgKiwgaW50KTsKc3RhdGljIGNoYXIgKmVuY29kZV8zMiAodW5zaWduZWQgaW50KTsKc3RhdGljIGNoYXIgKmVuY29kZV8xNiAodW5zaWduZWQgaW50KTsKc3RhdGljIGludCBkZWNvZGVfMTYgKGNvbnN0IGNoYXIgKik7Cgpjb25zdCBwc2V1ZG9fdHlwZVMgb2JqX3BzZXVkb190YWJsZVtdID0KewogIHsgIndlYWsiLCBzX2V2YXhfd2VhaywgMH0sCiAgezAsIDAsIDB9LAp9OwkJCQkvKiBvYmpfcHNldWRvX3RhYmxlICovCgp2b2lkIG9ial9yZWFkX2JlZ2luX2hvb2sgKCkge30KCi8qIEhhbmRsZSB0aGUgd2VhayBzcGVjaWZpYyBwc2V1ZG8tb3AuICAqLwoKc3RhdGljIHZvaWQKc19ldmF4X3dlYWsgKGludCBpZ25vcmUgQVRUUklCVVRFX1VOVVNFRCkKewogIGNoYXIgKm5hbWU7CiAgaW50IGM7CiAgc3ltYm9sUyAqc3ltYm9sUDsKICBjaGFyICpzdG9wID0gTlVMTDsKICBjaGFyIHN0b3BjOwoKICBpZiAoZmxhZ19tcmkpCiAgICBzdG9wID0gbXJpX2NvbW1lbnRfZmllbGQgKCZzdG9wYyk7CgogIGRvCiAgICB7CiAgICAgIGMgPSBnZXRfc3ltYm9sX25hbWUgKCZuYW1lKTsKICAgICAgc3ltYm9sUCA9IHN5bWJvbF9maW5kX29yX21ha2UgKG5hbWUpOwogICAgICAodm9pZCkgcmVzdG9yZV9saW5lX3BvaW50ZXIgKGMpOwogICAgICBTS0lQX1dISVRFU1BBQ0UgKCk7CiAgICAgIFNfU0VUX1dFQUsgKHN5bWJvbFApOwogICAgICBpZiAoYyA9PSAnLCcpCgl7CgkgIGlucHV0X2xpbmVfcG9pbnRlcisrOwoJICBTS0lQX1dISVRFU1BBQ0UgKCk7CgkgIGlmICgqaW5wdXRfbGluZV9wb2ludGVyID09ICdcbicpCgkgICAgYyA9ICdcbic7Cgl9CiAgICB9CiAgd2hpbGUgKGMgPT0gJywnKTsKCiAgaWYgKGZsYWdfbXJpKQogICAgbXJpX2NvbW1lbnRfZW5kIChzdG9wLCBzdG9wYyk7CgogIGRlbWFuZF9lbXB0eV9yZXN0X29mX2xpbmUgKCk7Cn0KCnZvaWQKZXZheF9zeW1ib2xfbmV3X2hvb2sgKHN5bWJvbFMgKnN5bSkKewogIHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICp1ZGF0YTsKCiAgdWRhdGEgPSBYTkVXIChzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCk7CgogIHVkYXRhLT5ic3ltID0gc3ltYm9sX2dldF9iZmRzeW0gKHN5bSk7CiAgdWRhdGEtPmVuYnN5bSA9IE5VTEw7CiAgdWRhdGEtPm9yaWduYW1lID0geHN0cmR1cCAoU19HRVRfTkFNRSAoc3ltKSk7CiAgdWRhdGEtPmxraW5kZXggPSAwOwogIHN5bWJvbF9nZXRfYmZkc3ltKHN5bSktPnVkYXRhLnAgPSAoUFRSKSB1ZGF0YTsKfQoKdm9pZApldmF4X2Zyb2Jfc3ltYm9sIChzeW1ib2xTICpzeW0sIGludCAqcHVudCkKewogIGNvbnN0IGNoYXIgKnN5bW5hbWUgPSBTX0dFVF9OQU1FIChzeW0pOwogIGludCBzeW1sZW4gPSBzdHJsZW4gKHN5bW5hbWUpOwogIGFzeW1ib2wgKnN5bWJvbCA9IHN5bWJvbF9nZXRfYmZkc3ltIChzeW0pOwoKICBpZiAoc3ltbGVuID4gNAogICAgICAmJiBzdHJjbXAgKHN5bW5hbWUgKyBzeW1sZW4gLSA0LCAiLi5lbiIpID09IDAKICAgICAgJiYgU19HRVRfU0VHTUVOVCAoc3ltKSA9PSB1bmRlZmluZWRfc2VjdGlvbikKICAgIHsKICAgICAgc3ltYm9sX2NsZWFyX3VzZWRfaW5fcmVsb2MgKHN5bSk7CiAgICAgICpwdW50ID0gMTsKICAgIH0KCiAgZWxzZSBpZiAoKHN5bWJvbC0+ZmxhZ3MgJiBCU0ZfR0xPQkFMKSAmJiAoc3ltYm9sLT5mbGFncyAmIEJTRl9GVU5DVElPTikpCiAgICB7CiAgICAgIHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICp1ZGF0YQoJPSAoc3RydWN0IGV2YXhfcHJpdmF0ZV91ZGF0YV9zdHJ1Y3QgKilzeW1ib2wtPnVkYXRhLnA7CgogICAgICAvKiBGaXggdXAgZXF1YXRlcyBvZiBmdW5jdGlvbiBkZWZpbml0aW9ucy4gICovCiAgICAgIHdoaWxlICh1ZGF0YS0+ZW5ic3ltID09IE5VTEwpCgl7CgkgIC8qID8/PyBFcXVhdGVzIGhhdmUgYmVlbiByZXNvbHZlZCBhdCB0aGlzIHBvaW50IHNvIHRoZWlyCgkgICAgIGV4cHJlc3Npb24gaXMgT19jb25zdGFudDsgYnV0IHRoZXkgcHJldmlvdXNseSB3ZXJlCgkgICAgIE9fc3ltYm9sIGFuZCB3ZSBob3BlIHRoZSBlcXVhdGVkIHN5bWJvbCBpcyBzdGlsbCB0aGVyZS4gICovCgkgIHN5bSA9IHN5bWJvbF9nZXRfdmFsdWVfZXhwcmVzc2lvbiAoc3ltKS0+WF9hZGRfc3ltYm9sOwoJICBpZiAoc3ltID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBhc19iYWQgKF8oIm5vIGVudHJ5IHN5bWJvbCBmb3IgZ2xvYmFsIGZ1bmN0aW9uICclcyciKSwgc3ltbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgkgIHN5bWJvbCA9IHN5bWJvbF9nZXRfYmZkc3ltIChzeW0pOwoJICB1ZGF0YS0+ZW5ic3ltCgkgICAgPSAoKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopc3ltYm9sLT51ZGF0YS5wKS0+ZW5ic3ltOwoJfQogICAgfQp9Cgp2b2lkCmV2YXhfZnJvYl9maWxlX2JlZm9yZV9hZGp1c3QgKHZvaWQpCnsKICBzdHJ1Y3QgYWxwaGFfbGlua2FnZV9maXh1cHMgKmw7CiAgc2VnVCBjdXJyZW50X3NlY3Rpb24gPSBub3dfc2VnOwogIGludCBjdXJyZW50X3N1YnNlYyA9IG5vd19zdWJzZWc7CiAgc2VnbWVudF9pbmZvX3R5cGUgKnNlZ2luZm87CiAgaW50IGxpbmthZ2VfaW5kZXggPSAxOwoKICBzdWJzZWdfc2V0IChhbHBoYV9saW5rX3NlY3Rpb24sIDApOwogIHNlZ2luZm8gPSBzZWdfaW5mbyAoYWxwaGFfbGlua19zZWN0aW9uKTsKCiAgLyogSGFuZGxlIC5saW5rYWdlIGZpeHVwcy4gICovCiAgZm9yIChsID0gYWxwaGFfbGlua2FnZV9maXh1cF9yb290OyBsICE9IE5VTEw7IGwgPSBsLT5uZXh0KQogICAgewogICAgICBpZiAoU19HRVRfU0VHTUVOVCAobC0+Zml4cC0+ZnhfYWRkc3kpID09IGFscGhhX2xpbmtfc2VjdGlvbikKCXsKICAgICAgICAgIC8qIFRoZSBzeW1ib2wgaXMgZGVmaW5lZCBpbiB0aGUgZmlsZS4gIFRoZSBsaW5rYWdlIGVudHJ5IGRlY2F5cyB0bwogICAgICAgICAgICAgdHdvIHJlbG9jcy4gICovCgkgIHN5bWJvbFMgKmVudHJ5X3N5bTsKCSAgZml4UyAqZml4cGVudHJ5LCAqZml4cHBkZXNjLCAqZml4dGFpbDsKCgkgIGZpeHRhaWwgPSBzZWdpbmZvLT5maXhfdGFpbDsKCgkgIC8qIFJlcGxhY2UgdGhlIGxpbmthZ2Ugd2l0aCB0aGUgbG9jYWwgc3ltYm9scyAqLwoJICBlbnRyeV9zeW0gPSBzeW1ib2xfZmluZAoJICAgICgoKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopc3ltYm9sX2dldF9iZmRzeW0gKGwtPmZpeHAtPmZ4X2FkZHN5KS0+dWRhdGEucCktPmVuYnN5bS0+bmFtZSk7CgkgIGlmICghZW50cnlfc3ltKQoJICAgIGFib3J0ICgpOwoJICBmaXhwZW50cnkgPSBmaXhfbmV3IChsLT5maXhwLT5meF9mcmFnLCBsLT5maXhwLT5meF93aGVyZSwgOCwKCQkJICAgICAgIGVudHJ5X3N5bSwgbC0+Zml4cC0+Znhfb2Zmc2V0LCAwLAoJCQkgICAgICAgQkZEX1JFTE9DXzY0KTsKCSAgZml4cHBkZXNjID0gZml4X25ldyAobC0+Zml4cC0+ZnhfZnJhZywgbC0+Zml4cC0+Znhfd2hlcmUgKyA4LCA4LAoJCQkgICAgICAgbC0+Zml4cC0+ZnhfYWRkc3ksIGwtPmZpeHAtPmZ4X29mZnNldCwgMCwKCQkJICAgICAgIEJGRF9SRUxPQ182NCk7CgkgIGwtPmZpeHAtPmZ4X3NpemUgPSAwOwoJICBsLT5maXhwLT5meF9kb25lID0gMTsKCgkgIC8qIElmIG5vdCBhbHJlYWR5IGF0IHRoZSB0YWlsLCBzcGxpY2UgdGhlIG5ldyBmaXh1cHMgaW50bwoJICAgICB0aGUgY2hhaW4gcmlnaHQgYWZ0ZXIgdGhlIG9uZSB3ZSBhcmUgbnVsbGluZyBvdXQgKi8KCSAgaWYgKGZpeHRhaWwgIT0gbC0+Zml4cCkKCSAgICB7CgkgICAgICBmaXhwcGRlc2MtPmZ4X25leHQgPSBsLT5maXhwLT5meF9uZXh0OwoJICAgICAgbC0+Zml4cC0+ZnhfbmV4dCA9IGZpeHBlbnRyeTsKCSAgICAgIGZpeHRhaWwtPmZ4X25leHQgPSAwOwoJICAgICAgc2VnaW5mby0+Zml4X3RhaWwgPSBmaXh0YWlsOwoJICAgIH0KCX0KICAgICAgZWxzZQoJewogICAgICAgICAgLyogQXNzaWduIGEgbGlua2FnZSBpbmRleC4gICovCgkgICgoc3RydWN0IGV2YXhfcHJpdmF0ZV91ZGF0YV9zdHJ1Y3QgKikKCSAgIHN5bWJvbF9nZXRfYmZkc3ltIChsLT5sYWJlbCktPnVkYXRhLnApLT5sa2luZGV4ID0gbGlua2FnZV9pbmRleDsKCgkgIGwtPmZpeHAtPmZ4X2FkZG51bWJlciA9IGxpbmthZ2VfaW5kZXg7CgoJICBsaW5rYWdlX2luZGV4ICs9IDI7Cgl9CiAgICB9CgogIHN1YnNlZ19zZXQgKGN1cnJlbnRfc2VjdGlvbiwgY3VycmVudF9zdWJzZWMpOwp9Cgp2b2lkCmV2YXhfZnJvYl9maWxlX2JlZm9yZV9maXggKHZvaWQpCnsKICAvKiBOb3cgdGhhdCB0aGUgZml4dXBzIGFyZSBkb25lIGVhcmxpZXIsIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhlIHZhbHVlcwogICAgIGludG8gdGhlIEJGRCBzeW1ib2xzIGJlZm9yZSBjYWxsaW5nIGZpeF9zZWdtZW50IChpZGVhbGx5IHNob3VsZCBub3QKICAgICBiZSBkb25lIGFsc28gbGF0ZXIpLiAgKi8KICBpZiAoc3ltYm9sX3Jvb3RQKQogICAgewogICAgICBzeW1ib2xTICpzeW1wOwoKICAgICAgLyogU2V0IHRoZSB2YWx1ZSBpbnRvIHRoZSBCRkQgc3ltYm9sLiAgVXAgdGlsIG5vdyB0aGUgdmFsdWUKCSBoYXMgb25seSBiZWVuIGtlcHQgaW4gdGhlIGdhcyBzeW1ib2xTIHN0cnVjdC4gICovCiAgICAgIGZvciAoc3ltcCA9IHN5bWJvbF9yb290UDsgc3ltcDsgc3ltcCA9IHN5bWJvbF9uZXh0IChzeW1wKSkKCXN5bWJvbF9nZXRfYmZkc3ltIChzeW1wKS0+dmFsdWUgPSBTX0dFVF9WQUxVRSAoc3ltcCk7CiAgICB9Cn0KCi8qIFRoZSBsZW5ndGggaXMgY29tcHV0ZWQgZnJvbSB0aGUgbWF4aW11bSBhbGxvd2FibGUgbGVuZ3RoIG9mIDY0IGxlc3MgdGhlCiAgIDQgY2hhcmFjdGVyIC4ueHggZXh0ZW5zaW9uIHRoYXQgbXVzdCBiZSBwcmVzZXJ2ZWQgKHJlbW92ZWQgYmVmb3JlCiAgIGtydW5jaGluZyBhbmQgYXBwZW5kZWQgYmFjayBvbiBhZnRlcndhcmRzKS4gIFRoZSAkPG5ubj4uLiBwcmVmaXggaXMKICAgYWxzbyByZW1vdmVkIGFuZCBwcmVwZW5lZCBiYWNrIG9uLCBidXQgZG9lc24ndCBlbnRlciBpbnRvIHRoZSBsZW5ndGgKICAgY29tcHV0YXRpb24gYmVjYXVzZSBzeW1ib2xzIHdpdGggdGhhdCBwcmVmaXggYXJlIGFsd2F5cyByZXNvbHZlZAogICBieSB0aGUgYXNzZW1ibGVyIGFuZCB3aWxsIG5ldmVyIGFwcGVhciBpbiB0aGUgc3ltYm9sIHRhYmxlLiBBdCBsZWFzdAogICBJIGhvcGUgdGhhdCdzIHRydWUsIFRCRC4gICovCiNkZWZpbmUgTUFYX0xBQkVMX0xFTkdUSCA2MAoKc3RhdGljIGNoYXIgKnNob3J0ZW5faWRlbnRpZmllciAoY2hhciAqKTsKc3RhdGljIGludCBpc190cnVuY2F0ZWRfaWRlbnRpZmllciAoY2hhciAqKTsKCmNoYXIgKgpldmF4X3Nob3J0ZW5fbmFtZSAoY2hhciAqaWQpCnsKICBpbnQgcHJlZml4X2RvdGRvdCA9IDA7CiAgY2hhciBwcmVmaXggWzY0XTsKICBpbnQgbGVuID0gc3RybGVuIChpZCk7CiAgaW50IHN1ZmZpeF9kb3Rkb3QgPSBsZW47CiAgY2hhciBzdWZmaXggWzY0XTsKICBjaGFyICpiYXNlX2lkOwoKICAvKiBUaGlzIHRlc3QgbWF5IGJlIHRvbyBjb25zZXJ2YXRpdmUuICAqLwogIGlmIChsZW4gPD0gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHJldHVybiBpZDsKCiAgc3VmZml4IFswXSA9IDA7CiAgcHJlZml4IFswXSA9IDA7CgogIC8qIENoZWNrIGZvciAuLnh4IHN1ZmZpeCBhbmQgc2F2ZSBpdC4gICovCiAgaWYgKHN0cm5jbXAgKCZpZFtsZW4tNF0sICIuLiIsIDIpID09IDApCiAgICB7CiAgICAgIHN1ZmZpeF9kb3Rkb3QgPSBsZW4gLSA0OwogICAgICBzdHJuY3B5IChzdWZmaXgsICZpZFtsZW4tNF0sIDQpOwogICAgICBzdWZmaXggWzRdID0gMDsKICAgIH0KCiAgLyogQ2hlY2sgZm9yICQ8bm5uPi4uIHByZWZpeCBhbmQgc2F2ZSBpdC4gICovCiAgaWYgKChpZFswXSA9PSAnJCcpICYmIElTRElHSVQgKGlkWzFdKSkKICAgIHsKICAgICAgaW50IGk7CgogICAgICBmb3IgKGk9MjsgaSA8IGxlbjsgaSsrKQogICAgICAgIHsKCSAgaWYgKCFJU0RJR0lUIChpZFtpXSkpCiAgICAgICAgICAgIHsKCSAgICAgIGlmIChpZFtpXSA9PSAnLicgJiYgaWQgW2krMV0gPT0gJy4nKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIHByZWZpeF9kb3Rkb3QgPSBpKzI7CiAgICAgICAgICAgICAgICAgICBzdHJuY3B5IChwcmVmaXgsIGlkLCBwcmVmaXhfZG90ZG90KTsKICAgICAgICAgICAgICAgICAgIHByZWZpeCBbcHJlZml4X2RvdGRvdF0gPSAwOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogIC8qIFdlIG9ubHkgbmVlZCB3b3JyeSBhYm91dCBrcnVuY2hpbmcgdGhlIGJhc2Ugc3ltYm9sLiAgKi8KICBiYXNlX2lkID0geG1lbWR1cDAgKCZpZFtwcmVmaXhfZG90ZG90XSwgc3VmZml4X2RvdGRvdCAtIHByZWZpeF9kb3Rkb3QpOwoKICBpZiAoc3RybGVuIChiYXNlX2lkKSA+IE1BWF9MQUJFTF9MRU5HVEgpCiAgICB7CiAgICAgIGNoYXIgbmV3X2lkIFs0MDk2XTsKICAgICAgY2hhciAqcmV0dXJuX2lkOwoKICAgICAgc3RyY3B5IChuZXdfaWQsIGJhc2VfaWQpOwoKICAgICAgLyogU2hvcnRlbiBpdC4gICovCiAgICAgIHN0cmNweSAobmV3X2lkLCBzaG9ydGVuX2lkZW50aWZpZXIgKG5ld19pZCkpOwoKICAgICAgLyogUHJlcGVuZCBiYWNrIHRoZSBwcmVmaXggaWYgdGhlcmUgd2FzIG9uZS4gICovCiAgICAgIGlmIChwcmVmaXhfZG90ZG90KQogICAgICAgIHsKICAgICAgICAgIG1lbW1vdmUgKCZuZXdfaWQgW3ByZWZpeF9kb3Rkb3RdLCBuZXdfaWQsIHN0cmxlbiAobmV3X2lkKSArIDEpOwogICAgICAgICAgc3RybmNweSAobmV3X2lkLCBwcmVmaXgsIHByZWZpeF9kb3Rkb3QpOwogICAgICAgIH0KCiAgICAgIC8qIEFwcGVuZCBiYWNrIHRoZSBzdWZmaXggaWYgdGhlcmUgd2FzIG9uZS4gICovCiAgICAgIGlmIChzdHJsZW4gKHN1ZmZpeCkpCglzdHJjYXQgKG5ld19pZCwgc3VmZml4KTsKCiAgICAgIC8qIFNhdmUgaXQgb24gdGhlIGhlYXAgYW5kIHJldHVybi4gICovCiAgICAgIHJldHVybl9pZCA9IHhzdHJkdXAgKG5ld19pZCk7CgogICAgICByZXR1cm4gcmV0dXJuX2lkOwogICAgfQogIGVsc2UKICAgIHJldHVybiBpZDsKfQoKLyogVGhlIGNvZGUgYmVsb3cgaW1wbGVtZW50cyBhIG1lY2hhbmlzbSBmb3IgdHJ1bmNhdGluZyBsb25nCiAgIGlkZW50aWZpZXJzIHRvIGFuIGFyYml0cmFyeSBsZW5ndGggKHNldCBieSBNQVhfTEFCRUxfTEVOR1RIKS4KCiAgIEl0IGF0dGVtcHRzIHRvIG1ha2UgZWFjaCB0cnVuY2F0ZWQgaWRlbnRpZmllciB1bmlxdWUgYnkgcmVwbGFjaW5nCiAgIHBhcnQgb2YgdGhlIGlkZW50aWZpZXIgd2l0aCBhbiBlbmNvZGVkIDMyLWJpdCBDUkMgYW5kIGFuIGFzc29jaWF0ZWQKICAgY2hlY2tzdW0gKHRoZSBjaGVja3N1bSBpcyB1c2VkIGFzIGEgd2F5IHRvIGRldGVybWluZSB0aGF0IHRoZSBuYW1lCiAgIHdhcyB0cnVuY2F0ZWQpLgoKICAgTm90ZSB0aGF0IGJvdGggYSBwb3J0aW9uIG9mIHRoZSBzdGFydCBhbmQgb2YgdGhlIGVuZCBvZiB0aGUKICAgaWRlbnRpZmllciBtYXkgYmUga2VwdC4gIFRoZSBtYWNybyBJRF9TVUZGSVhfTEVOR1RIIHdpbGwgcmV0dXJuIHRoZQogICBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgc3VmZml4IG9mIHRoZSBpZGVudGlmaWVyIHRoYXQgc2hvdWxkIGJlCiAgIGtlcHQuCgogICBUaGUgcG9ydGlvbiBvZiB0aGUgaWRlbnRpZmllciB0aGF0IGlzIGdvaW5nIHRvIGJlIHJlbW92ZWQgaXMKICAgY2hlY2tzdW1tZWQuICBUaGUgY2hlY2tzdW0gaXMgdGhlbiBlbmNvZGVkIGFzIGEgNS1jaGFyYWN0ZXIgc3RyaW5nLAogICB0aGUgY2hhcmFjdGVycyBvZiB3aGljaCBhcmUgdGhlbiBzdW1tZWQuICBUaGlzIHN1bSBpcyB0aGVuIGVuY29kZWQKICAgYXMgYSAzLWNoYXJhY3RlciBzdHJpbmcuICBGaW5hbGx5LCB0aGUgb3JpZ2luYWwgbGVuZ3RoIG9mIHRoZQogICBpZGVudGlmaWVyIGlzIGVuY29kZWQgYXMgYSAzLWNoYXJhY3RlciBzdHJpbmcuCgogICBUaGVzZSB0aHJlZSBzdHJpbmdzIGFyZSB0aGVuIGNvbmNhdGVuYXRlZCB0b2dldGhlciAoYWxvbmcgd2l0aCBhbiBfaAogICB3aGljaCBmdXJ0aGVyIGRlc2lnbmF0ZXMgdGhhdCB0aGUgbmFtZSB3YXMgdHJ1bmNhdGVkKToKCiAgICJvcmlnaW5hbF9pZGVudGlmaWVyIl9oYWFhYWFiYmJjY2MKCiAgIGFhYWFhID0gMzItYml0IENSQwogICBiYmIgPSBsZW5ndGggb2Ygb3JpZ2luYWwgaWRlbnRpZmllcgogICBjY2MgPSBzdW0gb2YgMzItYml0IENSQyBjaGFyYWN0ZXJzCgogICBUaGUgcmVzdWx0aW5nIGlkZW50aWZpZXIgd2lsbCBiZSBNQVhfTEFCRUxfTEVOR1RIIGNoYXJhY3RlcnMgbG9uZy4KCiAgICovCgoKLyogVGFibGUgdXNlZCB0byBjb252ZXJ0IGFuIGludGVnZXIgaW50byBhIHN0cmluZy4gICovCgpzdGF0aWMgY29uc3QgY2hhciBjb2RpbmdzW10gPSB7CiAgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICdmJywgJ2cnLCAnaCcsICdpJywgJ2onLCAnaycsICdsJywgJ20nLCAnbicsICdvJywKICAncCcsICdxJywgJ3InLCAncycsICd0JywgJ3UnLCAndicsICd3JywgJ3gnLCAneScsICd6JywKICAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLCAnTScsICdOJywgJ08nLAogICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsICdZJywgJ1onLAogICcwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywgJ18nfTsKCi8qIFRoZSBudW1iZXIgb2YgY29kaW5ncyBpbiB0aGUgYWJvdmUgdGFibGUuICAqLwpzdGF0aWMgY29uc3QgaW50IG51bWJlcl9vZl9jb2RpbmdzID0gc2l6ZW9mIChjb2RpbmdzKSAvIHNpemVvZiAoY2hhcik7CgovKiBUYWJsZSB1c2VkIGJ5IGRlY29kZV8xNiAoKSB0byBjb252ZXJ0IGFuIGVuY29kZWQgc3RyaW5nIGJhY2sgaW50bwogICBhbiBpbnRlZ2VyLiAgKi8Kc3RhdGljIGNoYXIgZGVjb2RpbmdzWzI1Nl07CgovKiBUYWJsZSB1c2VkIGJ5IHRoZSBjcmMzMiBmdW5jdGlvbiB0byBjYWxjdWF0ZSB0aGUgY2hlY2tzdW0uICAqLwpzdGF0aWMgdW5zaWduZWQgaW50IGNyYzMyX3RhYmxlWzI1Nl0gPSB7MCwgMH07CgovKiBHaXZlbiBhIHN0cmluZyBpbiBCVUYsIGNhbGN1bGF0ZSBhIDMyLWJpdCBDUkMgZm9yIGl0LgoKICAgVGhpcyBpcyB1c2VkIGFzIGEgcmVhc29uYWJseSB1bmlxdWUgaGFzaCBmb3IgdGhlIGdpdmVuIHN0cmluZy4gICovCgpzdGF0aWMgdW5zaWduZWQgaW50CmNyYzMyICh1bnNpZ25lZCBjaGFyICpidWYsIGludCBsZW4pCnsKICB1bnNpZ25lZCBpbnQgY3JjID0gMHhmZmZmZmZmZjsKCiAgaWYgKCEgY3JjMzJfdGFibGVbMV0pCiAgICB7CiAgICAgIC8qIEluaXRpYWxpemUgdGhlIENSQyB0YWJsZSBhbmQgdGhlIGRlY29kaW5nIHRhYmxlLiAqLwogICAgICBpbnQgaSwgajsKICAgICAgdW5zaWduZWQgaW50IGM7CgogICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspCgl7CgkgIGZvciAoYyA9IGkgPDwgMjQsIGogPSA4OyBqID4gMDsgLS1qKQoJICAgIGMgPSBjICYgMHg4MDAwMDAwMCA/IChjIDw8IDEpIF4gMHgwNGMxMWRiNyA6IChjIDw8IDEpOwoJICBjcmMzMl90YWJsZVtpXSA9IGM7CgkgIGRlY29kaW5nc1tpXSA9IDA7Cgl9CiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1iZXJfb2ZfY29kaW5nczsgaSsrKQoJZGVjb2RpbmdzW2NvZGluZ3NbaV0gJiAyNTVdID0gaTsKICAgIH0KCiAgd2hpbGUgKGxlbi0tKQogICAgewogICAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjMzJfdGFibGVbKGNyYyA+PiAyNCkgXiAqYnVmXTsKICAgICAgYnVmKys7CiAgICB9CiAgcmV0dXJuIGNyYzsKfQoKLyogRW5jb2RlIHRoZSBsb3dlciAzMiBiaXRzIG9mIFZBTFVFIGFzIGEgNS1jaGFyYWN0ZXIgc3RyaW5nLiAgKi8KCnN0YXRpYyBjaGFyICoKZW5jb2RlXzMyICh1bnNpZ25lZCBpbnQgdmFsdWUpCnsKICBzdGF0aWMgY2hhciByZXNbNl07CiAgaW50IHg7CgogIHJlc1s1XSA9IDA7CiAgZm9yKHggPSAwOyB4IDwgNTsgeCsrKQogICAgewogICAgICByZXNbeF0gPSBjb2RpbmdzW3ZhbHVlICUgbnVtYmVyX29mX2NvZGluZ3NdOwogICAgICB2YWx1ZSA9IHZhbHVlIC8gbnVtYmVyX29mX2NvZGluZ3M7CiAgICB9CiAgcmV0dXJuIHJlczsKfQoKLyogRW5jb2RlIHRoZSBsb3dlciAxNiBiaXRzIG9mIFZBTFVFIGFzIGEgMy1jaGFyYWN0ZXIgc3RyaW5nLiAgKi8KCnN0YXRpYyBjaGFyICoKZW5jb2RlXzE2ICh1bnNpZ25lZCBpbnQgdmFsdWUpCnsKICBzdGF0aWMgY2hhciByZXNbNF07CiAgaW50IHg7CgogIHJlc1szXSA9IDA7CiAgZm9yKHggPSAwOyB4IDwgMzsgeCsrKQogICAgewogICAgICByZXNbeF0gPSBjb2RpbmdzW3ZhbHVlICUgbnVtYmVyX29mX2NvZGluZ3NdOwogICAgICB2YWx1ZSA9IHZhbHVlIC8gbnVtYmVyX29mX2NvZGluZ3M7CiAgICB9CiAgcmV0dXJuIHJlczsKfQoKLyogQ29udmVydCB0aGUgZW5jb2RlZCBzdHJpbmcgb2J0YWluZWQgZnJvbSBlbmNvZGVfMTYgKCkgYmFjayBpbnRvIGEKICAgMTYtYml0IGludGVnZXIuICAqLwoKc3RhdGljIGludApkZWNvZGVfMTYgKGNvbnN0IGNoYXIgKnN0cmluZykKewogIHJldHVybiBkZWNvZGluZ3NbKGludCkgc3RyaW5nWzJdXSAqIG51bWJlcl9vZl9jb2RpbmdzICogbnVtYmVyX29mX2NvZGluZ3MKICAgICsgZGVjb2RpbmdzWyhpbnQpIHN0cmluZ1sxXV0gKiBudW1iZXJfb2ZfY29kaW5ncwogICAgKyBkZWNvZGluZ3NbKGludCkgc3RyaW5nWzBdXTsKfQoKLyogSURfU1VGRklYX0xFTkdUSCBpcyB1c2VkIHRvIGRldGVybWluZSBob3cgbWFueSBjaGFyYWN0ZXJzIGluIHRoZQogICBzdWZmaXggb2YgdGhlIGlkZW50aWZpZXIgYXJlIHRvIGJlIHByZXNlcnZlZCwgaWYgYW55LiAgKi8KCiNpZm5kZWYgSURfU1VGRklYX0xFTkdUSAojZGVmaW5lIElEX1NVRkZJWF9MRU5HVEgoSUQpICgwKQojZW5kaWYKCi8qIFJldHVybiBhIHJlYXNvbmFibHktdW5pcXVlIHZlcnNpb24gb2YgTkFNRSB0aGF0IGlzIGxlc3MgdGhhbiBvcgogICBlcXVhbCB0byBNQVhfTEFCRUxfTEVOR1RIIGNoYXJhY3RlcnMgbG9uZy4gIFRoZSBzdHJpbmcgcmV0dXJuZWQgZnJvbQogICB0aGlzIGZ1bmN0aW9uIG1heSBiZSBhIGNvcHkgb2YgTkFNRTsgdGhlIGZ1bmN0aW9uIHdpbGwgbmV2ZXIKICAgYWN0dWFsbHkgbW9kaWZ5IHRoZSBjb250ZW50cyBvZiBOQU1FLiAgKi8KCnN0YXRpYyBjaGFyIG5ld25hbWVbTUFYX0xBQkVMX0xFTkdUSCArIDFdOwoKc3RhdGljIGNoYXIgKgpzaG9ydGVuX2lkZW50aWZpZXIgKGNoYXIgKm5hbWUpCnsKICBpbnQgY3JjLCBsZW4sIHN1bSwgeCwgZmluYWxfbGVuOwogIGNoYXIgKmNyY19jaGFyczsKICBpbnQgc3VmZml4X2xlbmd0aCA9IElEX1NVRkZJWF9MRU5HVEggKG5hbWUpOwoKICBpZiAoKGxlbiA9IHN0cmxlbiAobmFtZSkpIDw9IE1BWF9MQUJFTF9MRU5HVEgpCiAgICByZXR1cm4gbmFtZTsKCiAgZmluYWxfbGVuID0gTUFYX0xBQkVMX0xFTkdUSCAtIDIgLSA1IC0gMyAtIDMgLSBzdWZmaXhfbGVuZ3RoOwogIGNyYyA9IGNyYzMyICgodW5zaWduZWQgY2hhciAqKW5hbWUgKyBmaW5hbF9sZW4sCgkgICAgICAgbGVuIC0gZmluYWxfbGVuIC0gc3VmZml4X2xlbmd0aCk7CiAgY3JjX2NoYXJzID0gZW5jb2RlXzMyIChjcmMpOwogIHN1bSA9IDA7CiAgZm9yICh4ID0gMDsgeCA8IDU7IHgrKykKICAgIHN1bSArPSBjcmNfY2hhcnMgW3hdOwogIHN0cm5jcHkgKG5ld25hbWUsIG5hbWUsIGZpbmFsX2xlbik7CiAgbmV3bmFtZSBbTUFYX0xBQkVMX0xFTkdUSF0gPSAwOwogIC8qIE5vdyBhcHBlbmQgdGhlIHN1ZmZpeCBvZiB0aGUgb3JpZ2luYWwgaWRlbnRpZmllciwgaWYgYW55LiAgKi8KICBpZiAoc3VmZml4X2xlbmd0aCkKICBzdHJuY3B5IChuZXduYW1lICsgTUFYX0xBQkVMX0xFTkdUSCAtIHN1ZmZpeF9sZW5ndGgsCgkgICBuYW1lICsgbGVuIC0gc3VmZml4X2xlbmd0aCwKCSAgIHN1ZmZpeF9sZW5ndGgpOwogIHN0cm5jcHkgKG5ld25hbWUgKyBmaW5hbF9sZW4sICJfaCIsIDIpOwogIHN0cm5jcHkgKG5ld25hbWUgKyBmaW5hbF9sZW4gKyAyICwgY3JjX2NoYXJzLCA1KTsKICBzdHJuY3B5IChuZXduYW1lICsgZmluYWxfbGVuICsgMiArIDUsIGVuY29kZV8xNiAobGVuKSwgMyk7CiAgc3RybmNweSAobmV3bmFtZSArIGZpbmFsX2xlbiArIDIgKyA1ICsgMywgZW5jb2RlXzE2IChzdW0pLCAzKTsKICBpZiAoIWlzX3RydW5jYXRlZF9pZGVudGlmaWVyIChuZXduYW1lKSkKICAgIGFib3J0ICgpOwogIHJldHVybiBuZXduYW1lOwp9CgovKiBEZXRlcm1pbmUgd2hldGhlciBvciBub3QgSUQgaXMgYSB0cnVuY2F0ZWQgaWRlbnRpZmllciwgYW5kIHJldHVybiBhCiAgIG5vbi16ZXJvIHZhbHVlIGlmIGl0IGlzLiAgKi8KCnN0YXRpYyBpbnQKaXNfdHJ1bmNhdGVkX2lkZW50aWZpZXIgKGNoYXIgKmlkKQp7CiAgY2hhciAqcHRyOwogIGludCBsZW4gPSBzdHJsZW4gKGlkKTsKICAvKiBJZiBpdCdzIG5vdCBleGFjdGx5IE1BWF9MQUJFTF9MRU5HVEggY2hhcmFjdGVycyBsb25nLCBpdCBjYW4ndCBiZQogICAgIGEgdHJ1bmNhdGVkIGlkZW50aWZpZXIuICAqLwogIGlmIChsZW4gIT0gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHJldHVybiAwOwoKICAvKiBTdGFydCBzY2FubmluZyBiYWNrd2FyZHMgZm9yIGEgX2guICAqLwogIGxlbiA9IGxlbiAtIDMgLSAzIC0gNSAtIDI7CiAgcHRyID0gaWQgKyBsZW47CiAgd2hpbGUgKHB0ciA+PSBpZCkKICAgIHsKICAgICAgaWYgKHB0clswXSA9PSAnXycgJiYgcHRyWzFdID09ICdoJykKCXsKCSAgLyogTm93IHNlZSBpZiB0aGUgc3VtIGVuY29kZWQgaW4gdGhlIGlkZW50aWZlciBtYXRjaGVzLiAgKi8KCSAgaW50IHgsIHN1bTsKCSAgc3VtID0gMDsKCSAgZm9yICh4ID0gMDsgeCA8IDU7IHgrKykKCSAgICBzdW0gKz0gcHRyW3ggKyAyXTsKCSAgLyogSWYgaXQgbWF0Y2hlcywgdGhpcyBpcyBwcm9iYWJseSBhIHRydW5jYXRlZCBpZGVudGlmaWVyLiAgKi8KCSAgaWYgKHN1bSA9PSBkZWNvZGVfMTYgKHB0ciArIDUgKyAyICsgMykpCgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgIHB0ci0tOwogICAgfQogIHJldHVybiAwOwp9CgovKiBlbmQgb2Ygb2JqLWV2YXguYyAqLwo=