LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2ludmVyLmgiCiNpbmNsdWRlICJ3aW5uZXR3ay5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgImV4ZGlzcC5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJzaGx3YXBpLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAibXNodG1oc3QuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKTsKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBEV09SRCBTSExXQVBJX1RocmVhZFJlZl9pbmRleDsKCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZShJVW5rbm93biosUkVGR1VJRCxSRUZJSUQsTFBWT0lEKik7CkhSRVNVTFQgV0lOQVBJIFNISW52b2tlQ29tbWFuZChIV05ELElTaGVsbEZvbGRlciosTFBDSVRFTUlETElTVCxCT09MKTsKQk9PTCAgICBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUixEV09SRCk7CgovKgogTk9URVM6IE1vc3QgZnVuY3Rpb25zIGV4cG9ydGVkIGJ5IG9yZGluYWwgc2VlbSB0byBiZSBzdXBlcmZsdW91cy4KIFRoZSByZWFzb24gZm9yIHRoZXNlIGZ1bmN0aW9ucyB0byBiZSB0aGVyZSBpcyB0byBwcm92aWRlIGEgd3JhcHBlcgogZm9yIHVuaWNvZGUgZnVuY3Rpb25zIHRvIHByb3ZpZGUgdGhlc2UgZnVuY3Rpb25zIG9uIHN5c3RlbXMgd2l0aG91dAogdW5pY29kZSBmdW5jdGlvbnMgZWcuIHdpbjk1L3dpbjk4LiBTaW5jZSB3ZSBoYXZlIHN1Y2ggZnVuY3Rpb25zIHdlIGp1c3QKIGNhbGwgdGhlc2UuIElmIHJ1bm5pbmcgV2luZSB3aXRoIG5hdGl2ZSBETExzLCBzb21lIGxhdGUgYm91bmQgY2FsbHMgbWF5CiBmYWlsLiBIb3dldmVyLCBpdCBpcyBiZXR0ZXIgdG8gaW1wbGVtZW50IHRoZSBmdW5jdGlvbnMgaW4gdGhlIGZvcndhcmQgRExMCiBhbmQgcmVjb21tZW5kIHRoZSBidWlsdGluIHJhdGhlciB0aGFuIHJlaW1wbGVtZW50aW5nIHRoZSBjYWxscyBoZXJlIQoqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUKICoKICogSW50ZXJuYWwgaW1wbGVtZXRhdGlvbiBvZiBTSExXQVBJXzExLgogKi8Kc3RhdGljCkhBTkRMRSBXSU5BUEkgU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3RHN0UHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1NyY1Byb2NJZCwgRFdPUkQgZHdBY2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3T3B0aW9ucykKewogIEhBTkRMRSBoRHN0LCBoU3JjOwogIERXT1JEIGR3TXlQcm9jSWQgPSBHZXRDdXJyZW50UHJvY2Vzc0lkKCk7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVkLCVkLCUwOHgsJTA4eClcbiIsIGhTaGFyZWQsIGR3RHN0UHJvY0lkLCBkd1NyY1Byb2NJZCwKICAgICAgICBkd0FjY2VzcywgZHdPcHRpb25zKTsKCiAgLyogR2V0IGRlc3QgcHJvY2VzcyBoYW5kbGUgKi8KICBpZiAoZHdEc3RQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgIGhEc3QgPSBHZXRDdXJyZW50UHJvY2VzcygpOwogIGVsc2UKICAgIGhEc3QgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3RHN0UHJvY0lkKTsKCiAgaWYgKGhEc3QpCiAgewogICAgLyogR2V0IHNyYyBwcm9jZXNzIGhhbmRsZSAqLwogICAgaWYgKGR3U3JjUHJvY0lkID09IGR3TXlQcm9jSWQpCiAgICAgIGhTcmMgPSBHZXRDdXJyZW50UHJvY2VzcygpOwogICAgZWxzZQogICAgICBoU3JjID0gT3BlblByb2Nlc3MoUFJPQ0VTU19EVVBfSEFORExFLCAwLCBkd1NyY1Byb2NJZCk7CgogICAgaWYgKGhTcmMpCiAgICB7CiAgICAgIC8qIE1ha2UgaGFuZGxlIGF2YWlsYWJsZSB0byBkZXN0IHByb2Nlc3MgKi8KICAgICAgaWYgKCFEdXBsaWNhdGVIYW5kbGUoaERzdCwgaFNoYXJlZCwgaFNyYywgJmhSZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCAwLCBkd09wdGlvbnMgfCBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpKQogICAgICAgIGhSZXQgPSBOVUxMOwoKICAgICAgaWYgKGR3U3JjUHJvY0lkICE9IGR3TXlQcm9jSWQpCiAgICAgICAgQ2xvc2VIYW5kbGUoaFNyYyk7CiAgICB9CgogICAgaWYgKGR3RHN0UHJvY0lkICE9IGR3TXlQcm9jSWQpCiAgICAgIENsb3NlSGFuZGxlKGhEc3QpOwogIH0KCiAgVFJBQ0UoIlJldHVybmluZyBoYW5kbGUgJXBcbiIsIGhSZXQpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS43XQogKgogKiBDcmVhdGUgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkgYW5kIGluaXRpYWxpc2UgaXQgd2l0aCBkYXRhLgogKgogKiBQQVJBTVMKICogbHB2RGF0YSAgW0ldIFBvaW50ZXIgdG8gZGF0YSB0byB3cml0ZQogKiBkd1NpemUgICBbSV0gU2l6ZSBvZiBkYXRhCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBkYXRhCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBzaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBGYWlsdXJlOiBOVUxMCiAqCiAqIE5PVEVTCiAqIE9yZGluYWxzIDctMTEgcHJvdmlkZSBhIHNldCBvZiBjYWxscyB0byBjcmVhdGUgc2hhcmVkIG1lbW9yeSBiZXR3ZWVuIGEKICogZ3JvdXAgb2YgcHJvY2Vzc2VzLiBUaGUgc2hhcmVkIG1lbW9yeSBpcyB0cmVhdGVkIG9wYXF1ZWx5IGluIHRoYXQgaXRzIHNpemUKICogaXMgbm90IGV4cG9zZWQgdG8gY2xpZW50cyB3aG8gbWFwIGl0LiBUaGlzIGlzIGFjY29tcGxpc2hlZCBieSBzdG9yaW5nCiAqIHRoZSBzaXplIG9mIHRoZSBtYXAgYXMgdGhlIGZpcnN0IERXT1JEIG9mIG1hcHBlZCBkYXRhLCBhbmQgdGhlbiBvZmZzZXR0aW5nCiAqIHRoZSB2aWV3IHBvaW50ZXIgcmV0dXJuZWQgYnkgdGhpcyBzaXplLgogKgogKi8KSEFORExFIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQQ1ZPSUQgbHB2RGF0YSwgRFdPUkQgZHdTaXplLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoTWFwOwogIExQVk9JRCBwTWFwcGVkOwogIEhBTkRMRSBoUmV0ID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlZCwlZClcbiIsIGxwdkRhdGEsIGR3U2l6ZSwgZHdQcm9jSWQpOwoKICAvKiBDcmVhdGUgZmlsZSBtYXBwaW5nIG9mIHRoZSBjb3JyZWN0IGxlbmd0aCAqLwogIGhNYXAgPSBDcmVhdGVGaWxlTWFwcGluZ0EoSU5WQUxJRF9IQU5ETEVfVkFMVUUsIE5VTEwsIEZJTEVfTUFQX1JFQUQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd1NpemUgKyBzaXplb2YoZHdTaXplKSwgTlVMTCk7CiAgaWYgKCFoTWFwKQogICAgcmV0dXJuIGhSZXQ7CgogIC8qIEdldCBhIHZpZXcgaW4gb3VyIHByb2Nlc3MgYWRkcmVzcyBzcGFjZSAqLwogIHBNYXBwZWQgPSBNYXBWaWV3T2ZGaWxlKGhNYXAsIEZJTEVfTUFQX1JFQUQgfCBGSUxFX01BUF9XUklURSwgMCwgMCwgMCk7CgogIGlmIChwTWFwcGVkKQogIHsKICAgIC8qIFdyaXRlIHNpemUgb2YgZGF0YSwgZm9sbG93ZWQgYnkgdGhlIGRhdGEsIHRvIHRoZSB2aWV3ICovCiAgICAqKChEV09SRCopcE1hcHBlZCkgPSBkd1NpemU7CiAgICBpZiAobHB2RGF0YSkKICAgICAgbWVtY3B5KChjaGFyICopIHBNYXBwZWQgKyBzaXplb2YoZHdTaXplKSwgbHB2RGF0YSwgZHdTaXplKTsKCiAgICAvKiBSZWxlYXNlIHZpZXcuIEFsbCBmdXJ0aGVyIHZpZXdzIG1hcHBlZCB3aWxsIGJlIG9wYXF1ZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKHBNYXBwZWQpOwogICAgaFJldCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhNYXAsIGR3UHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwgRklMRV9NQVBfQUxMX0FDQ0VTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpOwogIH0KCiAgQ2xvc2VIYW5kbGUoaE1hcCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOF0KICoKICogR2V0IGEgcG9pbnRlciB0byBhIGJsb2NrIG9mIHNoYXJlZCBtZW1vcnkgZnJvbSBhIHNoYXJlZCBtZW1vcnkgaGFuZGxlLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBwb2ludGVyIHRvIHRoZSBzaGFyZWQgbWVtb3J5CiAqIEZhaWx1cmU6IE5VTEwKICoKICovClBWT0lEIFdJTkFQSSBTSExvY2tTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhEdXA7CiAgTFBWT0lEIHBNYXBwZWQ7CgogIFRSQUNFKCIoJXAgJWQpXG4iLCBoU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBoYW5kbGUgdG8gc2hhcmVkIG1lbW9yeSBmb3IgY3VycmVudCBwcm9jZXNzICovCiAgaER1cCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsIDApOwogIC8qIEdldCBWaWV3ICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoaER1cCwgRklMRV9NQVBfUkVBRCB8IEZJTEVfTUFQX1dSSVRFLCAwLCAwLCAwKTsKICBDbG9zZUhhbmRsZShoRHVwKTsKCiAgaWYgKHBNYXBwZWQpCiAgICByZXR1cm4gKGNoYXIgKikgcE1hcHBlZCArIHNpemVvZihEV09SRCk7IC8qIEhpZGUgc2l6ZSAqLwogIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjldCiAqCiAqIFJlbGVhc2UgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2Ygc2hhcmVkIG1lbW9yeS4KICoKICogUEFSQU1TCiAqIGxwVmlldyBbSV0gU2hhcmVkIG1lbW9yeSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogVFJVRQogKiBGYWlsdXJlOiBGQUxTRQogKgogKi8KQk9PTCBXSU5BUEkgU0hVbmxvY2tTaGFyZWQoTFBWT0lEIGxwVmlldykKewogIFRSQUNFKCIoJXApXG4iLCBscFZpZXcpOwogIHJldHVybiBVbm1hcFZpZXdPZkZpbGUoKGNoYXIgKikgbHBWaWV3IC0gc2l6ZW9mKERXT1JEKSk7IC8qIEluY2x1ZGUgc2l6ZSAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjEwXQogKgogKiBEZXN0cm95IGEgYmxvY2sgb2Ygc2hhcmFibGUgbWVtb3J5LgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogVFJVRQogKiBGYWlsdXJlOiBGQUxTRQogKgogKi8KQk9PTCBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoQ2xvc2U7CgogIFRSQUNFKCIoJXAgJWQpXG4iLCBoU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBhIGNvcHkgb2YgdGhlIGhhbmRsZSBmb3Igb3VyIHByb2Nlc3MsIGNsb3NpbmcgdGhlIHNvdXJjZSBoYW5kbGUgKi8KICBoQ2xvc2UgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd1Byb2NJZCwgR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsRFVQTElDQVRFX0NMT1NFX1NPVVJDRSk7CiAgLyogQ2xvc2UgbG9jYWwgY29weSAqLwogIHJldHVybiBDbG9zZUhhbmRsZShoQ2xvc2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgW1NITFdBUEkuMTFdCiAqCiAqIENvcHkgYSBzaGFyYWJsZSBtZW1vcnkgaGFuZGxlIGZyb20gb25lIHByb2Nlc3MgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgICAgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZSB0byBkdXBsaWNhdGUKICogZHdEc3RQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIHdhbnRpbmcgdGhlIGR1cGxpY2F0ZWQgaGFuZGxlCiAqIGR3U3JjUHJvY0lkIFtJXSBJRCBvZiB0aGUgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKiBkd0FjY2VzcyAgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBhY2Nlc3MKICogZHdPcHRpb25zICAgW0ldIERlc2lyZWQgRHVwbGljYXRlSGFuZGxlKCkgb3B0aW9ucwogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgaGFuZGxlIHN1aXRhYmxlIGZvciB1c2UgYnkgdGhlIGR3RHN0UHJvY0lkIHByb2Nlc3MuCiAqIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNITWFwSGFuZGxlKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd0RzdFByb2NJZCwgRFdPUkQgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdBY2Nlc3MsIERXT1JEIGR3T3B0aW9ucykKewogIEhBTkRMRSBoUmV0OwoKICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0FjY2VzcywgZHdPcHRpb25zKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjEzXQogKgogKiBDcmVhdGUgYW5kIHJlZ2lzdGVyIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgZm9yIGEgd2ViIGJyb3dzZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBCQyAgICAgIFtJXSBCaW5kaW5nIGNvbnRleHQKICogIGxwVW5rbm93biBbSV0gQW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBJV2ViQnJvd3NlckFwcCBpbnRlcmZhY2UKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIFRoZSBlbnVtZXJhdG9yIGlzIHN0b3JlZCBhcyBhIHByb3BlcnR5IG9mIHRoZSB3ZWIgYnJvd3Nlci4gSWYgaXQgZG9lcyBub3QKICogIHlldCBleGlzdCwgaXQgaXMgY3JlYXRlZCBhbmQgc2V0IGJlZm9yZSBiZWluZyByZWdpc3RlcmVkLgogKi8KSFJFU1VMVCBXSU5BUEkgUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVycyhMUEJDIGxwQkMsIElVbmtub3duICpscFVua25vd24pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9wZXJ0eVtdID0geyAneycsJ0QnLCcwJywnRicsJ0MnLCdBJywnNCcsJzInLCcwJywKICAgICAgJy0nLCdEJywnMycsJ0YnLCc1JywnLScsJzEnLCcxJywnQycsJ0YnLCAnLScsJ0InLCcyJywnMScsJzEnLCctJywnMCcsCiAgICAgICcwJywnQScsJ0EnLCcwJywnMCcsJzQnLCdBJywnRScsJzgnLCczJywnNycsJ30nLCdcMCcgfTsKICBCU1RSIHByb3BlcnR5OwogIElFbnVtRk9STUFURVRDKiBwSUVudW1Gb3JtYXRFdGMgPSBOVUxMOwogIFZBUklBTlRBUkcgdmFyOwogIEhSRVNVTFQgaFJldDsKICBJV2ViQnJvd3NlckFwcCogcEJyb3dzZXIgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCAlcClcbiIsIGxwQkMsIGxwVW5rbm93bik7CgogIC8qIEdldCBBbiBJV2ViQnJvd3NlckFwcCBpbnRlcmZhY2UgZnJvbSAgbHBVbmtub3duICovCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5U2VydmljZShscFVua25vd24sICZJSURfSVdlYkJyb3dzZXJBcHAsICZJSURfSVdlYkJyb3dzZXJBcHAsIChQVk9JRCkmcEJyb3dzZXIpOwogIGlmIChGQUlMRUQoaFJldCkgfHwgIXBCcm93c2VyKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CgogIFZfVlQoJnZhcikgPSBWVF9FTVBUWTsKCiAgLyogVGhlIHByb3BlcnR5IHdlIGdldCBpcyB0aGUgYnJvd3NlcnMgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICBwcm9wZXJ0eSA9IFN5c0FsbG9jU3RyaW5nKHN6UHJvcGVydHkpOwogIGhSZXQgPSBJV2ViQnJvd3NlckFwcF9HZXRQcm9wZXJ0eShwQnJvd3NlciwgcHJvcGVydHksICZ2YXIpOwogIFN5c0ZyZWVTdHJpbmcocHJvcGVydHkpOwogIGlmIChGQUlMRUQoaFJldCkpCiAgICByZXR1cm4gaFJldDsKCiAgaWYgKFZfVlQoJnZhcikgPT0gVlRfRU1QVFkpCiAgewogICAgLyogSXRlcmF0ZSB0aHJvdWdoIGFjY2VwdGVkIGRvY3VtZW50cyBhbmQgUmVnaXN0ZXJDbGlwQm9hcmRGb3JtYXRBKCkgdGhlbSAqLwogICAgY2hhciBzektleUJ1ZmZbMTI4XSwgc3pWYWx1ZUJ1ZmZbMTI4XTsKICAgIERXT1JEIGR3S2V5U2l6ZSwgZHdWYWx1ZVNpemUsIGR3UmV0ID0gMCwgZHdDb3VudCA9IDAsIGR3TnVtVmFsdWVzLCBkd1R5cGU7CiAgICBGT1JNQVRFVEMqIGZvcm1hdExpc3QsICpmb3JtYXQ7CiAgICBIS0VZIGhEb2NzOwoKICAgIFRSQUNFKCJSZWdpc3RlcmluZyBmb3JtYXRzIGFuZCBjcmVhdGluZyBJRW51bUZPUk1BVEVUQyBpbnN0YW5jZVxuIik7CgogICAgaWYgKCFSZWdPcGVuS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50IgogICAgICAgICAgICAgICAgICAgICAiVmVyc2lvblxcSW50ZXJuZXQgU2V0dGluZ3NcXEFjY2VwdGVkIERvY3VtZW50cyIsICZoRG9jcykpCiAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgLyogR2V0IGNvdW50IG9mIHZhbHVlcyBpbiBrZXkgKi8KICAgIHdoaWxlICghZHdSZXQpCiAgICB7CiAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsZHdDb3VudCxzektleUJ1ZmYsJmR3S2V5U2l6ZSwwLCZkd1R5cGUsMCwwKTsKICAgICAgZHdDb3VudCsrOwogICAgfQoKICAgIGR3TnVtVmFsdWVzID0gZHdDb3VudDsKCiAgICAvKiBOb3RlOiBkd0NvdW50ID0gbnVtYmVyIG9mIGl0ZW1zICsgMTsgVGhlIGV4dHJhIGl0ZW0gaXMgdGhlIGVuZCBub2RlICovCiAgICBmb3JtYXQgPSBmb3JtYXRMaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGR3Q291bnQgKiBzaXplb2YoRk9STUFURVRDKSk7CiAgICBpZiAoIWZvcm1hdExpc3QpCiAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGlmIChkd051bVZhbHVlcyA+IDEpCiAgICB7CiAgICAgIGR3UmV0ID0gMDsKICAgICAgZHdDb3VudCA9IDA7CgogICAgICBkd051bVZhbHVlcy0tOwoKICAgICAgLyogUmVnaXN0ZXIgY2xpcGJvYXJkIGZvcm1hdHMgZm9yIHRoZSB2YWx1ZXMgYW5kIHBvcHVsYXRlIGZvcm1hdCBsaXN0ICovCiAgICAgIHdoaWxlKCFkd1JldCAmJiBkd0NvdW50IDwgZHdOdW1WYWx1ZXMpCiAgICAgIHsKICAgICAgICBkd0tleVNpemUgPSBzaXplb2Yoc3pLZXlCdWZmKTsKICAgICAgICBkd1ZhbHVlU2l6ZSA9IHNpemVvZihzelZhbHVlQnVmZik7CiAgICAgICAgZHdSZXQgPSBSZWdFbnVtVmFsdWVBKGhEb2NzLCBkd0NvdW50LCBzektleUJ1ZmYsICZkd0tleVNpemUsIDAsICZkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQQllURSlzelZhbHVlQnVmZiwgJmR3VmFsdWVTaXplKTsKICAgICAgICBpZiAoIWR3UmV0KQogICAgICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAgICAgZm9ybWF0LT5jZkZvcm1hdCA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0QShzelZhbHVlQnVmZik7CiAgICAgICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgICAgIGZvcm1hdC0+ZHdBc3BlY3QgPSAxOwogICAgICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgICAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgICAgIGZvcm1hdCsrOwogICAgICAgIGR3Q291bnQrKzsKICAgICAgfQogICAgfQoKICAgIC8qIFRlcm1pbmF0ZSB0aGUgKG1heWJlIGVtcHR5KSBsaXN0LCBsYXN0IGVudHJ5IGhhcyBhIGNmRm9ybWF0IG9mIDAgKi8KICAgIGZvcm1hdC0+Y2ZGb3JtYXQgPSAwOwogICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICBmb3JtYXQtPmxpbmRleCA9IDQ7CiAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgLyogQ3JlYXRlIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICAgIGhSZXQgPSBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yKGR3TnVtVmFsdWVzLCBmb3JtYXRMaXN0LCAmcElFbnVtRm9ybWF0RXRjKTsKCiAgICBpZiAoRkFJTEVEKGhSZXQpIHx8ICFwSUVudW1Gb3JtYXRFdGMpCiAgICAgIHJldHVybiBoUmV0OwoKICAgIC8qIFNldCBvdXIgZW51bWVyYXRvciBhcyB0aGUgYnJvd3NlcnMgcHJvcGVydHkgKi8KICAgIFZfVlQoJnZhcikgPSBWVF9VTktOT1dOOwogICAgVl9VTktOT1dOKCZ2YXIpID0gKElVbmtub3duKilwSUVudW1Gb3JtYXRFdGM7CgogICAgaFJldCA9IElXZWJCcm93c2VyQXBwX1B1dFByb3BlcnR5KHBCcm93c2VyLCAoQlNUUilzelByb3BlcnR5LCB2YXIpOwogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHsKICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElFbnVtRm9ybWF0RXRjKTsKICAgICAgIGdvdG8gUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVyc19FeGl0OwogICAgfQogIH0KCiAgaWYgKFZfVlQoJnZhcikgPT0gVlRfVU5LTk9XTikKICB7CiAgICAvKiBPdXIgdmFyaWFudCBpcyBob2xkaW5nIHRoZSBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogICAgSVVua25vd24qIHBJVW5rbm93biA9IFZfVU5LTk9XTigmdmFyKTsKICAgIElFbnVtRk9STUFURVRDKiBwQ2xvbmUgPSBOVUxMOwoKICAgIFRSQUNFKCJSZXRyaWV2ZWQgSUVudW1GT1JNQVRFVEMgcHJvcGVydHlcbiIpOwoKICAgIC8qIEdldCBhbiBJRW51bUZvcm1hdEV0YyBpbnRlcmZhY2UgZnJvbSB0aGUgdmFyaWFudHMgdmFsdWUgKi8KICAgIHBJRW51bUZvcm1hdEV0YyA9IE5VTEw7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElVbmtub3duLCAmSUlEX0lFbnVtRk9STUFURVRDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQVk9JRCkmcElFbnVtRm9ybWF0RXRjKTsKICAgIGlmICghaFJldCAmJiBwSUVudW1Gb3JtYXRFdGMpCiAgICB7CiAgICAgIC8qIENsb25lIGFuZCByZWdpc3RlciB0aGUgZW51bWVyYXRvciAqLwogICAgICBoUmV0ID0gSUVudW1GT1JNQVRFVENfQ2xvbmUocElFbnVtRm9ybWF0RXRjLCAmcENsb25lKTsKICAgICAgaWYgKCFoUmV0ICYmIHBDbG9uZSkKICAgICAgewogICAgICAgIFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcihscEJDLCBwQ2xvbmUsIDApOwoKICAgICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBDbG9uZSk7CiAgICAgIH0KCiAgICAgIC8qIFJlbGVhc2UgdGhlIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSAqLwogICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBJVW5rbm93bik7CiAgICB9CiAgICBJVW5rbm93bl9SZWxlYXNlKFZfVU5LTk9XTigmdmFyKSk7CiAgfQoKUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVyc19FeGl0OgogIElXZWJCcm93c2VyQXBwX1JlbGVhc2UocEJyb3dzZXIpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTVdCiAqCiAqIEdldCBFeHBsb3JlcnMgIkFjY2VwdExhbmd1YWdlIiBzZXR0aW5nLgogKgogKiBQQVJBTVMKICogIGxhbmdidWYgW09dIERlc3RpbmF0aW9uIGZvciBsYW5ndWFnZSBzdHJpbmcKICogIGJ1ZmxlbiAgW0ldIExlbmd0aCBvZiBsYW5nYnVmCiAqICAgICAgICAgIFswXSBTdWNjZXNzOiB1c2VkIGxlbmd0aCBvZiBsYW5nYnVmCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suICAgbGFuZ2J1ZiBpcyBzZXQgdG8gdGhlIGxhbmd1YWdlIHN0cmluZyBmb3VuZC4KICogIEZhaWx1cmU6IEVfRkFJTCwgSWYgYW55IGFyZ3VtZW50cyBhcmUgaW52YWxpZCwgZXJyb3Igb2NjdXJyZWQsIG9yIEV4cGxvcmVyCiAqICAgICAgICAgICBkb2VzIG5vdCBjb250YWluIHRoZSBzZXR0aW5nLgogKiAgICAgICAgICAgRV9JTlZBTElEQVJHLCBJZiB0aGUgYnVmZmVyIGlzIG5vdCBiaWcgZW5vdWdoCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNXKCBMUFdTVFIgbGFuZ2J1ZiwgTFBEV09SRCBidWZsZW4pCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzemtleVdbXSA9IHsKCSdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKCSdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsCgknSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLCcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCgknSScsJ24nLCd0JywnZScsJ3InLCduJywnYScsJ3QnLCdpJywnbycsJ24nLCdhJywnbCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgdmFsdWVXW10gPSB7CgknQScsJ2MnLCdjJywnZScsJ3AnLCd0JywnTCcsJ2EnLCduJywnZycsJ3UnLCdhJywnZycsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGVudXNXW10gPSB7J2UnLCduJywnLScsJ3UnLCdzJywwfTsKICAgIERXT1JEIG15c3RybGVuLCBteXR5cGU7CiAgICBIS0VZIG15a2V5OwogICAgSFJFU1VMVCByZXR2YWw7CiAgICBMQ0lEIG15bGNpZDsKICAgIFdDSEFSICpteXN0cjsKCiAgICBpZighbGFuZ2J1ZiB8fCAhYnVmbGVuIHx8ICEqYnVmbGVuKQoJcmV0dXJuIEVfRkFJTDsKCiAgICBteXN0cmxlbiA9ICgqYnVmbGVuID4gMjApID8gKmJ1ZmxlbiA6IDIwIDsKICAgIG15c3RyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikgKiBteXN0cmxlbik7CiAgICBSZWdPcGVuS2V5VyhIS0VZX0NVUlJFTlRfVVNFUiwgc3prZXlXLCAmbXlrZXkpOwogICAgaWYoUmVnUXVlcnlWYWx1ZUV4VyhteWtleSwgdmFsdWVXLCAwLCAmbXl0eXBlLCAoUEJZVEUpbXlzdHIsICZteXN0cmxlbikpIHsKICAgICAgICAvKiBEaWQgbm90IGZpbmQgdmFsdWUgKi8KICAgICAgICBteWxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgICAgICAvKiBzb21laG93IHRoZSBteWxjaWQgdHJhbnNsYXRlcyBpbnRvICJlbi11cyIKICAgICAgICAgKiAgdGhpcyBpcyBzaW1pbGFyIHRvICJMT0NBTEVfU0FCQlJFVkxBTkdOQU1FIgogICAgICAgICAqICB3aGljaCBjb3VsZCBiZSBnb3R0ZW4gdmlhIEdldExvY2FsZUluZm8uCiAgICAgICAgICogIFRoZSBvbmx5IHByb2JsZW0gaXMgTE9DQUxFX1NBQkJSRVZMQU5HVUFHRSIgaXMKICAgICAgICAgKiAgYSAzIGNoYXIgc3RyaW5nIChmaXJzdCAyIGFyZSBjb3VudHJ5IGNvZGUgYW5kIHRoaXJkIGlzCiAgICAgICAgICogIGxldHRlciBmb3IgInN1Ymxhbmd1YWdlIiwgd2hpY2ggZG9lcyBub3QgY29tZSBjbG9zZSB0bwogICAgICAgICAqICAiZW4tdXMiCiAgICAgICAgICovCiAgICAgICAgbHN0cmNweVcobXlzdHIsIGVudXNXKTsKICAgICAgICBteXN0cmxlbiA9IGxzdHJsZW5XKG15c3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogaGFuZGxlIHJldHVybmVkIHN0cmluZyAqLwogICAgICAgIEZJWE1FKCJtaXNzaW5nIGNvZGVcbiIpOwogICAgfQogICAgbWVtY3B5KCBsYW5nYnVmLCBteXN0ciwgbWluKCpidWZsZW4sc3RybGVuVyhteXN0cikrMSkqc2l6ZW9mKFdDSEFSKSApOwoKICAgIGlmKCpidWZsZW4gPiBzdHJsZW5XKG15c3RyKSkgewoJKmJ1ZmxlbiA9IHN0cmxlblcobXlzdHIpOwoJcmV0dmFsID0gU19PSzsKICAgIH0gZWxzZSB7CgkqYnVmbGVuID0gMDsKCXJldHZhbCA9IEVfSU5WQUxJREFSRzsKCVNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KG15a2V5KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG15c3RyKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNF0KICoKICogQXNjaWkgdmVyc2lvbiBvZiBHZXRBY2NlcHRMYW5ndWFnZXNXLgogKi8KSFJFU1VMVCBXSU5BUEkgR2V0QWNjZXB0TGFuZ3VhZ2VzQSggTFBTVFIgbGFuZ2J1ZiwgTFBEV09SRCBidWZsZW4pCnsKICAgIFdDSEFSICpsYW5nYnVmVzsKICAgIERXT1JEIGJ1ZmxlblcsIGNvbnZsZW47CiAgICBIUkVTVUxUIHJldHZhbDsKCiAgICBpZighbGFuZ2J1ZiB8fCAhYnVmbGVuIHx8ICEqYnVmbGVuKSByZXR1cm4gRV9GQUlMOwoKICAgIGJ1ZmxlblcgPSAqYnVmbGVuOwogICAgbGFuZ2J1ZlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIGJ1ZmxlblcpOwogICAgcmV0dmFsID0gR2V0QWNjZXB0TGFuZ3VhZ2VzVyhsYW5nYnVmVywgJmJ1ZmxlblcpOwoKICAgIGlmIChyZXR2YWwgPT0gU19PSykKICAgIHsKICAgICAgICBjb252bGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGxhbmdidWZXLCAtMSwgbGFuZ2J1ZiwgKmJ1ZmxlbiwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICBlbHNlICAvKiBjb3B5IHBhcnRpYWwgc3RyaW5nIGFueXdheSAqLwogICAgewogICAgICAgIGNvbnZsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgbGFuZ2J1ZlcsICpidWZsZW4sIGxhbmdidWYsICpidWZsZW4sIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChjb252bGVuIDwgKmJ1ZmxlbikgbGFuZ2J1Zltjb252bGVuXSA9IDA7CiAgICB9CiAgICAqYnVmbGVuID0gYnVmbGVuVyA/IGNvbnZsZW4gOiAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxhbmdidWZXKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yM10KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCAgICAgW0ldIEdVSUQgdG8gY29udmVydAogKiAgbHBzekRlc3QgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNjaE1heCAgIFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJREEoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4WC0lMDRYLSUwNFgtJTAyWCUwMlgtJTAyWCUwMlglMDJYJTAyWCUwMlglMDJYfSIsCiAgICAgICAgICBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW4oeGd1aWQpICsgMTsKCiAgaWYgKGlMZW4gPiBjY2hNYXgpCiAgICByZXR1cm4gMDsKICBtZW1jcHkobHBzekRlc3QsIHhndWlkLCBpTGVuKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0XQogKgogKiBDb252ZXJ0IGEgR1VJRCB0byBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBndWlkIFtJXSBHVUlEIHRvIGNvbnZlcnQKICogIHN0ciAgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNtYXggW0ldIExlbmd0aCBvZiBvdXRwdXQgYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBjcmVhdGVkLgogKi8KSU5UIFdJTkFQSSBTSFN0cmluZ0Zyb21HVUlEVyhSRUZHVUlEIGd1aWQsIExQV1NUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIFdDSEFSIHhndWlkWzQwXTsKICBJTlQgaUxlbjsKICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6Rm9ybWF0W10gPSB7J3snLCclJywnMCcsJzgnLCdsJywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywKICAgICAgJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnLScsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAgICdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCd9JywwfTsKCiAgVFJBQ0UoIiglcywlcCwlZClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIGxwc3pEZXN0LCBjY2hNYXgpOwoKICBzcHJpbnRmVyh4Z3VpZCwgd3N6Rm9ybWF0LCBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW5XKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbipzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIHNwYWNlLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgc3BhY2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJTcGFjZVcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1NQQUNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMwXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGJsYW5rLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgYmxhbmssCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJCbGFua1coV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0JMQU5LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBwdW5jdHVhdGlvbi4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBwdW5jdHVhdGlvbiwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclB1bmN0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfUFVOQ1QpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzJdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBjb250cm9sIGNoYXJhY3RlciwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckNudHJsVyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfQ05UUkwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzNdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckRpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfRElHSVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzRdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgaGV4IGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgaGV4IGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyWERpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfWERJR0lUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1XQogKgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZTNFeFcoTFBXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgdHlwZSkKewogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMywgc3JjLCBjb3VudCwgdHlwZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTFdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGguCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIElOVCBsZW4pCnsKICAgIHJldHVybiBTdHJDbXBOQShscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUyXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTkNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIFN0ckNtcE5XKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTNdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGgsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBTdHJDbXBOSUEobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcE5JQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTklDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgRFdPUkQgbGVuKQp7CiAgICByZXR1cm4gU3RyQ21wTklXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTVdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gbHN0cmNtcEEobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTZdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIGxzdHJjbXBXKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU3XQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcElDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBsc3RyY21waUEobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNThdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBJQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gbHN0cmNtcGlXKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYwXQogKgogKiBHZXQgYW4gaWRlbnRpZmljYXRpb24gc3RyaW5nIGZvciB0aGUgT1MgYW5kIGV4cGxvcmVyLgogKgogKiBQQVJBTVMKICogIGxwc3pEZXN0ICBbT10gRGVzdGluYXRpb24gZm9yIElkIHN0cmluZwogKiAgZHdEZXN0TGVuIFtJXSBMZW5ndGggb2YgbHBzekRlc3QKICoKICogUkVUVVJOUwogKiAgVFJVRSwgIElmIHRoZSBzdHJpbmcgd2FzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5CiAqICBGQUxTRSwgT3RoZXJ3aXNlCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb0EoTFBTVFIgbHBzekRlc3QsIERXT1JEIGR3RGVzdExlbikKewogIFdDSEFSIGJ1ZmZbMjA4NF07CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKGxwc3pEZXN0ICYmIFNIQWJvdXRJbmZvVyhidWZmLCBkd0Rlc3RMZW4pKQogIHsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBidWZmLCAtMSwgbHBzekRlc3QsIGR3RGVzdExlbiwgTlVMTCwgTlVMTCk7CiAgICByZXR1cm4gVFJVRTsKICB9CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYxXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hBYm91dEluZm9BLgogKi8KQk9PTCBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SUVLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLAogICAgJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbk50S2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCcgJywKICAgICdOJywnVCcsJ1xcJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pXaW5LZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelJlZ0tleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAogICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelZlcnNpb25bXSA9IHsgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDdXN0b21pemVkW10gPSB7ICdDJywndScsJ3MnLCd0JywnbycsJ20nLCdpJywneicsJ2UnLCdkJywKICAgICdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3duZXJbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCd3JywnbicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3JnW10gPSB7ICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdlJywncicsJ2UnLCdkJywKICAgICdPJywncicsJ2cnLCdhJywnbicsJ2knLCd6JywnYScsJ3QnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9kdWN0W10gPSB7ICdQJywncicsJ28nLCdkJywndScsJ2MnLCd0JywnSScsJ2QnLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pVcGRhdGVbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ1UnLCdwJywnZCcsJ2EnLCd0JywnZScsJ1UnLCdyJywnbCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekhlbHBbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ0gnLCdlJywnbCcsJ3AnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdcMCcgfTsKICBXQ0hBUiBidWZmWzIwODRdOwogIEhLRVkgaFJlZzsKICBEV09SRCBkd1R5cGUsIGR3TGVuOwoKICBUUkFDRSgiKCVwLCVkKVxuIiwgbHBzekRlc3QsIGR3RGVzdExlbik7CgogIGlmICghbHBzekRlc3QpCiAgICByZXR1cm4gRkFMU0U7CgogICpscHN6RGVzdCA9ICdcMCc7CgogIC8qIFRyeSB0aGUgTlQga2V5IGZpcnN0LCBmb2xsb3dlZCBieSA5NS85OCBrZXkgKi8KICBpZiAoUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luTnRLZXksIDAsIEtFWV9SRUFELCAmaFJlZykgJiYKICAgICAgUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCAwLCBLRVlfUkVBRCwgJmhSZWcpKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBPUyBWZXJzaW9uICovCiAgYnVmZlswXSA9ICdcMCc7CiAgZHdMZW4gPSAzMDsKICBpZiAoIVNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwgc3pWZXJzaW9uLCAmZHdUeXBlLCBidWZmLCAmZHdMZW4pKQogIHsKICAgIERXT1JEIGR3U3RyTGVuID0gc3RybGVuVyhidWZmKTsKICAgIGR3TGVuID0gMzAgLSBkd1N0ckxlbjsKICAgIFNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwKICAgICAgICAgICAgICAgIHN6Q3VzdG9taXplZCwgJmR3VHlwZSwgYnVmZitkd1N0ckxlbiwgJmR3TGVuKTsKICB9CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE93bmVyICovCiAgYnVmZlswXSA9ICd+JzsKICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoaFJlZywgc3pPd25lciwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE9yZ2FuaXphdGlvbiAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek9yZywgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIEZJWE1FOiBOb3Qgc3VyZSB3aGVyZSB0aGlzIG51bWJlciBjb21lcyBmcm9tICAqLwogIGJ1ZmZbMF0gPSAnfic7CiAgYnVmZlsxXSA9ICcwJzsKICBidWZmWzJdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflByb2R1Y3QgSWQgKi8KICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzelJlZ0tleSwgc3pQcm9kdWN0LCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogfklFIFVwZGF0ZSBVcmwgKi8KICBkd0xlbiA9IDIwNDg7CiAgaWYoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeldpbktleSwgc3pVcGRhdGUsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgSGVscCBTdHJpbmcgKi8KICBkd0xlbiA9IDI1NjsKICBpZihTSEdldFZhbHVlVyhoUmVnLCBzekhlbHAsIDAsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICBSZWdDbG9zZUtleShoUmVnKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2M10KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKiAgY0NtZHMgICAgICAgICBbSV0KICogIHByZ0NtZHMgICAgICAgW09dIENvbW1hbmRzCiAqICBwQ21kVGV4dCAgICAgIFtPXSBDb21tYW5kIHRleHQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVN0YXR1cyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMsIE9MRUNNRFRFWFQqIHBDbWRUZXh0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVkLCVwLCVwKVxuIixscFVua25vd24sIHBndWlkQ21kR3JvdXAsIGNDbWRzLCBwcmdDbWRzLCBwQ21kVGV4dCk7CgogIGlmIChscFVua25vd24pCiAgewogICAgSU9sZUNvbW1hbmRUYXJnZXQqIGxwT2xlOwoKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbW1hbmRUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBPbGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cyhscE9sZSwgcGd1aWRDbWRHcm91cCwgY0NtZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmdDbWRzLCBwQ21kVGV4dCk7CiAgICAgIElPbGVDb21tYW5kVGFyZ2V0X1JlbGVhc2UobHBPbGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNjRdCiAqCiAqIENhbGwgSU9sZUNvbW1hbmRUYXJnZXRfRXhlYygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBscFVua25vd24gaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElPbGVDb21tYW5kVGFyZ2V0LgogKiAgICAgICAgICAgT3RoZXJ3aXNlLCBhbiBlcnJvciBjb2RlIGZyb20gSU9sZUNvbW1hbmRUYXJnZXRfRXhlYygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRXhlYyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG5DbWRJRCwgRFdPUkQgbkNtZGV4ZWNvcHQsIFZBUklBTlQqIHB2YUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJJQU5UKiBwdmFPdXQpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJWQsJWQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfRXhlYyhscE9sZSwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CiAgICAgIElPbGVDb21tYW5kVGFyZ2V0X1JlbGVhc2UobHBPbGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2NV0KICoKICogUmV0cmlldmUsIG1vZGlmeSwgYW5kIHJlLXNldCBhIHZhbHVlIGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgIFtJXSBXaW5kb3cgdG8gZ2V0IHZhbHVlIGZyb20KICogIG9mZnNldCBbSV0gT2Zmc2V0IG9mIHZhbHVlCiAqICB3TWFzayAgW0ldIE1hc2sgZm9yIHVpRmxhZ3MKICogIHdGbGFncyBbSV0gQml0cyB0byBzZXQgaW4gd2luZG93IHZhbHVlCiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgdmFsdWUgYXMgaXQgd2FzIHNldCwgb3IgMCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQuCiAqCiAqIE5PVEVTCiAqICBBbnkgYml0cyBzZXQgaW4gdWlNYXNrIGFyZSBjbGVhcmVkIGZyb20gdGhlIHZhbHVlLCB0aGVuIGFueSBiaXRzIHNldCBpbgogKiAgdWlGbGFncyBhcmUgc2V0IGluIHRoZSB2YWx1ZS4KICovCkxPTkcgV0lOQVBJIFNIU2V0V2luZG93Qml0cyhIV05EIGh3bmQsIElOVCBvZmZzZXQsIFVJTlQgd01hc2ssIFVJTlQgd0ZsYWdzKQp7CiAgTE9ORyByZXQgPSBHZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQpOwogIExPTkcgbmV3RmxhZ3MgPSAod0ZsYWdzICYgd01hc2spIHwgKHJldCAmIH53RmxhZ3MpOwoKICBpZiAobmV3RmxhZ3MgIT0gcmV0KQogICAgcmV0ID0gU2V0V2luZG93TG9uZ0EoaHduZCwgb2Zmc2V0LCBuZXdGbGFncyk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2N10KICoKICogQ2hhbmdlIGEgd2luZG93J3MgcGFyZW50LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgW0ldIFdpbmRvdyB0byBjaGFuZ2UgcGFyZW50IG9mCiAqICBoV25kUGFyZW50IFtJXSBOZXcgcGFyZW50IHdpbmRvdwogKgogKiBSRVRVUk5TCiAqICBUaGUgb2xkIHBhcmVudCBvZiBoV25kLgogKgogKiBOT1RFUwogKiAgSWYgaFduZFBhcmVudCBpcyBOVUxMIChkZXNrdG9wKSwgdGhlIHdpbmRvdyBzdHlsZSBpcyBjaGFuZ2VkIHRvIFdTX1BPUFVQLgogKiAgSWYgaFduZFBhcmVudCBpcyBOT1QgTlVMTCB0aGVuIHdlIHNldCB0aGUgV1NfQ0hJTEQgc3R5bGUuCiAqLwpIV05EIFdJTkFQSSBTSFNldFBhcmVudEh3bmQoSFdORCBoV25kLCBIV05EIGhXbmRQYXJlbnQpCnsKICBUUkFDRSgiJXAsICVwXG4iLCBoV25kLCBoV25kUGFyZW50KTsKCiAgaWYoR2V0UGFyZW50KGhXbmQpID09IGhXbmRQYXJlbnQpCiAgICByZXR1cm4gMDsKCiAgaWYoaFduZFBhcmVudCkKICAgIFNIU2V0V2luZG93Qml0cyhoV25kLCBHV0xfU1RZTEUsIFdTX0NISUxELCBXU19DSElMRCk7CiAgZWxzZQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfUE9QVVAsIFdTX1BPUFVQKTsKCiAgcmV0dXJuIFNldFBhcmVudChoV25kLCBoV25kUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE2OF0KICoKICogTG9jYXRlIGFuZCBhZHZpc2UgYSBjb25uZWN0aW9uIHBvaW50IGluIGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rU2luayAgIFtJXSBTaW5rIGZvciB0aGUgY29ubmVjdGlvbiBwb2ludCBhZHZpc2UgY2FsbAogKiAgcmlpZCAgICAgICAgW0ldIFJFRklJRCBvZiBjb25uZWN0aW9uIHBvaW50IHRvIGFkdmlzZQogKiAgYkFkdmlzZU9ubHkgW0ldIFRSVUUgPSBBZHZpc2Ugb25seSwgRkFMU0UgPSBVbmFkdmlzZSBmaXJzdAogKiAgbHBVbmtub3duICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZQogKiAgbHBDb29raWUgICAgW09dIFBvaW50ZXIgdG8gY29ubmVjdGlvbiBwb2ludCBjb29raWUKICogIGxwcENQICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIElDb25uZWN0aW9uUG9pbnQgZm91bmQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgbHBwQ1AgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZCB3aXRoIHRoZSBJQ29ubmVjdGlvblBvaW50CiAqICAgICAgICAgICB0aGF0IHdhcyBhZHZpc2VkLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciByZWxlYXNpbmcgaXQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXNuJ3QgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZSBpZiBhbnkgY2FsbCBmYWlscy4KICovCkhSRVNVTFQgV0lOQVBJIENvbm5lY3RUb0Nvbm5lY3Rpb25Qb2ludChJVW5rbm93biogbHBVbmtTaW5rLCBSRUZJSUQgcmlpZCwgQk9PTCBiQWR2aXNlT25seSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24qIGxwVW5rbm93biwgTFBEV09SRCBscENvb2tpZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCAqKmxwcENQKQp7CiAgSFJFU1VMVCBoUmV0OwogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ29udGFpbmVyOwogIElDb25uZWN0aW9uUG9pbnQgKmxwQ1A7CgogIGlmKCFscFVua25vd24gfHwgKGJBZHZpc2VPbmx5ICYmICFscFVua1NpbmspKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYobHBwQ1ApCiAgICAqbHBwQ1AgPSBOVUxMOwoKICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ29udGFpbmVyKTsKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDb250YWluZXIsIHJpaWQsICZscENQKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgewogICAgICBpZighYkFkdmlzZU9ubHkpCiAgICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfVW5hZHZpc2UobHBDUCwgKmxwQ29va2llKTsKICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfQWR2aXNlKGxwQ1AsIGxwVW5rU2luaywgbHBDb29raWUpOwoKICAgICAgaWYgKEZBSUxFRChoUmV0KSkKICAgICAgICAqbHBDb29raWUgPSAwOwoKICAgICAgaWYgKGxwcENQICYmIFNVQ0NFRURFRChoUmV0KSkKICAgICAgICAqbHBwQ1AgPSBscENQOyAvKiBDYWxsZXIga2VlcHMgdGhlIGludGVyZmFjZSAqLwogICAgICBlbHNlCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGxwQ1ApOyAvKiBSZWxlYXNlIGl0ICovCiAgICB9CgogICAgSVVua25vd25fUmVsZWFzZShscENvbnRhaW5lcik7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglACVtTSExXQVBJLjE2OV0KICoKICogUmVsZWFzZSBhbiBpbnRlcmZhY2UuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gcmVsZWFzZQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX0F0b21pY1JlbGVhc2UoSVVua25vd24gKiogbHBVbmtub3duKQp7CiAgICBJVW5rbm93biAqdGVtcDsKCiAgICBUUkFDRSgiKCVwKVxuIixscFVua25vd24pOwoKICAgIGlmKCFscFVua25vd24gfHwgISooKExQRFdPUkQpbHBVbmtub3duKSkgcmV0dXJuIDA7CiAgICB0ZW1wID0gKmxwVW5rbm93bjsKICAgICpscFVua25vd24gPSBOVUxMOwoKICAgIFRSQUNFKCJkb2luZyBSZWxlYXNlXG4iKTsKCiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZSh0ZW1wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3MF0KICoKICogU2tpcCAnLy8nIGlmIHByZXNlbnQgaW4gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU3RyaW5nIHRvIGNoZWNrIGZvciAnLy8nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGUgJy8vJyBvciB0aGUgc3RyaW5nIGlmIG5vdCBwcmVzZW50CiAqICBGYWlsdXJlOiBOVUxMLCBpZiBscHN6U3RyIGlzIE5VTEwuCiAqLwpMUENTVFIgV0lOQVBJIFBhdGhTa2lwTGVhZGluZ1NsYXNoZXNBKExQQ1NUUiBscHN6U3JjKQp7CiAgaWYgKGxwc3pTcmMgJiYgbHBzelNyY1swXSA9PSAnLycgJiYgbHBzelNyY1sxXSA9PSAnLycpCiAgICBscHN6U3JjICs9IDI7CiAgcmV0dXJuIGxwc3pTcmM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTcxXQogKgogKiBDaGVjayBpZiB0d28gaW50ZXJmYWNlcyBjb21lIGZyb20gdGhlIHNhbWUgb2JqZWN0LgogKgogKiBQQVJBTVMKICogICBscEludDEgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50Mi4KICogICBscEludDIgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50MS4KICoKICogUkVUVVJOUwogKiAgIFRSVUUsIElmIHRoZSBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqICAgRkFMU0UgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc1NhbWVPYmplY3QoSVVua25vd24qIGxwSW50MSwgSVVua25vd24qIGxwSW50MikKewogIExQVk9JRCBscFVua25vd24xLCBscFVua25vd24yOwoKICBUUkFDRSgiJXAgJXBcbiIsIGxwSW50MSwgbHBJbnQyKTsKCiAgaWYgKCFscEludDEgfHwgIWxwSW50MikKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwSW50MSA9PSBscEludDIpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQxLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjEpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQyLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjIpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwVW5rbm93bjEgPT0gbHBVbmtub3duMikKICAgIHJldHVybiBUUlVFOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzJdCiAqCiAqIEdldCB0aGUgd2luZG93IGhhbmRsZSBvZiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mCiAqICBscGhXbmQgICAgW09dIERlc3RpbmF0aW9uIGZvciB3aW5kb3cgaGFuZGxlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwaFduZCBjb250YWlucyB0aGUgb2JqZWN0cyB3aW5kb3cgaGFuZGxlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIGlzIGV4cGVjdGVkIHRvIHN1cHBvcnQgb25lIG9mIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlczoKICogIElPbGVXaW5kb3coKSwgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKCksIG9yIElTaGVsbFZpZXcoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldFdpbmRvdyhJVW5rbm93biAqbHBVbmtub3duLCBIV05EICpscGhXbmQpCnsKICBJVW5rbm93biAqbHBPbGU7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscGhXbmQpOwoKICBpZiAoIWxwVW5rbm93bikKICAgIHJldHVybiBoUmV0OwoKICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVXaW5kb3csICh2b2lkKiopJmxwT2xlKTsKCiAgaWYgKEZBSUxFRChoUmV0KSkKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCZJSURfSVNoZWxsVmlldywgKHZvaWQqKikmbHBPbGUpOwoKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICB7CiAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKICAgIH0KICB9CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgLyogTGF6eW5lc3MgaGVyZSAtIFNpbmNlIEdldFdpbmRvdygpIGlzIHRoZSBmaXJzdCBtZXRob2QgZm9yIHRoZSBhYm92ZSAzCiAgICAgKiBpbnRlcmZhY2VzLCB3ZSB1c2UgdGhlIHNhbWUgY2FsbCBmb3IgdGhlbSBhbGwuCiAgICAgKi8KICAgIGhSZXQgPSBJT2xlV2luZG93X0dldFdpbmRvdygoSU9sZVdpbmRvdyopbHBPbGUsIGxwaFduZCk7CiAgICBJVW5rbm93bl9SZWxlYXNlKGxwT2xlKTsKICAgIGlmIChscGhXbmQpCiAgICAgIFRSQUNFKCJSZXR1cm5pbmcgSFdORD0lcFxuIiwgKmxwaFduZCk7CiAgfQoKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3M10KICoKICogQ2FsbCBhIG1ldGhvZCBvbiBhcyBhcyB5ZXQgdW5pZGVudGlmaWVkIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBwVW5rIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgdW5pZGVudGlmaWVkIGludGVyZmFjZSwKICogIGFyZyAgW0ldIEFyZ3VtZW50IGZvciB0aGUgY2FsbCBvbiB0aGUgb2JqZWN0LgogKgogKiBSRVRVUk5TCiAqICBTX09LLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fU2V0T3duZXIoSVVua25vd24gKnBVbmssIFVMT05HIGFyZykKewogIHN0YXRpYyBjb25zdCBHVUlEIGd1aWRfMTczID0gewogICAgMHg1ODM2ZmIwMCwgMHg4MTg3LCAweDExY2YsIHsgMHhhMSwweDJiLDB4MDAsMHhhYSwweDAwLDB4NGEsMHhlOCwweDM3IH0KICB9OwogIElNYWxsb2MgKnBVbmsyOwoKICBUUkFDRSgiKCVwLCVkKVxuIiwgcFVuaywgYXJnKTsKCiAgLyogTm90ZTogYXJnIG1heSBub3QgYmUgYSBVTE9ORyBhbmQgcFVuazIgaXMgZm9yIHN1cmUgbm90IGFuIElNYWxsb2MgLQogICAqICAgICAgIFdlIHVzZSB0aGlzIGludGVyZmFjZSBhcyBpdHMgdnRhYmxlIGVudHJ5IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUKICAgKiAgICAgICBvYmplY3QgaW4gcXVlc3Rpb24uCiAgICogRklYTUU6IEZpbmQgb3V0IHdoYXQgdGhpcyBvYmplY3QgaXMgYW5kIHdoZXJlIGl0IHNob3VsZCBiZSBkZWZpbmVkLgogICAqLwogIGlmIChwVW5rICYmCiAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rLCAmZ3VpZF8xNzMsICh2b2lkKiopJnBVbmsyKSkpCiAgewogICAgSU1hbGxvY19BbGxvYyhwVW5rMiwgYXJnKTsgLyogRmFrZWQgY2FsbCEhICovCiAgICBJTWFsbG9jX1JlbGVhc2UocFVuazIpOwogIH0KICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NF0KICoKICogQ2FsbCBlaXRoZXIgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUoKSBvciBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlKCkgb24KICogYW4gb2JqZWN0LgogKgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fU2V0U2l0ZSgKICAgICAgICBJVW5rbm93biAqb2JqLCAgICAgICAgLyogW2luXSAgIE9MRSBvYmplY3QgICAgICovCiAgICAgICAgSVVua25vd24gKnNpdGUpICAgICAgIC8qIFtpbl0gICBTaXRlIGludGVyZmFjZSAqLwp7CiAgICBIUkVTVUxUIGhyOwogICAgSU9iamVjdFdpdGhTaXRlICppb2Jqd2l0aHNpdGU7CiAgICBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIgKmlzZWNtZ3I7CgogICAgaWYgKCFvYmopIHJldHVybiBFX0ZBSUw7CgogICAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShvYmosICZJSURfSU9iamVjdFdpdGhTaXRlLCAoTFBWT0lEICopJmlvYmp3aXRoc2l0ZSk7CiAgICBUUkFDRSgiSUlEX0lPYmplY3RXaXRoU2l0ZSBRSSByZXQ9JTA4eCwgJXBcbiIsIGhyLCBpb2Jqd2l0aHNpdGUpOwogICAgaWYgKFNVQ0NFRURFRChocikpCiAgICB7CglociA9IElPYmplY3RXaXRoU2l0ZV9TZXRTaXRlKGlvYmp3aXRoc2l0ZSwgc2l0ZSk7CglUUkFDRSgiZG9uZSBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZSByZXQ9JTA4eFxuIiwgaHIpOwoJSVVua25vd25fUmVsZWFzZShpb2Jqd2l0aHNpdGUpOwogICAgfQogICAgZWxzZQogICAgewoJaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShvYmosICZJSURfSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyLCAoTFBWT0lEICopJmlzZWNtZ3IpOwoJVFJBQ0UoIklJRF9JSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIgUUkgcmV0PSUwOHgsICVwXG4iLCBociwgaXNlY21ncik7CglpZiAoRkFJTEVEKGhyKSkgcmV0dXJuIGhyOwoKCWhyID0gSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZShpc2VjbWdyLCAoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlICopc2l0ZSk7CglUUkFDRSgiZG9uZSBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlIHJldD0lMDh4XG4iLCBocik7CglJVW5rbm93bl9SZWxlYXNlKGlzZWNtZ3IpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc1XQogKgogKiBDYWxsIElQZXJzaXN0X0dldENsYXNzSUQoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSVBlcnNpc3QgaW50ZXJmYWNlCiAqICBscENsYXNzSWQgW09dIERlc3RpbmF0aW9uIGZvciBDbGFzcyBJZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBscENsYXNzSWQgY29udGFpbnMgdGhlIENsYXNzIElkIHJlcXVlc3RlZC4KICogIEZhaWx1cmU6IEVfRkFJTCwgSWYgbHBVbmtub3duIGlzIE5VTEwsCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFIElmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElQZXJzaXN0LAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0Q2xhc3NJRChJVW5rbm93biAqbHBVbmtub3duLCBDTFNJRCogbHBDbGFzc0lkKQp7CiAgSVBlcnNpc3QqIGxwUGVyc2lzdDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGRlYnVnc3RyX2d1aWQobHBDbGFzc0lkKSk7CgogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwmSUlEX0lQZXJzaXN0LCh2b2lkKiopJmxwUGVyc2lzdCk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgewogICAgICBJUGVyc2lzdF9HZXRDbGFzc0lEKGxwUGVyc2lzdCwgbHBDbGFzc0lkKTsKICAgICAgSVBlcnNpc3RfUmVsZWFzZShscFBlcnNpc3QpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3Nl0KICoKICogUmV0cmlldmUgYSBTZXJ2aWNlIEludGVyZmFjZSBmcm9tIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBnZXQgYW4gSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgZnJvbQogKiAgc2lkICAgICAgIFtJXSBTZXJ2aWNlIElEIGZvciBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZSgpIGNhbGwKICogIHJpaWQgICAgICBbSV0gRnVuY3Rpb24gcmVxdWVzdGVkIGZvciBRdWVyeVNlcnZpY2UgY2FsbAogKiAgbHBwT3V0ICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIHNlcnZpY2UgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBwT3V0IGNvbnRhaW5zIGFuIG9iamVjdCBwcm92aWRpbmcgdGhlIHJlcXVlc3RlZCBzZXJ2aWNlCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUKICoKICogTk9URVMKICogIGxwVW5rbm93biBpcyBleHBlY3RlZCB0byBzdXBwb3J0IHRoZSBJU2VydmljZVByb3ZpZGVyIGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZShJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHNpZCwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqbHBwT3V0KQp7CiAgSVNlcnZpY2VQcm92aWRlciogcFNlcnZpY2UgPSBOVUxMOwogIEhSRVNVTFQgaFJldDsKCiAgaWYgKCFscHBPdXQpCiAgICByZXR1cm4gRV9GQUlMOwoKICAqbHBwT3V0ID0gTlVMTDsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICAvKiBHZXQgYW4gSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgZnJvbSB0aGUgb2JqZWN0ICovCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JU2VydmljZVByb3ZpZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcFNlcnZpY2UpOwoKICBpZiAoIWhSZXQgJiYgcFNlcnZpY2UpCiAgewogICAgVFJBQ0UoIlF1ZXJ5SW50ZXJmYWNlIHJldHVybmVkIChJU2VydmljZVByb3ZpZGVyKiklcFxuIiwgcFNlcnZpY2UpOwoKICAgIC8qIEdldCBhIFNlcnZpY2UgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogICAgaFJldCA9IElTZXJ2aWNlUHJvdmlkZXJfUXVlcnlTZXJ2aWNlKHBTZXJ2aWNlLCBzaWQsIHJpaWQsIGxwcE91dCk7CgogICAgVFJBQ0UoIihJU2VydmljZVByb3ZpZGVyKiklcCByZXR1cm5lZCAoSVVua25vd24qKSVwXG4iLCBwU2VydmljZSwgKmxwcE91dCk7CgogICAgLyogUmVsZWFzZSB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgKi8KICAgIElVbmtub3duX1JlbGVhc2UocFNlcnZpY2UpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3N10KICoKICogTG9hZHMgYSBwb3B1cCBtZW51LgogKgogKiBQQVJBTVMKICogIGhJbnN0ICBbSV0gSW5zdGFuY2UgaGFuZGxlCiAqICBzek5hbWUgW0ldIE1lbnUgbmFtZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuCiAqLwpCT09MIFdJTkFQSSBTSExvYWRNZW51UG9wdXAoSElOU1RBTkNFIGhJbnN0LCBMUENXU1RSIHN6TmFtZSkKewogIEhNRU5VIGhNZW51OwoKICBpZiAoKGhNZW51ID0gTG9hZE1lbnVXKGhJbnN0LCBzek5hbWUpKSkKICB7CiAgICBpZiAoR2V0U3ViTWVudShoTWVudSwgMCkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0IF9lbnVtV25kRGF0YQp7CiAgVUlOVCAgIHVpTXNnSWQ7CiAgV1BBUkFNIHdQYXJhbTsKICBMUEFSQU0gbFBhcmFtOwogIExSRVNVTFQgKFdJTkFQSSAqcGZuUG9zdCkoSFdORCxVSU5ULFdQQVJBTSxMUEFSQU0pOwp9IGVudW1XbmREYXRhOwoKLyogQ2FsbGJhY2sgZm9yIFNITFdBUElfMTc4ICovCnN0YXRpYyBCT09MIENBTExCQUNLIFNITFdBUElfRW51bUNoaWxkUHJvYyhIV05EIGhXbmQsIExQQVJBTSBsUGFyYW0pCnsKICBlbnVtV25kRGF0YSAqZGF0YSA9IChlbnVtV25kRGF0YSAqKWxQYXJhbTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGhXbmQsIGRhdGEpOwogIGRhdGEtPnBmblBvc3QoaFduZCwgZGF0YS0+dWlNc2dJZCwgZGF0YS0+d1BhcmFtLCBkYXRhLT5sUGFyYW0pOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xNzhdCiAqCiAqIFNlbmQgb3IgcG9zdCBhIG1lc3NhZ2UgdG8gZXZlcnkgY2hpbGQgb2YgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICBbSV0gV2luZG93IHdob3NlIGNoaWxkcmVuIHdpbGwgZ2V0IHRoZSBtZXNzYWdlcwogKiAgdWlNc2dJZCBbSV0gTWVzc2FnZSBJZAogKiAgd1BhcmFtICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqICBiU2VuZCAgIFtJXSBUUlVFID0gVXNlIFNlbmRNZXNzYWdlQSgpLCBGQUxTRSA9IFVzZSBQb3N0TWVzc2FnZUEoKQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKgogKiBOT1RFUwogKiAgVGhlIGFwcHJvcHJpYXRlIEFTQ0lJIG9yIFVuaWNvZGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciB0aGUgd2luZG93LgogKi8Kdm9pZCBXSU5BUEkgU0hQcm9wYWdhdGVNZXNzYWdlKEhXTkQgaFduZCwgVUlOVCB1aU1zZ0lkLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtLCBCT09MIGJTZW5kKQp7CiAgZW51bVduZERhdGEgZGF0YTsKCiAgVFJBQ0UoIiglcCwldSwlbGQsJWxkLCVkKVxuIiwgaFduZCwgdWlNc2dJZCwgd1BhcmFtLCBsUGFyYW0sIGJTZW5kKTsKCiAgaWYoaFduZCkKICB7CiAgICBkYXRhLnVpTXNnSWQgPSB1aU1zZ0lkOwogICAgZGF0YS53UGFyYW0gID0gd1BhcmFtOwogICAgZGF0YS5sUGFyYW0gID0gbFBhcmFtOwoKICAgIGlmIChiU2VuZCkKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVNlbmRNZXNzYWdlVyA6ICh2b2lkKilTZW5kTWVzc2FnZUE7CiAgICBlbHNlCiAgICAgIGRhdGEucGZuUG9zdCA9IElzV2luZG93VW5pY29kZShoV25kKSA/ICh2b2lkKilQb3N0TWVzc2FnZVcgOiAodm9pZCopUG9zdE1lc3NhZ2VBOwoKICAgIEVudW1DaGlsZFdpbmRvd3MoaFduZCwgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jLCAoTFBBUkFNKSZkYXRhKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODBdCiAqCiAqIFJlbW92ZSBhbGwgc3ViLW1lbnVzIGZyb20gYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIHJlbW92ZSBzdWItbWVudXMgZnJvbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiAwLiAgQWxsIHN1Yi1tZW51cyB1bmRlciBoTWVudSBhcmUgcmVtb3ZlZAogKiAgRmFpbHVyZTogLTEsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KRFdPUkQgV0lOQVBJIFNIUmVtb3ZlQWxsU3ViTWVudXMoSE1FTlUgaE1lbnUpCnsKICBpbnQgaUl0ZW1Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpIC0gMTsKICB3aGlsZSAoaUl0ZW1Db3VudCA+PSAwKQogIHsKICAgIEhNRU5VIGhTdWJNZW51ID0gR2V0U3ViTWVudShoTWVudSwgaUl0ZW1Db3VudCk7CiAgICBpZiAoaFN1Yk1lbnUpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIGlJdGVtQ291bnQsIE1GX0JZUE9TSVRJT04pOwogICAgaUl0ZW1Db3VudC0tOwogIH0KICByZXR1cm4gaUl0ZW1Db3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MV0KICoKICogRW5hYmxlIG9yIGRpc2FibGUgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgICBbSV0gSUQgb2YgbWVudSBpdGVtIHRvIGVuYWJsZS9kaXNhYmxlCiAqICBiRW5hYmxlIFtJXSBXaGV0aGVyIHRvIGVuYWJsZSAoVFJVRSkgb3IgZGlzYWJsZSAoRkFMU0UpIHRoZSBpdGVtLgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0dXJuIGNvZGUgZnJvbSBFbmFibGVNZW51SXRlbS4KICovClVJTlQgV0lOQVBJIFNIRW5hYmxlTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgd0l0ZW1JRCwgQk9PTCBiRW5hYmxlKQp7CiAgcmV0dXJuIEVuYWJsZU1lbnVJdGVtKGhNZW51LCB3SXRlbUlELCBiRW5hYmxlID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMTgyXQogKgogKiBDaGVjayBvciB1bmNoZWNrIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51ICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gY2hlY2svdW5jaGVjawogKiAgYkNoZWNrIFtJXSBXaGV0aGVyIHRvIGNoZWNrIChUUlVFKSBvciB1bmNoZWNrIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIENoZWNrTWVudUl0ZW0uCiAqLwpEV09SRCBXSU5BUEkgU0hDaGVja01lbnVJdGVtKEhNRU5VIGhNZW51LCBVSU5UIHVJRCwgQk9PTCBiQ2hlY2spCnsKICByZXR1cm4gQ2hlY2tNZW51SXRlbShoTWVudSwgdUlELCBiQ2hlY2sgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4M10KICoKICogUmVnaXN0ZXIgYSB3aW5kb3cgY2xhc3MgaWYgaXQgaXNuJ3QgYWxyZWFkeS4KICoKICogUEFSQU1TCiAqICBscFduZENsYXNzIFtJXSBXaW5kb3cgY2xhc3MgdG8gcmVnaXN0ZXIKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiB0aGUgUmVnaXN0ZXJDbGFzc0EgY2FsbC4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NBKFdORENMQVNTQSAqd25kY2xhc3MpCnsKICBXTkRDTEFTU0Egd2NhOwogIGlmIChHZXRDbGFzc0luZm9BKHduZGNsYXNzLT5oSW5zdGFuY2UsIHduZGNsYXNzLT5scHN6Q2xhc3NOYW1lLCAmd2NhKSkKICAgIHJldHVybiBUUlVFOwogIHJldHVybiAoRFdPUkQpUmVnaXN0ZXJDbGFzc0Eod25kY2xhc3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg2XQogKi8KQk9PTCBXSU5BUEkgU0hTaW11bGF0ZURyb3AoSURyb3BUYXJnZXQgKnBEcm9wLCBJRGF0YU9iamVjdCAqcERhdGFPYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGdyZktleVN0YXRlLCBQUE9JTlRMIGxwUHQsIERXT1JEKiBwZHdFZmZlY3QpCnsKICBEV09SRCBkd0VmZmVjdCA9IERST1BFRkZFQ1RfTElOSyB8IERST1BFRkZFQ1RfTU9WRSB8IERST1BFRkZFQ1RfQ09QWTsKICBQT0lOVEwgcHQgPSB7IDAsIDAgfTsKCiAgaWYgKCFscFB0KQogICAgbHBQdCA9ICZwdDsKCiAgaWYgKCFwZHdFZmZlY3QpCiAgICBwZHdFZmZlY3QgPSAmZHdFZmZlY3Q7CgogIElEcm9wVGFyZ2V0X0RyYWdFbnRlcihwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgaWYgKCpwZHdFZmZlY3QpCiAgICByZXR1cm4gSURyb3BUYXJnZXRfRHJvcChwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgSURyb3BUYXJnZXRfRHJhZ0xlYXZlKHBEcm9wKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4N10KICoKICogQ2FsbCBJUGVyc2lzdFByb3BlcnR5QmFnX0xvYWQoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSVBlcnNpc3RQcm9wZXJ0eUJhZyBpbnRlcmZhY2UKICogIGxwUHJvcEJhZyBbT10gRGVzdGluYXRpb24gZm9yIGxvYWRlZCBJUHJvcGVydHlCYWcKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIFNITG9hZEZyb21Qcm9wZXJ0eUJhZyhJVW5rbm93biAqbHBVbmtub3duLCBJUHJvcGVydHlCYWcqIGxwUHJvcEJhZykKewogIElQZXJzaXN0UHJvcGVydHlCYWcqIGxwUFBCYWc7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscFByb3BCYWcpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVBlcnNpc3RQcm9wZXJ0eUJhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFBQQmFnKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBQUEJhZykKICAgIHsKICAgICAgaFJldCA9IElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZChscFBQQmFnLCBscFByb3BCYWcsIE5VTEwpOwogICAgICBJUGVyc2lzdFByb3BlcnR5QmFnX1JlbGVhc2UobHBQUEJhZyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODhdCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX1RyYW5zbGF0ZUFjY2VsZXJhdG9yKCkgIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb250cm9sU2l0ZSBpbnRlcmZhY2UuCiAqICBscE1zZyAgICAgICBbSV0gS2V5IG1lc3NhZ2UgdG8gYmUgcHJvY2Vzc2VkLgogKiAgZHdNb2RpZmllcnMgW0ldIEZsYWdzIGNvbnRhaW5pbmcgdGhlIHN0YXRlIG9mIHRoZSBtb2RpZmllciBrZXlzLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9UcmFuc2xhdGVBY2NlbGVyYXRvck9DUyhJVW5rbm93biAqbHBVbmtub3duLCBMUE1TRyBscE1zZywgRFdPUkQgZHdNb2RpZmllcnMpCnsKICBJT2xlQ29udHJvbFNpdGUqIGxwQ1NpdGUgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgVFJBQ0UoIiglcCwlcCwweCUwOHgpXG4iLCBscFVua25vd24sIGxwTXNnLCBkd01vZGlmaWVycyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9UcmFuc2xhdGVBY2NlbGVyYXRvcihscENTaXRlLCBscE1zZywgZHdNb2RpZmllcnMpOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX09uRm9jdXMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZS4KICogIGZHb3RGb2N1cyBbSV0gV2hldGhlciBmb2N1cyB3YXMgZ2FpbmVkIChUUlVFKSBvciBsb3N0IChGQUxTRSkuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfRkFJTCBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX09uRm9jdXNPQ1MoSVVua25vd24gKmxwVW5rbm93biwgQk9PTCBmR290Rm9jdXMpCnsKICBJT2xlQ29udHJvbFNpdGUqIGxwQ1NpdGUgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIGxwVW5rbm93biwgZkdvdEZvY3VzID8gIlRSVUUiIDogIkZBTFNFIik7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9PbkZvY3VzKGxwQ1NpdGUsIGZHb3RGb2N1cyk7CiAgICAgIElPbGVDb250cm9sU2l0ZV9SZWxlYXNlKGxwQ1NpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICBbU0hMV0FQSS4xOTBdCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9IYW5kbGVJUmVzdHJpY3QoTFBVTktOT1dOIGxwVW5rbm93biwgUFZPSUQgbHBBcmcxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFZPSUQgbHBBcmcyLCBQVk9JRCBscEFyZzMsIFBWT0lEIGxwQXJnNCkKewogIC8qIEZJWE1FOiB7RDEyRjI2QjItRDkwQS0xMUQwLTgzMEQtMDBBQTAwNUI0MzgzfSAtIFdoYXQgb2JqZWN0IGRvZXMgdGhpcyByZXByZXNlbnQ/ICovCiAgc3RhdGljIGNvbnN0IERXT1JEIHNlcnZpY2VfaWRbXSA9IHsgMHhkMTJmMjZiMiwgMHgxMWQwZDkwYSwgMHhhYTAwMGQ4MywgMHg4MzQzNWIwMCB9OwogIC8qIEZJWE1FOiB7RDEyRjI2QjEtRDkwQS0xMUQwLTgzMEQtMDBBQTAwNUI0MzgzfSAtIEFsc28gVW5rbm93bi91bmRvY3VtZW50ZWQgKi8KICBzdGF0aWMgY29uc3QgRFdPUkQgZnVuY3Rpb25faWRbXSA9IHsgMHhkMTJmMjZiMSwgMHgxMWQwZDkwYSwgMHhhYTAwMGQ4MywgMHg4MzQzNWIwMCB9OwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKICBMUFVOS05PV04gbHBVbmtJbm5lciA9IE5VTEw7IC8qIEZJWE1FOiBSZWFsIHR5cGUgaXMgdW5rbm93biAqLwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVwKVxuIiwgbHBVbmtub3duLCBscEFyZzEsIGxwQXJnMiwgbHBBcmczLCBscEFyZzQpOwoKICBpZiAobHBVbmtub3duICYmIGxwQXJnNCkKICB7CiAgICAgaFJldCA9IElVbmtub3duX1F1ZXJ5U2VydmljZShscFVua25vd24sIChSRUZHVUlEKXNlcnZpY2VfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUkVGR1VJRClmdW5jdGlvbl9pZCwgKHZvaWQqKikmbHBVbmtJbm5lcik7CgogICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBVbmtJbm5lcikKICAgICB7CiAgICAgICAvKiBGSVhNRTogVGhlIHR5cGUgb2Ygc2VydmljZSBvYmplY3QgcmVxdWVzdGVkIGlzIHVua25vd24sIGhvd2V2ZXIKCSogdGVzdGluZyBzaG93cyB0aGF0IGl0cyBmaXJzdCBtZXRob2QgaXMgY2FsbGVkIHdpdGggNCBwYXJhbWV0ZXJzLgoJKiBGYWtlIHRoaXMgYnkgdXNpbmcgSVBhcnNlRGlzcGxheU5hbWVfUGFyc2VEaXNwbGF5TmFtZSBzaW5jZSB0aGUKCSogc2lnbmF0dXJlIGFuZCBwb3NpdGlvbiBpbiB0aGUgdnRhYmxlIG1hdGNoZXMgb3VyIHVua25vd24gb2JqZWN0IHR5cGUuCgkqLwogICAgICAgaFJldCA9IElQYXJzZURpc3BsYXlOYW1lX1BhcnNlRGlzcGxheU5hbWUoKExQUEFSU0VESVNQTEFZTkFNRSlscFVua0lubmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBBcmcxLCBscEFyZzIsIGxwQXJnMywgbHBBcmc0KTsKICAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmtJbm5lcik7CiAgICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICBbU0hMV0FQSS4xOTJdCiAqCiAqIEdldCBhIHN1Yi1tZW51IGZyb20gYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gZ2V0IHN1Yi1tZW51IGZyb20KICogIHVJRCAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gY29udGFpbmluZyBzdWItbWVudQogKgogKiBSRVRVUk5TCiAqICBUaGUgc3ViLW1lbnUgb2YgdGhlIGl0ZW0sIG9yIGEgTlVMTCBoYW5kbGUgaWYgYW55IHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLwpITUVOVSBXSU5BUEkgU0hHZXRNZW51RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogIE1FTlVJVEVNSU5GT1cgbWk7CgogIFRSQUNFKCIoJXAsJXUpXG4iLCBoTWVudSwgdUlEKTsKCiAgbWkuY2JTaXplID0gc2l6ZW9mKG1pKTsKICBtaS5mTWFzayA9IE1JSU1fU1VCTUVOVTsKCiAgaWYgKCFHZXRNZW51SXRlbUluZm9XKGhNZW51LCB1SUQsIEZBTFNFLCAmbWkpKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiBtaS5oU3ViTWVudTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5M10KICoKICogR2V0IHRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0Q3VyQ29sb3JSZXModm9pZCkKewogICAgSERDIGhkYzsKICAgIERXT1JEIHJldDsKCiAgICBUUkFDRSgiKClcbiIpOwoKICAgIGhkYyA9IEdldERDKDApOwogICAgcmV0ID0gR2V0RGV2aWNlQ2FwcyhoZGMsIEJJVFNQSVhFTCkgKiBHZXREZXZpY2VDYXBzKGhkYywgUExBTkVTKTsKICAgIFJlbGVhc2VEQygwLCBoZGMpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5NF0KICoKICogV2FpdCBmb3IgYSBtZXNzYWdlIHRvIGFycml2ZSwgd2l0aCBhIHRpbWVvdXQuCiAqCiAqIFBBUkFNUwogKiAgaGFuZCAgICAgIFtJXSBIYW5kbGUgdG8gcXVlcnkKICogIGR3VGltZW91dCBbSV0gVGltZW91dCBpbiB0aWNrcyBvciBJTkZJTklURSB0byBuZXZlciB0aW1lb3V0CiAqCiAqIFJFVFVSTlMKICogIFNUQVRVU19USU1FT1VUIGlmIG5vIG1lc3NhZ2UgaXMgcmVjZWl2ZWQgYmVmb3JlIGR3VGltZW91dCB0aWNrcyBwYXNzZXMuCiAqICBPdGhlcndpc2UgcmV0dXJucyB0aGUgdmFsdWUgZnJvbSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXggd2hlbiBhCiAqICBtZXNzYWdlIGlzIGF2YWlsYWJsZS4KICovCkRXT1JEIFdJTkFQSSBTSFdhaXRGb3JTZW5kTWVzc2FnZVRocmVhZChIQU5ETEUgaGFuZCwgRFdPUkQgZHdUaW1lb3V0KQp7CiAgRFdPUkQgZHdFbmRUaWNrcyA9IEdldFRpY2tDb3VudCgpICsgZHdUaW1lb3V0OwogIERXT1JEIGR3UmV0OwoKICB3aGlsZSAoKGR3UmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0c0V4KDEsICZoYW5kLCBkd1RpbWVvdXQsIFFTX1NFTkRNRVNTQUdFLCAwKSkgPT0gMSkKICB7CiAgICBNU0cgbXNnOwoKICAgIFBlZWtNZXNzYWdlVygmbXNnLCBOVUxMLCAwLCAwLCBQTV9OT1JFTU9WRSk7CgogICAgaWYgKGR3VGltZW91dCAhPSBJTkZJTklURSkKICAgIHsKICAgICAgICBpZiAoKGludCkoZHdUaW1lb3V0ID0gZHdFbmRUaWNrcyAtIEdldFRpY2tDb3VudCgpKSA8PSAwKQogICAgICAgICAgICByZXR1cm4gV0FJVF9USU1FT1VUOwogICAgfQogIH0KCiAgcmV0dXJuIGR3UmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTk1XQogKgogKiBEZXRlcm1pbmUgaWYgYSBzaGVsbCBmb2xkZXIgY2FuIGJlIGV4cGFuZGVkLgogKgogKiBQQVJBTVMKICogIGxwRm9sZGVyIFtJXSBQYXJlbnQgZm9sZGVyIGNvbnRhaW5pbmcgdGhlIG9iamVjdCB0byB0ZXN0LgogKiAgcGlkbCAgICAgW0ldIElkIG9mIHRoZSBvYmplY3QgdG8gdGVzdC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSywgaWYgdGhlIG9iamVjdCBpcyBleHBhbmRhYmxlLCBTX0ZBTFNFIG90aGVyd2lzZS4KICogIEZhaWx1cmU6IEVfSU5WQUxJREFSRywgaWYgYW55IGFyZ3VtZW50IGlzIGludmFsaWQuCiAqCiAqIE5PVEVTCiAqICBJZiB0aGUgb2JqZWN0IHRvIGJlIHRlc3RlZCBkb2VzIG5vdCBleHBvc2UgdGhlIElRdWVyeUluZm8oKSBpbnRlcmZhY2UgaXQKICogIHdpbGwgbm90IGJlIGlkZW50aWZpZWQgYXMgYW4gZXhwYW5kYWJsZSBmb2xkZXIuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSElzRXhwYW5kYWJsZUZvbGRlcihMUFNIRUxMRk9MREVSIGxwRm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CiAgSVF1ZXJ5SW5mbyAqbHBJbmZvOwoKICBpZiAobHBGb2xkZXIgJiYgcGlkbCkKICB7CiAgICBoUmV0ID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YobHBGb2xkZXIsIE5VTEwsIDEsICZwaWRsLCAmSUlEX0lRdWVyeUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgKHZvaWQqKikmbHBJbmZvKTsKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICAgIGhSZXQgPSBTX0ZBTFNFOyAvKiBEb2Vzbid0IGV4cG9zZSBJUXVlcnlJbmZvICovCiAgICBlbHNlCiAgICB7CiAgICAgIERXT1JEIGR3RmxhZ3MgPSAwOwoKICAgICAgLyogTVNETiBzdGF0ZXMgb2YgSVF1ZXJ5SW5mb19HZXRJbmZvRmxhZ3MoKSB0aGF0ICJUaGlzIG1ldGhvZCBpcyBub3QKICAgICAgICogY3VycmVudGx5IHVzZWQiLiBSZWFsbHk/IFlvdSB3b3VsZG4ndCBiZSBob2xkaW5nIG91dCBvbiBtZSB3b3VsZCB5b3U/CiAgICAgICAqLwogICAgICBoUmV0ID0gSVF1ZXJ5SW5mb19HZXRJbmZvRmxhZ3MobHBJbmZvLCAmZHdGbGFncyk7CgogICAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgICB7CiAgICAgICAgLyogMHgyIGlzIGFuIHVuZG9jdW1lbnRlZCBmbGFnIGFwcGFyZW50bHkgaW5kaWNhdGluZyBleHBhbmRhYmlsaXR5ICovCiAgICAgICAgaFJldCA9IGR3RmxhZ3MgJiAweDIgPyBTX09LIDogU19GQUxTRTsKICAgICAgfQoKICAgICAgSVF1ZXJ5SW5mb19SZWxlYXNlKGxwSW5mbyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTk3XQogKgogKiBCbGFuayBvdXQgYSByZWdpb24gb2YgdGV4dCBieSBkcmF3aW5nIHRoZSBiYWNrZ3JvdW5kIG9ubHkuCiAqCiAqIFBBUkFNUwogKiAgaERDICAgW0ldIERldmljZSBjb250ZXh0IHRvIGRyYXcgaW4KICogIHBSZWN0IFtJXSBBcmVhIHRvIGRyYXcgaW4KICogIGNSZWYgIFtJXSBDb2xvciB0byBkcmF3IGluCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgU0hGaWxsUmVjdENscihIREMgaERDLCBMUENSRUNUIHBSZWN0LCBDT0xPUlJFRiBjUmVmKQp7CiAgICBDT0xPUlJFRiBjT2xkQ29sb3IgPSBTZXRCa0NvbG9yKGhEQywgY1JlZik7CiAgICBFeHRUZXh0T3V0QShoREMsIDAsIDAsIEVUT19PUEFRVUUsIHBSZWN0LCAwLCAwLCAwKTsKICAgIFNldEJrQ29sb3IoaERDLCBjT2xkQ29sb3IpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOThdCiAqCiAqIFJldHVybiB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGEga2V5IGluIGEgbWFwLgogKgogKiBQQVJBTVMKICogIGxwS2V5cyAgIFtJXSBBIGxpc3Qgb2Yga2V5cyBvZiBsZW5ndGggaUxlbgogKiAgbHBWYWx1ZXMgW0ldIEEgbGlzdCBvZiB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxwS2V5cywgb2YgbGVuZ3RoIGlMZW4KICogIGlMZW4gICAgIFtJXSBMZW5ndGggb2YgYm90aCBscEtleXMgYW5kIGxwVmFsdWVzCiAqICBpS2V5ICAgICBbSV0gVGhlIGtleSB2YWx1ZSB0byBsb29rIHVwIGluIGxwS2V5cwogKgogKiBSRVRVUk5TCiAqICBUaGUgdmFsdWUgaW4gbHBWYWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGlLZXksIG9yIC0xIGlmIGlLZXkgaXMgbm90CiAqICBmb3VuZCBpbiBscEtleXMuCiAqCiAqIE5PVEVTCiAqICAtIElmIHR3byBlbGVtZW50cyBpbiB0aGUgbWFwIHNoYXJlIHRoZSBzYW1lIGtleSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zCiAqICAgIHRoZSB2YWx1ZSBjbG9zZXN0IHRvIHRoZSBzdGFydCBvZiB0aGUgbWFwCiAqICAtIFRoZSBuYXRpdmUgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIGNyYXNoZXMgaWYgbHBLZXlzIG9yIGxwVmFsdWVzIGlzIE5VTEwuCiAqLwppbnQgV0lOQVBJIFNIU2VhcmNoTWFwSW50KGNvbnN0IGludCAqbHBLZXlzLCBjb25zdCBpbnQgKmxwVmFsdWVzLCBpbnQgaUxlbiwgaW50IGlLZXkpCnsKICBpZiAobHBLZXlzICYmIGxwVmFsdWVzKQogIHsKICAgIGludCBpID0gMDsKCiAgICB3aGlsZSAoaSA8IGlMZW4pCiAgICB7CiAgICAgIGlmIChscEtleXNbaV0gPT0gaUtleSkKICAgICAgICByZXR1cm4gbHBWYWx1ZXNbaV07IC8qIEZvdW5kICovCiAgICAgIGkrKzsKICAgIH0KICB9CiAgcmV0dXJuIC0xOyAvKiBOb3QgZm91bmQgKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTldCiAqCiAqIENvcHkgYW4gaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUEFSQU1TCiAqICAgbHBwRGVzdCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29weQogKiAgIGxwVW5rbm93biBbSV0gU291cmNlIGZvciBjb3B5CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBJVW5rbm93bl9TZXQoSVVua25vd24gKipscHBEZXN0LCBJVW5rbm93biAqbHBVbmtub3duKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwcERlc3QsIGxwVW5rbm93bik7CgogIGlmIChscHBEZXN0KQogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBEZXN0KTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICAvKiBDb3B5ICovCiAgICBJVW5rbm93bl9BZGRSZWYobHBVbmtub3duKTsKICAgICpscHBEZXN0ID0gbHBVbmtub3duOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMF0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heVFTRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBQVk9JRCBscFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGR1VJRCByaWlkQ21kR3JwLCBVTE9ORyBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBGSVhNRSgiKCVwLCVwLCVwLCVkLCVwLCVwKSAtIHN0dWJcbiIsCiAgICAgICAgbHBVbmtub3duLCBscFJlc2VydmVkLCByaWlkQ21kR3JwLCBjQ21kcywgcHJnQ21kcywgcENtZFRleHQpOwoKICAvKiBGSVhNRTogQ2FsbHMgSXNRU0ZvcndhcmQgJiBJVW5rbm93bl9RdWVyeVN0YXR1cyAqLwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBNYXlFeGVjRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBJTlQgaVVuaywgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBuQ21kSUQsIERXT1JEIG5DbWRleGVjb3B0LCBWQVJJQU5UKiBwdmFJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFOVCogcHZhT3V0KQp7CiAgRklYTUUoIiglcCwlZCwlcCwlZCwlZCwlcCwlcCkgLSBzdHViIVxuIiwgbHBVbmtub3duLCBpVW5rLCBwZ3VpZENtZEdyb3VwLAogICAgICAgIG5DbWRJRCwgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBJc1FTRm9yd2FyZChSRUZHVUlEIHBndWlkQ21kR3JvdXAsVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcykKewogIEZJWE1FKCIoJXAsJWQsJXApIC0gc3R1YiFcbiIsIHBndWlkQ21kR3JvdXAsIGNDbWRzLCBwcmdDbWRzKTsKICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBACVtTSExXQVBJLjIwNF0KICoKICogRGV0ZXJtaW5lIGlmIGEgd2luZG93IGlzIG5vdCBhIGNoaWxkIG9mIGFub3RoZXIgd2luZG93LgogKgogKiBQQVJBTVMKICogaFBhcmVudCBbSV0gU3VzcGVjdGVkIHBhcmVudCB3aW5kb3cKICogaENoaWxkICBbSV0gU3VzcGVjdGVkIGNoaWxkIHdpbmRvdwogKgogKiBSRVRVUk5TCiAqIFRSVUU6ICBJZiBoQ2hpbGQgaXMgYSBjaGlsZCB3aW5kb3cgb2YgaFBhcmVudAogKiBGQUxTRTogSWYgaENoaWxkIGlzIG5vdCBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50LCBvciB0aGV5IGFyZSBlcXVhbAogKi8KQk9PTCBXSU5BUEkgU0hJc0NoaWxkT3JTZWxmKEhXTkQgaFBhcmVudCwgSFdORCBoQ2hpbGQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFBhcmVudCwgaENoaWxkKTsKCiAgaWYgKCFoUGFyZW50IHx8ICFoQ2hpbGQpCiAgICByZXR1cm4gVFJVRTsKICBlbHNlIGlmKGhQYXJlbnQgPT0gaENoaWxkKQogICAgcmV0dXJuIEZBTFNFOwogIHJldHVybiAhSXNDaGlsZChoUGFyZW50LCBoQ2hpbGQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICBGRFNBIGZ1bmN0aW9ucy4gIE1hbmFnZSBhIGR5bmFtaWMgYXJyYXkgb2YgZml4ZWQgc2l6ZSBtZW1vcnkgYmxvY2tzLgogKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIERXT1JEIG51bV9pdGVtczsgICAgICAgLyogTnVtYmVyIG9mIGVsZW1lbnRzIGluc2VydGVkICovCiAgICB2b2lkICptZW07ICAgICAgICAgICAgIC8qIFB0ciB0byBhcnJheSAqLwogICAgRFdPUkQgYmxvY2tzX2FsbG9jZWQ7ICAvKiBOdW1iZXIgb2YgZWxlbWVudHMgYWxsb2NhdGVkICovCiAgICBCWVRFIGluYzsgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBlbGVtZW50cyB0byBncm93IGJ5IHdoZW4gd2UgbmVlZCB0byBleHBhbmQgKi8KICAgIEJZVEUgYmxvY2tfc2l6ZTsgICAgICAgLyogU2l6ZSBpbiBieXRlcyBvZiBhbiBlbGVtZW50ICovCiAgICBCWVRFIGZsYWdzOyAgICAgICAgICAgIC8qIEZsYWdzICovCn0gRkRTQV9pbmZvOwoKI2RlZmluZSBGRFNBX0ZMQUdfSU5URVJOQUxfQUxMT0MgMHgwMSAvKiBXaGVuIHNldCB3ZSBoYXZlIGFsbG9jYXRlZCBtZW0gaW50ZXJuYWxseSAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwOF0KICoKICogSW5pdGlhbGl6ZSBhbiBGRFNBIGFycmF5LgogKi8KQk9PTCBXSU5BUEkgRkRTQV9Jbml0aWFsaXplKERXT1JEIGJsb2NrX3NpemUsIERXT1JEIGluYywgRkRTQV9pbmZvICppbmZvLCB2b2lkICptZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBpbml0X2Jsb2NrcykKewogICAgVFJBQ0UoIigweCUwOHggMHglMDh4ICVwICVwIDB4JTA4eClcbiIsIGJsb2NrX3NpemUsIGluYywgaW5mbywgbWVtLCBpbml0X2Jsb2Nrcyk7CgogICAgaWYoaW5jID09IDApCiAgICAgICAgaW5jID0gMTsKCiAgICBpZihtZW0pCiAgICAgICAgbWVtc2V0KG1lbSwgMCwgYmxvY2tfc2l6ZSAqIGluaXRfYmxvY2tzKTsKICAgIAogICAgaW5mby0+bnVtX2l0ZW1zID0gMDsKICAgIGluZm8tPmluYyA9IGluYzsKICAgIGluZm8tPm1lbSA9IG1lbTsKICAgIGluZm8tPmJsb2Nrc19hbGxvY2VkID0gaW5pdF9ibG9ja3M7CiAgICBpbmZvLT5ibG9ja19zaXplID0gYmxvY2tfc2l6ZTsKICAgIGluZm8tPmZsYWdzID0gMDsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwOV0KICoKICogRGVzdHJveSBhbiBGRFNBIGFycmF5CiAqLwpCT09MIFdJTkFQSSBGRFNBX0Rlc3Ryb3koRkRTQV9pbmZvICppbmZvKQp7CiAgICBUUkFDRSgiKCVwKVxuIiwgaW5mbyk7CgogICAgaWYoaW5mby0+ZmxhZ3MgJiBGRFNBX0ZMQUdfSU5URVJOQUxfQUxMT0MpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mby0+bWVtKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTBdCiAqCiAqIEluc2VydCBlbGVtZW50IGludG8gYW4gRkRTQSBhcnJheQogKi8KRFdPUkQgV0lOQVBJIEZEU0FfSW5zZXJ0SXRlbShGRFNBX2luZm8gKmluZm8sIERXT1JEIHdoZXJlLCBjb25zdCB2b2lkICpibG9jaykKewogICAgVFJBQ0UoIiglcCAweCUwOHggJXApXG4iLCBpbmZvLCB3aGVyZSwgYmxvY2spOwogICAgaWYod2hlcmUgPiBpbmZvLT5udW1faXRlbXMpCiAgICAgICAgd2hlcmUgPSBpbmZvLT5udW1faXRlbXM7CgogICAgaWYoaW5mby0+bnVtX2l0ZW1zID49IGluZm8tPmJsb2Nrc19hbGxvY2VkKQogICAgewogICAgICAgIERXT1JEIHNpemUgPSAoaW5mby0+YmxvY2tzX2FsbG9jZWQgKyBpbmZvLT5pbmMpICogaW5mby0+YmxvY2tfc2l6ZTsKICAgICAgICBpZihpbmZvLT5mbGFncyAmIDB4MSkKICAgICAgICAgICAgaW5mby0+bWVtID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgaW5mby0+bWVtLCBzaXplKTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b2lkICpvbGRfbWVtID0gaW5mby0+bWVtOwogICAgICAgICAgICBpbmZvLT5tZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZSk7CiAgICAgICAgICAgIG1lbWNweShpbmZvLT5tZW0sIG9sZF9tZW0sIGluZm8tPmJsb2Nrc19hbGxvY2VkICogaW5mby0+YmxvY2tfc2l6ZSk7CiAgICAgICAgfQogICAgICAgIGluZm8tPmJsb2Nrc19hbGxvY2VkICs9IGluZm8tPmluYzsKICAgICAgICBpbmZvLT5mbGFncyB8PSAweDE7CiAgICB9CgogICAgaWYod2hlcmUgPCBpbmZvLT5udW1faXRlbXMpCiAgICB7CiAgICAgICAgbWVtbW92ZSgoY2hhciopaW5mby0+bWVtICsgKHdoZXJlICsgMSkgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGNoYXIqKWluZm8tPm1lbSArIHdoZXJlICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChpbmZvLT5udW1faXRlbXMgLSB3aGVyZSkgKiBpbmZvLT5ibG9ja19zaXplKTsKICAgIH0KICAgIG1lbWNweSgoY2hhciopaW5mby0+bWVtICsgd2hlcmUgKiBpbmZvLT5ibG9ja19zaXplLCBibG9jaywgaW5mby0+YmxvY2tfc2l6ZSk7CgogICAgaW5mby0+bnVtX2l0ZW1zKys7CiAgICByZXR1cm4gd2hlcmU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTFdCiAqCiAqIERlbGV0ZSBhbiBlbGVtZW50IGZyb20gYW4gRkRTQSBhcnJheS4KICovCkJPT0wgV0lOQVBJIEZEU0FfRGVsZXRlSXRlbShGRFNBX2luZm8gKmluZm8sIERXT1JEIHdoZXJlKQp7CiAgICBUUkFDRSgiKCVwIDB4JTA4eClcbiIsIGluZm8sIHdoZXJlKTsKCiAgICBpZih3aGVyZSA+PSBpbmZvLT5udW1faXRlbXMpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmKHdoZXJlIDwgaW5mby0+bnVtX2l0ZW1zIC0gMSkKICAgIHsKICAgICAgICBtZW1tb3ZlKChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoY2hhciopaW5mby0+bWVtICsgKHdoZXJlICsgMSkgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGluZm8tPm51bV9pdGVtcyAtIHdoZXJlIC0gMSkgKiBpbmZvLT5ibG9ja19zaXplKTsKICAgIH0KICAgIG1lbXNldCgoY2hhciopaW5mby0+bWVtICsgKGluZm8tPm51bV9pdGVtcyAtIDEpICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAwLCBpbmZvLT5ibG9ja19zaXplKTsKICAgIGluZm8tPm51bV9pdGVtcy0tOwogICAgcmV0dXJuIFRSVUU7Cn0KCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBSRUZJSUQgICByZWZpZDsKICAgIERXT1JEICAgIGluZHg7Cn0gSUZBQ0VfSU5ERVhfVEJMOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxOV0KICoKICogQ2FsbCBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgpIG9uIGEgdGFibGUgb2Ygb2JqZWN0cy4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiBvciBFX05PSU5URVJGQUNFLgogKi8KSFJFU1VMVCBXSU5BUEkgUUlTZWFyY2goCglMUFZPSUQgdywgICAgICAgICAgIC8qIFtpbl0gICBUYWJsZSBvZiBpbnRlcmZhY2VzICovCglJRkFDRV9JTkRFWF9UQkwgKngsIC8qIFtpbl0gICBBcnJheSBvZiBSRUZJSURzIGFuZCBpbmRleGVzIGludG8gdGhlIHRhYmxlICovCglSRUZJSUQgcmlpZCwgICAgICAgIC8qIFtpbl0gICBSRUZJSUQgdG8gZ2V0IGludGVyZmFjZSBmb3IgKi8KCUxQVk9JRCAqcHB2KSAgICAgICAgICAvKiBbb3V0XSAgRGVzdGluYXRpb24gZm9yIGludGVyZmFjZSBwb2ludGVyICovCnsKCUhSRVNVTFQgcmV0OwoJSVVua25vd24gKmFfdnRibDsKCUlGQUNFX0lOREVYX1RCTCAqeG1vdmU7CgoJVFJBQ0UoIiglcCAlcCAlcyAlcClcbiIsIHcseCxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdik7CglpZiAocHB2KSB7CgkgICAgeG1vdmUgPSB4OwoJICAgIHdoaWxlICh4bW92ZS0+cmVmaWQpIHsKCQlUUkFDRSgidHJ5aW5nIChpbmR4ICVkKSAlc1xuIiwgeG1vdmUtPmluZHgsIGRlYnVnc3RyX2d1aWQoeG1vdmUtPnJlZmlkKSk7CgkJaWYgKElzRXF1YWxJSUQocmlpZCwgeG1vdmUtPnJlZmlkKSkgewoJCSAgICBhX3Z0YmwgPSAoSVVua25vd24qKSh4bW92ZS0+aW5keCArIChMUEJZVEUpdyk7CgkJICAgIFRSQUNFKCJtYXRjaGVkLCByZXR1cm5pbmcgKCVwKVxuIiwgYV92dGJsKTsKCQkgICAgKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCSAgICBJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQkgICAgcmV0dXJuIFNfT0s7CgkJfQoJCXhtb3ZlKys7CgkgICAgfQoKCSAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgewoJCWFfdnRibCA9IChJVW5rbm93biopKHgtPmluZHggKyAoTFBCWVRFKXcpOwoJCVRSQUNFKCJyZXR1cm5pbmcgZmlyc3QgZm9yIElVbmtub3duICglcClcbiIsIGFfdnRibCk7CgkJKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCUlVbmtub3duX0FkZFJlZihhX3Z0YmwpOwoJCXJldHVybiBTX09LOwoJICAgIH0KCSAgICAqcHB2ID0gMDsKCSAgICByZXQgPSBFX05PSU5URVJGQUNFOwoJfSBlbHNlCgkgICAgcmV0ID0gRV9QT0lOVEVSOwoKCVRSQUNFKCItLSAweCUwOHhcbiIsIHJldCk7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjIxXQogKgogKiBSZW1vdmUgdGhlICJQcm9wRGxnRm9udCIgcHJvcGVydHkgZnJvbSBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kIFtJXSBXaW5kb3cgdG8gcmVtb3ZlIHRoZSBwcm9wZXJ0eSBmcm9tCiAqCiAqIFJFVFVSTlMKICogIEEgaGFuZGxlIHRvIHRoZSByZW1vdmVkIHByb3BlcnR5LCBvciBOVUxMIGlmIGl0IGRpZCBub3QgZXhpc3QuCiAqLwpIQU5ETEUgV0lOQVBJIFNIUmVtb3ZlRGVmYXVsdERpYWxvZ0ZvbnQoSFdORCBoV25kKQp7CiAgSEFORExFIGhQcm9wOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIGhQcm9wID0gR2V0UHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CgogIGlmKGhQcm9wKQogIHsKICAgIERlbGV0ZU9iamVjdChoUHJvcCk7CiAgICBoUHJvcCA9IFJlbW92ZVByb3BBKGhXbmQsICJQcm9wRGxnRm9udCIpOwogIH0KICByZXR1cm4gaFByb3A7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzZdCiAqCiAqIExvYWQgdGhlIGluLXByb2Nlc3Mgc2VydmVyIG9mIGEgZ2l2ZW4gR1VJRC4KICoKICogUEFSQU1TCiAqICByZWZpaWQgW0ldIEdVSUQgb2YgdGhlIHNlcnZlciB0byBsb2FkLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIGhhbmRsZSB0byB0aGUgbG9hZGVkIHNlcnZlciBkbGwuCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgU0hQaW5EbGxPZkNMU0lEKFJFRklJRCByZWZpaWQpCnsKICAgIEhLRVkgbmV3a2V5OwogICAgRFdPUkQgdHlwZSwgY291bnQ7CiAgICBDSEFSIHZhbHVlW01BWF9QQVRIXSwgc3RyaW5nW01BWF9QQVRIXTsKCiAgICBzdHJjcHkoc3RyaW5nLCAiQ0xTSURcXCIpOwogICAgU0hTdHJpbmdGcm9tR1VJREEocmVmaWlkLCBzdHJpbmcgKyA2LCBzaXplb2Yoc3RyaW5nKS9zaXplb2YoY2hhcikgLSA2KTsKICAgIHN0cmNhdChzdHJpbmcsICJcXEluUHJvY1NlcnZlcjMyIik7CgogICAgY291bnQgPSBNQVhfUEFUSDsKICAgIFJlZ09wZW5LZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIHN0cmluZywgMCwgMSwgJm5ld2tleSk7CiAgICBSZWdRdWVyeVZhbHVlRXhBKG5ld2tleSwgMCwgMCwgJnR5cGUsIChQQllURSl2YWx1ZSwgJmNvdW50KTsKICAgIFJlZ0Nsb3NlS2V5KG5ld2tleSk7CiAgICByZXR1cm4gTG9hZExpYnJhcnlFeEEodmFsdWUsIDAsIDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM3XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hMV0FQSV8xODMuCiAqLwpEV09SRCBXSU5BUEkgU0hSZWdpc3RlckNsYXNzVyhXTkRDTEFTU1cgKiBscFduZENsYXNzKQp7CglXTkRDTEFTU1cgV25kQ2xhc3M7CgoJVFJBQ0UoIiglcCAlcylcbiIsbHBXbmRDbGFzcy0+aEluc3RhbmNlLCBkZWJ1Z3N0cl93KGxwV25kQ2xhc3MtPmxwc3pDbGFzc05hbWUpKTsKCglpZiAoR2V0Q2xhc3NJbmZvVyhscFduZENsYXNzLT5oSW5zdGFuY2UsIGxwV25kQ2xhc3MtPmxwc3pDbGFzc05hbWUsICZXbmRDbGFzcykpCgkJcmV0dXJuIFRSVUU7CglyZXR1cm4gUmVnaXN0ZXJDbGFzc1cobHBXbmRDbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzhdCiAqCiAqIFVucmVnaXN0ZXIgYSBsaXN0IG9mIGNsYXNzZXMuCiAqCiAqIFBBUkFNUwogKiAgaEluc3QgICAgICBbSV0gQXBwbGljYXRpb24gaW5zdGFuY2UgdGhhdCByZWdpc3RlcmVkIHRoZSBjbGFzc2VzCiAqICBscHBDbGFzc2VzIFtJXSBMaXN0IG9mIGNsYXNzIG5hbWVzCiAqICBpQ291bnQgICAgIFtJXSBOdW1iZXIgb2YgbmFtZXMgaW4gbHBwQ2xhc3NlcwogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8Kdm9pZCBXSU5BUEkgU0hVbnJlZ2lzdGVyQ2xhc3Nlc0EoSElOU1RBTkNFIGhJbnN0LCBMUENTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU0EgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb0EoaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NBKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzldCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSFVucmVnaXN0ZXJDbGFzc2VzQS4KICovCnZvaWQgV0lOQVBJIFNIVW5yZWdpc3RlckNsYXNzZXNXKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiAqbHBwQ2xhc3NlcywgSU5UIGlDb3VudCkKewogIFdORENMQVNTVyBXbmRDbGFzczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGhJbnN0LCBscHBDbGFzc2VzLCBpQ291bnQpOwoKICB3aGlsZSAoaUNvdW50ID4gMCkKICB7CiAgICBpZiAoR2V0Q2xhc3NJbmZvVyhoSW5zdCwgKmxwcENsYXNzZXMsICZXbmRDbGFzcykpCiAgICAgIFVucmVnaXN0ZXJDbGFzc1coKmxwcENsYXNzZXMsIGhJbnN0KTsKICAgIGxwcENsYXNzZXMrKzsKICAgIGlDb3VudC0tOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0MF0KICoKICogQ2FsbCBUaGUgY29ycmVjdCAoQXNjaWkvVW5pY29kZSkgZGVmYXVsdCB3aW5kb3cgcHJvY2VkdXJlIGZvciBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gV2luZG93IHRvIGNhbGwgdGhlIGRlZmF1bHQgcHJvY2VkdXJlIGZvcgogKiAgdU1lc3NhZ2UgW0ldIE1lc3NhZ2UgSUQKICogIHdQYXJhbSAgIFtJXSBXUEFSQU0gb2YgbWVzc2FnZQogKiAgbFBhcmFtICAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXN1bHQgb2YgY2FsbGluZyBEZWZXaW5kb3dQcm9jQSgpIG9yIERlZldpbmRvd1Byb2NXKCkuCiAqLwpMUkVTVUxUIENBTExCQUNLIFNIRGVmV2luZG93UHJvYyhIV05EIGhXbmQsIFVJTlQgdU1lc3NhZ2UsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKCWlmIChJc1dpbmRvd1VuaWNvZGUoaFduZCkpCgkJcmV0dXJuIERlZldpbmRvd1Byb2NXKGhXbmQsIHVNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjI1Nl0KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldFNpdGUoTFBVTktOT1dOIGxwVW5rbm93biwgUkVGSUlEIGlpZCwgUFZPSUQgKmxwcFNpdGUpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CiAgTFBPQkpFQ1RXSVRIU0lURSBscFNpdGUgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGlpZCksIGxwcFNpdGUpOwoKICBpZiAobHBVbmtub3duICYmIGlpZCAmJiBscHBTaXRlKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9iamVjdFdpdGhTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwU2l0ZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPYmplY3RXaXRoU2l0ZV9HZXRTaXRlKGxwU2l0ZSwgaWlkLCBscHBTaXRlKTsKICAgICAgSU9iamVjdFdpdGhTaXRlX1JlbGVhc2UobHBTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNTddCiAqCiAqIENyZWF0ZSBhIHdvcmtlciB3aW5kb3cgdXNpbmcgQ3JlYXRlV2luZG93RXhBKCkuCiAqCiAqIFBBUkFNUwogKiAgd25kUHJvYyAgICBbSV0gV2luZG93IHByb2NlZHVyZQogKiAgaFduZFBhcmVudCBbSV0gUGFyZW50IHdpbmRvdwogKiAgZHdFeFN0eWxlICBbSV0gRXh0cmEgc3R5bGUgZmxhZ3MKICogIGR3U3R5bGUgICAgW0ldIFN0eWxlIGZsYWdzCiAqICBoTWVudSAgICAgIFtJXSBXaW5kb3cgbWVudQogKiAgeiAgICAgICAgICBbSV0gVW5rbm93bgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgd2luZG93IGhhbmRsZSBvZiB0aGUgbmV3bHkgY3JlYXRlZCB3aW5kb3cuCiAqICBGYWlsdXJlOiAwLgogKi8KSFdORCBXSU5BUEkgU0hDcmVhdGVXb3JrZXJXaW5kb3dBKExPTkcgd25kUHJvYywgSFdORCBoV25kUGFyZW50LCBEV09SRCBkd0V4U3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3R5bGUsIEhNRU5VIGhNZW51LCBMT05HIHopCnsKICBzdGF0aWMgY29uc3QgY2hhciBzekNsYXNzW10gPSAiV29ya2VyQSI7CiAgV05EQ0xBU1NBIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOHgsJXAsMHglMDh4LDB4JTA4eCwlcCwweCUwOHgpXG4iLAogICAgICAgICB3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogQ3JlYXRlIFdpbmRvdyBjbGFzcyAqLwogIHdjLnN0eWxlICAgICAgICAgPSAwOwogIHdjLmxwZm5XbmRQcm9jICAgPSBEZWZXaW5kb3dQcm9jQTsKICB3Yy5jYkNsc0V4dHJhICAgID0gMDsKICB3Yy5jYlduZEV4dHJhICAgID0gNDsKICB3Yy5oSW5zdGFuY2UgICAgID0gc2hsd2FwaV9oSW5zdGFuY2U7CiAgd2MuaEljb24gICAgICAgICA9IE5VTEw7CiAgd2MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JBKE5VTEwsIChMUFNUUilJRENfQVJST1cpOwogIHdjLmhickJhY2tncm91bmQgPSAoSEJSVVNIKShDT0xPUl9CVE5GQUNFICsgMSk7CiAgd2MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgd2MubHBzekNsYXNzTmFtZSA9IHN6Q2xhc3M7CgogIFNIUmVnaXN0ZXJDbGFzc0EoJndjKTsgLyogUmVnaXN0ZXIgY2xhc3MgKi8KCiAgLyogRklYTUU6IFNldCBleHRyYSBiaXRzIGluIGR3RXhTdHlsZSAqLwoKICBoV25kID0gQ3JlYXRlV2luZG93RXhBKGR3RXhTdHlsZSwgc3pDbGFzcywgMCwgZHdTdHlsZSwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIGhXbmRQYXJlbnQsIGhNZW51LCBzaGx3YXBpX2hJbnN0YW5jZSwgMCk7CiAgaWYgKGhXbmQpCiAgewogICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgRFdMUF9NU0dSRVNVTFQsIHopOwoKICAgIGlmICh3bmRQcm9jKQogICAgICBTZXRXaW5kb3dMb25nUHRyQShoV25kLCBHV0xQX1dORFBST0MsIHduZFByb2MpOwogIH0KICByZXR1cm4gaFduZDsKfQoKdHlwZWRlZiBzdHJ1Y3QgdGFnUE9MSUNZREFUQQp7CiAgRFdPUkQgcG9saWN5OyAgICAgICAgLyogZmxhZ3MgdmFsdWUgcGFzc2VkIHRvIFNIUmVzdHJpY3RlZCAqLwogIExQQ1dTVFIgYXBwc3RyOyAgICAgIC8qIGFwcGxpY2F0aW9uIHN0ciBzdWNoIGFzICJFeHBsb3JlciIgKi8KICBMUENXU1RSIGtleXN0cjsgICAgICAvKiBuYW1lIG9mIHRoZSBhY3R1YWwgcmVnaXN0cnkga2V5IC8gcG9saWN5ICovCn0gUE9MSUNZREFUQSwgKkxQUE9MSUNZREFUQTsKCiNkZWZpbmUgU0hFTExfTk9fUE9MSUNZIDB4ZmZmZmZmZmYKCi8qIGRlZmF1bHQgc2hlbGwgcG9saWN5IHJlZ2lzdHJ5IGtleSAqLwpzdGF0aWMgY29uc3QgV0NIQVIgc3RyUmVnaXN0cnlQb2xpY3lXW10gPSB7J1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLCdNJywnaScsJ2MnLCdyJywnbycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXFwnLCdQJywnbycsJ2wnLCdpJywnYycsJ2knLCdlJywncycsMH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgICBbU0hMV0FQSS4yNzFdCiAqCiAqIFJldHJpZXZlIGEgcG9saWN5IHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LgogKgogKiBQQVJBTVMKICogIGxwU3ViS2V5ICAgW0ldICAgcmVnaXN0cnkga2V5IG5hbWUKICogIGxwU3ViTmFtZSAgW0ldICAgc3VibmFtZSBvZiByZWdpc3RyeSBrZXkKICogIGxwVmFsdWUgICAgW0ldICAgdmFsdWUgbmFtZSBvZiByZWdpc3RyeSB2YWx1ZQogKgogKiBSRVRVUk5TCiAqICB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeSBrZXkgb3IgMCBpZiBub3QgZm91bmQKICovCkRXT1JEIFdJTkFQSSBTSEdldFJlc3RyaWN0aW9uKExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBTdWJOYW1lLCBMUENXU1RSIGxwVmFsdWUpCnsKCURXT1JEIHJldHZhbCwgZGF0c2l6ZSA9IHNpemVvZihyZXR2YWwpOwoJSEtFWSBoS2V5OwoKCWlmICghbHBTdWJLZXkpCgkgIGxwU3ViS2V5ID0gc3RyUmVnaXN0cnlQb2xpY3lXOwoKCXJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfTE9DQUxfTUFDSElORSwgbHBTdWJLZXksICZoS2V5KTsKICAgIGlmIChyZXR2YWwgIT0gRVJST1JfU1VDQ0VTUykKCSAgcmV0dmFsID0gUmVnT3BlbktleVcoSEtFWV9DVVJSRU5UX1VTRVIsIGxwU3ViS2V5LCAmaEtleSk7CglpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHVybiAwOwoKCVNIR2V0VmFsdWVXKGhLZXksIGxwU3ViTmFtZSwgbHBWYWx1ZSwgTlVMTCwgKExQQllURSkmcmV0dmFsLCAmZGF0c2l6ZSk7CglSZWdDbG9zZUtleShoS2V5KTsKCXJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjY2XQogKgogKiBIZWxwZXIgZnVuY3Rpb24gdG8gcmV0cmlldmUgdGhlIHBvc3NpYmx5IGNhY2hlZCB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBwb2xpY3kKICoKICogUEFSQU1TCiAqICBwb2xpY3kgICAgIFtJXSAgIFRoZSBwb2xpY3kgdG8gbG9vayBmb3IKICogIGluaXRpYWwgICAgW0ldICAgTWFpbiByZWdpc3RyeSBrZXkgdG8gb3BlbiwgaWYgTlVMTCB1c2UgZGVmYXVsdAogKiAgcG9sVGFibGUgICBbSV0gICBUYWJsZSBvZiBrbm93biBwb2xpY2llcywgMCB0ZXJtaW5hdGVkCiAqICBwb2xBcnIgICAgIFtJXSAgIENhY2hlIGFycmF5IG9mIHBvbGljeSB2YWx1ZXMKICoKICogUkVUVVJOUwogKiAgVGhlIHJldHJpZXZlZCBwb2xpY3kgdmFsdWUgb3IgMCBpZiBub3Qgc3VjY2Vzc2Z1bAogKgogKiBOT1RFUwogKiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJ5IHRoZSBuYXRpdmUgU0hSZXN0cmljdGVkIGZ1bmN0aW9uIHRvIHNlYXJjaCBmb3IgdGhlCiAqICBwb2xpY3kgYW5kIGNhY2hlIGl0IG9uY2UgcmV0cmlldmVkLiBUaGUgY3VycmVudCBXaW5lIGltcGxlbWVudGF0aW9uIHVzZXMgYQogKiAgZGlmZmVyZW50IFBPTElDWURBVEEgc3RydWN0dXJlIGFuZCBpbXBsZW1lbnRzIGEgc2ltaWxhciBhbGdvcml0aG0gYWRhcHRlZCB0bwogKiAgdGhhdCBzdHJ1Y3R1cmUuCiAqLwpEV09SRCBXSU5BUEkgU0hSZXN0cmljdGlvbkxvb2t1cCgKCURXT1JEIHBvbGljeSwKCUxQQ1dTVFIgaW5pdGlhbCwKCUxQUE9MSUNZREFUQSBwb2xUYWJsZSwKCUxQRFdPUkQgcG9sQXJyKQp7CglUUkFDRSgiKDB4JTA4eCAlcyAlcCAlcClcbiIsIHBvbGljeSwgZGVidWdzdHJfdyhpbml0aWFsKSwgcG9sVGFibGUsIHBvbEFycik7CgoJaWYgKCFwb2xUYWJsZSB8fCAhcG9sQXJyKQoJICByZXR1cm4gMDsKCglmb3IgKDtwb2xUYWJsZS0+cG9saWN5OyBwb2xUYWJsZSsrLCBwb2xBcnIrKykKCXsKCSAgaWYgKHBvbGljeSA9PSBwb2xUYWJsZS0+cG9saWN5KQoJICB7CgkgICAgLyogd2UgaGF2ZSBhIGtub3duIHBvbGljeSAqLwoKCSAgICAvKiBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQgKi8KCQlpZiAoKnBvbEFyciA9PSBTSEVMTF9OT19QT0xJQ1kpCgkgICAgICAqcG9sQXJyID0gU0hHZXRSZXN0cmljdGlvbihpbml0aWFsLCBwb2xUYWJsZS0+YXBwc3RyLCBwb2xUYWJsZS0+a2V5c3RyKTsKCSAgICByZXR1cm4gKnBvbEFycjsKCSAgfQoJfQoJLyogd2UgZG9uJ3Qga25vdyB0aGlzIHBvbGljeSwgcmV0dXJuIDAgKi8KCVRSQUNFKCJ1bmtub3duIHBvbGljeTogKCUwOHgpXG4iLCBwb2xpY3kpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjddCiAqCiAqIEdldCBhbiBpbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIHBwdiBjb250YWlucyB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogICBUaGlzIFF1ZXJ5SW50ZXJmYWNlIGFza3MgdGhlIGlubmVyIG9iamVjdCBmb3IgYW4gaW50ZXJmYWNlLiBJbiBjYXNlCiAqICAgb2YgYWdncmVnYXRpb24gdGhpcyByZXF1ZXN0IHdvdWxkIGJlIGZvcndhcmRlZCBieSB0aGUgaW5uZXIgdG8gdGhlCiAqICAgb3V0ZXIgb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIGFza3MgdGhlIGlubmVyIG9iamVjdCBkaXJlY3RseSBmb3IgdGhlCiAqICAgaW50ZXJmYWNlIGNpcmN1bXZlbnRpbmcgdGhlIGZvcndhcmRpbmcgdG8gdGhlIG91dGVyIG9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIFNIV2Vha1F1ZXJ5SW50ZXJmYWNlKAoJSVVua25vd24gKiBwVW5rLCAgIC8qIFtpbl0gT3V0ZXIgb2JqZWN0ICovCglJVW5rbm93biAqIHBJbm5lciwgLyogW2luXSBJbm5lciBvYmplY3QgKi8KCUlJRCAqIHJpaWQsIC8qIFtpbl0gSW50ZXJmYWNlIEdVSUQgdG8gcXVlcnkgZm9yICovCglMUFZPSUQqIHBwdikgLyogW291dF0gRGVzdGluYXRpb24gZm9yIHF1ZXJpZWQgaW50ZXJmYWNlICovCnsKCUhSRVNVTFQgaHJldCA9IEVfTk9JTlRFUkZBQ0U7CglUUkFDRSgiKHBVbms9JXAgcElubmVyPSVwXG5cdElJRDogICVzICVwKVxuIixwVW5rLHBJbm5lcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKCSpwcHYgPSBOVUxMOwoJaWYocFVuayAmJiBwSW5uZXIpIHsKCSAgICBocmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElubmVyLCByaWlkLCAoTFBWT0lEKilwcHYpOwoJICAgIGlmIChTVUNDRUVERUQoaHJldCkpIElVbmtub3duX1JlbGVhc2UocFVuayk7Cgl9CglUUkFDRSgiLS0gMHglMDh4XG4iLCBocmV0KTsKCXJldHVybiBocmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY4XQogKgogKiBNb3ZlIGEgcmVmZXJlbmNlIGZyb20gb25lIGludGVyZmFjZSB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogICBscERlc3QgICAgIFtPXSBEZXN0aW5hdGlvbiB0byByZWNlaXZlIHRoZSByZWZlcmVuY2UKICogICBscHBVbmtub3duIFtPXSBTb3VyY2UgdG8gZ2l2ZSB1cCB0aGUgcmVmZXJlbmNlIHRvIGxwRGVzdAogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgU0hXZWFrUmVsZWFzZUludGVyZmFjZShJVW5rbm93biAqbHBEZXN0LCBJVW5rbm93biAqKmxwcFVua25vd24pCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBEZXN0LCBscHBVbmtub3duKTsKCiAgaWYgKCpscHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgUmVmZXJlbmNlKi8KICAgIElVbmtub3duX0FkZFJlZihscERlc3QpOwogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBVbmtub3duKTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjldCiAqCiAqIENvbnZlcnQgYW4gQVNDSUkgc3RyaW5nIG9mIGEgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyIFtJXSBTdHJpbmcgcmVwcmVzZW50aW5nIGEgQ0xTSUQgaW4gcmVnaXN0cnkgZm9ybWF0CiAqICBpZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjb252ZXJ0ZWQgQ0xTSUQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gaWQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCBDTFNJRC4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdBKExQQ1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgV0NIQVIgd0Nsc2lkWzQwXTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgaWRzdHIsIC0xLCB3Q2xzaWQsIHNpemVvZih3Q2xzaWQpL3NpemVvZihXQ0hBUikpOwogIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nKHdDbHNpZCwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3MF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIEdVSURGcm9tU3RyaW5nQS4KICovCkJPT0wgV0lOQVBJIEdVSURGcm9tU3RyaW5nVyhMUENXU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICAgIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nKChMUE9MRVNUUilpZHN0ciwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3Nl0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQgaW50byB0aGUgc2hlbGwsIGFuZCBzZXQgYSByZWdpc3RyeQogKiBrZXkgYWNjb3JkaW5nbHkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgMSwgSWYgdGhlIGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQuCiAqICAyLCBJZiB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkLgogKgogKiBOT1RFUwogKiAgVGhlIGtleSAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZWdyYXRlZEJyb3dzZXIiIGlzCiAqICBlaXRoZXIgc2V0IHRvIFRSVUUsIG9yIHJlbW92ZWQgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgZGVlbWVkCiAqICB0byBiZSBpbnRlZ3JhdGVkLgogKi8KRFdPUkQgV0lOQVBJIFdoaWNoUGxhdGZvcm0odm9pZCkKewogIHN0YXRpYyBjb25zdCBjaGFyIHN6SW50ZWdyYXRlZEJyb3dzZXJbXSA9ICJJbnRlZ3JhdGVkQnJvd3NlciI7CiAgc3RhdGljIERXT1JEIGR3U3RhdGUgPSAwOwogIEhLRVkgaEtleTsKICBEV09SRCBkd1JldCwgZHdEYXRhLCBkd1NpemU7CiAgSE1PRFVMRSBoc2hlbGwzMjsKCiAgaWYgKGR3U3RhdGUpCiAgICByZXR1cm4gZHdTdGF0ZTsKCiAgLyogSWYgc2hlbGwzMiBleHBvcnRzIERsbEdldFZlcnNpb24oKSwgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCAqLwogIGR3U3RhdGUgPSAxOwogIGhzaGVsbDMyID0gTG9hZExpYnJhcnlBKCJzaGVsbDMyLmRsbCIpOwogIGlmIChoc2hlbGwzMikKICB7CiAgICBGQVJQUk9DIHBEbGxHZXRWZXJzaW9uOwogICAgcERsbEdldFZlcnNpb24gPSBHZXRQcm9jQWRkcmVzcyhoc2hlbGwzMiwgIkRsbEdldFZlcnNpb24iKTsKICAgIGR3U3RhdGUgPSBwRGxsR2V0VmVyc2lvbiA/IDIgOiAxOwogICAgRnJlZUxpYnJhcnkoaHNoZWxsMzIpOwogIH0KCiAgLyogU2V0IG9yIGRlbGV0ZSB0aGUga2V5IGFjY29yZGluZ2x5ICovCiAgZHdSZXQgPSBSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwKICAgICAgICAgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXEludGVybmV0IEV4cGxvcmVyIiwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9BTExfQUNDRVNTLCAmaEtleSk7CiAgaWYgKCFkd1JldCkKICB7CiAgICBkd1JldCA9IFJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsICZkd1NpemUpOwoKICAgIGlmICghZHdSZXQgJiYgZHdTdGF0ZSA9PSAxKQogICAgewogICAgICAvKiBWYWx1ZSBleGlzdHMgYnV0IGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQgKi8KICAgICAgUmVnRGVsZXRlVmFsdWVBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIpOwogICAgfQogICAgZWxzZSBpZiAoZHdSZXQgJiYgZHdTdGF0ZSA9PSAyKQogICAgewogICAgICAvKiBCcm93c2VyIGlzIGludGVncmF0ZWQgYnV0IHZhbHVlIGRvZXMgbm90IGV4aXN0ICovCiAgICAgIGR3RGF0YSA9IFRSVUU7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgKExQQllURSkmZHdEYXRhLCBzaXplb2YoZHdEYXRhKSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoS2V5KTsKICB9CiAgcmV0dXJuIGR3U3RhdGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzhdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSENyZWF0ZVdvcmtlcldpbmRvd0EuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd1coTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsYXNzW10gPSB7ICdXJywgJ28nLCAncicsICdrJywgJ2UnLCAncicsICdXJywgJ1wwJyB9OwogIFdORENMQVNTVyB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDh4LCVwLDB4JTA4eCwweCUwOHgsJXAsMHglMDh4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIElmIG91ciBPUyBpcyBuYXRpdmVseSBBU0NJSSwgdXNlIHRoZSBBU0NJSSB2ZXJzaW9uICovCiAgaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpICAvKiBOVCAqLwogICAgcmV0dXJuIFNIQ3JlYXRlV29ya2VyV2luZG93QSh3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogQ3JlYXRlIFdpbmRvdyBjbGFzcyAqLwogIHdjLnN0eWxlICAgICAgICAgPSAwOwogIHdjLmxwZm5XbmRQcm9jICAgPSBEZWZXaW5kb3dQcm9jVzsKICB3Yy5jYkNsc0V4dHJhICAgID0gMDsKICB3Yy5jYlduZEV4dHJhICAgID0gNDsKICB3Yy5oSW5zdGFuY2UgICAgID0gc2hsd2FwaV9oSW5zdGFuY2U7CiAgd2MuaEljb24gICAgICAgICA9IE5VTEw7CiAgd2MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JXKE5VTEwsIChMUFdTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NXKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4Vyhkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIERXTFBfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzldCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VEZWZhdWx0Q29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCkKewogIHJldHVybiBTSEludm9rZUNvbW1hbmQoaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4MV0KICoKICogX1NIUGFja0Rpc3BQYXJhbXNWCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zVihESVNQUEFSQU1TICpwYXJhbXMsIFZBUklBTlRBUkcgKmFyZ3MsIFVJTlQgY250LCB2YV9saXN0IHZhbGlzdCkKewogIFZBUklBTlRBUkcgKml0ZXI7CgogIFRSQUNFKCIoJXAgJXAgJXUgLi4uKVxuIiwgcGFyYW1zLCBhcmdzLCBjbnQpOwoKICBwYXJhbXMtPnJndmFyZyA9IGFyZ3M7CiAgcGFyYW1zLT5yZ2Rpc3BpZE5hbWVkQXJncyA9IE5VTEw7CiAgcGFyYW1zLT5jQXJncyA9IGNudDsKICBwYXJhbXMtPmNOYW1lZEFyZ3MgPSAwOwoKICBpdGVyID0gYXJncytjbnQ7CgogIHdoaWxlKGl0ZXItLSA+IGFyZ3MpIHsKICAgIFZfVlQoaXRlcikgPSB2YV9hcmcodmFsaXN0LCBlbnVtIFZBUkVOVU0pOwoKICAgIFRSQUNFKCJ2dD0lZFxuIiwgVl9WVChpdGVyKSk7CgogICAgaWYoVl9WVChpdGVyKSAmIFZUX0JZUkVGKSB7CiAgICAgIFZfQllSRUYoaXRlcikgPSB2YV9hcmcodmFsaXN0LCBMUFZPSUQpOwogICAgfSBlbHNlIHsKICAgICAgc3dpdGNoKFZfVlQoaXRlcikpIHsKICAgICAgY2FzZSBWVF9JNDoKICAgICAgICBWX0k0KGl0ZXIpID0gdmFfYXJnKHZhbGlzdCwgTE9ORyk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgVlRfQlNUUjoKICAgICAgICBWX0JTVFIoaXRlcikgPSB2YV9hcmcodmFsaXN0LCBCU1RSKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBWVF9ESVNQQVRDSDoKICAgICAgICBWX0RJU1BBVENIKGl0ZXIpID0gdmFfYXJnKHZhbGlzdCwgSURpc3BhdGNoKik7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgVlRfQk9PTDoKICAgICAgICBWX0JPT0woaXRlcikgPSB2YV9hcmcodmFsaXN0LCBpbnQpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFZUX1VOS05PV046CiAgICAgICAgVl9VTktOT1dOKGl0ZXIpID0gdmFfYXJnKHZhbGlzdCwgSVVua25vd24qKTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBWX1ZUKGl0ZXIpID0gVlRfSTQ7CiAgICAgICAgVl9JNChpdGVyKSA9IHZhX2FyZyh2YWxpc3QsIExPTkcpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjI4Ml0KICoKICogU0hQYWNrRGlzcFBhcmFtcwogKi8KSFJFU1VMVCBXSU5BUElWIFNIUGFja0Rpc3BQYXJhbXMoRElTUFBBUkFNUyAqcGFyYW1zLCBWQVJJQU5UQVJHICphcmdzLCBVSU5UIGNudCwgLi4uKQp7CiAgdmFfbGlzdCB2YWxpc3Q7CiAgSFJFU1VMVCBocmVzOwoKICB2YV9zdGFydCh2YWxpc3QsIGNudCk7CgogIGhyZXMgPSBTSFBhY2tEaXNwUGFyYW1zVihwYXJhbXMsIGFyZ3MsIGNudCwgdmFsaXN0KTsKCiAgdmFfZW5kKHZhbGlzdCk7CiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hMV0FQSV9JbnZva2VCeUlJRAogKgogKiAgIFRoaXMgaGVscGVyIGZ1bmN0aW9uIGNhbGxzIElEaXNwYXRjaDo6SW52b2tlIGZvciBlYWNoIHNpbmsKICogd2hpY2ggaW1wbGVtZW50cyBnaXZlbiBpaWQgb3IgSURpc3BhdGNoLgogKgogKi8Kc3RhdGljIEhSRVNVTFQgU0hMV0FQSV9JbnZva2VCeUlJRCgKICAgICAgICBJQ29ubmVjdGlvblBvaW50KiBpQ1AsCiAgICAgICAgUkVGSUlEIGlpZCwKICAgICAgICBESVNQSUQgZGlzcElkLAogICAgICAgIERJU1BQQVJBTVMqIGRpc3BQYXJhbXMpCnsKICBJRW51bUNvbm5lY3Rpb25zICplbnVtZXJhdG9yOwogIENPTk5FQ1REQVRBIHJnY2Q7CgogIEhSRVNVTFQgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludF9FbnVtQ29ubmVjdGlvbnMoaUNQLCAmZW51bWVyYXRvcik7CiAgaWYgKEZBSUxFRChyZXN1bHQpKQogICAgcmV0dXJuIHJlc3VsdDsKCiAgd2hpbGUoSUVudW1Db25uZWN0aW9uc19OZXh0KGVudW1lcmF0b3IsIDEsICZyZ2NkLCBOVUxMKT09U19PSykKICB7CiAgICBJRGlzcGF0Y2ggKmRpc3BJZmFjZTsKICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocmdjZC5wVW5rLCBpaWQsIChMUFZPSUQqKSZkaXNwSWZhY2UpKSB8fAogICAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShyZ2NkLnBVbmssICZJSURfSURpc3BhdGNoLCAoTFBWT0lEKikmZGlzcElmYWNlKSkpCiAgICB7CiAgICAgIElEaXNwYXRjaF9JbnZva2UoZGlzcElmYWNlLCBkaXNwSWQsICZJSURfTlVMTCwgMCwgRElTUEFUQ0hfTUVUSE9ELCBkaXNwUGFyYW1zLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgSURpc3BhdGNoX1JlbGVhc2UoZGlzcElmYWNlKTsKICAgIH0KICB9CgogIElFbnVtQ29ubmVjdGlvbnNfUmVsZWFzZShlbnVtZXJhdG9yKTsKCiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODRdCiAqCiAqICBJQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZQogKi8KSFJFU1VMVCBXSU5BUEkgSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UoCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCogaUNQLAogICAgICAgIERJU1BJRCBkaXNwSWQsCiAgICAgICAgRElTUFBBUkFNUyogZGlzcFBhcmFtcykKewogIElJRCBpaWQ7CiAgSFJFU1VMVCByZXN1bHQ7CgogIFRSQUNFKCIoJXApLT4oMHgleCAlcClcbiIsaUNQLGRpc3BJZCxkaXNwUGFyYW1zKTsKCiAgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludF9HZXRDb25uZWN0aW9uSW50ZXJmYWNlKGlDUCwgJmlpZCk7CiAgaWYgKFNVQ0NFRURFRChyZXN1bHQpKQogICAgcmVzdWx0ID0gU0hMV0FQSV9JbnZva2VCeUlJRChpQ1AsICZpaWQsIGRpc3BJZCwgZGlzcFBhcmFtcyk7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODVdCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50IG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwQ1AgICBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBDUCBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50IGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKElDb25uZWN0aW9uUG9pbnQqIGxwQ1AsIERJU1BJRCBkaXNwSUQpCnsKICBJRW51bUNvbm5lY3Rpb25zICpscEVudW07CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4WClcbiIsIGxwQ1AsIGRpc3BJRCk7CgogIC8qIEdldCBhbiBlbnVtZXJhdG9yIGZvciB0aGUgY29ubmVjdGlvbnMgKi8KICBpZiAobHBDUCkKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X0VudW1Db25uZWN0aW9ucyhscENQLCAmbHBFbnVtKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJUHJvcGVydHlOb3RpZnlTaW5rICpscFNpbms7CiAgICBDT05ORUNUREFUQSBjb25uRGF0YTsKICAgIFVMT05HIHVsRmV0Y2hlZDsKCiAgICAvKiBDYWxsIE9uQ2hhbmdlZCgpIGZvciBldmVyeSBub3RpZnkgc2luayBpbiB0aGUgY29ubmVjdGlvbiBwb2ludCAqLwogICAgd2hpbGUgKElFbnVtQ29ubmVjdGlvbnNfTmV4dChscEVudW0sIDEsICZjb25uRGF0YSwgJnVsRmV0Y2hlZCkgPT0gU19PSykKICAgIHsKICAgICAgaWYgKFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb25uRGF0YS5wVW5rLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICh2b2lkKiopJmxwU2luaykpICYmCiAgICAgICAgICBscFNpbmspCiAgICAgIHsKICAgICAgICBJUHJvcGVydHlOb3RpZnlTaW5rX09uQ2hhbmdlZChscFNpbmssIGRpc3BJRCk7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19SZWxlYXNlKGxwU2luayk7CiAgICAgIH0KICAgICAgSVVua25vd25fUmVsZWFzZShjb25uRGF0YS5wVW5rKTsKICAgIH0KCiAgICBJRW51bUNvbm5lY3Rpb25zX1JlbGVhc2UobHBFbnVtKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODZdCiAqCiAqICBJVW5rbm93bl9DUENvbnRhaW5lckludm9rZVBhcmFtCiAqLwpIUkVTVUxUIFdJTkFQSVYgSVVua25vd25fQ1BDb250YWluZXJJbnZva2VQYXJhbSgKICAgICAgICBJVW5rbm93biAqY29udGFpbmVyLAogICAgICAgIFJFRklJRCByaWlkLAogICAgICAgIERJU1BJRCBkaXNwSWQsCiAgICAgICAgVkFSSUFOVEFSRyogYnVmZmVyLAogICAgICAgIERXT1JEIGNQYXJhbXMsIC4uLikKewogIEhSRVNVTFQgcmVzdWx0OwogIElDb25uZWN0aW9uUG9pbnQgKmlDUDsKICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyICppQ1BDOwogIERJU1BQQVJBTVMgZGlzcFBhcmFtcyA9IHtidWZmZXIsIE5VTEwsIGNQYXJhbXMsIDB9OwogIHZhX2xpc3QgdmFsaXN0OwoKICBpZiAoIWNvbnRhaW5lcikKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwoKICByZXN1bHQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwoTFBWT0lEKikgJmlDUEMpOwogIGlmIChGQUlMRUQocmVzdWx0KSkKICAgICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGlDUEMsIHJpaWQsICZpQ1ApOwogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfUmVsZWFzZShpQ1BDKTsKICBpZihGQUlMRUQocmVzdWx0KSkKICAgICAgcmV0dXJuIHJlc3VsdDsKCiAgdmFfc3RhcnQodmFsaXN0LCBjUGFyYW1zKTsKICBTSFBhY2tEaXNwUGFyYW1zVigmZGlzcFBhcmFtcywgYnVmZmVyLCBjUGFyYW1zLCB2YWxpc3QpOwogIHZhX2VuZCh2YWxpc3QpOwoKICByZXN1bHQgPSBTSExXQVBJX0ludm9rZUJ5SUlEKGlDUCwgcmlpZCwgZGlzcElkLCAmZGlzcFBhcmFtcyk7CiAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGlDUCk7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODddCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEICAgIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGlzIE5VTEwgb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUKICogICAgICAgICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fQ1BDb250YWluZXJPbkNoYW5nZWQoSVVua25vd24gKmxwVW5rbm93biwgRElTUElEIGRpc3BJRCkKewogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ1BDID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX05PSU5URVJGQUNFOwoKICBUUkFDRSgiKCVwLDB4JThYKVxuIiwgbHBVbmtub3duLCBkaXNwSUQpOwoKICBpZiAobHBVbmtub3duKQogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLCAodm9pZCoqKSZscENQQyk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSUNvbm5lY3Rpb25Qb2ludCogbHBDUDsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGxwQ1BDLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICZscENQKTsKICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfUmVsZWFzZShscENQQyk7CgogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKGxwQ1AsIGRpc3BJRCk7CiAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg5XQogKgogKiBTZWUgUGxheVNvdW5kVy4KICovCkJPT0wgV0lOQVBJIFBsYXlTb3VuZFdyYXBXKExQQ1dTVFIgcHN6U291bmQsIEhNT0RVTEUgaG1vZCwgRFdPUkQgZmR3U291bmQpCnsKICAgIHJldHVybiBQbGF5U291bmRXKHBzelNvdW5kLCBobW9kLCBmZHdTb3VuZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTRdCiAqLwpCT09MIFdJTkFQSSBTSEdldEluaVN0cmluZ1coTFBDV1NUUiBzdHIxLCBMUENXU1RSIHN0cjIsIExQV1NUUiBwU3RyLCBEV09SRCBzb21lX2xlbiwgTFBDV1NUUiBscFN0cjIpCnsKICAgIEZJWE1FKCIoJXMsJXMsJXAsJTA4eCwlcyk6IHN0dWIhXG4iLCBkZWJ1Z3N0cl93KHN0cjEpLCBkZWJ1Z3N0cl93KHN0cjIpLAogICAgICAgIHBTdHIsIHNvbWVfbGVuLCBkZWJ1Z3N0cl93KGxwU3RyMikpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTVdCiAqCiAqIENhbGxlZCBieSBJQ1EyMDAwYiBpbnN0YWxsIHZpYSBTSERPQ1ZXOgogKiBzdHIxOiAiSW50ZXJuZXRTaG9ydGN1dCIKICogeDogc29tZSB1bmtub3duIHBvaW50ZXIKICogc3RyMjogImh0dHA6Ly9mcmVlLmFvbC5jb20vdHJ5YW9sZnJlZS9pbmRleC5hZHA/MTM5MjY5IgogKiBzdHIzOiAiQzpcXFdJTkRPV1NcXERlc2t0b3AubmV3MlxcRnJlZSBBT0wgJiBVbmxpbWl0ZWQgSW50ZXJuZXQudXJsIgogKgogKiBJbiBzaG9ydDogdGhpcyBvbmUgbWF5YmUgY3JlYXRlcyBhIGRlc2t0b3AgbGluayA6LSkKICovCkJPT0wgV0lOQVBJIFNIU2V0SW5pU3RyaW5nVyhMUFdTVFIgc3RyMSwgTFBWT0lEIHgsIExQV1NUUiBzdHIyLCBMUFdTVFIgc3RyMykKewogICAgRklYTUUoIiglcywgJXAsICVzLCAlcyksIHN0dWIuXG4iLCBkZWJ1Z3N0cl93KHN0cjEpLCB4LCBkZWJ1Z3N0cl93KHN0cjIpLCBkZWJ1Z3N0cl93KHN0cjMpKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzEzXQogKgogKiBTZWUgU0hHZXRGaWxlSW5mb1cuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRGaWxlSW5mb1dyYXBXKExQQ1dTVFIgcGF0aCwgRFdPUkQgZHdGaWxlQXR0cmlidXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgIFNIRklMRUlORk9XICpwc2ZpLCBVSU5UIHNpemVvZnBzZmksIFVJTlQgZmxhZ3MpCnsKICAgIHJldHVybiBTSEdldEZpbGVJbmZvVyhwYXRoLCBkd0ZpbGVBdHRyaWJ1dGVzLCBwc2ZpLCBzaXplb2Zwc2ZpLCBmbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMThdCiAqCiAqIFNlZSBEcmFnUXVlcnlGaWxlVy4KICovClVJTlQgV0lOQVBJIERyYWdRdWVyeUZpbGVXcmFwVyhIRFJPUCBoRHJvcCwgVUlOVCBsRmlsZSwgTFBXU1RSIGxwc3pGaWxlLCBVSU5UIGxMZW5ndGgpCnsKICAgIHJldHVybiBEcmFnUXVlcnlGaWxlVyhoRHJvcCwgbEZpbGUsIGxwc3pGaWxlLCBsTGVuZ3RoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzM10KICoKICogU2VlIFNIQnJvd3NlRm9yRm9sZGVyVy4KICovCkxQSVRFTUlETElTVCBXSU5BUEkgU0hCcm93c2VGb3JGb2xkZXJXcmFwVyhMUEJST1dTRUlORk9XIGxwQmkpCnsKICAgIHJldHVybiBTSEJyb3dzZUZvckZvbGRlclcobHBCaSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzRdCiAqCiAqIFNlZSBTSEdldFBhdGhGcm9tSURMaXN0Vy4KICovCkJPT0wgV0lOQVBJIFNIR2V0UGF0aEZyb21JRExpc3RXcmFwVyhMUENJVEVNSURMSVNUIHBpZGwsTFBXU1RSIHBzelBhdGgpCnsKICAgIHJldHVybiBTSEdldFBhdGhGcm9tSURMaXN0VyhwaWRsLCBwc3pQYXRoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNV0KICoKICogU2VlIFNoZWxsRXhlY3V0ZUV4Vy4KICovCkJPT0wgV0lOQVBJIFNoZWxsRXhlY3V0ZUV4V3JhcFcoTFBTSEVMTEVYRUNVVEVJTkZPVyBscEV4ZWNJbmZvKQp7CiAgICByZXR1cm4gU2hlbGxFeGVjdXRlRXhXKGxwRXhlY0luZm8pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM2XQogKgogKiBTZWUgU0hGaWxlT3BlcmF0aW9uVy4KICovCklOVCBXSU5BUEkgU0hGaWxlT3BlcmF0aW9uV3JhcFcoTFBTSEZJTEVPUFNUUlVDVFcgbHBGaWxlT3ApCnsKICAgIHJldHVybiBTSEZpbGVPcGVyYXRpb25XKGxwRmlsZU9wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM0Ml0KICoKICovClBWT0lEIFdJTkFQSSBTSEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlKCBQVk9JRCAqZGVzdCwgUFZPSUQgeGNoZywgUFZPSUQgY29tcGFyZSApCnsKICAgIHJldHVybiBJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZVBvaW50ZXIoIGRlc3QsIHhjaGcsIGNvbXBhcmUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MF0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXLgogKi8KRFdPUkQgV0lOQVBJIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXcmFwVyggTFBDV1NUUiBmaWxlbmFtZSwgTFBEV09SRCBoYW5kbGUgKQp7CiAgICByZXR1cm4gR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcoIGZpbGVuYW1lLCBoYW5kbGUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MV0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1cuCiAqLwpCT09MICBXSU5BUEkgR2V0RmlsZVZlcnNpb25JbmZvV3JhcFcoIExQQ1dTVFIgZmlsZW5hbWUsIERXT1JEIGhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkYXRhc2l6ZSwgTFBWT0lEIGRhdGEgKQp7CiAgICByZXR1cm4gR2V0RmlsZVZlcnNpb25JbmZvVyggZmlsZW5hbWUsIGhhbmRsZSwgZGF0YXNpemUsIGRhdGEgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1Ml0KICoKICogU2VlIFZlclF1ZXJ5VmFsdWVXLgogKi8KV09SRCBXSU5BUEkgVmVyUXVlcnlWYWx1ZVdyYXBXKCBMUFZPSUQgcEJsb2NrLCBMUENXU1RSIGxwU3ViQmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpscGxwQnVmZmVyLCBVSU5UICpwdUxlbiApCnsKICAgIHJldHVybiBWZXJRdWVyeVZhbHVlVyggcEJsb2NrLCBscFN1YkJsb2NrLCBscGxwQnVmZmVyLCBwdUxlbiApOwp9CgojZGVmaW5lIElzSWZhY2UodHlwZSkgU1VDQ0VFREVEKChoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEXyMjdHlwZSwgKHZvaWQqKikmbHBPYmopKSkKI2RlZmluZSBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3NTQgojZGVmaW5lIEVuYWJsZU1vZGVsZXNzKHR5cGUpIHR5cGUjI19FbmFibGVNb2RlbGVzcygodHlwZSopbHBPYmosIGJNb2RlbGVzcykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTVdCiAqCiAqIENoYW5nZSB0aGUgbW9kYWxpdHkgb2YgYSBzaGVsbCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gbWFrZSBtb2RlbGVzcwogKiAgYk1vZGVsZXNzIFtJXSBUUlVFPU1ha2UgbW9kZWxlc3MsIEZBTFNFPU1ha2UgbW9kYWwKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gVGhlIG1vZGFsaXR5IGxwVW5rbm93biBpcyBjaGFuZ2VkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIG11c3Qgc3VwcG9ydCB0aGUgSU9sZUluUGxhY2VGcmFtZSBpbnRlcmZhY2UsIHRoZQogKiAgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlIGludGVyZmFjZSwgdGhlIElTaGVsbEJyb3dzZXIgaW50ZXJmYWNlCiAqICB0aGUgSURvY0hvc3RVSUhhbmRsZXIgaW50ZXJmYWNlLCBvciB0aGUgSU9sZUluUGxhY2VBY3RpdmVPYmplY3QgaW50ZXJmYWNlLAogKiAgb3IgdGhpcyBjYWxsIHdpbGwgZmFpbC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0VuYWJsZU1vZGVsZXNzKElVbmtub3duICpscFVua25vd24sIEJPT0wgYk1vZGVsZXNzKQp7CiAgSVVua25vd24gKmxwT2JqOwogIEhSRVNVTFQgaFJldDsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIGxwVW5rbm93biwgYk1vZGVsZXNzKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZiAoSXNJZmFjZShJT2xlSW5QbGFjZUFjdGl2ZU9iamVjdCkpCiAgICBFbmFibGVNb2RlbGVzcyhJT2xlSW5QbGFjZUFjdGl2ZU9iamVjdCk7CiAgZWxzZSBpZiAoSXNJZmFjZShJT2xlSW5QbGFjZUZyYW1lKSkKICAgIEVuYWJsZU1vZGVsZXNzKElPbGVJblBsYWNlRnJhbWUpOwogIGVsc2UgaWYgKElzSWZhY2UoSVNoZWxsQnJvd3NlcikpCiAgICBFbmFibGVNb2RlbGVzcyhJU2hlbGxCcm93c2VyKTsKICBlbHNlIGlmIChJc0lmYWNlKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpOwogIGVsc2UgaWYgKElzSWZhY2UoSURvY0hvc3RVSUhhbmRsZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSURvY0hvc3RVSUhhbmRsZXIpOwogIGVsc2UKICAgIHJldHVybiBoUmV0OwoKICBJVW5rbm93bl9SZWxlYXNlKGxwT2JqKTsKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1N10KICoKICogU2VlIFNIR2V0TmV3TGlua0luZm9XLgogKi8KQk9PTCBXSU5BUEkgU0hHZXROZXdMaW5rSW5mb1dyYXBXKExQQ1dTVFIgcHN6TGlua1RvLCBMUENXU1RSIHBzekRpciwgTFBXU1RSIHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgKnBmTXVzdENvcHksIFVJTlQgdUZsYWdzKQp7CiAgICByZXR1cm4gU0hHZXROZXdMaW5rSW5mb1cocHN6TGlua1RvLCBwc3pEaXIsIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNThdCiAqCiAqIFNlZSBTSERlZkV4dHJhY3RJY29uVy4KICovClVJTlQgV0lOQVBJIFNIRGVmRXh0cmFjdEljb25XcmFwVyhMUENXU1RSIHBzekljb25GaWxlLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgSElDT04qIHBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04qIHBoaWNvblNtYWxsLCBVSU5UIG5JY29uU2l6ZSkKewogICAgcmV0dXJuIFNIRGVmRXh0cmFjdEljb25XKHBzekljb25GaWxlLCBpSW5kZXgsIHVGbGFncywgcGhpY29uTGFyZ2UsIHBoaWNvblNtYWxsLCBuSWNvblNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzYzXQogKgogKiBHZXQgYW5kIHNob3cgYSBjb250ZXh0IG1lbnUgZnJvbSBhIHNoZWxsIGZvbGRlci4KICoKICogUEFSQU1TCiAqICBoV25kICAgICAgICAgICBbSV0gV2luZG93IGRpc3BsYXlpbmcgdGhlIHNoZWxsIGZvbGRlcgogKiAgbHBGb2xkZXIgICAgICAgW0ldIElTaGVsbEZvbGRlciBpbnRlcmZhY2UKICogIGxwQXBpZGwgICAgICAgIFtJXSBJZCBmb3IgdGhlIHBhcnRpY3VsYXIgZm9sZGVyIGRlc2lyZWQKICogIGJJbnZva2VEZWZhdWx0IFtJXSBXaGV0aGVyIHRvIGludm9rZSB0aGUgZGVmYXVsdCBtZW51IGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgYkludm9rZURlZmF1bHQgaXMgVFJVRSwgdGhlIGRlZmF1bHQgbWVudSBhY3Rpb24gd2FzCiAqICAgICAgICAgICBleGVjdXRlZC4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICovCkhSRVNVTFQgV0lOQVBJIFNISW52b2tlQ29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCwgQk9PTCBiSW52b2tlRGVmYXVsdCkKewogIElDb250ZXh0TWVudSAqaUNvbnRleHQ7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVkKVxuIiwgaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIGJJbnZva2VEZWZhdWx0KTsKCiAgaWYgKCFscEZvbGRlcikKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgdGhlIGNvbnRleHQgbWVudSBmcm9tIHRoZSBzaGVsbCBmb2xkZXIgKi8KICBoUmV0ID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YobHBGb2xkZXIsIGhXbmQsIDEsICZscEFwaWRsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmSUlEX0lDb250ZXh0TWVudSwgMCwgKHZvaWQqKikmaUNvbnRleHQpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSE1FTlUgaE1lbnU7CiAgICBpZiAoKGhNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCkpKQogICAgewogICAgICBIUkVTVUxUIGhRdWVyeTsKICAgICAgRFdPUkQgZHdEZWZhdWx0SWQgPSAwOwoKICAgICAgLyogQWRkIHRoZSBjb250ZXh0IG1lbnUgZW50cmllcyB0byB0aGUgcG9wdXAgKi8KICAgICAgaFF1ZXJ5ID0gSUNvbnRleHRNZW51X1F1ZXJ5Q29udGV4dE1lbnUoaUNvbnRleHQsIGhNZW51LCAwLCAxLCAweDdGRkYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJJbnZva2VEZWZhdWx0ID8gQ01GX05PUk1BTCA6IENNRl9ERUZBVUxUT05MWSk7CgogICAgICBpZiAoU1VDQ0VFREVEKGhRdWVyeSkpCiAgICAgIHsKICAgICAgICBpZiAoYkludm9rZURlZmF1bHQgJiYKICAgICAgICAgICAgKGR3RGVmYXVsdElkID0gR2V0TWVudURlZmF1bHRJdGVtKGhNZW51LCAwLCAwKSkgIT0gMHhGRkZGRkZGRikKICAgICAgICB7CiAgICAgICAgICBDTUlOVk9LRUNPTU1BTkRJTkZPIGNtSWNpOwogICAgICAgICAgLyogSW52b2tlIHRoZSBkZWZhdWx0IGl0ZW0gKi8KICAgICAgICAgIG1lbXNldCgmY21JY2ksMCxzaXplb2YoY21JY2kpKTsKICAgICAgICAgIGNtSWNpLmNiU2l6ZSA9IHNpemVvZihjbUljaSk7CiAgICAgICAgICBjbUljaS5mTWFzayA9IENNSUNfTUFTS19BU1lOQ09LOwogICAgICAgICAgY21JY2kuaHduZCA9IGhXbmQ7CiAgICAgICAgICBjbUljaS5scFZlcmIgPSBNQUtFSU5UUkVTT1VSQ0VBKGR3RGVmYXVsdElkKTsKICAgICAgICAgIGNtSWNpLm5TaG93ID0gU1dfU0NST0xMQ0hJTERSRU47CgogICAgICAgICAgaFJldCA9IElDb250ZXh0TWVudV9JbnZva2VDb21tYW5kKGlDb250ZXh0LCAmY21JY2kpOwogICAgICAgIH0KICAgICAgfQogICAgICBEZXN0cm95TWVudShoTWVudSk7CiAgICB9CiAgICBJQ29udGV4dE1lbnVfUmVsZWFzZShpQ29udGV4dCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzcwXQogKgogKiBTZWUgRXh0cmFjdEljb25XLgogKi8KSElDT04gV0lOQVBJIEV4dHJhY3RJY29uV3JhcFcoSElOU1RBTkNFIGhJbnN0YW5jZSwgTFBDV1NUUiBscHN6RXhlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIG5JY29uSW5kZXgpCnsKICAgIHJldHVybiBFeHRyYWN0SWNvblcoaEluc3RhbmNlLCBscHN6RXhlRmlsZU5hbWUsIG5JY29uSW5kZXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgICAgICAgW0ldIExpYnJhcnkgbmFtZQogKiAgaW5zdF9od25kICAgICAgW0ldIE1vZHVsZSB3aG9zZSBkaXJlY3RvcnkgaXMgdG8gYmUgdXNlZAogKiAgZHdDcm9zc0NvZGVQYWdlIFtJXSBTaG91bGQgYmUgRkFMU0UgKGN1cnJlbnRseSBpZ25vcmVkKQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIGhhbmRsZSB0byB0aGUgbG9hZGVkIG1vZHVsZQogKiAgRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICovCkhNT0RVTEUgV0lOQVBJIE1MTG9hZExpYnJhcnlBKExQQ1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdDcm9zc0NvZGVQYWdlKQp7CiAgLyogRklYTUU6IE5hdGl2ZSBhcHBlYXJzIHRvIGRvIERQQV9DcmVhdGUgYW5kIGEgRFBBX0luc2VydFB0ciBmb3IKICAgKiAgICAgICAgZWFjaCBjYWxsIGhlcmUuCiAgICogRklYTUU6IE5hdGl2ZSBzaG93cyBjYWxscyB0bzoKICAgKiAgU0hSZWdHZXRVU1ZhbHVlIGZvciAiU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogICAgICAgICAgICAgICAgICAgICAgQ2hlY2tWZXJzaW9uCiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlciIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxQS0luc3RhbGxlZCIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLQ1VcU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJSZXNvdXJjZUxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEFjdGl2ZSBTZXR1cFxJbnN0YWxsZWQgQ29tcG9uZW50c1x7Z3VpZH0iCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIGFuZCB0aGVuIHRlc3RzIHRoZSBMb2NhbGUgKCJlbiIgZm9yIG1lKS4KICAgKiAgICAgY29kZSBiZWxvdwogICAqICBhZnRlciB0aGUgY29kZSB0aGVuIGEgRFBBX0NyZWF0ZSAoZmlyc3QgdGltZSkgYW5kIERQQV9JbnNlcnRQdHIgYXJlIGRvbmUuCiAgICovCiAgICBDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsJWQpIHNlbWktc3R1YiFcbiIsIGRlYnVnc3RyX2EobmV3X21vZCksIGluc3RfaHduZCwgZHdDcm9zc0NvZGVQYWdlKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIE1MTG9hZExpYnJhcnlBLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeVcoTFBDV1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdDcm9zc0NvZGVQYWdlKQp7CiAgICBXQ0hBUiBtb2RfcGF0aFsyKk1BWF9QQVRIXTsKICAgIExQV1NUUiBwdHI7CiAgICBEV09SRCBsZW47CgogICAgRklYTUUoIiglcywlcCwlZCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfdyhuZXdfbW9kKSwgaW5zdF9od25kLCBkd0Nyb3NzQ29kZVBhZ2UpOwogICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVXKGluc3RfaHduZCwgbW9kX3BhdGgsIHNpemVvZihtb2RfcGF0aCkgLyBzaXplb2YoV0NIQVIpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSkgcmV0dXJuIE5VTEw7CgogICAgcHRyID0gc3RycmNoclcobW9kX3BhdGgsICdcXCcpOwogICAgaWYgKHB0cikgewoJc3RyY3B5VyhwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfdyhtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5Vyhtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29sb3JBZGp1c3RMdW1hICAgICAgW1NITFdBUEkuQF0KICoKICogQWRqdXN0IHRoZSBsdW1pbm9zaXR5IG9mIGEgY29sb3IKICoKICogUEFSQU1TCiAqICBjUkdCICAgICAgICAgW0ldIFJHQiB2YWx1ZSB0byBjb252ZXJ0CiAqICBkd0x1bWEgICAgICAgW0ldIEx1bWEgYWRqdXN0bWVudAogKiAgYlVua25vd24gICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFRoZSBhZGp1c3RlZCBSR0IgY29sb3IuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JBZGp1c3RMdW1hKENPTE9SUkVGIGNSR0IsIGludCBkd0x1bWEsIEJPT0wgYlVua25vd24pCnsKICBUUkFDRSgiKDB4JTh4LCVkLCVkKVxuIiwgY1JHQiwgZHdMdW1hLCBiVW5rbm93bik7CgogIGlmIChkd0x1bWEpCiAgewogICAgV09SRCB3SCwgd0wsIHdTOwoKICAgIENvbG9yUkdCVG9ITFMoY1JHQiwgJndILCAmd0wsICZ3Uyk7CgogICAgRklYTUUoIklnbm9yaW5nIGx1bWEgYWRqdXN0bWVudFxuIik7CgogICAgLyogRklYTUU6IFRoZSBhZGp1c3RtZW50IGlzIG5vdCBsaW5lYXIgKi8KCiAgICBjUkdCID0gQ29sb3JITFNUb1JHQih3SCwgd0wsIHdTKTsKICB9CiAgcmV0dXJuIGNSR0I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zODldCiAqCiAqIFNlZSBHZXRTYXZlRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgR2V0U2F2ZUZpbGVOYW1lV3JhcFcoTFBPUEVORklMRU5BTUVXIG9mbikKewogICAgcmV0dXJuIEdldFNhdmVGaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MF0KICoKICogU2VlIFdOZXRSZXN0b3JlQ29ubmVjdGlvblcuCiAqLwpEV09SRCBXSU5BUEkgV05ldFJlc3RvcmVDb25uZWN0aW9uV3JhcFcoSFdORCBod25kT3duZXIsIExQV1NUUiBscHN6RGV2aWNlKQp7CiAgICByZXR1cm4gV05ldFJlc3RvcmVDb25uZWN0aW9uVyhod25kT3duZXIsIGxwc3pEZXZpY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzkxXQogKgogKiBTZWUgV05ldEdldExhc3RFcnJvclcuCiAqLwpEV09SRCBXSU5BUEkgV05ldEdldExhc3RFcnJvcldyYXBXKExQRFdPUkQgbHBFcnJvciwgTFBXU1RSIGxwRXJyb3JCdWYsIERXT1JEIG5FcnJvckJ1ZlNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBOYW1lQnVmLCBEV09SRCBuTmFtZUJ1ZlNpemUpCnsKICAgIHJldHVybiBXTmV0R2V0TGFzdEVycm9yVyhscEVycm9yLCBscEVycm9yQnVmLCBuRXJyb3JCdWZTaXplLCBscE5hbWVCdWYsIG5OYW1lQnVmU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDFdCiAqCiAqIFNlZSBQYWdlU2V0dXBEbGdXLgogKi8KQk9PTCBXSU5BUEkgUGFnZVNldHVwRGxnV3JhcFcoTFBQQUdFU0VUVVBETEdXIHBhZ2VkbGcpCnsKICAgIHJldHVybiBQYWdlU2V0dXBEbGdXKHBhZ2VkbGcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAyXQogKgogKiBTZWUgUHJpbnREbGdXLgogKi8KQk9PTCBXSU5BUEkgUHJpbnREbGdXcmFwVyhMUFBSSU5URExHVyBwcmludGRsZykKewogICAgcmV0dXJuIFByaW50RGxnVyhwcmludGRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDNdCiAqCiAqIFNlZSBHZXRPcGVuRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgR2V0T3BlbkZpbGVOYW1lV3JhcFcoTFBPUEVORklMRU5BTUVXIG9mbikKewogICAgcmV0dXJuIEdldE9wZW5GaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwNF0KICovCkhSRVNVTFQgV0lOQVBJIFNISVNoZWxsRm9sZGVyX0VudW1PYmplY3RzKExQU0hFTExGT0xERVIgbHBGb2xkZXIsIEhXTkQgaHduZCwgU0hDT05URiBmbGFncywgSUVudW1JRExpc3QgKipwcGVudW0pCnsKICAgIElQZXJzaXN0ICpwZXJzaXN0OwogICAgSFJFU1VMVCBocjsKCiAgICBociA9IElTaGVsbEZvbGRlcl9RdWVyeUludGVyZmFjZShscEZvbGRlciwgJklJRF9JUGVyc2lzdCwgKExQVk9JRCkmcGVyc2lzdCk7CiAgICBpZihTVUNDRUVERUQoaHIpKQogICAgewogICAgICAgIENMU0lEIGNsc2lkOwogICAgICAgIGhyID0gSVBlcnNpc3RfR2V0Q2xhc3NJRChwZXJzaXN0LCAmY2xzaWQpOwogICAgICAgIGlmKFNVQ0NFRURFRChocikpCiAgICAgICAgewogICAgICAgICAgICBpZihJc0VxdWFsQ0xTSUQoJmNsc2lkLCAmQ0xTSURfU2hlbGxGU0ZvbGRlcikpCiAgICAgICAgICAgICAgICBociA9IElTaGVsbEZvbGRlcl9FbnVtT2JqZWN0cyhscEZvbGRlciwgaHduZCwgZmxhZ3MsIHBwZW51bSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGhyID0gRV9GQUlMOwogICAgICAgIH0KICAgICAgICBJUGVyc2lzdF9SZWxlYXNlKHBlcnNpc3QpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKiBJTlRFUk5BTDogTWFwIGZyb20gSExTIGNvbG9yIHNwYWNlIHRvIFJHQiAqLwpzdGF0aWMgV09SRCBXSU5BUEkgQ29udmVydEh1ZShpbnQgd0h1ZSwgV09SRCB3TWlkMSwgV09SRCB3TWlkMikKewogIHdIdWUgPSB3SHVlID4gMjQwID8gd0h1ZSAtIDI0MCA6IHdIdWUgPCAwID8gd0h1ZSArIDI0MCA6IHdIdWU7CgogIGlmICh3SHVlID4gMTYwKQogICAgcmV0dXJuIHdNaWQxOwogIGVsc2UgaWYgKHdIdWUgPiAxMjApCiAgICB3SHVlID0gMTYwIC0gd0h1ZTsKICBlbHNlIGlmICh3SHVlID4gNDApCiAgICByZXR1cm4gd01pZDI7CgogIHJldHVybiAoKHdIdWUgKiAod01pZDIgLSB3TWlkMSkgKyAyMCkgLyA0MCkgKyB3TWlkMTsKfQoKLyogQ29udmVydCB0byBSR0IgYW5kIHNjYWxlIGludG8gUkdCIHJhbmdlICgwLi4yNTUpICovCiNkZWZpbmUgR0VUX1JHQihoKSAoQ29udmVydEh1ZShoLCB3TWlkMSwgd01pZDIpICogMjU1ICsgMTIwKSAvIDI0MAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvckhMU1RvUkdCCVtTSExXQVBJLkBdCiAqCiAqIENvbnZlcnQgZnJvbSBobHMgY29sb3Igc3BhY2UgaW50byBhbiByZ2IgQ09MT1JSRUYuCiAqCiAqIFBBUkFNUwogKiAgd0h1ZSAgICAgICAgW0ldIEh1ZSBhbW91bnQKICogIHdMdW1pbm9zaXR5IFtJXSBMdW1pbm9zaXR5IGFtb3VudAogKiAgd1NhdHVyYXRpb24gW0ldIFNhdHVyYXRpb24gYW1vdW50CiAqCiAqIFJFVFVSTlMKICogIEEgQ09MT1JSRUYgcmVwcmVzZW50aW5nIHRoZSBjb252ZXJ0ZWQgY29sb3IuCiAqCiAqIE5PVEVTCiAqICBJbnB1dCBobHMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JITFNUb1JHQihXT1JEIHdIdWUsIFdPUkQgd0x1bWlub3NpdHksIFdPUkQgd1NhdHVyYXRpb24pCnsKICBXT1JEIHdSZWQ7CgogIGlmICh3U2F0dXJhdGlvbikKICB7CiAgICBXT1JEIHdHcmVlbiwgd0JsdWUsIHdNaWQxLCB3TWlkMjsKCiAgICBpZiAod0x1bWlub3NpdHkgPiAxMjApCiAgICAgIHdNaWQyID0gd1NhdHVyYXRpb24gKyB3THVtaW5vc2l0eSAtICh3U2F0dXJhdGlvbiAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKICAgIGVsc2UKICAgICAgd01pZDIgPSAoKHdTYXR1cmF0aW9uICsgMjQwKSAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKCiAgICB3TWlkMSA9IHdMdW1pbm9zaXR5ICogMiAtIHdNaWQyOwoKICAgIHdSZWQgICA9IEdFVF9SR0Iod0h1ZSArIDgwKTsKICAgIHdHcmVlbiA9IEdFVF9SR0Iod0h1ZSk7CiAgICB3Qmx1ZSAgPSBHRVRfUkdCKHdIdWUgLSA4MCk7CgogICAgcmV0dXJuIFJHQih3UmVkLCB3R3JlZW4sIHdCbHVlKTsKICB9CgogIHdSZWQgPSB3THVtaW5vc2l0eSAqIDI1NSAvIDI0MDsKICByZXR1cm4gUkdCKHdSZWQsIHdSZWQsIHdSZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDEzXQogKgogKiBHZXQgdGhlIGN1cnJlbnQgZG9ja2luZyBzdGF0dXMgb2YgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBET0NLSU5GT18gZmxhZ3MgZnJvbSAid2luYmFzZS5oIiwgdW51c2VkCiAqCiAqIFJFVFVSTlMKICogIE9uZSBvZiBET0NLSU5GT19VTkRPQ0tFRCwgRE9DS0lORk9fVU5ET0NLRUQsIG9yIDAgaWYgdGhlIHN5c3RlbSBpcyBub3QKICogIGEgbm90ZWJvb2suCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRNYWNoaW5lSW5mbyhEV09SRCBkd0ZsYWdzKQp7CiAgSFdfUFJPRklMRV9JTkZPQSBod0luZm87CgogIFRSQUNFKCIoMHglMDh4KVxuIiwgZHdGbGFncyk7CgogIEdldEN1cnJlbnRId1Byb2ZpbGVBKCZod0luZm8pOwogIHN3aXRjaCAoaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKSkKICB7CiAgY2FzZSBET0NLSU5GT19ET0NLRUQ6CiAgY2FzZSBET0NLSU5GT19VTkRPQ0tFRDoKICAgIHJldHVybiBod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MThdCiAqCiAqIEZ1bmN0aW9uIHNlZW1zIHRvIGRvIEZyZWVMaWJyYXJ5IHBsdXMgb3RoZXIgdGhpbmdzLgogKgogKiBGSVhNRSBuYXRpdmUgc2hvd3MgdGhlIGZvbGxvd2luZyBjYWxsczoKICogICBSdGxFbnRlckNyaXRpY2FsU2VjdGlvbgogKiAgIExvY2FsRnJlZQogKiAgIEdldFByb2NBZGRyZXNzKENvbWN0bDMyPz8sIDE1MEwpCiAqICAgRFBBX0RlbGV0ZVB0cgogKiAgIFJ0bExlYXZlQ3JpdGljYWxTZWN0aW9uCiAqICBmb2xsb3dlZCBieSB0aGUgRnJlZUxpYnJhcnkuCiAqICBUaGUgYWJvdmUgY29kZSBtYXkgYmUgcmVsYXRlZCB0byAuMzc3IGFib3ZlLgogKi8KQk9PTCBXSU5BUEkgTUxGcmVlTGlicmFyeShITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTldCiAqLwpCT09MIFdJTkFQSSBTSEZsdXNoU0ZDYWNoZVdyYXAodm9pZCkgewogIEZJWE1FKCI6IHN0dWJcbiIpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICBbU0hMV0FQSS40MjldCiAqIEZJWE1FIEkgaGF2ZSBubyBpZGVhIHdoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIG9yIHdoYXQgaXRzIGFyZ3VtZW50cyBhcmUuCiAqLwpCT09MIFdJTkFQSSBNTElzTUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0KQp7CiAgICAgICBGSVhNRSgiKCVwKSBzdHViXG4iLCBoSW5zdCk7CiAgICAgICByZXR1cm4gRkFMU0U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMwXQogKi8KRFdPUkQgV0lOQVBJIE1MU2V0TUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0LCBIQU5ETEUgaEhlYXApCnsKCUZJWE1FKCIoJXAsJXApIHN0dWJcbiIsIGhJbnN0LCBoSGVhcCk7CglyZXR1cm4gRV9GQUlMOyAgIC8qIFRoaXMgaXMgd2hhdCBpcyB1c2VkIGlmIHNobHdhcGkgbm90IGxvYWRlZCAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMxXQogKi8KRFdPUkQgV0lOQVBJIE1MQ2xlYXJNTEhJbnN0YW5jZShEV09SRCB4KQp7CglGSVhNRSgiKDB4JTA4eClzdHViXG4iLCB4KTsKCXJldHVybiAweGFiYmExMjQ3Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM2XQogKgogKiBDb252ZXJ0IGFuIFVuaWNvZGUgc3RyaW5nIENMU0lEIGludG8gYSBDTFNJRC4KICoKICogUEFSQU1TCiAqICBpZHN0ciAgICAgIFtJXSAgIHN0cmluZyBjb250YWluaW5nIGEgQ0xTSUQgaW4gdGV4dCBmb3JtCiAqICBpZCAgICAgICAgIFtPXSAgIENMU0lEIGV4dHJhY3RlZCBmcm9tIHRoZSBzdHJpbmcKICoKICogUkVUVVJOUwogKiAgU19PSyBvbiBzdWNjZXNzIG9yIEVfSU5WQUxJREFSRyBvbiBmYWlsdXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBDTFNJREZyb21TdHJpbmdXcmFwKExQQ1dTVFIgaWRzdHIsIENMU0lEICppZCkKewogICAgcmV0dXJuIENMU0lERnJvbVN0cmluZygoTFBPTEVTVFIpaWRzdHIsIGlkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzN10KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBPUyBzdXBwb3J0cyBhIGdpdmVuIGZlYXR1cmUuCiAqCiAqIFBBUkFNUwogKiAgZHdGZWF0dXJlIFtJXSBGZWF0dXJlIHJlcXVlc3RlZCAodW5kb2N1bWVudGVkKQogKgogKiBSRVRVUk5TCiAqICBUUlVFICBJZiB0aGUgZmVhdHVyZSBpcyBhdmFpbGFibGUuCiAqICBGQUxTRSBJZiB0aGUgZmVhdHVyZSBpcyBub3QgYXZhaWxhYmxlLgogKi8KQk9PTCBXSU5BUEkgSXNPUyhEV09SRCBmZWF0dXJlKQp7CiAgICBPU1ZFUlNJT05JTkZPQSBvc3ZpOwogICAgRFdPUkQgcGxhdGZvcm0sIG1ham9ydiwgbWlub3J2OwoKICAgIG9zdmkuZHdPU1ZlcnNpb25JbmZvU2l6ZSA9IHNpemVvZihPU1ZFUlNJT05JTkZPQSk7CiAgICBpZighR2V0VmVyc2lvbkV4QSgmb3N2aSkpICB7CiAgICAgICAgRVJSKCJHZXRWZXJzaW9uRXggZmFpbGVkXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbWFqb3J2ID0gb3N2aS5kd01ham9yVmVyc2lvbjsKICAgIG1pbm9ydiA9IG9zdmkuZHdNaW5vclZlcnNpb247CiAgICBwbGF0Zm9ybSA9IG9zdmkuZHdQbGF0Zm9ybUlkOwoKI2RlZmluZSBJU09TX1JFVFVSTih4KSBcCiAgICBUUkFDRSgiKDB4JXgpIHJldD0lZFxuIixmZWF0dXJlLCh4KSk7IFwKICAgIHJldHVybiAoeCk7CgogICAgc3dpdGNoKGZlYXR1cmUpICB7CiAgICBjYXNlIE9TX1dJTjMyU09SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJzCiAgICAgICAgICAgICAgICAgfHwgcGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV0lOOTVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UNE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDQpCiAgICBjYXNlIE9TX1dJTjIwMDBPUkdSRUFURVJfQUxUOgogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfV0lOOThPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDEwKQogICAgY2FzZSBPU19XSU45OF9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAxMCkKICAgIGNhc2UgT1NfV0lOMjAwMFBSTzoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjIwMDBTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBBRFZTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBEQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwVEVSTUlOQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX0VNQkVEREVEOgogICAgICAgIEZJWE1FKCIoT1NfRU1CRURERUQpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19URVJNSU5BTENMSUVOVDoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMQ0xJRU5UKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxSRU1PVEVBRE1JTjoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMUkVNT1RFQURNSU4pIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XSU45NV9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAwKQogICAgY2FzZSBPU19NRU9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPj0gOTApCiAgICBjYXNlIE9TX1hQT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSAmJiBtaW5vcnYgPj0gMSkKICAgIGNhc2UgT1NfSE9NRToKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX1BST0ZFU1NJT05BTDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX0RBVEFDRU5URVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19BRFZTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19TRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19URVJNSU5BTFNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1BFUlNPTkFMVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1pbm9ydiA+PSAxICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19GQVNUVVNFUlNXSVRDSElORzoKICAgICAgICBGSVhNRSgiKE9TX0ZBU1RVU0VSU1dJVENISU5HKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgY2FzZSBPU19XRUxDT01FTE9HT05VSToKICAgICAgICBGSVhNRSgiKE9TX1dFTENPTUVMT0dPTlVJKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfRE9NQUlOTUVNQkVSOgogICAgICAgIEZJWE1FKCIoT1NfRE9NQUlOTUVNQkVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgY2FzZSBPU19BTllTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19XT1c2NDMyOgogICAgICAgIEZJWE1FKCIoT1NfV09XNjQzMikgU2hvdWxkIHdlIGNoZWNrIHRoaXM/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1dFQlNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1NNQUxMQlVTSU5FU1NTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19UQUJMRVRQQzoKICAgICAgICBGSVhNRSgiKE9TX1RBQkxFUEMpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19TRVJWRVJBRE1JTlVJOgogICAgICAgIEZJWE1FKCIoT1NfU0VSVkVSQURNSU5VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX01FRElBQ0VOVEVSOgogICAgICAgIEZJWE1FKCIoT1NfTUVESUFDRU5URVIpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19BUFBMSUFOQ0U6CiAgICAgICAgRklYTUUoIihPU19BUFBMSUFOQ0UpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKI3VuZGVmIElTT1NfUkVUVVJOCgogICAgV0FSTigiKDB4JXgpIHVua25vd24gcGFyYW1ldGVyXG4iLGZlYXR1cmUpOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuNDM5XQogKi8KSFJFU1VMVCBXSU5BUEkgU0hMb2FkUmVnVUlTdHJpbmdXKEhLRVkgaGtleSwgTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZiwgRFdPUkQgc2l6ZSkKewogICAgRFdPUkQgdHlwZSwgc3ogPSBzaXplOwoKICAgIGlmKFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgdmFsdWUsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWJ1ZiwgJnN6KSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgcmV0dXJuIFNITG9hZEluZGlyZWN0U3RyaW5nKGJ1ZiwgYnVmLCBzaXplLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuNDc4XQogKgogKiBDYWxsIElJbnB1dE9iamVjdF9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElJbnB1dE9iamVjdCBpbnRlcmZhY2UuCiAqICBscE1zZyAgICAgW0ldIEtleSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9JTlZBTElEQVJHIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fVHJhbnNsYXRlQWNjZWxlcmF0b3JJTyhJVW5rbm93biAqbHBVbmtub3duLCBMUE1TRyBscE1zZykKewogIElJbnB1dE9iamVjdCogbHBJbnB1dCA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscE1zZyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnB1dE9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscElucHV0KTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBJbnB1dCkKICAgIHsKICAgICAgaFJldCA9IElJbnB1dE9iamVjdF9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKGxwSW5wdXQsIGxwTXNnKTsKICAgICAgSUlucHV0T2JqZWN0X1JlbGVhc2UobHBJbnB1dCk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40ODFdCiAqCiAqIENhbGwgSUlucHV0T2JqZWN0X0hhc0ZvY3VzSU8oKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSUlucHV0T2JqZWN0IGludGVyZmFjZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSywgaWYgbHBVbmtub3duIGlzIGFuIElJbnB1dE9iamVjdCBvYmplY3QgYW5kIGhhcyB0aGUgZm9jdXMsCiAqICAgICAgICAgICBvciBTX0ZBTFNFIG90aGVyd2lzZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9JTlZBTElEQVJHIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fSGFzRm9jdXNJTyhJVW5rbm93biAqbHBVbmtub3duKQp7CiAgSUlucHV0T2JqZWN0KiBscElucHV0ID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CgogIFRSQUNFKCIoJXApXG4iLCBscFVua25vd24pOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW5wdXRPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBJbnB1dCk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwSW5wdXQpCiAgICB7CiAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RfSGFzRm9jdXNJTyhscElucHV0KTsKICAgICAgSUlucHV0T2JqZWN0X1JlbGVhc2UobHBJbnB1dCk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9yUkdCVG9ITFMJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBhbiByZ2IgQ09MT1JSRUYgaW50byB0aGUgaGxzIGNvbG9yIHNwYWNlLgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gU291cmNlIHJnYiB2YWx1ZQogKiAgcHdIdWUgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGh1ZQogKiAgcHdMdW1pbmFuY2UgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGx1bWluYW5jZQogKiAgcHdTYXR1cmF0aW9uIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIHNhdHVyYXRpb24KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4gcHdIdWUsIHB3THVtaW5hbmNlIGFuZCBwd1NhdHVyYXRpb24gYXJlIHNldCB0byB0aGUgY29udmVydGVkCiAqICB2YWx1ZXMuCiAqCiAqIE5PVEVTCiAqICBPdXRwdXQgSExTIHZhbHVlcyBhcmUgY29uc3RyYWluZWQgdG8gdGhlIHJhbmdlICgwLi4yNDApLgogKiAgRm9yIEFjaHJvbWF0aWMgY29udmVyc2lvbnMsIEh1ZSBpcyBzZXQgdG8gMTYwLgogKi8KVk9JRCBXSU5BUEkgQ29sb3JSR0JUb0hMUyhDT0xPUlJFRiBjUkdCLCBMUFdPUkQgcHdIdWUsCgkJCSAgTFBXT1JEIHB3THVtaW5hbmNlLCBMUFdPUkQgcHdTYXR1cmF0aW9uKQp7CiAgaW50IHdSLCB3Rywgd0IsIHdNYXgsIHdNaW4sIHdIdWUsIHdMdW1pbm9zaXR5LCB3U2F0dXJhdGlvbjsKCiAgVFJBQ0UoIiglMDh4LCVwLCVwLCVwKVxuIiwgY1JHQiwgcHdIdWUsIHB3THVtaW5hbmNlLCBwd1NhdHVyYXRpb24pOwoKICB3UiA9IEdldFJWYWx1ZShjUkdCKTsKICB3RyA9IEdldEdWYWx1ZShjUkdCKTsKICB3QiA9IEdldEJWYWx1ZShjUkdCKTsKCiAgd01heCA9IG1heCh3UiwgbWF4KHdHLCB3QikpOwogIHdNaW4gPSBtaW4od1IsIG1pbih3Rywgd0IpKTsKCiAgLyogTHVtaW5vc2l0eSAqLwogIHdMdW1pbm9zaXR5ID0gKCh3TWF4ICsgd01pbikgKiAyNDAgKyAyNTUpIC8gNTEwOwoKICBpZiAod01heCA9PSB3TWluKQogIHsKICAgIC8qIEFjaHJvbWF0aWMgY2FzZSAqLwogICAgd1NhdHVyYXRpb24gPSAwOwogICAgLyogSHVlIGlzIG5vdyB1bnJlcHJlc2VudGFibGUsIGJ1dCB0aGlzIGlzIHdoYXQgbmF0aXZlIHJldHVybnMuLi4gKi8KICAgIHdIdWUgPSAxNjA7CiAgfQogIGVsc2UKICB7CiAgICAvKiBDaHJvbWF0aWMgY2FzZSAqLwogICAgaW50IHdEZWx0YSA9IHdNYXggLSB3TWluLCB3Uk5vcm0sIHdHTm9ybSwgd0JOb3JtOwoKICAgIC8qIFNhdHVyYXRpb24gKi8KICAgIGlmICh3THVtaW5vc2l0eSA8PSAxMjApCiAgICAgIHdTYXR1cmF0aW9uID0gKCh3TWF4ICsgd01pbikvMiArIHdEZWx0YSAqIDI0MCkgLyAod01heCArIHdNaW4pOwogICAgZWxzZQogICAgICB3U2F0dXJhdGlvbiA9ICgoNTEwIC0gd01heCAtIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKDUxMCAtIHdNYXggLSB3TWluKTsKCiAgICAvKiBIdWUgKi8KICAgIHdSTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdSICogNDApIC8gd0RlbHRhOwogICAgd0dOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0cgKiA0MCkgLyB3RGVsdGE7CiAgICB3Qk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3QiAqIDQwKSAvIHdEZWx0YTsKCiAgICBpZiAod1IgPT0gd01heCkKICAgICAgd0h1ZSA9IHdCTm9ybSAtIHdHTm9ybTsKICAgIGVsc2UgaWYgKHdHID09IHdNYXgpCiAgICAgIHdIdWUgPSA4MCArIHdSTm9ybSAtIHdCTm9ybTsKICAgIGVsc2UKICAgICAgd0h1ZSA9IDE2MCArIHdHTm9ybSAtIHdSTm9ybTsKICAgIGlmICh3SHVlIDwgMCkKICAgICAgd0h1ZSArPSAyNDA7CiAgICBlbHNlIGlmICh3SHVlID4gMjQwKQogICAgICB3SHVlIC09IDI0MDsKICB9CiAgaWYgKHB3SHVlKQogICAgKnB3SHVlID0gd0h1ZTsKICBpZiAocHdMdW1pbmFuY2UpCiAgICAqcHdMdW1pbmFuY2UgPSB3THVtaW5vc2l0eTsKICBpZiAocHdTYXR1cmF0aW9uKQogICAgKnB3U2F0dXJhdGlvbiA9IHdTYXR1cmF0aW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQ3JlYXRlU2hlbGxQYWxldHRlCVtTSExXQVBJLkBdCiAqLwpIUEFMRVRURSBXSU5BUEkgU0hDcmVhdGVTaGVsbFBhbGV0dGUoSERDIGhkYykKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIENyZWF0ZUhhbGZ0b25lUGFsZXR0ZShoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTSEdldEludmVyc2VDTUFQIChTSExXQVBJLkApCiAqCiAqIEdldCBhbiBpbnZlcnNlIGNvbG9yIG1hcCB0YWJsZS4KICoKICogUEFSQU1TCiAqICBscENtYXAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29sb3IgbWFwCiAqICBkd1NpemUgIFtJXSBTaXplIG9mIG1lbW9yeSBwb2ludGVkIHRvIGJ5IGxwQ21hcAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSLCAgICBJZiBscENtYXAgaXMgaW52YWxpZC4KICogICAgICAgICAgIEVfSU5WQUxJREFSRywgSWYgZHdGbGFncyBpcyBpbnZhbGlkCiAqICAgICAgICAgICBFX09VVE9GTUVNT1JZLCBJZiB0aGVyZSBpcyBubyBtZW1vcnkgYXZhaWxhYmxlCiAqCiAqIE5PVEVTCiAqICBkd1NpemUgbWF5IG9ubHkgYmUgQ01BUF9QVFJfU0laRSAoNCkgb3IgQ01BUF9TSVpFICg4MTkyKS4KICogIElmIGR3U2l6ZSA9IENNQVBfUFRSX1NJWkUsICpscENtYXAgaXMgc2V0IHRvIHRoZSBhZGRyZXNzIG9mIHRoaXMgRExMJ3MKICogIGludGVybmFsIENNYXAuCiAqICBJZiBkd1NpemUgPSBDTUFQX1NJWkUsIGxwQ21hcCBpcyBmaWxsZWQgd2l0aCBhIGNvcHkgb2YgdGhlIGRhdGEgZnJvbQogKiAgdGhpcyBETEwncyBpbnRlcm5hbCBDTWFwLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnZlcnNlQ01BUChMUERXT1JEIGRlc3QsIERXT1JEIGR3U2l6ZSkKewogICAgaWYgKGR3U2l6ZSA9PSA0KSB7CglGSVhNRSgiIC0gcmV0dXJuaW5nIGJvZ3VzIGFkZHJlc3MgZm9yIFNIR2V0SW52ZXJzZUNNQVBcbiIpOwoJKmRlc3QgPSAoRFdPUkQpMHhhYmJhMTI0OTsKCXJldHVybiAwOwogICAgfQogICAgRklYTUUoIiglcCwgJSN4KSBzdHViXG4iLCBkZXN0LCBkd1NpemUpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hJc0xvd01lbW9yeU1hY2hpbmUJW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBjdXJyZW50IGNvbXB1dGVyIGhhcyBsb3cgbWVtb3J5LgogKgogKiBQQVJBTVMKICogIHggW0ldIEZJWE1FCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgaWYgdGhlIHVzZXJzIG1hY2hpbmUgaGFzIDE2IE1lZ2FieXRlcyBvZiBtZW1vcnkgb3IgbGVzcywKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNISXNMb3dNZW1vcnlNYWNoaW5lIChEV09SRCB4KQp7CiAgRklYTUUoIigweCUwOHgpIHN0dWJcbiIsIHgpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBHZXRNZW51UG9zRnJvbUlECVtTSExXQVBJLkBdCiAqCiAqIFJldHVybiB0aGUgcG9zaXRpb24gb2YgYSBtZW51IGl0ZW0gZnJvbSBpdHMgSWQuCiAqCiAqIFBBUkFNUwogKiAgIGhNZW51IFtJXSBNZW51IGNvbnRhaW5pbmcgdGhlIGl0ZW0KICogICB3SUQgICBbSV0gSWQgb2YgdGhlIG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgaW5kZXggb2YgdGhlIG1lbnUgaXRlbSBpbiBoTWVudS4KICogIEZhaWx1cmU6IC0xLCBJZiB0aGUgaXRlbSBpcyBub3QgZm91bmQuCiAqLwpJTlQgV0lOQVBJIEdldE1lbnVQb3NGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgd0lEKQp7CiBNRU5VSVRFTUlORk9XIG1pOwogSU5UIG5Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpLCBuSXRlciA9IDA7Cgogd2hpbGUgKG5JdGVyIDwgbkNvdW50KQogewogICBtaS5jYlNpemUgPSBzaXplb2YobWkpOwogICBtaS5mTWFzayA9IE1JSU1fSUQ7CiAgIGlmIChHZXRNZW51SXRlbUluZm9XKGhNZW51LCBuSXRlciwgVFJVRSwgJm1pKSAmJiBtaS53SUQgPT0gd0lEKQogICAgIHJldHVybiBuSXRlcjsKICAgbkl0ZXIrKzsKIH0KIHJldHVybiAtMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3OV0KICoKICogU2FtZSBhcyBTSExXQVBJLkdldE1lbnVQb3NGcm9tSUQKICovCkRXT1JEIFdJTkFQSSBTSE1lbnVJbmRleEZyb21JRChITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICAgIHJldHVybiBHZXRNZW51UG9zRnJvbUlEKGhNZW51LCB1SUQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ0OF0KICovClZPSUQgV0lOQVBJIEZpeFNsYXNoZXNBbmRDb2xvblcoTFBXU1RSIGxwd3N0cikKewogICAgd2hpbGUgKCpscHdzdHIpCiAgICB7CiAgICAgICAgaWYgKCpscHdzdHIgPT0gJy8nKQogICAgICAgICAgICAqbHB3c3RyID0gJ1xcJzsKICAgICAgICBscHdzdHIrKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40NjFdCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRBcHBDb21wYXRGbGFncyhEV09SRCBkd1Vua25vd24pCnsKICBGSVhNRSgiKDB4JTA4eCkgc3R1YlxuIiwgZHdVbmtub3duKTsKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS41NDldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2VBQyhSRUZDTFNJRCByY2xzaWQsIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3Q2xzQ29udGV4dCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHJldHVybiBDb0NyZWF0ZUluc3RhbmNlKHJjbHNpZCwgcFVua091dGVyLCBkd0Nsc0NvbnRleHQsIGlpZCwgcHB2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTa2lwSnVuY3Rpb24JW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIGEgYmluZCBjb250ZXh0IGNhbiBiZSBib3VuZCB0byBhbiBvYmplY3QKICoKICogUEFSQU1TCiAqICBwYmMgICAgW0ldIEJpbmQgY29udGV4dCB0byBjaGVjawogKiAgcGNsc2lkIFtJXSBDTFNJRCBvZiBvYmplY3QgdG8gYmUgYm91bmQgdG8KICoKICogUkVUVVJOUwogKiAgVFJVRTogSWYgaXQgaXMgc2FmZSB0byBiaW5kCiAqICBGQUxTRTogSWYgcGJjIGlzIGludmFsaWQgb3IgYmluZGluZyB3b3VsZCBub3QgYmUgc2FmZQogKgogKi8KQk9PTCBXSU5BUEkgU0hTa2lwSnVuY3Rpb24oSUJpbmRDdHggKnBiYywgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIHN0YXRpYyBXQ0hBUiBzelNraXBCaW5kaW5nW10gPSB7ICdTJywnaycsJ2knLCdwJywnICcsCiAgICAnQicsJ2knLCduJywnZCcsJ2knLCduJywnZycsJyAnLCdDJywnTCcsJ1MnLCdJJywnRCcsJ1wwJyB9OwogIEJPT0wgYlJldCA9IEZBTFNFOwoKICBpZiAocGJjKQogIHsKICAgIElVbmtub3duKiBscFVuazsKCiAgICBpZiAoU1VDQ0VFREVEKElCaW5kQ3R4X0dldE9iamVjdFBhcmFtKHBiYywgKExQT0xFU1RSKXN6U2tpcEJpbmRpbmcsICZscFVuaykpKQogICAgewogICAgICBDTFNJRCBjbHNpZDsKCiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fR2V0Q2xhc3NJRChscFVuaywgJmNsc2lkKSkgJiYKICAgICAgICAgIElzRXF1YWxHVUlEKHBjbHNpZCwgJmNsc2lkKSkKICAgICAgICBiUmV0ID0gVFJVRTsKCiAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmspOwogICAgfQogIH0KICByZXR1cm4gYlJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFNoZWxsS2V5IChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRTaGVsbEtleShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAgICBGSVhNRSgiKCV4LCAleCwgJXgpOiBzdHViXG4iLCBhLCBiLCBjKTsKICAgIHJldHVybiAweDUwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIUXVldWVVc2VyV29ya0l0ZW0gKFNITFdBUEkuQCkKICovCkJPT0wgV0lOQVBJIFNIUXVldWVVc2VyV29ya0l0ZW0oTFBUSFJFQURfU1RBUlRfUk9VVElORSBwZm5DYWxsYmFjaywgCiAgICAgICAgTFBWT0lEIHBDb250ZXh0LCBMT05HIGxQcmlvcml0eSwgRFdPUkRfUFRSIGR3VGFnLAogICAgICAgIERXT1JEX1BUUiAqcGR3SWQsIExQQ1NUUiBwc3pNb2R1bGUsIERXT1JEIGR3RmxhZ3MpCnsKICAgIFRSQUNFKCIoJXAsICVwLCAlZCwgJWx4LCAlcCwgJXMsICUwOHgpXG4iLCBwZm5DYWxsYmFjaywgcENvbnRleHQsCiAgICAgICAgICBsUHJpb3JpdHksIGR3VGFnLCBwZHdJZCwgZGVidWdzdHJfYShwc3pNb2R1bGUpLCBkd0ZsYWdzKTsKCiAgICBpZihsUHJpb3JpdHkgfHwgZHdUYWcgfHwgcGR3SWQgfHwgcHN6TW9kdWxlIHx8IGR3RmxhZ3MpCiAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGFyZ3VtZW50c1xuIik7CgogICAgcmV0dXJuIFF1ZXVlVXNlcldvcmtJdGVtKHBmbkNhbGxiYWNrLCBwQ29udGV4dCwgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hTZXRUaW1lclF1ZXVlVGltZXIgKFNITFdBUEkuMjYzKQogKi8KSEFORExFIFdJTkFQSSBTSFNldFRpbWVyUXVldWVUaW1lcihIQU5ETEUgaFF1ZXVlLAogICAgICAgIFdBSVRPUlRJTUVSQ0FMTEJBQ0sgcGZuQ2FsbGJhY2ssIExQVk9JRCBwQ29udGV4dCwgRFdPUkQgZHdEdWVUaW1lLAogICAgICAgIERXT1JEIGR3UGVyaW9kLCBMUENTVFIgbHBzekxpYnJhcnksIERXT1JEIGR3RmxhZ3MpCnsKICAgIEhBTkRMRSBoTmV3VGltZXI7CgogICAgLyogU0hTZXRUaW1lclF1ZXVlVGltZXIgZmxhZ3MgLT4gQ3JlYXRlVGltZXJRdWV1ZVRpbWVyIGZsYWdzICovCiAgICBpZiAoZHdGbGFncyAmIFRQU19MT05HRVhFQ1RJTUUpIHsKICAgICAgICBkd0ZsYWdzICY9IH5UUFNfTE9OR0VYRUNUSU1FOwogICAgICAgIGR3RmxhZ3MgfD0gV1RfRVhFQ1VURUxPTkdGVU5DVElPTjsKICAgIH0KICAgIGlmIChkd0ZsYWdzICYgVFBTX0VYRUNVVEVJTykgewogICAgICAgIGR3RmxhZ3MgJj0gflRQU19FWEVDVVRFSU87CiAgICAgICAgZHdGbGFncyB8PSBXVF9FWEVDVVRFSU5JT1RIUkVBRDsKICAgIH0KCiAgICBpZiAoIUNyZWF0ZVRpbWVyUXVldWVUaW1lcigmaE5ld1RpbWVyLCBoUXVldWUsIHBmbkNhbGxiYWNrLCBwQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3RHVlVGltZSwgZHdQZXJpb2QsIGR3RmxhZ3MpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHJldHVybiBoTmV3VGltZXI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSVVua25vd25fT25Gb2N1c0NoYW5nZUlTIChTSExXQVBJLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMoTFBVTktOT1dOIGxwVW5rbm93biwgTFBVTktOT1dOIHBGb2N1c09iamVjdCwgQk9PTCBiRm9jdXMpCnsKICAgIElJbnB1dE9iamVjdFNpdGUgKnBJT1MgPSBOVUxMOwogICAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICAgIFRSQUNFKCIoJXAsICVwLCAlcylcbiIsIGxwVW5rbm93biwgcEZvY3VzT2JqZWN0LCBiRm9jdXMgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCiAgICBpZiAobHBVbmtub3duKQogICAgewogICAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0U2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJnBJT1MpOwogICAgICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgcElPUykKICAgICAgICB7CiAgICAgICAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RTaXRlX09uRm9jdXNDaGFuZ2VJUyhwSU9TLCBwRm9jdXNPYmplY3QsIGJGb2N1cyk7CiAgICAgICAgICAgIElJbnB1dE9iamVjdFNpdGVfUmVsZWFzZShwSU9TKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFZhbHVlVyAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgU0tHZXRWYWx1ZVcoRFdPUkQgYSwgTFBXU1RSIGIsIExQV1NUUiBjLCBEV09SRCBkLCBEV09SRCBlLCBEV09SRCBmKQp7CiAgICBGSVhNRSgiKCV4LCAlcywgJXMsICV4LCAleCwgJXgpOiBzdHViXG4iLCBhLCBkZWJ1Z3N0cl93KGIpLCBkZWJ1Z3N0cl93KGMpLCBkLCBlLCBmKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpEbGxHZXRWZXJzaW9uX2Z1bmMpKERMTFZFUlNJT05JTkZPICopOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRVSVZlcnNpb24gKFNITFdBUEkuNDUyKQogKi8KRFdPUkQgV0lOQVBJIEdldFVJVmVyc2lvbih2b2lkKQp7CiAgICBzdGF0aWMgRFdPUkQgdmVyc2lvbjsKCiAgICBpZiAoIXZlcnNpb24pCiAgICB7CiAgICAgICAgRGxsR2V0VmVyc2lvbl9mdW5jIHBEbGxHZXRWZXJzaW9uOwogICAgICAgIEhNT0RVTEUgZGxsID0gTG9hZExpYnJhcnlBKCJzaGVsbDMyLmRsbCIpOwogICAgICAgIGlmICghZGxsKSByZXR1cm4gMDsKCiAgICAgICAgcERsbEdldFZlcnNpb24gPSAoRGxsR2V0VmVyc2lvbl9mdW5jKUdldFByb2NBZGRyZXNzKGRsbCwgIkRsbEdldFZlcnNpb24iKTsKICAgICAgICBpZiAocERsbEdldFZlcnNpb24pCiAgICAgICAgewogICAgICAgICAgICBETExWRVJTSU9OSU5GTyBkdmk7CiAgICAgICAgICAgIGR2aS5jYlNpemUgPSBzaXplb2YoRExMVkVSU0lPTklORk8pOwogICAgICAgICAgICBpZiAocERsbEdldFZlcnNpb24oJmR2aSkgPT0gU19PSykgdmVyc2lvbiA9IGR2aS5kd01ham9yVmVyc2lvbjsKICAgICAgICB9CiAgICAgICAgRnJlZUxpYnJhcnkoIGRsbCApOwogICAgICAgIGlmICghdmVyc2lvbikgdmVyc2lvbiA9IDM7ICAvKiBvbGQgc2hlbGwgZGxscyBkb24ndCBoYXZlIERsbEdldFZlcnNpb24gKi8KICAgIH0KICAgIHJldHVybiB2ZXJzaW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIFNoZWxsTWVzc2FnZUJveFdyYXBXIFtTSExXQVBJLjM4OF0KICoKICogU2VlIHNoZWxsMzIuU2hlbGxNZXNzYWdlQm94VwogKgogKiBOT1RFOgogKiBzaGx3YXBpLlNoZWxsTWVzc2FnZUJveFdyYXBXIGlzIGEgZHVwbGljYXRlIG9mIHNoZWxsMzIuU2hlbGxNZXNzYWdlQm94VwogKiBiZWNhdXNlIHdlIGNhbid0IGZvcndhcmQgdG8gaXQgaW4gdGhlIC5zcGVjIGZpbGUgc2luY2UgaXQncyBleHBvcnRlZCBieQogKiBvcmRpbmFsLiBJZiB5b3UgY2hhbmdlIHRoZSBpbXBsZW1lbnRhdGlvbiBoZXJlIHBsZWFzZSB1cGRhdGUgdGhlIGNvZGUgaW4KICogc2hlbGwzMiBhcyB3ZWxsLgogKi8KSU5UIFdJTkFQSVYgU2hlbGxNZXNzYWdlQm94V3JhcFcoSElOU1RBTkNFIGhJbnN0YW5jZSwgSFdORCBoV25kLCBMUENXU1RSIGxwVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscENhcHRpb24sIFVJTlQgdVR5cGUsIC4uLikKewogICAgV0NIQVIgc3pUZXh0WzEwMF0sIHN6VGl0bGVbMTAwXTsKICAgIExQQ1dTVFIgcHN6VGV4dCA9IHN6VGV4dCwgcHN6VGl0bGUgPSBzelRpdGxlOwogICAgTFBXU1RSIHBzelRlbXA7CiAgICB2YV9saXN0IGFyZ3M7CiAgICBpbnQgcmV0OwoKICAgIHZhX3N0YXJ0KGFyZ3MsIHVUeXBlKTsKCiAgICBUUkFDRSgiKCVwLCVwLCVwLCVwLCUwOHgpXG4iLCBoSW5zdGFuY2UsIGhXbmQsIGxwVGV4dCwgbHBDYXB0aW9uLCB1VHlwZSk7CgogICAgaWYgKElTX0lOVFJFU09VUkNFKGxwQ2FwdGlvbikpCiAgICAgICAgTG9hZFN0cmluZ1coaEluc3RhbmNlLCBMT1dPUkQobHBDYXB0aW9uKSwgc3pUaXRsZSwgc2l6ZW9mKHN6VGl0bGUpL3NpemVvZihzelRpdGxlWzBdKSk7CiAgICBlbHNlCiAgICAgICAgcHN6VGl0bGUgPSBscENhcHRpb247CgogICAgaWYgKElTX0lOVFJFU09VUkNFKGxwVGV4dCkpCiAgICAgICAgTG9hZFN0cmluZ1coaEluc3RhbmNlLCBMT1dPUkQobHBUZXh0KSwgc3pUZXh0LCBzaXplb2Yoc3pUZXh0KS9zaXplb2Yoc3pUZXh0WzBdKSk7CiAgICBlbHNlCiAgICAgICAgcHN6VGV4dCA9IGxwVGV4dDsKCiAgICBGb3JtYXRNZXNzYWdlVyhGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVIgfCBGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORywKICAgICAgICAgICAgICAgICAgIHBzelRleHQsIDAsIDAsIChMUFdTVFIpJnBzelRlbXAsIDAsICZhcmdzKTsKCiAgICB2YV9lbmQoYXJncyk7CgogICAgcmV0ID0gTWVzc2FnZUJveFcoaFduZCwgcHN6VGVtcCwgcHN6VGl0bGUsIHVUeXBlKTsKICAgIExvY2FsRnJlZSgoSExPQ0FMKXBzelRlbXApOwogICAgcmV0dXJuIHJldDsKfQoKSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUXVlcnlTZXJ2aWNlRXhlYyhJVW5rbm93biAqdW5rLCBSRUZJSUQgc2VydmljZSwgUkVGSUlEIGNsc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHgxLCBEV09SRCB4MiwgRFdPUkQgeDMsIHZvaWQgKipwcHZPdXQpCnsKICAgIEZJWE1FKCIlcCAlcyAlcyAlMDh4ICUwOHggJTA4eCAlcFxuIiwgdW5rLAogICAgICAgICAgZGVidWdzdHJfZ3VpZChzZXJ2aWNlKSwgZGVidWdzdHJfZ3VpZChjbHNpZCksIHgxLCB4MiwgeDMsIHBwdk91dCk7CiAgICByZXR1cm4gRV9OT1RJTVBMOwp9CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9Qcm9mZmVyU2VydmljZShJVW5rbm93biAqdW5rLCB2b2lkICp4MCwgdm9pZCAqeDEsIHZvaWQgKngyKQp7CiAgICBGSVhNRSgiJXAgJXAgJXAgJXBcbiIsIHVuaywgeDAsIHgxLCB4Mik7CiAgICByZXR1cm4gRV9OT1RJTVBMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIFpvbmVDb21wdXRlUGFuZVNpemUgW1NITFdBUEkuMzgyXQogKi8KVUlOVCBXSU5BUEkgWm9uZUNvbXB1dGVQYW5lU2l6ZShIV05EIGh3bmQpCnsKICAgIEZJWE1FKCJcbiIpOwogICAgcmV0dXJuIDB4OTU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgU0hDaGFuZ2VOb3RpZnlXcmFwIFtTSExXQVBJLjM5NF0KICovCnZvaWQgV0lOQVBJIFNIQ2hhbmdlTm90aWZ5V3JhcChMT05HIHdFdmVudElkLCBVSU5UIHVGbGFncywgTFBDVk9JRCBkd0l0ZW0xLCBMUENWT0lEIGR3SXRlbTIpCnsKICAgIFNIQ2hhbmdlTm90aWZ5KHdFdmVudElkLCB1RmxhZ3MsIGR3SXRlbTEsIGR3SXRlbTIpOwp9Cgp0eXBlZGVmIHN0cnVjdCBTSEVMTF9VU0VSX1NJRCB7ICAgLyogYWNjb3JkaW5nIHRvIE1TRE4gdGhpcyBzaG91bGQgYmUgaW4gc2hsb2JqLmguLi4gKi8KICAgIFNJRF9JREVOVElGSUVSX0FVVEhPUklUWSBzaWRBdXRob3JpdHk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgZHdVc2VyR3JvdXBJRDsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICBkd1VzZXJJRDsKfSBTSEVMTF9VU0VSX1NJRCwgKlBTSEVMTF9VU0VSX1NJRDsKCnR5cGVkZWYgc3RydWN0IFNIRUxMX1VTRVJfUEVSTUlTU0lPTiB7IC8qIC4uLmFuZCB0aGlzIHNob3VsZCBiZSBpbiBzaGx3YXBpLmggKi8KICAgIFNIRUxMX1VTRVJfU0lEIHN1c0lEOwogICAgRFdPUkQgICAgICAgICAgZHdBY2Nlc3NUeXBlOwogICAgQk9PTCAgICAgICAgICAgZkluaGVyaXQ7CiAgICBEV09SRCAgICAgICAgICBkd0FjY2Vzc01hc2s7CiAgICBEV09SRCAgICAgICAgICBkd0luaGVyaXRNYXNrOwogICAgRFdPUkQgICAgICAgICAgZHdJbmhlcml0QWNjZXNzTWFzazsKfSBTSEVMTF9VU0VSX1BFUk1JU1NJT04sICpQU0hFTExfVVNFUl9QRVJNSVNTSU9OOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIEdldFNoZWxsU2VjdXJpdHlEZXNjcmlwdG9yIFtTSExXQVBJLjQ3NV0KICoKICogcHJlcGFyZXMgU0VDVVJJVFlfREVTQ1JJUFRPUiBmcm9tIGEgc2V0IG9mIEFDRXMKICoKICogUEFSQU1TCiAqICBhcFVzZXJQZXJtIFtJXSBhcnJheSBvZiBwb2ludGVycyB0byBTSEVMTF9VU0VSX1BFUk1JU1NJT04gc3RydWN0dXJlcywKICogICAgICAgICAgICAgICAgIGVhY2ggb2Ygd2hpY2ggZGVzY3JpYmVzIHBlcm1pc3Npb25zIHRvIGFwcGx5CiAqICBjVXNlclBlcm0gIFtJXSBudW1iZXIgb2YgZW50cmllcyBpbiBhcFVzZXJQZXJtIGFycmF5CiAqCiAqIFJFVFVSTlMKICogIHN1Y2Nlc3M6IHBvaW50ZXIgdG8gU0VDVVJJVFlfREVTQ1JJUFRPUgogKiAgZmFpbHVyZTogTlVMTAogKgogKiBOT1RFUwogKiAgQ2FsbCBzaG91bGQgZnJlZSByZXR1cm5lZCBkZXNjcmlwdG9yIHdpdGggTG9jYWxGcmVlCiAqLwpQU0VDVVJJVFlfREVTQ1JJUFRPUiBXSU5BUEkgR2V0U2hlbGxTZWN1cml0eURlc2NyaXB0b3IoUFNIRUxMX1VTRVJfUEVSTUlTU0lPTiAqYXBVc2VyUGVybSwgaW50IGNVc2VyUGVybSkKewogICAgUFNJRCAqc2lkbGlzdDsKICAgIFBTSUQgIGN1cl91c2VyID0gTlVMTDsKICAgIEJZVEUgIHR1VXNlclsyMDAwXTsKICAgIERXT1JEIGFjbF9zaXplOwogICAgaW50ICAgc2lkX2NvdW50LCBpOwogICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcHNkID0gTlVMTDsKCiAgICBUUkFDRSgiJXAgJWRcbiIsIGFwVXNlclBlcm0sIGNVc2VyUGVybSk7CgogICAgaWYgKGFwVXNlclBlcm0gPT0gTlVMTCB8fCBjVXNlclBlcm0gPD0gMCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBzaWRsaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNVc2VyUGVybSAqIHNpemVvZihQU0lEKSk7CiAgICBpZiAoIXNpZGxpc3QpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgYWNsX3NpemUgPSBzaXplb2YoQUNMKTsKCiAgICBmb3Ioc2lkX2NvdW50ID0gMDsgc2lkX2NvdW50IDwgY1VzZXJQZXJtOyBzaWRfY291bnQrKykKICAgIHsKICAgICAgICBzdGF0aWMgU0hFTExfVVNFUl9TSUQgbnVsbF9zaWQgPSB7e1NFQ1VSSVRZX05VTExfU0lEX0FVVEhPUklUWX0sIDAsIDB9OwogICAgICAgIFBTSEVMTF9VU0VSX1BFUk1JU1NJT04gcGVybSA9IGFwVXNlclBlcm1bc2lkX2NvdW50XTsKICAgICAgICBQU0hFTExfVVNFUl9TSUQgc2lkID0gJnBlcm0tPnN1c0lEOwogICAgICAgIFBTSUQgcFNpZDsKICAgICAgICBCT09MIHJldCA9IFRSVUU7CgogICAgICAgIGlmICghbWVtY21wKCh2b2lkKilzaWQsICh2b2lkKikmbnVsbF9zaWQsIHNpemVvZihTSEVMTF9VU0VSX1NJRCkpKQogICAgICAgIHsgIC8qIGN1cnJlbnQgdXNlcidzIFNJRCAqLyAKICAgICAgICAgICAgaWYgKCFjdXJfdXNlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIFRva2VuOwogICAgICAgICAgICAgICAgRFdPUkQgYnVmc2l6ZSA9IHNpemVvZih0dVVzZXIpOwoKICAgICAgICAgICAgICAgIHJldCA9IE9wZW5Qcm9jZXNzVG9rZW4oR2V0Q3VycmVudFByb2Nlc3MoKSwgVE9LRU5fUVVFUlksICZUb2tlbik7CiAgICAgICAgICAgICAgICBpZiAocmV0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldCA9IEdldFRva2VuSW5mb3JtYXRpb24oVG9rZW4sIFRva2VuVXNlciwgKHZvaWQqKXR1VXNlciwgYnVmc2l6ZSwgJmJ1ZnNpemUgKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmV0KQogICAgICAgICAgICAgICAgICAgICAgICBjdXJfdXNlciA9ICgoUFRPS0VOX1VTRVIpJnR1VXNlciktPlVzZXIuU2lkOwogICAgICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKFRva2VuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwU2lkID0gY3VyX3VzZXI7CiAgICAgICAgfSBlbHNlIGlmIChzaWQtPmR3VXNlcklEPT0wKSAvKiBvbmUgc3ViLWF1dGhvcml0eSAqLwogICAgICAgICAgICByZXQgPSBBbGxvY2F0ZUFuZEluaXRpYWxpemVTaWQoJnNpZC0+c2lkQXV0aG9yaXR5LCAxLCBzaWQtPmR3VXNlckdyb3VwSUQsIDAsCiAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgJnBTaWQpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0ID0gQWxsb2NhdGVBbmRJbml0aWFsaXplU2lkKCZzaWQtPnNpZEF1dGhvcml0eSwgMiwgc2lkLT5kd1VzZXJHcm91cElELCBzaWQtPmR3VXNlcklELAogICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsICZwU2lkKTsKICAgICAgICBpZiAoIXJldCkKICAgICAgICAgICAgZ290byBmcmVlX3NpZHM7CgogICAgICAgIHNpZGxpc3Rbc2lkX2NvdW50XSA9IHBTaWQ7CiAgICAgICAgLyogaW5jcmVtZW50IGFjbF9zaXplICgxIEFDRSBmb3Igbm9uLWluaGVyaXRhYmxlIGFuZCAyIEFDRXMgZm9yIGluaGVyaXRhYmxlIHJlY29yZHMgKi8KICAgICAgICBhY2xfc2l6ZSArPSAoc2l6ZW9mKEFDQ0VTU19BTExPV0VEX0FDRSktc2l6ZW9mKERXT1JEKSArIEdldExlbmd0aFNpZChwU2lkKSkgKiAocGVybS0+ZkluaGVyaXQgPyAyIDogMSk7CiAgICB9CgogICAgcHNkID0gTG9jYWxBbGxvYygwLCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikgKyBhY2xfc2l6ZSk7CgogICAgaWYgKHBzZCAhPSBOVUxMKQogICAgewogICAgICAgIFBBQ0wgcEFjbCA9IChQQUNMKSgoKEJZVEUqKXBzZCkrc2l6ZW9mKFNFQ1VSSVRZX0RFU0NSSVBUT1IpKTsKCiAgICAgICAgaWYgKCFJbml0aWFsaXplU2VjdXJpdHlEZXNjcmlwdG9yKHBzZCwgU0VDVVJJVFlfREVTQ1JJUFRPUl9SRVZJU0lPTikpCiAgICAgICAgICAgIGdvdG8gZXJyb3I7CgogICAgICAgIGlmICghSW5pdGlhbGl6ZUFjbChwQWNsLCBhY2xfc2l6ZSwgQUNMX1JFVklTSU9OKSkKICAgICAgICAgICAgZ290byBlcnJvcjsKCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc2lkX2NvdW50OyBpKyspCiAgICAgICAgewogICAgICAgICAgICBQU0hFTExfVVNFUl9QRVJNSVNTSU9OIHN1cCA9IGFwVXNlclBlcm1baV07CiAgICAgICAgICAgIFBTSUQgc2lkID0gc2lkbGlzdFtpXTsKCiAgICAgICAgICAgIHN3aXRjaChzdXAtPmR3QWNjZXNzVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBBQ0NFU1NfQUxMT1dFRF9BQ0VfVFlQRToKICAgICAgICAgICAgICAgICAgICBpZiAoIUFkZEFjY2Vzc0FsbG93ZWRBY2UocEFjbCwgQUNMX1JFVklTSU9OLCBzdXAtPmR3QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VwLT5mSW5oZXJpdCAmJiAhQWRkQWNjZXNzQWxsb3dlZEFjZUV4KHBBY2wsIEFDTF9SRVZJU0lPTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEJZVEUpc3VwLT5kd0luaGVyaXRNYXNrLCBzdXAtPmR3SW5oZXJpdEFjY2Vzc01hc2ssIHNpZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFDQ0VTU19ERU5JRURfQUNFX1RZUEU6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFBZGRBY2Nlc3NEZW5pZWRBY2UocEFjbCwgQUNMX1JFVklTSU9OLCBzdXAtPmR3QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VwLT5mSW5oZXJpdCAmJiAhQWRkQWNjZXNzRGVuaWVkQWNlRXgocEFjbCwgQUNMX1JFVklTSU9OLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSlzdXAtPmR3SW5oZXJpdE1hc2ssIHN1cC0+ZHdJbmhlcml0QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFTZXRTZWN1cml0eURlc2NyaXB0b3JEYWNsKHBzZCwgVFJVRSwgcEFjbCwgRkFMU0UpKQogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgZ290byBmcmVlX3NpZHM7CgplcnJvcjoKICAgIExvY2FsRnJlZShwc2QpOwogICAgcHNkID0gTlVMTDsKZnJlZV9zaWRzOgogICAgZm9yKGkgPSAwOyBpIDwgc2lkX2NvdW50OyBpKyspCiAgICB7CiAgICAgICAgaWYgKCFjdXJfdXNlciB8fCBzaWRsaXN0W2ldICE9IGN1cl91c2VyKQogICAgICAgICAgICBGcmVlU2lkKHNpZGxpc3RbaV0pOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2lkbGlzdCk7CgogICAgcmV0dXJuIHBzZDsKfQo=