LyoKICoKICogVGhpcyBpcyBiYXNlZCBvbiBBcHBsZSBleGFtcGxlIHNvZnR3YXJlIEF1ZGlvQmFja0VuZC5jcHAKICogCiAqIENvcHlyaWdodCCpIDIwMDQgQXBwbGUgQ29tcHV0ZXIsIEluYy4sIEFsbCBSaWdodHMgUmVzZXJ2ZWQKICogT3JpZ2luYWwgQXBwbGUgY29kZSBtb2RpZmllZCBieSBEYW5pZWwgU3Vtb3JvawogKiAKICogIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqICBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLyAKCiNpbmNsdWRlICJBdWRpb0JhY2tFbmQuaCIKCiNwcmFnbWEgbWFyayAtLS1QdWJsaWMgTWV0aG9kcy0tLQoKQXVkaW9CYWNrRW5kOjpBdWRpb0JhY2tFbmQoaW50IGJpdHNQZXJTYW1wbGUsIGludCBudW1DaGFubmVscywgaW50IHNhbXBsZVJhdGUpOgogIG1CaXRzUGVyU2FtcGxlKGJpdHNQZXJTYW1wbGUpLAogIG1TYW1wbGVSYXRlKHNhbXBsZVJhdGUpLAogIG1OdW1DaGFubmVscyhudW1DaGFubmVscyksCiAgbUNhbGxiYWNrKE5VTEwpLAogIG1DYWxsYmFja0FyZyhOVUxMKSwKICBtQnVmZmVyU2l6ZUZyYW1lcygwKSwKICBtRnJhbWVzUHJvY2Vzc2VkKDApLAogIG1BdWRpb0J1ZmZlcihOVUxMKSwKICBtQXVkaW9CdWZmZXJXcml0ZUluZGV4KDApLAogIG1BdWRpb0J1ZmZlclJlYWRJbmRleCgwKSwKICBtQnl0ZXNQZXJGcmFtZSgwKSwKICBtQXVkaW9CdWZmZXJTaXplKDApIHsKICBPU1N0YXR1cyBlcnIgPSBub0VycjsKICBlcnIgPSBJbml0KCk7CiAgaWYoZXJyKSB7CiAgICBmcHJpbnRmKHN0ZGVyciwiQXVkaW9CYWNrRW5kIEVSUk9SOiBDYW5ub3QgSW5pdCBBdWRpb0JhY2tFbmQiKTsKICAgIGV4aXQoMSk7CiAgfQp9CgpBdWRpb0JhY2tFbmQ6On5BdWRpb0JhY2tFbmQoKSB7ICAgLy9jbGVhbiB1cAogIFN0b3AoKTsKCiAgQVVHcmFwaENsb3NlKG1HcmFwaCk7CiAgRGlzcG9zZUFVR3JhcGgobUdyYXBoKTsKICAgICAgICAKICBpZihtQXVkaW9CdWZmZXIgIT0gTlVMTCkgewogICAgZGVsZXRlIG1BdWRpb0J1ZmZlcjsKICAgIG1BdWRpb0J1ZmZlciA9IE5VTEw7CiAgICBtQXVkaW9CdWZmZXJTaXplID0gMDsKICB9Cn0KCk9TU3RhdHVzIEF1ZGlvQmFja0VuZDo6SW5pdCgpIHsKICBPU1N0YXR1cyBlcnIgPSBub0VycjsKCiAgZXJyID0gU2V0dXBHcmFwaCgpOyAgIAogIGNoZWNrRXJyKGVycik7CgogIGVyciA9IFNldHVwQnVmZmVycygpOwogIGNoZWNrRXJyKGVycik7CgogIGVyciA9IEFVR3JhcGhJbml0aWFsaXplKG1HcmFwaCk7IAogIGNoZWNrRXJyKGVycik7CgogIHJldHVybiBlcnI7ICAgCn0KCiNwcmFnbWEgbWFyayAtLS0gT3BlcmF0aW9uLS0tCgpPU1N0YXR1cyBBdWRpb0JhY2tFbmQ6OlN0YXJ0KCkKewogIE9TU3RhdHVzIGVyciA9IG5vRXJyOwogIGlmKCFJc1J1bm5pbmcoKSkgewogICAgbUZyYW1lc1Byb2Nlc3NlZCA9IDA7CiAgICBtQXVkaW9CdWZmZXJXcml0ZUluZGV4ID0gMDsgICAgICAgICAKICAgIG1BdWRpb0J1ZmZlclJlYWRJbmRleCA9IDA7CiAgICAgICAgICAgICAgICAKICAgIGVyciA9IEFVR3JhcGhTdGFydChtR3JhcGgpOwogIH0KICByZXR1cm4gZXJyOyAgIAp9CgpPU1N0YXR1cyBBdWRpb0JhY2tFbmQ6OlN0b3AoKSB7CiAgT1NTdGF0dXMgZXJyID0gbm9FcnI7CgogIGlmKElzUnVubmluZygpKSB7CiAgICBlcnIgPSBBVUdyYXBoU3RvcChtR3JhcGgpOwogIH0KICByZXR1cm4gZXJyOwp9CgpCb29sZWFuIEF1ZGlvQmFja0VuZDo6SXNSdW5uaW5nKCkgeyAgICAgCiAgT1NTdGF0dXMgZXJyID0gbm9FcnI7CiAgQm9vbGVhbiBncmFwaFJ1bm5pbmc7CgogIGVyciA9IEFVR3JhcGhJc1J1bm5pbmcobUdyYXBoLCZncmFwaFJ1bm5pbmcpOwogICAgICAgIAogIHJldHVybiAoZ3JhcGhSdW5uaW5nKTsgICAgICAgIAp9CgojcHJhZ21hIG1hcmsgLQojcHJhZ21hIG1hcmsgLS1Qcml2YXRlIG1ldGhvZHMtLS0KT1NTdGF0dXMgQXVkaW9CYWNrRW5kOjpTZXR1cEdyYXBoKCkgewogIE9TU3RhdHVzIGVyciA9IG5vRXJyOwogIEFVUmVuZGVyQ2FsbGJhY2tTdHJ1Y3Qgb3V0cHV0OwogIFVJbnQzMiBzaXplOwogIENvbXBvbmVudERlc2NyaXB0aW9uIG91dERlc2M7CiAgQXVkaW9EZXZpY2VJRCBvdXQ7CgogIC8vTWFrZSBhIE5ldyBHcmFwaAogIGVyciA9IE5ld0FVR3JhcGgoJm1HcmFwaCk7ICAKICBjaGVja0VycihlcnIpOwoKICAvL09wZW4gdGhlIEdyYXBoLCBBdWRpb1VuaXRzIGFyZSBvcGVuZWQgYnV0IG5vdCBpbml0aWFsaXplZCAgICAKICBlcnIgPSBBVUdyYXBoT3BlbihtR3JhcGgpOwogIGNoZWNrRXJyKGVycik7CiAgCiAgb3V0RGVzYy5jb21wb25lbnRUeXBlID0ga0F1ZGlvVW5pdFR5cGVfT3V0cHV0OwogIG91dERlc2MuY29tcG9uZW50U3ViVHlwZSA9IGtBdWRpb1VuaXRTdWJUeXBlX0RlZmF1bHRPdXRwdXQ7CiAgb3V0RGVzYy5jb21wb25lbnRNYW51ZmFjdHVyZXIgPSBrQXVkaW9Vbml0TWFudWZhY3R1cmVyX0FwcGxlOwogIG91dERlc2MuY29tcG9uZW50RmxhZ3MgPSAwOwogIG91dERlc2MuY29tcG9uZW50RmxhZ3NNYXNrID0gMDsKICAgICAgICAKICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogIC8vL01BS0UgTk9ERVMKICAvL1RoaXMgY3JlYXRlcyBhIG5vZGUgaW4gdGhlIGdyYXBoIHRoYXQgaXMgYW4gQXVkaW9Vbml0LCB1c2luZwogIC8vdGhlIHN1cHBsaWVkIENvbXBvbmVudERlc2NyaXB0aW9uIHRvIGZpbmQgYW5kIG9wZW4gdGhhdCB1bml0ICAgICAgICAKICBlcnIgPSBBVUdyYXBoTmV3Tm9kZShtR3JhcGgsICZvdXREZXNjLCAwLCBOVUxMLCAmbU91dHB1dE5vZGUpOwogIGNoZWNrRXJyKGVycik7CiAgICAgICAgCiAgLy9HZXQgQXVkaW8gVW5pdHMgZnJvbSBBVUdyYXBoIG5vZGUKICBlcnIgPSBBVUdyYXBoR2V0Tm9kZUluZm8obUdyYXBoLCBtT3V0cHV0Tm9kZSwgTlVMTCwgTlVMTCwgTlVMTCwgJm1PdXRwdXRVbml0KTsgICAgICAgICAKICBjaGVja0VycihlcnIpOwogICAgICAgIAogIGVyciA9IEFVR3JhcGhVcGRhdGUobUdyYXBoLCBOVUxMKTsKICBjaGVja0VycihlcnIpOwoKICBzaXplID0gc2l6ZW9mKEF1ZGlvRGV2aWNlSUQpOwogIGVyciA9IEF1ZGlvSGFyZHdhcmVHZXRQcm9wZXJ0eShrQXVkaW9IYXJkd2FyZVByb3BlcnR5RGVmYXVsdE91dHB1dERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNpemUsICZvdXQpOwogIGNoZWNrRXJyKGVycik7CiAgbU91dHB1dERldmljZS5Jbml0KG91dCwgZmFsc2UpOwogICAgICAgIAogIC8vU2V0IHRoZSBDdXJyZW50IERldmljZSB0byB0aGUgRGVmYXVsdCBPdXRwdXQgVW5pdC4KICBlcnIgPSBBdWRpb1VuaXRTZXRQcm9wZXJ0eShtT3V0cHV0VW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrQXVkaW9PdXRwdXRVbml0UHJvcGVydHlfQ3VycmVudERldmljZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0F1ZGlvVW5pdFNjb3BlX0dsb2JhbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm91dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG91dCkpOwogIGNoZWNrRXJyKGVycik7CiAgICAgICAgICAgICAgICAgICAgICAgIAogIG91dHB1dC5pbnB1dFByb2MgPSBPdXRwdXRQcm9jOwogIG91dHB1dC5pbnB1dFByb2NSZWZDb24gPSB0aGlzOwogICAgICAgIAogIGVyciA9IEF1ZGlvVW5pdFNldFByb3BlcnR5KG1PdXRwdXRVbml0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrQXVkaW9Vbml0UHJvcGVydHlfU2V0UmVuZGVyQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtBdWRpb1VuaXRTY29wZV9JbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvdXRwdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvdXRwdXQpKTsKICBjaGVja0VycihlcnIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogIHJldHVybiBlcnI7Cn0KCi8vQWxsb2NhdGUgQXVkaW8gQnVmZmVyIExpc3QocykgdG8gaG9sZCB0aGUgZGF0YSBmcm9tIGlucHV0LgpPU1N0YXR1cyBBdWRpb0JhY2tFbmQ6OlNldHVwQnVmZmVycygpIHsKICBPU1N0YXR1cyBlcnIgPSBub0VycjsKICBVSW50MzIgc2FmZXR5T2Zmc2V0OwogIEF1ZGlvU3RyZWFtQmFzaWNEZXNjcmlwdGlvbiBhc2JkOwogIFVJbnQzMiBwcm9wZXJ0eVNpemU7CgogIHByb3BlcnR5U2l6ZSA9IHNpemVvZihtQnVmZmVyU2l6ZUZyYW1lcyk7CiAgZXJyID0gQXVkaW9Vbml0R2V0UHJvcGVydHkobU91dHB1dFVuaXQsIGtBdWRpb0RldmljZVByb3BlcnR5QnVmZmVyRnJhbWVTaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrQXVkaW9Vbml0U2NvcGVfR2xvYmFsLCAwLCAmbUJ1ZmZlclNpemVGcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwcm9wZXJ0eVNpemUpOwoKICBwcm9wZXJ0eVNpemUgPSBzaXplb2Yoc2FmZXR5T2Zmc2V0KTsKICBzYWZldHlPZmZzZXQgPSAwOwogIGVyciA9IEF1ZGlvVW5pdEdldFByb3BlcnR5KG1PdXRwdXRVbml0LCBrQXVkaW9EZXZpY2VQcm9wZXJ0eVNhZmV0eU9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0F1ZGlvVW5pdFNjb3BlX0dsb2JhbCwgMCwgJnNhZmV0eU9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnByb3BlcnR5U2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgogIGFzYmQubUZvcm1hdElEID0gMHg2YzcwNjM2ZDsgLy8gJ2xwY20nCiAgYXNiZC5tRm9ybWF0RmxhZ3MgPSAoa0F1ZGlvRm9ybWF0RmxhZ0lzU2lnbmVkSW50ZWdlciB8CiAgICAgICAgICAgICAgICAgICAgICAga0F1ZGlvRm9ybWF0RmxhZ0lzQmlnRW5kaWFuIHwKICAgICAgICAgICAgICAgICAgICAgICBrQXVkaW9Gb3JtYXRGbGFnSXNQYWNrZWQpOwogIGFzYmQubUNoYW5uZWxzUGVyRnJhbWUgPSBtTnVtQ2hhbm5lbHM7CiAgYXNiZC5tU2FtcGxlUmF0ZSA9IG1TYW1wbGVSYXRlOwogICAgICAgIAogIGlmKGFzYmQubUZvcm1hdEZsYWdzICYga0F1ZGlvRm9ybWF0RmxhZ0lzU2lnbmVkSW50ZWdlcikgewogICAgYXNiZC5tQml0c1BlckNoYW5uZWwgPSBtQml0c1BlclNhbXBsZTsKICB9IGVsc2UgaWYoYXNiZC5tRm9ybWF0RmxhZ3MgJiBrQXVkaW9Gb3JtYXRGbGFnSXNGbG9hdCkgICAgICAgIHsKICAgIGFzYmQubUJpdHNQZXJDaGFubmVsID0gMzI7CiAgfSBlbHNlIHsKICAgIGFzYmQubUJpdHNQZXJDaGFubmVsID0gMDsKICB9CgogIGFzYmQubUZyYW1lc1BlclBhY2tldCA9IDE7CiAgYXNiZC5tQnl0ZXNQZXJGcmFtZSA9IChhc2JkLm1CaXRzUGVyQ2hhbm5lbCAvIDgpICogYXNiZC5tQ2hhbm5lbHNQZXJGcmFtZTsKICBhc2JkLm1CeXRlc1BlclBhY2tldCA9IGFzYmQubUJ5dGVzUGVyRnJhbWUgKiBhc2JkLm1GcmFtZXNQZXJQYWNrZXQ7CgogIGFzYmQubVJlc2VydmVkID0gMDsKCiAgbUJ5dGVzUGVyRnJhbWUgPSBhc2JkLm1CeXRlc1BlckZyYW1lOwogIGlmKChtQnl0ZXNQZXJGcmFtZSAmIChtQnl0ZXNQZXJGcmFtZSAtIDEpKSAhPSAwKSB7CiAgICBwcmludGYoIkF1ZGlvIGJ1ZmZlciBzaXplIG11c3QgYmUgYSBwb3dlciBvZiB0d28hXG4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIHByb3BlcnR5U2l6ZSA9IHNpemVvZihhc2JkKTsKICBlcnIgPSBBdWRpb1VuaXRTZXRQcm9wZXJ0eShtT3V0cHV0VW5pdCwga0F1ZGlvVW5pdFByb3BlcnR5X1N0cmVhbUZvcm1hdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0F1ZGlvVW5pdFNjb3BlX0lucHV0LCAwLCAmYXNiZCwgcHJvcGVydHlTaXplKTsKICBjaGVja0VycihlcnIpOwoKICBpZihtQXVkaW9CdWZmZXIgIT0gTlVMTCkgewogICAgZGVsZXRlIG1BdWRpb0J1ZmZlcjsKICAgIG1BdWRpb0J1ZmZlclNpemUgPSAwOwogIH0KCiAgbUF1ZGlvQnVmZmVyU2l6ZSA9IG1CeXRlc1BlckZyYW1lICogbUJ1ZmZlclNpemVGcmFtZXMgKiAyOwogIG1BdWRpb0J1ZmZlciA9IG5ldyBVSW50OFttQXVkaW9CdWZmZXJTaXplXTsKICBiemVybyhtQXVkaW9CdWZmZXIsIG1BdWRpb0J1ZmZlclNpemUpOwogIHJldHVybiBlcnI7Cn0KCiNwcmFnbWEgbWFyayAtCiNwcmFnbWEgbWFyayAtLSBJTyBQcm9jcyAtLQpPU1N0YXR1cyBBdWRpb0JhY2tFbmQ6Ok91dHB1dFByb2Modm9pZCAqaW5SZWZDb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb1VuaXRSZW5kZXJBY3Rpb25GbGFncyAqaW9BY3Rpb25GbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEF1ZGlvVGltZVN0YW1wICpUaW1lU3RhbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSW50MzIgaW5CdXNOdW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSW50MzIgaW5OdW1iZXJGcmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb0J1ZmZlckxpc3QgKiBpb0RhdGEpIHsKICBPU1N0YXR1cyBlcnIgPSBub0VycjsKICBBdWRpb0JhY2tFbmQgKlRoaXMgPSAoQXVkaW9CYWNrRW5kICopaW5SZWZDb247CiAgVUludDggKmRzdFB0cjsKICBVSW50MzIgYnl0ZXNUb0NvcHk7CiAgVUludDMyIGJ5dGVzVW50aWxFbmQ7CgogIFRoaXMtPm1GcmFtZXNQcm9jZXNzZWQgKz0gaW5OdW1iZXJGcmFtZXM7CgogIGRzdFB0ciA9IChVSW50OCAqKWlvRGF0YS0+bUJ1ZmZlcnNbMF0ubURhdGE7CiAgaWYoVGhpcy0+bUF1ZGlvQnVmZmVyID09IE5VTEwpIHsKICAgIGJ6ZXJvKGRzdFB0ciwgaW5OdW1iZXJGcmFtZXMgKiBUaGlzLT5tQnl0ZXNQZXJGcmFtZSk7CiAgICByZXR1cm4gbm9FcnI7CiAgfQoKICBieXRlc1RvQ29weSA9IGluTnVtYmVyRnJhbWVzICogVGhpcy0+bUJ5dGVzUGVyRnJhbWU7CiAgYnl0ZXNVbnRpbEVuZCA9IFRoaXMtPm1BdWRpb0J1ZmZlclNpemUgLSBUaGlzLT5tQXVkaW9CdWZmZXJSZWFkSW5kZXg7CiAgaWYoYnl0ZXNVbnRpbEVuZCA8IGJ5dGVzVG9Db3B5KSB7CiAgICBtZW1jcHkoZHN0UHRyLCAmVGhpcy0+bUF1ZGlvQnVmZmVyW1RoaXMtPm1BdWRpb0J1ZmZlclJlYWRJbmRleF0sIAogICAgICAgICAgIGJ5dGVzVW50aWxFbmQpOwogICAgbWVtY3B5KGRzdFB0ciwgVGhpcy0+bUF1ZGlvQnVmZmVyLCBieXRlc1RvQ29weSAtIGJ5dGVzVW50aWxFbmQpOwoKICAgIFRoaXMtPm1BdWRpb0J1ZmZlclJlYWRJbmRleCA9IGJ5dGVzVG9Db3B5IC0gYnl0ZXNVbnRpbEVuZDsKICB9IGVsc2UgewogICAgbWVtY3B5KGRzdFB0ciwgJlRoaXMtPm1BdWRpb0J1ZmZlcltUaGlzLT5tQXVkaW9CdWZmZXJSZWFkSW5kZXhdLCAKICAgICAgICAgICBieXRlc1RvQ29weSk7CiAgICBUaGlzLT5tQXVkaW9CdWZmZXJSZWFkSW5kZXggKz0gYnl0ZXNUb0NvcHk7CiAgfQoKCiAgd2hpbGUoVGhpcy0+bUZyYW1lc1Byb2Nlc3NlZCA+PSBUaGlzLT5tQnVmZmVyU2l6ZUZyYW1lcykgewogICAgVGhpcy0+bUZyYW1lc1Byb2Nlc3NlZCAtPSBUaGlzLT5tQnVmZmVyU2l6ZUZyYW1lczsKICAgIGlmKFRoaXMtPm1DYWxsYmFjayAhPSBOVUxMKSB7CiAgICAgIFRoaXMtPm1DYWxsYmFjayhUaGlzLT5tQ2FsbGJhY2tBcmcpOwogICAgfQogIH0KCiAgcmV0dXJuIGVycjsKfQoKdm9pZCBBdWRpb0JhY2tFbmQ6OnNldENhbGxiYWNrKHBsYXl0aHJ1Q2FsbGJhY2sgZnVuYywgdm9pZCAqYXJnKSB7CiAgbUNhbGxiYWNrID0gZnVuYzsKICBtQ2FsbGJhY2tBcmcgPSBhcmc7Cn0KClVJbnQzMiBBdWRpb0JhY2tFbmQ6OkJ1ZmZlclNpemVGcmFtZXMoKSB7CiAgcmV0dXJuIG1CdWZmZXJTaXplRnJhbWVzOwp9CgppbnQgQXVkaW9CYWNrRW5kOjpzZW5kQXVkaW9CdWZmZXIodm9pZCAqYnVmZmVyLCBpbnQgbnVtRnJhbWVzKSB7CiAgVUludDggKmRzdEJ1ZmZlcjsKICBpbnQgdG90YWxCeXRlczsKICAgICAgICAKICBtQXVkaW9CdWZmZXJXcml0ZUluZGV4ICs9IChtQXVkaW9CdWZmZXJTaXplIC8gMik7CiAgbUF1ZGlvQnVmZmVyV3JpdGVJbmRleCAmPSAobUF1ZGlvQnVmZmVyU2l6ZSAtIDEpOwoKICBkc3RCdWZmZXIgPSAmbUF1ZGlvQnVmZmVyW21BdWRpb0J1ZmZlcldyaXRlSW5kZXhdOwogIHRvdGFsQnl0ZXMgPSBtQnl0ZXNQZXJGcmFtZSAqIG51bUZyYW1lczsKICBtZW1jcHkoZHN0QnVmZmVyLCBidWZmZXIsIHRvdGFsQnl0ZXMpOwoKICBkc3RCdWZmZXIgKz0gdG90YWxCeXRlczsKICBiemVybyhkc3RCdWZmZXIsIChtQnVmZmVyU2l6ZUZyYW1lcyAqIG1CeXRlc1BlckZyYW1lKSAtIHRvdGFsQnl0ZXMpOwoKICByZXR1cm4gbnVtRnJhbWVzOwp9Cg==