LyogY29ubmVjdGlvbi5jIC0gdGhlIGNvbm5lY3Rpb24gdHlwZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDQtMjAwNiBHZXJoYXJkIEjkcmluZyA8Z2hAZ2hhZXJpbmcuZGU+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgogKiAKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgImNhY2hlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImNvbm5lY3Rpb24uaCIKI2luY2x1ZGUgInN0YXRlbWVudC5oIgojaW5jbHVkZSAiY3Vyc29yLmgiCiNpbmNsdWRlICJwcmVwYXJlX3Byb3RvY29sLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJzcWxpdGVjb21wYXQuaCIKCiNpbmNsdWRlICJweXRocmVhZC5oIgoKc3RhdGljIGludCBjb25uZWN0aW9uX3NldF9pc29sYXRpb25fbGV2ZWwoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbCk7CgppbnQgY29ubmVjdGlvbl9pbml0KENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImRhdGFiYXNlIiwgInRpbWVvdXQiLCAiZGV0ZWN0X3R5cGVzIiwgImlzb2xhdGlvbl9sZXZlbCIsICJjaGVja19zYW1lX3RocmVhZCIsICJmYWN0b3J5IiwgImNhY2hlZF9zdGF0ZW1lbnRzIiwgTlVMTCwgTlVMTH07CgogICAgY2hhciogZGF0YWJhc2U7CiAgICBpbnQgZGV0ZWN0X3R5cGVzID0gMDsKICAgIFB5T2JqZWN0KiBpc29sYXRpb25fbGV2ZWwgPSBOVUxMOwogICAgUHlPYmplY3QqIGZhY3RvcnkgPSBOVUxMOwogICAgaW50IGNoZWNrX3NhbWVfdGhyZWFkID0gMTsKICAgIGludCBjYWNoZWRfc3RhdGVtZW50cyA9IDEwMDsKICAgIGRvdWJsZSB0aW1lb3V0ID0gNS4wOwogICAgaW50IHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInN8ZGlPaU9pIiwga3dsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRhdGFiYXNlLCAmdGltZW91dCwgJmRldGVjdF90eXBlcywgJmlzb2xhdGlvbl9sZXZlbCwgJmNoZWNrX3NhbWVfdGhyZWFkLCAmZmFjdG9yeSwgJmNhY2hlZF9zdGF0ZW1lbnRzKSkKICAgIHsKICAgICAgICByZXR1cm4gLTE7IAogICAgfQoKICAgIHNlbGYtPmJlZ2luX3N0YXRlbWVudCA9IE5VTEw7CgogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlID0gTlVMTDsKICAgIHNlbGYtPnN0YXRlbWVudHMgPSBOVUxMOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHNlbGYtPnJvd19mYWN0b3J5ID0gUHlfTm9uZTsKCiAgICBQeV9JTkNSRUYoJlB5VW5pY29kZV9UeXBlKTsKICAgIHNlbGYtPnRleHRfZmFjdG9yeSA9IChQeU9iamVjdCopJlB5VW5pY29kZV9UeXBlOwoKICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgIHJjID0gc3FsaXRlM19vcGVuKGRhdGFiYXNlLCAmc2VsZi0+ZGIpOwogICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKCFpc29sYXRpb25fbGV2ZWwpIHsKICAgICAgICBpc29sYXRpb25fbGV2ZWwgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCIiKTsKICAgICAgICBpZiAoIWlzb2xhdGlvbl9sZXZlbCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoaXNvbGF0aW9uX2xldmVsKTsKICAgIH0KICAgIHNlbGYtPmlzb2xhdGlvbl9sZXZlbCA9IE5VTEw7CiAgICBjb25uZWN0aW9uX3NldF9pc29sYXRpb25fbGV2ZWwoc2VsZiwgaXNvbGF0aW9uX2xldmVsKTsKICAgIFB5X0RFQ1JFRihpc29sYXRpb25fbGV2ZWwpOwoKICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZSA9IChDYWNoZSopUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKChQeU9iamVjdCopJkNhY2hlVHlwZSwgIk9pIiwgc2VsZiwgY2FjaGVkX3N0YXRlbWVudHMpOwogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgc2VsZi0+c3RhdGVtZW50cyA9IFB5TGlzdF9OZXcoMCk7CiAgICBpZiAoIXNlbGYtPnN0YXRlbWVudHMpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBzZWxmLT5jcmVhdGVkX3N0YXRlbWVudHMgPSAwOwoKICAgIC8qIEJ5IGRlZmF1bHQsIHRoZSBDYWNoZSBjbGFzcyBJTkNSRUZzIHRoZSBmYWN0b3J5IGluIGl0cyBpbml0aWFsaXplciwgYW5kCiAgICAgKiBkZWNyZWZzIGl0IGluIGl0cyBkZWFsbG9jYXRvciBtZXRob2QuIFNpbmNlIHRoaXMgd291bGQgY3JlYXRlIGEgY2lyY3VsYXIKICAgICAqIHJlZmVyZW5jZSBoZXJlLCB3ZSdyZSBicmVha2luZyBpdCBieSBkZWNyZW1lbnRpbmcgc2VsZiwgYW5kIHRlbGxpbmcgdGhlCiAgICAgKiBjYWNoZSBjbGFzcyB0byBub3QgZGVjcmVmIHRoZSBmYWN0b3J5IChzZWxmKSBpbiBpdHMgZGVhbGxvY2F0b3IuCiAgICAgKi8KICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZS0+ZGVjcmVmX2ZhY3RvcnkgPSAwOwogICAgUHlfREVDUkVGKHNlbGYpOwoKICAgIHNlbGYtPmluVHJhbnNhY3Rpb24gPSAwOwogICAgc2VsZi0+ZGV0ZWN0X3R5cGVzID0gZGV0ZWN0X3R5cGVzOwogICAgc2VsZi0+dGltZW91dCA9IHRpbWVvdXQ7CiAgICAodm9pZClzcWxpdGUzX2J1c3lfdGltZW91dChzZWxmLT5kYiwgKGludCkodGltZW91dCoxMDAwKSk7CgogICAgc2VsZi0+dGhyZWFkX2lkZW50ID0gUHlUaHJlYWRfZ2V0X3RocmVhZF9pZGVudCgpOwogICAgc2VsZi0+Y2hlY2tfc2FtZV90aHJlYWQgPSBjaGVja19zYW1lX3RocmVhZDsKCiAgICBzZWxmLT5mdW5jdGlvbl9waW5ib2FyZCA9IFB5RGljdF9OZXcoKTsKICAgIGlmICghc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgc2VsZi0+Y29sbGF0aW9ucyA9IFB5RGljdF9OZXcoKTsKICAgIGlmICghc2VsZi0+Y29sbGF0aW9ucykgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBzZWxmLT5XYXJuaW5nID0gV2FybmluZzsKICAgIHNlbGYtPkVycm9yID0gRXJyb3I7CiAgICBzZWxmLT5JbnRlcmZhY2VFcnJvciA9IEludGVyZmFjZUVycm9yOwogICAgc2VsZi0+RGF0YWJhc2VFcnJvciA9IERhdGFiYXNlRXJyb3I7CiAgICBzZWxmLT5EYXRhRXJyb3IgPSBEYXRhRXJyb3I7CiAgICBzZWxmLT5PcGVyYXRpb25hbEVycm9yID0gT3BlcmF0aW9uYWxFcnJvcjsKICAgIHNlbGYtPkludGVncml0eUVycm9yID0gSW50ZWdyaXR5RXJyb3I7CiAgICBzZWxmLT5JbnRlcm5hbEVycm9yID0gSW50ZXJuYWxFcnJvcjsKICAgIHNlbGYtPlByb2dyYW1taW5nRXJyb3IgPSBQcm9ncmFtbWluZ0Vycm9yOwogICAgc2VsZi0+Tm90U3VwcG9ydGVkRXJyb3IgPSBOb3RTdXBwb3J0ZWRFcnJvcjsKCiAgICByZXR1cm4gMDsKfQoKLyogRW1wdHkgdGhlIGVudGlyZSBzdGF0ZW1lbnQgY2FjaGUgb2YgdGhpcyBjb25uZWN0aW9uICovCnZvaWQgZmx1c2hfc3RhdGVtZW50X2NhY2hlKENvbm5lY3Rpb24qIHNlbGYpCnsKICAgIE5vZGUqIG5vZGU7CiAgICBTdGF0ZW1lbnQqIHN0YXRlbWVudDsKCiAgICBub2RlID0gc2VsZi0+c3RhdGVtZW50X2NhY2hlLT5maXJzdDsKCiAgICB3aGlsZSAobm9kZSkgewogICAgICAgIHN0YXRlbWVudCA9IChTdGF0ZW1lbnQqKShub2RlLT5kYXRhKTsKICAgICAgICAodm9pZClzdGF0ZW1lbnRfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICBub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KCiAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50X2NhY2hlKTsKICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZSA9IChDYWNoZSopUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKChQeU9iamVjdCopJkNhY2hlVHlwZSwgIk8iLCBzZWxmKTsKICAgIFB5X0RFQ1JFRihzZWxmKTsKICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZS0+ZGVjcmVmX2ZhY3RvcnkgPSAwOwp9Cgp2b2lkIHJlc2V0X2FsbF9zdGF0ZW1lbnRzKENvbm5lY3Rpb24qIHNlbGYpCnsKICAgIGludCBpOwogICAgUHlPYmplY3QqIHdlYWtyZWY7CiAgICBQeU9iamVjdCogc3RhdGVtZW50OwoKICAgIGZvciAoaSA9IDA7IGkgPCBQeUxpc3RfU2l6ZShzZWxmLT5zdGF0ZW1lbnRzKTsgaSsrKSB7CiAgICAgICAgd2Vha3JlZiA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnN0YXRlbWVudHMsIGkpOwogICAgICAgIHN0YXRlbWVudCA9IFB5V2Vha3JlZl9HZXRPYmplY3Qod2Vha3JlZik7CiAgICAgICAgaWYgKHN0YXRlbWVudCAhPSBQeV9Ob25lKSB7CiAgICAgICAgICAgICh2b2lkKXN0YXRlbWVudF9yZXNldCgoU3RhdGVtZW50KilzdGF0ZW1lbnQpOwogICAgICAgIH0KICAgIH0KfQoKdm9pZCBjb25uZWN0aW9uX2RlYWxsb2MoQ29ubmVjdGlvbiogc2VsZikKewogICAgUHlfWERFQ1JFRihzZWxmLT5zdGF0ZW1lbnRfY2FjaGUpOwoKICAgIC8qIENsZWFuIHVwIGlmIHVzZXIgaGFzIG5vdCBjYWxsZWQgLmNsb3NlKCkgZXhwbGljaXRseS4gKi8KICAgIGlmIChzZWxmLT5kYikgewogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICBzcWxpdGUzX2Nsb3NlKHNlbGYtPmRiKTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgfQoKICAgIGlmIChzZWxmLT5iZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICBQeU1lbV9GcmVlKHNlbGYtPmJlZ2luX3N0YXRlbWVudCk7CiAgICB9CiAgICBQeV9YREVDUkVGKHNlbGYtPmlzb2xhdGlvbl9sZXZlbCk7CiAgICBQeV9YREVDUkVGKHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+cm93X2ZhY3RvcnkpOwogICAgUHlfWERFQ1JFRihzZWxmLT50ZXh0X2ZhY3RvcnkpOwogICAgUHlfWERFQ1JFRihzZWxmLT5jb2xsYXRpb25zKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+c3RhdGVtZW50cyk7CgogICAgc2VsZi0+b2JfdHlwZS0+dHBfZnJlZSgoUHlPYmplY3QqKXNlbGYpOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jdXJzb3IoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiZmFjdG9yeSIsIE5VTEwsIE5VTEx9OwogICAgUHlPYmplY3QqIGZhY3RvcnkgPSBOVUxMOwogICAgUHlPYmplY3QqIGN1cnNvcjsKCgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAifE8iLCBrd2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmFjdG9yeSkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIWNoZWNrX3RocmVhZChzZWxmKSB8fCAhY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChmYWN0b3J5ID09IE5VTEwpIHsKICAgICAgICBmYWN0b3J5ID0gKFB5T2JqZWN0KikmQ3Vyc29yVHlwZTsKICAgIH0KCiAgICBjdXJzb3IgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oZmFjdG9yeSwgIk8iLCBzZWxmKTsKCiAgICBpZiAoY3Vyc29yICYmIHNlbGYtPnJvd19mYWN0b3J5ICE9IFB5X05vbmUpIHsKICAgICAgICBQeV9YREVDUkVGKCgoQ3Vyc29yKiljdXJzb3IpLT5yb3dfZmFjdG9yeSk7CiAgICAgICAgUHlfSU5DUkVGKHNlbGYtPnJvd19mYWN0b3J5KTsKICAgICAgICAoKEN1cnNvciopY3Vyc29yKS0+cm93X2ZhY3RvcnkgPSBzZWxmLT5yb3dfZmFjdG9yeTsKICAgIH0KCiAgICByZXR1cm4gY3Vyc29yOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jbG9zZShDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgaW50IHJjOwoKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgZmx1c2hfc3RhdGVtZW50X2NhY2hlKHNlbGYpOwoKICAgIGlmIChzZWxmLT5kYikgewogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfY2xvc2Uoc2VsZi0+ZGIpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZi0+ZGIgPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKLyoKICogQ2hlY2tzIGlmIGEgY29ubmVjdGlvbiBvYmplY3QgaXMgdXNhYmxlIChpLiBlLiBub3QgY2xvc2VkKS4KICoKICogMCA9PiBlcnJvcjsgMSA9PiBvawogKi8KaW50IGNoZWNrX2Nvbm5lY3Rpb24oQ29ubmVjdGlvbiogY29uKQp7CiAgICBpZiAoIWNvbi0+ZGIpIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHJvZ3JhbW1pbmdFcnJvciwgIkNhbm5vdCBvcGVyYXRlIG9uIGEgY2xvc2VkIGRhdGFiYXNlLiIpOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KfQoKUHlPYmplY3QqIF9jb25uZWN0aW9uX2JlZ2luKENvbm5lY3Rpb24qIHNlbGYpCnsKICAgIGludCByYzsKICAgIGNvbnN0IGNoYXIqIHRhaWw7CiAgICBzcWxpdGUzX3N0bXQqIHN0YXRlbWVudDsKCiAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5kYiwgc2VsZi0+YmVnaW5fc3RhdGVtZW50LCAtMSwgJnN0YXRlbWVudCwgJnRhaWwpOwogICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHJjID0gX3NxbGl0ZV9zdGVwX3dpdGhfYnVzeWhhbmRsZXIoc3RhdGVtZW50LCBzZWxmKTsKICAgIGlmIChyYyA9PSBTUUxJVEVfRE9ORSkgewogICAgICAgIHNlbGYtPmluVHJhbnNhY3Rpb24gPSAxOwogICAgfSBlbHNlIHsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgfQoKICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgIHJjID0gc3FsaXRlM19maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LICYmICFQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgIH0KCmVycm9yOgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jb21taXQoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIGludCByYzsKICAgIGNvbnN0IGNoYXIqIHRhaWw7CiAgICBzcWxpdGUzX3N0bXQqIHN0YXRlbWVudDsKCiAgICBpZiAoIWNoZWNrX3RocmVhZChzZWxmKSB8fCAhY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChzZWxmLT5pblRyYW5zYWN0aW9uKSB7CiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHJjID0gc3FsaXRlM19wcmVwYXJlKHNlbGYtPmRiLCAiQ09NTUlUIiwgLTEsICZzdGF0ZW1lbnQsICZ0YWlsKTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHJjID0gX3NxbGl0ZV9zdGVwX3dpdGhfYnVzeWhhbmRsZXIoc3RhdGVtZW50LCBzZWxmKTsKICAgICAgICBpZiAocmMgPT0gU1FMSVRFX0RPTkUpIHsKICAgICAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICB9CgogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0sgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICB9CgogICAgfQoKZXJyb3I6CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX3JvbGxiYWNrKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpbnQgcmM7CiAgICBjb25zdCBjaGFyKiB0YWlsOwogICAgc3FsaXRlM19zdG10KiBzdGF0ZW1lbnQ7CgogICAgaWYgKCFjaGVja190aHJlYWQoc2VsZikgfHwgIWNoZWNrX2Nvbm5lY3Rpb24oc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoc2VsZi0+aW5UcmFuc2FjdGlvbikgewogICAgICAgIHJlc2V0X2FsbF9zdGF0ZW1lbnRzKHNlbGYpOwoKICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgcmMgPSBzcWxpdGUzX3ByZXBhcmUoc2VsZi0+ZGIsICJST0xMQkFDSyIsIC0xLCAmc3RhdGVtZW50LCAmdGFpbCk7CiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgICAgIF9zZXRlcnJvcihzZWxmLT5kYik7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICByYyA9IF9zcWxpdGVfc3RlcF93aXRoX2J1c3loYW5kbGVyKHN0YXRlbWVudCwgc2VsZik7CiAgICAgICAgaWYgKHJjID09IFNRTElURV9ET05FKSB7CiAgICAgICAgICAgIHNlbGYtPmluVHJhbnNhY3Rpb24gPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIF9zZXRlcnJvcihzZWxmLT5kYik7CiAgICAgICAgfQoKICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgcmMgPSBzcWxpdGUzX2ZpbmFsaXplKHN0YXRlbWVudCk7CiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX09LICYmICFQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgICAgIF9zZXRlcnJvcihzZWxmLT5kYik7CiAgICAgICAgfQoKICAgIH0KCmVycm9yOgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQp9Cgp2b2lkIF9zZXRfcmVzdWx0KHNxbGl0ZTNfY29udGV4dCogY29udGV4dCwgUHlPYmplY3QqIHB5X3ZhbCkKewogICAgbG9uZyBsb25ndmFsOwogICAgY29uc3QgY2hhciogYnVmZmVyOwogICAgUHlfc3NpemVfdCBidWZsZW47CiAgICBQeU9iamVjdCogc3RyaW5ndmFsOwoKICAgIGlmICgoIXB5X3ZhbCkgfHwgUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIC8qIEVycm9ycyBpbiBjYWxsYmFja3MgYXJlIGlnbm9yZWQsIGFuZCB3ZSByZXR1cm4gTlVMTCAqLwogICAgICAgIFB5RXJyX0NsZWFyKCk7CiAgICAgICAgc3FsaXRlM19yZXN1bHRfbnVsbChjb250ZXh0KTsKICAgIH0gZWxzZSBpZiAocHlfdmFsID09IFB5X05vbmUpIHsKICAgICAgICBzcWxpdGUzX3Jlc3VsdF9udWxsKGNvbnRleHQpOwogICAgfSBlbHNlIGlmIChQeUludF9DaGVjayhweV92YWwpKSB7CiAgICAgICAgbG9uZ3ZhbCA9IFB5SW50X0FzTG9uZyhweV92YWwpOwogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2ludDY0KGNvbnRleHQsIChQWV9MT05HX0xPTkcpbG9uZ3ZhbCk7CiAgICB9IGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2RvdWJsZShjb250ZXh0LCBQeUZsb2F0X0FzRG91YmxlKHB5X3ZhbCkpOwogICAgfSBlbHNlIGlmIChQeUJ1ZmZlcl9DaGVjayhweV92YWwpKSB7CiAgICAgICAgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihweV92YWwsICZidWZmZXIsICZidWZsZW4pICE9IDApIHsKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJjb3VsZCBub3QgY29udmVydCBCTE9CIHRvIGJ1ZmZlciIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNxbGl0ZTNfcmVzdWx0X2Jsb2IoY29udGV4dCwgYnVmZmVyLCBidWZsZW4sIFNRTElURV9UUkFOU0lFTlQpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X3RleHQoY29udGV4dCwgUHlTdHJpbmdfQXNTdHJpbmcocHlfdmFsKSwgLTEsIFNRTElURV9UUkFOU0lFTlQpOwogICAgfSBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHN0cmluZ3ZhbCA9IFB5VW5pY29kZV9Bc1VURjhTdHJpbmcocHlfdmFsKTsKICAgICAgICBpZiAoc3RyaW5ndmFsKSB7CiAgICAgICAgICAgIHNxbGl0ZTNfcmVzdWx0X3RleHQoY29udGV4dCwgUHlTdHJpbmdfQXNTdHJpbmcoc3RyaW5ndmFsKSwgLTEsIFNRTElURV9UUkFOU0lFTlQpOwogICAgICAgICAgICBQeV9ERUNSRUYoc3RyaW5ndmFsKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRPRE86IHJhaXNlIGVycm9yICovCiAgICB9Cn0KClB5T2JqZWN0KiBfYnVpbGRfcHlfcGFyYW1zKHNxbGl0ZTNfY29udGV4dCAqY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIGludCBpOwogICAgc3FsaXRlM192YWx1ZSogY3VyX3ZhbHVlOwogICAgUHlPYmplY3QqIGN1cl9weV92YWx1ZTsKICAgIGNvbnN0IGNoYXIqIHZhbF9zdHI7CiAgICBQWV9MT05HX0xPTkcgdmFsX2ludDsKICAgIFB5X3NzaXplX3QgYnVmbGVuOwogICAgdm9pZCogcmF3X2J1ZmZlcjsKCiAgICBhcmdzID0gUHlUdXBsZV9OZXcoYXJnYyk7CiAgICBpZiAoIWFyZ3MpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgYXJnYzsgaSsrKSB7CiAgICAgICAgY3VyX3ZhbHVlID0gYXJndltpXTsKICAgICAgICBzd2l0Y2ggKHNxbGl0ZTNfdmFsdWVfdHlwZShhcmd2W2ldKSkgewogICAgICAgICAgICBjYXNlIFNRTElURV9JTlRFR0VSOgogICAgICAgICAgICAgICAgdmFsX2ludCA9IHNxbGl0ZTNfdmFsdWVfaW50NjQoY3VyX3ZhbHVlKTsKICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IFB5SW50X0Zyb21Mb25nKChsb25nKXZhbF9pbnQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0ZMT0FUOgogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlGbG9hdF9Gcm9tRG91YmxlKHNxbGl0ZTNfdmFsdWVfZG91YmxlKGN1cl92YWx1ZSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX1RFWFQ6CiAgICAgICAgICAgICAgICB2YWxfc3RyID0gKGNvbnN0IGNoYXIqKXNxbGl0ZTNfdmFsdWVfdGV4dChjdXJfdmFsdWUpOwogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlVbmljb2RlX0RlY29kZVVURjgodmFsX3N0ciwgc3RybGVuKHZhbF9zdHIpLCBOVUxMKTsKICAgICAgICAgICAgICAgIC8qIFRPRE86IGhhdmUgYSB3YXkgdG8gc2hvdyBlcnJvcnMgaGVyZSAqLwogICAgICAgICAgICAgICAgaWYgKCFjdXJfcHlfdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgICAgICBjdXJfcHlfdmFsdWUgPSBQeV9Ob25lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0JMT0I6CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzcWxpdGUzX3ZhbHVlX2J5dGVzKGN1cl92YWx1ZSk7CiAgICAgICAgICAgICAgICBjdXJfcHlfdmFsdWUgPSBQeUJ1ZmZlcl9OZXcoYnVmbGVuKTsKICAgICAgICAgICAgICAgIGlmICghY3VyX3B5X3ZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoUHlPYmplY3RfQXNXcml0ZUJ1ZmZlcihjdXJfcHlfdmFsdWUsICZyYXdfYnVmZmVyLCAmYnVmbGVuKSkgewogICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihjdXJfcHlfdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtZW1jcHkocmF3X2J1ZmZlciwgc3FsaXRlM192YWx1ZV9ibG9iKGN1cl92YWx1ZSksIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTUUxJVEVfTlVMTDoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IFB5X05vbmU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWN1cl9weV92YWx1ZSkgewogICAgICAgICAgICBQeV9ERUNSRUYoYXJncyk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgUHlUdXBsZV9TZXRJdGVtKGFyZ3MsIGksIGN1cl9weV92YWx1ZSk7CgogICAgfQoKICAgIHJldHVybiBhcmdzOwp9Cgp2b2lkIF9mdW5jX2NhbGxiYWNrKHNxbGl0ZTNfY29udGV4dCogY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIFB5T2JqZWN0KiBweV9mdW5jOwogICAgUHlPYmplY3QqIHB5X3JldHZhbCA9IE5VTEw7CgogICAgUHlHSUxTdGF0ZV9TVEFURSB0aHJlYWRzdGF0ZTsKCiAgICB0aHJlYWRzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CgogICAgcHlfZnVuYyA9IChQeU9iamVjdCopc3FsaXRlM191c2VyX2RhdGEoY29udGV4dCk7CgogICAgYXJncyA9IF9idWlsZF9weV9wYXJhbXMoY29udGV4dCwgYXJnYywgYXJndik7CiAgICBpZiAoYXJncykgewogICAgICAgIHB5X3JldHZhbCA9IFB5T2JqZWN0X0NhbGxPYmplY3QocHlfZnVuYywgYXJncyk7CiAgICAgICAgUHlfREVDUkVGKGFyZ3MpOwogICAgfQoKICAgIF9zZXRfcmVzdWx0KGNvbnRleHQsIHB5X3JldHZhbCk7CiAgICBQeV9YREVDUkVGKHB5X3JldHZhbCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKHRocmVhZHN0YXRlKTsKfQoKc3RhdGljIHZvaWQgX3N0ZXBfY2FsbGJhY2soc3FsaXRlM19jb250ZXh0ICpjb250ZXh0LCBpbnQgYXJnYywgc3FsaXRlM192YWx1ZSoqIHBhcmFtcykKewogICAgUHlPYmplY3QqIGFyZ3M7CiAgICBQeU9iamVjdCogZnVuY3Rpb25fcmVzdWx0ID0gTlVMTDsKICAgIFB5T2JqZWN0KiBhZ2dyZWdhdGVfY2xhc3M7CiAgICBQeU9iamVjdCoqIGFnZ3JlZ2F0ZV9pbnN0YW5jZTsKICAgIFB5T2JqZWN0KiBzdGVwbWV0aG9kID0gTlVMTDsKCiAgICBQeUdJTFN0YXRlX1NUQVRFIHRocmVhZHN0YXRlOwoKICAgIHRocmVhZHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBhZ2dyZWdhdGVfY2xhc3MgPSAoUHlPYmplY3QqKXNxbGl0ZTNfdXNlcl9kYXRhKGNvbnRleHQpOwoKICAgIGFnZ3JlZ2F0ZV9pbnN0YW5jZSA9IChQeU9iamVjdCoqKXNxbGl0ZTNfYWdncmVnYXRlX2NvbnRleHQoY29udGV4dCwgc2l6ZW9mKFB5T2JqZWN0KikpOwoKICAgIGlmICgqYWdncmVnYXRlX2luc3RhbmNlID09IDApIHsKICAgICAgICAqYWdncmVnYXRlX2luc3RhbmNlID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKGFnZ3JlZ2F0ZV9jbGFzcywgIiIpOwoKICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAqYWdncmVnYXRlX2luc3RhbmNlID0gMDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9CgogICAgc3RlcG1ldGhvZCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoKmFnZ3JlZ2F0ZV9pbnN0YW5jZSwgInN0ZXAiKTsKICAgIGlmICghc3RlcG1ldGhvZCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgYXJncyA9IF9idWlsZF9weV9wYXJhbXMoY29udGV4dCwgYXJnYywgcGFyYW1zKTsKICAgIGlmICghYXJncykgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgZnVuY3Rpb25fcmVzdWx0ID0gUHlPYmplY3RfQ2FsbE9iamVjdChzdGVwbWV0aG9kLCBhcmdzKTsKICAgIFB5X0RFQ1JFRihhcmdzKTsKCiAgICBpZiAoIWZ1bmN0aW9uX3Jlc3VsdCkgewogICAgICAgIFB5RXJyX0NsZWFyKCk7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYoc3RlcG1ldGhvZCk7CiAgICBQeV9YREVDUkVGKGZ1bmN0aW9uX3Jlc3VsdCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKHRocmVhZHN0YXRlKTsKfQoKdm9pZCBfZmluYWxfY2FsbGJhY2soc3FsaXRlM19jb250ZXh0KiBjb250ZXh0KQp7CiAgICBQeU9iamVjdCogZnVuY3Rpb25fcmVzdWx0ID0gTlVMTDsKICAgIFB5T2JqZWN0KiogYWdncmVnYXRlX2luc3RhbmNlOwogICAgUHlPYmplY3QqIGFnZ3JlZ2F0ZV9jbGFzczsKCiAgICBQeUdJTFN0YXRlX1NUQVRFIHRocmVhZHN0YXRlOwoKICAgIHRocmVhZHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBhZ2dyZWdhdGVfY2xhc3MgPSAoUHlPYmplY3QqKXNxbGl0ZTNfdXNlcl9kYXRhKGNvbnRleHQpOwoKICAgIGFnZ3JlZ2F0ZV9pbnN0YW5jZSA9IChQeU9iamVjdCoqKXNxbGl0ZTNfYWdncmVnYXRlX2NvbnRleHQoY29udGV4dCwgc2l6ZW9mKFB5T2JqZWN0KikpOwogICAgaWYgKCEqYWdncmVnYXRlX2luc3RhbmNlKSB7CiAgICAgICAgLyogdGhpcyBicmFuY2ggaXMgZXhlY3V0ZWQgaWYgdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbiBpbiB0aGUgYWdncmVnYXRlJ3MKICAgICAgICAgKiBfX2luaXRfXyAqLwoKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGZ1bmN0aW9uX3Jlc3VsdCA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKmFnZ3JlZ2F0ZV9pbnN0YW5jZSwgImZpbmFsaXplIiwgIiIpOwogICAgaWYgKCFmdW5jdGlvbl9yZXN1bHQpIHsKICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICBmdW5jdGlvbl9yZXN1bHQgPSBQeV9Ob25lOwogICAgfQoKICAgIF9zZXRfcmVzdWx0KGNvbnRleHQsIGZ1bmN0aW9uX3Jlc3VsdCk7CgplcnJvcjoKICAgIFB5X1hERUNSRUYoKmFnZ3JlZ2F0ZV9pbnN0YW5jZSk7CiAgICBQeV9YREVDUkVGKGZ1bmN0aW9uX3Jlc3VsdCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKHRocmVhZHN0YXRlKTsKfQoKdm9pZCBfZHJvcF91bnVzZWRfc3RhdGVtZW50X3JlZmVyZW5jZXMoQ29ubmVjdGlvbiogc2VsZikKewogICAgUHlPYmplY3QqIG5ld19saXN0OwogICAgUHlPYmplY3QqIHdlYWtyZWY7CiAgICBpbnQgaTsKCiAgICAvKiB3ZSBvbmx5IG5lZWQgdG8gZG8gdGhpcyBvbmNlIGluIGEgd2hpbGUgKi8KICAgIGlmIChzZWxmLT5jcmVhdGVkX3N0YXRlbWVudHMrKyA8IDIwMCkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBzZWxmLT5jcmVhdGVkX3N0YXRlbWVudHMgPSAwOwoKICAgIG5ld19saXN0ID0gUHlMaXN0X05ldygwKTsKICAgIGlmICghbmV3X2xpc3QpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IFB5TGlzdF9TaXplKHNlbGYtPnN0YXRlbWVudHMpOyBpKyspIHsKICAgICAgICB3ZWFrcmVmID0gUHlMaXN0X0dldEl0ZW0oc2VsZi0+c3RhdGVtZW50cywgaSk7CiAgICAgICAgaWYgKHdlYWtyZWYgIT0gUHlfTm9uZSkgewogICAgICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChuZXdfbGlzdCwgd2Vha3JlZikgIT0gMCkgewogICAgICAgICAgICAgICAgUHlfREVDUkVGKG5ld19saXN0KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50cyk7CiAgICBzZWxmLT5zdGF0ZW1lbnRzID0gbmV3X2xpc3Q7Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2NyZWF0ZV9mdW5jdGlvbihDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJuYW1lIiwgIm5hcmciLCAiZnVuYyIsIE5VTEwsIE5VTEx9OwoKICAgIFB5T2JqZWN0KiBmdW5jOwogICAgY2hhciogbmFtZTsKICAgIGludCBuYXJnOwogICAgaW50IHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInNpTyIsIGt3bGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYW1lLCAmbmFyZywgJmZ1bmMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJjID0gc3FsaXRlM19jcmVhdGVfZnVuY3Rpb24oc2VsZi0+ZGIsIG5hbWUsIG5hcmcsIFNRTElURV9VVEY4LCAodm9pZCopZnVuYywgX2Z1bmNfY2FsbGJhY2ssIE5VTEwsIE5VTEwpOwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAvKiBXb3JrYXJvdW5kIGZvciBTUUxpdGUgYnVnOiBubyBlcnJvciBjb2RlIG9yIHN0cmluZyBpcyBhdmFpbGFibGUgaGVyZSAqLwogICAgICAgIFB5RXJyX1NldFN0cmluZyhPcGVyYXRpb25hbEVycm9yLCAiRXJyb3IgY3JlYXRpbmcgZnVuY3Rpb24iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQsIGZ1bmMsIFB5X05vbmUpOwoKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2NyZWF0ZV9hZ2dyZWdhdGUoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBhZ2dyZWdhdGVfY2xhc3M7CgogICAgaW50IG5fYXJnOwogICAgY2hhciogbmFtZTsKICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsgIm5hbWUiLCAibl9hcmciLCAiYWdncmVnYXRlX2NsYXNzIiwgTlVMTCB9OwogICAgaW50IHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInNpTzpjcmVhdGVfYWdncmVnYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZuYW1lLCAmbl9hcmcsICZhZ2dyZWdhdGVfY2xhc3MpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmMgPSBzcWxpdGUzX2NyZWF0ZV9mdW5jdGlvbihzZWxmLT5kYiwgbmFtZSwgbl9hcmcsIFNRTElURV9VVEY4LCAodm9pZCopYWdncmVnYXRlX2NsYXNzLCAwLCAmX3N0ZXBfY2FsbGJhY2ssICZfZmluYWxfY2FsbGJhY2spOwogICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgIC8qIFdvcmthcm91bmQgZm9yIFNRTGl0ZSBidWc6IG5vIGVycm9yIGNvZGUgb3Igc3RyaW5nIGlzIGF2YWlsYWJsZSBoZXJlICovCiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE9wZXJhdGlvbmFsRXJyb3IsICJFcnJvciBjcmVhdGluZyBhZ2dyZWdhdGUiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQsIGFnZ3JlZ2F0ZV9jbGFzcywgUHlfTm9uZSk7CgogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR1cm4gUHlfTm9uZTsKICAgIH0KfQoKaW50IGNoZWNrX3RocmVhZChDb25uZWN0aW9uKiBzZWxmKQp7CiAgICBpZiAoc2VsZi0+Y2hlY2tfc2FtZV90aHJlYWQpIHsKICAgICAgICBpZiAoUHlUaHJlYWRfZ2V0X3RocmVhZF9pZGVudCgpICE9IHNlbGYtPnRocmVhZF9pZGVudCkgewogICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHJvZ3JhbW1pbmdFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgIlNRTGl0ZSBvYmplY3RzIGNyZWF0ZWQgaW4gYSB0aHJlYWQgY2FuIG9ubHkgYmUgdXNlZCBpbiB0aGF0IHNhbWUgdGhyZWFkLiIKICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQgaW4gdGhyZWFkIGlkICVsZCBhbmQgdGhpcyBpcyB0aHJlYWQgaWQgJWxkIiwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+dGhyZWFkX2lkZW50LCBQeVRocmVhZF9nZXRfdGhyZWFkX2lkZW50KCkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgUHlPYmplY3QqIGNvbm5lY3Rpb25fZ2V0X2lzb2xhdGlvbl9sZXZlbChDb25uZWN0aW9uKiBzZWxmLCB2b2lkKiB1bnVzZWQpCnsKICAgIFB5X0lOQ1JFRihzZWxmLT5pc29sYXRpb25fbGV2ZWwpOwogICAgcmV0dXJuIHNlbGYtPmlzb2xhdGlvbl9sZXZlbDsKfQoKc3RhdGljIFB5T2JqZWN0KiBjb25uZWN0aW9uX2dldF90b3RhbF9jaGFuZ2VzKENvbm5lY3Rpb24qIHNlbGYsIHZvaWQqIHVudXNlZCkKewogICAgaWYgKCFjaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCJpIiwgc3FsaXRlM190b3RhbF9jaGFuZ2VzKHNlbGYtPmRiKSk7CiAgICB9Cn0KCnN0YXRpYyBpbnQgY29ubmVjdGlvbl9zZXRfaXNvbGF0aW9uX2xldmVsKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBpc29sYXRpb25fbGV2ZWwpCnsKICAgIFB5T2JqZWN0KiByZXM7CiAgICBQeU9iamVjdCogYmVnaW5fc3RhdGVtZW50OwoKICAgIFB5X1hERUNSRUYoc2VsZi0+aXNvbGF0aW9uX2xldmVsKTsKCiAgICBpZiAoc2VsZi0+YmVnaW5fc3RhdGVtZW50KSB7CiAgICAgICAgUHlNZW1fRnJlZShzZWxmLT5iZWdpbl9zdGF0ZW1lbnQpOwogICAgICAgIHNlbGYtPmJlZ2luX3N0YXRlbWVudCA9IE5VTEw7CiAgICB9CgogICAgaWYgKGlzb2xhdGlvbl9sZXZlbCA9PSBQeV9Ob25lKSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHNlbGYtPmlzb2xhdGlvbl9sZXZlbCA9IFB5X05vbmU7CgogICAgICAgIHJlcyA9IGNvbm5lY3Rpb25fY29tbWl0KHNlbGYsIE5VTEwpOwogICAgICAgIGlmICghcmVzKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgUHlfREVDUkVGKHJlcyk7CgogICAgICAgIHNlbGYtPmluVHJhbnNhY3Rpb24gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoaXNvbGF0aW9uX2xldmVsKTsKICAgICAgICBzZWxmLT5pc29sYXRpb25fbGV2ZWwgPSBpc29sYXRpb25fbGV2ZWw7CgogICAgICAgIGJlZ2luX3N0YXRlbWVudCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoIkJFR0lOICIpOwogICAgICAgIGlmICghYmVnaW5fc3RhdGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgUHlTdHJpbmdfQ29uY2F0KCZiZWdpbl9zdGF0ZW1lbnQsIGlzb2xhdGlvbl9sZXZlbCk7CiAgICAgICAgaWYgKCFiZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgc2VsZi0+YmVnaW5fc3RhdGVtZW50ID0gUHlNZW1fTWFsbG9jKFB5U3RyaW5nX1NpemUoYmVnaW5fc3RhdGVtZW50KSArIDIpOwogICAgICAgIGlmICghc2VsZi0+YmVnaW5fc3RhdGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIHN0cmNweShzZWxmLT5iZWdpbl9zdGF0ZW1lbnQsIFB5U3RyaW5nX0FzU3RyaW5nKGJlZ2luX3N0YXRlbWVudCkpOwogICAgICAgIFB5X0RFQ1JFRihiZWdpbl9zdGF0ZW1lbnQpOwogICAgfQoKICAgIHJldHVybiAwOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jYWxsKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogc3FsOwogICAgU3RhdGVtZW50KiBzdGF0ZW1lbnQ7CiAgICBQeU9iamVjdCogd2Vha3JlZjsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8iLCAmc3FsKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIF9kcm9wX3VudXNlZF9zdGF0ZW1lbnRfcmVmZXJlbmNlcyhzZWxmKTsKCiAgICBzdGF0ZW1lbnQgPSBQeU9iamVjdF9OZXcoU3RhdGVtZW50LCAmU3RhdGVtZW50VHlwZSk7CiAgICBpZiAoIXN0YXRlbWVudCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJjID0gc3RhdGVtZW50X2NyZWF0ZShzdGF0ZW1lbnQsIHNlbGYsIHNxbCk7CgogICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgIGlmIChyYyA9PSBQWVNRTElURV9UT09fTVVDSF9TUUwpIHsKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFdhcm5pbmcsICJZb3UgY2FuIG9ubHkgZXhlY3V0ZSBvbmUgc3RhdGVtZW50IGF0IGEgdGltZS4iKTsKICAgICAgICB9IGVsc2UgaWYgKHJjID09IFBZU1FMSVRFX1NRTF9XUk9OR19UWVBFKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhXYXJuaW5nLCAiU1FMIGlzIG9mIHdyb25nIHR5cGUuIE11c3QgYmUgc3RyaW5nIG9yIHVuaWNvZGUuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICB9CgogICAgICAgIFB5X0RFQ1JFRihzdGF0ZW1lbnQpOwogICAgICAgIHN0YXRlbWVudCA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIHdlYWtyZWYgPSBQeVdlYWtyZWZfTmV3UmVmKChQeU9iamVjdCopc3RhdGVtZW50LCBOVUxMKTsKICAgICAgICBpZiAoIXdlYWtyZWYpIHsKICAgICAgICAgICAgUHlfREVDUkVGKHN0YXRlbWVudCk7CiAgICAgICAgICAgIHN0YXRlbWVudCA9IDA7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChzZWxmLT5zdGF0ZW1lbnRzLCB3ZWFrcmVmKSAhPSAwKSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRih3ZWFrcmVmKTsKICAgICAgICAgICAgc3RhdGVtZW50ID0gMDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIFB5X0RFQ1JFRih3ZWFrcmVmKTsKICAgIH0KCmVycm9yOgogICAgcmV0dXJuIChQeU9iamVjdCopc3RhdGVtZW50Owp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9leGVjdXRlKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogY3Vyc29yID0gMDsKICAgIFB5T2JqZWN0KiByZXN1bHQgPSAwOwogICAgUHlPYmplY3QqIG1ldGhvZCA9IDA7CgogICAgY3Vyc29yID0gUHlPYmplY3RfQ2FsbE1ldGhvZCgoUHlPYmplY3QqKXNlbGYsICJjdXJzb3IiLCAiIik7CiAgICBpZiAoIWN1cnNvcikgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgbWV0aG9kID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhjdXJzb3IsICJleGVjdXRlIik7CiAgICBpZiAoIW1ldGhvZCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsT2JqZWN0KG1ldGhvZCwgYXJncyk7CiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYocmVzdWx0KTsKICAgIFB5X1hERUNSRUYobWV0aG9kKTsKCiAgICByZXR1cm4gY3Vyc29yOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9leGVjdXRlbWFueShDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlPYmplY3QqIGN1cnNvciA9IDA7CiAgICBQeU9iamVjdCogcmVzdWx0ID0gMDsKICAgIFB5T2JqZWN0KiBtZXRob2QgPSAwOwoKICAgIGN1cnNvciA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKFB5T2JqZWN0KilzZWxmLCAiY3Vyc29yIiwgIiIpOwogICAgaWYgKCFjdXJzb3IpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG1ldGhvZCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoY3Vyc29yLCAiZXhlY3V0ZW1hbnkiKTsKICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3QobWV0aG9kLCBhcmdzKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihyZXN1bHQpOwogICAgUHlfWERFQ1JFRihtZXRob2QpOwoKICAgIHJldHVybiBjdXJzb3I7Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2V4ZWN1dGVzY3JpcHQoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBjdXJzb3IgPSAwOwogICAgUHlPYmplY3QqIHJlc3VsdCA9IDA7CiAgICBQeU9iamVjdCogbWV0aG9kID0gMDsKCiAgICBjdXJzb3IgPSBQeU9iamVjdF9DYWxsTWV0aG9kKChQeU9iamVjdCopc2VsZiwgImN1cnNvciIsICIiKTsKICAgIGlmICghY3Vyc29yKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBtZXRob2QgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGN1cnNvciwgImV4ZWN1dGVzY3JpcHQiKTsKICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3QobWV0aG9kLCBhcmdzKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihyZXN1bHQpOwogICAgUHlfWERFQ1JFRihtZXRob2QpOwoKICAgIHJldHVybiBjdXJzb3I7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ09MTEFUSU9OIENPREUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgaW50CmNvbGxhdGlvbl9jYWxsYmFjaygKICAgICAgICB2b2lkKiBjb250ZXh0LAogICAgICAgIGludCB0ZXh0MV9sZW5ndGgsIGNvbnN0IHZvaWQqIHRleHQxX2RhdGEsCiAgICAgICAgaW50IHRleHQyX2xlbmd0aCwgY29uc3Qgdm9pZCogdGV4dDJfZGF0YSkKewogICAgUHlPYmplY3QqIGNhbGxiYWNrID0gKFB5T2JqZWN0Kiljb250ZXh0OwogICAgUHlPYmplY3QqIHN0cmluZzEgPSAwOwogICAgUHlPYmplY3QqIHN0cmluZzIgPSAwOwogICAgUHlHSUxTdGF0ZV9TVEFURSBnaWxzdGF0ZTsKCiAgICBQeU9iamVjdCogcmV0dmFsID0gTlVMTDsKICAgIGludCByZXN1bHQgPSAwOwoKICAgIGdpbHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBzdHJpbmcxID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKGNvbnN0IGNoYXIqKXRleHQxX2RhdGEsIHRleHQxX2xlbmd0aCk7CiAgICBzdHJpbmcyID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKGNvbnN0IGNoYXIqKXRleHQyX2RhdGEsIHRleHQyX2xlbmd0aCk7CgogICAgaWYgKCFzdHJpbmcxIHx8ICFzdHJpbmcyKSB7CiAgICAgICAgZ290byBmaW5hbGx5OyAvKiBmYWlsZWQgdG8gYWxsb2NhdGUgc3RyaW5ncyAqLwogICAgfQoKICAgIHJldHZhbCA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoY2FsbGJhY2ssIHN0cmluZzEsIHN0cmluZzIsIE5VTEwpOwoKICAgIGlmICghcmV0dmFsKSB7CiAgICAgICAgLyogZXhlY3V0aW9uIGZhaWxlZCAqLwogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICByZXN1bHQgPSBQeUludF9Bc0xvbmcocmV0dmFsKTsKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmVzdWx0ID0gMDsKICAgIH0KCmZpbmFsbHk6CiAgICBQeV9YREVDUkVGKHN0cmluZzEpOwogICAgUHlfWERFQ1JFRihzdHJpbmcyKTsKICAgIFB5X1hERUNSRUYocmV0dmFsKTsKCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UoZ2lsc3RhdGUpOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBQeU9iamVjdCAqCmNvbm5lY3Rpb25fY3JlYXRlX2NvbGxhdGlvbihDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIGNhbGxhYmxlOwogICAgUHlPYmplY3QqIHVwcGVyY2FzZV9uYW1lID0gMDsKICAgIFB5T2JqZWN0KiBuYW1lOwogICAgUHlPYmplY3QqIHJldHZhbDsKICAgIGNoYXIqIGNoazsKICAgIGludCByYzsKCiAgICBpZiAoIWNoZWNrX3RocmVhZChzZWxmKSB8fCAhY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hTzpjcmVhdGVfY29sbGF0aW9uKG5hbWUsIGNhbGxiYWNrKSIsICZQeVN0cmluZ19UeXBlLCAmbmFtZSwgJmNhbGxhYmxlKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICB1cHBlcmNhc2VfbmFtZSA9IFB5T2JqZWN0X0NhbGxNZXRob2QobmFtZSwgInVwcGVyIiwgIiIpOwogICAgaWYgKCF1cHBlcmNhc2VfbmFtZSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBjaGsgPSBQeVN0cmluZ19Bc1N0cmluZyh1cHBlcmNhc2VfbmFtZSk7CiAgICB3aGlsZSAoKmNoaykgewogICAgICAgIGlmICgoKmNoayA+PSAnMCcgJiYgKmNoayA8PSAnOScpCiAgICAgICAgIHx8ICgqY2hrID49ICdBJyAmJiAqY2hrIDw9ICdaJykKICAgICAgICAgfHwgKCpjaGsgPT0gJ18nKSkKICAgICAgICB7CiAgICAgICAgICAgIGNoaysrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQcm9ncmFtbWluZ0Vycm9yLCAiaW52YWxpZCBjaGFyYWN0ZXIgaW4gY29sbGF0aW9uIG5hbWUiKTsKICAgICAgICAgICAgZ290byBmaW5hbGx5OwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY2FsbGFibGUgIT0gUHlfTm9uZSAmJiAhUHlDYWxsYWJsZV9DaGVjayhjYWxsYWJsZSkpIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAicGFyYW1ldGVyIG11c3QgYmUgY2FsbGFibGUiKTsKICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgaWYgKGNhbGxhYmxlICE9IFB5X05vbmUpIHsKICAgICAgICBQeURpY3RfU2V0SXRlbShzZWxmLT5jb2xsYXRpb25zLCB1cHBlcmNhc2VfbmFtZSwgY2FsbGFibGUpOwogICAgfSBlbHNlIHsKICAgICAgICBQeURpY3RfRGVsSXRlbShzZWxmLT5jb2xsYXRpb25zLCB1cHBlcmNhc2VfbmFtZSk7CiAgICB9CgogICAgcmMgPSBzcWxpdGUzX2NyZWF0ZV9jb2xsYXRpb24oc2VsZi0+ZGIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyh1cHBlcmNhc2VfbmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTUUxJVEVfVVRGOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYWxsYWJsZSAhPSBQeV9Ob25lKSA/IGNhbGxhYmxlIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYWxsYWJsZSAhPSBQeV9Ob25lKSA/IGNvbGxhdGlvbl9jYWxsYmFjayA6IE5VTEwpOwogICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgIFB5RGljdF9EZWxJdGVtKHNlbGYtPmNvbGxhdGlvbnMsIHVwcGVyY2FzZV9uYW1lKTsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCmZpbmFsbHk6CiAgICBQeV9YREVDUkVGKHVwcGVyY2FzZV9uYW1lKTsKCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHZhbCA9IE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR2YWwgPSBQeV9Ob25lOwogICAgfQoKICAgIHJldHVybiByZXR2YWw7Cn0KCnN0YXRpYyBjaGFyIGNvbm5lY3Rpb25fZG9jW10gPQpQeURvY19TVFIoIlNRTGl0ZSBkYXRhYmFzZSBjb25uZWN0aW9uIG9iamVjdC4iKTsKCnN0YXRpYyBQeUdldFNldERlZiBjb25uZWN0aW9uX2dldHNldFtdID0gewogICAgeyJpc29sYXRpb25fbGV2ZWwiLCAgKGdldHRlciljb25uZWN0aW9uX2dldF9pc29sYXRpb25fbGV2ZWwsIChzZXR0ZXIpY29ubmVjdGlvbl9zZXRfaXNvbGF0aW9uX2xldmVsfSwKICAgIHsidG90YWxfY2hhbmdlcyIsICAoZ2V0dGVyKWNvbm5lY3Rpb25fZ2V0X3RvdGFsX2NoYW5nZXMsIChzZXR0ZXIpMH0sCiAgICB7TlVMTH0KfTsKCnN0YXRpYyBQeU1ldGhvZERlZiBjb25uZWN0aW9uX21ldGhvZHNbXSA9IHsKICAgIHsiY3Vyc29yIiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fY3Vyc29yLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKICAgICAgICBQeURvY19TVFIoIlJldHVybiBhIGN1cnNvciBmb3IgdGhlIGNvbm5lY3Rpb24uIil9LAogICAgeyJjbG9zZSIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2Nsb3NlLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkNsb3NlcyB0aGUgY29ubmVjdGlvbi4iKX0sCiAgICB7ImNvbW1pdCIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2NvbW1pdCwgTUVUSF9OT0FSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJDb21taXQgdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24uIil9LAogICAgeyJyb2xsYmFjayIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX3JvbGxiYWNrLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIlJvbGwgYmFjayB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi4iKX0sCiAgICB7ImNyZWF0ZV9mdW5jdGlvbiIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2NyZWF0ZV9mdW5jdGlvbiwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJDcmVhdGVzIGEgbmV3IGZ1bmN0aW9uLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJjcmVhdGVfYWdncmVnYXRlIiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fY3JlYXRlX2FnZ3JlZ2F0ZSwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJDcmVhdGVzIGEgbmV3IGFnZ3JlZ2F0ZS4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiZXhlY3V0ZSIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2V4ZWN1dGUsIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIkV4ZWN1dGVzIGEgU1FMIHN0YXRlbWVudC4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiZXhlY3V0ZW1hbnkiLCAoUHlDRnVuY3Rpb24pY29ubmVjdGlvbl9leGVjdXRlbWFueSwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiUmVwZWF0ZWRseSBleGVjdXRlcyBhIFNRTCBzdGF0ZW1lbnQuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImV4ZWN1dGVzY3JpcHQiLCAoUHlDRnVuY3Rpb24pY29ubmVjdGlvbl9leGVjdXRlc2NyaXB0LCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJFeGVjdXRlcyBhIG11bHRpcGxlIFNRTCBzdGF0ZW1lbnRzIGF0IG9uY2UuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImNyZWF0ZV9jb2xsYXRpb24iLCAoUHlDRnVuY3Rpb24pY29ubmVjdGlvbl9jcmVhdGVfY29sbGF0aW9uLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJDcmVhdGVzIGEgY29sbGF0aW9uIGZ1bmN0aW9uLiBOb24tc3RhbmRhcmQuIil9LAogICAge05VTEwsIE5VTEx9Cn07CgpzdGF0aWMgc3RydWN0IFB5TWVtYmVyRGVmIGNvbm5lY3Rpb25fbWVtYmVyc1tdID0KewogICAgeyJXYXJuaW5nIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIFdhcm5pbmcpLCBST30sCiAgICB7IkVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIEVycm9yKSwgUk99LAogICAgeyJJbnRlcmZhY2VFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBJbnRlcmZhY2VFcnJvciksIFJPfSwKICAgIHsiRGF0YWJhc2VFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBEYXRhYmFzZUVycm9yKSwgUk99LAogICAgeyJEYXRhRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgRGF0YUVycm9yKSwgUk99LAogICAgeyJPcGVyYXRpb25hbEVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIE9wZXJhdGlvbmFsRXJyb3IpLCBST30sCiAgICB7IkludGVncml0eUVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIEludGVncml0eUVycm9yKSwgUk99LAogICAgeyJJbnRlcm5hbEVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIEludGVybmFsRXJyb3IpLCBST30sCiAgICB7IlByb2dyYW1taW5nRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgUHJvZ3JhbW1pbmdFcnJvciksIFJPfSwKICAgIHsiTm90U3VwcG9ydGVkRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgTm90U3VwcG9ydGVkRXJyb3IpLCBST30sCiAgICB7InJvd19mYWN0b3J5IiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIHJvd19mYWN0b3J5KX0sCiAgICB7InRleHRfZmFjdG9yeSIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCB0ZXh0X2ZhY3RvcnkpfSwKICAgIHtOVUxMfQp9OwoKUHlUeXBlT2JqZWN0IENvbm5lY3Rpb25UeXBlID0gewogICAgICAgIFB5T2JqZWN0X0hFQURfSU5JVChOVUxMKQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9iX3NpemUgKi8KICAgICAgICBNT0RVTEVfTkFNRSAiLkNvbm5lY3Rpb24iLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCiAgICAgICAgc2l6ZW9mKENvbm5lY3Rpb24pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KICAgICAgICAoZGVzdHJ1Y3Rvciljb25uZWN0aW9uX2RlYWxsb2MsICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLwogICAgICAgICh0ZXJuYXJ5ZnVuYyljb25uZWN0aW9uX2NhbGwsICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxUfFB5X1RQRkxBR1NfQkFTRVRZUEUsICAgICAgICAgLyogdHBfZmxhZ3MgKi8KICAgICAgICBjb25uZWN0aW9uX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLwogICAgICAgIGNvbm5lY3Rpb25fbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KICAgICAgICBjb25uZWN0aW9uX21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCiAgICAgICAgY29ubmVjdGlvbl9nZXRzZXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCiAgICAgICAgKGluaXRwcm9jKWNvbm5lY3Rpb25faW5pdCwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCiAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLwp9OwoKZXh0ZXJuIGludCBjb25uZWN0aW9uX3NldHVwX3R5cGVzKHZvaWQpCnsKICAgIENvbm5lY3Rpb25UeXBlLnRwX25ldyA9IFB5VHlwZV9HZW5lcmljTmV3OwogICAgcmV0dXJuIFB5VHlwZV9SZWFkeSgmQ29ubmVjdGlvblR5cGUpOwp9Cg==