LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAicnBjLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInJwY19iaW5kaW5nLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIFJwY0Nvbm5lY3Rpb24qIGNvbm5fY2FjaGU7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNvbm5fY2FjaGVfY3MgPSBDUklUSUNBTF9TRUNUSU9OX0lOSVQoImNvbm5fY2FjaGVfY3MiKTsKCkxQU1RSIFJQQ1JUNF9zdHJuZHVwQShMUFNUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBpZiAoc3JjKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSwgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LCBMUFNUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIE5ld0Nvbm5lY3Rpb24gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb24pKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgTmV3Q29ubmVjdGlvbi0+TmV4dCA9IGNvbm5fY2FjaGU7CiAgY29ubl9jYWNoZSA9IE5ld0Nvbm5lY3Rpb247CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbm5fY2FjaGVfY3MpOwoKICBUUkFDRSgiY29ubmVjdGlvbjogJXBcbiIsIE5ld0Nvbm5lY3Rpb24pOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbiogUHJldkNvbm5lY3Rpb247CgogIFRSQUNFKCJjb25uZWN0aW9uOiAlcFxuIiwgQ29ubmVjdGlvbik7CiAgaWYgKENvbm5lY3Rpb24tPlVzZWQpIEVSUigiY29ubmVjdGlvbiBpcyBzdGlsbCBpbiB1c2VcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgUHJldkNvbm5lY3Rpb24gPSBjb25uX2NhY2hlOwogIHdoaWxlIChQcmV2Q29ubmVjdGlvbiAmJiBQcmV2Q29ubmVjdGlvbi0+TmV4dCAhPSBDb25uZWN0aW9uKQogICAgUHJldkNvbm5lY3Rpb24gPSBQcmV2Q29ubmVjdGlvbi0+TmV4dDsKICBpZiAoUHJldkNvbm5lY3Rpb24pIFByZXZDb25uZWN0aW9uLT5OZXh0ID0gQ29ubmVjdGlvbi0+TmV4dDsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CgogIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBDb25uZWN0aW9uKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0dldENvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIEJPT0wgc2VydmVyLCBMUFNUUiBQcm90c2VxLCBMUFNUUiBOZXR3b3JrQWRkciwgTFBTVFIgRW5kcG9pbnQsIExQU1RSIE5ldHdvcmtPcHRpb25zLCBScGNCaW5kaW5nKiBCaW5kaW5nKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKCiAgaWYgKCFzZXJ2ZXIpIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjb25uX2NhY2hlX2NzKTsKICAgIGZvciAoTmV3Q29ubmVjdGlvbiA9IGNvbm5fY2FjaGU7IE5ld0Nvbm5lY3Rpb247IE5ld0Nvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uLT5OZXh0KSB7CiAgICAgIGlmIChOZXdDb25uZWN0aW9uLT5Vc2VkKSBjb250aW51ZTsKICAgICAgaWYgKE5ld0Nvbm5lY3Rpb24tPnNlcnZlciAhPSBzZXJ2ZXIpIGNvbnRpbnVlOwogICAgICBpZiAoUHJvdHNlcSAmJiBzdHJjbXAoTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSwgUHJvdHNlcSkpIGNvbnRpbnVlOwogICAgICBpZiAoTmV0d29ya0FkZHIgJiYgc3RyY21wKE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBOZXR3b3JrQWRkcikpIGNvbnRpbnVlOwogICAgICBpZiAoRW5kcG9pbnQgJiYgc3RyY21wKE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50LCBFbmRwb2ludCkpIGNvbnRpbnVlOwogICAgICAvKiB0aGlzIGNvbm5lY3Rpb24gZml0cyB0aGUgYmlsbCAqLwogICAgICBOZXdDb25uZWN0aW9uLT5Vc2VkID0gQmluZGluZzsKICAgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgICBpZiAoTmV3Q29ubmVjdGlvbikgewogICAgICBUUkFDRSgiY2FjaGVkIGNvbm5lY3Rpb246ICVwXG4iLCBOZXdDb25uZWN0aW9uKTsKICAgICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CiAgfQogIHJldHVybiBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbihDb25uZWN0aW9uLCBzZXJ2ZXIsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgTmV0d29ya09wdGlvbnMsIEJpbmRpbmcpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9SZWxlYXNlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKICBDb25uZWN0aW9uLT5Vc2VkID0gTlVMTDsKICBpZiAoIUNvbm5lY3Rpb24tPnNlcnZlcikgewogICAgLyogY2FjaGUgdGhlIG9wZW4gY29ubmVjdGlvbiBmb3IgcmV1c2UgbGF0ZXIgKi8KICAgIC8qIEZJWE1FOiB3ZSBzaG91bGQgcHJvYmFibHkgY2xlYW4gdGhlIGNhY2hlIHNvbWVkYXkgKi8KICAgIHJldHVybiBSUENfU19PSzsKICB9CiAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoIUNvbm5lY3Rpb24tPmNvbm4pIHsKICAgIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpIHsgLyogc2VydmVyICovCiAgICAgIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgICAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICAgICAgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhbHJwYyIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBTVFIgcHJlZml4ID0gIlxcXFwuXFxwaXBlXFxscnBjXFwiOwogICAgICAgIExQU1RSIHBuYW1lOwogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgibGlzdGVuaW5nIG9uICVzXG4iLCBwbmFtZSk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IENyZWF0ZU5hbWVkUGlwZUEocG5hbWUsIFBJUEVfQUNDRVNTX0RVUExFWCB8IEZJTEVfRkxBR19PVkVSTEFQUEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFBJUEVfVU5MSU1JVEVEX0lOU1RBTkNFUywgMCwgMCwgNTAwMCwgTlVMTCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYgKCFDb25uZWN0TmFtZWRQaXBlKENvbm5lY3Rpb24tPmNvbm4sICZDb25uZWN0aW9uLT5vdmwpKSB7CiAgICAgICAgICBEV09SRCBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgIGlmIChlcnIgPT0gRVJST1JfUElQRV9DT05ORUNURUQpIHsKICAgICAgICAgICAgU2V0RXZlbnQoQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19PSzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgICAgIGVsc2UgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhY25fbnAiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQU1RSIHByZWZpeCA9ICJcXFxcLiI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgcG5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgICAgICAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogICAgICAgIFRSQUNFKCJsaXN0ZW5pbmcgb24gJXNcbiIsIHBuYW1lKTsKICAgICAgICBDb25uZWN0aW9uLT5jb25uID0gQ3JlYXRlTmFtZWRQaXBlQShwbmFtZSwgUElQRV9BQ0NFU1NfRFVQTEVYIHwgRklMRV9GTEFHX09WRVJMQVBQRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLCAwLCAwLCA1MDAwLCBOVUxMKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgICAgICBpZiAoIUNvbm5lY3ROYW1lZFBpcGUoQ29ubmVjdGlvbi0+Y29ubiwgJkNvbm5lY3Rpb24tPm92bCkpIHsKICAgICAgICAgIERXT1JEIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkgewogICAgICAgICAgICBTZXRFdmVudChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgRVJSKCJwcm90c2VxICVzIG5vdCBzdXBwb3J0ZWRcbiIsIENvbm5lY3Rpb24tPlByb3RzZXEpOwogICAgICAgIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgeyAvKiBjbGllbnQgKi8KICAgICAgLyogcHJvdHNlcT1uY2FscnBjOiBzdXBwb3NlZCB0byB1c2UgTlQgTFBDIHBvcnRzLAogICAgICAgKiBidXQgd2UnbGwgaW1wbGVtZW50IGl0IHdpdGggbmFtZWQgcGlwZXMgZm9yIG5vdyAqLwogICAgICBpZiAoc3RyY21wKENvbm5lY3Rpb24tPlByb3RzZXEsICJuY2FscnBjIikgPT0gMCkgewogICAgICAgIHN0YXRpYyBMUFNUUiBwcmVmaXggPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwoKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImNvbm5lY3RpbmcgdG8gJXNcbiIsIHBuYW1lKTsKICAgICAgICB3aGlsZSAoVFJVRSkgewogICAgICAgICAgaWYgKFdhaXROYW1lZFBpcGVBKHBuYW1lLCBOTVBXQUlUX1dBSVRfRk9SRVZFUikpIHsKICAgICAgICAgICAgY29ubiA9IENyZWF0ZUZpbGVBKHBuYW1lLCBHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIEZJTEVfRkxBR19PVkVSTEFQUEVELCAwKTsKICAgICAgICAgICAgaWYgKGNvbm4gIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpIGNvbnRpbnVlOwogICAgICAgICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgICByZXR1cm4gZXJyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAgIFRSQUNFKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IGNvbm47CiAgICAgIH0KICAgICAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICAgICAgZWxzZSBpZiAoc3RyY21wKENvbm5lY3Rpb24tPlByb3RzZXEsICJuY2Fjbl9ucCIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBTVFIgcHJlZml4ID0gIlxcXFwuIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBIQU5ETEUgY29ubjsKICAgICAgICBEV09SRCBlcnI7CgogICAgICAgIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogICAgICAgIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICAgICAgICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwogICAgICAgIGNvbm4gPSBDcmVhdGVGaWxlQShwbmFtZSwgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEUsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIEZJTEVfRkxBR19PVkVSTEFQUEVELCAwKTsKICAgICAgICBpZiAoY29ubiA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewogICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAvKiB3ZSBkb24ndCBuZWVkIHRvIGhhbmRsZSBFUlJPUl9QSVBFX0JVU1kgaGVyZSwKICAgICAgICAgICAqIHRoZSBkb2Mgc2F5cyB0aGF0IGl0IGlzIHJldHVybmVkIHRvIHRoZSBhcHAgKi8KICAgICAgICAgIFRSQUNFKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CgogICAgICAgIC8qIHN1Y2Nlc3MgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgbWVtc2V0KCZDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihDb25uZWN0aW9uLT5vdmwpKTsKICAgICAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgICAgICBDb25uZWN0aW9uLT5jb25uID0gY29ubjsKICAgICAgfSBlbHNlIHsKICAgICAgICBFUlIoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihDb25uZWN0aW9uID09IF4lcClcbiIsIENvbm5lY3Rpb24pOwogIGlmIChDb25uZWN0aW9uLT5jb25uKSB7CiAgICBDYW5jZWxJbyhDb25uZWN0aW9uLT5jb25uKTsKICAgIENsb3NlSGFuZGxlKENvbm5lY3Rpb24tPmNvbm4pOwogICAgQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgfQogIGlmIChDb25uZWN0aW9uLT5vdmwuaEV2ZW50KSB7CiAgICBDbG9zZUhhbmRsZShDb25uZWN0aW9uLT5vdmwuaEV2ZW50KTsKICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSAwOwogIH0KICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUnBjQ29ubmVjdGlvbiogT2xkQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CiAgUlBDX1NUQVRVUyBlcnIgPSBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmTmV3Q29ubmVjdGlvbiwgT2xkQ29ubmVjdGlvbi0+c2VydmVyLCBPbGRDb25uZWN0aW9uLT5Qcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2xkQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIE9sZENvbm5lY3Rpb24tPkVuZHBvaW50LCBOVUxMLCBOVUxMKTsKICBpZiAoZXJyID09IFJQQ19TX09LKSB7CiAgICAvKiBiZWNhdXNlIG9mIHRoZSB3YXkgbmFtZWQgcGlwZXMgd29yaywgd2UnbGwgdHJhbnNmZXIgdGhlIGNvbm5lY3RlZCBwaXBlCiAgICAgKiB0byB0aGUgY2hpbGQsIHRoZW4gcmVvcGVuIHRoZSBzZXJ2ZXIgYmluZGluZyB0byBjb250aW51ZSBsaXN0ZW5pbmcgKi8KICAgIE5ld0Nvbm5lY3Rpb24tPmNvbm4gPSBPbGRDb25uZWN0aW9uLT5jb25uOwogICAgTmV3Q29ubmVjdGlvbi0+b3ZsID0gT2xkQ29ubmVjdGlvbi0+b3ZsOwogICAgT2xkQ29ubmVjdGlvbi0+Y29ubiA9IDA7CiAgICBtZW1zZXQoJk9sZENvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKE9sZENvbm5lY3Rpb24tPm92bCkpOwogICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgUlBDUlQ0X09wZW5Db25uZWN0aW9uKE9sZENvbm5lY3Rpb24pOwogIH0KICByZXR1cm4gZXJyOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9BbGxvY0JpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgTmV3QmluZGluZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjQmluZGluZykpOwogIE5ld0JpbmRpbmctPnJlZnMgPSAxOwogIE5ld0JpbmRpbmctPnNlcnZlciA9IHNlcnZlcjsKCiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NyZWF0ZUJpbmRpbmdBKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nVyhScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQV1NUUiBQcm90c2VxKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgc2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cFd0b0EoUHJvdHNlcSk7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoUnBjQmluZGluZyogQmluZGluZywgTFBTVFIgTmV0d29ya0FkZHIsICBMUFNUUiBFbmRwb2ludCwgIExQU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gXCIlc1wiLCBFbmRQb2ludCA9PSBcIiVzXCIsIE5ldHdvcmtPcHRpb25zID09IFwiJXNcIilcbiIsIEJpbmRpbmcsCiAgIGRlYnVnc3RyX2EoTmV0d29ya0FkZHIpLCBkZWJ1Z3N0cl9hKEVuZHBvaW50KSwgZGVidWdzdHJfYShOZXR3b3JrT3B0aW9ucykpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgQmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShOZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIGlmIChFbmRwb2ludCkgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CiAgfSBlbHNlIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoIiIpOwogIH0KICBpZiAoIUJpbmRpbmctPkVuZHBvaW50KSBFUlIoIm91dCBvZiBtZW1vcnk/XG4iKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdXKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQV1NUUiBOZXR3b3JrQWRkciwgTFBXU1RSIEVuZHBvaW50LCBMUFdTVFIgTmV0d29ya09wdGlvbnMpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBOZXR3b3JrQWRkciA9PSBcIiVzXCIsIEVuZFBvaW50ID09IFwiJXNcIiwgTmV0d29ya09wdGlvbnMgPT0gXCIlc1wiKVxuIiwgQmluZGluZywgCiAgIGRlYnVnc3RyX3coTmV0d29ya0FkZHIpLCBkZWJ1Z3N0cl93KEVuZHBvaW50KSwgZGVidWdzdHJfdyhOZXR3b3JrT3B0aW9ucykpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgQmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwV3RvQShOZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIGlmIChFbmRwb2ludCkgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwV3RvQShFbmRwb2ludCk7CiAgfSBlbHNlIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoIiIpOwogIH0KICBpZiAoIUJpbmRpbmctPkVuZHBvaW50KSBFUlIoIm91dCBvZiBtZW1vcnk/XG4iKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9SZXNvbHZlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFNUUiBFbmRwb2ludCkKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIEVuZFBvaW50ID09IFwiJXNcIlxuIiwgQmluZGluZywgRW5kcG9pbnQpOwoKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfU2V0QmluZGluZ09iamVjdChScGNCaW5kaW5nKiBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkKQp7CiAgVFJBQ0UoIigqUnBjQmluZGluZyA9PSBeJXAsIFVVSUQgPT0gJXMpXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9ndWlkKE9iamVjdFV1aWQpKTsgCiAgaWYgKE9iamVjdFV1aWQpIG1lbWNweSgmQmluZGluZy0+T2JqZWN0VXVpZCwgT2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICBlbHNlIFV1aWRDcmVhdGVOaWwoJkJpbmRpbmctPk9iamVjdFV1aWQpOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfTWFrZUJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwogIFRSQUNFKCIoKlJwY0JpbmRpbmcgPT0gXiVwLCBDb25uZWN0aW9uID09IF4lcClcbiIsICpCaW5kaW5nLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgQ29ubmVjdGlvbi0+c2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgTmV3QmluZGluZy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5OZXR3b3JrQWRkcik7CiAgTmV3QmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgTmV3QmluZGluZy0+RnJvbUNvbm4gPSBDb25uZWN0aW9uOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9FeHBvcnRCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNCaW5kaW5nKiBPbGRCaW5kaW5nKQp7CiAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJk9sZEJpbmRpbmctPnJlZnMpOwogICpCaW5kaW5nID0gT2xkQmluZGluZzsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpCnsKICBpZiAoSW50ZXJsb2NrZWREZWNyZW1lbnQoJkJpbmRpbmctPnJlZnMpKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIEJpbmRpbmcpOwogIC8qIEZJWE1FOiByZWxlYXNlIGNvbm5lY3Rpb25zICovCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5CaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKICBUUkFDRSgiKEJpbmRpbmcgPT0gXiVwKVxuIiwgQmluZGluZyk7CiAgaWYgKEJpbmRpbmctPkZyb21Db25uKSB7CiAgICAqQ29ubmVjdGlvbiA9IEJpbmRpbmctPkZyb21Db25uOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KCiAgUlBDUlQ0X0dldENvbm5lY3Rpb24oJk5ld0Nvbm5lY3Rpb24sIEJpbmRpbmctPnNlcnZlciwgQmluZGluZy0+UHJvdHNlcSwgQmluZGluZy0+TmV0d29ya0FkZHIsIEJpbmRpbmctPkVuZHBvaW50LCBOVUxMLCBCaW5kaW5nKTsKICAqQ29ubmVjdGlvbiA9IE5ld0Nvbm5lY3Rpb247CiAgcmV0dXJuIFJQQ1JUNF9PcGVuQ29ubmVjdGlvbihOZXdDb25uZWN0aW9uKTsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ2xvc2VCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBUUkFDRSgiKEJpbmRpbmcgPT0gXiVwKVxuIiwgQmluZGluZyk7CiAgaWYgKCFDb25uZWN0aW9uKSByZXR1cm4gUlBDX1NfT0s7CiAgaWYgKEJpbmRpbmctPkZyb21Db25uID09IENvbm5lY3Rpb24pIHJldHVybiBSUENfU19PSzsKICByZXR1cm4gUlBDUlQ0X1JlbGVhc2VDb25uZWN0aW9uKENvbm5lY3Rpb24pOwp9CgovKiB1dGlsaXR5IGZ1bmN0aW9ucyBmb3Igc3RyaW5nIGNvbXBvc2luZyBhbmQgcGFyc2luZyAqLwpzdGF0aWMgdW5zaWduZWQgUlBDUlQ0X3N0cmNvcHlBKExQU1RSIGRhdGEsIExQQ1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW4oc3JjKTsKICBtZW1jcHkoZGF0YSwgc3JjLCBsZW4qc2l6ZW9mKENIQVIpKTsKICByZXR1cm4gbGVuOwp9CgpzdGF0aWMgdW5zaWduZWQgUlBDUlQ0X3N0cmNvcHlXKExQV1NUUiBkYXRhLCBMUENXU1RSIHNyYykKewogIHVuc2lnbmVkIGxlbiA9IHN0cmxlblcoc3JjKTsKICBtZW1jcHkoZGF0YSwgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIExQU1RSIFJQQ1JUNF9zdHJjb25jYXRBKExQU1RSIGRzdCwgTFBDU1RSIHNyYykKewogIERXT1JEIGxlbiA9IHN0cmxlbihkc3QpLCBzbGVuID0gc3RybGVuKHNyYyk7CiAgTFBTVFIgbmRzdCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdCwgKGxlbitzbGVuKzIpKnNpemVvZihDSEFSKSk7CiAgaWYgKCFuZHN0KSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKnNpemVvZihDSEFSKSk7CiAgbmRzdFtsZW4rc2xlbisxXSA9IDA7CiAgcmV0dXJuIG5kc3Q7Cn0KCnN0YXRpYyBMUFdTVFIgUlBDUlQ0X3N0cmNvbmNhdFcoTFBXU1RSIGRzdCwgTFBDV1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW5XKGRzdCksIHNsZW4gPSBzdHJsZW5XKHNyYyk7CiAgTFBXU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoV0NIQVIpKTsKICBpZiAoIW5kc3QpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdCk7CiAgbmRzdFtsZW5dID0gJywnOwogIG1lbWNweShuZHN0K2xlbisxLCBzcmMsIHNsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgbmRzdFtsZW4rc2xlbisxXSA9IDA7CiAgcmV0dXJuIG5kc3Q7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlQSggTFBTVFIgT2JqVXVpZCwgTFBTVFIgUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIE5ldHdvcmtBZGRyLCBMUFNUUiBFbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIE9wdGlvbnMsIExQU1RSKiBTdHJpbmdCaW5kaW5nICkKewogIERXT1JEIGxlbiA9IDE7CiAgTFBTVFIgZGF0YTsKCiAgVFJBQ0UoICIoJXMsJXMsJXMsJXMsJXMsJXApXG4iLAogICAgICAgIGRlYnVnc3RyX2EoIE9ialV1aWQgKSwgZGVidWdzdHJfYSggUHJvdHNlcSApLAogICAgICAgIGRlYnVnc3RyX2EoIE5ldHdvcmtBZGRyICksIGRlYnVnc3RyX2EoIEVuZHBvaW50ICksCiAgICAgICAgZGVidWdzdHJfYSggT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nICk7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSBsZW4gKz0gc3RybGVuKE9ialV1aWQpICsgMTsKICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgbGVuICs9IHN0cmxlbihQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlbihOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgbGVuICs9IHN0cmxlbihFbmRwb2ludCkgKyAyOwogIGlmIChPcHRpb25zICYmICpPcHRpb25zKSBsZW4gKz0gc3RybGVuKE9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwogICpTdHJpbmdCaW5kaW5nID0gZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIE9ialV1aWQpOwogICAgKmRhdGErKyA9ICdAJzsKICB9CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIFByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIE5ldHdvcmtBZGRyKTsKCiAgaWYgKChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHx8CiAgICAgIChPcHRpb25zICYmICpPcHRpb25zKSkgewogICAgKmRhdGErKyA9ICdbJzsKICAgIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgRW5kcG9pbnQpOwogICAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgKmRhdGErKyA9ICcsJzsKICAgIH0KICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIE9wdGlvbnMpOwogICAgfQogICAgKmRhdGErKyA9ICddJzsKICB9CiAgKmRhdGEgPSAwOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VXKCBMUFdTVFIgT2JqVXVpZCwgTFBXU1RSIFByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIE5ldHdvcmtBZGRyLCBMUFdTVFIgRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIE9wdGlvbnMsIExQV1NUUiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQV1NUUiBkYXRhOwoKICBUUkFDRSgiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgIGRlYnVnc3RyX3coIE9ialV1aWQgKSwgZGVidWdzdHJfdyggUHJvdHNlcSApLAogICAgICAgZGVidWdzdHJfdyggTmV0d29ya0FkZHIgKSwgZGVidWdzdHJfdyggRW5kcG9pbnQgKSwKICAgICAgIGRlYnVnc3RyX3coIE9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyk7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSBsZW4gKz0gc3RybGVuVyhPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW5XKFByb3RzZXEpICsgMTsKICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSBsZW4gKz0gc3RybGVuVyhOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgbGVuICs9IHN0cmxlblcoRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlblcoT3B0aW9ucykgKyAyOwoKICBkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpKTsKICAqU3RyaW5nQmluZGluZyA9IGRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBQcm90c2VxKTsKICAgICpkYXRhKysgPSAnOic7CiAgfQogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE5ldHdvcmtBZGRyKTsKICB9CiAgaWYgKChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHx8CiAgICAgIChPcHRpb25zICYmICpPcHRpb25zKSkgewogICAgKmRhdGErKyA9ICdbJzsKICAgIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgRW5kcG9pbnQpOwogICAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgKmRhdGErKyA9ICcsJzsKICAgIH0KICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE9wdGlvbnMpOwogICAgfQogICAgKmRhdGErKyA9ICddJzsKICB9CiAgKmRhdGEgPSAwOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ1BhcnNlQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nUGFyc2VBKCBMUFNUUiBTdHJpbmdCaW5kaW5nLCBMUFNUUiAqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgKlByb3RzZXEsIExQU1RSICpOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgKkVuZHBvaW50LCBMUFNUUiAqT3B0aW9ucykKewogIENIQVIgKmRhdGEsICpuZXh0OwogIHN0YXRpYyBjb25zdCBjaGFyIGVwX29wdFtdID0gImVuZHBvaW50PSI7CgogIFRSQUNFKCIoJXMsJXAsJXAsJXAsJXAsJXApXG4iLCBkZWJ1Z3N0cl9hKFN0cmluZ0JpbmRpbmcpLAogICAgICAgT2JqVXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gTlVMTDsKICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBOVUxMOwogIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gTlVMTDsKICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IE5VTEw7CiAgaWYgKE9wdGlvbnMpICpPcHRpb25zID0gTlVMTDsKCiAgZGF0YSA9IFN0cmluZ0JpbmRpbmc7CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ0AnKTsKICBpZiAobmV4dCkgewogICAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnWycpOwogIGlmIChuZXh0KSB7CiAgICBDSEFSICpjbG9zZSwgKm9wdDsKCiAgICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogICAgY2xvc2UgPSBzdHJjaHIoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHIoZGF0YSwgJywnKTsKICAgICAgaWYgKCFuZXh0IHx8IG5leHQgPiBjbG9zZSkgbmV4dCA9IGNsb3NlOwogICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgIG9wdCA9IFJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICAgIGRhdGEgPSBuZXh0KzE7CgogICAgICAvKiBwYXJzZSBvcHRpb24gKi8KICAgICAgbmV4dCA9IHN0cmNocihvcHQsICc9Jyk7CiAgICAgIGlmICghbmV4dCkgewogICAgICAgIC8qIG5vdCBhbiBvcHRpb24sIG11c3QgYmUgYW4gZW5kcG9pbnQgKi8KICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgKkVuZHBvaW50ID0gb3B0OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJuY21wKG9wdCwgZXBfb3B0LCBzdHJsZW4oZXBfb3B0KSkgPT0gMCkgewogICAgICAgICAgLyogZW5kcG9pbnQgb3B0aW9uICovCiAgICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgICAqRW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShuZXh0KzEpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbmV0d29yayBvcHRpb24gKi8KICAgICAgICAgIGlmICgqT3B0aW9ucykgewogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgICAgICAgICpPcHRpb25zID0gUlBDUlQ0X3N0cmNvbmNhdEEoKk9wdGlvbnMsIG9wdCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgICB9IGVsc2UgCgkgICAgKk9wdGlvbnMgPSBvcHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGF0YSA9IGNsb3NlKzE7CiAgICBpZiAoKmRhdGEpIGdvdG8gZmFpbDsKICB9CiAgZWxzZSBpZiAoTmV0d29ya0FkZHIpIAogICAgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoZGF0YSk7CgogIHJldHVybiBSUENfU19PSzsKCmZhaWw6CiAgaWYgKE9ialV1aWQpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopUHJvdHNlcSk7CiAgaWYgKE5ldHdvcmtBZGRyKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9wdGlvbnMpOwogIHJldHVybiBSUENfU19JTlZBTElEX1NUUklOR19CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nUGFyc2VXKCBMUFdTVFIgU3RyaW5nQmluZGluZywgTFBXU1RSICpPYmpVdWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgKlByb3RzZXEsIExQV1NUUiAqTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiAqRW5kcG9pbnQsIExQV1NUUiAqT3B0aW9ucykKewogIFdDSEFSICpkYXRhLCAqbmV4dDsKICBzdGF0aWMgY29uc3QgV0NIQVIgZXBfb3B0W10gPSB7J2UnLCduJywnZCcsJ3AnLCdvJywnaScsJ24nLCd0JywnPScsMH07CgogIFRSQUNFKCIoJXMsJXAsJXAsJXAsJXAsJXApXG4iLCBkZWJ1Z3N0cl93KFN0cmluZ0JpbmRpbmcpLAogICAgICAgT2JqVXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gTlVMTDsKICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBOVUxMOwogIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gTlVMTDsKICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IE5VTEw7CiAgaWYgKE9wdGlvbnMpICpPcHRpb25zID0gTlVMTDsKCiAgZGF0YSA9IFN0cmluZ0JpbmRpbmc7CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICdAJyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJzonKTsKICBpZiAobmV4dCkgewogICAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnWycpOwogIGlmIChuZXh0KSB7CiAgICBXQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICAgIGNsb3NlID0gc3RyY2hyVyhkYXRhLCAnXScpOwogICAgaWYgKCFjbG9zZSkgZ290byBmYWlsOwoKICAgIC8qIHRva2VuaXplIG9wdGlvbnMgKi8KICAgIHdoaWxlIChkYXRhIDwgY2xvc2UpIHsKICAgICAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJywnKTsKICAgICAgaWYgKCFuZXh0IHx8IG5leHQgPiBjbG9zZSkgbmV4dCA9IGNsb3NlOwogICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgIG9wdCA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICAgIGRhdGEgPSBuZXh0KzE7CgogICAgICAvKiBwYXJzZSBvcHRpb24gKi8KICAgICAgbmV4dCA9IHN0cmNoclcob3B0LCAnPScpOwogICAgICBpZiAoIW5leHQpIHsKICAgICAgICAvKiBub3QgYW4gb3B0aW9uLCBtdXN0IGJlIGFuIGVuZHBvaW50ICovCiAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICpFbmRwb2ludCA9IG9wdDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RybmNtcFcob3B0LCBlcF9vcHQsIHN0cmxlblcoZXBfb3B0KSkgPT0gMCkgewogICAgICAgICAgLyogZW5kcG9pbnQgb3B0aW9uICovCiAgICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgICAqRW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwVyhuZXh0KzEpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbmV0d29yayBvcHRpb24gKi8KICAgICAgICAgIGlmICgqT3B0aW9ucykgewogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgICAgICAgICpPcHRpb25zID0gUlBDUlQ0X3N0cmNvbmNhdFcoKk9wdGlvbnMsIG9wdCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgICB9IGVsc2UgCgkgICAgKk9wdGlvbnMgPSBvcHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGF0YSA9IGNsb3NlKzE7CiAgICBpZiAoKmRhdGEpIGdvdG8gZmFpbDsKICB9IGVsc2UgaWYgKE5ldHdvcmtBZGRyKSAKICAgICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBXKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlVyhPYmpVdWlkKTsKICBpZiAoUHJvdHNlcSkgUnBjU3RyaW5nRnJlZVcoUHJvdHNlcSk7CiAgaWYgKE5ldHdvcmtBZGRyKSBScGNTdHJpbmdGcmVlVyhOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlVyhFbmRwb2ludCk7CiAgaWYgKE9wdGlvbnMpIFJwY1N0cmluZ0ZyZWVXKE9wdGlvbnMpOwogIHJldHVybiBSUENfU19JTlZBTElEX1NUUklOR19CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0ZyZWUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0ZyZWUoIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBUUkFDRSgiKCVwKSA9ICVwXG4iLCBCaW5kaW5nLCAqQmluZGluZyk7CiAgc3RhdHVzID0gUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKCpCaW5kaW5nKTsKICBpZiAoc3RhdHVzID09IFJQQ19TX09LKSAqQmluZGluZyA9IDA7CiAgcmV0dXJuIHN0YXR1czsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1ZlY3RvckZyZWUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1ZlY3RvckZyZWUoIFJQQ19CSU5ESU5HX1ZFQ1RPUioqIEJpbmRpbmdWZWN0b3IgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgdW5zaWduZWQgbG9uZyBjOwoKICBUUkFDRSgiKCVwKVxuIiwgQmluZGluZ1ZlY3Rvcik7CiAgZm9yIChjPTA7IGM8KCpCaW5kaW5nVmVjdG9yKS0+Q291bnQ7IGMrKykgewogICAgc3RhdHVzID0gUnBjQmluZGluZ0ZyZWUoJigqQmluZGluZ1ZlY3RvciktPkJpbmRpbmdIW2NdKTsKICB9CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKkJpbmRpbmdWZWN0b3IpOwogICpCaW5kaW5nVmVjdG9yID0gTlVMTDsKICByZXR1cm4gUlBDX1NfT0s7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFPYmplY3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0lucU9iamVjdCggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSgiKCVwLCVwKSA9ICVzXG4iLCBCaW5kaW5nLCBPYmplY3RVdWlkLCBkZWJ1Z3N0cl9ndWlkKCZiaW5kLT5PYmplY3RVdWlkKSk7CiAgbWVtY3B5KE9iamVjdFV1aWQsICZiaW5kLT5PYmplY3RVdWlkLCBzaXplb2YoVVVJRCkpOwogIHJldHVybiBSUENfU19PSzsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldE9iamVjdCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nU2V0T2JqZWN0KCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCApCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCIoJXAsJXMpXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9ndWlkKE9iamVjdFV1aWQpKTsKICBpZiAoYmluZC0+c2VydmVyKSByZXR1cm4gUlBDX1NfV1JPTkdfS0lORF9PRl9CSU5ESU5HOwogIHJldHVybiBSUENSVDRfU2V0QmluZGluZ09iamVjdChCaW5kaW5nLCBPYmplY3RVdWlkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ0EgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nQSggTFBTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIExQU1RSIE9iamVjdFV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9uczsKICBVVUlEIFV1aWQ7CgogIFRSQUNFKCIoJXMsJXApXG4iLCBkZWJ1Z3N0cl9hKFN0cmluZ0JpbmRpbmcpLCBCaW5kaW5nKTsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ1BhcnNlQShTdHJpbmdCaW5kaW5nLCAmT2JqZWN0VXVpZCwgJlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZOZXR3b3JrQWRkciwgJkVuZHBvaW50LCAmT3B0aW9ucyk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gVXVpZEZyb21TdHJpbmdBKE9iamVjdFV1aWQsICZVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9DcmVhdGVCaW5kaW5nQSgmYmluZCwgRkFMU0UsIFByb3RzZXEpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfU2V0QmluZGluZ09iamVjdChiaW5kLCAmVXVpZCk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdBKGJpbmQsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9wdGlvbnMpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZOZXR3b3JrQWRkcik7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmUHJvdHNlcSk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spIAogICAgKkJpbmRpbmcgPSAoUlBDX0JJTkRJTkdfSEFORExFKWJpbmQ7CiAgZWxzZSAKICAgIFJQQ1JUNF9EZXN0cm95QmluZGluZyhiaW5kKTsKCiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyggTFBXU1RSIFN0cmluZ0JpbmRpbmcsIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gTlVMTDsKICBMUFdTVFIgT2JqZWN0VXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX3coU3RyaW5nQmluZGluZyksIEJpbmRpbmcpOwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nUGFyc2VXKFN0cmluZ0JpbmRpbmcsICZPYmplY3RVdWlkLCAmUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ldHdvcmtBZGRyLCAmRW5kcG9pbnQsICZPcHRpb25zKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBVdWlkRnJvbVN0cmluZ1coT2JqZWN0VXVpZCwgJlV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NyZWF0ZUJpbmRpbmdXKCZiaW5kLCBGQUxTRSwgUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ1coYmluZCwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZVcoJk9wdGlvbnMpOwogIFJwY1N0cmluZ0ZyZWVXKCZFbmRwb2ludCk7CiAgUnBjU3RyaW5nRnJlZVcoJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlVygmUHJvdHNlcSk7CiAgUnBjU3RyaW5nRnJlZVcoJk9iamVjdFV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgKkJpbmRpbmcgPSAoUlBDX0JJTkRJTkdfSEFORExFKWJpbmQ7CiAgZWxzZQogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQSggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIExQU1RSKiBTdHJpbmdCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKICBMUFNUUiBPYmplY3RVdWlkOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgQmluZGluZywgU3RyaW5nQmluZGluZyk7CgogIHJldCA9IFV1aWRUb1N0cmluZ0EoJmJpbmQtPk9iamVjdFV1aWQsICh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlQShPYmplY3RVdWlkLCBiaW5kLT5Qcm90c2VxLCBiaW5kLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmluZC0+RW5kcG9pbnQsIE5VTEwsIFN0cmluZ0JpbmRpbmcpOwoKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgcmV0dXJuIHJldDsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1coIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBMUFdTVFIqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgTFBTVFIgc3RyID0gTlVMTDsKICBUUkFDRSgiKCVwLCVwKVxuIiwgQmluZGluZywgU3RyaW5nQmluZGluZyk7CiAgcmV0ID0gUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ0EoQmluZGluZywgJnN0cik7CiAgKlN0cmluZ0JpbmRpbmcgPSBSUENSVDRfc3RyZHVwQXRvVyhzdHIpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJnN0cik7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjQmluZGluZ1NldEFzeW5jIChSUENSVDQuQCkKICogTk9URVMKICogIEV4aXN0cyBpbiB3aW45eCBhbmQgd2luTlQsIGJ1dCB3aXRoIGRpZmZlcmVudCBudW1iZXIgb2YgYXJndW1lbnRzCiAqICAoOXggdmVyc2lvbiBoYXMgMyBhcmd1bWVudHMsIE5UIGhhcyAyKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjQmluZGluZ1NldEFzeW5jKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0JMT0NLSU5HX0ZOIEJsb2NraW5nRm4pCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCAiKCVwLCVwKTogc3R1YlxuIiwgQmluZGluZywgQmxvY2tpbmdGbiApOwoKICBiaW5kLT5CbG9ja2luZ0ZuID0gQmxvY2tpbmdGbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9Cg==