LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQWxsb2NCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlcikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIE5ld0JpbmRpbmcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0JpbmRpbmcpKTsKICBOZXdCaW5kaW5nLT5yZWZzID0gMTsKICBOZXdCaW5kaW5nLT5zZXJ2ZXIgPSBzZXJ2ZXI7CgogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nQShScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQU1RSIFByb3RzZXEpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBzZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShQcm90c2VxKTsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ1coUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUFdTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdBKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQU1RSIE5ldHdvcmtBZGRyLCAgTFBTVFIgRW5kcG9pbnQsICBMUFNUUiBOZXR3b3JrT3B0aW9ucykKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09IFwiJXNcIiwgRW5kUG9pbnQgPT0gXCIlc1wiLCBOZXR3b3JrT3B0aW9ucyA9PSBcIiVzXCIpXG4iLCBCaW5kaW5nLAogICBkZWJ1Z3N0cl9hKE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfYShFbmRwb2ludCksIGRlYnVnc3RyX2EoTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFdTVFIgTmV0d29ya0FkZHIsIExQV1NUUiBFbmRwb2ludCwgTFBXU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gXCIlc1wiLCBFbmRQb2ludCA9PSBcIiVzXCIsIE5ldHdvcmtPcHRpb25zID09IFwiJXNcIilcbiIsIEJpbmRpbmcsIAogICBkZWJ1Z3N0cl93KE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfdyhFbmRwb2ludCksIGRlYnVnc3RyX3coTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFd0b0EoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfUmVzb2x2ZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgTFBTVFIgRW5kcG9pbnQpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBFbmRQb2ludCA9PSBcIiVzXCJcbiIsIEJpbmRpbmcsIEVuZHBvaW50KTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoUnBjQmluZGluZyogQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCkKewogIFRSQUNFKCIoKlJwY0JpbmRpbmcgPT0gXiVwLCBVVUlEID09ICVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7IAogIGlmIChPYmplY3RVdWlkKSBtZW1jcHkoJkJpbmRpbmctPk9iamVjdFV1aWQsIE9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgZWxzZSBVdWlkQ3JlYXRlTmlsKCZCaW5kaW5nLT5PYmplY3RVdWlkKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X01ha2VCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBDb25uZWN0aW9uID09IF4lcClcbiIsIEJpbmRpbmcsIENvbm5lY3Rpb24pOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBDb25uZWN0aW9uLT5zZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShycGNydDRfY29ubl9nZXRfbmFtZShDb25uZWN0aW9uKSk7CiAgTmV3QmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5OZXR3b3JrQWRkcik7CiAgTmV3QmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgTmV3QmluZGluZy0+RnJvbUNvbm4gPSBDb25uZWN0aW9uOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9FeHBvcnRCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNCaW5kaW5nKiBPbGRCaW5kaW5nKQp7CiAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJk9sZEJpbmRpbmctPnJlZnMpOwogICpCaW5kaW5nID0gT2xkQmluZGluZzsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpCnsKICBpZiAoSW50ZXJsb2NrZWREZWNyZW1lbnQoJkJpbmRpbmctPnJlZnMpKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIEJpbmRpbmcpOwogIC8qIEZJWE1FOiByZWxlYXNlIGNvbm5lY3Rpb25zICovCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5CaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIFRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIEludGVyZmFjZUlkKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwoKICBpZiAoIUJpbmRpbmctPnNlcnZlcikgewogICAgLyogdHJ5IHRvIGZpbmQgYSBjb21wYXRpYmxlIGNvbm5lY3Rpb24gZnJvbSB0aGUgY29ubmVjdGlvbiBwb29sICovCiAgICBOZXdDb25uZWN0aW9uID0gUlBDUlQ0X0dldElkbGVDb25uZWN0aW9uKEludGVyZmFjZUlkLCBUcmFuc2ZlclN5bnRheCwKICAgICAgICBCaW5kaW5nLT5Qcm90c2VxLCBCaW5kaW5nLT5OZXR3b3JrQWRkciwgQmluZGluZy0+RW5kcG9pbnQsCiAgICAgICAgQmluZGluZy0+QXV0aEluZm8pOwogICAgaWYgKE5ld0Nvbm5lY3Rpb24pIHsKICAgICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIHdlIGFscmVhZHkgaGF2ZSBhIGNvbm5lY3Rpb24gd2l0aCBhY2NlcHRhYmxlIGJpbmRpbmcsIHNvIHVzZSBpdCAqLwogICAgaWYgKEJpbmRpbmctPkZyb21Db25uKSB7CiAgICAgICpDb25uZWN0aW9uID0gQmluZGluZy0+RnJvbUNvbm47CiAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0KICB9CiAgCiAgLyogY3JlYXRlIGEgbmV3IGNvbm5lY3Rpb24gKi8KICBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgQmluZGluZy0+c2VydmVyLCBCaW5kaW5nLT5Qcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgIEJpbmRpbmctPk5ldHdvcmtBZGRyLCBCaW5kaW5nLT5FbmRwb2ludCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5kaW5nLT5BdXRoSW5mbywgQmluZGluZyk7CiAgc3RhdHVzID0gUlBDUlQ0X09wZW5Db25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgewogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogICAgcmV0dXJuIHN0YXR1czsKICB9CiAKICAvKiB3ZSBuZWVkIHRvIHNlbmQgYSBiaW5kaW5nIHBhY2tldCBpZiB3ZSBhcmUgY2xpZW50LiAqLwogIGlmICghTmV3Q29ubmVjdGlvbi0+c2VydmVyKSB7CiAgICBScGNQa3RIZHIgKmhkcjsKICAgIFJwY1BrdEhkciAqcmVzcG9uc2VfaGRyOwogICAgUlBDX01FU1NBR0UgbXNnOwoKICAgIFRSQUNFKCJzZW5kaW5nIGJpbmQgcmVxdWVzdCB0byBzZXJ2ZXJcbiIpOwoKICAgIGhkciA9IFJQQ1JUNF9CdWlsZEJpbmRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsIFJQQ19NQVhfUEFDS0VUX1NJWkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVyZmFjZUlkLCBUcmFuc2ZlclN5bnRheCk7CgogICAgc3RhdHVzID0gUlBDUlQ0X1NlbmQoTmV3Q29ubmVjdGlvbiwgaGRyLCBOVUxMLCAwKTsKICAgIFJQQ1JUNF9GcmVlSGVhZGVyKGhkcik7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihOZXdDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBzdGF0dXMgPSBSUENSVDRfUmVjZWl2ZShOZXdDb25uZWN0aW9uLCAmcmVzcG9uc2VfaGRyLCAmbXNnKTsKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgICAgRVJSKCJyZWNlaXZlIGZhaWxlZFxuIik7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihOZXdDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBpZiAocmVzcG9uc2VfaGRyLT5jb21tb24ucHR5cGUgIT0gUEtUX0JJTkRfQUNLIHx8CiAgICAgICAgcmVzcG9uc2VfaGRyLT5iaW5kX2Fjay5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFKSB7CiAgICAgIEVSUigiZmFpbGVkIHRvIGJpbmQgZm9yIGludGVyZmFjZSAlcywgJWQuJWRcbiIsCiAgICAgICAgZGVidWdzdHJfZ3VpZCgmSW50ZXJmYWNlSWQtPlN5bnRheEdVSUQpLAogICAgICAgIEludGVyZmFjZUlkLT5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiwKICAgICAgICBJbnRlcmZhY2VJZC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24pOwogICAgICBSUENSVDRfRnJlZUhlYWRlcihyZXNwb25zZV9oZHIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oTmV3Q29ubmVjdGlvbik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICAvKiBGSVhNRTogZG8gbW9yZSBjaGVja3M/ICovCgogICAgTmV3Q29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IHJlc3BvbnNlX2hkci0+YmluZF9hY2subWF4X3RzaXplOwogICAgTmV3Q29ubmVjdGlvbi0+QWN0aXZlSW50ZXJmYWNlID0gKkludGVyZmFjZUlkOwogICAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2VfaGRyKTsKICB9CgogIGlmIChCaW5kaW5nLT5zZXJ2ZXIpCiAgICBCaW5kaW5nLT5Gcm9tQ29ubiA9IE5ld0Nvbm5lY3Rpb247CiAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmICghQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIGlmIChCaW5kaW5nLT5zZXJ2ZXIpIHsKICAgIC8qIGRvbid0IGRlc3Ryb3kgYSBjb25uZWN0aW9uIHRoYXQgaXMgY2FjaGVkIGluIHRoZSBiaW5kaW5nICovCiAgICBpZiAoQmluZGluZy0+RnJvbUNvbm4gPT0gQ29ubmVjdGlvbikKICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKICB9CiAgZWxzZSB7CiAgICBSUENSVDRfUmVsZWFzZUlkbGVDb25uZWN0aW9uKENvbm5lY3Rpb24pOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KfQoKLyogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHN0cmluZyBjb21wb3NpbmcgYW5kIHBhcnNpbmcgKi8Kc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5QShMUFNUUiBkYXRhLCBMUENTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5VyhMUFdTVFIgZGF0YSwgTFBDV1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW5XKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyBMUFNUUiBSUENSVDRfc3RyY29uY2F0QShMUFNUUiBkc3QsIExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW4oZHN0KSwgc2xlbiA9IHN0cmxlbihzcmMpOwogIExQU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoQ0hBUikpOwogIGlmICghbmRzdCkKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKzEpOwogIHJldHVybiBuZHN0Owp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJjb25jYXRXKExQV1NUUiBkc3QsIExQQ1dTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuVyhkc3QpLCBzbGVuID0gc3RybGVuVyhzcmMpOwogIExQV1NUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKCFuZHN0KSAKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCAoc2xlbisxKSpzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbmRzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKHVuc2lnbmVkIGNoYXIgKk9ialV1aWQsIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpOZXR3b3JrQWRkciwgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpPcHRpb25zLCB1bnNpZ25lZCBjaGFyKiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQU1RSIGRhdGE7CgogIFRSQUNFKCAiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopT2JqVXVpZCApLCBkZWJ1Z3N0cl9hKCAoY2hhciopUHJvdHNlcSApLAogICAgICAgIGRlYnVnc3RyX2EoIChjaGFyKilOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl9hKCAoY2hhciopRW5kcG9pbnQgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nICk7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSBsZW4gKz0gc3RybGVuKChjaGFyKilPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW4oKGNoYXIqKVByb3RzZXEpICsgMTsKICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSBsZW4gKz0gc3RybGVuKChjaGFyKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgbGVuICs9IHN0cmxlbigoY2hhciopRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlbigoY2hhciopT3B0aW9ucykgKyAyOwoKICBkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CiAgKlN0cmluZ0JpbmRpbmcgPSAodW5zaWduZWQgY2hhciopZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKQogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKU5ldHdvcmtBZGRyKTsKCiAgaWYgKChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHx8CiAgICAgIChPcHRpb25zICYmICpPcHRpb25zKSkgewogICAgKmRhdGErKyA9ICdbJzsKICAgIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKUVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoIExQV1NUUiBPYmpVdWlkLCBMUFdTVFIgUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgTmV0d29ya0FkZHIsIExQV1NUUiBFbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgT3B0aW9ucywgTFBXU1RSKiBTdHJpbmdCaW5kaW5nICkKewogIERXT1JEIGxlbiA9IDE7CiAgTFBXU1RSIGRhdGE7CgogIFRSQUNFKCIoJXMsJXMsJXMsJXMsJXMsJXApXG4iLAogICAgICAgZGVidWdzdHJfdyggT2JqVXVpZCApLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksCiAgICAgICBkZWJ1Z3N0cl93KCBOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLAogICAgICAgZGVidWdzdHJfdyggT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nKTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIGxlbiArPSBzdHJsZW5XKE9ialV1aWQpICsgMTsKICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgbGVuICs9IHN0cmxlblcoUHJvdHNlcSkgKyAxOwogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIGxlbiArPSBzdHJsZW5XKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSBsZW4gKz0gc3RybGVuVyhFbmRwb2ludCkgKyAyOwogIGlmIChPcHRpb25zICYmICpPcHRpb25zKSBsZW4gKz0gc3RybGVuVyhPcHRpb25zKSArIDI7CgogIGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogICpTdHJpbmdCaW5kaW5nID0gZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE9ialV1aWQpOwogICAgKmRhdGErKyA9ICdAJzsKICB9CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIFByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgTmV0d29ya0FkZHIpOwogIH0KICBpZiAoKEVuZHBvaW50ICYmICpFbmRwb2ludCkgfHwKICAgICAgKE9wdGlvbnMgJiYgKk9wdGlvbnMpKSB7CiAgICAqZGF0YSsrID0gJ1snOwogICAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nUGFyc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEoIHVuc2lnbmVkIGNoYXIgKlN0cmluZ0JpbmRpbmcsIHVuc2lnbmVkIGNoYXIgKipPYmpVdWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICoqUHJvdHNlcSwgdW5zaWduZWQgY2hhciAqKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICoqRW5kcG9pbnQsIHVuc2lnbmVkIGNoYXIgKipPcHRpb25zKQp7CiAgQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IGNoYXIgZXBfb3B0W10gPSAiZW5kcG9pbnQ9IjsKCiAgVFJBQ0UoIiglcywlcCwlcCwlcCwlcCwlcClcbiIsIGRlYnVnc3RyX2EoKGNoYXIqKVN0cmluZ0JpbmRpbmcpLAogICAgICAgT2JqVXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gTlVMTDsKICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBOVUxMOwogIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gTlVMTDsKICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IE5VTEw7CiAgaWYgKE9wdGlvbnMpICpPcHRpb25zID0gTlVMTDsKCiAgZGF0YSA9IChjaGFyKikgU3RyaW5nQmluZGluZzsKCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9ICh1bnNpZ25lZCBjaGFyKilSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNocihkYXRhLCAnXScpOwogICAgaWYgKCFjbG9zZSkgZ290byBmYWlsOwoKICAgIC8qIHRva2VuaXplIG9wdGlvbnMgKi8KICAgIHdoaWxlIChkYXRhIDwgY2xvc2UpIHsKICAgICAgbmV4dCA9IHN0cmNocihkYXRhLCAnLCcpOwogICAgICBpZiAoIW5leHQgfHwgbmV4dCA+IGNsb3NlKSBuZXh0ID0gY2xvc2U7CiAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgb3B0ID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgICAgZGF0YSA9IG5leHQrMTsKCiAgICAgIC8qIHBhcnNlIG9wdGlvbiAqLwogICAgICBuZXh0ID0gc3RyY2hyKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAqRW5kcG9pbnQgPSAodW5zaWduZWQgY2hhciopIG9wdDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RybmNtcChvcHQsIGVwX29wdCwgc3RybGVuKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gKHVuc2lnbmVkIGNoYXIqKSBSUENSVDRfc3RyZHVwQShuZXh0KzEpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbmV0d29yayBvcHRpb24gKi8KICAgICAgICAgIGlmICgqT3B0aW9ucykgewogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgICAgICAgICpPcHRpb25zID0gKHVuc2lnbmVkIGNoYXIqKSBSUENSVDRfc3RyY29uY2F0QSggKGNoYXIqKSpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gKHVuc2lnbmVkIGNoYXIqKSBvcHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGF0YSA9IGNsb3NlKzE7CiAgICBpZiAoKmRhdGEpIGdvdG8gZmFpbDsKICB9CiAgZWxzZSBpZiAoTmV0d29ya0FkZHIpIAogICAgKk5ldHdvcmtBZGRyID0gKHVuc2lnbmVkIGNoYXIqKVJQQ1JUNF9zdHJkdXBBKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKVByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKUVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyggTFBXU1RSIFN0cmluZ0JpbmRpbmcsIExQV1NUUiAqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSICpQcm90c2VxLCBMUFdTVFIgKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgKkVuZHBvaW50LCBMUFdTVFIgKk9wdGlvbnMpCnsKICBXQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IFdDSEFSIGVwX29wdFtdID0geydlJywnbicsJ2QnLCdwJywnbycsJ2knLCduJywndCcsJz0nLDB9OwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgV0NIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNoclcoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHJXKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHJXKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAqRW5kcG9pbnQgPSBvcHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXBXKG9wdCwgZXBfb3B0LCBzdHJsZW5XKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFcobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9IFJQQ1JUNF9zdHJjb25jYXRXKCpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfSBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwVyhkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZVcoT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVXKFByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZVcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZVcoRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlVyhPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcmVlKCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgVFJBQ0UoIiglcCkgPSAlcFxuIiwgQmluZGluZywgKkJpbmRpbmcpOwogIHN0YXR1cyA9IFJQQ1JUNF9EZXN0cm95QmluZGluZygqQmluZGluZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykgKkJpbmRpbmcgPSAwOwogIHJldHVybiBzdGF0dXM7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdWZWN0b3JGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdWZWN0b3JGcmVlKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIHVuc2lnbmVkIGxvbmcgYzsKCiAgVFJBQ0UoIiglcClcbiIsIEJpbmRpbmdWZWN0b3IpOwogIGZvciAoYz0wOyBjPCgqQmluZGluZ1ZlY3RvciktPkNvdW50OyBjKyspIHsKICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdGcmVlKCYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjXSk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsICpCaW5kaW5nVmVjdG9yKTsKICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xT2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdJbnFPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcCkgPSAlc1xuIiwgQmluZGluZywgT2JqZWN0VXVpZCwgZGVidWdzdHJfZ3VpZCgmYmluZC0+T2JqZWN0VXVpZCkpOwogIG1lbWNweShPYmplY3RVdWlkLCAmYmluZC0+T2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdTZXRPYmplY3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1NldE9iamVjdCggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7CiAgaWYgKGJpbmQtPnNlcnZlcikgcmV0dXJuIFJQQ19TX1dST05HX0tJTkRfT0ZfQklORElORzsKICByZXR1cm4gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoQmluZGluZywgT2JqZWN0VXVpZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ0EoIHVuc2lnbmVkIGNoYXIgKlN0cmluZ0JpbmRpbmcsIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gTlVMTDsKICB1bnNpZ25lZCBjaGFyICpPYmplY3RVdWlkLCAqUHJvdHNlcSwgKk5ldHdvcmtBZGRyLCAqRW5kcG9pbnQsICpPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX2EoKGNoYXIqKVN0cmluZ0JpbmRpbmcpLCBCaW5kaW5nKTsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ1BhcnNlQShTdHJpbmdCaW5kaW5nLCAmT2JqZWN0VXVpZCwgJlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZOZXR3b3JrQWRkciwgJkVuZHBvaW50LCAmT3B0aW9ucyk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gVXVpZEZyb21TdHJpbmdBKE9iamVjdFV1aWQsICZVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9DcmVhdGVCaW5kaW5nQSgmYmluZCwgRkFMU0UsIChjaGFyKilQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nQShiaW5kLCAoY2hhciopTmV0d29ya0FkZHIsIChjaGFyKilFbmRwb2ludCwgKGNoYXIqKU9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPcHRpb25zKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZFbmRwb2ludCk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJlByb3RzZXEpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKSAKICAgICpCaW5kaW5nID0gKFJQQ19CSU5ESU5HX0hBTkRMRSliaW5kOwogIGVsc2UgCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ1coIExQV1NUUiBTdHJpbmdCaW5kaW5nLCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IE5VTEw7CiAgTFBXU1RSIE9iamVjdFV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9uczsKICBVVUlEIFV1aWQ7CgogIFRSQUNFKCIoJXMsJXApXG4iLCBkZWJ1Z3N0cl93KFN0cmluZ0JpbmRpbmcpLCBCaW5kaW5nKTsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ1BhcnNlVyhTdHJpbmdCaW5kaW5nLCAmT2JqZWN0VXVpZCwgJlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZOZXR3b3JrQWRkciwgJkVuZHBvaW50LCAmT3B0aW9ucyk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gVXVpZEZyb21TdHJpbmdXKE9iamVjdFV1aWQsICZVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9DcmVhdGVCaW5kaW5nVygmYmluZCwgRkFMU0UsIFByb3RzZXEpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfU2V0QmluZGluZ09iamVjdChiaW5kLCAmVXVpZCk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdXKGJpbmQsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIFJwY1N0cmluZ0ZyZWVXKCZPcHRpb25zKTsKICBScGNTdHJpbmdGcmVlVygmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVXKCZOZXR3b3JrQWRkcik7CiAgUnBjU3RyaW5nRnJlZVcoJlByb3RzZXEpOwogIFJwY1N0cmluZ0ZyZWVXKCZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgICpCaW5kaW5nID0gKFJQQ19CSU5ESU5HX0hBTkRMRSliaW5kOwogIGVsc2UKICAgIFJQQ1JUNF9EZXN0cm95QmluZGluZyhiaW5kKTsKCiAgcmV0dXJuIHJldDsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ0EgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ0EoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBjaGFyKiogU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CiAgTFBTVFIgT2JqZWN0VXVpZDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIEJpbmRpbmcsIFN0cmluZ0JpbmRpbmcpOwoKICByZXQgPSBVdWlkVG9TdHJpbmdBKCZiaW5kLT5PYmplY3RVdWlkLCAodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEoKHVuc2lnbmVkIGNoYXIqKSBPYmplY3RVdWlkLCAodW5zaWduZWQgY2hhciopYmluZC0+UHJvdHNlcSwgKHVuc2lnbmVkIGNoYXIqKSBiaW5kLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIqKSBiaW5kLT5FbmRwb2ludCwgTlVMTCwgU3RyaW5nQmluZGluZyk7CgogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIHVuc2lnbmVkIHNob3J0KiogU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICB1bnNpZ25lZCBjaGFyICpzdHIgPSBOVUxMOwogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKICByZXQgPSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQShCaW5kaW5nLCAmc3RyKTsKICAqU3RyaW5nQmluZGluZyA9IFJQQ1JUNF9zdHJkdXBBdG9XKChjaGFyKilzdHIpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJnN0cik7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjQmluZGluZ1NldEFzeW5jIChSUENSVDQuQCkKICogTk9URVMKICogIEV4aXN0cyBpbiB3aW45eCBhbmQgd2luTlQsIGJ1dCB3aXRoIGRpZmZlcmVudCBudW1iZXIgb2YgYXJndW1lbnRzCiAqICAoOXggdmVyc2lvbiBoYXMgMyBhcmd1bWVudHMsIE5UIGhhcyAyKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjQmluZGluZ1NldEFzeW5jKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0JMT0NLSU5HX0ZOIEJsb2NraW5nRm4pCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCAiKCVwLCVwKTogc3R1YlxuIiwgQmluZGluZywgQmxvY2tpbmdGbiApOwoKICBiaW5kLT5CbG9ja2luZ0ZuID0gQmxvY2tpbmdGbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0NvcHkgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBSUENfRU5UUlkgUnBjQmluZGluZ0NvcHkoCiAgUlBDX0JJTkRJTkdfSEFORExFIFNvdXJjZUJpbmRpbmcsCiAgUlBDX0JJTkRJTkdfSEFORExFKiBEZXN0aW5hdGlvbkJpbmRpbmcpCnsKICBScGNCaW5kaW5nICpEZXN0QmluZGluZzsKICBScGNCaW5kaW5nICpTcmNCaW5kaW5nID0gKFJwY0JpbmRpbmcqKVNvdXJjZUJpbmRpbmc7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXAsICVwKVxuIiwgU291cmNlQmluZGluZywgRGVzdGluYXRpb25CaW5kaW5nKTsKCiAgc3RhdHVzID0gUlBDUlQ0X0FsbG9jQmluZGluZygmRGVzdEJpbmRpbmcsIFNyY0JpbmRpbmctPnNlcnZlcik7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKCiAgRGVzdEJpbmRpbmctPk9iamVjdFV1aWQgPSBTcmNCaW5kaW5nLT5PYmplY3RVdWlkOwogIERlc3RCaW5kaW5nLT5CbG9ja2luZ0ZuID0gU3JjQmluZGluZy0+QmxvY2tpbmdGbjsKICBEZXN0QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwQShTcmNCaW5kaW5nLT5Qcm90c2VxLCAtMSk7CiAgRGVzdEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBBKFNyY0JpbmRpbmctPk5ldHdvcmtBZGRyLCAtMSk7CiAgRGVzdEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cm5kdXBBKFNyY0JpbmRpbmctPkVuZHBvaW50LCAtMSk7CgogIGlmIChTcmNCaW5kaW5nLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fQWRkUmVmKFNyY0JpbmRpbmctPkF1dGhJbmZvKTsKICBEZXN0QmluZGluZy0+QXV0aEluZm8gPSBTcmNCaW5kaW5nLT5BdXRoSW5mbzsKCiAgKkRlc3RpbmF0aW9uQmluZGluZyA9IERlc3RCaW5kaW5nOwogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0ltcGVyc29uYXRlQ2xpZW50IChSUENSVDQuQCkKICoKICogSW1wZXJzb25hdGVzIHRoZSBjbGllbnQgY29ubmVjdGVkIHZpYSBhIGJpbmRpbmcgaGFuZGxlIHNvIHRoYXQgc2VjdXJpdHkKICogY2hlY2tzIGFyZSBkb25lIGluIHRoZSBjb250ZXh0IG9mIHRoZSBjbGllbnQuCiAqCiAqIFBBUkFNUwogKiAgQmluZGluZ0hhbmRsZSBbSV0gSGFuZGxlIHRvIHRoZSBiaW5kaW5nIHRvIHRoZSBjbGllbnQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFJQU19TX09LLgogKiAgRmFpbHVyZTogUlBDX1NUQVRVUyB2YWx1ZS4KICoKICogTk9URVMKICoKICogSWYgQmluZGluZ0hhbmRsZSBpcyBOVUxMIHRoZW4gdGhlIGZ1bmN0aW9uIGltcGVyc29uYXRlcyB0aGUgY2xpZW50CiAqIGNvbm5lY3RlZCB0byB0aGUgYmluZGluZyBoYW5kbGUgb2YgdGhlIGN1cnJlbnQgdGhyZWFkLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjSW1wZXJzb25hdGVDbGllbnQoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmdIYW5kbGUpCnsKICAgIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlKTsKICAgIEltcGVyc29uYXRlU2VsZihTZWN1cml0eUltcGVyc29uYXRpb24pOwogICAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjUmV2ZXJ0VG9TZWxmRXggKFJQQ1JUNC5AKQogKgogKiBTdG9wcyBpbXBlcnNvbmF0aW5nIHRoZSBjbGllbnQgY29ubmVjdGVkIHRvIHRoZSBiaW5kaW5nIGhhbmRsZSBzbyB0aGF0IHNlY3VyaXR5CiAqIGNoZWNrcyBhcmUgbm8gbG9uZ2VyIGRvbmUgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGNsaWVudC4KICoKICogUEFSQU1TCiAqICBCaW5kaW5nSGFuZGxlIFtJXSBIYW5kbGUgdG8gdGhlIGJpbmRpbmcgdG8gdGhlIGNsaWVudC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBTX1NfT0suCiAqICBGYWlsdXJlOiBSUENfU1RBVFVTIHZhbHVlLgogKgogKiBOT1RFUwogKgogKiBJZiBCaW5kaW5nSGFuZGxlIGlzIE5VTEwgdGhlbiB0aGUgZnVuY3Rpb24gc3RvcHMgaW1wZXJzb25hdGluZyB0aGUgY2xpZW50CiAqIGNvbm5lY3RlZCB0byB0aGUgYmluZGluZyBoYW5kbGUgb2YgdGhlIGN1cnJlbnQgdGhyZWFkLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjUmV2ZXJ0VG9TZWxmRXgoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmdIYW5kbGUpCnsKICAgIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUnBjQXV0aEluZm9fQ3JlYXRlKHVuc2lnbmVkIGxvbmcgQXV0aG5MZXZlbCwgdW5zaWduZWQgbG9uZyBBdXRoblN2YywgQ3JlZEhhbmRsZSBjcmVkLCBUaW1lU3RhbXAgZXhwLCBScGNBdXRoSW5mbyAqKnJldCkKewogICAgUnBjQXV0aEluZm8gKkF1dGhJbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqQXV0aEluZm8pKTsKICAgIGlmICghQXV0aEluZm8pCiAgICAgICAgcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwoKICAgIEF1dGhJbmZvLT5BdXRobkxldmVsID0gQXV0aG5MZXZlbDsKICAgIEF1dGhJbmZvLT5BdXRoblN2YyA9IEF1dGhuU3ZjOwogICAgQXV0aEluZm8tPmNyZWQgPSBjcmVkOwogICAgQXV0aEluZm8tPmV4cCA9IGV4cDsKICAgICpyZXQgPSBBdXRoSW5mbzsKICAgIHJldHVybiBSUENfU19PSzsKfQoKVUxPTkcgUnBjQXV0aEluZm9fQWRkUmVmKFJwY0F1dGhJbmZvICpBdXRoSW5mbykKewogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZBdXRoSW5mby0+cmVmcyk7Cn0KClVMT05HIFJwY0F1dGhJbmZvX1JlbGVhc2UoUnBjQXV0aEluZm8gKkF1dGhJbmZvKQp7CiAgICBVTE9ORyByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJkF1dGhJbmZvLT5yZWZzKTsKCiAgICBpZiAoIXJlZnMpCiAgICB7CiAgICAgICAgRnJlZUNyZWRlbnRpYWxzSGFuZGxlKCZBdXRoSW5mby0+Y3JlZCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8pOwogICAgfQoKICAgIHJldHVybiByZWZzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjUmV2ZXJ0VG9TZWxmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1JldmVydFRvU2VsZih2b2lkKQp7CiAgICBGSVhNRSgic3R1YlxuIik7CiAgICBSZXZlcnRUb1NlbGYoKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXRDb21UaW1lb3V0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRTZXRDb21UaW1lb3V0KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlLCB1bnNpZ25lZCBpbnQgVGltZW91dCkKewogICAgRklYTUUoIiglcCwgJWQpOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlLCBUaW1lb3V0KTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb0V4QSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9FeEEoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBjaGFyICoqIFNlcnZlclByaW5jTmFtZSwgdW5zaWduZWQgbG9uZyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nICpBdXRoblN2YywgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFICpBdXRoSWRlbnRpdHksIHVuc2lnbmVkIGxvbmcgKkF1dGh6U3ZjLAogICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgUnBjUW9zVmVyc2lvbiwgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRT1MgKQp7CiAgICBGSVhNRSgiJXAgJXAgJXAgJXAgJXAgJXAgJWx1ICVwXG4iLCBCaW5kaW5nLCBTZXJ2ZXJQcmluY05hbWUsIEF1dGhuTGV2ZWwsCiAgICAgICAgICBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2YywgUnBjUW9zVmVyc2lvbiwgU2VjdXJpdHlRT1MpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb0V4VyAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9FeFcoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBzaG9ydCAqKiBTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgKkF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCB1bnNpZ25lZCBsb25nICpBdXRoelN2YywKICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIFJwY1Fvc1ZlcnNpb24sIFJQQ19TRUNVUklUWV9RT1MgKlNlY3VyaXR5UU9TICkKewogICAgRklYTUUoIiVwICVwICVwICVwICVwICVwICVsdSAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMsIFJwY1Fvc1ZlcnNpb24sIFNlY3VyaXR5UU9TKTsKICAgIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdJbnFBdXRoSW5mb0EoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBjaGFyICoqIFNlcnZlclByaW5jTmFtZSwgdW5zaWduZWQgbG9uZyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCB1bnNpZ25lZCBsb25nICpBdXRoelN2YyApCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcCAlcCAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb1cgKFJQQ1JUNC5AKQogKi8KUlBDUlRBUEkgUlBDX1NUQVRVUyBSUENfRU5UUlkKUnBjQmluZGluZ0lucUF1dGhJbmZvVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIHVuc2lnbmVkIHNob3J0ICoqIFNlcnZlclByaW5jTmFtZSwgdW5zaWduZWQgbG9uZyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCB1bnNpZ25lZCBsb25nICpBdXRoelN2YyApCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcCAlcCAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdTZXRBdXRoSW5mb0V4QSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nU2V0QXV0aEluZm9FeEEoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBjaGFyICpTZXJ2ZXJQcmluY05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBBdXRobkxldmVsLCB1bnNpZ25lZCBsb25nIEF1dGhuU3ZjLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSBBdXRoSWRlbnRpdHksIHVuc2lnbmVkIGxvbmcgQXV0aHpTdnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRb3MgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIFNFQ1VSSVRZX1NUQVRVUyByOwogIENyZWRIYW5kbGUgY3JlZDsKICBUaW1lU3RhbXAgZXhwOwogIFVMT05HIHBhY2thZ2VfY291bnQ7CiAgVUxPTkcgaTsKICBQU2VjUGtnSW5mb0EgcGFja2FnZXM7CgogIFRSQUNFKCIlcCAlcyAlbHUgJWx1ICVwICVsdSAlcFxuIiwgQmluZGluZywgZGVidWdzdHJfYSgoY29uc3QgY2hhciopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgU2VjdXJpdHlRb3MpOwoKICBpZiAoQXV0aG5MZXZlbCAhPSBSUENfQ19BVVRITl9MRVZFTF9DT05ORUNUKQogIHsKICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCBBdXRobkxldmVsICVsdVxuIiwgQXV0aG5MZXZlbCk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9MRVZFTDsKICB9CgogIGlmIChBdXRoelN2cikKICB7CiAgICBGSVhNRSgidW5zdXBwb3J0ZWQgQXV0aHpTdnIgJWx1XG4iLCBBdXRoelN2cik7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRIWl9TRVJWSUNFOwogIH0KCiAgaWYgKFNlY3VyaXR5UW9zKQogICAgRklYTUUoIlNlY3VyaXR5UW9zIGlnbm9yZWRcbiIpOwoKICByID0gRW51bWVyYXRlU2VjdXJpdHlQYWNrYWdlc0EoJnBhY2thZ2VfY291bnQsICZwYWNrYWdlcyk7CiAgaWYgKHIgIT0gU0VDX0VfT0spCiAgewogICAgRVJSKCJFbnVtZXJhdGVTZWN1cml0eVBhY2thZ2VzQSBmYWlsZWQgd2l0aCBlcnJvciAweCUwOGx4XG4iLCByKTsKICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogIH0KCiAgZm9yIChpID0gMDsgaSA8IHBhY2thZ2VfY291bnQ7IGkrKykKICAgIGlmIChwYWNrYWdlc1tpXS53UlBDSUQgPT0gQXV0aG5TdmMpCiAgICAgICAgYnJlYWs7CgogIGlmIChpID09IHBhY2thZ2VfY291bnQpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGhuU3ZjICVsdVxuIiwgQXV0aG5TdmMpOwogICAgRnJlZUNvbnRleHRCdWZmZXIocGFja2FnZXMpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsKICB9CgogIFRSQUNFKCJmb3VuZCBwYWNrYWdlICVzIGZvciBzZXJ2aWNlICVsZFxuIiwgcGFja2FnZXNbaV0uTmFtZSwgQXV0aG5TdmMpOwogIHIgPSBBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBKChTRUNfQ0hBUiAqKVNlcnZlclByaW5jTmFtZSwgcGFja2FnZXNbaV0uTmFtZSwgU0VDUEtHX0NSRURfT1VUQk9VTkQsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aElkZW50aXR5LCBOVUxMLCBOVUxMLCAmY3JlZCwgJmV4cCk7CiAgRnJlZUNvbnRleHRCdWZmZXIocGFja2FnZXMpOwogIGlmIChyID09IEVSUk9SX1NVQ0NFU1MpCiAgewogICAgaWYgKGJpbmQtPkF1dGhJbmZvKSBScGNBdXRoSW5mb19SZWxlYXNlKGJpbmQtPkF1dGhJbmZvKTsKICAgIGJpbmQtPkF1dGhJbmZvID0gTlVMTDsKICAgIHIgPSBScGNBdXRoSW5mb19DcmVhdGUoQXV0aG5MZXZlbCwgQXV0aG5TdmMsIGNyZWQsIGV4cCwgJmJpbmQtPkF1dGhJbmZvKTsKICAgIGlmIChyICE9IFJQQ19TX09LKQogICAgICBGcmVlQ3JlZGVudGlhbHNIYW5kbGUoJmNyZWQpOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBlbHNlCiAgewogICAgRVJSKCJBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4bHhcbiIsIHIpOwogICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldEF1dGhJbmZvRXhXIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb0V4VyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIHVuc2lnbmVkIHNob3J0ICpTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCB1bnNpZ25lZCBsb25nIEF1dGh6U3ZyLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19TRUNVUklUWV9RT1MgKlNlY3VyaXR5UW9zICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKICBTRUNVUklUWV9TVEFUVVMgcjsKICBDcmVkSGFuZGxlIGNyZWQ7CiAgVGltZVN0YW1wIGV4cDsKICBVTE9ORyBwYWNrYWdlX2NvdW50OwogIFVMT05HIGk7CiAgUFNlY1BrZ0luZm9XIHBhY2thZ2VzOwoKICBUUkFDRSgiJXAgJXMgJWx1ICVsdSAlcCAlbHUgJXBcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX3coKGNvbnN0IFdDSEFSKilTZXJ2ZXJQcmluY05hbWUpLAogICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyLCBTZWN1cml0eVFvcyk7CgogIGlmIChBdXRobkxldmVsICE9IFJQQ19DX0FVVEhOX0xFVkVMX0NPTk5FQ1QpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGhuTGV2ZWwgJWx1XG4iLCBBdXRobkxldmVsKTsKICAgIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX0xFVkVMOwogIH0KCiAgaWYgKEF1dGh6U3ZyKQogIHsKICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCBBdXRoelN2ciAlbHVcbiIsIEF1dGh6U3ZyKTsKICAgIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhaX1NFUlZJQ0U7CiAgfQoKICBpZiAoU2VjdXJpdHlRb3MpCiAgICBGSVhNRSgiU2VjdXJpdHlRb3MgaWdub3JlZFxuIik7CgogIHIgPSBFbnVtZXJhdGVTZWN1cml0eVBhY2thZ2VzVygmcGFja2FnZV9jb3VudCwgJnBhY2thZ2VzKTsKICBpZiAociAhPSBTRUNfRV9PSykKICB7CiAgICBFUlIoIkVudW1lcmF0ZVNlY3VyaXR5UGFja2FnZXNBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4bHhcbiIsIHIpOwogICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgfQoKICBmb3IgKGkgPSAwOyBpIDwgcGFja2FnZV9jb3VudDsgaSsrKQogICAgaWYgKHBhY2thZ2VzW2ldLndSUENJRCA9PSBBdXRoblN2YykKICAgICAgICBicmVhazsKCiAgaWYgKGkgPT0gcGFja2FnZV9jb3VudCkKICB7CiAgICBGSVhNRSgidW5zdXBwb3J0ZWQgQXV0aG5TdmMgJWx1XG4iLCBBdXRoblN2Yyk7CiAgICBGcmVlQ29udGV4dEJ1ZmZlcihwYWNrYWdlcyk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOwogIH0KCiAgVFJBQ0UoImZvdW5kIHBhY2thZ2UgJXMgZm9yIHNlcnZpY2UgJWxkXG4iLCBkZWJ1Z3N0cl93KHBhY2thZ2VzW2ldLk5hbWUpLCBBdXRoblN2Yyk7CiAgciA9IEFjcXVpcmVDcmVkZW50aWFsc0hhbmRsZVcoKFNFQ19XQ0hBUiAqKVNlcnZlclByaW5jTmFtZSwgcGFja2FnZXNbaV0uTmFtZSwgU0VDUEtHX0NSRURfT1VUQk9VTkQsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aElkZW50aXR5LCBOVUxMLCBOVUxMLCAmY3JlZCwgJmV4cCk7CiAgRnJlZUNvbnRleHRCdWZmZXIocGFja2FnZXMpOwogIGlmIChyID09IEVSUk9SX1NVQ0NFU1MpCiAgewogICAgaWYgKGJpbmQtPkF1dGhJbmZvKSBScGNBdXRoSW5mb19SZWxlYXNlKGJpbmQtPkF1dGhJbmZvKTsKICAgIGJpbmQtPkF1dGhJbmZvID0gTlVMTDsKICAgIHIgPSBScGNBdXRoSW5mb19DcmVhdGUoQXV0aG5MZXZlbCwgQXV0aG5TdmMsIGNyZWQsIGV4cCwgJmJpbmQtPkF1dGhJbmZvKTsKICAgIGlmIChyICE9IFJQQ19TX09LKQogICAgICBGcmVlQ3JlZGVudGlhbHNIYW5kbGUoJmNyZWQpOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBlbHNlCiAgewogICAgRVJSKCJBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4bHhcbiIsIHIpOwogICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldEF1dGhJbmZvQSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nU2V0QXV0aEluZm9BKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgdW5zaWduZWQgY2hhciAqU2VydmVyUHJpbmNOYW1lLCB1bnNpZ25lZCBsb25nIEF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSBBdXRoSWRlbnRpdHksIHVuc2lnbmVkIGxvbmcgQXV0aHpTdnIgKQp7CiAgICBUUkFDRSgiJXAgJXMgJWx1ICVsdSAlcCAlbHVcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2EoKGNvbnN0IGNoYXIqKVNlcnZlclByaW5jTmFtZSksCiAgICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2cik7CiAgICByZXR1cm4gUnBjQmluZGluZ1NldEF1dGhJbmZvRXhBKEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdnIsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldEF1dGhJbmZvVyAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nU2V0QXV0aEluZm9XKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgdW5zaWduZWQgc2hvcnQgKlNlcnZlclByaW5jTmFtZSwgdW5zaWduZWQgbG9uZyBBdXRobkxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCB1bnNpZ25lZCBsb25nIEF1dGh6U3ZyICkKewogICAgVFJBQ0UoIiVwICVzICVsdSAlbHUgJXAgJWx1XG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl93KChjb25zdCBXQ0hBUiopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyKTsKICAgIHJldHVybiBScGNCaW5kaW5nU2V0QXV0aEluZm9FeFcoQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0T3B0aW9uIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdTZXRPcHRpb24oUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmdIYW5kbGUsIFVMT05HIE9wdGlvbiwgVUxPTkcgT3B0aW9uVmFsdWUpCnsKICAgIEZJWE1FKCIoJXAsICVsZCwgJWxkKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSwgT3B0aW9uLCBPcHRpb25WYWx1ZSk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0K