Lyogb2JqLWV2YXguYyAtIEVWQVggKG9wZW5WTVMvQWxwaGEpIG9iamVjdCBmaWxlIGZvcm1hdC4KICAgQ29weXJpZ2h0IDE5OTYsIDE5OTcsIDIwMDUsIDIwMDcsIDIwMDgsIDIwMDksIDIwMTAsIDIwMTEsIDIwMTIKICAgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCiAgIENvbnRyaWJ1dGVkIGJ5IEtsYXVzIEvkbXBmIChra2FlbXBmQHByb2dpcy5kZSkgb2YKICAgICBwcm9HSVMgU29mdHdhcmUsIEFhY2hlbiwgR2VybWFueS4KICAgRXh0ZW5zaXZlbHkgZW5oYW5jZWQgYnkgRG91Z2xhcyBSdXBwIG9mIEFkYUNvcmUuCgogICBUaGlzIGZpbGUgaXMgcGFydCBvZiBHQVMsIHRoZSBHTlUgQXNzZW1ibGVyCgogICBHQVMgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzLCBvciAoYXQgeW91ciBvcHRpb24pCiAgIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgR0FTIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgIGFsb25nIHdpdGggR0FTOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwgd3JpdGUgdG8KICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgNTEgRnJhbmtsaW4gU3RyZWV0IC0gRmlmdGggRmxvb3IsIEJvc3RvbiwKICAgTUEgMDIxMTAtMTMwMSwgVVNBLiAgKi8KCiNkZWZpbmUgT0JKX0hFQURFUiAib2JqLWV2YXguaCIKCiNpbmNsdWRlICJhcy5oIgojaW5jbHVkZSAiYmZkLmgiCiNpbmNsdWRlICJ2bXMuaCIKI2luY2x1ZGUgInN1YnNlZ3MuaCIKI2luY2x1ZGUgInN0cnVjLXN5bWJvbC5oIgojaW5jbHVkZSAic2FmZS1jdHlwZS5oIgoKc3RhdGljIHZvaWQgc19ldmF4X3dlYWsgKGludCk7CnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzIgKHVuc2lnbmVkIGNoYXIgKiwgaW50KTsKc3RhdGljIGNoYXIgKmVuY29kZV8zMiAodW5zaWduZWQgaW50KTsKc3RhdGljIGNoYXIgKmVuY29kZV8xNiAodW5zaWduZWQgaW50KTsKc3RhdGljIGludCBkZWNvZGVfMTYgKGNvbnN0IGNoYXIgKik7Cgpjb25zdCBwc2V1ZG9fdHlwZVMgb2JqX3BzZXVkb190YWJsZVtdID0KewogIHsgIndlYWsiLCBzX2V2YXhfd2VhaywgMH0sCiAgezAsIDAsIDB9LAp9OwkJCQkvKiBvYmpfcHNldWRvX3RhYmxlICovCgp2b2lkIG9ial9yZWFkX2JlZ2luX2hvb2sgKCkge30KCi8qIEhhbmRsZSB0aGUgd2VhayBzcGVjaWZpYyBwc2V1ZG8tb3AuICAqLwoKc3RhdGljIHZvaWQKc19ldmF4X3dlYWsgKGludCBpZ25vcmUgQVRUUklCVVRFX1VOVVNFRCkKewogIGNoYXIgKm5hbWU7CiAgaW50IGM7CiAgc3ltYm9sUyAqc3ltYm9sUDsKICBjaGFyICpzdG9wID0gTlVMTDsKICBjaGFyIHN0b3BjOwoKICBpZiAoZmxhZ19tcmkpCiAgICBzdG9wID0gbXJpX2NvbW1lbnRfZmllbGQgKCZzdG9wYyk7CgogIGRvCiAgICB7CiAgICAgIG5hbWUgPSBpbnB1dF9saW5lX3BvaW50ZXI7CiAgICAgIGMgPSBnZXRfc3ltYm9sX2VuZCAoKTsKICAgICAgc3ltYm9sUCA9IHN5bWJvbF9maW5kX29yX21ha2UgKG5hbWUpOwogICAgICAqaW5wdXRfbGluZV9wb2ludGVyID0gYzsKICAgICAgU0tJUF9XSElURVNQQUNFICgpOwogICAgICBTX1NFVF9XRUFLIChzeW1ib2xQKTsKICAgICAgaWYgKGMgPT0gJywnKQoJewoJICBpbnB1dF9saW5lX3BvaW50ZXIrKzsKCSAgU0tJUF9XSElURVNQQUNFICgpOwoJICBpZiAoKmlucHV0X2xpbmVfcG9pbnRlciA9PSAnXG4nKQoJICAgIGMgPSAnXG4nOwoJfQogICAgfQogIHdoaWxlIChjID09ICcsJyk7CgogIGlmIChmbGFnX21yaSkKICAgIG1yaV9jb21tZW50X2VuZCAoc3RvcCwgc3RvcGMpOwoKICBkZW1hbmRfZW1wdHlfcmVzdF9vZl9saW5lICgpOwp9Cgp2b2lkCmV2YXhfc3ltYm9sX25ld19ob29rIChzeW1ib2xTICpzeW0pCnsKICBzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCAqdWRhdGE7CgogIHVkYXRhID0gKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopCiAgICB4bWFsbG9jIChzaXplb2YgKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0KSk7CgogIHVkYXRhLT5ic3ltID0gc3ltYm9sX2dldF9iZmRzeW0gKHN5bSk7CiAgdWRhdGEtPmVuYnN5bSA9IE5VTEw7CiAgdWRhdGEtPm9yaWduYW1lID0geHN0cmR1cCAoU19HRVRfTkFNRSAoc3ltKSk7CiAgdWRhdGEtPmxraW5kZXggPSAwOwogIHN5bWJvbF9nZXRfYmZkc3ltKHN5bSktPnVkYXRhLnAgPSAoUFRSKSB1ZGF0YTsKfQoKdm9pZApldmF4X2Zyb2Jfc3ltYm9sIChzeW1ib2xTICpzeW0sIGludCAqcHVudCkKewogIGNvbnN0IGNoYXIgKnN5bW5hbWUgPSBTX0dFVF9OQU1FIChzeW0pOwogIGludCBzeW1sZW4gPSBzdHJsZW4gKHN5bW5hbWUpOwogIGFzeW1ib2wgKnN5bWJvbCA9IHN5bWJvbF9nZXRfYmZkc3ltIChzeW0pOwoKICBpZiAoc3ltbGVuID4gNAogICAgICAmJiBzdHJjbXAgKHN5bW5hbWUgKyBzeW1sZW4gLSA0LCAiLi5lbiIpID09IDAKICAgICAgJiYgU19HRVRfU0VHTUVOVCAoc3ltKSA9PSB1bmRlZmluZWRfc2VjdGlvbikKICAgIHsKICAgICAgc3ltYm9sX2NsZWFyX3VzZWRfaW5fcmVsb2MgKHN5bSk7CiAgICAgICpwdW50ID0gMTsKICAgIH0KCiAgZWxzZSBpZiAoKHN5bWJvbC0+ZmxhZ3MgJiBCU0ZfR0xPQkFMKSAmJiAoc3ltYm9sLT5mbGFncyAmIEJTRl9GVU5DVElPTikpCiAgICB7CiAgICAgIHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICp1ZGF0YQoJPSAoc3RydWN0IGV2YXhfcHJpdmF0ZV91ZGF0YV9zdHJ1Y3QgKilzeW1ib2wtPnVkYXRhLnA7CgogICAgICAvKiBGaXggdXAgZXF1YXRlcyBvZiBmdW5jdGlvbiBkZWZpbml0aW9ucy4gICovCiAgICAgIHdoaWxlICh1ZGF0YS0+ZW5ic3ltID09IE5VTEwpCgl7CgkgIC8qID8/PyBFcXVhdGVzIGhhdmUgYmVlbiByZXNvbHZlZCBhdCB0aGlzIHBvaW50IHNvIHRoZWlyCgkgICAgIGV4cHJlc3Npb24gaXMgT19jb25zdGFudDsgYnV0IHRoZXkgcHJldmlvdXNseSB3ZXJlCgkgICAgIE9fc3ltYm9sIGFuZCB3ZSBob3BlIHRoZSBlcXVhdGVkIHN5bWJvbCBpcyBzdGlsbCB0aGVyZS4gICovCgkgIHN5bSA9IHN5bWJvbF9nZXRfdmFsdWVfZXhwcmVzc2lvbiAoc3ltKS0+WF9hZGRfc3ltYm9sOwoJICBpZiAoc3ltID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBhc19iYWQgKF8oIm5vIGVudHJ5IHN5bWJvbCBmb3IgZ2xvYmFsIGZ1bmN0aW9uICclcyciKSwgc3ltbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgkgIHN5bWJvbCA9IHN5bWJvbF9nZXRfYmZkc3ltIChzeW0pOwoJICB1ZGF0YS0+ZW5ic3ltCgkgICAgPSAoKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopc3ltYm9sLT51ZGF0YS5wKS0+ZW5ic3ltOwoJfQogICAgfQp9Cgp2b2lkCmV2YXhfZnJvYl9maWxlX2JlZm9yZV9hZGp1c3QgKHZvaWQpCnsKICBzdHJ1Y3QgYWxwaGFfbGlua2FnZV9maXh1cHMgKmw7CiAgc2VnVCBjdXJyZW50X3NlY3Rpb24gPSBub3dfc2VnOwogIGludCBjdXJyZW50X3N1YnNlYyA9IG5vd19zdWJzZWc7CiAgc2VnbWVudF9pbmZvX3R5cGUgKnNlZ2luZm87CiAgaW50IGxpbmthZ2VfaW5kZXggPSAxOwoKICBzdWJzZWdfc2V0IChhbHBoYV9saW5rX3NlY3Rpb24sIDApOwogIHNlZ2luZm8gPSBzZWdfaW5mbyAoYWxwaGFfbGlua19zZWN0aW9uKTsKCiAgLyogSGFuZGxlIC5saW5rYWdlIGZpeHVwcy4gICovCiAgZm9yIChsID0gYWxwaGFfbGlua2FnZV9maXh1cF9yb290OyBsICE9IE5VTEw7IGwgPSBsLT5uZXh0KQogICAgewogICAgICBpZiAoU19HRVRfU0VHTUVOVCAobC0+Zml4cC0+ZnhfYWRkc3kpID09IGFscGhhX2xpbmtfc2VjdGlvbikKCXsKICAgICAgICAgIC8qIFRoZSBzeW1ib2wgaXMgZGVmaW5lZCBpbiB0aGUgZmlsZS4gIFRoZSBsaW5rYWdlIGVudHJ5IGRlY2F5cyB0bwogICAgICAgICAgICAgdHdvIHJlbG9jcy4gICovCgkgIHN5bWJvbFMgKmVudHJ5X3N5bTsKCSAgZml4UyAqZml4cGVudHJ5LCAqZml4cHBkZXNjLCAqZml4dGFpbDsKCgkgIGZpeHRhaWwgPSBzZWdpbmZvLT5maXhfdGFpbDsKCgkgIC8qIFJlcGxhY2UgdGhlIGxpbmthZ2Ugd2l0aCB0aGUgbG9jYWwgc3ltYm9scyAqLwoJICBlbnRyeV9zeW0gPSBzeW1ib2xfZmluZAoJICAgICgoKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopc3ltYm9sX2dldF9iZmRzeW0gKGwtPmZpeHAtPmZ4X2FkZHN5KS0+dWRhdGEucCktPmVuYnN5bS0+bmFtZSk7CgkgIGlmICghZW50cnlfc3ltKQoJICAgIGFib3J0ICgpOwoJICBmaXhwZW50cnkgPSBmaXhfbmV3IChsLT5maXhwLT5meF9mcmFnLCBsLT5maXhwLT5meF93aGVyZSwgOCwKCQkJICAgICAgIGVudHJ5X3N5bSwgbC0+Zml4cC0+Znhfb2Zmc2V0LCAwLAoJCQkgICAgICAgQkZEX1JFTE9DXzY0KTsKCSAgZml4cHBkZXNjID0gZml4X25ldyAobC0+Zml4cC0+ZnhfZnJhZywgbC0+Zml4cC0+Znhfd2hlcmUgKyA4LCA4LAoJCQkgICAgICAgbC0+Zml4cC0+ZnhfYWRkc3ksIGwtPmZpeHAtPmZ4X29mZnNldCwgMCwKCQkJICAgICAgIEJGRF9SRUxPQ182NCk7CgkgIGwtPmZpeHAtPmZ4X3NpemUgPSAwOwoJICBsLT5maXhwLT5meF9kb25lID0gMTsKCgkgIC8qIElmIG5vdCBhbHJlYWR5IGF0IHRoZSB0YWlsLCBzcGxpY2UgdGhlIG5ldyBmaXh1cHMgaW50bwoJICAgICB0aGUgY2hhaW4gcmlnaHQgYWZ0ZXIgdGhlIG9uZSB3ZSBhcmUgbnVsbGluZyBvdXQgKi8KCSAgaWYgKGZpeHRhaWwgIT0gbC0+Zml4cCkKCSAgICB7CgkgICAgICBmaXhwcGRlc2MtPmZ4X25leHQgPSBsLT5maXhwLT5meF9uZXh0OwoJICAgICAgbC0+Zml4cC0+ZnhfbmV4dCA9IGZpeHBlbnRyeTsKCSAgICAgIGZpeHRhaWwtPmZ4X25leHQgPSAwOwoJICAgICAgc2VnaW5mby0+Zml4X3RhaWwgPSBmaXh0YWlsOwoJICAgIH0KCX0KICAgICAgZWxzZQoJewogICAgICAgICAgLyogQXNzaWduIGEgbGlua2FnZSBpbmRleC4gICovCgkgICgoc3RydWN0IGV2YXhfcHJpdmF0ZV91ZGF0YV9zdHJ1Y3QgKikKCSAgIHN5bWJvbF9nZXRfYmZkc3ltIChsLT5sYWJlbCktPnVkYXRhLnApLT5sa2luZGV4ID0gbGlua2FnZV9pbmRleDsKCgkgIGwtPmZpeHAtPmZ4X2FkZG51bWJlciA9IGxpbmthZ2VfaW5kZXg7CgoJICBsaW5rYWdlX2luZGV4ICs9IDI7Cgl9CiAgICB9CgogIHN1YnNlZ19zZXQgKGN1cnJlbnRfc2VjdGlvbiwgY3VycmVudF9zdWJzZWMpOwp9Cgp2b2lkCmV2YXhfZnJvYl9maWxlX2JlZm9yZV9maXggKHZvaWQpCnsKICAvKiBOb3cgdGhhdCB0aGUgZml4dXBzIGFyZSBkb25lIGVhcmxpZXIsIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhlIHZhbHVlcwogICAgIGludG8gdGhlIEJGRCBzeW1ib2xzIGJlZm9yZSBjYWxsaW5nIGZpeF9zZWdtZW50IChpZGVhbGx5IHNob3VsZCBub3QKICAgICBiZSBkb25lIGFsc28gbGF0ZXIpLiAgKi8KICBpZiAoc3ltYm9sX3Jvb3RQKQogICAgewogICAgICBzeW1ib2xTICpzeW1wOwoKICAgICAgLyogU2V0IHRoZSB2YWx1ZSBpbnRvIHRoZSBCRkQgc3ltYm9sLiAgVXAgdGlsIG5vdyB0aGUgdmFsdWUKCSBoYXMgb25seSBiZWVuIGtlcHQgaW4gdGhlIGdhcyBzeW1ib2xTIHN0cnVjdC4gICovCiAgICAgIGZvciAoc3ltcCA9IHN5bWJvbF9yb290UDsgc3ltcDsgc3ltcCA9IHN5bWJvbF9uZXh0IChzeW1wKSkKCXN5bWJvbF9nZXRfYmZkc3ltIChzeW1wKS0+dmFsdWUgPSBTX0dFVF9WQUxVRSAoc3ltcCk7CiAgICB9Cn0KCi8qIFRoZSBsZW5ndGggaXMgY29tcHV0ZWQgZnJvbSB0aGUgbWF4aW11bSBhbGxvd2FibGUgbGVuZ3RoIG9mIDY0IGxlc3MgdGhlCiAgIDQgY2hhcmFjdGVyIC4ueHggZXh0ZW5zaW9uIHRoYXQgbXVzdCBiZSBwcmVzZXJ2ZWQgKHJlbW92ZWQgYmVmb3JlCiAgIGtydW5jaGluZyBhbmQgYXBwZW5kZWQgYmFjayBvbiBhZnRlcndhcmRzKS4gIFRoZSAkPG5ubj4uLiBwcmVmaXggaXMKICAgYWxzbyByZW1vdmVkIGFuZCBwcmVwZW5lZCBiYWNrIG9uLCBidXQgZG9lc24ndCBlbnRlciBpbnRvIHRoZSBsZW5ndGgKICAgY29tcHV0YXRpb24gYmVjYXVzZSBzeW1ib2xzIHdpdGggdGhhdCBwcmVmaXggYXJlIGFsd2F5cyByZXNvbHZlZAogICBieSB0aGUgYXNzZW1ibGVyIGFuZCB3aWxsIG5ldmVyIGFwcGVhciBpbiB0aGUgc3ltYm9sIHRhYmxlLiBBdCBsZWFzdAogICBJIGhvcGUgdGhhdCdzIHRydWUsIFRCRC4gICovCiNkZWZpbmUgTUFYX0xBQkVMX0xFTkdUSCA2MAoKc3RhdGljIGNoYXIgKnNob3J0ZW5faWRlbnRpZmllciAoY2hhciAqKTsKc3RhdGljIGludCBpc190cnVuY2F0ZWRfaWRlbnRpZmllciAoY2hhciAqKTsKCmNoYXIgKgpldmF4X3Nob3J0ZW5fbmFtZSAoY2hhciAqaWQpCnsKICBpbnQgcHJlZml4X2RvdGRvdCA9IDA7CiAgY2hhciBwcmVmaXggWzY0XTsKICBpbnQgbGVuID0gc3RybGVuIChpZCk7CiAgaW50IHN1ZmZpeF9kb3Rkb3QgPSBsZW47CiAgY2hhciBzdWZmaXggWzY0XTsKICBjaGFyICpiYXNlX2lkOwoKICAvKiBUaGlzIHRlc3QgbWF5IGJlIHRvbyBjb25zZXJ2YXRpdmUuICAqLwogIGlmIChsZW4gPD0gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHJldHVybiBpZDsKCiAgc3VmZml4IFswXSA9IDA7CiAgcHJlZml4IFswXSA9IDA7CgogIC8qIENoZWNrIGZvciAuLnh4IHN1ZmZpeCBhbmQgc2F2ZSBpdC4gICovCiAgaWYgKHN0cm5jbXAgKCZpZFtsZW4tNF0sICIuLiIsIDIpID09IDApCiAgICB7CiAgICAgIHN1ZmZpeF9kb3Rkb3QgPSBsZW4gLSA0OwogICAgICBzdHJuY3B5IChzdWZmaXgsICZpZFtsZW4tNF0sIDQpOwogICAgICBzdWZmaXggWzRdID0gMDsKICAgIH0KCiAgLyogQ2hlY2sgZm9yICQ8bm5uPi4uIHByZWZpeCBhbmQgc2F2ZSBpdC4gICovCiAgaWYgKChpZFswXSA9PSAnJCcpICYmIElTRElHSVQgKGlkWzFdKSkKICAgIHsKICAgICAgaW50IGk7CgogICAgICBmb3IgKGk9MjsgaSA8IGxlbjsgaSsrKQogICAgICAgIHsKCSAgaWYgKCFJU0RJR0lUIChpZFtpXSkpCiAgICAgICAgICAgIHsKCSAgICAgIGlmIChpZFtpXSA9PSAnLicgJiYgaWQgW2krMV0gPT0gJy4nKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIHByZWZpeF9kb3Rkb3QgPSBpKzI7CiAgICAgICAgICAgICAgICAgICBzdHJuY3B5IChwcmVmaXgsIGlkLCBwcmVmaXhfZG90ZG90KTsKICAgICAgICAgICAgICAgICAgIHByZWZpeCBbcHJlZml4X2RvdGRvdF0gPSAwOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogIC8qIFdlIG9ubHkgbmVlZCB3b3JyeSBhYm91dCBrcnVuY2hpbmcgdGhlIGJhc2Ugc3ltYm9sLiAgKi8KICBiYXNlX2lkID0geG1hbGxvYyAoc3VmZml4X2RvdGRvdCAtIHByZWZpeF9kb3Rkb3QgKyAxKTsKICBzdHJuY3B5IChiYXNlX2lkLCAmaWRbcHJlZml4X2RvdGRvdF0sIHN1ZmZpeF9kb3Rkb3QgLSBwcmVmaXhfZG90ZG90KTsKICBiYXNlX2lkIFtzdWZmaXhfZG90ZG90IC0gcHJlZml4X2RvdGRvdF0gPSAwOwoKICBpZiAoc3RybGVuIChiYXNlX2lkKSA+IE1BWF9MQUJFTF9MRU5HVEgpCiAgICB7CiAgICAgIGNoYXIgbmV3X2lkIFs0MDk2XTsKICAgICAgY2hhciAqcmV0dXJuX2lkOwoKICAgICAgc3RyY3B5IChuZXdfaWQsIGJhc2VfaWQpOwoKICAgICAgLyogU2hvcnRlbiBpdC4gICovCiAgICAgIHN0cmNweSAobmV3X2lkLCBzaG9ydGVuX2lkZW50aWZpZXIgKG5ld19pZCkpOwoKICAgICAgLyogUHJlcGVuZCBiYWNrIHRoZSBwcmVmaXggaWYgdGhlcmUgd2FzIG9uZS4gICovCiAgICAgIGlmIChwcmVmaXhfZG90ZG90KQogICAgICAgIHsKICAgICAgICAgIG1lbW1vdmUgKCZuZXdfaWQgW3ByZWZpeF9kb3Rkb3RdLCBuZXdfaWQsIHN0cmxlbiAobmV3X2lkKSArIDEpOwogICAgICAgICAgc3RybmNweSAobmV3X2lkLCBwcmVmaXgsIHByZWZpeF9kb3Rkb3QpOwogICAgICAgIH0KCiAgICAgIC8qIEFwcGVuZCBiYWNrIHRoZSBzdWZmaXggaWYgdGhlcmUgd2FzIG9uZS4gICovCiAgICAgIGlmIChzdHJsZW4gKHN1ZmZpeCkpCglzdHJjYXQgKG5ld19pZCwgc3VmZml4KTsKCiAgICAgIC8qIFNhdmUgaXQgb24gdGhlIGhlYXAgYW5kIHJldHVybi4gICovCiAgICAgIHJldHVybl9pZCA9IHhtYWxsb2MgKHN0cmxlbiAobmV3X2lkKSArIDEpOwogICAgICBzdHJjcHkgKHJldHVybl9pZCwgbmV3X2lkKTsKCiAgICAgIHJldHVybiByZXR1cm5faWQ7CiAgICB9CiAgZWxzZQogICAgcmV0dXJuIGlkOwp9CgovKiBUaGUgY29kZSBiZWxvdyBpbXBsZW1lbnRzIGEgbWVjaGFuaXNtIGZvciB0cnVuY2F0aW5nIGxvbmcKICAgaWRlbnRpZmllcnMgdG8gYW4gYXJiaXRyYXJ5IGxlbmd0aCAoc2V0IGJ5IE1BWF9MQUJFTF9MRU5HVEgpLgoKICAgSXQgYXR0ZW1wdHMgdG8gbWFrZSBlYWNoIHRydW5jYXRlZCBpZGVudGlmaWVyIHVuaXF1ZSBieSByZXBsYWNpbmcKICAgcGFydCBvZiB0aGUgaWRlbnRpZmllciB3aXRoIGFuIGVuY29kZWQgMzItYml0IENSQyBhbmQgYW4gYXNzb2NpYXRlZAogICBjaGVja3N1bSAodGhlIGNoZWNrc3VtIGlzIHVzZWQgYXMgYSB3YXkgdG8gZGV0ZXJtaW5lIHRoYXQgdGhlIG5hbWUKICAgd2FzIHRydW5jYXRlZCkuCgogICBOb3RlIHRoYXQgYm90aCBhIHBvcnRpb24gb2YgdGhlIHN0YXJ0IGFuZCBvZiB0aGUgZW5kIG9mIHRoZQogICBpZGVudGlmaWVyIG1heSBiZSBrZXB0LiAgVGhlIG1hY3JvIElEX1NVRkZJWF9MRU5HVEggd2lsbCByZXR1cm4gdGhlCiAgIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBzdWZmaXggb2YgdGhlIGlkZW50aWZpZXIgdGhhdCBzaG91bGQgYmUKICAga2VwdC4KCiAgIFRoZSBwb3J0aW9uIG9mIHRoZSBpZGVudGlmaWVyIHRoYXQgaXMgZ29pbmcgdG8gYmUgcmVtb3ZlZCBpcwogICBjaGVja3N1bW1lZC4gIFRoZSBjaGVja3N1bSBpcyB0aGVuIGVuY29kZWQgYXMgYSA1LWNoYXJhY3RlciBzdHJpbmcsCiAgIHRoZSBjaGFyYWN0ZXJzIG9mIHdoaWNoIGFyZSB0aGVuIHN1bW1lZC4gIFRoaXMgc3VtIGlzIHRoZW4gZW5jb2RlZAogICBhcyBhIDMtY2hhcmFjdGVyIHN0cmluZy4gIEZpbmFsbHksIHRoZSBvcmlnaW5hbCBsZW5ndGggb2YgdGhlCiAgIGlkZW50aWZpZXIgaXMgZW5jb2RlZCBhcyBhIDMtY2hhcmFjdGVyIHN0cmluZy4KCiAgIFRoZXNlIHRocmVlIHN0cmluZ3MgYXJlIHRoZW4gY29uY2F0ZW5hdGVkIHRvZ2V0aGVyIChhbG9uZyB3aXRoIGFuIF9oCiAgIHdoaWNoIGZ1cnRoZXIgZGVzaWduYXRlcyB0aGF0IHRoZSBuYW1lIHdhcyB0cnVuY2F0ZWQpOgoKICAgIm9yaWdpbmFsX2lkZW50aWZpZXIiX2hhYWFhYWJiYmNjYwogICAKICAgYWFhYWEgPSAzMi1iaXQgQ1JDCiAgIGJiYiA9IGxlbmd0aCBvZiBvcmlnaW5hbCBpZGVudGlmaWVyCiAgIGNjYyA9IHN1bSBvZiAzMi1iaXQgQ1JDIGNoYXJhY3RlcnMKCiAgIFRoZSByZXN1bHRpbmcgaWRlbnRpZmllciB3aWxsIGJlIE1BWF9MQUJFTF9MRU5HVEggY2hhcmFjdGVycyBsb25nLgoKICAgKi8KCgovKiBUYWJsZSB1c2VkIHRvIGNvbnZlcnQgYW4gaW50ZWdlciBpbnRvIGEgc3RyaW5nLiAgKi8KCnN0YXRpYyBjb25zdCBjaGFyIGNvZGluZ3NbXSA9IHsKICAnYScsICdiJywgJ2MnLCAnZCcsICdlJywgJ2YnLCAnZycsICdoJywgJ2knLCAnaicsICdrJywgJ2wnLCAnbScsICduJywgJ28nLAogICdwJywgJ3EnLCAncicsICdzJywgJ3QnLCAndScsICd2JywgJ3cnLCAneCcsICd5JywgJ3onLAogICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsICdNJywgJ04nLCAnTycsCiAgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywgJ1knLCAnWicsCiAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLCAnXyd9OwoKLyogVGhlIG51bWJlciBvZiBjb2RpbmdzIGluIHRoZSBhYm92ZSB0YWJsZS4gICovCnN0YXRpYyBjb25zdCBpbnQgbnVtYmVyX29mX2NvZGluZ3MgPSBzaXplb2YgKGNvZGluZ3MpIC8gc2l6ZW9mIChjaGFyKTsKCi8qIFRhYmxlIHVzZWQgYnkgZGVjb2RlXzE2ICgpIHRvIGNvbnZlcnQgYW4gZW5jb2RlZCBzdHJpbmcgYmFjayBpbnRvCiAgIGFuIGludGVnZXIuICAqLwpzdGF0aWMgY2hhciBkZWNvZGluZ3NbMjU2XTsKCi8qIFRhYmxlIHVzZWQgYnkgdGhlIGNyYzMyIGZ1bmN0aW9uIHRvIGNhbGN1YXRlIHRoZSBjaGVja3N1bS4gICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzJfdGFibGVbMjU2XSA9IHswLCAwfTsKCi8qIEdpdmVuIGEgc3RyaW5nIGluIEJVRiwgY2FsY3VsYXRlIGEgMzItYml0IENSQyBmb3IgaXQuIAoKICAgVGhpcyBpcyB1c2VkIGFzIGEgcmVhc29uYWJseSB1bmlxdWUgaGFzaCBmb3IgdGhlIGdpdmVuIHN0cmluZy4gICovCgpzdGF0aWMgdW5zaWduZWQgaW50CmNyYzMyICh1bnNpZ25lZCBjaGFyICpidWYsIGludCBsZW4pCnsKICB1bnNpZ25lZCBpbnQgY3JjID0gMHhmZmZmZmZmZjsKCiAgaWYgKCEgY3JjMzJfdGFibGVbMV0pCiAgICB7CiAgICAgIC8qIEluaXRpYWxpemUgdGhlIENSQyB0YWJsZSBhbmQgdGhlIGRlY29kaW5nIHRhYmxlLiAqLwogICAgICBpbnQgaSwgajsKICAgICAgdW5zaWduZWQgaW50IGM7CgogICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspCgl7CgkgIGZvciAoYyA9IGkgPDwgMjQsIGogPSA4OyBqID4gMDsgLS1qKQoJICAgIGMgPSBjICYgMHg4MDAwMDAwMCA/IChjIDw8IDEpIF4gMHgwNGMxMWRiNyA6IChjIDw8IDEpOwoJICBjcmMzMl90YWJsZVtpXSA9IGM7CgkgIGRlY29kaW5nc1tpXSA9IDA7Cgl9CiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1iZXJfb2ZfY29kaW5nczsgaSsrKQoJZGVjb2RpbmdzW2NvZGluZ3NbaV0gJiAyNTVdID0gaTsKICAgIH0KCiAgd2hpbGUgKGxlbi0tKQogICAgewogICAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjMzJfdGFibGVbKGNyYyA+PiAyNCkgXiAqYnVmXTsKICAgICAgYnVmKys7CiAgICB9CiAgcmV0dXJuIGNyYzsKfQoKLyogRW5jb2RlIHRoZSBsb3dlciAzMiBiaXRzIG9mIFZBTFVFIGFzIGEgNS1jaGFyYWN0ZXIgc3RyaW5nLiAgKi8KCnN0YXRpYyBjaGFyICoKZW5jb2RlXzMyICh1bnNpZ25lZCBpbnQgdmFsdWUpCnsKICBzdGF0aWMgY2hhciByZXNbNl07CiAgaW50IHg7CgogIHJlc1s1XSA9IDA7CiAgZm9yKHggPSAwOyB4IDwgNTsgeCsrKQogICAgewogICAgICByZXNbeF0gPSBjb2RpbmdzW3ZhbHVlICUgbnVtYmVyX29mX2NvZGluZ3NdOwogICAgICB2YWx1ZSA9IHZhbHVlIC8gbnVtYmVyX29mX2NvZGluZ3M7CiAgICB9CiAgcmV0dXJuIHJlczsKfQoKLyogRW5jb2RlIHRoZSBsb3dlciAxNiBiaXRzIG9mIFZBTFVFIGFzIGEgMy1jaGFyYWN0ZXIgc3RyaW5nLiAgKi8KCnN0YXRpYyBjaGFyICoKZW5jb2RlXzE2ICh1bnNpZ25lZCBpbnQgdmFsdWUpCnsKICBzdGF0aWMgY2hhciByZXNbNF07CiAgaW50IHg7CgogIHJlc1szXSA9IDA7CiAgZm9yKHggPSAwOyB4IDwgMzsgeCsrKQogICAgewogICAgICByZXNbeF0gPSBjb2RpbmdzW3ZhbHVlICUgbnVtYmVyX29mX2NvZGluZ3NdOwogICAgICB2YWx1ZSA9IHZhbHVlIC8gbnVtYmVyX29mX2NvZGluZ3M7CiAgICB9CiAgcmV0dXJuIHJlczsKfQoKLyogQ29udmVydCB0aGUgZW5jb2RlZCBzdHJpbmcgb2J0YWluZWQgZnJvbSBlbmNvZGVfMTYgKCkgYmFjayBpbnRvIGEKICAgMTYtYml0IGludGVnZXIuICAqLwoKc3RhdGljIGludApkZWNvZGVfMTYgKGNvbnN0IGNoYXIgKnN0cmluZykKewogIHJldHVybiBkZWNvZGluZ3NbKGludCkgc3RyaW5nWzJdXSAqIG51bWJlcl9vZl9jb2RpbmdzICogbnVtYmVyX29mX2NvZGluZ3MKICAgICsgZGVjb2RpbmdzWyhpbnQpIHN0cmluZ1sxXV0gKiBudW1iZXJfb2ZfY29kaW5ncwogICAgKyBkZWNvZGluZ3NbKGludCkgc3RyaW5nWzBdXTsKfQoKLyogSURfU1VGRklYX0xFTkdUSCBpcyB1c2VkIHRvIGRldGVybWluZSBob3cgbWFueSBjaGFyYWN0ZXJzIGluIHRoZQogICBzdWZmaXggb2YgdGhlIGlkZW50aWZpZXIgYXJlIHRvIGJlIHByZXNlcnZlZCwgaWYgYW55LiAgKi8KCiNpZm5kZWYgSURfU1VGRklYX0xFTkdUSAojZGVmaW5lIElEX1NVRkZJWF9MRU5HVEgoSUQpICgwKQojZW5kaWYKCi8qIFJldHVybiBhIHJlYXNvbmFibHktdW5pcXVlIHZlcnNpb24gb2YgTkFNRSB0aGF0IGlzIGxlc3MgdGhhbiBvcgogICBlcXVhbCB0byBNQVhfTEFCRUxfTEVOR1RIIGNoYXJhY3RlcnMgbG9uZy4gIFRoZSBzdHJpbmcgcmV0dXJuZWQgZnJvbQogICB0aGlzIGZ1bmN0aW9uIG1heSBiZSBhIGNvcHkgb2YgTkFNRTsgdGhlIGZ1bmN0aW9uIHdpbGwgbmV2ZXIKICAgYWN0dWFsbHkgbW9kaWZ5IHRoZSBjb250ZW50cyBvZiBOQU1FLiAgKi8KCnN0YXRpYyBjaGFyIG5ld25hbWVbTUFYX0xBQkVMX0xFTkdUSCArIDFdOwoKc3RhdGljIGNoYXIgKgpzaG9ydGVuX2lkZW50aWZpZXIgKGNoYXIgKm5hbWUpCnsKICBpbnQgY3JjLCBsZW4sIHN1bSwgeCwgZmluYWxfbGVuOwogIGNoYXIgKmNyY19jaGFyczsKICBpbnQgc3VmZml4X2xlbmd0aCA9IElEX1NVRkZJWF9MRU5HVEggKG5hbWUpOwoKICBpZiAoKGxlbiA9IHN0cmxlbiAobmFtZSkpIDw9IE1BWF9MQUJFTF9MRU5HVEgpCiAgICByZXR1cm4gbmFtZTsKCiAgZmluYWxfbGVuID0gTUFYX0xBQkVMX0xFTkdUSCAtIDIgLSA1IC0gMyAtIDMgLSBzdWZmaXhfbGVuZ3RoOwogIGNyYyA9IGNyYzMyICgodW5zaWduZWQgY2hhciAqKW5hbWUgKyBmaW5hbF9sZW4sCgkgICAgICAgbGVuIC0gZmluYWxfbGVuIC0gc3VmZml4X2xlbmd0aCk7CiAgY3JjX2NoYXJzID0gZW5jb2RlXzMyIChjcmMpOwogIHN1bSA9IDA7CiAgZm9yICh4ID0gMDsgeCA8IDU7IHgrKykKICAgIHN1bSArPSBjcmNfY2hhcnMgW3hdOwogIHN0cm5jcHkgKG5ld25hbWUsIG5hbWUsIGZpbmFsX2xlbik7CiAgbmV3bmFtZSBbTUFYX0xBQkVMX0xFTkdUSF0gPSAwOwogIC8qIE5vdyBhcHBlbmQgdGhlIHN1ZmZpeCBvZiB0aGUgb3JpZ2luYWwgaWRlbnRpZmllciwgaWYgYW55LiAgKi8KICBpZiAoc3VmZml4X2xlbmd0aCkKICBzdHJuY3B5IChuZXduYW1lICsgTUFYX0xBQkVMX0xFTkdUSCAtIHN1ZmZpeF9sZW5ndGgsCgkgICBuYW1lICsgbGVuIC0gc3VmZml4X2xlbmd0aCwKCSAgIHN1ZmZpeF9sZW5ndGgpOwogIHN0cm5jcHkgKG5ld25hbWUgKyBmaW5hbF9sZW4sICJfaCIsIDIpOwogIHN0cm5jcHkgKG5ld25hbWUgKyBmaW5hbF9sZW4gKyAyICwgY3JjX2NoYXJzLCA1KTsKICBzdHJuY3B5IChuZXduYW1lICsgZmluYWxfbGVuICsgMiArIDUsIGVuY29kZV8xNiAobGVuKSwgMyk7CiAgc3RybmNweSAobmV3bmFtZSArIGZpbmFsX2xlbiArIDIgKyA1ICsgMywgZW5jb2RlXzE2IChzdW0pLCAzKTsKICBpZiAoIWlzX3RydW5jYXRlZF9pZGVudGlmaWVyIChuZXduYW1lKSkKICAgIGFib3J0ICgpOwogIHJldHVybiBuZXduYW1lOwp9CgovKiBEZXRlcm1pbmUgd2hldGhlciBvciBub3QgSUQgaXMgYSB0cnVuY2F0ZWQgaWRlbnRpZmllciwgYW5kIHJldHVybiBhCiAgIG5vbi16ZXJvIHZhbHVlIGlmIGl0IGlzLiAgKi8KCnN0YXRpYyBpbnQKaXNfdHJ1bmNhdGVkX2lkZW50aWZpZXIgKGNoYXIgKmlkKQp7CiAgY2hhciAqcHRyOwogIGludCBsZW4gPSBzdHJsZW4gKGlkKTsKICAvKiBJZiBpdCdzIG5vdCBleGFjdGx5IE1BWF9MQUJFTF9MRU5HVEggY2hhcmFjdGVycyBsb25nLCBpdCBjYW4ndCBiZQogICAgIGEgdHJ1bmNhdGVkIGlkZW50aWZpZXIuICAqLwogIGlmIChsZW4gIT0gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHJldHVybiAwOwogIAogIC8qIFN0YXJ0IHNjYW5uaW5nIGJhY2t3YXJkcyBmb3IgYSBfaC4gICovCiAgbGVuID0gbGVuIC0gMyAtIDMgLSA1IC0gMjsKICBwdHIgPSBpZCArIGxlbjsKICB3aGlsZSAocHRyID49IGlkKQogICAgewogICAgICBpZiAocHRyWzBdID09ICdfJyAmJiBwdHJbMV0gPT0gJ2gnKQoJewoJICAvKiBOb3cgc2VlIGlmIHRoZSBzdW0gZW5jb2RlZCBpbiB0aGUgaWRlbnRpZmVyIG1hdGNoZXMuICAqLwoJICBpbnQgeCwgc3VtOwoJICBzdW0gPSAwOwoJICBmb3IgKHggPSAwOyB4IDwgNTsgeCsrKQoJICAgIHN1bSArPSBwdHJbeCArIDJdOwoJICAvKiBJZiBpdCBtYXRjaGVzLCB0aGlzIGlzIHByb2JhYmx5IGEgdHJ1bmNhdGVkIGlkZW50aWZpZXIuICAqLwoJICBpZiAoc3VtID09IGRlY29kZV8xNiAocHRyICsgNSArIDIgKyAzKSkKCSAgICByZXR1cm4gMTsKCX0KICAgICAgcHRyLS07CiAgICB9CiAgcmV0dXJuIDA7Cn0KCi8qIGVuZCBvZiBvYmotZXZheC5jICovCg==