LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSwgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LCBMUFNUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIE5ld0Nvbm5lY3Rpb24gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb24pKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwogIE5ld0Nvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUgPSBSUENfTUFYX1BBQ0tFVF9TSVpFOwoKICBUUkFDRSgiY29ubmVjdGlvbjogJXBcbiIsIE5ld0Nvbm5lY3Rpb24pOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihDb25uZWN0aW9uKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPlByb3RzZXEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIENvbm5lY3Rpb24pOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoIUNvbm5lY3Rpb24tPmNvbm4pIHsKICAgIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpIHsgLyogc2VydmVyICovCiAgICAgIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgICAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICAgICAgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhbHJwYyIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQUk9GSUxFX1NFUlZFUiB8IFBJUEVfQUNDRVNTX0RVUExFWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSVBFX1RZUEVfTUVTU0FHRSB8IFBJUEVfUkVBRE1PREVfTUVTU0FHRSwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsIFJQQ19NQVhfUEFDS0VUX1NJWkUsIDUwMDAsIE5VTEwpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICBtZW1zZXQoJkNvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKENvbm5lY3Rpb24tPm92bCkpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShDb25uZWN0aW9uLT5jb25uLCAmQ29ubmVjdGlvbi0+b3ZsKSkgewogICAgICAgICAgV0FSTigiQ291bGRuJ3QgQ29ubmVjdE5hbWVkUGlwZSAoZXJyb3Igd2FzICVsZClcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICAgIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkgewogICAgICAgICAgICBTZXRFdmVudChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgICAgICAgfSBlbHNlIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JT19QRU5ESU5HKSB7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgICAgIGVsc2UgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhY25fbnAiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC4iOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgibGlzdGVuaW5nIG9uICVzXG4iLCBwbmFtZSk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IENyZWF0ZU5hbWVkUGlwZUEocG5hbWUsIFBST0ZJTEVfU0VSVkVSIHwgUElQRV9BQ0NFU1NfRFVQTEVYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9NRVNTQUdFIHwgUElQRV9SRUFETU9ERV9NRVNTQUdFIHwgUElQRV9XQUlULCBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwgUlBDX01BWF9QQUNLRVRfU0laRSwgNTAwMCwgTlVMTCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYgKCFDb25uZWN0TmFtZWRQaXBlKENvbm5lY3Rpb24tPmNvbm4sICZDb25uZWN0aW9uLT5vdmwpKSB7CiAgICAgICAgICBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfUElQRV9DT05ORUNURUQpIHsKICAgICAgICAgICAgU2V0RXZlbnQoQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0gZWxzZSBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU9fUEVORElORykgewogICAgICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICAgICAgICB9CiAgICAgICAgICBXQVJOKCJDb3VsZG4ndCBDb25uZWN0TmFtZWRQaXBlIChlcnJvciB3YXMgJWxkKVxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgRVJSKCJwcm90c2VxICVzIG5vdCBzdXBwb3J0ZWRcbiIsIENvbm5lY3Rpb24tPlByb3RzZXEpOwogICAgICAgIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgeyAvKiBjbGllbnQgKi8KICAgICAgLyogcHJvdHNlcT1uY2FscnBjOiBzdXBwb3NlZCB0byB1c2UgTlQgTFBDIHBvcnRzLAogICAgICAgKiBidXQgd2UnbGwgaW1wbGVtZW50IGl0IHdpdGggbmFtZWQgcGlwZXMgZm9yIG5vdyAqLwogICAgICBpZiAoc3RyY21wKENvbm5lY3Rpb24tPlByb3RzZXEsICJuY2FscnBjIikgPT0gMCkgewogICAgICAgIHN0YXRpYyBMUENTVFIgcHJlZml4ID0gIlxcXFwuXFxwaXBlXFxscnBjXFwiOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIEhBTkRMRSBjb25uOwogICAgICAgIERXT1JEIGVycjsKICAgICAgICBEV09SRCBkd01vZGU7CgogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwogICAgICAgIHdoaWxlIChUUlVFKSB7CiAgICAgICAgICBpZiAoV2FpdE5hbWVkUGlwZUEocG5hbWUsIE5NUFdBSVRfV0FJVF9GT1JFVkVSKSkgewogICAgICAgICAgICBjb25uID0gQ3JlYXRlRmlsZUEocG5hbWUsIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1BFTl9FWElTVElORywgMCwgMCk7CiAgICAgICAgICAgIGlmIChjb25uICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSBicmVhazsKICAgICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAgIGlmIChlcnIgPT0gRVJST1JfUElQRV9CVVNZKSBjb250aW51ZTsKICAgICAgICAgICAgVFJBQ0UoImNvbm5lY3Rpb24gZmFpbGVkLCBlcnJvcj0lbHhcbiIsIGVycik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9UT09fQlVTWTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgICAgICAgICBXQVJOKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgLyogcGlwZSBpcyBjb25uZWN0ZWQ7IGNoYW5nZSB0byBtZXNzYWdlLXJlYWQgbW9kZS4gKi8KICAgICAgICBkd01vZGUgPSBQSVBFX1JFQURNT0RFX01FU1NBR0U7IAogICAgICAgIFNldE5hbWVkUGlwZUhhbmRsZVN0YXRlKGNvbm4sICZkd01vZGUsIE5VTEwsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBjb25uOwogICAgICB9CiAgICAgIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgICAgIGVsc2UgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhY25fbnAiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC4iOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIEhBTkRMRSBjb25uOwogICAgICAgIERXT1JEIGVycjsKICAgICAgICBEV09SRCBkd01vZGU7CgogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwogICAgICAgIGNvbm4gPSBDcmVhdGVGaWxlQShwbmFtZSwgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogICAgICAgIGlmIChjb25uID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgIC8qIHdlIGRvbid0IG5lZWQgdG8gaGFuZGxlIEVSUk9SX1BJUEVfQlVTWSBoZXJlLAogICAgICAgICAgICogdGhlIGRvYyBzYXlzIHRoYXQgaXQgaXMgcmV0dXJuZWQgdG8gdGhlIGFwcCAqLwogICAgICAgICAgV0FSTigiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICAgIGlmIChlcnIgPT0gRVJST1JfUElQRV9CVVNZKQogICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1RPT19CVVNZOwogICAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogICAgICAgIH0KCiAgICAgICAgLyogc3VjY2VzcyAqLwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICBtZW1zZXQoJkNvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKENvbm5lY3Rpb24tPm92bCkpOwogICAgICAgIC8qIHBpcGUgaXMgY29ubmVjdGVkOyBjaGFuZ2UgdG8gbWVzc2FnZS1yZWFkIG1vZGUuICovCiAgICAgICAgZHdNb2RlID0gUElQRV9SRUFETU9ERV9NRVNTQUdFOwogICAgICAgIFNldE5hbWVkUGlwZUhhbmRsZVN0YXRlKGNvbm4sICZkd01vZGUsIE5VTEwsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBjb25uOwogICAgICB9IGVsc2UgewogICAgICAgIEVSUigicHJvdHNlcSAlcyBub3Qgc3VwcG9ydGVkXG4iLCBDb25uZWN0aW9uLT5Qcm90c2VxKTsKICAgICAgICByZXR1cm4gUlBDX1NfUFJPVFNFUV9OT1RfU1VQUE9SVEVEOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ2xvc2VDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBUUkFDRSgiKENvbm5lY3Rpb24gPT0gXiVwKVxuIiwgQ29ubmVjdGlvbik7CiAgaWYgKENvbm5lY3Rpb24tPmNvbm4pIHsKICAgIENhbmNlbElvKENvbm5lY3Rpb24tPmNvbm4pOwogICAgQ2xvc2VIYW5kbGUoQ29ubmVjdGlvbi0+Y29ubik7CiAgICBDb25uZWN0aW9uLT5jb25uID0gMDsKICB9CiAgaWYgKENvbm5lY3Rpb24tPm92bC5oRXZlbnQpIHsKICAgIENsb3NlSGFuZGxlKENvbm5lY3Rpb24tPm92bC5oRXZlbnQpOwogICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IDA7CiAgfQogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfU3Bhd25Db25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBScGNDb25uZWN0aW9uKiBPbGRDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKICBSUENfU1RBVFVTIGVyciA9IFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKCZOZXdDb25uZWN0aW9uLCBPbGRDb25uZWN0aW9uLT5zZXJ2ZXIsIE9sZENvbm5lY3Rpb24tPlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbGRDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwgT2xkQ29ubmVjdGlvbi0+RW5kcG9pbnQsIE5VTEwsIE5VTEwpOwogIGlmIChlcnIgPT0gUlBDX1NfT0spIHsKICAgIC8qIGJlY2F1c2Ugb2YgdGhlIHdheSBuYW1lZCBwaXBlcyB3b3JrLCB3ZSdsbCB0cmFuc2ZlciB0aGUgY29ubmVjdGVkIHBpcGUKICAgICAqIHRvIHRoZSBjaGlsZCwgdGhlbiByZW9wZW4gdGhlIHNlcnZlciBiaW5kaW5nIHRvIGNvbnRpbnVlIGxpc3RlbmluZyAqLwogICAgTmV3Q29ubmVjdGlvbi0+Y29ubiA9IE9sZENvbm5lY3Rpb24tPmNvbm47CiAgICBOZXdDb25uZWN0aW9uLT5vdmwgPSBPbGRDb25uZWN0aW9uLT5vdmw7CiAgICBPbGRDb25uZWN0aW9uLT5jb25uID0gMDsKICAgIG1lbXNldCgmT2xkQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoT2xkQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAqQ29ubmVjdGlvbiA9IE5ld0Nvbm5lY3Rpb247CiAgICBSUENSVDRfT3BlbkNvbm5lY3Rpb24oT2xkQ29ubmVjdGlvbik7CiAgfQogIHJldHVybiBlcnI7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0FsbG9jQmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBOZXdCaW5kaW5nID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNCaW5kaW5nKSk7CiAgTmV3QmluZGluZy0+cmVmcyA9IDE7CiAgTmV3QmluZGluZy0+c2VydmVyID0gc2VydmVyOwoKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ0EoUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUFNUUiBQcm90c2VxKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgc2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoUHJvdHNlcSk7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NyZWF0ZUJpbmRpbmdXKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlciwgTFBXU1RSIFByb3RzZXEpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBzZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwV3RvQShQcm90c2VxKTsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nQShScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFNUUiBOZXR3b3JrQWRkciwgIExQU1RSIEVuZHBvaW50LCAgTFBTVFIgTmV0d29ya09wdGlvbnMpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBOZXR3b3JrQWRkciA9PSBcIiVzXCIsIEVuZFBvaW50ID09IFwiJXNcIiwgTmV0d29ya09wdGlvbnMgPT0gXCIlc1wiKVxuIiwgQmluZGluZywKICAgZGVidWdzdHJfYShOZXR3b3JrQWRkciksIGRlYnVnc3RyX2EoRW5kcG9pbnQpLCBkZWJ1Z3N0cl9hKE5ldHdvcmtPcHRpb25zKSk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKE5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgaWYgKEVuZHBvaW50KSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKEVuZHBvaW50KTsKICB9IGVsc2UgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQSgiIik7CiAgfQogIGlmICghQmluZGluZy0+RW5kcG9pbnQpIEVSUigib3V0IG9mIG1lbW9yeT9cbiIpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NvbXBsZXRlQmluZGluZ1coUnBjQmluZGluZyogQmluZGluZywgTFBXU1RSIE5ldHdvcmtBZGRyLCBMUFdTVFIgRW5kcG9pbnQsIExQV1NUUiBOZXR3b3JrT3B0aW9ucykKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09IFwiJXNcIiwgRW5kUG9pbnQgPT0gXCIlc1wiLCBOZXR3b3JrT3B0aW9ucyA9PSBcIiVzXCIpXG4iLCBCaW5kaW5nLCAKICAgZGVidWdzdHJfdyhOZXR3b3JrQWRkciksIGRlYnVnc3RyX3coRW5kcG9pbnQpLCBkZWJ1Z3N0cl93KE5ldHdvcmtPcHRpb25zKSk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBXdG9BKE5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgaWYgKEVuZHBvaW50KSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXdG9BKEVuZHBvaW50KTsKICB9IGVsc2UgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQSgiIik7CiAgfQogIGlmICghQmluZGluZy0+RW5kcG9pbnQpIEVSUigib3V0IG9mIG1lbW9yeT9cbiIpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1Jlc29sdmVCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQU1RSIEVuZHBvaW50KQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgRW5kUG9pbnQgPT0gXCIlc1wiXG4iLCBCaW5kaW5nLCBFbmRwb2ludCk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKEVuZHBvaW50KTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KFJwY0JpbmRpbmcqIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQpCnsKICBUUkFDRSgiKCpScGNCaW5kaW5nID09IF4lcCwgVVVJRCA9PSAlcylcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2d1aWQoT2JqZWN0VXVpZCkpOyAKICBpZiAoT2JqZWN0VXVpZCkgbWVtY3B5KCZCaW5kaW5nLT5PYmplY3RVdWlkLCBPYmplY3RVdWlkLCBzaXplb2YoVVVJRCkpOwogIGVsc2UgVXVpZENyZWF0ZU5pbCgmQmluZGluZy0+T2JqZWN0VXVpZCk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9NYWtlQmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBCaW5kaW5nLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgQ29ubmVjdGlvbi0+c2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgTmV3QmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5OZXR3b3JrQWRkcik7CiAgTmV3QmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgTmV3QmluZGluZy0+RnJvbUNvbm4gPSBDb25uZWN0aW9uOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9FeHBvcnRCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNCaW5kaW5nKiBPbGRCaW5kaW5nKQp7CiAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJk9sZEJpbmRpbmctPnJlZnMpOwogICpCaW5kaW5nID0gT2xkQmluZGluZzsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpCnsKICBpZiAoSW50ZXJsb2NrZWREZWNyZW1lbnQoJkJpbmRpbmctPnJlZnMpKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIEJpbmRpbmcpOwogIC8qIEZJWE1FOiByZWxlYXNlIGNvbm5lY3Rpb25zICovCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5CaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIFRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1NZTlRBWF9JREVOVElGSUVSIEludGVyZmFjZUlkKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwoKICAvKiBpZiB3ZSB0cnkgdG8gYmluZCBhIG5ldyBpbnRlcmZhY2UgYW5kIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgb3BlbmVkLAogICAqIGNsb3NlIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gYW5kIGNyZWF0ZSBhIG5ldyB3aXRoIHRoZSBuZXcgYmluZGluZy4gKi8gCiAgaWYgKCFCaW5kaW5nLT5zZXJ2ZXIgJiYgQmluZGluZy0+RnJvbUNvbm4gJiYKICAgICAgbWVtY21wKCZCaW5kaW5nLT5Gcm9tQ29ubi0+QWN0aXZlSW50ZXJmYWNlLCBJbnRlcmZhY2VJZCwKICAgICAgICAgICAgIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSkgewoKICAgIFRSQUNFKCJyZWxlYXNpbmcgcHJlLWV4aXN0aW5nIGNvbm5lY3Rpb25cbiIpOwogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKEJpbmRpbmctPkZyb21Db25uKTsKICAgIEJpbmRpbmctPkZyb21Db25uID0gTlVMTDsKICB9IGVsc2UgewogICAgLyogd2UgYWxyZWFkeSBoYXZlIGFuIGNvbm5lY3Rpb24gd2l0aCBhY2NlcHRhYmxlIGJpbmRpbmcsIHNvIHVzZSBpdCAqLwogICAgaWYgKEJpbmRpbmctPkZyb21Db25uKSB7CiAgICAgICpDb25uZWN0aW9uID0gQmluZGluZy0+RnJvbUNvbm47CiAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0KICB9CiAgCiAgLyogY3JlYXRlIGEgbmV3IGNvbm5lY3Rpb24gKi8KICBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgQmluZGluZy0+c2VydmVyLCBCaW5kaW5nLT5Qcm90c2VxLCBCaW5kaW5nLT5OZXR3b3JrQWRkciwgQmluZGluZy0+RW5kcG9pbnQsIE5VTEwsIEJpbmRpbmcpOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKICBzdGF0dXMgPSBSUENSVDRfT3BlbkNvbm5lY3Rpb24oTmV3Q29ubmVjdGlvbik7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgcmV0dXJuIHN0YXR1czsKICB9CgogIC8qIHdlIG5lZWQgdG8gc2VuZCBhIGJpbmRpbmcgcGFja2V0IGlmIHdlIGFyZSBjbGllbnQuICovCiAgaWYgKCEoKkNvbm5lY3Rpb24pLT5zZXJ2ZXIpIHsKICAgIFJwY1BrdEhkciAqaGRyOwogICAgRFdPUkQgY291bnQ7CiAgICBCWVRFICpyZXNwb25zZTsKICAgIFJwY1BrdEhkciAqcmVzcG9uc2VfaGRyOwoKICAgIFRSQUNFKCJzZW5kaW5nIGJpbmQgcmVxdWVzdCB0byBzZXJ2ZXJcbiIpOwoKICAgIGhkciA9IFJQQ1JUNF9CdWlsZEJpbmRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsIFJQQ19NQVhfUEFDS0VUX1NJWkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVyZmFjZUlkLCBUcmFuc2ZlclN5bnRheCk7CgogICAgc3RhdHVzID0gUlBDUlQ0X1NlbmQoKkNvbm5lY3Rpb24sIGhkciwgTlVMTCwgMCk7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgcmVzcG9uc2UgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgUlBDX01BWF9QQUNLRVRfU0laRSk7CiAgICBpZiAocmVzcG9uc2UgPT0gTlVMTCkgewogICAgICBXQVJOKCJDYW4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGJpbmRpbmcgcmVzcG9uc2VcbiIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICAvKiBnZXQgYSByZXBseSAqLwogICAgaWYgKCFSZWFkRmlsZShOZXdDb25uZWN0aW9uLT5jb25uLCByZXNwb25zZSwgUlBDX01BWF9QQUNLRVRfU0laRSwgJmNvdW50LCBOVUxMKSkgewogICAgICBXQVJOKCJSZWFkRmlsZSBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIGlmIChjb3VudCA8IHNpemVvZihyZXNwb25zZV9oZHItPmNvbW1vbikpIHsKICAgICAgV0FSTigicmVjZWl2ZWQgaW52YWxpZCBoZWFkZXJcbiIpOwogICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oKkNvbm5lY3Rpb24pOwogICAgICByZXR1cm4gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICB9CgogICAgcmVzcG9uc2VfaGRyID0gKFJwY1BrdEhkciopcmVzcG9uc2U7CgogICAgaWYgKHJlc3BvbnNlX2hkci0+Y29tbW9uLnJwY192ZXIgIT0gUlBDX1ZFUl9NQUpPUiB8fAogICAgICAgIHJlc3BvbnNlX2hkci0+Y29tbW9uLnJwY192ZXJfbWlub3IgIT0gUlBDX1ZFUl9NSU5PUiB8fAogICAgICAgIHJlc3BvbnNlX2hkci0+Y29tbW9uLnB0eXBlICE9IFBLVF9CSU5EX0FDSykgewogICAgICBXQVJOKCJpbnZhbGlkIHByb3RvY29sIHZlcnNpb24gb3IgcmVqZWN0aW9uIHBhY2tldFxuIik7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbigqQ29ubmVjdGlvbik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICBpZiAocmVzcG9uc2VfaGRyLT5iaW5kX2Fjay5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFKSB7CiAgICAgIFdBUk4oInNlcnZlciBkb2Vzbid0IGFsbG93IGxhcmdlIGVub3VnaCBwYWNrZXRzXG4iKTsKICAgICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKCpDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcz8gKi8KCiAgICAoKkNvbm5lY3Rpb24pLT5NYXhUcmFuc21pc3Npb25TaXplID0gcmVzcG9uc2VfaGRyLT5iaW5kX2Fjay5tYXhfdHNpemU7CiAgICAoKkNvbm5lY3Rpb24pLT5BY3RpdmVJbnRlcmZhY2UgPSAqSW50ZXJmYWNlSWQ7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmICghQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIGlmIChCaW5kaW5nLT5Gcm9tQ29ubiA9PSBDb25uZWN0aW9uKSByZXR1cm4gUlBDX1NfT0s7CiAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKfQoKLyogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHN0cmluZyBjb21wb3NpbmcgYW5kIHBhcnNpbmcgKi8Kc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5QShMUFNUUiBkYXRhLCBMUENTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5VyhMUFdTVFIgZGF0YSwgTFBDV1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW5XKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyBMUFNUUiBSUENSVDRfc3RyY29uY2F0QShMUFNUUiBkc3QsIExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW4oZHN0KSwgc2xlbiA9IHN0cmxlbihzcmMpOwogIExQU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoQ0hBUikpOwogIGlmICghbmRzdCkKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKzEpOwogIHJldHVybiBuZHN0Owp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJjb25jYXRXKExQV1NUUiBkc3QsIExQQ1dTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuVyhkc3QpLCBzbGVuID0gc3RybGVuVyhzcmMpOwogIExQV1NUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKCFuZHN0KSAKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCAoc2xlbisxKSpzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbmRzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKHVuc2lnbmVkIGNoYXIgKk9ialV1aWQsIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpOZXR3b3JrQWRkciwgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpPcHRpb25zLCB1bnNpZ25lZCBjaGFyKiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQU1RSIGRhdGE7CgogIFRSQUNFKCAiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgICBkZWJ1Z3N0cl9hKCBPYmpVdWlkICksIGRlYnVnc3RyX2EoIFByb3RzZXEgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCBOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl9hKCBFbmRwb2ludCApLAogICAgICAgIGRlYnVnc3RyX2EoIE9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyApOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlbihPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW4oUHJvdHNlcSkgKyAxOwogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIGxlbiArPSBzdHJsZW4oTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW4oRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlbihPcHRpb25zKSArIDI7CgogIGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICAqU3RyaW5nQmluZGluZyA9IGRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBQcm90c2VxKTsKICAgICpkYXRhKysgPSAnOic7CiAgfQogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpCiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBOZXR3b3JrQWRkcik7CgogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIEVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBPcHRpb25zKTsKICAgIH0KICAgICpkYXRhKysgPSAnXSc7CiAgfQogICpkYXRhID0gMDsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVyggTFBXU1RSIE9ialV1aWQsIExQV1NUUiBQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBOZXR3b3JrQWRkciwgTFBXU1RSIEVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBPcHRpb25zLCBMUFdTVFIqIFN0cmluZ0JpbmRpbmcgKQp7CiAgRFdPUkQgbGVuID0gMTsKICBMUFdTVFIgZGF0YTsKCiAgVFJBQ0UoIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICBkZWJ1Z3N0cl93KCBPYmpVdWlkICksIGRlYnVnc3RyX3coIFByb3RzZXEgKSwKICAgICAgIGRlYnVnc3RyX3coIE5ldHdvcmtBZGRyICksIGRlYnVnc3RyX3coIEVuZHBvaW50ICksCiAgICAgICBkZWJ1Z3N0cl93KCBPcHRpb25zICksIFN0cmluZ0JpbmRpbmcpOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlblcoT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuVyhQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlblcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW5XKEVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW5XKE9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgKlN0cmluZ0JpbmRpbmcgPSBkYXRhOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBOZXR3b3JrQWRkcik7CiAgfQogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIEVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBPcHRpb25zKTsKICAgIH0KICAgICpkYXRhKysgPSAnXSc7CiAgfQogICpkYXRhID0gMDsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlQSggdW5zaWduZWQgY2hhciAqU3RyaW5nQmluZGluZywgdW5zaWduZWQgY2hhciAqKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKipQcm90c2VxLCB1bnNpZ25lZCBjaGFyICoqTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKipFbmRwb2ludCwgdW5zaWduZWQgY2hhciAqKk9wdGlvbnMpCnsKICBDSEFSICpkYXRhLCAqbmV4dDsKICBzdGF0aWMgY29uc3QgY2hhciBlcF9vcHRbXSA9ICJlbmRwb2ludD0iOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfYShTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICdAJyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnOicpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICAgIGNsb3NlID0gc3RyY2hyKGRhdGEsICddJyk7CiAgICBpZiAoIWNsb3NlKSBnb3RvIGZhaWw7CgogICAgLyogdG9rZW5pemUgb3B0aW9ucyAqLwogICAgd2hpbGUgKGRhdGEgPCBjbG9zZSkgewogICAgICBuZXh0ID0gc3RyY2hyKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHIob3B0LCAnPScpOwogICAgICBpZiAoIW5leHQpIHsKICAgICAgICAvKiBub3QgYW4gb3B0aW9uLCBtdXN0IGJlIGFuIGVuZHBvaW50ICovCiAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICpFbmRwb2ludCA9IG9wdDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RybmNtcChvcHQsIGVwX29wdCwgc3RybGVuKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9IFJQQ1JUNF9zdHJjb25jYXRBKCpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfQogIGVsc2UgaWYgKE5ldHdvcmtBZGRyKSAKICAgICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKVByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKUVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyggTFBXU1RSIFN0cmluZ0JpbmRpbmcsIExQV1NUUiAqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSICpQcm90c2VxLCBMUFdTVFIgKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgKkVuZHBvaW50LCBMUFdTVFIgKk9wdGlvbnMpCnsKICBXQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IFdDSEFSIGVwX29wdFtdID0geydlJywnbicsJ2QnLCdwJywnbycsJ2knLCduJywndCcsJz0nLDB9OwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgV0NIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNoclcoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHJXKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHJXKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAqRW5kcG9pbnQgPSBvcHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXBXKG9wdCwgZXBfb3B0LCBzdHJsZW5XKGVwX29wdCkpID09IDApIHsKICAgICAgICAgIC8qIGVuZHBvaW50IG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICAgKkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFcobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICAgICAgICAqT3B0aW9ucyA9IFJQQ1JUNF9zdHJjb25jYXRXKCpPcHRpb25zLCBvcHQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgfSBlbHNlIAoJICAgICpPcHRpb25zID0gb3B0OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfSBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwVyhkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZVcoT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVXKFByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZVcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZVcoRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlVyhPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcmVlKCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgVFJBQ0UoIiglcCkgPSAlcFxuIiwgQmluZGluZywgKkJpbmRpbmcpOwogIHN0YXR1cyA9IFJQQ1JUNF9EZXN0cm95QmluZGluZygqQmluZGluZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykgKkJpbmRpbmcgPSAwOwogIHJldHVybiBzdGF0dXM7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdWZWN0b3JGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdWZWN0b3JGcmVlKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIHVuc2lnbmVkIGxvbmcgYzsKCiAgVFJBQ0UoIiglcClcbiIsIEJpbmRpbmdWZWN0b3IpOwogIGZvciAoYz0wOyBjPCgqQmluZGluZ1ZlY3RvciktPkNvdW50OyBjKyspIHsKICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdGcmVlKCYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjXSk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsICpCaW5kaW5nVmVjdG9yKTsKICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xT2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdJbnFPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcCkgPSAlc1xuIiwgQmluZGluZywgT2JqZWN0VXVpZCwgZGVidWdzdHJfZ3VpZCgmYmluZC0+T2JqZWN0VXVpZCkpOwogIG1lbWNweShPYmplY3RVdWlkLCAmYmluZC0+T2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdTZXRPYmplY3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1NldE9iamVjdCggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7CiAgaWYgKGJpbmQtPnNlcnZlcikgcmV0dXJuIFJQQ19TX1dST05HX0tJTkRfT0ZfQklORElORzsKICByZXR1cm4gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoQmluZGluZywgT2JqZWN0VXVpZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ0EoIHVuc2lnbmVkIGNoYXIgKlN0cmluZ0JpbmRpbmcsIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gTlVMTDsKICB1bnNpZ25lZCBjaGFyICpPYmplY3RVdWlkLCAqUHJvdHNlcSwgKk5ldHdvcmtBZGRyLCAqRW5kcG9pbnQsICpPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX2EoU3RyaW5nQmluZGluZyksIEJpbmRpbmcpOwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nUGFyc2VBKFN0cmluZ0JpbmRpbmcsICZPYmplY3RVdWlkLCAmUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ldHdvcmtBZGRyLCAmRW5kcG9pbnQsICZPcHRpb25zKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBVdWlkRnJvbVN0cmluZ0EoT2JqZWN0VXVpZCwgJlV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NyZWF0ZUJpbmRpbmdBKCZiaW5kLCBGQUxTRSwgUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoYmluZCwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykgCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlIAogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKCBMUFdTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIExQV1NUUiBPYmplY3RVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnM7CiAgVVVJRCBVdWlkOwoKICBUUkFDRSgiKCVzLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nVyhPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ1coJmJpbmQsIEZBTFNFLCBQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhiaW5kLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlVygmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZVcoJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlVygmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVXKCZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlVygmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgdW5zaWduZWQgY2hhcioqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIExQU1RSIE9iamVjdFV1aWQ7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKCiAgcmV0ID0gVXVpZFRvU3RyaW5nQSgmYmluZC0+T2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKikmT2JqZWN0VXVpZCk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKE9iamVjdFV1aWQsIGJpbmQtPlByb3RzZXEsIGJpbmQtPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5kLT5FbmRwb2ludCwgTlVMTCwgU3RyaW5nQmluZGluZyk7CgogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIHVuc2lnbmVkIHNob3J0KiogU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICB1bnNpZ25lZCBjaGFyICpzdHIgPSBOVUxMOwogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKICByZXQgPSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQShCaW5kaW5nLCAmc3RyKTsKICAqU3RyaW5nQmluZGluZyA9IFJQQ1JUNF9zdHJkdXBBdG9XKHN0cik7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmc3RyKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNCaW5kaW5nU2V0QXN5bmMgKFJQQ1JUNC5AKQogKiBOT1RFUwogKiAgRXhpc3RzIGluIHdpbjl4IGFuZCB3aW5OVCwgYnV0IHdpdGggZGlmZmVyZW50IG51bWJlciBvZiBhcmd1bWVudHMKICogICg5eCB2ZXJzaW9uIGhhcyAzIGFyZ3VtZW50cywgTlQgaGFzIDIpLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNCaW5kaW5nU2V0QXN5bmMoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQkxPQ0tJTkdfRk4gQmxvY2tpbmdGbikKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoICIoJXAsJXApOiBzdHViXG4iLCBCaW5kaW5nLCBCbG9ja2luZ0ZuICk7CgogIGJpbmQtPkJsb2NraW5nRm4gPSBCbG9ja2luZ0ZuOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNOZXR3b3JrSXNQcm90c2VxVmFsaWRBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY05ldHdvcmtJc1Byb3RzZXFWYWxpZEEodW5zaWduZWQgY2hhciAqcHJvdHNlcSkgewogIFVOSUNPREVfU1RSSU5HIHByb3RzZXFXOwoKICBpZiAoIXByb3RzZXEpIHJldHVybiBSUENfU19JTlZBTElEX1JQQ19QUk9UU0VROyAvKiA/ICovCiAgCiAgaWYgKFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCZwcm90c2VxVywgcHJvdHNlcSkpIHsKICAgIFJQQ19TVEFUVVMgcmV0ID0gUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhwcm90c2VxVy5CdWZmZXIpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoJnByb3RzZXFXKTsKICAgIHJldHVybiByZXQ7CiAgfSBlbHNlIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyAoUlBDUlQ0LkApCiAqIAogKiBDaGVja3MgaWYgdGhlIGdpdmVuIHByb3RvY29sIHNlcXVlbmNlIGlzIGtub3duIGJ5IHRoZSBSUEMgc3lzdGVtLgogKiBJZiBpdCBpcywgcmV0dXJucyBSUENfU19PSywgb3RoZXJ3aXNlIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRC4KICoKICogV2UgY3VycmVudGx5IHN1cHBvcnQ6CiAqICAgbmNhbHJwYyAgIGxvY2FsLW9ubHkgcnBjIG92ZXIgTFBDIChMUEMgaXMgbm90IHJlYWxseSB1c2VkKQogKiAgIG5jYWNuX25wICBycGMgb3ZlciBuYW1lZCBwaXBlcwogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhMUFdTVFIgcHJvdHNlcSkgewogIHN0YXRpYyBjb25zdCBXQ0hBUiBwcm90c2Vxc1dbXVsxNV0gPSB7IAogICAgeyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfSwKICAgIHsnbicsJ2MnLCdhJywnYycsJ24nLCdfJywnbicsJ3AnLDB9CiAgfTsKICBzdGF0aWMgY29uc3QgaW50IGNvdW50ID0gc2l6ZW9mKHByb3RzZXFzVykgLyBzaXplb2YocHJvdHNlcXNXWzBdKTsKICBpbnQgaTsKCiAgaWYgKCFwcm90c2VxKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsgLyogPyAqLwoKICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogICAgaWYgKCFzdHJjbXBXKHByb3RzZXEsIHByb3RzZXFzV1tpXSkpIHJldHVybiBSUENfU19PSzsKICB9CiAgCiAgRklYTUUoIlVua25vd24gcHJvdHNlcSAlcyAtIHdlIHByb2JhYmx5IG5lZWQgdG8gaW1wbGVtZW50IGl0IG9uZSBkYXlcbiIsIGRlYnVnc3RyX3cocHJvdHNlcSkpOwogIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNJbXBlcnNvbmF0ZUNsaWVudCAoUlBDUlQ0LkApCiAqCiAqIEltcGVyc29uYXRlcyB0aGUgY2xpZW50IGNvbm5lY3RlZCB2aWEgYSBiaW5kaW5nIGhhbmRsZSBzbyB0aGF0IHNlY3VyaXR5CiAqIGNoZWNrcyBhcmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgY2xpZW50LgogKgogKiBQQVJBTVMKICogIEJpbmRpbmdIYW5kbGUgW0ldIEhhbmRsZSB0byB0aGUgYmluZGluZyB0byB0aGUgY2xpZW50LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUFNfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TVEFUVVMgdmFsdWUuCiAqCiAqIE5PVEVTCiAqCiAqIElmIEJpbmRpbmdIYW5kbGUgaXMgTlVMTCB0aGVuIHRoZSBmdW5jdGlvbiBpbXBlcnNvbmF0ZXMgdGhlIGNsaWVudAogKiBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIG9mIHRoZSBjdXJyZW50IHRocmVhZC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0ltcGVyc29uYXRlQ2xpZW50KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlKQp7CiAgICBGSVhNRSgiKCVwKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNSZXZlcnRUb1NlbGZFeCAoUlBDUlQ0LkApCiAqCiAqIFN0b3BzIGltcGVyc29uYXRpbmcgdGhlIGNsaWVudCBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIHNvIHRoYXQgc2VjdXJpdHkKICogY2hlY2tzIGFyZSBubyBsb25nZXIgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgY2xpZW50LgogKgogKiBQQVJBTVMKICogIEJpbmRpbmdIYW5kbGUgW0ldIEhhbmRsZSB0byB0aGUgYmluZGluZyB0byB0aGUgY2xpZW50LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUFNfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TVEFUVVMgdmFsdWUuCiAqCiAqIE5PVEVTCiAqCiAqIElmIEJpbmRpbmdIYW5kbGUgaXMgTlVMTCB0aGVuIHRoZSBmdW5jdGlvbiBzdG9wcyBpbXBlcnNvbmF0aW5nIHRoZSBjbGllbnQKICogY29ubmVjdGVkIHRvIHRoZSBiaW5kaW5nIGhhbmRsZSBvZiB0aGUgY3VycmVudCB0aHJlYWQuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNSZXZlcnRUb1NlbGZFeChSUENfQklORElOR19IQU5ETEUgQmluZGluZ0hhbmRsZSkKewogICAgRklYTUUoIiglcCk6IHN0dWJcbiIsIEJpbmRpbmdIYW5kbGUpOwogICAgcmV0dXJuIFJQQ19TX09LOwp9Cg==