LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSwgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LCBMUFNUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIE5ld0Nvbm5lY3Rpb24gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb24pKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwogIE5ld0Nvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUgPSBSUENfTUFYX1BBQ0tFVF9TSVpFOwoKICBUUkFDRSgiY29ubmVjdGlvbjogJXBcbiIsIE5ld0Nvbm5lY3Rpb24pOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihDb25uZWN0aW9uKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPlByb3RzZXEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIENvbm5lY3Rpb24pOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoIUNvbm5lY3Rpb24tPmNvbm4pIHsKICAgIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpIHsgLyogc2VydmVyICovCiAgICAgIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgICAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICAgICAgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhbHJwYyIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQSVBFX0FDQ0VTU19EVVBMRVgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9UWVBFX01FU1NBR0UgfCBQSVBFX1JFQURNT0RFX01FU1NBR0UsIFBJUEVfVU5MSU1JVEVEX0lOU1RBTkNFUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLCBSUENfTUFYX1BBQ0tFVF9TSVpFLCA1MDAwLCBOVUxMKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgICAgICBpZiAoIUNvbm5lY3ROYW1lZFBpcGUoQ29ubmVjdGlvbi0+Y29ubiwgJkNvbm5lY3Rpb24tPm92bCkpIHsKICAgICAgICAgIFdBUk4oIkNvdWxkbid0IENvbm5lY3ROYW1lZFBpcGUgKGVycm9yIHdhcyAlbGQpXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfUElQRV9DT05ORUNURUQpIHsKICAgICAgICAgICAgU2V0RXZlbnQoQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0gZWxzZSBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU9fUEVORElORykgewogICAgICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBwcm90c2VxPW5jYWNuX25wOiBuYW1lZCBwaXBlcyAqLwogICAgICBlbHNlIGlmIChzdHJjbXAoQ29ubmVjdGlvbi0+UHJvdHNlcSwgIm5jYWNuX25wIikgPT0gMCkgewogICAgICAgIHN0YXRpYyBMUENTVFIgcHJlZml4ID0gIlxcXFwuIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQSVBFX0FDQ0VTU19EVVBMRVgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9UWVBFX01FU1NBR0UgfCBQSVBFX1JFQURNT0RFX01FU1NBR0UgfCBQSVBFX1dBSVQsIFBJUEVfVU5MSU1JVEVEX0lOU1RBTkNFUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLCBSUENfTUFYX1BBQ0tFVF9TSVpFLCA1MDAwLCBOVUxMKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgICAgICBpZiAoIUNvbm5lY3ROYW1lZFBpcGUoQ29ubmVjdGlvbi0+Y29ubiwgJkNvbm5lY3Rpb24tPm92bCkpIHsKICAgICAgICAgIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkgewogICAgICAgICAgICBTZXRFdmVudChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgICAgICAgfSBlbHNlIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JT19QRU5ESU5HKSB7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0KICAgICAgICAgIFdBUk4oIkNvdWxkbid0IENvbm5lY3ROYW1lZFBpcGUgKGVycm9yIHdhcyAlbGQpXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBFUlIoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICAgICAgfQogICAgfQogICAgZWxzZSB7IC8qIGNsaWVudCAqLwogICAgICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICAgICAqIGJ1dCB3ZSdsbCBpbXBsZW1lbnQgaXQgd2l0aCBuYW1lZCBwaXBlcyBmb3Igbm93ICovCiAgICAgIGlmIChzdHJjbXAoQ29ubmVjdGlvbi0+UHJvdHNlcSwgIm5jYWxycGMiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwogICAgICAgIERXT1JEIGR3TW9kZTsKCiAgICAgICAgcG5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgICAgICAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogICAgICAgIFRSQUNFKCJjb25uZWN0aW5nIHRvICVzXG4iLCBwbmFtZSk7CiAgICAgICAgd2hpbGUgKFRSVUUpIHsKICAgICAgICAgIGlmIChXYWl0TmFtZWRQaXBlQShwbmFtZSwgTk1QV0FJVF9XQUlUX0ZPUkVWRVIpKSB7CiAgICAgICAgICAgIGNvbm4gPSBDcmVhdGVGaWxlQShwbmFtZSwgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICAgICAgICAgICAgaWYgKGNvbm4gIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpIGNvbnRpbnVlOwogICAgICAgICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1RPT19CVVNZOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAgIFdBUk4oImNvbm5lY3Rpb24gZmFpbGVkLCBlcnJvcj0lbHhcbiIsIGVycik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIHN1Y2Nlc3MgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICAvKiBwaXBlIGlzIGNvbm5lY3RlZDsgY2hhbmdlIHRvIG1lc3NhZ2UtcmVhZCBtb2RlLiAqLwogICAgICAgIGR3TW9kZSA9IFBJUEVfUkVBRE1PREVfTUVTU0FHRTsgCiAgICAgICAgU2V0TmFtZWRQaXBlSGFuZGxlU3RhdGUoY29ubiwgJmR3TW9kZSwgTlVMTCwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IGNvbm47CiAgICAgIH0KICAgICAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICAgICAgZWxzZSBpZiAoc3RyY21wKENvbm5lY3Rpb24tPlByb3RzZXEsICJuY2Fjbl9ucCIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLiI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwogICAgICAgIERXT1JEIGR3TW9kZTsKCiAgICAgICAgcG5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgICAgICAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogICAgICAgIFRSQUNFKCJjb25uZWN0aW5nIHRvICVzXG4iLCBwbmFtZSk7CiAgICAgICAgY29ubiA9IENyZWF0ZUZpbGVBKHBuYW1lLCBHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgT1BFTl9FWElTVElORywgMCwgMCk7CiAgICAgICAgaWYgKGNvbm4gPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKICAgICAgICAgIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCB0byBoYW5kbGUgRVJST1JfUElQRV9CVVNZIGhlcmUsCiAgICAgICAgICAgKiB0aGUgZG9jIHNheXMgdGhhdCBpdCBpcyByZXR1cm5lZCB0byB0aGUgYXBwICovCiAgICAgICAgICBXQVJOKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpCiAgICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVE9PX0JVU1k7CiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgLyogcGlwZSBpcyBjb25uZWN0ZWQ7IGNoYW5nZSB0byBtZXNzYWdlLXJlYWQgbW9kZS4gKi8KICAgICAgICBkd01vZGUgPSBQSVBFX1JFQURNT0RFX01FU1NBR0U7CiAgICAgICAgU2V0TmFtZWRQaXBlSGFuZGxlU3RhdGUoY29ubiwgJmR3TW9kZSwgTlVMTCwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IGNvbm47CiAgICAgIH0gZWxzZSB7CiAgICAgICAgRVJSKCJwcm90c2VxICVzIG5vdCBzdXBwb3J0ZWRcbiIsIENvbm5lY3Rpb24tPlByb3RzZXEpOwogICAgICAgIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoQ29ubmVjdGlvbi0+Y29ubikgewogICAgRmx1c2hGaWxlQnVmZmVycyhDb25uZWN0aW9uLT5jb25uKTsKICAgIENsb3NlSGFuZGxlKENvbm5lY3Rpb24tPmNvbm4pOwogICAgQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgfQogIGlmIChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KSB7CiAgICBDbG9zZUhhbmRsZShDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSAwOwogIH0KICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUnBjQ29ubmVjdGlvbiogT2xkQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CiAgUlBDX1NUQVRVUyBlcnIgPSBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgT2xkQ29ubmVjdGlvbi0+c2VydmVyLCBPbGRDb25uZWN0aW9uLT5Qcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2xkQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIE9sZENvbm5lY3Rpb24tPkVuZHBvaW50LCBOVUxMLCBOVUxMKTsKICBpZiAoZXJyID09IFJQQ19TX09LKSB7CiAgICAvKiBiZWNhdXNlIG9mIHRoZSB3YXkgbmFtZWQgcGlwZXMgd29yaywgd2UnbGwgdHJhbnNmZXIgdGhlIGNvbm5lY3RlZCBwaXBlCiAgICAgKiB0byB0aGUgY2hpbGQsIHRoZW4gcmVvcGVuIHRoZSBzZXJ2ZXIgYmluZGluZyB0byBjb250aW51ZSBsaXN0ZW5pbmcgKi8KICAgIE5ld0Nvbm5lY3Rpb24tPmNvbm4gPSBPbGRDb25uZWN0aW9uLT5jb25uOwogICAgTmV3Q29ubmVjdGlvbi0+b3ZsID0gT2xkQ29ubmVjdGlvbi0+b3ZsOwogICAgT2xkQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgICBtZW1zZXQoJk9sZENvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKE9sZENvbm5lY3Rpb24tPm92bCkpOwogICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgUlBDUlQ0X09wZW5Db25uZWN0aW9uKE9sZENvbm5lY3Rpb24pOwogIH0KICByZXR1cm4gZXJyOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQWxsb2NCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlcikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIE5ld0JpbmRpbmcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0JpbmRpbmcpKTsKICBOZXdCaW5kaW5nLT5yZWZzID0gMTsKICBOZXdCaW5kaW5nLT5zZXJ2ZXIgPSBzZXJ2ZXI7CgogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nQShScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQU1RSIFByb3RzZXEpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBzZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShQcm90c2VxKTsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ1coUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUFdTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdBKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQU1RSIE5ldHdvcmtBZGRyLCAgTFBTVFIgRW5kcG9pbnQsICBMUFNUUiBOZXR3b3JrT3B0aW9ucykKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09IFwiJXNcIiwgRW5kUG9pbnQgPT0gXCIlc1wiLCBOZXR3b3JrT3B0aW9ucyA9PSBcIiVzXCIpXG4iLCBCaW5kaW5nLAogICBkZWJ1Z3N0cl9hKE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfYShFbmRwb2ludCksIGRlYnVnc3RyX2EoTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFdTVFIgTmV0d29ya0FkZHIsIExQV1NUUiBFbmRwb2ludCwgTFBXU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gXCIlc1wiLCBFbmRQb2ludCA9PSBcIiVzXCIsIE5ldHdvcmtPcHRpb25zID09IFwiJXNcIilcbiIsIEJpbmRpbmcsIAogICBkZWJ1Z3N0cl93KE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfdyhFbmRwb2ludCksIGRlYnVnc3RyX3coTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFd0b0EoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfUmVzb2x2ZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgTFBTVFIgRW5kcG9pbnQpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBFbmRQb2ludCA9PSBcIiVzXCJcbiIsIEJpbmRpbmcsIEVuZHBvaW50KTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoUnBjQmluZGluZyogQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCkKewogIFRSQUNFKCIoKlJwY0JpbmRpbmcgPT0gXiVwLCBVVUlEID09ICVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7IAogIGlmIChPYmplY3RVdWlkKSBtZW1jcHkoJkJpbmRpbmctPk9iamVjdFV1aWQsIE9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgZWxzZSBVdWlkQ3JlYXRlTmlsKCZCaW5kaW5nLT5PYmplY3RVdWlkKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X01ha2VCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBDb25uZWN0aW9uID09IF4lcClcbiIsIEJpbmRpbmcsIENvbm5lY3Rpb24pOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBDb25uZWN0aW9uLT5zZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5Qcm90c2VxKTsKICBOZXdCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBOZXdCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICBOZXdCaW5kaW5nLT5Gcm9tQ29ubiA9IENvbm5lY3Rpb247CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0V4cG9ydEJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0JpbmRpbmcqIE9sZEJpbmRpbmcpCnsKICBJbnRlcmxvY2tlZEluY3JlbWVudCgmT2xkQmluZGluZy0+cmVmcyk7CiAgKkJpbmRpbmcgPSBPbGRCaW5kaW5nOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZykKewogIGlmIChJbnRlcmxvY2tlZERlY3JlbWVudCgmQmluZGluZy0+cmVmcykpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgQmluZGluZyk7CiAgLyogRklYTUU6IHJlbGVhc2UgY29ubmVjdGlvbnMgKi8KICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPlByb3RzZXEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEJpbmRpbmcpOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfU1lOVEFYX0lERU5USUZJRVIgVHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfU1lOVEFYX0lERU5USUZJRVIgSW50ZXJmYWNlSWQpCnsKICBScGNDb25uZWN0aW9uKiBOZXdDb25uZWN0aW9uOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiKEJpbmRpbmcgPT0gXiVwKVxuIiwgQmluZGluZyk7CgogIC8qIGlmIHdlIHRyeSB0byBiaW5kIGEgbmV3IGludGVyZmFjZSBhbmQgdGhlIGNvbm5lY3Rpb24gaXMgYWxyZWFkeSBvcGVuZWQsCiAgICogY2xvc2UgdGhlIGN1cnJlbnQgY29ubmVjdGlvbiBhbmQgY3JlYXRlIGEgbmV3IHdpdGggdGhlIG5ldyBiaW5kaW5nLiAqLyAKICBpZiAoIUJpbmRpbmctPnNlcnZlciAmJiBCaW5kaW5nLT5Gcm9tQ29ubiAmJgogICAgICBtZW1jbXAoJkJpbmRpbmctPkZyb21Db25uLT5BY3RpdmVJbnRlcmZhY2UsIEludGVyZmFjZUlkLAogICAgICAgICAgICAgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpKSB7CgogICAgVFJBQ0UoInJlbGVhc2luZyBwcmUtZXhpc3RpbmcgY29ubmVjdGlvblxuIik7CiAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oQmluZGluZy0+RnJvbUNvbm4pOwogICAgQmluZGluZy0+RnJvbUNvbm4gPSBOVUxMOwogIH0gZWxzZSB7CiAgICAvKiB3ZSBhbHJlYWR5IGhhdmUgYSBjb25uZWN0aW9uIHdpdGggYWNjZXB0YWJsZSBiaW5kaW5nLCBzbyB1c2UgaXQgKi8KICAgIGlmIChCaW5kaW5nLT5Gcm9tQ29ubikgewogICAgICAqQ29ubmVjdGlvbiA9IEJpbmRpbmctPkZyb21Db25uOwogICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CiAgfQogIAogIC8qIGNyZWF0ZSBhIG5ldyBjb25uZWN0aW9uICovCiAgUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oJk5ld0Nvbm5lY3Rpb24sIEJpbmRpbmctPnNlcnZlciwgQmluZGluZy0+UHJvdHNlcSwgQmluZGluZy0+TmV0d29ya0FkZHIsIEJpbmRpbmctPkVuZHBvaW50LCBOVUxMLCBCaW5kaW5nKTsKICAqQ29ubmVjdGlvbiA9IE5ld0Nvbm5lY3Rpb247CiAgc3RhdHVzID0gUlBDUlQ0X09wZW5Db25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgIHJldHVybiBzdGF0dXM7CiAgfQoKICAvKiB3ZSBuZWVkIHRvIHNlbmQgYSBiaW5kaW5nIHBhY2tldCBpZiB3ZSBhcmUgY2xpZW50LiAqLwogIGlmICghKCpDb25uZWN0aW9uKS0+c2VydmVyKSB7CiAgICBScGNQa3RIZHIgKmhkcjsKICAgIERXT1JEIGNvdW50OwogICAgQllURSAqcmVzcG9uc2U7CiAgICBScGNQa3RIZHIgKnJlc3BvbnNlX2hkcjsKCiAgICBUUkFDRSgic2VuZGluZyBiaW5kIHJlcXVlc3QgdG8gc2VydmVyXG4iKTsKCiAgICBoZHIgPSBSUENSVDRfQnVpbGRCaW5kSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLCBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlcmZhY2VJZCwgVHJhbnNmZXJTeW50YXgpOwoKICAgIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKCpDb25uZWN0aW9uLCBoZHIsIE5VTEwsIDApOwogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIHJlc3BvbnNlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFJQQ19NQVhfUEFDS0VUX1NJWkUpOwogICAgaWYgKHJlc3BvbnNlID09IE5VTEwpIHsKICAgICAgV0FSTigiQ2FuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciBiaW5kaW5nIHJlc3BvbnNlXG4iKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgLyogZ2V0IGEgcmVwbHkgKi8KICAgIGlmICghUmVhZEZpbGUoTmV3Q29ubmVjdGlvbi0+Y29ubiwgcmVzcG9uc2UsIFJQQ19NQVhfUEFDS0VUX1NJWkUsICZjb3VudCwgTlVMTCkpIHsKICAgICAgV0FSTigiUmVhZEZpbGUgZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICBpZiAoY291bnQgPCBzaXplb2YocmVzcG9uc2VfaGRyLT5jb21tb24pKSB7CiAgICAgIFdBUk4oInJlY2VpdmVkIGludmFsaWQgaGVhZGVyXG4iKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIHJlc3BvbnNlX2hkciA9IChScGNQa3RIZHIqKXJlc3BvbnNlOwoKICAgIGlmIChyZXNwb25zZV9oZHItPmNvbW1vbi5ycGNfdmVyICE9IFJQQ19WRVJfTUFKT1IgfHwKICAgICAgICByZXNwb25zZV9oZHItPmNvbW1vbi5ycGNfdmVyX21pbm9yICE9IFJQQ19WRVJfTUlOT1IgfHwKICAgICAgICByZXNwb25zZV9oZHItPmNvbW1vbi5wdHlwZSAhPSBQS1RfQklORF9BQ0spIHsKICAgICAgV0FSTigiaW52YWxpZCBwcm90b2NvbCB2ZXJzaW9uIG9yIHJlamVjdGlvbiBwYWNrZXRcbiIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICB9CgogICAgaWYgKHJlc3BvbnNlX2hkci0+YmluZF9hY2subWF4X3RzaXplIDwgUlBDX01JTl9QQUNLRVRfU0laRSkgewogICAgICBXQVJOKCJzZXJ2ZXIgZG9lc24ndCBhbGxvdyBsYXJnZSBlbm91Z2ggcGFja2V0c1xuIik7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICAvKiBGSVhNRTogZG8gbW9yZSBjaGVja3M/ICovCgogICAgKCpDb25uZWN0aW9uKS0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IHJlc3BvbnNlX2hkci0+YmluZF9hY2subWF4X3RzaXplOwogICAgKCpDb25uZWN0aW9uKS0+QWN0aXZlSW50ZXJmYWNlID0gKkludGVyZmFjZUlkOwogIH0KCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQmluZGluZyA9PSBeJXApXG4iLCBCaW5kaW5nKTsKICBpZiAoIUNvbm5lY3Rpb24pIHJldHVybiBSUENfU19PSzsKICBpZiAoQmluZGluZy0+RnJvbUNvbm4gPT0gQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIHJldHVybiBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7Cn0KCi8qIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBzdHJpbmcgY29tcG9zaW5nIGFuZCBwYXJzaW5nICovCnN0YXRpYyB1bnNpZ25lZCBSUENSVDRfc3RyY29weUEoTFBTVFIgZGF0YSwgTFBDU1RSIHNyYykKewogIHVuc2lnbmVkIGxlbiA9IHN0cmxlbihzcmMpOwogIG1lbWNweShkYXRhLCBzcmMsIGxlbipzaXplb2YoQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyB1bnNpZ25lZCBSUENSVDRfc3RyY29weVcoTFBXU1RSIGRhdGEsIExQQ1dTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuVyhzcmMpOwogIG1lbWNweShkYXRhLCBzcmMsIGxlbipzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbGVuOwp9CgpzdGF0aWMgTFBTVFIgUlBDUlQ0X3N0cmNvbmNhdEEoTFBTVFIgZHN0LCBMUENTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuKGRzdCksIHNsZW4gPSBzdHJsZW4oc3JjKTsKICBMUFNUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKENIQVIpKTsKICBpZiAoIW5kc3QpCiAgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIHJldHVybiBOVUxMOwogIH0KICBuZHN0W2xlbl0gPSAnLCc7CiAgbWVtY3B5KG5kc3QrbGVuKzEsIHNyYywgc2xlbisxKTsKICByZXR1cm4gbmRzdDsKfQoKc3RhdGljIExQV1NUUiBSUENSVDRfc3RyY29uY2F0VyhMUFdTVFIgZHN0LCBMUENXU1RSIHNyYykKewogIERXT1JEIGxlbiA9IHN0cmxlblcoZHN0KSwgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBMUFdTVFIgbmRzdCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdCwgKGxlbitzbGVuKzIpKnNpemVvZihXQ0hBUikpOwogIGlmICghbmRzdCkgCiAgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIHJldHVybiBOVUxMOwogIH0KICBuZHN0W2xlbl0gPSAnLCc7CiAgbWVtY3B5KG5kc3QrbGVuKzEsIHNyYywgKHNsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIG5kc3Q7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlQSh1bnNpZ25lZCBjaGFyICpPYmpVdWlkLCB1bnNpZ25lZCBjaGFyICpQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqTmV0d29ya0FkZHIsIHVuc2lnbmVkIGNoYXIgKkVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqT3B0aW9ucywgdW5zaWduZWQgY2hhcioqIFN0cmluZ0JpbmRpbmcgKQp7CiAgRFdPUkQgbGVuID0gMTsKICBMUFNUUiBkYXRhOwoKICBUUkFDRSggIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICAgZGVidWdzdHJfYSggKGNoYXIqKU9ialV1aWQgKSwgZGVidWdzdHJfYSggKGNoYXIqKVByb3RzZXEgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopTmV0d29ya0FkZHIgKSwgZGVidWdzdHJfYSggKGNoYXIqKUVuZHBvaW50ICksCiAgICAgICAgZGVidWdzdHJfYSggKGNoYXIqKU9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyApOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlbigoY2hhciopT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuKChjaGFyKilQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlbigoY2hhciopTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW4oKGNoYXIqKUVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW4oKGNoYXIqKU9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwogICpTdHJpbmdCaW5kaW5nID0gKHVuc2lnbmVkIGNoYXIqKWRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKVByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilOZXR3b3JrQWRkcik7CgogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKU9wdGlvbnMpOwogICAgfQogICAgKmRhdGErKyA9ICddJzsKICB9CiAgKmRhdGEgPSAwOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VXKCBMUFdTVFIgT2JqVXVpZCwgTFBXU1RSIFByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIE5ldHdvcmtBZGRyLCBMUFdTVFIgRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIE9wdGlvbnMsIExQV1NUUiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQV1NUUiBkYXRhOwoKICBUUkFDRSgiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgIGRlYnVnc3RyX3coIE9ialV1aWQgKSwgZGVidWdzdHJfdyggUHJvdHNlcSApLAogICAgICAgZGVidWdzdHJfdyggTmV0d29ya0FkZHIgKSwgZGVidWdzdHJfdyggRW5kcG9pbnQgKSwKICAgICAgIGRlYnVnc3RyX3coIE9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyk7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSBsZW4gKz0gc3RybGVuVyhPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW5XKFByb3RzZXEpICsgMTsKICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSBsZW4gKz0gc3RybGVuVyhOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgbGVuICs9IHN0cmxlblcoRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlblcoT3B0aW9ucykgKyAyOwoKICBkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpKTsKICAqU3RyaW5nQmluZGluZyA9IGRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBQcm90c2VxKTsKICAgICpkYXRhKysgPSAnOic7CiAgfQogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE5ldHdvcmtBZGRyKTsKICB9CiAgaWYgKChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHx8CiAgICAgIChPcHRpb25zICYmICpPcHRpb25zKSkgewogICAgKmRhdGErKyA9ICdbJzsKICAgIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgRW5kcG9pbnQpOwogICAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgKmRhdGErKyA9ICcsJzsKICAgIH0KICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE9wdGlvbnMpOwogICAgfQogICAgKmRhdGErKyA9ICddJzsKICB9CiAgKmRhdGEgPSAwOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ1BhcnNlQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nUGFyc2VBKCB1bnNpZ25lZCBjaGFyICpTdHJpbmdCaW5kaW5nLCB1bnNpZ25lZCBjaGFyICoqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqKlByb3RzZXEsIHVuc2lnbmVkIGNoYXIgKipOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqKkVuZHBvaW50LCB1bnNpZ25lZCBjaGFyICoqT3B0aW9ucykKewogIENIQVIgKmRhdGEsICpuZXh0OwogIHN0YXRpYyBjb25zdCBjaGFyIGVwX29wdFtdID0gImVuZHBvaW50PSI7CgogIFRSQUNFKCIoJXMsJXAsJXAsJXAsJXAsJXApXG4iLCBkZWJ1Z3N0cl9hKChjaGFyKilTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSAoY2hhciopIFN0cmluZ0JpbmRpbmc7CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ0AnKTsKICBpZiAobmV4dCkgewogICAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gKHVuc2lnbmVkIGNoYXIqKVJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnOicpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICdbJyk7CiAgaWYgKG5leHQpIHsKICAgIENIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gKHVuc2lnbmVkIGNoYXIqKVJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogICAgY2xvc2UgPSBzdHJjaHIoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHIoZGF0YSwgJywnKTsKICAgICAgaWYgKCFuZXh0IHx8IG5leHQgPiBjbG9zZSkgbmV4dCA9IGNsb3NlOwogICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgIG9wdCA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICAgIGRhdGEgPSBuZXh0KzE7CgogICAgICAvKiBwYXJzZSBvcHRpb24gKi8KICAgICAgbmV4dCA9IHN0cmNocihvcHQsICc9Jyk7CiAgICAgIGlmICghbmV4dCkgewogICAgICAgIC8qIG5vdCBhbiBvcHRpb24sIG11c3QgYmUgYW4gZW5kcG9pbnQgKi8KICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgKkVuZHBvaW50ID0gKHVuc2lnbmVkIGNoYXIqKSBvcHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXAob3B0LCBlcF9vcHQsIHN0cmxlbihlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAgICpFbmRwb2ludCA9ICh1bnNpZ25lZCBjaGFyKikgUlBDUlQ0X3N0cmR1cEEobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9ICh1bnNpZ25lZCBjaGFyKikgUlBDUlQ0X3N0cmNvbmNhdEEoIChjaGFyKikqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICAgIH0gZWxzZSAKCSAgICAqT3B0aW9ucyA9ICh1bnNpZ25lZCBjaGFyKikgb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfQogIGVsc2UgaWYgKE5ldHdvcmtBZGRyKSAKICAgICpOZXR3b3JrQWRkciA9ICh1bnNpZ25lZCBjaGFyKilSUENSVDRfc3RyZHVwQShkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPYmpVdWlkKTsKICBpZiAoUHJvdHNlcSkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilQcm90c2VxKTsKICBpZiAoTmV0d29ya0FkZHIpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilFbmRwb2ludCk7CiAgaWYgKE9wdGlvbnMpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopT3B0aW9ucyk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfU1RSSU5HX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nUGFyc2VXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoIExQV1NUUiBTdHJpbmdCaW5kaW5nLCBMUFdTVFIgKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiAqUHJvdHNlcSwgTFBXU1RSICpOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSICpFbmRwb2ludCwgTFBXU1RSICpPcHRpb25zKQp7CiAgV0NIQVIgKmRhdGEsICpuZXh0OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBlcF9vcHRbXSA9IHsnZScsJ24nLCdkJywncCcsJ28nLCdpJywnbicsJ3QnLCc9JywwfTsKCiAgVFJBQ0UoIiglcywlcCwlcCwlcCwlcCwlcClcbiIsIGRlYnVnc3RyX3coU3RyaW5nQmluZGluZyksCiAgICAgICBPYmpVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBOVUxMOwogIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IE5VTEw7CiAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBOVUxMOwogIGlmIChFbmRwb2ludCkgKkVuZHBvaW50ID0gTlVMTDsKICBpZiAoT3B0aW9ucykgKk9wdGlvbnMgPSBOVUxMOwoKICBkYXRhID0gU3RyaW5nQmluZGluZzsKCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ0AnKTsKICBpZiAobmV4dCkgewogICAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnOicpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICdbJyk7CiAgaWYgKG5leHQpIHsKICAgIFdDSEFSICpjbG9zZSwgKm9wdDsKCiAgICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogICAgY2xvc2UgPSBzdHJjaHJXKGRhdGEsICddJyk7CiAgICBpZiAoIWNsb3NlKSBnb3RvIGZhaWw7CgogICAgLyogdG9rZW5pemUgb3B0aW9ucyAqLwogICAgd2hpbGUgKGRhdGEgPCBjbG9zZSkgewogICAgICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnLCcpOwogICAgICBpZiAoIW5leHQgfHwgbmV4dCA+IGNsb3NlKSBuZXh0ID0gY2xvc2U7CiAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgb3B0ID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgICAgZGF0YSA9IG5leHQrMTsKCiAgICAgIC8qIHBhcnNlIG9wdGlvbiAqLwogICAgICBuZXh0ID0gc3RyY2hyVyhvcHQsICc9Jyk7CiAgICAgIGlmICghbmV4dCkgewogICAgICAgIC8qIG5vdCBhbiBvcHRpb24sIG11c3QgYmUgYW4gZW5kcG9pbnQgKi8KICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgKkVuZHBvaW50ID0gb3B0OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJuY21wVyhvcHQsIGVwX29wdCwgc3RybGVuVyhlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAgICpFbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXKG5leHQrMSk7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiBuZXR3b3JrIG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpPcHRpb25zKSB7CiAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgICAgICAgKk9wdGlvbnMgPSBSUENSVDRfc3RyY29uY2F0VygqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICAgIH0gZWxzZSAKCSAgICAqT3B0aW9ucyA9IG9wdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gY2xvc2UrMTsKICAgIGlmICgqZGF0YSkgZ290byBmYWlsOwogIH0gZWxzZSBpZiAoTmV0d29ya0FkZHIpIAogICAgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFcoZGF0YSk7CgogIHJldHVybiBSUENfU19PSzsKCmZhaWw6CiAgaWYgKE9ialV1aWQpIFJwY1N0cmluZ0ZyZWVXKE9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlVyhQcm90c2VxKTsKICBpZiAoTmV0d29ya0FkZHIpIFJwY1N0cmluZ0ZyZWVXKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQpIFJwY1N0cmluZ0ZyZWVXKEVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZVcoT3B0aW9ucyk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfU1RSSU5HX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJlZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJlZSggUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFRSQUNFKCIoJXApID0gJXBcbiIsIEJpbmRpbmcsICpCaW5kaW5nKTsKICBzdGF0dXMgPSBSUENSVDRfRGVzdHJveUJpbmRpbmcoKkJpbmRpbmcpOwogIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spICpCaW5kaW5nID0gMDsKICByZXR1cm4gc3RhdHVzOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVmVjdG9yRnJlZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVmVjdG9yRnJlZSggUlBDX0JJTkRJTkdfVkVDVE9SKiogQmluZGluZ1ZlY3RvciApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICB1bnNpZ25lZCBsb25nIGM7CgogIFRSQUNFKCIoJXApXG4iLCBCaW5kaW5nVmVjdG9yKTsKICBmb3IgKGM9MDsgYzwoKkJpbmRpbmdWZWN0b3IpLT5Db3VudDsgYysrKSB7CiAgICBzdGF0dXMgPSBScGNCaW5kaW5nRnJlZSgmKCpCaW5kaW5nVmVjdG9yKS0+QmluZGluZ0hbY10pOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCAqQmluZGluZ1ZlY3Rvcik7CiAgKkJpbmRpbmdWZWN0b3IgPSBOVUxMOwogIHJldHVybiBSUENfU19PSzsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0lucU9iamVjdCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nSW5xT2JqZWN0KCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCApCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCIoJXAsJXApID0gJXNcbiIsIEJpbmRpbmcsIE9iamVjdFV1aWQsIGRlYnVnc3RyX2d1aWQoJmJpbmQtPk9iamVjdFV1aWQpKTsKICBtZW1jcHkoT2JqZWN0VXVpZCwgJmJpbmQtPk9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0T2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdTZXRPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2d1aWQoT2JqZWN0VXVpZCkpOwogIGlmIChiaW5kLT5zZXJ2ZXIpIHJldHVybiBSUENfU19XUk9OR19LSU5EX09GX0JJTkRJTkc7CiAgcmV0dXJuIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KEJpbmRpbmcsIE9iamVjdFV1aWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBKCB1bnNpZ25lZCBjaGFyICpTdHJpbmdCaW5kaW5nLCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IE5VTEw7CiAgdW5zaWduZWQgY2hhciAqT2JqZWN0VXVpZCwgKlByb3RzZXEsICpOZXR3b3JrQWRkciwgKkVuZHBvaW50LCAqT3B0aW9uczsKICBVVUlEIFV1aWQ7CgogIFRSQUNFKCIoJXMsJXApXG4iLCBkZWJ1Z3N0cl9hKChjaGFyKilTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nQShPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ0EoJmJpbmQsIEZBTFNFLCAoY2hhciopUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoYmluZCwgKGNoYXIqKU5ldHdvcmtBZGRyLCAoY2hhciopRW5kcG9pbnQsIChjaGFyKilPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykgCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlIAogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKCBMUFdTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIExQV1NUUiBPYmplY3RVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnM7CiAgVVVJRCBVdWlkOwoKICBUUkFDRSgiKCVzLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nVyhPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ1coJmJpbmQsIEZBTFNFLCBQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhiaW5kLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlVygmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZVcoJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlVygmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVXKCZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlVygmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgdW5zaWduZWQgY2hhcioqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIExQU1RSIE9iamVjdFV1aWQ7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKCiAgcmV0ID0gVXVpZFRvU3RyaW5nQSgmYmluZC0+T2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKikmT2JqZWN0VXVpZCk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKCh1bnNpZ25lZCBjaGFyKikgT2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKWJpbmQtPlByb3RzZXEsICh1bnNpZ25lZCBjaGFyKikgYmluZC0+TmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBjaGFyKikgYmluZC0+RW5kcG9pbnQsIE5VTEwsIFN0cmluZ0JpbmRpbmcpOwoKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgcmV0dXJuIHJldDsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1coIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBzaG9ydCoqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgdW5zaWduZWQgY2hhciAqc3RyID0gTlVMTDsKICBUUkFDRSgiKCVwLCVwKVxuIiwgQmluZGluZywgU3RyaW5nQmluZGluZyk7CiAgcmV0ID0gUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ0EoQmluZGluZywgJnN0cik7CiAgKlN0cmluZ0JpbmRpbmcgPSBSUENSVDRfc3RyZHVwQXRvVygoY2hhciopc3RyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZzdHIpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY0JpbmRpbmdTZXRBc3luYyAoUlBDUlQ0LkApCiAqIE5PVEVTCiAqICBFeGlzdHMgaW4gd2luOXggYW5kIHdpbk5ULCBidXQgd2l0aCBkaWZmZXJlbnQgbnVtYmVyIG9mIGFyZ3VtZW50cwogKiAgKDl4IHZlcnNpb24gaGFzIDMgYXJndW1lbnRzLCBOVCBoYXMgMikuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0JpbmRpbmdTZXRBc3luYyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19CTE9DS0lOR19GTiBCbG9ja2luZ0ZuKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSggIiglcCwlcCk6IHN0dWJcbiIsIEJpbmRpbmcsIEJsb2NraW5nRm4gKTsKCiAgYmluZC0+QmxvY2tpbmdGbiA9IEJsb2NraW5nRm47CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY05ldHdvcmtJc1Byb3RzZXFWYWxpZEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkQSh1bnNpZ25lZCBjaGFyICpwcm90c2VxKSB7CiAgVU5JQ09ERV9TVFJJTkcgcHJvdHNlcVc7CgogIGlmICghcHJvdHNlcSkgcmV0dXJuIFJQQ19TX0lOVkFMSURfUlBDX1BST1RTRVE7IC8qID8gKi8KICAKICBpZiAoUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooJnByb3RzZXFXLCAoY2hhciopcHJvdHNlcSkpIHsKICAgIFJQQ19TVEFUVVMgcmV0ID0gUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhwcm90c2VxVy5CdWZmZXIpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoJnByb3RzZXFXKTsKICAgIHJldHVybiByZXQ7CiAgfSBlbHNlIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyAoUlBDUlQ0LkApCiAqIAogKiBDaGVja3MgaWYgdGhlIGdpdmVuIHByb3RvY29sIHNlcXVlbmNlIGlzIGtub3duIGJ5IHRoZSBSUEMgc3lzdGVtLgogKiBJZiBpdCBpcywgcmV0dXJucyBSUENfU19PSywgb3RoZXJ3aXNlIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRC4KICoKICogV2UgY3VycmVudGx5IHN1cHBvcnQ6CiAqICAgbmNhbHJwYyAgIGxvY2FsLW9ubHkgcnBjIG92ZXIgTFBDIChMUEMgaXMgbm90IHJlYWxseSB1c2VkKQogKiAgIG5jYWNuX25wICBycGMgb3ZlciBuYW1lZCBwaXBlcwogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhMUFdTVFIgcHJvdHNlcSkgewogIHN0YXRpYyBjb25zdCBXQ0hBUiBwcm90c2Vxc1dbXVsxNV0gPSB7IAogICAgeyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfSwKICAgIHsnbicsJ2MnLCdhJywnYycsJ24nLCdfJywnbicsJ3AnLDB9CiAgfTsKICBzdGF0aWMgY29uc3QgaW50IGNvdW50ID0gc2l6ZW9mKHByb3RzZXFzVykgLyBzaXplb2YocHJvdHNlcXNXWzBdKTsKICBpbnQgaTsKCiAgaWYgKCFwcm90c2VxKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsgLyogPyAqLwoKICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogICAgaWYgKCFzdHJjbXBXKHByb3RzZXEsIHByb3RzZXFzV1tpXSkpIHJldHVybiBSUENfU19PSzsKICB9CiAgCiAgRklYTUUoIlVua25vd24gcHJvdHNlcSAlcyAtIHdlIHByb2JhYmx5IG5lZWQgdG8gaW1wbGVtZW50IGl0IG9uZSBkYXlcbiIsIGRlYnVnc3RyX3cocHJvdHNlcSkpOwogIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNJbXBlcnNvbmF0ZUNsaWVudCAoUlBDUlQ0LkApCiAqCiAqIEltcGVyc29uYXRlcyB0aGUgY2xpZW50IGNvbm5lY3RlZCB2aWEgYSBiaW5kaW5nIGhhbmRsZSBzbyB0aGF0IHNlY3VyaXR5CiAqIGNoZWNrcyBhcmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgY2xpZW50LgogKgogKiBQQVJBTVMKICogIEJpbmRpbmdIYW5kbGUgW0ldIEhhbmRsZSB0byB0aGUgYmluZGluZyB0byB0aGUgY2xpZW50LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUFNfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TVEFUVVMgdmFsdWUuCiAqCiAqIE5PVEVTCiAqCiAqIElmIEJpbmRpbmdIYW5kbGUgaXMgTlVMTCB0aGVuIHRoZSBmdW5jdGlvbiBpbXBlcnNvbmF0ZXMgdGhlIGNsaWVudAogKiBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIG9mIHRoZSBjdXJyZW50IHRocmVhZC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0ltcGVyc29uYXRlQ2xpZW50KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlKQp7CiAgICBGSVhNRSgiKCVwKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNSZXZlcnRUb1NlbGZFeCAoUlBDUlQ0LkApCiAqCiAqIFN0b3BzIGltcGVyc29uYXRpbmcgdGhlIGNsaWVudCBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIHNvIHRoYXQgc2VjdXJpdHkKICogY2hlY2tzIGFyZSBubyBsb25nZXIgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgY2xpZW50LgogKgogKiBQQVJBTVMKICogIEJpbmRpbmdIYW5kbGUgW0ldIEhhbmRsZSB0byB0aGUgYmluZGluZyB0byB0aGUgY2xpZW50LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUFNfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TVEFUVVMgdmFsdWUuCiAqCiAqIE5PVEVTCiAqCiAqIElmIEJpbmRpbmdIYW5kbGUgaXMgTlVMTCB0aGVuIHRoZSBmdW5jdGlvbiBzdG9wcyBpbXBlcnNvbmF0aW5nIHRoZSBjbGllbnQKICogY29ubmVjdGVkIHRvIHRoZSBiaW5kaW5nIGhhbmRsZSBvZiB0aGUgY3VycmVudCB0aHJlYWQuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNSZXZlcnRUb1NlbGZFeChSUENfQklORElOR19IQU5ETEUgQmluZGluZ0hhbmRsZSkKewogICAgRklYTUUoIiglcCk6IHN0dWJcbiIsIEJpbmRpbmdIYW5kbGUpOwogICAgcmV0dXJuIFJQQ19TX09LOwp9Cg==