LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnZlci5oIgojaW5jbHVkZSAid2lubmV0d2suaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgImNvbW1kbGcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKTsKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBEV09SRCBTSExXQVBJX1RocmVhZFJlZl9pbmRleDsKCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZShJVW5rbm93biosUkVGR1VJRCxSRUZJSUQsTFBWT0lEKik7CkhSRVNVTFQgV0lOQVBJIFNISW52b2tlQ29tbWFuZChIV05ELElTaGVsbEZvbGRlciosTFBDSVRFTUlETElTVCxCT09MKTsKQk9PTCAgICBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUixEV09SRCk7CgovKgogTk9URVM6IE1vc3QgZnVuY3Rpb25zIGV4cG9ydGVkIGJ5IG9yZGluYWwgc2VlbSB0byBiZSBzdXBlcmZsb3VzLgogVGhlIHJlYXNvbiBmb3IgdGhlc2UgZnVuY3Rpb25zIHRvIGJlIHRoZXJlIGlzIHRvIHByb3ZpZGUgYSB3cmFwcGVyCiBmb3IgdW5pY29kZSBmdW5jdGlvbnMgdG8gcHJvdmlkZSB0aGVzZSBmdW5jdGlvbnMgb24gc3lzdGVtcyB3aXRob3V0CiB1bmljb2RlIGZ1bmN0aW9ucyBlZy4gd2luOTUvd2luOTguIFNpbmNlIHdlIGhhdmUgc3VjaCBmdW5jdGlvbnMgd2UganVzdAogY2FsbCB0aGVzZS4gSWYgcnVubmluZyBXaW5lIHdpdGggbmF0aXZlIERMTHMsIHNvbWUgbGF0ZSBib3VuZCBjYWxscyBtYXkKIGZhaWwuIEhvd2V2ZXIsIGl0IGlzIGJldHRlciB0byBpbXBsZW1lbnQgdGhlIGZ1bmN0aW9ucyBpbiB0aGUgZm9yd2FyZCBETEwKIGFuZCByZWNvbW1lbmQgdGhlIGJ1aWx0aW4gcmF0aGVyIHRoYW4gcmVpbXBsZW1lbnRpbmcgdGhlIGNhbGxzIGhlcmUhCiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZQogKgogKiBJbnRlcm5hbCBpbXBsZW1ldGF0aW9uIG9mIFNITFdBUElfMTEuCiAqLwpzdGF0aWMKSEFORExFIFdJTkFQSSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3JjUHJvY0lkLCBEV09SRCBkd0FjY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhEc3QsIGhTcmM7CiAgRFdPUkQgZHdNeVByb2NJZCA9IEdldEN1cnJlbnRQcm9jZXNzSWQoKTsKICBIQU5ETEUgaFJldCA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJWQsJWQsJTA4eCwlMDh4KVxuIiwgaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwoKICAvKiBHZXQgZGVzdCBwcm9jZXNzIGhhbmRsZSAqLwogIGlmIChkd0RzdFByb2NJZCA9PSBkd015UHJvY0lkKQogICAgaERzdCA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgZWxzZQogICAgaERzdCA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdEc3RQcm9jSWQpOwoKICBpZiAoaERzdCkKICB7CiAgICAvKiBHZXQgc3JjIHByb2Nlc3MgaGFuZGxlICovCiAgICBpZiAoZHdTcmNQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgICAgaFNyYyA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgICBlbHNlCiAgICAgIGhTcmMgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3U3JjUHJvY0lkKTsKCiAgICBpZiAoaFNyYykKICAgIHsKICAgICAgLyogTWFrZSBoYW5kbGUgYXZhaWxhYmxlIHRvIGRlc3QgcHJvY2VzcyAqLwogICAgICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShoRHN0LCBoU2hhcmVkLCBoU3JjLCAmaFJldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdBY2Nlc3MsIDAsIGR3T3B0aW9ucyB8IERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICAgICAgaFJldCA9IE5VTEw7CgogICAgICBpZiAoZHdTcmNQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgICBDbG9zZUhhbmRsZShoU3JjKTsKICAgIH0KCiAgICBpZiAoZHdEc3RQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgQ2xvc2VIYW5kbGUoaERzdCk7CiAgfQoKICBUUkFDRSgiUmV0dXJuaW5nIGhhbmRsZSAlcFxuIiwgaFJldCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjddCiAqCiAqIENyZWF0ZSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeSBhbmQgaW5pdGlhbGlzZSBpdCB3aXRoIGRhdGEuCiAqCiAqIFBBUkFNUwogKiBscHZEYXRhICBbSV0gUG9pbnRlciB0byBkYXRhIHRvIHdyaXRlCiAqIGR3U2l6ZSAgIFtJXSBTaXplIG9mIGRhdGEKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGRhdGEKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogT3JkaW5hbHMgNy0xMSBwcm92aWRlIGEgc2V0IG9mIGNhbGxzIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IGJldHdlZW4gYQogKiBncm91cCBvZiBwcm9jZXNzZXMuIFRoZSBzaGFyZWQgbWVtb3J5IGlzIHRyZWF0ZWQgb3BhcXVlbHkgaW4gdGhhdCBpdHMgc2l6ZQogKiBpcyBub3QgZXhwb3NlZCB0byBjbGllbnRzIHdobyBtYXAgaXQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHN0b3JpbmcKICogdGhlIHNpemUgb2YgdGhlIG1hcCBhcyB0aGUgZmlyc3QgRFdPUkQgb2YgbWFwcGVkIGRhdGEsIGFuZCB0aGVuIG9mZnNldHRpbmcKICogdGhlIHZpZXcgcG9pbnRlciByZXR1cm5lZCBieSB0aGlzIHNpemUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNIQWxsb2NTaGFyZWQoTFBDVk9JRCBscHZEYXRhLCBEV09SRCBkd1NpemUsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhNYXA7CiAgTFBWT0lEIHBNYXBwZWQ7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgbHB2RGF0YSwgZHdTaXplLCBkd1Byb2NJZCk7CgogIC8qIENyZWF0ZSBmaWxlIG1hcHBpbmcgb2YgdGhlIGNvcnJlY3QgbGVuZ3RoICovCiAgaE1hcCA9IENyZWF0ZUZpbGVNYXBwaW5nQShJTlZBTElEX0hBTkRMRV9WQUxVRSwgTlVMTCwgRklMRV9NQVBfUkVBRCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3U2l6ZSArIHNpemVvZihkd1NpemUpLCBOVUxMKTsKICBpZiAoIWhNYXApCiAgICByZXR1cm4gaFJldDsKCiAgLyogR2V0IGEgdmlldyBpbiBvdXIgcHJvY2VzcyBhZGRyZXNzIHNwYWNlICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoaE1hcCwgRklMRV9NQVBfUkVBRCB8IEZJTEVfTUFQX1dSSVRFLCAwLCAwLCAwKTsKCiAgaWYgKHBNYXBwZWQpCiAgewogICAgLyogV3JpdGUgc2l6ZSBvZiBkYXRhLCBmb2xsb3dlZCBieSB0aGUgZGF0YSwgdG8gdGhlIHZpZXcgKi8KICAgICooKERXT1JEKilwTWFwcGVkKSA9IGR3U2l6ZTsKICAgIGlmIChscHZEYXRhKQogICAgICBtZW1jcHkoKGNoYXIgKikgcE1hcHBlZCArIHNpemVvZihkd1NpemUpLCBscHZEYXRhLCBkd1NpemUpOwoKICAgIC8qIFJlbGVhc2Ugdmlldy4gQWxsIGZ1cnRoZXIgdmlld3MgbWFwcGVkIHdpbGwgYmUgb3BhcXVlICovCiAgICBVbm1hcFZpZXdPZkZpbGUocE1hcHBlZCk7CiAgICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaE1hcCwgZHdQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3NJZCgpLCBGSUxFX01BUF9BTExfQUNDRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERVUExJQ0FURV9TQU1FX0FDQ0VTUyk7CiAgfQoKICBDbG9zZUhhbmRsZShoTWFwKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS44XQogKgogKiBHZXQgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2Ygc2hhcmVkIG1lbW9yeSBmcm9tIGEgc2hhcmVkIG1lbW9yeSBoYW5kbGUuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHBvaW50ZXIgdG8gdGhlIHNoYXJlZCBtZW1vcnkKICogRmFpbHVyZTogTlVMTAogKgogKi8KUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICBIQU5ETEUgaER1cDsKICBMUFZPSUQgcE1hcHBlZDsKCiAgVFJBQ0UoIiglcCAlZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGhhbmRsZSB0byBzaGFyZWQgbWVtb3J5IGZvciBjdXJyZW50IHByb2Nlc3MgKi8KICBoRHVwID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUywgMCk7CiAgLyogR2V0IFZpZXcgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoRHVwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwogIENsb3NlSGFuZGxlKGhEdXApOwoKICBpZiAocE1hcHBlZCkKICAgIHJldHVybiAoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKERXT1JEKTsgLyogSGlkZSBzaXplICovCiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOV0KICoKICogUmVsZWFzZSBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5LgogKgogKiBQQVJBTVMKICogbHBWaWV3IFtJXSBTaGFyZWQgbWVtb3J5IHBvaW50ZXIKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChMUFZPSUQgbHBWaWV3KQp7CiAgVFJBQ0UoIiglcClcbiIsIGxwVmlldyk7CiAgcmV0dXJuIFVubWFwVmlld09mRmlsZSgoY2hhciAqKSBscFZpZXcgLSBzaXplb2YoRFdPUkQpKTsgLyogSW5jbHVkZSBzaXplICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuMTBdCiAqCiAqIERlc3Ryb3kgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhDbG9zZTsKCiAgVFJBQ0UoIiglcCAlZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGEgY29weSBvZiB0aGUgaGFuZGxlIGZvciBvdXIgcHJvY2VzcywgY2xvc2luZyB0aGUgc291cmNlIGhhbmRsZSAqLwogIGhDbG9zZSA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUyxEVVBMSUNBVEVfQ0xPU0VfU09VUkNFKTsKICAvKiBDbG9zZSBsb2NhbCBjb3B5ICovCiAgcmV0dXJuIENsb3NlSGFuZGxlKGhDbG9zZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICBbU0hMV0FQSS4xMV0KICoKICogQ29weSBhIHNoYXJhYmxlIG1lbW9yeSBoYW5kbGUgZnJvbSBvbmUgcHJvY2VzcyB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgICAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlIHRvIGR1cGxpY2F0ZQogKiBkd0RzdFByb2NJZCBbSV0gSUQgb2YgdGhlIHByb2Nlc3Mgd2FudGluZyB0aGUgZHVwbGljYXRlZCBoYW5kbGUKICogZHdTcmNQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqIGR3QWNjZXNzICAgIFtJXSBEZXNpcmVkIER1cGxpY2F0ZUhhbmRsZSgpIGFjY2VzcwogKiBkd09wdGlvbnMgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBvcHRpb25zCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBoYW5kbGUgc3VpdGFibGUgZm9yIHVzZSBieSB0aGUgZHdEc3RQcm9jSWQgcHJvY2Vzcy4KICogRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICoKICovCkhBTkRMRSBXSU5BUEkgU0hNYXBIYW5kbGUoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3RHN0UHJvY0lkLCBEV09SRCBkd1NyY1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0FjY2VzcywgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhSZXQ7CgogIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd0RzdFByb2NJZCwgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTNdCiAqCiAqIENyZWF0ZSBhbmQgcmVnaXN0ZXIgYSBjbGlwYm9hcmQgZW51bWVyYXRvciBmb3IgYSB3ZWIgYnJvd3Nlci4KICoKICogUEFSQU1TCiAqICBscEJDICAgICAgW0ldIEJpbmRpbmcgY29udGV4dAogKiAgbHBVbmtub3duIFtJXSBBbiBvYmplY3QgZXhwb3NpbmcgdGhlIElXZWJCcm93c2VyQXBwIGludGVyZmFjZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgVGhlIGVudW1lcmF0b3IgaXMgc3RvcmVkIGFzIGEgcHJvcGVydHkgb2YgdGhlIHdlYiBicm93c2VyLiBJZiBpdCBkb2VzIG5vdAogKiAgeWV0IGV4aXN0LCBpdCBpcyBjcmVhdGVkIGFuZCBzZXQgYmVmb3JlIGJlaW5nIHJlZ2lzdGVyZWQuCiAqLwpIUkVTVUxUIFdJTkFQSSBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzKExQQkMgbHBCQywgSVVua25vd24gKmxwVW5rbm93bikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb3BlcnR5W10gPSB7ICd7JywnRCcsJzAnLCdGJywnQycsJ0EnLCc0JywnMicsJzAnLAogICAgICAnLScsJ0QnLCczJywnRicsJzUnLCctJywnMScsJzEnLCdDJywnRicsICctJywnQicsJzInLCcxJywnMScsJy0nLCcwJywKICAgICAgJzAnLCdBJywnQScsJzAnLCcwJywnNCcsJ0EnLCdFJywnOCcsJzMnLCc3JywnfScsJ1wwJyB9OwogIEJTVFIgcHJvcGVydHk7CiAgSUVudW1GT1JNQVRFVEMqIHBJRW51bUZvcm1hdEV0YyA9IE5VTEw7CiAgVkFSSUFOVEFSRyB2YXI7CiAgSFJFU1VMVCBoUmV0OwogIElXZWJCcm93c2VyQXBwKiBwQnJvd3NlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwKVxuIiwgbHBCQywgbHBVbmtub3duKTsKCiAgLyogR2V0IEFuIElXZWJCcm93c2VyQXBwIGludGVyZmFjZSBmcm9tICBscFVua25vd24gKi8KICBoUmV0ID0gSVVua25vd25fUXVlcnlTZXJ2aWNlKGxwVW5rbm93biwgJklJRF9JV2ViQnJvd3NlckFwcCwgJklJRF9JV2ViQnJvd3NlckFwcCwgKFBWT0lEKSZwQnJvd3Nlcik7CiAgaWYgKEZBSUxFRChoUmV0KSB8fCAhcEJyb3dzZXIpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgVl9WVCgmdmFyKSA9IFZUX0VNUFRZOwoKICAvKiBUaGUgcHJvcGVydHkgd2UgZ2V0IGlzIHRoZSBicm93c2VycyBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogIHByb3BlcnR5ID0gU3lzQWxsb2NTdHJpbmcoc3pQcm9wZXJ0eSk7CiAgaFJldCA9IElXZWJCcm93c2VyQXBwX0dldFByb3BlcnR5KHBCcm93c2VyLCBwcm9wZXJ0eSwgJnZhcik7CiAgU3lzRnJlZVN0cmluZyhwcm9wZXJ0eSk7CiAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHJldHVybiBoUmV0OwoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9FTVBUWSkKICB7CiAgICAvKiBJdGVyYXRlIHRocm91Z2ggYWNjZXB0ZWQgZG9jdW1lbnRzIGFuZCBSZWdpc3RlckNsaXBCb2FyZEZvcm1hdEEoKSB0aGVtICovCiAgICBjaGFyIHN6S2V5QnVmZlsxMjhdLCBzelZhbHVlQnVmZlsxMjhdOwogICAgRFdPUkQgZHdLZXlTaXplLCBkd1ZhbHVlU2l6ZSwgZHdSZXQgPSAwLCBkd0NvdW50ID0gMCwgZHdOdW1WYWx1ZXMsIGR3VHlwZTsKICAgIEZPUk1BVEVUQyogZm9ybWF0TGlzdCwgKmZvcm1hdDsKICAgIEhLRVkgaERvY3M7CgogICAgVFJBQ0UoIlJlZ2lzdGVyaW5nIGZvcm1hdHMgYW5kIGNyZWF0aW5nIElFbnVtRk9STUFURVRDIGluc3RhbmNlXG4iKTsKCiAgICBpZiAoIVJlZ09wZW5LZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnQiCiAgICAgICAgICAgICAgICAgICAgICJWZXJzaW9uXFxJbnRlcm5ldCBTZXR0aW5nc1xcQWNjZXB0ZWQgRG9jdW1lbnRzIiwgJmhEb2NzKSkKICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAvKiBHZXQgY291bnQgb2YgdmFsdWVzIGluIGtleSAqLwogICAgd2hpbGUgKCFkd1JldCkKICAgIHsKICAgICAgZHdLZXlTaXplID0gc2l6ZW9mKHN6S2V5QnVmZik7CiAgICAgIGR3UmV0ID0gUmVnRW51bVZhbHVlQShoRG9jcyxkd0NvdW50LHN6S2V5QnVmZiwmZHdLZXlTaXplLDAsJmR3VHlwZSwwLDApOwogICAgICBkd0NvdW50Kys7CiAgICB9CgogICAgZHdOdW1WYWx1ZXMgPSBkd0NvdW50OwoKICAgIC8qIE5vdGU6IGR3Q291bnQgPSBudW1iZXIgb2YgaXRlbXMgKyAxOyBUaGUgZXh0cmEgaXRlbSBpcyB0aGUgZW5kIG5vZGUgKi8KICAgIGZvcm1hdCA9IGZvcm1hdExpc3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHdDb3VudCAqIHNpemVvZihGT1JNQVRFVEMpKTsKICAgIGlmICghZm9ybWF0TGlzdCkKICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgaWYgKGR3TnVtVmFsdWVzID4gMSkKICAgIHsKICAgICAgZHdSZXQgPSAwOwogICAgICBkd0NvdW50ID0gMDsKCiAgICAgIGR3TnVtVmFsdWVzLS07CgogICAgICAvKiBSZWdpc3RlciBjbGlwYm9hcmQgZm9ybWF0cyBmb3IgdGhlIHZhbHVlcyBhbmQgcG9wdWxhdGUgZm9ybWF0IGxpc3QgKi8KICAgICAgd2hpbGUoIWR3UmV0ICYmIGR3Q291bnQgPCBkd051bVZhbHVlcykKICAgICAgewogICAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICAgIGR3VmFsdWVTaXplID0gc2l6ZW9mKHN6VmFsdWVCdWZmKTsKICAgICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsIGR3Q291bnQsIHN6S2V5QnVmZiwgJmR3S2V5U2l6ZSwgMCwgJmR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBCWVRFKXN6VmFsdWVCdWZmLCAmZHdWYWx1ZVNpemUpOwogICAgICAgIGlmICghZHdSZXQpCiAgICAgICAgICByZXR1cm4gRV9GQUlMOwoKICAgICAgICBmb3JtYXQtPmNmRm9ybWF0ID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXRBKHN6VmFsdWVCdWZmKTsKICAgICAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICAgICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICAgICAgZm9ybWF0LT5saW5kZXggPSA0OwogICAgICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAgICAgZm9ybWF0Kys7CiAgICAgICAgZHdDb3VudCsrOwogICAgICB9CiAgICB9CgogICAgLyogVGVybWluYXRlIHRoZSAobWF5YmUgZW1wdHkpIGxpc3QsIGxhc3QgZW50cnkgaGFzIGEgY2ZGb3JtYXQgb2YgMCAqLwogICAgZm9ybWF0LT5jZkZvcm1hdCA9IDA7CiAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICBmb3JtYXQtPmR3QXNwZWN0ID0gMTsKICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAvKiBDcmVhdGUgYSBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogICAgaFJldCA9IENyZWF0ZUZvcm1hdEVudW1lcmF0b3IoZHdOdW1WYWx1ZXMsIGZvcm1hdExpc3QsICZwSUVudW1Gb3JtYXRFdGMpOwoKICAgIGlmIChGQUlMRUQoaFJldCkgfHwgIXBJRW51bUZvcm1hdEV0YykKICAgICAgcmV0dXJuIGhSZXQ7CgogICAgLyogU2V0IG91ciBlbnVtZXJhdG9yIGFzIHRoZSBicm93c2VycyBwcm9wZXJ0eSAqLwogICAgVl9WVCgmdmFyKSA9IFZUX1VOS05PV047CiAgICBWX1VOS05PV04oJnZhcikgPSAoSVVua25vd24qKXBJRW51bUZvcm1hdEV0YzsKCiAgICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfUHV0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksIHZhcik7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSUVudW1Gb3JtYXRFdGMpOwogICAgICAgZ290byBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ7CiAgICB9CiAgfQoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9VTktOT1dOKQogIHsKICAgIC8qIE91ciB2YXJpYW50IGlzIGhvbGRpbmcgdGhlIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBJVW5rbm93biogcElVbmtub3duID0gVl9VTktOT1dOKCZ2YXIpOwogICAgSUVudW1GT1JNQVRFVEMqIHBDbG9uZSA9IE5VTEw7CgogICAgVFJBQ0UoIlJldHJpZXZlZCBJRW51bUZPUk1BVEVUQyBwcm9wZXJ0eVxuIik7CgogICAgLyogR2V0IGFuIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSBmcm9tIHRoZSB2YXJpYW50cyB2YWx1ZSAqLwogICAgcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSVVua25vd24sICZJSURfSUVudW1GT1JNQVRFVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBWT0lEKSZwSUVudW1Gb3JtYXRFdGMpOwogICAgaWYgKCFoUmV0ICYmIHBJRW51bUZvcm1hdEV0YykKICAgIHsKICAgICAgLyogQ2xvbmUgYW5kIHJlZ2lzdGVyIHRoZSBlbnVtZXJhdG9yICovCiAgICAgIGhSZXQgPSBJRW51bUZPUk1BVEVUQ19DbG9uZShwSUVudW1Gb3JtYXRFdGMsICZwQ2xvbmUpOwogICAgICBpZiAoIWhSZXQgJiYgcENsb25lKQogICAgICB7CiAgICAgICAgUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yKGxwQkMsIHBDbG9uZSwgMCk7CgogICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocENsb25lKTsKICAgICAgfQoKICAgICAgLyogUmVsZWFzZSB0aGUgSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlICovCiAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElVbmtub3duKTsKICAgIH0KICAgIElVbmtub3duX1JlbGVhc2UoVl9VTktOT1dOKCZ2YXIpKTsKICB9CgpSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ6CiAgSVdlYkJyb3dzZXJBcHBfUmVsZWFzZShwQnJvd3Nlcik7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNV0KICoKICogR2V0IEV4cGxvcmVycyAiQWNjZXB0TGFuZ3VhZ2UiIHNldHRpbmcuCiAqCiAqIFBBUkFNUwogKiAgbGFuZ2J1ZiBbT10gRGVzdGluYXRpb24gZm9yIGxhbmd1YWdlIHN0cmluZwogKiAgYnVmbGVuICBbSV0gTGVuZ3RoIG9mIGxhbmdidWYKICogICAgICAgICAgWzBdIFN1Y2Nlc3M6IHVzZWQgbGVuZ3RoIG9mIGxhbmdidWYKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gICBsYW5nYnVmIGlzIHNldCB0byB0aGUgbGFuZ3VhZ2Ugc3RyaW5nIGZvdW5kLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBhbnkgYXJndW1lbnRzIGFyZSBpbnZhbGlkLCBlcnJvciBvY2N1cnJlZCwgb3IgRXhwbG9yZXIKICogICAgICAgICAgIGRvZXMgbm90IGNvbnRhaW4gdGhlIHNldHRpbmcuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIHRoZSBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2gKICovCkhSRVNVTFQgV0lOQVBJIEdldEFjY2VwdExhbmd1YWdlc1coIExQV1NUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6a2V5V1tdID0gewoJJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAoJJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB2YWx1ZVdbXSA9IHsKCSdBJywnYycsJ2MnLCdlJywncCcsJ3QnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW51c1dbXSA9IHsnZScsJ24nLCctJywndScsJ3MnLDB9OwogICAgRFdPUkQgbXlzdHJsZW4sIG15dHlwZTsKICAgIEhLRVkgbXlrZXk7CiAgICBIUkVTVUxUIHJldHZhbDsKICAgIExDSUQgbXlsY2lkOwogICAgV0NIQVIgKm15c3RyOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pCglyZXR1cm4gRV9GQUlMOwoKICAgIG15c3RybGVuID0gKCpidWZsZW4gPiAyMCkgPyAqYnVmbGVuIDogMjAgOwogICAgbXlzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIG15c3RybGVuKTsKICAgIFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBzemtleVcsICZteWtleSk7CiAgICBpZihSZWdRdWVyeVZhbHVlRXhXKG15a2V5LCB2YWx1ZVcsIDAsICZteXR5cGUsIChQQllURSlteXN0ciwgJm15c3RybGVuKSkgewogICAgICAgIC8qIERpZCBub3QgZmluZCB2YWx1ZSAqLwogICAgICAgIG15bGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIC8qIHNvbWVob3cgdGhlIG15bGNpZCB0cmFuc2xhdGVzIGludG8gImVuLXVzIgogICAgICAgICAqICB0aGlzIGlzIHNpbWlsYXIgdG8gIkxPQ0FMRV9TQUJCUkVWTEFOR05BTUUiCiAgICAgICAgICogIHdoaWNoIGNvdWxkIGJlIGdvdHRlbiB2aWEgR2V0TG9jYWxlSW5mby4KICAgICAgICAgKiAgVGhlIG9ubHkgcHJvYmxlbSBpcyBMT0NBTEVfU0FCQlJFVkxBTkdVQUdFIiBpcwogICAgICAgICAqICBhIDMgY2hhciBzdHJpbmcgKGZpcnN0IDIgYXJlIGNvdW50cnkgY29kZSBhbmQgdGhpcmQgaXMKICAgICAgICAgKiAgbGV0dGVyIGZvciAic3VibGFuZ3VhZ2UiLCB3aGljaCBkb2VzIG5vdCBjb21lIGNsb3NlIHRvCiAgICAgICAgICogICJlbi11cyIKICAgICAgICAgKi8KICAgICAgICBsc3RyY3B5VyhteXN0ciwgZW51c1cpOwogICAgICAgIG15c3RybGVuID0gbHN0cmxlblcobXlzdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBoYW5kbGUgcmV0dXJuZWQgc3RyaW5nICovCiAgICAgICAgRklYTUUoIm1pc3NpbmcgY29kZVxuIik7CiAgICB9CiAgICBtZW1jcHkoIGxhbmdidWYsIG15c3RyLCBtaW4oKmJ1ZmxlbixzdHJsZW5XKG15c3RyKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYoKmJ1ZmxlbiA+IHN0cmxlblcobXlzdHIpKSB7CgkqYnVmbGVuID0gc3RybGVuVyhteXN0cik7CglyZXR2YWwgPSBTX09LOwogICAgfSBlbHNlIHsKCSpidWZsZW4gPSAwOwoJcmV0dmFsID0gRV9JTlZBTElEQVJHOwoJU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgfQogICAgUmVnQ2xvc2VLZXkobXlrZXkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXlzdHIpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE0XQogKgogKiBBc2NpaSB2ZXJzaW9uIG9mIEdldEFjY2VwdExhbmd1YWdlc1cuCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNBKCBMUFNUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgV0NIQVIgKmxhbmdidWZXOwogICAgRFdPUkQgYnVmbGVuVywgY29udmxlbjsKICAgIEhSRVNVTFQgcmV0dmFsOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pIHJldHVybiBFX0ZBSUw7CgogICAgYnVmbGVuVyA9ICpidWZsZW47CiAgICBsYW5nYnVmVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpICogYnVmbGVuVyk7CiAgICByZXR2YWwgPSBHZXRBY2NlcHRMYW5ndWFnZXNXKGxhbmdidWZXLCAmYnVmbGVuVyk7CgogICAgLyogRklYTUU6IHRoaXMgaXMgd3JvbmcsIHRoZSBzdHJpbmcgbWF5IG5vdCBiZSBudWxsLXRlcm1pbmF0ZWQgKi8KICAgIGNvbnZsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgbGFuZ2J1ZlcsIC0xLCBsYW5nYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1ZmxlbiwgTlVMTCwgTlVMTCk7CiAgICAqYnVmbGVuID0gYnVmbGVuVyA/IGNvbnZsZW4gOiAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxhbmdidWZXKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yM10KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCAgICAgW0ldIEdVSUQgdG8gY29udmVydAogKiAgbHBzekRlc3QgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNjaE1heCAgIFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJREEoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4WC0lMDRYLSUwNFgtJTAyWCUwMlgtJTAyWCUwMlglMDJYJTAyWCUwMlglMDJYfSIsCiAgICAgICAgICBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW4oeGd1aWQpICsgMTsKCiAgaWYgKGlMZW4gPiBjY2hNYXgpCiAgICByZXR1cm4gMDsKICBtZW1jcHkobHBzekRlc3QsIHhndWlkLCBpTGVuKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0XQogKgogKiBDb252ZXJ0IGEgR1VJRCB0byBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBndWlkIFtJXSBHVUlEIHRvIGNvbnZlcnQKICogIHN0ciAgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNtYXggW0ldIExlbmd0aCBvZiBvdXRwdXQgYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBjcmVhdGVkLgogKi8KSU5UIFdJTkFQSSBTSFN0cmluZ0Zyb21HVUlEVyhSRUZHVUlEIGd1aWQsIExQV1NUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIFdDSEFSIHhndWlkWzQwXTsKICBJTlQgaUxlbjsKICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6Rm9ybWF0W10gPSB7J3snLCclJywnMCcsJzgnLCdsJywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywKICAgICAgJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnLScsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAgICdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCd9JywwfTsKCiAgVFJBQ0UoIiglcywlcCwlZClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIGxwc3pEZXN0LCBjY2hNYXgpOwoKICBzcHJpbnRmVyh4Z3VpZCwgd3N6Rm9ybWF0LCBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW5XKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbipzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIHNwYWNlLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgc3BhY2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJTcGFjZVcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1NQQUNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMwXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGJsYW5rLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgYmxhbmssCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJCbGFua1coV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0JMQU5LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBwdW5jdHVhdGlvbi4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBwdW5jdHVhdGlvbiwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclB1bmN0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfUFVOQ1QpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzJdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBjb250cm9sIGNoYXJhY3RlciwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckNudHJsVyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfQ05UUkwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzNdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckRpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfRElHSVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzRdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgaGV4IGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgaGV4IGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyWERpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfWERJR0lUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1XQogKgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZTNFeFcoTFBXU1RSIGxwc3pTdHIsIERXT1JEIGR3TGVuLCBMUFZPSUQgcDMpCnsKICAgIEZJWE1FKCIoJXMsMHglMDh4LCVwKTogc3R1YlxuIiwgZGVidWdzdHJfdyhscHN6U3RyKSwgZHdMZW4sIHAzKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzZdCiAqCiAqIEluc2VydCBhIGJpdG1hcCBtZW51IGl0ZW0gYXQgdGhlIGJvdHRvbSBvZiBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gaW5zZXJ0IGludG8KICogIGZsYWdzIFtJXSBGbGFncyBmb3IgaW5zZXJ0aW9uCiAqICBpZCAgICBbSV0gTWVudSBJRCBvZiB0aGUgaXRlbQogKiAgc3RyICAgW0ldIE1lbnUgdGV4dCBmb3IgdGhlIGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRSwgIHRoZSBpdGVtIGlzIGluc2VydGVkIGludG8gdGhlIG1lbnUKICogIEZhaWx1cmU6IEZBTFNFLCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQKICovCkJPT0wgV0lOQVBJIEFwcGVuZE1lbnVXcmFwVyhITUVOVSBoTWVudSwgVUlOVCBmbGFncywgVUlOVCBpZCwgTFBDV1NUUiBzdHIpCnsKICAgIFRSQUNFKCIoJXAsMHglMDh4LDB4JTA4eCwlcylcbiIsaE1lbnUsIGZsYWdzLCBpZCwgZGVidWdzdHJfdyhzdHIpKTsKICAgIHJldHVybiBJbnNlcnRNZW51VyhoTWVudSwgLTEsIGZsYWdzIHwgTUZfQklUTUFQLCBpZCwgc3RyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgW1NITFdBUEkuMTM4XQogKgogKiBTZXQgdGhlIHRleHQgb2YgYSBnaXZlbiBkaWFsb2cgaXRlbS4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gSGFuZGxlIG9mIGRpYWxvZwogKiAgaUl0ZW0gICAgW0ldIEluZGV4IG9mIGl0ZW0KICogIGxwc3pUZXh0IFtPXSBUZXh0IHRvIHNldAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiAgVGhlIHRleHQgb2YgdGhlIGRpYWxvZyBpcyBzZXQgdG8gbHBzelRleHQuCiAqICBGYWlsdXJlOiBGQUxTRSwgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU2V0RGxnSXRlbVRleHRXcmFwVyhIV05EIGhXbmQsIElOVCBpSXRlbSwgTFBDV1NUUiBscHN6VGV4dCkKewogICAgSFdORCBoV25kSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgaUl0ZW0pOwogICAgaWYgKGhXbmRJdGVtKQogICAgICAgIHJldHVybiBTZXRXaW5kb3dUZXh0VyhoV25kSXRlbSwgbHBzelRleHQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUxXQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzIHVwIHRvIGEgZ2l2ZW4gbGVuZ3RoLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICogIGxlbiAgICAgW0ldIE1heGltdW0gbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBJTlQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUyXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTkNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTNdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGgsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY2FzZWNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU0XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTklDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21waVcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NV0KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTZdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcFcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTddCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNhc2VjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNThdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBJQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21waVcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjBdCiAqCiAqIEdldCBhbiBpZGVudGlmaWNhdGlvbiBzdHJpbmcgZm9yIHRoZSBPUyBhbmQgZXhwbG9yZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBzekRlc3QgIFtPXSBEZXN0aW5hdGlvbiBmb3IgSWQgc3RyaW5nCiAqICBkd0Rlc3RMZW4gW0ldIExlbmd0aCBvZiBscHN6RGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCAgSWYgdGhlIHN0cmluZyB3YXMgY3JlYXRlZCBzdWNjZXNzZnVsbHkKICogIEZBTFNFLCBPdGhlcndpc2UKICovCkJPT0wgV0lOQVBJIFNIQWJvdXRJbmZvQShMUFNUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgV0NIQVIgYnVmZlsyMDg0XTsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAobHBzekRlc3QgJiYgU0hBYm91dEluZm9XKGJ1ZmYsIGR3RGVzdExlbikpCiAgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGJ1ZmYsIC0xLCBscHN6RGVzdCwgZHdEZXN0TGVuLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjFdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSEFib3V0SW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pJRUtleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6V2luTnRLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJyAnLAogICAgJ04nLCdUJywnXFwnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbktleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UmVnS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywKICAgICcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCiAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmVyc2lvbltdID0geyAnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekN1c3RvbWl6ZWRbXSA9IHsgJ0MnLCd1JywncycsJ3QnLCdvJywnbScsJ2knLCd6JywnZScsJ2QnLAogICAgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPd25lcltdID0geyAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywnZScsJ3InLCdlJywnZCcsCiAgICAnTycsJ3cnLCduJywnZScsJ3InLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPcmdbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCdyJywnZycsJ2EnLCduJywnaScsJ3onLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb2R1Y3RbXSA9IHsgJ1AnLCdyJywnbycsJ2QnLCd1JywnYycsJ3QnLCdJJywnZCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelVwZGF0ZVtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnVScsJ3AnLCdkJywnYScsJ3QnLCdlJywnVScsJ3InLCdsJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SGVscFtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnSCcsJ2UnLCdsJywncCcsJ1MnLCd0JywncicsJ2knLCduJywnZycsJ1wwJyB9OwogIFdDSEFSIGJ1ZmZbMjA4NF07CiAgSEtFWSBoUmVnOwogIERXT1JEIGR3VHlwZSwgZHdMZW47CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKCFscHN6RGVzdCkKICAgIHJldHVybiBGQUxTRTsKCiAgKmxwc3pEZXN0ID0gJ1wwJzsKCiAgLyogVHJ5IHRoZSBOVCBrZXkgZmlyc3QsIGZvbGxvd2VkIGJ5IDk1Lzk4IGtleSAqLwogIGlmIChSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5OdEtleSwgMCwgS0VZX1JFQUQsICZoUmVnKSAmJgogICAgICBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5LZXksIDAsIEtFWV9SRUFELCAmaFJlZykpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIE9TIFZlcnNpb24gKi8KICBidWZmWzBdID0gJ1wwJzsKICBkd0xlbiA9IDMwOwogIGlmICghU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LCBzelZlcnNpb24sICZkd1R5cGUsIGJ1ZmYsICZkd0xlbikpCiAgewogICAgRFdPUkQgZHdTdHJMZW4gPSBzdHJsZW5XKGJ1ZmYpOwogICAgZHdMZW4gPSAzMCAtIGR3U3RyTGVuOwogICAgU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LAogICAgICAgICAgICAgICAgc3pDdXN0b21pemVkLCAmZHdUeXBlLCBidWZmK2R3U3RyTGVuLCAmZHdMZW4pOwogIH0KICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3duZXIgKi8KICBidWZmWzBdID0gJ34nOwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek93bmVyLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3JnYW5pemF0aW9uICovCiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKGhSZWcsIHN6T3JnLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogRklYTUU6IE5vdCBzdXJlIHdoZXJlIHRoaXMgbnVtYmVyIGNvbWVzIGZyb20gICovCiAgYnVmZlswXSA9ICd+JzsKICBidWZmWzFdID0gJzAnOwogIGJ1ZmZbMl0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UHJvZHVjdCBJZCAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6UmVnS2V5LCBzelByb2R1Y3QsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgVXBkYXRlIFVybCAqLwogIGR3TGVuID0gMjA0ODsKICBpZihTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCBzelVwZGF0ZSwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5JRSBIZWxwIFN0cmluZyAqLwogIGR3TGVuID0gMjU2OwogIGlmKFNIR2V0VmFsdWVXKGhSZWcsIHN6SGVscCwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIFJlZ0Nsb3NlS2V5KGhSZWcpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYzXQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqICBjQ21kcyAgICAgICAgIFtJXQogKiAgcHJnQ21kcyAgICAgICBbT10gQ29tbWFuZHMKICogIHBDbWRUZXh0ICAgICAgW09dIENvbW1hbmQgdGV4dAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBscFVua25vd24gaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElPbGVDb21tYW5kVGFyZ2V0LgogKiAgICAgICAgICAgT3RoZXJ3aXNlLCBhbiBlcnJvciBjb2RlIGZyb20gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U3RhdHVzKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJWQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMsIHBDbWRUZXh0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscE9sZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZ0NtZHMsIHBDbWRUZXh0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJCVtTSExXQVBJLjE2NF0KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSU9sZUNvbW1hbmRUYXJnZXQuCiAqICAgICAgICAgICBPdGhlcndpc2UsIGFuIGVycm9yIGNvZGUgZnJvbSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FeGVjKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlZCwlZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBPbGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY1XQogKgogKiBSZXRyaWV2ZSwgbW9kaWZ5LCBhbmQgcmUtc2V0IGEgdmFsdWUgZnJvbSBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgW0ldIFdpbmRvdyB0byBnZXQgdmFsdWUgZnJvbQogKiAgb2Zmc2V0IFtJXSBPZmZzZXQgb2YgdmFsdWUKICogIHdNYXNrICBbSV0gTWFzayBmb3IgdWlGbGFncwogKiAgd0ZsYWdzIFtJXSBCaXRzIHRvIHNldCBpbiB3aW5kb3cgdmFsdWUKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyB2YWx1ZSBhcyBpdCB3YXMgc2V0LCBvciAwIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZC4KICoKICogTk9URVMKICogIEFueSBiaXRzIHNldCBpbiB1aU1hc2sgYXJlIGNsZWFyZWQgZnJvbSB0aGUgdmFsdWUsIHRoZW4gYW55IGJpdHMgc2V0IGluCiAqICB1aUZsYWdzIGFyZSBzZXQgaW4gdGhlIHZhbHVlLgogKi8KTE9ORyBXSU5BUEkgU0hTZXRXaW5kb3dCaXRzKEhXTkQgaHduZCwgSU5UIG9mZnNldCwgVUlOVCB3TWFzaywgVUlOVCB3RmxhZ3MpCnsKICBMT05HIHJldCA9IEdldFdpbmRvd0xvbmdBKGh3bmQsIG9mZnNldCk7CiAgTE9ORyBuZXdGbGFncyA9ICh3RmxhZ3MgJiB3TWFzaykgfCAocmV0ICYgfndGbGFncyk7CgogIGlmIChuZXdGbGFncyAhPSByZXQpCiAgICByZXQgPSBTZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQsIG5ld0ZsYWdzKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY3XQogKgogKiBDaGFuZ2UgYSB3aW5kb3cncyBwYXJlbnQuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICBbSV0gV2luZG93IHRvIGNoYW5nZSBwYXJlbnQgb2YKICogIGhXbmRQYXJlbnQgW0ldIE5ldyBwYXJlbnQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogIFRoZSBvbGQgcGFyZW50IG9mIGhXbmQuCiAqCiAqIE5PVEVTCiAqICBJZiBoV25kUGFyZW50IGlzIE5VTEwgKGRlc2t0b3ApLCB0aGUgd2luZG93IHN0eWxlIGlzIGNoYW5nZWQgdG8gV1NfUE9QVVAuCiAqICBJZiBoV25kUGFyZW50IGlzIE5PVCBOVUxMIHRoZW4gd2Ugc2V0IHRoZSBXU19DSElMRCBzdHlsZS4KICovCkhXTkQgV0lOQVBJIFNIU2V0UGFyZW50SHduZChIV05EIGhXbmQsIEhXTkQgaFduZFBhcmVudCkKewogIFRSQUNFKCIlcCwgJXBcbiIsIGhXbmQsIGhXbmRQYXJlbnQpOwoKICBpZihHZXRQYXJlbnQoaFduZCkgPT0gaFduZFBhcmVudCkKICAgIHJldHVybiAwOwoKICBpZihoV25kUGFyZW50KQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfQ0hJTEQsIFdTX0NISUxEKTsKICBlbHNlCiAgICBTSFNldFdpbmRvd0JpdHMoaFduZCwgR1dMX1NUWUxFLCBXU19QT1BVUCwgV1NfUE9QVVApOwoKICByZXR1cm4gU2V0UGFyZW50KGhXbmQsIGhXbmRQYXJlbnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTY4XQogKgogKiBMb2NhdGUgYW5kIGFkdmlzZSBhIGNvbm5lY3Rpb24gcG9pbnQgaW4gYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtTaW5rICAgW0ldIFNpbmsgZm9yIHRoZSBjb25uZWN0aW9uIHBvaW50IGFkdmlzZSBjYWxsCiAqICByaWlkICAgICAgICBbSV0gUkVGSUlEIG9mIGNvbm5lY3Rpb24gcG9pbnQgdG8gYWR2aXNlCiAqICBiQWR2aXNlT25seSBbSV0gVFJVRSA9IEFkdmlzZSBvbmx5LCBGQUxTRSA9IFVuYWR2aXNlIGZpcnN0CiAqICBscFVua25vd24gICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlCiAqICBscENvb2tpZSAgICBbT10gUG9pbnRlciB0byBjb25uZWN0aW9uIHBvaW50IGNvb2tpZQogKiAgbHBwQ1AgICAgICAgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgSUNvbm5lY3Rpb25Qb2ludCBmb3VuZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBscHBDUCBpcyBub24tTlVMTCwgaXQgaXMgZmlsbGVkIHdpdGggdGhlIElDb25uZWN0aW9uUG9pbnQKICogICAgICAgICAgIHRoYXQgd2FzIGFkdmlzZWQuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHJlbGVhc2luZyBpdC4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgYW55IGFyZ3VtZW50cyBhcmUgaW52YWxpZC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBpc24ndCBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlIGlmIGFueSBjYWxsIGZhaWxzLgogKi8KSFJFU1VMVCBXSU5BUEkgQ29ubmVjdFRvQ29ubmVjdGlvblBvaW50KElVbmtub3duKiBscFVua1NpbmssIFJFRklJRCByaWlkLCBCT09MIGJBZHZpc2VPbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biogbHBVbmtub3duLCBMUERXT1JEIGxwQ29va2llLAogICAgICAgICAgICAgICAgICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50ICoqbHBwQ1ApCnsKICBIUkVTVUxUIGhSZXQ7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDb250YWluZXI7CiAgSUNvbm5lY3Rpb25Qb2ludCAqbHBDUDsKCiAgaWYoIWxwVW5rbm93biB8fCAoYkFkdmlzZU9ubHkgJiYgIWxwVW5rU2luaykpCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZihscHBDUCkKICAgICpscHBDUCA9IE5VTEw7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDb250YWluZXIpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENvbnRhaW5lciwgcmlpZCwgJmxwQ1ApOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICB7CiAgICAgIGlmKCFiQWR2aXNlT25seSkKICAgICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9VbmFkdmlzZShscENQLCAqbHBDb29raWUpOwogICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9BZHZpc2UobHBDUCwgbHBVbmtTaW5rLCBscENvb2tpZSk7CgogICAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICAgICpscENvb2tpZSA9IDA7CgogICAgICBpZiAobHBwQ1AgJiYgU1VDQ0VFREVEKGhSZXQpKQogICAgICAgICpscHBDUCA9IGxwQ1A7IC8qIENhbGxlciBrZWVwcyB0aGUgaW50ZXJmYWNlICovCiAgICAgIGVsc2UKICAgICAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7IC8qIFJlbGVhc2UgaXQgKi8KICAgIH0KCiAgICBJVW5rbm93bl9SZWxlYXNlKGxwQ29udGFpbmVyKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCUAJW1NITFdBUEkuMTY5XQogKgogKiBSZWxlYXNlIGFuIGludGVyZmFjZS4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byByZWxlYXNlCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fQXRvbWljUmVsZWFzZShJVW5rbm93biAqKiBscFVua25vd24pCnsKICAgIElVbmtub3duICp0ZW1wOwoKICAgIFRSQUNFKCIoJXApXG4iLGxwVW5rbm93bik7CgogICAgaWYoIWxwVW5rbm93biB8fCAhKigoTFBEV09SRClscFVua25vd24pKSByZXR1cm4gMDsKICAgIHRlbXAgPSAqbHBVbmtub3duOwogICAgKmxwVW5rbm93biA9IE5VTEw7CgogICAgVFJBQ0UoImRvaW5nIFJlbGVhc2VcbiIpOwoKICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKHRlbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcwXQogKgogKiBTa2lwICcvLycgaWYgcHJlc2VudCBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTdHJpbmcgdG8gY2hlY2sgZm9yICcvLycKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIG5leHQgY2hhcmFjdGVyIGFmdGVyIHRoZSAnLy8nIG9yIHRoZSBzdHJpbmcgaWYgbm90IHByZXNlbnQKICogIEZhaWx1cmU6IE5VTEwsIGlmIGxwc3pTdHIgaXMgTlVMTC4KICovCkxQQ1NUUiBXSU5BUEkgUGF0aFNraXBMZWFkaW5nU2xhc2hlc0EoTFBDU1RSIGxwc3pTcmMpCnsKICBpZiAobHBzelNyYyAmJiBscHN6U3JjWzBdID09ICcvJyAmJiBscHN6U3JjWzFdID09ICcvJykKICAgIGxwc3pTcmMgKz0gMjsKICByZXR1cm4gbHBzelNyYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNzFdCiAqCiAqIENoZWNrIGlmIHR3byBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgIGxwSW50MSBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQyLgogKiAgIGxwSW50MiBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQxLgogKgogKiBSRVRVUk5TCiAqICAgVFJVRSwgSWYgdGhlIGludGVyZmFjZXMgY29tZSBmcm9tIHRoZSBzYW1lIG9iamVjdC4KICogICBGQUxTRSBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzU2FtZU9iamVjdChJVW5rbm93biogbHBJbnQxLCBJVW5rbm93biogbHBJbnQyKQp7CiAgTFBWT0lEIGxwVW5rbm93bjEsIGxwVW5rbm93bjI7CgogIFRSQUNFKCIlcCAlcFxuIiwgbHBJbnQxLCBscEludDIpOwoKICBpZiAoIWxwSW50MSB8fCAhbHBJbnQyKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBJbnQxID09IGxwSW50MikKICAgIHJldHVybiBUUlVFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDEsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMSkpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDIsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMikpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBVbmtub3duMSA9PSBscFVua25vd24yKQogICAgcmV0dXJuIFRSVUU7CgogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3Ml0KICoKICogR2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBnZXQgdGhlIHdpbmRvdyBoYW5kbGUgb2YKICogIGxwaFduZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHdpbmRvdyBoYW5kbGUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBoV25kIGNvbnRhaW5zIHRoZSBvYmplY3RzIHdpbmRvdyBoYW5kbGUuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCBvbmUgb2YgdGhlIGZvbGxvd2luZyBpbnRlcmZhY2VzOgogKiAgSU9sZVdpbmRvdygpLCBJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUoKSwgb3IgSVNoZWxsVmlldygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0V2luZG93KElVbmtub3duICpscFVua25vd24sIEhXTkQgKmxwaFduZCkKewogIC8qIEZJWE1FOiBXaW5lIGhhcyBubyBoZWFkZXIgZm9yIHRoaXMgb2JqZWN0ICovCiAgc3RhdGljIGNvbnN0IEdVSUQgSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSA9IHsgMHg3OWVhYzllZCwKICAgIDB4YmFmOSwgMHgxMWNlLCB7IDB4OGMsIDB4ODIsIDB4MDAsIDB4YWEsIDB4MDAsIDB4NGIsIDB4YTksIDB4MGIgfX07CiAgSVVua25vd24gKmxwT2xlOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBoV25kKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gaFJldDsKCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlV2luZG93LCAodm9pZCoqKSZscE9sZSk7CgogIGlmIChGQUlMRUQoaFJldCkpCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwmSUlEX0lTaGVsbFZpZXcsICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICB9CiAgfQoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIC8qIExhenluZXNzIGhlcmUgLSBTaW5jZSBHZXRXaW5kb3coKSBpcyB0aGUgZmlyc3QgbWV0aG9kIGZvciB0aGUgYWJvdmUgMwogICAgICogaW50ZXJmYWNlcywgd2UgdXNlIHRoZSBzYW1lIGNhbGwgZm9yIHRoZW0gYWxsLgogICAgICovCiAgICBoUmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cqKWxwT2xlLCBscGhXbmQpOwogICAgSVVua25vd25fUmVsZWFzZShscE9sZSk7CiAgICBpZiAobHBoV25kKQogICAgICBUUkFDRSgiUmV0dXJuaW5nIEhXTkQ9JXBcbiIsICpscGhXbmQpOwogIH0KCiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzNdCiAqCiAqIENhbGwgYSBtZXRob2Qgb24gYXMgYXMgeWV0IHVuaWRlbnRpZmllZCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgcFVuayBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIHVuaWRlbnRpZmllZCBpbnRlcmZhY2UsCiAqICBhcmcgIFtJXSBBcmd1bWVudCBmb3IgdGhlIGNhbGwgb24gdGhlIG9iamVjdC4KICoKICogUkVUVVJOUwogKiAgU19PSy4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1NldE93bmVyKElVbmtub3duICpwVW5rLCBVTE9ORyBhcmcpCnsKICBzdGF0aWMgY29uc3QgR1VJRCBndWlkXzE3MyA9IHsKICAgIDB4NTgzNmZiMDAsIDB4ODE4NywgMHgxMWNmLCB7IDB4YTEsMHgyYiwweDAwLDB4YWEsMHgwMCwweDRhLDB4ZTgsMHgzNyB9CiAgfTsKICBJTWFsbG9jICpwVW5rMjsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIHBVbmssIGFyZyk7CgogIC8qIE5vdGU6IGFyZyBtYXkgbm90IGJlIGEgVUxPTkcgYW5kIHBVbmsyIGlzIGZvciBzdXJlIG5vdCBhbiBJTWFsbG9jIC0KICAgKiAgICAgICBXZSB1c2UgdGhpcyBpbnRlcmZhY2UgYXMgaXRzIHZ0YWJsZSBlbnRyeSBpcyBjb21wYXRpYmxlIHdpdGggdGhlCiAgICogICAgICAgb2JqZWN0IGluIHF1ZXN0aW9uLgogICAqIEZJWE1FOiBGaW5kIG91dCB3aGF0IHRoaXMgb2JqZWN0IGlzIGFuZCB3aGVyZSBpdCBzaG91bGQgYmUgZGVmaW5lZC4KICAgKi8KICBpZiAocFVuayAmJgogICAgICBTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocFVuaywgJmd1aWRfMTczLCAodm9pZCoqKSZwVW5rMikpKQogIHsKICAgIElNYWxsb2NfQWxsb2MocFVuazIsIGFyZyk7IC8qIEZha2VkIGNhbGwhISAqLwogICAgSU1hbGxvY19SZWxlYXNlKHBVbmsyKTsKICB9CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzRdCiAqCiAqIENhbGwgZWl0aGVyIElPYmplY3RXaXRoU2l0ZV9TZXRTaXRlKCkgb3IgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZSgpIG9uCiAqIGFuIG9iamVjdC4KICoKICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1NldFNpdGUoCiAgICAgICAgSVVua25vd24gKm9iaiwgICAgICAgIC8qIFtpbl0gICBPTEUgb2JqZWN0ICAgICAqLwogICAgICAgIElVbmtub3duICpzaXRlKSAgICAgICAvKiBbaW5dICAgU2l0ZSBpbnRlcmZhY2UgKi8KewogICAgSFJFU1VMVCBocjsKICAgIElPYmplY3RXaXRoU2l0ZSAqaW9iandpdGhzaXRlOwogICAgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyICppc2VjbWdyOwoKICAgIGlmICghb2JqKSByZXR1cm4gRV9GQUlMOwoKICAgIGhyID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2Uob2JqLCAmSUlEX0lPYmplY3RXaXRoU2l0ZSwgKExQVk9JRCAqKSZpb2Jqd2l0aHNpdGUpOwogICAgVFJBQ0UoIklJRF9JT2JqZWN0V2l0aFNpdGUgUUkgcmV0PSUwOHgsICVwXG4iLCBociwgaW9iandpdGhzaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgewoJaHIgPSBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZShpb2Jqd2l0aHNpdGUsIHNpdGUpOwoJVFJBQ0UoImRvbmUgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUgcmV0PSUwOHhcbiIsIGhyKTsKCUlVbmtub3duX1JlbGVhc2UoaW9iandpdGhzaXRlKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWhyID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2Uob2JqLCAmSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWFuYWdlciwgKExQVk9JRCAqKSZpc2VjbWdyKTsKCVRSQUNFKCJJSURfSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyIFFJIHJldD0lMDh4LCAlcFxuIiwgaHIsIGlzZWNtZ3IpOwoJaWYgKEZBSUxFRChocikpIHJldHVybiBocjsKCglociA9IElJbnRlcm5ldFNlY3VyaXR5TWFuYWdlcl9TZXRTZWN1cml0eVNpdGUoaXNlY21nciwgKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSAqKXNpdGUpOwoJVFJBQ0UoImRvbmUgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZSByZXQ9JTA4eFxuIiwgaHIpOwoJSVVua25vd25fUmVsZWFzZShpc2VjbWdyKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NV0KICoKICogQ2FsbCBJUGVyc2lzdF9HZXRDbGFzc0lEKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0IGludGVyZmFjZQogKiAgbHBDbGFzc0lkIFtPXSBEZXN0aW5hdGlvbiBmb3IgQ2xhc3MgSWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBDbGFzc0lkIGNvbnRhaW5zIHRoZSBDbGFzcyBJZCByZXF1ZXN0ZWQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGxwVW5rbm93biBpcyBOVUxMLAogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSBJZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJUGVyc2lzdCwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldENsYXNzSUQoSVVua25vd24gKmxwVW5rbm93biwgQ0xTSUQqIGxwQ2xhc3NJZCkKewogIElQZXJzaXN0KiBscFBlcnNpc3Q7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGxwQ2xhc3NJZCkpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JUGVyc2lzdCwodm9pZCoqKSZscFBlcnNpc3QpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgSVBlcnNpc3RfR2V0Q2xhc3NJRChscFBlcnNpc3QsIGxwQ2xhc3NJZCk7CiAgICAgIElQZXJzaXN0X1JlbGVhc2UobHBQZXJzaXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzZdCiAqCiAqIFJldHJpZXZlIGEgU2VydmljZSBJbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20KICogIHNpZCAgICAgICBbSV0gU2VydmljZSBJRCBmb3IgSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UoKSBjYWxsCiAqICByaWlkICAgICAgW0ldIEZ1bmN0aW9uIHJlcXVlc3RlZCBmb3IgUXVlcnlTZXJ2aWNlIGNhbGwKICogIGxwcE91dCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBzZXJ2aWNlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwcE91dCBjb250YWlucyBhbiBvYmplY3QgcHJvdmlkaW5nIHRoZSByZXF1ZXN0ZWQgc2VydmljZQogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBzaWQsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKmxwcE91dCkKewogIElTZXJ2aWNlUHJvdmlkZXIqIHBTZXJ2aWNlID0gTlVMTDsKICBIUkVTVUxUIGhSZXQ7CgogIGlmICghbHBwT3V0KQogICAgcmV0dXJuIEVfRkFJTDsKCiAgKmxwcE91dCA9IE5VTEw7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgLyogR2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVNlcnZpY2VQcm92aWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopJnBTZXJ2aWNlKTsKCiAgaWYgKCFoUmV0ICYmIHBTZXJ2aWNlKQogIHsKICAgIFRSQUNFKCJRdWVyeUludGVyZmFjZSByZXR1cm5lZCAoSVNlcnZpY2VQcm92aWRlciopJXBcbiIsIHBTZXJ2aWNlKTsKCiAgICAvKiBHZXQgYSBTZXJ2aWNlIGludGVyZmFjZSBmcm9tIHRoZSBvYmplY3QgKi8KICAgIGhSZXQgPSBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZShwU2VydmljZSwgc2lkLCByaWlkLCBscHBPdXQpOwoKICAgIFRSQUNFKCIoSVNlcnZpY2VQcm92aWRlciopJXAgcmV0dXJuZWQgKElVbmtub3duKiklcFxuIiwgcFNlcnZpY2UsICpscHBPdXQpOwoKICAgIC8qIFJlbGVhc2UgdGhlIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlICovCiAgICBJVW5rbm93bl9SZWxlYXNlKHBTZXJ2aWNlKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzddCiAqCiAqIExvYWRzIGEgcG9wdXAgbWVudS4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgW0ldIEluc3RhbmNlIGhhbmRsZQogKiAgc3pOYW1lIFtJXSBNZW51IG5hbWUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgU0hMb2FkTWVudVBvcHVwKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiBzek5hbWUpCnsKICBITUVOVSBoTWVudSwgaFN1Yk1lbnU7CgogIGlmICgoaE1lbnUgPSBMb2FkTWVudVcoaEluc3QsIHN6TmFtZSkpKQogIHsKICAgIGlmICgoaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCAwKSkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0IF9lbnVtV25kRGF0YQp7CiAgVUlOVCAgIHVpTXNnSWQ7CiAgV1BBUkFNIHdQYXJhbTsKICBMUEFSQU0gbFBhcmFtOwogIExSRVNVTFQgKFdJTkFQSSAqcGZuUG9zdCkoSFdORCxVSU5ULFdQQVJBTSxMUEFSQU0pOwp9IGVudW1XbmREYXRhOwoKLyogQ2FsbGJhY2sgZm9yIFNITFdBUElfMTc4ICovCnN0YXRpYyBCT09MIENBTExCQUNLIFNITFdBUElfRW51bUNoaWxkUHJvYyhIV05EIGhXbmQsIExQQVJBTSBsUGFyYW0pCnsKICBlbnVtV25kRGF0YSAqZGF0YSA9IChlbnVtV25kRGF0YSAqKWxQYXJhbTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGhXbmQsIGRhdGEpOwogIGRhdGEtPnBmblBvc3QoaFduZCwgZGF0YS0+dWlNc2dJZCwgZGF0YS0+d1BhcmFtLCBkYXRhLT5sUGFyYW0pOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xNzhdCiAqCiAqIFNlbmQgb3IgcG9zdCBhIG1lc3NhZ2UgdG8gZXZlcnkgY2hpbGQgb2YgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICBbSV0gV2luZG93IHdob3NlIGNoaWxkcmVuIHdpbGwgZ2V0IHRoZSBtZXNzYWdlcwogKiAgdWlNc2dJZCBbSV0gTWVzc2FnZSBJZAogKiAgd1BhcmFtICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqICBiU2VuZCAgIFtJXSBUUlVFID0gVXNlIFNlbmRNZXNzYWdlQSgpLCBGQUxTRSA9IFVzZSBQb3N0TWVzc2FnZUEoKQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKgogKiBOT1RFUwogKiAgVGhlIGFwcHJvcHJpYXRlIEFTQ0lJIG9yIFVuaWNvZGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciB0aGUgd2luZG93LgogKi8Kdm9pZCBXSU5BUEkgU0hQcm9wYWdhdGVNZXNzYWdlKEhXTkQgaFduZCwgVUlOVCB1aU1zZ0lkLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtLCBCT09MIGJTZW5kKQp7CiAgZW51bVduZERhdGEgZGF0YTsKCiAgVFJBQ0UoIiglcCwldSwlbGQsJWxkLCVkKVxuIiwgaFduZCwgdWlNc2dJZCwgd1BhcmFtLCBsUGFyYW0sIGJTZW5kKTsKCiAgaWYoaFduZCkKICB7CiAgICBkYXRhLnVpTXNnSWQgPSB1aU1zZ0lkOwogICAgZGF0YS53UGFyYW0gID0gd1BhcmFtOwogICAgZGF0YS5sUGFyYW0gID0gbFBhcmFtOwoKICAgIGlmIChiU2VuZCkKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVNlbmRNZXNzYWdlVyA6ICh2b2lkKilTZW5kTWVzc2FnZUE7CiAgICBlbHNlCiAgICAgIGRhdGEucGZuUG9zdCA9IElzV2luZG93VW5pY29kZShoV25kKSA/ICh2b2lkKilQb3N0TWVzc2FnZVcgOiAodm9pZCopUG9zdE1lc3NhZ2VBOwoKICAgIEVudW1DaGlsZFdpbmRvd3MoaFduZCwgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jLCAoTFBBUkFNKSZkYXRhKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODBdCiAqCiAqIFJlbW92ZSBhbGwgc3ViLW1lbnVzIGZyb20gYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIHJlbW92ZSBzdWItbWVudXMgZnJvbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiAwLiAgQWxsIHN1Yi1tZW51cyB1bmRlciBoTWVudSBhcmUgcmVtb3ZlZAogKiAgRmFpbHVyZTogLTEsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KRFdPUkQgV0lOQVBJIFNIUmVtb3ZlQWxsU3ViTWVudXMoSE1FTlUgaE1lbnUpCnsKICBpbnQgaUl0ZW1Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpIC0gMTsKICB3aGlsZSAoaUl0ZW1Db3VudCA+PSAwKQogIHsKICAgIEhNRU5VIGhTdWJNZW51ID0gR2V0U3ViTWVudShoTWVudSwgaUl0ZW1Db3VudCk7CiAgICBpZiAoaFN1Yk1lbnUpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIGlJdGVtQ291bnQsIE1GX0JZUE9TSVRJT04pOwogICAgaUl0ZW1Db3VudC0tOwogIH0KICByZXR1cm4gaUl0ZW1Db3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MV0KICoKICogRW5hYmxlIG9yIGRpc2FibGUgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgICBbSV0gSUQgb2YgbWVudSBpdGVtIHRvIGVuYWJsZS9kaXNhYmxlCiAqICBiRW5hYmxlIFtJXSBXaGV0aGVyIHRvIGVuYWJsZSAoVFJVRSkgb3IgZGlzYWJsZSAoRkFMU0UpIHRoZSBpdGVtLgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0dXJuIGNvZGUgZnJvbSBFbmFibGVNZW51SXRlbS4KICovClVJTlQgV0lOQVBJIFNIRW5hYmxlTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgd0l0ZW1JRCwgQk9PTCBiRW5hYmxlKQp7CiAgcmV0dXJuIEVuYWJsZU1lbnVJdGVtKGhNZW51LCB3SXRlbUlELCBiRW5hYmxlID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMTgyXQogKgogKiBDaGVjayBvciB1bmNoZWNrIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51ICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gY2hlY2svdW5jaGVjawogKiAgYkNoZWNrIFtJXSBXaGV0aGVyIHRvIGNoZWNrIChUUlVFKSBvciB1bmNoZWNrIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIENoZWNrTWVudUl0ZW0uCiAqLwpEV09SRCBXSU5BUEkgU0hDaGVja01lbnVJdGVtKEhNRU5VIGhNZW51LCBVSU5UIHVJRCwgQk9PTCBiQ2hlY2spCnsKICByZXR1cm4gQ2hlY2tNZW51SXRlbShoTWVudSwgdUlELCBiQ2hlY2sgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4M10KICoKICogUmVnaXN0ZXIgYSB3aW5kb3cgY2xhc3MgaWYgaXQgaXNuJ3QgYWxyZWFkeS4KICoKICogUEFSQU1TCiAqICBscFduZENsYXNzIFtJXSBXaW5kb3cgY2xhc3MgdG8gcmVnaXN0ZXIKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiB0aGUgUmVnaXN0ZXJDbGFzc0EgY2FsbC4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NBKFdORENMQVNTQSAqd25kY2xhc3MpCnsKICBXTkRDTEFTU0Egd2NhOwogIGlmIChHZXRDbGFzc0luZm9BKHduZGNsYXNzLT5oSW5zdGFuY2UsIHduZGNsYXNzLT5scHN6Q2xhc3NOYW1lLCAmd2NhKSkKICAgIHJldHVybiBUUlVFOwogIHJldHVybiAoRFdPUkQpUmVnaXN0ZXJDbGFzc0Eod25kY2xhc3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg2XQogKi8KQk9PTCBXSU5BUEkgU0hTaW11bGF0ZURyb3AoSURyb3BUYXJnZXQgKnBEcm9wLCBJRGF0YU9iamVjdCAqcERhdGFPYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGdyZktleVN0YXRlLCBQUE9JTlRMIGxwUHQsIERXT1JEKiBwZHdFZmZlY3QpCnsKICBEV09SRCBkd0VmZmVjdCA9IERST1BFRkZFQ1RfTElOSyB8IERST1BFRkZFQ1RfTU9WRSB8IERST1BFRkZFQ1RfQ09QWTsKICBQT0lOVEwgcHQgPSB7IDAsIDAgfTsKCiAgaWYgKCFscFB0KQogICAgbHBQdCA9ICZwdDsKCiAgaWYgKCFwZHdFZmZlY3QpCiAgICBwZHdFZmZlY3QgPSAmZHdFZmZlY3Q7CgogIElEcm9wVGFyZ2V0X0RyYWdFbnRlcihwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgaWYgKCpwZHdFZmZlY3QpCiAgICByZXR1cm4gSURyb3BUYXJnZXRfRHJvcChwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgSURyb3BUYXJnZXRfRHJhZ0xlYXZlKHBEcm9wKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4N10KICoKICogQ2FsbCBJUGVyc2lzdFByb3BlcnR5QmFnX0xvYWQoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSVBlcnNpc3RQcm9wZXJ0eUJhZyBpbnRlcmZhY2UKICogIGxwUHJvcEJhZyBbT10gRGVzdGluYXRpb24gZm9yIGxvYWRlZCBJUHJvcGVydHlCYWcKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIFNITG9hZEZyb21Qcm9wZXJ0eUJhZyhJVW5rbm93biAqbHBVbmtub3duLCBJUHJvcGVydHlCYWcqIGxwUHJvcEJhZykKewogIElQZXJzaXN0UHJvcGVydHlCYWcqIGxwUFBCYWc7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscFByb3BCYWcpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVBlcnNpc3RQcm9wZXJ0eUJhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFBQQmFnKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBQUEJhZykKICAgIHsKICAgICAgaFJldCA9IElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZChscFBQQmFnLCBscFByb3BCYWcsIE5VTEwpOwogICAgICBJUGVyc2lzdFByb3BlcnR5QmFnX1JlbGVhc2UobHBQUEJhZyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODhdCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX1RyYW5zbGF0ZUFjY2VsZXJhdG9yKCkgIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb250cm9sU2l0ZSBpbnRlcmZhY2UuCiAqICBscE1zZyAgICAgICBbSV0gS2V5IG1lc3NhZ2UgdG8gYmUgcHJvY2Vzc2VkLgogKiAgZHdNb2RpZmllcnMgW0ldIEZsYWdzIGNvbnRhaW5pbmcgdGhlIHN0YXRlIG9mIHRoZSBtb2RpZmllciBrZXlzLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9UcmFuc2xhdGVBY2NlbGVyYXRvck9DUyhJVW5rbm93biAqbHBVbmtub3duLCBMUE1TRyBscE1zZywgRFdPUkQgZHdNb2RpZmllcnMpCnsKICBJT2xlQ29udHJvbFNpdGUqIGxwQ1NpdGUgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgVFJBQ0UoIiglcCwlcCwweCUwOHgpXG4iLCBscFVua25vd24sIGxwTXNnLCBkd01vZGlmaWVycyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9UcmFuc2xhdGVBY2NlbGVyYXRvcihscENTaXRlLCBscE1zZywgZHdNb2RpZmllcnMpOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX09uRm9jdXMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZS4KICogIGZHb3RGb2N1cyBbSV0gV2hldGhlciBmb2N1cyB3YXMgZ2FpbmVkIChUUlVFKSBvciBsb3N0IChGQUxTRSkuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfRkFJTCBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX09uRm9jdXNPQ1MoSVVua25vd24gKmxwVW5rbm93biwgQk9PTCBmR290Rm9jdXMpCnsKICBJT2xlQ29udHJvbFNpdGUqIGxwQ1NpdGUgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIGxwVW5rbm93biwgZkdvdEZvY3VzID8gIlRSVUUiIDogIkZBTFNFIik7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9PbkZvY3VzKGxwQ1NpdGUsIGZHb3RGb2N1cyk7CiAgICAgIElPbGVDb250cm9sU2l0ZV9SZWxlYXNlKGxwQ1NpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICBbU0hMV0FQSS4xOTBdCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9IYW5kbGVJUmVzdHJpY3QoTFBVTktOT1dOIGxwVW5rbm93biwgUFZPSUQgbHBBcmcxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFZPSUQgbHBBcmcyLCBQVk9JRCBscEFyZzMsIFBWT0lEIGxwQXJnNCkKewogIC8qIEZJWE1FOiB7RDEyRjI2QjItRDkwQS0xMUQwLTgzMEQtMDBBQTAwNUI0MzgzfSAtIFdoYXQgb2JqZWN0IGRvZXMgdGhpcyByZXByZXNlbnQ/ICovCiAgc3RhdGljIGNvbnN0IERXT1JEIHNlcnZpY2VfaWRbXSA9IHsgMHhkMTJmMjZiMiwgMHgxMWQwZDkwYSwgMHhhYTAwMGQ4MywgMHg4MzQzNWIwMCB9OwogIC8qIEZJWE1FOiB7RDEyRjI2QjEtRDkwQS0xMUQwLTgzMEQtMDBBQTAwNUI0MzgzfSAtIEFsc28gVW5rbm93bi91bmRvY3VtZW50ZWQgKi8KICBzdGF0aWMgY29uc3QgRFdPUkQgZnVuY3Rpb25faWRbXSA9IHsgMHhkMTJmMjZiMSwgMHgxMWQwZDkwYSwgMHhhYTAwMGQ4MywgMHg4MzQzNWIwMCB9OwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKICBMUFVOS05PV04gbHBVbmtJbm5lciA9IE5VTEw7IC8qIEZJWE1FOiBSZWFsIHR5cGUgaXMgdW5rbm93biAqLwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVwKVxuIiwgbHBVbmtub3duLCBscEFyZzEsIGxwQXJnMiwgbHBBcmczLCBscEFyZzQpOwoKICBpZiAobHBVbmtub3duICYmIGxwQXJnNCkKICB7CiAgICAgaFJldCA9IElVbmtub3duX1F1ZXJ5U2VydmljZShscFVua25vd24sIChSRUZHVUlEKXNlcnZpY2VfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUkVGR1VJRClmdW5jdGlvbl9pZCwgKHZvaWQqKikmbHBVbmtJbm5lcik7CgogICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBVbmtJbm5lcikKICAgICB7CiAgICAgICAvKiBGSVhNRTogVGhlIHR5cGUgb2Ygc2VydmljZSBvYmplY3QgcmVxdWVzdGVkIGlzIHVua25vd24sIGhvd2V2ZXIKCSogdGVzdGluZyBzaG93cyB0aGF0IGl0cyBmaXJzdCBtZXRob2QgaXMgY2FsbGVkIHdpdGggNCBwYXJhbWV0ZXJzLgoJKiBGYWtlIHRoaXMgYnkgdXNpbmcgSVBhcnNlRGlzcGxheU5hbWVfUGFyc2VEaXNwbGF5TmFtZSBzaW5jZSB0aGUKCSogc2lnbmF0dXJlIGFuZCBwb3NpdGlvbiBpbiB0aGUgdnRhYmxlIG1hdGNoZXMgb3VyIHVua25vd24gb2JqZWN0IHR5cGUuCgkqLwogICAgICAgaFJldCA9IElQYXJzZURpc3BsYXlOYW1lX1BhcnNlRGlzcGxheU5hbWUoKExQUEFSU0VESVNQTEFZTkFNRSlscFVua0lubmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBBcmcxLCBscEFyZzIsIGxwQXJnMywgbHBBcmc0KTsKICAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmtJbm5lcik7CiAgICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICBbU0hMV0FQSS4xOTJdCiAqCiAqIEdldCBhIHN1Yi1tZW51IGZyb20gYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gZ2V0IHN1Yi1tZW51IGZyb20KICogIHVJRCAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gY29udGFpbmluZyBzdWItbWVudQogKgogKiBSRVRVUk5TCiAqICBUaGUgc3ViLW1lbnUgb2YgdGhlIGl0ZW0sIG9yIGEgTlVMTCBoYW5kbGUgaWYgYW55IHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLwpITUVOVSBXSU5BUEkgU0hHZXRNZW51RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogIE1FTlVJVEVNSU5GT1cgbWk7CgogIFRSQUNFKCIoJXAsJXUpXG4iLCBoTWVudSwgdUlEKTsKCiAgbWkuY2JTaXplID0gc2l6ZW9mKG1pKTsKICBtaS5mTWFzayA9IE1JSU1fU1VCTUVOVTsKCiAgaWYgKCFHZXRNZW51SXRlbUluZm9XKGhNZW51LCB1SUQsIEZBTFNFLCAmbWkpKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiBtaS5oU3ViTWVudTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5M10KICoKICogR2V0IHRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0Q3VyQ29sb3JSZXModm9pZCkKewogICAgSERDIGhkYzsKICAgIERXT1JEIHJldDsKCiAgICBUUkFDRSgiKClcbiIpOwoKICAgIGhkYyA9IEdldERDKDApOwogICAgcmV0ID0gR2V0RGV2aWNlQ2FwcyhoZGMsIEJJVFNQSVhFTCkgKiBHZXREZXZpY2VDYXBzKGhkYywgUExBTkVTKTsKICAgIFJlbGVhc2VEQygwLCBoZGMpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5NF0KICoKICogV2FpdCBmb3IgYSBtZXNzYWdlIHRvIGFycml2ZSwgd2l0aCBhIHRpbWVvdXQuCiAqCiAqIFBBUkFNUwogKiAgaGFuZCAgICAgIFtJXSBIYW5kbGUgdG8gcXVlcnkKICogIGR3VGltZW91dCBbSV0gVGltZW91dCBpbiB0aWNrcyBvciBJTkZJTklURSB0byBuZXZlciB0aW1lb3V0CiAqCiAqIFJFVFVSTlMKICogIFNUQVRVU19USU1FT1VUIGlmIG5vIG1lc3NhZ2UgaXMgcmVjZWl2ZWQgYmVmb3JlIGR3VGltZW91dCB0aWNrcyBwYXNzZXMuCiAqICBPdGhlcndpc2UgcmV0dXJucyB0aGUgdmFsdWUgZnJvbSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXggd2hlbiBhCiAqICBtZXNzYWdlIGlzIGF2YWlsYWJsZS4KICovCkRXT1JEIFdJTkFQSSBTSFdhaXRGb3JTZW5kTWVzc2FnZVRocmVhZChIQU5ETEUgaGFuZCwgRFdPUkQgZHdUaW1lb3V0KQp7CiAgRFdPUkQgZHdFbmRUaWNrcyA9IEdldFRpY2tDb3VudCgpICsgZHdUaW1lb3V0OwogIERXT1JEIGR3UmV0OwoKICB3aGlsZSAoKGR3UmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0c0V4KDEsICZoYW5kLCBkd1RpbWVvdXQsIFFTX1NFTkRNRVNTQUdFLCAwKSkgPT0gMSkKICB7CiAgICBNU0cgbXNnOwoKICAgIFBlZWtNZXNzYWdlVygmbXNnLCBOVUxMLCAwLCAwLCBQTV9OT1JFTU9WRSk7CgogICAgaWYgKGR3VGltZW91dCAhPSBJTkZJTklURSkKICAgIHsKICAgICAgICBpZiAoKGludCkoZHdUaW1lb3V0ID0gZHdFbmRUaWNrcyAtIEdldFRpY2tDb3VudCgpKSA8PSAwKQogICAgICAgICAgICByZXR1cm4gV0FJVF9USU1FT1VUOwogICAgfQogIH0KCiAgcmV0dXJuIGR3UmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTk1XQogKgogKiBEZXRlcm1pbmUgaWYgYSBzaGVsbCBmb2xkZXIgY2FuIGJlIGV4cGFuZGVkLgogKgogKiBQQVJBTVMKICogIGxwRm9sZGVyIFtJXSBQYXJlbnQgZm9sZGVyIGNvbnRhaW5pbmcgdGhlIG9iamVjdCB0byB0ZXN0LgogKiAgcGlkbCAgICAgW0ldIElkIG9mIHRoZSBvYmplY3QgdG8gdGVzdC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSywgaWYgdGhlIG9iamVjdCBpcyBleHBhbmRhYmxlLCBTX0ZBTFNFIG90aGVyd2lzZS4KICogIEZhaWx1cmU6IEVfSU5WQUxJREFSRywgaWYgYW55IGFyZ3VtZW50IGlzIGludmFsaWQuCiAqCiAqIE5PVEVTCiAqICBJZiB0aGUgb2JqZWN0IHRvIGJlIHRlc3RlZCBkb2VzIG5vdCBleHBvc2UgdGhlIElRdWVyeUluZm8oKSBpbnRlcmZhY2UgaXQKICogIHdpbGwgbm90IGJlIGlkZW50aWZpZWQgYXMgYW4gZXhwYW5kYWJsZSBmb2xkZXIuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSElzRXhwYW5kYWJsZUZvbGRlcihMUFNIRUxMRk9MREVSIGxwRm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CiAgSVF1ZXJ5SW5mbyAqbHBJbmZvOwoKICBpZiAobHBGb2xkZXIgJiYgcGlkbCkKICB7CiAgICBoUmV0ID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YobHBGb2xkZXIsIE5VTEwsIDEsICZwaWRsLCAmSUlEX0lRdWVyeUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgKHZvaWQqKikmbHBJbmZvKTsKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICAgIGhSZXQgPSBTX0ZBTFNFOyAvKiBEb2Vzbid0IGV4cG9zZSBJUXVlcnlJbmZvICovCiAgICBlbHNlCiAgICB7CiAgICAgIERXT1JEIGR3RmxhZ3MgPSAwOwoKICAgICAgLyogTVNETiBzdGF0ZXMgb2YgSVF1ZXJ5SW5mb19HZXRJbmZvRmxhZ3MoKSB0aGF0ICJUaGlzIG1ldGhvZCBpcyBub3QKICAgICAgICogY3VycmVudGx5IHVzZWQiLiBSZWFsbHk/IFlvdSB3b3VsZG4ndCBiZSBob2xkaW5nIG91dCBvbiBtZSB3b3VsZCB5b3U/CiAgICAgICAqLwogICAgICBoUmV0ID0gSVF1ZXJ5SW5mb19HZXRJbmZvRmxhZ3MobHBJbmZvLCAmZHdGbGFncyk7CgogICAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgICB7CiAgICAgICAgLyogMHgyIGlzIGFuIHVuZG9jdW1lbnRlZCBmbGFnIGFwcGFyZW50bHkgaW5kaWNhdGluZyBleHBhbmRhYmlsaXR5ICovCiAgICAgICAgaFJldCA9IGR3RmxhZ3MgJiAweDIgPyBTX09LIDogU19GQUxTRTsKICAgICAgfQoKICAgICAgSVF1ZXJ5SW5mb19SZWxlYXNlKGxwSW5mbyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTk3XQogKgogKiBCbGFuayBvdXQgYSByZWdpb24gb2YgdGV4dCBieSBkcmF3aW5nIHRoZSBiYWNrZ3JvdW5kIG9ubHkuCiAqCiAqIFBBUkFNUwogKiAgaERDICAgW0ldIERldmljZSBjb250ZXh0IHRvIGRyYXcgaW4KICogIHBSZWN0IFtJXSBBcmVhIHRvIGRyYXcgaW4KICogIGNSZWYgIFtJXSBDb2xvciB0byBkcmF3IGluCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgU0hGaWxsUmVjdENscihIREMgaERDLCBMUENSRUNUIHBSZWN0LCBDT0xPUlJFRiBjUmVmKQp7CiAgICBDT0xPUlJFRiBjT2xkQ29sb3IgPSBTZXRCa0NvbG9yKGhEQywgY1JlZik7CiAgICBFeHRUZXh0T3V0QShoREMsIDAsIDAsIEVUT19PUEFRVUUsIHBSZWN0LCAwLCAwLCAwKTsKICAgIFNldEJrQ29sb3IoaERDLCBjT2xkQ29sb3IpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOThdCiAqCiAqIFJldHVybiB0aGUgdmFsdWUgYXNvY2lhdGVkIHdpdGggYSBrZXkgaW4gYSBtYXAuCiAqCiAqIFBBUkFNUwogKiAgbHBLZXlzICAgW0ldIEEgbGlzdCBvZiBrZXlzIG9mIGxlbmd0aCBpTGVuCiAqICBscFZhbHVlcyBbSV0gQSBsaXN0IG9mIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggbHBLZXlzLCBvZiBsZW5ndGggaUxlbgogKiAgaUxlbiAgICAgW0ldIExlbmd0aCBvZiBib3RoIGxwS2V5cyBhbmQgbHBWYWx1ZXMKICogIGlLZXkgICAgIFtJXSBUaGUga2V5IHZhbHVlIHRvIGxvb2sgdXAgaW4gbHBLZXlzCiAqCiAqIFJFVFVSTlMKICogIFRoZSB2YWx1ZSBpbiBscFZhbHVlcyBhc3NvY2lhdGVkIHdpdGggaUtleSwgb3IgLTEgaWYgaUtleSBpcyBub3QKICogIGZvdW5kIGluIGxwS2V5cy4KICoKICogTk9URVMKICogIC0gSWYgdHdvIGVsZW1lbnRzIGluIHRoZSBtYXAgc2hhcmUgdGhlIHNhbWUga2V5LCB0aGlzIGZ1bmN0aW9uIHJldHVybnMKICogICAgdGhlIHZhbHVlIGNsb3Nlc3QgdG8gdGhlIHN0YXJ0IG9mIHRoZSBtYXAKICogIC0gVGhlIG5hdGl2ZSB2ZXJzaW9uIG9mIHRoaXMgZnVuY3Rpb24gY3Jhc2hlcyBpZiBscEtleXMgb3IgbHBWYWx1ZXMgaXMgTlVMTC4KICovCmludCBXSU5BUEkgU0hTZWFyY2hNYXBJbnQoY29uc3QgaW50ICpscEtleXMsIGNvbnN0IGludCAqbHBWYWx1ZXMsIGludCBpTGVuLCBpbnQgaUtleSkKewogIGlmIChscEtleXMgJiYgbHBWYWx1ZXMpCiAgewogICAgaW50IGkgPSAwOwoKICAgIHdoaWxlIChpIDwgaUxlbikKICAgIHsKICAgICAgaWYgKGxwS2V5c1tpXSA9PSBpS2V5KQogICAgICAgIHJldHVybiBscFZhbHVlc1tpXTsgLyogRm91bmQgKi8KICAgICAgaSsrOwogICAgfQogIH0KICByZXR1cm4gLTE7IC8qIE5vdCBmb3VuZCAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5OV0KICoKICogQ29weSBhbiBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBQQVJBTVMKICogICBscHBEZXN0ICAgW09dIERlc3RpbmF0aW9uIGZvciBjb3B5CiAqICAgbHBVbmtub3duIFtJXSBTb3VyY2UgZm9yIGNvcHkKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovClZPSUQgV0lOQVBJIElVbmtub3duX1NldChJVW5rbm93biAqKmxwcERlc3QsIElVbmtub3duICpscFVua25vd24pCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBwRGVzdCwgbHBVbmtub3duKTsKCiAgaWYgKGxwcERlc3QpCiAgICBJVW5rbm93bl9BdG9taWNSZWxlYXNlKGxwcERlc3QpOyAvKiBSZWxlYXNlIGV4aXN0aW5nIGludGVyZmFjZSAqLwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgKi8KICAgIElVbmtub3duX0FkZFJlZihscFVua25vd24pOwogICAgKmxwcERlc3QgPSBscFVua25vd247CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjAwXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgTWF5UVNGb3J3YXJkKElVbmtub3duKiBscFVua25vd24sIFBWT0lEIGxwUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHJpaWRDbWRHcnAsIFVMT05HIGNDbWRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgT0xFQ01EICpwcmdDbWRzLCBPTEVDTURURVhUKiBwQ21kVGV4dCkKewogIEZJWE1FKCIoJXAsJXAsJXAsJWQsJXAsJXApIC0gc3R1YlxuIiwKICAgICAgICBscFVua25vd24sIGxwUmVzZXJ2ZWQsIHJpaWRDbWRHcnAsIGNDbWRzLCBwcmdDbWRzLCBwQ21kVGV4dCk7CgogIC8qIEZJWE1FOiBDYWxscyBJc1FTRm9yd2FyZCAmIElVbmtub3duX1F1ZXJ5U3RhdHVzICovCiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heUV4ZWNGb3J3YXJkKElVbmtub3duKiBscFVua25vd24sIElOVCBpVW5rLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG5DbWRJRCwgRFdPUkQgbkNtZGV4ZWNvcHQsIFZBUklBTlQqIHB2YUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJJQU5UKiBwdmFPdXQpCnsKICBGSVhNRSgiKCVwLCVkLCVwLCVkLCVkLCVwLCVwKSAtIHN0dWIhXG4iLCBscFVua25vd24sIGlVbmssIHBndWlkQ21kR3JvdXAsCiAgICAgICAgbkNtZElELCBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMl0KICoKICovCkhSRVNVTFQgV0lOQVBJIElzUVNGb3J3YXJkKFJFRkdVSUQgcGd1aWRDbWRHcm91cCxVTE9ORyBjQ21kcywgT0xFQ01EICpwcmdDbWRzKQp7CiAgRklYTUUoIiglcCwlZCwlcCkgLSBzdHViIVxuIiwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMjA0XQogKgogKiBEZXRlcm1pbmUgaWYgYSB3aW5kb3cgaXMgbm90IGEgY2hpbGQgb2YgYW5vdGhlciB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiBoUGFyZW50IFtJXSBTdXNwZWN0ZWQgcGFyZW50IHdpbmRvdwogKiBoQ2hpbGQgIFtJXSBTdXNwZWN0ZWQgY2hpbGQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogVFJVRTogIElmIGhDaGlsZCBpcyBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50CiAqIEZBTFNFOiBJZiBoQ2hpbGQgaXMgbm90IGEgY2hpbGQgd2luZG93IG9mIGhQYXJlbnQsIG9yIHRoZXkgYXJlIGVxdWFsCiAqLwpCT09MIFdJTkFQSSBTSElzQ2hpbGRPclNlbGYoSFdORCBoUGFyZW50LCBIV05EIGhDaGlsZCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBoUGFyZW50LCBoQ2hpbGQpOwoKICBpZiAoIWhQYXJlbnQgfHwgIWhDaGlsZCkKICAgIHJldHVybiBUUlVFOwogIGVsc2UgaWYoaFBhcmVudCA9PSBoQ2hpbGQpCiAgICByZXR1cm4gRkFMU0U7CiAgcmV0dXJuICFJc0NoaWxkKGhQYXJlbnQsIGhDaGlsZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgIEZEU0EgZnVuY3Rpb25zLiAgTWFuYWdlIGEgZHluYW1pYyBhcnJheSBvZiBmaXhlZCBzaXplIG1lbW9yeSBibG9ja3MuCiAqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgRFdPUkQgbnVtX2l0ZW1zOyAgICAgICAvKiBOdW1iZXIgb2YgZWxlbWVudHMgaW5zZXJ0ZWQgKi8KICAgIHZvaWQgKm1lbTsgICAgICAgICAgICAgLyogUHRyIHRvIGFycmF5ICovCiAgICBEV09SRCBibG9ja3NfYWxsb2NlZDsgIC8qIE51bWJlciBvZiBlbGVtZW50cyBhbGxvY2F0ZWQgKi8KICAgIEJZVEUgaW5jOyAgICAgICAgICAgICAgLyogTnVtYmVyIG9mIGVsZW1lbnRzIHRvIGdyb3cgYnkgd2hlbiB3ZSBuZWVkIHRvIGV4cGFuZCAqLwogICAgQllURSBibG9ja19zaXplOyAgICAgICAvKiBTaXplIGluIGJ5dGVzIG9mIGFuIGVsZW1lbnQgKi8KICAgIEJZVEUgZmxhZ3M7ICAgICAgICAgICAgLyogRmxhZ3MgKi8KfSBGRFNBX2luZm87CgojZGVmaW5lIEZEU0FfRkxBR19JTlRFUk5BTF9BTExPQyAweDAxIC8qIFdoZW4gc2V0IHdlIGhhdmUgYWxsb2NhdGVkIG1lbSBpbnRlcm5hbGx5ICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA4XQogKgogKiBJbml0aWFsaXplIGFuIEZEU0EgYXJyYXJ5LiAKICovCkJPT0wgV0lOQVBJIEZEU0FfSW5pdGlhbGl6ZShEV09SRCBibG9ja19zaXplLCBEV09SRCBpbmMsIEZEU0FfaW5mbyAqaW5mbywgdm9pZCAqbWVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgaW5pdF9ibG9ja3MpCnsKICAgIFRSQUNFKCIoMHglMDh4IDB4JTA4eCAlcCAlcCAweCUwOHgpXG4iLCBibG9ja19zaXplLCBpbmMsIGluZm8sIG1lbSwgaW5pdF9ibG9ja3MpOwoKICAgIGlmKGluYyA9PSAwKQogICAgICAgIGluYyA9IDE7CgogICAgaWYobWVtKQogICAgICAgIG1lbXNldChtZW0sIDAsIGJsb2NrX3NpemUgKiBpbml0X2Jsb2Nrcyk7CiAgICAKICAgIGluZm8tPm51bV9pdGVtcyA9IDA7CiAgICBpbmZvLT5pbmMgPSBpbmM7CiAgICBpbmZvLT5tZW0gPSBtZW07CiAgICBpbmZvLT5ibG9ja3NfYWxsb2NlZCA9IGluaXRfYmxvY2tzOwogICAgaW5mby0+YmxvY2tfc2l6ZSA9IGJsb2NrX3NpemU7CiAgICBpbmZvLT5mbGFncyA9IDA7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDldCiAqCiAqIERlc3Ryb3kgYW4gRkRTQSBhcnJheQogKi8KQk9PTCBXSU5BUEkgRkRTQV9EZXN0cm95KEZEU0FfaW5mbyAqaW5mbykKewogICAgVFJBQ0UoIiglcClcbiIsIGluZm8pOwoKICAgIGlmKGluZm8tPmZsYWdzICYgRkRTQV9GTEFHX0lOVEVSTkFMX0FMTE9DKQogICAgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm8tPm1lbSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjEwXQogKgogKiBJbnNlcnQgZWxlbWVudCBpbnRvIGFuIEZEU0EgYXJyYXkKICovCkRXT1JEIFdJTkFQSSBGRFNBX0luc2VydEl0ZW0oRkRTQV9pbmZvICppbmZvLCBEV09SRCB3aGVyZSwgY29uc3Qgdm9pZCAqYmxvY2spCnsKICAgIFRSQUNFKCIoJXAgMHglMDh4ICVwKVxuIiwgaW5mbywgd2hlcmUsIGJsb2NrKTsKICAgIGlmKHdoZXJlID4gaW5mby0+bnVtX2l0ZW1zKQogICAgICAgIHdoZXJlID0gaW5mby0+bnVtX2l0ZW1zOwoKICAgIGlmKGluZm8tPm51bV9pdGVtcyA+PSBpbmZvLT5ibG9ja3NfYWxsb2NlZCkKICAgIHsKICAgICAgICBEV09SRCBzaXplID0gKGluZm8tPmJsb2Nrc19hbGxvY2VkICsgaW5mby0+aW5jKSAqIGluZm8tPmJsb2NrX3NpemU7CiAgICAgICAgaWYoaW5mby0+ZmxhZ3MgJiAweDEpCiAgICAgICAgICAgIGluZm8tPm1lbSA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGluZm8tPm1lbSwgc2l6ZSk7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdm9pZCAqb2xkX21lbSA9IGluZm8tPm1lbTsKICAgICAgICAgICAgaW5mby0+bWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemUpOwogICAgICAgICAgICBtZW1jcHkoaW5mby0+bWVtLCBvbGRfbWVtLCBpbmZvLT5ibG9ja3NfYWxsb2NlZCAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgICAgIH0KICAgICAgICBpbmZvLT5ibG9ja3NfYWxsb2NlZCArPSBpbmZvLT5pbmM7CiAgICAgICAgaW5mby0+ZmxhZ3MgfD0gMHgxOwogICAgfQoKICAgIGlmKHdoZXJlIDwgaW5mby0+bnVtX2l0ZW1zKQogICAgewogICAgICAgIG1lbW1vdmUoKGNoYXIqKWluZm8tPm1lbSArICh3aGVyZSArIDEpICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoaW5mby0+bnVtX2l0ZW1zIC0gd2hlcmUpICogaW5mby0+YmxvY2tfc2l6ZSk7CiAgICB9CiAgICBtZW1jcHkoKGNoYXIqKWluZm8tPm1lbSArIHdoZXJlICogaW5mby0+YmxvY2tfc2l6ZSwgYmxvY2ssIGluZm8tPmJsb2NrX3NpemUpOwoKICAgIGluZm8tPm51bV9pdGVtcysrOwogICAgcmV0dXJuIHdoZXJlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjExXQogKgogKiBEZWxldGUgYW4gZWxlbWVudCBmcm9tIGFuIEZEU0EgYXJyYXkuCiAqLwpCT09MIFdJTkFQSSBGRFNBX0RlbGV0ZUl0ZW0oRkRTQV9pbmZvICppbmZvLCBEV09SRCB3aGVyZSkKewogICAgVFJBQ0UoIiglcCAweCUwOHgpXG4iLCBpbmZvLCB3aGVyZSk7CgogICAgaWYod2hlcmUgPj0gaW5mby0+bnVtX2l0ZW1zKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZih3aGVyZSA8IGluZm8tPm51bV9pdGVtcyAtIDEpCiAgICB7CiAgICAgICAgbWVtbW92ZSgoY2hhciopaW5mby0+bWVtICsgd2hlcmUgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGNoYXIqKWluZm8tPm1lbSArICh3aGVyZSArIDEpICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChpbmZvLT5udW1faXRlbXMgLSB3aGVyZSAtIDEpICogaW5mby0+YmxvY2tfc2l6ZSk7CiAgICB9CiAgICBtZW1zZXQoKGNoYXIqKWluZm8tPm1lbSArIChpbmZvLT5udW1faXRlbXMgLSAxKSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgMCwgaW5mby0+YmxvY2tfc2l6ZSk7CiAgICBpbmZvLT5udW1faXRlbXMtLTsKICAgIHJldHVybiBUUlVFOwp9CgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgUkVGSUlEICAgcmVmaWQ7CiAgICBEV09SRCAgICBpbmR4Owp9IElGQUNFX0lOREVYX1RCTDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTldCiAqCiAqIENhbGwgSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKSBvbiBhIHRhYmxlIG9mIG9iamVjdHMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX1BPSU5URVIgb3IgRV9OT0lOVEVSRkFDRS4KICovCkhSRVNVTFQgV0lOQVBJIFFJU2VhcmNoKAoJTFBWT0lEIHcsICAgICAgICAgICAvKiBbaW5dICAgVGFibGUgb2YgaW50ZXJmYWNlcyAqLwoJSUZBQ0VfSU5ERVhfVEJMICp4LCAvKiBbaW5dICAgQXJyYXkgb2YgUkVGSUlEcyBhbmQgaW5kZXhlcyBpbnRvIHRoZSB0YWJsZSAqLwoJUkVGSUlEIHJpaWQsICAgICAgICAvKiBbaW5dICAgUkVGSUlEIHRvIGdldCBpbnRlcmZhY2UgZm9yICovCglMUFZPSUQgKnBwdikgICAgICAgICAgLyogW291dF0gIERlc3RpbmF0aW9uIGZvciBpbnRlcmZhY2UgcG9pbnRlciAqLwp7CglIUkVTVUxUIHJldDsKCUlVbmtub3duICphX3Z0Ymw7CglJRkFDRV9JTkRFWF9UQkwgKnhtb3ZlOwoKCVRSQUNFKCIoJXAgJXAgJXMgJXApXG4iLCB3LHgsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHYpOwoJaWYgKHBwdikgewoJICAgIHhtb3ZlID0geDsKCSAgICB3aGlsZSAoeG1vdmUtPnJlZmlkKSB7CgkJVFJBQ0UoInRyeWluZyAoaW5keCAlZCkgJXNcbiIsIHhtb3ZlLT5pbmR4LCBkZWJ1Z3N0cl9ndWlkKHhtb3ZlLT5yZWZpZCkpOwoJCWlmIChJc0VxdWFsSUlEKHJpaWQsIHhtb3ZlLT5yZWZpZCkpIHsKCQkgICAgYV92dGJsID0gKElVbmtub3duKikoeG1vdmUtPmluZHggKyAoTFBCWVRFKXcpOwoJCSAgICBUUkFDRSgibWF0Y2hlZCwgcmV0dXJuaW5nICglcClcbiIsIGFfdnRibCk7CgkJICAgICpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQkgICAgSVVua25vd25fQWRkUmVmKGFfdnRibCk7CgkJICAgIHJldHVybiBTX09LOwoJCX0KCQl4bW92ZSsrOwoJICAgIH0KCgkgICAgaWYgKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikpIHsKCQlhX3Z0YmwgPSAoSVVua25vd24qKSh4LT5pbmR4ICsgKExQQllURSl3KTsKCQlUUkFDRSgicmV0dXJuaW5nIGZpcnN0IGZvciBJVW5rbm93biAoJXApXG4iLCBhX3Z0YmwpOwoJCSpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQlJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQlyZXR1cm4gU19PSzsKCSAgICB9CgkgICAgKnBwdiA9IDA7CgkgICAgcmV0ID0gRV9OT0lOVEVSRkFDRTsKCX0gZWxzZQoJICAgIHJldCA9IEVfUE9JTlRFUjsKCglUUkFDRSgiLS0gMHglMDh4XG4iLCByZXQpOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIyMV0KICoKICogUmVtb3ZlIHRoZSAiUHJvcERsZ0ZvbnQiIHByb3BlcnR5IGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCBbSV0gV2luZG93IHRvIHJlbW92ZSB0aGUgcHJvcGVydHkgZnJvbQogKgogKiBSRVRVUk5TCiAqICBBIGhhbmRsZSB0byB0aGUgcmVtb3ZlZCBwcm9wZXJ0eSwgb3IgTlVMTCBpZiBpdCBkaWQgbm90IGV4aXN0LgogKi8KSEFORExFIFdJTkFQSSBTSFJlbW92ZURlZmF1bHREaWFsb2dGb250KEhXTkQgaFduZCkKewogIEhBTkRMRSBoUHJvcDsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBoUHJvcCA9IEdldFByb3BBKGhXbmQsICJQcm9wRGxnRm9udCIpOwoKICBpZihoUHJvcCkKICB7CiAgICBEZWxldGVPYmplY3QoaFByb3ApOwogICAgaFByb3AgPSBSZW1vdmVQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKICB9CiAgcmV0dXJuIGhQcm9wOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM2XQogKgogKiBMb2FkIHRoZSBpbi1wcm9jZXNzIHNlcnZlciBvZiBhIGdpdmVuIEdVSUQuCiAqCiAqIFBBUkFNUwogKiAgcmVmaWlkIFtJXSBHVUlEIG9mIHRoZSBzZXJ2ZXIgdG8gbG9hZC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBzZXJ2ZXIgZGxsLgogKiAgRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICovCkhNT0RVTEUgV0lOQVBJIFNIUGluRGxsT2ZDTFNJRChSRUZJSUQgcmVmaWlkKQp7CiAgICBIS0VZIG5ld2tleTsKICAgIERXT1JEIHR5cGUsIGNvdW50OwogICAgQ0hBUiB2YWx1ZVtNQVhfUEFUSF0sIHN0cmluZ1tNQVhfUEFUSF07CgogICAgc3RyY3B5KHN0cmluZywgIkNMU0lEXFwiKTsKICAgIFNIU3RyaW5nRnJvbUdVSURBKHJlZmlpZCwgc3RyaW5nICsgNiwgc2l6ZW9mKHN0cmluZykvc2l6ZW9mKGNoYXIpIC0gNik7CiAgICBzdHJjYXQoc3RyaW5nLCAiXFxJblByb2NTZXJ2ZXIzMiIpOwoKICAgIGNvdW50ID0gTUFYX1BBVEg7CiAgICBSZWdPcGVuS2V5RXhBKEhLRVlfQ0xBU1NFU19ST09ULCBzdHJpbmcsIDAsIDEsICZuZXdrZXkpOwogICAgUmVnUXVlcnlWYWx1ZUV4QShuZXdrZXksIDAsIDAsICZ0eXBlLCAoUEJZVEUpdmFsdWUsICZjb3VudCk7CiAgICBSZWdDbG9zZUtleShuZXdrZXkpOwogICAgcmV0dXJuIExvYWRMaWJyYXJ5RXhBKHZhbHVlLCAwLCAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzN10KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMTgzLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJDbGFzc1coV05EQ0xBU1NXICogbHBXbmRDbGFzcykKewoJV05EQ0xBU1NXIFduZENsYXNzOwoKCVRSQUNFKCIoJXAgJXMpXG4iLGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgZGVidWdzdHJfdyhscFduZENsYXNzLT5scHN6Q2xhc3NOYW1lKSk7CgoJaWYgKEdldENsYXNzSW5mb1cobHBXbmRDbGFzcy0+aEluc3RhbmNlLCBscFduZENsYXNzLT5scHN6Q2xhc3NOYW1lLCAmV25kQ2xhc3MpKQoJCXJldHVybiBUUlVFOwoJcmV0dXJuIFJlZ2lzdGVyQ2xhc3NXKGxwV25kQ2xhc3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM4XQogKgogKiBVbnJlZ2lzdGVyIGEgbGlzdCBvZiBjbGFzc2VzLgogKgogKiBQQVJBTVMKICogIGhJbnN0ICAgICAgW0ldIEFwcGxpY2F0aW9uIGluc3RhbmNlIHRoYXQgcmVnaXN0ZXJlZCB0aGUgY2xhc3NlcwogKiAgbHBwQ2xhc3NlcyBbSV0gTGlzdCBvZiBjbGFzcyBuYW1lcwogKiAgaUNvdW50ICAgICBbSV0gTnVtYmVyIG9mIG5hbWVzIGluIGxwcENsYXNzZXMKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCnZvaWQgV0lOQVBJIFNIVW5yZWdpc3RlckNsYXNzZXNBKEhJTlNUQU5DRSBoSW5zdCwgTFBDU1RSICpscHBDbGFzc2VzLCBJTlQgaUNvdW50KQp7CiAgV05EQ0xBU1NBIFduZENsYXNzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaEluc3QsIGxwcENsYXNzZXMsIGlDb3VudCk7CgogIHdoaWxlIChpQ291bnQgPiAwKQogIHsKICAgIGlmIChHZXRDbGFzc0luZm9BKGhJbnN0LCAqbHBwQ2xhc3NlcywgJlduZENsYXNzKSkKICAgICAgVW5yZWdpc3RlckNsYXNzQSgqbHBwQ2xhc3NlcywgaEluc3QpOwogICAgbHBwQ2xhc3NlcysrOwogICAgaUNvdW50LS07CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM5XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hVbnJlZ2lzdGVyQ2xhc3Nlc0EuCiAqLwp2b2lkIFdJTkFQSSBTSFVucmVnaXN0ZXJDbGFzc2VzVyhISU5TVEFOQ0UgaEluc3QsIExQQ1dTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU1cgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb1coaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NXKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNDBdCiAqCiAqIENhbGwgVGhlIGNvcnJlY3QgKEFzY2lpL1VuaWNvZGUpIGRlZmF1bHQgd2luZG93IHByb2NlZHVyZSBmb3IgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIFdpbmRvdyB0byBjYWxsIHRoZSBkZWZhdWx0IHByb2NlZHVyZSBmb3IKICogIHVNZXNzYWdlIFtJXSBNZXNzYWdlIElECiAqICB3UGFyYW0gICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgIFtJXSBMUEFSQU0gb2YgbWVzc2FnZQogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIGNhbGxpbmcgRGVmV2luZG93UHJvY0EoKSBvciBEZWZXaW5kb3dQcm9jVygpLgogKi8KTFJFU1VMVCBDQUxMQkFDSyBTSERlZldpbmRvd1Byb2MoSFdORCBoV25kLCBVSU5UIHVNZXNzYWdlLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CglpZiAoSXNXaW5kb3dVbmljb2RlKGhXbmQpKQoJCXJldHVybiBEZWZXaW5kb3dQcm9jVyhoV25kLCB1TWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4yNTZdCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9HZXRTaXRlKExQVU5LTk9XTiBscFVua25vd24sIFJFRklJRCBpaWQsIFBWT0lEICpscHBTaXRlKQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIExQT0JKRUNUV0lUSFNJVEUgbHBTaXRlID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGxwVW5rbm93biwgZGVidWdzdHJfZ3VpZChpaWQpLCBscHBTaXRlKTsKCiAgaWYgKGxwVW5rbm93biAmJiBpaWQgJiYgbHBwU2l0ZSkKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPYmplY3RXaXRoU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFNpdGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFNpdGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2JqZWN0V2l0aFNpdGVfR2V0U2l0ZShscFNpdGUsIGlpZCwgbHBwU2l0ZSk7CiAgICAgIElPYmplY3RXaXRoU2l0ZV9SZWxlYXNlKGxwU2l0ZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjU3XQogKgogKiBDcmVhdGUgYSB3b3JrZXIgd2luZG93IHVzaW5nIENyZWF0ZVdpbmRvd0V4QSgpLgogKgogKiBQQVJBTVMKICogIHduZFByb2MgICAgW0ldIFdpbmRvdyBwcm9jZWR1cmUKICogIGhXbmRQYXJlbnQgW0ldIFBhcmVudCB3aW5kb3cKICogIGR3RXhTdHlsZSAgW0ldIEV4dHJhIHN0eWxlIGZsYWdzCiAqICBkd1N0eWxlICAgIFtJXSBTdHlsZSBmbGFncwogKiAgaE1lbnUgICAgICBbSV0gV2luZG93IG1lbnUKICogIHogICAgICAgICAgW0ldIFVua25vd24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHdpbmRvdyBoYW5kbGUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgd2luZG93LgogKiAgRmFpbHVyZTogMC4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93QShMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IGNoYXIgc3pDbGFzc1tdID0gIldvcmtlckEiOwogIFdORENMQVNTQSB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDh4LCVwLDB4JTA4eCwweCUwOHgsJXAsMHglMDh4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIENyZWF0ZSBXaW5kb3cgY2xhc3MgKi8KICB3Yy5zdHlsZSAgICAgICAgID0gMDsKICB3Yy5scGZuV25kUHJvYyAgID0gRGVmV2luZG93UHJvY0E7CiAgd2MuY2JDbHNFeHRyYSAgICA9IDA7CiAgd2MuY2JXbmRFeHRyYSAgICA9IDQ7CiAgd2MuaEluc3RhbmNlICAgICA9IHNobHdhcGlfaEluc3RhbmNlOwogIHdjLmhJY29uICAgICAgICAgPSBOVUxMOwogIHdjLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yQShOVUxMLCAoTFBTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NBKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4QShkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIERXTFBfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0ckEoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCnR5cGVkZWYgc3RydWN0IHRhZ1BPTElDWURBVEEKewogIERXT1JEIHBvbGljeTsgICAgICAgIC8qIGZsYWdzIHZhbHVlIHBhc3NlZCB0byBTSFJlc3RyaWN0ZWQgKi8KICBMUENXU1RSIGFwcHN0cjsgICAgICAvKiBhcHBsaWNhdGlvbiBzdHIgc3VjaCBhcyAiRXhwbG9yZXIiICovCiAgTFBDV1NUUiBrZXlzdHI7ICAgICAgLyogbmFtZSBvZiB0aGUgYWN0dWFsIHJlZ2lzdHJ5IGtleSAvIHBvbGljeSAqLwp9IFBPTElDWURBVEEsICpMUFBPTElDWURBVEE7CgojZGVmaW5lIFNIRUxMX05PX1BPTElDWSAweGZmZmZmZmZmCgovKiBkZWZhdWx0IHNoZWxsIHBvbGljeSByZWdpc3RyeSBrZXkgKi8Kc3RhdGljIGNvbnN0IFdDSEFSIHN0clJlZ2lzdHJ5UG9saWN5V1tdID0geydTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywnTScsJ2knLCdjJywncicsJ28nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xcJywnUCcsJ28nLCdsJywnaScsJ2MnLCdpJywnZScsJ3MnLDB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjcxXQogKgogKiBSZXRyaWV2ZSBhIHBvbGljeSB2YWx1ZSBmcm9tIHRoZSByZWdpc3RyeS4KICoKICogUEFSQU1TCiAqICBscFN1YktleSAgIFtJXSAgIHJlZ2lzdHJ5IGtleSBuYW1lCiAqICBscFN1Yk5hbWUgIFtJXSAgIHN1Ym5hbWUgb2YgcmVnaXN0cnkga2V5CiAqICBscFZhbHVlICAgIFtJXSAgIHZhbHVlIG5hbWUgb2YgcmVnaXN0cnkgdmFsdWUKICoKICogUkVUVVJOUwogKiAgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkga2V5IG9yIDAgaWYgbm90IGZvdW5kCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRSZXN0cmljdGlvbihMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwU3ViTmFtZSwgTFBDV1NUUiBscFZhbHVlKQp7CglEV09SRCByZXR2YWwsIGRhdHNpemUgPSBzaXplb2YocmV0dmFsKTsKCUhLRVkgaEtleTsKCglpZiAoIWxwU3ViS2V5KQoJICBscFN1YktleSA9IHN0clJlZ2lzdHJ5UG9saWN5VzsKCglyZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGxwU3ViS2V5LCAmaEtleSk7CiAgICBpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBscFN1YktleSwgJmhLZXkpOwoJaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR1cm4gMDsKCglTSEdldFZhbHVlVyhoS2V5LCBscFN1Yk5hbWUsIGxwVmFsdWUsIE5VTEwsIChMUEJZVEUpJnJldHZhbCwgJmRhdHNpemUpOwoJUmVnQ2xvc2VLZXkoaEtleSk7CglyZXR1cm4gcmV0dmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgIFtTSExXQVBJLjI2Nl0KICoKICogSGVscGVyIGZ1bmN0aW9uIHRvIHJldHJpZXZlIHRoZSBwb3NzaWJseSBjYWNoZWQgdmFsdWUgZm9yIGEgc3BlY2lmaWMgcG9saWN5CiAqCiAqIFBBUkFNUwogKiAgcG9saWN5ICAgICBbSV0gICBUaGUgcG9saWN5IHRvIGxvb2sgZm9yCiAqICBpbml0aWFsICAgIFtJXSAgIE1haW4gcmVnaXN0cnkga2V5IHRvIG9wZW4sIGlmIE5VTEwgdXNlIGRlZmF1bHQKICogIHBvbFRhYmxlICAgW0ldICAgVGFibGUgb2Yga25vd24gcG9saWNpZXMsIDAgdGVybWluYXRlZAogKiAgcG9sQXJyICAgICBbSV0gICBDYWNoZSBhcnJheSBvZiBwb2xpY3kgdmFsdWVzCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXRyaWV2ZWQgcG9saWN5IHZhbHVlIG9yIDAgaWYgbm90IHN1Y2Nlc3NmdWwKICoKICogTk9URVMKICogIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBieSB0aGUgbmF0aXZlIFNIUmVzdHJpY3RlZCBmdW5jdGlvbiB0byBzZWFyY2ggZm9yIHRoZQogKiAgcG9saWN5IGFuZCBjYWNoZSBpdCBvbmNlIHJldHJpZXZlZC4gVGhlIGN1cnJlbnQgV2luZSBpbXBsZW1lbnRhdGlvbiB1c2VzIGEKICogIGRpZmZlcmVudCBQT0xJQ1lEQVRBIHN0cnVjdHVyZSBhbmQgaW1wbGVtZW50cyBhIHNpbWlsYXIgYWxnb3JpdGhtZSBhZGFwdGVkIHRvCiAqICB0aGF0IHN0cnVjdHVyZS4KICovCkRXT1JEIFdJTkFQSSBTSFJlc3RyaWN0aW9uTG9va3VwKAoJRFdPUkQgcG9saWN5LAoJTFBDV1NUUiBpbml0aWFsLAoJTFBQT0xJQ1lEQVRBIHBvbFRhYmxlLAoJTFBEV09SRCBwb2xBcnIpCnsKCVRSQUNFKCIoMHglMDh4ICVzICVwICVwKVxuIiwgcG9saWN5LCBkZWJ1Z3N0cl93KGluaXRpYWwpLCBwb2xUYWJsZSwgcG9sQXJyKTsKCglpZiAoIXBvbFRhYmxlIHx8ICFwb2xBcnIpCgkgIHJldHVybiAwOwoKCWZvciAoO3BvbFRhYmxlLT5wb2xpY3k7IHBvbFRhYmxlKyssIHBvbEFycisrKQoJewoJICBpZiAocG9saWN5ID09IHBvbFRhYmxlLT5wb2xpY3kpCgkgIHsKCSAgICAvKiB3ZSBoYXZlIGEga25vd24gcG9saWN5ICovCgoJICAgIC8qIGNoZWNrIGlmIHRoaXMgcG9saWN5IGhhcyBiZWVuIGNhY2hlZCAqLwoJCWlmICgqcG9sQXJyID09IFNIRUxMX05PX1BPTElDWSkKCSAgICAgICpwb2xBcnIgPSBTSEdldFJlc3RyaWN0aW9uKGluaXRpYWwsIHBvbFRhYmxlLT5hcHBzdHIsIHBvbFRhYmxlLT5rZXlzdHIpOwoJICAgIHJldHVybiAqcG9sQXJyOwoJICB9Cgl9CgkvKiB3ZSBkb24ndCBrbm93IHRoaXMgcG9saWN5LCByZXR1cm4gMCAqLwoJVFJBQ0UoInVua25vd24gcG9saWN5OiAoJTA4eClcbiIsIHBvbGljeSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2N10KICoKICogR2V0IGFuIGludGVyZmFjZSBmcm9tIGFuIG9iamVjdC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gcHB2IGNvbnRhaW5zIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgIFRoaXMgUXVlcnlJbnRlcmZhY2UgYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGZvciBhbiBpbnRlcmZhY2UuIEluIGNhc2UKICogICBvZiBhZ2dyZWdhdGlvbiB0aGlzIHJlcXVlc3Qgd291bGQgYmUgZm9yd2FyZGVkIGJ5IHRoZSBpbm5lciB0byB0aGUKICogICBvdXRlciBvYmplY3QuIFRoaXMgZnVuY3Rpb24gYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGRpcmVjdGx5IGZvciB0aGUKICogICBpbnRlcmZhY2UgY2lyY3VtdmVudGluZyB0aGUgZm9yd2FyZGluZyB0byB0aGUgb3V0ZXIgb2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgU0hXZWFrUXVlcnlJbnRlcmZhY2UoCglJVW5rbm93biAqIHBVbmssICAgLyogW2luXSBPdXRlciBvYmplY3QgKi8KCUlVbmtub3duICogcElubmVyLCAvKiBbaW5dIElubmVyIG9iamVjdCAqLwoJSUlEICogcmlpZCwgLyogW2luXSBJbnRlcmZhY2UgR1VJRCB0byBxdWVyeSBmb3IgKi8KCUxQVk9JRCogcHB2KSAvKiBbb3V0XSBEZXN0aW5hdGlvbiBmb3IgcXVlcmllZCBpbnRlcmZhY2UgKi8KewoJSFJFU1VMVCBocmV0ID0gRV9OT0lOVEVSRkFDRTsKCVRSQUNFKCIocFVuaz0lcCBwSW5uZXI9JXBcblx0SUlEOiAgJXMgJXApXG4iLHBVbmsscElubmVyLGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CgoJKnBwdiA9IE5VTEw7CglpZihwVW5rICYmIHBJbm5lcikgewoJICAgIGhyZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSW5uZXIsIHJpaWQsIChMUFZPSUQqKXBwdik7CgkgICAgaWYgKFNVQ0NFRURFRChocmV0KSkgSVVua25vd25fUmVsZWFzZShwVW5rKTsKCX0KCVRSQUNFKCItLSAweCUwOHhcbiIsIGhyZXQpOwoJcmV0dXJuIGhyZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjhdCiAqCiAqIE1vdmUgYSByZWZlcmVuY2UgZnJvbSBvbmUgaW50ZXJmYWNlIHRvIGFub3RoZXIuCiAqCiAqIFBBUkFNUwogKiAgIGxwRGVzdCAgICAgW09dIERlc3RpbmF0aW9uIHRvIHJlY2VpdmUgdGhlIHJlZmVyZW5jZQogKiAgIGxwcFVua25vd24gW09dIFNvdXJjZSB0byBnaXZlIHVwIHRoZSByZWZlcmVuY2UgdG8gbHBEZXN0CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBTSFdlYWtSZWxlYXNlSW50ZXJmYWNlKElVbmtub3duICpscERlc3QsIElVbmtub3duICoqbHBwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscERlc3QsIGxwcFVua25vd24pOwoKICBpZiAoKmxwcFVua25vd24pCiAgewogICAgLyogQ29weSBSZWZlcmVuY2UqLwogICAgSVVua25vd25fQWRkUmVmKGxwRGVzdCk7CiAgICBJVW5rbm93bl9BdG9taWNSZWxlYXNlKGxwcFVua25vd24pOyAvKiBSZWxlYXNlIGV4aXN0aW5nIGludGVyZmFjZSAqLwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2OV0KICoKICogQ29udmVydCBhbiBBU0NJSSBzdHJpbmcgb2YgYSBDTFNJRCBpbnRvIGEgQ0xTSUQuCiAqCiAqIFBBUkFNUwogKiAgaWRzdHIgW0ldIFN0cmluZyByZXByZXNlbnRpbmcgYSBDTFNJRCBpbiByZWdpc3RyeSBmb3JtYXQKICogIGlkICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGNvbnZlcnRlZCBDTFNJRAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBpZCBjb250YWlucyB0aGUgY29udmVydGVkIENMU0lELgogKiAgRmFpbHVyZTogRkFMU0UuCiAqLwpCT09MIFdJTkFQSSBHVUlERnJvbVN0cmluZ0EoTFBDU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICBXQ0hBUiB3Q2xzaWRbNDBdOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBpZHN0ciwgLTEsIHdDbHNpZCwgc2l6ZW9mKHdDbHNpZCkvc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIFNVQ0NFRURFRChDTFNJREZyb21TdHJpbmcod0Nsc2lkLCBpZCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjcwXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgR1VJREZyb21TdHJpbmdBLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdXKExQQ1dTVFIgaWRzdHIsIENMU0lEICppZCkKewogICAgcmV0dXJuIFNVQ0NFRURFRChDTFNJREZyb21TdHJpbmcoKExQT0xFU1RSKWlkc3RyLCBpZCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc2XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCBpbnRvIHRoZSBzaGVsbCwgYW5kIHNldCBhIHJlZ2lzdHJ5CiAqIGtleSBhY2NvcmRpbmdseS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAxLCBJZiB0aGUgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZC4KICogIDIsIElmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQuCiAqCiAqIE5PVEVTCiAqICBUaGUga2V5ICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlclxJbnRlZ3JhdGVkQnJvd3NlciIgaXMKICogIGVpdGhlciBzZXQgdG8gVFJVRSwgb3IgcmVtb3ZlZCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgYnJvd3NlciBpcyBkZWVtZWQKICogIHRvIGJlIGludGVncmF0ZWQuCiAqLwpEV09SRCBXSU5BUEkgV2hpY2hQbGF0Zm9ybSh2b2lkKQp7CiAgc3RhdGljIGNvbnN0IGNoYXIgc3pJbnRlZ3JhdGVkQnJvd3NlcltdID0gIkludGVncmF0ZWRCcm93c2VyIjsKICBzdGF0aWMgRFdPUkQgZHdTdGF0ZSA9IDA7CiAgSEtFWSBoS2V5OwogIERXT1JEIGR3UmV0LCBkd0RhdGEsIGR3U2l6ZTsKICBITU9EVUxFIGhzaGVsbDMyOwoKICBpZiAoZHdTdGF0ZSkKICAgIHJldHVybiBkd1N0YXRlOwoKICAvKiBJZiBzaGVsbDMyIGV4cG9ydHMgRGxsR2V0VmVyc2lvbigpLCB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkICovCiAgZHdTdGF0ZSA9IDE7CiAgaHNoZWxsMzIgPSBMb2FkTGlicmFyeUEoInNoZWxsMzIuZGxsIik7CiAgaWYgKGhzaGVsbDMyKQogIHsKICAgIEZBUlBST0MgcERsbEdldFZlcnNpb247CiAgICBwRGxsR2V0VmVyc2lvbiA9IEdldFByb2NBZGRyZXNzKGhzaGVsbDMyLCAiRGxsR2V0VmVyc2lvbiIpOwogICAgZHdTdGF0ZSA9IHBEbGxHZXRWZXJzaW9uID8gMiA6IDE7CiAgICBGcmVlTGlicmFyeShoc2hlbGwzMik7CiAgfQoKICAvKiBTZXQgb3IgZGVsZXRlIHRoZSBrZXkgYWNjb3JkaW5nbHkgKi8KICBkd1JldCA9IFJlZ09wZW5LZXlFeEEoSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAgICAgICAgICAgICAiU29mdHdhcmVcXE1pY3Jvc29mdFxcSW50ZXJuZXQgRXhwbG9yZXIiLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0FMTF9BQ0NFU1MsICZoS2V5KTsKICBpZiAoIWR3UmV0KQogIHsKICAgIGR3UmV0ID0gUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCBzekludGVncmF0ZWRCcm93c2VyLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpJmR3RGF0YSwgJmR3U2l6ZSk7CgogICAgaWYgKCFkd1JldCAmJiBkd1N0YXRlID09IDEpCiAgICB7CiAgICAgIC8qIFZhbHVlIGV4aXN0cyBidXQgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZCAqLwogICAgICBSZWdEZWxldGVWYWx1ZUEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3Nlcik7CiAgICB9CiAgICBlbHNlIGlmIChkd1JldCAmJiBkd1N0YXRlID09IDIpCiAgICB7CiAgICAgIC8qIEJyb3dzZXIgaXMgaW50ZWdyYXRlZCBidXQgdmFsdWUgZG9lcyBub3QgZXhpc3QgKi8KICAgICAgZHdEYXRhID0gVFJVRTsKICAgICAgUmVnU2V0VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsIHNpemVvZihkd0RhdGEpKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogIH0KICByZXR1cm4gZHdTdGF0ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIQ3JlYXRlV29ya2VyV2luZG93QS4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93VyhMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xhc3NbXSA9IHsgJ1cnLCAnbycsICdyJywgJ2snLCAnZScsICdyJywgJ1cnLCAnXDAnIH07CiAgV05EQ0xBU1NXIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOHgsJXAsMHglMDh4LDB4JTA4eCwlcCwweCUwOHgpXG4iLAogICAgICAgICB3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogSWYgb3VyIE9TIGlzIG5hdGl2ZWx5IEFTQ0lJLCB1c2UgdGhlIEFTQ0lJIHZlcnNpb24gKi8KICBpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgIC8qIE5UICovCiAgICByZXR1cm4gU0hDcmVhdGVXb3JrZXJXaW5kb3dBKHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NXOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gTlVMTDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvclcoTlVMTCwgKExQV1NUUilJRENfQVJST1cpOwogIHdjLmhickJhY2tncm91bmQgPSAoSEJSVVNIKShDT0xPUl9CVE5GQUNFICsgMSk7CiAgd2MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgd2MubHBzekNsYXNzTmFtZSA9IHN6Q2xhc3M7CgogIFNIUmVnaXN0ZXJDbGFzc1coJndjKTsgLyogUmVnaXN0ZXIgY2xhc3MgKi8KCiAgLyogRklYTUU6IFNldCBleHRyYSBiaXRzIGluIGR3RXhTdHlsZSAqLwoKICBoV25kID0gQ3JlYXRlV2luZG93RXhXKGR3RXhTdHlsZSwgc3pDbGFzcywgMCwgZHdTdHlsZSwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIGhXbmRQYXJlbnQsIGhNZW51LCBzaGx3YXBpX2hJbnN0YW5jZSwgMCk7CiAgaWYgKGhXbmQpCiAgewogICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgRFdMUF9NU0dSRVNVTFQsIHopOwoKICAgIGlmICh3bmRQcm9jKQogICAgICBTZXRXaW5kb3dMb25nUHRyVyhoV25kLCBHV0xQX1dORFBST0MsIHduZFByb2MpOwogIH0KICByZXR1cm4gaFduZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3OV0KICoKICogR2V0IGFuZCBzaG93IGEgY29udGV4dCBtZW51IGZyb20gYSBzaGVsbCBmb2xkZXIuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICAgICAgW0ldIFdpbmRvdyBkaXNwbGF5aW5nIHRoZSBzaGVsbCBmb2xkZXIKICogIGxwRm9sZGVyICAgICAgIFtJXSBJU2hlbGxGb2xkZXIgaW50ZXJmYWNlCiAqICBscEFwaWRsICAgICAgICBbSV0gSWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZvbGRlciBkZXNpcmVkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZURlZmF1bHRDb21tYW5kKEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsKQp7CiAgcmV0dXJuIFNISW52b2tlQ29tbWFuZChoV25kLCBscEZvbGRlciwgbHBBcGlkbCwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjgxXQogKgogKiBfU0hQYWNrRGlzcFBhcmFtc1YKICovCkhSRVNVTFQgV0lOQVBJIFNIUGFja0Rpc3BQYXJhbXNWKExQVk9JRCB3LCBMUFZPSUQgeCwgTFBWT0lEIHksIExQVk9JRCB6KQp7CglGSVhNRSgiJXAgJXAgJXAgJXBcbiIsdyx4LHkseik7CglyZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMjgyXQogKgogKiBUaGlzIGZ1bmN0aW9uIHNlZW1zIHRvIGJlIGEgZm9yd2FyZCB0byBTSFBhY2tEaXNwUGFyYW1zViAod2hhdGV2ZXIgVEhBVAogKiBmdW5jdGlvbiBkb2VzLi4uKS4KICovCkhSRVNVTFQgV0lOQVBJIFNIUGFja0Rpc3BQYXJhbXMoTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKICBGSVhNRSgiJXAgJXAgJXAgJXBcbiIsIHcsIHgsIHksIHopOwogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hMV0FQSV9JbnZva2VCeUlJRAogKgogKiAgIFRoaXMgaGVscGVyIGZ1bmN0aW9uIGNhbGxzIElEaXNwYXRjaDo6SW52b2tlIGZvciBlYWNoIHNpbmsKICogd2hpY2ggaW1wbGVtZW50cyBnaXZlbiBpaWQgb3IgSURpc3BhdGNoLgogKgogKi8Kc3RhdGljIEhSRVNVTFQgU0hMV0FQSV9JbnZva2VCeUlJRCgKICAgICAgICBJQ29ubmVjdGlvblBvaW50KiBpQ1AsCiAgICAgICAgUkVGSUlEIGlpZCwKICAgICAgICBESVNQSUQgZGlzcElkLAogICAgICAgIERJU1BQQVJBTVMqIGRpc3BQYXJhbXMpCnsKICBJRW51bUNvbm5lY3Rpb25zICplbnVtZXJhdG9yOwogIENPTk5FQ1REQVRBIHJnY2Q7CgogIEhSRVNVTFQgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludF9FbnVtQ29ubmVjdGlvbnMoaUNQLCAmZW51bWVyYXRvcik7CiAgaWYgKEZBSUxFRChyZXN1bHQpKQogICAgcmV0dXJuIHJlc3VsdDsKCiAgd2hpbGUoSUVudW1Db25uZWN0aW9uc19OZXh0KGVudW1lcmF0b3IsIDEsICZyZ2NkLCBOVUxMKT09U19PSykKICB7CiAgICBJRGlzcGF0Y2ggKmRpc3BJZmFjZTsKICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocmdjZC5wVW5rLCBpaWQsIChMUFZPSUQqKSZkaXNwSWZhY2UpKSB8fAogICAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShyZ2NkLnBVbmssICZJSURfSURpc3BhdGNoLCAoTFBWT0lEKikmZGlzcElmYWNlKSkpCiAgICB7CiAgICAgIElEaXNwYXRjaF9JbnZva2UoZGlzcElmYWNlLCBkaXNwSWQsICZJSURfTlVMTCwgMCwgRElTUEFUQ0hfTUVUSE9ELCBkaXNwUGFyYW1zLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgSURpc3BhdGNoX1JlbGVhc2UoZGlzcElmYWNlKTsKICAgIH0KICB9CgogIElFbnVtQ29ubmVjdGlvbnNfUmVsZWFzZShlbnVtZXJhdG9yKTsKCiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODRdCiAqCiAqICBJQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZQogKi8KSFJFU1VMVCBXSU5BUEkgSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UoCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCogaUNQLAogICAgICAgIERJU1BJRCBkaXNwSWQsCiAgICAgICAgRElTUFBBUkFNUyogZGlzcFBhcmFtcykKewogIElJRCBpaWQ7CiAgSFJFU1VMVCByZXN1bHQ7CgogIFRSQUNFKCIoJXApLT4oMHgleCAlcClcbiIsaUNQLGRpc3BJZCxkaXNwUGFyYW1zKTsKCiAgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludF9HZXRDb25uZWN0aW9uSW50ZXJmYWNlKGlDUCwgJmlpZCk7CiAgaWYgKFNVQ0NFRURFRChyZXN1bHQpKQogICAgcmVzdWx0ID0gU0hMV0FQSV9JbnZva2VCeUlJRChpQ1AsICZpaWQsIGRpc3BJZCwgZGlzcFBhcmFtcyk7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODVdCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50IG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwQ1AgICBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBDUCBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50IGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKElDb25uZWN0aW9uUG9pbnQqIGxwQ1AsIERJU1BJRCBkaXNwSUQpCnsKICBJRW51bUNvbm5lY3Rpb25zICpscEVudW07CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4WClcbiIsIGxwQ1AsIGRpc3BJRCk7CgogIC8qIEdldCBhbiBlbnVtZXJhdG9yIGZvciB0aGUgY29ubmVjdGlvbnMgKi8KICBpZiAobHBDUCkKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X0VudW1Db25uZWN0aW9ucyhscENQLCAmbHBFbnVtKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJUHJvcGVydHlOb3RpZnlTaW5rICpscFNpbms7CiAgICBDT05ORUNUREFUQSBjb25uRGF0YTsKICAgIFVMT05HIHVsRmV0Y2hlZDsKCiAgICAvKiBDYWxsIE9uQ2hhbmdlZCgpIGZvciBldmVyeSBub3RpZnkgc2luayBpbiB0aGUgY29ubmVjdGlvbiBwb2ludCAqLwogICAgd2hpbGUgKElFbnVtQ29ubmVjdGlvbnNfTmV4dChscEVudW0sIDEsICZjb25uRGF0YSwgJnVsRmV0Y2hlZCkgPT0gU19PSykKICAgIHsKICAgICAgaWYgKFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb25uRGF0YS5wVW5rLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICh2b2lkKiopJmxwU2luaykpICYmCiAgICAgICAgICBscFNpbmspCiAgICAgIHsKICAgICAgICBJUHJvcGVydHlOb3RpZnlTaW5rX09uQ2hhbmdlZChscFNpbmssIGRpc3BJRCk7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19SZWxlYXNlKGxwU2luayk7CiAgICAgIH0KICAgICAgSVVua25vd25fUmVsZWFzZShjb25uRGF0YS5wVW5rKTsKICAgIH0KCiAgICBJRW51bUNvbm5lY3Rpb25zX1JlbGVhc2UobHBFbnVtKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODZdCiAqCiAqICBJVW5rbm93bl9DUENvbnRhaW5lckludm9rZVBhcmFtCiAqLwpIUkVTVUxUIFdJTkFQSVYgSVVua25vd25fQ1BDb250YWluZXJJbnZva2VQYXJhbSgKICAgICAgICBJVW5rbm93biAqY29udGFpbmVyLAogICAgICAgIFJFRklJRCByaWlkLAogICAgICAgIERJU1BJRCBkaXNwSWQsCiAgICAgICAgVkFSSUFOVEFSRyogYnVmZmVyLAogICAgICAgIERXT1JEIGNQYXJhbXMsIC4uLikKewogIEhSRVNVTFQgcmVzdWx0OwogIElDb25uZWN0aW9uUG9pbnQgKmlDUDsKICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyICppQ1BDOwoKICBpZiAoIWNvbnRhaW5lcikKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwoKICByZXN1bHQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwoTFBWT0lEKikgJmlDUEMpOwogIGlmIChTVUNDRUVERUQocmVzdWx0KSkKICB7CiAgICByZXN1bHQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQoaUNQQywgcmlpZCwgJmlDUCk7CiAgICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX1JlbGVhc2UoaUNQQyk7CiAgfQoKICBpZiAoU1VDQ0VFREVEKHJlc3VsdCkpCiAgewogICAgVUxPTkcgY250OwogICAgVkFSSUFOVEFSRyAqY3VydmFyID0gYnVmZmVyK2NQYXJhbXMtMTsKICAgIERJU1BQQVJBTVMgZGlzcFBhcmFtcyA9IHtidWZmZXIsIE5VTEwsIGNQYXJhbXMsIDB9OwogICAgdmFfbGlzdCB2YWxpc3Q7CgogICAgdmFfc3RhcnQodmFsaXN0LCBjUGFyYW1zKTsKICAgIGZvcihjbnQ9Y1BhcmFtcztjbnQ+MDtjbnQtLSxjdXJ2YXItLSkgLyogYmFja3dhcmRzIGZvciBzb21lIHJlYXNvbiAqLwogICAgewogICAgICBlbnVtIFZBUkVOVU0gdnQgPSB2YV9hcmcodmFsaXN0LCBlbnVtIFZBUkVOVU0pOwogICAgICBtZW1zZXQoY3VydmFyLCAwLCBzaXplb2YoKmN1cnZhcikpOwogICAgICBpZiAodnQgJiBWVF9CWVJFRikKICAgICAgewogICAgICAgIFZfVlQoY3VydmFyKSA9IHZ0OwogICAgICAgIFZfQllSRUYoY3VydmFyKSA9IHZhX2FyZyh2YWxpc3QsIExQVk9JRCk7CiAgICAgIH0gZWxzZQogICAgICAgIHN3aXRjaCh2dCkKICAgICAgICB7CiAgICAgICAgY2FzZSBWVF9CU1RSOgogICAgICAgICAgVl9WVChjdXJ2YXIpID0gdnQ7CiAgICAgICAgICBWX0JTVFIoY3VydmFyKSA9IHZhX2FyZyh2YWxpc3QsIEJTVFIpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWVF9ESVNQQVRDSDoKICAgICAgICAgIFZfVlQoY3VydmFyKSA9IHZ0OwogICAgICAgICAgVl9ESVNQQVRDSChjdXJ2YXIpID0gdmFfYXJnKHZhbGlzdCwgSURpc3BhdGNoKik7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZUX0JPT0w6CiAgICAgICAgICBWX1ZUKGN1cnZhcikgPSB2dDsKICAgICAgICAgIFZfQk9PTChjdXJ2YXIpID0gdmFfYXJnKHZhbGlzdCwgaW50KTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVlRfVU5LTk9XTjoKICAgICAgICAgIFZfVlQoY3VydmFyKSA9IHZ0OwogICAgICAgICAgVl9VTktOT1dOKGN1cnZhcikgPSB2YV9hcmcodmFsaXN0LCBJVW5rbm93biopOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWVF9JNDoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgVl9WVChjdXJ2YXIpID0gVlRfSTQ7CiAgICAgICAgICBWX0k0KGN1cnZhcikgPSB2YV9hcmcodmFsaXN0LCBMT05HKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHZhX2VuZCh2YWxpc3QpOwoKICAgIHJlc3VsdCA9IFNITFdBUElfSW52b2tlQnlJSUQoaUNQLCByaWlkLCBkaXNwSWQsICZkaXNwUGFyYW1zKTsKICAgIElDb25uZWN0aW9uUG9pbnRfUmVsZWFzZShpQ1ApOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4N10KICoKICogTm90aWZ5IGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0IG9mIGNoYW5nZXMuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gbm90aWZ5CiAqICBkaXNwSUQgICAgW0ldCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXMgTlVMTCBvciBkb2VzIG5vdCBzdXBwb3J0IHRoZQogKiAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9DUENvbnRhaW5lck9uQ2hhbmdlZChJVW5rbm93biAqbHBVbmtub3duLCBESVNQSUQgZGlzcElEKQp7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDUEMgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfTk9JTlRFUkZBQ0U7CgogIFRSQUNFKCIoJXAsMHglOFgpXG4iLCBscFVua25vd24sIGRpc3BJRCk7CgogIGlmIChscFVua25vd24pCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsICh2b2lkKiopJmxwQ1BDKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJQ29ubmVjdGlvblBvaW50KiBscENQOwoKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDUEMsICZJSURfSVByb3BlcnR5Tm90aWZ5U2luaywgJmxwQ1ApOwogICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9SZWxlYXNlKGxwQ1BDKTsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9PbkNoYW5nZWQobHBDUCwgZGlzcElEKTsKICAgIElDb25uZWN0aW9uUG9pbnRfUmVsZWFzZShscENQKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODldCiAqCiAqIFNlZSBQbGF5U291bmRXLgogKi8KQk9PTCBXSU5BUEkgUGxheVNvdW5kV3JhcFcoTFBDV1NUUiBwc3pTb3VuZCwgSE1PRFVMRSBobW9kLCBEV09SRCBmZHdTb3VuZCkKewogICAgcmV0dXJuIFBsYXlTb3VuZFcocHN6U291bmQsIGhtb2QsIGZkd1NvdW5kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NF0KICovCkJPT0wgV0lOQVBJIFNIR2V0SW5pU3RyaW5nVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMiwgTFBXU1RSIHBTdHIsIERXT1JEIHNvbWVfbGVuLCBMUENXU1RSIGxwU3RyMikKewogICAgRklYTUUoIiglcywlcywlcCwlMDh4LCVzKTogc3R1YiFcbiIsIGRlYnVnc3RyX3coc3RyMSksIGRlYnVnc3RyX3coc3RyMiksCiAgICAgICAgcFN0ciwgc29tZV9sZW4sIGRlYnVnc3RyX3cobHBTdHIyKSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NV0KICoKICogQ2FsbGVkIGJ5IElDUTIwMDBiIGluc3RhbGwgdmlhIFNIRE9DVlc6CiAqIHN0cjE6ICJJbnRlcm5ldFNob3J0Y3V0IgogKiB4OiBzb21lIHVua25vd24gcG9pbnRlcgogKiBzdHIyOiAiaHR0cDovL2ZyZWUuYW9sLmNvbS90cnlhb2xmcmVlL2luZGV4LmFkcD8xMzkyNjkiCiAqIHN0cjM6ICJDOlxcV0lORE9XU1xcRGVza3RvcC5uZXcyXFxGcmVlIEFPTCAmIFVubGltaXRlZCBJbnRlcm5ldC51cmwiCiAqCiAqIEluIHNob3J0OiB0aGlzIG9uZSBtYXliZSBjcmVhdGVzIGEgZGVza3RvcCBsaW5rIDotKQogKi8KQk9PTCBXSU5BUEkgU0hTZXRJbmlTdHJpbmdXKExQV1NUUiBzdHIxLCBMUFZPSUQgeCwgTFBXU1RSIHN0cjIsIExQV1NUUiBzdHIzKQp7CiAgICBGSVhNRSgiKCVzLCAlcCwgJXMsICVzKSwgc3R1Yi5cbiIsIGRlYnVnc3RyX3coc3RyMSksIHgsIGRlYnVnc3RyX3coc3RyMiksIGRlYnVnc3RyX3coc3RyMykpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMTNdCiAqCiAqIFNlZSBTSEdldEZpbGVJbmZvVy4KICovCkRXT1JEIFdJTkFQSSBTSEdldEZpbGVJbmZvV3JhcFcoTFBDV1NUUiBwYXRoLCBEV09SRCBkd0ZpbGVBdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgU0hGSUxFSU5GT1cgKnBzZmksIFVJTlQgc2l6ZW9mcHNmaSwgVUlOVCBmbGFncykKewogICAgcmV0dXJuIFNIR2V0RmlsZUluZm9XKHBhdGgsIGR3RmlsZUF0dHJpYnV0ZXMsIHBzZmksIHNpemVvZnBzZmksIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxOF0KICoKICogU2VlIERyYWdRdWVyeUZpbGVXLgogKi8KVUlOVCBXSU5BUEkgRHJhZ1F1ZXJ5RmlsZVdyYXBXKEhEUk9QIGhEcm9wLCBVSU5UIGxGaWxlLCBMUFdTVFIgbHBzekZpbGUsIFVJTlQgbExlbmd0aCkKewogICAgcmV0dXJuIERyYWdRdWVyeUZpbGVXKGhEcm9wLCBsRmlsZSwgbHBzekZpbGUsIGxMZW5ndGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzMzXQogKgogKiBTZWUgU0hCcm93c2VGb3JGb2xkZXJXLgogKi8KTFBJVEVNSURMSVNUIFdJTkFQSSBTSEJyb3dzZUZvckZvbGRlcldyYXBXKExQQlJPV1NFSU5GT1cgbHBCaSkKewogICAgcmV0dXJuIFNIQnJvd3NlRm9yRm9sZGVyVyhscEJpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNF0KICoKICogU2VlIFNIR2V0UGF0aEZyb21JRExpc3RXLgogKi8KQk9PTCBXSU5BUEkgU0hHZXRQYXRoRnJvbUlETGlzdFdyYXBXKExQQ0lURU1JRExJU1QgcGlkbCxMUFdTVFIgcHN6UGF0aCkKewogICAgcmV0dXJuIFNIR2V0UGF0aEZyb21JRExpc3RXKHBpZGwsIHBzelBhdGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM1XQogKgogKiBTZWUgU2hlbGxFeGVjdXRlRXhXLgogKi8KQk9PTCBXSU5BUEkgU2hlbGxFeGVjdXRlRXhXcmFwVyhMUFNIRUxMRVhFQ1VURUlORk9XIGxwRXhlY0luZm8pCnsKICAgIHJldHVybiBTaGVsbEV4ZWN1dGVFeFcobHBFeGVjSW5mbyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzZdCiAqCiAqIFNlZSBTSEZpbGVPcGVyYXRpb25XLgogKi8KSU5UIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25XcmFwVyhMUFNIRklMRU9QU1RSVUNUVyBscEZpbGVPcCkKewogICAgcmV0dXJuIFNIRmlsZU9wZXJhdGlvblcobHBGaWxlT3ApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzQyXQogKgogKi8KUFZPSUQgV0lOQVBJIFNISW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoIFBWT0lEICpkZXN0LCBQVk9JRCB4Y2hnLCBQVk9JRCBjb21wYXJlICkKewogICAgcmV0dXJuIEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlUG9pbnRlciggZGVzdCwgeGNoZywgY29tcGFyZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUwXQogKgogKiBTZWUgR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcuCiAqLwpEV09SRCBXSU5BUEkgR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVdyYXBXKCBMUENXU1RSIGZpbGVuYW1lLCBMUERXT1JEIGhhbmRsZSApCnsKICAgIHJldHVybiBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyggZmlsZW5hbWUsIGhhbmRsZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUxXQogKgogKiBTZWUgR2V0RmlsZVZlcnNpb25JbmZvVy4KICovCkJPT0wgIFdJTkFQSSBHZXRGaWxlVmVyc2lvbkluZm9XcmFwVyggTFBDV1NUUiBmaWxlbmFtZSwgRFdPUkQgaGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRhdGFzaXplLCBMUFZPSUQgZGF0YSApCnsKICAgIHJldHVybiBHZXRGaWxlVmVyc2lvbkluZm9XKCBmaWxlbmFtZSwgaGFuZGxlLCBkYXRhc2l6ZSwgZGF0YSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUyXQogKgogKiBTZWUgVmVyUXVlcnlWYWx1ZVcuCiAqLwpXT1JEIFdJTkFQSSBWZXJRdWVyeVZhbHVlV3JhcFcoIExQVk9JRCBwQmxvY2ssIExQQ1dTVFIgbHBTdWJCbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKmxwbHBCdWZmZXIsIFVJTlQgKnB1TGVuICkKewogICAgcmV0dXJuIFZlclF1ZXJ5VmFsdWVXKCBwQmxvY2ssIGxwU3ViQmxvY2ssIGxwbHBCdWZmZXIsIHB1TGVuICk7Cn0KCiNkZWZpbmUgSXNJZmFjZSh0eXBlKSBTVUNDRUVERUQoKGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfIyN0eXBlLCAodm9pZCoqKSZscE9iaikpKQojZGVmaW5lIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3MgSVNoZWxsQnJvd3Nlcl9FbmFibGVNb2RlbGVzc1NCCiNkZWZpbmUgRW5hYmxlTW9kZWxlc3ModHlwZSkgdHlwZSMjX0VuYWJsZU1vZGVsZXNzKCh0eXBlKilscE9iaiwgYk1vZGVsZXNzKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1NV0KICoKICogQ2hhbmdlIHRoZSBtb2RhbGl0eSBvZiBhIHNoZWxsIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBtYWtlIG1vZGVsZXNzCiAqICBiTW9kZWxlc3MgW0ldIFRSVUU9TWFrZSBtb2RlbGVzcywgRkFMU0U9TWFrZSBtb2RhbAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBUaGUgbW9kYWxpdHkgbHBVbmtub3duIGlzIGNoYW5nZWQuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gbXVzdCBzdXBwb3J0IHRoZSBJT2xlSW5QbGFjZUZyYW1lIGludGVyZmFjZSwgdGhlCiAqICBJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUgaW50ZXJmYWNlLCB0aGUgSVNoZWxsQnJvd3NlciBpbnRlcmZhY2UKICogIHRoZSBJRG9jSG9zdFVJSGFuZGxlciBpbnRlcmZhY2UsIG9yIHRoZSBJT2xlSW5QbGFjZUFjdGl2ZU9iamVjdCBpbnRlcmZhY2UsCiAqICBvciB0aGlzIGNhbGwgd2lsbCBmYWlsLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRW5hYmxlTW9kZWxlc3MoSVVua25vd24gKmxwVW5rbm93biwgQk9PTCBiTW9kZWxlc3MpCnsKICBJVW5rbm93biAqbHBPYmo7CiAgSFJFU1VMVCBoUmV0OwoKICBUUkFDRSgiKCVwLCVkKVxuIiwgbHBVbmtub3duLCBiTW9kZWxlc3MpOwoKICBpZiAoIWxwVW5rbm93bikKICAgIHJldHVybiBFX0ZBSUw7CgogIGlmIChJc0lmYWNlKElPbGVJblBsYWNlQWN0aXZlT2JqZWN0KSkKICAgIEVuYWJsZU1vZGVsZXNzKElPbGVJblBsYWNlQWN0aXZlT2JqZWN0KTsKICBlbHNlIGlmIChJc0lmYWNlKElPbGVJblBsYWNlRnJhbWUpKQogICAgRW5hYmxlTW9kZWxlc3MoSU9sZUluUGxhY2VGcmFtZSk7CiAgZWxzZSBpZiAoSXNJZmFjZShJU2hlbGxCcm93c2VyKSkKICAgIEVuYWJsZU1vZGVsZXNzKElTaGVsbEJyb3dzZXIpOwojaWYgMAogIC8qIEZJWE1FOiBXaW5lIGhhcyBubyBoZWFkZXJzIGZvciB0aGVzZSBvYmplY3RzIHlldCAqLwogIGVsc2UgaWYgKElzSWZhY2UoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKSkKICAgIEVuYWJsZU1vZGVsZXNzKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSk7CiAgZWxzZSBpZiAoSXNJZmFjZShJRG9jSG9zdFVJSGFuZGxlcikpCiAgICBFbmFibGVNb2RlbGVzcyhJRG9jSG9zdFVJSGFuZGxlcik7CiNlbmRpZgogIGVsc2UKICAgIHJldHVybiBoUmV0OwoKICBJVW5rbm93bl9SZWxlYXNlKGxwT2JqKTsKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1N10KICoKICogU2VlIFNIR2V0TmV3TGlua0luZm9XLgogKi8KQk9PTCBXSU5BUEkgU0hHZXROZXdMaW5rSW5mb1dyYXBXKExQQ1dTVFIgcHN6TGlua1RvLCBMUENXU1RSIHBzekRpciwgTFBXU1RSIHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgKnBmTXVzdENvcHksIFVJTlQgdUZsYWdzKQp7CiAgICByZXR1cm4gU0hHZXROZXdMaW5rSW5mb1cocHN6TGlua1RvLCBwc3pEaXIsIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNThdCiAqCiAqIFNlZSBTSERlZkV4dHJhY3RJY29uVy4KICovClVJTlQgV0lOQVBJIFNIRGVmRXh0cmFjdEljb25XcmFwVyhMUENXU1RSIHBzekljb25GaWxlLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgSElDT04qIHBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04qIHBoaWNvblNtYWxsLCBVSU5UIG5JY29uU2l6ZSkKewogICAgcmV0dXJuIFNIRGVmRXh0cmFjdEljb25XKHBzekljb25GaWxlLCBpSW5kZXgsIHVGbGFncywgcGhpY29uTGFyZ2UsIHBoaWNvblNtYWxsLCBuSWNvblNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzYzXQogKgogKiBHZXQgYW5kIHNob3cgYSBjb250ZXh0IG1lbnUgZnJvbSBhIHNoZWxsIGZvbGRlci4KICoKICogUEFSQU1TCiAqICBoV25kICAgICAgICAgICBbSV0gV2luZG93IGRpc3BsYXlpbmcgdGhlIHNoZWxsIGZvbGRlcgogKiAgbHBGb2xkZXIgICAgICAgW0ldIElTaGVsbEZvbGRlciBpbnRlcmZhY2UKICogIGxwQXBpZGwgICAgICAgIFtJXSBJZCBmb3IgdGhlIHBhcnRpY3VsYXIgZm9sZGVyIGRlc2lyZWQKICogIGJJbnZva2VEZWZhdWx0IFtJXSBXaGV0aGVyIHRvIGludm9rZSB0aGUgZGVmYXVsdCBtZW51IGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgYkludm9rZURlZmF1bHQgaXMgVFJVRSwgdGhlIGRlZmF1bHQgbWVudSBhY3Rpb24gd2FzCiAqICAgICAgICAgICBleGVjdXRlZC4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICovCkhSRVNVTFQgV0lOQVBJIFNISW52b2tlQ29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCwgQk9PTCBiSW52b2tlRGVmYXVsdCkKewogIElDb250ZXh0TWVudSAqaUNvbnRleHQ7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVkKVxuIiwgaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIGJJbnZva2VEZWZhdWx0KTsKCiAgaWYgKCFscEZvbGRlcikKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgdGhlIGNvbnRleHQgbWVudSBmcm9tIHRoZSBzaGVsbCBmb2xkZXIgKi8KICBoUmV0ID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YobHBGb2xkZXIsIGhXbmQsIDEsICZscEFwaWRsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmSUlEX0lDb250ZXh0TWVudSwgMCwgKHZvaWQqKikmaUNvbnRleHQpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSE1FTlUgaE1lbnU7CiAgICBpZiAoKGhNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCkpKQogICAgewogICAgICBIUkVTVUxUIGhRdWVyeTsKICAgICAgRFdPUkQgZHdEZWZhdWx0SWQgPSAwOwoKICAgICAgLyogQWRkIHRoZSBjb250ZXh0IG1lbnUgZW50cmllcyB0byB0aGUgcG9wdXAgKi8KICAgICAgaFF1ZXJ5ID0gSUNvbnRleHRNZW51X1F1ZXJ5Q29udGV4dE1lbnUoaUNvbnRleHQsIGhNZW51LCAwLCAxLCAweDdGRkYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJJbnZva2VEZWZhdWx0ID8gQ01GX05PUk1BTCA6IENNRl9ERUZBVUxUT05MWSk7CgogICAgICBpZiAoU1VDQ0VFREVEKGhRdWVyeSkpCiAgICAgIHsKICAgICAgICBpZiAoYkludm9rZURlZmF1bHQgJiYKICAgICAgICAgICAgKGR3RGVmYXVsdElkID0gR2V0TWVudURlZmF1bHRJdGVtKGhNZW51LCAwLCAwKSkgIT0gMHhGRkZGRkZGRikKICAgICAgICB7CiAgICAgICAgICBDTUlOVk9LRUNPTU1BTkRJTkZPIGNtSWNpOwogICAgICAgICAgLyogSW52b2tlIHRoZSBkZWZhdWx0IGl0ZW0gKi8KICAgICAgICAgIG1lbXNldCgmY21JY2ksMCxzaXplb2YoY21JY2kpKTsKICAgICAgICAgIGNtSWNpLmNiU2l6ZSA9IHNpemVvZihjbUljaSk7CiAgICAgICAgICBjbUljaS5mTWFzayA9IENNSUNfTUFTS19BU1lOQ09LOwogICAgICAgICAgY21JY2kuaHduZCA9IGhXbmQ7CiAgICAgICAgICBjbUljaS5scFZlcmIgPSBNQUtFSU5UUkVTT1VSQ0VBKGR3RGVmYXVsdElkKTsKICAgICAgICAgIGNtSWNpLm5TaG93ID0gU1dfU0NST0xMQ0hJTERSRU47CgogICAgICAgICAgaFJldCA9IElDb250ZXh0TWVudV9JbnZva2VDb21tYW5kKGlDb250ZXh0LCAmY21JY2kpOwogICAgICAgIH0KICAgICAgfQogICAgICBEZXN0cm95TWVudShoTWVudSk7CiAgICB9CiAgICBJQ29udGV4dE1lbnVfUmVsZWFzZShpQ29udGV4dCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzcwXQogKgogKiBTZWUgRXh0cmFjdEljb25XLgogKi8KSElDT04gV0lOQVBJIEV4dHJhY3RJY29uV3JhcFcoSElOU1RBTkNFIGhJbnN0YW5jZSwgTFBDV1NUUiBscHN6RXhlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIG5JY29uSW5kZXgpCnsKICAgIHJldHVybiBFeHRyYWN0SWNvblcoaEluc3RhbmNlLCBscHN6RXhlRmlsZU5hbWUsIG5JY29uSW5kZXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgICAgICAgW0ldIExpYnJhcnkgbmFtZQogKiAgaW5zdF9od25kICAgICAgW0ldIE1vZHVsZSB3aG9zZSBkaXJlY3RvcnkgaXMgdG8gYmUgdXNlZAogKiAgZHdDcm9zc0NvZGVQYWdlIFtJXSBTaG91bGQgYmUgRkFMU0UgKGN1cnJlbnRseSBpZ25vcmVkKQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIGhhbmRsZSB0byB0aGUgbG9hZGVkIG1vZHVsZQogKiAgRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICovCkhNT0RVTEUgV0lOQVBJIE1MTG9hZExpYnJhcnlBKExQQ1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdDcm9zc0NvZGVQYWdlKQp7CiAgLyogRklYTUU6IE5hdGl2ZSBhcHBlYXJzIHRvIGRvIERQQV9DcmVhdGUgYW5kIGEgRFBBX0luc2VydFB0ciBmb3IKICAgKiAgICAgICAgZWFjaCBjYWxsIGhlcmUuCiAgICogRklYTUU6IE5hdGl2ZSBzaG93cyBjYWxscyB0bzoKICAgKiAgU0hSZWdHZXRVU1ZhbHVlIGZvciAiU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogICAgICAgICAgICAgICAgICAgICAgQ2hlY2tWZXJzaW9uCiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlciIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxQS0luc3RhbGxlZCIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLQ1VcU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJSZXNvdXJjZUxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEFjdGl2ZSBTZXR1cFxJbnN0YWxsZWQgQ29tcG9uZW50c1x7Z3VpZH0iCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIGFuZCB0aGVuIHRlc3RzIHRoZSBMb2NhbGUgKCJlbiIgZm9yIG1lKS4KICAgKiAgICAgY29kZSBiZWxvdwogICAqICBhZnRlciB0aGUgY29kZSB0aGVuIGEgRFBBX0NyZWF0ZSAoZmlyc3QgdGltZSkgYW5kIERQQV9JbnNlcnRQdHIgYXJlIGRvbmUuCiAgICovCiAgICBDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsJWQpIHNlbWktc3R1YiFcbiIsIGRlYnVnc3RyX2EobmV3X21vZCksIGluc3RfaHduZCwgZHdDcm9zc0NvZGVQYWdlKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIE1MTG9hZExpYnJhcnlBLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeVcoTFBDV1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdDcm9zc0NvZGVQYWdlKQp7CiAgICBXQ0hBUiBtb2RfcGF0aFsyKk1BWF9QQVRIXTsKICAgIExQV1NUUiBwdHI7CiAgICBEV09SRCBsZW47CgogICAgRklYTUUoIiglcywlcCwlZCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfdyhuZXdfbW9kKSwgaW5zdF9od25kLCBkd0Nyb3NzQ29kZVBhZ2UpOwogICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVXKGluc3RfaHduZCwgbW9kX3BhdGgsIHNpemVvZihtb2RfcGF0aCkgLyBzaXplb2YoV0NIQVIpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSkgcmV0dXJuIE5VTEw7CgogICAgcHRyID0gc3RycmNoclcobW9kX3BhdGgsICdcXCcpOwogICAgaWYgKHB0cikgewoJc3RyY3B5VyhwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfdyhtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5Vyhtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29sb3JBZGp1c3RMdW1hICAgICAgW1NITFdBUEkuQF0KICoKICogQWRqdXN0IHRoZSBsdW1pbm9zaXR5IG9mIGEgY29sb3IKICoKICogUEFSQU1TCiAqICBjUkdCICAgICAgICAgW0ldIFJHQiB2YWx1ZSB0byBjb252ZXJ0CiAqICBkd0x1bWEgICAgICAgW0ldIEx1bWEgYWRqdXN0bWVudAogKiAgYlVua25vd24gICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFRoZSBhZGp1c3RlZCBSR0IgY29sb3IuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JBZGp1c3RMdW1hKENPTE9SUkVGIGNSR0IsIGludCBkd0x1bWEsIEJPT0wgYlVua25vd24pCnsKICBUUkFDRSgiKDB4JTh4LCVkLCVkKVxuIiwgY1JHQiwgZHdMdW1hLCBiVW5rbm93bik7CgogIGlmIChkd0x1bWEpCiAgewogICAgV09SRCB3SCwgd0wsIHdTOwoKICAgIENvbG9yUkdCVG9ITFMoY1JHQiwgJndILCAmd0wsICZ3Uyk7CgogICAgRklYTUUoIklnbm9yaW5nIGx1bWEgYWRqdXN0bWVudFxuIik7CgogICAgLyogRklYTUU6IFRoZSBhamR1c3RtZW50IGlzIG5vdCBsaW5lYXIgKi8KCiAgICBjUkdCID0gQ29sb3JITFNUb1JHQih3SCwgd0wsIHdTKTsKICB9CiAgcmV0dXJuIGNSR0I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zODldCiAqCiAqIFNlZSBHZXRTYXZlRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgR2V0U2F2ZUZpbGVOYW1lV3JhcFcoTFBPUEVORklMRU5BTUVXIG9mbikKewogICAgcmV0dXJuIEdldFNhdmVGaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MF0KICoKICogU2VlIFdOZXRSZXN0b3JlQ29ubmVjdGlvblcuCiAqLwpEV09SRCBXSU5BUEkgV05ldFJlc3RvcmVDb25uZWN0aW9uV3JhcFcoSFdORCBod25kT3duZXIsIExQV1NUUiBscHN6RGV2aWNlKQp7CiAgICByZXR1cm4gV05ldFJlc3RvcmVDb25uZWN0aW9uVyhod25kT3duZXIsIGxwc3pEZXZpY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzkxXQogKgogKiBTZWUgV05ldEdldExhc3RFcnJvclcuCiAqLwpEV09SRCBXSU5BUEkgV05ldEdldExhc3RFcnJvcldyYXBXKExQRFdPUkQgbHBFcnJvciwgTFBXU1RSIGxwRXJyb3JCdWYsIERXT1JEIG5FcnJvckJ1ZlNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBOYW1lQnVmLCBEV09SRCBuTmFtZUJ1ZlNpemUpCnsKICAgIHJldHVybiBXTmV0R2V0TGFzdEVycm9yVyhscEVycm9yLCBscEVycm9yQnVmLCBuRXJyb3JCdWZTaXplLCBscE5hbWVCdWYsIG5OYW1lQnVmU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDFdCiAqCiAqIFNlZSBQYWdlU2V0dXBEbGdXLgogKi8KQk9PTCBXSU5BUEkgUGFnZVNldHVwRGxnV3JhcFcoTFBQQUdFU0VUVVBETEdXIHBhZ2VkbGcpCnsKICAgIHJldHVybiBQYWdlU2V0dXBEbGdXKHBhZ2VkbGcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAyXQogKgogKiBTZWUgUHJpbnREbGdXLgogKi8KQk9PTCBXSU5BUEkgUHJpbnREbGdXcmFwVyhMUFBSSU5URExHVyBwcmludGRsZykKewogICAgcmV0dXJuIFByaW50RGxnVyhwcmludGRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDNdCiAqCiAqIFNlZSBHZXRPcGVuRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgR2V0T3BlbkZpbGVOYW1lV3JhcFcoTFBPUEVORklMRU5BTUVXIG9mbikKewogICAgcmV0dXJuIEdldE9wZW5GaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwNF0KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0VudW1PYmplY3RzKExQU0hFTExGT0xERVIgbHBGb2xkZXIsIEhXTkQgaHduZCwgU0hDT05URiBmbGFncywgSUVudW1JRExpc3QgKipwcGVudW0pCnsKICAgIElQZXJzaXN0ICpwZXJzaXN0OwogICAgSFJFU1VMVCBocjsKCiAgICBociA9IElTaGVsbEZvbGRlcl9RdWVyeUludGVyZmFjZShscEZvbGRlciwgJklJRF9JUGVyc2lzdCwgKExQVk9JRCkmcGVyc2lzdCk7CiAgICBpZihTVUNDRUVERUQoaHIpKQogICAgewogICAgICAgIENMU0lEIGNsc2lkOwogICAgICAgIGhyID0gSVBlcnNpc3RfR2V0Q2xhc3NJRChwZXJzaXN0LCAmY2xzaWQpOwogICAgICAgIGlmKFNVQ0NFRURFRChocikpCiAgICAgICAgewogICAgICAgICAgICBpZihJc0VxdWFsQ0xTSUQoJmNsc2lkLCAmQ0xTSURfU2hlbGxGU0ZvbGRlcikpCiAgICAgICAgICAgICAgICBociA9IElTaGVsbEZvbGRlcl9FbnVtT2JqZWN0cyhscEZvbGRlciwgaHduZCwgZmxhZ3MsIHBwZW51bSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGhyID0gRV9GQUlMOwogICAgICAgIH0KICAgICAgICBJUGVyc2lzdF9SZWxlYXNlKHBlcnNpc3QpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKiBJTlRFUk5BTDogTWFwIGZyb20gSExTIGNvbG9yIHNwYWNlIHRvIFJHQiAqLwpzdGF0aWMgV09SRCBXSU5BUEkgQ29udmVydEh1ZShpbnQgd0h1ZSwgV09SRCB3TWlkMSwgV09SRCB3TWlkMikKewogIHdIdWUgPSB3SHVlID4gMjQwID8gd0h1ZSAtIDI0MCA6IHdIdWUgPCAwID8gd0h1ZSArIDI0MCA6IHdIdWU7CgogIGlmICh3SHVlID4gMTYwKQogICAgcmV0dXJuIHdNaWQxOwogIGVsc2UgaWYgKHdIdWUgPiAxMjApCiAgICB3SHVlID0gMTYwIC0gd0h1ZTsKICBlbHNlIGlmICh3SHVlID4gNDApCiAgICByZXR1cm4gd01pZDI7CgogIHJldHVybiAoKHdIdWUgKiAod01pZDIgLSB3TWlkMSkgKyAyMCkgLyA0MCkgKyB3TWlkMTsKfQoKLyogQ29udmVydCB0byBSR0IgYW5kIHNjYWxlIGludG8gUkdCIHJhbmdlICgwLi4yNTUpICovCiNkZWZpbmUgR0VUX1JHQihoKSAoQ29udmVydEh1ZShoLCB3TWlkMSwgd01pZDIpICogMjU1ICsgMTIwKSAvIDI0MAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvckhMU1RvUkdCCVtTSExXQVBJLkBdCiAqCiAqIENvbnZlcnQgZnJvbSBobHMgY29sb3Igc3BhY2UgaW50byBhbiByZ2IgQ09MT1JSRUYuCiAqCiAqIFBBUkFNUwogKiAgd0h1ZSAgICAgICAgW0ldIEh1ZSBhbW91bnQKICogIHdMdW1pbm9zaXR5IFtJXSBMdW1pbm9zaXR5IGFtb3VudAogKiAgd1NhdHVyYXRpb24gW0ldIFNhdHVyYXRpb24gYW1vdW50CiAqCiAqIFJFVFVSTlMKICogIEEgQ09MT1JSRUYgcmVwcmVzZW50aW5nIHRoZSBjb252ZXJ0ZWQgY29sb3IuCiAqCiAqIE5PVEVTCiAqICBJbnB1dCBobHMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JITFNUb1JHQihXT1JEIHdIdWUsIFdPUkQgd0x1bWlub3NpdHksIFdPUkQgd1NhdHVyYXRpb24pCnsKICBXT1JEIHdSZWQ7CgogIGlmICh3U2F0dXJhdGlvbikKICB7CiAgICBXT1JEIHdHcmVlbiwgd0JsdWUsIHdNaWQxLCB3TWlkMjsKCiAgICBpZiAod0x1bWlub3NpdHkgPiAxMjApCiAgICAgIHdNaWQyID0gd1NhdHVyYXRpb24gKyB3THVtaW5vc2l0eSAtICh3U2F0dXJhdGlvbiAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKICAgIGVsc2UKICAgICAgd01pZDIgPSAoKHdTYXR1cmF0aW9uICsgMjQwKSAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKCiAgICB3TWlkMSA9IHdMdW1pbm9zaXR5ICogMiAtIHdNaWQyOwoKICAgIHdSZWQgICA9IEdFVF9SR0Iod0h1ZSArIDgwKTsKICAgIHdHcmVlbiA9IEdFVF9SR0Iod0h1ZSk7CiAgICB3Qmx1ZSAgPSBHRVRfUkdCKHdIdWUgLSA4MCk7CgogICAgcmV0dXJuIFJHQih3UmVkLCB3R3JlZW4sIHdCbHVlKTsKICB9CgogIHdSZWQgPSB3THVtaW5vc2l0eSAqIDI1NSAvIDI0MDsKICByZXR1cm4gUkdCKHdSZWQsIHdSZWQsIHdSZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDEzXQogKgogKiBHZXQgdGhlIGN1cnJlbnQgZG9ja2luZyBzdGF0dXMgb2YgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBET0NLSU5GT18gZmxhZ3MgZnJvbSAid2luYmFzZS5oIiwgdW51c2VkCiAqCiAqIFJFVFVSTlMKICogIE9uZSBvZiBET0NLSU5GT19VTkRPQ0tFRCwgRE9DS0lORk9fVU5ET0NLRUQsIG9yIDAgaWYgdGhlIHN5c3RlbSBpcyBub3QKICogIGEgbm90ZWJvb2suCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRNYWNoaW5lSW5mbyhEV09SRCBkd0ZsYWdzKQp7CiAgSFdfUFJPRklMRV9JTkZPQSBod0luZm87CgogIFRSQUNFKCIoMHglMDh4KVxuIiwgZHdGbGFncyk7CgogIEdldEN1cnJlbnRId1Byb2ZpbGVBKCZod0luZm8pOwogIHN3aXRjaCAoaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKSkKICB7CiAgY2FzZSBET0NLSU5GT19ET0NLRUQ6CiAgY2FzZSBET0NLSU5GT19VTkRPQ0tFRDoKICAgIHJldHVybiBod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MThdCiAqCiAqIEZ1bmN0aW9uIHNlZW1zIHRvIGRvIEZyZWVMaWJyYXJ5IHBsdXMgb3RoZXIgdGhpbmdzLgogKgogKiBGSVhNRSBuYXRpdmUgc2hvd3MgdGhlIGZvbGxvd2luZyBjYWxsczoKICogICBSdGxFbnRlckNyaXRpY2FsU2VjdGlvbgogKiAgIExvY2FsRnJlZQogKiAgIEdldFByb2NBZGRyZXNzKENvbWN0bDMyPz8sIDE1MEwpCiAqICAgRFBBX0RlbGV0ZVB0cgogKiAgIFJ0bExlYXZlQ3JpdGljYWxTZWN0aW9uCiAqICBmb2xsb3dlZCBieSB0aGUgRnJlZUxpYnJhcnkuCiAqICBUaGUgYWJvdmUgY29kZSBtYXkgYmUgcmVsYXRlZCB0byAuMzc3IGFib3ZlLgogKi8KQk9PTCBXSU5BUEkgTUxGcmVlTGlicmFyeShITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTldCiAqLwpCT09MIFdJTkFQSSBTSEZsdXNoU0ZDYWNoZVdyYXAodm9pZCkgewogIEZJWE1FKCI6IHN0dWJcbiIpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDI1XQogKi8KQk9PTCBXSU5BUEkgRGVsZXRlTWVudVdyYXAoSE1FTlUgaG1lbnUsIFVJTlQgcG9zLCBVSU5UIGZsYWdzKQp7CiAgICAvKiBGSVhNRTogVGhpcyBzaG91bGQgZG8gbW9yZSB0aGFuIHNpbXBseSBjYWxsIERlbGV0ZU1lbnUgKi8KICAgIEZJWE1FKCIlcCAlMDh4ICUwOHgpOiBzZW1pLXN0dWJcbiIsIGhtZW51LCBwb3MsIGZsYWdzKTsKICAgIHJldHVybiBEZWxldGVNZW51KGhtZW51LCBwb3MsIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgW1NITFdBUEkuNDI5XQogKiBGSVhNRSBJIGhhdmUgbm8gaWRlYSB3aGF0IHRoaXMgZnVuY3Rpb24gZG9lcyBvciB3aGF0IGl0cyBhcmd1bWVudHMgYXJlLgogKi8KQk9PTCBXSU5BUEkgTUxJc01MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCkKewogICAgICAgRklYTUUoIiglcCkgc3R1YlxuIiwgaEluc3QpOwogICAgICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMF0KICovCkRXT1JEIFdJTkFQSSBNTFNldE1MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCwgSEFORExFIGhIZWFwKQp7CglGSVhNRSgiKCVwLCVwKSBzdHViXG4iLCBoSW5zdCwgaEhlYXApOwoJcmV0dXJuIEVfRkFJTDsgICAvKiBUaGlzIGlzIHdoYXQgaXMgdXNlZCBpZiBzaGx3YXBpIG5vdCBsb2FkZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMV0KICovCkRXT1JEIFdJTkFQSSBNTENsZWFyTUxISW5zdGFuY2UoRFdPUkQgeCkKewoJRklYTUUoIigweCUwOHgpc3R1YlxuIiwgeCk7CglyZXR1cm4gMHhhYmJhMTI0NzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzNl0KICoKICogQ29udmVydCBhbiBVbmljb2RlIHN0cmluZyBDTFNJRCBpbnRvIGEgQ0xTSUQuCiAqCiAqIFBBUkFNUwogKiAgaWRzdHIgICAgICBbSV0gICBzdHJpbmcgY29udGFpbmluZyBhIENMU0lEIGluIHRleHQgZm9ybQogKiAgaWQgICAgICAgICBbT10gICBDTFNJRCBleHRyYWN0ZWQgZnJvbSB0aGUgc3RyaW5nCiAqCiAqIFJFVFVSTlMKICogIFNfT0sgb24gc3VjY2VzcyBvciBFX0lOVkFMSURBUkcgb24gZmFpbHVyZQogKi8KSFJFU1VMVCBXSU5BUEkgQ0xTSURGcm9tU3RyaW5nV3JhcChMUENXU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICAgIHJldHVybiBDTFNJREZyb21TdHJpbmcoKExQT0xFU1RSKWlkc3RyLCBpZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzddCiAqCiAqIERldGVybWluZSBpZiB0aGUgT1Mgc3VwcG9ydHMgYSBnaXZlbiBmZWF0dXJlLgogKgogKiBQQVJBTVMKICogIGR3RmVhdHVyZSBbSV0gRmVhdHVyZSByZXF1ZXN0ZWQgKHVuZG9jdW1lbnRlZCkKICoKICogUkVUVVJOUwogKiAgVFJVRSAgSWYgdGhlIGZlYXR1cmUgaXMgYXZhaWxhYmxlLgogKiAgRkFMU0UgSWYgdGhlIGZlYXR1cmUgaXMgbm90IGF2YWlsYWJsZS4KICovCkJPT0wgV0lOQVBJIElzT1MoRFdPUkQgZmVhdHVyZSkKewogICAgT1NWRVJTSU9OSU5GT0Egb3N2aTsKICAgIERXT1JEIHBsYXRmb3JtLCBtYWpvcnYsIG1pbm9ydjsKCiAgICBvc3ZpLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GT0EpOwogICAgaWYoIUdldFZlcnNpb25FeEEoJm9zdmkpKSAgewogICAgICAgIEVSUigiR2V0VmVyc2lvbkV4IGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1ham9ydiA9IG9zdmkuZHdNYWpvclZlcnNpb247CiAgICBtaW5vcnYgPSBvc3ZpLmR3TWlub3JWZXJzaW9uOwogICAgcGxhdGZvcm0gPSBvc3ZpLmR3UGxhdGZvcm1JZDsKCiNkZWZpbmUgSVNPU19SRVRVUk4oeCkgXAogICAgVFJBQ0UoIigweCV4KSByZXQ9JWRcbiIsZmVhdHVyZSwoeCkpOyBcCiAgICByZXR1cm4gKHgpOwoKICAgIHN3aXRjaChmZWF0dXJlKSAgewogICAgY2FzZSBPU19XSU4zMlNPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMycwogICAgICAgICAgICAgICAgIHx8IHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1dJTjk1T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDRPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA0KQogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSX0FMVDoKICAgIGNhc2UgT1NfV0lOMjAwME9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjk4T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA+PSAxMCkKICAgIGNhc2UgT1NfV0lOOThfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMTApCiAgICBjYXNlIE9TX1dJTjIwMDBQUk86CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19XSU4yMDAwU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwREFUQUNFTlRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgKG1pbm9ydiA9PSAwIHx8IG1pbm9ydiA9PSAxKSkKICAgIGNhc2UgT1NfV0lOMjAwMFRFUk1JTkFMOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19FTUJFRERFRDoKICAgICAgICBGSVhNRSgiKE9TX0VNQkVEREVEKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxDTElFTlQ6CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTENMSUVOVCkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1RFUk1JTkFMUkVNT1RFQURNSU46CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTFJFTU9URUFETUlOKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfV0lOOTVfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMCkKICAgIGNhc2UgT1NfTUVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDkwKQogICAgY2FzZSBPU19YUE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX0hPTUU6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1ICYmIG1pbm9ydiA+PSAxKQogICAgY2FzZSBPU19QUk9GRVNTSU9OQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19EQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19QRVJTT05BTFRFUk1JTkFMU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtaW5vcnYgPj0gMSAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfRkFTVFVTRVJTV0lUQ0hJTkc6CiAgICAgICAgRklYTUUoIihPU19GQVNUVVNFUlNXSVRDSElORykgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfV0VMQ09NRUxPR09OVUk6CiAgICAgICAgRklYTUUoIihPU19XRUxDT01FTE9HT05VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX0RPTUFJTk1FTUJFUjoKICAgICAgICBGSVhNRSgiKE9TX0RPTUFJTk1FTUJFUikgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfQU5ZU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV09XNjQzMjoKICAgICAgICBGSVhNRSgiKE9TX1dPVzY0MzIpIFNob3VsZCB3ZSBjaGVjayB0aGlzP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XRUJTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19TTUFMTEJVU0lORVNTU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEFCTEVUUEM6CiAgICAgICAgRklYTUUoIihPU19UQUJMRVBDKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfU0VSVkVSQURNSU5VSToKICAgICAgICBGSVhNRSgiKE9TX1NFUlZFUkFETUlOVUkpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19NRURJQUNFTlRFUjoKICAgICAgICBGSVhNRSgiKE9TX01FRElBQ0VOVEVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfQVBQTElBTkNFOgogICAgICAgIEZJWE1FKCIoT1NfQVBQTElBTkNFKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiN1bmRlZiBJU09TX1JFVFVSTgoKICAgIFdBUk4oIigweCV4KSB1bmtub3duIHBhcmFtZXRlclxuIixmZWF0dXJlKTsKCiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjQzOV0KICovCkhSRVNVTFQgV0lOQVBJIFNITG9hZFJlZ1VJU3RyaW5nVyhIS0VZIGhrZXksIExQQ1dTVFIgdmFsdWUsIExQV1NUUiBidWYsIERXT1JEIHNpemUpCnsKICAgIERXT1JEIHR5cGUsIHN6ID0gc2l6ZTsKCiAgICBpZihSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHZhbHVlLCBOVUxMLCAmdHlwZSwgKExQQllURSlidWYsICZzeikgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gRV9GQUlMOwoKICAgIHJldHVybiBTSExvYWRJbmRpcmVjdFN0cmluZyhidWYsIGJ1Ziwgc2l6ZSwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjQ3OF0KICoKICogQ2FsbCBJSW5wdXRPYmplY3RfVHJhbnNsYXRlQWNjZWxlcmF0b3JJTygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJSW5wdXRPYmplY3QgaW50ZXJmYWNlLgogKiAgbHBNc2cgICAgIFtJXSBLZXkgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfSU5WQUxJREFSRyBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1RyYW5zbGF0ZUFjY2VsZXJhdG9ySU8oSVVua25vd24gKmxwVW5rbm93biwgTFBNU0cgbHBNc2cpCnsKICBJSW5wdXRPYmplY3QqIGxwSW5wdXQgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBNc2cpOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW5wdXRPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBJbnB1dCk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwSW5wdXQpCiAgICB7CiAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RfVHJhbnNsYXRlQWNjZWxlcmF0b3JJTyhscElucHV0LCBscE1zZyk7CiAgICAgIElJbnB1dE9iamVjdF9SZWxlYXNlKGxwSW5wdXQpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuNDgxXQogKgogKiBDYWxsIElJbnB1dE9iamVjdF9IYXNGb2N1c0lPKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElJbnB1dE9iamVjdCBpbnRlcmZhY2UuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0ssIGlmIGxwVW5rbm93biBpcyBhbiBJSW5wdXRPYmplY3Qgb2JqZWN0IGFuZCBoYXMgdGhlIGZvY3VzLAogKiAgICAgICAgICAgb3IgU19GQUxTRSBvdGhlcndpc2UuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfSU5WQUxJREFSRyBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0hhc0ZvY3VzSU8oSVVua25vd24gKmxwVW5rbm93bikKewogIElJbnB1dE9iamVjdCogbHBJbnB1dCA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwKVxuIiwgbHBVbmtub3duKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwSW5wdXQpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscElucHV0KQogICAgewogICAgICBoUmV0ID0gSUlucHV0T2JqZWN0X0hhc0ZvY3VzSU8obHBJbnB1dCk7CiAgICAgIElJbnB1dE9iamVjdF9SZWxlYXNlKGxwSW5wdXQpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvclJHQlRvSExTCVtTSExXQVBJLkBdCiAqCiAqIENvbnZlcnQgYW4gcmdiIENPTE9SUkVGIGludG8gdGhlIGhscyBjb2xvciBzcGFjZS4KICoKICogUEFSQU1TCiAqICBjUkdCICAgICAgICAgW0ldIFNvdXJjZSByZ2IgdmFsdWUKICogIHB3SHVlICAgICAgICBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBodWUKICogIHB3THVtaW5hbmNlICBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBsdW1pbmFuY2UKICogIHB3U2F0dXJhdGlvbiBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBzYXR1cmF0aW9uCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuIHB3SHVlLCBwd0x1bWluYW5jZSBhbmQgcHdTYXR1cmF0aW9uIGFyZSBzZXQgdG8gdGhlIGNvbnZlcnRlZAogKiAgdmFsdWVzLgogKgogKiBOT1RFUwogKiAgT3V0cHV0IEhMUyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICogIEZvciBBY2hyb21hdGljIGNvbnZlcnNpb25zLCBIdWUgaXMgc2V0IHRvIDE2MC4KICovClZPSUQgV0lOQVBJIENvbG9yUkdCVG9ITFMoQ09MT1JSRUYgY1JHQiwgTFBXT1JEIHB3SHVlLAoJCQkgIExQV09SRCBwd0x1bWluYW5jZSwgTFBXT1JEIHB3U2F0dXJhdGlvbikKewogIGludCB3Uiwgd0csIHdCLCB3TWF4LCB3TWluLCB3SHVlLCB3THVtaW5vc2l0eSwgd1NhdHVyYXRpb247CgogIFRSQUNFKCIoJTA4eCwlcCwlcCwlcClcbiIsIGNSR0IsIHB3SHVlLCBwd0x1bWluYW5jZSwgcHdTYXR1cmF0aW9uKTsKCiAgd1IgPSBHZXRSVmFsdWUoY1JHQik7CiAgd0cgPSBHZXRHVmFsdWUoY1JHQik7CiAgd0IgPSBHZXRCVmFsdWUoY1JHQik7CgogIHdNYXggPSBtYXgod1IsIG1heCh3Rywgd0IpKTsKICB3TWluID0gbWluKHdSLCBtaW4od0csIHdCKSk7CgogIC8qIEx1bWlub3NpdHkgKi8KICB3THVtaW5vc2l0eSA9ICgod01heCArIHdNaW4pICogMjQwICsgMjU1KSAvIDUxMDsKCiAgaWYgKHdNYXggPT0gd01pbikKICB7CiAgICAvKiBBY2hyb21hdGljIGNhc2UgKi8KICAgIHdTYXR1cmF0aW9uID0gMDsKICAgIC8qIEh1ZSBpcyBub3cgdW5yZXByZXNlbnRhYmxlLCBidXQgdGhpcyBpcyB3aGF0IG5hdGl2ZSByZXR1cm5zLi4uICovCiAgICB3SHVlID0gMTYwOwogIH0KICBlbHNlCiAgewogICAgLyogQ2hyb21hdGljIGNhc2UgKi8KICAgIGludCB3RGVsdGEgPSB3TWF4IC0gd01pbiwgd1JOb3JtLCB3R05vcm0sIHdCTm9ybTsKCiAgICAvKiBTYXR1cmF0aW9uICovCiAgICBpZiAod0x1bWlub3NpdHkgPD0gMTIwKQogICAgICB3U2F0dXJhdGlvbiA9ICgod01heCArIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKHdNYXggKyB3TWluKTsKICAgIGVsc2UKICAgICAgd1NhdHVyYXRpb24gPSAoKDUxMCAtIHdNYXggLSB3TWluKS8yICsgd0RlbHRhICogMjQwKSAvICg1MTAgLSB3TWF4IC0gd01pbik7CgogICAgLyogSHVlICovCiAgICB3Uk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3UiAqIDQwKSAvIHdEZWx0YTsKICAgIHdHTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdHICogNDApIC8gd0RlbHRhOwogICAgd0JOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0IgKiA0MCkgLyB3RGVsdGE7CgogICAgaWYgKHdSID09IHdNYXgpCiAgICAgIHdIdWUgPSB3Qk5vcm0gLSB3R05vcm07CiAgICBlbHNlIGlmICh3RyA9PSB3TWF4KQogICAgICB3SHVlID0gODAgKyB3Uk5vcm0gLSB3Qk5vcm07CiAgICBlbHNlCiAgICAgIHdIdWUgPSAxNjAgKyB3R05vcm0gLSB3Uk5vcm07CiAgICBpZiAod0h1ZSA8IDApCiAgICAgIHdIdWUgKz0gMjQwOwogICAgZWxzZSBpZiAod0h1ZSA+IDI0MCkKICAgICAgd0h1ZSAtPSAyNDA7CiAgfQogIGlmIChwd0h1ZSkKICAgICpwd0h1ZSA9IHdIdWU7CiAgaWYgKHB3THVtaW5hbmNlKQogICAgKnB3THVtaW5hbmNlID0gd0x1bWlub3NpdHk7CiAgaWYgKHB3U2F0dXJhdGlvbikKICAgICpwd1NhdHVyYXRpb24gPSB3U2F0dXJhdGlvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSENyZWF0ZVNoZWxsUGFsZXR0ZQlbU0hMV0FQSS5AXQogKi8KSFBBTEVUVEUgV0lOQVBJIFNIQ3JlYXRlU2hlbGxQYWxldHRlKEhEQyBoZGMpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBDcmVhdGVIYWxmdG9uZVBhbGV0dGUoaGRjKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hHZXRJbnZlcnNlQ01BUCAoU0hMV0FQSS5AKQogKgogKiBHZXQgYW4gaW52ZXJzZSBjb2xvciBtYXAgdGFibGUuCiAqCiAqIFBBUkFNUwogKiAgbHBDbWFwICBbT10gRGVzdGluYXRpb24gZm9yIGNvbG9yIG1hcAogKiAgZHdTaXplICBbSV0gU2l6ZSBvZiBtZW1vcnkgcG9pbnRlZCB0byBieSBscENtYXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiwgICAgSWYgbHBDbWFwIGlzIGludmFsaWQuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIGR3RmxhZ3MgaXMgaW52YWxpZAogKiAgICAgICAgICAgRV9PVVRPRk1FTU9SWSwgSWYgdGhlcmUgaXMgbm8gbWVtb3J5IGF2YWlsYWJsZQogKgogKiBOT1RFUwogKiAgZHdTaXplIG1heSBvbmx5IGJlIENNQVBfUFRSX1NJWkUgKDQpIG9yIENNQVBfU0laRSAoODE5MikuCiAqICBJZiBkd1NpemUgPSBDTUFQX1BUUl9TSVpFLCAqbHBDbWFwIGlzIHNldCB0byB0aGUgYWRkcmVzcyBvZiB0aGlzIERMTCdzCiAqICBpbnRlcm5hbCBDTWFwLgogKiAgSWYgZHdTaXplID0gQ01BUF9TSVpFLCBscENtYXAgaXMgZmlsbGVkIHdpdGggYSBjb3B5IG9mIHRoZSBkYXRhIGZyb20KICogIHRoaXMgRExMJ3MgaW50ZXJuYWwgQ01hcC4KICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW52ZXJzZUNNQVAoTFBEV09SRCBkZXN0LCBEV09SRCBkd1NpemUpCnsKICAgIGlmIChkd1NpemUgPT0gNCkgewoJRklYTUUoIiAtIHJldHVybmluZyBib2d1cyBhZGRyZXNzIGZvciBTSEdldEludmVyc2VDTUFQXG4iKTsKCSpkZXN0ID0gKERXT1JEKTB4YWJiYTEyNDk7CglyZXR1cm4gMDsKICAgIH0KICAgIEZJWE1FKCIoJXAsICUjeCkgc3R1YlxuIiwgZGVzdCwgZHdTaXplKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNISXNMb3dNZW1vcnlNYWNoaW5lCVtTSExXQVBJLkBdCiAqCiAqIERldGVybWluZSBpZiB0aGUgY3VycmVudCBjb21wdXRlciBoYXMgbG93IG1lbW9yeS4KICoKICogUEFSQU1TCiAqICB4IFtJXSBGSVhNRQogKgogKiBSRVRVUk5TCiAqICBUUlVFIGlmIHRoZSB1c2VycyBtYWNoaW5lIGhhcyAxNiBNZWdhYnl0ZXMgb2YgbWVtb3J5IG9yIGxlc3MsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzTG93TWVtb3J5TWFjaGluZSAoRFdPUkQgeCkKewogIEZJWE1FKCIoMHglMDh4KSBzdHViXG4iLCB4KTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgR2V0TWVudVBvc0Zyb21JRAlbU0hMV0FQSS5AXQogKgogKiBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIGEgbWVudSBpdGVtIGZyb20gaXRzIElkLgogKgogKiBQQVJBTVMKICogICBoTWVudSBbSV0gTWVudSBjb250YWluaW5nIHRoZSBpdGVtCiAqICAgd0lEICAgW0ldIElkIG9mIHRoZSBtZW51IGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGluZGV4IG9mIHRoZSBtZW51IGl0ZW0gaW4gaE1lbnUuCiAqICBGYWlsdXJlOiAtMSwgSWYgdGhlIGl0ZW0gaXMgbm90IGZvdW5kLgogKi8KSU5UIFdJTkFQSSBHZXRNZW51UG9zRnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHdJRCkKewogTUVOVUlURU1JTkZPVyBtaTsKIElOVCBuQ291bnQgPSBHZXRNZW51SXRlbUNvdW50KGhNZW51KSwgbkl0ZXIgPSAwOwoKIHdoaWxlIChuSXRlciA8IG5Db3VudCkKIHsKICAgbWkuY2JTaXplID0gc2l6ZW9mKG1pKTsKICAgbWkuZk1hc2sgPSBNSUlNX0lEOwogICBpZiAoR2V0TWVudUl0ZW1JbmZvVyhoTWVudSwgbkl0ZXIsIFRSVUUsICZtaSkgJiYgbWkud0lEID09IHdJRCkKICAgICByZXR1cm4gbkl0ZXI7CiAgIG5JdGVyKys7CiB9CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzldCiAqCiAqIFNhbWUgYXMgU0hMV0FQSS5HZXRNZW51UG9zRnJvbUlECiAqLwpEV09SRCBXSU5BUEkgU0hNZW51SW5kZXhGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgdUlEKQp7CiAgICByZXR1cm4gR2V0TWVudVBvc0Zyb21JRChoTWVudSwgdUlEKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40NDhdCiAqLwpWT0lEIFdJTkFQSSBGaXhTbGFzaGVzQW5kQ29sb25XKExQV1NUUiBscHdzdHIpCnsKICAgIHdoaWxlICgqbHB3c3RyKQogICAgewogICAgICAgIGlmICgqbHB3c3RyID09ICcvJykKICAgICAgICAgICAgKmxwd3N0ciA9ICdcXCc7CiAgICAgICAgbHB3c3RyKys7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDYxXQogKi8KRFdPUkQgV0lOQVBJIFNIR2V0QXBwQ29tcGF0RmxhZ3MoRFdPUkQgZHdVbmtub3duKQp7CiAgRklYTUUoIigweCUwOHgpIHN0dWJcbiIsIGR3VW5rbm93bik7CiAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNTQ5XQogKi8KSFJFU1VMVCBXSU5BUEkgU0hDb0NyZWF0ZUluc3RhbmNlQUMoUkVGQ0xTSUQgcmNsc2lkLCBMUFVOS05PV04gcFVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0Nsc0NvbnRleHQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KQp7CiAgICByZXR1cm4gQ29DcmVhdGVJbnN0YW5jZShyY2xzaWQsIHBVbmtPdXRlciwgZHdDbHNDb250ZXh0LCBpaWQsIHBwdik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2tpcEp1bmN0aW9uCVtTSExXQVBJLkBdCiAqCiAqIERldGVybWluZSBpZiBhIGJpbmQgY29udGV4dCBjYW4gYmUgYm91bmQgdG8gYW4gb2JqZWN0CiAqCiAqIFBBUkFNUwogKiAgcGJjICAgIFtJXSBCaW5kIGNvbnRleHQgdG8gY2hlY2sKICogIHBjbHNpZCBbSV0gQ0xTSUQgb2Ygb2JqZWN0IHRvIGJlIGJvdW5kIHRvCiAqCiAqIFJFVFVSTlMKICogIFRSVUU6IElmIGl0IGlzIHNhZmUgdG8gYmluZAogKiAgRkFMU0U6IElmIHBiYyBpcyBpbnZhbGlkIG9yIGJpbmRpbmcgd291bGQgbm90IGJlIHNhZmUKICoKICovCkJPT0wgV0lOQVBJIFNIU2tpcEp1bmN0aW9uKElCaW5kQ3R4ICpwYmMsIGNvbnN0IENMU0lEICpwY2xzaWQpCnsKICBzdGF0aWMgV0NIQVIgc3pTa2lwQmluZGluZ1tdID0geyAnUycsJ2snLCdpJywncCcsJyAnLAogICAgJ0InLCdpJywnbicsJ2QnLCdpJywnbicsJ2cnLCcgJywnQycsJ0wnLCdTJywnSScsJ0QnLCdcMCcgfTsKICBCT09MIGJSZXQgPSBGQUxTRTsKCiAgaWYgKHBiYykKICB7CiAgICBJVW5rbm93biogbHBVbms7CgogICAgaWYgKFNVQ0NFRURFRChJQmluZEN0eF9HZXRPYmplY3RQYXJhbShwYmMsIChMUE9MRVNUUilzelNraXBCaW5kaW5nLCAmbHBVbmspKSkKICAgIHsKICAgICAgQ0xTSUQgY2xzaWQ7CgogICAgICBpZiAoU1VDQ0VFREVEKElVbmtub3duX0dldENsYXNzSUQobHBVbmssICZjbHNpZCkpICYmCiAgICAgICAgICBJc0VxdWFsR1VJRChwY2xzaWQsICZjbHNpZCkpCiAgICAgICAgYlJldCA9IFRSVUU7CgogICAgICBJVW5rbm93bl9SZWxlYXNlKGxwVW5rKTsKICAgIH0KICB9CiAgcmV0dXJuIGJSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hHZXRTaGVsbEtleSAoU0hMV0FQSS5AKQogKi8KRFdPUkQgV0lOQVBJIFNIR2V0U2hlbGxLZXkoRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYykKewogICAgRklYTUUoIigleCwgJXgsICV4KTogc3R1YlxuIiwgYSwgYiwgYyk7CiAgICByZXR1cm4gMHg1MDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSFF1ZXVlVXNlcldvcmtJdGVtIChTSExXQVBJLkApCiAqLwpCT09MIFdJTkFQSSBTSFF1ZXVlVXNlcldvcmtJdGVtKExQVEhSRUFEX1NUQVJUX1JPVVRJTkUgcGZuQ2FsbGJhY2ssIAogICAgICAgIExQVk9JRCBwQ29udGV4dCwgTE9ORyBsUHJpb3JpdHksIERXT1JEX1BUUiBkd1RhZywKICAgICAgICBEV09SRF9QVFIgKnBkd0lkLCBMUENTVFIgcHN6TW9kdWxlLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBUUkFDRSgiKCVwLCAlcCwgJWQsICVseCwgJXAsICVzLCAlMDh4KVxuIiwgcGZuQ2FsbGJhY2ssIHBDb250ZXh0LAogICAgICAgICAgbFByaW9yaXR5LCBkd1RhZywgcGR3SWQsIGRlYnVnc3RyX2EocHN6TW9kdWxlKSwgZHdGbGFncyk7CgogICAgaWYobFByaW9yaXR5IHx8IGR3VGFnIHx8IHBkd0lkIHx8IHBzek1vZHVsZSB8fCBkd0ZsYWdzKQogICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBhcmd1bWVudHNcbiIpOwoKICAgIHJldHVybiBRdWV1ZVVzZXJXb3JrSXRlbShwZm5DYWxsYmFjaywgcENvbnRleHQsIDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIU2V0VGltZXJRdWV1ZVRpbWVyIChTSExXQVBJLjI2MykKICovCkhBTkRMRSBXSU5BUEkgU0hTZXRUaW1lclF1ZXVlVGltZXIoSEFORExFIGhRdWV1ZSwKICAgICAgICBXQUlUT1JUSU1FUkNBTExCQUNLIHBmbkNhbGxiYWNrLCBMUFZPSUQgcENvbnRleHQsIERXT1JEIGR3RHVlVGltZSwKICAgICAgICBEV09SRCBkd1BlcmlvZCwgTFBDU1RSIGxwc3pMaWJyYXJ5LCBEV09SRCBkd0ZsYWdzKQp7CiAgICBIQU5ETEUgaE5ld1RpbWVyOwoKICAgIC8qIFNIU2V0VGltZXJRdWV1ZVRpbWVyIGZsYWdzIC0+IENyZWF0ZVRpbWVyUXVldWVUaW1lciBmbGFncyAqLwogICAgaWYgKGR3RmxhZ3MgJiBUUFNfTE9OR0VYRUNUSU1FKSB7CiAgICAgICAgZHdGbGFncyAmPSB+VFBTX0xPTkdFWEVDVElNRTsKICAgICAgICBkd0ZsYWdzIHw9IFdUX0VYRUNVVEVMT05HRlVOQ1RJT047CiAgICB9CiAgICBpZiAoZHdGbGFncyAmIFRQU19FWEVDVVRFSU8pIHsKICAgICAgICBkd0ZsYWdzICY9IH5UUFNfRVhFQ1VURUlPOwogICAgICAgIGR3RmxhZ3MgfD0gV1RfRVhFQ1VURUlOSU9USFJFQUQ7CiAgICB9CgogICAgaWYgKCFDcmVhdGVUaW1lclF1ZXVlVGltZXIoJmhOZXdUaW1lciwgaFF1ZXVlLCBwZm5DYWxsYmFjaywgcENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0R1ZVRpbWUsIGR3UGVyaW9kLCBkd0ZsYWdzKSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICByZXR1cm4gaE5ld1RpbWVyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlVbmtub3duX09uRm9jdXNDaGFuZ2VJUyAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fT25Gb2N1c0NoYW5nZUlTKExQVU5LTk9XTiBscFVua25vd24sIExQVU5LTk9XTiBwRm9jdXNPYmplY3QsIEJPT0wgYkZvY3VzKQp7CiAgICBJSW5wdXRPYmplY3RTaXRlICpwSU9TID0gTlVMTDsKICAgIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJXMpXG4iLCBscFVua25vd24sIHBGb2N1c09iamVjdCwgYkZvY3VzID8gIlRSVUUiIDogIkZBTFNFIik7CgogICAgaWYgKGxwVW5rbm93bikKICAgIHsKICAgICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnB1dE9iamVjdFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICoqKSZwSU9TKTsKICAgICAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIHBJT1MpCiAgICAgICAgewogICAgICAgICAgICBoUmV0ID0gSUlucHV0T2JqZWN0U2l0ZV9PbkZvY3VzQ2hhbmdlSVMocElPUywgcEZvY3VzT2JqZWN0LCBiRm9jdXMpOwogICAgICAgICAgICBJSW5wdXRPYmplY3RTaXRlX1JlbGVhc2UocElPUyk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hHZXRWYWx1ZVcgKFNITFdBUEkuQCkKICovCkhSRVNVTFQgV0lOQVBJIFNLR2V0VmFsdWVXKERXT1JEIGEsIExQV1NUUiBiLCBMUFdTVFIgYywgRFdPUkQgZCwgRFdPUkQgZSwgRFdPUkQgZikKewogICAgRklYTUUoIigleCwgJXMsICVzLCAleCwgJXgsICV4KTogc3R1YlxuIiwgYSwgZGVidWdzdHJfdyhiKSwgZGVidWdzdHJfdyhjKSwgZCwgZSwgZik7CiAgICByZXR1cm4gRV9GQUlMOwp9Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGxsR2V0VmVyc2lvbl9mdW5jKShETExWRVJTSU9OSU5GTyAqKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0VUlWZXJzaW9uIChTSExXQVBJLjQ1MikKICovCkRXT1JEIFdJTkFQSSBHZXRVSVZlcnNpb24odm9pZCkKewogICAgc3RhdGljIERXT1JEIHZlcnNpb247CgogICAgaWYgKCF2ZXJzaW9uKQogICAgewogICAgICAgIERsbEdldFZlcnNpb25fZnVuYyBwRGxsR2V0VmVyc2lvbjsKICAgICAgICBITU9EVUxFIGRsbCA9IExvYWRMaWJyYXJ5QSgic2hlbGwzMi5kbGwiKTsKICAgICAgICBpZiAoIWRsbCkgcmV0dXJuIDA7CgogICAgICAgIHBEbGxHZXRWZXJzaW9uID0gKERsbEdldFZlcnNpb25fZnVuYylHZXRQcm9jQWRkcmVzcyhkbGwsICJEbGxHZXRWZXJzaW9uIik7CiAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKQogICAgICAgIHsKICAgICAgICAgICAgRExMVkVSU0lPTklORk8gZHZpOwogICAgICAgICAgICBkdmkuY2JTaXplID0gc2l6ZW9mKERMTFZFUlNJT05JTkZPKTsKICAgICAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKCZkdmkpID09IFNfT0spIHZlcnNpb24gPSBkdmkuZHdNYWpvclZlcnNpb247CiAgICAgICAgfQogICAgICAgIEZyZWVMaWJyYXJ5KCBkbGwgKTsKICAgICAgICBpZiAoIXZlcnNpb24pIHZlcnNpb24gPSAzOyAgLyogb2xkIHNoZWxsIGRsbHMgZG9uJ3QgaGF2ZSBEbGxHZXRWZXJzaW9uICovCiAgICB9CiAgICByZXR1cm4gdmVyc2lvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBTaGVsbE1lc3NhZ2VCb3hXcmFwVyBbU0hMV0FQSS4zODhdCiAqCiAqIFNlZSBzaGVsbDMyLlNoZWxsTWVzc2FnZUJveFcKICoKICogTk9URToKICogc2hsd2FwaS5TaGVsbE1lc3NhZ2VCb3hXcmFwVyBpcyBhIGR1cGxpY2F0ZSBvZiBzaGVsbDMyLlNoZWxsTWVzc2FnZUJveFcKICogYmVjYXVzZSB3ZSBjYW4ndCBmb3J3YXJkIHRvIGl0IGluIHRoZSAuc3BlYyBmaWxlIHNpbmNlIGl0J3MgZXhwb3J0ZWQgYnkKICogb3JkaW5hbC4gSWYgeW91IGNoYW5nZSB0aGUgaW1wbGVtZW50YXRpb24gaGVyZSBwbGVhc2UgdXBkYXRlIHRoZSBjb2RlIGluCiAqIHNoZWxsMzIgYXMgd2VsbC4KICovCklOVCBXSU5BUElWIFNoZWxsTWVzc2FnZUJveFdyYXBXKEhJTlNUQU5DRSBoSW5zdGFuY2UsIEhXTkQgaFduZCwgTFBDV1NUUiBscFRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBDYXB0aW9uLCBVSU5UIHVUeXBlLCAuLi4pCnsKICAgIFdDSEFSIHN6VGV4dFsxMDBdLCBzelRpdGxlWzEwMF07CiAgICBMUENXU1RSIHBzelRleHQgPSBzelRleHQsIHBzelRpdGxlID0gc3pUaXRsZTsKICAgIExQV1NUUiBwc3pUZW1wOwogICAgdmFfbGlzdCBhcmdzOwogICAgaW50IHJldDsKCiAgICB2YV9zdGFydChhcmdzLCB1VHlwZSk7CgogICAgVFJBQ0UoIiglcCwlcCwlcCwlcCwlMDh4KVxuIiwgaEluc3RhbmNlLCBoV25kLCBscFRleHQsIGxwQ2FwdGlvbiwgdVR5cGUpOwoKICAgIGlmIChJU19JTlRSRVNPVVJDRShscENhcHRpb24pKQogICAgICAgIExvYWRTdHJpbmdXKGhJbnN0YW5jZSwgTE9XT1JEKGxwQ2FwdGlvbiksIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKS9zaXplb2Yoc3pUaXRsZVswXSkpOwogICAgZWxzZQogICAgICAgIHBzelRpdGxlID0gbHBDYXB0aW9uOwoKICAgIGlmIChJU19JTlRSRVNPVVJDRShscFRleHQpKQogICAgICAgIExvYWRTdHJpbmdXKGhJbnN0YW5jZSwgTE9XT1JEKGxwVGV4dCksIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkvc2l6ZW9mKHN6VGV4dFswXSkpOwogICAgZWxzZQogICAgICAgIHBzelRleHQgPSBscFRleHQ7CgogICAgRm9ybWF0TWVzc2FnZVcoRk9STUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSIHwgRk9STUFUX01FU1NBR0VfRlJPTV9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBXU1RSKSZwc3pUZW1wLCAwLCAmYXJncyk7CgogICAgdmFfZW5kKGFyZ3MpOwoKICAgIHJldCA9IE1lc3NhZ2VCb3hXKGhXbmQsIHBzelRlbXAsIHBzelRpdGxlLCB1VHlwZSk7CiAgICBMb2NhbEZyZWUoKEhMT0NBTClwc3pUZW1wKTsKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZUV4ZWMoSVVua25vd24gKnVuaywgUkVGSUlEIHNlcnZpY2UsIFJFRklJRCBjbHNpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCB4MSwgRFdPUkQgeDIsIERXT1JEIHgzLCB2b2lkICoqcHB2T3V0KQp7CiAgICBGSVhNRSgiJXAgJXMgJXMgJTA4eCAlMDh4ICUwOHggJXBcbiIsIHVuaywKICAgICAgICAgIGRlYnVnc3RyX2d1aWQoc2VydmljZSksIGRlYnVnc3RyX2d1aWQoY2xzaWQpLCB4MSwgeDIsIHgzLCBwcHZPdXQpOwogICAgcmV0dXJuIEVfTk9USU1QTDsKfQoKSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUHJvZmZlclNlcnZpY2UoSVVua25vd24gKnVuaywgdm9pZCAqeDAsIHZvaWQgKngxLCB2b2lkICp4MikKewogICAgRklYTUUoIiVwICVwICVwICVwXG4iLCB1bmssIHgwLCB4MSwgeDIpOwogICAgcmV0dXJuIEVfTk9USU1QTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBab25lQ29tcHV0ZVBhbmVTaXplIFtTSExXQVBJLjM4Ml0KICovClVJTlQgV0lOQVBJIFpvbmVDb21wdXRlUGFuZVNpemUoSFdORCBod25kKQp7CiAgICBGSVhNRSgiXG4iKTsKICAgIHJldHVybiAweDk1Owp9Cgp2b2lkIFdJTkFQSSBTSENoYW5nZU5vdGlmeShMT05HIHdFdmVudElkLCBVSU5UIHVGbGFncywgTFBDVk9JRCBkd0l0ZW0xLCBMUENWT0lEIGR3SXRlbTIpCnsKICAgIFNIQ2hhbmdlTm90aWZ5KHdFdmVudElkLCB1RmxhZ3MsIGR3SXRlbTEsIGR3SXRlbTIpOwp9Cgp0eXBlZGVmIHN0cnVjdCBTSEVMTF9VU0VSX1NJRCB7ICAgLyogYWNjb3JkaW5nIHRvIE1TRE4gdGhpcyBzaG91bGQgYmUgaW4gc2hsb2JqLmguLi4gKi8KICAgIFNJRF9JREVOVElGSUVSX0FVVEhPUklUWSBzaWRBdXRob3JpdHk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgZHdVc2VyR3JvdXBJRDsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICBkd1VzZXJJRDsKfSBTSEVMTF9VU0VSX1NJRCwgKlBTSEVMTF9VU0VSX1NJRDsKCnR5cGVkZWYgc3RydWN0IFNIRUxMX1VTRVJfUEVSTUlTU0lPTiB7IC8qIC4uLmFuZCB0aGlzIHNob3VsZCBiZSBpbiBzaGx3YXBpLmggKi8KICAgIFNIRUxMX1VTRVJfU0lEIHN1c0lEOwogICAgRFdPUkQgICAgICAgICAgZHdBY2Nlc3NUeXBlOwogICAgQk9PTCAgICAgICAgICAgZkluaGVyaXQ7CiAgICBEV09SRCAgICAgICAgICBkd0FjY2Vzc01hc2s7CiAgICBEV09SRCAgICAgICAgICBkd0luaGVyaXRNYXNrOwogICAgRFdPUkQgICAgICAgICAgZHdJbmhlcml0QWNjZXNzTWFzazsKfSBTSEVMTF9VU0VSX1BFUk1JU1NJT04sICpQU0hFTExfVVNFUl9QRVJNSVNTSU9OOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIEdldFNoZWxsU2VjdXJpdHlEZXNjcmlwdG9yIFtTSExXQVBJLjQ3NV0KICoKICogcHJlcGFyZXMgU0VDVVJJVFlfREVTQ1JJUFRPUiBmcm9tIGEgc2V0IG9mIEFDRXMKICoKICogUEFSQU1TCiAqICBhcFVzZXJQZXJtIFtJXSBhcnJheSBvZiBwb2ludGVycyB0byBTSEVMTF9VU0VSX1BFUk1JU1NJT04gc3RydWN0dXJlcywKICogICAgICAgICAgICAgICAgIGVhY2ggb2Ygd2hpY2ggZGVzY3JpYmVzIHBlcm1pc3Npb25zIHRvIGFwcGx5CiAqICBjVXNlclBlcm0gIFtJXSBudW1iZXIgb2YgZW50cmllcyBpbiBhcFVzZXJQZXJtIGFycmF5CiAqCiAqIFJFVFVSTlMKICogIHN1Y2Nlc3M6IHBvaW50ZXIgdG8gU0VDVVJJVFlfREVTQ1JJUFRPUgogKiAgZmFpbHVyZTogTlVMTAogKgogKiBOT1RFUwogKiAgQ2FsbCBzaG91bGQgZnJlZSByZXR1cm5lZCBkZXNjcmlwdG9yIHdpdGggTG9jYWxGcmVlCiAqLwpQU0VDVVJJVFlfREVTQ1JJUFRPUiBXSU5BUEkgR2V0U2hlbGxTZWN1cml0eURlc2NyaXB0b3IoUFNIRUxMX1VTRVJfUEVSTUlTU0lPTiAqYXBVc2VyUGVybSwgaW50IGNVc2VyUGVybSkKewogICAgUFNJRCAqc2lkbGlzdDsKICAgIFBTSUQgIGN1cl91c2VyID0gTlVMTDsKICAgIEJZVEUgIHR1VXNlclsyMDAwXTsKICAgIERXT1JEIGFjbF9zaXplOwogICAgaW50ICAgc2lkX2NvdW50LCBpOwogICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcHNkID0gTlVMTDsKCiAgICBUUkFDRSgiJXAgJWRcbiIsIGFwVXNlclBlcm0sIGNVc2VyUGVybSk7CgogICAgaWYgKGFwVXNlclBlcm0gPT0gTlVMTCB8fCBjVXNlclBlcm0gPD0gMCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBzaWRsaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNVc2VyUGVybSAqIHNpemVvZihQU0lEKSk7CiAgICBpZiAoIXNpZGxpc3QpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgYWNsX3NpemUgPSBzaXplb2YoQUNMKTsKCiAgICBmb3Ioc2lkX2NvdW50ID0gMDsgc2lkX2NvdW50IDwgY1VzZXJQZXJtOyBzaWRfY291bnQrKykKICAgIHsKICAgICAgICBzdGF0aWMgU0hFTExfVVNFUl9TSUQgbnVsbF9zaWQgPSB7e1NFQ1VSSVRZX05VTExfU0lEX0FVVEhPUklUWX0sIDAsIDB9OwogICAgICAgIFBTSEVMTF9VU0VSX1BFUk1JU1NJT04gcGVybSA9IGFwVXNlclBlcm1bc2lkX2NvdW50XTsKICAgICAgICBQU0hFTExfVVNFUl9TSUQgc2lkID0gJnBlcm0tPnN1c0lEOwogICAgICAgIFBTSUQgcFNpZDsKICAgICAgICBCT09MIHJldCA9IFRSVUU7CgogICAgICAgIGlmICghbWVtY21wKCh2b2lkKilzaWQsICh2b2lkKikmbnVsbF9zaWQsIHNpemVvZihTSEVMTF9VU0VSX1NJRCkpKQogICAgICAgIHsgIC8qIGN1cnJlbnQgdXNlcidzIFNJRCAqLyAKICAgICAgICAgICAgaWYgKCFjdXJfdXNlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIFRva2VuOwogICAgICAgICAgICAgICAgRFdPUkQgYnVmc2l6ZSA9IHNpemVvZih0dVVzZXIpOwoKICAgICAgICAgICAgICAgIHJldCA9IE9wZW5Qcm9jZXNzVG9rZW4oR2V0Q3VycmVudFByb2Nlc3MoKSwgVE9LRU5fUVVFUlksICZUb2tlbik7CiAgICAgICAgICAgICAgICBpZiAocmV0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldCA9IEdldFRva2VuSW5mb3JtYXRpb24oVG9rZW4sIFRva2VuVXNlciwgKHZvaWQqKXR1VXNlciwgYnVmc2l6ZSwgJmJ1ZnNpemUgKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmV0KQogICAgICAgICAgICAgICAgICAgICAgICBjdXJfdXNlciA9ICgoUFRPS0VOX1VTRVIpJnR1VXNlciktPlVzZXIuU2lkOwogICAgICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKFRva2VuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwU2lkID0gY3VyX3VzZXI7CiAgICAgICAgfSBlbHNlIGlmIChzaWQtPmR3VXNlcklEPT0wKSAvKiBvbmUgc3ViLWF1dGhvcml0eSAqLwogICAgICAgICAgICByZXQgPSBBbGxvY2F0ZUFuZEluaXRpYWxpemVTaWQoJnNpZC0+c2lkQXV0aG9yaXR5LCAxLCBzaWQtPmR3VXNlckdyb3VwSUQsIDAsCiAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgJnBTaWQpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0ID0gQWxsb2NhdGVBbmRJbml0aWFsaXplU2lkKCZzaWQtPnNpZEF1dGhvcml0eSwgMiwgc2lkLT5kd1VzZXJHcm91cElELCBzaWQtPmR3VXNlcklELAogICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsICZwU2lkKTsKICAgICAgICBpZiAoIXJldCkKICAgICAgICAgICAgZ290byBmcmVlX3NpZHM7CgogICAgICAgIHNpZGxpc3Rbc2lkX2NvdW50XSA9IHBTaWQ7CiAgICAgICAgLyogaW5jcmVtZW50IGFjbF9zaXplICgxIEFDRSBmb3Igbm9uLWluaGVyaXRhYmxlIGFuZCAyIEFDRXMgZm9yIGluaGVyaXRhYmxlIHJlY29yZHMgKi8KICAgICAgICBhY2xfc2l6ZSArPSAoc2l6ZW9mKEFDQ0VTU19BTExPV0VEX0FDRSktc2l6ZW9mKERXT1JEKSArIEdldExlbmd0aFNpZChwU2lkKSkgKiAocGVybS0+ZkluaGVyaXQgPyAyIDogMSk7CiAgICB9CgogICAgcHNkID0gTG9jYWxBbGxvYygwLCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikgKyBhY2xfc2l6ZSk7CgogICAgaWYgKHBzZCAhPSBOVUxMKQogICAgewogICAgICAgIFBBQ0wgcEFjbCA9IChQQUNMKSgoKEJZVEUqKXBzZCkrc2l6ZW9mKFNFQ1VSSVRZX0RFU0NSSVBUT1IpKTsKCiAgICAgICAgaWYgKCFJbml0aWFsaXplU2VjdXJpdHlEZXNjcmlwdG9yKHBzZCwgU0VDVVJJVFlfREVTQ1JJUFRPUl9SRVZJU0lPTikpCiAgICAgICAgICAgIGdvdG8gZXJyb3I7CgogICAgICAgIGlmICghSW5pdGlhbGl6ZUFjbChwQWNsLCBhY2xfc2l6ZSwgQUNMX1JFVklTSU9OKSkKICAgICAgICAgICAgZ290byBlcnJvcjsKCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc2lkX2NvdW50OyBpKyspCiAgICAgICAgewogICAgICAgICAgICBQU0hFTExfVVNFUl9QRVJNSVNTSU9OIHN1cCA9IGFwVXNlclBlcm1baV07CiAgICAgICAgICAgIFBTSUQgc2lkID0gc2lkbGlzdFtpXTsKCiAgICAgICAgICAgIHN3aXRjaChzdXAtPmR3QWNjZXNzVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBBQ0NFU1NfQUxMT1dFRF9BQ0VfVFlQRToKICAgICAgICAgICAgICAgICAgICBpZiAoIUFkZEFjY2Vzc0FsbG93ZWRBY2UocEFjbCwgQUNMX1JFVklTSU9OLCBzdXAtPmR3QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VwLT5mSW5oZXJpdCAmJiAhQWRkQWNjZXNzQWxsb3dlZEFjZUV4KHBBY2wsIEFDTF9SRVZJU0lPTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEJZVEUpc3VwLT5kd0luaGVyaXRNYXNrLCBzdXAtPmR3SW5oZXJpdEFjY2Vzc01hc2ssIHNpZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFDQ0VTU19ERU5JRURfQUNFX1RZUEU6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFBZGRBY2Nlc3NEZW5pZWRBY2UocEFjbCwgQUNMX1JFVklTSU9OLCBzdXAtPmR3QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VwLT5mSW5oZXJpdCAmJiAhQWRkQWNjZXNzRGVuaWVkQWNlRXgocEFjbCwgQUNMX1JFVklTSU9OLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSlzdXAtPmR3SW5oZXJpdE1hc2ssIHN1cC0+ZHdJbmhlcml0QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFTZXRTZWN1cml0eURlc2NyaXB0b3JEYWNsKHBzZCwgVFJVRSwgcEFjbCwgRkFMU0UpKQogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgZ290byBmcmVlX3NpZHM7CgplcnJvcjoKICAgIExvY2FsRnJlZShwc2QpOwogICAgcHNkID0gTlVMTDsKZnJlZV9zaWRzOgogICAgZm9yKGkgPSAwOyBpIDwgc2lkX2NvdW50OyBpKyspCiAgICB7CiAgICAgICAgaWYgKCFjdXJfdXNlciB8fCBzaWRsaXN0W2ldICE9IGN1cl91c2VyKQogICAgICAgICAgICBGcmVlU2lkKHNpZGxpc3RbaV0pOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2lkbGlzdCk7CgogICAgcmV0dXJuIHBzZDsKfQo=