LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGV3ZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIgIC8qIGZvciBSVF9TVFJJTkdXICovCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG5scyk7CgojZGVmaW5lIExPQ0FMRV9MT0NBTEVJTkZPRkxBR1NNQVNLIChMT0NBTEVfTk9VU0VST1ZFUlJJREV8TE9DQUxFX1VTRV9DUF9BQ1B8TE9DQUxFX1JFVFVSTl9OVU1CRVIpCgpleHRlcm4gdm9pZCBDT0RFUEFHRV9Jbml0KCBVSU5UIGFuc2ksIFVJTlQgb2VtLCBVSU5UIG1hYywgTENJRCBsY2lkICk7CgojZGVmaW5lIE5MU19NQVhfTEFOR1VBR0VTIDIwCnR5cGVkZWYgc3RydWN0IHsKICAgIGNoYXIgbGFuZ1sxMjhdOwogICAgY2hhciBjb3VudHJ5WzEyOF07CiAgICBMQU5HSUQgZm91bmRfbGFuZ19pZFtOTFNfTUFYX0xBTkdVQUdFU107CiAgICBjaGFyIGZvdW5kX2xhbmd1YWdlW05MU19NQVhfTEFOR1VBR0VTXVszXTsKICAgIGNoYXIgZm91bmRfY291bnRyeVtOTFNfTUFYX0xBTkdVQUdFU11bM107CiAgICBpbnQgbl9mb3VuZDsKfSBMQU5HX0ZJTkRfREFUQTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9sY2lkX2NvZGVwYWdlCiAqCiAqIFJldHJpZXZlIHRoZSBBTlNJIGNvZGVwYWdlIGZvciBhIGdpdmVuIGxvY2FsZS4KICovCmlubGluZSBzdGF0aWMgVUlOVCBnZXRfbGNpZF9jb2RlcGFnZSggTENJRCBsY2lkICkKewogICAgVUlOVCByZXQ7CiAgICBpZiAoIUdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRBTlNJQ09ERVBBR0V8TE9DQUxFX1JFVFVSTl9OVU1CRVIsIChXQ0hBUiAqKSZyZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocmV0KS9zaXplb2YoV0NIQVIpICkpIHJldCA9IDA7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQljcmVhdGVfcmVnaXN0cnlfa2V5CiAqCiAqIENyZWF0ZSB0aGUgQ29udHJvbCBQYW5lbFxcSW50ZXJuYXRpb25hbCByZWdpc3RyeSBrZXkuCiAqLwppbmxpbmUgc3RhdGljIEhLRVkgY3JlYXRlX3JlZ2lzdHJ5X2tleSh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaW50bFdbXSA9IHsnQycsJ28nLCduJywndCcsJ3InLCdvJywnbCcsJyAnLCdQJywnYScsJ24nLCdlJywnbCcsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEhLRVkgaGtleTsKCiAgICBpZiAoUnRsT3BlbkN1cnJlbnRVc2VyKCBLRVlfQUxMX0FDQ0VTUywgJmhrZXkgKSAhPSBTVEFUVVNfU1VDQ0VTUykgcmV0dXJuIDA7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGludGxXICk7CgogICAgaWYgKE50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkgIT0gU1RBVFVTX1NVQ0NFU1MpIGhrZXkgPSAwOwogICAgTnRDbG9zZSggYXR0ci5Sb290RGlyZWN0b3J5ICk7CiAgICByZXR1cm4gaGtleTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJdXBkYXRlX3JlZ2lzdHJ5CiAqCiAqIFVwZGF0ZSByZWdpc3RyeSBjb250ZW50cyBvbiBzdGFydHVwIGlmIHRoZSB1c2VyIGxvY2FsZSBoYXMgY2hhbmdlZC4KICogVGhpcyBzaW11bGF0ZXMgdGhlIGFjdGlvbiBvZiB0aGUgV2luZG93cyBjb250cm9sIHBhbmVsLgogKi8KaW5saW5lIHN0YXRpYyB2b2lkIHVwZGF0ZV9yZWdpc3RyeSggTENJRCBsY2lkICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIExvY2FsZVdbXSA9IHsnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywwfTsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgY2hhciBidWZmZXJbMjBdOwogICAgV0NIQVIgYnVmZmVyV1s4MF07CiAgICBEV09SRCBjb3VudCA9IHNpemVvZihidWZmZXIpOwogICAgSEtFWSBoa2V5OwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKQogICAgICAgIHJldHVybjsgIC8qIGRvbid0IGRvIGFueXRoaW5nIGlmIHdlIGNhbid0IGNyZWF0ZSB0aGUgcmVnaXN0cnkga2V5ICovCgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTG9jYWxlVyApOwogICAgY291bnQgPSBzaXplb2YoYnVmZmVyVyk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleShoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCAoTFBCWVRFKWJ1ZmZlclcsIGNvdW50LCAmY291bnQpKQogICAgewogICAgICAgIEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyVzsKICAgICAgICBSdGxVbmljb2RlVG9NdWx0aUJ5dGVOKCBidWZmZXIsIHNpemVvZihidWZmZXIpLTEsICZjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0NIQVIgKilpbmZvLT5EYXRhLCBpbmZvLT5EYXRhTGVuZ3RoICk7CiAgICAgICAgYnVmZmVyW2NvdW50XSA9IDA7CiAgICAgICAgaWYgKHN0cnRvbCggYnVmZmVyLCBOVUxMLCAxNiApID09IGxjaWQpICAvKiBhbHJlYWR5IHNldCBjb3JyZWN0bHkgKi8KICAgICAgICB7CiAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBUUkFDRSggInVwZGF0aW5nIHJlZ2lzdHJ5LCBsb2NhbGUgY2hhbmdlZCAlcyAtPiAlMDhseFxuIiwgYnVmZmVyLCBsY2lkICk7CiAgICB9CiAgICBlbHNlIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSBjaGFuZ2VkIG5vbmUgLT4gJTA4bHhcbiIsIGxjaWQgKTsKCiAgICBzcHJpbnRmKCBidWZmZXIsICIlMDhseCIsIGxjaWQgKTsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKSwgTlVMTCwgYnVmZmVyLCBzdHJsZW4oYnVmZmVyKSsxICk7CiAgICBOdFNldFZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgKHN0cmxlblcoYnVmZmVyVykrMSkgKiBzaXplb2YoV0NIQVIpICk7CiAgICBOdENsb3NlKCBoa2V5ICk7CgojZGVmaW5lIFVQREFURV9WQUxVRShsY3R5cGUpIGRvIHsgXAogICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIChsY3R5cGUpfExPQ0FMRV9OT1VTRVJPVkVSUklERSwgYnVmZmVyVywgc2l6ZW9mKGJ1ZmZlclcpL3NpemVvZihXQ0hBUikgKTsgXAogICAgU2V0TG9jYWxlSW5mb1coIGxjaWQsIChsY3R5cGUpLCBidWZmZXJXICk7IH0gd2hpbGUgKDApCgogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9TTEFOR1VBR0UpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9TQ09VTlRSWSk7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX0lDT1VOVFJZKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfUzExNTkpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9TMjM1OSk7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX1NUSU1FKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfSVRJTUUpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9JVExaRVJPKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfU1NIT1JUREFURSk7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX0lEQVRFKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfU0xPTkdEQVRFKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfU0RBVEUpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9TQ1VSUkVOQ1kpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9JQ1VSUkVOQ1kpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9JTkVHQ1VSUik7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX0lDVVJSRElHSVRTKTsKICAgIFVQREFURV9WQUxVRShMT0NBTEVfU0RFQ0lNQUwpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9TTElTVCk7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX1NUSE9VU0FORCk7CiAgICBVUERBVEVfVkFMVUUoTE9DQUxFX0lESUdJVFMpOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9JTFpFUk8pOwogICAgVVBEQVRFX1ZBTFVFKExPQ0FMRV9JTUVBU1VSRSk7CiN1bmRlZiBVUERBVEVfVkFMVUUKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jCiAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBmaW5kX2xhbmd1YWdlX2lkX3Byb2MoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIG5hbWUsIFdPUkQgTGFuZ0lELCBMUEFSQU0gbFBhcmFtICkKewogICAgTEFOR19GSU5EX0RBVEEgKmxfZGF0YSA9IChMQU5HX0ZJTkRfREFUQSAqKWxQYXJhbTsKICAgIExDSUQgbGNpZCA9IE1BS0VMQ0lEKExhbmdJRCwgU09SVF9ERUZBVUxUKTsKICAgIGNoYXIgYnVmX2xhbmd1YWdlWzEyOF07CiAgICBjaGFyIGJ1Zl9jb3VudHJ5WzEyOF07CiAgICBjaGFyIGJ1Zl9lbl9sYW5ndWFnZVsxMjhdOwoKICAgIFRSQUNFKCIlMDRYXG4iLCAoVUlOVClMYW5nSUQpOwogICAgaWYoUFJJTUFSWUxBTkdJRChMYW5nSUQpID09IExBTkdfTkVVVFJBTCkKICAgICAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgYnVmX2xhbmd1YWdlWzBdID0gMDsKICAgIGJ1Zl9jb3VudHJ5WzBdID0gMDsKCiAgICBHZXRMb2NhbGVJbmZvQShsY2lkLCBMT0NBTEVfU0lTTzYzOUxBTkdOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERXxMT0NBTEVfVVNFX0NQX0FDUCwKICAgICAgICAgICAgICAgICAgIGJ1Zl9sYW5ndWFnZSwgc2l6ZW9mKGJ1Zl9sYW5ndWFnZSkpOwogICAgVFJBQ0UoIkxPQ0FMRV9TSVNPNjM5TEFOR05BTUU6ICVzXG4iLCBidWZfbGFuZ3VhZ2UpOwoKICAgIEdldExvY2FsZUluZm9BKGxjaWQsIExPQ0FMRV9TSVNPMzE2NkNUUllOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERXxMT0NBTEVfVVNFX0NQX0FDUCwKICAgICAgICAgICAgICAgICAgIGJ1Zl9jb3VudHJ5LCBzaXplb2YoYnVmX2NvdW50cnkpKTsKICAgIFRSQUNFKCJMT0NBTEVfU0lTTzMxNjZDVFJZTkFNRTogJXNcbiIsIGJ1Zl9jb3VudHJ5KTsKCiAgICBpZihsX2RhdGEtPmxhbmcgJiYgc3RybGVuKGxfZGF0YS0+bGFuZykgPiAwICYmICFzdHJjYXNlY21wKGxfZGF0YS0+bGFuZywgYnVmX2xhbmd1YWdlKSkKICAgIHsKICAgICAgICBpZihsX2RhdGEtPmNvdW50cnkgJiYgc3RybGVuKGxfZGF0YS0+Y291bnRyeSkgPiAwKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIXN0cmNhc2VjbXAobF9kYXRhLT5jb3VudHJ5LCBidWZfY291bnRyeSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxfZGF0YS0+Zm91bmRfbGFuZ19pZFswXSA9IExhbmdJRDsKICAgICAgICAgICAgICAgIGxfZGF0YS0+bl9mb3VuZCA9IDE7CiAgICAgICAgICAgICAgICBUUkFDRSgiRm91bmQgbGFuZ19pZCAlMDRYIGZvciAlc18lc1xuIiwgTGFuZ0lELCBsX2RhdGEtPmxhbmcsIGxfZGF0YS0+Y291bnRyeSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7IC8qIHN0b3AgZW51bWVyYXRpb24gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIC8qIGxfZGF0YS0+Y291bnRyeSBub3Qgc3BlY2lmaWVkICovCiAgICAgICAgewogICAgICAgICAgICBpZihsX2RhdGEtPm5fZm91bmQgPCBOTFNfTUFYX0xBTkdVQUdFUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkW2xfZGF0YS0+bl9mb3VuZF0gPSBMYW5nSUQ7CiAgICAgICAgICAgICAgICBzdHJuY3B5KGxfZGF0YS0+Zm91bmRfY291bnRyeVtsX2RhdGEtPm5fZm91bmRdLCBidWZfY291bnRyeSwgMyk7CiAgICAgICAgICAgICAgICBzdHJuY3B5KGxfZGF0YS0+Zm91bmRfbGFuZ3VhZ2VbbF9kYXRhLT5uX2ZvdW5kXSwgYnVmX2xhbmd1YWdlLCAzKTsKICAgICAgICAgICAgICAgIGxfZGF0YS0+bl9mb3VuZCsrOwogICAgICAgICAgICAgICAgVFJBQ0UoIkZvdW5kIGxhbmdfaWQgJTA0WCBmb3IgJXNcbiIsIExhbmdJRCwgbF9kYXRhLT5sYW5nKTsKICAgICAgICAgICAgICAgIHJldHVybiBUUlVFOyAvKiBjb250aW51ZSBzZWFyY2ggKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBKdXN0IGluIGNhc2UsIGNoZWNrIExPQ0FMRV9TRU5HTEFOR1VBR0UgdG9vLAogICAgICogaW4gaG9wZSB0aGF0IHBvc3NpYmxlIGFsaWFzIG5hbWUgbWlnaHQgaGF2ZSB0aGF0IHZhbHVlLgogICAgICovCiAgICBidWZfZW5fbGFuZ3VhZ2VbMF0gPSAwOwogICAgR2V0TG9jYWxlSW5mb0EobGNpZCwgTE9DQUxFX1NFTkdMQU5HVUFHRXxMT0NBTEVfTk9VU0VST1ZFUlJJREV8TE9DQUxFX1VTRV9DUF9BQ1AsCiAgICAgICAgICAgICAgICAgICBidWZfZW5fbGFuZ3VhZ2UsIHNpemVvZihidWZfZW5fbGFuZ3VhZ2UpKTsKICAgIFRSQUNFKCJMT0NBTEVfU0VOR0xBTkdVQUdFOiAlc1xuIiwgYnVmX2VuX2xhbmd1YWdlKTsKCiAgICBpZihsX2RhdGEtPmxhbmcgJiYgc3RybGVuKGxfZGF0YS0+bGFuZykgPiAwICYmICFzdHJjYXNlY21wKGxfZGF0YS0+bGFuZywgYnVmX2VuX2xhbmd1YWdlKSkKICAgIHsKICAgICAgICBsX2RhdGEtPmZvdW5kX2xhbmdfaWRbbF9kYXRhLT5uX2ZvdW5kXSA9IExhbmdJRDsKICAgICAgICBzdHJuY3B5KGxfZGF0YS0+Zm91bmRfY291bnRyeVtsX2RhdGEtPm5fZm91bmRdLCBidWZfY291bnRyeSwgMyk7CiAgICAgICAgc3RybmNweShsX2RhdGEtPmZvdW5kX2xhbmd1YWdlW2xfZGF0YS0+bl9mb3VuZF0sIGJ1Zl9sYW5ndWFnZSwgMyk7CiAgICAgICAgbF9kYXRhLT5uX2ZvdW5kKys7CiAgICAgICAgVFJBQ0UoIkZvdW5kIGxhbmdfaWQgJTA0WCBmb3IgJXNcbiIsIExhbmdJRCwgbF9kYXRhLT5sYW5nKTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGdldF9sYW5ndWFnZV9pZAogKgogKiBJTlBVVDoKICoJTGFuZzogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoJQ291bnRyeTogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgY291bnRyeQogKglDaGFyc2V0OiBhIHN0cmluZyBkZWZpbmluZyB0aGUgY2hvc2VuIGNoYXJzZXQgZW5jb2RpbmcKICoJRGlhbGVjdDogYSBzdHJpbmcgZGVmaW5pbmcgYSB2YXJpYXRpb24gb2YgdGhlIGxvY2FsZQogKgogKglhbGwgdGhvc2UgdmFsdWVzIGFyZSBmcm9tIHRoZSBzdGFuZGFyZGl6ZWQgZm9ybWF0IG9mIGxvY2FsZQogKgluYW1lIGluIHVuaXggd2hpY2ggaXM6IExhbmdbX0NvdW50cnldWy5DaGFyc2V0XVtARGlhbGVjdF0KICoKICogUkVUVVJOUzoKICoJdGhlIG51bWVyaWMgY29kZSBvZiB0aGUgbGFuZ3VhZ2UgdXNlZCBieSBXaW5kb3dzCiAqCiAqIEZJWE1FOiBDaGFyc2V0IGFuZCBEaWFsZWN0IGFyZSBub3QgaGFuZGxlZAogKi8Kc3RhdGljIExBTkdJRCBnZXRfbGFuZ3VhZ2VfaWQoTFBDU1RSIExhbmcsIExQQ1NUUiBDb3VudHJ5LCBMUENTVFIgQ2hhcnNldCwgTFBDU1RSIERpYWxlY3QpCnsKICAgIExBTkdfRklORF9EQVRBIGxfZGF0YTsKICAgIGNoYXIgbGFuZ19zdHJpbmdbMjU2XTsKCiAgICBpZighTGFuZykKICAgIHsKICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIGdvdG8gRU5EOwogICAgfQoKICAgIG1lbXNldCgmbF9kYXRhLCAwLCBzaXplb2YoTEFOR19GSU5EX0RBVEEpKTsKICAgIHN0cm5jcHkobF9kYXRhLmxhbmcsIExhbmcsIHNpemVvZihsX2RhdGEubGFuZykpOwoKICAgIGlmKENvdW50cnkgJiYgc3RybGVuKENvdW50cnkpID4gMCkKICAgICAgICBzdHJuY3B5KGxfZGF0YS5jb3VudHJ5LCBDb3VudHJ5LCBzaXplb2YobF9kYXRhLmNvdW50cnkpKTsKCiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNBKEdldE1vZHVsZUhhbmRsZUEoIktFUk5FTDMyIiksIFJUX1NUUklOR0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTFBBUkFNKSZsX2RhdGEpOwoKICAgIHN0cmNweShsYW5nX3N0cmluZywgbF9kYXRhLmxhbmcpOwogICAgaWYobF9kYXRhLmNvdW50cnkgJiYgc3RybGVuKGxfZGF0YS5jb3VudHJ5KSA+IDApCiAgICB7CiAgICAgICAgc3RyY2F0KGxhbmdfc3RyaW5nLCAiXyIpOwogICAgICAgIHN0cmNhdChsYW5nX3N0cmluZywgbF9kYXRhLmNvdW50cnkpOwogICAgfQoKICAgIGlmKCFsX2RhdGEubl9mb3VuZCkKICAgIHsKICAgICAgICBpZihsX2RhdGEuY291bnRyeSAmJiBzdHJsZW4obF9kYXRhLmNvdW50cnkpID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIE1FU1NBR0UoIldhcm5pbmc6IExhbmd1YWdlICclcycgd2FzIG5vdCBmb3VuZCwgcmV0cnlpbmcgd2l0aG91dCBjb3VudHJ5IG5hbWUuLi5cbiIsIGxhbmdfc3RyaW5nKTsKICAgICAgICAgICAgbF9kYXRhLmNvdW50cnlbMF0gPSAwOwogICAgICAgICAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNBKEdldE1vZHVsZUhhbmRsZUEoIktFUk5FTDMyIiksIFJUX1NUUklOR0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQ1NUUilMT0NBTEVfSUxBTkdVQUdFLCBmaW5kX2xhbmd1YWdlX2lkX3Byb2MsIChMT05HKSZsX2RhdGEpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZS1ldmFsdWF0ZSBsYW5nX3N0cmluZyAqLwogICAgc3RyY3B5KGxhbmdfc3RyaW5nLCBsX2RhdGEubGFuZyk7CiAgICBpZihsX2RhdGEuY291bnRyeSAmJiBzdHJsZW4obF9kYXRhLmNvdW50cnkpID4gMCkKICAgIHsKICAgICAgICBzdHJjYXQobGFuZ19zdHJpbmcsICJfIik7CiAgICAgICAgc3RyY2F0KGxhbmdfc3RyaW5nLCBsX2RhdGEuY291bnRyeSk7CiAgICB9CgogICAgaWYoIWxfZGF0YS5uX2ZvdW5kKQogICAgewogICAgICAgIE1FU1NBR0UoIldhcm5pbmc6IExhbmd1YWdlICclcycgd2FzIG5vdCByZWNvZ25pemVkLCBkZWZhdWx0aW5nIHRvIEVuZ2xpc2hcbiIsIGxhbmdfc3RyaW5nKTsKICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmKGxfZGF0YS5uX2ZvdW5kID09IDEpCiAgICAgICAgICAgIFRSQUNFKCJGb3IgbGFuZ3VhZ2UgJyVzJyBsYW5nX2lkICUwNFggd2FzIGZvdW5kXG4iLCBsYW5nX3N0cmluZywgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pOwogICAgICAgIGVsc2UgLyogbF9kYXRhLT5uX2ZvdW5kID4gMSAqLwogICAgICAgIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIE1FU1NBR0UoIkZvciBsYW5ndWFnZSAnJXMnIHNldmVyYWwgbGFuZ3VhZ2UgaWRzIHdlcmUgZm91bmQ6XG4iLCBsYW5nX3N0cmluZyk7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGxfZGF0YS5uX2ZvdW5kOyBpKyspCiAgICAgICAgICAgICAgICBNRVNTQUdFKCIlc18lcyAtICUwNFg7ICIsIGxfZGF0YS5mb3VuZF9sYW5ndWFnZVtpXSwgbF9kYXRhLmZvdW5kX2NvdW50cnlbaV0sIGxfZGF0YS5mb3VuZF9sYW5nX2lkW2ldKTsKCiAgICAgICAgICAgIE1FU1NBR0UoIlxuSW5zdGVhZCBvZiB1c2luZyBmaXJzdCBpbiB0aGUgbGlzdCwgc3VnZ2VzdCB0byBkZWZpbmVcbiIKICAgICAgICAgICAgICAgICAgICAieW91ciBMQU5HIGVudmlyb25tZW50IHZhcmlhYmxlIGxpa2UgdGhpczogTEFORz0lc18lc1xuIiwKICAgICAgICAgICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ3VhZ2VbMF0sIGxfZGF0YS5mb3VuZF9jb3VudHJ5WzBdKTsKICAgICAgICB9CiAgICB9CkVORDoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA0WFxuIiwgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pOwogICAgcmV0dXJuIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlpbml0X2RlZmF1bHRfbGNpZAogKi8Kc3RhdGljIExDSUQgaW5pdF9kZWZhdWx0X2xjaWQodm9pZCkKewogICAgY2hhciBidWZbMjU2XTsKICAgIGNoYXIgKmxhbmcsKmNvdW50cnksKmNoYXJzZXQsKmRpYWxlY3QsKm5leHQ7CiAgICBMQ0lEIHJldCA9IDA7CgogICAgaWYgKEdldEVudmlyb25tZW50VmFyaWFibGVBKCAiTENfQUxMIiwgYnVmLCBzaXplb2YoYnVmKSApIHx8CiAgICAgICAgR2V0RW52aXJvbm1lbnRWYXJpYWJsZUEoICJMQ19DVFlQRSIsIGJ1Ziwgc2l6ZW9mKGJ1ZikgKSB8fAogICAgICAgIEdldEVudmlyb25tZW50VmFyaWFibGVBKCAiTEFOR1VBR0UiLCBidWYsIHNpemVvZihidWYpICkgfHwKICAgICAgICBHZXRFbnZpcm9ubWVudFZhcmlhYmxlQSggIkxDX01FU1NBR0VTIiwgYnVmLCBzaXplb2YoYnVmKSApIHx8CiAgICAgICAgR2V0RW52aXJvbm1lbnRWYXJpYWJsZUEoICJMQU5HIiwgYnVmLCBzaXplb2YoYnVmKSApKQogICAgewogICAgICAgIGlmICghc3RyY21wKGJ1ZiwiUE9TSVgiKSB8fCAhc3RyY21wKGJ1ZiwiQyIpKSBnb3RvIGRvbmU7CgogICAgICAgIGxhbmc9YnVmOwoKICAgICAgICBkbyB7CiAgICAgICAgICAgIG5leHQ9c3RyY2hyKGxhbmcsJzonKTsgaWYgKG5leHQpICpuZXh0Kys9J1wwJzsKICAgICAgICAgICAgZGlhbGVjdD1zdHJjaHIobGFuZywnQCcpOyBpZiAoZGlhbGVjdCkgKmRpYWxlY3QrKz0nXDAnOwogICAgICAgICAgICBjaGFyc2V0PXN0cmNocihsYW5nLCcuJyk7IGlmIChjaGFyc2V0KSAqY2hhcnNldCsrPSdcMCc7CiAgICAgICAgICAgIGNvdW50cnk9c3RyY2hyKGxhbmcsJ18nKTsgaWYgKGNvdW50cnkpICpjb3VudHJ5Kys9J1wwJzsKCiAgICAgICAgICAgIHJldCA9IGdldF9sYW5ndWFnZV9pZChsYW5nLCBjb3VudHJ5LCBjaGFyc2V0LCBkaWFsZWN0KTsKCiAgICAgICAgICAgIGxhbmc9bmV4dDsKICAgICAgICB9IHdoaWxlIChsYW5nICYmICFyZXQpOwoKICAgICAgICBpZiAoIXJldCkgTUVTU0FHRSgiV2FybmluZzogbGFuZ3VhZ2UgJyVzJyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoXG4iLCBidWYpOwogICAgfQoKIGRvbmU6CiAgICBpZiAoIXJldCkgcmV0ID0gTUFLRUxDSUQoIE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILFNVQkxBTkdfREVGQVVMVCksIFNPUlRfREVGQVVMVCkgOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9sb2NhbGVfdmFsdWVfbmFtZQogKgogKiBHZXRzIHRoZSByZWdpc3RyeSB2YWx1ZSBuYW1lIGZvciBhIGdpdmVuIGxjdHlwZS4KICovCnN0YXRpYyBjb25zdCBXQ0hBUiAqZ2V0X2xvY2FsZV92YWx1ZV9uYW1lKCBEV09SRCBsY3R5cGUgKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUNhbGVuZGFyVHlwZVdbXSA9IHsnaScsJ0MnLCdhJywnbCcsJ2UnLCduJywnZCcsJ2EnLCdyJywnVCcsJ3knLCdwJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUNvdW50cnlXW10gPSB7J2knLCdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ3VyckRpZ2l0c1dbXSA9IHsnaScsJ0MnLCd1JywncicsJ3InLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDdXJyZW5jeVdbXSA9IHsnaScsJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ2MnLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpRGF0ZVdbXSA9IHsnaScsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlEaWdpdHNXW10gPSB7J2knLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlGaXJzdERheU9mV2Vla1dbXSA9IHsnaScsJ0YnLCdpJywncicsJ3MnLCd0JywnRCcsJ2EnLCd5JywnTycsJ2YnLCdXJywnZScsJ2UnLCdrJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpRmlyc3RXZWVrT2ZZZWFyV1tdID0geydpJywnRicsJ2knLCdyJywncycsJ3QnLCdXJywnZScsJ2UnLCdrJywnTycsJ2YnLCdZJywnZScsJ2EnLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTERhdGVXW10gPSB7J2knLCdMJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUxaZXJvV1tdID0geydpJywnTCcsJ1onLCdlJywncicsJ28nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlNZWFzdXJlV1tdID0geydpJywnTScsJ2UnLCdhJywncycsJ3UnLCdyJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU5lZ0N1cnJXW10gPSB7J2knLCdOJywnZScsJ2cnLCdDJywndScsJ3InLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTmVnTnVtYmVyV1tdID0geydpJywnTicsJ2UnLCdnJywnTicsJ3UnLCdtJywnYicsJ2UnLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpUGFwZXJTaXplV1tdID0geydpJywnUCcsJ2EnLCdwJywnZScsJ3InLCdTJywnaScsJ3onLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpVExaZXJvV1tdID0geydpJywnVCcsJ0wnLCdaJywnZScsJ3InLCdvJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpVGltZVdbXSA9IHsnaScsJ1QnLCdpJywnbScsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMxMTU5V1tdID0geydzJywnMScsJzEnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgczIzNTlXW10gPSB7J3MnLCcyJywnMycsJzUnLCc5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ291bnRyeVdbXSA9IHsncycsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNDdXJyZW5jeVdbXSA9IHsncycsJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ2MnLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGF0ZVdbXSA9IHsncycsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNEZWNpbWFsV1tdID0geydzJywnRCcsJ2UnLCdjJywnaScsJ20nLCdhJywnbCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0dyb3VwaW5nV1tdID0geydzJywnRycsJ3InLCdvJywndScsJ3AnLCdpJywnbicsJ2cnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNMYW5ndWFnZVdbXSA9IHsncycsJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGlzdFdbXSA9IHsncycsJ0wnLCdpJywncycsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNMb25nRGF0ZVdbXSA9IHsncycsJ0wnLCdvJywnbicsJ2cnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uRGVjaW1hbFNlcFdbXSA9IHsncycsJ00nLCdvJywnbicsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNNb25Hcm91cGluZ1dbXSA9IHsncycsJ00nLCdvJywnbicsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uVGhvdXNhbmRTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdUJywnaCcsJ28nLCd1JywncycsJ2EnLCduJywnZCcsJ1MnLCdlJywncCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc05lZ2F0aXZlU2lnbldbXSA9IHsncycsJ04nLCdlJywnZycsJ2EnLCd0JywnaScsJ3YnLCdlJywnUycsJ2knLCdnJywnbicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Bvc2l0aXZlU2lnbldbXSA9IHsncycsJ1AnLCdvJywncycsJ2knLCd0JywnaScsJ3YnLCdlJywnUycsJ2knLCdnJywnbicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Nob3J0RGF0ZVdbXSA9IHsncycsJ1MnLCdoJywnbycsJ3InLCd0JywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Rob3VzYW5kV1tdID0geydzJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lRm9ybWF0V1tdID0geydzJywnVCcsJ2knLCdtJywnZScsJ0YnLCdvJywncicsJ20nLCdhJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1RpbWVXW10gPSB7J3MnLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzWWVhck1vbnRoV1tdID0geydzJywnWScsJ2UnLCdhJywncicsJ00nLCdvJywnbicsJ3QnLCdoJywwfTsKCiAgICBzd2l0Y2ggKGxjdHlwZSAmIH5MT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSykKICAgIHsKICAgIC8qIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBieSBTZXRMb2NhbGVJbmZvIGFuZCBHZXRMb2NhbGVJbmZvLCBhbmQKICAgICAqIHRoZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVnaXN0cnksIGNvbmZpcm1lZCB1bmRlciBXaW5kb3dzLgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOiAgICByZXR1cm4gaUNhbGVuZGFyVHlwZVc7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzogICAgICByZXR1cm4gaUN1cnJEaWdpdHNXOwogICAgY2FzZSBMT0NBTEVfSUNVUlJFTkNZOiAgICAgICAgcmV0dXJuIGlDdXJyZW5jeVc7CiAgICBjYXNlIExPQ0FMRV9JRElHSVRTOiAgICAgICAgICByZXR1cm4gaURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6ICByZXR1cm4gaUZpcnN0RGF5T2ZXZWVrVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVFdFRUtPRllFQVI6IHJldHVybiBpRmlyc3RXZWVrT2ZZZWFyVzsKICAgIGNhc2UgTE9DQUxFX0lMWkVSTzogICAgICAgICAgIHJldHVybiBpTFplcm9XOwogICAgY2FzZSBMT0NBTEVfSU1FQVNVUkU6ICAgICAgICAgcmV0dXJuIGlNZWFzdXJlVzsKICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOiAgICAgICAgIHJldHVybiBpTmVnQ3Vyclc7CiAgICBjYXNlIExPQ0FMRV9JTkVHTlVNQkVSOiAgICAgICByZXR1cm4gaU5lZ051bWJlclc7CiAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOiAgICAgICByZXR1cm4gaVBhcGVyU2l6ZVc7CiAgICBjYXNlIExPQ0FMRV9JVElNRTogICAgICAgICAgICByZXR1cm4gaVRpbWVXOwogICAgY2FzZSBMT0NBTEVfUzExNTk6ICAgICAgICAgICAgcmV0dXJuIHMxMTU5VzsKICAgIGNhc2UgTE9DQUxFX1MyMzU5OiAgICAgICAgICAgIHJldHVybiBzMjM1OVc7CiAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gc0N1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX1NEQVRFOiAgICAgICAgICAgIHJldHVybiBzRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TREVDSU1BTDogICAgICAgICByZXR1cm4gc0RlY2ltYWxXOwogICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOiAgICAgICAgcmV0dXJuIHNHcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTElTVDogICAgICAgICAgICByZXR1cm4gc0xpc3RXOwogICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOiAgICAgICAgcmV0dXJuIHNMb25nRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TTU9OREVDSU1BTFNFUDogICByZXR1cm4gc01vbkRlY2ltYWxTZXBXOwogICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOiAgICAgcmV0dXJuIHNNb25Hcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVA6ICByZXR1cm4gc01vblRob3VzYW5kU2VwVzsKICAgIGNhc2UgTE9DQUxFX1NORUdBVElWRVNJR046ICAgIHJldHVybiBzTmVnYXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NQT1NJVElWRVNJR046ICAgIHJldHVybiBzUG9zaXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NTSE9SVERBVEU6ICAgICAgIHJldHVybiBzU2hvcnREYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NUSE9VU0FORDogICAgICAgIHJldHVybiBzVGhvdXNhbmRXOwogICAgY2FzZSBMT0NBTEVfU1RJTUU6ICAgICAgICAgICAgcmV0dXJuIHNUaW1lVzsKICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOiAgICAgIHJldHVybiBzVGltZUZvcm1hdFc7CiAgICBjYXNlIExPQ0FMRV9TWUVBUk1PTlRIOiAgICAgICByZXR1cm4gc1llYXJNb250aFc7CgogICAgLyogVGhlIGZvbGxvd2luZyBhcmUgbm90IGxpc3RlZCB1bmRlciBNU0ROIGFzIHN1cHBvcnRlZCwKICAgICAqIGJ1dCBzZWVtIHRvIGJlIHVzZWQgYW5kIGFsc28gc3RvcmVkIGluIHRoZSByZWdpc3RyeS4KICAgICAqLwogICAgY2FzZSBMT0NBTEVfSUNPVU5UUlk6ICAgICAgICAgcmV0dXJuIGlDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX0lEQVRFOiAgICAgICAgICAgIHJldHVybiBpRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9JTERBVEU6ICAgICAgICAgICByZXR1cm4gaUxEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lUTFpFUk86ICAgICAgICAgIHJldHVybiBpVExaZXJvVzsKICAgIGNhc2UgTE9DQUxFX1NDT1VOVFJZOiAgICAgICAgIHJldHVybiBzQ291bnRyeVc7CiAgICBjYXNlIExPQ0FMRV9TTEFOR1VBR0U6ICAgICAgICByZXR1cm4gc0xhbmd1YWdlVzsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvCiAqCiAqIFJldHJpZXZlIHVzZXItbW9kaWZpZWQgbG9jYWxlIGluZm8gZnJvbSB0aGUgcmVnaXN0cnkuCiAqIFJldHVybiBsZW5ndGgsIDAgb24gZXJyb3IsIC0xIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyBJTlQgZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCBMUENXU1RSIHZhbHVlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgRFdPUkQgc2l6ZTsKICAgIElOVCByZXQ7CiAgICBIS0VZIGhrZXk7CiAgICBOVFNUQVRVUyBzdGF0dXM7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvOwogICAgc3RhdGljIGNvbnN0IGludCBpbmZvX3NpemUgPSBGSUVMRF9PRkZTRVQoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04sIERhdGEpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKSByZXR1cm4gLTE7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdmFsdWUgKTsKICAgIHNpemUgPSBpbmZvX3NpemUgKyBsZW4gKiBzaXplb2YoV0NIQVIpOwoKICAgIGlmICghKGluZm8gPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUgKSkpCiAgICB7CiAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzdGF0dXMgPSBOdFF1ZXJ5VmFsdWVLZXkoIGhrZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIGluZm8sIHNpemUsICZzaXplICk7CiAgICBpZiAoc3RhdHVzID09IFNUQVRVU19CVUZGRVJfT1ZFUkZMT1cgJiYgIWJ1ZmZlcikgc3RhdHVzID0gMDsKCiAgICBpZiAoIXN0YXR1cykKICAgIHsKICAgICAgICByZXQgPSAoc2l6ZSAtIGluZm9fc2l6ZSkgLyBzaXplb2YoV0NIQVIpOwogICAgICAgIC8qIGFwcGVuZCB0ZXJtaW5hdGluZyBudWxsIGlmIG5lZWRlZCAqLwogICAgICAgIGlmICghcmV0IHx8ICgoV0NIQVIgKilpbmZvLT5EYXRhKVtyZXQtMV0pCiAgICAgICAgewogICAgICAgICAgICBpZiAocmV0IDwgbGVuIHx8ICFidWZmZXIpIHJldCsrOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgcmV0ID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmV0ICYmIGJ1ZmZlcikKICAgICAgICB7CiAgICAgICAgICAgIG1lbWNweSggYnVmZmVyLCBpbmZvLT5EYXRhLCAocmV0LTEpICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICBidWZmZXJbcmV0LTFdID0gMDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKHN0YXR1cyA9PSBTVEFUVVNfT0JKRUNUX05BTUVfTk9UX0ZPVU5EKSByZXQgPSAtMTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIFJ0bE50U3RhdHVzVG9Eb3NFcnJvcihzdGF0dXMpICk7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgfQogICAgfQogICAgTnRDbG9zZSggaGtleSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm8gKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvQSAoS0VSTkVMMzIuQCkKICoKICogTk9URVMKICogIExBTkdfTkVVVFJBTCBpcyBlcXVhbCB0byBMT0NBTEVfU1lTVEVNX0RFRkFVTFQKICoKICogIE1TIG9ubGluZSBkb2N1bWVudGF0aW9uIHN0YXRlcyB0aGF0IHRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgTlVMTCB0ZXJtaW5hdGVkCiAqICBleGNlcHQgZm9yIExPQ0FMRV9GT05UU0lHTkFUVVJFICB3aGljaCAid2lsbCByZXR1cm4gYSBub24tTlVMTAogKiAgdGVybWluYXRlZCBzdHJpbmciLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvQSggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFNUUiBidWZmZXIsIElOVCBsZW4gKQp7CiAgICBXQ0hBUiAqYnVmZmVyVzsKICAgIElOVCBsZW5XLCByZXQ7CgogICAgaWYgKGxlbiA8IDAgfHwgKGxlbiAmJiAhYnVmZmVyKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoIWxlbikgYnVmZmVyID0gTlVMTDsKCiAgICBpZiAoIShsZW5XID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIGxjdHlwZSwgTlVMTCwgMCApKSkgcmV0dXJuIDA7CgogICAgaWYgKCEoYnVmZmVyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuVyAqIHNpemVvZihXQ0hBUikgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKChyZXQgPSBHZXRMb2NhbGVJbmZvVyggbGNpZCwgbGN0eXBlLCBidWZmZXJXLCBsZW5XICkpKQogICAgewogICAgICAgIGlmICgobGN0eXBlICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpIHx8CiAgICAgICAgICAgICgobGN0eXBlICYgfkxPQ0FMRV9MT0NBTEVJTkZPRkxBR1NNQVNLKSA9PSBMT0NBTEVfRk9OVFNJR05BVFVSRSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBpdCdzIG5vdCBhbiBBU0NJSSBzdHJpbmcsIGp1c3QgYnl0ZXMgKi8KICAgICAgICAgICAgcmV0ICo9IHNpemVvZihXQ0hBUik7CiAgICAgICAgICAgIGlmIChidWZmZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChyZXQgPD0gbGVuKSBtZW1jcHkoIGJ1ZmZlciwgYnVmZmVyVywgcmV0ICk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBVSU5UIGNvZGVwYWdlID0gQ1BfQUNQOwogICAgICAgICAgICBpZiAoIShsY3R5cGUgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGNvZGVwYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgICAgICAgICAgcmV0ID0gV2lkZUNoYXJUb011bHRpQnl0ZSggY29kZXBhZ2UsIDAsIGJ1ZmZlclcsIHJldCwgYnVmZmVyLCBsZW4sIE5VTEwsIE5VTEwgKTsKICAgICAgICB9CiAgICB9CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyVyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldExvY2FsZUluZm9XIChLRVJORUwzMi5AKQogKgogKiBOT1RFUwogKiAgTEFOR19ORVVUUkFMIGlzIGVxdWFsIHRvIExPQ0FMRV9TWVNURU1fREVGQVVMVAogKgogKiAgTVMgb25saW5lIGRvY3VtZW50YXRpb24gc3RhdGVzIHRoYXQgdGhlIHN0cmluZyByZXR1cm5lZCBpcyBOVUxMIHRlcm1pbmF0ZWQKICogIGV4Y2VwdCBmb3IgTE9DQUxFX0ZPTlRTSUdOQVRVUkUgIHdoaWNoICJ3aWxsIHJldHVybiBhIG5vbi1OVUxMCiAqICB0ZXJtaW5hdGVkIHN0cmluZyIuCiAqLwpJTlQgV0lOQVBJIEdldExvY2FsZUluZm9XKCBMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQV1NUUiBidWZmZXIsIElOVCBsZW4gKQp7CiAgICBMQU5HSUQgbGFuZ19pZDsKICAgIEhSU1JDIGhyc3JjOwogICAgSEdMT0JBTCBobWVtOwogICAgSE1PRFVMRSBoTW9kdWxlOwogICAgSU5UIHJldDsKICAgIFVJTlQgbGNmbGFnczsKICAgIGNvbnN0IFdDSEFSICpwOwogICAgaW50IGk7CgogICAgaWYgKGxlbiA8IDAgfHwgKGxlbiAmJiAhYnVmZmVyKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoIWxlbikgYnVmZmVyID0gTlVMTDsKCiAgICBpZiAobGNpZCA9PSBMT0NBTEVfTkVVVFJBTCB8fCBsY2lkID09IExBTkdfU1lTVEVNX0RFRkFVTFQpIGxjaWQgPSBHZXRTeXN0ZW1EZWZhdWx0TENJRCgpOwogICAgZWxzZSBpZiAobGNpZCA9PSBMQU5HX1VTRVJfREVGQVVMVCkgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwoKICAgIGxjZmxhZ3MgPSBsY3R5cGUgJiBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSzsKICAgIGxjdHlwZSAmPSB+TE9DQUxFX0xPQ0FMRUlORk9GTEFHU01BU0s7CgogICAgLyogZmlyc3QgY2hlY2sgZm9yIG92ZXJyaWRlcyBpbiB0aGUgcmVnaXN0cnkgKi8KCiAgICBpZiAoIShsY2ZsYWdzICYgTE9DQUxFX05PVVNFUk9WRVJSSURFKSAmJiBsY2lkID09IEdldFVzZXJEZWZhdWx0TENJRCgpKQogICAgewogICAgICAgIGNvbnN0IFdDSEFSICp2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZShsY3R5cGUpOwoKICAgICAgICBpZiAodmFsdWUgJiYgKChyZXQgPSBnZXRfcmVnaXN0cnlfbG9jYWxlX2luZm8oIHZhbHVlLCBidWZmZXIsIGxlbiApKSAhPSAtMSkpIHJldHVybiByZXQ7CiAgICB9CgogICAgLyogbm93IGxvYWQgaXQgZnJvbSBrZXJuZWwgcmVzb3VyY2VzICovCgogICAgbGFuZ19pZCA9IExBTkdJREZST01MQ0lEKCBsY2lkICk7CgogICAgLyogcmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgYnkgU1VCTEFOR19ERUZBVUxUICovCiAgICBpZiAoU1VCTEFOR0lEKGxhbmdfaWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nX2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdfaWQpLCBTVUJMQU5HX0RFRkFVTFQpOwoKICAgIGhNb2R1bGUgPSBHZXRNb2R1bGVIYW5kbGVBKCAia2VybmVsMzIuZGxsIiApOwogICAgaWYgKCEoaHJzcmMgPSBGaW5kUmVzb3VyY2VFeFcoIGhNb2R1bGUsIFJUX1NUUklOR1csIChMUENXU1RSKSgobGN0eXBlID4+IDQpICsgMSksIGxhbmdfaWQgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7ICAvKiBubyBzdWNoIGxjdHlwZSAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCEoaG1lbSA9IExvYWRSZXNvdXJjZSggaE1vZHVsZSwgaHJzcmMgKSkpCiAgICAgICAgcmV0dXJuIDA7CgogICAgcCA9IExvY2tSZXNvdXJjZSggaG1lbSApOwogICAgZm9yIChpID0gMDsgaSA8IChsY3R5cGUgJiAweDBmKTsgaSsrKSBwICs9ICpwICsgMTsKCiAgICBpZiAobGNmbGFncyAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSByZXQgPSBzaXplb2YoVUlOVCkvc2l6ZW9mKFdDSEFSKTsKICAgIGVsc2UgcmV0ID0gKGxjdHlwZSA9PSBMT0NBTEVfRk9OVFNJR05BVFVSRSkgPyAqcCA6ICpwICsgMTsKCiAgICBpZiAoIWJ1ZmZlcikgcmV0dXJuIHJldDsKCiAgICBpZiAocmV0ID4gbGVuKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpCiAgICB7CiAgICAgICAgVUlOVCBudW1iZXI7CiAgICAgICAgV0NIQVIgKmVuZCwgKnRtcCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKCpwICsgMSkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgaWYgKCF0bXApIHJldHVybiAwOwogICAgICAgIG1lbWNweSggdG1wLCBwICsgMSwgKnAgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgdG1wWypwXSA9IDA7CiAgICAgICAgbnVtYmVyID0gc3RydG9sVyggdG1wLCAmZW5kLCAxMCApOwogICAgICAgIGlmICghKmVuZCkKICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsICZudW1iZXIsIHNpemVvZihudW1iZXIpICk7CiAgICAgICAgZWxzZSAgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgICAgICByZXQgPSAwOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgdG1wICk7CgogICAgICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKSByZXR1cm5pbmcgbnVtYmVyICVkXG4iLAogICAgICAgICAgICAgICBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuLCBudW1iZXIgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgcCArIDEsICpwICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIGlmIChsY3R5cGUgIT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpIGJ1ZmZlcltyZXQtMV0gPSAwOwoKICAgICAgICBUUkFDRSggIihsY2lkPTB4JWx4LGxjdHlwZT0weCVseCwlcCwlZCkgcmV0dXJuaW5nICVkICVzXG4iLAogICAgICAgICAgICAgICBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuLCByZXQsIGRlYnVnc3RyX3coYnVmZmVyKSApOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldExvY2FsZUluZm9BCVtLRVJORUwzMi5AXQogKi8KQk9PTCBXSU5BUEkgU2V0TG9jYWxlSW5mb0EoTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUENTVFIgZGF0YSkKewogICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgIFdDSEFSICpzdHJXOwogICAgRFdPUkQgbGVuOwogICAgQk9PTCByZXQ7CgogICAgaWYgKGxjaWQgPT0gTE9DQUxFX05FVVRSQUwgfHwgbGNpZCA9PSBMQU5HX1NZU1RFTV9ERUZBVUxUKSBsY2lkID0gR2V0U3lzdGVtRGVmYXVsdExDSUQoKTsKICAgIGVsc2UgaWYgKGxjaWQgPT0gTEFOR19VU0VSX0RFRkFVTFQpIGxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKCiAgICBpZiAoIShsY3R5cGUgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGNvZGVwYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKCEoc3RyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggY29kZXBhZ2UsIDAsIGRhdGEsIC0xLCBzdHJXLCBsZW4gKTsKICAgIHJldCA9IFNldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIHN0clcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb1cJKEtFUk5FTDMyLkApCiAqLwpCT09MIFdJTkFQSSBTZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUENXU1RSIGRhdGEgKQp7CiAgICBjb25zdCBXQ0hBUiAqdmFsdWU7CiAgICBjb25zdCBXQ0hBUiBpbnRsV1tdID0geydpJywnbicsJ3QnLCdsJywwIH07CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZVc7CiAgICBOVFNUQVRVUyBzdGF0dXM7CiAgICBIS0VZIGhrZXk7CgogICAgaWYgKGxjaWQgPT0gTE9DQUxFX05FVVRSQUwgfHwgbGNpZCA9PSBMQU5HX1NZU1RFTV9ERUZBVUxUKSBsY2lkID0gR2V0U3lzdGVtRGVmYXVsdExDSUQoKTsKICAgIGVsc2UgaWYgKGxjaWQgPT0gTEFOR19VU0VSX0RFRkFVTFQpIGxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKCiAgICBpZiAoISh2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAobGNpZCAhPSBHZXRVc2VyRGVmYXVsdExDSUQoKSkgcmV0dXJuIFRSVUU7ICAvKiBmYWtlIHN1Y2Nlc3MgKi8KCiAgICBUUkFDRSgic2V0dGluZyAlbHggdG8gJXNcbiIsIGxjdHlwZSwgZGVidWdzdHJfdyhkYXRhKSApOwoKICAgIC8qIEZJWE1FOiBzaG91bGQgY2hlY2sgdGhhdCBkYXRhIHRvIHNldCBpcyBzYW5lICovCgogICAgLyogRklYTUU6IHByb2ZpbGUgZnVuY3Rpb25zIHNob3VsZCBtYXAgdG8gcmVnaXN0cnkgKi8KICAgIFdyaXRlUHJvZmlsZVN0cmluZ1coIGludGxXLCB2YWx1ZSwgZGF0YSApOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKSByZXR1cm4gRkFMU0U7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJnZhbHVlVywgdmFsdWUgKTsKICAgIHN0YXR1cyA9IE50U2V0VmFsdWVLZXkoIGhrZXksICZ2YWx1ZVcsIDAsIFJFR19TWiwgZGF0YSwgKHN0cmxlblcoZGF0YSkrMSkqc2l6ZW9mKFdDSEFSKSApOwogICAgTnRDbG9zZSggaGtleSApOwoKICAgIGlmIChzdGF0dXMpIFNldExhc3RFcnJvciggUnRsTnRTdGF0dXNUb0Rvc0Vycm9yKHN0YXR1cykgKTsKICAgIHJldHVybiAhc3RhdHVzOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICovCkxDSUQgV0lOQVBJIEdldFRocmVhZExvY2FsZSh2b2lkKQp7CiAgICBMQ0lEIHJldCA9IE50Q3VycmVudFRlYigpLT5DdXJyZW50TG9jYWxlOwogICAgaWYgKCFyZXQpIE50Q3VycmVudFRlYigpLT5DdXJyZW50TG9jYWxlID0gcmV0ID0gR2V0VXNlckRlZmF1bHRMQ0lEKCk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICoKICogRklYTUUKICogIGNoZWNrIGlmIGxjaWQgaXMgYSB2YWxpZCBjcAogKi8KQk9PTCBXSU5BUEkgU2V0VGhyZWFkTG9jYWxlKCBMQ0lEIGxjaWQgKSAvKiBbaW5dIExvY2FsZSBpZGVudGlmaWVyICovCnsKICAgIGlmIChsY2lkID09IExPQ0FMRV9ORVVUUkFMIHx8IGxjaWQgPT0gTEFOR19TWVNURU1fREVGQVVMVCkgbGNpZCA9IEdldFN5c3RlbURlZmF1bHRMQ0lEKCk7CiAgICBlbHNlIGlmIChsY2lkID09IExBTkdfVVNFUl9ERUZBVUxUKSBsY2lkID0gR2V0VXNlckRlZmF1bHRMQ0lEKCk7CgogICAgTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGUgPSBsY2lkOwogICAgTnRDdXJyZW50VGViKCktPmNvZGVfcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICByZXR1cm4gVFJVRTsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlVyAgICAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVXKCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBpZiAoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuVyhzcmMpICsgMTsKICAgIHN3aXRjaCh0eXBlKQogICAgewogICAgY2FzZSBDVF9DVFlQRTE6CiAgICAgICAgd2hpbGUgKGNvdW50LS0pICpjaGFydHlwZSsrID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMjoKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgPj4gMTI7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMzoKICAgIHsKICAgICAgICBXQVJOKCJDVF9DVFlQRTM6IHNlbWktc3R1Yi5cbiIpOwogICAgICAgIHdoaWxlIChjb3VudC0tKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGMgPSAqc3JjOwogICAgICAgICAgICBXT1JEIHR5cGUxLCB0eXBlMyA9IDA7IC8qIEMzX05PVEFQUExJQ0FCTEUgKi8KCiAgICAgICAgICAgIHR5cGUxID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgICAgIC8qIHRyeSB0byBjb25zdHJ1Y3QgdHlwZTMgZnJvbSB0eXBlMSAqLwogICAgICAgICAgICBpZih0eXBlMSAmIEMxX1NQQUNFKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfQUxQSEEpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzBBMCkmJihjPD0weDMwRkYpKSB0eXBlMyB8PSBDM19LQVRBS0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwNDApJiYoYzw9MHgzMDlGKSkgdHlwZTMgfD0gQzNfSElSQUdBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHg0RTAwKSYmKGM8PTB4OUZBRikpIHR5cGUzIHw9IEMzX0lERU9HUkFQSDsKICAgICAgICAgICAgaWYgKChjPj0weDA2MDApJiYoYzw9MHgwNkZGKSkgdHlwZTMgfD0gQzNfS0FTSElEQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwMDApJiYoYzw9MHgzMDNGKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGMDApJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGMjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjNCKSYmKGM8PTB4RkY0MCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNUIpJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYyMSkmJihjPD0weEZGM0EpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGNDEpJiYoYzw9MHhGRjVBKSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkUwKSYmKGM8PTB4RkZFNikpIHR5cGUzIHw9IEMzX0ZVTExXSURUSDsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGNjEpJiYoYzw9MHhGRkRDKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGNjQpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2NSkmJihjPD0weEZGOUYpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTgpJiYoYzw9MHhGRkVFKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgICpjaGFydHlwZSsrID0gdHlwZTM7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhXICAgIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4VyggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1dTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIC8qIGxvY2FsZSBpcyBpZ25vcmVkIGZvciBVbmljb2RlICovCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoIHR5cGUsIHNyYywgY291bnQsIGNoYXJ0eXBlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlQSAgICAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVBKCBMQ0lEIGxvY2FsZSwgRFdPUkQgdHlwZSwgTFBDU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBVSU5UIGNwOwogICAgSU5UIGNvdW50VzsKICAgIExQV1NUUiBzcmNXOwogICAgQk9PTCByZXQgPSBGQUxTRTsKCiAgICBpZihjb3VudCA9PSAtMSkgY291bnQgPSBzdHJsZW4oc3JjKSArIDE7CgogICAgaWYgKCEoY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbG9jYWxlICkpKQogICAgewogICAgICAgIEZJWE1FKCJGb3IgbG9jYWxlICUwNGx4IHVzaW5nIGN1cnJlbnQgQU5TSSBjb2RlIHBhZ2VcbiIsIGxvY2FsZSk7CiAgICAgICAgY3AgPSBHZXRBQ1AoKTsKICAgIH0KCiAgICBjb3VudFcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBOVUxMLCAwKTsKICAgIGlmKChzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50VyAqIHNpemVvZihXQ0hBUikpKSkKICAgIHsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBzcmNXLCBjb3VudFcpOwogICAgLyoKICAgICAqIE5PVEU6IHRoZSB0YXJnZXQgYnVmZmVyIGhhcyAxIHdvcmQgZm9yIGVhY2ggQ0hBUkFDVEVSIGluIHRoZSBzb3VyY2UKICAgICAqIHN0cmluZywgd2l0aCBtdWx0aWJ5dGUgY2hhcmFjdGVycyB0aGVyZSBtYXliZSBiZSBtb3JlIGJ5dGVzIGluIGNvdW50CiAgICAgKiB0aGFuIGNoYXJhY3RlciBzcGFjZSBpbiB0aGUgYnVmZmVyIQogICAgICovCiAgICAgICAgcmV0ID0gR2V0U3RyaW5nVHlwZVcodHlwZSwgc3JjVywgY291bnRXLCBjaGFydHlwZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhBICAgIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4QSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVBKGxvY2FsZSwgdHlwZSwgc3JjLCBjb3VudCwgY2hhcnR5cGUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTE9DQUxFX0luaXQKICovCnZvaWQgTE9DQUxFX0luaXQodm9pZCkKewogICAgVUlOVCBhbnNpID0gMTI1Miwgb2VtID0gNDM3LCBtYWMgPSAxMDAwMDsKICAgIExDSUQgbGNpZCA9IGluaXRfZGVmYXVsdF9sY2lkKCk7CgogICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVEFOU0lDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJmFuc2ksIHNpemVvZihhbnNpKS9zaXplb2YoV0NIQVIpICk7CiAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX0lERUZBVUxUTUFDQ09ERVBBR0UgfCBMT0NBTEVfUkVUVVJOX05VTUJFUiwKICAgICAgICAgICAgICAgICAgICAoTFBXU1RSKSZtYWMsIHNpemVvZihtYWMpL3NpemVvZihXQ0hBUikgKTsKICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm9lbSwgc2l6ZW9mKG9lbSkvc2l6ZW9mKFdDSEFSKSApOwoKICAgIENPREVQQUdFX0luaXQoIGFuc2ksIG9lbSwgbWFjLCBsY2lkICk7CiAgICB1cGRhdGVfcmVnaXN0cnkoIGxjaWQgKTsKfQo=