LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJudHN0YXR1cy5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAicnBjX3NlcnZlci5oIgojaW5jbHVkZSAicnBjX21pc2MuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCiNpbmNsdWRlICJycGNfZGVmcy5oIgoKI2RlZmluZSBNQVhfVEhSRUFEUyAxMjgKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjUGFja2V0CnsKICBzdHJ1Y3QgX1JwY1BhY2tldCogbmV4dDsKICBzdHJ1Y3QgX1JwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUnBjUGt0SGRyKiBoZHI7CiAgUlBDX01FU1NBR0UqIG1zZzsKfSBScGNQYWNrZXQ7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjT2JqVHlwZU1hcAp7CiAgLyogRklYTUU6IGEgaGFzaCB0YWJsZSB3b3VsZCBiZSBiZXR0ZXIuICovCiAgc3RydWN0IF9ScGNPYmpUeXBlTWFwICpuZXh0OwogIFVVSUQgT2JqZWN0OwogIFVVSUQgVHlwZTsKfSBScGNPYmpUeXBlTWFwOwoKc3RhdGljIFJwY09ialR5cGVNYXAgKlJwY09ialR5cGVNYXBzOwoKc3RhdGljIFJwY1NlcnZlclByb3RzZXEqIHByb3RzZXFzOwpzdGF0aWMgUnBjU2VydmVySW50ZXJmYWNlKiBpZnM7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzZXJ2ZXJfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIHNlcnZlcl9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZzZXJ2ZXJfY3MsCiAgICB7ICZzZXJ2ZXJfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJnNlcnZlcl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgMCwgKERXT1JEKShfX0ZJTEVfXyAiOiBzZXJ2ZXJfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jcyA9IHsgJnNlcnZlcl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgbGlzdGVuX2NzX2RlYnVnID0KewogICAgMCwgMCwgJmxpc3Rlbl9jcywKICAgIHsgJmxpc3Rlbl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmbGlzdGVuX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAwLCAoRFdPUkQpKF9fRklMRV9fICI6IGxpc3Rlbl9jcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gbGlzdGVuX2NzID0geyAmbGlzdGVuX2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIEJPT0wgc3RkX2xpc3RlbjsKc3RhdGljIExPTkcgbGlzdGVuX2NvdW50ID0gLTE7CnN0YXRpYyBIQU5ETEUgbWdyX2V2ZW50LCBzZXJ2ZXJfdGhyZWFkOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gc3BhY2tldF9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgc3BhY2tldF9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZzcGFja2V0X2NzLAogICAgeyAmc3BhY2tldF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmc3BhY2tldF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgMCwgKERXT1JEKShfX0ZJTEVfXyAiOiBzcGFja2V0X2NzIikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzcGFja2V0X2NzID0geyAmc3BhY2tldF9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBScGNQYWNrZXQqIHNwYWNrZXRfaGVhZDsKc3RhdGljIFJwY1BhY2tldCogc3BhY2tldF90YWlsOwpzdGF0aWMgSEFORExFIHNlcnZlcl9zZW07CgpzdGF0aWMgRFdPUkQgd29ya2VyX2NvdW50LCB3b3JrZXJfZnJlZSwgd29ya2VyX3RsczsKCnN0YXRpYyBVVUlEIHV1aWRfbmlsOwoKaW5saW5lIHN0YXRpYyBScGNPYmpUeXBlTWFwICpMb29rdXBPYmpUeXBlTWFwKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICpyc2x0ID0gUnBjT2JqVHlwZU1hcHM7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgd2hpbGUgKHJzbHQpIHsKICAgIGlmICghIFV1aWRDb21wYXJlKE9ialV1aWQsICZyc2x0LT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcnNsdCA9IHJzbHQtPm5leHQ7CiAgfQoKICByZXR1cm4gcnNsdDsKfQoKaW5saW5lIHN0YXRpYyBVVUlEICpMb29rdXBPYmpUeXBlKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICptYXAgPSBMb29rdXBPYmpUeXBlTWFwKE9ialV1aWQpOwogIGlmIChtYXApCiAgICByZXR1cm4gJm1hcC0+VHlwZTsKICBlbHNlCiAgICByZXR1cm4gJnV1aWRfbmlsOwp9CgpzdGF0aWMgUnBjU2VydmVySW50ZXJmYWNlKiBSUENSVDRfZmluZF9pbnRlcmZhY2UoVVVJRCogb2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSKiBpZl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgY2hlY2tfb2JqZWN0KQp7CiAgVVVJRCogTWdyVHlwZSA9IE5VTEw7CiAgUnBjU2VydmVySW50ZXJmYWNlKiBjaWYgPSBOVUxMOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBpZiAoY2hlY2tfb2JqZWN0KQogICAgTWdyVHlwZSA9IExvb2t1cE9ialR5cGUob2JqZWN0KTsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBjaWYgPSBpZnM7CiAgd2hpbGUgKGNpZikgewogICAgaWYgKCFtZW1jbXAoaWZfaWQsICZjaWYtPklmLT5JbnRlcmZhY2VJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpICYmCiAgICAgICAgKGNoZWNrX29iamVjdCA9PSBGQUxTRSB8fCBVdWlkRXF1YWwoTWdyVHlwZSwgJmNpZi0+TWdyVHlwZVV1aWQsICZzdGF0dXMpKSAmJgogICAgICAgIChzdGRfbGlzdGVuIHx8IChjaWYtPkZsYWdzICYgUlBDX0lGX0FVVE9MSVNURU4pKSkgYnJlYWs7CiAgICBjaWYgPSBjaWYtPk5leHQ7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIFRSQUNFKCJyZXR1cm5pbmcgJXAgZm9yICVzXG4iLCBjaWYsIGRlYnVnc3RyX2d1aWQob2JqZWN0KSk7CiAgcmV0dXJuIGNpZjsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3B1c2hfcGFja2V0KFJwY1BhY2tldCogcGFja2V0KQp7CiAgcGFja2V0LT5uZXh0ID0gTlVMTDsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc3BhY2tldF9jcyk7CiAgaWYgKHNwYWNrZXRfdGFpbCkgewogICAgc3BhY2tldF90YWlsLT5uZXh0ID0gcGFja2V0OwogICAgc3BhY2tldF90YWlsID0gcGFja2V0OwogIH0gZWxzZSB7CiAgICBzcGFja2V0X2hlYWQgPSBwYWNrZXQ7CiAgICBzcGFja2V0X3RhaWwgPSBwYWNrZXQ7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzcGFja2V0X2NzKTsKfQoKc3RhdGljIFJwY1BhY2tldCogUlBDUlQ0X3BvcF9wYWNrZXQodm9pZCkKewogIFJwY1BhY2tldCogcGFja2V0OwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzcGFja2V0X2NzKTsKICBwYWNrZXQgPSBzcGFja2V0X2hlYWQ7CiAgaWYgKHBhY2tldCkgewogICAgc3BhY2tldF9oZWFkID0gcGFja2V0LT5uZXh0OwogICAgaWYgKCFzcGFja2V0X2hlYWQpIHNwYWNrZXRfdGFpbCA9IE5VTEw7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzcGFja2V0X2NzKTsKICBpZiAocGFja2V0KSBwYWNrZXQtPm5leHQgPSBOVUxMOwogIHJldHVybiBwYWNrZXQ7Cn0KCnR5cGVkZWYgc3RydWN0IHsKICBQUlBDX01FU1NBR0UgbXNnOwogIHZvaWQqIGJ1ZjsKfSBwYWNrZXRfc3RhdGU7CgpzdGF0aWMgV0lORV9FWENFUFRJT05fRklMVEVSKHJwY19maWx0ZXIpCnsKICBwYWNrZXRfc3RhdGUqIHN0YXRlOwogIFBSUENfTUVTU0FHRSBtc2c7CiAgc3RhdGUgPSBUbHNHZXRWYWx1ZSh3b3JrZXJfdGxzKTsKICBtc2cgPSBzdGF0ZS0+bXNnOwogIGlmIChtc2ctPkJ1ZmZlciAhPSBzdGF0ZS0+YnVmKSBJX1JwY0ZyZWVCdWZmZXIobXNnKTsKICBtc2ctPlJwY0ZsYWdzIHw9IFdJTkVfUlBDRkxBR19FWENFUFRJT047CiAgbXNnLT5CdWZmZXJMZW5ndGggPSBzaXplb2YoRFdPUkQpOwogIElfUnBjR2V0QnVmZmVyKG1zZyk7CiAgKihEV09SRCopbXNnLT5CdWZmZXIgPSBHZXRFeGNlcHRpb25Db2RlKCk7CiAgV0FSTigiZXhjZXB0aW9uIGNhdWdodCB3aXRoIGNvZGUgMHglMDhseCA9ICVsZFxuIiwgKihEV09SRCopbXNnLT5CdWZmZXIsICooRFdPUkQqKW1zZy0+QnVmZmVyKTsKICBUUkFDRSgicmV0dXJuaW5nIGZhaWx1cmUgcGFja2V0XG4iKTsKICByZXR1cm4gRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3Byb2Nlc3NfcGFja2V0KFJwY0Nvbm5lY3Rpb24qIGNvbm4sIFJwY1BrdEhkciogaGRyLCBSUENfTUVTU0FHRSogbXNnKQp7CiAgUnBjU2VydmVySW50ZXJmYWNlKiBzaWY7CiAgUlBDX0RJU1BBVENIX0ZVTkNUSU9OIGZ1bmM7CiAgcGFja2V0X3N0YXRlIHN0YXRlOwogIFVVSUQgKm9iamVjdF91dWlkOwogIFJwY1BrdEhkciAqcmVzcG9uc2U7CiAgdm9pZCAqYnVmID0gbXNnLT5CdWZmZXI7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIHN0YXRlLm1zZyA9IG1zZzsKICBzdGF0ZS5idWYgPSBidWY7CiAgVGxzU2V0VmFsdWUod29ya2VyX3RscywgJnN0YXRlKTsKCiAgc3dpdGNoIChoZHItPmNvbW1vbi5wdHlwZSkgewogICAgY2FzZSBQS1RfQklORDoKICAgICAgVFJBQ0UoImdvdCBiaW5kIHBhY2tldFxuIik7CgogICAgICAvKiBGSVhNRTogZG8gbW9yZSBjaGVja3MhICovCiAgICAgIGlmIChoZHItPmJpbmQubWF4X3RzaXplIDwgUlBDX01JTl9QQUNLRVRfU0laRSB8fAogICAgICAgICAgIVV1aWRJc05pbCgmY29ubi0+QWN0aXZlSW50ZXJmYWNlLlN5bnRheEdVSUQsICZzdGF0dXMpKSB7CiAgICAgICAgVFJBQ0UoInBhY2tldCBzaXplIGxlc3MgdGhhbiBtaW4gc2l6ZSwgb3IgYWN0aXZlIGludGVyZmFjZSBzeW50YXggZ3VpZCBub24tbnVsbFxuIik7CiAgICAgICAgc2lmID0gTlVMTDsKICAgICAgfSBlbHNlIHsKICAgICAgICBzaWYgPSBSUENSVDRfZmluZF9pbnRlcmZhY2UoTlVMTCwgJmhkci0+YmluZC5hYnN0cmFjdCwgRkFMU0UpOwogICAgICB9CiAgICAgIGlmIChzaWYgPT0gTlVMTCkgewogICAgICAgIFRSQUNFKCJyZWplY3RpbmcgYmluZCByZXF1ZXN0IG9uIGNvbm5lY3Rpb24gJXBcbiIsIGNvbm4pOwogICAgICAgIC8qIFJlcG9ydCBmYWlsdXJlIHRvIGNsaWVudC4gKi8KICAgICAgICByZXNwb25zZSA9IFJQQ1JUNF9CdWlsZEJpbmROYWNrSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1ZFUl9NQUpPUiwgUlBDX1ZFUl9NSU5PUik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoImFjY2VwdGluZyBiaW5kIHJlcXVlc3Qgb24gY29ubmVjdGlvbiAlcFxuIiwgY29ubik7CgogICAgICAgIC8qIGFjY2VwdC4gKi8KICAgICAgICByZXNwb25zZSA9IFJQQ1JUNF9CdWlsZEJpbmRBY2tIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19NQVhfUEFDS0VUX1NJWkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPkVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRVNVTFRfQUNDRVBULCBOT19SRUFTT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzaWYtPklmLT5UcmFuc2ZlclN5bnRheCk7CgogICAgICAgIC8qIHNhdmUgdGhlIGludGVyZmFjZSBmb3IgbGF0ZXIgdXNlICovCiAgICAgICAgY29ubi0+QWN0aXZlSW50ZXJmYWNlID0gaGRyLT5iaW5kLmFic3RyYWN0OwogICAgICAgIGNvbm4tPk1heFRyYW5zbWlzc2lvblNpemUgPSBoZHItPmJpbmQubWF4X3RzaXplOwogICAgICB9CgogICAgICBpZiAoUlBDUlQ0X1NlbmQoY29ubiwgcmVzcG9uc2UsIE5VTEwsIDApICE9IFJQQ19TX09LKQogICAgICAgIGdvdG8gZmFpbDsKCiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUEtUX1JFUVVFU1Q6CiAgICAgIFRSQUNFKCJnb3QgcmVxdWVzdCBwYWNrZXRcbiIpOwoKICAgICAgLyogZmFpbCBpZiB0aGUgY29ubmVjdGlvbiBpc24ndCBib3VuZCB3aXRoIGFuIGludGVyZmFjZSAqLwogICAgICBpZiAoVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICByZXNwb25zZSA9IFJQQ1JUNF9CdWlsZEZhdWx0SGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKCiAgICAgICAgUlBDUlQ0X1NlbmQoY29ubiwgcmVzcG9uc2UsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICBpZiAoaGRyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX09CSkVDVF9VVUlEKSB7CiAgICAgICAgb2JqZWN0X3V1aWQgPSAoVVVJRCopKCZoZHItPnJlcXVlc3QgKyAxKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvYmplY3RfdXVpZCA9IE5VTEw7CiAgICAgIH0KCiAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShvYmplY3RfdXVpZCwgJmNvbm4tPkFjdGl2ZUludGVyZmFjZSwgVFJVRSk7CiAgICAgIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24gPSBzaWYtPklmOwogICAgICAvKiBjb3B5IHRoZSBlbmRwb2ludCB2ZWN0b3IgZnJvbSBzaWYgdG8gbXNnIHNvIHRoYXQgbWlkbC1nZW5lcmF0ZWQgY29kZSB3aWxsIHVzZSBpdCAqLwogICAgICBtc2ctPk1hbmFnZXJFcHYgPSBzaWYtPk1nckVwdjsKICAgICAgaWYgKG9iamVjdF91dWlkICE9IE5VTEwpIHsKICAgICAgICBSUENSVDRfU2V0QmluZGluZ09iamVjdChtc2ctPkhhbmRsZSwgb2JqZWN0X3V1aWQpOwogICAgICB9CgogICAgICAvKiBmaW5kIGRpc3BhdGNoIGZ1bmN0aW9uICovCiAgICAgIG1zZy0+UHJvY051bSA9IGhkci0+cmVxdWVzdC5vcG51bTsKICAgICAgaWYgKHNpZi0+RmxhZ3MgJiBSUENfSUZfT0xFKSB7CiAgICAgICAgLyogbmF0aXZlIG9sZTMyIGFsd2F5cyBnaXZlcyB1cyBhIGRpc3BhdGNoIHRhYmxlIHdpdGggYSBzaW5nbGUgZW50cnkKICAgICAgICAgKiAoSSBhc3N1bWUgdGhhdCdzIGEgd3JhcHBlciBmb3IgSVJwY1N0dWJCdWZmZXI6Okludm9rZSkgKi8KICAgICAgICBmdW5jID0gKnNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG1zZy0+UHJvY051bSA+PSBzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlQ291bnQpIHsKICAgICAgICAgIEVSUigiaW52YWxpZCBwcm9jbnVtXG4iKTsKICAgICAgICAgIGZ1bmMgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBmdW5jID0gc2lmLT5JZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZVttc2ctPlByb2NOdW1dOwogICAgICB9CgogICAgICAvKiBwdXQgaW4gdGhlIGRyZXAuIEZJWE1FOiBpcyB0aGlzIG1vcmUgdW5pdmVyc2FsbHkgYXBwbGljYWJsZT8KICAgICAgICAgcGVyaGFwcyB3ZSBzaG91bGQgbW92ZSB0aGlzIG91dHdhcmQuLi4gKi8KICAgICAgbXNnLT5EYXRhUmVwcmVzZW50YXRpb24gPSAKICAgICAgICBNQUtFTE9ORyggTUFLRVdPUkQoaGRyLT5jb21tb24uZHJlcFswXSwgaGRyLT5jb21tb24uZHJlcFsxXSksCiAgICAgICAgICAgICAgICAgIE1BS0VXT1JEKGhkci0+Y29tbW9uLmRyZXBbMl0sIGhkci0+Y29tbW9uLmRyZXBbM10pKTsKCiAgICAgIC8qIGRpc3BhdGNoICovCiAgICAgIF9fVFJZIHsKICAgICAgICBpZiAoZnVuYykgZnVuYyhtc2cpOwogICAgICB9IF9fRVhDRVBUKHJwY19maWx0ZXIpIHsKICAgICAgICAvKiBmYWlsdXJlIHBhY2tldCB3YXMgY3JlYXRlZCBpbiBycGNfZmlsdGVyICovCiAgICAgIH0gX19FTkRUUlkKCiAgICAgIC8qIHNlbmQgcmVzcG9uc2UgcGFja2V0ICovCiAgICAgIElfUnBjU2VuZChtc2cpOwoKICAgICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IE5VTEw7CgogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlXG4iKTsKICAgICAgYnJlYWs7CiAgfQoKZmFpbDoKICAvKiBjbGVhbiB1cCAqLwogIGlmIChtc2ctPkJ1ZmZlciA9PSBidWYpIG1zZy0+QnVmZmVyID0gTlVMTDsKICBUUkFDRSgiZnJlZWluZyBCdWZmZXI9JXBcbiIsIGJ1Zik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmKTsKICBSUENSVDRfRGVzdHJveUJpbmRpbmcobXNnLT5IYW5kbGUpOwogIG1zZy0+SGFuZGxlID0gMDsKICBJX1JwY0ZyZWVCdWZmZXIobXNnKTsKICBtc2ctPkJ1ZmZlciA9IE5VTEw7CiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKICBUbHNTZXRWYWx1ZSh3b3JrZXJfdGxzLCBOVUxMKTsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF93b3JrZXJfdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgRFdPUkQgb2JqOwogIFJwY1BhY2tldCogcGt0OwoKICBmb3IgKDs7KSB7CiAgICAvKiBpZGxlIHRpbWVvdXQgYWZ0ZXIgNXMgKi8KICAgIG9iaiA9IFdhaXRGb3JTaW5nbGVPYmplY3Qoc2VydmVyX3NlbSwgNTAwMCk7CiAgICBpZiAob2JqID09IFdBSVRfVElNRU9VVCkgewogICAgICAvKiBpZiBhbm90aGVyIGlkbGUgdGhyZWFkIGV4aXN0LCBzZWxmLWRlc3RydWN0ICovCiAgICAgIGlmICh3b3JrZXJfZnJlZSA+IDEpIGJyZWFrOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIHBrdCA9IFJQQ1JUNF9wb3BfcGFja2V0KCk7CiAgICBpZiAoIXBrdCkgY29udGludWU7CiAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmd29ya2VyX2ZyZWUpOwogICAgZm9yICg7OykgewogICAgICBSUENSVDRfcHJvY2Vzc19wYWNrZXQocGt0LT5jb25uLCBwa3QtPmhkciwgcGt0LT5tc2cpOwogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwa3QpOwogICAgICAvKiB0cnkgdG8gZ3JhYiBhbm90aGVyIHBhY2tldCBoZXJlIHdpdGhvdXQgd2FpdGluZwogICAgICAgKiBvbiB0aGUgc2VtYXBob3JlLCBpbiBjYXNlIGl0IGhpdHMgbWF4ICovCiAgICAgIHBrdCA9IFJQQ1JUNF9wb3BfcGFja2V0KCk7CiAgICAgIGlmICghcGt0KSBicmVhazsKICAgICAgLyogZGVjcmVtZW50IHNlbWFwaG9yZSAqLwogICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHNlcnZlcl9zZW0sIDApOwogICAgfQogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJndvcmtlcl9mcmVlKTsKICB9CiAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJndvcmtlcl9mcmVlKTsKICBJbnRlcmxvY2tlZERlY3JlbWVudCgmd29ya2VyX2NvdW50KTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X2NyZWF0ZV93b3JrZXJfaWZfbmVlZGVkKHZvaWQpCnsKICBpZiAoIXdvcmtlcl9mcmVlICYmIHdvcmtlcl9jb3VudCA8IE1BWF9USFJFQURTKSB7CiAgICBIQU5ETEUgdGhyZWFkOwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJndvcmtlcl9jb3VudCk7CiAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmd29ya2VyX2ZyZWUpOwogICAgdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIFJQQ1JUNF93b3JrZXJfdGhyZWFkLCBOVUxMLCAwLCBOVUxMKTsKICAgIGlmICh0aHJlYWQpIENsb3NlSGFuZGxlKHRocmVhZCk7CiAgICBlbHNlIHsKICAgICAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJndvcmtlcl9mcmVlKTsKICAgICAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJndvcmtlcl9jb3VudCk7CiAgICB9CiAgfQp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X2lvX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIFJwY0Nvbm5lY3Rpb24qIGNvbm4gPSAoUnBjQ29ubmVjdGlvbiopdGhlX2FyZzsKICBScGNQa3RIZHIgKmhkcjsKICBScGNCaW5kaW5nICpwYmluZDsKICBSUENfTUVTU0FHRSAqbXNnOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFJwY1BhY2tldCAqcGFja2V0OwoKICBUUkFDRSgiKCVwKVxuIiwgY29ubik7CgogIGZvciAoOzspIHsKICAgIG1zZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUlBDX01FU1NBR0UpKTsKCiAgICAvKiBjcmVhdGUgdGVtcG9yYXJ5IGJpbmRpbmcgZm9yIGRpc3BhdGNoLCBpdCB3aWxsIGJlIGZyZWVkIGluCiAgICAgKiBSUENSVDRfcHJvY2Vzc19wYWNrZXQgKi8KICAgIFJQQ1JUNF9NYWtlQmluZGluZygmcGJpbmQsIGNvbm4pOwogICAgbXNnLT5IYW5kbGUgPSAoUlBDX0JJTkRJTkdfSEFORExFKXBiaW5kOwoKICAgIHN0YXR1cyA9IFJQQ1JUNF9SZWNlaXZlKGNvbm4sICZoZHIsIG1zZyk7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICAgIFdBUk4oInJlY2VpdmUgZmFpbGVkIHdpdGggZXJyb3IgJWx4XG4iLCBzdGF0dXMpOwogICAgICBicmVhazsKICAgIH0KCiNpZiAwCiAgICBSUENSVDRfcHJvY2Vzc19wYWNrZXQoY29ubiwgaGRyLCBtc2cpOwojZWxzZQogICAgcGFja2V0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihScGNQYWNrZXQpKTsKICAgIHBhY2tldC0+Y29ubiA9IGNvbm47CiAgICBwYWNrZXQtPmhkciA9IGhkcjsKICAgIHBhY2tldC0+bXNnID0gbXNnOwogICAgUlBDUlQ0X2NyZWF0ZV93b3JrZXJfaWZfbmVlZGVkKCk7CiAgICBSUENSVDRfcHVzaF9wYWNrZXQocGFja2V0KTsKICAgIFJlbGVhc2VTZW1hcGhvcmUoc2VydmVyX3NlbSwgMSwgTlVMTCk7CiNlbmRpZgogICAgbXNnID0gTlVMTDsKICB9CiAgaWYgKG1zZykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oY29ubik7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9uZXdfY2xpZW50KFJwY0Nvbm5lY3Rpb24qIGNvbm4pCnsKICBIQU5ETEUgdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIFJQQ1JUNF9pb190aHJlYWQsIGNvbm4sIDAsIE5VTEwpOwogIGlmICghdGhyZWFkKSB7CiAgICBEV09SRCBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgIEVSUigiZmFpbGVkIHRvIGNyZWF0ZSB0aHJlYWQsIGVycm9yPSUwOGx4XG4iLCBlcnIpOwogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKGNvbm4pOwogIH0KICAvKiB3ZSBjb3VsZCBzZXQgY29ubi0+dGhyZWFkLCBidXQgdGhlbiB3ZSdkIGhhdmUgdG8gbWFrZSB0aGUgaW9fdGhyZWFkIHdhaXQKICAgKiBmb3IgdGhhdCwgb3RoZXJ3aXNlIHRoZSB0aHJlYWQgbWlnaHQgZmluaXNoLCBkZXN0cm95IHRoZSBjb25uZWN0aW9uLCBhbmQKICAgKiBmcmVlIHRoZSBtZW1vcnkgd2UnZCB3cml0ZSB0byBiZWZvcmUgd2UgZGlkLCBjYXVzaW5nIGNyYXNoZXMgYW5kIHN0dWZmIC0KICAgKiBzbyBsZXQncyBpbXBsZW1lbnQgdGhhdCBsYXRlciwgd2hlbiB3ZSByZWFsbHkgbmVlZCBjb25uLT50aHJlYWQgKi8KCiAgQ2xvc2VIYW5kbGUoIHRocmVhZCApOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X3NlcnZlcl90aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBIQU5ETEUgbV9ldmVudCA9IG1ncl9ldmVudCwgYl9oYW5kbGU7CiAgSEFORExFICpvYmpzID0gTlVMTDsKICBEV09SRCBjb3VudCwgcmVzOwogIFJwY1NlcnZlclByb3RzZXEqIGNwczsKICBScGNDb25uZWN0aW9uKiBjb25uOwogIFJwY0Nvbm5lY3Rpb24qIGNjb25uOwoKICBUUkFDRSgiKHRoZV9hcmcgPT0gXiVwKVxuIiwgdGhlX2FyZyk7CgogIGZvciAoOzspIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgLyogb3BlbiBhbmQgY291bnQgY29ubmVjdGlvbnMgKi8KICAgIGNvdW50ID0gMTsKICAgIGNwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKGNwcykgewogICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICB3aGlsZSAoY29ubikgewogICAgICAgIFJQQ1JUNF9PcGVuQ29ubmVjdGlvbihjb25uKTsKICAgICAgICBpZiAoY29ubi0+b3ZsLmhFdmVudCkgY291bnQrKzsKICAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgfQogICAgICBjcHMgPSBjcHMtPk5leHQ7CiAgICB9CiAgICAvKiBtYWtlIGFycmF5IG9mIGNvbm5lY3Rpb25zICovCiAgICBpZiAob2JqcykKCW9ianMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmpzLCBjb3VudCpzaXplb2YoSEFORExFKSk7CiAgICBlbHNlCglvYmpzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50KnNpemVvZihIQU5ETEUpKTsKCiAgICBvYmpzWzBdID0gbV9ldmVudDsKICAgIGNvdW50ID0gMTsKICAgIGNwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKGNwcykgewogICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICB3aGlsZSAoY29ubikgewogICAgICAgIGlmIChjb25uLT5vdmwuaEV2ZW50KSBvYmpzW2NvdW50KytdID0gY29ubi0+b3ZsLmhFdmVudDsKICAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgfQogICAgICBjcHMgPSBjcHMtPk5leHQ7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgICAvKiBzdGFydCB3YWl0aW5nICovCiAgICByZXMgPSBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKGNvdW50LCBvYmpzLCBGQUxTRSwgSU5GSU5JVEUpOwogICAgaWYgKHJlcyA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgIFJlc2V0RXZlbnQobV9ldmVudCk7CiAgICAgIGlmICghc3RkX2xpc3RlbikgYnJlYWs7CiAgICB9CiAgICBlbHNlIGlmIChyZXMgPT0gV0FJVF9GQUlMRUQpIHsKICAgICAgRVJSKCJ3YWl0IGZhaWxlZFxuIik7CiAgICB9CiAgICBlbHNlIHsKICAgICAgYl9oYW5kbGUgPSBvYmpzW3JlcyAtIFdBSVRfT0JKRUNUXzBdOwogICAgICAvKiBmaW5kIHdoaWNoIGNvbm5lY3Rpb24gZ290IGEgUlBDICovCiAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgICBjb25uID0gTlVMTDsKICAgICAgY3BzID0gcHJvdHNlcXM7CiAgICAgIHdoaWxlIChjcHMpIHsKICAgICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgICBpZiAoY29ubi0+b3ZsLmhFdmVudCA9PSBiX2hhbmRsZSkgYnJlYWs7CiAgICAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbm4pIGJyZWFrOwogICAgICAgIGNwcyA9IGNwcy0+TmV4dDsKICAgICAgfQogICAgICBjY29ubiA9IE5VTEw7CiAgICAgIGlmIChjb25uKSBSUENSVDRfU3Bhd25Db25uZWN0aW9uKCZjY29ubiwgY29ubik7CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgICBpZiAoIWNvbm4pIHsKICAgICAgICBFUlIoImZhaWxlZCB0byBsb2NhdGUgY29ubmVjdGlvbiBmb3IgaGFuZGxlICVwXG4iLCBiX2hhbmRsZSk7CiAgICAgIH0KICAgICAgaWYgKGNjb25uKSBSUENSVDRfbmV3X2NsaWVudChjY29ubik7CiAgICB9CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9ianMpOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIC8qIGNsb3NlIGNvbm5lY3Rpb25zICovCiAgY3BzID0gcHJvdHNlcXM7CiAgd2hpbGUgKGNwcykgewogICAgY29ubiA9IGNwcy0+Y29ubjsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oY29ubik7CiAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgfQogICAgY3BzID0gY3BzLT5OZXh0OwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3N0YXJ0X2xpc3Rlbih2b2lkKQp7CiAgVFJBQ0UoIlxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmICghICsrbGlzdGVuX2NvdW50KSB7CiAgICBpZiAoIW1ncl9ldmVudCkgbWdyX2V2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIGlmICghc2VydmVyX3NlbSkgc2VydmVyX3NlbSA9IENyZWF0ZVNlbWFwaG9yZUEoTlVMTCwgMCwgTUFYX1RIUkVBRFMsIE5VTEwpOwogICAgaWYgKCF3b3JrZXJfdGxzKSB3b3JrZXJfdGxzID0gVGxzQWxsb2MoKTsKICAgIHN0ZF9saXN0ZW4gPSBUUlVFOwogICAgc2VydmVyX3RocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBSUENSVDRfc2VydmVyX3RocmVhZCwgTlVMTCwgMCwgTlVMTCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICB9IGVsc2UgewogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgICBTZXRFdmVudChtZ3JfZXZlbnQpOwogIH0KfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3N0b3BfbGlzdGVuKHZvaWQpCnsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICBpZiAobGlzdGVuX2NvdW50ID09IC0xKQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgZWxzZSBpZiAoLS1saXN0ZW5fY291bnQgPT0gLTEpIHsKICAgIHN0ZF9saXN0ZW4gPSBGQUxTRTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogICAgU2V0RXZlbnQobWdyX2V2ZW50KTsKICB9IGVsc2UKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGFzc2VydChsaXN0ZW5fY291bnQgPiAtMik7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF91c2VfcHJvdHNlcShScGNTZXJ2ZXJQcm90c2VxKiBwcykKewogIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKCZwcy0+Y29ubiwgVFJVRSwgcHMtPlByb3RzZXEsIE5VTEwsIHBzLT5FbmRwb2ludCwgTlVMTCwgTlVMTCk7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIHBzLT5OZXh0ID0gcHJvdHNlcXM7CiAgcHJvdHNlcXMgPSBwczsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgaWYgKHN0ZF9saXN0ZW4pIFNldEV2ZW50KG1ncl9ldmVudCk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlcklucUJpbmRpbmdzIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlcklucUJpbmRpbmdzKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIERXT1JEIGNvdW50OwogIFJwY1NlcnZlclByb3RzZXEqIHBzOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CgogIGlmIChCaW5kaW5nVmVjdG9yKQogICAgVFJBQ0UoIigqQmluZGluZ1ZlY3RvciA9PSBeJXApXG4iLCAqQmluZGluZ1ZlY3Rvcik7CiAgZWxzZQogICAgRVJSKCIoQmluZGluZ1ZlY3RvciA9PSBOVUxMISE/KVxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIC8qIGNvdW50IGNvbm5lY3Rpb25zICovCiAgY291bnQgPSAwOwogIHBzID0gcHJvdHNlcXM7CiAgd2hpbGUgKHBzKSB7CiAgICBjb25uID0gcHMtPmNvbm47CiAgICB3aGlsZSAoY29ubikgewogICAgICBjb3VudCsrOwogICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgIH0KICAgIHBzID0gcHMtPk5leHQ7CiAgfQogIGlmIChjb3VudCkgewogICAgLyogZXhwb3J0IGJpbmRpbmdzICovCiAgICAqQmluZGluZ1ZlY3RvciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoUlBDX0JJTkRJTkdfVkVDVE9SKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19IQU5ETEUpKihjb3VudC0xKSk7CiAgICAoKkJpbmRpbmdWZWN0b3IpLT5Db3VudCA9IGNvdW50OwogICAgY291bnQgPSAwOwogICAgcHMgPSBwcm90c2VxczsKICAgIHdoaWxlIChwcykgewogICAgICBjb25uID0gcHMtPmNvbm47CiAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICBSUENSVDRfTWFrZUJpbmRpbmcoKFJwY0JpbmRpbmcqKikmKCpCaW5kaW5nVmVjdG9yKS0+QmluZGluZ0hbY291bnRdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4pOwogICAgICAgY291bnQrKzsKICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICB9CiAgICAgIHBzID0gcHMtPk5leHQ7CiAgICB9CiAgICBzdGF0dXMgPSBSUENfU19PSzsKICB9IGVsc2UgewogICAgKkJpbmRpbmdWZWN0b3IgPSBOVUxMOwogICAgc3RhdHVzID0gUlBDX1NfTk9fQklORElOR1M7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEEoIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIHVuc2lnbmVkIGNoYXIgKkVuZHBvaW50LCBMUFZPSUQgU2VjdXJpdHlEZXNjcmlwdG9yICkKewogIFJQQ19QT0xJQ1kgcG9saWN5OwogIAogIFRSQUNFKCAiKCVzLCV1LCVzLCVwKVxuIiwgUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IgKTsKICAKICAvKiBUaGlzIHNob3VsZCBwcm92aWRlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciAqLwogIHBvbGljeS5MZW5ndGggICAgICAgID0gc2l6ZW9mKCBwb2xpY3kgKTsKICBwb2xpY3kuRW5kcG9pbnRGbGFncyA9IDA7CiAgcG9saWN5Lk5JQ0ZsYWdzICAgICAgPSAwOwogIAogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEoIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yLCAmcG9saWN5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcFcoIExQV1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBMUFdTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksIE1heENhbGxzLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IgKTsKICAKICAvKiBUaGlzIHNob3VsZCBwcm92aWRlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciAqLwogIHBvbGljeS5MZW5ndGggICAgICAgID0gc2l6ZW9mKCBwb2xpY3kgKTsKICBwb2xpY3kuRW5kcG9pbnRGbGFncyA9IDA7CiAgcG9saWN5Lk5JQ0ZsYWdzICAgICAgPSAwOwogIAogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcoIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yLCAmcG9saWN5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBKCB1bnNpZ25lZCBjaGFyICpQcm90c2VxLCBVSU5UIE1heENhbGxzLCB1bnNpZ25lZCBjaGFyICpFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1BPTElDWSBscFBvbGljeSApCnsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKCiAgVFJBQ0UoIiglcywldSwlcywlcCx7JXUsJWx1LCVsdX0pXG4iLCBkZWJ1Z3N0cl9hKCBQcm90c2VxICksIE1heENhbGxzLAogICAgICAgZGVidWdzdHJfYSggRW5kcG9pbnQgKSwgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgbHBQb2xpY3ktPkxlbmd0aCwgbHBQb2xpY3ktPkVuZHBvaW50RmxhZ3MsIGxwUG9saWN5LT5OSUNGbGFncyApOwoKICBwcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjU2VydmVyUHJvdHNlcSkpOwogIHBzLT5NYXhDYWxscyA9IE1heENhbGxzOwogIHBzLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoUHJvdHNlcSk7CiAgcHMtPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwoKICByZXR1cm4gUlBDUlQ0X3VzZV9wcm90c2VxKHBzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcoIExQV1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBMUFdTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19QT0xJQ1kgbHBQb2xpY3kgKQp7CiAgUnBjU2VydmVyUHJvdHNlcSogcHM7CgogIFRSQUNFKCIoJXMsJXUsJXMsJXAseyV1LCVsdSwlbHV9KVxuIiwgZGVidWdzdHJfdyggUHJvdHNlcSApLCBNYXhDYWxscywKICAgICAgIGRlYnVnc3RyX3coIEVuZHBvaW50ICksIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgIGxwUG9saWN5LT5MZW5ndGgsIGxwUG9saWN5LT5FbmRwb2ludEZsYWdzLCBscFBvbGljeS0+TklDRmxhZ3MgKTsKCiAgcHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY1NlcnZlclByb3RzZXEpKTsKICBwcy0+TWF4Q2FsbHMgPSBNYXhDYWxsczsKICBwcy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpOwogIHBzLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXdG9BKEVuZHBvaW50KTsKCiAgcmV0dXJuIFJQQ1JUNF91c2VfcHJvdHNlcShwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxQSh1bnNpZ25lZCBjaGFyICpQcm90c2VxLCB1bnNpZ25lZCBpbnQgTWF4Q2FsbHMsIHZvaWQgKlNlY3VyaXR5RGVzY3JpcHRvcikKewogIFRSQUNFKCIoUHJvdHNlcSA9PSAlcywgTWF4Q2FsbHMgPT0gJWQsIFNlY3VyaXR5RGVzY3JpcHRvciA9PSBeJXApXG4iLCBkZWJ1Z3N0cl9hKFByb3RzZXEpLCBNYXhDYWxscywgU2VjdXJpdHlEZXNjcmlwdG9yKTsKICByZXR1cm4gUnBjU2VydmVyVXNlUHJvdHNlcUVwQShQcm90c2VxLCBNYXhDYWxscywgTlVMTCwgU2VjdXJpdHlEZXNjcmlwdG9yKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFXKExQV1NUUiBQcm90c2VxLCB1bnNpZ25lZCBpbnQgTWF4Q2FsbHMsIHZvaWQgKlNlY3VyaXR5RGVzY3JpcHRvcikKewogIFRSQUNFKCJQcm90c2VxID09ICVzLCBNYXhDYWxscyA9PSAlZCwgU2VjdXJpdHlEZXNjcmlwdG9yID09IF4lcClcbiIsIGRlYnVnc3RyX3coUHJvdHNlcSksIE1heENhbGxzLCBTZWN1cml0eURlc2NyaXB0b3IpOwogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXKFByb3RzZXEsIE1heENhbGxzLCBOVUxMLCBTZWN1cml0eURlc2NyaXB0b3IpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJJZiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlcklmKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFJQQ19NR1JfRVBWKiBNZ3JFcHYgKQp7CiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdik7CiAgcmV0dXJuIFJwY1NlcnZlclJlZ2lzdGVySWYyKCBJZlNwZWMsIE1nclR5cGVVdWlkLCBNZ3JFcHYsIDAsIFJQQ19DX0xJU1RFTl9NQVhfQ0FMTFNfREVGQVVMVCwgKFVJTlQpLTEsIE5VTEwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVySWZFeCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlcklmRXgoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgUlBDX01HUl9FUFYqIE1nckVwdiwKICAgICAgICAgICAgICAgICAgICAgICBVSU5UIEZsYWdzLCBVSU5UIE1heENhbGxzLCBSUENfSUZfQ0FMTEJBQ0tfRk4qIElmQ2FsbGJhY2tGbiApCnsKICBUUkFDRSgiKCVwLCVzLCVwLCV1LCV1LCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2LCBGbGFncywgTWF4Q2FsbHMsIElmQ2FsbGJhY2tGbik7CiAgcmV0dXJuIFJwY1NlcnZlclJlZ2lzdGVySWYyKCBJZlNwZWMsIE1nclR5cGVVdWlkLCBNZ3JFcHYsIEZsYWdzLCBNYXhDYWxscywgKFVJTlQpLTEsIElmQ2FsbGJhY2tGbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJJZjIgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJJZjIoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgUlBDX01HUl9FUFYqIE1nckVwdiwKICAgICAgICAgICAgICAgICAgICAgIFVJTlQgRmxhZ3MsIFVJTlQgTWF4Q2FsbHMsIFVJTlQgTWF4UnBjU2l6ZSwgUlBDX0lGX0NBTExCQUNLX0ZOKiBJZkNhbGxiYWNrRm4gKQp7CiAgUFJQQ19TRVJWRVJfSU5URVJGQUNFIElmID0gKFBSUENfU0VSVkVSX0lOVEVSRkFDRSlJZlNwZWM7CiAgUnBjU2VydmVySW50ZXJmYWNlKiBzaWY7CiAgaW50IGk7CgogIFRSQUNFKCIoJXAsJXMsJXAsJXUsJXUsJXUsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYsIEZsYWdzLCBNYXhDYWxscywKICAgICAgICAgTWF4UnBjU2l6ZSwgSWZDYWxsYmFja0ZuKTsKICBUUkFDRSgiIGludGVyZmFjZSBpZDogJXMgJWQuJWRcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5JbnRlcmZhY2VJZC5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5JbnRlcmZhY2VJZC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgVFJBQ0UoIiB0cmFuc2ZlciBzeW50YXg6ICVzICVkLiVkXG4iLCBkZWJ1Z3N0cl9ndWlkKCZJZi0+VHJhbnNmZXJTeW50YXguU3ludGF4R1VJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+VHJhbnNmZXJTeW50YXguU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+VHJhbnNmZXJTeW50YXguU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24pOwogIFRSQUNFKCIgZGlzcGF0Y2ggdGFibGU6ICVwXG4iLCBJZi0+RGlzcGF0Y2hUYWJsZSk7CiAgaWYgKElmLT5EaXNwYXRjaFRhYmxlKSB7CiAgICBUUkFDRSgiICBkaXNwYXRjaCB0YWJsZSBjb3VudDogJWRcbiIsIElmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlQ291bnQpOwogICAgZm9yIChpPTA7IGk8SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudDsgaSsrKSB7CiAgICAgIFRSQUNFKCIgICBlbnRyeSAlZDogJXBcbiIsIGksIElmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlW2ldKTsKICAgIH0KICAgIFRSQUNFKCIgIHJlc2VydmVkOiAlbGRcbiIsIElmLT5EaXNwYXRjaFRhYmxlLT5SZXNlcnZlZCk7CiAgfQogIFRSQUNFKCIgcHJvdHNlcSBlbmRwb2ludCBjb3VudDogJWRcbiIsIElmLT5ScGNQcm90c2VxRW5kcG9pbnRDb3VudCk7CiAgVFJBQ0UoIiBkZWZhdWx0IG1hbmFnZXIgZXB2OiAlcFxuIiwgSWYtPkRlZmF1bHRNYW5hZ2VyRXB2KTsKICBUUkFDRSgiIGludGVycHJldGVyIGluZm86ICVwXG4iLCBJZi0+SW50ZXJwcmV0ZXJJbmZvKTsKCiAgc2lmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNTZXJ2ZXJJbnRlcmZhY2UpKTsKICBzaWYtPklmICAgICAgICAgICA9IElmOwogIGlmIChNZ3JUeXBlVXVpZCkgewogICAgbWVtY3B5KCZzaWYtPk1nclR5cGVVdWlkLCBNZ3JUeXBlVXVpZCwgc2l6ZW9mKFVVSUQpKTsKICAgIHNpZi0+TWdyRXB2ICAgICAgID0gTWdyRXB2OwogIH0gZWxzZSB7CiAgICBtZW1zZXQoJnNpZi0+TWdyVHlwZVV1aWQsIDAsIHNpemVvZihVVUlEKSk7CiAgICBzaWYtPk1nckVwdiAgICAgICA9IElmLT5EZWZhdWx0TWFuYWdlckVwdjsKICB9CiAgc2lmLT5GbGFncyAgICAgICAgPSBGbGFnczsKICBzaWYtPk1heENhbGxzICAgICA9IE1heENhbGxzOwogIHNpZi0+TWF4UnBjU2l6ZSAgID0gTWF4UnBjU2l6ZTsKICBzaWYtPklmQ2FsbGJhY2tGbiA9IElmQ2FsbGJhY2tGbjsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgc2lmLT5OZXh0ID0gaWZzOwogIGlmcyA9IHNpZjsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgaWYgKHNpZi0+RmxhZ3MgJiBSUENfSUZfQVVUT0xJU1RFTikgewogICAgLyogd2VsbCwgc3RhcnQgbGlzdGVuaW5nLCBJIHRoaW5rLi4uICovCiAgICBSUENSVDRfc3RhcnRfbGlzdGVuKCk7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVW5yZWdpc3RlcklmKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFVJTlQgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSApCnsKICBGSVhNRSgiKElmU3BlYyA9PSAoUlBDX0lGX0hBTkRMRSleJXAsIE1nclR5cGVVdWlkID09ICVzLCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlID09ICV1KTogc3R1YlxuIiwKICAgIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIFdhaXRGb3JDYWxsc1RvQ29tcGxldGUpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBpbnQgUnVuZG93bkNvbnRleHRIYW5kbGVzICkKewogIEZJWE1FKCIoSWZTcGVjID09IChSUENfSUZfSEFORExFKV4lcCwgTWdyVHlwZVV1aWQgPT0gJXMsIFJ1bmRvd25Db250ZXh0SGFuZGxlcyA9PSAlZCk6IHN0dWJcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBSdW5kb3duQ29udGV4dEhhbmRsZXMpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNPYmplY3RTZXRUeXBlIChSUENSVDQuQCkKICoKICogUEFSQU1TCiAqICAgT2JqVXVpZCAgW0ldICJPYmplY3QiIFVVSUQKICogICBUeXBlVXVpZCBbSV0gIlR5cGUiIFVVSUQKICoKICogUkVUVVJOUwogKiAgIFJQQ19TX09LICAgICAgICAgICAgICAgICBUaGUgY2FsbCBzdWNjZWVkZWQKICogICBSUENfU19JTlZBTElEX09CSkVDVCAgICAgVGhlIHByb3ZpZGVkIG9iamVjdCAobmlsKSBpcyBub3QgdmFsaWQKICogICBSUENfU19BTFJFQURZX1JFR0lTVEVSRUQgVGhlIHByb3ZpZGVkIG9iamVjdCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQKICoKICogTWFwcyAiT2JqZWN0IiBVVUlEcyB0byAiVHlwZSIgVVVJRCdzLiAgUGFzc2luZyB0aGUgbmlsIFVVSUQgYXMgdGhlIHR5cGUKICogcmVzZXRzIHRoZSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBVVUlEIHRvIG5pbCAodGhlIGRlZmF1bHQpLgogKiBUaGUgbmlsIG9iamVjdCBpcyBhbHdheXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBuaWwgdHlwZSBhbmQgY2Fubm90IGJlCiAqIHJlYXNzaWduZWQuICBTZXJ2ZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlIGltcGxlbWVudGF0aW9ucyBvbiB0aGUgc2FtZQogKiBpbnRlcmZhY2UgYnkgcmVnaXN0ZXJpbmcgZGlmZmVyZW50IGVuZC1wb2ludCB2ZWN0b3JzIGZvciB0aGUgZGlmZmVyZW50CiAqIHR5cGVzLiAgVGhlcmUncyBubyBuZWVkIHRvIGNhbGwgdGhpcyBpZiBhIHNlcnZlciBvbmx5IHN1cHBvcnRzIHRoZSBuaWwKICogdHlwZSwgYXMgaXMgdHlwaWNhbC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY09iamVjdFNldFR5cGUoIFVVSUQqIE9ialV1aWQsIFVVSUQqIFR5cGVVdWlkICkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IFJwY09ialR5cGVNYXBzLCAqcHJldiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgVFJBQ0UoIihPYmpVVUlEID09ICVzLCBUeXBlVXVpZCA9PSAlcykuXG4iLCBkZWJ1Z3N0cl9ndWlkKE9ialV1aWQpLCBkZWJ1Z3N0cl9ndWlkKFR5cGVVdWlkKSk7CiAgaWYgKCghIE9ialV1aWQpIHx8IFV1aWRJc05pbChPYmpVdWlkLCAmZHVtbXkpKSB7CiAgICAvKiBuaWwgdXVpZCBjYW5ub3QgYmUgcmVtYXBwZWQgKi8KICAgIHJldHVybiBSUENfU19JTlZBTElEX09CSkVDVDsKICB9CgogIC8qIGZpbmQgdGhlIG1hcHBpbmcgZm9yIHRoaXMgb2JqZWN0IGlmIHRoZXJlIGlzIG9uZSAuLi4gKi8KICB3aGlsZSAobWFwKSB7CiAgICBpZiAoISBVdWlkQ29tcGFyZShPYmpVdWlkLCAmbWFwLT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcHJldiA9IG1hcDsKICAgIG1hcCA9IG1hcC0+bmV4dDsKICB9CiAgaWYgKCghIFR5cGVVdWlkKSB8fCBVdWlkSXNOaWwoVHlwZVV1aWQsICZkdW1teSkpIHsKICAgIC8qIC4uLiBhbmQgZHJvcCBpdCBmcm9tIHRoZSBsaXN0ICovCiAgICBpZiAobWFwKSB7CiAgICAgIGlmIChwcmV2KSAKICAgICAgICBwcmV2LT5uZXh0ID0gbWFwLT5uZXh0OwogICAgICBlbHNlCiAgICAgICAgUnBjT2JqVHlwZU1hcHMgPSBtYXAtPm5leHQ7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1hcCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIC4uLiAsIGZhaWwgaWYgd2UgZm91bmQgaXQgLi4uICovCiAgICBpZiAobWFwKQogICAgICByZXR1cm4gUlBDX1NfQUxSRUFEWV9SRUdJU1RFUkVEOwogICAgLyogLi4uIG90aGVyd2lzZSBjcmVhdGUgYSBuZXcgb25lIGFuZCBhZGQgaXQgaW4uICovCiAgICBtYXAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY09ialR5cGVNYXApKTsKICAgIG1lbWNweSgmbWFwLT5PYmplY3QsIE9ialV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtZW1jcHkoJm1hcC0+VHlwZSwgVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtYXAtPm5leHQgPSBOVUxMOwogICAgaWYgKHByZXYpCiAgICAgIHByZXYtPm5leHQgPSBtYXA7IC8qIHByZXYgaXMgdGhlIGxhc3QgbWFwIGluIHRoZSBsaW5rbGlzdCAqLwogICAgZWxzZQogICAgICBScGNPYmpUeXBlTWFwcyA9IG1hcDsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BKCB1bnNpZ25lZCBjaGFyICpTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9LRVlfUkVUUklFVkFMX0ZOIEdldEtleUZuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIEFyZyApCnsKICBGSVhNRSggIiglcywlbHUsJXAsJXApOiBzdHViXG4iLCBTZXJ2ZXJQcmluY05hbWUsIEF1dGhuU3ZjLCBHZXRLZXlGbiwgQXJnICk7CiAgCiAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsgLyogV2UgZG9uJ3Qga25vdyBhbnkgYXV0aGVudGljYXRpb24gc2VydmljZXMgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9XIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9XKCBMUFdTVFIgU2VydmVyUHJpbmNOYW1lLCBVTE9ORyBBdXRoblN2YywgUlBDX0FVVEhfS0VZX1JFVFJJRVZBTF9GTiBHZXRLZXlGbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBBcmcgKQp7CiAgRklYTUUoICIoJXMsJWx1LCVwLCVwKTogc3R1YlxuIiwgZGVidWdzdHJfdyggU2VydmVyUHJpbmNOYW1lICksIEF1dGhuU3ZjLCBHZXRLZXlGbiwgQXJnICk7CiAgCiAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsgLyogV2UgZG9uJ3Qga25vdyBhbnkgYXV0aGVudGljYXRpb24gc2VydmljZXMgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlckxpc3RlbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJMaXN0ZW4oIFVJTlQgTWluaW11bUNhbGxUaHJlYWRzLCBVSU5UIE1heENhbGxzLCBVSU5UIERvbnRXYWl0ICkKewogIFRSQUNFKCIoJXUsJXUsJXUpXG4iLCBNaW5pbXVtQ2FsbFRocmVhZHMsIE1heENhbGxzLCBEb250V2FpdCk7CgogIGlmICghcHJvdHNlcXMpCiAgICByZXR1cm4gUlBDX1NfTk9fUFJPVFNFUVNfUkVHSVNURVJFRDsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmIChzdGRfbGlzdGVuKSB7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgIHJldHVybiBSUENfU19BTFJFQURZX0xJU1RFTklORzsKICB9CgogIFJQQ1JUNF9zdGFydF9saXN0ZW4oKTsKCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmIChEb250V2FpdCkgcmV0dXJuIFJQQ19TX09LOwoKICByZXR1cm4gUnBjTWdtdFdhaXRTZXJ2ZXJMaXN0ZW4oKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXJ2ZXJXYWl0TGlzdGVuIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRXYWl0U2VydmVyTGlzdGVuKCB2b2lkICkKewogIFJQQ19TVEFUVVMgcnNsdCA9IFJQQ19TX09LOwoKICBUUkFDRSgiXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmICghc3RkX2xpc3RlbikKICAgIGlmICggKHJzbHQgPSBScGNTZXJ2ZXJMaXN0ZW4oMSwgMCwgVFJVRSkpICE9IFJQQ19TX09LICkgewogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgICAgcmV0dXJuIHJzbHQ7CiAgICB9CiAgCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIHdoaWxlIChzdGRfbGlzdGVuKSB7CiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KG1ncl9ldmVudCwgSU5GSU5JVEUpOwogICAgaWYgKCFzdGRfbGlzdGVuKSB7CiAgICAgIFNsZWVwKDEwMCk7IC8qIGRvbid0IHNwaW4gdmlvbGVudGx5ICovCiAgICAgIFRSQUNFKCJzcGlubmluZy5cbiIpOwogICAgfQogIH0KCiAgcmV0dXJuIHJzbHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nICkKewogIFRSQUNFKCIoQmluZGluZyA9PSAoUlBDX0JJTkRJTkdfSEFORExFKV4lcClcbiIsIEJpbmRpbmcpOwoKICBpZiAoQmluZGluZykgewogICAgRklYTUUoImNsaWVudC1zaWRlIGludm9jYXRpb24gbm90IGltcGxlbWVudGVkLlxuIik7CiAgICByZXR1cm4gUlBDX1NfV1JPTkdfS0lORF9PRl9CSU5ESU5HOwogIH0KICAKICAvKiBobW0uLi4gKi8KICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICB3aGlsZSAoc3RkX2xpc3RlbikKICAgIFJQQ1JUNF9zdG9wX2xpc3RlbigpOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1NlcnZlclN0YXJ0TGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RhcnRMaXN0ZW5pbmcoIEhXTkQgaFduZCApCnsKICBGSVhNRSggIiglcCk6IHN0dWJcbiIsIGhXbmQgKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNTZXJ2ZXJTdG9wTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RvcExpc3RlbmluZyggdm9pZCApCnsKICBGSVhNRSggIigpOiBzdHViXG4iICk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjV2luZG93UHJvYyAoUlBDUlQ0LkApCiAqLwpVSU5UIFdJTkFQSSBJX1JwY1dpbmRvd1Byb2MoIHZvaWQgKmhXbmQsIFVJTlQgTWVzc2FnZSwgVUlOVCB3UGFyYW0sIFVMT05HIGxQYXJhbSApCnsKICBGSVhNRSggIiglcCwlMDh4LCUwOHgsJTA4bHgpOiBzdHViXG4iLCBoV25kLCBNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSApOwoKICByZXR1cm4gMDsKfQo=