LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBpZiAoc3JjKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSwgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LCBMUFNUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIE5ld0Nvbm5lY3Rpb24gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb24pKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwogIE5ld0Nvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUgPSBSUENfTUFYX1BBQ0tFVF9TSVpFOwoKICBUUkFDRSgiY29ubmVjdGlvbjogJXBcbiIsIE5ld0Nvbm5lY3Rpb24pOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihDb25uZWN0aW9uKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPlByb3RzZXEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIENvbm5lY3Rpb24pOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoIUNvbm5lY3Rpb24tPmNvbm4pIHsKICAgIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpIHsgLyogc2VydmVyICovCiAgICAgIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgICAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICAgICAgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhbHJwYyIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQUk9GSUxFX1NFUlZFUiB8IFBJUEVfQUNDRVNTX0RVUExFWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSVBFX1RZUEVfTUVTU0FHRSB8IFBJUEVfUkVBRE1PREVfTUVTU0FHRSwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsIFJQQ19NQVhfUEFDS0VUX1NJWkUsIDUwMDAsIE5VTEwpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICBtZW1zZXQoJkNvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKENvbm5lY3Rpb24tPm92bCkpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShDb25uZWN0aW9uLT5jb25uLCAmQ29ubmVjdGlvbi0+b3ZsKSkgewogICAgICAgICAgV0FSTigiQ291bGRuJ3QgQ29ubmVjdE5hbWVkUGlwZSAoZXJyb3Igd2FzICVsZClcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICAgIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkgewogICAgICAgICAgICBTZXRFdmVudChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgICAgICAgfSBlbHNlIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JT19QRU5ESU5HKSB7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgICAgIGVsc2UgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhY25fbnAiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC4iOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgibGlzdGVuaW5nIG9uICVzXG4iLCBwbmFtZSk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IENyZWF0ZU5hbWVkUGlwZUEocG5hbWUsIFBST0ZJTEVfU0VSVkVSIHwgUElQRV9BQ0NFU1NfRFVQTEVYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9NRVNTQUdFIHwgUElQRV9SRUFETU9ERV9NRVNTQUdFIHwgUElQRV9XQUlULCBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwgUlBDX01BWF9QQUNLRVRfU0laRSwgNTAwMCwgTlVMTCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYgKCFDb25uZWN0TmFtZWRQaXBlKENvbm5lY3Rpb24tPmNvbm4sICZDb25uZWN0aW9uLT5vdmwpKSB7CiAgICAgICAgICBXQVJOKCJDb3VsZG4ndCBDb25uZWN0TmFtZWRQaXBlIChlcnJvciB3YXMgJWxkKVxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgaWYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX1BJUEVfQ09OTkVDVEVEKSB7CiAgICAgICAgICAgIFNldEV2ZW50KENvbm5lY3Rpb24tPm92bC5oRXZlbnQpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBFUlIoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICAgICAgfQogICAgfQogICAgZWxzZSB7IC8qIGNsaWVudCAqLwogICAgICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICAgICAqIGJ1dCB3ZSdsbCBpbXBsZW1lbnQgaXQgd2l0aCBuYW1lZCBwaXBlcyBmb3Igbm93ICovCiAgICAgIGlmIChzdHJjbXAoQ29ubmVjdGlvbi0+UHJvdHNlcSwgIm5jYWxycGMiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwogICAgICAgIERXT1JEIGR3TW9kZTsKCiAgICAgICAgcG5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgICAgICAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogICAgICAgIFRSQUNFKCJjb25uZWN0aW5nIHRvICVzXG4iLCBwbmFtZSk7CiAgICAgICAgd2hpbGUgKFRSVUUpIHsKICAgICAgICAgIGlmIChXYWl0TmFtZWRQaXBlQShwbmFtZSwgTk1QV0FJVF9XQUlUX0ZPUkVWRVIpKSB7CiAgICAgICAgICAgIGNvbm4gPSBDcmVhdGVGaWxlQShwbmFtZSwgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICAgICAgICAgICAgaWYgKGNvbm4gIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpIGNvbnRpbnVlOwogICAgICAgICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1RPT19CVVNZOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAgIFRSQUNFKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgLyogcGlwZSBpcyBjb25uZWN0ZWQ7IGNoYW5nZSB0byBtZXNzYWdlLXJlYWQgbW9kZS4gKi8KICAgICAgICBkd01vZGUgPSBQSVBFX1JFQURNT0RFX01FU1NBR0U7IAogICAgICAgIFNldE5hbWVkUGlwZUhhbmRsZVN0YXRlKGNvbm4sICZkd01vZGUsIE5VTEwsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBjb25uOwogICAgICB9CiAgICAgIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgICAgIGVsc2UgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhY25fbnAiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC4iOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIEhBTkRMRSBjb25uOwogICAgICAgIERXT1JEIGVycjsKICAgICAgICBEV09SRCBkd01vZGU7CgogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwogICAgICAgIGNvbm4gPSBDcmVhdGVGaWxlQShwbmFtZSwgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogICAgICAgIGlmIChjb25uID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgIC8qIHdlIGRvbid0IG5lZWQgdG8gaGFuZGxlIEVSUk9SX1BJUEVfQlVTWSBoZXJlLAogICAgICAgICAgICogdGhlIGRvYyBzYXlzIHRoYXQgaXQgaXMgcmV0dXJuZWQgdG8gdGhlIGFwcCAqLwogICAgICAgICAgVFJBQ0UoImNvbm5lY3Rpb24gZmFpbGVkLCBlcnJvcj0lbHhcbiIsIGVycik7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgICBpZiAoZXJyID09IEVSUk9SX1BJUEVfQlVTWSkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9UT09fQlVTWTsKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgICAgICB9CgogICAgICAgIC8qIHN1Y2Nlc3MgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICAvKiBwaXBlIGlzIGNvbm5lY3RlZDsgY2hhbmdlIHRvIG1lc3NhZ2UtcmVhZCBtb2RlLiAqLwogICAgICAgIGR3TW9kZSA9IFBJUEVfUkVBRE1PREVfTUVTU0FHRTsKICAgICAgICBTZXROYW1lZFBpcGVIYW5kbGVTdGF0ZShjb25uLCAmZHdNb2RlLCBOVUxMLCBOVUxMKTsKICAgICAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgICAgICBDb25uZWN0aW9uLT5jb25uID0gY29ubjsKICAgICAgfSBlbHNlIHsKICAgICAgICBFUlIoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihDb25uZWN0aW9uID09IF4lcClcbiIsIENvbm5lY3Rpb24pOwogIGlmIChDb25uZWN0aW9uLT5jb25uKSB7CiAgICBDYW5jZWxJbyhDb25uZWN0aW9uLT5jb25uKTsKICAgIENsb3NlSGFuZGxlKENvbm5lY3Rpb24tPmNvbm4pOwogICAgQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgfQogIGlmIChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KSB7CiAgICBDbG9zZUhhbmRsZShDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSAwOwogIH0KICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUnBjQ29ubmVjdGlvbiogT2xkQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CiAgUlBDX1NUQVRVUyBlcnIgPSBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgT2xkQ29ubmVjdGlvbi0+c2VydmVyLCBPbGRDb25uZWN0aW9uLT5Qcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2xkQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIE9sZENvbm5lY3Rpb24tPkVuZHBvaW50LCBOVUxMLCBOVUxMKTsKICBpZiAoZXJyID09IFJQQ19TX09LKSB7CiAgICAvKiBiZWNhdXNlIG9mIHRoZSB3YXkgbmFtZWQgcGlwZXMgd29yaywgd2UnbGwgdHJhbnNmZXIgdGhlIGNvbm5lY3RlZCBwaXBlCiAgICAgKiB0byB0aGUgY2hpbGQsIHRoZW4gcmVvcGVuIHRoZSBzZXJ2ZXIgYmluZGluZyB0byBjb250aW51ZSBsaXN0ZW5pbmcgKi8KICAgIE5ld0Nvbm5lY3Rpb24tPmNvbm4gPSBPbGRDb25uZWN0aW9uLT5jb25uOwogICAgTmV3Q29ubmVjdGlvbi0+b3ZsID0gT2xkQ29ubmVjdGlvbi0+b3ZsOwogICAgT2xkQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgICBtZW1zZXQoJk9sZENvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKE9sZENvbm5lY3Rpb24tPm92bCkpOwogICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgUlBDUlQ0X09wZW5Db25uZWN0aW9uKE9sZENvbm5lY3Rpb24pOwogIH0KICByZXR1cm4gZXJyOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9BbGxvY0JpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgTmV3QmluZGluZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjQmluZGluZykpOwogIE5ld0JpbmRpbmctPnJlZnMgPSAxOwogIE5ld0JpbmRpbmctPnNlcnZlciA9IHNlcnZlcjsKCiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NyZWF0ZUJpbmRpbmdBKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nVyhScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQV1NUUiBQcm90c2VxKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgc2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cFd0b0EoUHJvdHNlcSk7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoUnBjQmluZGluZyogQmluZGluZywgTFBTVFIgTmV0d29ya0FkZHIsICBMUFNUUiBFbmRwb2ludCwgIExQU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gXCIlc1wiLCBFbmRQb2ludCA9PSBcIiVzXCIsIE5ldHdvcmtPcHRpb25zID09IFwiJXNcIilcbiIsIEJpbmRpbmcsCiAgIGRlYnVnc3RyX2EoTmV0d29ya0FkZHIpLCBkZWJ1Z3N0cl9hKEVuZHBvaW50KSwgZGVidWdzdHJfYShOZXR3b3JrT3B0aW9ucykpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgQmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShOZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIGlmIChFbmRwb2ludCkgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CiAgfSBlbHNlIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoIiIpOwogIH0KICBpZiAoIUJpbmRpbmctPkVuZHBvaW50KSBFUlIoIm91dCBvZiBtZW1vcnk/XG4iKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdXKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQV1NUUiBOZXR3b3JrQWRkciwgTFBXU1RSIEVuZHBvaW50LCBMUFdTVFIgTmV0d29ya09wdGlvbnMpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBOZXR3b3JrQWRkciA9PSBcIiVzXCIsIEVuZFBvaW50ID09IFwiJXNcIiwgTmV0d29ya09wdGlvbnMgPT0gXCIlc1wiKVxuIiwgQmluZGluZywgCiAgIGRlYnVnc3RyX3coTmV0d29ya0FkZHIpLCBkZWJ1Z3N0cl93KEVuZHBvaW50KSwgZGVidWdzdHJfdyhOZXR3b3JrT3B0aW9ucykpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgQmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwV3RvQShOZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIGlmIChFbmRwb2ludCkgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwV3RvQShFbmRwb2ludCk7CiAgfSBlbHNlIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoIiIpOwogIH0KICBpZiAoIUJpbmRpbmctPkVuZHBvaW50KSBFUlIoIm91dCBvZiBtZW1vcnk/XG4iKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9SZXNvbHZlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFNUUiBFbmRwb2ludCkKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIEVuZFBvaW50ID09IFwiJXNcIlxuIiwgQmluZGluZywgRW5kcG9pbnQpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfU2V0QmluZGluZ09iamVjdChScGNCaW5kaW5nKiBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkKQp7CiAgVFJBQ0UoIigqUnBjQmluZGluZyA9PSBeJXAsIFVVSUQgPT0gJXMpXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9ndWlkKE9iamVjdFV1aWQpKTsgCiAgaWYgKE9iamVjdFV1aWQpIG1lbWNweSgmQmluZGluZy0+T2JqZWN0VXVpZCwgT2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICBlbHNlIFV1aWRDcmVhdGVOaWwoJkJpbmRpbmctPk9iamVjdFV1aWQpOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfTWFrZUJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwogIFRSQUNFKCIoKlJwY0JpbmRpbmcgPT0gXiVwLCBDb25uZWN0aW9uID09IF4lcClcbiIsICpCaW5kaW5nLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgQ29ubmVjdGlvbi0+c2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgTmV3QmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5OZXR3b3JrQWRkcik7CiAgTmV3QmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgTmV3QmluZGluZy0+RnJvbUNvbm4gPSBDb25uZWN0aW9uOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9FeHBvcnRCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNCaW5kaW5nKiBPbGRCaW5kaW5nKQp7CiAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJk9sZEJpbmRpbmctPnJlZnMpOwogICpCaW5kaW5nID0gT2xkQmluZGluZzsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpCnsKICBpZiAoSW50ZXJsb2NrZWREZWNyZW1lbnQoJkJpbmRpbmctPnJlZnMpKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIEJpbmRpbmcpOwogIC8qIEZJWE1FOiByZWxlYXNlIGNvbm5lY3Rpb25zICovCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5CaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIFRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIEludGVyZmFjZUlkKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwoKICAvKiBpZiB3ZSB0cnkgdG8gYmluZCBhIG5ldyBpbnRlcmZhY2UgYW5kIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgb3BlbmVkLAogICAqIGNsb3NlIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gYW5kIGNyZWF0ZSBhIG5ldyB3aXRoIHRoZSBuZXcgYmluZGluZy4gKi8gCiAgaWYgKCFCaW5kaW5nLT5zZXJ2ZXIgJiYgQmluZGluZy0+RnJvbUNvbm4gJiYKICAgICAgbWVtY21wKCZCaW5kaW5nLT5Gcm9tQ29ubi0+QWN0aXZlSW50ZXJmYWNlLCBJbnRlcmZhY2VJZCwKICAgICAgICAgICAgIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSkgewoKICAgIFRSQUNFKCJyZWxlYXNpbmcgcHJlLWV4aXN0aW5nIGNvbm5lY3Rpb25cbiIpOwogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKEJpbmRpbmctPkZyb21Db25uKTsKICAgIEJpbmRpbmctPkZyb21Db25uID0gTlVMTDsKICB9IGVsc2UgewogICAgLyogd2UgYWxyZWFkeSBoYXZlIGFuIGNvbm5lY3Rpb24gd2l0aCBhY2NlcHRhYmxlIGJpbmRpbmcsIHNvIHVzZSBpdCAqLwogICAgaWYgKEJpbmRpbmctPkZyb21Db25uKSB7CiAgICAgICpDb25uZWN0aW9uID0gQmluZGluZy0+RnJvbUNvbm47CiAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0KICB9CiAgCiAgLyogY3JlYXRlIGEgbmV3IGNvbm5lY3Rpb24gKi8KICBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgQmluZGluZy0+c2VydmVyLCBCaW5kaW5nLT5Qcm90c2VxLCBCaW5kaW5nLT5OZXR3b3JrQWRkciwgQmluZGluZy0+RW5kcG9pbnQsIE5VTEwsIEJpbmRpbmcpOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKICBzdGF0dXMgPSBSUENSVDRfT3BlbkNvbm5lY3Rpb24oTmV3Q29ubmVjdGlvbik7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgcmV0dXJuIHN0YXR1czsKICB9CgogIC8qIHdlIG5lZWQgdG8gc2VuZCBhIGJpbmRpbmcgcGFja2V0IGlmIHdlIGFyZSBjbGllbnQuICovCiAgaWYgKCEoKkNvbm5lY3Rpb24pLT5zZXJ2ZXIpIHsKICAgIFJwY1BrdEhkciAqaGRyOwogICAgRFdPUkQgY291bnQ7CiAgICBCWVRFICpyZXNwb25zZTsKICAgIFJwY1BrdEhkciAqcmVzcG9uc2VfaGRyOwoKICAgIFRSQUNFKCJzZW5kaW5nIGJpbmQgcmVxdWVzdCB0byBzZXJ2ZXJcbiIpOwoKICAgIGhkciA9IFJQQ1JUNF9CdWlsZEJpbmRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsIFJQQ19NQVhfUEFDS0VUX1NJWkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVyZmFjZUlkLCBUcmFuc2ZlclN5bnRheCk7CgogICAgc3RhdHVzID0gUlBDUlQ0X1NlbmQoKkNvbm5lY3Rpb24sIGhkciwgTlVMTCwgMCk7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgcmVzcG9uc2UgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgUlBDX01BWF9QQUNLRVRfU0laRSk7CiAgICBpZiAocmVzcG9uc2UgPT0gTlVMTCkgewogICAgICBXQVJOKCJDYW4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGJpbmRpbmcgcmVzcG9uc2VcbiIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICAvKiBnZXQgYSByZXBseSAqLwogICAgaWYgKCFSZWFkRmlsZShOZXdDb25uZWN0aW9uLT5jb25uLCByZXNwb25zZSwgUlBDX01BWF9QQUNLRVRfU0laRSwgJmNvdW50LCBOVUxMKSkgewogICAgICBXQVJOKCJSZWFkRmlsZSBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIGlmIChjb3VudCA8IHNpemVvZihyZXNwb25zZV9oZHItPmNvbW1vbikpIHsKICAgICAgV0FSTigicmVjZWl2ZWQgaW52YWxpZCBoZWFkZXJcbiIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICB9CgogICAgcmVzcG9uc2VfaGRyID0gKFJwY1BrdEhkciopcmVzcG9uc2U7CgogICAgaWYgKHJlc3BvbnNlX2hkci0+Y29tbW9uLnJwY192ZXIgIT0gUlBDX1ZFUl9NQUpPUiB8fAogICAgICAgIHJlc3BvbnNlX2hkci0+Y29tbW9uLnJwY192ZXJfbWlub3IgIT0gUlBDX1ZFUl9NSU5PUiB8fAogICAgICAgIHJlc3BvbnNlX2hkci0+Y29tbW9uLnB0eXBlICE9IFBLVF9CSU5EX0FDSykgewogICAgICBXQVJOKCJpbnZhbGlkIHByb3RvY29sIHZlcnNpb24gb3IgcmVqZWN0aW9uIHBhY2tldFxuIik7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICBpZiAocmVzcG9uc2VfaGRyLT5iaW5kX2Fjay5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFKSB7CiAgICAgIFdBUk4oInNlcnZlciBkb2Vzbid0IGFsbG93IGxhcmdlIGVub3VnaCBwYWNrZXRzXG4iKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcz8gKi8KCiAgICAoKkNvbm5lY3Rpb24pLT5NYXhUcmFuc21pc3Npb25TaXplID0gcmVzcG9uc2VfaGRyLT5iaW5kX2Fjay5tYXhfdHNpemU7CiAgICAoKkNvbm5lY3Rpb24pLT5BY3RpdmVJbnRlcmZhY2UgPSAqSW50ZXJmYWNlSWQ7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmICghQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIGlmIChCaW5kaW5nLT5Gcm9tQ29ubiA9PSBDb25uZWN0aW9uKSByZXR1cm4gUlBDX1NfT0s7CiAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKfQoKLyogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHN0cmluZyBjb21wb3NpbmcgYW5kIHBhcnNpbmcgKi8Kc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5QShMUFNUUiBkYXRhLCBMUENTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5VyhMUFdTVFIgZGF0YSwgTFBDV1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW5XKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyBMUFNUUiBSUENSVDRfc3RyY29uY2F0QShMUFNUUiBkc3QsIExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW4oZHN0KSwgc2xlbiA9IHN0cmxlbihzcmMpOwogIExQU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoQ0hBUikpOwogIGlmICghbmRzdCkKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKzEpOwogIHJldHVybiBuZHN0Owp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJjb25jYXRXKExQV1NUUiBkc3QsIExQQ1dTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuVyhkc3QpLCBzbGVuID0gc3RybGVuVyhzcmMpOwogIExQV1NUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKCFuZHN0KSAKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCAoc2xlbisxKSpzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbmRzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKHVuc2lnbmVkIGNoYXIgKk9ialV1aWQsIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpOZXR3b3JrQWRkciwgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpPcHRpb25zLCB1bnNpZ25lZCBjaGFyKiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQU1RSIGRhdGE7CgogIFRSQUNFKCAiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgICBkZWJ1Z3N0cl9hKCBPYmpVdWlkICksIGRlYnVnc3RyX2EoIFByb3RzZXEgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCBOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl9hKCBFbmRwb2ludCApLAogICAgICAgIGRlYnVnc3RyX2EoIE9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyApOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlbihPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW4oUHJvdHNlcSkgKyAxOwogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIGxlbiArPSBzdHJsZW4oTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW4oRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlbihPcHRpb25zKSArIDI7CgogIGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICAqU3RyaW5nQmluZGluZyA9IGRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBQcm90c2VxKTsKICAgICpkYXRhKysgPSAnOic7CiAgfQogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpCiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBOZXR3b3JrQWRkcik7CgogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIEVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBPcHRpb25zKTsKICAgIH0KICAgICpkYXRhKysgPSAnXSc7CiAgfQogICpkYXRhID0gMDsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVyggTFBXU1RSIE9ialV1aWQsIExQV1NUUiBQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBOZXR3b3JrQWRkciwgTFBXU1RSIEVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBPcHRpb25zLCBMUFdTVFIqIFN0cmluZ0JpbmRpbmcgKQp7CiAgRFdPUkQgbGVuID0gMTsKICBMUFdTVFIgZGF0YTsKCiAgVFJBQ0UoIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICBkZWJ1Z3N0cl93KCBPYmpVdWlkICksIGRlYnVnc3RyX3coIFByb3RzZXEgKSwKICAgICAgIGRlYnVnc3RyX3coIE5ldHdvcmtBZGRyICksIGRlYnVnc3RyX3coIEVuZHBvaW50ICksCiAgICAgICBkZWJ1Z3N0cl93KCBPcHRpb25zICksIFN0cmluZ0JpbmRpbmcpOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlblcoT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuVyhQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlblcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW5XKEVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW5XKE9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgKlN0cmluZ0JpbmRpbmcgPSBkYXRhOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBOZXR3b3JrQWRkcik7CiAgfQogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIEVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBPcHRpb25zKTsKICAgIH0KICAgICpkYXRhKysgPSAnXSc7CiAgfQogICpkYXRhID0gMDsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlQSggdW5zaWduZWQgY2hhciAqU3RyaW5nQmluZGluZywgdW5zaWduZWQgY2hhciAqKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKipQcm90c2VxLCB1bnNpZ25lZCBjaGFyICoqTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKipFbmRwb2ludCwgdW5zaWduZWQgY2hhciAqKk9wdGlvbnMpCnsKICBDSEFSICpkYXRhLCAqbmV4dDsKICBzdGF0aWMgY29uc3QgY2hhciBlcF9vcHRbXSA9ICJlbmRwb2ludD0iOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfYShTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICdAJyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnOicpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICAgIGNsb3NlID0gc3RyY2hyKGRhdGEsICddJyk7CiAgICBpZiAoIWNsb3NlKSBnb3RvIGZhaWw7CgogICAgLyogdG9rZW5pemUgb3B0aW9ucyAqLwogICAgd2hpbGUgKGRhdGEgPCBjbG9zZSkgewogICAgICBuZXh0ID0gc3RyY2hyKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHIob3B0LCAnPScpOwogICAgICBpZiAoIW5leHQpIHsKICAgICAgICAvKiBub3QgYW4gb3B0aW9uLCBtdXN0IGJlIGFuIGVuZHBvaW50ICovCiAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICpFbmRwb2ludCA9IG9wdDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RybmNtcChvcHQsIGVwX29wdCwgc3RybGVuKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9IFJQQ1JUNF9zdHJjb25jYXRBKCpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfQogIGVsc2UgaWYgKE5ldHdvcmtBZGRyKSAKICAgICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKVByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKUVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyggTFBXU1RSIFN0cmluZ0JpbmRpbmcsIExQV1NUUiAqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSICpQcm90c2VxLCBMUFdTVFIgKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgKkVuZHBvaW50LCBMUFdTVFIgKk9wdGlvbnMpCnsKICBXQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IFdDSEFSIGVwX29wdFtdID0geydlJywnbicsJ2QnLCdwJywnbycsJ2knLCduJywndCcsJz0nLDB9OwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgV0NIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNoclcoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHJXKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHJXKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAqRW5kcG9pbnQgPSBvcHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXBXKG9wdCwgZXBfb3B0LCBzdHJsZW5XKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFcobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9IFJQQ1JUNF9zdHJjb25jYXRXKCpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfSBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwVyhkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZVcoT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVXKFByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZVcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZVcoRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlVyhPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcmVlKCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgVFJBQ0UoIiglcCkgPSAlcFxuIiwgQmluZGluZywgKkJpbmRpbmcpOwogIHN0YXR1cyA9IFJQQ1JUNF9EZXN0cm95QmluZGluZygqQmluZGluZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykgKkJpbmRpbmcgPSAwOwogIHJldHVybiBzdGF0dXM7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdWZWN0b3JGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdWZWN0b3JGcmVlKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIHVuc2lnbmVkIGxvbmcgYzsKCiAgVFJBQ0UoIiglcClcbiIsIEJpbmRpbmdWZWN0b3IpOwogIGZvciAoYz0wOyBjPCgqQmluZGluZ1ZlY3RvciktPkNvdW50OyBjKyspIHsKICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdGcmVlKCYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjXSk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsICpCaW5kaW5nVmVjdG9yKTsKICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xT2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdJbnFPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcCkgPSAlc1xuIiwgQmluZGluZywgT2JqZWN0VXVpZCwgZGVidWdzdHJfZ3VpZCgmYmluZC0+T2JqZWN0VXVpZCkpOwogIG1lbWNweShPYmplY3RVdWlkLCAmYmluZC0+T2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdTZXRPYmplY3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1NldE9iamVjdCggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7CiAgaWYgKGJpbmQtPnNlcnZlcikgcmV0dXJuIFJQQ19TX1dST05HX0tJTkRfT0ZfQklORElORzsKICByZXR1cm4gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoQmluZGluZywgT2JqZWN0VXVpZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ0EoIHVuc2lnbmVkIGNoYXIgKlN0cmluZ0JpbmRpbmcsIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gTlVMTDsKICB1bnNpZ25lZCBjaGFyICpPYmplY3RVdWlkLCAqUHJvdHNlcSwgKk5ldHdvcmtBZGRyLCAqRW5kcG9pbnQsICpPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX2EoU3RyaW5nQmluZGluZyksIEJpbmRpbmcpOwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nUGFyc2VBKFN0cmluZ0JpbmRpbmcsICZPYmplY3RVdWlkLCAmUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ldHdvcmtBZGRyLCAmRW5kcG9pbnQsICZPcHRpb25zKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBVdWlkRnJvbVN0cmluZ0EoT2JqZWN0VXVpZCwgJlV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NyZWF0ZUJpbmRpbmdBKCZiaW5kLCBGQUxTRSwgUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoYmluZCwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykgCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlIAogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKCBMUFdTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIExQV1NUUiBPYmplY3RVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnM7CiAgVVVJRCBVdWlkOwoKICBUUkFDRSgiKCVzLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nVyhPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ1coJmJpbmQsIEZBTFNFLCBQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhiaW5kLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlVygmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZVcoJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlVygmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVXKCZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlVygmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgdW5zaWduZWQgY2hhcioqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIExQU1RSIE9iamVjdFV1aWQ7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKCiAgcmV0ID0gVXVpZFRvU3RyaW5nQSgmYmluZC0+T2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKikmT2JqZWN0VXVpZCk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKE9iamVjdFV1aWQsIGJpbmQtPlByb3RzZXEsIGJpbmQtPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5kLT5FbmRwb2ludCwgTlVMTCwgU3RyaW5nQmluZGluZyk7CgogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIHVuc2lnbmVkIHNob3J0KiogU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICB1bnNpZ25lZCBjaGFyICpzdHIgPSBOVUxMOwogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKICByZXQgPSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQShCaW5kaW5nLCAmc3RyKTsKICAqU3RyaW5nQmluZGluZyA9IFJQQ1JUNF9zdHJkdXBBdG9XKHN0cik7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmc3RyKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNCaW5kaW5nU2V0QXN5bmMgKFJQQ1JUNC5AKQogKiBOT1RFUwogKiAgRXhpc3RzIGluIHdpbjl4IGFuZCB3aW5OVCwgYnV0IHdpdGggZGlmZmVyZW50IG51bWJlciBvZiBhcmd1bWVudHMKICogICg5eCB2ZXJzaW9uIGhhcyAzIGFyZ3VtZW50cywgTlQgaGFzIDIpLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNCaW5kaW5nU2V0QXN5bmMoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQkxPQ0tJTkdfRk4gQmxvY2tpbmdGbikKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoICIoJXAsJXApOiBzdHViXG4iLCBCaW5kaW5nLCBCbG9ja2luZ0ZuICk7CgogIGJpbmQtPkJsb2NraW5nRm4gPSBCbG9ja2luZ0ZuOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNOZXR3b3JrSXNQcm90c2VxVmFsaWRBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY05ldHdvcmtJc1Byb3RzZXFWYWxpZEEodW5zaWduZWQgY2hhciAqcHJvdHNlcSkgewogIFVOSUNPREVfU1RSSU5HIHByb3RzZXFXOwoKICBpZiAoIXByb3RzZXEpIHJldHVybiBSUENfU19JTlZBTElEX1JQQ19QUk9UU0VROyAvKiA/ICovCiAgCiAgaWYgKFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCZwcm90c2VxVywgcHJvdHNlcSkpIHsKICAgIFJQQ19TVEFUVVMgcmV0ID0gUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhwcm90c2VxVy5CdWZmZXIpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoJnByb3RzZXFXKTsKICAgIHJldHVybiByZXQ7CiAgfSBlbHNlIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyAoUlBDUlQ0LkApCiAqIAogKiBDaGVja3MgaWYgdGhlIGdpdmVuIHByb3RvY29sIHNlcXVlbmNlIGlzIGtub3duIGJ5IHRoZSBSUEMgc3lzdGVtLgogKiBJZiBpdCBpcywgcmV0dXJucyBSUENfU19PSywgb3RoZXJ3aXNlIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRC4KICoKICogV2UgY3VycmVudGx5IHN1cHBvcnQ6CiAqICAgbmNhbHJwYyAgIGxvY2FsLW9ubHkgcnBjIG92ZXIgTFBDIChMUEMgaXMgbm90IHJlYWxseSB1c2VkKQogKiAgIG5jYWNuX25wICBycGMgb3ZlciBuYW1lZCBwaXBlcwogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhMUFdTVFIgcHJvdHNlcSkgewogIHN0YXRpYyBjb25zdCBXQ0hBUiBwcm90c2Vxc1dbXVsxNV0gPSB7IAogICAgeyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfSwKICAgIHsnbicsJ2MnLCdhJywnYycsJ24nLCdfJywnbicsJ3AnLDB9CiAgfTsKICBzdGF0aWMgY29uc3QgaW50IGNvdW50ID0gc2l6ZW9mKHByb3RzZXFzVykgLyBzaXplb2YocHJvdHNlcXNXWzBdKTsKICBpbnQgaTsKCiAgaWYgKCFwcm90c2VxKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsgLyogPyAqLwoKICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogICAgaWYgKCFzdHJjbXBXKHByb3RzZXEsIHByb3RzZXFzV1tpXSkpIHJldHVybiBSUENfU19PSzsKICB9CiAgCiAgRklYTUUoIlVua25vd24gcHJvdHNlcSAlcyAtIHdlIHByb2JhYmx5IG5lZWQgdG8gaW1wbGVtZW50IGl0IG9uZSBkYXlcbiIsIGRlYnVnc3RyX3cocHJvdHNlcSkpOwogIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7Cn0K