LyoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBNaWNoYWVsIEf8bm5ld2lnCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCi8qIFRPRE86CiAqICAgLSBzb21lIGltcHJvdmVtZW50cyBwb3NzaWJsZQogKiAgIC0gaW1wbGVtZW50IERlY29tcHJlc3NTZXRQYWxldHRlPyAtLSBkbyB3ZSBuZWVkIGl0IGZvciBhbnl0aGluZz8KICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibXNybGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2ludXNlci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zcmxlMzIpOwoKc3RhdGljIEhJTlNUQU5DRSBNU1JMRTMyX2hNb2R1bGUgPSAwOwoKI2RlZmluZSBBQlMoYSkgICAgICAgICAgICAgICAgKChhKSA8IDAgPyAtKGEpIDogKGEpKQojZGVmaW5lIFNRUihhKSAgICAgICAgICAgICAgICAoKGEpICogKGEpKQoKI2RlZmluZSBRVUFMSVRZX3RvX0RJU1QocSkgICAgKElDUVVBTElUWV9ISUdIIC0gcSkKaW5saW5lIFdPUkQgQ29sb3JDbXAoV09SRCBjbHIxLCBXT1JEIGNscjIpCnsKICByZWdpc3RlciBVSU5UIGEgPSAoY2xyMS1jbHIyKTsKICByZXR1cm4gU1FSKGEpOwp9CmlubGluZSBXT1JEIEludGVuc2l0eShSR0JRVUFEIGNscikKewogIHJldHVybiAoMzAgKiBjbHIucmdiUmVkICsgNTkgKiBjbHIucmdiR3JlZW4gKyAxMSAqIGNsci5yZ2JCbHVlKS80Owp9CgojZGVmaW5lIEdldFJhd1BpeGVsKGxwYmksbHAseCkgXAogICgobHBiaSktPmJpQml0Q291bnQgPT0gMSA/ICgobHApWyh4KS84XSA+PiAoOCAtICh4KSU4KSkgJiAxIDogXAogICAoKGxwYmkpLT5iaUJpdENvdW50ID09IDQgPyAoKGxwKVsoeCkvMl0gPj4gKDQgKiAoMSAtICh4KSUyKSkpICYgMTUgOiBscFt4XSkpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiB1dGlsaXR5IGZ1bmN0aW9ucyAqLwpzdGF0aWMgQk9PTCAgICBpc1N1cHBvcnRlZERJQihMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpOwpzdGF0aWMgQk9PTCAgICBpc1N1cHBvcnRlZE1STEUoTFBDQklUTUFQSU5GT0hFQURFUiBscGJpKTsKc3RhdGljIEJZVEUgICAgTVNSTEUzMl9HZXROZWFyZXN0UGFsZXR0ZUluZGV4KFVJTlQgY291bnQsIGNvbnN0IFJHQlFVQUQgKmNscnMsIFJHQlFVQUQgY2xyKTsKCi8qIGNvbXByZXNzaW9uIGZ1bmN0aW9ucyAqLwpzdGF0aWMgdm9pZCAgICBjb21wdXRlSW50ZXJuYWxGcmFtZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwgTFBCWVRFIGxwSW4pOwpzdGF0aWMgTE9ORyAgICBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSk7CnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfQ29tcHJlc3NSTEU0KENvZGVjSW5mbyAqcGksIExQQklUTUFQSU5GT0hFQURFUiBscGJpSW4sIExQQllURSBscEluLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwgTFBCWVRFIGxwT3V0LCBCT09MIGlzS2V5KTsKc3RhdGljIExSRVNVTFQgTVNSTEUzMl9Db21wcmVzc1JMRTgoQ29kZWNJbmZvICpwaSwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwgTFBCWVRFIGxwSW4sIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LCBMUEJZVEUgbHBPdXQsIEJPT0wgaXNLZXkpOwoKLyogZGVjb21wcmVzc2lvbiBmdW5jdGlvbnMgKi8Kc3RhdGljIExSRVNVTFQgTVNSTEUzMl9EZWNvbXByZXNzUkxFNChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksCgkJCQkgICAgICBMUEJZVEUgbHBJbiwgTFBCWVRFIGxwT3V0KTsKc3RhdGljIExSRVNVTFQgTVNSTEUzMl9EZWNvbXByZXNzUkxFOChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksCgkJCQkgICAgICBMUEJZVEUgbHBJbiwgTFBCWVRFIGxwT3V0KTsKCi8qIEFQSSBmdW5jdGlvbnMgKi8Kc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRGb3JtYXQoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0dldFNpemUoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgICBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc1F1ZXJ5KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIENvbXByZXNzQmVnaW4oQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgQ29tcHJlc3MoQ29kZWNJbmZvICpwaSwgSUNDT01QUkVTUyogbHBpYywgRFdPUkQgZHdTaXplKTsKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NFbmQoQ29kZWNJbmZvICpwaSk7CgpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzR2V0Rm9ybWF0KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzUXVlcnkoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgICBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzQmVnaW4oQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgICBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzKENvZGVjSW5mbyAqcGksIElDREVDT01QUkVTUyAqcGljLCBEV09SRCBkd1NpemUpOwpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzRW5kKENvZGVjSW5mbyAqcGkpOwpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzR2V0UGFsZXR0ZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgQk9PTCBpc1N1cHBvcnRlZE1STEUoTFBDQklUTUFQSU5GT0hFQURFUiBscGJpKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQobHBiaSAhPSBOVUxMKTsKCiAgaWYgKGxwYmktPmJpU2l6ZSA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSB8fCBcCiAgICAgIGxwYmktPmJpUGxhbmVzICE9IDEpCiAgICByZXR1cm4gRkFMU0U7CgogIGlmIChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JMRTQpIHsKICAgIGlmIChscGJpLT5iaUJpdENvdW50ICE9IDQgfHwgXAoJKGxwYmktPmJpV2lkdGggJSAyKSAhPSAwKQogICAgICByZXR1cm4gRkFMU0U7CiAgfSBlbHNlIGlmIChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JMRTgpIHsKICAgIGlmIChscGJpLT5iaUJpdENvdW50ICE9IDgpCiAgICAgIHJldHVybiBGQUxTRTsKICB9IGVsc2UKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MICBpc1N1cHBvcnRlZERJQihMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChscGJpICE9IE5VTEwpOwoKICAvKiBjaGVjayBzdHJ1Y3R1cmUgdmVyc2lvbi9wbGFuZXMvY29tcHJlc3Npb24gKi8KICBpZiAobHBiaS0+YmlTaXplIDwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpIHx8CiAgICAgIGxwYmktPmJpUGxhbmVzICE9IDEpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCICYmCiAgICAgIGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfQklURklFTERTKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBjaGVjayBiaXQtZGVwdGggKi8KICBpZiAobHBiaS0+YmlCaXRDb3VudCAhPSAxICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gNCAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDggJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSAxNSAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDE2ICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gMjQgJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSAzMikKICAgIHJldHVybiBGQUxTRTsKCiAgLyogY2hlY2sgZm9yIHNpemUocykgKi8KICBpZiAoIWxwYmktPmJpV2lkdGggfHwgIWxwYmktPmJpSGVpZ2h0KQogICAgcmV0dXJuIEZBTFNFOyAvKiBpbWFnZSB3aXRoIHplcm8gc2l6ZSwgbWFrZXMgbm8gc2Vuc2Ugc28gZXJyb3IgISAqLwogIGlmIChESUJXSURUSEJZVEVTKCpscGJpKSAqIChEV09SRClscGJpLT5iaUhlaWdodCA+PSAoMVVMIDw8IDMxKSAtIDEpCiAgICByZXR1cm4gRkFMU0U7IC8qIGltYWdlIHRvbyBiaWcgISAqLwoKICAvKiBjaGVjayBmb3Igbm9uZXhpc3RlbnQgY29sb3J0YWJsZSBmb3IgaGktIGFuZCB0cnVlLWNvbG9yIERJQidzICovCiAgaWYgKGxwYmktPmJpQml0Q291bnQgPj0gMTUgJiYgbHBiaS0+YmlDbHJVc2VkID4gMCkKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCWVRFIE1TUkxFMzJfR2V0TmVhcmVzdFBhbGV0dGVJbmRleChVSU5UIGNvdW50LCBjb25zdCBSR0JRVUFEICpjbHJzLCBSR0JRVUFEIGNscikKewogIElOVCAgZGlmZiA9IDB4MDBGRkZGRkY7CiAgVUlOVCBpOwogIFVJTlQgaWR4ID0gMDsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoY2xycyAhPSBOVUxMKTsKCiAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKICAgIGludCByID0gKChpbnQpY2xyc1tpXS5yZ2JSZWQgICAtIChpbnQpY2xyLnJnYlJlZCk7CiAgICBpbnQgZyA9ICgoaW50KWNscnNbaV0ucmdiR3JlZW4gLSAoaW50KWNsci5yZ2JHcmVlbik7CiAgICBpbnQgYiA9ICgoaW50KWNscnNbaV0ucmdiQmx1ZSAgLSAoaW50KWNsci5yZ2JCbHVlKTsKCiAgICByID0gcipyICsgZypnICsgYipiOwoKICAgIGlmIChyIDwgZGlmZikgewogICAgICBpZHggID0gaTsKICAgICAgZGlmZiA9IHI7CiAgICAgIGlmIChkaWZmID09IDApCglicmVhazsKICAgIH0KICB9CgogIHJldHVybiBpZHg7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQgY29tcHV0ZUludGVybmFsRnJhbWUoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sIExQQllURSBscEluKQp7CiAgV09SRCAgIHdJbnRlbnNpdHlUYmxbMjU2XTsKICBEV09SRCAgbEluTGluZSwgbE91dExpbmU7CiAgTFBXT1JEIGxwT3V0OwogIFVJTlQgICBpOwogIExPTkcgICB5OwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlJbiAhPSBOVUxMICYmIGxwSW4gIT0gTlVMTCk7CiAgYXNzZXJ0KHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCk7CgogIGxJbkxpbmUgID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsT3V0TGluZSA9IFdJRFRIQllURVMoKFdPUkQpbHBiaUluLT5iaVdpZHRoICogOHUgKiBzaXplb2YoV09SRCkpIC8gMnU7CiAgbHBPdXQgICAgPSBwaS0+cEN1ckZyYW1lOwoKICBhc3NlcnQobHBiaUluLT5iaUNsclVzZWQgIT0gMCk7CgogIHsKICAgIGNvbnN0IFJHQlFVQUQgKmxwID0KICAgICAgKGNvbnN0IFJHQlFVQUQgKikoKGNvbnN0IEJZVEUqKWxwYmlJbiArIGxwYmlJbi0+YmlTaXplKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbHBiaUluLT5iaUNsclVzZWQ7IGkrKykKICAgICAgd0ludGVuc2l0eVRibFtpXSA9IEludGVuc2l0eShscFtpXSk7CiAgfQoKICBmb3IgKHkgPSAwOyB5IDwgbHBiaUluLT5iaUhlaWdodDsgeSsrKSB7CiAgICBMT05HIHg7CgogICAgc3dpdGNoIChscGJpSW4tPmJpQml0Q291bnQpIHsKICAgIGNhc2UgMToKICAgICAgZm9yICh4ID0gMDsgeCA8IGxwYmlJbi0+YmlXaWR0aCAvIDg7IHgrKykgewoJZm9yIChpID0gMDsgaSA8IDc7IGkrKykKCSAgbHBPdXRbOCAqIHggKyBpXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gPj4gKDcgLSBpKSkgJiAxXTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgNDoKICAgICAgZm9yICh4ID0gMDsgeCA8IGxwYmlJbi0+YmlXaWR0aCAvIDI7IHgrKykgewoJbHBPdXRbMiAqIHggKyAwXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gPj4gNCldOwoJbHBPdXRbMiAqIHggKyAxXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gJiAweDBGKV07CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIDg6CiAgICAgIGZvciAoeCA9IDA7IHggPCBscGJpSW4tPmJpV2lkdGg7IHgrKykKCWxwT3V0W3hdID0gd0ludGVuc2l0eVRibFtscEluW3hdXTsKICAgICAgYnJlYWs7CiAgICB9CgogICAgbHBJbiAgKz0gbEluTGluZTsKICAgIGxwT3V0ICs9IGxPdXRMaW5lOwogIH0KfQoKc3RhdGljIExPTkcgTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpCnsKICBMT05HIGEsIGIsIHNpemU7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQobHBiaSAhPSBOVUxMKTsKCiAgYSA9IGxwYmktPmJpV2lkdGggLyAyNTU7CiAgYiA9IGxwYmktPmJpV2lkdGggJSAyNTU7CiAgaWYgKGxwYmktPmJpQml0Q291bnQgPD0gNCkgewogICAgYSAvPSAyOwogICAgYiAvPSAyOwogIH0KCiAgc2l6ZSA9ICgyICsgYSAqICgyICsgKChhICsgMikgJiB+MikpICsgYiAqICgyICsgKChiICsgMikgJiB+MikpKTsKICByZXR1cm4gc2l6ZSAqIGxwYmktPmJpSGVpZ2h0Owp9CgovKiBscFAgPT4gY3VycmVudCAgcG9zIGluIHByZXZpb3VzIGZyYW1lCiAqIGxwQSA9PiBwcmV2aW91cyBwb3MgaW4gY3VycmVudCAgZnJhbWUKICogbHBCID0+IGN1cnJlbnQgIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKi8Kc3RhdGljIElOVCBjb3VudERpZmZSTEU0KExQV09SRCBscFAsIExQV09SRCBscEEsIExQV09SRCBscEIsIElOVCBwb3MsIExPTkcgbERpc3QsIExPTkcgd2lkdGgpCnsKICBJTlQgIGNvdW50OwogIFdPUkQgY2xyMSwgY2xyMjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQobHBBICYmIGxwQiAmJiBsRGlzdCA+PSAwICYmIHdpZHRoID4gMCk7CgogIGlmIChwb3MgPj0gd2lkdGgpCiAgICByZXR1cm4gMDsKICBpZiAocG9zKzEgPT0gd2lkdGgpCiAgICByZXR1cm4gMTsKCiAgY2xyMSA9IGxwQltwb3MrK107CiAgY2xyMiA9IGxwQltwb3NdOwoKICBjb3VudCA9IDI7CiAgd2hpbGUgKHBvcyArIDEgPCB3aWR0aCkgewogICAgV09SRCBjbHIzLCBjbHI0OwoKICAgIGNscjMgPSBscEJbKytwb3NdOwogICAgaWYgKHBvcyArIDEgPj0gd2lkdGgpCiAgICAgIHJldHVybiBjb3VudCArIDE7CgogICAgY2xyNCA9IGxwQlsrK3Bvc107CiAgICBpZiAoQ29sb3JDbXAoY2xyMSwgY2xyMykgPD0gbERpc3QgJiYKCUNvbG9yQ21wKGNscjIsIGNscjQpIDw9IGxEaXN0KSB7CiAgICAgIC8qIGRpZmYgYXQgZW5kPyAtLSBsb29rLWFoZWFkIGZvciBhdCBsZWFzdCA/PyBtb3JlIGVuY29kYWJsZSBwaXhlbHMgKi8KICAgICAgaWYgKHBvcyArIDIgPCB3aWR0aCAmJiBDb2xvckNtcChjbHIxLGxwQltwb3MrMV0pIDw9IGxEaXN0ICYmCgkgIENvbG9yQ21wKGNscjIsbHBCW3BvcysyXSkgPD0gbERpc3QpIHsKCWlmIChwb3MgKyA0IDwgd2lkdGggJiYgQ29sb3JDbXAobHBCW3BvcysxXSxscEJbcG9zKzNdKSA8PSBsRGlzdCAmJgoJICAgIENvbG9yQ21wKGxwQltwb3MrMl0sbHBCW3Bvcys0XSkgPD0gbERpc3QpCgkgIHJldHVybiBjb3VudCAtIDM7IC8qIGZvbGxvd2VkIGJ5IGF0IGxlYXN0IDQgZW5jb2RhYmxlIHBpeGVscyAqLwoJcmV0dXJuIGNvdW50IC0gMjsKICAgICAgfQogICAgfSBlbHNlIGlmIChscFAgIT0gTlVMTCAmJiBDb2xvckNtcChscFBbcG9zXSwgbHBCW3Bvc10pIDw9IGxEaXN0KSB7CiAgICAgIC8qICdjb21wYXJlJyB3aXRoIHByZXZpb3VzIGZyYW1lIGZvciBlbmQgb2YgZGlmZiAqLwogICAgICBJTlQgY291bnQyID0gMDsKCiAgICAgIC8qIEZJWE1FICovCgogICAgICBpZiAoY291bnQyID49IDgpCglyZXR1cm4gY291bnQ7CgogICAgICBwb3MgLT0gY291bnQyOwogICAgfQoKICAgIGNvdW50ICs9IDI7CiAgICBjbHIxID0gY2xyMzsKICAgIGNscjIgPSBjbHI0OwogIH0KCiAgcmV0dXJuIGNvdW50Owp9CgovKiBscFAgPT4gY3VycmVudCAgcG9zIGluIHByZXZpb3VzIGZyYW1lCiAqIGxwQSA9PiBwcmV2aW91cyBwb3MgaW4gY3VycmVudCAgZnJhbWUKICogbHBCID0+IGN1cnJlbnQgIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKi8Kc3RhdGljIElOVCBjb3VudERpZmZSTEU4KExQV09SRCBscFAsIExQV09SRCBscEEsIExQV09SRCBscEIsIElOVCBwb3MsIExPTkcgbERpc3QsIExPTkcgd2lkdGgpCnsKICBJTlQgY291bnQ7CgogIGZvciAoY291bnQgPSAwOyBwb3MgPCB3aWR0aDsgcG9zKyssIGNvdW50KyspIHsKICAgIGlmIChDb2xvckNtcChscEFbcG9zXSwgbHBCW3Bvc10pIDw9IGxEaXN0KSB7CiAgICAgIC8qIGRpZmYgYXQgZW5kPyAtLSBsb29rLWFoZWFkIGZvciBzb21lIG1vcmUgZW5jb2RhYmxlIHBpeGVsICovCiAgICAgIGlmIChwb3MgKyAxIDwgd2lkdGggJiYgQ29sb3JDbXAobHBCW3Bvc10sIGxwQltwb3MrMV0pIDw9IGxEaXN0KQoJcmV0dXJuIGNvdW50IC0gMTsKICAgICAgaWYgKHBvcyArIDIgPCB3aWR0aCAmJiBDb2xvckNtcChscEJbcG9zKzFdLCBscEJbcG9zKzJdKSA8PSBsRGlzdCkKCXJldHVybiBjb3VudCAtIDE7CiAgICB9IGVsc2UgaWYgKGxwUCAhPSBOVUxMICYmIENvbG9yQ21wKGxwUFtwb3NdLCBscEJbcG9zXSkgPD0gbERpc3QpIHsKICAgICAgLyogJ2NvbXBhcmUnIHdpdGggcHJldmlvdXMgZnJhbWUgZm9yIGVuZCBvZiBkaWZmICovCiAgICAgIElOVCBjb3VudDIgPSAwOwoKICAgICAgZm9yIChjb3VudDIgPSAwLCBwb3MrKzsgcG9zIDwgd2lkdGggJiYgY291bnQyIDw9IDU7IHBvcysrLCBjb3VudDIrKykgewoJaWYgKENvbG9yQ21wKGxwUFtwb3NdLCBscEJbcG9zXSkgPiBsRGlzdCkKCSAgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKGNvdW50MiA+IDQpCglyZXR1cm4gY291bnQ7CgogICAgICBwb3MgLT0gY291bnQyOwogICAgfQogIH0KCiAgcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgSU5UIE1TUkxFMzJfQ29tcHJlc3NSTEU0TGluZShDb2RlY0luZm8gKnBpLCBMUFdPUkQgbHBQLCBMUFdPUkQgbHBDLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksIEJZVEUgKmxwSW4sIExPTkcgbERpc3QsIElOVCB4LCBMUEJZVEUgKnBwT3V0LCBEV09SRCAqbHBTaXplSW1hZ2UpCnsKICBMUEJZVEUgbHBPdXQgPSAqcHBPdXQ7CiAgSU5UICAgIGNvdW50LCBwb3M7CiAgV09SRCAgIGNscjEsIGNscjI7CgogIC8qIHRyeSB0byBlbmNvZGUgYXMgbWFueSBwaXhlbCBhcyBwb3NzaWJsZSAqLwogIGNvdW50ID0gMTsKICBwb3MgICA9IHg7CiAgY2xyMSAgPSBscENbcG9zKytdOwogIGlmIChwb3MgPCBscGJpLT5iaVdpZHRoKSB7CiAgICBjbHIyID0gbHBDW3Bvc107CiAgICBmb3IgKCsrY291bnQ7IHBvcyArIDEgPCBscGJpLT5iaVdpZHRoOyApIHsKICAgICAgKytwb3M7CiAgICAgIGlmIChDb2xvckNtcChjbHIxLCBscENbcG9zXSkgPiBsRGlzdCkKCWJyZWFrOwogICAgICBjb3VudCsrOwogICAgICBpZiAocG9zICsgMSA+PSBscGJpLT5iaVdpZHRoKQoJYnJlYWs7CiAgICAgICsrcG9zOwogICAgICBpZiAoQ29sb3JDbXAoY2xyMiwgbHBDW3Bvc10pID4gbERpc3QpCglicmVhazsKICAgICAgY291bnQrKzsKICAgIH0KICB9CgogIGlmIChjb3VudCA8IDQpIHsKICAgIC8qIGFkZCBzb21lIHBpeGVsIGZvciBhYnNvbHV0aW5nIGlmIHBvc3NpYmxlICovCiAgICBjb3VudCArPSBjb3VudERpZmZSTEU0KGxwUCwgbHBDIC0gMSwgbHBDLCBwb3MtMSwgbERpc3QsIGxwYmktPmJpV2lkdGgpOwoKICAgIGFzc2VydChjb3VudCA+IDApOwoKICAgIC8qIGNoZWNrIGZvciBuZWFyIGVuZCBvZiBsaW5lICovCiAgICBpZiAoeCArIGNvdW50ID4gbHBiaS0+YmlXaWR0aCkKICAgICAgY291bnQgPSBscGJpLT5iaVdpZHRoIC0geDsKCiAgICAvKiBhYnNvbHV0ZSBwaXhlbChzKSBpbiBncm91cHMgb2YgYXQgbGVhc3QgMyBhbmQgYXQgbW9zdCAyNTQgcGl4ZWxzICovCiAgICB3aGlsZSAoY291bnQgPiAyKSB7CiAgICAgIElOVCAgaTsKICAgICAgSU5UICBzaXplICAgICAgID0gbWluKGNvdW50LCAyNTQpOwogICAgICBpbnQgIGJ5dGVzICAgICAgPSAoKHNpemUgKyAxKSAmICh+MSkpIC8gMjsKICAgICAgQk9PTCBleHRyYV9ieXRlID0gYnl0ZXMgJiAweDAxOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDIgKyBieXRlcyArIGV4dHJhX2J5dGU7CiAgICAgIGFzc2VydCgoKCpscFNpemVJbWFnZSkgJSAyKSA9PSAwKTsKICAgICAgY291bnQgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgPSAwOwogICAgICAqbHBPdXQrKyA9IHNpemU7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpICs9IDIpIHsKCWNscjEgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCXgrKzsKCWlmIChpICsgMSA8IHNpemUpIHsKCSAgY2xyMiA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJICB4Kys7Cgl9IGVsc2UKCSAgY2xyMiA9IDA7CgoJKmxwT3V0KysgPSAoY2xyMSA8PCA0KSB8IGNscjI7CiAgICAgIH0KICAgICAgaWYgKGV4dHJhX2J5dGUpCgkqbHBPdXQrKyA9IDA7CiAgICB9CgogICAgaWYgKGNvdW50ID4gMCkgewogICAgICAvKiB0b28gbGl0dGxlIGZvciBhYnNvbHV0aW5nIHNvIHdlIG11c3QgZW5jb2RlIHRoZW0gKi8KICAgICAgYXNzZXJ0KGNvdW50IDw9IDIpOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDI7CiAgICAgIGNscjEgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKICAgICAgeCsrOwogICAgICBpZiAoY291bnQgPT0gMikgewoJY2xyMiA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJeCsrOwogICAgICB9IGVsc2UKCWNscjIgPSAwOwogICAgICAqbHBPdXQrKyA9IGNvdW50OwogICAgICAqbHBPdXQrKyA9IChjbHIxIDw8IDQpIHwgY2xyMjsKICAgIH0KICB9IGVsc2UgewogICAgLyogZW5jb2RlIGNvdW50IHBpeGVsKHMpICovCiAgICBjbHIxID0gKChwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXSA8PCA0KSB8CgkgICAgcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4ICsgMSldKTsKCiAgICB4ICs9IGNvdW50OwogICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICBJTlQgc2l6ZSA9IG1pbihjb3VudCwgMjU0KTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyOwogICAgICBjb3VudCAgICAtPSBzaXplOwogICAgICAqbHBPdXQrKyAgPSBzaXplOwogICAgICAqbHBPdXQrKyAgPSBjbHIxOwogICAgfQogIH0KCiAgKnBwT3V0ID0gbHBPdXQ7CgogIHJldHVybiB4Owp9CgpzdGF0aWMgSU5UIE1TUkxFMzJfQ29tcHJlc3NSTEU4TGluZShDb2RlY0luZm8gKnBpLCBMUFdPUkQgbHBQLCBMUFdPUkQgbHBDLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksIEJZVEUgKmxwSW4sIExPTkcgbERpc3QsIElOVCB4LCBMUEJZVEUgKnBwT3V0LCBEV09SRCAqbHBTaXplSW1hZ2UpCnsKICBMUEJZVEUgbHBPdXQgPSAqcHBPdXQ7CiAgSU5UICAgIGNvdW50LCBwb3M7CiAgV09SRCAgIGNscjsKCiAgYXNzZXJ0KGxwYmktPmJpQml0Q291bnQgPD0gOCk7CiAgYXNzZXJ0KGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKCiAgLyogdHJ5IHRvIGVuY29kZSBhcyBtdWNoIGFzIHBvc3NpYmxlICovCiAgcG9zID0geDsKICBjbHIgPSBscENbcG9zKytdOwogIGZvciAoY291bnQgPSAxOyBwb3MgPCBscGJpLT5iaVdpZHRoOyBjb3VudCsrKSB7CiAgICBpZiAoQ29sb3JDbXAoY2xyLCBscENbcG9zKytdKSA+IGxEaXN0KQogICAgICBicmVhazsKICB9CgogIGlmIChjb3VudCA8IDIpIHsKICAgIC8qIGFkZCBzb21lIG1vcmUgcGl4ZWxzIGZvciBhYnNvbHV0aW5nIGlmIHBvc3NpYmxlICovCiAgICBjb3VudCArPSBjb3VudERpZmZSTEU4KGxwUCwgbHBDIC0gMSwgbHBDLCBwb3MtMSwgbERpc3QsIGxwYmktPmJpV2lkdGgpOwoKICAgIGFzc2VydChjb3VudCA+IDApOwoKICAgIC8qIGNoZWNrIGZvciBvdmVyIGVuZCBvZiBsaW5lICovCiAgICBpZiAoeCArIGNvdW50ID4gbHBiaS0+YmlXaWR0aCkKICAgICAgY291bnQgPSBscGJpLT5iaVdpZHRoIC0geDsKCiAgICAvKiBhYnNvbHV0ZSBwaXhlbChzKSBpbiBncm91cHMgb2YgYXQgbGVhc3QgMyBhbmQgYXQgbW9zdCAyNTUgcGl4ZWxzICovCiAgICB3aGlsZSAoY291bnQgPiAyKSB7CiAgICAgIElOVCAgaTsKICAgICAgSU5UICBzaXplICAgICAgID0gbWluKGNvdW50LCAyNTUpOwogICAgICBCT09MIGV4dHJhX2J5dGUgPSBzaXplICUgMjsKCiAgICAgICpscFNpemVJbWFnZSArPSAyICsgc2l6ZSArIGV4dHJhX2J5dGU7CiAgICAgIGNvdW50IC09IHNpemU7CiAgICAgICpscE91dCsrID0gMDsKICAgICAgKmxwT3V0KysgPSBzaXplOwogICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkqbHBPdXQrKyA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJeCsrOwogICAgICB9CiAgICAgIGlmIChleHRyYV9ieXRlKQoJKmxwT3V0KysgPSAwOwogICAgfQogICAgaWYgKGNvdW50ID4gMCkgewogICAgICAvKiB0b28gbGl0dGxlIGZvciBhYnNvbHV0aW5nIHNvIHdlIG11c3QgZW5jb2RlIHRoZW0gZXZlbiBpZiBpdCdzIGV4cGVuc2l2ZSEgKi8KICAgICAgYXNzZXJ0KGNvdW50IDw9IDIpOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDIgKiBjb3VudDsKICAgICAgKmxwT3V0KysgPSAxOwogICAgICAqbHBPdXQrKyA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwogICAgICB4Kys7CgogICAgICBpZiAoY291bnQgPT0gMikgewoJKmxwT3V0KysgPSAxOwoJKmxwT3V0KysgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCXgrKzsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBlbmNvZGUgY291bnQgcGl4ZWwocykgKi8KICAgIGNsciA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoKICAgIC8qIG9wdGltaXplIGVuZCBvZiBsaW5lICovCiAgICBpZiAoeCArIGNvdW50ICsgMSA9PSBscGJpLT5iaVdpZHRoKQogICAgICBjb3VudCsrOwoKICAgIHggKz0gY291bnQ7CiAgICB3aGlsZSAoY291bnQgPiAwKSB7CiAgICAgIElOVCBzaXplID0gbWluKGNvdW50LCAyNTUpOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDI7CiAgICAgIGNvdW50ICAgIC09IHNpemU7CiAgICAgICpscE91dCsrICA9IHNpemU7CiAgICAgICpscE91dCsrICA9IGNscjsKICAgIH0KICB9CgogICpwcE91dCA9IGxwT3V0OwoKICByZXR1cm4geDsKfQoKTFJFU1VMVCBNU1JMRTMyX0NvbXByZXNzUkxFNChDb2RlY0luZm8gKnBpLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaUluLCBMUEJZVEUgbHBJbiwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQsIExQQllURSBscE91dCwgQk9PTCBpc0tleSkKewogIExQV09SRCBscEM7CiAgTE9ORyAgIGxMaW5lLCBsSW5MaW5lLCBsRGlzdDsKICBMUEJZVEUgbHBPdXRTdGFydCA9IGxwT3V0OwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlPdXQgIT0gTlVMTCk7CiAgYXNzZXJ0KGxwSW4gIT0gTlVMTCAmJiBscE91dCAhPSBOVUxMKTsKICBhc3NlcnQocGktPnBDdXJGcmFtZSAhPSBOVUxMKTsKCiAgbHBDICAgICAgPSBwaS0+cEN1ckZyYW1lOwogIGxEaXN0ICAgID0gUVVBTElUWV90b19ESVNUKHBpLT5kd1F1YWxpdHkpOwogIGxJbkxpbmUgID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsTGluZSAgICA9IFdJRFRIQllURVMobHBiaU91dC0+YmlXaWR0aCAqIDE2KSAvIDI7CgogIGxwYmlPdXQtPmJpU2l6ZUltYWdlID0gMDsKICBpZiAoaXNLZXkpIHsKICAgIC8qIGtleWZyYW1lIC0tIGNvbnZlcnQgaW50ZXJuYWwgZnJhbWUgdG8gb3V0cHV0IGZvcm1hdCAqLwogICAgSU5UIHgsIHk7CgogICAgZm9yICh5ID0gMDsgeSA8IGxwYmlPdXQtPmJpSGVpZ2h0OyB5KyspIHsKICAgICAgeCA9IDA7CgogICAgICBkbyB7Cgl4ID0gTVNSTEUzMl9Db21wcmVzc1JMRTRMaW5lKHBpLCBOVUxMLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCQkgICAgICZscE91dCwgJmxwYmlPdXQtPmJpU2l6ZUltYWdlKTsKICAgICAgfSB3aGlsZSAoeCA8IGxwYmlPdXQtPmJpV2lkdGgpOwoKICAgICAgbHBDICAgKz0gbExpbmU7CiAgICAgIGxwSW4gICs9IGxJbkxpbmU7CgogICAgICAvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCiAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CiAgICAgICooTFBXT1JEKWxwT3V0ID0gMDsKICAgICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwogICAgICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBkZWx0YS1mcmFtZSAtLSBjb21wdXRlIGRlbHRhIGJldHdlZW4gbGFzdCBhbmQgdGhpcyBpbnRlcm5hbCBmcmFtZSAqLwogICAgTFBXT1JEIGxwUDsKICAgIElOVCAgICB4LCB5OwogICAgSU5UICAgIGp1bXB4LCBqdW1weTsKCiAgICBhc3NlcnQocGktPnBQcmV2RnJhbWUgIT0gTlVMTCk7CgogICAgbHBQICAgPSBwaS0+cFByZXZGcmFtZTsKICAgIGp1bXB5ID0gMDsKICAgIGp1bXB4ID0gLTE7CgogICAgZm9yICh5ID0gMDsgeSA8IGxwYmlPdXQtPmJpSGVpZ2h0OyB5KyspIHsKICAgICAgeCA9IDA7CgogICAgICBkbyB7CglJTlQgY291bnQsIHBvczsKCglpZiAoanVtcHggPT0gLTEpCgkgIGp1bXB4ID0geDsKCWZvciAoY291bnQgPSAwLCBwb3MgPSB4OyBwb3MgPCBscGJpT3V0LT5iaVdpZHRoOyBwb3MrKywgY291bnQrKykgewoJICBpZiAoQ29sb3JDbXAobHBQW3Bvc10sIGxwQ1twb3NdKSA+IGxEaXN0KQoJICAgIGJyZWFrOwoJfQoKCWlmIChwb3MgPT0gbHBiaU91dC0+YmlXaWR0aCAmJiBjb3VudCA+IDgpIHsKCSAgLyogKGNvdW50ID4gOCkgc2VjdXJlcyB0aGF0IHdlIHdpbGwgc2F2ZSBzcGFjZSAqLwoJICBqdW1weSsrOwoJICBicmVhazsKCX0gZWxzZSBpZiAoanVtcHkgfHwganVtcHggIT0gcG9zKSB7CgkgIC8qIHRpbWUgdG8ganVtcCAqLwoJICBhc3NlcnQoanVtcHggIT0gLTEpOwoKCSAgaWYgKHBvcyA8IGp1bXB4KSB7CgkgICAgLyogY2FuIG9ubHkganVtcCBpbiBwb3NpdGl2ZSBkaXJlY3Rpb24gLS0ganVtcCB1bnRpbCBFT0wsIEVPTCAqLwoJICAgIElOVCB3ID0gbHBiaU91dC0+YmlXaWR0aCAtIGp1bXB4OwoKCSAgICBhc3NlcnQoanVtcHkgPiAwKTsKCSAgICBhc3NlcnQodyA+PSA0KTsKCgkgICAganVtcHggPSAwOwoJICAgIGp1bXB5LS07CgkgICAgLyogaWYgKHcgJSAyNTUgPT0gMikgdGhlbiBlcXVhbCBjb3N0cwoJICAgICAqIGVsc2UgaWYgKHcgJSAyNTUgPCA0ICYmIHdlIGNvdWxkIGVuY29kZSBhbGwpIHRoZW4gMiBieXRlcyB0b28gZXhwZW5zaXZlCgkgICAgICogZWxzZSBpdCB3aWxsIGJlIGNoZWFwZXIKCSAgICAgKi8KCSAgICB3aGlsZSAodyA+IDApIHsKCSAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgICAqbHBPdXQrKyA9IDA7CgkgICAgICAqbHBPdXQrKyA9IDI7CgkgICAgICAqbHBPdXQgICA9IG1pbih3LCAyNTUpOwoJICAgICAgdyAgICAgICAtPSAqbHBPdXQrKzsKCSAgICAgICpscE91dCsrID0gMDsKCSAgICB9CgkgICAgLyogYWRkIEVPTCAtLSBlbmQgb2YgbGluZSAqLwoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CgkgICAgKigoTFBXT1JEKWxwT3V0KSA9IDA7CgkgICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwoJICB9CgoJICAvKiBGSVhNRTogaWYgKGp1bXB5ID09IDAgJiYgY291bGQgZW5jb2RlIGFsbCkgdGhlbiBqdW1wIHRvbyBleHBlbnNpdmUgKi8KCgkgIC8qIHdyaXRlIG91dCByZWFsIGp1bXAocykgKi8KCSAgd2hpbGUgKGp1bXB5IHx8IHBvcyAhPSBqdW1weCkgewoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgKmxwT3V0KysgPSAwOwoJICAgICpscE91dCsrID0gMjsKCSAgICAqbHBPdXQgICA9IG1pbihwb3MgLSBqdW1weCwgMjU1KTsKCSAgICB4ICAgICAgICs9ICpscE91dDsKCSAgICBqdW1weCAgICs9ICpscE91dCsrOwoJICAgICpscE91dCAgID0gbWluKGp1bXB5LCAyNTUpOwoJICAgIGp1bXB5ICAgLT0gKmxwT3V0Kys7CgkgIH0KCgkgIGp1bXB5ID0gMDsKCX0KCglqdW1weCA9IC0xOwoKCWlmICh4IDwgbHBiaU91dC0+YmlXaWR0aCkgewoJICAvKiBza2lwcGVkIHRoZSAnc2FtZScgdGhpbmdzIGNvcnJlc3BvbmRpbmcgdG8gcHJldmlvdXMgZnJhbWUgKi8KCSAgeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU0TGluZShwaSwgbHBQLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCSAgICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7Cgl9CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwUCAgICs9IGxMaW5lOwogICAgICBscEMgICArPSBsTGluZTsKICAgICAgbHBJbiAgKz0gbEluTGluZTsKCiAgICAgIGlmIChqdW1weSA9PSAwKSB7Cglhc3NlcnQoanVtcHggPT0gLTEpOwoKCS8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KCWxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CgkqKChMUFdPUkQpbHBPdXQpID0gMDsKICAgICAgICBscE91dCArPSBzaXplb2YoV09SRCk7Cglhc3NlcnQobHBPdXQgPT0gbHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKTsKICAgICAgfQogICAgfQoKICAgIC8qIGFkZCBFT0wgLS0gd2lsbCBiZSBjaGFuZ2VkIHRvIEVPSSAqLwogICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKICAgICooKExQV09SRClscE91dCkgPSAwOwogICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwogIH0KCiAgLyogY2hhbmdlIEVPTCB0byBFT0kgLS0gZW5kIG9mIGltYWdlICovCiAgbHBPdXRbLTFdID0gMTsKICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCkxSRVNVTFQgTVNSTEUzMl9Db21wcmVzc1JMRTgoQ29kZWNJbmZvICpwaSwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwgTFBCWVRFIGxwSW4sIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LCBMUEJZVEUgbHBPdXQsIEJPT0wgaXNLZXkpCnsKICBMUFdPUkQgbHBDOwogIExPTkcgICBsRGlzdCwgbEluTGluZSwgbExpbmU7CiAgTFBCWVRFIGxwT3V0U3RhcnQgPSBscE91dDsKCiAgYXNzZXJ0KHBpICE9IE5VTEwgJiYgbHBiaU91dCAhPSBOVUxMKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwogIGFzc2VydChwaS0+cEN1ckZyYW1lICE9IE5VTEwpOwoKICBscEMgICAgID0gcGktPnBDdXJGcmFtZTsKICBsRGlzdCAgID0gUVVBTElUWV90b19ESVNUKHBpLT5kd1F1YWxpdHkpOwogIGxJbkxpbmUgPSBESUJXSURUSEJZVEVTKCpscGJpSW4pOwogIGxMaW5lICAgPSBXSURUSEJZVEVTKGxwYmlPdXQtPmJpV2lkdGggKiAxNikgLyAyOwoKICBscGJpT3V0LT5iaVNpemVJbWFnZSA9IDA7CiAgaWYgKGlzS2V5KSB7CiAgICAvKiBrZXlmcmFtZSAtLSBjb252ZXJ0IGludGVybmFsIGZyYW1lIHRvIG91dHB1dCBmb3JtYXQgKi8KICAgIElOVCB4LCB5OwoKICAgIGZvciAoeSA9IDA7IHkgPCBscGJpT3V0LT5iaUhlaWdodDsgeSsrKSB7CiAgICAgIHggPSAwOwoKICAgICAgZG8gewoJeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU4TGluZShwaSwgTlVMTCwgbHBDLCBscGJpSW4sIGxwSW4sIGxEaXN0LCB4LAoJCQkgICAgICZscE91dCwgJmxwYmlPdXQtPmJpU2l6ZUltYWdlKTsKCWFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwQyAgKz0gbExpbmU7CiAgICAgIGxwSW4gKz0gbEluTGluZTsKCiAgICAgIC8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KICAgICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKICAgICAgKigoTFBXT1JEKWxwT3V0KSA9IDA7CiAgICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKICAgICAgYXNzZXJ0KGxwT3V0ID09IChscE91dFN0YXJ0ICsgbHBiaU91dC0+YmlTaXplSW1hZ2UpKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogZGVsdGEtZnJhbWUgLS0gY29tcHV0ZSBkZWx0YSBiZXR3ZWVuIGxhc3QgYW5kIHRoaXMgaW50ZXJuYWwgZnJhbWUgKi8KICAgIExQV09SRCBscFA7CiAgICBJTlQgICAgeCwgeTsKICAgIElOVCAgICBqdW1weCwganVtcHk7CgogICAgYXNzZXJ0KHBpLT5wUHJldkZyYW1lICE9IE5VTEwpOwoKICAgIGxwUCAgID0gcGktPnBQcmV2RnJhbWU7CiAgICBqdW1weCA9IC0xOwogICAganVtcHkgPSAwOwoKICAgIGZvciAoeSA9IDA7IHkgPCBscGJpT3V0LT5iaUhlaWdodDsgeSsrKSB7CiAgICAgIHggPSAwOwoKICAgICAgZG8gewoJSU5UIGNvdW50LCBwb3M7CgoJaWYgKGp1bXB4ID09IC0xKQoJICBqdW1weCA9IHg7Cglmb3IgKGNvdW50ID0gMCwgcG9zID0geDsgcG9zIDwgbHBiaU91dC0+YmlXaWR0aDsgcG9zKyssIGNvdW50KyspIHsKCSAgaWYgKENvbG9yQ21wKGxwUFtwb3NdLCBscENbcG9zXSkgPiBsRGlzdCkKCSAgICBicmVhazsKCX0KCglpZiAocG9zID09IGxwYmlPdXQtPmJpV2lkdGggJiYgY291bnQgPiA0KSB7CgkgIC8qIChjb3VudCA+IDQpIHNlY3VyZXMgdGhhdCB3ZSB3aWxsIHNhdmUgc3BhY2UgKi8KCSAganVtcHkrKzsKCSAgYnJlYWs7Cgl9IGVsc2UgaWYgKGp1bXB5IHx8IGp1bXB4ICE9IHBvcykgewoJICAvKiB0aW1lIHRvIGp1bXAgKi8KCSAgYXNzZXJ0KGp1bXB4ICE9IC0xKTsKCgkgIGlmIChwb3MgPCBqdW1weCkgewoJICAgIC8qIGNhbiBvbmx5IGp1bXAgaW4gcG9zaXRpdmUgZGlyZWN0aW9uIC0tIGRvIGFuIEVPTCB0aGVuIGp1bXAgKi8KCSAgICBhc3NlcnQoanVtcHkgPiAwKTsKCgkgICAganVtcHggPSAwOwoJICAgIGp1bXB5LS07CgoJICAgIC8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KCSAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJICAgICooKExQV09SRClscE91dCkgPSAwOwoJICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKCSAgICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoJICB9CgoJICAvKiBGSVhNRTogaWYgKGp1bXB5ID09IDAgJiYgY291bGQgZW5jb2RlIGFsbCkgdGhlbiBqdW1wIHRvbyBleHBlbnNpdmUgKi8KCgkgIC8qIHdyaXRlIG91dCByZWFsIGp1bXAocykgKi8KCSAgd2hpbGUgKGp1bXB5IHx8IHBvcyAhPSBqdW1weCkgewoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgKmxwT3V0KysgPSAwOwoJICAgICpscE91dCsrID0gMjsKCSAgICAqbHBPdXQgICA9IG1pbihwb3MgLSBqdW1weCwgMjU1KTsKCSAgICBqdW1weCAgICs9ICpscE91dCsrOwoJICAgICpscE91dCAgID0gbWluKGp1bXB5LCAyNTUpOwoJICAgIGp1bXB5ICAgLT0gKmxwT3V0Kys7CgkgIH0KCSAgeCA9IHBvczsKCgkgIGp1bXB5ID0gMDsKCX0KCglqdW1weCA9IC0xOwoKCWlmICh4IDwgbHBiaU91dC0+YmlXaWR0aCkgewoJICAvKiBza2lwIHRoZSAnc2FtZScgdGhpbmdzIGNvcnJlc3BvbmRpbmcgdG8gcHJldmlvdXMgZnJhbWUgKi8KCSAgeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU4TGluZShwaSwgbHBQLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCSAgICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7CgkgIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7Cgl9CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwUCAgKz0gbExpbmU7CiAgICAgIGxwQyAgKz0gbExpbmU7CiAgICAgIGxwSW4gKz0gbEluTGluZTsKCiAgICAgIGlmIChqdW1weSA9PSAwKSB7CgkvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCglscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJKigoTFBXT1JEKWxwT3V0KSA9IDA7CglscE91dCArPSBzaXplb2YoV09SRCk7Cglhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgICB9CiAgICB9CgogICAgLyogYWRkIEVPTCAtLSB3aWxsIGJlIGNoYW5nZWQgdG8gRU9JICovCiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwogICAgKigoTFBXT1JEKWxwT3V0KSA9IDA7CiAgICBscE91dCArPSBzaXplb2YoV09SRCk7CiAgfQoKICAvKiBjaGFuZ2UgRU9MIHRvIEVPSSAtLSBlbmQgb2YgaW1hZ2UgKi8KICBscE91dFstMV0gPSAxOwogIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIExSRVNVTFQgTVNSTEUzMl9EZWNvbXByZXNzUkxFNChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksCgkJCQkgICAgICBMUEJZVEUgbHBJbiwgTFBCWVRFIGxwT3V0KQp7CiAgaW50ICBieXRlc19wZXJfcGl4ZWw7CiAgaW50ICBsaW5lX3NpemU7CiAgaW50ICBwaXhlbF9wdHIgID0gMDsKICBpbnQgIGk7CiAgQk9PTCBiRW5kRmxhZyAgID0gRkFMU0U7CgogIGFzc2VydChwaSAhPSBOVUxMKTsKICBhc3NlcnQobHBiaSAhPSBOVUxMICYmIGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwoKICBieXRlc19wZXJfcGl4ZWwgPSAobHBiaS0+YmlCaXRDb3VudCArIDEpIC8gODsKICBsaW5lX3NpemUgICAgICAgPSBESUJXSURUSEJZVEVTKCpscGJpKTsKCiAgZG8gewogICAgQllURSBjb2RlMCwgY29kZTE7CgogICAgY29kZTAgPSAqbHBJbisrOwogICAgY29kZTEgPSAqbHBJbisrOwoKICAgIGlmIChjb2RlMCA9PSAwKSB7CiAgICAgIGludCAgZXh0cmFfYnl0ZTsKCiAgICAgIHN3aXRjaCAoY29kZTEpIHsKICAgICAgY2FzZSAgMDogLyogRU9MIC0gZW5kIG9mIGxpbmUgICovCglwaXhlbF9wdHIgPSAwOwoJbHBPdXQgKz0gbGluZV9zaXplOwoJYnJlYWs7CiAgICAgIGNhc2UgIDE6IC8qIEVPSSAtIGVuZCBvZiBpbWFnZSAqLwoJYkVuZEZsYWcgPSBUUlVFOwoJYnJlYWs7CiAgICAgIGNhc2UgIDI6IC8qIHNraXAgKi8KCXBpeGVsX3B0ciArPSAqbHBJbisrICogYnl0ZXNfcGVyX3BpeGVsOwoJbHBPdXQgICAgICs9ICpscEluKysgKiBsaW5lX3NpemU7CglpZiAocGl4ZWxfcHRyID49IGxwYmktPmJpV2lkdGggKiBieXRlc19wZXJfcGl4ZWwpIHsKCSAgcGl4ZWxfcHRyID0gMDsKCSAgbHBPdXQgICAgKz0gbGluZV9zaXplOwoJfQoJYnJlYWs7CiAgICAgIGRlZmF1bHQ6IC8qIGFic29sdXRlIG1vZGUgKi8KCWV4dHJhX2J5dGUgPSAoKChjb2RlMSArIDEpICYgKH4xKSkgLyAyKSAmIDB4MDE7CgoJaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMSA+IGxwYmktPmJpV2lkdGgpCgkgIHJldHVybiBJQ0VSUl9FUlJPUjsKCgljb2RlMCA9IGNvZGUxOwoJZm9yIChpID0gMDsgaSA8IGNvZGUwIC8gMjsgaSsrKSB7CgkgIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMSkgewoJICAgIGNvZGUxID0gbHBJbltpXTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpXTsKCSAgICBpZiAoMiAqIGkgKyAxIDw9IGNvZGUwKQoJICAgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpXTsKCSAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgoJICAgIGlmICgyICogaSArIDEgPD0gY29kZTApIHsKCSAgICAgIGNvZGUxID0gbHBJbltpXSAmIDB4MEY7CgkgICAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMF07CgkgICAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgkgICAgfQoJICB9IGVsc2UgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDJdOwoJICAgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7CgoJICAgIGlmICgyICogaSArIDEgPD0gY29kZTApIHsKCSAgICAgIGNvZGUxID0gbHBJbltpXSAmIDB4MEY7CgkgICAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCSAgICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgICAgbHBPdXRbcGl4ZWxfcHRyICsgMl0gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiA0ICsgMl07CgkgICAgICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJICAgIH0KCSAgfQoJfQoJaWYgKGNvZGUwICYgMHgwMSkgewoJICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCSAgICBjb2RlMSA9IGxwSW5baV07CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSA+PiA0KV07CgkgIH0gZWxzZSBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDIpIHsKCSAgICBjb2RlMSA9IGxwSW5baV0gPj4gNDsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMF07CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogMiArIDFdOwoJICB9IGVsc2UgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDJdOwoJICAgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7CgkgIH0KCSAgbHBJbisrOwoJfQoJbHBJbiArPSBjb2RlMCAvIDI7CgoJLyogaWYgdGhlIFJMRSBjb2RlIGlzIG9kZCwgc2tpcCBhIGJ5dGUgaW4gdGhlIHN0cmVhbSAqLwoJaWYgKGV4dHJhX2J5dGUpCgkgIGxwSW4rKzsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNvZGVkIG1vZGUgKi8KICAgICAgaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMCA+IGxwYmktPmJpV2lkdGgpCglyZXR1cm4gSUNFUlJfRVJST1I7CgogICAgICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCUJZVEUgYzEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpXTsKCUJZVEUgYzIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRildOwoKCWZvciAoaSA9IDA7IGkgPCBjb2RlMDsgaSsrKSB7CgkgIGlmICgoaSAmIDEpID09IDApCgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gYzE7CgkgIGVsc2UKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBjMjsKCX0KICAgICAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJQllURSBoaTEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogMiArIDBdOwoJQllURSBsbzEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogMiArIDFdOwoKCUJZVEUgaGkyID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpICogMiArIDBdOwoJQllURSBsbzIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRikgKiAyICsgMV07CgoJZm9yIChpID0gMDsgaSA8IGNvZGUwOyBpKyspIHsKCSAgaWYgKChpICYgMSkgPT0gMCkgewoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IGhpMTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBsbzE7CgkgIH0gZWxzZSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gaGkyOwoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IGxvMjsKCSAgfQoJfQogICAgICB9IGVsc2UgewoJQllURSBiMSA9IHBpLT5wYWxldHRlX21hcFsoY29kZTEgPj4gNCkgKiA0ICsgMF07CglCWVRFIGcxID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSA+PiA0KSAqIDQgKyAxXTsKCUJZVEUgcjEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogNCArIDJdOwoKCUJZVEUgYjIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRikgKiA0ICsgMF07CglCWVRFIGcyID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpICogNCArIDFdOwoJQllURSByMiA9IHBpLT5wYWxldHRlX21hcFsoY29kZTEgJiAweDBGKSAqIDQgKyAyXTsKCglmb3IgKGkgPSAwOyBpIDwgY29kZTA7IGkrKykgewoJICBpZiAoKGkgJiAxKSA9PSAwKSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcxOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjE7CgkgIH0gZWxzZSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMjsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcyOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjI7CgkgIH0KCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfQogICAgfQogIH0gd2hpbGUgKCEgYkVuZEZsYWcpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTgoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgTFBCWVRFIGxwSW4sIExQQllURSBscE91dCkKewogIGludCAgYnl0ZXNfcGVyX3BpeGVsOwogIGludCAgbGluZV9zaXplOwogIGludCAgcGl4ZWxfcHRyICA9IDA7CiAgQk9PTCBiRW5kRmxhZyAgID0gRkFMU0U7CgogIGFzc2VydChwaSAhPSBOVUxMKTsKICBhc3NlcnQobHBiaSAhPSBOVUxMICYmIGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwoKICBieXRlc19wZXJfcGl4ZWwgPSAobHBiaS0+YmlCaXRDb3VudCArIDEpIC8gODsKICBsaW5lX3NpemUgICAgICAgPSBESUJXSURUSEJZVEVTKCpscGJpKTsKCiAgZG8gewogICAgQllURSBjb2RlMCwgY29kZTE7CgogICAgY29kZTAgPSAqbHBJbisrOwogICAgY29kZTEgPSAqbHBJbisrOwoKICAgIGlmIChjb2RlMCA9PSAwKSB7CiAgICAgIGludCAgZXh0cmFfYnl0ZTsKCiAgICAgIHN3aXRjaCAoY29kZTEpIHsKICAgICAgY2FzZSAgMDogLyogRU9MIC0gZW5kIG9mIGxpbmUgICovCglwaXhlbF9wdHIgPSAwOwoJbHBPdXQgKz0gbGluZV9zaXplOwoJYnJlYWs7CiAgICAgIGNhc2UgIDE6IC8qIEVPSSAtIGVuZCBvZiBpbWFnZSAqLwoJYkVuZEZsYWcgPSBUUlVFOwoJYnJlYWs7CiAgICAgIGNhc2UgIDI6IC8qIHNraXAgKi8KCXBpeGVsX3B0ciArPSAqbHBJbisrICogYnl0ZXNfcGVyX3BpeGVsOwoJbHBPdXQgICAgICs9ICpscEluKysgKiBsaW5lX3NpemU7CglpZiAocGl4ZWxfcHRyID49IGxwYmktPmJpV2lkdGggKiBieXRlc19wZXJfcGl4ZWwpIHsKCSAgcGl4ZWxfcHRyID0gMDsKCSAgbHBPdXQgICAgKz0gbGluZV9zaXplOwoJfQoJYnJlYWs7CiAgICAgIGRlZmF1bHQ6IC8qIGFic29sdXRlIG1vZGUgKi8KCWlmIChwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTEgPiBscGJpLT5iaVdpZHRoKSB7CgkgIFdBUk4oImFib3J0ZWQgYWJzb2x1dGU6ICglZD0lZC8lZCslZCkgPiAlbGRcbiIscGl4ZWxfcHRyL2J5dGVzX3Blcl9waXhlbCArIGNvZGUxLHBpeGVsX3B0cixieXRlc19wZXJfcGl4ZWwsY29kZTEsbHBiaS0+YmlXaWR0aCk7CgkgIHJldHVybiBJQ0VSUl9FUlJPUjsKCX0KCWV4dHJhX2J5dGUgPSBjb2RlMSAmIDB4MDE7CgoJY29kZTAgPSBjb2RlMTsKCXdoaWxlIChjb2RlMC0tKSB7CgkgIGNvZGUxID0gKmxwSW4rKzsKCSAgaWYgKGJ5dGVzX3Blcl9waXhlbCA9PSAxKSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMV07CgkgIH0gZWxzZSBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDIpIHsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAxXTsKCSAgfSBlbHNlIHsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAxXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAyXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAyXTsKCSAgfQoJICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJfQoKCS8qIGlmIHRoZSBSTEUgY29kZSBpcyBvZGQsIHNraXAgYSBieXRlIGluIHRoZSBzdHJlYW0gKi8KCWlmIChleHRyYV9ieXRlKQoJICBscEluKys7CiAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAvKiBjb2RlZCBtb2RlICovCiAgICAgIGlmIChwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTAgPiBscGJpLT5iaVdpZHRoKSB7CglXQVJOKCJhYm9ydGVkIGNvZGVkOiAoJWQ9JWQvJWQrJWQpID4gJWxkXG4iLHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMSxwaXhlbF9wdHIsYnl0ZXNfcGVyX3BpeGVsLGNvZGUxLGxwYmktPmJpV2lkdGgpOwoJcmV0dXJuIElDRVJSX0VSUk9SOwogICAgICB9CgogICAgICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCWNvZGUxID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxXTsKCXdoaWxlIChjb2RlMC0tKQoJICBscE91dFtwaXhlbF9wdHIrK10gPSBjb2RlMTsKICAgICAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJQllURSBoaSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCUJZVEUgbG8gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgoJd2hpbGUgKGNvZGUwLS0pIHsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBoaTsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMV0gPSBsbzsKCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfSBlbHNlIHsKCUJZVEUgciA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAyXTsKCUJZVEUgZyA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAxXTsKCUJZVEUgYiA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCgl3aGlsZSAoY29kZTAtLSkgewoJICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IGI7CgkgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gZzsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMl0gPSByOwoJICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJfQogICAgICB9CiAgICB9CiAgfSB3aGlsZSAoISBiRW5kRmxhZyk7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIENvZGVjSW5mbyogT3BlbihMUElDT1BFTiBpY2luZm8pCnsKICBDb2RlY0luZm8qIHBpID0gTlVMTDsKCiAgaWYgKGljaW5mbyA9PSBOVUxMKSB7CiAgICBUUkFDRSgiKE5VTEwpXG4iKTsKICAgIHJldHVybiAoTFBWT0lEKTB4RkZGRjAwMDA7CiAgfQoKICBpZiAoaWNpbmZvLT5mY2NUeXBlICE9IElDVFlQRV9WSURFTykgcmV0dXJuIE5VTEw7CgogIFRSQUNFKCIoJXAgPSB7JWx1LDB4JTA4bFgoJTQuNHMpLDB4JTA4bFgoJTQuNHMpLDB4JWxYLDB4JWxYLC4uLn0pXG4iLCBpY2luZm8sCglpY2luZm8tPmR3U2l6ZSwJaWNpbmZvLT5mY2NUeXBlLCAoY2hhciopJmljaW5mby0+ZmNjVHlwZSwKCWljaW5mby0+ZmNjSGFuZGxlciwgKGNoYXIqKSZpY2luZm8tPmZjY0hhbmRsZXIsCglpY2luZm8tPmR3VmVyc2lvbixpY2luZm8tPmR3RmxhZ3MpOwoKICBzd2l0Y2ggKGljaW5mby0+ZmNjSGFuZGxlcikgewogIGNhc2UgRk9VUkNDX1JMRToKICBjYXNlIEZPVVJDQ19STEU0OgogIGNhc2UgRk9VUkNDX1JMRTg6CiAgY2FzZSBGT1VSQ0NfTVJMRToKICAgIGJyZWFrOwogIGNhc2UgbW1pb0ZPVVJDQygnbScsJ3InLCdsJywnZScpOgogICAgaWNpbmZvLT5mY2NIYW5kbGVyID0gRk9VUkNDX01STEU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigidW5rbm93biBGT1VSQ0MgPSAweCUwOGxYKCU0LjRzKSAhXG4iLAoJIGljaW5mby0+ZmNjSGFuZGxlciwoY2hhciopJmljaW5mby0+ZmNjSGFuZGxlcik7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIHBpID0gKENvZGVjSW5mbyopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoQ29kZWNJbmZvKSk7CgogIGlmIChwaSAhPSBOVUxMKSB7CiAgICBwaS0+ZmNjSGFuZGxlciAgPSBpY2luZm8tPmZjY0hhbmRsZXI7CgogICAgcGktPmJDb21wcmVzcyAgID0gRkFMU0U7CiAgICBwaS0+ZHdRdWFsaXR5ICAgPSBNU1JMRTMyX0RFRkFVTFRRVUFMSVRZOwogICAgcGktPm5QcmV2RnJhbWUgID0gLTE7CiAgICBwaS0+cFByZXZGcmFtZSAgPSBwaS0+cEN1ckZyYW1lID0gTlVMTDsKCiAgICBwaS0+YkRlY29tcHJlc3MgPSBGQUxTRTsKICAgIHBpLT5wYWxldHRlX21hcCA9IE5VTEw7CiAgfQoKICBpY2luZm8tPmR3RXJyb3IgPSAocGkgIT0gTlVMTCA/IElDRVJSX09LIDogSUNFUlJfTUVNT1JZKTsKCiAgcmV0dXJuIHBpOwp9CgpzdGF0aWMgTFJFU1VMVCBDbG9zZShDb2RlY0luZm8gKnBpKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBpKTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgaWYgKHBpLT5wUHJldkZyYW1lICE9IE5VTEwgfHwgcGktPnBDdXJGcmFtZSAhPSBOVUxMKQogICAgQ29tcHJlc3NFbmQocGkpOwoKICBMb2NhbEZyZWUoKEhMT0NBTClwaSk7CiAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBMUkVTVUxUIEdldEluZm8oQ29kZWNJbmZvICpwaSwgSUNJTkZPICppY2luZm8sIERXT1JEIGR3U2l6ZSkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoaWNpbmZvID09IE5VTEwpCiAgICByZXR1cm4gc2l6ZW9mKElDSU5GTyk7CiAgaWYgKGR3U2l6ZSA8IHNpemVvZihJQ0lORk8pKQogICAgcmV0dXJuIDA7CgogIGljaW5mby0+ZHdTaXplICAgICAgID0gc2l6ZW9mKElDSU5GTyk7CiAgaWNpbmZvLT5mY2NUeXBlICAgICAgPSBJQ1RZUEVfVklERU87CiAgaWNpbmZvLT5mY2NIYW5kbGVyICAgPSAocGkgIT0gTlVMTCA/IHBpLT5mY2NIYW5kbGVyIDogRk9VUkNDX01STEUpOwogIGljaW5mby0+ZHdGbGFncyAgICAgID0gVklEQ0ZfUVVBTElUWSB8IFZJRENGX1RFTVBPUkFMIHwgVklEQ0ZfQ1JVTkNIIHwgVklEQ0ZfRkFTVFRFTVBPUkFMQzsKICBpY2luZm8tPmR3VmVyc2lvbiAgICA9IElDVkVSU0lPTjsKICBpY2luZm8tPmR3VmVyc2lvbklDTSA9IElDVkVSU0lPTjsKCiAgTG9hZFN0cmluZ1coTVNSTEUzMl9oTW9kdWxlLCBJRFNfTkFNRSwgaWNpbmZvLT5zek5hbWUsIHNpemVvZihpY2luZm8tPnN6TmFtZSkvc2l6ZW9mKFdDSEFSKSk7CiAgTG9hZFN0cmluZ1coTVNSTEUzMl9oTW9kdWxlLCBJRFNfREVTQ1JJUFRJT04sIGljaW5mby0+c3pEZXNjcmlwdGlvbiwgc2l6ZW9mKGljaW5mby0+c3pEZXNjcmlwdGlvbikvc2l6ZW9mKFdDSEFSKSk7CgogIHJldHVybiBzaXplb2YoSUNJTkZPKTsKfQoKc3RhdGljIExSRVNVTFQgU2V0UXVhbGl0eShDb2RlY0luZm8gKnBpLCBMT05HIGxRdWFsaXR5KQp7CiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgaWYgKGxRdWFsaXR5ID09IC0xKQogICAgbFF1YWxpdHkgPSBNU1JMRTMyX0RFRkFVTFRRVUFMSVRZOwogIGVsc2UgaWYgKElDUVVBTElUWV9MT1cgPiBsUXVhbGl0eSB8fCBsUXVhbGl0eSA+IElDUVVBTElUWV9ISUdIKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwoKICBwaS0+ZHdRdWFsaXR5ID0gKERXT1JEKWxRdWFsaXR5OwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIENvbmZpZ3VyZShDb2RlY0luZm8gKnBpLCBIV05EIGhXbmQpCnsKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBGSVhNRSAqLwogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgQWJvdXQoQ29kZWNJbmZvICpwaSwgSFdORCBoV25kKQp7CiAgQ0hBUiBzelRpdGxlWzIwXTsKICBDSEFSIHN6QWJvdXRbMTI4XTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChNU1JMRTMyX2hNb2R1bGUgIT0gMCk7CgogIExvYWRTdHJpbmdBKE1TUkxFMzJfaE1vZHVsZSwgSURTX05BTUUsIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKSk7CiAgTG9hZFN0cmluZ0EoTVNSTEUzMl9oTW9kdWxlLCBJRFNfQUJPVVQsIHN6QWJvdXQsIHNpemVvZihzekFib3V0KSk7CgogIE1lc3NhZ2VCb3hBKGhXbmQsIHN6QWJvdXQsIHN6VGl0bGUsIE1CX09LfE1CX0lDT05JTkZPUk1BVElPTik7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRGb3JtYXQoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpCnsKICBMUkVTVUxUIHNpemU7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAtLSBuZWVkIGF0IGxlYXN0IGlucHV0IGZvcm1hdCAqLwogIGlmIChscGJpSW4gPT0gTlVMTCkgewogICAgaWYgKGxwYmlPdXQgIT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBoYW5kbGUgdW5zdXBwb3J0ZWQgaW5wdXQgZm9ybWF0ICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgTlVMTCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gKGxwYmlPdXQgPT0gTlVMTCA/IElDRVJSX0JBREZPUk1BVCA6IDApOwoKICBhc3NlcnQoMCA8IGxwYmlJbi0+YmlCaXRDb3VudCAmJiBscGJpSW4tPmJpQml0Q291bnQgPD0gOCk7CgogIHN3aXRjaCAocGktPmZjY0hhbmRsZXIpIHsKICBjYXNlIEZPVVJDQ19STEU0OgogICAgc2l6ZSA9IDEgPDwgNDsKICAgIGJyZWFrOwogIGNhc2UgRk9VUkNDX1JMRTg6CiAgICBzaXplID0gMSA8PCA4OwogICAgYnJlYWs7CiAgY2FzZSBGT1VSQ0NfUkxFOgogIGNhc2UgRk9VUkNDX01STEU6CiAgICBzaXplID0gKGxwYmlJbi0+YmlCaXRDb3VudCA8PSA0ID8gMSA8PCA0IDogMSA8PCA4KTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gSUNFUlJfRVJST1I7CiAgfQoKICBpZiAobHBiaUluLT5iaUNsclVzZWQgIT0gMCkKICAgIHNpemUgPSBscGJpSW4tPmJpQ2xyVXNlZDsKCiAgc2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSArIHNpemUgKiBzaXplb2YoUkdCUVVBRCk7CgogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIGxwYmlPdXQtPmJpU2l6ZSAgICAgICAgICA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKICAgIGxwYmlPdXQtPmJpV2lkdGggICAgICAgICA9IGxwYmlJbi0+YmlXaWR0aDsKICAgIGxwYmlPdXQtPmJpSGVpZ2h0ICAgICAgICA9IGxwYmlJbi0+YmlIZWlnaHQ7CiAgICBscGJpT3V0LT5iaVBsYW5lcyAgICAgICAgPSAxOwogICAgaWYgKHBpLT5mY2NIYW5kbGVyID09IEZPVVJDQ19STEU0IHx8CglscGJpSW4tPmJpQml0Q291bnQgPD0gNCkgewogICAgICBscGJpT3V0LT5iaUNvbXByZXNzaW9uID0gQklfUkxFNDsKICAgICAgbHBiaU91dC0+YmlCaXRDb3VudCAgICA9IDQ7CiAgICB9IGVsc2UgewogICAgICBscGJpT3V0LT5iaUNvbXByZXNzaW9uID0gQklfUkxFODsKICAgICAgbHBiaU91dC0+YmlCaXRDb3VudCAgICA9IDg7CiAgICB9CiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSAgICAgPSBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKGxwYmlPdXQpOwogICAgbHBiaU91dC0+YmlYUGVsc1Blck1ldGVyID0gbHBiaUluLT5iaVhQZWxzUGVyTWV0ZXI7CiAgICBscGJpT3V0LT5iaVlQZWxzUGVyTWV0ZXIgPSBscGJpSW4tPmJpWVBlbHNQZXJNZXRlcjsKICAgIGlmIChscGJpSW4tPmJpQ2xyVXNlZCA9PSAwKQogICAgICBzaXplID0gMTw8bHBiaUluLT5iaUJpdENvdW50OwogICAgZWxzZQogICAgICBzaXplID0gbHBiaUluLT5iaUNsclVzZWQ7CiAgICBscGJpT3V0LT5iaUNsclVzZWQgICAgICAgPSBtaW4oc2l6ZSwgMSA8PCBscGJpT3V0LT5iaUJpdENvdW50KTsKICAgIGxwYmlPdXQtPmJpQ2xySW1wb3J0YW50ICA9IDA7CgogICAgbWVtY3B5KChMUEJZVEUpbHBiaU91dCArIGxwYmlPdXQtPmJpU2l6ZSwKCSAgIChjb25zdCBCWVRFKilscGJpSW4gKyBscGJpSW4tPmJpU2l6ZSwgbHBiaU91dC0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKTsKCiAgICByZXR1cm4gSUNFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRTaXplKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgLS0gbmVlZCBhdCBsZWFzdCBvbmUgZm9ybWF0ICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMICYmIGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiAwOwogIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBmb3JtYXQgaXMgc3VwcG9ydGVkICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gMDsKCiAgLyogdGhlIHdvcnN0IGNhc2UgaXMgY29kaW5nIHRoZSBjb21wbGV0ZSBpbWFnZSBpbiBhYnNvbHV0ZSBtb2RlLiAqLwogIGlmIChscGJpSW4pCiAgICByZXR1cm4gTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShscGJpSW4pOwogIGVsc2UKICAgIHJldHVybiBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKGxwYmlPdXQpOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc1F1ZXJ5KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIG5lZWQgYXQgbGVhc3Qgb25lIGZvcm1hdCAqLwogIGlmIChscGJpSW4gPT0gTlVMTCAmJiBscGJpT3V0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIC8qIGNoZWNrIGlucHV0IGZvcm1hdCBpZiBnaXZlbiAqLwogIGlmIChscGJpSW4gIT0gTlVMTCkgewogICAgaWYgKCFpc1N1cHBvcnRlZERJQihscGJpSW4pKQogICAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAgIC8qIGZvciA0LWJpdCBuZWVkIGFuIGV2ZW4gd2lkdGggKi8KICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPD0gNCAmJiAobHBiaUluLT5iaVdpZHRoICUgMikpCiAgICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogICAgaWYgKHBpLT5mY2NIYW5kbGVyID09IEZPVVJDQ19STEU0ICYmIGxwYmlJbi0+YmlCaXRDb3VudCA+IDQpCiAgICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgIGVsc2UgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA+IDgpCiAgICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIG91dHB1dCBmb3JtYXQgaWYgZ2l2ZW4gKi8KICBpZiAobHBiaU91dCAhPSBOVUxMKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkTVJMRShscGJpT3V0KSkKICAgICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgICBpZiAobHBiaUluICE9IE5VTEwpIHsKICAgICAgaWYgKGxwYmlJbi0+YmlXaWR0aCAgIT0gbHBiaU91dC0+YmlXaWR0aCkKCXJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgICAgaWYgKGxwYmlJbi0+YmlIZWlnaHQgIT0gbHBiaU91dC0+YmlIZWlnaHQpCglyZXR1cm4gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPiBscGJpT3V0LT5iaUJpdENvdW50KQoJcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogICAgfQogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIGNvbnN0IFJHQlFVQUQgKnJnYkluOwogIGNvbnN0IFJHQlFVQUQgKnJnYk91dDsKICBVSU5UICAgaTsKICBzaXplX3Qgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzIC0tIG5lZWQgYm90aCBmb3JtYXRzICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMIHx8IGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKICAvKiBBbmQgYm90aCBtdXN0IGJlIHN1cHBvcnRlZCAqLwogIGlmIChDb21wcmVzc1F1ZXJ5KHBpLCBscGJpSW4sIGxwYmlPdXQpICE9IElDRVJSX09LKQogICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgLyogRklYTUU6IGNhbm5vdCBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBhdCBzYW1lIHRpbWUhICovCiAgaWYgKHBpLT5iRGVjb21wcmVzcykgewogICAgRklYTUUoImNhbm5vdCBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBhdCBzYW1lIHRpbWUhXG4iKTsKICAgIHJldHVybiBJQ0VSUl9FUlJPUjsKICB9CgogIGlmIChwaS0+YkNvbXByZXNzKQogICAgQ29tcHJlc3NFbmQocGkpOwoKICBzaXplID0gV0lEVEhCWVRFUyhscGJpT3V0LT5iaVdpZHRoICogMTYpIC8gMiAqIGxwYmlPdXQtPmJpSGVpZ2h0OwogIHBpLT5wUHJldkZyYW1lID0gR2xvYmFsTG9jayhHbG9iYWxBbGxvYyhHUFRSLCBzaXplICogc2l6ZW9mKFdPUkQpKSk7CiAgaWYgKHBpLT5wUHJldkZyYW1lID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogIHBpLT5wQ3VyRnJhbWUgPSBHbG9iYWxMb2NrKEdsb2JhbEFsbG9jKEdQVFIsIHNpemUgKiBzaXplb2YoV09SRCkpKTsKICBpZiAocGktPnBDdXJGcmFtZSA9PSBOVUxMKSB7CiAgICBDb21wcmVzc0VuZChwaSk7CiAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogIH0KICBwaS0+blByZXZGcmFtZSA9IC0xOwogIHBpLT5iQ29tcHJlc3MgID0gVFJVRTsKCiAgcmdiSW4gID0gKGNvbnN0IFJHQlFVQUQqKSgoY29uc3QgQllURSopbHBiaUluICArIGxwYmlJbi0+YmlTaXplKTsKICByZ2JPdXQgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpT3V0ICsgbHBiaU91dC0+YmlTaXplKTsKCiAgc3dpdGNoIChscGJpT3V0LT5iaUJpdENvdW50KSB7CiAgY2FzZSA0OgogIGNhc2UgODoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCk7CiAgICBpZiAocGktPnBhbGV0dGVfbWFwID09IE5VTEwpIHsKICAgICAgQ29tcHJlc3NFbmQocGkpOwogICAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKSB7CiAgICAgIHBpLT5wYWxldHRlX21hcFtpXSA9IE1TUkxFMzJfR2V0TmVhcmVzdFBhbGV0dGVJbmRleChscGJpT3V0LT5iaUNsclVzZWQsIHJnYk91dCwgcmdiSW5baV0pOwogICAgfQogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzcyhDb2RlY0luZm8gKnBpLCBJQ0NPTVBSRVNTKiBscGljLCBEV09SRCBkd1NpemUpCnsKICBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcCwlbHUpXG4iLHBpLGxwaWMsZHdTaXplKTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscGljID09IE5VTEwgfHwgZHdTaXplIDwgc2l6ZW9mKElDQ09NUFJFU1MpKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogIGlmICghbHBpYy0+bHBiaU91dHB1dCB8fCAhbHBpYy0+bHBPdXRwdXQgfHwKICAgICAgIWxwaWMtPmxwYmlJbnB1dCAgfHwgIWxwaWMtPmxwSW5wdXQpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIFRSQUNFKCJscGljPXsweCVsWCwlcCwlcCwlcCwlcCwlcCwlcCwlbGQsJWx1LCVsdSwlcCwlcH1cbiIsbHBpYy0+ZHdGbGFncyxscGljLT5scGJpT3V0cHV0LGxwaWMtPmxwT3V0cHV0LGxwaWMtPmxwYmlJbnB1dCxscGljLT5scElucHV0LGxwaWMtPmxwY2tpZCxscGljLT5scGR3RmxhZ3MsbHBpYy0+bEZyYW1lTnVtLGxwaWMtPmR3RnJhbWVTaXplLGxwaWMtPmR3UXVhbGl0eSxscGljLT5scGJpUHJldixscGljLT5scFByZXYpOwoKICBpZiAoISBwaS0+YkNvbXByZXNzKSB7CiAgICBMUkVTVUxUIGhyID0gQ29tcHJlc3NCZWdpbihwaSwgbHBpYy0+bHBiaUlucHV0LCBscGljLT5scGJpT3V0cHV0KTsKICAgIGlmIChociAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIGhyOwogIH0gZWxzZSBpZiAoQ29tcHJlc3NRdWVyeShwaSwgbHBpYy0+bHBiaUlucHV0LCBscGljLT5scGJpT3V0cHV0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIGlmIChscGljLT5sRnJhbWVOdW0gPj0gcGktPm5QcmV2RnJhbWUgKyAxKSB7CiAgICAvKiB3ZSBjb250aW51ZSBpbiB0aGUgc2VxdWVuY2Ugc28gd2UgbmVlZCB0byBpbml0aWFsaXplIAogICAgICogb3VyIGludGVybmFsIGZyYW1lZGF0YSAqLwoKICAgIGNvbXB1dGVJbnRlcm5hbEZyYW1lKHBpLCBscGljLT5scGJpSW5wdXQsIGxwaWMtPmxwSW5wdXQpOwogIH0gZWxzZSBpZiAobHBpYy0+bEZyYW1lTnVtID09IHBpLT5uUHJldkZyYW1lKSB7CiAgICAvKiBPb3BzLCBjb21wcmVzcyBzYW1lIGZyYW1lIGFnYWluID8gT2theSwgYXMgeW91IHdpc2guCiAgICAgKiBObyBuZWVkIHRvIHJlY29tcHV0ZSBpbnRlcm5hbCBmcmFtZWRhdGEsIGJlY2F1c2Ugd2Ugb25seSBzd2FwcGVkIGJ1ZmZlcnMgKi8KICAgIExQV09SRCBwVG1wID0gcGktPnBQcmV2RnJhbWU7CgogICAgcGktPnBQcmV2RnJhbWUgPSBwaS0+cEN1ckZyYW1lOwogICAgcGktPnBDdXJGcmFtZSAgPSBwVG1wOwogIH0gZWxzZSBpZiAoKGxwaWMtPmR3RmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKSA9PSAwKSB7CiAgICBMUFdPUkQgcFRtcDsKCiAgICBXQVJOKCI6IHByZXY9JWxkIGN1cj0lbGQgZ29uZSBiYWNrPyAtLSB1bnRlc3RlZFxuIixwaS0+blByZXZGcmFtZSxscGljLT5sRnJhbWVOdW0pOwogICAgaWYgKGxwaWMtPmxwYmlQcmV2ID09IE5VTEwgfHwgbHBpYy0+bHBQcmV2ID09IE5VTEwpCiAgICAgIHJldHVybiBJQ0VSUl9HT1RPS0VZRlJBTUU7IC8qIE5lZWQgYSBrZXlmcmFtZSBpZiB5b3UgZ28gYmFjayAqLwogICAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwaWMtPmxwYmlQcmV2LCBscGljLT5scGJpT3V0cHV0KSAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgICBXQVJOKCI6IHByZXY9JWxkIGN1cj0lbGQgY29tcHV0ZSBzd2FwcGVkIC0tIHVudGVzdGVkXG4iLHBpLT5uUHJldkZyYW1lLGxwaWMtPmxGcmFtZU51bSk7CiAgICBjb21wdXRlSW50ZXJuYWxGcmFtZShwaSwgbHBpYy0+bHBiaVByZXYsIGxwaWMtPmxwUHJldik7CgogICAgLyogc3dhcCBidWZmZXJzIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICBwVG1wID0gcGktPnBQcmV2RnJhbWU7CiAgICBwaS0+cFByZXZGcmFtZSA9IHBpLT5wQ3VyRnJhbWU7CiAgICBwaS0+cEN1ckZyYW1lICA9IHBUbXA7CiAgICBwaS0+blByZXZGcmFtZSA9IGxwaWMtPmxGcmFtZU51bTsKICB9CgogIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgIFNldFF1YWxpdHkocGksIGxwaWMtPmR3UXVhbGl0eSk7CgogICAgbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPSAwOwoKICAgIGlmIChscGljLT5scGJpT3V0cHV0LT5iaUJpdENvdW50ID09IDQpCiAgICAgIE1TUkxFMzJfQ29tcHJlc3NSTEU0KHBpLCBscGljLT5scGJpSW5wdXQsIChMUEJZVEUpbHBpYy0+bHBJbnB1dCwKCQkgICBscGljLT5scGJpT3V0cHV0LCAoTFBCWVRFKWxwaWMtPmxwT3V0cHV0LCAobHBpYy0+ZHdGbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpICE9IDApOwogICAgZWxzZQogICAgICBNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgKGxwaWMtPmR3RmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKSAhPSAwKTsKCiAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPCBscGljLT5kd0ZyYW1lU2l6ZSkKICAgICAgYnJlYWs7CgogICAgaWYgKCgqbHBpYy0+bHBkd0ZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkgPT0gMCkgewogICAgICBpZiAobHBpYy0+bHBiaU91dHB1dC0+YmlCaXRDb3VudCA9PSA0KQoJTVNSTEUzMl9Db21wcmVzc1JMRTQocGksIGxwaWMtPmxwYmlJbnB1dCwgKExQQllURSlscGljLT5scElucHV0LAoJCQkgICAgIGxwaWMtPmxwYmlPdXRwdXQsIChMUEJZVEUpbHBpYy0+bHBPdXRwdXQsIFRSVUUpOwogICAgICBlbHNlCglNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJCSAgICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgVFJVRSk7CgogICAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJICBscGljLT5scGJpT3V0cHV0LT5iaVNpemVJbWFnZSA8IGxwaWMtPmR3RnJhbWVTaXplKSB7CglXQVJOKCJzd2l0Y2hlZCB0byBrZXlmcmFtZSwgd2FzIHNtYWxsIGVub3VnaCFcbiIpOwoJKmxwaWMtPmxwZHdGbGFncyB8PSBJQ0NPTVBSRVNTX0tFWUZSQU1FOwoJKmxwaWMtPmxwY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsCgkJCQkgICAgICAgU3RyZWFtRnJvbUZPVVJDQygqbHBpYy0+bHBja2lkKSk7CglicmVhazsKICAgICAgfQogICAgfQoKICAgIGlmIChscGljLT5kd1F1YWxpdHkgPCAxMDAwKQogICAgICBicmVhazsKCiAgICBscGljLT5kd1F1YWxpdHkgLT0gMTAwMDsgLyogcmVkdWNlIHF1YWxpdHkgYnkgMTAlICovCiAgfQoKICB7IC8qIHN3YXAgYnVmZmVyIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICByZWdpc3RlciBMUFdPUkQgcFRtcCA9IHBpLT5wUHJldkZyYW1lOwoKICAgIHBpLT5wUHJldkZyYW1lID0gcGktPnBDdXJGcmFtZTsKICAgIHBpLT5wQ3VyRnJhbWUgID0gcFRtcDsKICAgIHBpLT5uUHJldkZyYW1lID0gbHBpYy0+bEZyYW1lTnVtOwogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKQp7CiAgVFJBQ0UoIiglcClcbiIscGkpOwoKICBpZiAocGkgIT0gTlVMTCkgewogICAgaWYgKHBpLT5wUHJldkZyYW1lICE9IE5VTEwpCiAgICB7CiAgICAgIEdsb2JhbFVubG9jayhHbG9iYWxIYW5kbGUocGktPnBQcmV2RnJhbWUpKTsKICAgICAgR2xvYmFsRnJlZShHbG9iYWxIYW5kbGUocGktPnBQcmV2RnJhbWUpKTsKICAgIH0KICAgIGlmIChwaS0+cEN1ckZyYW1lICE9IE5VTEwpCiAgICB7CiAgICAgIEdsb2JhbFVubG9jayhHbG9iYWxIYW5kbGUocGktPnBDdXJGcmFtZSkpOwogICAgICBHbG9iYWxGcmVlKEdsb2JhbEhhbmRsZShwaS0+cEN1ckZyYW1lKSk7CiAgICB9CiAgICBwaS0+cFByZXZGcmFtZSA9IE5VTEw7CiAgICBwaS0+cEN1ckZyYW1lICA9IE5VTEw7CiAgICBwaS0+blByZXZGcmFtZSA9IC0xOwogICAgcGktPmJDb21wcmVzcyAgPSBGQUxTRTsKICB9CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0dldEZvcm1hdChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgRFdPUkQgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICBpZiAobHBiaUluID09IE5VTEwpCiAgICByZXR1cm4gKGxwYmlPdXQgIT0gTlVMTCA/IElDRVJSX0JBRFBBUkFNIDogMCk7CgogIGlmIChEZWNvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgTlVMTCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gKGxwYmlPdXQgIT0gTlVMTCA/IElDRVJSX0JBREZPUk1BVCA6IDApOwoKICBzaXplID0gbHBiaUluLT5iaVNpemU7CgogIGlmIChscGJpSW4tPmJpQml0Q291bnQgPD0gOCkKICAgIHNpemUgKz0gbHBiaUluLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCk7CgogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIG1lbWNweShscGJpT3V0LCBscGJpSW4sIHNpemUpOwogICAgbHBiaU91dC0+YmlDb21wcmVzc2lvbiAgPSBCSV9SR0I7CiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSAgICA9IERJQldJRFRIQllURVMoKmxwYmlPdXQpICogbHBiaU91dC0+YmlIZWlnaHQ7CgogICAgcmV0dXJuIElDRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NRdWVyeShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIExSRVNVTFQgaHIgPSBJQ0VSUl9PSzsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBuZWVkIGF0IGxlYXN0IG9uZSBmb3JtYXQgKi8KICBpZiAobHBiaUluID09IE5VTEwgJiYgbHBiaU91dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwoKICAvKiBjaGVjayBpbnB1dCBmb3JtYXQgaWYgZ2l2ZW4gKi8KICBpZiAobHBiaUluICE9IE5VTEwpIHsKICAgIGlmICghaXNTdXBwb3J0ZWRNUkxFKGxwYmlJbikpCiAgICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CiAgfQoKICAvKiBjaGVjayBvdXRwdXQgZm9ybWF0IGlmIGdpdmVuICovCiAgaWYgKGxwYmlPdXQgIT0gTlVMTCkgewogICAgaWYgKCFpc1N1cHBvcnRlZERJQihscGJpT3V0KSkKICAgICAgaHIgPSBJQ0VSUl9CQURGT1JNQVQ7CgogICAgaWYgKGxwYmlJbiAhPSBOVUxMKSB7CiAgICAgIGlmIChscGJpSW4tPmJpV2lkdGggICE9IGxwYmlPdXQtPmJpV2lkdGgpCglociA9IElDRVJSX1VOU1VQUE9SVEVEOwogICAgICBpZiAobHBiaUluLT5iaUhlaWdodCAhPSBscGJpT3V0LT5iaUhlaWdodCkKCWhyID0gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPiBscGJpT3V0LT5iaUJpdENvdW50KQoJaHIgPSBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgIH0KICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgY29uc3QgUkdCUVVBRCAqcmdiSW47CiAgY29uc3QgUkdCUVVBRCAqcmdiT3V0OwogIFVJTlQgIGk7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscGJpSW4gPT0gTlVMTCB8fCBscGJpT3V0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CiAgaWYgKERlY29tcHJlc3NRdWVyeShwaSwgbHBiaUluLCBscGJpT3V0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIC8qIEZJWE1FOiBjYW5ub3QgY29tcHJlc3MgYW5kIGRlY29tcHJlc3MgYXQgYSB0aW1lISAqLwogIGlmIChwaS0+YkNvbXByZXNzKSB7CiAgICBGSVhNRSgiY2Fubm90IGNvbXByZXNzIGFuZCBkZWNvbXByZXNzIGF0IHNhbWUgdGltZSFcbiIpOwogICAgcmV0dXJuIElDRVJSX0VSUk9SOwogIH0KCiAgaWYgKHBpLT5iRGVjb21wcmVzcykKICAgIERlY29tcHJlc3NFbmQocGkpOwoKICByZ2JJbiAgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpSW4gICsgbHBiaUluLT5iaVNpemUpOwogIHJnYk91dCA9IChjb25zdCBSR0JRVUFEKikoKGNvbnN0IEJZVEUqKWxwYmlPdXQgKyBscGJpT3V0LT5iaVNpemUpOwoKICBzd2l0Y2ggKGxwYmlPdXQtPmJpQml0Q291bnQpIHsKICBjYXNlIDQ6CiAgY2FzZSA4OgogICAgcGktPnBhbGV0dGVfbWFwID0gKExQQllURSlMb2NhbEFsbG9jKExQVFIsIGxwYmlJbi0+YmlDbHJVc2VkKTsKICAgIGlmIChwaS0+cGFsZXR0ZV9tYXAgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX01FTU9SWTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbHBiaUluLT5iaUNsclVzZWQ7IGkrKykgewogICAgICBwaS0+cGFsZXR0ZV9tYXBbaV0gPSBNU1JMRTMyX0dldE5lYXJlc3RQYWxldHRlSW5kZXgobHBiaU91dC0+YmlDbHJVc2VkLCByZ2JPdXQsIHJnYkluW2ldKTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMTU6CiAgY2FzZSAxNjoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCAqIDIpOwogICAgaWYgKHBpLT5wYWxldHRlX21hcCA9PSBOVUxMKQogICAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKSB7CiAgICAgIFdPUkQgY29sb3I7CgogICAgICBpZiAobHBiaU91dC0+YmlCaXRDb3VudCA9PSAxNSkKCWNvbG9yID0gKChyZ2JJbltpXS5yZ2JSZWQgPj4gMykgPDwgMTApCgkgIHwgKChyZ2JJbltpXS5yZ2JHcmVlbiA+PiAzKSA8PCA1KSB8IChyZ2JJbltpXS5yZ2JCbHVlID4+IDMpOwogICAgICBlbHNlCgljb2xvciA9ICgocmdiSW5baV0ucmdiUmVkID4+IDMpIDw8IDExKQoJICB8ICgocmdiSW5baV0ucmdiR3JlZW4gPj4gMykgPDwgNSkgfCAocmdiSW5baV0ucmdiQmx1ZSA+PiAzKTsKCiAgICAgIHBpLT5wYWxldHRlX21hcFtpICogMiArIDFdID0gY29sb3IgPj4gODsKICAgICAgcGktPnBhbGV0dGVfbWFwW2kgKiAyICsgMF0gPSBjb2xvciAmIDB4RkY7CiAgICB9OwogICAgYnJlYWs7CiAgY2FzZSAyNDoKICBjYXNlIDMyOgogICAgcGktPnBhbGV0dGVfbWFwID0gKExQQllURSlMb2NhbEFsbG9jKExQVFIsIGxwYmlJbi0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKTsKICAgIGlmIChwaS0+cGFsZXR0ZV9tYXAgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX01FTU9SWTsKICAgIG1lbWNweShwaS0+cGFsZXR0ZV9tYXAsIHJnYkluLCBscGJpSW4tPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKSk7CiAgICBicmVhazsKICB9OwoKICBwaS0+YkRlY29tcHJlc3MgPSBUUlVFOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3MoQ29kZWNJbmZvICpwaSwgSUNERUNPTVBSRVNTICpwaWMsIERXT1JEIGR3U2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWx1KVxuIixwaSxwaWMsZHdTaXplKTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChwaWMgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKICBpZiAocGljLT5scGJpSW5wdXQgPT0gTlVMTCB8fCBwaWMtPmxwSW5wdXQgPT0gTlVMTCB8fAogICAgICBwaWMtPmxwYmlPdXRwdXQgPT0gTlVMTCB8fCBwaWMtPmxwT3V0cHV0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIC8qIGNoZWNrIGZvcm1hdHMgKi8KICBpZiAoISBwaS0+YkRlY29tcHJlc3MpIHsKICAgIExSRVNVTFQgaHIgPSBEZWNvbXByZXNzQmVnaW4ocGksIHBpYy0+bHBiaUlucHV0LCBwaWMtPmxwYmlPdXRwdXQpOwogICAgaWYgKGhyICE9IElDRVJSX09LKQogICAgICByZXR1cm4gaHI7CiAgfSBlbHNlIGlmIChEZWNvbXByZXNzUXVlcnkocGksIHBpYy0+bHBiaUlucHV0LCBwaWMtPmxwYmlPdXRwdXQpICE9IElDRVJSX09LKQogICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgYXNzZXJ0KHBpYy0+bHBiaUlucHV0LT5iaVdpZHRoICA9PSBwaWMtPmxwYmlPdXRwdXQtPmJpV2lkdGgpOwogIGFzc2VydChwaWMtPmxwYmlJbnB1dC0+YmlIZWlnaHQgPT0gcGljLT5scGJpT3V0cHV0LT5iaUhlaWdodCk7CgogIHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPSBESUJXSURUSEJZVEVTKCpwaWMtPmxwYmlPdXRwdXQpICogcGljLT5scGJpT3V0cHV0LT5iaUhlaWdodDsKICBpZiAocGljLT5scGJpSW5wdXQtPmJpQml0Q291bnQgPT0gNCkKICAgIHJldHVybiBNU1JMRTMyX0RlY29tcHJlc3NSTEU0KHBpLCBwaWMtPmxwYmlPdXRwdXQsIHBpYy0+bHBJbnB1dCwgcGljLT5scE91dHB1dCk7CiAgZWxzZQogICAgcmV0dXJuIE1TUkxFMzJfRGVjb21wcmVzc1JMRTgocGksIHBpYy0+bHBiaU91dHB1dCwgcGljLT5scElucHV0LCBwaWMtPmxwT3V0cHV0KTsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKQp7CiAgVFJBQ0UoIiglcClcbiIscGkpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICBwaS0+YkRlY29tcHJlc3MgPSBGQUxTRTsKCiAgaWYgKHBpLT5wYWxldHRlX21hcCAhPSBOVUxMKSB7CiAgICBMb2NhbEZyZWUoKEhMT0NBTClwaS0+cGFsZXR0ZV9tYXApOwogICAgcGktPnBhbGV0dGVfbWFwID0gTlVMTDsKICB9CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0dldFBhbGV0dGUoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpCnsKICBpbnQgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMIHx8IGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgaWYgKERlY29tcHJlc3NRdWVyeShwaSwgbHBiaUluLCBscGJpT3V0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIGlmIChscGJpT3V0LT5iaUJpdENvdW50ID4gOCkKICAgIHJldHVybiBJQ0VSUl9FUlJPUjsKCiAgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA8PSA4KSB7CiAgICBpZiAobHBiaUluLT5iaUNsclVzZWQgPiAwKQogICAgICBzaXplID0gbHBiaUluLT5iaUNsclVzZWQ7CiAgICBlbHNlCiAgICAgIHNpemUgPSAoMSA8PCBscGJpSW4tPmJpQml0Q291bnQpOwoKICAgIGxwYmlPdXQtPmJpQ2xyVXNlZCA9IHNpemU7CgogICAgbWVtY3B5KChMUEJZVEUpbHBiaU91dCArIGxwYmlPdXQtPmJpU2l6ZSwgKGNvbnN0IEJZVEUqKWxwYmlJbiArIGxwYmlJbi0+YmlTaXplLCBzaXplICogc2l6ZW9mKFJHQlFVQUQpKTsKICB9IC8qIGVsc2UgY291bGQgbmV2ZXIgb2NjdXIgISAqLwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCi8qIERyaXZlclByb2MgLSBlbnRyeSBwb2ludCBmb3IgYW4gaW5zdGFsbGFibGUgZHJpdmVyICovCkxSRVNVTFQgQ0FMTEJBQ0sgTVNSTEUzMl9Ecml2ZXJQcm9jKERXT1JEX1BUUiBkd0RydklELCBIRFJWUiBoRHJ2LCBVSU5UIHVNc2csCgkJCQkgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgQ29kZWNJbmZvICpwaSA9IChDb2RlY0luZm8qKWR3RHJ2SUQ7CgogIFRSQUNFKCIoJWx4LCVwLDB4JTA0WCwweCUwOGxYLDB4JTA4bFgpXG4iLCBkd0RydklELCBoRHJ2LCB1TXNnLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgc3dpdGNoICh1TXNnKSB7CiAgICAvKiBzdGFuZGFyZCBkcml2ZXIgbWVzc2FnZXMgKi8KICBjYXNlIERSVl9MT0FEOgogICAgcmV0dXJuIERSVkNORl9PSzsKICBjYXNlIERSVl9PUEVOOgogICAgICByZXR1cm4gKExSRVNVTFQpT3BlbigoSUNPUEVOKilsUGFyYW0yKTsKICBjYXNlIERSVl9DTE9TRToKICAgIGlmIChkd0RydklEICE9IDB4RkZGRjAwMDAgJiYgKExQVk9JRClkd0RydklEICE9IE5VTEwpCiAgICAgIENsb3NlKHBpKTsKICAgIHJldHVybiBEUlZDTkZfT0s7CiAgY2FzZSBEUlZfRU5BQkxFOgogIGNhc2UgRFJWX0RJU0FCTEU6CiAgICByZXR1cm4gRFJWQ05GX09LOwogIGNhc2UgRFJWX0ZSRUU6CiAgICByZXR1cm4gRFJWQ05GX09LOwogIGNhc2UgRFJWX1FVRVJZQ09ORklHVVJFOgogICAgcmV0dXJuIERSVkNORl9DQU5DRUw7IC8qIEZJWE1FICovCiAgY2FzZSBEUlZfQ09ORklHVVJFOgogICAgcmV0dXJuIERSVkNORl9PSzsgICAgIC8qIEZJWE1FICovCiAgY2FzZSBEUlZfSU5TVEFMTDoKICBjYXNlIERSVl9SRU1PVkU6CiAgICByZXR1cm4gRFJWQ05GX09LOwoKICAgIC8qIGluc3RhbGxhYmxlIGNvbXByZXNzaW9uIG1hbmFnZXIgbWVzc2FnZXMgKi8KICBjYXNlIElDTV9DT05GSUdVUkU6CiAgICBGSVhNRSgiSUNNX0NPTkZJR1VSRSAoJWxkKVxuIixsUGFyYW0xKTsKICAgIGlmIChsUGFyYW0xID09IC0xKQogICAgICByZXR1cm4gSUNFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FICovCiAgICBlbHNlCiAgICAgIHJldHVybiBDb25maWd1cmUocGksIChIV05EKWxQYXJhbTEpOwogIGNhc2UgSUNNX0FCT1VUOgogICAgaWYgKGxQYXJhbTEgPT0gLTEpCiAgICAgIHJldHVybiBJQ0VSUl9PSzsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFib3V0KHBpLCAoSFdORClsUGFyYW0xKTsKICBjYXNlIElDTV9HRVRTVEFURToKICBjYXNlIElDTV9TRVRTVEFURToKICAgIHJldHVybiAwOyAvKiBubyBzdGF0ZSAqLwogIGNhc2UgSUNNX0dFVElORk86CiAgICByZXR1cm4gR2V0SW5mbyhwaSwgKElDSU5GTyopbFBhcmFtMSwgKERXT1JEKWxQYXJhbTIpOwogIGNhc2UgSUNNX0dFVERFRkFVTFRRVUFMSVRZOgogICAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMKSB7CiAgICAgICooKExQRFdPUkQpbFBhcmFtMSkgPSBNU1JMRTMyX0RFRkFVTFRRVUFMSVRZOwogICAgICByZXR1cm4gSUNFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIElDTV9HRVRRVUFMSVRZOgogICAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMKSB7CiAgICAgICooKExQRFdPUkQpbFBhcmFtMSkgPSBwaS0+ZHdRdWFsaXR5OwogICAgICByZXR1cm4gSUNFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIElDTV9TRVRRVUFMSVRZOgogICAgcmV0dXJuIFNldFF1YWxpdHkocGksICooTFBMT05HKWxQYXJhbTEpOwogIGNhc2UgSUNNX0NPTVBSRVNTX0dFVF9GT1JNQVQ6CiAgICByZXR1cm4gQ29tcHJlc3NHZXRGb3JtYXQocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAgICAgKExQQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTU19HRVRfU0laRToKICAgIHJldHVybiBDb21wcmVzc0dldFNpemUocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAgIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0NPTVBSRVNTX1FVRVJZOgogICAgcmV0dXJuIENvbXByZXNzUXVlcnkocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTU19CRUdJTjoKICAgIHJldHVybiBDb21wcmVzc0JlZ2luKHBpLCAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0xLAoJCQkgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fQ09NUFJFU1M6CiAgICByZXR1cm4gQ29tcHJlc3MocGksIChJQ0NPTVBSRVNTKilsUGFyYW0xLCAoRFdPUkQpbFBhcmFtMik7CiAgY2FzZSBJQ01fQ09NUFJFU1NfRU5EOgogICAgcmV0dXJuIENvbXByZXNzRW5kKHBpKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTX0dFVF9GT1JNQVQ6CiAgICByZXR1cm4gRGVjb21wcmVzc0dldEZvcm1hdChwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgICAgIChMUEJJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fREVDT01QUkVTU19RVUVSWToKICAgIHJldHVybiBEZWNvbXByZXNzUXVlcnkocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAgIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfQkVHSU46CiAgICByZXR1cm4gRGVjb21wcmVzc0JlZ2luKHBpLCAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0xLAoJCQkgICAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTOgogICAgcmV0dXJuIERlY29tcHJlc3MocGksIChJQ0RFQ09NUFJFU1MqKWxQYXJhbTEsIChEV09SRClsUGFyYW0yKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTX0VORDoKICAgIHJldHVybiBEZWNvbXByZXNzRW5kKHBpKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTX1NFVF9QQUxFVFRFOgogICAgRklYTUUoIiguLi4pIC0+IFNldFBhbGV0dGUoJXAsJXAsJXApOiBzdHViIVxuIiwgcGksIChMUFZPSUQpbFBhcmFtMSwgKExQVk9JRClsUGFyYW0yKTsKICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICBjYXNlIElDTV9ERUNPTVBSRVNTX0dFVF9QQUxFVFRFOgogICAgcmV0dXJuIERlY29tcHJlc3NHZXRQYWxldHRlKHBpLCAoTFBCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCQkoTFBCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0dFVERFRkFVTFRLRVlGUkFNRVJBVEU6CiAgICBpZiAoKExQVk9JRClsUGFyYW0xICE9IE5VTEwpCiAgICAgICooTFBEV09SRClsUGFyYW0xID0gMTU7CiAgICByZXR1cm4gSUNFUlJfT0s7CiAgZGVmYXVsdDoKICAgIGlmICh1TXNnIDwgRFJWX1VTRVIpCiAgICAgIHJldHVybiBEZWZEcml2ZXJQcm9jKGR3RHJ2SUQsIGhEcnYsIHVNc2csIGxQYXJhbTEsIGxQYXJhbTIpOwogICAgZWxzZQogICAgICBGSVhNRSgiVW5rbm93biBtZXNzYWdlIHVNc2c9MHglMDhYIGxQYXJhbTE9MHglMDhsWCBsUGFyYW0yPTB4JTA4bFhcbiIsdU1zZyxsUGFyYW0xLGxQYXJhbTIpOwogIH07CgogIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKfQoKLyogRGxsTWFpbiAtIGxpYnJhcnkgaW5pdGlhbGl6YXRpb24gY29kZSAqLwpCT09MIFdJTkFQSSBEbGxNYWluKEhJTlNUQU5DRSBoTW9kdWxlLCBEV09SRCBkd1JlYXNvbiwgTFBWT0lEIGxwUmVzZXJ2ZWQpCnsKICBUUkFDRSgiKCVwLCVsZCwlcClcbiIsKExQVk9JRCloTW9kdWxlLGR3UmVhc29uLGxwUmVzZXJ2ZWQpOwoKICBzd2l0Y2ggKGR3UmVhc29uKSB7CiAgY2FzZSBETExfUFJPQ0VTU19BVFRBQ0g6CiAgICBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKGhNb2R1bGUpOwogICAgTVNSTEUzMl9oTW9kdWxlID0gaE1vZHVsZTsKICAgIGJyZWFrOwoKICBjYXNlIERMTF9QUk9DRVNTX0RFVEFDSDoKICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIFRSVUU7Cn0K