LyogSGVscGVyIGxpYnJhcnkgZm9yIE1TSSBjcmVhdGlvbiB3aXRoIFB5dGhvbi4KICogQ29weXJpZ2h0IChDKSAyMDA1IE1hcnRpbiB2LiBM9ndpcwogKiBMaWNlbnNlZCB0byBQU0YgdW5kZXIgYSBjb250cmlidXRvciBhZ3JlZW1lbnQuCiAqLwoKI2luY2x1ZGUgPFB5dGhvbi5oPgojaW5jbHVkZSA8ZmNpLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxtc2lxdWVyeS5oPgojaW5jbHVkZSA8bXNpZGVmcy5oPgojaW5jbHVkZSA8cnBjLmg+CgpzdGF0aWMgUHlPYmplY3QgKk1TSUVycm9yOwoKc3RhdGljIFB5T2JqZWN0Kgp1dWlkY3JlYXRlKFB5T2JqZWN0KiBvYmosIFB5T2JqZWN0KmFyZ3MpCnsKICAgIFVVSUQgcmVzdWx0OwogICAgY2hhciAqY3Jlc3VsdDsKICAgIFB5T2JqZWN0ICpvcmVzdWx0OwogICAgCiAgICAvKiBNYXkgcmV0dXJuIG9rLCBsb2NhbCBvbmx5LCBhbmQgbm8gYWRkcmVzcy4KICAgICAgIEZvciBsb2NhbCBvbmx5LCB0aGUgZG9jdW1lbnRhdGlvbiBzYXlzIHdlIHN0aWxsIGdldCBhIHV1aWQuCiAgICAgICBGb3IgUlBDX1NfVVVJRF9OT19BRERSRVNTLCBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIHdlIGNhbgogICAgICAgdXNlIHRoZSByZXN1bHQuICovCiAgICBpZiAoVXVpZENyZWF0ZSgmcmVzdWx0KSA9PSBSUENfU19VVUlEX05PX0FERFJFU1MpIHsKCVB5RXJyX1NldFN0cmluZyhQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAicHJvY2Vzc2luZyAnbm8gYWRkcmVzcycgcmVzdWx0Iik7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoVXVpZFRvU3RyaW5nKCZyZXN1bHQsICZjcmVzdWx0KSA9PSBSUENfU19PVVRfT0ZfTUVNT1JZKSB7CglQeUVycl9TZXRTdHJpbmcoUHlFeGNfTWVtb3J5RXJyb3IsICJvdXQgb2YgbWVtb3J5IGluIHV1aWRnZW4iKTsKCXJldHVybiBOVUxMOwogICAgfQoKICAgIG9yZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGNyZXN1bHQpOwogICAgUnBjU3RyaW5nRnJlZSgmY3Jlc3VsdCk7CiAgICByZXR1cm4gb3Jlc3VsdDsKCn0KCi8qIEZDSSBjYWxsYmFjayBmdW5jdGlvbnMgKi8KCnN0YXRpYyBGTkZDSUFMTE9DKGNiX2FsbG9jKQp7CiAgICByZXR1cm4gbWFsbG9jKGNiKTsKfQoKc3RhdGljIEZORkNJRlJFRShjYl9mcmVlKQp7CiAgICBmcmVlKG1lbW9yeSk7Cn0KCnN0YXRpYyBGTkZDSU9QRU4oY2Jfb3BlbikKewogICAgaW50IHJlc3VsdCA9IF9vcGVuKHBzekZpbGUsIG9mbGFnLCBwbW9kZSk7CiAgICBpZiAocmVzdWx0ID09IC0xKQoJKmVyciA9IGVycm5vOwogICAgcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIEZORkNJUkVBRChjYl9yZWFkKQp7CiAgICBVSU5UIHJlc3VsdCA9IChVSU5UKV9yZWFkKGhmLCBtZW1vcnksIGNiKTsKICAgIGlmIChyZXN1bHQgIT0gY2IpCgkqZXJyID0gZXJybm87CiAgICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgRk5GQ0lXUklURShjYl93cml0ZSkKewogICAgVUlOVCByZXN1bHQgPSAoVUlOVClfd3JpdGUoaGYsIG1lbW9yeSwgY2IpOwogICAgaWYgKHJlc3VsdCAhPSBjYikKCSplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSUNMT1NFKGNiX2Nsb3NlKQp7CiAgICBpbnQgcmVzdWx0ID0gX2Nsb3NlKGhmKTsKICAgIGlmIChyZXN1bHQgIT0gMCkKCSplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSVNFRUsoY2Jfc2VlaykKewogICAgbG9uZyByZXN1bHQgPSAobG9uZylfbHNlZWsoaGYsIGRpc3QsIHNlZWt0eXBlKTsKICAgIGlmIChyZXN1bHQgPT0gLTEpCgkqZXJyID0gZXJybm87CiAgICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgRk5GQ0lERUxFVEUoY2JfZGVsZXRlKQp7CiAgICBpbnQgcmVzdWx0ID0gcmVtb3ZlKHBzekZpbGUpOwogICAgaWYgKHJlc3VsdCAhPSAwKQoJKmVyciA9IGVycm5vOwogICAgcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIEZORkNJRklMRVBMQUNFRChjYl9maWxlcGxhY2VkKQp7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZORkNJR0VUVEVNUEZJTEUoY2JfZ2V0dGVtcGZpbGUpCnsKICAgIGNoYXIgKm5hbWUgPSBfdGVtcG5hbSgiIiwgInRtcCIpOwogICAgaWYgKChuYW1lICE9IE5VTEwpICYmICgoaW50KXN0cmxlbihuYW1lKSA8IGNiVGVtcE5hbWUpKSB7CglzdHJjcHkocHN6VGVtcE5hbWUsIG5hbWUpOwoJZnJlZShuYW1lKTsKCXJldHVybiBUUlVFOwogICAgfQoKICAgIGlmIChuYW1lKSBmcmVlKG5hbWUpOwogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgRk5GQ0lTVEFUVVMoY2Jfc3RhdHVzKQp7CiAgICBpZiAocHYpIHsKCVB5T2JqZWN0ICpyZXN1bHQgPSBQeU9iamVjdF9DYWxsTWV0aG9kKHB2LCAic3RhdHVzIiwgImlpaSIsIHR5cGVTdGF0dXMsIGNiMSwgY2IyKTsKCWlmIChyZXN1bHQgPT0gTlVMTCkKCSAgICByZXR1cm4gLTE7CglQeV9ERUNSRUYocmVzdWx0KTsKICAgIH0KICAgIHJldHVybiAwOwp9CgpzdGF0aWMgRk5GQ0lHRVRORVhUQ0FCSU5FVChjYl9nZXRuZXh0Y2FiaW5ldCkKewogICAgaWYgKHB2KSB7CglQeU9iamVjdCAqcmVzdWx0ID0gUHlPYmplY3RfQ2FsbE1ldGhvZChwdiwgImdldG5leHRjYWJpbmV0IiwgImkiLCBwY2NhYi0+aUNhYik7CglpZiAocmVzdWx0ID09IE5VTEwpCgkgICAgcmV0dXJuIC0xOwoJaWYgKCFQeVN0cmluZ19DaGVjayhyZXN1bHQpKSB7CgkgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgCgkJIkluY29ycmVjdCByZXR1cm4gdHlwZSAlcyBmcm9tIGdldG5leHRjYWJpbmV0IiwKCQlyZXN1bHQtPm9iX3R5cGUtPnRwX25hbWUpOwoJICAgIFB5X0RFQ1JFRihyZXN1bHQpOwoJICAgIHJldHVybiBGQUxTRTsKCX0KCXN0cm5jcHkocGNjYWItPnN6Q2FiLCBQeVN0cmluZ19Bc1N0cmluZyhyZXN1bHQpLCBzaXplb2YocGNjYWItPnN6Q2FiKSk7CglyZXR1cm4gVFJVRTsKICAgIH0KICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEZORkNJR0VUT1BFTklORk8oY2JfZ2V0b3BlbmluZm8pCnsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBGSUxFVElNRSBmaWxldGltZTsKICAgIEhBTkRMRSBoYW5kbGU7CgogICAgLyogTmVlZCBXaW4zMiBoYW5kbGUgdG8gZ2V0IHRpbWUgc3RhbXBzICovCiAgICBoYW5kbGUgPSBDcmVhdGVGaWxlKHBzek5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLAoJT1BFTl9FWElTVElORywgRklMRV9BVFRSSUJVVEVfTk9STUFMLCBOVUxMKTsKICAgIGlmIChoYW5kbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCglyZXR1cm4gLTE7CgogICAgaWYgKEdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhhbmRsZSwgJmJoZmkpID09IEZBTFNFKQogICAgewoJQ2xvc2VIYW5kbGUoaGFuZGxlKTsKCXJldHVybiAtMTsKICAgIH0KCiAgICBGaWxlVGltZVRvTG9jYWxGaWxlVGltZSgmYmhmaS5mdExhc3RXcml0ZVRpbWUsICZmaWxldGltZSk7CiAgICBGaWxlVGltZVRvRG9zRGF0ZVRpbWUoJmZpbGV0aW1lLCBwZGF0ZSwgcHRpbWUpOwoKICAgICpwYXR0cmlicyA9IChpbnQpKGJoZmkuZHdGaWxlQXR0cmlidXRlcyAmIAoJKF9BX1JET05MWSB8IF9BX1NZU1RFTSB8IF9BX0hJRERFTiB8IF9BX0FSQ0gpKTsKCiAgICBDbG9zZUhhbmRsZShoYW5kbGUpOwoKICAgIHJldHVybiBfb3Blbihwc3pOYW1lLCBfT19SRE9OTFkgfCBfT19CSU5BUlkpOwp9CgpzdGF0aWMgUHlPYmplY3QqIGZjaWNyZWF0ZShQeU9iamVjdCogb2JqLCBQeU9iamVjdCogYXJncykKewogICAgY2hhciAqY2FibmFtZSwgKnA7CiAgICBQeU9iamVjdCAqZmlsZXM7CiAgICBDQ0FCIGNjYWI7CiAgICBIRkNJIGhmY2k7CiAgICBFUkYgZXJmOwogICAgUHlfc3NpemVfdCBpOwoKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInNPOkZDSUNyZWF0ZSIsICZjYWJuYW1lLCAmZmlsZXMpKQoJcmV0dXJuIE5VTEw7CgogICAgaWYgKCFQeUxpc3RfQ2hlY2soZmlsZXMpKSB7CglQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiRkNJQ3JlYXRlIGV4cGVjdHMgYSBsaXN0Iik7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICBjY2FiLmNiID0gSU5UX01BWDsgLyogbm8gbmVlZCB0byBzcGxpdCBDQUIgaW50byBtdWx0aXBsZSBtZWRpYSAqLwogICAgY2NhYi5jYkZvbGRlclRocmVzaCA9IDEwMDAwMDA7IC8qIGZsdXNoIGRpcmVjdG9yeSBhZnRlciB0aGlzIG1hbnkgYnl0ZXMgKi8KICAgIGNjYWIuY2JSZXNlcnZlQ0ZEYXRhID0gMDsKICAgIGNjYWIuY2JSZXNlcnZlQ0ZGb2xkZXIgPSAwOwogICAgY2NhYi5jYlJlc2VydmVDRkhlYWRlciA9IDA7CgogICAgY2NhYi5pQ2FiID0gMTsKICAgIGNjYWIuaURpc2sgPSAxOwoKICAgIGNjYWIuc2V0SUQgPSAwOwogICAgY2NhYi5zekRpc2tbMF0gPSAnXDAnOwoKICAgIGZvciAoaSA9IDAsIHAgPSBjYWJuYW1lOyAqcDsgcCA9IENoYXJOZXh0KHApKQoJaWYgKCpwID09ICdcXCcgfHwgKnAgPT0gJy8nKQoJICAgIGkgPSBwIC0gY2FibmFtZSArIDE7CgogICAgaWYgKGkgPj0gc2l6ZW9mKGNjYWIuc3pDYWJQYXRoKSB8fAoJc3RybGVuKGNhYm5hbWUraSkgPj0gc2l6ZW9mKGNjYWIuc3pDYWIpKSB7CglQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgInBhdGggbmFtZSB0b28gbG9uZyIpOwoJcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGkgPiAwKSB7CgltZW1jcHkoY2NhYi5zekNhYlBhdGgsIGNhYm5hbWUsIGkpOwoJY2NhYi5zekNhYlBhdGhbaV0gPSAnXDAnOwoJc3RyY3B5KGNjYWIuc3pDYWIsIGNhYm5hbWUraSk7CiAgICB9IGVsc2UgewoJc3RyY3B5KGNjYWIuc3pDYWJQYXRoLCAiLlxcIik7CglzdHJjcHkoY2NhYi5zekNhYiwgY2FibmFtZSk7CiAgICB9CgogICAgaGZjaSA9IEZDSUNyZWF0ZSgmZXJmLCBjYl9maWxlcGxhY2VkLCBjYl9hbGxvYywgY2JfZnJlZSwKCWNiX29wZW4sIGNiX3JlYWQsIGNiX3dyaXRlLCBjYl9jbG9zZSwgY2Jfc2VlaywgY2JfZGVsZXRlLAoJY2JfZ2V0dGVtcGZpbGUsICZjY2FiLCBOVUxMKTsKCiAgICBpZiAoaGZjaSA9PSBOVUxMKSB7CglQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIkZDSSBlcnJvciAlZCIsIGVyZi5lcmZPcGVyKTsKCXJldHVybiBOVUxMOwogICAgfQoKICAgIGZvciAoaT0wOyBpIDwgUHlMaXN0X0dFVF9TSVpFKGZpbGVzKTsgaSsrKSB7CglQeU9iamVjdCAqaXRlbSA9IFB5TGlzdF9HRVRfSVRFTShmaWxlcywgaSk7CgljaGFyICpmaWxlbmFtZSwgKmNhYm5hbWU7CglpZiAoIVB5QXJnX1BhcnNlVHVwbGUoaXRlbSwgInNzIiwgJmZpbGVuYW1lLCAmY2FibmFtZSkpCgkgICAgZ290byBlcnI7CglpZiAoIUZDSUFkZEZpbGUoaGZjaSwgZmlsZW5hbWUsIGNhYm5hbWUsIEZBTFNFLCAKCSAgICBjYl9nZXRuZXh0Y2FiaW5ldCwgY2Jfc3RhdHVzLCBjYl9nZXRvcGVuaW5mbywKCSAgICB0Y29tcFRZUEVfTVNaSVApKQoJICAgIGdvdG8gZXJyOwogICAgfQoKICAgIGlmICghRkNJRmx1c2hDYWJpbmV0KGhmY2ksIEZBTFNFLCBjYl9nZXRuZXh0Y2FiaW5ldCwgY2Jfc3RhdHVzKSkKCWdvdG8gZXJyOwoKICAgIGlmICghRkNJRGVzdHJveShoZmNpKSkKCWdvdG8gZXJyOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwplcnI6CiAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIkZDSSBlcnJvciAlZCIsIGVyZi5lcmZPcGVyKTsgLyogWFhYIGJldHRlciBlcnJvciB0eXBlICovCiAgICBGQ0lEZXN0cm95KGhmY2kpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnR5cGVkZWYgc3RydWN0IG1zaW9iansKICAgIFB5T2JqZWN0X0hFQUQKICAgIE1TSUhBTkRMRSBoOwp9bXNpb2JqOwoKc3RhdGljIHZvaWQgCm1zaW9ial9kZWFsbG9jKG1zaW9iaiogbXNpZGIpCnsKICAgIE1zaUNsb3NlSGFuZGxlKG1zaWRiLT5oKTsKICAgIG1zaWRiLT5oID0gMDsKfQoKc3RhdGljIFB5T2JqZWN0Kgptc2lvYmpfY2xvc2UobXNpb2JqKiBtc2lkYiwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIE1zaUNsb3NlSGFuZGxlKG1zaWRiLT5oKTsKICAgIG1zaWRiLT5oID0gMDsKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCm1zaWVycm9yKGludCBzdGF0dXMpCnsKICAgIGludCBjb2RlOwogICAgY2hhciBidWZbMjAwMF07CiAgICBjaGFyICpyZXMgPSBidWY7CiAgICBEV09SRCBzaXplID0gc2l6ZW9mKGJ1Zik7CiAgICBNU0lIQU5ETEUgZXJyID0gTXNpR2V0TGFzdEVycm9yUmVjb3JkKCk7CgogICAgaWYgKGVyciA9PSAwKSB7Cglzd2l0Y2goc3RhdHVzKSB7CgljYXNlIEVSUk9SX0FDQ0VTU19ERU5JRUQ6CgkgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiYWNjZXNzIGRlbmllZCIpOwoJICAgIHJldHVybiBOVUxMOwoJY2FzZSBFUlJPUl9GVU5DVElPTl9GQUlMRUQ6CgkgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiZnVuY3Rpb24gZmFpbGVkIik7CgkgICAgcmV0dXJuIE5VTEw7CgljYXNlIEVSUk9SX0lOVkFMSURfREFUQToKCSAgICBQeUVycl9TZXRTdHJpbmcoTVNJRXJyb3IsICJpbnZhbGlkIGRhdGEiKTsKCSAgICByZXR1cm4gTlVMTDsKCWNhc2UgRVJST1JfSU5WQUxJRF9IQU5ETEU6CgkgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiaW52YWxpZCBoYW5kbGUiKTsKCSAgICByZXR1cm4gTlVMTDsKCWNhc2UgRVJST1JfSU5WQUxJRF9TVEFURToKCSAgICBQeUVycl9TZXRTdHJpbmcoTVNJRXJyb3IsICJpbnZhbGlkIHN0YXRlIik7CgkgICAgcmV0dXJuIE5VTEw7CgljYXNlIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOgoJICAgIFB5RXJyX1NldFN0cmluZyhNU0lFcnJvciwgImludmFsaWQgcGFyYW1ldGVyIik7CgkgICAgcmV0dXJuIE5VTEw7CglkZWZhdWx0OgoJICAgIFB5RXJyX0Zvcm1hdChNU0lFcnJvciwgInVua25vd24gZXJyb3IgJXgiLCBzdGF0dXMpOwoJICAgIHJldHVybiBOVUxMOwoJfQogICAgfQoKICAgIGNvZGUgPSBNc2lSZWNvcmRHZXRJbnRlZ2VyKGVyciwgMSk7IC8qIFhYWCBjb2RlICovCiAgICBpZiAoTXNpRm9ybWF0UmVjb3JkKDAsIGVyciwgcmVzLCAmc2l6ZSkgPT0gRVJST1JfTU9SRV9EQVRBKSB7CglyZXMgPSBtYWxsb2Moc2l6ZSsxKTsKCU1zaUZvcm1hdFJlY29yZCgwLCBlcnIsIHJlcywgJnNpemUpOwoJcmVzW3NpemVdPSdcMCc7CiAgICB9CiAgICBNc2lDbG9zZUhhbmRsZShlcnIpOwogICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCByZXMpOwogICAgaWYgKHJlcyAhPSBidWYpCglmcmVlKHJlcyk7CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKiBSZWNvcmQgb2JqZWN0cyAqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfZ2V0ZmllbGRjb3VudChtc2lvYmoqIHJlY29yZCwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhNc2lSZWNvcmRHZXRGaWVsZENvdW50KHJlY29yZC0+aCkpOwp9CgpzdGF0aWMgUHlPYmplY3QqCnJlY29yZF9nZXRpbnRlZ2VyKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCogYXJncykKewogICAgdW5zaWduZWQgaW50IGZpZWxkOwogICAgaW50IHN0YXR1czsKICAgIAogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJJOkdldEludGVnZXIiLCAmZmllbGQpKQogICAgICAgIHJldHVybiBOVUxMOwogICAgc3RhdHVzID0gTXNpUmVjb3JkR2V0SW50ZWdlcihyZWNvcmQtPmgsIGZpZWxkKTsKICAgIGlmIChzdGF0dXMgPT0gTVNJX05VTExfSU5URUdFUil7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiY291bGQgbm90IGNvbnZlcnQgcmVjb3JkIGZpZWxkIHRvIGludGVnZXIiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygobG9uZykgc3RhdHVzKTsKfQoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfZ2V0c3RyaW5nKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCogYXJncykKewogICAgdW5zaWduZWQgaW50IGZpZWxkOwogICAgdW5zaWduZWQgaW50IHN0YXR1czsKICAgIGNoYXIgYnVmWzIwMDBdOwogICAgY2hhciAqcmVzID0gYnVmOwogICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWYpOwogICAgUHlPYmplY3QqIHN0cmluZzsKICAgIAogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJJOkdldFN0cmluZyIsICZmaWVsZCkpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBzdGF0dXMgPSBNc2lSZWNvcmRHZXRTdHJpbmcocmVjb3JkLT5oLCBmaWVsZCwgcmVzLCAmc2l6ZSk7CiAgICBpZiAoc3RhdHVzID09IEVSUk9SX01PUkVfREFUQSkgewogICAgICAgIHJlcyA9IChjaGFyKikgbWFsbG9jKHNpemUgKyAxKTsKICAgICAgICBpZiAocmVzID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOwogICAgICAgIHN0YXR1cyA9IE1zaVJlY29yZEdldFN0cmluZyhyZWNvcmQtPmgsIGZpZWxkLCByZXMsICZzaXplKTsKICAgIH0KICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3IoKGludCkgc3RhdHVzKTsKICAgIHN0cmluZyA9IFB5U3RyaW5nX0Zyb21TdHJpbmcocmVzKTsKICAgIGlmIChidWYgIT0gcmVzKQogICAgICAgIGZyZWUocmVzKTsKICAgIHJldHVybiBzdHJpbmc7Cn0KCnN0YXRpYyBQeU9iamVjdCoKcmVjb3JkX2NsZWFyZGF0YShtc2lvYmoqIHJlY29yZCwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXMgPSBNc2lSZWNvcmRDbGVhckRhdGEocmVjb3JkLT5oKTsKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCnJlY29yZF9zZXRzdHJpbmcobXNpb2JqKiByZWNvcmQsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgaW50IGZpZWxkOwogICAgY2hhciAqZGF0YTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImlzOlNldFN0cmluZyIsICZmaWVsZCwgJmRhdGEpKQoJcmV0dXJuIE5VTEw7CgogICAgaWYgKChzdGF0dXMgPSBNc2lSZWNvcmRTZXRTdHJpbmcocmVjb3JkLT5oLCBmaWVsZCwgZGF0YSkpICE9IEVSUk9SX1NVQ0NFU1MpCglyZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfc2V0c3RyZWFtKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBmaWVsZDsKICAgIGNoYXIgKmRhdGE7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpczpTZXRTdHJlYW0iLCAmZmllbGQsICZkYXRhKSkKCXJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpUmVjb3JkU2V0U3RyZWFtKHJlY29yZC0+aCwgZmllbGQsIGRhdGEpKSAhPSBFUlJPUl9TVUNDRVNTKQoJcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7Cn0KCnN0YXRpYyBQeU9iamVjdCoKcmVjb3JkX3NldGludGVnZXIobXNpb2JqKiByZWNvcmQsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgaW50IGZpZWxkOwogICAgaW50IGRhdGE7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpaTpTZXRJbnRlZ2VyIiwgJmZpZWxkLCAmZGF0YSkpCglyZXR1cm4gTlVMTDsKCiAgICBpZiAoKHN0YXR1cyA9IE1zaVJlY29yZFNldEludGVnZXIocmVjb3JkLT5oLCBmaWVsZCwgZGF0YSkpICE9IEVSUk9SX1NVQ0NFU1MpCglyZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKCgpzdGF0aWMgUHlNZXRob2REZWYgcmVjb3JkX21ldGhvZHNbXSA9IHsKICAgIHsgIkdldEZpZWxkQ291bnQiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2dldGZpZWxkY291bnQsIE1FVEhfTk9BUkdTLCAKCVB5RG9jX1NUUigiR2V0RmllbGRDb3VudCgpIC0+IGludFxuV3JhcHMgTXNpUmVjb3JkR2V0RmllbGRDb3VudCIpfSwKICAgIHsgIkdldEludGVnZXIiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2dldGludGVnZXIsIE1FVEhfVkFSQVJHUywKICAgIFB5RG9jX1NUUigiR2V0SW50ZWdlcihmaWVsZCkgLT4gaW50XG5XcmFwcyBNc2lSZWNvcmRHZXRJbnRlZ2VyIil9LAogICAgeyAiR2V0U3RyaW5nIiwgKFB5Q0Z1bmN0aW9uKXJlY29yZF9nZXRzdHJpbmcsIE1FVEhfVkFSQVJHUywKICAgIFB5RG9jX1NUUigiR2V0U3RyaW5nKGZpZWxkKSAtPiBzdHJpbmdcbldyYXBzIE1zaVJlY29yZEdldFN0cmluZyIpfSwKICAgIHsgIlNldFN0cmluZyIsIChQeUNGdW5jdGlvbilyZWNvcmRfc2V0c3RyaW5nLCBNRVRIX1ZBUkFSR1MsIAoJUHlEb2NfU1RSKCJTZXRTdHJpbmcoZmllbGQsc3RyKSAtPiBOb25lXG5XcmFwcyBNc2lSZWNvcmRTZXRTdHJpbmciKX0sCiAgICB7ICJTZXRTdHJlYW0iLCAoUHlDRnVuY3Rpb24pcmVjb3JkX3NldHN0cmVhbSwgTUVUSF9WQVJBUkdTLCAKCVB5RG9jX1NUUigiU2V0U3RyZWFtKGZpZWxkLGZpbGVuYW1lKSAtPiBOb25lXG5XcmFwcyBNc2lSZWNvcmRTZXRJbnRlZ2VyIil9LAogICAgeyAiU2V0SW50ZWdlciIsIChQeUNGdW5jdGlvbilyZWNvcmRfc2V0aW50ZWdlciwgTUVUSF9WQVJBUkdTLCAKCVB5RG9jX1NUUigiU2V0SW50ZWdlcihmaWVsZCxpbnQpIC0+IE5vbmVcbldyYXBzIE1zaVJlY29yZFNldEludGVnZXIiKX0sCiAgICB7ICJDbGVhckRhdGEiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2NsZWFyZGF0YSwgTUVUSF9OT0FSR1MsIAoJUHlEb2NfU1RSKCJDbGVhckRhdGEoKSAtPiBpbnRcbldyYXBzIE1zaVJlY29yZEdDbGVhckRhdGEiKX0sCiAgICB7IE5VTEwsIE5VTEwgfQp9OwoKc3RhdGljIFB5VHlwZU9iamVjdCByZWNvcmRfVHlwZSA9IHsKCVB5VmFyT2JqZWN0X0hFQURfSU5JVChOVUxMLCAwKQoJIl9tc2kuUmVjb3JkIiwJCS8qdHBfbmFtZSovCglzaXplb2YobXNpb2JqKSwJLyp0cF9iYXNpY3NpemUqLwoJMCwJCQkvKnRwX2l0ZW1zaXplKi8KCS8qIG1ldGhvZHMgKi8KCShkZXN0cnVjdG9yKW1zaW9ial9kZWFsbG9jLCAvKnRwX2RlYWxsb2MqLwoJMCwJCQkvKnRwX3ByaW50Ki8KCTAsCQkJLyp0cF9nZXRhdHRyKi8KCTAsCQkJLyp0cF9zZXRhdHRyKi8KCTAsCQkJLyp0cF9jb21wYXJlKi8KCTAsCQkJLyp0cF9yZXByKi8KCTAsCQkJLyp0cF9hc19udW1iZXIqLwoJMCwJCQkvKnRwX2FzX3NlcXVlbmNlKi8KCTAsCQkJLyp0cF9hc19tYXBwaW5nKi8KCTAsCQkJLyp0cF9oYXNoKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NhbGwqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc3RyKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwvKnRwX2dldGF0dHJvKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljU2V0QXR0ciwvKnRwX3NldGF0dHJvKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX2J1ZmZlciovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgLyp0cF9mbGFncyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfdHJhdmVyc2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2xlYXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmljaGNvbXBhcmUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVybmV4dCovCiAgICAgICAgcmVjb3JkX21ldGhvZHMsICAgICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCnN0YXRpYyBQeU9iamVjdCoKcmVjb3JkX25ldyhNU0lIQU5ETEUgaCkKewogICAgbXNpb2JqICpyZXN1bHQgPSBQeU9iamVjdF9ORVcoc3RydWN0IG1zaW9iaiwgJnJlY29yZF9UeXBlKTsKCiAgICBpZiAoIXJlc3VsdCkgewoJTXNpQ2xvc2VIYW5kbGUoaCk7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXN1bHQtPmggPSBoOwogICAgcmV0dXJuIChQeU9iamVjdCopcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqIFN1bW1hcnlJbmZvcm1hdGlvbiBvYmplY3RzICoqKioqKioqKioqKioqLwoKc3RhdGljIFB5T2JqZWN0KgpzdW1tYXJ5X2dldHByb3BlcnR5KG1zaW9iaiogc2ksIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgaW50IGZpZWxkOwogICAgUHlPYmplY3QgKnJlc3VsdDsKICAgIFVJTlQgdHlwZTsKICAgIElOVCBpdmFsOwogICAgRklMRVRJTUUgZnZhbDsKICAgIGNoYXIgc2J1ZlsxMDAwXTsKICAgIGNoYXIgKnN2YWwgPSBzYnVmOwogICAgRFdPUkQgc3NpemUgPSBzaXplb2Yoc3ZhbCk7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpOkdldFByb3BlcnR5IiwgJmZpZWxkKSkKCXJldHVybiBOVUxMOwoKICAgIHN0YXR1cyA9IE1zaVN1bW1hcnlJbmZvR2V0UHJvcGVydHkoc2ktPmgsIGZpZWxkLCAmdHlwZSwgJml2YWwsIAoJJmZ2YWwsIHN2YWwsICZzc2l6ZSk7CiAgICBpZiAoc3RhdHVzID09IEVSUk9SX01PUkVfREFUQSkgewoJc3ZhbCA9IG1hbGxvYyhzc2l6ZSk7CiAgICAgICAgc3RhdHVzID0gTXNpU3VtbWFyeUluZm9HZXRQcm9wZXJ0eShzaS0+aCwgZmllbGQsICZ0eXBlLCAmaXZhbCwgCiAgICAJICAgICZmdmFsLCBzdmFsLCAmc3NpemUpOwogICAgfQoKICAgIHN3aXRjaCh0eXBlKSB7CgljYXNlIFZUX0kyOiBjYXNlIFZUX0k0OgoJICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhpdmFsKTsKCWNhc2UgVlRfRklMRVRJTUU6CgkgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IsICJGSUxFVElNRSByZXN1bHQiKTsKCSAgICByZXR1cm4gTlVMTDsKCWNhc2UgVlRfTFBTVFI6CgkgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoc3ZhbCwgc3NpemUpOwoJICAgIGlmIChzdmFsICE9IHNidWYpCgkJZnJlZShzdmFsKTsKCSAgICByZXR1cm4gcmVzdWx0OwogICAgfQogICAgUHlFcnJfRm9ybWF0KFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IsICJyZXN1bHQgb2YgdHlwZSAlZCIsIHR5cGUpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBQeU9iamVjdCoKc3VtbWFyeV9nZXRwcm9wZXJ0eWNvdW50KG1zaW9iaiogc2ksIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgVUlOVCByZXN1bHQ7CgogICAgc3RhdHVzID0gTXNpU3VtbWFyeUluZm9HZXRQcm9wZXJ0eUNvdW50KHNpLT5oLCAmcmVzdWx0KTsKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyZXN1bHQpOwp9CgpzdGF0aWMgUHlPYmplY3QqCnN1bW1hcnlfc2V0cHJvcGVydHkobXNpb2JqKiBzaSwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBpbnQgZmllbGQ7CiAgICBQeU9iamVjdCogZGF0YTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImlPOlNldFByb3BlcnR5IiwgJmZpZWxkLCAmZGF0YSkpCglyZXR1cm4gTlVMTDsKCiAgICBpZiAoUHlTdHJpbmdfQ2hlY2soZGF0YSkpIHsKCXN0YXR1cyA9IE1zaVN1bW1hcnlJbmZvU2V0UHJvcGVydHkoc2ktPmgsIGZpZWxkLCBWVF9MUFNUUiwKCSAgICAwLCBOVUxMLCBQeVN0cmluZ19Bc1N0cmluZyhkYXRhKSk7CiAgICB9IGVsc2UgaWYgKFB5SW50X0NoZWNrKGRhdGEpKSB7CglzdGF0dXMgPSBNc2lTdW1tYXJ5SW5mb1NldFByb3BlcnR5KHNpLT5oLCBmaWVsZCwgVlRfSTQsCgkgICAgUHlJbnRfQXNMb25nKGRhdGEpLCBOVUxMLCBOVUxMKTsKICAgIH0gZWxzZSB7CglQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAidW5zdXBwb3J0ZWQgdHlwZSIpOwoJcmV0dXJuIE5VTEw7CiAgICB9CiAgICAKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgoKc3RhdGljIFB5T2JqZWN0KgpzdW1tYXJ5X3BlcnNpc3QobXNpb2JqKiBzaSwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CgogICAgc3RhdHVzID0gTXNpU3VtbWFyeUluZm9QZXJzaXN0KHNpLT5oKTsKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7Cn0KCnN0YXRpYyBQeU1ldGhvZERlZiBzdW1tYXJ5X21ldGhvZHNbXSA9IHsKICAgIHsgIkdldFByb3BlcnR5IiwgKFB5Q0Z1bmN0aW9uKXN1bW1hcnlfZ2V0cHJvcGVydHksIE1FVEhfVkFSQVJHUywgCglQeURvY19TVFIoIkdldFByb3BlcnR5KHByb3BpZCkgLT4gdmFsdWVcbldyYXBzIE1zaVN1bW1hcnlJbmZvR2V0UHJvcGVydHkiKX0sCiAgICB7ICJHZXRQcm9wZXJ0eUNvdW50IiwgKFB5Q0Z1bmN0aW9uKXN1bW1hcnlfZ2V0cHJvcGVydHljb3VudCwgTUVUSF9OT0FSR1MsIAoJUHlEb2NfU1RSKCJHZXRQcm9wZXJ0eSgpIC0+IGludFxuV3JhcHMgTXNpU3VtbWFyeUluZm9HZXRQcm9wZXJ0eUNvdW50Iil9LAogICAgeyAiU2V0UHJvcGVydHkiLCAoUHlDRnVuY3Rpb24pc3VtbWFyeV9zZXRwcm9wZXJ0eSwgTUVUSF9WQVJBUkdTLCAKCVB5RG9jX1NUUigiU2V0UHJvcGVydHkodmFsdWUpIC0+IE5vbmVcbldyYXBzIE1zaVN1bW1hcnlJbmZvUHJvcGVydHkiKX0sCiAgICB7ICJQZXJzaXN0IiwgKFB5Q0Z1bmN0aW9uKXN1bW1hcnlfcGVyc2lzdCwgTUVUSF9OT0FSR1MsIAoJUHlEb2NfU1RSKCJQZXJzaXN0KCkgLT4gTm9uZVxuV3JhcHMgTXNpU3VtbWFyeUluZm9QZXJzaXN0Iil9LAogICAgeyBOVUxMLCBOVUxMIH0KfTsKCnN0YXRpYyBQeVR5cGVPYmplY3Qgc3VtbWFyeV9UeXBlID0gewoJUHlWYXJPYmplY3RfSEVBRF9JTklUKE5VTEwsIDApCgkiX21zaS5TdW1tYXJ5SW5mb3JtYXRpb24iLAkJLyp0cF9uYW1lKi8KCXNpemVvZihtc2lvYmopLAkvKnRwX2Jhc2ljc2l6ZSovCgkwLAkJCS8qdHBfaXRlbXNpemUqLwoJLyogbWV0aG9kcyAqLwoJKGRlc3RydWN0b3IpbXNpb2JqX2RlYWxsb2MsIC8qdHBfZGVhbGxvYyovCgkwLAkJCS8qdHBfcHJpbnQqLwoJMCwJCQkvKnRwX2dldGF0dHIqLwoJMCwJCQkvKnRwX3NldGF0dHIqLwoJMCwJCQkvKnRwX2NvbXBhcmUqLwoJMCwJCQkvKnRwX3JlcHIqLwoJMCwJCQkvKnRwX2FzX251bWJlciovCgkwLAkJCS8qdHBfYXNfc2VxdWVuY2UqLwoJMCwJCQkvKnRwX2FzX21hcHBpbmcqLwoJMCwJCQkvKnRwX2hhc2gqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zdHIqLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLC8qdHBfZ2V0YXR0cm8qLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLC8qdHBfc2V0YXR0cm8qLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAvKnRwX2ZsYWdzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF90cmF2ZXJzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jbGVhciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yaWNoY29tcGFyZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF93ZWFrbGlzdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8KICAgICAgICBzdW1tYXJ5X21ldGhvZHMsICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogVmlldyBvYmplY3RzICoqKioqKioqKioqKioqLwoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2V4ZWN1dGUobXNpb2JqICp2aWV3LCBQeU9iamVjdCphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgTVNJSEFORExFIHBhcmFtcyA9IDA7CiAgICBQeU9iamVjdCAqb3BhcmFtcyA9IFB5X05vbmU7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOkV4ZWN1dGUiLCAmb3BhcmFtcykpCglyZXR1cm4gTlVMTDsKCiAgICBpZiAob3BhcmFtcyAhPSBQeV9Ob25lKSB7CiAgICAgICAgaWYgKG9wYXJhbXMtPm9iX3R5cGUgIT0gJnJlY29yZF9UeXBlKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJFeGVjdXRlIGFyZ3VtZW50IG11c3QgYmUgYSByZWNvcmQiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIHBhcmFtcyA9ICgobXNpb2JqKilvcGFyYW1zKS0+aDsKICAgIH0KCiAgICBzdGF0dXMgPSBNc2lWaWV3RXhlY3V0ZSh2aWV3LT5oLCBwYXJhbXMpOwogICAgaWYgKHN0YXR1cyAhPSBFUlJPUl9TVUNDRVNTKQoJcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7Cn0KCnN0YXRpYyBQeU9iamVjdCoKdmlld19mZXRjaChtc2lvYmogKnZpZXcsIFB5T2JqZWN0KmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBNU0lIQU5ETEUgcmVzdWx0OwoKICAgIGlmICgoc3RhdHVzID0gTXNpVmlld0ZldGNoKHZpZXctPmgsICZyZXN1bHQpKSAhPSBFUlJPUl9TVUNDRVNTKQoJcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmV0dXJuIHJlY29yZF9uZXcocmVzdWx0KTsKfQoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2dldGNvbHVtbmluZm8obXNpb2JqICp2aWV3LCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBraW5kOwogICAgTVNJSEFORExFIHJlc3VsdDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImk6R2V0Q29sdW1uSW5mbyIsICZraW5kKSkKCXJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpVmlld0dldENvbHVtbkluZm8odmlldy0+aCwga2luZCwgJnJlc3VsdCkpICE9IEVSUk9SX1NVQ0NFU1MpCglyZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICByZXR1cm4gcmVjb3JkX25ldyhyZXN1bHQpOwp9CgpzdGF0aWMgUHlPYmplY3QqCnZpZXdfbW9kaWZ5KG1zaW9iaiAqdmlldywgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBraW5kOwogICAgUHlPYmplY3QgKmRhdGE7CiAgICBpbnQgc3RhdHVzOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiaU86TW9kaWZ5IiwgJmtpbmQsICZkYXRhKSkKCXJldHVybiBOVUxMOwoKICAgIGlmIChkYXRhLT5vYl90eXBlICE9ICZyZWNvcmRfVHlwZSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIk1vZGlmeSBleHBlY3RzIGEgcmVjb3JkIG9iamVjdCIpOwoJcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKChzdGF0dXMgPSBNc2lWaWV3TW9kaWZ5KHZpZXctPmgsIGtpbmQsICgobXNpb2JqKilkYXRhKS0+aCkpICE9IEVSUk9SX1NVQ0NFU1MpCglyZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2Nsb3NlKG1zaW9iaiAqdmlldywgUHlPYmplY3QqYXJncykKewogICAgaW50IHN0YXR1czsKCiAgICBpZiAoKHN0YXR1cyA9IE1zaVZpZXdDbG9zZSh2aWV3LT5oKSkgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlNZXRob2REZWYgdmlld19tZXRob2RzW10gPSB7CiAgICB7ICJFeGVjdXRlIiwgKFB5Q0Z1bmN0aW9uKXZpZXdfZXhlY3V0ZSwgTUVUSF9WQVJBUkdTLCAKCVB5RG9jX1NUUigiRXhlY3V0ZShwYXJhbXM9Tm9uZSkgLT4gTm9uZVxuV3JhcHMgTXNpVmlld0V4ZWN1dGUiKX0sCiAgICB7ICJHZXRDb2x1bW5JbmZvIiwgKFB5Q0Z1bmN0aW9uKXZpZXdfZ2V0Y29sdW1uaW5mbywgTUVUSF9WQVJBUkdTLAoJUHlEb2NfU1RSKCJHZXRDb2x1bW5JbmZvKCkgLT4gcmVzdWx0XG5XcmFwcyBNc2lHZXRDb2x1bW5JbmZvIil9LAogICAgeyAiRmV0Y2giLCAoUHlDRnVuY3Rpb24pdmlld19mZXRjaCwgTUVUSF9OT0FSR1MsCglQeURvY19TVFIoIkZldGNoKCkgLT4gcmVzdWx0XG5XcmFwcyBNc2lWaWV3RmV0Y2giKX0sCiAgICB7ICJNb2RpZnkiLCAoUHlDRnVuY3Rpb24pdmlld19tb2RpZnksIE1FVEhfVkFSQVJHUywKCVB5RG9jX1NUUigiTW9kaWZ5KG1vZGUscmVjb3JkKSAtPiBOb25lXG5XcmFwcyBNc2lWaWV3TW9kaWZ5Iil9LAogICAgeyAiQ2xvc2UiLCAoUHlDRnVuY3Rpb24pdmlld19jbG9zZSwgTUVUSF9OT0FSR1MsCglQeURvY19TVFIoIkNsb3NlKCkgLT4gcmVzdWx0XG5XcmFwcyBNc2lWaWV3Q2xvc2UiKX0sCiAgICB7IE5VTEwsIE5VTEwgfQp9OwoKc3RhdGljIFB5VHlwZU9iamVjdCBtc2l2aWV3X1R5cGUgPSB7CglQeVZhck9iamVjdF9IRUFEX0lOSVQoTlVMTCwgMCkKCSJfbXNpLlZpZXciLAkJLyp0cF9uYW1lKi8KCXNpemVvZihtc2lvYmopLAkvKnRwX2Jhc2ljc2l6ZSovCgkwLAkJCS8qdHBfaXRlbXNpemUqLwoJLyogbWV0aG9kcyAqLwoJKGRlc3RydWN0b3IpbXNpb2JqX2RlYWxsb2MsIC8qdHBfZGVhbGxvYyovCgkwLAkJCS8qdHBfcHJpbnQqLwoJMCwJCQkvKnRwX2dldGF0dHIqLwoJMCwJCQkvKnRwX3NldGF0dHIqLwoJMCwJCQkvKnRwX2NvbXBhcmUqLwoJMCwJCQkvKnRwX3JlcHIqLwoJMCwJCQkvKnRwX2FzX251bWJlciovCgkwLAkJCS8qdHBfYXNfc2VxdWVuY2UqLwoJMCwJCQkvKnRwX2FzX21hcHBpbmcqLwoJMCwJCQkvKnRwX2hhc2gqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zdHIqLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLC8qdHBfZ2V0YXR0cm8qLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLC8qdHBfc2V0YXR0cm8qLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAvKnRwX2ZsYWdzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF90cmF2ZXJzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jbGVhciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yaWNoY29tcGFyZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF93ZWFrbGlzdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8KICAgICAgICB2aWV3X21ldGhvZHMsICAgICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogRGF0YWJhc2Ugb2JqZWN0cyAqKioqKioqKioqKioqKi8KCnN0YXRpYyBQeU9iamVjdCoKbXNpZGJfb3BlbnZpZXcobXNpb2JqICptc2lkYiwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBjaGFyICpzcWw7CiAgICBNU0lIQU5ETEUgaFZpZXc7CiAgICBtc2lvYmogKnJlc3VsdDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInM6T3BlblZpZXciLCAmc3FsKSkKCXJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpRGF0YWJhc2VPcGVuVmlldyhtc2lkYi0+aCwgc3FsLCAmaFZpZXcpKSAhPSBFUlJPUl9TVUNDRVNTKQoJcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmVzdWx0ID0gUHlPYmplY3RfTkVXKHN0cnVjdCBtc2lvYmosICZtc2l2aWV3X1R5cGUpOwogICAgaWYgKCFyZXN1bHQpIHsKCU1zaUNsb3NlSGFuZGxlKGhWaWV3KTsKCXJldHVybiBOVUxMOwogICAgfQoKICAgIHJlc3VsdC0+aCA9IGhWaWV3OwogICAgcmV0dXJuIChQeU9iamVjdCopcmVzdWx0Owp9CgpzdGF0aWMgUHlPYmplY3QqCm1zaWRiX2NvbW1pdChtc2lvYmogKm1zaWRiLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKCiAgICBpZiAoKHN0YXR1cyA9IE1zaURhdGFiYXNlQ29tbWl0KG1zaWRiLT5oKSkgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCm1zaWRiX2dldHN1bW1hcnlpbmZvcm1hdGlvbihtc2lvYmogKmRiLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBjb3VudDsKICAgIE1TSUhBTkRMRSByZXN1bHQ7CiAgICBtc2lvYmogKm9yZXN1bHQ7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpOkdldFN1bW1hcnlJbmZvcm1hdGlvbiIsICZjb3VudCkpCglyZXR1cm4gTlVMTDsKCiAgICBzdGF0dXMgPSBNc2lHZXRTdW1tYXJ5SW5mb3JtYXRpb24oZGItPmgsIE5VTEwsIGNvdW50LCAmcmVzdWx0KTsKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKCXJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIG9yZXN1bHQgPSBQeU9iamVjdF9ORVcoc3RydWN0IG1zaW9iaiwgJnN1bW1hcnlfVHlwZSk7CiAgICBpZiAoIXJlc3VsdCkgewoJTXNpQ2xvc2VIYW5kbGUocmVzdWx0KTsKCXJldHVybiBOVUxMOwogICAgfQoKICAgIG9yZXN1bHQtPmggPSByZXN1bHQ7CiAgICByZXR1cm4gKFB5T2JqZWN0KilvcmVzdWx0Owp9CgpzdGF0aWMgUHlNZXRob2REZWYgZGJfbWV0aG9kc1tdID0gewogICAgeyAiT3BlblZpZXciLCAoUHlDRnVuY3Rpb24pbXNpZGJfb3BlbnZpZXcsIE1FVEhfVkFSQVJHUywgCglQeURvY19TVFIoIk9wZW5WaWV3KHNxbCkgLT4gdmlld29ialxuV3JhcHMgTXNpRGF0YWJhc2VPcGVuVmlldyIpfSwKICAgIHsgIkNvbW1pdCIsIChQeUNGdW5jdGlvbiltc2lkYl9jb21taXQsIE1FVEhfTk9BUkdTLAoJUHlEb2NfU1RSKCJDb21taXQoKSAtPiBOb25lXG5XcmFwcyBNc2lEYXRhYmFzZUNvbW1pdCIpfSwKICAgIHsgIkdldFN1bW1hcnlJbmZvcm1hdGlvbiIsIChQeUNGdW5jdGlvbiltc2lkYl9nZXRzdW1tYXJ5aW5mb3JtYXRpb24sIE1FVEhfVkFSQVJHUywgCglQeURvY19TVFIoIkdldFN1bW1hcnlJbmZvcm1hdGlvbih1cGRhdGVDb3VudCkgLT4gdmlld29ialxuV3JhcHMgTXNpR2V0U3VtbWFyeUluZm9ybWF0aW9uIil9LAogICAgeyBOVUxMLCBOVUxMIH0KfTsKCnN0YXRpYyBQeVR5cGVPYmplY3QgbXNpZGJfVHlwZSA9IHsKCVB5VmFyT2JqZWN0X0hFQURfSU5JVChOVUxMLCAwKQoJIl9tc2kuRGF0YWJhc2UiLAkJLyp0cF9uYW1lKi8KCXNpemVvZihtc2lvYmopLAkvKnRwX2Jhc2ljc2l6ZSovCgkwLAkJCS8qdHBfaXRlbXNpemUqLwoJLyogbWV0aG9kcyAqLwoJKGRlc3RydWN0b3IpbXNpb2JqX2RlYWxsb2MsIC8qdHBfZGVhbGxvYyovCgkwLAkJCS8qdHBfcHJpbnQqLwoJMCwJCQkvKnRwX2dldGF0dHIqLwoJMCwJCQkvKnRwX3NldGF0dHIqLwoJMCwJCQkvKnRwX2NvbXBhcmUqLwoJMCwJCQkvKnRwX3JlcHIqLwoJMCwJCQkvKnRwX2FzX251bWJlciovCgkwLAkJCS8qdHBfYXNfc2VxdWVuY2UqLwoJMCwJCQkvKnRwX2FzX21hcHBpbmcqLwoJMCwJCQkvKnRwX2hhc2gqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zdHIqLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLC8qdHBfZ2V0YXR0cm8qLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLC8qdHBfc2V0YXR0cm8qLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAvKnRwX2ZsYWdzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF90cmF2ZXJzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jbGVhciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yaWNoY29tcGFyZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF93ZWFrbGlzdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8KICAgICAgICBkYl9tZXRob2RzLCAgICAgICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCnN0YXRpYyBQeU9iamVjdCogbXNpb3BlbmRiKFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgY2hhciAqcGF0aDsKICAgIGludCBwZXJzaXN0OwogICAgTVNJSEFORExFIGg7CiAgICBtc2lvYmogKnJlc3VsdDsKICAgIAogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJzaTpNU0lPcGVuRGF0YWJhc2UiLCAmcGF0aCwgJnBlcnNpc3QpKQoJcmV0dXJuIE5VTEw7CgoJc3RhdHVzID0gTXNpT3BlbkRhdGFiYXNlKHBhdGgsIChMUENTVFIpcGVyc2lzdCwgJmgpOwogICAgaWYgKHN0YXR1cyAhPSBFUlJPUl9TVUNDRVNTKQoJcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmVzdWx0ID0gUHlPYmplY3RfTkVXKHN0cnVjdCBtc2lvYmosICZtc2lkYl9UeXBlKTsKICAgIGlmICghcmVzdWx0KSB7CglNc2lDbG9zZUhhbmRsZShoKTsKCXJldHVybiBOVUxMOwogICAgfQogICAgcmVzdWx0LT5oID0gaDsKICAgIHJldHVybiAoUHlPYmplY3QqKXJlc3VsdDsKfQoKc3RhdGljIFB5T2JqZWN0KgpjcmVhdGVyZWNvcmQoUHlPYmplY3QgKm8sIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgY291bnQ7CiAgICBNU0lIQU5ETEUgaDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImk6Q3JlYXRlUmVjb3JkIiwgJmNvdW50KSkKCXJldHVybiBOVUxMOwogICAgCiAgICBoID0gTXNpQ3JlYXRlUmVjb3JkKGNvdW50KTsKICAgIGlmIChoID09IDApCglyZXR1cm4gbXNpZXJyb3IoMCk7CgogICAgcmV0dXJuIHJlY29yZF9uZXcoaCk7Cn0KCgpzdGF0aWMgUHlNZXRob2REZWYgbXNpX21ldGhvZHNbXSA9IHsKICAgICAgICB7IlV1aWRDcmVhdGUiLCAoUHlDRnVuY3Rpb24pdXVpZGNyZWF0ZSwgTUVUSF9OT0FSR1MsCgkJUHlEb2NfU1RSKCJVdWlkQ3JlYXRlKCkgLT4gc3RyaW5nIil9LAoJeyJGQ0lDcmVhdGUiLAkoUHlDRnVuY3Rpb24pZmNpY3JlYXRlLAlNRVRIX1ZBUkFSR1MsCgkJUHlEb2NfU1RSKCJmY2ljcmVhdGUoY2FibmFtZSxmaWxlcykgLT4gTm9uZSIpfSwKCXsiT3BlbkRhdGFiYXNlIiwgKFB5Q0Z1bmN0aW9uKW1zaW9wZW5kYiwgTUVUSF9WQVJBUkdTLAoJUHlEb2NfU1RSKCJPcGVuRGF0YWJhc2UobmFtZSwgZmxhZ3MpIC0+IGRib2JqXG5XcmFwcyBNc2lPcGVuRGF0YWJhc2UiKX0sCgl7IkNyZWF0ZVJlY29yZCIsIChQeUNGdW5jdGlvbiljcmVhdGVyZWNvcmQsIE1FVEhfVkFSQVJHUywKCVB5RG9jX1NUUigiT3BlbkRhdGFiYXNlKG5hbWUsIGZsYWdzKSAtPiBkYm9ialxuV3JhcHMgTXNpQ3JlYXRlUmVjb3JkIil9LAoJe05VTEwsCQlOVUxMfQkJLyogc2VudGluZWwgKi8KfTsKCnN0YXRpYyBjaGFyIG1zaV9kb2NbXSA9ICJEb2N1bWVudGF0aW9uIjsKClB5TU9ESU5JVF9GVU5DCmluaXRfbXNpKHZvaWQpCnsKICAgIFB5T2JqZWN0ICptOwoKICAgIG0gPSBQeV9Jbml0TW9kdWxlMygiX21zaSIsIG1zaV9tZXRob2RzLCBtc2lfZG9jKTsKICAgIGlmIChtID09IE5VTEwpCglyZXR1cm47CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9DUkVBVEVESVJFQ1QiLCAoaW50KU1TSURCT1BFTl9DUkVBVEVESVJFQ1QpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9DUkVBVEUiLCAoaW50KU1TSURCT1BFTl9DUkVBVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9ESVJFQ1QiLCAoaW50KU1TSURCT1BFTl9ESVJFQ1QpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9SRUFET05MWSIsIChpbnQpTVNJREJPUEVOX1JFQURPTkxZKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lEQk9QRU5fVFJBTlNBQ1QiLCAoaW50KU1TSURCT1BFTl9UUkFOU0FDVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJREJPUEVOX1BBVENIRklMRSIsIChpbnQpTVNJREJPUEVOX1BBVENIRklMRSk7CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSUNPTElORk9fTkFNRVMiLCBNU0lDT0xJTkZPX05BTUVTKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lDT0xJTkZPX1RZUEVTIiwgTVNJQ09MSU5GT19UWVBFUyk7CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9TRUVLIiwgTVNJTU9ESUZZX1NFRUspOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9SRUZSRVNIIiwgTVNJTU9ESUZZX1JFRlJFU0gpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9JTlNFUlQiLCBNU0lNT0RJRllfSU5TRVJUKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lNT0RJRllfVVBEQVRFIiwgTVNJTU9ESUZZX1VQREFURSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX0FTU0lHTiIsIE1TSU1PRElGWV9BU1NJR04pOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9SRVBMQUNFIiwgTVNJTU9ESUZZX1JFUExBQ0UpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9NRVJHRSIsIE1TSU1PRElGWV9NRVJHRSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX0RFTEVURSIsIE1TSU1PRElGWV9ERUxFVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9JTlNFUlRfVEVNUE9SQVJZIiwgTVNJTU9ESUZZX0lOU0VSVF9URU1QT1JBUlkpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9WQUxJREFURSIsIE1TSU1PRElGWV9WQUxJREFURSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX1ZBTElEQVRFX05FVyIsIE1TSU1PRElGWV9WQUxJREFURV9ORVcpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9WQUxJREFURV9GSUVMRCIsIE1TSU1PRElGWV9WQUxJREFURV9GSUVMRCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX1ZBTElEQVRFX0RFTEVURSIsIE1TSU1PRElGWV9WQUxJREFURV9ERUxFVEUpOwoKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfQ09ERVBBR0UiLCBQSURfQ09ERVBBR0UpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9USVRMRSIsIFBJRF9USVRMRSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX1NVQkpFQ1QiLCBQSURfU1VCSkVDVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX0FVVEhPUiIsIFBJRF9BVVRIT1IpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9LRVlXT1JEUyIsIFBJRF9LRVlXT1JEUyk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX0NPTU1FTlRTIiwgUElEX0NPTU1FTlRTKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfVEVNUExBVEUiLCBQSURfVEVNUExBVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9MQVNUQVVUSE9SIiwgUElEX0xBU1RBVVRIT1IpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9SRVZOVU1CRVIiLCBQSURfUkVWTlVNQkVSKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfTEFTVFBSSU5URUQiLCBQSURfTEFTVFBSSU5URUQpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9DUkVBVEVfRFRNIiwgUElEX0NSRUFURV9EVE0pOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9MQVNUU0FWRV9EVE0iLCBQSURfTEFTVFNBVkVfRFRNKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfUEFHRUNPVU5UIiwgUElEX1BBR0VDT1VOVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX1dPUkRDT1VOVCIsIFBJRF9XT1JEQ09VTlQpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9DSEFSQ09VTlQiLCBQSURfQ0hBUkNPVU5UKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfQVBQTkFNRSIsIFBJRF9BUFBOQU1FKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfU0VDVVJJVFkiLCBQSURfU0VDVVJJVFkpOwoKICAgIE1TSUVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uICgiX21zaS5NU0lFcnJvciIsIE5VTEwsIE5VTEwpOwogICAgaWYgKCFNU0lFcnJvcikKCXJldHVybjsKICAgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAiTVNJRXJyb3IiLCBNU0lFcnJvcik7Cn0K