LyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDggVk13YXJlLCBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgogKgogKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKgogKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAqICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAqCiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiBWTXdhcmUsIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heSBiZQogKiAgIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQKICogICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIgogKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBWTVdBUkUsIElOQy4gT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUgogKiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUgogKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0gKICogREFNQUdFLgogKi8KCi8qIENvcHlyaWdodCAoYykgMjAwMy0yMDA3IERldGVybWluYSBDb3JwLiAqLwovKiBDb3B5cmlnaHQgKGMpIDIwMDItMjAwMyBNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5ICovCi8qIENvcHlyaWdodCAoYykgMjAwMiBIZXdsZXR0LVBhY2thcmQgQ29tcGFueSAqLwoKI2luY2x1ZGUgInN0ZGFmeC5oIgojaW5jbHVkZSAid2l6YXJkLmgiCiNpbmNsdWRlICJTaGVsbEludGVyZmFjZS5oIgojaW5jbHVkZSAiYXNzZXJ0LmgiCgojaW5jbHVkZSA8c2hsb2JqLmg+CiNpbmNsdWRlIDxvYmpiYXNlLmg+CiNpbmNsdWRlIDxzaGx3YXBpLmg+CgojaWZkZWYgX0RFQlVHCiN1bmRlZiBUSElTX0ZJTEUKc3RhdGljIGNoYXIgVEhJU19GSUxFW109X19GSUxFX187CiNkZWZpbmUgbmV3IERFQlVHX05FVwojZW5kaWYKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLy8gQ29uc3RydWN0aW9uL0Rlc3RydWN0aW9uCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCkNTaGVsbEludGVyZmFjZTo6Q1NoZWxsSW50ZXJmYWNlKCkKewoKfQoKQ1NoZWxsSW50ZXJmYWNlOjp+Q1NoZWxsSW50ZXJmYWNlKCkKewoKfQoKLypzdGF0aWMgKi9CT09MIENTaGVsbEludGVyZmFjZTo6bV9iSW5pdGlhbGl6ZWQgPSBGQUxTRTsKCi8qc3RhdGljICovdm9pZCBDU2hlbGxJbnRlcmZhY2U6OkluaXRpYWxpemUoKQp7CiAgICBpZiAobV9iSW5pdGlhbGl6ZWQpCiAgICAgICAgcmV0dXJuOwogICAgaW50IHJlcyA9IENvSW5pdGlhbGl6ZShOVUxMKTsKICAgIGFzc2VydChyZXMgPT0gU19PSyk7CiAgICBtX2JJbml0aWFsaXplZCA9IFRSVUU7Cn0KCi8qc3RhdGljICovdm9pZCBDU2hlbGxJbnRlcmZhY2U6OlVuaW5pdGlhbGl6ZSgpCnsKICAgIGlmICghbV9iSW5pdGlhbGl6ZWQpCiAgICAgICAgcmV0dXJuOwogICAgQ29VbmluaXRpYWxpemUoKTsKICAgIG1fYkluaXRpYWxpemVkID0gRkFMU0U7Cn0KCi8qc3RhdGljKi8gQk9PTCBDU2hlbGxJbnRlcmZhY2U6OkNyZWF0ZUxpbmtGaWxlKExQQ1RTVFIgcHN6U2hvcnRjdXRGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFRTVFIgcHN6TGluaywgTFBUU1RSIHBzekRlc2MpCnsKICAgIEhSRVNVTFQgaHJlczsKICAgIElTaGVsbExpbmsgKnBzbDsKCiAgICAvLyBDcmVhdGUgYW4gSVNoZWxsTGluayBvYmplY3QgYW5kIGdldCBhIHBvaW50ZXIgdG8gdGhlIElTaGVsbExpbmsKICAgIC8vIGludGVyZmFjZSAocmV0dXJuZWQgZnJvbSBDb0NyZWF0ZUluc3RhbmNlKS4KICAgIGhyZXMgPSBDb0NyZWF0ZUluc3RhbmNlIChDTFNJRF9TaGVsbExpbmssIE5VTEwsIENMU0NUWF9JTlBST0NfU0VSVkVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElJRF9JU2hlbGxMaW5rLCAodm9pZCAqKikmcHNsKTsKICAgIGlmIChTVUNDRUVERUQgKGhyZXMpKSB7CiAgICAgICAgSVBlcnNpc3RGaWxlICpwcGY7CgogICAgICAgIC8vIFF1ZXJ5IElTaGVsbExpbmsgZm9yIHRoZSBJUGVyc2lzdEZpbGUgaW50ZXJmYWNlIGZvcgogICAgICAgIC8vIHNhdmluZyB0aGUgc2hvcnRjdXQgaW4gcGVyc2lzdGVudCBzdG9yYWdlLgogICAgICAgIGhyZXMgPSBwc2wtPlF1ZXJ5SW50ZXJmYWNlIChJSURfSVBlcnNpc3RGaWxlLCAodm9pZCAqKikmcHBmKTsKICAgICAgICBpZiAoU1VDQ0VFREVEIChocmVzKSkgewogICAgICAgICAgICAvLyBTZXQgdGhlIHBhdGggdG8gdGhlIHNob3J0Y3V0IHRhcmdldC4KICAgICAgICAgICAgaHJlcyA9IHBzbC0+U2V0UGF0aCAocHN6U2hvcnRjdXRGaWxlKTsKCiAgICAgICAgICAgIGlmICghIFNVQ0NFRURFRCAoaHJlcykpCiAgICAgICAgICAgICAgICBBZnhNZXNzYWdlQm94IChfVCgiU2V0UGF0aCBmYWlsZWQhIikpOwoKICAgICAgICAgICAgLy8gU2V0IHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2hvcnRjdXQuCiAgICAgICAgICAgIGhyZXMgPSBwc2wtPlNldERlc2NyaXB0aW9uIChwc3pEZXNjKTsKCiAgICAgICAgICAgIGlmICghIFNVQ0NFRURFRCAoaHJlcykpCiAgICAgICAgICAgICAgICBBZnhNZXNzYWdlQm94IChfVCgiU2V0RGVzY3JpcHRpb24gZmFpbGVkISIpKTsKCiNpZm5kZWYgVU5JQ09ERQogICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc3RyaW5nIGNvbnNpc3RzIG9mIEFOU0kgY2hhcmFjdGVycy4KICAgICAgICAgICAgV09SRCB3c3ogW01BWF9QQVRIXTsgLy8gYnVmZmVyIGZvciBVbmljb2RlIHN0cmluZwogICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyIChDUF9BQ1AsIDAsIHBzekxpbmssIC0xLCB3c3osIE1BWF9QQVRIKTsKICAgICAgICAgICAgLy8gU2F2ZSB0aGUgc2hvcnRjdXQgdmlhIHRoZSBJUGVyc2lzdEZpbGU6OlNhdmUgbWVtYmVyIGZ1bmN0aW9uLgogICAgICAgICAgICBocmVzID0gcHBmLT5TYXZlICh3c3osIFRSVUUpOwojZWxzZQogICAgICAgICAgICAvLyBTYXZlIHRoZSBzaG9ydGN1dCB2aWEgdGhlIElQZXJzaXN0RmlsZTo6U2F2ZSBtZW1iZXIgZnVuY3Rpb24uCiAgICAgICAgICAgIGhyZXMgPSBwcGYtPlNhdmUgKHBzekxpbmssIFRSVUUpOwojZW5kaWYKCgogICAgICAgICAgICBpZiAoISBTVUNDRUVERUQgKGhyZXMpKQogICAgICAgICAgICAgICAgQWZ4TWVzc2FnZUJveCAoX1QoIlNhdmUgZmFpbGVkISIpKTsKCiAgICAgICAgICAgIC8vIFJlbGVhc2UgdGhlIHBvaW50ZXIgdG8gSVBlcnNpc3RGaWxlLgogICAgICAgICAgICBwcGYtPlJlbGVhc2UgKCk7CiAgICAgICAgfQogICAgICAgIC8vIFJlbGVhc2UgdGhlIHBvaW50ZXIgdG8gSVNoZWxsTGluay4KICAgICAgICBwc2wtPlJlbGVhc2UgKCk7CiAgICB9CiAgICByZXR1cm4gKFNVQ0NFRURFRChocmVzKSk7Cn0KCgovKnN0YXRpYyovIEJPT0wgQ1NoZWxsSW50ZXJmYWNlOjpDb3B5RGlyKExQQ1RTVFIgZnJvbSwgTFBDVFNUUiB0bywgSFdORCBod25kKQp7CiAgICBhc3NlcnQoX3Rjc2xlbihmcm9tKSA8IE1BWF9QQVRILTEpOwogICAgYXNzZXJ0KF90Y3NsZW4odG8pIDwgTUFYX1BBVEgtMSk7CiAgICAvLyBzdHJpbmdzIG11c3QgZW5kIHdpdGggcGFpciBvZiBudWxscwogICAgVENIQVIgbXlmcm9tW01BWF9QQVRIKzJdOwogICAgX3Rjc2NweShteWZyb20sIGZyb20pOwogICAgbXlmcm9tW190Y3NsZW4obXlmcm9tKSsxXSA9IF9UKCdcMCcpOwogICAgVENIQVIgbXl0b1tNQVhfUEFUSCsyXTsKICAgIF90Y3NjcHkobXl0bywgdG8pOwogICAgbXl0b1tfdGNzbGVuKG15dG8pKzFdID0gX1QoJ1wwJyk7CiAgICBTSEZJTEVPUFNUUlVDVCBmaWxlb3A7CiAgICBmaWxlb3AuaHduZCA9IGh3bmQ7CiAgICBmaWxlb3Aud0Z1bmMgPSBGT19DT1BZOwogICAgZmlsZW9wLnBGcm9tID0gbXlmcm9tOwogICAgZmlsZW9wLnBUbyA9IG15dG87CiAgICBmaWxlb3AuZkZsYWdzID0gRk9GX05PQ09ORklSTU1LRElSIHwgRk9GX05PQ09ORklSTUFUSU9OIHwgRk9GX1NJTEVOVDsKICAgIGludCByZXMgPSBTSEZpbGVPcGVyYXRpb24oJmZpbGVvcCk7CiAgICByZXR1cm4gKHJlcyA9PSAwKTsKfQoKLypzdGF0aWMqLyBCT09MIENTaGVsbEludGVyZmFjZTo6RGVsZXRlRmlsZShMUENUU1RSIG5hbWUsIEhXTkQgaHduZCkKewogICAgYXNzZXJ0KF90Y3NsZW4obmFtZSkgPCBNQVhfUEFUSC0xKTsKICAgIC8vIHN0cmluZyBtdXN0IGVuZCB3aXRoIHBhaXIgb2YgbnVsbHMKICAgIFRDSEFSIG15bmFtZVtNQVhfUEFUSCsyXTsKICAgIF90Y3NjcHkobXluYW1lLCBuYW1lKTsKICAgIG15bmFtZVtfdGNzbGVuKG15bmFtZSkrMV0gPSBfVCgnXDAnKTsKICAgIFNIRklMRU9QU1RSVUNUIGZpbGVvcDsKICAgIGZpbGVvcC5od25kID0gaHduZDsKICAgIGZpbGVvcC53RnVuYyA9IEZPX0RFTEVURTsKICAgIGZpbGVvcC5wRnJvbSA9IG15bmFtZTsKICAgIGZpbGVvcC5wVG8gPSBOVUxMOwogICAgZmlsZW9wLmZGbGFncyA9IEZPRl9BTExPV1VORE8gfCBGT0ZfTk9DT05GSVJNQVRJT04gfCBGT0ZfU0lMRU5UOwogICAgaW50IHJlcyA9IFNIRmlsZU9wZXJhdGlvbigmZmlsZW9wKTsKICAgIHJldHVybiAocmVzID09IDApOwp9CgoKI2lmIDAKLyogRnJvbSBNU0ROJ3MgTUZDIHNhbXBsZToKICAgIlNIT1JUQ1VUOiBBIFNhbXBsZVRoYXQgTWFuaXB1bGF0ZXMgU2hvcnRjdXRzIgogICBleGNlcHQgdGhhdCBzYW1wbGUgaGFkIGFuc2kgc3RyaW5ncwoqLwoKSFJFU1VMVCBDcmVhdGVTaG9ydEN1dDo6Q3JlYXRlSXQgKExQQ1NUUiBwc3pTaG9ydGN1dEZpbGUsIExQU1RSIHBzekxpbmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBwc3pEZXNjKQp7CiAgICBIUkVTVUxUIGhyZXM7CiAgICBJU2hlbGxMaW5rICpwc2w7CgogICAgLy8gQ3JlYXRlIGFuIElTaGVsbExpbmsgb2JqZWN0IGFuZCBnZXQgYSBwb2ludGVyIHRvIHRoZSBJU2hlbGxMaW5rCiAgICAvLyBpbnRlcmZhY2UgKHJldHVybmVkIGZyb20gQ29DcmVhdGVJbnN0YW5jZSkuCiAgICBocmVzID0gQ29DcmVhdGVJbnN0YW5jZSAoQ0xTSURfU2hlbGxMaW5rLCBOVUxMLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJSURfSVNoZWxsTGluaywgKHZvaWQgKiopJnBzbCk7CiAgICBpZiAoU1VDQ0VFREVEIChocmVzKSkgewogICAgICAgIElQZXJzaXN0RmlsZSAqcHBmOwoKICAgICAgICAvLyBRdWVyeSBJU2hlbGxMaW5rIGZvciB0aGUgSVBlcnNpc3RGaWxlIGludGVyZmFjZSBmb3IKICAgICAgICAvLyBzYXZpbmcgdGhlIHNob3J0Y3V0IGluIHBlcnNpc3RlbnQgc3RvcmFnZS4KICAgICAgICBocmVzID0gcHNsLT5RdWVyeUludGVyZmFjZSAoSUlEX0lQZXJzaXN0RmlsZSwgKHZvaWQgKiopJnBwZik7CiAgICAgICAgaWYgKFNVQ0NFRURFRCAoaHJlcykpIHsKICAgICAgICAgICAgV09SRCB3c3ogW01BWF9QQVRIXTsgLy8gYnVmZmVyIGZvciBVbmljb2RlIHN0cmluZwoKICAgICAgICAgICAgLy8gU2V0IHRoZSBwYXRoIHRvIHRoZSBzaG9ydGN1dCB0YXJnZXQuCiAgICAgICAgICAgIGhyZXMgPSBwc2wtPlNldFBhdGggKHBzelNob3J0Y3V0RmlsZSk7CgogICAgICAgICAgICBpZiAoISBTVUNDRUVERUQgKGhyZXMpKQogICAgICAgICAgICAgICAgQWZ4TWVzc2FnZUJveCAoX1QoIlNldFBhdGggZmFpbGVkISIpKTsKCiAgICAgICAgICAgIC8vIFNldCB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHNob3J0Y3V0LgogICAgICAgICAgICBocmVzID0gcHNsLT5TZXREZXNjcmlwdGlvbiAocHN6RGVzYyk7CgogICAgICAgICAgICBpZiAoISBTVUNDRUVERUQgKGhyZXMpKQogICAgICAgICAgICAgICAgQWZ4TWVzc2FnZUJveCAoX1QoIlNldERlc2NyaXB0aW9uIGZhaWxlZCEiKSk7CgogICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc3RyaW5nIGNvbnNpc3RzIG9mIEFOU0kgY2hhcmFjdGVycy4KICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhciAoQ1BfQUNQLCAwLCBwc3pMaW5rLCAtMSwgd3N6LCBNQVhfUEFUSCk7CgogICAgICAgICAgICAvLyBTYXZlIHRoZSBzaG9ydGN1dCB2aWEgdGhlIElQZXJzaXN0RmlsZTo6U2F2ZSBtZW1iZXIgZnVuY3Rpb24uCiAgICAgICAgICAgIGhyZXMgPSBwcGYtPlNhdmUgKHdzeiwgVFJVRSk7CgogICAgICAgICAgICBpZiAoISBTVUNDRUVERUQgKGhyZXMpKQogICAgICAgICAgICAgICAgQWZ4TWVzc2FnZUJveCAok1NhdmUgZmFpbGVkIZQpOwoKICAgICAgICAgICAgLy8gUmVsZWFzZSB0aGUgcG9pbnRlciB0byBJUGVyc2lzdEZpbGUuCiAgICAgICAgICAgIHBwZi0+UmVsZWFzZSAoKTsKICAgICAgICB9CiAgICAgICAgLy8gUmVsZWFzZSB0aGUgcG9pbnRlciB0byBJU2hlbGxMaW5rLgogICAgICAgIHBzbC0+UmVsZWFzZSAoKTsKICAgIH0KICAgIHJldHVybiBocmVzOwp9CiNlbmRpZgo=