Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBIRFIgTG9hZGVyIGFuZCB3cml0ZXIKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieSAKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlIDxjbWF0aD4KI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbnRlcmZhY2UKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIGludCBzX2Zvcm1hdF9pZDsKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUkdCRSBsaWJyYXJ5Ci8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIG1heGltdW0gc2l6ZSBvZiBhIGxpbmUgaW4gdGhlIGhlYWRlcgojZGVmaW5lIEhEUl9NQVhMSU5FCTI1NgoKLy8gZmxhZ3MgaW5kaWNhdGluZyB3aGljaCBmaWVsZHMgaW4gYW4gcmdiZUhlYWRlckluZm8gYXJlIHZhbGlkCiNkZWZpbmUgUkdCRV9WQUxJRF9QUk9HUkFNVFlQRQkweDAxCiNkZWZpbmUgUkdCRV9WQUxJRF9DT01NRU5UCQkweDAyCiNkZWZpbmUgUkdCRV9WQUxJRF9HQU1NQQkJMHgwNAojZGVmaW5lIFJHQkVfVkFMSURfRVhQT1NVUkUJCTB4MDgKCi8vIG9mZnNldHMgdG8gcmVkLCBncmVlbiwgYW5kIGJsdWUgY29tcG9uZW50cyBpbiBhIGRhdGEgKGZsb2F0KSBwaXhlbAojZGVmaW5lIFJHQkVfREFUQV9SRUQgICAgMAojZGVmaW5lIFJHQkVfREFUQV9HUkVFTiAgMQojZGVmaW5lIFJHQkVfREFUQV9CTFVFICAgMgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojaWZkZWYgX1dJTjMyCiNwcmFnbWEgcGFjayhwdXNoLCAxKQojZWxzZQojcHJhZ21hIHBhY2soMSkKI2VuZGlmCgp0eXBlZGVmIHN0cnVjdCB0YWdIZWFkZXJJbmZvIHsKCWludCB2YWxpZDsJCQkJCS8vIGluZGljYXRlIHdoaWNoIGZpZWxkcyBhcmUgdmFsaWQKCWNoYXIgcHJvZ3JhbXR5cGVbMTZdOwkJLy8gbGlzdGVkIGF0IGJlZ2lubmluZyBvZiBmaWxlIHRvIGlkZW50aWZ5IGl0IGFmdGVyICIjPyIuIGRlZmF1bHRzIHRvICJSR0JFIgoJY2hhciBjb21tZW50W0hEUl9NQVhMSU5FXTsJLy8gY29tbWVudCBiZWdpbm5pbmcgd2l0aCAiIyAiIAoJZmxvYXQgZ2FtbWE7CQkJCS8vIGltYWdlIGhhcyBhbHJlYWR5IGJlZW4gZ2FtbWEgY29ycmVjdGVkIHdpdGggZ2l2ZW4gZ2FtbWEuIGRlZmF1bHRzIHRvIDEuMCAobm8gY29ycmVjdGlvbikKCWZsb2F0IGV4cG9zdXJlOwkJCQkvLyBhIHZhbHVlIG9mIDEuMCBpbiBhbiBpbWFnZSBjb3JyZXNwb25kcyB0byA8ZXhwb3N1cmU+IHdhdHRzL3N0ZXJhZGlhbi9tXjIuIGRlZmF1bHRzIHRvIDEuMAp9IHJnYmVIZWFkZXJJbmZvOwoKI2lmZGVmIF9XSU4zMgojcHJhZ21hIHBhY2socG9wKQojZWxzZQojcHJhZ21hIHBhY2soKQojZW5kaWYKCnR5cGVkZWYgZW51bSB7CglyZ2JlX3JlYWRfZXJyb3IsCglyZ2JlX3dyaXRlX2Vycm9yLAoJcmdiZV9mb3JtYXRfZXJyb3IsCglyZ2JlX21lbW9yeV9lcnJvcgp9IHJnYmVfZXJyb3JfY29kZTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUHJvdG90eXBlcwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCByZ2JlX0Vycm9yKHJnYmVfZXJyb3JfY29kZSBlcnJvcl9jb2RlLCBjb25zdCBjaGFyICptc2cpOwpzdGF0aWMgQk9PTCByZ2JlX0dldExpbmUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBjaGFyICpidWZmZXIsIGludCBsZW5ndGgpOwpzdGF0aWMgaW5saW5lIHZvaWQgcmdiZV9GbG9hdFRvUkdCRShCWVRFIHJnYmVbNF0sIEZJUkdCRiAqcmdiZik7CnN0YXRpYyBpbmxpbmUgdm9pZCByZ2JlX1JHQkVUb0Zsb2F0KEZJUkdCRiAqcmdiZiwgQllURSByZ2JlWzRdKTsKc3RhdGljIEJPT0wgcmdiZV9SZWFkSGVhZGVyKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgdW5zaWduZWQgKndpZHRoLCB1bnNpZ25lZCAqaGVpZ2h0LCByZ2JlSGVhZGVySW5mbyAqaGVhZGVyX2luZm8pOwpzdGF0aWMgQk9PTCByZ2JlX1dyaXRlSGVhZGVyKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgdW5zaWduZWQgd2lkdGgsIHVuc2lnbmVkIGhlaWdodCwgcmdiZUhlYWRlckluZm8gKmluZm8pOwpzdGF0aWMgQk9PTCByZ2JlX1JlYWRQaXhlbHMoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIHVuc2lnbmVkIG51bXBpeGVscyk7CnN0YXRpYyBCT09MIHJnYmVfV3JpdGVQaXhlbHMoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIHVuc2lnbmVkIG51bXBpeGVscyk7CnN0YXRpYyBCT09MIHJnYmVfUmVhZFBpeGVsc19STEUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIGludCBzY2FubGluZV93aWR0aCwgdW5zaWduZWQgbnVtX3NjYW5saW5lcyk7CnN0YXRpYyBCT09MIHJnYmVfV3JpdGVCeXRlc19STEUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBCWVRFICpkYXRhLCBpbnQgbnVtYnl0ZXMpOwpzdGF0aWMgQk9PTCByZ2JlX1dyaXRlUGl4ZWxzX1JMRShGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIEZJUkdCRiAqZGF0YSwgdW5zaWduZWQgc2NhbmxpbmVfd2lkdGgsIHVuc2lnbmVkIG51bV9zY2FubGluZXMpOwpzdGF0aWMgQk9PTCByZ2JlX1JlYWRNZXRhZGF0YShGSUJJVE1BUCAqZGliLCByZ2JlSGVhZGVySW5mbyAqaGVhZGVyX2luZm8pOwpzdGF0aWMgQk9PTCByZ2JlX1dyaXRlTWV0YWRhdGEoRklCSVRNQVAgKmRpYiwgcmdiZUhlYWRlckluZm8gKmhlYWRlcl9pbmZvKTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpEZWZhdWx0IGVycm9yIHJvdXRpbmUuICBjaGFuZ2UgdGhpcyB0byBjaGFuZ2UgZXJyb3IgaGFuZGxpbmcgCiovCnN0YXRpYyBCT09MICAKcmdiZV9FcnJvcihyZ2JlX2Vycm9yX2NvZGUgZXJyb3JfY29kZSwgY29uc3QgY2hhciAqbXNnKSB7Cglzd2l0Y2ggKGVycm9yX2NvZGUpIHsKCQljYXNlIHJnYmVfcmVhZF9lcnJvcjoKCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiUkdCRSByZWFkIGVycm9yIik7CgkJCWJyZWFrOwoJCWNhc2UgcmdiZV93cml0ZV9lcnJvcjoKCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiUkdCRSB3cml0ZSBlcnJvciIpOwoJCQlicmVhazsKCQljYXNlIHJnYmVfZm9ybWF0X2Vycm9yOgoJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsICJSR0JFIGJhZCBmaWxlIGZvcm1hdDogJXNcbiIsIG1zZyk7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJY2FzZSByZ2JlX21lbW9yeV9lcnJvcjoKCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiUkdCRSBlcnJvcjogJXNcbiIsbXNnKTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8qKgpHZXQgYSBsaW5lIGZyb20gYSBBU0NJSSBpbyBzdHJlYW0KKi8Kc3RhdGljIEJPT0wgCnJnYmVfR2V0TGluZShGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGNoYXIgKmJ1ZmZlciwgaW50IGxlbmd0aCkgewoJaW50IGk7CgltZW1zZXQoYnVmZmVyLCAwLCBsZW5ndGgpOwoJZm9yKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCQlpZighaW8tPnJlYWRfcHJvYygmYnVmZmVyW2ldLCAxLCAxLCBoYW5kbGUpKQoJCQlyZXR1cm4gRkFMU0U7CgkJaWYoYnVmZmVyW2ldID09IDB4MEEpCgkJCWJyZWFrOwoJfQoJCglyZXR1cm4gKGkgPCBsZW5ndGgpID8gVFJVRSA6IEZBTFNFOwp9CgovKioKU3RhbmRhcmQgY29udmVyc2lvbiBmcm9tIGZsb2F0IHBpeGVscyB0byByZ2JlIHBpeGVscy4gCk5vdGU6IHlvdSBjYW4gcmVtb3ZlIHRoZSAiaW5saW5lInMgaWYgeW91ciBjb21waWxlciBjb21wbGFpbnMgYWJvdXQgaXQgCiovCnN0YXRpYyBpbmxpbmUgdm9pZCAKcmdiZV9GbG9hdFRvUkdCRShCWVRFIHJnYmVbNF0sIEZJUkdCRiAqcmdiZikgewoJZmxvYXQgdjsKCWludCBlOwoKCXYgPSByZ2JmLT5yZWQ7CglpZiAocmdiZi0+Z3JlZW4gPiB2KSB2ID0gcmdiZi0+Z3JlZW47CglpZiAocmdiZi0+Ymx1ZSA+IHYpIHYgPSByZ2JmLT5ibHVlOwoJaWYgKHYgPCAxZS0zMikgewoJCXJnYmVbMF0gPSByZ2JlWzFdID0gcmdiZVsyXSA9IHJnYmVbM10gPSAwOwoJfQoJZWxzZSB7CiAgICAgICAgICB2ID0gKGZsb2F0KShzdGQ6OmZyZXhwKHYsICZlKSAqIDI1Ni4wIC8gdik7CiAgICAgICAgICByZ2JlWzBdID0gKEJZVEUpKHJnYmYtPnJlZCAqIHYpOwogICAgICAgICAgcmdiZVsxXSA9IChCWVRFKShyZ2JmLT5ncmVlbiAqIHYpOwogICAgICAgICAgcmdiZVsyXSA9IChCWVRFKShyZ2JmLT5ibHVlICogdik7CiAgICAgICAgICByZ2JlWzNdID0gKEJZVEUpKGUgKyAxMjgpOwogICAgICAgIH0KfQoKLyoqClN0YW5kYXJkIGNvbnZlcnNpb24gZnJvbSByZ2JlIHRvIGZsb2F0IHBpeGVscy4gCk5vdGU6IFdhcmQgdXNlcyBsZGV4cChjb2wrMC41LGV4cC0oMTI4KzgpKS4gCkhvd2V2ZXIgd2Ugd2FudGVkIHBpeGVscyBpbiB0aGUgcmFuZ2UgWzAsMV0gdG8gbWFwIGJhY2sgaW50byB0aGUgcmFuZ2UgWzAsMV0uCiovCnN0YXRpYyBpbmxpbmUgdm9pZCAKcmdiZV9SR0JFVG9GbG9hdChGSVJHQkYgKnJnYmYsIEJZVEUgcmdiZVs0XSkgewoJaWYgKHJnYmVbM10pIHsgICAvLyBub256ZXJvIHBpeGVsCgkJZmxvYXQgZiA9IChmbG9hdCkobGRleHAoMS4wLCByZ2JlWzNdIC0gKGludCkoMTI4KzgpKSk7CgkJcmdiZi0+cmVkICAgPSByZ2JlWzBdICogZjsKCQlyZ2JmLT5ncmVlbiA9IHJnYmVbMV0gKiBmOwoJCXJnYmYtPmJsdWUgID0gcmdiZVsyXSAqIGY7CgoJfQoJZWxzZSB7CgkJcmdiZi0+cmVkID0gcmdiZi0+Z3JlZW4gPSByZ2JmLT5ibHVlID0gMDsKCX0KfQoKLyoqCk1pbmltYWwgaGVhZGVyIHJlYWRpbmcuIE1vZGlmeSBpZiB5b3Ugd2FudCB0byBwYXJzZSBtb3JlIGluZm9ybWF0aW9uIAoqLwpzdGF0aWMgQk9PTCAKcmdiZV9SZWFkSGVhZGVyKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgdW5zaWduZWQgKndpZHRoLCB1bnNpZ25lZCAqaGVpZ2h0LCByZ2JlSGVhZGVySW5mbyAqaGVhZGVyX2luZm8pIHsKCWNoYXIgYnVmW0hEUl9NQVhMSU5FXTsKCWZsb2F0IHRlbXBmOwoJaW50IGk7CglCT09MIGJGb3JtYXRGb3VuZCA9IEZBTFNFOwoJQk9PTCBiSGVhZGVyRm91bmQgPSBGQUxTRTsKCgloZWFkZXJfaW5mby0+dmFsaWQgPSAwOwoJaGVhZGVyX2luZm8tPnByb2dyYW10eXBlWzBdID0gMDsKCWhlYWRlcl9pbmZvLT5nYW1tYSA9IDEuMDsKCWhlYWRlcl9pbmZvLT5leHBvc3VyZSA9IDEuMDsKCgkvLyBnZXQgdGhlIGZpcnN0IGxpbmUKCWlmKCFyZ2JlX0dldExpbmUoaW8sIGhhbmRsZSwgYnVmLCBIRFJfTUFYTElORSkpCgkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV9yZWFkX2Vycm9yLCBOVUxMKTsKCgkvLyBjaGVjayB0aGUgc2lnbmF0dXJlCgoJaWYgKChidWZbMF0gIT0gJyMnKXx8KGJ1ZlsxXSAhPSAnPycpKSB7CgkJLy8gaWYgeW91IGRvbid0IHdhbnQgdG8gcmVxdWlyZSB0aGUgbWFnaWMgdG9rZW4gdGhlbiBjb21tZW50IHRoZSBuZXh0IGxpbmUKCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX2Zvcm1hdF9lcnJvciwiYmFkIGluaXRpYWwgdG9rZW4iKTsKCX0KCWVsc2UgewoJCWhlYWRlcl9pbmZvLT52YWxpZCB8PSBSR0JFX1ZBTElEX1BST0dSQU1UWVBFOwoJCWZvcihpID0gMDsgaSA8IHNpemVvZihoZWFkZXJfaW5mby0+cHJvZ3JhbXR5cGUpIC0gMTsgaSsrKSB7CgkJCWlmKChidWZbaSsyXSA9PSAwKSB8fCBpc3NwYWNlKGJ1ZltpKzJdKSkKCQkJCWJyZWFrOwoJCQloZWFkZXJfaW5mby0+cHJvZ3JhbXR5cGVbaV0gPSBidWZbaSsyXTsKCQl9CgkJaGVhZGVyX2luZm8tPnByb2dyYW10eXBlW2ldID0gMDsKCX0KCglmb3IoOzspIHsKCQkvLyBnZXQgbmV4dCBsaW5lCgkJaWYoIXJnYmVfR2V0TGluZShpbywgaGFuZGxlLCBidWYsIEhEUl9NQVhMSU5FKSkKCQkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV9yZWFkX2Vycm9yLCBOVUxMKTsKCgkJaWYoKGJ1ZlswXSA9PSAwKSB8fCAoYnVmWzBdID09ICdcbicpKSB7CgkJCS8vIGVuZCBvZiBoZWFkZXIgc28gYnJlYWsgb3V0IG9mIGxvb3AKCQkJYkhlYWRlckZvdW5kID0gVFJVRTsKCQkJYnJlYWs7CgkJfQoJCWVsc2UgaWYoc3RyY21wKGJ1ZiwiRk9STUFUPTMyLWJpdF9ybGVfcmdiZVxuIikgPT0gMCkgewoJCQliRm9ybWF0Rm91bmQgPSBUUlVFOwoJCX0KCQllbHNlIGlmKHNzY2FuZihidWYsICJHQU1NQT0lZyIsICZ0ZW1wZikgPT0gMSkgewoJCQloZWFkZXJfaW5mby0+Z2FtbWEgPSB0ZW1wZjsKCQkJaGVhZGVyX2luZm8tPnZhbGlkIHw9IFJHQkVfVkFMSURfR0FNTUE7CgkJfQoJCWVsc2UgaWYoc3NjYW5mKGJ1ZiwiRVhQT1NVUkU9JWciLCZ0ZW1wZikgPT0gMSkgewoJCQloZWFkZXJfaW5mby0+ZXhwb3N1cmUgPSB0ZW1wZjsKCQkJaGVhZGVyX2luZm8tPnZhbGlkIHw9IFJHQkVfVkFMSURfRVhQT1NVUkU7CgkJfQoJCWVsc2UgaWYoKGJ1ZlswXSA9PSAnIycpICYmIChidWZbMV0gPT0gMHgyMCkpIHsKCQkJaGVhZGVyX2luZm8tPnZhbGlkIHw9IFJHQkVfVkFMSURfQ09NTUVOVDsKCQkJc3RyY3B5KGhlYWRlcl9pbmZvLT5jb21tZW50LCBidWYpOwoJCX0KCX0KCWlmKCFiSGVhZGVyRm91bmQgfHwgIWJGb3JtYXRGb3VuZCkgewoJCXJldHVybiByZ2JlX0Vycm9yKHJnYmVfZm9ybWF0X2Vycm9yLCAiaW52YWxpZCBoZWFkZXIiKTsKCX0KCgkvLyBnZXQgbmV4dCBsaW5lCglpZighcmdiZV9HZXRMaW5lKGlvLCBoYW5kbGUsIGJ1ZiwgSERSX01BWExJTkUpKQoJCXJldHVybiByZ2JlX0Vycm9yKHJnYmVfcmVhZF9lcnJvciwgTlVMTCk7CgoJLy8gZ2V0IHRoZSBpbWFnZSB3aWR0aCAmIGhlaWdodAoJaWYoc3NjYW5mKGJ1ZiwiLVkgJWQgK1ggJWQiLCBoZWlnaHQsIHdpZHRoKSA8IDIpIHsKCQlpZihzc2NhbmYoYnVmLCIrWCAlZCArWSAlZCIsIGhlaWdodCwgd2lkdGgpIDwgMikgewoJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX2Zvcm1hdF9lcnJvciwgIm1pc3NpbmcgaW1hZ2Ugc2l6ZSBzcGVjaWZpZXIiKTsKCQl9Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKgogZGVmYXVsdCBtaW5pbWFsIGhlYWRlci4gbW9kaWZ5IGlmIHlvdSB3YW50IG1vcmUgaW5mb3JtYXRpb24gaW4gaGVhZGVyIAoqLwpzdGF0aWMgQk9PTCAKcmdiZV9Xcml0ZUhlYWRlcihGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIHVuc2lnbmVkIHdpZHRoLCB1bnNpZ25lZCBoZWlnaHQsIHJnYmVIZWFkZXJJbmZvICppbmZvKSB7CgljaGFyIGJ1ZmZlcltIRFJfTUFYTElORV07CgoJY29uc3QgY2hhciAqcHJvZ3JhbXR5cGUgPSAiUkFESUFOQ0UiOwoKCWlmKGluZm8gJiYgKGluZm8tPnZhbGlkICYgUkdCRV9WQUxJRF9QUk9HUkFNVFlQRSkpIHsKCQlwcm9ncmFtdHlwZSA9IGluZm8tPnByb2dyYW10eXBlOwoJfQoJLy8gVGhlICM/IGlzIHRvIGlkZW50aWZ5IGZpbGUgdHlwZSwgdGhlIHByb2dyYW10eXBlIGlzIG9wdGlvbmFsCglzcHJpbnRmKGJ1ZmZlciwgIiM/JXNcbiIsIHByb2dyYW10eXBlKTsKCWlmKGlvLT53cml0ZV9wcm9jKGJ1ZmZlciwgMSwgKHVuc2lnbmVkIGludClzdHJsZW4oYnVmZmVyKSwgaGFuZGxlKSA8IDEpCgkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvciwgTlVMTCk7CglzcHJpbnRmKGJ1ZmZlciwgIiVzXG4iLCBpbmZvLT5jb21tZW50KTsKCWlmKGlvLT53cml0ZV9wcm9jKGJ1ZmZlciwgMSwgKHVuc2lnbmVkIGludClzdHJsZW4oYnVmZmVyKSwgaGFuZGxlKSA8IDEpCgkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvciwgTlVMTCk7CglzcHJpbnRmKGJ1ZmZlciwgIkZPUk1BVD0zMi1iaXRfcmxlX3JnYmVcbiIpOwoJaWYoaW8tPndyaXRlX3Byb2MoYnVmZmVyLCAxLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCBoYW5kbGUpIDwgMSkKCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3dyaXRlX2Vycm9yLCBOVUxMKTsKCWlmKGluZm8gJiYgKGluZm8tPnZhbGlkICYgUkdCRV9WQUxJRF9HQU1NQSkpIHsKCQlzcHJpbnRmKGJ1ZmZlciwgIkdBTU1BPSVnXG4iLCBpbmZvLT5nYW1tYSk7CgkJaWYoaW8tPndyaXRlX3Byb2MoYnVmZmVyLCAxLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCBoYW5kbGUpIDwgMSkKCQkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvciwgTlVMTCk7Cgl9CglpZihpbmZvICYmIChpbmZvLT52YWxpZCAmIFJHQkVfVkFMSURfRVhQT1NVUkUpKSB7CgkJc3ByaW50ZihidWZmZXIsIkVYUE9TVVJFPSVnXG4iLCBpbmZvLT5leHBvc3VyZSk7CgkJaWYoaW8tPndyaXRlX3Byb2MoYnVmZmVyLCAxLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCBoYW5kbGUpIDwgMSkKCQkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvciwgTlVMTCk7Cgl9CglzcHJpbnRmKGJ1ZmZlciwgIlxuLVkgJWQgK1ggJWRcbiIsIGhlaWdodCwgd2lkdGgpOwoJaWYoaW8tPndyaXRlX3Byb2MoYnVmZmVyLCAxLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCBoYW5kbGUpIDwgMSkKCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3dyaXRlX2Vycm9yLCBOVUxMKTsKCglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgCnJnYmVfUmVhZE1ldGFkYXRhKEZJQklUTUFQICpkaWIsIHJnYmVIZWFkZXJJbmZvICpoZWFkZXJfaW5mbykgewoJcmV0dXJuIFRSVUU7Cn0Kc3RhdGljIEJPT0wgCnJnYmVfV3JpdGVNZXRhZGF0YShGSUJJVE1BUCAqZGliLCByZ2JlSGVhZGVySW5mbyAqaGVhZGVyX2luZm8pIHsKCWhlYWRlcl9pbmZvLT5nYW1tYSA9IDE7CgloZWFkZXJfaW5mby0+dmFsaWQgfD0gUkdCRV9WQUxJRF9HQU1NQTsKCWhlYWRlcl9pbmZvLT5leHBvc3VyZSA9IDA7CgloZWFkZXJfaW5mby0+dmFsaWQgfD0gUkdCRV9WQUxJRF9FWFBPU1VSRTsKCglyZXR1cm4gVFJVRTsKfQoKLyoqIApTaW1wbGUgcmVhZCByb3V0aW5lLiBXaWxsIG5vdCBjb3JyZWN0bHkgaGFuZGxlIHJ1biBsZW5ndGggZW5jb2RpbmcgCiovCnN0YXRpYyBCT09MIApyZ2JlX1JlYWRQaXhlbHMoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIHVuc2lnbmVkIG51bXBpeGVscykgewogIEJZVEUgcmdiZVs0XTsKCiAgZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgbnVtcGl4ZWxzOyB4KyspIHsKCWlmKGlvLT5yZWFkX3Byb2MocmdiZSwgMSwgc2l6ZW9mKHJnYmUpLCBoYW5kbGUpIDwgMSkgewoJCXJldHVybiByZ2JlX0Vycm9yKHJnYmVfcmVhZF9lcnJvciwgTlVMTCk7Cgl9CglyZ2JlX1JHQkVUb0Zsb2F0KCZkYXRhW3hdLCByZ2JlKTsKICB9CgogIHJldHVybiBUUlVFOwp9CgovKioKIFNpbXBsZSB3cml0ZSByb3V0aW5lIHRoYXQgZG9lcyBub3QgdXNlIHJ1biBsZW5ndGggZW5jb2RpbmcuIAogVGhlc2Ugcm91dGluZXMgY2FuIGJlIG1hZGUgZmFzdGVyIGJ5IGFsbG9jYXRpbmcgYSBsYXJnZXIgYnVmZmVyIGFuZAogZnJlYWQtaW5nIGFuZCBmd3JpdGUtaW5nIHRoZSBkYXRhIGluIGxhcmdlciBjaHVua3MuCiovCnN0YXRpYyBCT09MIApyZ2JlX1dyaXRlUGl4ZWxzKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgRklSR0JGICpkYXRhLCB1bnNpZ25lZCBudW1waXhlbHMpIHsKICBCWVRFIHJnYmVbNF07CgogIGZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IG51bXBpeGVsczsgeCsrKSB7CgkgIHJnYmVfRmxvYXRUb1JHQkUocmdiZSwgJmRhdGFbeF0pOwoJICBpZihpby0+d3JpdGVfcHJvYyhyZ2JlLCBzaXplb2YocmdiZSksIDEsIGhhbmRsZSkgPCAxKQoJCSAgcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvciwgTlVMTCk7CiAgfQoKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgCnJnYmVfUmVhZFBpeGVsc19STEUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIGludCBzY2FubGluZV93aWR0aCwgdW5zaWduZWQgbnVtX3NjYW5saW5lcykgewoJQllURSByZ2JlWzRdLCAqc2NhbmxpbmVfYnVmZmVyLCAqcHRyLCAqcHRyX2VuZDsKCWludCBpLCBjb3VudDsKCUJZVEUgYnVmWzJdOwoJCglpZiAoKHNjYW5saW5lX3dpZHRoIDwgOCl8fChzY2FubGluZV93aWR0aCA+IDB4N2ZmZikpIHsKCQkvLyBydW4gbGVuZ3RoIGVuY29kaW5nIGlzIG5vdCBhbGxvd2VkIHNvIHJlYWQgZmxhdAoJCXJldHVybiByZ2JlX1JlYWRQaXhlbHMoaW8sIGhhbmRsZSwgZGF0YSwgc2NhbmxpbmVfd2lkdGggKiBudW1fc2NhbmxpbmVzKTsKCX0KCXNjYW5saW5lX2J1ZmZlciA9IE5VTEw7CgkvLyByZWFkIGluIGVhY2ggc3VjY2Vzc2l2ZSBzY2FubGluZSAKCXdoaWxlKG51bV9zY2FubGluZXMgPiAwKSB7CgkJaWYoaW8tPnJlYWRfcHJvYyhyZ2JlLCAxLCBzaXplb2YocmdiZSksIGhhbmRsZSkgPCAxKSB7CgkJCWZyZWUoc2NhbmxpbmVfYnVmZmVyKTsKCQkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV9yZWFkX2Vycm9yLE5VTEwpOwoJCX0KCQlpZigocmdiZVswXSAhPSAyKSB8fCAocmdiZVsxXSAhPSAyKSB8fCAocmdiZVsyXSAmIDB4ODApKSB7CgkJCS8vIHRoaXMgZmlsZSBpcyBub3QgcnVuIGxlbmd0aCBlbmNvZGVkCgkJCXJnYmVfUkdCRVRvRmxvYXQoZGF0YSwgcmdiZSk7CgkJCWRhdGEgKys7CgkJCWZyZWUoc2NhbmxpbmVfYnVmZmVyKTsKCQkJcmV0dXJuIHJnYmVfUmVhZFBpeGVscyhpbywgaGFuZGxlLCBkYXRhLCBzY2FubGluZV93aWR0aCAqIG51bV9zY2FubGluZXMgLSAxKTsKCQl9CgkJaWYoKCgoaW50KXJnYmVbMl0pIDw8IDggfCByZ2JlWzNdKSAhPSBzY2FubGluZV93aWR0aCkgewoJCQlmcmVlKHNjYW5saW5lX2J1ZmZlcik7CgkJCXJldHVybiByZ2JlX0Vycm9yKHJnYmVfZm9ybWF0X2Vycm9yLCJ3cm9uZyBzY2FubGluZSB3aWR0aCIpOwoJCX0KCQlpZihzY2FubGluZV9idWZmZXIgPT0gTlVMTCkgewoJCQlzY2FubGluZV9idWZmZXIgPSAoQllURSopbWFsbG9jKHNpemVvZihCWVRFKSAqIDQgKiBzY2FubGluZV93aWR0aCk7CgkJCWlmKHNjYW5saW5lX2J1ZmZlciA9PSBOVUxMKSB7CgkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX21lbW9yeV9lcnJvciwgInVuYWJsZSB0byBhbGxvY2F0ZSBidWZmZXIgc3BhY2UiKTsKCQkJfQoJCX0KCQkKCQlwdHIgPSAmc2NhbmxpbmVfYnVmZmVyWzBdOwoJCS8vIHJlYWQgZWFjaCBvZiB0aGUgZm91ciBjaGFubmVscyBmb3IgdGhlIHNjYW5saW5lIGludG8gdGhlIGJ1ZmZlcgoJCWZvcihpID0gMDsgaSA8IDQ7IGkrKykgewoJCQlwdHJfZW5kID0gJnNjYW5saW5lX2J1ZmZlclsoaSsxKSpzY2FubGluZV93aWR0aF07CgkJCXdoaWxlKHB0ciA8IHB0cl9lbmQpIHsKCQkJCWlmKGlvLT5yZWFkX3Byb2MoYnVmLCAxLCAyICogc2l6ZW9mKEJZVEUpLCBoYW5kbGUpIDwgMSkgewoJCQkJCWZyZWUoc2NhbmxpbmVfYnVmZmVyKTsKCQkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3JlYWRfZXJyb3IsIE5VTEwpOwoJCQkJfQoJCQkJaWYoYnVmWzBdID4gMTI4KSB7CgkJCQkJLy8gYSBydW4gb2YgdGhlIHNhbWUgdmFsdWUKCQkJCQljb3VudCA9IGJ1ZlswXSAtIDEyODsKCQkJCQlpZigoY291bnQgPT0gMCkgfHwgKGNvdW50ID4gcHRyX2VuZCAtIHB0cikpIHsKCQkJCQkJZnJlZShzY2FubGluZV9idWZmZXIpOwoJCQkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX2Zvcm1hdF9lcnJvciwgImJhZCBzY2FubGluZSBkYXRhIik7CgkJCQkJfQoJCQkJCXdoaWxlKGNvdW50LS0gPiAwKQoJCQkJCQkqcHRyKysgPSBidWZbMV07CgkJCQl9CgkJCQllbHNlIHsKCQkJCQkvLyBhIG5vbi1ydW4KCQkJCQljb3VudCA9IGJ1ZlswXTsKCQkJCQlpZigoY291bnQgPT0gMCkgfHwgKGNvdW50ID4gcHRyX2VuZCAtIHB0cikpIHsKCQkJCQkJZnJlZShzY2FubGluZV9idWZmZXIpOwoJCQkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX2Zvcm1hdF9lcnJvciwgImJhZCBzY2FubGluZSBkYXRhIik7CgkJCQkJfQoJCQkJCSpwdHIrKyA9IGJ1ZlsxXTsKCQkJCQlpZigtLWNvdW50ID4gMCkgewoJCQkJCQlpZihpby0+cmVhZF9wcm9jKHB0ciwgMSwgc2l6ZW9mKEJZVEUpICogY291bnQsIGhhbmRsZSkgPCAxKSB7CgkJCQkJCQlmcmVlKHNjYW5saW5lX2J1ZmZlcik7CgkJCQkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3JlYWRfZXJyb3IsIE5VTEwpOwoJCQkJCQl9CgkJCQkJCXB0ciArPSBjb3VudDsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJLy8gbm93IGNvbnZlcnQgZGF0YSBmcm9tIGJ1ZmZlciBpbnRvIGZsb2F0cwoJCWZvcihpID0gMDsgaSA8IHNjYW5saW5lX3dpZHRoOyBpKyspIHsKCQkJcmdiZVswXSA9IHNjYW5saW5lX2J1ZmZlcltpXTsKCQkJcmdiZVsxXSA9IHNjYW5saW5lX2J1ZmZlcltpK3NjYW5saW5lX3dpZHRoXTsKCQkJcmdiZVsyXSA9IHNjYW5saW5lX2J1ZmZlcltpKzIqc2NhbmxpbmVfd2lkdGhdOwoJCQlyZ2JlWzNdID0gc2NhbmxpbmVfYnVmZmVyW2krMypzY2FubGluZV93aWR0aF07CgkJCXJnYmVfUkdCRVRvRmxvYXQoZGF0YSwgcmdiZSk7CgkJCWRhdGEgKys7CgkJfQoKCQludW1fc2NhbmxpbmVzLS07Cgl9CgoJZnJlZShzY2FubGluZV9idWZmZXIpOwoJCglyZXR1cm4gVFJVRTsKfQoKLyoqCiBUaGUgY29kZSBiZWxvdyBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIHJ1bi1sZW5ndGggZW5jb2RlZCBmaWxlcy4KIFJ1biBsZW5ndGggZW5jb2RpbmcgYWRkcyBjb25zaWRlcmFibGUgY29tcGxleGl0eSBidXQgZG9lcyAKIHNhdmUgc29tZSBzcGFjZS4gIEZvciBlYWNoIHNjYW5saW5lLCBlYWNoIGNoYW5uZWwgKHIsZyxiLGUpIGlzIAogZW5jb2RlZCBzZXBhcmF0ZWx5IGZvciBiZXR0ZXIgY29tcHJlc3Npb24uIAogQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgCnJnYmVfV3JpdGVCeXRlc19STEUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBCWVRFICpkYXRhLCBpbnQgbnVtYnl0ZXMpIHsKCXN0YXRpYyBjb25zdCBpbnQgTUlOUlVOTEVOR1RIID0gNDsKCWludCBjdXIsIGJlZ19ydW4sIHJ1bl9jb3VudCwgb2xkX3J1bl9jb3VudCwgbm9ucnVuX2NvdW50OwoJQllURSBidWZbMl07CgkKCWN1ciA9IDA7Cgl3aGlsZShjdXIgPCBudW1ieXRlcykgewoJCWJlZ19ydW4gPSBjdXI7CgkJLy8gZmluZCBuZXh0IHJ1biBvZiBsZW5ndGggYXQgbGVhc3QgNCBpZiBvbmUgZXhpc3RzIAoJCXJ1bl9jb3VudCA9IG9sZF9ydW5fY291bnQgPSAwOwoJCXdoaWxlKChydW5fY291bnQgPCBNSU5SVU5MRU5HVEgpICYmIChiZWdfcnVuIDwgbnVtYnl0ZXMpKSB7CgkJCWJlZ19ydW4gKz0gcnVuX2NvdW50OwoJCQlvbGRfcnVuX2NvdW50ID0gcnVuX2NvdW50OwoJCQlydW5fY291bnQgPSAxOwoJCQl3aGlsZSgoYmVnX3J1biArIHJ1bl9jb3VudCA8IG51bWJ5dGVzKSAmJiAocnVuX2NvdW50IDwgMTI3KSAmJiAoZGF0YVtiZWdfcnVuXSA9PSBkYXRhW2JlZ19ydW4gKyBydW5fY291bnRdKSkgewoJCQkJcnVuX2NvdW50Kys7CgkJCX0KCQl9CgkJLy8gaWYgZGF0YSBiZWZvcmUgbmV4dCBiaWcgcnVuIGlzIGEgc2hvcnQgcnVuIHRoZW4gd3JpdGUgaXQgYXMgc3VjaCAKCQlpZiAoKG9sZF9ydW5fY291bnQgPiAxKSYmKG9sZF9ydW5fY291bnQgPT0gYmVnX3J1biAtIGN1cikpIHsKCQkJYnVmWzBdID0gKEJZVEUpKDEyOCArIG9sZF9ydW5fY291bnQpOyAgIC8vIHdyaXRlIHNob3J0IHJ1bgoJCQlidWZbMV0gPSBkYXRhW2N1cl07CgkJCWlmKGlvLT53cml0ZV9wcm9jKGJ1ZiwgMiAqIHNpemVvZihCWVRFKSwgMSwgaGFuZGxlKSA8IDEpCgkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3dyaXRlX2Vycm9yLCBOVUxMKTsKCQkJY3VyID0gYmVnX3J1bjsKCQl9CgkJLy8gd3JpdGUgb3V0IGJ5dGVzIHVudGlsIHdlIHJlYWNoIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBydW4gCgkJd2hpbGUoY3VyIDwgYmVnX3J1bikgewoJCQlub25ydW5fY291bnQgPSBiZWdfcnVuIC0gY3VyOwoJCQlpZiAobm9ucnVuX2NvdW50ID4gMTI4KSAKCQkJCW5vbnJ1bl9jb3VudCA9IDEyODsKCQkJYnVmWzBdID0gKEJZVEUpbm9ucnVuX2NvdW50OwoJCQlpZihpby0+d3JpdGVfcHJvYyhidWYsIHNpemVvZihidWZbMF0pLCAxLCBoYW5kbGUpIDwgMSkKCQkJCXJldHVybiByZ2JlX0Vycm9yKHJnYmVfd3JpdGVfZXJyb3IsTlVMTCk7CgkJCWlmKGlvLT53cml0ZV9wcm9jKCZkYXRhW2N1cl0sIHNpemVvZihkYXRhWzBdKSAqIG5vbnJ1bl9jb3VudCwgMSwgaGFuZGxlKSA8IDEpCgkJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3dyaXRlX2Vycm9yLE5VTEwpOwoJCQljdXIgKz0gbm9ucnVuX2NvdW50OwoJCX0KCQkvLyB3cml0ZSBvdXQgbmV4dCBydW4gaWYgb25lIHdhcyBmb3VuZCAKCQlpZiAocnVuX2NvdW50ID49IE1JTlJVTkxFTkdUSCkgewoJCQlidWZbMF0gPSAoQllURSkoMTI4ICsgcnVuX2NvdW50KTsKCQkJYnVmWzFdID0gZGF0YVtiZWdfcnVuXTsKCQkJaWYoaW8tPndyaXRlX3Byb2MoYnVmLCBzaXplb2YoYnVmWzBdKSAqIDIsIDEsIGhhbmRsZSkgPCAxKQoJCQkJcmV0dXJuIHJnYmVfRXJyb3IocmdiZV93cml0ZV9lcnJvcixOVUxMKTsKCQkJY3VyICs9IHJ1bl9jb3VudDsKCQl9Cgl9CgkKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCAKcmdiZV9Xcml0ZVBpeGVsc19STEUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBGSVJHQkYgKmRhdGEsIHVuc2lnbmVkIHNjYW5saW5lX3dpZHRoLCB1bnNpZ25lZCBudW1fc2NhbmxpbmVzKSB7CglCWVRFIHJnYmVbNF07CglCWVRFICpidWZmZXI7CgkKCWlmICgoc2NhbmxpbmVfd2lkdGggPCA4KXx8KHNjYW5saW5lX3dpZHRoID4gMHg3ZmZmKSkgewoJCS8vIHJ1biBsZW5ndGggZW5jb2RpbmcgaXMgbm90IGFsbG93ZWQgc28gd3JpdGUgZmxhdAoJCXJldHVybiByZ2JlX1dyaXRlUGl4ZWxzKGlvLCBoYW5kbGUsIGRhdGEsIHNjYW5saW5lX3dpZHRoICogbnVtX3NjYW5saW5lcyk7Cgl9CglidWZmZXIgPSAoQllURSopbWFsbG9jKHNpemVvZihCWVRFKSAqIDQgKiBzY2FubGluZV93aWR0aCk7CglpZiAoYnVmZmVyID09IE5VTEwpIHsKCQkvLyBubyBidWZmZXIgc3BhY2Ugc28gd3JpdGUgZmxhdCAKCQlyZXR1cm4gcmdiZV9Xcml0ZVBpeGVscyhpbywgaGFuZGxlLCBkYXRhLCBzY2FubGluZV93aWR0aCAqIG51bV9zY2FubGluZXMpOwoJfQoJd2hpbGUobnVtX3NjYW5saW5lcy0tID4gMCkgewoJCXJnYmVbMF0gPSAoQllURSkyOwoJCXJnYmVbMV0gPSAoQllURSkyOwoJCXJnYmVbMl0gPSAoQllURSkoc2NhbmxpbmVfd2lkdGggPj4gOCk7CgkJcmdiZVszXSA9IChCWVRFKShzY2FubGluZV93aWR0aCAmIDB4RkYpOwoJCWlmKGlvLT53cml0ZV9wcm9jKHJnYmUsIHNpemVvZihyZ2JlKSwgMSwgaGFuZGxlKSA8IDEpIHsKCQkJZnJlZShidWZmZXIpOwoJCQlyZXR1cm4gcmdiZV9FcnJvcihyZ2JlX3dyaXRlX2Vycm9yLCBOVUxMKTsKCQl9CgkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgc2NhbmxpbmVfd2lkdGg7IHgrKykgewoJCQlyZ2JlX0Zsb2F0VG9SR0JFKHJnYmUsIGRhdGEpOwoJCQlidWZmZXJbeF0gPSByZ2JlWzBdOwoJCQlidWZmZXJbeCtzY2FubGluZV93aWR0aF0gPSByZ2JlWzFdOwoJCQlidWZmZXJbeCsyKnNjYW5saW5lX3dpZHRoXSA9IHJnYmVbMl07CgkJCWJ1ZmZlclt4KzMqc2NhbmxpbmVfd2lkdGhdID0gcmdiZVszXTsKCQkJZGF0YSArKzsKCQl9CgkJLy8gd3JpdGUgb3V0IGVhY2ggb2YgdGhlIGZvdXIgY2hhbm5lbHMgc2VwYXJhdGVseSBydW4gbGVuZ3RoIGVuY29kZWQKCQkvLyBmaXJzdCByZWQsIHRoZW4gZ3JlZW4sIHRoZW4gYmx1ZSwgdGhlbiBleHBvbmVudAoJCWZvcihpbnQgaSA9IDA7IGkgPCA0OyBpKyspIHsKCQkJQk9PTCBiT0sgPSByZ2JlX1dyaXRlQnl0ZXNfUkxFKGlvLCBoYW5kbGUsICZidWZmZXJbaSpzY2FubGluZV93aWR0aF0sIHNjYW5saW5lX3dpZHRoKTsKCQkJaWYoIWJPSykgewoJCQkJZnJlZShidWZmZXIpOwoJCQkJcmV0dXJuIGJPSzsKCQkJfQoJCX0KCX0KCWZyZWUoYnVmZmVyKTsKCQoJcmV0dXJuIFRSVUU7Cn0KCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUGx1Z2luIEltcGxlbWVudGF0aW9uCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkZvcm1hdCgpIHsKCXJldHVybiAiSERSIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRGVzY3JpcHRpb24oKSB7CglyZXR1cm4gIkhpZ2ggRHluYW1pYyBSYW5nZSBJbWFnZSI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkV4dGVuc2lvbigpIHsKCXJldHVybiAiaGRyIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKUmVnRXhwcigpIHsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2Uvdm5kLnJhZGlhbmNlIjsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClZhbGlkYXRlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJQllURSBoZHJfc2lnbmF0dXJlW10gPSB7ICcjJywgJz8nIH07CglCWVRFIHNpZ25hdHVyZVtdID0geyAwLCAwIH07CgoJaW8tPnJlYWRfcHJvYyhzaWduYXR1cmUsIDEsIDIsIGhhbmRsZSk7CgoJcmV0dXJuIChtZW1jbXAoaGRyX3NpZ25hdHVyZSwgc2lnbmF0dXJlLCAyKSA9PSAwKTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzRXhwb3J0RGVwdGgoaW50IGRlcHRoKSB7CglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OViAKU3VwcG9ydHNFeHBvcnRUeXBlKEZSRUVfSU1BR0VfVFlQRSB0eXBlKSB7CglyZXR1cm4gKHR5cGUgPT0gRklUX1JHQkYpID8gVFJVRSA6IEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU3VwcG9ydHNOb1BpeGVscygpIHsKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIEZJQklUTUFQICogRExMX0NBTExDT05WCkxvYWQoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgcGFnZSwgaW50IGZsYWdzLCB2b2lkICpkYXRhKSB7CglGSUJJVE1BUCAqZGliID0gTlVMTDsKCglpZighaGFuZGxlKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJQk9PTCBoZWFkZXJfb25seSA9IChmbGFncyAmIEZJRl9MT0FEX05PUElYRUxTKSA9PSBGSUZfTE9BRF9OT1BJWEVMUzsKCgl0cnkgewoKCQlyZ2JlSGVhZGVySW5mbyBoZWFkZXJfaW5mbzsKCQl1bnNpZ25lZCB3aWR0aCwgaGVpZ2h0OwoKCQkvLyBSZWFkIHRoZSBoZWFkZXIKCQlpZihyZ2JlX1JlYWRIZWFkZXIoaW8sIGhhbmRsZSwgJndpZHRoLCAmaGVpZ2h0LCAmaGVhZGVyX2luZm8pID09IEZBTFNFKSB7CgkJCXJldHVybiBOVUxMOwoJCX0KCgkJLy8gYWxsb2NhdGUgYSBSR0JGIGltYWdlCgkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyVChoZWFkZXJfb25seSwgRklUX1JHQkYsIHdpZHRoLCBoZWlnaHQpOwoJCWlmKCFkaWIpIHsKCQkJdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCQl9CgoJCS8vIHNldCB0aGUgbWV0YWRhdGEgYXMgY29tbWVudHMKCQlyZ2JlX1JlYWRNZXRhZGF0YShkaWIsICZoZWFkZXJfaW5mbyk7CgoJCWlmKGhlYWRlcl9vbmx5KSB7CgkJCS8vIGhlYWRlciBvbmx5IG1vZGUKCQkJcmV0dXJuIGRpYjsKCQl9CgoJCS8vIHJlYWQgdGhlIGltYWdlIHBpeGVscyBhbmQgZmlsbCB0aGUgZGliCgkJCgkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJRklSR0JGICpzY2FubGluZSA9IChGSVJHQkYqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIDEgLSB5KTsKCQkJaWYoIXJnYmVfUmVhZFBpeGVsc19STEUoaW8sIGhhbmRsZSwgc2NhbmxpbmUsIHdpZHRoLCAxKSkgewoJCQkJRnJlZUltYWdlX1VubG9hZChkaWIpOwoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQl9CgoJfQoJY2F0Y2goY29uc3QgY2hhciAqdGV4dCkgewoJCWlmKGRpYiAhPSBOVUxMKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCQl9CgkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCB0ZXh0KTsKCX0KCglyZXR1cm4gZGliOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU2F2ZShGcmVlSW1hZ2VJTyAqaW8sIEZJQklUTUFQICpkaWIsIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCWlmKCFkaWIpIHJldHVybiBGQUxTRTsKCglGUkVFX0lNQUdFX1RZUEUgc3JjX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CglpZihzcmNfdHlwZSAhPSBGSVRfUkdCRikgewoJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgIkZSRUVfSU1BR0VfVFlQRTogVW5hYmxlIHRvIGNvbnZlcnQgZnJvbSB0eXBlICVkIHRvIHR5cGUgJWQuXG4gTm8gc3VjaCBjb252ZXJzaW9uIGV4aXN0cy4iLCBzcmNfdHlwZSwgRklUX1JHQkYpOwoJCXJldHVybiBGQUxTRTsKCX0KCgl1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCgkvLyB3cml0ZSB0aGUgaGVhZGVyCgoJcmdiZUhlYWRlckluZm8gaGVhZGVyX2luZm87CgltZW1zZXQoJmhlYWRlcl9pbmZvLCAwLCBzaXplb2YocmdiZUhlYWRlckluZm8pKTsKCS8vIGZpbGwgdGhlIGhlYWRlciB3aXRoIGNvcnJlY3QgZ2FtbWEgYW5kIGV4cG9zdXJlCglyZ2JlX1dyaXRlTWV0YWRhdGEoZGliLCAmaGVhZGVyX2luZm8pOwoJLy8gZmlsbCBhIGNvbW1lbnQKCXNwcmludGYoaGVhZGVyX2luZm8uY29tbWVudCwgIiMgTWFkZSB3aXRoIEZyZWVJbWFnZSAlcyIsIEZyZWVJbWFnZV9HZXRWZXJzaW9uKCkpOwoJaWYoIXJnYmVfV3JpdGVIZWFkZXIoaW8sIGhhbmRsZSwgd2lkdGgsIGhlaWdodCwgJmhlYWRlcl9pbmZvKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCgkvLyB3cml0ZSBlYWNoIHNjYW5saW5lCgoJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQlGSVJHQkYgKnNjYW5saW5lID0gKEZJUkdCRiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoJCWlmKCFyZ2JlX1dyaXRlUGl4ZWxzX1JMRShpbywgaGFuZGxlLCBzY2FubGluZSwgd2lkdGgsIDEpKSB7CgkJCXJldHVybiBGQUxTRTsKCQl9Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gICBJbml0Ci8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnZvaWQgRExMX0NBTExDT05WCkluaXRIRFIoUGx1Z2luICpwbHVnaW4sIGludCBmb3JtYXRfaWQpIHsKCXNfZm9ybWF0X2lkID0gZm9ybWF0X2lkOwoKCXBsdWdpbi0+Zm9ybWF0X3Byb2MgPSBGb3JtYXQ7CglwbHVnaW4tPmRlc2NyaXB0aW9uX3Byb2MgPSBEZXNjcmlwdGlvbjsKCXBsdWdpbi0+ZXh0ZW5zaW9uX3Byb2MgPSBFeHRlbnNpb247CglwbHVnaW4tPnJlZ2V4cHJfcHJvYyA9IFJlZ0V4cHI7CglwbHVnaW4tPm9wZW5fcHJvYyA9IE5VTEw7CglwbHVnaW4tPmNsb3NlX3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5wYWdlY291bnRfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnBhZ2VjYXBhYmlsaXR5X3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5sb2FkX3Byb2MgPSBMb2FkOwoJcGx1Z2luLT5zYXZlX3Byb2MgPSBTYXZlOwoJcGx1Z2luLT52YWxpZGF0ZV9wcm9jID0gVmFsaWRhdGU7CglwbHVnaW4tPm1pbWVfcHJvYyA9IE1pbWVUeXBlOwoJcGx1Z2luLT5zdXBwb3J0c19leHBvcnRfYnBwX3Byb2MgPSBTdXBwb3J0c0V4cG9ydERlcHRoOwoJcGx1Z2luLT5zdXBwb3J0c19leHBvcnRfdHlwZV9wcm9jID0gU3VwcG9ydHNFeHBvcnRUeXBlOwoJcGx1Z2luLT5zdXBwb3J0c19pY2NfcHJvZmlsZXNfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnN1cHBvcnRzX25vX3BpeGVsc19wcm9jID0gU3VwcG9ydHNOb1BpeGVsczsKfQo=