LyogCiAqIEltcGxlbWVudGF0aW9uIG9mIFZFUi5ETEwKICogCiAqIENvcHlyaWdodCAxOTk2IE1hcmN1cyBNZWlzc25lcgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJ2ZXIuaCIKI2luY2x1ZGUgImx6ZXhwYW5kLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2RlZmluZSBMWlJFQUQod2hhdCkgXAogIGlmIChzaXplb2YoKndoYXQpIT1MWlJlYWQzMihsemZkLHdoYXQsc2l6ZW9mKCp3aGF0KSkpIHJldHVybiAwOwojZGVmaW5lIExaVEVMTChsemZkKSBMWlNlZWszMihsemZkLCAwLCBTRUVLX0NVUik7CgppbnQKcmVhZF9uZV9oZWFkZXIoSEZJTEUzMiBsemZkLHN0cnVjdCBuZV9oZWFkZXJfcyAqbmVoZCkgewoJc3RydWN0CW16X2hlYWRlcl9zCW16aDsKCglMWlNlZWszMihsemZkLDAsU0VFS19TRVQpOwoJaWYgKHNpemVvZihtemgpIT1MWlJlYWQzMihsemZkLCZtemgsc2l6ZW9mKG16aCkpKQoJCXJldHVybiAwOwoJaWYgKG16aC5tel9tYWdpYyE9TVpfU0lHTkFUVVJFKQoJCXJldHVybiAwOwoJTFpTZWVrMzIobHpmZCxtemgubmVfb2Zmc2V0LFNFRUtfU0VUKTsKCUxaUkVBRChuZWhkKTsKCWlmIChuZWhkLT5uZV9tYWdpYyA9PSBORV9TSUdOQVRVUkUpIHsKCQlMWlNlZWszMihsemZkLG16aC5uZV9vZmZzZXQsU0VFS19TRVQpOwoJCXJldHVybiAxOwoJfQoJLyogbXVzdCBoYW5kbGUgUEUgZmlsZXMgdG9vLiBMYXRlci4gKi8KCXJldHVybiAwOwp9CgoKaW50CmZpbmRfbmVfcmVzb3VyY2UoCglIRklMRTMyIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkLFNFR1BUUiB0eXBlaWQsU0VHUFRSIHJlc2lkLAoJQllURSAqKnJlc2RhdGEsaW50ICpyZXNsZW4sRFdPUkQgKm9mZgopIHsKCU5FX1RZUEVJTkZPCXRpOwoJTkVfTkFNRUlORk8Jbmk7CglpbnQJCWk7CglXT1JECQlzaGlmdGNvdW50OwoJRFdPUkQJCW5laGRvZmZzZXQ7CgoJbmVoZG9mZnNldCA9IExaVEVMTChsemZkKTsKCUxaU2VlazMyKGx6ZmQsbmVoZC0+cmVzb3VyY2VfdGFiX29mZnNldCxTRUVLX0NVUik7CglMWlJFQUQoJnNoaWZ0Y291bnQpOwoJZHByaW50Zl92ZXIoc3RkZGViLCJzaGlmdGNvdW50IGlzICVkXG4iLHNoaWZ0Y291bnQpOwoJZHByaW50Zl92ZXIoc3RkZGViLCJyZWFkaW5nIHJlc291cmNlIHR5cGVpbmZvIGRpci5cbiIpOwoKCWlmICghSElXT1JEKHR5cGVpZCkpIHR5cGVpZCA9IChTRUdQVFIpKExPV09SRCh0eXBlaWQpIHwgMHg4MDAwKTsKCWlmICghSElXT1JEKHJlc2lkKSkgIHJlc2lkICA9IChTRUdQVFIpKExPV09SRChyZXNpZCkgfCAweDgwMDApOwoJd2hpbGUgKDEpIHsKCQlpbnQJc2tpcGZsYWc7CgoJCUxaUkVBRCgmdGkpOwoJCWlmICghdGkudHlwZV9pZCkKCQkJcmV0dXJuIDA7CgkJZHByaW50Zl92ZXIoc3RkZGViLCIgICAgdGkudHlwZWlkID0lMDR4LGNvdW50PSVkXG4iLHRpLnR5cGVfaWQsdGkuY291bnQpOwoJCXNraXBmbGFnPTA7CgkJaWYgKCFISVdPUkQodHlwZWlkKSkgewoJCQlpZiAoKHRpLnR5cGVfaWQmMHg4MDAwKSYmKHR5cGVpZCE9dGkudHlwZV9pZCkpCgkJCQlza2lwZmxhZz0xOwoJCX0gZWxzZSB7CgkJCWlmICh0aS50eXBlX2lkICYgMHg4MDAwKSB7CgkJCQlza2lwZmxhZz0xOyAKCQkJfSBlbHNlIHsKCQkJCUJZVEUJbGVuOwoJCQkJY2hhcgkqc3RyOwoJCQkJRFdPUkQJd2hlcmVsZWZ0OwoKCQkJCXdoZXJlbGVmdCA9IExaVEVMTChsemZkKTsKCQkJCUxaU2VlazMyKAoJCQkJCWx6ZmQsCgkJCQkJbmVoZG9mZnNldCtuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0K3RpLnR5cGVfaWQsCgkJCQkJU0VFS19TRVQKCQkJCSk7CgkJCQlMWlJFQUQoJmxlbik7CgkJCQlzdHI9eG1hbGxvYyhsZW4pOwoJCQkJaWYgKGxlbiE9TFpSZWFkMzIobHpmZCxzdHIsbGVuKSkKCQkJCQlyZXR1cm4gMDsKCQkJCWRwcmludGZfdmVyKHN0ZGRlYiwicmVhZCAlcyB0byBjb21wYXJlIGl0IHdpdGggJXNcbiIsCgkJCQkJc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpCgkJCQkpOwoJCQkJaWYgKGxzdHJjbXBpMzJBKHN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKSkpCgkJCQkJc2tpcGZsYWc9MTsKCQkJCWZyZWUoc3RyKTsKCQkJCUxaU2VlazMyKGx6ZmQsd2hlcmVsZWZ0LFNFRUtfU0VUKTsKCQkJfQoJCX0KCQlpZiAoc2tpcGZsYWcpIHsKCQkJTFpTZWVrMzIobHpmZCx0aS5jb3VudCpzaXplb2YobmkpLFNFRUtfQ1VSKTsKCQkJY29udGludWU7CgkJfQoJCWZvciAoaT0wO2k8dGkuY291bnQ7aSsrKSB7CgkJCVdPUkQJKnJkYXRhOwoJCQlpbnQJbGVuOwoKCQkJTFpSRUFEKCZuaSk7CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiCW5pLmlkPSU0eCxvZmZzZXQ9JWQsbGVuZ3RoPSVkXG4iLAoJCQkJbmkuaWQsbmkub2Zmc2V0LG5pLmxlbmd0aAoJCQkpOwoJCQlza2lwZmxhZz0xOwoJCQlpZiAoIUhJV09SRChyZXNpZCkpIHsKCQkJCWlmIChuaS5pZCA9PSByZXNpZCkKCQkJCQlza2lwZmxhZz0wOwoJCQl9IGVsc2UgewoJCQkJaWYgKCEobmkuaWQgJiAweDgwMDApKSB7CgkJCQkJQllURQlsZW47CgkJCQkJY2hhcgkqc3RyOwoJCQkJCURXT1JECXdoZXJlbGVmdDsKCgkJCQkJd2hlcmVsZWZ0ID0gTFpURUxMKGx6ZmQpOwoJCQkJCSAgTFpTZWVrMzIoCgkJCQkJCWx6ZmQsCgkJCQkJCW5laGRvZmZzZXQrbmVoZC0+cmVzb3VyY2VfdGFiX29mZnNldCtuaS5pZCwKCQkJCQkJU0VFS19TRVQKCQkJCQkpOwoJCQkJCUxaUkVBRCgmbGVuKTsKCQkJCQlzdHI9eG1hbGxvYyhsZW4pOwoJCQkJCWlmIChsZW4hPUxaUmVhZDMyKGx6ZmQsc3RyLGxlbikpCgkJCQkJCXJldHVybiAwOwoJCQkJCWRwcmludGZfdmVyKHN0ZGRlYiwicmVhZCAlcyB0byBjb21wYXJlIGl0IHdpdGggJXNcbiIsCgkJCQkJCXN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKQoJCQkJCSk7CgkJCQkJaWYgKCFsc3RyY21waTMyQShzdHIsKGNoYXIqKVBUUl9TRUdfVE9fTElOKHR5cGVpZCkpKQoJCQkJCQlza2lwZmxhZz0wOwoJCQkJCWZyZWUoc3RyKTsKCQkJCQlMWlNlZWszMihsemZkLHdoZXJlbGVmdCxTRUVLX1NFVCk7CgkJCQl9CgkJCX0KCQkJaWYgKHNraXBmbGFnKQoJCQkJY29udGludWU7CgkJCUxaU2VlazMyKGx6ZmQsKChpbnQpbmkub2Zmc2V0PDxzaGlmdGNvdW50KSxTRUVLX1NFVCk7CgkJCSpvZmYJPSAoaW50KW5pLm9mZnNldDw8c2hpZnRjb3VudDsKCQkJbGVuCT0gbmkubGVuZ3RoPDxzaGlmdGNvdW50OwoJCQlyZGF0YT0oV09SRCopeG1hbGxvYyhsZW4pOwoJCQlpZiAobGVuIT1MWlJlYWQzMihsemZkLHJkYXRhLGxlbikpIHsKCQkJCWZyZWUocmRhdGEpOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJZHByaW50Zl92ZXIoc3RkZGViLCJyZXNvdXJjZSBmb3VuZC5cbiIpOwoJCQkqcmVzZGF0YT0gKEJZVEUqKXJkYXRhOwoJCQkqcmVzbGVuCT0gbGVuOwoJCQlyZXR1cm4gMTsKCQl9Cgl9Cn0KCi8qIEdldEZpbGVSZXNvdXJjZVNpemUJCQkJW1ZFUi4yXSAqLwpEV09SRApHZXRGaWxlUmVzb3VyY2VTaXplKExQQ1NUUiBmaWxlbmFtZSxTRUdQVFIgcmVzdHlwZSxTRUdQVFIgcmVzaWQsTFBEV09SRCBvZmYpIHsKCUhGSUxFMzIJbHpmZDsKCU9GU1RSVUNUCW9mczsKCUJZVEUJKnJlc2RhdGE7CglpbnQJcmVzbGVuOwoJc3RydWN0CW5lX2hlYWRlcl9zCW5laGQ7CgoJZHByaW50Zl92ZXIoc3RkZGViLCJHZXRGaWxlUmVzb3VyY2VTaXplKCVzLCVseCwlbHgsJXApXG4iLAoJCWZpbGVuYW1lLChMT05HKXJlc3R5cGUsKExPTkcpcmVzaWQsb2ZmCgkpOwoJbHpmZD1MWk9wZW5GaWxlMzJBKGZpbGVuYW1lLCZvZnMsT0ZfUkVBRCk7CglpZiAobHpmZD09MCkKCQlyZXR1cm4gMDsKCWlmICghcmVhZF9uZV9oZWFkZXIobHpmZCwmbmVoZCkpIHsKCQlMWkNsb3NlMzIobHpmZCk7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIWZpbmRfbmVfcmVzb3VyY2UobHpmZCwmbmVoZCxyZXN0eXBlLHJlc2lkLCZyZXNkYXRhLCZyZXNsZW4sb2ZmKSkgewoJCUxaQ2xvc2UzMihsemZkKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUocmVzZGF0YSk7CglMWkNsb3NlMzIobHpmZCk7CglyZXR1cm4gcmVzbGVuOwp9CgovKiBHZXRGaWxlUmVzb3VyY2UJCQkJW1ZFUi4zXSAqLwpEV09SRApHZXRGaWxlUmVzb3VyY2UoTFBDU1RSIGZpbGVuYW1lLFNFR1BUUiByZXN0eXBlLFNFR1BUUiByZXNpZCwKCQlEV09SRCBvZmYsRFdPUkQgZGF0YWxlbixMUFZPSUQgZGF0YQopIHsKCUhGSUxFMzIJbHpmZDsKCU9GU1RSVUNUCW9mczsKCUJZVEUJKnJlc2RhdGE7CglpbnQJcmVzbGVuPWRhdGFsZW47CglzdHJ1Y3QJbmVfaGVhZGVyX3MJbmVoZDsKCWRwcmludGZfdmVyKHN0ZGRlYiwiR2V0RmlsZVJlc291cmNlKCVzLCVseCwlbHgsJWxkLCVsZCwlcClcbiIsCgkJZmlsZW5hbWUsKExPTkcpcmVzdHlwZSwoTE9ORylyZXNpZCxvZmYsZGF0YWxlbixkYXRhCgkpOwoKCWx6ZmQ9TFpPcGVuRmlsZTMyQShmaWxlbmFtZSwmb2ZzLE9GX1JFQUQpOwoJaWYgKGx6ZmQ9PTApCgkJcmV0dXJuIDA7CglpZiAoIW9mZikgewoJCWlmICghcmVhZF9uZV9oZWFkZXIobHpmZCwmbmVoZCkpIHsKCQkJTFpDbG9zZTMyKGx6ZmQpOwoJCQlyZXR1cm4gMDsKCQl9CgkJaWYgKCFmaW5kX25lX3Jlc291cmNlKGx6ZmQsJm5laGQscmVzdHlwZSxyZXNpZCwmcmVzZGF0YSwmcmVzbGVuLCZvZmYpKSB7CgkJCUxaQ2xvc2UzMihsemZkKTsKCQkJcmV0dXJuIDA7CgkJfQoJCWZyZWUocmVzZGF0YSk7Cgl9CglMWlNlZWszMihsemZkLG9mZixTRUVLX1NFVCk7CglpZiAocmVzbGVuPmRhdGFsZW4pCgkJcmVzbGVuPWRhdGFsZW47CglMWlJlYWQzMihsemZkLGRhdGEscmVzbGVuKTsKCUxaQ2xvc2UzMihsemZkKTsKCXJldHVybiByZXNsZW47Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUJCQlbVkVSLjZdICovCkRXT1JECkdldEZpbGVWZXJzaW9uSW5mb1NpemUxNihMUENTVFIgZmlsZW5hbWUsTFBEV09SRCBoYW5kbGUpIHsKCURXT1JECWxlbixyZXQ7CglCWVRFCWJ1Zls3Ml07CglWU19GSVhFREZJTEVJTkZPICp2ZmZpOwoKCWRwcmludGZfdmVyKHN0ZGRlYiwiR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KCVzLCVwKVxuIixmaWxlbmFtZSxoYW5kbGUpOwoJbGVuPUdldEZpbGVSZXNvdXJjZVNpemUoZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTyxoYW5kbGUpOwoJaWYgKCFsZW4pCgkJcmV0dXJuIDA7CglyZXQ9R2V0RmlsZVJlc291cmNlKAoJCWZpbGVuYW1lLFZTX0ZJTEVfSU5GTyxWU19WRVJTSU9OX0lORk8sKmhhbmRsZSxzaXplb2YoYnVmKSxidWYKCSk7CglpZiAoIXJldCkKCQlyZXR1cm4gMDsKCgl2ZmZpPShWU19GSVhFREZJTEVJTkZPKikoYnVmKzB4MTQpOwoJaWYgKHZmZmktPmR3U2lnbmF0dXJlICE9IFZTX0ZGSV9TSUdOQVRVUkUpCgkJcmV0dXJuIDA7CglpZiAoKihXT1JEKilidWYgPCBsZW4pCgkJbGVuID0gKihXT1JEKilidWY7CglkcHJpbnRmX3ZlcihzdGRkZWIsIi0+c3RydWN2ZXI9JWxkLiVsZCxmaWxldmVyPSVsZC4lbGQscHJvZHVjdHZlcj0lbGQuJWxkLGZsYWdtYXNrPSVseCxmbGFncz0lbHgsT1M9IiwKCQkodmZmaS0+ZHdTdHJ1Y1ZlcnNpb24+PjE2KSx2ZmZpLT5kd1N0cnVjVmVyc2lvbiYweEZGRkYsCgkJdmZmaS0+ZHdGaWxlVmVyc2lvbk1TLHZmZmktPmR3RmlsZVZlcnNpb25MUywKCQl2ZmZpLT5kd1Byb2R1Y3RWZXJzaW9uTVMsdmZmaS0+ZHdQcm9kdWN0VmVyc2lvbkxTLAoJCXZmZmktPmR3RmlsZUZsYWdzTWFzayx2ZmZpLT5kd0ZpbGVGbGFncwoJKTsKCXN3aXRjaCAodmZmaS0+ZHdGaWxlT1MmMHhGRkZGMDAwMCkgewoJY2FzZSBWT1NfRE9TOmRwcmludGZfdmVyKHN0ZGRlYiwiRE9TLCIpO2JyZWFrOwoJY2FzZSBWT1NfT1MyMTY6ZHByaW50Zl92ZXIoc3RkZGViLCJPUy8yLTE2LCIpO2JyZWFrOwoJY2FzZSBWT1NfT1MyMzI6ZHByaW50Zl92ZXIoc3RkZGViLCJPUy8yLTMyLCIpO2JyZWFrOwoJY2FzZSBWT1NfTlQ6ZHByaW50Zl92ZXIoc3RkZGViLCJOVCwiKTticmVhazsKCWNhc2UgVk9TX1VOS05PV046CglkZWZhdWx0OgoJCWRwcmludGZfdmVyKHN0ZGRlYiwiVU5LTk9XTiglbGQpLCIsdmZmaS0+ZHdGaWxlT1MmMHhGRkZGMDAwMCk7YnJlYWs7Cgl9Cglzd2l0Y2ggKHZmZmktPmR3RmlsZU9TICYgMHhGRkZGKSB7CgljYXNlIFZPU19fQkFTRTpkcHJpbnRmX3ZlcihzdGRkZWIsIkJBU0UiKTticmVhazsKCWNhc2UgVk9TX19XSU5ET1dTMTY6ZHByaW50Zl92ZXIoc3RkZGViLCJXSU4xNiIpO2JyZWFrOwoJY2FzZSBWT1NfX1dJTkRPV1MzMjpkcHJpbnRmX3ZlcihzdGRkZWIsIldJTjMyIik7YnJlYWs7CgljYXNlIFZPU19fUE0xNjpkcHJpbnRmX3ZlcihzdGRkZWIsIlBNMTYiKTticmVhazsKCWNhc2UgVk9TX19QTTMyOmRwcmludGZfdmVyKHN0ZGRlYiwiUE0zMiIpO2JyZWFrOwoJZGVmYXVsdDpkcHJpbnRmX3ZlcihzdGRkZWIsIlVOS05PV04oJWxkKSIsdmZmaS0+ZHdGaWxlT1MmMHhGRkZGKTticmVhazsKCX0KCXN3aXRjaCAodmZmaS0+ZHdGaWxlVHlwZSkgewoJZGVmYXVsdDoKCWNhc2UgVkZUX1VOS05PV046CgkJZHByaW50Zl92ZXIoc3RkZGViLCJmaWxldHlwZT1Vbmtub3duKCVsZCkiLHZmZmktPmR3RmlsZVR5cGUpOwoJCWJyZWFrOwoJY2FzZSBWRlRfQVBQOmRwcmludGZfdmVyKHN0ZGRlYiwiZmlsZXR5cGU9QVBQIik7YnJlYWs7CgljYXNlIFZGVF9ETEw6ZHByaW50Zl92ZXIoc3RkZGViLCJmaWxldHlwZT1ETEwiKTticmVhazsKCWNhc2UgVkZUX0RSVjoKCQlkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPURSViwiKTsKCQlzd2l0Y2godmZmaS0+ZHdGaWxlU3VidHlwZSkgewoJCWRlZmF1bHQ6CgkJY2FzZSBWRlQyX1VOS05PV046CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVTdWJ0eXBlKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9QUklOVEVSOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIlBSSU5URVIiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9LRVlCT0FSRDoKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJLRVlCT0FSRCIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0xBTkdVQUdFOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIkxBTkdVQUdFIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfRElTUExBWToKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJESVNQTEFZIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfTU9VU0U6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiTU9VU0UiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9ORVRXT1JLOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIk5FVFdPUksiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9TWVNURU06CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiU1lTVEVNIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfSU5TVEFMTEFCTEU6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiSU5TVEFMTEFCTEUiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9TT1VORDoKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJTT1VORCIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0NPTU06CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiQ09NTSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0lOUFVUTUVUSE9EOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIklOUFVUTUVUSE9EIik7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgVkZUX0ZPTlQ6CgkJZHByaW50Zl92ZXIoc3RkZGViLCJmaWxldHlwZT1GT05ULiIpOwoJCXN3aXRjaCAodmZmaS0+ZHdGaWxlU3VidHlwZSkgewoJCWRlZmF1bHQ6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVTdWJ0eXBlKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfUkFTVEVSOmRwcmludGZfdmVyKHN0ZGRlYiwiUkFTVEVSIik7YnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfVkVDVE9SOmRwcmludGZfdmVyKHN0ZGRlYiwiVkVDVE9SIik7YnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfVFJVRVRZUEU6ZHByaW50Zl92ZXIoc3RkZGViLCJUUlVFVFlQRSIpO2JyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgVkZUX1ZYRDpkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPVZYRCIpO2JyZWFrOwoJY2FzZSBWRlRfU1RBVElDX0xJQjpkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPVNUQVRJQ19MSUIiKTticmVhazsKCX0KCWRwcmludGZfdmVyKHN0ZGRlYiwiZmlsZWRhdGE9JWx4LiVseFxuIix2ZmZpLT5kd0ZpbGVEYXRlTVMsdmZmaS0+ZHdGaWxlRGF0ZUxTKTsKCXJldHVybiBsZW47Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEJCQlbVkVSU0lPTi4xXSAqLwpEV09SRApHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJBKExQQ1NUUiBmaWxlbmFtZSxMUERXT1JEIGhhbmRsZSkgewoJZHByaW50Zl92ZXIoc3RkZGViLCJHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJBKCVzLCVwKVxuIixmaWxlbmFtZSxoYW5kbGUpOwoJcmV0dXJuIEdldEZpbGVWZXJzaW9uSW5mb1NpemUxNihmaWxlbmFtZSxoYW5kbGUpOwp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJXCQkJW1ZFUlNJT04uMl0gKi8KRFdPUkQgR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTMyVyggTFBDV1NUUiBmaWxlbmFtZSwgTFBEV09SRCBoYW5kbGUgKQp7CiAgICBMUFNUUiB4Zm4gPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIGZpbGVuYW1lICk7CiAgICBEV09SRCByZXQgPSBHZXRGaWxlVmVyc2lvbkluZm9TaXplMTYoIHhmbiwgaGFuZGxlICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgeGZuICk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm8JCQkJW1ZFUi43XSAqLwpEV09SRCAKR2V0RmlsZVZlcnNpb25JbmZvMTYoTFBDU1RSIGZpbGVuYW1lLERXT1JEIGhhbmRsZSxEV09SRCBkYXRhc2l6ZSxMUFZPSUQgZGF0YSkgewoJZHByaW50Zl92ZXIoc3RkZGViLCJHZXRGaWxlVmVyc2lvbkluZm8xNiglcywlbGQsJWxkLCVwKVxuLT4iLAoJCWZpbGVuYW1lLGhhbmRsZSxkYXRhc2l6ZSxkYXRhCgkpOwoJcmV0dXJuIEdldEZpbGVSZXNvdXJjZSgKCQlmaWxlbmFtZSxWU19GSUxFX0lORk8sVlNfVkVSU0lPTl9JTkZPLGhhbmRsZSxkYXRhc2l6ZSxkYXRhCgkpOwp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm9BCQkJCVtWRVJTSU9OLjBdICovCkRXT1JEIApHZXRGaWxlVmVyc2lvbkluZm8zMkEoTFBDU1RSIGZpbGVuYW1lLERXT1JEIGhhbmRsZSxEV09SRCBkYXRhc2l6ZSxMUFZPSUQgZGF0YSkgewoJcmV0dXJuIEdldEZpbGVWZXJzaW9uSW5mbzE2KGZpbGVuYW1lLGhhbmRsZSxkYXRhc2l6ZSxkYXRhKTsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvVwkJCQlbVkVSU0lPTi4zXSAqLwpEV09SRCBHZXRGaWxlVmVyc2lvbkluZm8zMlcoIExQQ1dTVFIgZmlsZW5hbWUsIERXT1JEIGhhbmRsZSwgRFdPUkQgZGF0YXNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIGRhdGEpCnsKICAgIExQU1RSIGZuID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBmaWxlbmFtZSApOwogICAgRFdPUkQgcmV0ID0gR2V0RmlsZVZlcnNpb25JbmZvMTYoIGZuLCBoYW5kbGUsIGRhdGFzaXplLCBkYXRhICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm4gKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIFZlckZpbmRGaWxlCQkJCVtWRVIuOF0gKi8KRFdPUkQKVmVyRmluZEZpbGUxNigKCVVJTlQxNiBmbGFncyxMUENTVFIgZmlsZW5hbWUsTFBDU1RSIHdpbmRpcixMUENTVFIgYXBwZGlyLAoJTFBTVFIgY3VyZGlyLFVJTlQxNiAqY3VyZGlybGVuLExQU1RSIGRlc3RkaXIsVUlOVDE2ICpkZXN0ZGlybGVuCikgewoJZHByaW50Zl92ZXIoc3RkZGViLCJWZXJGaW5kRmlsZSgleCwlcywlcywlcywlcCwlZCwlcCwlZClcbiIsCgkJZmxhZ3MsZmlsZW5hbWUsd2luZGlyLGFwcGRpcixjdXJkaXIsKmN1cmRpcmxlbixkZXN0ZGlyLCpkZXN0ZGlybGVuCgkpOwoJc3RyY3B5KGN1cmRpciwiWjpcXFJPT1RcXC5XSU5FXFwiKTsvKkZJWE1FKi8KCSpjdXJkaXJsZW49c3RybGVuKGN1cmRpcik7CglzdHJjcHkoZGVzdGRpciwiWjpcXFJPT1RcXC5XSU5FXFwiKTsvKkZJWE1FKi8KCSpkZXN0ZGlybGVuPXN0cmxlbihkZXN0ZGlyKTsKCXJldHVybiAwOwp9CgovKiBWZXJGaW5kRmlsZUEJCQkJCQlbVkVSU0lPTi41XSAqLwpEV09SRApWZXJGaW5kRmlsZTMyQSgKCVVJTlQzMiBmbGFncyxMUENTVFIgZmlsZW5hbWUsTFBDU1RSIHdpbmRpcixMUENTVFIgYXBwZGlyLAoJTFBTVFIgY3VyZGlyLFVJTlQzMiAqcGN1cmRpcmxlbixMUFNUUiBkZXN0ZGlyLFVJTlQzMiAqcGRlc3RkaXJsZW4gKQp7CiAgICBVSU5UMTYgY3VyZGlybGVuLCBkZXN0ZGlybGVuOwogICAgRFdPUkQgcmV0ID0gVmVyRmluZEZpbGUxNihmbGFncyxmaWxlbmFtZSx3aW5kaXIsYXBwZGlyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJkaXIsJmN1cmRpcmxlbixkZXN0ZGlyLCZkZXN0ZGlybGVuKTsKICAgICpwY3VyZGlybGVuID0gY3VyZGlybGVuOwogICAgKnBkZXN0ZGlybGVuID0gZGVzdGRpcmxlbjsKICAgIHJldHVybiByZXQ7Cn0KCi8qIFZlckZpbmRGaWxlVwkJCQkJCVtWRVJTSU9OLjZdICovCkRXT1JEClZlckZpbmRGaWxlMzJXKAoJVUlOVDMyIGZsYWdzLExQQ1dTVFIgZmlsZW5hbWUsTFBDV1NUUiB3aW5kaXIsTFBDV1NUUiBhcHBkaXIsCglMUFdTVFIgY3VyZGlyLFVJTlQzMiAqcGN1cmRpcmxlbixMUFdTVFIgZGVzdGRpcixVSU5UMzIgKnBkZXN0ZGlybGVuICkKewogICAgVUlOVDE2IGN1cmRpcmxlbiwgZGVzdGRpcmxlbjsKICAgIExQU1RSIHdmbix3d2Qsd2FkLHdkZCx3Y2Q7CiAgICBEV09SRCByZXQ7CgogICAgd2ZuID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBmaWxlbmFtZSApOwogICAgd3dkID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3aW5kaXIgKTsKICAgIHdhZCA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYXBwZGlyICk7CiAgICB3Y2QgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsICpwY3VyZGlybGVuICk7CiAgICB3ZGQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsICpwZGVzdGRpcmxlbiApOwogICAgcmV0ID0gVmVyRmluZEZpbGUxNihmbGFncyx3Zm4sd3dkLHdhZCx3Y2QsJmN1cmRpcmxlbix3ZGQsJmRlc3RkaXJsZW4pOwogICAgbHN0cmNweW5BdG9XKGN1cmRpcix3Y2QsKnBjdXJkaXJsZW4pOwogICAgbHN0cmNweW5BdG9XKGRlc3RkaXIsd2RkLCpwZGVzdGRpcmxlbik7CiAgICAqcGN1cmRpcmxlbiA9IHN0cmxlbih3Y2QpOwogICAgKnBkZXN0ZGlybGVuID0gc3RybGVuKHdkZCk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2ZuICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3dkICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2FkICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2NkICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2RkICk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBWZXJJbnN0YWxsRmlsZQkJCQkJW1ZFUi45XSAqLwpEV09SRApWZXJJbnN0YWxsRmlsZTE2KAoJVUlOVDE2IGZsYWdzLExQQ1NUUiBzcmNmaWxlbmFtZSxMUENTVFIgZGVzdGZpbGVuYW1lLExQQ1NUUiBzcmNkaXIsCglMUENTVFIgZGVzdGRpcixMUFNUUiB0bXBmaWxlLFVJTlQxNiAqdG1wZmlsZWxlbgopIHsKCWRwcmludGZfdmVyKHN0ZGRlYiwiVmVySW5zdGFsbEZpbGUoJXgsJXMsJXMsJXMsJXMsJXAsJWQpXG4iLAoJCWZsYWdzLHNyY2ZpbGVuYW1lLGRlc3RmaWxlbmFtZSxzcmNkaXIsZGVzdGRpcix0bXBmaWxlLCp0bXBmaWxlbGVuCgkpOwoKCS8qIEZJWE1FOiBJbXBsZW1lbnRhdGlvbiBzdGlsbCBtaXNzaW5nIC4uLi4gKi8KCglyZXR1cm4gVklGX1NSQ09MRDsKfQoKLyogVmVyRmluZEZpbGVBCQkJCQlbVkVSU0lPTi41XSAqLwpEV09SRApWZXJJbnN0YWxsRmlsZTMyQSgKCVVJTlQzMiBmbGFncyxMUENTVFIgc3JjZmlsZW5hbWUsTFBDU1RSIGRlc3RmaWxlbmFtZSxMUENTVFIgc3JjZGlyLAoJTFBDU1RSIGRlc3RkaXIsTFBTVFIgdG1wZmlsZSxVSU5UMzIgKnRtcGZpbGVsZW4gKQp7CiAgICBVSU5UMTYgZmlsZWxlbjsKICAgIERXT1JEIHJldD0gVmVySW5zdGFsbEZpbGUxNihmbGFncyxzcmNmaWxlbmFtZSxkZXN0ZmlsZW5hbWUsc3JjZGlyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RkaXIsdG1wZmlsZSwmZmlsZWxlbik7CiAgICAqdG1wZmlsZWxlbiA9IGZpbGVsZW47CiAgICByZXR1cm4gcmV0Owp9CgovKiBWZXJGaW5kRmlsZVcJCQkJCVtWRVJTSU9OLjZdICovCkRXT1JEClZlckluc3RhbGxGaWxlMzJXKAoJVUlOVDMyIGZsYWdzLExQQ1dTVFIgc3JjZmlsZW5hbWUsTFBDV1NUUiBkZXN0ZmlsZW5hbWUsTFBDV1NUUiBzcmNkaXIsCglMUENXU1RSIGRlc3RkaXIsTFBXU1RSIHRtcGZpbGUsVUlOVDMyICp0bXBmaWxlbGVuICkKewogICAgTFBTVFIgd3NyY2Ysd3NyY2Qsd2Rlc3RmLHdkZXN0ZCx3dG1wZjsKICAgIERXT1JEIHJldDsKCiAgICB3c3JjZiAgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2ZpbGVuYW1lICk7CiAgICB3c3JjZCAgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2RpciApOwogICAgd2Rlc3RmID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0ZmlsZW5hbWUgKTsKICAgIHdkZXN0ZCA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGVzdGRpciApOwogICAgd3RtcGYgID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB0bXBmaWxlICk7CiAgICByZXQgPSBWZXJJbnN0YWxsRmlsZTMyQShmbGFncyx3c3JjZix3ZGVzdGYsd3NyY2Qsd2Rlc3RkLHd0bXBmLHRtcGZpbGVsZW4pOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdzcmNmICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3NyY2QgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3ZGVzdGYgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3ZGVzdGQgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3dG1wZiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogRklYTUU6IFRoaXMgdGFibGUgc2hvdWxkLCBvZiBjb3Vyc2UsIGJlIGxhbmd1YWdlIGRlcGVuZGVuZCAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IG1hcF9pZDJzdHIgewoJVUlOVAlsYW5naWQ7Cgljb25zdCBjaGFyICpsYW5nbmFtZTsKfSBsYW5ndWFnZXNbXT17Cgl7MHgwNDAxLCJBcmFiaXNjaCJ9LAoJezB4MDQwMiwiQnVsZ2FyaXNjaCJ9LAoJezB4MDQwMywiS2F0YWxhbmlzY2gifSwKCXsweDA0MDQsIlRyYWRpdGlvbmFsZXMgQ2hpbmVzaXNjaCJ9LAoJezB4MDQwNSwiVHNjaGVjaXNjaCJ9LAoJezB4MDQwNiwiRORuaXNjaCJ9LAoJezB4MDQwNywiRGV1dHNjaCJ9LAoJezB4MDQwOCwiR3JpZWNoaXNjaCJ9LAoJezB4MDQwOSwiQW1lcmlrYW5pc2NoZXMgRW5nbGlzY2gifSwKCXsweDA0MEEsIkthc3RpbGlzY2hlcyBTcGFuaXNjaCJ9LAoJezB4MDQwQiwiRmlubmlzY2gifSwKCXsweDA0MEMsIkZyYW569nNpc2NoIn0sCgl7MHgwNDBELCJIZWJy5GlzY2gifSwKCXsweDA0MEUsIlVuZ2FyaXNjaCJ9LAoJezB4MDQwRiwiSXNs5G5kaXNjaCJ9LAoJezB4MDQxMCwiSXRhbGllbmlzY2gifSwKCXsweDA0MTEsIkphcGFuaXNjaCJ9LAoJezB4MDQxMiwiS29yZWFuaXNjaCJ9LAoJezB4MDQxMywiTmllZGVybORuZGlzY2gifSwKCXsweDA0MTQsIk5vcndlZ2lzY2gtQm9rbWFsIn0sCgl7MHgwNDE1LCJQb2xuaXNjaCJ9LAoJezB4MDQxNiwiQnJhc2lsaWFuaXNjaGVzIFBvcnR1Z2llc2lzY2gifSwKCXsweDA0MTcsIlLkdG9yb21hbmlzY2gifSwKCXsweDA0MTgsIlJ1beRuaXNjaCJ9LAoJezB4MDQxOSwiUnVzc2lzY2gifSwKCXsweDA0MUEsIktyb2F0b3NlcmJpc2NoIChsYXRlaW5pc2NoKSJ9LAoJezB4MDQxQiwiU2xvd2VuaXNjaCJ9LAoJezB4MDQxQywiQWxiYW5pc2NoIn0sCgl7MHgwNDFELCJTY2h3ZWRpc2NoIn0sCgl7MHgwNDFFLCJUaGFpIn0sCgl7MHgwNDFGLCJU/HJraXNjaCJ9LAoJezB4MDQyMCwiVXJkdSJ9LAoJezB4MDQyMSwiQmFoYXNhIn0sCgl7MHgwODA0LCJWZXJlaW5mYWNodGVzIENoaW5lc2lzY2gifSwKCXsweDA4MDcsIlNjaHdlaXplcmRldXRzY2gifSwKCXsweDA4MDksIkJyaXRpc2NoZXMgRW5nbGlzY2gifSwKCXsweDA4MEEsIk1leGlrYW5pc2NoZXMgU3BhbmlzY2gifSwKCXsweDA4MEMsIkJlbGdpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDA4MTAsIlNjaHdlaXplcmlzY2hlcyBJdGFsaWVuaXNjaCJ9LAoJezB4MDgxMywiQmVsZ2lzY2hlcyBOaWVkZXJs5G5kaXNjaCJ9LAoJezB4MDgxNCwiTm9yZ3dlZ2lzY2gtTnlub3JzayJ9LAoJezB4MDgxNiwiUG9ydHVnaWVzaXNjaCJ9LAoJezB4MDgxQSwiU2VyYm9rcmF0aXNjaCAoa3lyaWxsaXNjaCkifSwKCXsweDBDMUMsIkthbmFkaXNjaGVzIEZyYW569nNpc2NoIn0sCgl7MHgxMDBDLCJTY2h3ZWl6ZXJpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDAwMDAsIlVuYmVrYW5udCJ9LAp9OwoKLyogVmVyTGFuZ3VhZ2VOYW1lCQkJCVtWRVIuMTBdICovCkRXT1JEClZlckxhbmd1YWdlTmFtZTE2KFVJTlQxNiBsYW5naWQsTFBTVFIgbGFuZ25hbWUsVUlOVDE2IGxhbmduYW1lbGVuKSB7CglpbnQJaTsKCWNoYXIJKmJ1ZjsKCglkcHJpbnRmX3ZlcihzdGRkZWIsIlZlckxhbmd1YWdlTmFtZSglZCwlcCwlZClcbiIsbGFuZ2lkLGxhbmduYW1lLGxhbmduYW1lbGVuKTsKCS8qIEZpcnN0LCBjaGVjayBcU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0XGNvbnRyb2xcTmxzXExvY2FsZVw8bGFuZ2lkPgoJICogZnJvbSB0aGUgcmVnaXN0cnkuIAoJICovCglidWY9KGNoYXIqKW1hbGxvYyhzdHJsZW4oIlxcU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcY29udHJvbFxcTmxzXFxMb2NhbGVcXCIpKzkpOwoJc3ByaW50ZihidWYsIlxcU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcY29udHJvbFxcTmxzXFxMb2NhbGVcXCUwOHgiLGxhbmdpZCk7CglpZiAoRVJST1JfU1VDQ0VTUz09UmVnUXVlcnlWYWx1ZTE2KEhLRVlfTE9DQUxfTUFDSElORSxidWYsbGFuZ25hbWUsKExQRFdPUkQpJmxhbmduYW1lbGVuKSkgewoJCWxhbmduYW1lW2xhbmduYW1lbGVuLTFdPSdcMCc7CgkJcmV0dXJuIGxhbmduYW1lbGVuOwoJfQoJLyogaWYgdGhhdCBmYWlscywgdXNlIHRoZSBpbnRlcmFsIHRhYmxlICovCglmb3IgKGk9MDtsYW5ndWFnZXNbaV0ubGFuZ2lkIT0wO2krKykKCQlpZiAobGFuZ2lkPT1sYW5ndWFnZXNbaV0ubGFuZ2lkKQoJCQlicmVhazsKCXN0cm5jcHkobGFuZ25hbWUsbGFuZ3VhZ2VzW2ldLmxhbmduYW1lLGxhbmduYW1lbGVuKTsKCWxhbmduYW1lW2xhbmduYW1lbGVuLTFdPSdcMCc7CglyZXR1cm4gc3RybGVuKGxhbmd1YWdlc1tpXS5sYW5nbmFtZSk7Cn0KCi8qIFZlckxhbmd1YWdlTmFtZUEJCQkJW1ZFUlNJT04uOV0gKi8KRFdPUkQKVmVyTGFuZ3VhZ2VOYW1lMzJBKFVJTlQzMiBsYW5naWQsTFBTVFIgbGFuZ25hbWUsVUlOVDMyIGxhbmduYW1lbGVuKSB7CglyZXR1cm4gVmVyTGFuZ3VhZ2VOYW1lMTYobGFuZ2lkLGxhbmduYW1lLGxhbmduYW1lbGVuKTsKfQoKLyogVmVyTGFuZ3VhZ2VOYW1lVwkJCQlbVkVSU0lPTi4xMF0gKi8KRFdPUkQKVmVyTGFuZ3VhZ2VOYW1lMzJXKFVJTlQzMiBsYW5naWQsTFBXU1RSIGxhbmduYW1lLFVJTlQzMiBsYW5nbmFtZWxlbikgewoJaW50CWk7CgljaGFyCWJ1ZmZlcls4MF07CglMUFdTVFIJa2V5bmFtZTsKCgkvKiBGaXJzdCwgY2hlY2sgXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldFxjb250cm9sXE5sc1xMb2NhbGVcPGxhbmdpZD4KCSAqIGZyb20gdGhlIHJlZ2lzdHJ5LiAKCSAqLwoJc3ByaW50ZihidWZmZXIsIlxcU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcY29udHJvbFxcTmxzXFxMb2NhbGVcXCUwOHgiLGxhbmdpZCk7CglrZXluYW1lID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWZmZXIgKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdRdWVyeVZhbHVlMzJXKEhLRVlfTE9DQUxfTUFDSElORSxrZXluYW1lLGxhbmduYW1lLChMUERXT1JEKSZsYW5nbmFtZWxlbikpIHsKCQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwga2V5bmFtZSApOwoJCXJldHVybiBsYW5nbmFtZWxlbjsKCX0KICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwga2V5bmFtZSApOwoJLyogaWYgdGhhdCBmYWlscywgdXNlIHRoZSBpbnRlcmFsIHRhYmxlICovCglmb3IgKGk9MDtsYW5ndWFnZXNbaV0ubGFuZ2lkIT0wO2krKykKCQlpZiAobGFuZ2lkPT1sYW5ndWFnZXNbaV0ubGFuZ2lkKQoJCQlicmVhazsKICAgICAgICBsc3RyY3B5QXRvVyggbGFuZ25hbWUsIGxhbmd1YWdlc1tpXS5sYW5nbmFtZSApOwoJcmV0dXJuIHN0cmxlbihsYW5ndWFnZXNbaV0ubGFuZ25hbWUpOyAvKiBzYW1lIGFzIHN0cmxlblcobGFuZ25hbWUpOyAqLwp9CgovKiBGSVhNRTogVU5JQ09ERT8gKi8Kc3RydWN0IGRiIHsKCVdPUkQJbmV4dG9mZjsKCVdPUkQJZGF0YWxlbjsKLyogaW4gbWVtb3J5IHN0cnVjdHVyZS4uLiAqLwoJY2hhcgluYW1lWzFdOyAJLyogcGFkZGVkIHRvIGR3b3JkIGFsaWdubWVudCAqLwovKiAuLi4uIAoJY2hhcglkYXRhW2RhdGFsZW5dOyAgICAgcGFkZGVkIHRvIGR3b3JkIGFsaWduZW1udAoJQllURQlzdWJkaXJkYXRhW107ICAgICAgdW50aWwgbmV4dG9mZgogKi8KfTsKCnN0YXRpYyBCWVRFKgpfZmluZF9kYXRhKEJZVEUgKmJsb2NrLExQQ1NUUiBzdHIpIHsKCWNoYXIJKm5leHRzbGFzaDsKCWludAlzdWJzdHJsZW47CglzdHJ1Y3QJZGIJKmRiOwoKCXdoaWxlICgqc3RyICYmICpzdHI9PSdcXCcpCgkJc3RyKys7CglpZiAoTlVMTCE9KG5leHRzbGFzaD1zdHJjaHIoc3RyLCdcXCcpKSkKCQlzdWJzdHJsZW49bmV4dHNsYXNoLXN0cjsKCWVsc2UKCQlzdWJzdHJsZW49c3RybGVuKHN0cik7CglpZiAobmV4dHNsYXNoIT1OVUxMKSB7CgkJd2hpbGUgKCpuZXh0c2xhc2ggJiYgKm5leHRzbGFzaD09J1xcJykKCQkJbmV4dHNsYXNoKys7CgkJaWYgKCEqbmV4dHNsYXNoKQoJCQluZXh0c2xhc2g9TlVMTDsKCX0KCgoJd2hpbGUgKDEpIHsKCQlkYj0oc3RydWN0IGRiKilibG9jazsKCQlkcHJpbnRmX3ZlcihzdGRkZWIsImRiPSVwLGRiLT5uZXh0b2ZmPSVkLGRiLT5kYXRhbGVuPSVkLGRiLT5uYW1lPSVzLGRiLT5kYXRhPSVzXG4iLAoJCQlkYixkYi0+bmV4dG9mZixkYi0+ZGF0YWxlbixkYi0+bmFtZSwoY2hhciopKChjaGFyKilkYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+MykpCgkJKTsKCQlpZiAoIWRiLT5uZXh0b2ZmKQoJCQlyZXR1cm4gTlVMTDsKCgkJZHByaW50Zl92ZXIoc3RkZGViLCJjb21wYXJpbmcgd2l0aCAlc1xuIixkYi0+bmFtZSk7CgkJaWYgKCFzdHJuY21wKGRiLT5uYW1lLHN0cixzdWJzdHJsZW4pKSB7CgkJCWlmIChuZXh0c2xhc2gpCgkJCQlyZXR1cm4gX2ZpbmRfZGF0YSgKCQkJCQlibG9jays0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+MykrKChkYi0+ZGF0YWxlbiszKSZ+MykKCQkJCQksbmV4dHNsYXNoCgkJCQkpOwoJCQllbHNlCgkJCQlyZXR1cm4gYmxvY2s7CgkJfQoJCWJsb2NrPWJsb2NrKygoZGItPm5leHRvZmYrMykmfjMpOwoJfQp9CgovKiBWZXJRdWVyeVZhbHVlIAkJCVtWRVIuMTFdICovCi8qIHRha2UgY2FyZSwgJ2J1ZmZlcicgaXMgTk9UIGEgU0VHUFRSLCBpdCBqdXN0IHBvaW50cyB0byBvbmUgKi8KRFdPUkQKVmVyUXVlcnlWYWx1ZTE2KFNFR1BUUiBzZWdibG9jayxMUENTVFIgc3ViYmxvY2ssU0VHUFRSICpidWZmZXIsVUlOVDE2ICpidWZsZW4pCnsKCUJZVEUJKmJsb2NrPVBUUl9TRUdfVE9fTElOKHNlZ2Jsb2NrKSwqYjsKCXN0cnVjdAlkYgkqZGI7CgljaGFyCSpzOwoKCWRwcmludGZfdmVyKHN0ZGRlYiwiVmVyUXVlcnlWYWx1ZTE2KCVwLCVzLCVwLCVkKVxuIiwKCQlibG9jayxzdWJibG9jayxidWZmZXIsKmJ1ZmxlbgoJKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk9cXCIpK3N0cmxlbihzdWJibG9jaykrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPXFwiKTtzdHJjYXQocyxzdWJibG9jayk7CgliPV9maW5kX2RhdGEoYmxvY2sscyk7CglpZiAoYj09TlVMTCkgewoJCSpidWZsZW49MDsKCQlyZXR1cm4gMDsKCX0KCWRiPShzdHJ1Y3QgZGIqKWI7CgkqYnVmbGVuCT0gZGItPmRhdGFsZW47CgkvKiBsZXQgYiBwb2ludCB0byBkYXRhIGFyZWEgKi8KCWIJPSBiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKTsKCS8qIG5vdyBsb29rIHVwIHdoYXQgdGhlIHJlc3AuIFNFR1BUUiB3b3VsZCBiZSAuLi4gKi8KCSpidWZmZXIJPSAoYi1ibG9jaykrc2VnYmxvY2s7CglkcHJpbnRmX3ZlcihzdGRkZWIsIgktPiAlcz0lc1xuIixzdWJibG9jayxiKTsKCXJldHVybiAxOwp9CgpEV09SRApWZXJRdWVyeVZhbHVlMzJBKExQVk9JRCB2YmxvY2ssTFBDU1RSIHN1YmJsb2NrLExQVk9JRCAqdmJ1ZmZlcixVSU5UMzIgKmJ1ZmxlbikKewoJQllURQkqYiwqYmxvY2s9KExQQllURSl2YmxvY2ssKipidWZmZXI9KExQQllURSopdmJ1ZmZlcjsKCXN0cnVjdAlkYgkqZGI7CgljaGFyCSpzOwoKCWRwcmludGZfdmVyKHN0ZGRlYiwiVmVyUXVlcnlWYWx1ZTMyQSglcCwlcywlcCwlZClcbiIsCgkJYmxvY2ssc3ViYmxvY2ssYnVmZmVyLCpidWZsZW4KCSk7CglzPShjaGFyKil4bWFsbG9jKHN0cmxlbigiVlNfVkVSU0lPTl9JTkZPXFwiKStzdHJsZW4oc3ViYmxvY2spKzEpOwoJc3RyY3B5KHMsIlZTX1ZFUlNJT05fSU5GT1xcIik7c3RyY2F0KHMsc3ViYmxvY2spOwoJYj1fZmluZF9kYXRhKGJsb2NrLHMpOwoJaWYgKGI9PU5VTEwpIHsKCQkqYnVmbGVuPTA7CgkJcmV0dXJuIDA7Cgl9CglkYj0oc3RydWN0IGRiKiliOwoJKmJ1Zmxlbgk9IGRiLT5kYXRhbGVuOwoJLyogbGV0IGIgcG9pbnQgdG8gZGF0YSBhcmVhICovCgliCT0gYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+Myk7CgkqYnVmZmVyCT0gYjsKCWRwcmludGZfdmVyKHN0ZGRlYiwiCS0+ICVzPSVzXG4iLHN1YmJsb2NrLGIpOwoJcmV0dXJuIDE7Cn0KCkRXT1JEClZlclF1ZXJ5VmFsdWUzMlcoTFBWT0lEIHZibG9jayxMUENXU1RSIHN1YmJsb2NrLExQVk9JRCAqdmJ1ZmZlcixVSU5UMzIgKmJ1ZmxlbikKewoJLyogRklYTUU6IGhtbSwgd2Ugbm90IG9ubHkgbmVlZCB0byBjb252ZXJ0IHN1YmJsb2NrLCBidXQgYWxzbyAKCSAqICAgICAgICB0aGUgY29udGVudC4uLm9yPwoJICogQW5kIHdoYXQgYWJvdXQgVU5JQ09ERSB2ZXJzaW9uIGluZm8/CgkgKiBBbmQgdGhlIE5BTUVTIG9mIHRoZSB2YWx1ZXM/CgkgKi8KCUJZVEUJCSpiLCoqYnVmZmVyPShMUEJZVEUqKXZidWZmZXIsKmJsb2NrPShMUEJZVEUpdmJsb2NrOwoJc3RydWN0CWRiCSpkYjsKCWNoYXIJCSpzLCpzYjsKCglzYiA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3ViYmxvY2sgKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk9cXCIpK3N0cmxlbihzYikrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPXFwiKTtzdHJjYXQocyxzYik7CgliPV9maW5kX2RhdGEoYmxvY2sscyk7CglpZiAoYj09TlVMTCkgewoJCSpidWZsZW49MDsKCQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2IgKTsKCQlyZXR1cm4gMDsKCX0KCWRiPShzdHJ1Y3QgZGIqKWI7CgkqYnVmbGVuCT0gZGItPmRhdGFsZW47CgkvKiBsZXQgYiBwb2ludCB0byBkYXRhIGFyZWEgKi8KCWIJPSBiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKTsKCSpidWZmZXIJPSBiOwoJZHByaW50Zl92ZXIoc3RkZGViLCIJLT4gJXM9JXNcbiIsc2IsYik7CiAgICAgICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNiICk7CglyZXR1cm4gMTsKfQovKiAyMCBHRVRGSUxFVkVSU0lPTklORk9SQVcgKi8K