Lyogb2JqLWV2YXguYyAtIEVWQVggKG9wZW5WTVMvQWxwaGEpIG9iamVjdCBmaWxlIGZvcm1hdC4KICAgQ29weXJpZ2h0IChDKSAxOTk2LTIwMjEgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCiAgIENvbnRyaWJ1dGVkIGJ5IEtsYXVzIEvkbXBmIChra2FlbXBmQHByb2dpcy5kZSkgb2YKICAgICBwcm9HSVMgU29mdHdhcmUsIEFhY2hlbiwgR2VybWFueS4KICAgRXh0ZW5zaXZlbHkgZW5oYW5jZWQgYnkgRG91Z2xhcyBSdXBwIG9mIEFkYUNvcmUuCgogICBUaGlzIGZpbGUgaXMgcGFydCBvZiBHQVMsIHRoZSBHTlUgQXNzZW1ibGVyCgogICBHQVMgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzLCBvciAoYXQgeW91ciBvcHRpb24pCiAgIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgR0FTIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgIGFsb25nIHdpdGggR0FTOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwgd3JpdGUgdG8KICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgNTEgRnJhbmtsaW4gU3RyZWV0IC0gRmlmdGggRmxvb3IsIEJvc3RvbiwKICAgTUEgMDIxMTAtMTMwMSwgVVNBLiAgKi8KCiNkZWZpbmUgT0JKX0hFQURFUiAib2JqLWV2YXguaCIKCiNpbmNsdWRlICJhcy5oIgojaW5jbHVkZSAiYmZkLmgiCiNpbmNsdWRlICJ2bXMuaCIKI2luY2x1ZGUgInN1YnNlZ3MuaCIKI2luY2x1ZGUgInNhZmUtY3R5cGUuaCIKCnN0YXRpYyB2b2lkIHNfZXZheF93ZWFrIChpbnQpOwoKY29uc3QgcHNldWRvX3R5cGVTIG9ial9wc2V1ZG9fdGFibGVbXSA9CnsKICB7ICJ3ZWFrIiwgc19ldmF4X3dlYWssIDB9LAogIHswLCAwLCAwfSwKfTsJCQkJLyogb2JqX3BzZXVkb190YWJsZSAqLwoKdm9pZCBvYmpfcmVhZF9iZWdpbl9ob29rICgpIHt9CgovKiBIYW5kbGUgdGhlIHdlYWsgc3BlY2lmaWMgcHNldWRvLW9wLiAgKi8KCnN0YXRpYyB2b2lkCnNfZXZheF93ZWFrIChpbnQgaWdub3JlIEFUVFJJQlVURV9VTlVTRUQpCnsKICBjaGFyICpuYW1lOwogIGludCBjOwogIHN5bWJvbFMgKnN5bWJvbFA7CiAgY2hhciAqc3RvcCA9IE5VTEw7CiAgY2hhciBzdG9wYzsKCiAgaWYgKGZsYWdfbXJpKQogICAgc3RvcCA9IG1yaV9jb21tZW50X2ZpZWxkICgmc3RvcGMpOwoKICBkbwogICAgewogICAgICBjID0gZ2V0X3N5bWJvbF9uYW1lICgmbmFtZSk7CiAgICAgIHN5bWJvbFAgPSBzeW1ib2xfZmluZF9vcl9tYWtlIChuYW1lKTsKICAgICAgKHZvaWQpIHJlc3RvcmVfbGluZV9wb2ludGVyIChjKTsKICAgICAgU0tJUF9XSElURVNQQUNFICgpOwogICAgICBTX1NFVF9XRUFLIChzeW1ib2xQKTsKICAgICAgaWYgKGMgPT0gJywnKQoJewoJICBpbnB1dF9saW5lX3BvaW50ZXIrKzsKCSAgU0tJUF9XSElURVNQQUNFICgpOwoJICBpZiAoKmlucHV0X2xpbmVfcG9pbnRlciA9PSAnXG4nKQoJICAgIGMgPSAnXG4nOwoJfQogICAgfQogIHdoaWxlIChjID09ICcsJyk7CgogIGlmIChmbGFnX21yaSkKICAgIG1yaV9jb21tZW50X2VuZCAoc3RvcCwgc3RvcGMpOwoKICBkZW1hbmRfZW1wdHlfcmVzdF9vZl9saW5lICgpOwp9Cgp2b2lkCmV2YXhfc3ltYm9sX25ld19ob29rIChzeW1ib2xTICpzeW0pCnsKICBzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCAqdWRhdGE7CgogIHVkYXRhID0gWE5FVyAoc3RydWN0IGV2YXhfcHJpdmF0ZV91ZGF0YV9zdHJ1Y3QpOwoKICB1ZGF0YS0+YnN5bSA9IHN5bWJvbF9nZXRfYmZkc3ltIChzeW0pOwogIHVkYXRhLT5lbmJzeW0gPSBOVUxMOwogIHVkYXRhLT5vcmlnbmFtZSA9IHhzdHJkdXAgKFNfR0VUX05BTUUgKHN5bSkpOwogIHVkYXRhLT5sa2luZGV4ID0gMDsKICBzeW1ib2xfZ2V0X2JmZHN5bShzeW0pLT51ZGF0YS5wID0gKFBUUikgdWRhdGE7Cn0KCnZvaWQKZXZheF9mcm9iX3N5bWJvbCAoc3ltYm9sUyAqc3ltLCBpbnQgKnB1bnQpCnsKICBjb25zdCBjaGFyICpzeW1uYW1lID0gU19HRVRfTkFNRSAoc3ltKTsKICBpbnQgc3ltbGVuID0gc3RybGVuIChzeW1uYW1lKTsKICBhc3ltYm9sICpzeW1ib2wgPSBzeW1ib2xfZ2V0X2JmZHN5bSAoc3ltKTsKCiAgaWYgKHN5bWxlbiA+IDQKICAgICAgJiYgc3RyY21wIChzeW1uYW1lICsgc3ltbGVuIC0gNCwgIi4uZW4iKSA9PSAwCiAgICAgICYmIFNfR0VUX1NFR01FTlQgKHN5bSkgPT0gdW5kZWZpbmVkX3NlY3Rpb24pCiAgICB7CiAgICAgIHN5bWJvbF9jbGVhcl91c2VkX2luX3JlbG9jIChzeW0pOwogICAgICAqcHVudCA9IDE7CiAgICB9CgogIGVsc2UgaWYgKChzeW1ib2wtPmZsYWdzICYgQlNGX0dMT0JBTCkgJiYgKHN5bWJvbC0+ZmxhZ3MgJiBCU0ZfRlVOQ1RJT04pKQogICAgewogICAgICBzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCAqdWRhdGEKCT0gKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopc3ltYm9sLT51ZGF0YS5wOwoKICAgICAgLyogRml4IHVwIGVxdWF0ZXMgb2YgZnVuY3Rpb24gZGVmaW5pdGlvbnMuICAqLwogICAgICB3aGlsZSAodWRhdGEtPmVuYnN5bSA9PSBOVUxMKQoJewoJICAvKiA/Pz8gRXF1YXRlcyBoYXZlIGJlZW4gcmVzb2x2ZWQgYXQgdGhpcyBwb2ludCBzbyB0aGVpcgoJICAgICBleHByZXNzaW9uIGlzIE9fY29uc3RhbnQ7IGJ1dCB0aGV5IHByZXZpb3VzbHkgd2VyZQoJICAgICBPX3N5bWJvbCBhbmQgd2UgaG9wZSB0aGUgZXF1YXRlZCBzeW1ib2wgaXMgc3RpbGwgdGhlcmUuICAqLwoJICBzeW0gPSBzeW1ib2xfZ2V0X3ZhbHVlX2V4cHJlc3Npb24gKHN5bSktPlhfYWRkX3N5bWJvbDsKCSAgaWYgKHN5bSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgYXNfYmFkIChfKCJubyBlbnRyeSBzeW1ib2wgZm9yIGdsb2JhbCBmdW5jdGlvbiAnJXMnIiksIHN5bW5hbWUpOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoJICBzeW1ib2wgPSBzeW1ib2xfZ2V0X2JmZHN5bSAoc3ltKTsKCSAgdWRhdGEtPmVuYnN5bQoJICAgID0gKChzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCAqKXN5bWJvbC0+dWRhdGEucCktPmVuYnN5bTsKCX0KICAgIH0KfQoKdm9pZApldmF4X2Zyb2JfZmlsZV9iZWZvcmVfYWRqdXN0ICh2b2lkKQp7CiAgc3RydWN0IGFscGhhX2xpbmthZ2VfZml4dXBzICpsOwogIHNlZ1QgY3VycmVudF9zZWN0aW9uID0gbm93X3NlZzsKICBpbnQgY3VycmVudF9zdWJzZWMgPSBub3dfc3Vic2VnOwogIHNlZ21lbnRfaW5mb190eXBlICpzZWdpbmZvOwogIGludCBsaW5rYWdlX2luZGV4ID0gMTsKCiAgc3Vic2VnX3NldCAoYWxwaGFfbGlua19zZWN0aW9uLCAwKTsKICBzZWdpbmZvID0gc2VnX2luZm8gKGFscGhhX2xpbmtfc2VjdGlvbik7CgogIC8qIEhhbmRsZSAubGlua2FnZSBmaXh1cHMuICAqLwogIGZvciAobCA9IGFscGhhX2xpbmthZ2VfZml4dXBfcm9vdDsgbCAhPSBOVUxMOyBsID0gbC0+bmV4dCkKICAgIHsKICAgICAgaWYgKFNfR0VUX1NFR01FTlQgKGwtPmZpeHAtPmZ4X2FkZHN5KSA9PSBhbHBoYV9saW5rX3NlY3Rpb24pCgl7CiAgICAgICAgICAvKiBUaGUgc3ltYm9sIGlzIGRlZmluZWQgaW4gdGhlIGZpbGUuICBUaGUgbGlua2FnZSBlbnRyeSBkZWNheXMgdG8KICAgICAgICAgICAgIHR3byByZWxvY3MuICAqLwoJICBzeW1ib2xTICplbnRyeV9zeW07CgkgIGZpeFMgKmZpeHBlbnRyeSwgKmZpeHBwZGVzYywgKmZpeHRhaWw7CgoJICBmaXh0YWlsID0gc2VnaW5mby0+Zml4X3RhaWw7CgoJICAvKiBSZXBsYWNlIHRoZSBsaW5rYWdlIHdpdGggdGhlIGxvY2FsIHN5bWJvbHMgKi8KCSAgZW50cnlfc3ltID0gc3ltYm9sX2ZpbmQKCSAgICAoKChzdHJ1Y3QgZXZheF9wcml2YXRlX3VkYXRhX3N0cnVjdCAqKXN5bWJvbF9nZXRfYmZkc3ltIChsLT5maXhwLT5meF9hZGRzeSktPnVkYXRhLnApLT5lbmJzeW0tPm5hbWUpOwoJICBpZiAoIWVudHJ5X3N5bSkKCSAgICBhYm9ydCAoKTsKCSAgZml4cGVudHJ5ID0gZml4X25ldyAobC0+Zml4cC0+ZnhfZnJhZywgbC0+Zml4cC0+Znhfd2hlcmUsIDgsCgkJCSAgICAgICBlbnRyeV9zeW0sIGwtPmZpeHAtPmZ4X29mZnNldCwgMCwKCQkJICAgICAgIEJGRF9SRUxPQ182NCk7CgkgIGZpeHBwZGVzYyA9IGZpeF9uZXcgKGwtPmZpeHAtPmZ4X2ZyYWcsIGwtPmZpeHAtPmZ4X3doZXJlICsgOCwgOCwKCQkJICAgICAgIGwtPmZpeHAtPmZ4X2FkZHN5LCBsLT5maXhwLT5meF9vZmZzZXQsIDAsCgkJCSAgICAgICBCRkRfUkVMT0NfNjQpOwoJICBsLT5maXhwLT5meF9zaXplID0gMDsKCSAgbC0+Zml4cC0+ZnhfZG9uZSA9IDE7CgoJICAvKiBJZiBub3QgYWxyZWFkeSBhdCB0aGUgdGFpbCwgc3BsaWNlIHRoZSBuZXcgZml4dXBzIGludG8KCSAgICAgdGhlIGNoYWluIHJpZ2h0IGFmdGVyIHRoZSBvbmUgd2UgYXJlIG51bGxpbmcgb3V0ICovCgkgIGlmIChmaXh0YWlsICE9IGwtPmZpeHApCgkgICAgewoJICAgICAgZml4cHBkZXNjLT5meF9uZXh0ID0gbC0+Zml4cC0+ZnhfbmV4dDsKCSAgICAgIGwtPmZpeHAtPmZ4X25leHQgPSBmaXhwZW50cnk7CgkgICAgICBmaXh0YWlsLT5meF9uZXh0ID0gMDsKCSAgICAgIHNlZ2luZm8tPmZpeF90YWlsID0gZml4dGFpbDsKCSAgICB9Cgl9CiAgICAgIGVsc2UKCXsKICAgICAgICAgIC8qIEFzc2lnbiBhIGxpbmthZ2UgaW5kZXguICAqLwoJICAoKHN0cnVjdCBldmF4X3ByaXZhdGVfdWRhdGFfc3RydWN0ICopCgkgICBzeW1ib2xfZ2V0X2JmZHN5bSAobC0+bGFiZWwpLT51ZGF0YS5wKS0+bGtpbmRleCA9IGxpbmthZ2VfaW5kZXg7CgoJICBsLT5maXhwLT5meF9hZGRudW1iZXIgPSBsaW5rYWdlX2luZGV4OwoKCSAgbGlua2FnZV9pbmRleCArPSAyOwoJfQogICAgfQoKICBzdWJzZWdfc2V0IChjdXJyZW50X3NlY3Rpb24sIGN1cnJlbnRfc3Vic2VjKTsKfQoKdm9pZApldmF4X2Zyb2JfZmlsZV9iZWZvcmVfZml4ICh2b2lkKQp7CiAgLyogTm93IHRoYXQgdGhlIGZpeHVwcyBhcmUgZG9uZSBlYXJsaWVyLCB3ZSBuZWVkIHRvIHRyYW5zZmVyIHRoZSB2YWx1ZXMKICAgICBpbnRvIHRoZSBCRkQgc3ltYm9scyBiZWZvcmUgY2FsbGluZyBmaXhfc2VnbWVudCAoaWRlYWxseSBzaG91bGQgbm90CiAgICAgYmUgZG9uZSBhbHNvIGxhdGVyKS4gICovCiAgaWYgKHN5bWJvbF9yb290UCkKICAgIHsKICAgICAgc3ltYm9sUyAqc3ltcDsKCiAgICAgIC8qIFNldCB0aGUgdmFsdWUgaW50byB0aGUgQkZEIHN5bWJvbC4gIFVwIHRpbCBub3cgdGhlIHZhbHVlCgkgaGFzIG9ubHkgYmVlbiBrZXB0IGluIHRoZSBnYXMgc3ltYm9sUyBzdHJ1Y3QuICAqLwogICAgICBmb3IgKHN5bXAgPSBzeW1ib2xfcm9vdFA7IHN5bXA7IHN5bXAgPSBzeW1ib2xfbmV4dCAoc3ltcCkpCglzeW1ib2xfZ2V0X2JmZHN5bSAoc3ltcCktPnZhbHVlID0gU19HRVRfVkFMVUUgKHN5bXApOwogICAgfQp9CgovKiBUaGUgbGVuZ3RoIGlzIGNvbXB1dGVkIGZyb20gdGhlIG1heGltdW0gYWxsb3dhYmxlIGxlbmd0aCBvZiA2NCBsZXNzIHRoZQogICA0IGNoYXJhY3RlciAuLnh4IGV4dGVuc2lvbiB0aGF0IG11c3QgYmUgcHJlc2VydmVkIChyZW1vdmVkIGJlZm9yZQogICBjcnVuY2hpbmcgYW5kIGFwcGVuZGVkIGJhY2sgb24gYWZ0ZXJ3YXJkcykuICBUaGUgJDxubm4+Li4gcHJlZml4IGlzCiAgIGFsc28gcmVtb3ZlZCBhbmQgcHJlcGVuZWQgYmFjayBvbiwgYnV0IGRvZXNuJ3QgZW50ZXIgaW50byB0aGUgbGVuZ3RoCiAgIGNvbXB1dGF0aW9uIGJlY2F1c2Ugc3ltYm9scyB3aXRoIHRoYXQgcHJlZml4IGFyZSBhbHdheXMgcmVzb2x2ZWQKICAgYnkgdGhlIGFzc2VtYmxlciBhbmQgd2lsbCBuZXZlciBhcHBlYXIgaW4gdGhlIHN5bWJvbCB0YWJsZS4gQXQgbGVhc3QKICAgSSBob3BlIHRoYXQncyB0cnVlLCBUQkQuICAqLwojZGVmaW5lIE1BWF9MQUJFTF9MRU5HVEggNjAKCnN0YXRpYyBjaGFyICpzaG9ydGVuX2lkZW50aWZpZXIgKGNoYXIgKik7CnN0YXRpYyBpbnQgaXNfdHJ1bmNhdGVkX2lkZW50aWZpZXIgKGNoYXIgKik7CgpjaGFyICoKZXZheF9zaG9ydGVuX25hbWUgKGNoYXIgKmlkKQp7CiAgaW50IHByZWZpeF9kb3Rkb3QgPSAwOwogIGNoYXIgcHJlZml4IFs2NF07CiAgaW50IGxlbiA9IHN0cmxlbiAoaWQpOwogIGludCBzdWZmaXhfZG90ZG90ID0gbGVuOwogIGNoYXIgc3VmZml4IFs2NF07CiAgY2hhciAqYmFzZV9pZDsKCiAgLyogVGhpcyB0ZXN0IG1heSBiZSB0b28gY29uc2VydmF0aXZlLiAgKi8KICBpZiAobGVuIDw9IE1BWF9MQUJFTF9MRU5HVEgpCiAgICByZXR1cm4gaWQ7CgogIHN1ZmZpeCBbMF0gPSAwOwogIHByZWZpeCBbMF0gPSAwOwoKICAvKiBDaGVjayBmb3IgLi54eCBzdWZmaXggYW5kIHNhdmUgaXQuICAqLwogIGlmIChzdGFydHN3aXRoICgmaWRbbGVuLTRdLCAiLi4iKSkKICAgIHsKICAgICAgc3VmZml4X2RvdGRvdCA9IGxlbiAtIDQ7CiAgICAgIHN0cm5jcHkgKHN1ZmZpeCwgJmlkW2xlbi00XSwgNCk7CiAgICAgIHN1ZmZpeCBbNF0gPSAwOwogICAgfQoKICAvKiBDaGVjayBmb3IgJDxubm4+Li4gcHJlZml4IGFuZCBzYXZlIGl0LiAgKi8KICBpZiAoKGlkWzBdID09ICckJykgJiYgSVNESUdJVCAoaWRbMV0pKQogICAgewogICAgICBpbnQgaTsKCiAgICAgIGZvciAoaT0yOyBpIDwgbGVuOyBpKyspCiAgICAgICAgewoJICBpZiAoIUlTRElHSVQgKGlkW2ldKSkKICAgICAgICAgICAgewoJICAgICAgaWYgKGlkW2ldID09ICcuJyAmJiBpZCBbaSsxXSA9PSAnLicpCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgcHJlZml4X2RvdGRvdCA9IGkrMjsKICAgICAgICAgICAgICAgICAgIHN0cm5jcHkgKHByZWZpeCwgaWQsIHByZWZpeF9kb3Rkb3QpOwogICAgICAgICAgICAgICAgICAgcHJlZml4IFtwcmVmaXhfZG90ZG90XSA9IDA7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgLyogV2Ugb25seSBuZWVkIHdvcnJ5IGFib3V0IGNydW5jaGluZyB0aGUgYmFzZSBzeW1ib2wuICAqLwogIGJhc2VfaWQgPSB4bWVtZHVwMCAoJmlkW3ByZWZpeF9kb3Rkb3RdLCBzdWZmaXhfZG90ZG90IC0gcHJlZml4X2RvdGRvdCk7CgogIGlmIChzdHJsZW4gKGJhc2VfaWQpID4gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHsKICAgICAgY2hhciBuZXdfaWQgWzQwOTZdOwogICAgICBjaGFyICpyZXR1cm5faWQ7CgogICAgICBzdHJjcHkgKG5ld19pZCwgYmFzZV9pZCk7CgogICAgICAvKiBTaG9ydGVuIGl0LiAgKi8KICAgICAgc3RyY3B5IChuZXdfaWQsIHNob3J0ZW5faWRlbnRpZmllciAobmV3X2lkKSk7CgogICAgICAvKiBQcmVwZW5kIGJhY2sgdGhlIHByZWZpeCBpZiB0aGVyZSB3YXMgb25lLiAgKi8KICAgICAgaWYgKHByZWZpeF9kb3Rkb3QpCiAgICAgICAgewogICAgICAgICAgbWVtbW92ZSAoJm5ld19pZCBbcHJlZml4X2RvdGRvdF0sIG5ld19pZCwgc3RybGVuIChuZXdfaWQpICsgMSk7CiAgICAgICAgICBzdHJuY3B5IChuZXdfaWQsIHByZWZpeCwgcHJlZml4X2RvdGRvdCk7CiAgICAgICAgfQoKICAgICAgLyogQXBwZW5kIGJhY2sgdGhlIHN1ZmZpeCBpZiB0aGVyZSB3YXMgb25lLiAgKi8KICAgICAgaWYgKHN0cmxlbiAoc3VmZml4KSkKCXN0cmNhdCAobmV3X2lkLCBzdWZmaXgpOwoKICAgICAgLyogU2F2ZSBpdCBvbiB0aGUgaGVhcCBhbmQgcmV0dXJuLiAgKi8KICAgICAgcmV0dXJuX2lkID0geHN0cmR1cCAobmV3X2lkKTsKCiAgICAgIHJldHVybiByZXR1cm5faWQ7CiAgICB9CiAgZWxzZQogICAgcmV0dXJuIGlkOwp9CgovKiBUaGUgY29kZSBiZWxvdyBpbXBsZW1lbnRzIGEgbWVjaGFuaXNtIGZvciB0cnVuY2F0aW5nIGxvbmcKICAgaWRlbnRpZmllcnMgdG8gYW4gYXJiaXRyYXJ5IGxlbmd0aCAoc2V0IGJ5IE1BWF9MQUJFTF9MRU5HVEgpLgoKICAgSXQgYXR0ZW1wdHMgdG8gbWFrZSBlYWNoIHRydW5jYXRlZCBpZGVudGlmaWVyIHVuaXF1ZSBieSByZXBsYWNpbmcKICAgcGFydCBvZiB0aGUgaWRlbnRpZmllciB3aXRoIGFuIGVuY29kZWQgMzItYml0IENSQyBhbmQgYW4gYXNzb2NpYXRlZAogICBjaGVja3N1bSAodGhlIGNoZWNrc3VtIGlzIHVzZWQgYXMgYSB3YXkgdG8gZGV0ZXJtaW5lIHRoYXQgdGhlIG5hbWUKICAgd2FzIHRydW5jYXRlZCkuCgogICBOb3RlIHRoYXQgYm90aCBhIHBvcnRpb24gb2YgdGhlIHN0YXJ0IGFuZCBvZiB0aGUgZW5kIG9mIHRoZQogICBpZGVudGlmaWVyIG1heSBiZSBrZXB0LiAgVGhlIG1hY3JvIElEX1NVRkZJWF9MRU5HVEggd2lsbCByZXR1cm4gdGhlCiAgIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBzdWZmaXggb2YgdGhlIGlkZW50aWZpZXIgdGhhdCBzaG91bGQgYmUKICAga2VwdC4KCiAgIFRoZSBwb3J0aW9uIG9mIHRoZSBpZGVudGlmaWVyIHRoYXQgaXMgZ29pbmcgdG8gYmUgcmVtb3ZlZCBpcwogICBjaGVja3N1bW1lZC4gIFRoZSBjaGVja3N1bSBpcyB0aGVuIGVuY29kZWQgYXMgYSA1LWNoYXJhY3RlciBzdHJpbmcsCiAgIHRoZSBjaGFyYWN0ZXJzIG9mIHdoaWNoIGFyZSB0aGVuIHN1bW1lZC4gIFRoaXMgc3VtIGlzIHRoZW4gZW5jb2RlZAogICBhcyBhIDMtY2hhcmFjdGVyIHN0cmluZy4gIEZpbmFsbHksIHRoZSBvcmlnaW5hbCBsZW5ndGggb2YgdGhlCiAgIGlkZW50aWZpZXIgaXMgZW5jb2RlZCBhcyBhIDMtY2hhcmFjdGVyIHN0cmluZy4KCiAgIFRoZXNlIHRocmVlIHN0cmluZ3MgYXJlIHRoZW4gY29uY2F0ZW5hdGVkIHRvZ2V0aGVyIChhbG9uZyB3aXRoIGFuIF9oCiAgIHdoaWNoIGZ1cnRoZXIgZGVzaWduYXRlcyB0aGF0IHRoZSBuYW1lIHdhcyB0cnVuY2F0ZWQpOgoKICAgIm9yaWdpbmFsX2lkZW50aWZpZXIiX2hhYWFhYWJiYmNjYwoKICAgYWFhYWEgPSAzMi1iaXQgQ1JDCiAgIGJiYiA9IGxlbmd0aCBvZiBvcmlnaW5hbCBpZGVudGlmaWVyCiAgIGNjYyA9IHN1bSBvZiAzMi1iaXQgQ1JDIGNoYXJhY3RlcnMKCiAgIFRoZSByZXN1bHRpbmcgaWRlbnRpZmllciB3aWxsIGJlIE1BWF9MQUJFTF9MRU5HVEggY2hhcmFjdGVycyBsb25nLgoKICAgKi8KCgovKiBUYWJsZSB1c2VkIHRvIGNvbnZlcnQgYW4gaW50ZWdlciBpbnRvIGEgc3RyaW5nLiAgKi8KCnN0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIGNvZGluZ3NbXSA9IHsKICAnYScsICdiJywgJ2MnLCAnZCcsICdlJywgJ2YnLCAnZycsICdoJywgJ2knLCAnaicsICdrJywgJ2wnLCAnbScsICduJywgJ28nLAogICdwJywgJ3EnLCAncicsICdzJywgJ3QnLCAndScsICd2JywgJ3cnLCAneCcsICd5JywgJ3onLAogICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsICdNJywgJ04nLCAnTycsCiAgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywgJ1knLCAnWicsCiAgJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsICc4JywgJzknLCAnXyd9OwoKLyogVGFibGUgdXNlZCBieSBkZWNvZGVfMTYgKCkgdG8gY29udmVydCBhbiBlbmNvZGVkIHN0cmluZyBiYWNrIGludG8KICAgYW4gaW50ZWdlci4gICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGRlY29kaW5nc1syNTZdOwoKLyogVGFibGUgdXNlZCBieSB0aGUgY3JjMzIgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBjaGVja3N1bS4gICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzJfdGFibGVbMjU2XSA9IHswLCAwfTsKCi8qIEdpdmVuIGEgc3RyaW5nIGluIEJVRiwgY2FsY3VsYXRlIGEgMzItYml0IENSQyBmb3IgaXQuCgogICBUaGlzIGlzIHVzZWQgYXMgYSByZWFzb25hYmx5IHVuaXF1ZSBoYXNoIGZvciB0aGUgZ2l2ZW4gc3RyaW5nLiAgKi8KCnN0YXRpYyB1bnNpZ25lZCBpbnQKY3JjMzIgKHVuc2lnbmVkIGNoYXIgKmJ1ZiwgaW50IGxlbikKewogIHVuc2lnbmVkIGludCBjcmMgPSAweGZmZmZmZmZmOwoKICBpZiAoISBjcmMzMl90YWJsZVsxXSkKICAgIHsKICAgICAgLyogSW5pdGlhbGl6ZSB0aGUgQ1JDIHRhYmxlIGFuZCB0aGUgZGVjb2RpbmcgdGFibGUuICovCiAgICAgIHVuc2lnbmVkIGludCBpLCBqOwogICAgICB1bnNpZ25lZCBpbnQgYzsKCiAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykKCXsKCSAgZm9yIChjID0gaSA8PCAyNCwgaiA9IDg7IGogPiAwOyAtLWopCgkgICAgYyA9IGMgJiAweDgwMDAwMDAwID8gKGMgPDwgMSkgXiAweDA0YzExZGI3IDogKGMgPDwgMSk7CgkgIGNyYzMyX3RhYmxlW2ldID0gYzsKCSAgZGVjb2RpbmdzW2ldID0gMDsKCX0KICAgICAgZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUgKGNvZGluZ3MpOyBpKyspCglkZWNvZGluZ3NbY29kaW5nc1tpXV0gPSBpOwogICAgfQoKICB3aGlsZSAobGVuLS0pCiAgICB7CiAgICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmMzMl90YWJsZVsoY3JjID4+IDI0KSBeICpidWZdOwogICAgICBidWYrKzsKICAgIH0KICByZXR1cm4gY3JjOwp9CgovKiBFbmNvZGUgdGhlIGxvd2VyIDMyIGJpdHMgb2YgVkFMVUUgYXMgYSA1LWNoYXJhY3RlciBzdHJpbmcuICAqLwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKgplbmNvZGVfMzIgKHVuc2lnbmVkIGludCB2YWx1ZSkKewogIHN0YXRpYyB1bnNpZ25lZCBjaGFyIHJlc1s2XTsKICBpbnQgeDsKCiAgcmVzWzVdID0gMDsKICBmb3IoeCA9IDA7IHggPCA1OyB4KyspCiAgICB7CiAgICAgIHJlc1t4XSA9IGNvZGluZ3NbdmFsdWUgJSBBUlJBWV9TSVpFIChjb2RpbmdzKV07CiAgICAgIHZhbHVlID0gdmFsdWUgLyBBUlJBWV9TSVpFIChjb2RpbmdzKTsKICAgIH0KICByZXR1cm4gcmVzOwp9CgovKiBFbmNvZGUgdGhlIGxvd2VyIDE2IGJpdHMgb2YgVkFMVUUgYXMgYSAzLWNoYXJhY3RlciBzdHJpbmcuICAqLwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKgplbmNvZGVfMTYgKHVuc2lnbmVkIGludCB2YWx1ZSkKewogIHN0YXRpYyB1bnNpZ25lZCBjaGFyIHJlc1s0XTsKICBpbnQgeDsKCiAgcmVzWzNdID0gMDsKICBmb3IoeCA9IDA7IHggPCAzOyB4KyspCiAgICB7CiAgICAgIHJlc1t4XSA9IGNvZGluZ3NbdmFsdWUgJSBBUlJBWV9TSVpFIChjb2RpbmdzKV07CiAgICAgIHZhbHVlID0gdmFsdWUgLyBBUlJBWV9TSVpFIChjb2RpbmdzKTsKICAgIH0KICByZXR1cm4gcmVzOwp9CgovKiBDb252ZXJ0IHRoZSBlbmNvZGVkIHN0cmluZyBvYnRhaW5lZCBmcm9tIGVuY29kZV8xNiAoKSBiYWNrIGludG8gYQogICAxNi1iaXQgaW50ZWdlci4gICovCgpzdGF0aWMgaW50CmRlY29kZV8xNiAoY29uc3QgdW5zaWduZWQgY2hhciAqc3RyaW5nKQp7CiAgcmV0dXJuIChkZWNvZGluZ3Nbc3RyaW5nWzJdXSAqIEFSUkFZX1NJWkUgKGNvZGluZ3MpICogQVJSQVlfU0laRSAoY29kaW5ncykKCSAgKyBkZWNvZGluZ3Nbc3RyaW5nWzFdXSAqIEFSUkFZX1NJWkUgKGNvZGluZ3MpCgkgICsgZGVjb2RpbmdzW3N0cmluZ1swXV0pOwp9CgovKiBJRF9TVUZGSVhfTEVOR1RIIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGhvdyBtYW55IGNoYXJhY3RlcnMgaW4gdGhlCiAgIHN1ZmZpeCBvZiB0aGUgaWRlbnRpZmllciBhcmUgdG8gYmUgcHJlc2VydmVkLCBpZiBhbnkuICAqLwoKI2lmbmRlZiBJRF9TVUZGSVhfTEVOR1RICiNkZWZpbmUgSURfU1VGRklYX0xFTkdUSChJRCkgKDApCiNlbmRpZgoKLyogUmV0dXJuIGEgcmVhc29uYWJseS11bmlxdWUgdmVyc2lvbiBvZiBOQU1FIHRoYXQgaXMgbGVzcyB0aGFuIG9yCiAgIGVxdWFsIHRvIE1BWF9MQUJFTF9MRU5HVEggY2hhcmFjdGVycyBsb25nLiAgVGhlIHN0cmluZyByZXR1cm5lZCBmcm9tCiAgIHRoaXMgZnVuY3Rpb24gbWF5IGJlIGEgY29weSBvZiBOQU1FOyB0aGUgZnVuY3Rpb24gd2lsbCBuZXZlcgogICBhY3R1YWxseSBtb2RpZnkgdGhlIGNvbnRlbnRzIG9mIE5BTUUuICAqLwoKc3RhdGljIGNoYXIgbmV3bmFtZVtNQVhfTEFCRUxfTEVOR1RIICsgMV07CgpzdGF0aWMgY2hhciAqCnNob3J0ZW5faWRlbnRpZmllciAoY2hhciAqbmFtZSkKewogIGludCBjcmMsIGxlbiwgc3VtLCB4LCBmaW5hbF9sZW47CiAgdW5zaWduZWQgY2hhciAqY3JjX2NoYXJzOwogIGludCBzdWZmaXhfbGVuZ3RoID0gSURfU1VGRklYX0xFTkdUSCAobmFtZSk7CgogIGlmICgobGVuID0gc3RybGVuIChuYW1lKSkgPD0gTUFYX0xBQkVMX0xFTkdUSCkKICAgIHJldHVybiBuYW1lOwoKICBmaW5hbF9sZW4gPSBNQVhfTEFCRUxfTEVOR1RIIC0gMiAtIDUgLSAzIC0gMyAtIHN1ZmZpeF9sZW5ndGg7CiAgY3JjID0gY3JjMzIgKCh1bnNpZ25lZCBjaGFyICopIG5hbWUgKyBmaW5hbF9sZW4sCgkgICAgICAgbGVuIC0gZmluYWxfbGVuIC0gc3VmZml4X2xlbmd0aCk7CiAgY3JjX2NoYXJzID0gZW5jb2RlXzMyIChjcmMpOwogIHN1bSA9IDA7CiAgZm9yICh4ID0gMDsgeCA8IDU7IHgrKykKICAgIHN1bSArPSBjcmNfY2hhcnMgW3hdOwogIHN0cm5jcHkgKG5ld25hbWUsIG5hbWUsIGZpbmFsX2xlbik7CiAgbmV3bmFtZSBbTUFYX0xBQkVMX0xFTkdUSF0gPSAwOwogIC8qIE5vdyBhcHBlbmQgdGhlIHN1ZmZpeCBvZiB0aGUgb3JpZ2luYWwgaWRlbnRpZmllciwgaWYgYW55LiAgKi8KICBpZiAoc3VmZml4X2xlbmd0aCkKICAgIHN0cm5jcHkgKG5ld25hbWUgKyBNQVhfTEFCRUxfTEVOR1RIIC0gc3VmZml4X2xlbmd0aCwKCSAgICAgbmFtZSArIGxlbiAtIHN1ZmZpeF9sZW5ndGgsCgkgICAgIHN1ZmZpeF9sZW5ndGgpOwogIG1lbWNweSAobmV3bmFtZSArIGZpbmFsX2xlbiwgIl9oIiwgMik7CiAgbWVtY3B5IChuZXduYW1lICsgZmluYWxfbGVuICsgMiAsIGNyY19jaGFycywgNSk7CiAgbWVtY3B5IChuZXduYW1lICsgZmluYWxfbGVuICsgMiArIDUsIGVuY29kZV8xNiAobGVuKSwgMyk7CiAgbWVtY3B5IChuZXduYW1lICsgZmluYWxfbGVuICsgMiArIDUgKyAzLCBlbmNvZGVfMTYgKHN1bSksIDMpOwogIGlmICghaXNfdHJ1bmNhdGVkX2lkZW50aWZpZXIgKG5ld25hbWUpKQogICAgYWJvcnQgKCk7CiAgcmV0dXJuIG5ld25hbWU7Cn0KCi8qIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCBJRCBpcyBhIHRydW5jYXRlZCBpZGVudGlmaWVyLCBhbmQgcmV0dXJuIGEKICAgbm9uLXplcm8gdmFsdWUgaWYgaXQgaXMuICAqLwoKc3RhdGljIGludAppc190cnVuY2F0ZWRfaWRlbnRpZmllciAoY2hhciAqaWQpCnsKICB1bnNpZ25lZCBjaGFyICpwdHI7CiAgaW50IGxlbiA9IHN0cmxlbiAoaWQpOwogIC8qIElmIGl0J3Mgbm90IGV4YWN0bHkgTUFYX0xBQkVMX0xFTkdUSCBjaGFyYWN0ZXJzIGxvbmcsIGl0IGNhbid0IGJlCiAgICAgYSB0cnVuY2F0ZWQgaWRlbnRpZmllci4gICovCiAgaWYgKGxlbiAhPSBNQVhfTEFCRUxfTEVOR1RIKQogICAgcmV0dXJuIDA7CgogIC8qIFN0YXJ0IHNjYW5uaW5nIGJhY2t3YXJkcyBmb3IgYSBfaC4gICovCiAgbGVuID0gbGVuIC0gMyAtIDMgLSA1IC0gMjsKICBwdHIgPSAodW5zaWduZWQgY2hhciAqKSBpZCArIGxlbjsKICB3aGlsZSAocHRyID49ICh1bnNpZ25lZCBjaGFyICopIGlkKQogICAgewogICAgICBpZiAocHRyWzBdID09ICdfJyAmJiBwdHJbMV0gPT0gJ2gnKQoJewoJICAvKiBOb3cgc2VlIGlmIHRoZSBzdW0gZW5jb2RlZCBpbiB0aGUgaWRlbnRpZmllciBtYXRjaGVzLiAgKi8KCSAgaW50IHgsIHN1bTsKCSAgc3VtID0gMDsKCSAgZm9yICh4ID0gMDsgeCA8IDU7IHgrKykKCSAgICBzdW0gKz0gcHRyW3ggKyAyXTsKCSAgLyogSWYgaXQgbWF0Y2hlcywgdGhpcyBpcyBwcm9iYWJseSBhIHRydW5jYXRlZCBpZGVudGlmaWVyLiAgKi8KCSAgaWYgKHN1bSA9PSBkZWNvZGVfMTYgKHB0ciArIDUgKyAyICsgMykpCgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgIHB0ci0tOwogICAgfQogIHJldHVybiAwOwp9CgovKiBlbmQgb2Ygb2JqLWV2YXguYyAqLwo=