LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCi8qICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICBJTkZFUkVOQ0UgUlVMRVMgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICovCi8qICogICRNb2R1bGU6ICAgSU5GUlVMRVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICBDb3B5cmlnaHQgKEMpIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTksIDIwMDAsIDIwMDEgICAgICAqICovCi8qICogIE1QSSBmdWVyIEluZm9ybWF0aWsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgICAqICovCi8qICogIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgICAgICAgICogKi8KLyogKiAgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgICAgICAgKiAqLwovKiAqICBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCAqICovCi8qICogIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsICAqICovCi8qICogIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gICAgICogKi8KLyogKiAgdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgICAgKiAqLwovKiAqICBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyAqICovCi8qICogIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCAgICAqICovCi8qICogIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlICogKi8KLyogKiAgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlICAgICAgKiAqLwovKiAqICBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EgICAgICAgICAqICovCi8qICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAkUmV2aXNpb24kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogJFN0YXRlJCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAkRGF0ZSQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogJEF1dGhvciQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICovCi8qICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICBDb250YWN0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICAgICAgICAgICAgIENocmlzdG9waCBXZWlkZW5iYWNoICAgICAgICAgICAgICAgICAgICAgICAqICovCi8qICogICAgICAgICAgICAgTVBJIGZ1ZXIgSW5mb3JtYXRpayAgICAgICAgICAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICBTdHVobHNhdHplbmhhdXN3ZWcgODUgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICAgICAgICAgICAgIDY2MTIzIFNhYXJicnVlY2tlbiAgICAgICAgICAgICAgICAgICAgICAgICAqICovCi8qICogICAgICAgICAgICAgRW1haWw6IHdlaWRlbmJAbXBpLXNiLm1wZy5kZSAgICAgICAgICAgICAgICogKi8KLyogKiAgICAgICAgICAgICBHZXJtYW55ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAqLwovKiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICovCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCi8qICRSQ1NmaWxlJCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBJbmNsdWRlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJydWxlcy1pbmYuaCIKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFNvbWUgYXV4aWxpYXJ5IGZ1bmN0aW9ucyBmb3IgdGVzdGluZyBwb3N0Y29uZGl0aW9ucyAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEJPT0wgaW5mX0xpdE1heChDTEFVU0UgQ2xhdXNlLCBpbnQgaSwgaW50IGosIFNVQlNUIFN1YnN0LCBCT09MIFN0cmljdCwKCQkgICAgICAgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlLCB0aGUgaW5kZXggb2YgYSBtYXhpbWFsIGxpdGVyYWwsIGFub3RoZXIgCiAgICAgICAgICAgbGl0ZXJhbCBpbmRleCwgYSBzdWJzdGl0dXRpb24sIGEgYm9vbGVhbiBmbGFnLCBhIAoJICAgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IElmIDxTdHJpY3Q+PUZBTFNFIHRoZSBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWZmIHRoZQogICAgICAgICAgIGxpdGVyYWwgYXQgaW5kZXggPGk+IGlzIHN0aWxsIG1heGltYWwgaW4gdGhlIAoJICAgaW5zdGFudGlhdGVkIGNsYXVzZS4KCSAgIElmIDxTdHJpY3Q+PVRSVUUgdGhlIGZ1bmN0aW9uIHJldHVybnMgVFJVRSBpZmYgdGhlCgkgICBsaXRlcmFsIGlzIFNUUklDVExZIG1heGltYWwgaW4gdGhlIGluc3RhbnRpYXRlZCAKCSAgIGNsYXVzZS4gVGhlIGxpdGVyYWwgYXQgaW5kZXggaiBpcyBvbWl0dGVkIGF0IGxpdGVyYWwgCgkgICBjb21wYXJpc29uLgoJICAgSG93ZXZlciwgc2V0dGluZyBqIHRvIGEgbmVnYXRpdmUgbnVtYmVyIGVuc3VyZXMgdGhhdAoJICAgYWxsIGxpdGVyYWxzIGFyZSBjb21wYXJlZCB3aXRoIHRoZSBsaXRlcmFsIGF0IAoJICAgaW5kZXggPGk+LgogIENBVVRJT046IERPTidUIGNhbGwgdGhpcyBmdW5jdGlvbiB3aXRoIGEgY2xhdXNlIHdpdGggc2VsZWN0ZWQKICAgICAgICAgICBsaXRlcmFscyEKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgVEVSTSAgICAgICBNYXgsIExpdFRlcm07CiAgTElURVJBTCAgICBMaXQ7CiAgb3JkX1JFU1VMVCBDb21wYXJlOwogIGludCAgICAgICAgaywgbDsKCiNpZmRlZiBDSEVDSwogIGlmICghY2xhdXNlX0xpdGVyYWxJc01heGltYWwoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLCBpKSkgfHwKICAgICAgKFN0cmljdCAmJgogICAgICAgIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGkpLCBTVFJJQ1RNQVhJTUFMKSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdE1heDogTGl0ZXJhbCAlZCBpc24ndCAlc21heGltYWwuIiwKCQkgICAgIGksIFN0cmljdCA/ICJzdHJpY3RseSAiIDogIiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KICBpZiAoaSA8IGNsYXVzZV9GaXJzdEFudGVjZWRlbnRMaXRJbmRleChDbGF1c2UpIHx8CiAgICAgIGkgPiBjbGF1c2VfTGFzdFN1Y2NlZGVudExpdEluZGV4KENsYXVzZSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdE1heDogTGl0ZXJhbCBpbmRleCAlZCBpcyBvdXQgb2YgcmFuZ2UuIiwgaSk7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQogIC8qIElmIGxpdGVyYWwgPGk+IGlzIHNlbGVjdGVkLCB0aGVyZSdzIG5vIG5lZWQgdG8gY2hlY2sgZm9yIG1heGltYWxpdHksICovCiAgLyogaWYgPGk+IGlzbid0IHNlbGVjdGVkLCBidXQgdGhlcmUncmUgb3RoZXIgbGl0ZXJhbHMgc2VsZWN0ZWQsICAgICAgICAgKi8KICAvKiBpbmZlcmVuY2VzIHdpdGggbGl0ZXJhbCA8aT4gYXJlIGZvcmJpZGRlbi4gICAgICAgICAgICAgICAgICAgICAgICAgICAqLyAKICBpZiAoY2xhdXNlX0dldEZsYWcoQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9MaXRNYXg6IFRoZXJlJ3JlIHNlbGVjdGVkIGxpdGVyYWxzLiIsIGkpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0gICAgCiNlbmRpZgoKICBMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGkpOwogIC8qIENoZWNrIG5lY2Vzc2FyeSBjb25kaXRpb24gKi8KICBpZiAoIWNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKExpdCkgfHwKICAgICAgKFN0cmljdCAmJiAhY2xhdXNlX0xpdGVyYWxHZXRGbGFnKExpdCwgU1RSSUNUTUFYSU1BTCkpKQogICAgcmV0dXJuIEZBTFNFOwogIC8qIE9ubHkgYW50ZWNlZGVudCBhbmQgc3VjY2VkZW50IGxpdGVyYWxzIGFyZSBjb21wYXJlZCwgc28gaWYgdGhlcmUncyAqLwogIC8qIG9ubHkgb25lIHN1Y2ggbGl0ZXJhbCwgaXQncyBtYXhpbWFsLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogIC8qIElmIHRoZSBzdWJzdGl0dXRpb24gaXMgZW1wdHksIHRoZSBuZWNlc3NhcnkgY29uZGl0aW9uIHRlc3RlZCBhYm92ZSAqLwogIC8qIGlzIHN1ZmZpY2llbnQsIHRvby4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogIGlmICgoY2xhdXNlX051bU9mQW50ZUxpdHMoQ2xhdXNlKSArIGNsYXVzZV9OdW1PZlN1Y2NMaXRzKENsYXVzZSkgPT0gMSkgfHwKICAgICAgc3Vic3RfRW1wdHkoU3Vic3QpKQogICAgcmV0dXJuIFRSVUU7CgogIGwgICA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQ2xhdXNlKTsKICBNYXggPSBzdWJzdF9BcHBseShTdWJzdCx0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKENsYXVzZSxpKSkpOwoKICBmb3IgKGsgPSBjbGF1c2VfRmlyc3RBbnRlY2VkZW50TGl0SW5kZXgoQ2xhdXNlKTsgayA8PSBsOyBrKyspCiAgICBpZiAoayAhPSBpICYmIGsgIT0gaiAmJgoJY2xhdXNlX0xpdGVyYWxJc01heGltYWwoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLCBrKSkpIHsKICAgICAgLyogT25seSBjb21wYXJlIHdpdGggbWF4aW1hbCBsaXRlcmFscywgc2luY2UgZm9yIGV2ZXJ5IG5vbi1tYXhpbWFsICovCiAgICAgIC8qIGxpdGVyYWwsIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIG1heGltYWwgbGl0ZXJhbCwgdGhhdCBpcyBiaWdnZXIuICAqLwogICAgICBMaXRUZXJtID0gc3Vic3RfQXBwbHkoU3Vic3QsdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsaykpKTsKICAgICAgQ29tcGFyZSA9IG9yZF9MaXRlcmFsQ29tcGFyZShNYXgsCgkJCQkgICBjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSkpLAoJCQkJICAgTGl0VGVybSwKCQkJCSAgIGNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxrKSksCgkJCQkgICBUUlVFLCBGbGFncywgUHJlY2VkZW5jZSk7CiAgICAgIGlmIChDb21wYXJlID09IG9yZF9TbWFsbGVyVGhhbigpIHx8IChTdHJpY3QgJiYgQ29tcGFyZSA9PSBvcmRfRXF1YWwoKSkpIHsKCXRlcm1fRGVsZXRlKE1heCk7Cgl0ZXJtX0RlbGV0ZShMaXRUZXJtKTsKCXJldHVybiBGQUxTRTsKICAgICAgfQogICAgICB0ZXJtX0RlbGV0ZShMaXRUZXJtKTsKICAgIH0KICB0ZXJtX0RlbGV0ZShNYXgpOwoKICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIGluZl9MaXRlcmFsc01heChDTEFVU0UgQ2xhdXNlLCBpbnQgaSwgU1VCU1QgU3Vic3QsCgkJCSAgICBDTEFVU0UgUGFydG5lckNsYXVzZSwgaW50IGosIFNVQlNUIFBhcnRuZXJTdWJzdCwKCQkJICAgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUaGUgcGFyZW50cyBvZiBhIHJlc29sdXRpb24gaW5mZXJlbmNlLCB0aGUgcmVzcGVjdGl2ZQogICAgICAgICAgIGxpdGVyYWwgaW5kaWNlcyBhbmQgc3Vic3RpdHV0aW9ucywgYSBmbGFnIHN0b3JlIGFuZCAKCSAgIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBUUlVFIGlmZiB0aGUgcG9zaXRpdmUvbmVnYXRpdmUgbGl0ZXJhbHMgYXJlIHN0aWxsCiAgICAgICAgICAgc3RyaWN0bHkgbWF4aW1hbC9tYXhpbWFsIGluIHRoZSBpbnN0YW50aWF0ZWQgY2xhdXNlLgoJICAgSWYgYSBuZWdhdGl2ZSBsaXRlcmFsIGlzIHNlbGVjdGVkLCBubyBjb21wYXJpc29uCgkgICBpcyBtYWRlLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKI2lmZGVmIENIRUNLCiAgaWYgKChjbGF1c2VfR2V0RmxhZyhDbGF1c2UsIENMQVVTRVNFTEVDVCkgJiYKICAgICAgICFjbGF1c2VfTGl0ZXJhbEdldEZsYWcoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpLExJVFNFTEVDVCkpIHx8CiAgICAgIChjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpICYmCiAgICAgICAhY2xhdXNlX0xpdGVyYWxHZXRGbGFnKGNsYXVzZV9HZXRMaXRlcmFsKFBhcnRuZXJDbGF1c2UsaiksTElUU0VMRUNUKSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdGVyYWxzTWF4OiBBbm90aGVyIGxpdGVyYWwgaXMgc2VsZWN0ZWQuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQojZW5kaWYKCiAgaWYgKCFjbGF1c2VfR2V0RmxhZyhDbGF1c2UsIENMQVVTRVNFTEVDVCkgJiYKICAgICAgIWluZl9MaXRNYXgoQ2xhdXNlLGksLTEsU3Vic3QsCgkJICBpPmNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KENsYXVzZSksRmxhZ3MsIFByZWNlZGVuY2UpKQogICAgcmV0dXJuIEZBTFNFOwogIGlmICghY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSwgQ0xBVVNFU0VMRUNUKSAmJgogICAgICAhaW5mX0xpdE1heChQYXJ0bmVyQ2xhdXNlLGosLTEsUGFydG5lclN1YnN0LAoJCSAgaj5jbGF1c2VfTGFzdEFudGVjZWRlbnRMaXRJbmRleChQYXJ0bmVyQ2xhdXNlKSwgRmxhZ3MsIFByZWNlZGVuY2UpKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIGluZl9MaXRNYXhXaXRoMlN1YnN0KENMQVVTRSBDbGF1c2UsIGludCBpLCBpbnQgaiwgU1VCU1QgU3Vic3QyLAoJCQkJIFNVQlNUIFN1YnN0MSwgQk9PTCBTdHJpY3QsIEZMQUdTVE9SRSBGbGFncywKCQkJCSBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlLCB0aGUgaW5kZXggb2YgYSBtYXhpbWFsIGxpdGVyYWwsIGFub3RoZXIgCiAgICAgICAgICAgbGl0ZXJhbCBpbmRleCwgdHdvIHN1YnN0aXR1dGlvbnMsIGEgYm9vbGVhbiBmbGFnLCAKCSAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEluIGNvbnRyYXN0IHRvIHRoZSBmdW5jdGlvbiBpbmZfTGl0TWF4IHRoaXMgZnVuY3Rpb24gCiAgICAgICAgICAgY29tcGFyZXMgdGhlIGxpdGVyYWxzIHdpdGggcmVzcGVjdCB0byB0aGUgY29tcG9zaXRpb24gCgkgICBvZiB0aGUgdHdvIHN1YnN0aXR1dGlvbnMgU3Vic3QyILAgU3Vic3QxLgoJICAgSWYgPFN0cmljdD49RkFMU0UgdGhlIGZ1bmN0aW9uIHJldHVybnMgVFJVRSBpZmYgdGhlCiAgICAgICAgICAgbGl0ZXJhbCBhdCBpbmRleCA8aT4gaXMgc3RpbGwgbWF4aW1hbCBpbiB0aGUgCgkgICBpbnN0YW50aWF0ZWQgY2xhdXNlLgoJICAgSWYgPFN0cmljdD49VFJVRSB0aGUgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmZiB0aGUKCSAgIGxpdGVyYWwgaXMgU1RSSUNUTFkgbWF4aW1hbCBpbiB0aGUgaW5zdGFudGlhdGVkIAoJICAgY2xhdXNlLgoJICAgVGhlIGxpdGVyYWwgYXQgaW5kZXggaiBpcyBvbWl0dGVkIGF0IGxpdGVyYWwgCgkgICBjb21wYXJpc29uLgoJICAgSG93ZXZlciwgc2V0dGluZyBqIHRvIGEgbmVnYXRpdmUgbnVtYmVyIGVuc3VyZXMgdGhhdAoJICAgYWxsIGxpdGVyYWxzIGFyZSBjb21wYXJlZCB3aXRoIHRoZSBsaXRlcmFsIGF0IAoJICAgaW5kZXggPGk+LgogIENBVVRJT046IERPTidUIGNhbGwgdGhpcyBmdW5jdGlvbiB3aXRoIGEgY2xhdXNlIHdpdGggc2VsZWN0ZWQKICAgICAgICAgICBsaXRlcmFscyEKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgVEVSTSAgICAgICBNYXgsIExpdFRlcm07CiAgTElURVJBTCAgICBMaXQ7CiAgb3JkX1JFU1VMVCBDb21wYXJlOwogIGludCAgICAgICAgaywgbDsKCiNpZmRlZiBDSEVDSwogIGlmICghY2xhdXNlX0xpdGVyYWxJc01heGltYWwoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLCBpKSkgfHwKICAgICAgKFN0cmljdCAmJgogICAgICAgIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGkpLCBTVFJJQ1RNQVhJTUFMKSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdE1heFdpdGgyU3Vic3Q6IExpdGVyYWwgJWQgaXNuJ3QgJXNtYXhpbWFsLiIsCgkJICAgICBpLCBTdHJpY3QgPyAic3RyaWN0bHkgIiA6ICIiKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiAgaWYgKGkgPCBjbGF1c2VfRmlyc3RBbnRlY2VkZW50TGl0SW5kZXgoQ2xhdXNlKSB8fAogICAgICBpID4gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChDbGF1c2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9MaXRNYXhXaXRoMlN1YnN0OiBMaXRlcmFsIGluZGV4ICVkIGlzIG91dCBvZiByYW5nZS4iLCBpKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiAgLyogSWYgbGl0ZXJhbCA8aT4gaXMgc2VsZWN0ZWQsIHRoZXJlJ3Mgbm8gbmVlZCB0byBjaGVjayBmb3IgbWF4aW1hbGl0eSwgKi8KICAvKiBpZiA8aT4gaXNuJ3Qgc2VsZWN0ZWQsIGJ1dCB0aGVyZSdyZSBvdGhlciBsaXRlcmFscyBzZWxlY3RlZCwgICAgICAgICAqLwogIC8qIGluZmVyZW5jZXMgd2l0aCBsaXRlcmFsIDxpPiBhcmUgZm9yYmlkZGVuLiAgICAgICAgICAgICAgICAgICAgICAgICAgICovIAogIGlmIChjbGF1c2VfR2V0RmxhZyhDbGF1c2UsIENMQVVTRVNFTEVDVCkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdE1heFdpdGgyU3Vic3Q6IFRoZXJlJ3JlIHNlbGVjdGVkIGxpdGVyYWxzLiIsIGkpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0gICAgCiNlbmRpZgoKICBMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGkpOwogIC8qIENoZWNrIG5lY2Vzc2FyeSBjb25kaXRpb24gKi8KICBpZiAoIWNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKExpdCkgfHwKICAgICAgKFN0cmljdCAmJiAhY2xhdXNlX0xpdGVyYWxHZXRGbGFnKExpdCwgU1RSSUNUTUFYSU1BTCkpKQogICAgcmV0dXJuIEZBTFNFOwogIC8qIE9ubHkgYW50ZWNlZGVudCBhbmQgc3VjY2VkZW50IGxpdGVyYWxzIGFyZSBjb21wYXJlZCwgc28gaWYgdGhlcmUncyAgICAqLwogIC8qIG9ubHkgb25lIHN1Y2ggbGl0ZXJhbCwgaXQncyBtYXhpbWFsLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogIC8qIElmIGJvdGggc3Vic3RpdHV0aW9ucyBhcmUgZW1wdHksIHRoZSBuZWNlc3NhcnkgY29uZGl0aW9uIHRlc3RlZCBhYm92ZSAqLwogIC8qIGlzIHN1ZmZpY2llbnQsIHRvby4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogIGlmICgoY2xhdXNlX051bU9mQW50ZUxpdHMoQ2xhdXNlKSArIGNsYXVzZV9OdW1PZlN1Y2NMaXRzKENsYXVzZSkgPT0gMSkgfHwKICAgICAgKHN1YnN0X0VtcHR5KFN1YnN0MSkgJiYgc3Vic3RfRW1wdHkoU3Vic3QyKSkpCiAgICByZXR1cm4gVFJVRTsKCiAgbCAgID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChDbGF1c2UpOwogIE1heCA9IHN1YnN0X0FwcGx5KFN1YnN0MSwgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsaSkpKTsKICBNYXggPSBzdWJzdF9BcHBseShTdWJzdDIsIE1heCk7CgogIGZvciAoayA9IGNsYXVzZV9GaXJzdEFudGVjZWRlbnRMaXRJbmRleChDbGF1c2UpOyBrIDw9IGw7IGsrKykKICAgIGlmIChrICE9IGkgJiYgayAhPSBqICYmCgljbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGspKSkgewogICAgICAvKiBPbmx5IGNvbXBhcmUgd2l0aCBtYXhpbWFsIGxpdGVyYWxzLCBzaW5jZSBmb3IgZXZlcnkgbm9uLW1heGltYWwgKi8KICAgICAgLyogbGl0ZXJhbCwgdGhlcmUncyBhdCBsZWFzdCBvbmUgbWF4aW1hbCBsaXRlcmFsLCB0aGF0IGlzIGJpZ2dlci4gICovCiAgICAgIExpdFRlcm0gPSBzdWJzdF9BcHBseShTdWJzdDEsdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsaykpKTsKICAgICAgTGl0VGVybSA9IHN1YnN0X0FwcGx5KFN1YnN0MiwgTGl0VGVybSk7CiAgICAgIENvbXBhcmUgPSBvcmRfTGl0ZXJhbENvbXBhcmUoTWF4LAoJCQkJICAgY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpKSwKCQkJCSAgIExpdFRlcm0sCgkJCQkgICBjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaykpLAoJCQkJICAgVFJVRSwgRmxhZ3MsIFByZWNlZGVuY2UpOwogICAgICBpZiAoQ29tcGFyZSA9PSBvcmRfU21hbGxlclRoYW4oKSB8fCAoU3RyaWN0ICYmIENvbXBhcmUgPT0gb3JkX0VxdWFsKCkpKSB7Cgl0ZXJtX0RlbGV0ZShNYXgpOwoJdGVybV9EZWxldGUoTGl0VGVybSk7CglyZXR1cm4gRkFMU0U7CiAgICAgIH0KICAgICAgdGVybV9EZWxldGUoTGl0VGVybSk7CiAgICB9CiAgdGVybV9EZWxldGUoTWF4KTsKCiAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCBpbmZfTGl0ZXJhbHNNYXhXaXRoMlN1YnN0KENMQVVTRSBDbGF1c2UsIGludCBpLCBDTEFVU0UgUGFydG5lckNsYXVzZSwKCQkJCSAgICAgIGludCBqLCBTVUJTVCBTdWJzdDIsIFNVQlNUIFN1YnN0MSwKCQkJCSAgICAgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUaGUgcGFyZW50cyBvZiBhIHJlc29sdXRpb24gaW5mZXJlbmNlLCB0aGUgCiAgICAgICAgICAgcmVzcGVjdGl2ZSBsaXRlcmFsIGluZGljZXMgYW5kIHN1YnN0aXR1dGlvbnMsIGEgCgkgICBmbGFnIHN0b3JlIGFuZCBhIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogSW4gY29udHJhc3QgdG8gdGhlIGZ1bmN0aW9uIGluZl9MaXRlcmFsc01heAogICAgICAgICAgIHRoZSBjb21wb3NpdGlvbiBTdWJzdDIgsCBTdWJzdDEgaXMgYXBwbGllZCB0byBib3RoCgkgICBjbGF1c2VzLgoJICAgVGhlIGZ1bmN0aW9uIHJldHVybnMgVFJVRSBpZmYgdGhlIHBvc2l0aXZlL25lZ2F0aXZlIAoJICAgbGl0ZXJhbHMgYXJlIHN0aWxsIHN0cmljdGx5IG1heGltYWwvbWF4aW1hbCBpbiB0aGUgCgkgICBpbnN0YW50aWF0ZWQgY2xhdXNlLgoJICAgSWYgYSBuZWdhdGl2ZSBsaXRlcmFsIGlzIHNlbGVjdGVkLCBubyBjb21wYXJpc29uCgkgICBpcyBtYWRlLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKI2lmZGVmIENIRUNLCiAgaWYgKChjbGF1c2VfR2V0RmxhZyhDbGF1c2UsIENMQVVTRVNFTEVDVCkgJiYKICAgICAgICFjbGF1c2VfTGl0ZXJhbEdldEZsYWcoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpLExJVFNFTEVDVCkpIHx8CiAgICAgIChjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpICYmCiAgICAgICAhY2xhdXNlX0xpdGVyYWxHZXRGbGFnKGNsYXVzZV9HZXRMaXRlcmFsKFBhcnRuZXJDbGF1c2UsaiksTElUU0VMRUNUKSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0xpdGVyYWxzTWF4V2l0aDJTdWJzdDogQW5vdGhlciBsaXRlcmFsIGlzIHNlbGVjdGVkLiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KI2VuZGlmCgogIGlmICghY2xhdXNlX0dldEZsYWcoQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpICYmCiAgICAgICFpbmZfTGl0TWF4V2l0aDJTdWJzdChDbGF1c2UsIGksIC0xLCBTdWJzdDIsIFN1YnN0MSwKCQkJICAgIGk+Y2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoQ2xhdXNlKSwgRmxhZ3MsIFByZWNlZGVuY2UpKQogICAgcmV0dXJuIEZBTFNFOwogIGlmICghY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSwgQ0xBVVNFU0VMRUNUKSAmJgogICAgICAhaW5mX0xpdE1heFdpdGgyU3Vic3QoUGFydG5lckNsYXVzZSwgaiwgLTEsIFN1YnN0MiwgU3Vic3QxLAoJCSBqPmNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KFBhcnRuZXJDbGF1c2UpLCBGbGFncywgUHJlY2VkZW5jZSkpCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBJbmZlcmVuY2UgcnVsZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkxJU1QgaW5mX0VxdWFsaXR5UmVzb2x1dGlvbihDTEFVU0UgR2l2ZW5DbGF1c2UsIEJPT0wgT3JkZXJlZCwgRkxBR1NUT1JFIEZsYWdzLAoJCQkgICAgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSBhbmQgYSBmbGFnIGRldGVybWluaW5nIHdoZXRoZXIgb3JkZXJpbmcKICAgICAgICAgICBjb25zdHJhaW50cyBhcHBseS4KCSAgIEZvciA8T3JkZXJlZD49VFJVRSB0aGUgZnVuY3Rpb24gbWFrZXMgRXF1YWxpdHkgUmVzb2x1dGlvbgoJICAgaW5mZXJlbmNlcywgZm9yIDxPcmRlcmVkPj1GQUxTRSBSZWZsZXhpdml0eSBSZXNvbHV0aW9uCgkgICBpbmZlcmVuY2VzIGFyZSBtYWRlLgoJICAgQSBmbGFnIHN0b3JlLgoJICAgQSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGluZmVycmVkIGZyb20gdGhlIEdpdmVuQ2xhdXNlIGJ5CiAgICAgICAgICAgRXF1YWxpdHkvUmVmbGV4aXZpdHkgUmVzb2x1dGlvbi4KICBNRU1PUlk6ICBBIGxpc3Qgb2YgY2xhdXNlcyBpcyBwcm9kdWNlZCwgd2hlcmUgbWVtb3J5IGZvciB0aGUgbGlzdAogICAgICAgICAgIGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgICAgUmVzdWx0OwogIExJVEVSQUwgQWN0TGl0OwogIGludCAgICAgaSwgbGFzdDsKCiNpZmRlZiBDSEVDSwogIGlmICghY2xhdXNlX0lzQ2xhdXNlKEdpdmVuQ2xhdXNlLCBGbGFncywgUHJlY2VkZW5jZSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0VxdWFsaXR5UmVzb2x1dGlvbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBpZiAoY2xhdXNlX0hhc0VtcHR5QW50ZWNlZGVudChHaXZlbkNsYXVzZSkgfHwKICAgICAgIWNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KEdpdmVuQ2xhdXNlKSkgewogICAgcmV0dXJuIGxpc3RfTmlsKCk7CiAgfQoKICBSZXN1bHQgICAgICAgICAgPSBsaXN0X05pbCgpOwogIGxhc3QgICAgICAgICAgICA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KEdpdmVuQ2xhdXNlKTsKICAKICBmb3IgKGkgPSBjbGF1c2VfRmlyc3RBbnRlY2VkZW50TGl0SW5kZXgoR2l2ZW5DbGF1c2UpOyBpIDw9IGxhc3Q7IGkrKykgewogICAgQWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoR2l2ZW5DbGF1c2UsIGkpOwogICAgCiAgICBpZiAoY2xhdXNlX0xpdGVyYWxJc0VxdWFsaXR5KEFjdExpdCkgJiYKCShjbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LExJVFNFTEVDVCkgfHwKCSAoIWNsYXVzZV9HZXRGbGFnKEdpdmVuQ2xhdXNlLENMQVVTRVNFTEVDVCkgJiYKCSAgKCFPcmRlcmVkIHx8IGNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKEFjdExpdCkpKSkpIHsKICAgICAgVEVSTSBBdG9tOwogICAgICAKICAgICAgQXRvbSA9IGNsYXVzZV9HZXRMaXRlcmFsQXRvbShHaXZlbkNsYXVzZSwgaSk7CiAgICAgIAogICAgICBjb250X0NoZWNrKCk7CiAgICAgIGlmICh1bmlmeV9VbmlmeUNvbShjb250X0xlZnRDb250ZXh0KCksCgkJCSB0ZXJtX0ZpcnN0QXJndW1lbnQoQXRvbSksIAoJCQkgdGVybV9TZWNvbmRBcmd1bWVudChBdG9tKSkpIHsKCVNVQlNUICBtZ3U7CglDTEFVU0UgTmV3Q2xhdXNlOwoJaW50ICAgIGosIGssIGJvdW5kOwoJCglzdWJzdF9FeHRyYWN0VW5pZmllckNvbShjb250X0xlZnRDb250ZXh0KCksICZtZ3UpOwoJLyogQ2hlY2sgcG9zdGNvbmRpdGlvbiAqLwoJaWYgKGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhBY3RMaXQsTElUU0VMRUNUKSB8fAoJICAgICFPcmRlcmVkIHx8IGluZl9MaXRNYXgoR2l2ZW5DbGF1c2UsIGksIC0xLCBtZ3UsIAoJCQkJICAgRkFMU0UsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJICAKCSAgTmV3Q2xhdXNlID0gY2xhdXNlX0NyZWF0ZUJvZHkoY2xhdXNlX0xlbmd0aChHaXZlbkNsYXVzZSkgLSAxKTsKCSAgY2xhdXNlX1NldE51bU9mQ29uc0xpdHMoTmV3Q2xhdXNlLCBjbGF1c2VfTnVtT2ZDb25zTGl0cyhHaXZlbkNsYXVzZSkpOwoJICBjbGF1c2VfU2V0TnVtT2ZBbnRlTGl0cyhOZXdDbGF1c2UsCgkJCQkgIChjbGF1c2VfTnVtT2ZBbnRlTGl0cyhHaXZlbkNsYXVzZSkgLSAxKSk7CgkgIGNsYXVzZV9TZXROdW1PZlN1Y2NMaXRzKE5ld0NsYXVzZSwgY2xhdXNlX051bU9mU3VjY0xpdHMoR2l2ZW5DbGF1c2UpKTsKCSAgCgkgIGJvdW5kID0gY2xhdXNlX0xhc3RMaXRJbmRleChHaXZlbkNsYXVzZSk7CgkgIC8qIGogaXRlcmF0ZXMgb3ZlciB0aGUgZ2l2ZW4gY2xhdXNlLCBrIGl0ZXJhdGVzIG92ZXIgdGhlIG5ldyBvbmUgKi8KCSAgZm9yIChqID0gayA9IGNsYXVzZV9GaXJzdExpdEluZGV4KCk7IGogPD0gYm91bmQ7IGorKykgewoJICAgIGlmIChqICE9IGkpIHsKCSAgICAgIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgaywgCgkgICAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KG1ndSwKCSAgICAgICAgICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKEdpdmVuQ2xhdXNlLGopKSksTmV3Q2xhdXNlKSk7CgkgICAgICBrKys7CgkgICAgfQoJICB9CgkgIGNsYXVzZV9TZXREYXRhRnJvbUZhdGhlcihOZXdDbGF1c2UsIEdpdmVuQ2xhdXNlLCBpLCBGbGFncywgUHJlY2VkZW5jZSk7CgkgIGNsYXVzZV9TZXRGcm9tRXF1YWxpdHlSZXNvbHV0aW9uKE5ld0NsYXVzZSk7CgkgIAoJICBSZXN1bHQgPSBsaXN0X0NvbnMoTmV3Q2xhdXNlLCBSZXN1bHQpOwoJfQoJc3Vic3RfRGVsZXRlKG1ndSk7CiAgICAgIH0KICAgICAgY29udF9SZXNldCgpOwogICAgfQkvKiBlbmQgb2YgaWYgJ0FjdExpdCBpcyBtYXhpbWFsJy4gKi8KICB9IC8qZW5kIG9mIGZvciAnYWxsIGxpdGVyYWxzJy4gKi8KICByZXR1cm4oUmVzdWx0KTsKfQoKc3RhdGljIENMQVVTRSBpbmZfQXBwbHlFcXVhbGl0eUZhY3RvcmluZyhDTEFVU0UgQ2xhdXNlLCBURVJNIExlZnQsIFRFUk0gUmlnaHQsCgkJCQkJIGludCBpLCBpbnQgaiwgU1VCU1QgU3Vic3QsCgkJCQkJIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSwgdHdvIHRlcm1zLCB0d28gaW5kaWNlcyBpbiB0aGUgY2xhdXNlLAogICAgICAgICAgIGEgc3Vic3RpdHV0aW9uLCBhIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIG5ldyBjbGF1c2UsIHdoZXJlIDxMZWZ0Pj08UmlnaHQ+IGlzIGFkZGVkIGFzIGFudGVjZWRlbnQgYXRvbSwKICAgICAgICAgICB0aGUgPGk+dGggbGl0ZXJhbCBpcyBkZWxldGVkLCB0aGUgPGo+dGgga2VwdCBhbmQKCSAgIDxTdWJzdD4gaXMgYXBwbGllZCB0byBhIGNvcHkgb2YgPGNsYXVzZT4uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIENMQVVTRSBOZXdDbGF1c2U7CiAgVEVSTSAgIEF0b207CiAgaW50ICAgIGssYyxhLHM7CgogIE5ld0NsYXVzZSA9IGNsYXVzZV9DcmVhdGVCb2R5KGNsYXVzZV9MZW5ndGgoQ2xhdXNlKSk7CgogIGMgPSBjbGF1c2VfTGFzdENvbnN0cmFpbnRMaXRJbmRleChDbGF1c2UpOwogIGNsYXVzZV9TZXROdW1PZkNvbnNMaXRzKE5ld0NsYXVzZSwgY2xhdXNlX051bU9mQ29uc0xpdHMoQ2xhdXNlKSk7CiAgYSA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KENsYXVzZSk7CiAgY2xhdXNlX1NldE51bU9mQW50ZUxpdHMoTmV3Q2xhdXNlLCBjbGF1c2VfTnVtT2ZBbnRlTGl0cyhDbGF1c2UpICsgMSk7CiAgcyA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQ2xhdXNlKTsKICBjbGF1c2VfU2V0TnVtT2ZTdWNjTGl0cyhOZXdDbGF1c2UsIGNsYXVzZV9OdW1PZlN1Y2NMaXRzKENsYXVzZSkgLSAxKTsKCiAgZm9yIChrID0gY2xhdXNlX0ZpcnN0TGl0SW5kZXgoKTsgayA8PSBjOyBrKyspIHsKICAgIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgaywgCiAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFN1YnN0LAoJdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsIGspKSksTmV3Q2xhdXNlKSk7CiAgfQoKICBmb3IgKCA7IGsgPD0gYTsgaysrKSB7CiAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIGssIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdCwKICAgICAgICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKENsYXVzZSwgaykpKSxOZXdDbGF1c2UpKTsKICB9CgogIEF0b20gPSB0ZXJtX0NyZWF0ZShmb2xfRXF1YWxpdHkoKSwKCQkgICAgIGxpc3RfQ29ucyh0ZXJtX0NvcHkoTGVmdCksbGlzdF9MaXN0KHRlcm1fQ29weShSaWdodCkpKSk7CgogIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgaywgY2xhdXNlX0xpdGVyYWxDcmVhdGUoCiAgICB0ZXJtX0NyZWF0ZShmb2xfTm90KCksIGxpc3RfTGlzdChzdWJzdF9BcHBseShTdWJzdCxBdG9tKSkpLCBOZXdDbGF1c2UpKTsKCiAgYSA9IDE7IC8qIFNoaWZ0ICovCgogIGZvciAoIDsgayA8PSBzOyBrKyspIHsKICAgIGlmIChrID09IGkpCiAgICAgIGEgPSAwOwogICAgZWxzZSB7CiAgICAgIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgKGsgKyBhKSwKCWNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFN1YnN0LAoJICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKENsYXVzZSwgaykpKSxOZXdDbGF1c2UpKTsKICAgIH0KICB9CgogIGNsYXVzZV9BZGRQYXJlbnRDbGF1c2UoTmV3Q2xhdXNlLCBjbGF1c2VfTnVtYmVyKENsYXVzZSkpOwogIGNsYXVzZV9BZGRQYXJlbnRMaXRlcmFsKE5ld0NsYXVzZSwgaik7CiAgY2xhdXNlX1NldERhdGFGcm9tRmF0aGVyKE5ld0NsYXVzZSwgQ2xhdXNlLCBpLCBGbGFncywgUHJlY2VkZW5jZSk7CgogIGNsYXVzZV9TZXRGcm9tRXF1YWxpdHlGYWN0b3JpbmcoTmV3Q2xhdXNlKTsKCiAgcmV0dXJuIE5ld0NsYXVzZTsKfQoKCnN0YXRpYyBCT09MIGluZl9FcXVhbGl0eUZhY3RvcmluZ0FwcGxpY2FibGUoQ0xBVVNFIENsYXVzZSwgaW50IGksIFRFUk0gTGVmdCwKCQkJCQkgICAgVEVSTSBSaWdodCwgU1VCU1QgU3Vic3QsCgkJCQkJICAgIEZMQUdTVE9SRSBGbGFncywKCQkJCQkgICAgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSA8Q2xhdXNlPiwgdGhlIGluZGV4IDxpPiBvZiBhIG1heGltYWwgCiAgICAgICAgICAgZXF1YWxpdHkgbGl0ZXJhbCBpbiA8Q2xhdXNlPiA8aj4sIDxMZWZ0PiBhbmQgCgkgICA8UmlnaHQ+IGFyZSB0aGUgbGVmdCBhbmQgcmlnaHQgc2lkZSBvZiB0aGUgbGl0ZXJhbCwgCgkgICB3aGVyZSA8UmlnaHQ+IGlzIG5vdCBncmVhdGVyIHRoYW4gPExlZnQ+IHdydCB0aGUgCgkgICBvcmRlcmluZywgYSB1bmlmaWVyIDxTdWJzdD4sIGEgZmxhZyBzdG9yZSBhbmQgYSAKCSAgIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogVFJVRSBpZmYgdGhlIGxpdGVyYWwgYXQgaW5kZXggPGk+IGlzIHN0cmljdGx5IAogICAgICAgICAgIG1heGltYWwgaW4gdGhlIGluc3RhbnRpYXRlZCBjbGF1c2UgYW5kIDxSaWdodD4gaXMgCgkgICBub3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDxMZWZ0PiBhZnRlciAKCSAgIGFwcGxpY2F0aW9uIG9mIHRoZSBzdWJzdGl0dXRpb24uCgkgICBPdGhlcndpc2UsIHRoZSBmdW5jdGlvbiByZXR1cm5zIEZBTFNFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBvcmRfUkVTVUxUIEhlbHA7CgogIC8qIExpdGVyYWwgb3JpZW50ZWQ/ICovCiAgaWYgKCFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGkpKSkgewogICAgVEVSTSBOTGVmdCwgTlJpZ2h0OwogICAgTkxlZnQgID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShMZWZ0KSk7CiAgICBOUmlnaHQgPSBzdWJzdF9BcHBseShTdWJzdCwgdGVybV9Db3B5KFJpZ2h0KSk7CiAgICBpZiAoKEhlbHAgPSBvcmRfQ29tcGFyZShOTGVmdCxOUmlnaHQsRmxhZ3MsIFByZWNlZGVuY2UpKSA9PSBvcmRfU21hbGxlclRoYW4oKSB8fAoJSGVscCA9PSBvcmRfRXF1YWwoKSkgewogICAgICB0ZXJtX0RlbGV0ZShOTGVmdCk7CiAgICAgIHRlcm1fRGVsZXRlKE5SaWdodCk7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHRlcm1fRGVsZXRlKE5MZWZ0KTsKICAgIHRlcm1fRGVsZXRlKE5SaWdodCk7CiAgfQogIC8qIExpdGVyYWwgbWF4aW1hbD8gKi8KICByZXR1cm4gaW5mX0xpdE1heChDbGF1c2UsIGksIC0xLCBTdWJzdCwgRkFMU0UsIEZsYWdzLCBQcmVjZWRlbmNlKTsKfQoKCkxJU1QgaW5mX0VxdWFsaXR5RmFjdG9yaW5nKENMQVVTRSBHaXZlbkNsYXVzZSwgRkxBR1NUT1JFIEZsYWdzLAoJCQkgICBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlLCBhIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIGxpc3Qgb2YgY2xhdXNlcyBkZXJpdmFibGUgZnJvbSAnR2l2ZW5DbGF1c2UnIGJ5IEVGLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgIFJlc3VsdDsKICBMSVRFUkFMIEFjdExpdDsKICBpbnQgICAgIGksIGosIGxhc3Q7CiAgU1VCU1QgICBtZ3U7CgojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9FcXVhbGl0eUZhY3RvcmluZzogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBpZiAoY2xhdXNlX0hhc0VtcHR5U3VjY2VkZW50KEdpdmVuQ2xhdXNlKSB8fAogICAgICBjbGF1c2VfR2V0RmxhZyhHaXZlbkNsYXVzZSwgQ0xBVVNFU0VMRUNUKSB8fAogICAgICAhY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoR2l2ZW5DbGF1c2UpKSB7CiAgICByZXR1cm4gbGlzdF9OaWwoKTsKICB9CgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CiAgCiAgbGFzdCA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoR2l2ZW5DbGF1c2UpOwogIAogIGZvciAoaSA9IGNsYXVzZV9GaXJzdFN1Y2NlZGVudExpdEluZGV4KEdpdmVuQ2xhdXNlKTsgaSA8PSBsYXN0OyBpKyspIHsKICAgIAogICAgQWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoR2l2ZW5DbGF1c2UsIGkpOwogICAgCiAgICBpZiAoY2xhdXNlX0xpdGVyYWxJc01heGltYWwoQWN0TGl0KSAmJgoJY2xhdXNlX0xpdGVyYWxJc0VxdWFsaXR5KEFjdExpdCkpIHsKICAgICAgVEVSTSAgICBBdG9tLCBMZWZ0LCBSaWdodDsKICAgICAgTElURVJBTCBQYXJ0bmVyTGl0OwogICAgICAKICAgICAgQXRvbSAgPSBjbGF1c2VfTGl0ZXJhbEF0b20oQWN0TGl0KTsKICAgICAgTGVmdCAgPSB0ZXJtX0ZpcnN0QXJndW1lbnQoQXRvbSk7CiAgICAgIFJpZ2h0ID0gdGVybV9TZWNvbmRBcmd1bWVudChBdG9tKTsKICAgICAgCiAgICAgIGZvciAoaiA9IGNsYXVzZV9GaXJzdFN1Y2NlZGVudExpdEluZGV4KEdpdmVuQ2xhdXNlKTsgaiA8PSBsYXN0OyBqKyspIHsKCVBhcnRuZXJMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChHaXZlbkNsYXVzZSwgaik7CglpZiAoaSAhPSBqICYmIGNsYXVzZV9MaXRlcmFsSXNFcXVhbGl0eShQYXJ0bmVyTGl0KSkgewoJICAvKiBpPT1qIGNhbiBiZSBleGNsdWRlZCBzaW5jZSB0aGlzIGluZmVyZW5jZSB3b3VsZCBlaXRoZXIgZ2VuZXJhdGUgKi8KCSAgLyogYSBjb3B5IG9mIHRoZSBnaXZlbiBjbGF1c2UgKGlmIG9uZSBzaWRlIG9mIHRoZSBlcXVhbGl0eSBpcyAgICAgICovCgkgIC8qIHVuaWZpZWQgd2l0aCBpdHNlbGYpLCBvciBnZW5lcmF0ZSBhIHRhdXRvbG9neSAoaWYgZGlmZmVyZW50ICAgICAqLwoJICAvKiBzaWRlcyBvZiB0aGUgZXF1YWxpdHkgYXJlIHVuaWZpZWQpLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSAgVEVSTSBQYXJ0bmVyQXRvbSwgUGFydG5lckxlZnQsIFBhcnRuZXJSaWdodDsKCSAgCgkgIFBhcnRuZXJBdG9tICA9IGNsYXVzZV9MaXRlcmFsQXRvbShQYXJ0bmVyTGl0KTsKCSAgUGFydG5lckxlZnQgID0gdGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJBdG9tKTsKCSAgUGFydG5lclJpZ2h0ID0gdGVybV9TZWNvbmRBcmd1bWVudChQYXJ0bmVyQXRvbSk7CgoJICAvKiB0cnkgPExlZnQ+IGFuZCA8UGFydG5lckxlZnQ+ICovCgkgIGNvbnRfQ2hlY2soKTsKCSAgaWYgKHVuaWZ5X1VuaWZ5Q29tKGNvbnRfTGVmdENvbnRleHQoKSwgTGVmdCwgUGFydG5lckxlZnQpKSB7CgkgICAgc3Vic3RfRXh0cmFjdFVuaWZpZXJDb20oY29udF9MZWZ0Q29udGV4dCgpLCAmbWd1KTsKCSAgICBpZiAoaW5mX0VxdWFsaXR5RmFjdG9yaW5nQXBwbGljYWJsZShHaXZlbkNsYXVzZSwgaSwgTGVmdCwgUmlnaHQsCgkJCQkJCW1ndSwgRmxhZ3MsIFByZWNlZGVuY2UpKQoJICAgICAgUmVzdWx0ID0gbGlzdF9Db25zKGluZl9BcHBseUVxdWFsaXR5RmFjdG9yaW5nKEdpdmVuQ2xhdXNlLFJpZ2h0LAoJCQkJCQkJICAgIFBhcnRuZXJSaWdodCxpLGosCgkJCQkJCQkgICAgbWd1LEZsYWdzLCAKCQkJCQkJCSAgICBQcmVjZWRlbmNlKSwKCQkJCSBSZXN1bHQpOwoJICAgIHN1YnN0X0RlbGV0ZShtZ3UpOwoJICB9CgkgIGNvbnRfUmVzZXQoKTsKCgkgIC8qIHRyeSA8TGVmdD4gYW5kIDxQYXJ0bmVyUmlnaHQ+ICovCgkgIGNvbnRfQ2hlY2soKTsKCSAgaWYgKHVuaWZ5X1VuaWZ5Q29tKGNvbnRfTGVmdENvbnRleHQoKSwgTGVmdCwgUGFydG5lclJpZ2h0KSkgewoJICAgIHN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJm1ndSk7CgkgICAgCgkgICAgaWYgKGluZl9FcXVhbGl0eUZhY3RvcmluZ0FwcGxpY2FibGUoR2l2ZW5DbGF1c2UsIGksIExlZnQsIFJpZ2h0LAoJCQkJCQltZ3UsIEZsYWdzLCBQcmVjZWRlbmNlKSkKCSAgICAgIFJlc3VsdCA9IGxpc3RfQ29ucyhpbmZfQXBwbHlFcXVhbGl0eUZhY3RvcmluZyhHaXZlbkNsYXVzZSxSaWdodCwKCQkJCQkJCSAgICBQYXJ0bmVyTGVmdCxpLGosCgkJCQkJCQkgICAgbWd1LEZsYWdzLCAKCQkJCQkJCSAgICBQcmVjZWRlbmNlKSwKCQkJCSBSZXN1bHQpOwoJICAgIHN1YnN0X0RlbGV0ZShtZ3UpOwoJICB9CgkgIGNvbnRfUmVzZXQoKTsKCgkgIGlmICghY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoQWN0TGl0KSkgewoJICAgIC8qIHRyeSA8UmlnaHQ+IGFuZCA8UGFydG5lckxlZnQ+ICovCgkgICAgY29udF9DaGVjaygpOwoJICAgIGlmICh1bmlmeV9VbmlmeUNvbShjb250X0xlZnRDb250ZXh0KCksIFJpZ2h0LCBQYXJ0bmVyTGVmdCkpIHsKCSAgICAgIHN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJm1ndSk7CgkgICAgICAKCSAgICAgIGlmIChpbmZfRXF1YWxpdHlGYWN0b3JpbmdBcHBsaWNhYmxlKEdpdmVuQ2xhdXNlLCBpLCBSaWdodCwgTGVmdCwKCQkJCQkJICBtZ3UsIEZsYWdzLCBQcmVjZWRlbmNlKSkKCQlSZXN1bHQgPSBsaXN0X0NvbnMoaW5mX0FwcGx5RXF1YWxpdHlGYWN0b3JpbmcoR2l2ZW5DbGF1c2UsTGVmdCwKCQkJCQkJCSAgICAgIFBhcnRuZXJSaWdodCxpLGosCgkJCQkJCQkgICAgICBtZ3UsRmxhZ3MsCgkJCQkJCQkgICAgICBQcmVjZWRlbmNlKSwKCQkJCSAgIFJlc3VsdCk7CgkgICAgICBzdWJzdF9EZWxldGUobWd1KTsKCSAgICB9CgkgICAgY29udF9SZXNldCgpOwoJICAgIAoJICAgIC8qIHRyeSA8UmlnaHQ+IGFuZCA8UGFydG5lclJpZ2h0PiAqLwoJICAgIGNvbnRfQ2hlY2soKTsKCSAgICBpZiAodW5pZnlfVW5pZnlDb20oY29udF9MZWZ0Q29udGV4dCgpLCBSaWdodCwgUGFydG5lclJpZ2h0KSkgewoJICAgICAgc3Vic3RfRXh0cmFjdFVuaWZpZXJDb20oY29udF9MZWZ0Q29udGV4dCgpLCAmbWd1KTsKCSAgICAgIAoJICAgICAgaWYgKGluZl9FcXVhbGl0eUZhY3RvcmluZ0FwcGxpY2FibGUoR2l2ZW5DbGF1c2UsIGksIFJpZ2h0LCBMZWZ0LAoJCQkJCQkgIG1ndSwgRmxhZ3MsIFByZWNlZGVuY2UpKQoJCVJlc3VsdCA9IGxpc3RfQ29ucyhpbmZfQXBwbHlFcXVhbGl0eUZhY3RvcmluZyhHaXZlbkNsYXVzZSxMZWZ0LAoJCQkJCQkJICAgICAgUGFydG5lckxlZnQsaSxqLAoJCQkJCQkJICAgICAgbWd1LEZsYWdzLAoJCQkJCQkJICAgICAgUHJlY2VkZW5jZSksCgkJCQkgICBSZXN1bHQpOwoJICAgICAgc3Vic3RfRGVsZXRlKG1ndSk7CgkgICAgfQoJICAgIGNvbnRfUmVzZXQoKTsKCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBSZXN1bHQ7Cn0KCgovKiBTVEFSVCBvZiBibG9jayB3aXRoIG5ldyB0ZXJtIHJlcGxhY2VtZW50ICovCgpzdGF0aWMgQk9PTCBpbmZfTkFsbFRlcm1zUnBsYWMoVEVSTSBUZXJtLCBURVJNIFRlc3RUZXJtLCBURVJNIFJwbGFjVGVybSwKCQkJICAgICAgIFNVQlNUIFN1YnN0KQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUaHJlZSB0ZXJtcywgYSBzdWJzdGl0dXRpb24gYW5kIGFuIGludGVnZXIuCiAgICAgICAgICAgQWxsIG9jY3VycmVuY2VzIG9mIDxUZXN0VGVybT4gaW4gPFRlcm0+IGFyZSByZXBsYWNlZAogICAgICAgICAgIGJ5IDxScGxhY1Rlcm0+LiBUaGUgc3Vic3RpdHV0aW9uIDxTdWJzdD4gaXMgYXBwbGllZCB0byA8VGVybT4uCiAgUkVUVVJOUzogVFJVRSwgaWYgVGVzdFRlcm0gd2FzIHJlcGxhY2VkIGJ5IFJwbGFjVGVybSwKICAgICAgICAgICBGQUxTRSBvdGhlcndpc2UuCiAgRUZGRUNUOiAgPFRlcm0+IGlzIGRlc3RydWN0aXZlbHkgY2hhbmdlZCEKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgTElTVCBBcmdMaXN0Tm9kZTsKICBCT09MIFJlcGxhY2VkOwogIGludCAgQm90dG9tOwoKICBSZXBsYWNlZCA9IEZBTFNFOwoKICAvKiBjaGVjayBpZiB3aG9sZSB0ZXJtIG11c3QgYmUgcmVwbGFjZWQgKi8KICBpZiAodGVybV9FcXVhbChUZXJtLCBUZXN0VGVybSkpIHsKICAgIHRlcm1fUnBsYWNUb3AoVGVybSx0ZXJtX1RvcFN5bWJvbChScGxhY1Rlcm0pKTsKICAgIEFyZ0xpc3ROb2RlID0gdGVybV9Bcmd1bWVudExpc3QoVGVybSk7CiAgICB0ZXJtX1JwbGFjQXJndW1lbnRMaXN0KFRlcm0sIHRlcm1fQ29weVRlcm1MaXN0KHRlcm1fQXJndW1lbnRMaXN0KFJwbGFjVGVybSkpKTsKICAgIHRlcm1fRGVsZXRlVGVybUxpc3QoQXJnTGlzdE5vZGUpOwogICAgcmV0dXJuIFRSVUU7CiAgfQoKICBpZiAodGVybV9Jc1ZhcmlhYmxlKFRlcm0pKQogICAgc3Vic3RfQXBwbHkoU3Vic3QsIFRlcm0pOwoKICAvKiBpZiBub3QsIHNjYW4gd2hvbGUgdGVybS4gICovCiAgaWYgKCFsaXN0X0VtcHR5KHRlcm1fQXJndW1lbnRMaXN0KFRlcm0pKSkgewoKICAgIEJvdHRvbSA9IHN0YWNrX0JvdHRvbSgpOwogICAgc3RhY2tfUHVzaCh0ZXJtX0FyZ3VtZW50TGlzdChUZXJtKSk7CgogICAgd2hpbGUgKCFzdGFja19FbXB0eShCb3R0b20pKSB7CiAgICAgIEFyZ0xpc3ROb2RlID0gc3RhY2tfVG9wKCk7CiAgICAgIFRlcm0gICAgICAgID0gKFRFUk0pbGlzdF9DYXIoQXJnTGlzdE5vZGUpOwogICAgICBzdGFja19ScGxhY1RvcChsaXN0X0NkcihBcmdMaXN0Tm9kZSkpOwoKICAgICAgaWYgKHRlcm1fRXF1YWwoVGVybSwgVGVzdFRlcm0pKSB7CglSZXBsYWNlZCA9IFRSVUU7CglsaXN0X1JwbGFjYShBcmdMaXN0Tm9kZSwgdGVybV9Db3B5KFJwbGFjVGVybSkpOwoJdGVybV9EZWxldGUoVGVybSk7CiAgICAgIH0gICAgICAKICAgICAgZWxzZSB7CglpZiAodGVybV9Jc0NvbXBsZXgoVGVybSkpCgkgIHN0YWNrX1B1c2godGVybV9Bcmd1bWVudExpc3QoVGVybSkpOwoJZWxzZSBpZiAodGVybV9Jc1ZhcmlhYmxlKFRlcm0pKQoJICBzdWJzdF9BcHBseShTdWJzdCxUZXJtKTsKICAgICAgfQoKICAgICAgLyogcmVtb3ZlIGVtcHR5IGxpc3RzIChjb3JyZXNwb25kaW5nIHRvIHNjYW5uZWQgdGVybXMpICovCiAgICAgIHdoaWxlICghc3RhY2tfRW1wdHkoQm90dG9tKSAmJiBsaXN0X0VtcHR5KHN0YWNrX1RvcCgpKSkKCXN0YWNrX1BvcCgpOwogICAgfQogIH0KICByZXR1cm4gUmVwbGFjZWQ7Cn0KCgpzdGF0aWMgVEVSTSBpbmZfQWxsVGVybXNScGxhYyhURVJNIFRlcm0sIFRFUk0gVGVzdFRlcm0sIFRFUk0gUnBsYWNUZXJtLAoJCQkgICAgICBTVUJTVCBTdWJzdCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgVGhyZWUgdGVybXMsIGEgc3Vic3RpdHV0aW9uLgogICAgICAgICAgIEFsbCBvY2N1cnJlbmNlcyBvZiA8VGVzdFRlcm0+IGluIEEgQ09QWSBvZiA8VGVybT4gYXJlIHJlcGxhY2VkCiAgICAgICAgICAgYnkgPFJwbGFjVGVybT4uIFRoZSBzdWJzdGl0dXRpb24gPFN1YnN0PiBpcyBhcHBsaWVkIHRvIAoJICAgdGhlIGNvcHkgb2YgPFRlcm0+LiBJZiBubyBvY2N1cnJlbmNlIGlzIGZvdW5kLAoJICAgTlVMTCBpcyByZXR1cm5lZC4KCSAgIFRoaXMgZnVuY3Rpb24gaXMgbm90IGRlc3RydWN0aXZlCgkgICBsaWtlIE5BbGxUZXJtUnBsYWMuCiAgUkVUVVJOUzogVFJVRSwgaWYgVGVzdFRlcm0gd2FzIHJlcGxhY2VkIGJ5IFJwbGFjVGVybSwKICAgICAgICAgICBGQUxTRSBvdGhlcndpc2UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KeyAKICBURVJNIEFjdFRlcm0gPSB0ZXJtX0NvcHkoVGVybSk7CiAgCiAgaWYgKCFpbmZfTkFsbFRlcm1zUnBsYWMoQWN0VGVybSxUZXN0VGVybSwgUnBsYWNUZXJtLCBTdWJzdCApKSB7CiAgICB0ZXJtX0RlbGV0ZShBY3RUZXJtKTsKICAgIEFjdFRlcm0gPSBOVUxMOwogIH0KIAogIHJldHVybihBY3RUZXJtKTsKfQoKc3RhdGljIFRFUk0gaW5mX0FsbFRlcm1zU2lkZVJwbGFjcyhURVJNIFRlcm0sIFRFUk0gVGVzdFRlcm0sIFRFUk0gUnBsYWNUZXJtLAoJCQkJICAgU1VCU1QgU3Vic3QsIEJPT0wgUmlnaHQpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIFRocmVlIHRlcm1zLCBhIHN1YnN0aXR1dGlvbiBhbmQgYSBib29sZWFuIGZsYWcuIAogICAgICAgICAgIDxUZXJtPiBpcyB0eXBpY2FsbHkgYW4gZXF1YWxpdHkgdGVybS4KICBSRVRVUk5TOiBJZiA8VGVzdFRlcm0+IG9jY3VycyBpbiB0aGUgcmlnaHQgKFJpZ2h0PVRSVUUpIG9yCiAgICAgICAgICAgbGVmdCBzaWRlIChSaWdodD1GQUxTRSkgb2YgPFRlcm0+OgoKICAgICAgICAgICBBIGNvcHkgb2YgdGhlIHRlcm0gd2hlcmUgYWxsIG9jY3VycmVuY2VzIG9mIDxUZXN0VGVybT4KCSAgIGluIHRoZSBFTlRJUkUgPFRlcm0+IGFyZSByZXBsYWNlZCBieSA8UnBsYWNUZXJtPiBhbmQKCSAgIHRoZSBzdWJzdGl0dXRpb24gPFN1YnN0PiBpcyBhcHBsaWVkIHRvIGFsbCBvdGhlciBzdWJ0ZXJtcy4KCgkgICBJZiA8VGVzdFRlcm0+IGRvZXMgbm90IG9jY3VyIGluIHRoZSByaWdodC9sZWZ0IHNpZGUgb2YKCSAgIDxUZXJtPiwgTlVMTCBpcyByZXR1cm5lZC4KCgkgICBJbiBub24tZXF1YWxpdHkgdGVybXMsIFRoZSAnc2lkZXMnIGNvcnJlc3BvbmQgdG8gdGhlIAoJICAgZmlyc3QgYW5kIHNlY29uZCBhcmd1bWVudCBvZiB0aGUgdGVybS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgVEVSTSAgIEFjdFRlcm0gPSB0ZXJtX0NvcHkoVGVybSk7IAogIFRFUk0gICBSZXBsU2lkZSwgT3RoZXJTaWRlOyAvKiBSZXBsU2lkZSBpcyB0aGUgc2lkZSBpbiB3aGljaCB0ZXJtcyBhcmUKCQkJCSByZXBsYWNlZCAqLwoKICBpZiAoUmlnaHQpIHsgCiAgICBSZXBsU2lkZSAgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KEFjdFRlcm0pOwogICAgT3RoZXJTaWRlID0gdGVybV9GaXJzdEFyZ3VtZW50KEFjdFRlcm0pOwogIH0KICBlbHNlIHsgCiAgICBSZXBsU2lkZSAgPSB0ZXJtX0ZpcnN0QXJndW1lbnQoQWN0VGVybSk7CiAgICBPdGhlclNpZGUgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KEFjdFRlcm0pOwogIH0KCiAgaWYgKGluZl9OQWxsVGVybXNScGxhYyhSZXBsU2lkZSwgVGVzdFRlcm0sIFJwbGFjVGVybSwgU3Vic3QpKQogICAgLyogSWYgPFRlc3RUZXJtPiBvY2N1cnMgaW4gPFJlcGxTaWRlPiBhbHNvIHJlcGxhY2UgaXQgaW4gPE90aGVyU2lkZT4uICovCiAgICBpbmZfTkFsbFRlcm1zUnBsYWMoT3RoZXJTaWRlLCBUZXN0VGVybSwgUnBsYWNUZXJtLCBTdWJzdCk7CiAgZWxzZSB7IAogICAgIHRlcm1fRGVsZXRlKEFjdFRlcm0pOwogICAgIEFjdFRlcm0gPSBOVUxMOwogIH0KCiAgcmV0dXJuIEFjdFRlcm07Cn0KCgpzdGF0aWMgVEVSTSBpbmZfQWxsVGVybXNSaWdodFJwbGFjKFRFUk0gVGVybSwgVEVSTSBUZXN0VGVybSwgVEVSTSBScGxhY1Rlcm0sCgkJCQkgICBTVUJTVCBTdWJzdCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgVGhyZWUgdGVybXMsIGEgc3Vic3RpdHV0aW9uLgogICAgICAgICAgIDxUZXJtPiBpcyB0eXBpY2FsbHkgYW4gZXF1YWxpdHkgdGVybS4KICBSRVRVUk5TOiBTZWUgaW5mX0FsbFRlcm1TaWRlUnBsYWMgd2l0aCBhcmd1bWVudAogICAgICAgICAgICdSaWdodCcgc2V0IHRvIFRSVUUKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICByZXR1cm4oaW5mX0FsbFRlcm1zU2lkZVJwbGFjcyhUZXJtLCBUZXN0VGVybSwgUnBsYWNUZXJtLCBTdWJzdCwgVFJVRSkpOwp9CgoKc3RhdGljIFRFUk0gaW5mX0FsbFRlcm1zTGVmdFJwbGFjKFRFUk0gVGVybSwgVEVSTSBUZXN0VGVybSwgVEVSTSBScGxhY1Rlcm0sCgkJCQkgIFNVQlNUIFN1YnN0KQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUaHJlZSB0ZXJtcywgYSBzdWJzdGl0dXRpb24uCiAgICAgICAgICAgPFRlcm0+IGlzIHR5cGljYWxseSBhbiBlcXVhbGl0eSB0ZXJtLgogIFJFVFVSTlM6IFNlZSBpbmZfQWxsVGVybVNpZGVScGxhYyB3aXRoIGFyZ3VtZW50CiAgICAgICAgICAgJ1JpZ2h0JyBzZXQgdG8gRkFMU0UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIHJldHVybihpbmZfQWxsVGVybXNTaWRlUnBsYWNzKFRlcm0sIFRlc3RUZXJtLCBScGxhY1Rlcm0sIFN1YnN0LCBGQUxTRSkpOwp9CgoKLyogIEVORCBvZiBibG9jayB3aXRoIG5ldyB0ZXJtIHJlcGxhY2VtZW50ICovCgoKc3RhdGljIENMQVVTRSBpbmZfQXBwbHlHZW5TdXBlcnBvc2l0aW9uKENMQVVTRSBDbGF1c2UsIGludCBjaSwgU1VCU1QgU3Vic3QsCgkJCQkJQ0xBVVNFIFBhcnRuZXJDbGF1c2UsIGludCBwY2ksCgkJCQkJU1VCU1QgUGFydG5lclN1YnN0LCBURVJNIFN1cEF0b20sCgkJCQkJQk9PTCBSaWdodCwgQk9PTCBPcmRQYXJhLCBCT09MIE1heFBhcmEsCgkJCQkJRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAKICBJTlBVVDogIFR3byBjbGF1c2VzIHdoZXJlIGEgZ2VuZXJhbGl6ZWQgc3VwZXJwb3NpdGlvbiBpbmZlcmVuY2UgY2FuIGJlCiAgICAgICAgICBhcHBsaWVkIHVzaW5nIHRoZSBwb3NpdGl2ZSBlcXVhbGl0eSBsaXRlcmFsIDxpPiBmcm9tIDxDbGF1c2U+IHdpdGgKICAgICAgICAgIHN1YnN0IDxTdWJzdD4gdXNpbmcgdGhlIGxpdGVyYWwgPGo+IGZyb20gPFBhcnRuZXJDbGF1c2U+IHdpdGggc3Vic3QKICAgICAgICAgIDxQYXJ0bmVyU3Vic3Q+IHdoZXJlIFN1cEF0b20gaXMgYSBkZXJpdmFibGUgYXRvbS4gUmV0dXJucwoJICBOVUxMIGlmIFN1cEF0b20gaXMgTlVMTC4KCgkgICBSaWdodCBpcyBUUlVFIGlmIHRoZSBpbmZlcmVuY2UgaXMgYSBzdXBlcnBvc2l0aW9uIHJpZ2h0IGluZmVyZW5jZQoJICAgUmlnaHQgaXMgRkFMU0UgaWYgdGhlIGluZmVyZW5jZSBpcyBhIHN1cGVycG9zaXRpb24gbGVmdCBpbmZlcmVuY2UsCgoJICAgd2hlcmUgdGhlIGluZmVyZW5jZSBpcyBzZWxlY3RlZCBieSBNYXhQYXJhIGFuZCBPcmRQYXJhOgoJICAgKHNlZSBhbHNvIGluZl9HZW5TdXBlcnBvc2l0aW9uTGVmdCkKCSAgIAoJICAgT3JkUGFyYT1UUlVFLCBNYXhQYXJhPVRSVUUgCgkgICAtPiBTdXBlcnBvc2l0aW9uIChMZWZ0IG9yIFJpZ2h0KQoKCSAgIE9yZFBhcmE9VFJVRSwgTWF4UGFyYT1GQUxTRQoJICAgLT4gb3JkZXJlZCBQYXJhbW9kdWxhdGlvbgoKCSAgIE9yZFBhcmE9RkFMU0UsIE1heFBhcmE9RkFMU0UKCSAgIC0+IHNpbXBsZSBQYXJhbW9kdWxhdGlvbgoKCSAgIE9yZFBhcmE9RkFMU0UsIE1heFBhcmE9VFJVRQoJICAgLT4gbm90IGRlZmluZWQKCgkgICBBIGZsYWcgc3RvcmUuCgkgICBBIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogVGhlIG5ldyBjbGF1c2UuCiAgTUVNT1JZOiAgTWVtb3J5IGZvciB0aGUgbmV3IGNsYXVzZSBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIENMQVVTRSBOZXdDbGF1c2U7CiAgaW50ICAgIGosbGMsbGEsbHMscGxzLHBsYSxwbGMsaGVscDsKCiNpZmRlZiBDSEVDSwogIGlmICghT3JkUGFyYSAmJiBNYXhQYXJhKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9BcHBseUdlblN1cGVycG9zaXRpb24gOiBJbGxlZ2FsIGluZmVyZW5jZSIpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gcnVsZSBzZWxlY3Rpb24sIE9yZFBhcmE9RkFMU0UgYW5kIE1heFBhcmE9VFJVRS4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiAgaWYgKFN1cEF0b20gPT0gTlVMTCkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfQXBwbHlHZW5TdXBlcnBvc2l0aW9uOiBBdG9tIGlzIE5VTEwuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgICByZXR1cm4gY2xhdXNlX051bGwoKTsKICB9CiNlbmRpZgoKICBwbHMgPSBjbGF1c2VfTGFzdFN1Y2NlZGVudExpdEluZGV4KFBhcnRuZXJDbGF1c2UpOwogIHBsYSA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KFBhcnRuZXJDbGF1c2UpOwogIHBsYyA9IGNsYXVzZV9MYXN0Q29uc3RyYWludExpdEluZGV4KFBhcnRuZXJDbGF1c2UpOwoKICBscyAgPSBjbGF1c2VfTGFzdFN1Y2NlZGVudExpdEluZGV4KENsYXVzZSk7CiAgbGEgID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoQ2xhdXNlKTsKICBsYyAgPSBjbGF1c2VfTGFzdENvbnN0cmFpbnRMaXRJbmRleChDbGF1c2UpOwoKCiAgTmV3Q2xhdXNlID0gY2xhdXNlX0NyZWF0ZUJvZHkoY2xhdXNlX0xlbmd0aChDbGF1c2UpIC0gMSArCgkJCQljbGF1c2VfTGVuZ3RoKFBhcnRuZXJDbGF1c2UpKTsKCiAgY2xhdXNlX1NldE51bU9mQ29uc0xpdHMoTmV3Q2xhdXNlLCAoY2xhdXNlX051bU9mQ29uc0xpdHMoQ2xhdXNlKSArCgkJCQkgICAgICBjbGF1c2VfTnVtT2ZDb25zTGl0cyhQYXJ0bmVyQ2xhdXNlKSkpOwogIGNsYXVzZV9TZXROdW1PZkFudGVMaXRzKE5ld0NsYXVzZSwgKGNsYXVzZV9OdW1PZkFudGVMaXRzKENsYXVzZSkgKwoJCQkJICAgICAgY2xhdXNlX051bU9mQW50ZUxpdHMoUGFydG5lckNsYXVzZSkpKTsKICBjbGF1c2VfU2V0TnVtT2ZTdWNjTGl0cyhOZXdDbGF1c2UsICgoY2xhdXNlX051bU9mU3VjY0xpdHMoQ2xhdXNlKSAtMSkrCgkJCQkgICAgICBjbGF1c2VfTnVtT2ZTdWNjTGl0cyhQYXJ0bmVyQ2xhdXNlKSkpOwoKICAvKiBGaXJzdCBzZXQgdGhlIGxpdGVyYWxzIGZyb20gdGhlIENsYXVzZSA6ICovCiAgICAKICBmb3IgKGogPSBjbGF1c2VfRmlyc3RMaXRJbmRleCgpOyBqIDw9IGxjOyBqKyspIHsKICAgIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgaiwgCiAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFN1YnN0LCB0ZXJtX0NvcHkoCiAgICAgICAJY2xhdXNlX0dldExpdGVyYWxUZXJtKENsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKICB9CgogIC8qIGhlbHAgPSBudW1iZXIgb2YgbGl0ZXJhbHMgdG8gbGVhdmUgZW1wdHkgKi8KICBoZWxwID0gY2xhdXNlX051bU9mQ29uc0xpdHMoUGFydG5lckNsYXVzZSk7CgogIGZvciAoIDsgaiA8PSBsYTsgaisrKSB7CiAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdCwgdGVybV9Db3B5KAogICAgCWNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsIGopKSksTmV3Q2xhdXNlKSk7CiAgfQoKICAvKiBoZWxwID0gbnVtYmVyIG9mIGxpdGVyYWxzIHRvIGxlYXZlIGVtcHR5ICovCiAgaGVscCArPSBjbGF1c2VfTnVtT2ZBbnRlTGl0cyhQYXJ0bmVyQ2xhdXNlKTsKCiAgZm9yICggOyBqIDw9IGxzOyBqKyspIHsKICAgIGlmIChqICE9IGNpKSB7CiAgICAgIC8qIFRoZSBsaXRlcmFsIHVzZWQgaW4gdGhlIGluZmVyZW5jZSBpc24ndCBjb3BpZWQgKi8KICAgICAgY2xhdXNlX1NldExpdGVyYWwoTmV3Q2xhdXNlLCAoaiArIGhlbHApLCAKICAgICAgIAljbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdCwKCSAgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDbGF1c2UsIGopKSksTmV3Q2xhdXNlKSk7CgogICAgfSBlbHNlIHsKICAgICAgLyp0aGUgaW5kZXggaGFzIHRvIGJlIGRlY3JlYXNlZCB0byBhdm9pZCBhbiBlbXB0eSBsaXRlcmFsISAqLwogICAgICBoZWxwLS07CiAgICB9CiAgfQoKICAvKiBOb3cgd2UgY29uc2lkZXIgdGhlIFBhcnRuZXJDbGF1c2UgOiAqLwoKICAvKiBoZWxwID0gbnVtYmVyIG9mIGFscmVhZHkgc2V0IGNvbnN0cmFpbnQgKENsYXVzZSkgbGl0ZXJhbHMgKi8KICBoZWxwID0gY2xhdXNlX051bU9mQ29uc0xpdHMoQ2xhdXNlKTsKCiAgZm9yIChqID0gY2xhdXNlX0ZpcnN0TGl0SW5kZXgoKTsgaiA8PSBwbGM7IGorKykgewogICAgY2xhdXNlX1NldExpdGVyYWwoTmV3Q2xhdXNlLCAoaiArIGhlbHApLCAKICAgICAgY2xhdXNlX0xpdGVyYWxDcmVhdGUoc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAogICAgICAgIHRlcm1fQ29weShjbGF1c2VfR2V0TGl0ZXJhbFRlcm0oUGFydG5lckNsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKICB9CgogIC8qIGhlbHAgPSBudW1iZXIgb2YgYWxyZWFkeSBzZXQgY29uc3RyYWludCBhbmQgYW50ZWNlZGVudCBHaXZlbi1saXRlcmFscyAqLwogIGhlbHAgKz0gY2xhdXNlX051bU9mQW50ZUxpdHMoQ2xhdXNlKTsKCiAgZm9yICggOyBqIDw9IHBsYTsgaisrKSB7CiAgICBpZiAoaiAhPSBwY2kpIHsKICAgICAgY2xhdXNlX1NldExpdGVyYWwoTmV3Q2xhdXNlLCAoaiArIGhlbHApLCAKCWNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCSAgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShQYXJ0bmVyQ2xhdXNlLCBqKSkpLE5ld0NsYXVzZSkpOwogICAgfSBlbHNlIHsKICAgICAgLyogVGhlIFBhcnRuZXJMaXQgaXMgbW9kaWZpZWQgYXBwcm9wcmlhdGVseSEgICAqLwogICAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKAoJdGVybV9DcmVhdGUoZm9sX05vdCgpLGxpc3RfTGlzdChTdXBBdG9tKSksIE5ld0NsYXVzZSkpOwogICAgfQogIH0KCgogIC8qIGhlbHAgPSBudW1iZXIgb2YgYWxyZWFkeSBzZXQgR2l2ZW4tbGl0ZXJhbHMgKi8KICBoZWxwID0gY2xhdXNlX0xlbmd0aChDbGF1c2UpIC0gMTsKCiAgZm9yICggOyBqIDw9IHBsczsgaisrKSB7CiAgICBpZiAoaiAhPSBwY2kpIHsKICAgICAgLyogVGhlIFBhcnRuZXJMaXQgaXNuJ3QgY29waWVkISAqLwogICAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIAoJY2xhdXNlX0xpdGVyYWxDcmVhdGUoc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKFBhcnRuZXJDbGF1c2UsIGopKSksTmV3Q2xhdXNlKSk7CgogICAgfSBlbHNlIHsKICAgICAgLyogVGhlIFBhcnRuZXJMaXQgaXMgbW9kaWZpZWQgYXBwcm9wcmlhdGVseSEgICAqLwogICAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksCgkJCWNsYXVzZV9MaXRlcmFsQ3JlYXRlKFN1cEF0b20sIE5ld0NsYXVzZSkpOwogICAgfQogIH0KICAgIAogIC8qIAogICAqICBTZXQgaW5mZXJlbmNlIHR5cGUuIE5vdGUgdGhhdCwgaW4gdGhlIGNhc2Ugb2YgKG9yZGVyZWQpIHBhcmFtb2R1bGF0aW9uLAogICAqICB3ZSBkbyBub3QgZGlzdGluZ3Vpc2ggd2hpY2ggc2lkZSB3YXMgcGFyYW1vZHVsYXRlZCBpbnRvLCBhcyBjb21wYXJlZAogICAqICB0byB0aGUgY2FzZSBvZiBzdXBlcnBvc2l0aW9uLiAKICAgKi8KCiAgaWYgKE9yZFBhcmEgJiYgTWF4UGFyYSkgewogICAgaWYgKFJpZ2h0KQogICAgICBjbGF1c2VfU2V0RnJvbVN1cGVycG9zaXRpb25SaWdodChOZXdDbGF1c2UpOwogICAgZWxzZQogICAgICBjbGF1c2VfU2V0RnJvbVN1cGVycG9zaXRpb25MZWZ0KE5ld0NsYXVzZSk7CiAgfSAKICBlbHNlIGlmIChPcmRQYXJhICYmICFNYXhQYXJhKQogICAgY2xhdXNlX1NldEZyb21PcmRlcmVkUGFyYW1vZHVsYXRpb24oTmV3Q2xhdXNlKTsKICBlbHNlIAogICAgY2xhdXNlX1NldEZyb21QYXJhbW9kdWxhdGlvbihOZXdDbGF1c2UpOwoKICBjbGF1c2VfU2V0RGF0YUZyb21QYXJlbnRzKE5ld0NsYXVzZSwgUGFydG5lckNsYXVzZSwgcGNpLCBDbGF1c2UsIGNpLCBGbGFncywKCQkJICAgIFByZWNlZGVuY2UpOwoKICByZXR1cm4gTmV3Q2xhdXNlOwp9CgoKLyogU1RBUlQgb2YgYmxvY2sgd2l0aCBuZXcgc3VwZXJwb3NpdGlvbiByaWdodCBydWxlICovCgpzdGF0aWMgTElTVCBpbmZfR2VuTGl0U1BSaWdodChDTEFVU0UgQ2xhdXNlLCBURVJNIExlZnQsIFRFUk0gUmlnaHQsIGludCBpLAoJCQkgICAgICBTSEFSRURfSU5ERVggU2hJbmRleCwgQk9PTCBPcmRQYXJhLCBCT09MIE1heFBhcmEsCgkJCSAgICAgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSAodW5zaGFyZWQpIHdpdGggYSBwb3NpdGl2ZSBlcXVhbGl0eSBsaXRlcmFsCiAgICAgICAgICAgYXQgcG9zaXRpb24gPGk+IHdoZXJlIDxMZWZ0PiBhbmQgPFJpZ2h0PiBhcmUgdGhlIGFyZ3VtZW50cwoJICAgb2YganVzdCB0aGF0IGxpdGVyYWwgYW5kIDxSaWdodD4gaXMgbm90IGdyZWF0ZXIgd3J0LiB0aGUKCSAgIG9yZGVyaW5nIHRoYW4gPExlZnQ+LAoJICAgdHdvIGJvb2xlYW4gZmxhZ3MgZm9yIGNvbnRyb2xsaW5nIGluZmVyZW5jZQogICAgICAgICAgIHByZWNvbmRpdGlvbnMgKHNlZSBpbmZfR2VuU3VwZXJwb3NpdGlvblJpZ2h0KSwKCSAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSB3aXRoIHRoZSBsaXRlcmFscyBvd25pbmcKICAgICAgICAgICBjbGF1c2UgYnkgZ2VuZXJhbCBzdXBlcnBvc2l0aW9uIHJpZ2h0IHdydC4gdGhlIEluZGV4LgoJICAgKHNlZSBpbmZfR2VuU3VwZXJwb3NpdGlvblJpZ2h0IGZvciBzZWxlY3Rpb24gb2YgaW5mZXJlbmNlCgkgICBydWxlIGJ5IE9yZFBhcmEvTWF4UGFyYSkKICBNRU1PUlk6ICBUaGUgbGlzdCBvZiBjbGF1c2VzIGlzIGV4dGVuZGVkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZQogICAgICAgICAgIGxpc3QgYW5kIHRoZSBjbGF1c2VzIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgTElTVCBSZXN1bHQsIFRlcm1zOwoKICBSZXN1bHQgID0gbGlzdF9OaWwoKTsKICBUZXJtcyAgID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksIHNoYXJpbmdfSW5kZXgoU2hJbmRleCksCgkJCSAgY29udF9SaWdodENvbnRleHQoKSwgTGVmdCk7CgogIGZvciAoIDsgIWxpc3RfRW1wdHkoVGVybXMpOyBUZXJtcyA9IGxpc3RfUG9wKFRlcm1zKSkgewogICAgTElTVCBMaXRzOwogICAgVEVSTSBUZXJtOwoKICAgIFRlcm0gPSAoVEVSTSlsaXN0X0ZpcnN0KFRlcm1zKTsKCiAgICBpZiAoIXRlcm1fSXNWYXJpYWJsZShUZXJtKSAmJiAhc3ltYm9sX0lzUHJlZGljYXRlKHRlcm1fVG9wU3ltYm9sKFRlcm0pKSkgewoKICAgICAgTGl0cyA9IHNoYXJpbmdfR2V0RGF0YUxpc3QoVGVybSwgU2hJbmRleCk7CgogICAgICBmb3IgKCA7ICFsaXN0X0VtcHR5KExpdHMpOyBMaXRzID0gbGlzdF9Qb3AoTGl0cykpIHsKCUxJVEVSQUwgUGFydG5lckxpdDsKCVRFUk0gICAgUGFydG5lckF0b207CglDTEFVU0UgIFBhcnRuZXJDbGF1c2U7CglpbnQgICAgIHBsaTsKCglQYXJ0bmVyTGl0ICAgID0gKExJVEVSQUwpbGlzdF9DYXIoTGl0cyk7CglQYXJ0bmVyQXRvbSAgID0gY2xhdXNlX0xpdGVyYWxBdG9tKFBhcnRuZXJMaXQpOwoJcGxpICAgICAgICAgICA9IGNsYXVzZV9MaXRlcmFsR2V0SW5kZXgoUGFydG5lckxpdCk7CglQYXJ0bmVyQ2xhdXNlID0gY2xhdXNlX0xpdGVyYWxPd25pbmdDbGF1c2UoUGFydG5lckxpdCk7CgoJaWYgKCFjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLENMQVVTRVNFTEVDVCkgJiYKCSAgICAoIU1heFBhcmEgfHwgY2xhdXNlX0xpdGVyYWxHZXRGbGFnKFBhcnRuZXJMaXQsU1RSSUNUTUFYSU1BTCkpICYmCgkgICAgIWNsYXVzZV9HZXRGbGFnKFBhcnRuZXJDbGF1c2UsTk9QQVJBSU5UTykgJiYKCSAgICBjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgJiYKCSAgICBjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChQYXJ0bmVyQ2xhdXNlKSkgewoKCSAgU1VCU1QgIFN1YnN0LCBQYXJ0bmVyU3Vic3Q7CgkgIFRFUk0gICBOZXdMZWZ0LE5ld1JpZ2h0OwoJICBTWU1CT0wgUGFydG5lck1heFZhcjsKCSAgVEVSTSAgIFN1cEF0b207CgoJICBTdXBBdG9tID0gKFRFUk0pTlVMTDsKCgkgIFBhcnRuZXJNYXhWYXIgPSBjbGF1c2VfTWF4VmFyKFBhcnRuZXJDbGF1c2UpOwoJICBOZXdMZWZ0ICAgICAgID0gTGVmdDsKCSAgY2xhdXNlX1JlbmFtZVZhcnNCaWdnZXJUaGFuKENsYXVzZSwgUGFydG5lck1heFZhcik7CgkgIGNvbnRfQ2hlY2soKTsKCSAgdW5pZnlfVW5pZnlOb09DKGNvbnRfTGVmdENvbnRleHQoKSwgTGVmdCwgY29udF9SaWdodENvbnRleHQoKSwgVGVybSk7CgkgIHN1YnN0X0V4dHJhY3RVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSwgJlN1YnN0LCBjb250X1JpZ2h0Q29udGV4dCgpLCAmUGFydG5lclN1YnN0KTsKCSAgY29udF9SZXNldCgpOwoJICBpZiAoIU1heFBhcmEgfHwKCSAgICAgIGluZl9MaXRlcmFsc01heChDbGF1c2UsIGksIFN1YnN0LCBQYXJ0bmVyQ2xhdXNlLCBwbGksCgkJCSAgICAgIFBhcnRuZXJTdWJzdCwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CgkgICAgTmV3UmlnaHQgPSBzdWJzdF9BcHBseShTdWJzdCwgdGVybV9Db3B5KFJpZ2h0KSk7CgkgICAgaWYgKE9yZFBhcmEgJiYKCQkhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpKSkKCSAgICAgIE5ld0xlZnQgID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShMZWZ0KSk7CgkgICAgaWYgKCFPcmRQYXJhIHx8CgkJTmV3TGVmdCA9PSBMZWZ0IHx8ICAgICAgIC8qIFRSVUUsIGlmIG9yaWVudGVkICovCgkJb3JkX0NvbXBhcmUoTmV3TGVmdCxOZXdSaWdodCwgRmxhZ3MsIFByZWNlZGVuY2UpICE9IG9yZF9TbWFsbGVyVGhhbigpKSB7CgkgICAgICBpZiAoIU1heFBhcmEgfHwgY2xhdXNlX0xpdGVyYWxJc1ByZWRpY2F0ZShQYXJ0bmVyTGl0KSkgewoJCVN1cEF0b20gPSBpbmZfQWxsVGVybXNScGxhYyhQYXJ0bmVyQXRvbSwgVGVybSwKCQkJCQkgICAgTmV3UmlnaHQsIFBhcnRuZXJTdWJzdCk7CgkgICAgICB9IGVsc2UgewoJCS8qIFN1cGVycG9zaXRpb24gYW5kIDxQYXJ0bmVyTGl0PiBpcyBlcXVhbGl0eSAqLwoJCWlmIChjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShQYXJ0bmVyTGl0KSkKCQkgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNMZWZ0UnBsYWMoUGFydG5lckF0b20sIFRlcm0sCgkJCQkJCSAgTmV3UmlnaHQsIFBhcnRuZXJTdWJzdCk7CgkJZWxzZSB7CgkJICBURVJNIE5ld1BhcnRuZXJMZWZ0LE5ld1BhcnRuZXJSaWdodDsKCQkgIE5ld1BhcnRuZXJMZWZ0ICA9CgkJICAgIHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwgCgkJCQl0ZXJtX0NvcHkodGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJBdG9tKSkpOwoJCSAgTmV3UGFydG5lclJpZ2h0ID0KCQkgICAgc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LCAKCQkJCXRlcm1fQ29weSh0ZXJtX1NlY29uZEFyZ3VtZW50KFBhcnRuZXJBdG9tKSkpOwoJCSAgc3dpdGNoIChvcmRfQ29tcGFyZShOZXdQYXJ0bmVyTGVmdCxOZXdQYXJ0bmVyUmlnaHQsCgkJCQkgICAgICBGbGFncywgUHJlY2VkZW5jZSkpIHsKCQkgIGNhc2Ugb3JkX1NNQUxMRVJfVEhBTjoKCQkgICAgU3VwQXRvbSA9IGluZl9BbGxUZXJtc1JpZ2h0UnBsYWMoUGFydG5lckF0b20sVGVybSwKCQkJCQkJICAgICAgTmV3UmlnaHQsUGFydG5lclN1YnN0KTsKCQkgICAgYnJlYWs7CgkJICBjYXNlIG9yZF9HUkVBVEVSX1RIQU46CgkJICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNMZWZ0UnBsYWMoUGFydG5lckF0b20sVGVybSwKCQkJCQkJICAgICBOZXdSaWdodCxQYXJ0bmVyU3Vic3QpOwoJCSAgICBicmVhazsKCQkgIGRlZmF1bHQ6CgkJICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNScGxhYyhQYXJ0bmVyQXRvbSxUZXJtLAoJCQkJCQkgTmV3UmlnaHQsUGFydG5lclN1YnN0KTsKCQkgIH0KCQkgIHRlcm1fRGVsZXRlKE5ld1BhcnRuZXJMZWZ0KTsKCQkgIHRlcm1fRGVsZXRlKE5ld1BhcnRuZXJSaWdodCk7CgkJfQoJICAgICAgfQoKCSAgICAgIGlmIChTdXBBdG9tICE9IE5VTEwpCgkJUmVzdWx0ID0KCQkgIGxpc3RfQ29ucyhpbmZfQXBwbHlHZW5TdXBlcnBvc2l0aW9uKENsYXVzZSwgaSwgU3Vic3QsCgkJCQkJCSAgICAgIFBhcnRuZXJDbGF1c2UsIHBsaSwKCQkJCQkJICAgICAgUGFydG5lclN1YnN0LCBTdXBBdG9tLAoJCQkJCQkgICAgICBUUlVFLCBPcmRQYXJhLCBNYXhQYXJhLAoJCQkJCQkgICAgICBGbGFncywgUHJlY2VkZW5jZSksIAoJCQkgICAgUmVzdWx0KTsKCSAgICB9CgkgICAgaWYgKE5ld0xlZnQgIT0gTGVmdCkKCSAgICAgIHRlcm1fRGVsZXRlKE5ld0xlZnQpOwoJICAgIHRlcm1fRGVsZXRlKE5ld1JpZ2h0KTsKCSAgfQoJICBzdWJzdF9EZWxldGUoU3Vic3QpOwoJICBzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCX0KICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUmVzdWx0Owp9CgoKc3RhdGljIExJU1QgaW5mX0dlblNQUmlnaHRFcVRvR2l2ZW4oQ0xBVVNFIENsYXVzZSwgaW50IGksIEJPT0wgTGVmdCwKCQkJCSAgICBTSEFSRURfSU5ERVggU2hJbmRleCwgQk9PTCBPcmRQYXJhLAoJCQkJICAgIEJPT0wgTWF4UGFyYSwgQk9PTCBVbml0LCBGTEFHU1RPUkUgRmxhZ3MsCgkJCQkgICAgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBbiB1bnNoYXJlZCBjbGF1c2UsIHRoZSBpbmRleCBvZiBhIHN1Y2NlZGVudCBsaXRlcmFsCiAgICAgICAgICAgdGhhdCBpcyBhbiBlcXVhbGl0eSBsaXRlcmFsIGFuZCBhIGJvb2xlYW4gdmFsdWUgd2hpY2gKCSAgIGFyZ3VtZW50IHRvIHVzZToKCSAgIElmIExlZnQ9PVRSVUUgdGhlbiB0aGUgbGVmdCBhcmd1bWVudCBpcyB1c2VkCgkgICBvdGhlcndpc2UgdGhlIHJpZ2h0IGFyZ3VtZW50LgoJICAgVGhyZWUgYm9vbGVhbiBmbGFncyBmb3IgY29udHJvbGxpbmcgaW5mZXJlbmNlCiAgICAgICAgICAgcHJlY29uZGl0aW9ucyAoc2VlIGluZl9HZW5TdXBlcnBvc2l0aW9uUmlnaHQpLgoJICAgQSBmbGFnIHN0b3JlLgoJICAgQSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIGdlbmVyYWwgc3VwZXJwb3NpdGlvbiByaWdodCBvbiB0aGUKICAgICAgICAgICBHaXZlbkNvcHkgIHdydC4gdGhlIEluZGV4LgogICAgICAgICAgIChzZWUgaW5mX0dlblN1cGVycG9zaXRpb25SaWdodCBmb3Igc2VsZWN0aW9uIG9mIGluZmVyZW5jZQoJICAgcnVsZSBieSBPcmRQYXJhL01heFBhcmEpCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgIFJlc3VsdCwgVGVybUxpc3QsIFBhcmVudHM7CiAgaW50ICAgICBCb3R0b207CiAgTElURVJBTCBMaXQ7CiAgVEVSTSAgICBBdG9tLCBUZXJtLCBQYXJ0bmVyVGVybSwgUGFydG5lckVxOwoKICBSZXN1bHQgPSBsaXN0X05pbCgpOwogIExpdCAgICA9IGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKTsKICBBdG9tICAgPSBjbGF1c2VfTGl0ZXJhbEF0b20oTGl0KTsKCiNpZmRlZiBDSEVDSwogIGlmICghZm9sX0lzRXF1YWxpdHkoQXRvbSkgfHwKICAgICAgKE1heFBhcmEgJiYgY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoTGl0KSAmJiAhTGVmdCkgfHwKICAgICAgKE1heFBhcmEgJiYgIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhMaXQsIFNUUklDVE1BWElNQUwpKSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BSaWdodEVxVG9HaXZlbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBCb3R0b20gPSBzdGFja19Cb3R0b20oKTsKICBpZiAoTGVmdCkgLyogVG9wIExldmVsIGNvbnNpZGVyZWQgaW4gaW5mX0xpdFNQUmlnaHQgKi8gCiAgICBzaGFyaW5nX1B1c2hMaXN0T25TdGFjayh0ZXJtX0FyZ3VtZW50TGlzdCh0ZXJtX0ZpcnN0QXJndW1lbnQoQXRvbSkpKTsKICBlbHNlCiAgICBzaGFyaW5nX1B1c2hMaXN0T25TdGFjayh0ZXJtX0FyZ3VtZW50TGlzdCh0ZXJtX1NlY29uZEFyZ3VtZW50KEF0b20pKSk7CgogIHdoaWxlICghc3RhY2tfRW1wdHkoQm90dG9tKSkgewogICAgVGVybSA9IChURVJNKXN0YWNrX1BvcFJlc3VsdCgpOwogICAgaWYgKCF0ZXJtX0lzVmFyaWFibGUoVGVybSkpIHsKICAgICAgLyogU3VwZXJwb3NpdGlvbiBpbnRvIHZhcmlhYmxlcyBpcyBub3QgbmVjZXNzYXJ5ICovCiAgICAgIFRlcm1MaXN0ID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksIHNoYXJpbmdfSW5kZXgoU2hJbmRleCksCgkJCSAgICAgICBjb250X1JpZ2h0Q29udGV4dCgpLCBUZXJtKTsKICAgICAgZm9yICggOyAhbGlzdF9FbXB0eShUZXJtTGlzdCk7IFRlcm1MaXN0ID0gbGlzdF9Qb3AoVGVybUxpc3QpKSB7CglQYXJ0bmVyVGVybSA9IChURVJNKWxpc3RfQ2FyKFRlcm1MaXN0KTsKCWZvciAoUGFyZW50cyA9IHRlcm1fU3VwZXJ0ZXJtTGlzdChQYXJ0bmVyVGVybSk7CgkgICAgICFsaXN0X0VtcHR5KFBhcmVudHMpOyBQYXJlbnRzID0gbGlzdF9DZHIoUGFyZW50cykpIHsKCSAgUGFydG5lckVxID0gKFRFUk0pbGlzdF9DYXIoUGFyZW50cyk7CgkgIGlmIChmb2xfSXNFcXVhbGl0eShQYXJ0bmVyRXEpKSB7CgkgICAgQ0xBVVNFICBQYXJ0bmVyQ2xhdXNlOwoJICAgIExJVEVSQUwgUGFydG5lckxpdDsKCSAgICBMSVNUICAgIFNjbDsKCSAgICBpbnQgICAgIGo7CgkgICAgZm9yIChTY2wgPSBzaGFyaW5nX05BdG9tRGF0YUxpc3QoUGFydG5lckVxKTsKCQkgIWxpc3RfRW1wdHkoU2NsKTsgU2NsID0gbGlzdF9DZHIoU2NsKSkgewoJICAgICAgUGFydG5lckxpdCAgICA9IChMSVRFUkFMKWxpc3RfQ2FyKFNjbCk7CgkgICAgICBqICAgICAgICAgICAgID0gY2xhdXNlX0xpdGVyYWxHZXRJbmRleChQYXJ0bmVyTGl0KTsKCSAgICAgIFBhcnRuZXJDbGF1c2UgPSBjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShQYXJ0bmVyTGl0KTsKCSAgICAgIGlmICghY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSxDTEFVU0VTRUxFQ1QpICYmCgkJICAoIU1heFBhcmEgfHwKCQkgICBjbGF1c2VfTGl0ZXJhbEdldEZsYWcoUGFydG5lckxpdCxTVFJJQ1RNQVhJTUFMKSkgJiYKCQkgICghT3JkUGFyYSB8fCBQYXJ0bmVyVGVybT09dGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJFcSkgfHwKCQkgICAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkpICYmCgkJICBjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgJiYKCQkgIGNsYXVzZV9OdW1iZXIoUGFydG5lckNsYXVzZSkgIT0gY2xhdXNlX051bWJlcihDbGF1c2UpICYmCgkJICAoIVVuaXQgfHwgY2xhdXNlX0xlbmd0aChQYXJ0bmVyQ2xhdXNlKSA9PSAxKSAmJgoJCSAgY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoUGFydG5lckNsYXVzZSkpIHsKCQkvKiBXZSBleGNsdWRlIHRoZSBzYW1lIGNsYXVzZSBzaW5jZSB0aGF0IGluZmVyZW5jZSB3aWxsIGJlICovCgkJLyogbWFkZSBieSB0aGUgImZvcndhcmQiIGZ1bmN0aW9uIGluZl9HZW5MaXRTUFJpZ2h0LiAgICAgICAqLwoJCVNZTUJPTCBNYXhWYXI7CgkJU1VCU1QgIFN1YnN0LCBQYXJ0bmVyU3Vic3Q7CgoJCU1heFZhciA9IGNsYXVzZV9NYXhWYXIoUGFydG5lckNsYXVzZSk7CgkJY2xhdXNlX1JlbmFtZVZhcnNCaWdnZXJUaGFuKENsYXVzZSwgTWF4VmFyKTsKCQljb250X0NoZWNrKCk7CgkJdW5pZnlfVW5pZnlOb09DKGNvbnRfTGVmdENvbnRleHQoKSwgVGVybSwgY29udF9SaWdodENvbnRleHQoKSwKCQkJCVBhcnRuZXJUZXJtKTsKCQlzdWJzdF9FeHRyYWN0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksICZTdWJzdCwKCQkJCSAgICAgY29udF9SaWdodENvbnRleHQoKSwgJlBhcnRuZXJTdWJzdCk7CgkJY29udF9SZXNldCgpOwoJCWlmICghTWF4UGFyYSB8fAoJCSAgICBpbmZfTGl0ZXJhbHNNYXgoQ2xhdXNlLCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgaiwKCQkJCSAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJCSAgVEVSTSBQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQ7CgkJICBCT09MIENoZWNrLCBQYXJ0bmVyQ2hlY2s7CgkJICBQYXJ0bmVyTGVmdCA9IFBhcnRuZXJSaWdodCA9IE5VTEw7CgkJICBQYXJ0bmVyQ2hlY2sgPSBDaGVjayA9IFRSVUU7CgkJICBpZiAoT3JkUGFyYSAmJgoJCSAgICAgICFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShQYXJ0bmVyTGl0KSkgewoJCSAgICAvKiBDaGVjayBwb3N0IGNvbmRpdGlvbiBmb3IgcGFydG5lciBsaXRlcmFsICovCgkJICAgIGlmIChQYXJ0bmVyVGVybSA9PSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckVxKSkKCQkgICAgICBQYXJ0bmVyUmlnaHQgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KFBhcnRuZXJFcSk7CgkJICAgIGVsc2UKCQkgICAgICBQYXJ0bmVyUmlnaHQgPSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckVxKTsKCQkgICAgUGFydG5lckxlZnQgID0gc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJCQkJCSAgICAgICB0ZXJtX0NvcHkoUGFydG5lclRlcm0pKTsKCQkgICAgUGFydG5lclJpZ2h0ID0gc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJCQkJCSAgICAgICB0ZXJtX0NvcHkoUGFydG5lclJpZ2h0KSk7CgkJICAgIFBhcnRuZXJDaGVjayA9IChvcmRfQ29tcGFyZShQYXJ0bmVyTGVmdCwgUGFydG5lclJpZ2h0LAoJCQkJCQlGbGFncywgUHJlY2VkZW5jZSkKCQkJCSAgICAhPSBvcmRfU21hbGxlclRoYW4oKSk7CgkJICB9CgkJICBpZiAoUGFydG5lckNoZWNrICYmCgkJICAgICAgTWF4UGFyYSAmJiAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoTGl0KSkgewoJCSAgICAvKiBDaGVjayBwb3N0IGNvbmRpdGlvbiBmb3IgbGl0ZXJhbCBpbiBnaXZlbiBjbGF1c2UgKi8KCQkgICAgVEVSTSBOZXdMZWZ0LCBOZXdSaWdodDsKCQkgICAgaWYgKExlZnQpIHsKCQkgICAgICBOZXdMZWZ0ICA9IHRlcm1fRmlyc3RBcmd1bWVudChBdG9tKTsKCQkgICAgICBOZXdSaWdodCA9IHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSk7CgkJICAgIH0gZWxzZSB7CgkJICAgICAgTmV3TGVmdCAgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KEF0b20pOwoJCSAgICAgIE5ld1JpZ2h0ID0gdGVybV9GaXJzdEFyZ3VtZW50KEF0b20pOwoJCSAgICB9CgkJICAgIE5ld0xlZnQgID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShOZXdMZWZ0KSk7CgkJICAgIE5ld1JpZ2h0ID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShOZXdSaWdodCkpOwoJCSAgICBDaGVjayA9IChvcmRfQ29tcGFyZShOZXdMZWZ0LCBOZXdSaWdodCwgRmxhZ3MsIFByZWNlZGVuY2UpCgkJCSAgICAgIT0gb3JkX1NtYWxsZXJUaGFuKCkpOwoJCSAgICB0ZXJtX0RlbGV0ZShOZXdMZWZ0KTsKCQkgICAgdGVybV9EZWxldGUoTmV3UmlnaHQpOwoJCSAgfQoJCSAgaWYgKENoZWNrICYmIFBhcnRuZXJDaGVjaykgewoJCSAgICAvKiBNYWtlIGluZmVyZW5jZSBvbmx5IGlmIGJvdGggdGVzdHMgd2VyZSBzdWNjZXNzZnVsICovCgkJICAgIFRFUk0gU3VwQXRvbTsKCQkgICAgU3VwQXRvbSA9IE5VTEw7CgkJICAgIGlmIChQYXJ0bmVyUmlnaHQgPT0gTlVMTCkgewoJCSAgICAgIGlmIChQYXJ0bmVyVGVybT09dGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJFcSkpCgkJCVBhcnRuZXJSaWdodCA9IHRlcm1fU2Vjb25kQXJndW1lbnQoUGFydG5lckVxKTsKCQkgICAgICBlbHNlCgkJCVBhcnRuZXJSaWdodCA9IHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyRXEpOwoJCSAgICAgIFBhcnRuZXJSaWdodCA9IHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCQkJCQkJIHRlcm1fQ29weShQYXJ0bmVyUmlnaHQpKTsKCQkgICAgfQoJCSAgICBpZiAoTGVmdCkKCQkgICAgICBTdXBBdG9tID0gaW5mX0FsbFRlcm1zTGVmdFJwbGFjKEF0b20sIFRlcm0sCgkJCQkJCSAgICAgIFBhcnRuZXJSaWdodCwgU3Vic3QpOwoJCSAgICBlbHNlIAoJCSAgICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNSaWdodFJwbGFjKEF0b20sIFRlcm0sCgkJCQkJCSAgICAgICBQYXJ0bmVyUmlnaHQsIFN1YnN0KTsKI2lmZGVmIENIRUNLCgkJICAgIGlmIChTdXBBdG9tID09IE5VTEwpIHsKCQkgICAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKCQkgICAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BSaWdodEVxVG9HaXZlbjoiKTsKCQkgICAgICBtaXNjX0Vycm9yUmVwb3J0KCIgcmVwbGFjZW1lbnQgd2Fzbid0IHBvc3NpYmxlLiIpOwoJCSAgICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKCQkgICAgfQojZW5kaWYKCQkgICAgUmVzdWx0ID0KCQkgICAgICBsaXN0X0NvbnMoaW5mX0FwcGx5R2VuU3VwZXJwb3NpdGlvbihQYXJ0bmVyQ2xhdXNlLCBqLAoJCQkJCQkJICBQYXJ0bmVyU3Vic3QsIENsYXVzZSwKCQkJCQkJCSAgaSwgU3Vic3QsIFN1cEF0b20sCgkJCQkJCQkgIFRSVUUsT3JkUGFyYSxNYXhQYXJhLAoJCQkJCQkJICBGbGFncywgUHJlY2VkZW5jZSksIAoJCQkJUmVzdWx0KTsKCQkgIH0KCQkgIGlmIChQYXJ0bmVyTGVmdCAhPSB0ZXJtX051bGwoKSkKCQkgICAgdGVybV9EZWxldGUoUGFydG5lckxlZnQpOwoJCSAgaWYgKFBhcnRuZXJSaWdodCAhPSB0ZXJtX051bGwoKSkKCQkgICAgdGVybV9EZWxldGUoUGFydG5lclJpZ2h0KTsKCQl9CgkJc3Vic3RfRGVsZXRlKFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUmVzdWx0Owp9CgoKc3RhdGljIExJU1QgaW5mX0dlblNQUmlnaHRMaXRUb0dpdmVuKENMQVVTRSBDbGF1c2UsIGludCBpLCBURVJNIEF0b20sCgkJCQkgICAgIFNIQVJFRF9JTkRFWCBTaEluZGV4LCBCT09MIE9yZFBhcmEsCgkJCQkgICAgIEJPT0wgTWF4UGFyYSwgQk9PTCBVbml0LCBGTEFHU1RPUkUgRmxhZ3MsCgkJCQkgICAgIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQW4gdW5zaGFyZWQgY2xhdXNlLCB0aGUgaW5kZXggb2YgYSBzdWNjZWRlbnQgbGl0ZXJhbAogICAgICAgICAgIHRoYXQgaXMgbm90IGFuIGVxdWFsaXR5IGxpdGVyYWwgYW5kIGl0cyBhdG9tLAoJICAgdGhyZWUgYm9vbGVhbiBmbGFncyBmb3IgY29udHJvbGxpbmcgaW5mZXJlbmNlCiAgICAgICAgICAgcHJlY29uZGl0aW9ucyAoc2VlIGluZl9HZW5TdXBlcnBvc2l0aW9uUmlnaHQpLAoJICAgYSBmbGFnIHN0b3JlIGFuZCBhIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gZ2VuZXJhbCBzdXBlcnBvc2l0aW9uIHJpZ2h0IG9uIHRoZQogICAgICAgICAgIEdpdmVuQ29weSAgd3J0LiB0aGUgSW5kZXguCiAgICAgICAgICAgKHNlZSBpbmZfR2VuU3VwZXJwb3NpdGlvblJpZ2h0IGZvciBzZWxlY3Rpb24gb2YgaW5mZXJlbmNlCgkgICBydWxlIGJ5IE9yZFBhcmEvTWF4UGFyYSkKICBNRU1PUlk6ICBBIGxpc3Qgb2YgY2xhdXNlcyBpcyBwcm9kdWNlZCwgd2hlcmUgbWVtb3J5IGZvciB0aGUgbGlzdAogICAgICAgICAgIGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgICAgUmVzdWx0LCBUZXJtTGlzdCwgUGFyZW50TGlzdDsKICBpbnQgICAgIEJvdHRvbTsKICBURVJNICAgIFRlcm0sIFBhcnRuZXJUZXJtLCBQYXJ0bmVyRXE7CgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CgogIEJvdHRvbSA9IHN0YWNrX0JvdHRvbSgpOwogIHNoYXJpbmdfUHVzaExpc3RPblN0YWNrKHRlcm1fQXJndW1lbnRMaXN0KEF0b20pKTsKCiAgd2hpbGUgKCFzdGFja19FbXB0eShCb3R0b20pKSB7CiAgICBUZXJtID0gKFRFUk0pc3RhY2tfUG9wUmVzdWx0KCk7CiAgICBpZiAoIXRlcm1fSXNWYXJpYWJsZShUZXJtKSkgewogICAgICAvKiBTdXBlcnBvc2l0aW9uIGludG8gdmFyaWFibGVzIGlzIG5vdCBuZWNlc3NhcnkgKi8KICAgICAgVGVybUxpc3QgPSBzdF9HZXRVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSwgc2hhcmluZ19JbmRleChTaEluZGV4KSwKCQkJICAgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksIFRlcm0pOwogICAgICBmb3IgKCA7ICFsaXN0X0VtcHR5KFRlcm1MaXN0KTsgVGVybUxpc3Q9bGlzdF9Qb3AoVGVybUxpc3QpKSB7CglQYXJ0bmVyVGVybSA9IChURVJNKWxpc3RfQ2FyKFRlcm1MaXN0KTsKCWZvciAoUGFyZW50TGlzdCA9IHRlcm1fU3VwZXJ0ZXJtTGlzdChQYXJ0bmVyVGVybSk7CgkgICAgICFsaXN0X0VtcHR5KFBhcmVudExpc3QpOyBQYXJlbnRMaXN0ID0gbGlzdF9DZHIoUGFyZW50TGlzdCkpIHsKCSAgUGFydG5lckVxID0gKFRFUk0pbGlzdF9DYXIoUGFyZW50TGlzdCk7CgkgIGlmIChmb2xfSXNFcXVhbGl0eShQYXJ0bmVyRXEpKSB7CgkgICAgQ0xBVVNFICBQYXJ0bmVyQ2xhdXNlOwoJICAgIExJVEVSQUwgUGFydG5lckxpdDsKCSAgICBMSVNUICAgIFNjbDsKCSAgICBpbnQgICAgIGo7CgkgICAgZm9yIChTY2wgPSBzaGFyaW5nX05BdG9tRGF0YUxpc3QoUGFydG5lckVxKTsKCQkgIWxpc3RfRW1wdHkoU2NsKTsgU2NsID0gbGlzdF9DZHIoU2NsKSkgewoJICAgICAgUGFydG5lckxpdCAgICA9IChMSVRFUkFMKWxpc3RfQ2FyKFNjbCk7CgkgICAgICBqICAgICAgICAgICAgID0gY2xhdXNlX0xpdGVyYWxHZXRJbmRleChQYXJ0bmVyTGl0KTsKCSAgICAgIFBhcnRuZXJDbGF1c2UgPSBjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShQYXJ0bmVyTGl0KTsKCSAgICAgIGlmICghY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSxDTEFVU0VTRUxFQ1QpICYmCgkJICAoIU1heFBhcmEgfHwKCQkgICBjbGF1c2VfTGl0ZXJhbEdldEZsYWcoUGFydG5lckxpdCxTVFJJQ1RNQVhJTUFMKSkgJiYKCQkgICghT3JkUGFyYSB8fCBQYXJ0bmVyVGVybT09dGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJFcSkgfHwKCQkgICAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkpICYmCgkJICBjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgJiYKCQkgIGNsYXVzZV9OdW1iZXIoUGFydG5lckNsYXVzZSkgIT0gY2xhdXNlX051bWJlcihDbGF1c2UpICYmIAoJCSAgKCFVbml0IHx8IGNsYXVzZV9MZW5ndGgoUGFydG5lckNsYXVzZSkgPT0gMSkgJiYKCQkgIGNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KFBhcnRuZXJDbGF1c2UpKSB7CgkJLyogV2UgZXhjbHVkZSB0aGUgc2FtZSBjbGF1c2Ugc2luY2UgdGhhdCBpbmZlcmVuY2Ugd2lsbCBiZSAqLwoJCS8qIG1hZGUgYnkgdGhlICJmb3J3YXJkIiBmdW5jdGlvbiBpbmZfR2VuTGl0U1BSaWdodC4gICAgICAgKi8KCQlTWU1CT0wgTWF4VmFyOwoJCVRFUk0gICBQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQ7CgkJU1VCU1QgIFN1YnN0LCBQYXJ0bmVyU3Vic3Q7CgkJVEVSTSAgIFN1cEF0b207CgoJCVN1cEF0b20gPSAoVEVSTSlOVUxMOwoJCU1heFZhciAgICAgID0gY2xhdXNlX01heFZhcihQYXJ0bmVyQ2xhdXNlKTsKCQljbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oQ2xhdXNlLE1heFZhcik7CgkJY29udF9DaGVjaygpOwoJCXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIFRlcm0sCgkJCQljb250X1JpZ2h0Q29udGV4dCgpLFBhcnRuZXJUZXJtKTsKCQlzdWJzdF9FeHRyYWN0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksICZTdWJzdCwKCQkJCSAgICAgY29udF9SaWdodENvbnRleHQoKSwmUGFydG5lclN1YnN0KTsKCQljb250X1Jlc2V0KCk7CgoJCWlmICghTWF4UGFyYSB8fAoJCSAgICBpbmZfTGl0ZXJhbHNNYXgoQ2xhdXNlLCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgaiwKCQkJCSAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJCSAgUGFydG5lckxlZnQgPSBzdWJzdF9BcHBseShQYXJ0bmVyU3Vic3QsCgkJCQkJICAgIHRlcm1fQ29weShQYXJ0bmVyVGVybSkpOwoJCSAgaWYgKFBhcnRuZXJUZXJtID09IHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyRXEpKQoJCSAgICBQYXJ0bmVyUmlnaHQgPQoJCSAgICAgIHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCQkJCSAgdGVybV9Db3B5KHRlcm1fU2Vjb25kQXJndW1lbnQoUGFydG5lckVxKSkpOwoJCSAgZWxzZQoJCSAgICBQYXJ0bmVyUmlnaHQgPQoJCSAgICAgIHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCQkJCSAgdGVybV9Db3B5KHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyRXEpKSk7CgoJCSAgaWYgKCFPcmRQYXJhIHx8CgkJICAgICAgY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkgfHwKCQkgICAgICBvcmRfQ29tcGFyZShQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQsIEZsYWdzLCBQcmVjZWRlbmNlKQoJCSAgICAgICE9IG9yZF9TbWFsbGVyVGhhbigpKSB7CgkJICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNScGxhYyhBdG9tLFRlcm0sUGFydG5lclJpZ2h0LFN1YnN0KTsKI2lmZGVmIENIRUNLCgkJICAgIGlmIChTdXBBdG9tID09IE5VTEwpIHsKCQkgICAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKCQkgICAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BSaWdodExpdFRvR2l2ZW46Iik7CgkJICAgICAgbWlzY19FcnJvclJlcG9ydCgiIHJlcGxhY2VtZW50IHdhc24ndCBwb3NzaWJsZS4iKTsKCQkgICAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CgkJICAgIH0KI2VuZGlmCgkJICAgIFJlc3VsdCA9CgkJICAgICAgbGlzdF9Db25zKGluZl9BcHBseUdlblN1cGVycG9zaXRpb24oUGFydG5lckNsYXVzZSwgaiwKCQkJCQkJCSAgUGFydG5lclN1YnN0LCBDbGF1c2UsCgkJCQkJCQkgIGksIFN1YnN0LCBTdXBBdG9tLAoJCQkJCQkJICBUUlVFLE9yZFBhcmEsTWF4UGFyYSwKCQkJCQkJCSAgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQkJUmVzdWx0KTsKCQkgIAoJCSAgfQoJCSAgdGVybV9EZWxldGUoUGFydG5lckxlZnQpOwoJCSAgdGVybV9EZWxldGUoUGFydG5lclJpZ2h0KTsKCQl9CgkJc3Vic3RfRGVsZXRlKFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUmVzdWx0Owp9CgoKc3RhdGljIExJU1QgaW5mX0dlblNQUmlnaHRUb0dpdmVuKENMQVVTRSBDbGF1c2UsIGludCBpLCBTSEFSRURfSU5ERVggU2hJbmRleCwgCgkJCQkgIEJPT0wgT3JkUGFyYSwgQk9PTCBNYXhQYXJhLCBCT09MIFVuaXQsCgkJCQkgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBbiB1bnNoYXJlZCBjbGF1c2UsIHRoZSBpbmRleCBvZiBhIHN1Y2NlZGVudCBsaXRlcmFsCiAgICAgICAgICAgYW5kIGFuIGluZGV4IG9mIHNoYXJlZCBjbGF1c2VzLAogICAgICAgICAgIHRocmVlIGJvb2xlYW4gZmxhZ3MgZm9yIGNvbnRyb2xsaW5nIGluZmVyZW5jZQogICAgICAgICAgIHByZWNvbmRpdGlvbnMgKHNlZSBpbmZfR2VuU3VwZXJwb3NpdGlvblJpZ2h0KSwKCSAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIHN1cGVycG9zaXRpb24gcmlnaHQgb24gdGhlCiAgICAgICAgICAgR2l2ZW5Db3B5ICB3cnQuIHRoZSBJbmRleC4KCSAgIChzZWUgaW5mX0dlblN1cGVycG9zaXRpb25SaWdodCBmb3Igc2VsZWN0aW9uIG9mIGluZmVyZW5jZQoJICAgcnVsZSBieSBPcmRQYXJhL01heFBhcmEpCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBURVJNIEF0b207CiAgTElTVCBSZXN1bHQ7CiAgCiNpZmRlZiBDSEVDSwogIGlmIChjbGF1c2VfR2V0RmxhZyhDbGF1c2UsIE5PUEFSQUlOVE8pIHx8CiAgICAgIGNsYXVzZV9HZXRGbGFnKENsYXVzZSwgQ0xBVVNFU0VMRUNUKSB8fAogICAgICAoTWF4UGFyYSAmJgogICAgICAgIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSksIFNUUklDVE1BWElNQUwpKSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BSaWdodFRvR2l2ZW46IElsbGVnYWwgaW5wdXQuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQojZW5kaWYKCiAgUmVzdWx0ICA9IGxpc3RfTmlsKCk7CiAgQXRvbSAgICA9IGNsYXVzZV9MaXRlcmFsQXRvbShjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSkpOwogIAogIGlmIChmb2xfSXNFcXVhbGl0eShBdG9tKSkgewogICAgUmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfR2VuU1BSaWdodEVxVG9HaXZlbihDbGF1c2UsaSxUUlVFLFNoSW5kZXgsT3JkUGFyYSwKCQkJCQkJTWF4UGFyYSxVbml0LEZsYWdzLCBQcmVjZWRlbmNlKSwKCQkJUmVzdWx0KTsKICAgIAogICAgaWYgKCFNYXhQYXJhIHx8CgkhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpKSkKICAgICAgLyogRm9yIFNQbSBhbmQgT1BtIGFsd2F5cyB0cnkgb3RoZXIgZGlyZWN0aW9uLCBmb3IgU3BSIHRyeSBpdCAqLwogICAgICAvKiBvbmx5IGlmIHRoZSBsaXRlcmFsIGlzIG5vdCBvcmllbnRlZC4gICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgIFJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0dlblNQUmlnaHRFcVRvR2l2ZW4oQ2xhdXNlLCBpLCBGQUxTRSwgU2hJbmRleCwKCQkJCQkJICBPcmRQYXJhLE1heFBhcmEsVW5pdCwKCQkJCQkJICBGbGFncywgUHJlY2VkZW5jZSksCgkJCSAgUmVzdWx0KTsKICB9IGVsc2UKICAgIFJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0dlblNQUmlnaHRMaXRUb0dpdmVuKENsYXVzZSxpLEF0b20sU2hJbmRleCwKCQkJCQkJIE9yZFBhcmEsTWF4UGFyYSxVbml0LAoJCQkJCQkgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQlSZXN1bHQpOwogIAogIHJldHVybiBSZXN1bHQ7Cn0KCgpMSVNUIGluZl9HZW5TdXBlcnBvc2l0aW9uUmlnaHQoQ0xBVVNFIEdpdmVuQ2xhdXNlLCBTSEFSRURfSU5ERVggU2hJbmRleCwKCQkJICAgICAgIEJPT0wgT3JkUGFyYSwgQk9PTCBNYXhQYXJhLCBCT09MIFVuaXQsCgkJCSAgICAgICBGTEFHU1RPUkUgRmxhZ3MsIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2UgYW5kIGFuIEluZGV4LCB1c3VhbGx5IHRoZSBXb3JrZWRPZmZJbmRleCwKICAgICAgICAgICB0aHJlZSBib29sZWFuIGZsYWdzIGZvciBjb250cm9sbGluZyBpbmZlcmVuY2UKICAgICAgICAgICBwcmVjb25kaXRpb25zLCBhIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIGxpc3Qgb2YgY2xhdXNlcyBkZXJpdmFibGUgZnJvbSB0aGUgZ2l2ZW4gY2xhdXNlIGJ5IAogICAgICAgICAgIHN1cGVycG9zaXRpb24gcmlnaHQgd3J0LiB0aGUgSW5kZXguCgoJICAgT3JkUGFyYT1UUlVFLCBNYXhQYXJhPVRSVUUgCgkgICAtPiBTdXBlcnBvc2l0aW9uIFJpZ2h0CgoJICAgT3JkUGFyYT1UUlVFLCBNYXhQYXJhPUZBTFNFCgkgICAtPiBvcmRlcmVkIFBhcmFtb2R1bGF0aW9uCgoJICAgT3JkUGFyYT1GQUxTRSwgTWF4UGFyYT1GQUxTRQoJICAgLT4gc2ltcGxlIFBhcmFtb2R1bGF0aW9uCgoJICAgT3JkUGFyYT1GQUxTRSwgTWF4UGFyYT1UUlVFCgkgICAtPiBub3QgZGVmaW5lZAoKCSAgIElmIDxVbml0Pj09VFJVRSB0aGUgY2xhdXNlIHdpdGggdGhlIG1heGltYWwgZXF1YWxpdHkgCgkgICBhZGRpdGlvbmFsbHkgbXVzdCBiZSBhIHVuaXQgY2xhdXNlLgogIE1FTU9SWTogIEEgbGlzdCBvZiBjbGF1c2VzIGlzIHByb2R1Y2VkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZSBsaXN0CiAgICAgICAgICAgYW5kIHRoZSBjbGF1c2VzIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgTElTVCAgICBSZXN1bHQ7CiAgVEVSTSAgICBBdG9tOwogIENMQVVTRSAgQ29weTsKICBpbnQgICAgIGksIG47CiAgTElURVJBTCBBY3RMaXQ7CgojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZW5TdXBlcnBvc2l0aW9uUmlnaHQ6IElsbGVnYWwgaW5wdXQuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQogIGlmICghT3JkUGFyYSAmJiBNYXhQYXJhKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZW5TdXBlcnBvc2l0aW9uUmlnaHQ6IElsbGVnYWwgaW5mZXJlbmNlIik7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBydWxlIHNlbGVjdGlvbiwgT3JkUGFyYT1GQUxTRSAmIE1heFBhcmE9VFJVRS4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBpZiAoY2xhdXNlX0dldEZsYWcoR2l2ZW5DbGF1c2UsQ0xBVVNFU0VMRUNUKSB8fAogICAgICBjbGF1c2VfSGFzRW1wdHlTdWNjZWRlbnQoR2l2ZW5DbGF1c2UpIHx8CiAgICAgICFjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChHaXZlbkNsYXVzZSkpCiAgICByZXR1cm4gbGlzdF9OaWwoKTsKCiAgUmVzdWx0ID0gbGlzdF9OaWwoKTsKCiAgQ29weSA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICBuICAgID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChDb3B5KTsKICAKICBmb3IgKGkgPSBjbGF1c2VfRmlyc3RTdWNjZWRlbnRMaXRJbmRleChDb3B5KTsgaSA8PSBuOyBpKyspIHsKICAgIAogICAgQWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoQ29weSwgaSk7CiAgICBBdG9tICAgPSBjbGF1c2VfTGl0ZXJhbFNpZ25lZEF0b20oQWN0TGl0KTsKICAgIAogICAgaWYgKCFNYXhQYXJhIHx8CgljbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LFNUUklDVE1BWElNQUwpKSB7CiAgICAgIGlmIChmb2xfSXNFcXVhbGl0eShBdG9tKSAmJgoJICAoIVVuaXQgfHwgY2xhdXNlX0xlbmd0aChHaXZlbkNsYXVzZSkgPT0gMSkpIHsKCQoJUmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfR2VuTGl0U1BSaWdodChDb3B5LCB0ZXJtX0ZpcnN0QXJndW1lbnQoQXRvbSksIAoJCQkJCSAgICAgIHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSksIGksCgkJCQkJICAgICAgU2hJbmRleCxPcmRQYXJhLE1heFBhcmEsRmxhZ3MsCgkJCQkJICAgICAgUHJlY2VkZW5jZSksIAoJCQkgICAgUmVzdWx0KTsKCQoJaWYgKCFPcmRQYXJhIHx8CgkgICAgIWNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KEFjdExpdCkpCgkgIFJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0dlbkxpdFNQUmlnaHQoQ29weSwKCQkJCQkJdGVybV9TZWNvbmRBcmd1bWVudChBdG9tKSwgCgkJCQkJCXRlcm1fRmlyc3RBcmd1bWVudChBdG9tKSwgaSwKCQkJCQkJU2hJbmRleCxPcmRQYXJhLE1heFBhcmEsRmxhZ3MsCgkJCQkJCVByZWNlZGVuY2UpLAoJCQkgICAgICBSZXN1bHQpOwogICAgICB9CiAgICAgIGlmICghY2xhdXNlX0dldEZsYWcoQ29weSwgTk9QQVJBSU5UTykpCglSZXN1bHQgPSBsaXN0X05jb25jKGluZl9HZW5TUFJpZ2h0VG9HaXZlbihDb3B5LCBpLCBTaEluZGV4LCBPcmRQYXJhLAoJCQkJCQkgIE1heFBhcmEsVW5pdCxGbGFncyxQcmVjZWRlbmNlKSwKCQkJICAgIFJlc3VsdCk7CiAgICB9CiAgfQogIGNsYXVzZV9EZWxldGUoQ29weSk7CgogIHJldHVybiBSZXN1bHQ7Cn0KCgoKLyogRU5EIG9mIGJsb2NrIHdpdGggbmV3IHN1cGVycG9zaXRpb24gcmlnaHQgcnVsZSAqLwoKCnN0YXRpYyBMSVNUIGluZl9BcHBseU1QYXJhbW9kKENMQVVTRSBDMSwgQ0xBVVNFIEMyLCBpbnQgaSwgaW50IGosIGludCBrLAoJCQkgICAgICBURVJNIHVfdGF1LCBURVJNIHYsIFRFUk0gczIsIFRFUk0gdCwKCQkJICAgICAgVEVSTSB2Ml9zaWdtYSwgU1VCU1QgdGF1LCBTVUJTVCByaG8sCgkJCSAgICAgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUd28gY2xhdXNlcywgPGk+IGlzIGEgbGl0ZXJhbCBpbmRleCBpbiA8QzE+LCA8aj4gYW5kIDxrPgogICAgICAgICAgIGFyZSBsaXRlcmFsIGluZGljZXMgaW4gPEMyPiwgPHVfdGF1PiB3aXRoIDxyaG8+IGFwcGxpZWQKCSAgIGlzIHVzZWQgYXMgbGVmdCBzaWRlIG9mIHRoZSB0d28gbmV3IGxpdGVyYWxzLCA8dj4gd2l0aAoJICAgc3VidGVybSA8czI+IHJlcGxhY2VkIGJ5IDx0PiBpcyB1c2VkIGFzIHJpZ2h0IHNpZGUgb2YKCSAgIHRoZSBmaXJzdCBuZXcgbGl0ZXJhbCwgPHYyX3NpZ21hPiBhcyByaWdodCBzaWRlIG9mIHRoZQoJICAgc2Vjb25kIG5ldyBsaXRlcmFsLCB0d28gc3Vic3RpdHV0aW9ucyBhbmQgYSBmbGFnIHN0b3JlLgoJICAgVGhlIHN1YnN0aXR1dGlvbiA8cmhvPiBpcyBhcHBsaWVkIGFmdGVyIDx0YXU+LgoJICAgQSBmbGFnIHN0b3JlLgoJICAgQSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBjb250YWluaW5nIG9uZSBjbGF1c2UgZGVyaXZlZCBmcm9tIHRoZSBnaXZlbgogICAgICAgICAgIGNsYXVzZXMgYW5kIGxpdGVyYWxzIGJ5IG1lcmdpbmcgcGFyYW1vZHVsYXRpb24uCiAgTUVNT1JZOiAgTWVtb3J5IGZvciB0aGUgbGlzdCBhbmQgdGhlIGNsYXVzZSBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIENMQVVTRSBuZXdDbGF1c2U7CiAgVEVSTSAgIHVfc2lnbWE7CiAgaW50ICAgIG0sIGxjLCBsYSwgbHMsIHBscywgcGxhLCBwbGMsIGhlbHA7CgogIHBscyA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQzIpOwogIHBsYSA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KEMyKTsKICBwbGMgPSBjbGF1c2VfTGFzdENvbnN0cmFpbnRMaXRJbmRleChDMik7CgogIGxzICA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQzEpOwogIGxhICA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KEMxKTsKICBsYyAgPSBjbGF1c2VfTGFzdENvbnN0cmFpbnRMaXRJbmRleChDMSk7CgogIG5ld0NsYXVzZSA9IGNsYXVzZV9DcmVhdGVCb2R5KGNsYXVzZV9MZW5ndGgoQzEpICsgY2xhdXNlX0xlbmd0aChDMikgLSAxKTsKCiAgY2xhdXNlX1NldE51bU9mQ29uc0xpdHMobmV3Q2xhdXNlLCAoY2xhdXNlX051bU9mQ29uc0xpdHMoQzEpICsKCQkJCSAgICAgIGNsYXVzZV9OdW1PZkNvbnNMaXRzKEMyKSkpOwogIGNsYXVzZV9TZXROdW1PZkFudGVMaXRzKG5ld0NsYXVzZSwgKGNsYXVzZV9OdW1PZkFudGVMaXRzKEMxKSArCgkJCQkgICAgICBjbGF1c2VfTnVtT2ZBbnRlTGl0cyhDMikpKTsKICBjbGF1c2VfU2V0TnVtT2ZTdWNjTGl0cyhuZXdDbGF1c2UsIChjbGF1c2VfTnVtT2ZTdWNjTGl0cyhDMSkgLSAxICsKCQkJCSAgICAgIGNsYXVzZV9OdW1PZlN1Y2NMaXRzKEMyKSkpOwoKICBmb3IgKG0gPSBjbGF1c2VfRmlyc3RMaXRJbmRleCgpOyBtIDw9IGxjOyBtKyspCiAgICBjbGF1c2VfU2V0TGl0ZXJhbChuZXdDbGF1c2UsIG0sCiAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LAoJdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDMSwgbSkpKSksIG5ld0NsYXVzZSkpOwoKICAvKiBoZWxwID0gbnVtYmVyIG9mIGxpdGVyYWxzIHRvIGxlYXZlIGVtcHR5ICovCiAgaGVscCA9IGNsYXVzZV9OdW1PZkNvbnNMaXRzKEMyKTsKCiAgZm9yICggOyBtIDw9IGxhOyBtKyspCiAgICBjbGF1c2VfU2V0TGl0ZXJhbChuZXdDbGF1c2UsIChtICsgaGVscCksCiAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LAoJdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDMSwgbSkpKSksIG5ld0NsYXVzZSkpOwoKICAvKiBoZWxwID0gbnVtYmVyIG9mIGxpdGVyYWxzIHRvIGxlYXZlIGVtcHR5ICovCiAgaGVscCArPSBjbGF1c2VfTnVtT2ZBbnRlTGl0cyhDMik7CgogIGZvciAoIDsgbSA8PSBsczsgbSsrKSB7CiAgICBpZiAobSAhPSBpKQogICAgICAvKiBUaGUgbGl0ZXJhbCB1c2VkIGluIHRoZSBpbmZlcmVuY2UgaXNuJ3QgY29waWVkICovCiAgICAgIGNsYXVzZV9TZXRMaXRlcmFsKG5ld0NsYXVzZSwgKG0gKyBoZWxwKSwgCgljbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShyaG8sIHN1YnN0X0FwcGx5KHRhdSwKCSAgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDMSwgbSkpKSksbmV3Q2xhdXNlKSk7CiAgICBlbHNlCiAgICAgIC8qIHRoZSBpbmRleCBoYXMgdG8gYmUgZGVjcmVhc2VkIHRvIGF2b2lkIGFuIGVtcHR5IGxpdGVyYWwhICovCiAgICAgIGhlbHAtLTsKICB9CgogIC8qIE5vdyB3ZSBjb25zaWRlciB0aGUgUGFydG5lckNsYXVzZSA6ICovCiAgCiAgLyogaGVscCA9IG51bWJlciBvZiBhbHJlYWR5IHNldCBjb25zdHJhaW50IChDbGF1c2UpIGxpdGVyYWxzICovCiAgaGVscCA9IGNsYXVzZV9OdW1PZkNvbnNMaXRzKEMxKTsKICAKICBmb3IgKG0gPSBjbGF1c2VfRmlyc3RMaXRJbmRleCgpOyBtIDw9IHBsYzsgbSsrKQogICAgY2xhdXNlX1NldExpdGVyYWwobmV3Q2xhdXNlLCAobSArIGhlbHApLCAKICAgICAgY2xhdXNlX0xpdGVyYWxDcmVhdGUoc3Vic3RfQXBwbHkocmhvLCBzdWJzdF9BcHBseSh0YXUsCgl0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKEMyLCBtKSkpKSxuZXdDbGF1c2UpKTsKICAKICAvKiBoZWxwID0gbnVtYmVyIG9mIGFscmVhZHkgc2V0IGNvbnN0cmFpbnQgYW5kIGFudGVjZWRlbnQgR2l2ZW4tbGl0ZXJhbHMgKi8KICBoZWxwICs9IGNsYXVzZV9OdW1PZkFudGVMaXRzKEMxKTsKICAKICBmb3IgKCA7IG0gPD0gcGxhOyBtKyspCiAgICBjbGF1c2VfU2V0TGl0ZXJhbChuZXdDbGF1c2UsIChtICsgaGVscCksIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShyaG8sIHN1YnN0X0FwcGx5KHRhdSwKICAgICAgICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKEMyLCBtKSkpKSxuZXdDbGF1c2UpKTsKCiAgLyogaGVscCA9IG51bWJlciBvZiBhbHJlYWR5IHNldCBsaXRlcmFscyAqLwogIGhlbHAgKz0gY2xhdXNlX051bU9mU3VjY0xpdHMoQzEpIC0gMTsKICAvKmhlbHAgPSBjbGF1c2VfTGVuZ3RoKENsYXVzZSkgLSAxOyovCgogIHVfc2lnbWEgPSBzdWJzdF9BcHBseShyaG8sIHRlcm1fQ29weSh1X3RhdSkpOwoKICBmb3IgKCA7IG0gPD0gcGxzOyBtKyspIHsKICAgIFRFUk0gbmV3QXRvbTsKCiAgICBpZiAobSA9PSBqKSB7CiAgICAgIC8qIFRoZSBmaXJzdCBwYXJ0bmVyIGxpdGVyYWwgaXMgbW9kaWZpZWQgYXBwcm9wcmlhdGVseSEgKi8KICAgICAgVEVSTSByaWdodDsKICAgICAgaWYgKHYgPT0gczIpCgkvKiBOZWNlc3NhcnkgYmVjYXVzZSB0ZXJtX1JlcGxhY2VTdWJ0ZXJtQnkgZG9lc24ndCB0cmVhdCB0b3AgbGV2ZWwgKi8KCXJpZ2h0ID0gdGVybV9Db3B5KHQpOwogICAgICBlbHNlIHsKCXJpZ2h0ID0gdGVybV9Db3B5KHYpOwoJdGVybV9SZXBsYWNlU3VidGVybUJ5KHJpZ2h0LCBzMiwgdCk7CiAgICAgIH0JCQogICAgICBuZXdBdG9tID0gdGVybV9DcmVhdGUoZm9sX0VxdWFsaXR5KCksIGxpc3RfQ29ucyh0ZXJtX0NvcHkodV9zaWdtYSksCgkJICBsaXN0X0xpc3Qoc3Vic3RfQXBwbHkocmhvLCBzdWJzdF9BcHBseSh0YXUsIHJpZ2h0KSkpKSk7CiAgICB9IGVsc2UgaWYgKG0gPT0gaykgewogICAgICAvKiBUaGUgc2Vjb25kIHBhcnRuZXIgbGl0IGlzIG1vZGlmaWVkIGFwcHJvcHJpYXRlbHkhICAgICovCiAgICAgIG5ld0F0b20gPSB0ZXJtX0NyZWF0ZShmb2xfRXF1YWxpdHkoKSwgbGlzdF9Db25zKHRlcm1fQ29weSh1X3NpZ21hKSwKCSAgICAgICAgICBsaXN0X0xpc3QodGVybV9Db3B5KHYyX3NpZ21hKSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIEFwcGx5IHN1YnN0aXR1dGlvbnMgdG8gYWxsIG90aGVyIGxpdGVyYWxzICovCiAgICAgIG5ld0F0b20gPSBzdWJzdF9BcHBseShyaG8sIHN1YnN0X0FwcGx5KHRhdSwKICAgICAgICAgICAgICAgICAgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShDMiwgbSkpKSk7CiAgICB9CgogICAgY2xhdXNlX1NldExpdGVyYWwobmV3Q2xhdXNlLCAobSArIGhlbHApLAoJCSAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKG5ld0F0b20sIG5ld0NsYXVzZSkpOwogICB9CgogIHRlcm1fRGVsZXRlKHVfc2lnbWEpOwoKICBjbGF1c2VfU2V0RnJvbU1lcmdpbmdQYXJhbW9kdWxhdGlvbihuZXdDbGF1c2UpOwoKICBjbGF1c2VfQWRkUGFyZW50Q2xhdXNlKG5ld0NsYXVzZSwgY2xhdXNlX051bWJlcihDMikpOwogIGNsYXVzZV9BZGRQYXJlbnRMaXRlcmFsKG5ld0NsYXVzZSwgayk7CiAgY2xhdXNlX1NldERhdGFGcm9tUGFyZW50cyhuZXdDbGF1c2UsIEMyLCBqLCBDMSwgaywgRmxhZ3MsIFByZWNlZGVuY2UpOwoKICByZXR1cm4gbGlzdF9MaXN0KG5ld0NsYXVzZSk7Cn0KCgpzdGF0aWMgTElTVCBpbmZfTGl0Mk1QYXJhbW9kKENMQVVTRSBDMSwgQ0xBVVNFIEMyLCBpbnQgaSwgaW50IGosIFRFUk0gcywgVEVSTSB0LAoJCQkgICAgIFRFUk0gczIsIFRFUk0gdiwgVEVSTSB1X3RhdSwgU1VCU1QgdGF1LAoJCQkgICAgIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBUd28gY2xhdXNlcywgdGhlIGluZGV4IDxpPiBvZiBhIHN0cmljdCBtYXhpbWFsIGxpdGVyYWwKICAgICAgICAgICBpbiA8QzE+LCB0aGUgaW5kZXggPGo+IG9mIGEgc3RyaWN0IG1heGltYWwgaW5kZXggaW4gPEMyPiwKCSAgIDxzPiBhbmQgPHQ+IGFyZSBmcm9tIGxpdGVyYWwgPGk+LCA8czI+IGlzIGEgc3VidGVybQoJICAgb2YgPHY+LCA8dj4gaXMgZnJvbSBsaXRlcmFsIDxqPiwgPHVfdGF1PiBpcyA8dT4gd2l0aAoJICAgc3Vic3RpdHV0aW9uIDx0YXU+IGFwcGxpZWQsIGEgZmxhZyBzdG9yZSwgYW5kIGEgcHJlY2VkZW5jZS4KCSAgIDx1X3RhdT4gbXVzdCBiZSBncmVhdGVyIHRoYW4gPHY+dGF1IHdydC4gdGhlIG9yZGVyaW5nLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIHRoZSBnaXZlbiBkYXRhCiAgICAgICAgICAgYnkgbWVyZ2luZyBwYXJhbW9kdWxhdGlvbi4KCSAgIFRoaXMgZnVuY3Rpb24gc2VhcmNoZXMgPEMyPiBmb3IgYSBzZWNvbmQgcG9zaXRpdmUgbGl0ZXJhbAoJICAgdSc9dicsIHdoZXJlIHUnIGlzIHVuaWZpYWJsZSB3aXRoIDx1X3RhdT4uCiAgTUVNT1JZOiAgTWVtb3J5IGlzIGFsbG9jYXRlZCBmb3IgdGhlIGxpc3QgYW5kIHRoZSBjbGF1c2VzLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUIHJlc3VsdDsKICBpbnQgIGssIGxhc3Q7CgogIHJlc3VsdCA9IGxpc3RfTmlsKCk7CgogIC8qIE5vdyBmaW5kIHRoZSAzcmQgbGl0ZXJhbCB1JyA9IHYnIGluIEMyICovCiAgbGFzdCA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQzIpOyAgLyogTGFzdCBpbmRleCAqLwogIGZvciAoayA9IGNsYXVzZV9GaXJzdFN1Y2NlZGVudExpdEluZGV4KEMyKTsgayA8PSBsYXN0OyBrKyspIHsKICAgIExJVEVSQUwgcGFydG5lckxpdDIgID0gY2xhdXNlX0dldExpdGVyYWwoQzIsIGspOwogICAgVEVSTSAgICBwYXJ0bmVyQXRvbTIgPSBjbGF1c2VfTGl0ZXJhbFNpZ25lZEF0b20ocGFydG5lckxpdDIpOwoKICAgIGlmIChrICE9IGogJiYgZm9sX0lzRXF1YWxpdHkocGFydG5lckF0b20yKSkgewogICAgICAvKiBwYXJ0bmVyTGl0MjogdScgPSB2JyAgb3IgIHYnID0gdScgKi8KICAgICAgU1VCU1QgICAgICByaG87CiAgICAgIFRFUk0gICAgICAgcExlZnQyLCBwUmlnaHQyLCBzX3NpZ21hLCB0X3NpZ21hLCB2Ml9zaWdtYTsKICAgICAgb3JkX1JFU1VMVCBvcmRSZXN1bHQ7CiAgICAgIEJPT0wgICAgICAgY2hlY2tQYXNzZWQ7CgogICAgICBwTGVmdDIgID0gc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkodGVybV9GaXJzdEFyZ3VtZW50KHBhcnRuZXJBdG9tMikpKTsKICAgICAgcFJpZ2h0MiA9IHN1YnN0X0FwcGx5KHRhdSwgdGVybV9Db3B5KHRlcm1fU2Vjb25kQXJndW1lbnQocGFydG5lckF0b20yKSkpOwogICAgICAKICAgICAgLyogRmlyc3QgdHJ5IHVuaWZpY2F0aW9uIHdpdGggbGVmdCBzaWRlICovCiAgICAgIGNvbnRfQ2hlY2soKTsKCiAgICAgIGlmICh1bmlmeV9VbmlmeUNvbShjb250X0xlZnRDb250ZXh0KCksIHVfdGF1LCBwTGVmdDIpKSB7CglzdWJzdF9FeHRyYWN0VW5pZmllckNvbShjb250X0xlZnRDb250ZXh0KCksICZyaG8pOwoKCXNfc2lnbWEgPSB0X3NpZ21hID0gKFRFUk0pIE5VTEw7CgljaGVja1Bhc3NlZCA9IFRSVUU7CgoJaWYgKCFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShjbGF1c2VfR2V0TGl0ZXJhbChDMSxpKSkpIHsKCSAgc19zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkocykpKTsKCSAgdF9zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkodCkpKTsKCSAgb3JkUmVzdWx0ID0gb3JkX0NvbXBhcmUoc19zaWdtYSwgdF9zaWdtYSwgRmxhZ3MsIFByZWNlZGVuY2UpOwoJICBpZiAob3JkUmVzdWx0ID09IG9yZF9TbWFsbGVyVGhhbigpIHx8IG9yZFJlc3VsdCA9PSBvcmRfRXF1YWwoKSkKCSAgICBjaGVja1Bhc3NlZCA9IEZBTFNFOwoJfQoKCWlmIChjaGVja1Bhc3NlZCAmJiBpbmZfTGl0ZXJhbHNNYXhXaXRoMlN1YnN0KEMxLGksQzIsaixyaG8sdGF1LAoJCQkJCQkgICAgIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJICB2Ml9zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgdGVybV9Db3B5KHBSaWdodDIpKTsKCSAgcmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfQXBwbHlNUGFyYW1vZChDMSxDMixpLGosayx1X3RhdSx2LHMyLAoJCQkJCQl0LHYyX3NpZ21hLHRhdSxyaG8sCgkJCQkJCUZsYWdzLCBQcmVjZWRlbmNlKSwKCQkJICAgICAgcmVzdWx0KTsKCSAgdGVybV9EZWxldGUodjJfc2lnbWEpOwoJfQoJLyogTm93IGNsZWFudXAgKi8KCWlmIChzX3NpZ21hICE9IE5VTEwpIHsgICAgICAvKiBBbHNvIHRfc2lnbWEgIT0gTlVMTCAqLwoJICB0ZXJtX0RlbGV0ZShzX3NpZ21hKTsKCSAgdGVybV9EZWxldGUodF9zaWdtYSk7Cgl9CglzdWJzdF9EZWxldGUocmhvKTsKICAgICAgfQoKICAgICAgY29udF9SZXNldCgpOwoKICAgICAgLyogTm93IHRyeSB1bmlmaWNhdGlvbiB3aXRoIHJpZ2h0IHNpZGUgKi8KICAgICAgaWYgKHVuaWZ5X1VuaWZ5Q29tKGNvbnRfTGVmdENvbnRleHQoKSwgdV90YXUsIHBSaWdodDIpKSB7CglzdWJzdF9FeHRyYWN0VW5pZmllckNvbShjb250X0xlZnRDb250ZXh0KCksICZyaG8pOwoKCXNfc2lnbWEgPSB0X3NpZ21hID0gKFRFUk0pIE5VTEw7CgljaGVja1Bhc3NlZCA9IFRSVUU7CgoJaWYgKCFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShjbGF1c2VfR2V0TGl0ZXJhbChDMSxpKSkpIHsKCSAgc19zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkocykpKTsKCSAgdF9zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkodCkpKTsKCSAgb3JkUmVzdWx0ID0gb3JkX0NvbXBhcmUoc19zaWdtYSwgdF9zaWdtYSwgRmxhZ3MsIFByZWNlZGVuY2UpOwoJICBpZiAob3JkUmVzdWx0ID09IG9yZF9TbWFsbGVyVGhhbigpIHx8IG9yZFJlc3VsdCA9PSBvcmRfRXF1YWwoKSkKCSAgICBjaGVja1Bhc3NlZCA9IEZBTFNFOwoJfQoKCWlmIChjaGVja1Bhc3NlZCAmJiBpbmZfTGl0ZXJhbHNNYXhXaXRoMlN1YnN0KEMxLGksQzIsaixyaG8sdGF1LAoJCQkJCQkgICAgIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJICB2Ml9zaWdtYSA9IHN1YnN0X0FwcGx5KHJobywgdGVybV9Db3B5KHBMZWZ0MikpOwoJICByZXN1bHQgPSBsaXN0X05jb25jKGluZl9BcHBseU1QYXJhbW9kKEMxLEMyLGksaixrLHVfdGF1LHYsczIsCgkJCQkJCXQsdjJfc2lnbWEsdGF1LHJobywKCQkJCQkJRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQkgICAgICByZXN1bHQpOwoJICB0ZXJtX0RlbGV0ZSh2Ml9zaWdtYSk7Cgl9CgkvKiBOb3cgY2xlYW51cCAqLwoJaWYgKHNfc2lnbWEgIT0gTlVMTCkgeyAgICAgIC8qIEFsc28gdF9zaWdtYSAhPSBOVUxMICovCgkgIHRlcm1fRGVsZXRlKHNfc2lnbWEpOwoJICB0ZXJtX0RlbGV0ZSh0X3NpZ21hKTsKCX0KCXN1YnN0X0RlbGV0ZShyaG8pOwogICAgICB9CgogICAgICBjb250X1Jlc2V0KCk7CgogICAgICB0ZXJtX0RlbGV0ZShwTGVmdDIpOwogICAgICB0ZXJtX0RlbGV0ZShwUmlnaHQyKTsKICAgIH0gICAvKiBrICE9IGogKi8KICB9ICAgICAvKiBmb3IgayAqLwogIAogIHJldHVybiByZXN1bHQ7Cn0gIAogIAoKc3RhdGljIExJU1QgaW5mX0xpdE1QYXJhbW9kKENMQVVTRSBDbGF1c2UsIGludCBpLCBCT09MIFR1cm4sCgkJCSAgICBTSEFSRURfSU5ERVggU2hJbmRleCwgRkxBR1NUT1JFIEZsYWdzLAoJCQkgICAgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSB3aXRoIGEgc3RyaWN0IG1heGltYWwgZXF1YWxpdHkgbGl0ZXJhbCBhdCAKICAgICAgICAgICBwb3NpdGlvbiA8aT4sIGEgYm9vbGVhbiB2YWx1ZSwgYSBzaGFyZWQgaW5kZXgsIGEgCgkgICBmbGFnIHN0b3JlIGFuZCBhIHByZWNlZGVuY2UuCgkgICBJZiA8VHVybj4gaXMgVFJVRSwgdGhlIGxlZnQgYW5kIHJpZ2h0IHRlcm0gb2YgdGhlCgkgICBlcXVhbGl0eSBhcmUgZXhjaGFuZ2VkLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIHRoZSBnaXZlbiBjbGF1c2UKICAgICAgICAgICBieSBtZXJnaW5nIHBhcmFtb2R1bGF0aW9uLgoJICAgVGhpcyBmdW5jdGlvbiBzZWFyY2hlcyBhIHNlY29uZCBjbGF1c2Ugd2l0aCBhdCBsZWFzdAoJICAgdHdvIHBvc2l0aXZlIGVxdWFsaXRpZXMsIHdoZXJlIHRoZSBmaXJzdCBlcXVhdGlvbgoJICAgaGFzIGEgc3VidGVybSBzJywgdGhhdCBpcyB1bmlmaWFibGUgd2l0aCB0aGUgbGVmdAoJICAgKG9yIHJpZ2h0KSBzaWRlIG9mIHRoZSBnaXZlbiBlcXVhdGlvbi4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgTElTVCAgICByZXN1bHQsIHVuaWZpZXJzLCBsaXRlcmFsczsKICBMSVRFUkFMIGFjdExpdDsKICBURVJNICAgIHMsIHQsIGhlbHA7CgogIGFjdExpdCA9IGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSwgaSk7CiAgcyAgICAgID0gdGVybV9GaXJzdEFyZ3VtZW50KGNsYXVzZV9MaXRlcmFsU2lnbmVkQXRvbShhY3RMaXQpKTsKICB0ICAgICAgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KGNsYXVzZV9MaXRlcmFsU2lnbmVkQXRvbShhY3RMaXQpKTsKICBpZiAoVHVybikgewogICAgLyogRXhjaGFuZ2UgcyBhbmQgdCAqLwogICAgaGVscCA9IHM7CiAgICBzICAgID0gdDsKICAgIHQgICAgPSBoZWxwOwogIH0KICByZXN1bHQgPSBsaXN0X05pbCgpOwoKICB1bmlmaWVycyA9IHN0X0dldFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCBzaGFyaW5nX0luZGV4KFNoSW5kZXgpLAoJCQkgICBjb250X1JpZ2h0Q29udGV4dCgpLCBzKTsKICAKICBmb3IgKCA7ICFsaXN0X0VtcHR5KHVuaWZpZXJzKTsgdW5pZmllcnMgPSBsaXN0X1BvcCh1bmlmaWVycykpIHsKICAgIFRFUk0gczIgPSAoVEVSTSkgbGlzdF9DYXIodW5pZmllcnMpOyAgICAgLyogVW5pZmlhYmxlIHdpdGggcyAqLwoKICAgIGlmICghdGVybV9Jc1ZhcmlhYmxlKHMyKSAmJiAhdGVybV9Jc0F0b20oczIpKSB7CiAgICAgIGZvciAobGl0ZXJhbHMgPSBzaGFyaW5nX0dldERhdGFMaXN0KHMyLCBTaEluZGV4KTsKCSAgICFsaXN0X0VtcHR5KGxpdGVyYWxzKTsKCSAgIGxpdGVyYWxzID0gbGlzdF9Qb3AobGl0ZXJhbHMpKSB7CglMSVRFUkFMIHBhcnRuZXJMaXQgICAgPSAoTElURVJBTCkgbGlzdF9DYXIobGl0ZXJhbHMpOyAgLyogdSA9IHZbcyddICovCglDTEFVU0UgIHBhcnRuZXJDbGF1c2UgPSBjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShwYXJ0bmVyTGl0KTsKCVRFUk0gICAgcGFydG5lckF0b20gICA9IGNsYXVzZV9MaXRlcmFsQXRvbShwYXJ0bmVyTGl0KTsKCWludCAgICAgcGxpICAgICAgICAgICA9IGNsYXVzZV9MaXRlcmFsR2V0SW5kZXgocGFydG5lckxpdCk7CgoJaWYgKCFjbGF1c2VfR2V0RmxhZyhwYXJ0bmVyQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpICYmCgkgICAgY2xhdXNlX0xpdGVyYWxHZXRGbGFnKHBhcnRuZXJMaXQsIFNUUklDVE1BWElNQUwpICYmCgkgICAgY2xhdXNlX0xpdGVyYWxJc1Bvc2l0aXZlKHBhcnRuZXJMaXQpICYmICAgLyogc3VjY2VkZW50IGxpdGVyYWwgKi8KCSAgICBjbGF1c2VfTGl0ZXJhbElzRXF1YWxpdHkocGFydG5lckxpdCkgJiYKCSAgICBjbGF1c2VfTnVtT2ZTdWNjTGl0cyhwYXJ0bmVyQ2xhdXNlKSA+IDEgJiYgLyogPiAxIHBvcy4gbGl0ZXJhbHMgKi8KCSAgICBjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChwYXJ0bmVyQ2xhdXNlKSkgewoJICBURVJNIHBhcnRuZXJMZWZ0ICAgID0gdGVybV9GaXJzdEFyZ3VtZW50KHBhcnRuZXJBdG9tKTsKCSAgVEVSTSBwYXJ0bmVyUmlnaHQgICA9IHRlcm1fU2Vjb25kQXJndW1lbnQocGFydG5lckF0b20pOwoJICBCT09MIGluUGFydG5lclJpZ2h0ID0gdGVybV9IYXNQb2ludGVyU3VidGVybShwYXJ0bmVyUmlnaHQsIHMyKTsKCgkgIGlmICghY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkocGFydG5lckxpdCkgfHwgaW5QYXJ0bmVyUmlnaHQpewoJICAgIC8qIERvbid0IGRvIHRoaXMgaWYgdT12IGlzIG9yaWVudGVkIGFuZCBzMiBpcyBub3QgYSBzdWJ0ZXJtIG9mIHYgKi8KCSAgICBURVJNICAgICAgIG5ld1BMZWZ0LCBuZXdQUmlnaHQ7CgkgICAgU1VCU1QgICAgICB0YXU7CgkgICAgU1lNQk9MICAgICBwYXJ0bmVyTWF4VmFyOwoJICAgIG9yZF9SRVNVTFQgb3JkUmVzdWx0OwoKCSAgICBwYXJ0bmVyTWF4VmFyID0gY2xhdXNlX01heFZhcihwYXJ0bmVyQ2xhdXNlKTsKCSAgICBjbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oQ2xhdXNlLCBwYXJ0bmVyTWF4VmFyKTsKCSAgICBjb250X0NoZWNrKCk7CgkgICAgdW5pZnlfVW5pZnlOb09DKGNvbnRfTGVmdENvbnRleHQoKSwgcywgY29udF9SaWdodENvbnRleHQoKSwgczIpOwoJICAgIHN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJnRhdSk7CgkgICAgY29udF9SZXNldCgpOwoKCSAgICBuZXdQTGVmdCAgPSBzdWJzdF9BcHBseSh0YXUsIHRlcm1fQ29weShwYXJ0bmVyTGVmdCkpOwoJICAgIG5ld1BSaWdodCA9IHN1YnN0X0FwcGx5KHRhdSwgdGVybV9Db3B5KHBhcnRuZXJSaWdodCkpOwoJICAgIGlmIChjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShwYXJ0bmVyTGl0KSkKCSAgICAgIG9yZFJlc3VsdCA9IG9yZF9HcmVhdGVyVGhhbigpOwoJICAgIGVsc2UKCSAgICAgIG9yZFJlc3VsdCA9IG9yZF9Db21wYXJlKG5ld1BMZWZ0LCBuZXdQUmlnaHQsIEZsYWdzLCBQcmVjZWRlbmNlKTsKCgkgICAgaWYgKGluUGFydG5lclJpZ2h0ICYmIG9yZF9Jc0dyZWF0ZXJUaGFuKG9yZFJlc3VsdCkpIHsKCSAgICAgIC8qIFRha2UgYSBsb29rIGF0IHJpZ2h0IHNpZGUgKi8KCSAgICAgIHJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0xpdDJNUGFyYW1vZChDbGF1c2UscGFydG5lckNsYXVzZSxpLHBsaSwKCQkJCQkJICAgcywgdCxzMixwYXJ0bmVyUmlnaHQsbmV3UExlZnQsCgkJCQkJCSAgIHRhdSwgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQkJICByZXN1bHQpOwoJICAgIH0KCSAgICBpZiAob3JkX0lzU21hbGxlclRoYW4ob3JkUmVzdWx0KSAmJgoJCSghaW5QYXJ0bmVyUmlnaHQgfHwgdGVybV9IYXNQb2ludGVyU3VidGVybShwYXJ0bmVyTGVmdCwgczIpKSkgewoJICAgICAgLyogSWYgczIgaXMgbm90IGluIHBhcnRuZXJSaWdodCwgaXQgTVVTVCBiZSBpbiBwYXJ0bmVyTGVmdCwKCQkgZWxzZSByZWFsbHkgZG8gdGhlIHRlc3QgKi8KCSAgICAgIC8qIFRha2UgYSBsb29rIGF0IGxlZnQgc2lkZSAqLwoJICAgICAgcmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfTGl0Mk1QYXJhbW9kKENsYXVzZSxwYXJ0bmVyQ2xhdXNlLGkscGxpLAoJCQkJCQkgICBzLHQsczIscGFydG5lckxlZnQsbmV3UFJpZ2h0LAoJCQkJCQkgICB0YXUsRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQkJICByZXN1bHQpOwoJICAgIH0KCgkgICAgdGVybV9EZWxldGUobmV3UExlZnQpOwoJICAgIHRlcm1fRGVsZXRlKG5ld1BSaWdodCk7CgkgICAgc3Vic3RfRGVsZXRlKHRhdSk7CgkgIH0KCX0KICAgICAgfSAgLyogZm9yIGFsbCBMaXRlcmFscyBjb250YWluaW5nIHMyICovCiAgICB9ICAgIC8qIGlmIHMyIGlzbid0IGEgdmFyaWFibGUgKi8KICB9ICAgICAgLyogZm9yIGFsbCB1bmlmaWVycyBzMiAqLwoKICByZXR1cm4gcmVzdWx0Owp9CgoKc3RhdGljIExJU1QgaW5mX01QYXJhbW9kTGl0VG9HaXZlbihDTEFVU0UgQ2xhdXNlLCBpbnQgaiwgQk9PTCBUdXJuLAoJCQkJICAgU0hBUkVEX0lOREVYIFNoSW5kZXgsIEZMQUdTVE9SRSBGbGFncywKCQkJCSAgIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2Ugd2l0aCBhIHN0cmljdCBtYXhpbWFsIGVxdWFsaXR5IGxpdGVyYWwgYXQKICAgICAgICAgICBwb3NpdGlvbiA8aj4sIGEgYm9vbGVhbiB2YWx1ZSwgYSBzaGFyZWQgaW5kZXggYSAKCSAgIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KCSAgIElmIDxUdXJuPiBpcyBUUlVFLCB0aGUgbGVmdCBhbmQgcmlnaHQgdGVybSBvZiB0aGUKCSAgIGVxdWFsaXR5IGFyZSBleGNoYW5nZWQuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gdGhlIGdpdmVuIGNsYXVzZQogICAgICAgICAgIGJ5IG1lcmdpbmcgcGFyYW1vZHVsYXRpb24gd2l0aCB0aGlzIGxpdGVyYWwgYXMgc2Vjb25kCgkgICBsaXRlcmFsIG9mIHRoZSBydWxlLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgIHJlc3VsdCwgdW5pZmllcnMsIHN1cGVydGVybXMsIGxpdGVyYWxzOwogIExJVEVSQUwgYWN0TGl0OwogIFRFUk0gICAgdSwgdjsKICBpbnQgICAgIGJvdHRvbTsKCiAgaWYgKGNsYXVzZV9OdW1PZlN1Y2NMaXRzKENsYXVzZSkgPCAyKQogICAgcmV0dXJuIGxpc3RfTmlsKCk7ICAvKiBUaGVyZSBtdXN0IGJlIGF0IGxlYXN0IHR3byBwb3NpdGl2ZSBsaXRlcmFscyAqLwoKICBhY3RMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsIGopOwogIHUgID0gdGVybV9GaXJzdEFyZ3VtZW50KGNsYXVzZV9MaXRlcmFsU2lnbmVkQXRvbShhY3RMaXQpKTsKICB2ID0gdGVybV9TZWNvbmRBcmd1bWVudChjbGF1c2VfTGl0ZXJhbFNpZ25lZEF0b20oYWN0TGl0KSk7CiAgaWYgKFR1cm4pIHsKICAgIC8qIEV4Y2hhbmdlIHMgYW5kIHQgKi8KICAgIFRFUk0gaGVscCA9IHU7CiAgICB1ICA9IHY7CiAgICB2ID0gaGVscDsKICB9CiAgcmVzdWx0ID0gbGlzdF9OaWwoKTsKICBib3R0b20gPSBzdGFja19Cb3R0b20oKTsKCiAgc2hhcmluZ19QdXNoUmV2ZXJzZU9uU3RhY2sodik7ICAvKiBXaXRob3V0IHZhcmlhYmxlcyEgKi8KCiAgd2hpbGUgKCFzdGFja19FbXB0eShib3R0b20pKSB7CiAgICBURVJNIHMyID0gKFRFUk0pIHN0YWNrX1BvcFJlc3VsdCgpOwoKICAgIGZvciAodW5pZmllcnMgPSBzdF9HZXRVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSxzaGFyaW5nX0luZGV4KFNoSW5kZXgpLAoJCQkJICBjb250X1JpZ2h0Q29udGV4dCgpLCBzMik7CgkgIWxpc3RfRW1wdHkodW5pZmllcnMpOwoJIHVuaWZpZXJzID0gbGlzdF9Qb3AodW5pZmllcnMpKSB7CiAgICAgIFRFUk0gcyA9IChURVJNKSBsaXN0X0Nhcih1bmlmaWVycyk7CgogICAgICBmb3IgKHN1cGVydGVybXMgPSB0ZXJtX1N1cGVydGVybUxpc3Qocyk7CgkgICAhbGlzdF9FbXB0eShzdXBlcnRlcm1zKTsKCSAgIHN1cGVydGVybXMgPSBsaXN0X0NkcihzdXBlcnRlcm1zKSkgewoJVEVSTSBwYXJ0bmVyQXRvbSA9IChURVJNKSBsaXN0X0NhcihzdXBlcnRlcm1zKTsKCglpZiAoZm9sX0lzRXF1YWxpdHkocGFydG5lckF0b20pKSB7CgkgIGZvciAobGl0ZXJhbHMgPSBzaGFyaW5nX05BdG9tRGF0YUxpc3QocGFydG5lckF0b20pOwoJICAgICAgICFsaXN0X0VtcHR5KGxpdGVyYWxzKTsKCSAgICAgICBsaXRlcmFscyA9IGxpc3RfQ2RyKGxpdGVyYWxzKSkgewoJICAgIExJVEVSQUwgcGFydG5lckxpdCAgICA9IChMSVRFUkFMKSBsaXN0X0NhcihsaXRlcmFscyk7CgkgICAgQ0xBVVNFICBwYXJ0bmVyQ2xhdXNlID0gY2xhdXNlX0xpdGVyYWxPd25pbmdDbGF1c2UocGFydG5lckxpdCk7CgkgICAgaW50ICAgICBpICAgICAgICAgICAgID0gY2xhdXNlX0xpdGVyYWxHZXRJbmRleChwYXJ0bmVyTGl0KTsKCgkgICAgaWYgKCFjbGF1c2VfR2V0RmxhZyhwYXJ0bmVyQ2xhdXNlLENMQVVTRVNFTEVDVCkgJiYKCQljbGF1c2VfTGl0ZXJhbEdldEZsYWcocGFydG5lckxpdCxTVFJJQ1RNQVhJTUFMKSAmJgoJCWNsYXVzZV9MaXRlcmFsSXNQb3NpdGl2ZShwYXJ0bmVyTGl0KSAmJgoJCShzID09IHRlcm1fRmlyc3RBcmd1bWVudChwYXJ0bmVyQXRvbSkgfHwKCQkgIWNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KHBhcnRuZXJMaXQpKSAmJgoJCWNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KHBhcnRuZXJDbGF1c2UpICYmCgkJY2xhdXNlX051bWJlcihwYXJ0bmVyQ2xhdXNlKSAhPSBjbGF1c2VfTnVtYmVyKENsYXVzZSkpIHsKCSAgICAgIC8qIFdlIGRvbid0IGFsbG93IHNlbGYgaW5mZXJlbmNlcyAoYm90aCBjbGF1c2VzIGhhdmluZyB0aGUgICAgICovCgkgICAgICAvKiBzYW1lIG51bWJlcikgaGVyZSwgYmVjYXVzZSB0aGV5J3JlIGFscmVhZHkgbWFkZSBpbiBmdW5jdGlvbiAqLwoJICAgICAgLyogaW5mX0xpdE1QYXJhbW9kLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSAgICAgIFNZTUJPTCBwYXJ0bmVyTWF4VmFyOwoJICAgICAgU1VCU1QgIHRhdTsKCSAgICAgIFRFUk0gICB1X3RhdSwgdl90YXU7CgkgICAgICBCT09MICAgY2hlY2tQYXNzZWQ7CgoJICAgICAgcGFydG5lck1heFZhciA9IGNsYXVzZV9NYXhWYXIocGFydG5lckNsYXVzZSk7CgkgICAgICBjbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oQ2xhdXNlLCBwYXJ0bmVyTWF4VmFyKTsKCSAgICAgIGNvbnRfQ2hlY2soKTsKCSAgICAgIHVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIHMsIGNvbnRfUmlnaHRDb250ZXh0KCksIHMyKTsKCSAgICAgIHN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJnRhdSk7CgkgICAgICBjb250X1Jlc2V0KCk7CgoJICAgICAgdV90YXUgPSB2X3RhdSA9IChURVJNKSBOVUxMOwoJICAgICAgY2hlY2tQYXNzZWQgPSBUUlVFOwoKCSAgICAgIC8qIHVfdGF1IG11c3QgYmUgZ3JlYXRlciB0aGFuIHZfdGF1ICovCgkgICAgICBpZiAoIWNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KGFjdExpdCkpIHsKCQl1X3RhdSA9IHN1YnN0X0FwcGx5KHRhdSwgdGVybV9Db3B5KHUpKTsKCQl2X3RhdSA9IHN1YnN0X0FwcGx5KHRhdSwgdGVybV9Db3B5KHYpKTsKCQlpZiAob3JkX0NvbXBhcmUodV90YXUsIHZfdGF1LCBGbGFncywgUHJlY2VkZW5jZSkgIT0gb3JkX0dyZWF0ZXJUaGFuKCkpCgkJICBjaGVja1Bhc3NlZCA9IEZBTFNFOwoJICAgICAgfQoKCSAgICAgIGlmIChjaGVja1Bhc3NlZCkgewoJCS8qIHVfdGF1ID4gdl90YXUgKi8KCQlURVJNIHQ7CgoJCWlmIChzID09IHRlcm1fRmlyc3RBcmd1bWVudChwYXJ0bmVyQXRvbSkpCgkJICB0ID0gdGVybV9TZWNvbmRBcmd1bWVudChwYXJ0bmVyQXRvbSk7CgkJZWxzZQoJCSAgdCA9IHRlcm1fRmlyc3RBcmd1bWVudChwYXJ0bmVyQXRvbSk7CgkJaWYgKHVfdGF1ID09IChURVJNKU5VTEwpIHsKCQkgIHVfdGF1ID0gc3Vic3RfQXBwbHkodGF1LCB0ZXJtX0NvcHkodSkpOwoJCSAgdl90YXUgPSBzdWJzdF9BcHBseSh0YXUsIHRlcm1fQ29weSh2KSk7CgkJfQoKCQlyZXN1bHQgPSBsaXN0X05jb25jKGluZl9MaXQyTVBhcmFtb2QocGFydG5lckNsYXVzZSxDbGF1c2UsaSxqLAoJCQkJCQkgICAgIHMsdCxzMix2LHVfdGF1LCB0YXUsRmxhZ3MsCgkJCQkJCSAgICAgUHJlY2VkZW5jZSksCgkJCQkgICAgcmVzdWx0KTsKCSAgICAgIH0KCgkgICAgICAvKiBOb3cgY2xlYW51cCAqLwoJICAgICAgaWYgKHVfdGF1ICE9IChURVJNKU5VTEwpIHsKCQl0ZXJtX0RlbGV0ZSh1X3RhdSk7CgkJdGVybV9EZWxldGUodl90YXUpOwoJICAgICAgfQoJICAgICAgc3Vic3RfRGVsZXRlKHRhdSk7CgkgICAgICBjbGF1c2VfTm9ybWFsaXplKENsYXVzZSk7CgkgICAgfQoJICB9Cgl9ICAgLyogcGFydG5lckF0b20gaXMgZXF1YWxpdHkgKi8KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKCkxJU1QgaW5mX01lcmdpbmdQYXJhbW9kdWxhdGlvbihDTEFVU0UgR2l2ZW5DbGF1c2UsIFNIQVJFRF9JTkRFWCBTaEluZGV4LAoJCQkgICAgICAgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlLCBhIHNoYXJlZCBpbmRleCwgYSBmbGFnIHN0b3JlIGFuZCBhIAogICAgICAgICAgIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gdGhlIGdpdmVuIGNsYXVzZQogICAgICAgICAgIGJ5IG1lcmdpbmcgcGFyYW1vZHVsYXRpb24uCiAgTUVNT1JZOiAgTWVtb3J5IGlzIGFsbG9jYXRlZCBmb3IgdGhlIGxpc3QgYW5kIHRoZSBjbGF1c2VzLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgcmVzdWx0OwogIENMQVVTRSBjb3B5OwogIGludCAgICBsYXN0LCBpOwogIAojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9NZXJnaW5nUGFyYW1vZHVsYXRpb246IElsbGVnYWwgaW5wdXQuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQojZW5kaWYKCiAgaWYgKGNsYXVzZV9HZXRGbGFnKEdpdmVuQ2xhdXNlLCBDTEFVU0VTRUxFQ1QpIHx8CiAgICAgIGNsYXVzZV9IYXNFbXB0eVN1Y2NlZGVudChHaXZlbkNsYXVzZSkgfHwKICAgICAgIWNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KEdpdmVuQ2xhdXNlKSkKICAgIHJldHVybiBsaXN0X05pbCgpOwoKICByZXN1bHQgPSBsaXN0X05pbCgpOwogIGNvcHkgICA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICBsYXN0ICAgPSBjbGF1c2VfTGFzdFN1Y2NlZGVudExpdEluZGV4KGNvcHkpOwoKICBmb3IgKGkgPSBjbGF1c2VfRmlyc3RTdWNjZWRlbnRMaXRJbmRleChjb3B5KTsgaSA8PSBsYXN0OyBpKyspIHsKICAgIExJVEVSQUwgYWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoY29weSwgaSk7CiAgICBURVJNICAgIGF0b20gICA9IGNsYXVzZV9MaXRlcmFsU2lnbmVkQXRvbShhY3RMaXQpOwogICAgCiAgICBpZiAoY2xhdXNlX0xpdGVyYWxHZXRGbGFnKGFjdExpdCwgU1RSSUNUTUFYSU1BTCkgJiYKCWZvbF9Jc0VxdWFsaXR5KGF0b20pKSB7CiAgICAgIAogICAgICByZXN1bHQgPSBsaXN0X05jb25jKGluZl9MaXRNUGFyYW1vZChjb3B5LGksRkFMU0UsU2hJbmRleCwKCQkJCQkgIEZsYWdzLCBQcmVjZWRlbmNlKSwgCgkJCSAgcmVzdWx0KTsKICAgICAgLyogQXNzdW1lIEdpdmVuQ2xhdXNlIGlzIHRoZSBzZWNvbmQgY2xhdXNlIG9mIHRoZSBydWxlICovCiAgICAgIHJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX01QYXJhbW9kTGl0VG9HaXZlbihjb3B5LGksRkFMU0UsU2hJbmRleCwKCQkJCQkJIEZsYWdzLCBQcmVjZWRlbmNlKSwKCQkJICByZXN1bHQpOwogICAgICAKICAgICAgaWYgKCFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShhY3RMaXQpKSB7CgkvKiBGaXJzdCBjaGVjayBydWxlIHdpdGggbGVmdCBhbmQgcmlnaHQgc2lkZSBleGNoYW5nZWQgKi8KCXJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0xpdE1QYXJhbW9kKGNvcHksIGksIFRSVUUsIFNoSW5kZXgsIAoJCQkJCSAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCSAgICByZXN1bHQpOwoJLyogTm93IGFzc3VtZSBHaXZlbkNsYXVzZSBpcyB0aGUgc2Vjb25kIGNsYXVzZSBvZiB0aGUgcnVsZSAqLwoJLyogQ2hlY2sgd2l0aCBzaWRlcyBleGNoYW5nZWQgKi8KCXJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX01QYXJhbW9kTGl0VG9HaXZlbihjb3B5LGksVFJVRSxTaEluZGV4LAoJCQkJCQkgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCSAgICByZXN1bHQpOwogICAgICB9CiAgICB9CiAgfSAgLyogZm9yICovCiAgY2xhdXNlX0RlbGV0ZShjb3B5KTsKCiAgcmV0dXJuIHJlc3VsdDsKfQoKCnN0YXRpYyBDTEFVU0UgaW5mX0FwcGx5R2VuUmVzKExJVEVSQUwgUG9zTGl0LCBMSVRFUkFMIE5lZ0xpdCwgU1VCU1QgU3Vic3RUZXJtUywKCQkJICAgICAgU1VCU1QgU3Vic3RQYXJ0bmVyVGVybVMsIEZMQUdTVE9SRSBGbGFncywgCgkJCSAgICAgIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2UgdG8gdXNlIGZvciBSZXNvbHV0aW9uLCB0aGUgaW5kZXggb2YgYSAKICAgICAgICAgICBwb3NpdGl2ZSBub24tZXF1YWxpdHkgbGl0ZXJhbCwgYSB1bmlmaWFibGUgbGl0ZXJhbCwKICAgICAgICAgICB0aGUgc3Vic3RpdHV0aW9ucyBmb3IgdGhlIHRlcm1zIHRvIHVuaWZ5LCBhIGZsYWcgCgkgICBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgY2xhdXNlIGRlcml2YWJsZSBmcm9tIHRoZSBsaXRlcmFscyBvd25pbmcKICAgICAgICAgICBjbGF1c2UgYnkgUmVzb2x1dGlvbiB3cnQuIHRoZSBJbmRleC4KICBNRU1PUlk6ICBNZW1vcnkgZm9yIHRoZSBuZXcgY2xhdXNlIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgQ0xBVVNFIE5ld0NsYXVzZSwgR2l2ZW5DbGF1c2UsIFBhcnRuZXJDbGF1c2U7CiAgaW50ICAgIGksaixsYyxsYSxscyxwaSxwbHMscGxhLHBsYyxoZWxwLENvbk5lZyxBbnROZWc7IC8qIHA9UGFydG5lcixsPWxhc3QgKi8KCiAgUGFydG5lckNsYXVzZSA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKE5lZ0xpdCk7CiAgR2l2ZW5DbGF1c2UgICA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKFBvc0xpdCk7CgogIHBscyA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoUGFydG5lckNsYXVzZSk7CiAgcGxhID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoUGFydG5lckNsYXVzZSk7CiAgcGxjID0gY2xhdXNlX0xhc3RDb25zdHJhaW50TGl0SW5kZXgoUGFydG5lckNsYXVzZSk7CgogIHBpICA9IGNsYXVzZV9MaXRlcmFsR2V0SW5kZXgoTmVnTGl0KTsKCiAgbHMgID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChHaXZlbkNsYXVzZSk7CiAgbGEgID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoR2l2ZW5DbGF1c2UpOwogIGxjICA9IGNsYXVzZV9MYXN0Q29uc3RyYWludExpdEluZGV4KEdpdmVuQ2xhdXNlKTsKCiAgaSAgID0gY2xhdXNlX0xpdGVyYWxHZXRJbmRleChQb3NMaXQpOwoKICBpZiAocGkgPD0gcGxjKSB7CiAgICBDb25OZWcgPSAxOwogICAgQW50TmVnID0gMDsKICB9CiAgZWxzZSB7CiAgICBDb25OZWcgPSAwOwogICAgQW50TmVnID0gMTsKICB9CgogIE5ld0NsYXVzZSA9IGNsYXVzZV9DcmVhdGVCb2R5KChjbGF1c2VfTGVuZ3RoKEdpdmVuQ2xhdXNlKSAtMSkgKwoJCQkJY2xhdXNlX0xlbmd0aChQYXJ0bmVyQ2xhdXNlKSAtMSk7CgogIGNsYXVzZV9TZXROdW1PZkNvbnNMaXRzKE5ld0NsYXVzZSwKCQkJICAgIChjbGF1c2VfTnVtT2ZDb25zTGl0cyhHaXZlbkNsYXVzZSkgKwoJCQkgICAgIChjbGF1c2VfTnVtT2ZDb25zTGl0cyhQYXJ0bmVyQ2xhdXNlKS1Db25OZWcpKSk7CiAgCiAgY2xhdXNlX1NldE51bU9mQW50ZUxpdHMoTmV3Q2xhdXNlLAoJCQkgICAgKGNsYXVzZV9OdW1PZkFudGVMaXRzKEdpdmVuQ2xhdXNlKSArCgkJCSAgICAgKGNsYXVzZV9OdW1PZkFudGVMaXRzKFBhcnRuZXJDbGF1c2UpLUFudE5lZykpKTsKICAKICBjbGF1c2VfU2V0TnVtT2ZTdWNjTGl0cyhOZXdDbGF1c2UsCgkJCSAgKChjbGF1c2VfTnVtT2ZTdWNjTGl0cyhHaXZlbkNsYXVzZSkgLTEpKwoJCQkgICBjbGF1c2VfTnVtT2ZTdWNjTGl0cyhQYXJ0bmVyQ2xhdXNlKSkpOwoKCiAgLyogRmlyc3Qgc2V0IHRoZSBsaXRlcmFscyBmcm9tIHRoZSBHaXZlbkNsYXVzZSA6ICovCiAgZm9yIChqID0gY2xhdXNlX0ZpcnN0TGl0SW5kZXgoKTsgaiA8PSBsYzsgaisrKSB7CiAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIGosIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdFRlcm1TLAoJdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShHaXZlbkNsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKICB9CgogIC8qIGhlbHAgPSBudW1iZXIgb2YgbGl0ZXJhbHMgdG8gbGVhdmUgZW1wdHkgKi8KICBoZWxwID0gY2xhdXNlX051bU9mQ29uc0xpdHMoUGFydG5lckNsYXVzZSktQ29uTmVnOwogICAgCiAgZm9yICggOyBqIDw9IGxhOyBqKyspIHsKICAgIGNsYXVzZV9TZXRMaXRlcmFsKE5ld0NsYXVzZSwgKGogKyBoZWxwKSwgCiAgICAgIGNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFN1YnN0VGVybVMsCgl0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKEdpdmVuQ2xhdXNlLCBqKSkpLE5ld0NsYXVzZSkpOwogIH0KCiAgLyogaGVscCA9IG51bWJlciBvZiBsaXRlcmFscyB0byBsZWF2ZSBlbXB0eSAqLwogIGhlbHAgKz0gY2xhdXNlX051bU9mQW50ZUxpdHMoUGFydG5lckNsYXVzZSktQW50TmVnOwogICAgCiAgCgogIGZvciAoIDsgaiA8PSBsczsgaisrKSB7CiAgICBpZiAoaiAhPSBpKSB7CiAgICAgIC8qIFRoZSBBY3RMaXQgaXNuJ3QgY29waWVkISAqLwogICAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIAoJY2xhdXNlX0xpdGVyYWxDcmVhdGUoc3Vic3RfQXBwbHkoU3Vic3RUZXJtUywKCSAgdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsVGVybShHaXZlbkNsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKCiAgICB9IGVsc2UgewogICAgICAvKnRoZSBpbmRleCBoYXMgdG8gYmUgZGVjcmVhc2VkIHRvIGF2b2lkIGFuIGVtcHR5IGxpdGVyYWwhICovCiAgICAgIGhlbHAtLTsKICAgIH0KICB9CgogIC8qIE5vdyB3ZSBjb25zaWRlciB0aGUgUGFydG5lckNsYXVzZSA6ICovCgogIC8qIGhlbHAgPSBudW1iZXIgb2YgYWxyZWFkeSBzZXQgY29uc3RyYWludCAoR2l2ZW5DbGF1c2UtKSBsaXRlcmFscyAqLwogIGhlbHAgPSBjbGF1c2VfTnVtT2ZDb25zTGl0cyhHaXZlbkNsYXVzZSk7CgogIGZvciAoaiA9IGNsYXVzZV9GaXJzdExpdEluZGV4KCk7IGogPD0gcGxjOyBqKyspIHsKICAgIGlmIChqICE9IHBpKSB7CiAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdFBhcnRuZXJUZXJtUywKCXRlcm1fQ29weShjbGF1c2VfR2V0TGl0ZXJhbFRlcm0oUGFydG5lckNsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKICAgIH0gZWxzZSB7CiAgICAgIGhlbHAtLTsKICAgIH0KICB9CgogIC8qIGhlbHAgPSBudW1iZXIgb2YgYWxyZWFkeSBzZXQgY29uc3RyYWludCBhbmQgYW50ZWNlZGVudCBHaXZlbi1saXRlcmFscyAqLwogIGhlbHAgKz0gY2xhdXNlX051bU9mQW50ZUxpdHMoR2l2ZW5DbGF1c2UpOwoKICBmb3IgKCA7IGogPD0gcGxhOyBqKyspIHsKCiAgICBpZiAoaiAhPSBwaSkgewogICAgICAvKiBUaGUgTmVnTGl0IGlzbid0IGNvcGllZCEgKi8KICAgICAgY2xhdXNlX1NldExpdGVyYWwoTmV3Q2xhdXNlLCAoaiArIGhlbHApLCAKCWNsYXVzZV9MaXRlcmFsQ3JlYXRlKHN1YnN0X0FwcGx5KFN1YnN0UGFydG5lclRlcm1TLAoJICB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxUZXJtKFBhcnRuZXJDbGF1c2UsIGopKSksTmV3Q2xhdXNlKSk7CgogICAgfSBlbHNlIHsKICAgICAgLyogVGhlIGluZGV4IGhhcyB0byBiZSBzaGlmdGVkIGFzIGFib3ZlLiAgKi8KICAgICAgaGVscC0tOwogICAgfQogIH0KCiAgLyogaGVscCA9IG51bWJlciBvZiBhbHJlYWR5IHNldCAoR2l2ZW5DbGF1c2UtKSBsaXRlcmFscyAqLwogIGhlbHAgKz0gY2xhdXNlX051bU9mU3VjY0xpdHMoR2l2ZW5DbGF1c2UpIC0gMTsKCiAgZm9yICggOyBqIDw9IHBsczsgaisrKSB7CiAgICBjbGF1c2VfU2V0TGl0ZXJhbChOZXdDbGF1c2UsIChqICsgaGVscCksIAogICAgICBjbGF1c2VfTGl0ZXJhbENyZWF0ZShzdWJzdF9BcHBseShTdWJzdFBhcnRuZXJUZXJtUywKCXRlcm1fQ29weShjbGF1c2VfR2V0TGl0ZXJhbFRlcm0oUGFydG5lckNsYXVzZSwgaikpKSxOZXdDbGF1c2UpKTsKICB9IC8qIGVuZCBvZiBOZXdDbGF1c2UgY3JlYXRpb24gKGxhc3QgZm9yIGxvb3ApLiAqLwoKCiAgY2xhdXNlX1NldERhdGFGcm9tUGFyZW50cyhOZXdDbGF1c2UsUGFydG5lckNsYXVzZSxwaSxHaXZlbkNsYXVzZSxpLAoJCQkgICAgRmxhZ3MsIFByZWNlZGVuY2UpOwogIGNsYXVzZV9TZXRGcm9tR2VuZXJhbFJlc29sdXRpb24oTmV3Q2xhdXNlKTsKCiAgcmV0dXJuKE5ld0NsYXVzZSk7Cn0KCgpMSVNUIGluZl9HZW5lcmFsUmVzb2x1dGlvbihDTEFVU0UgR2l2ZW5DbGF1c2UsIFNIQVJFRF9JTkRFWCBTaEluZGV4LAoJCQkgICBCT09MIE9yZGVyZWQsIEJPT0wgRXF1YXRpb25zLCAKCQkJICAgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlIGFuZCBhbiBJbmRleCwgdXN1YWxseSB0aGUgV29ya2VkT2ZmSW5kZXgsCiAgICAgICAgICAgdHdvIGJvb2xlYW4gZmxhZ3MsIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIHRoZSBHaXZlbkNsYXVzZSBieSAKICAgICAgICAgICBHZW5lcmFsUmVzb2x1dGlvbiB3cnQuIHRoZSBJbmRleC4KCSAgIElmIDxPcmRlcmVkPj1UUlVFLCB0aGlzIGZ1bmN0aW9uIGdlbmVyYXRlcyBvcmRlcmVkCgkgICByZXNvbHV0aW9uIGluZmVyZW5jZXMgKHRoZSBsaXRlcmFscyBtdXN0IGJlIHNlbGVjdGVkIG9yCgkgICAoc3RyaWN0KSBtYXhpbWFsKSwgb3RoZXJ3aXNlIGl0IGdlbmVyYXRlcyBzdGFuZGFyZAoJICAgcmVzb2x1dGlvbiBpbmZlcmVuY2VzLgoJICAgSWYgPEVxdWF0aW9ucz49VFJVRSwgZXF1YXRpb25zIGFyZSBhbGxvd2VkIGZvciBpbmZlcmVuY2VzLAoJICAgZWxzZSBubyBpbmZlcmVuY2VzIHdpdGggZXF1YXRpb25zIGFyZSBnZW5lcmF0ZWQuIFRoZQoJICAgZGVmYXVsdCBpcyA8RXF1YXRpb25zPj1GQUxTRS4uCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBDTEFVU0UgR2l2ZW5Db3B5OwogIExJU1QgUmVzdWx0OwogIExJVEVSQUwgQWN0TGl0OwogIFRFUk0gQXRvbTsKICBpbnQgaSxuOwoKI2lmZGVmIENIRUNLCiAgaWYgKCFjbGF1c2VfSXNDbGF1c2UoR2l2ZW5DbGF1c2UsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuZXJhbFJlc29sdXRpb246IElsbGVnYWwgaW5wdXQuIik7CiAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CiAgfQojZW5kaWYKCiAgaWYgKCFjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChHaXZlbkNsYXVzZSkpCiAgICByZXR1cm4gbGlzdF9OaWwoKTsKICAKICBSZXN1bHQgPSBsaXN0X05pbCgpOwogIEdpdmVuQ29weSA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICAKICBpZiAoY2xhdXNlX0dldEZsYWcoR2l2ZW5Db3B5LENMQVVTRVNFTEVDVCkpCiAgICBuID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoR2l2ZW5Db3B5KTsKICBlbHNlCiAgICBuID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChHaXZlbkNvcHkpOwogIAogIGZvciAoaSA9IGNsYXVzZV9GaXJzdEFudGVjZWRlbnRMaXRJbmRleChHaXZlbkNvcHkpOyBpIDw9IG47IGkrKykgewogICAgCiAgICBBY3RMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChHaXZlbkNvcHksIGkpOwogICAgQXRvbSAgID0gY2xhdXNlX0xpdGVyYWxBdG9tKEFjdExpdCk7CiAgICAKICAgIGlmICgoRXF1YXRpb25zIHx8ICFmb2xfSXNFcXVhbGl0eShBdG9tKSkgJiYKCShjbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LExJVFNFTEVDVCkgfHwKCSAoIWNsYXVzZV9HZXRGbGFnKEdpdmVuQ29weSxDTEFVU0VTRUxFQ1QpICYmCgkgICghT3JkZXJlZCB8fCBjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChBY3RMaXQpKSkpICYmCQoJKCFPcmRlcmVkIHx8IGNsYXVzZV9MaXRlcmFsSXNGcm9tQW50ZWNlZGVudChBY3RMaXQpIHx8IAoJIGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhBY3RMaXQsU1RSSUNUTUFYSU1BTCkpKSB7CiAgICAgIC8qIFBvc2l0aXZlIGxpdGVyYWxzIG11c3QgYmUgc3RyaWN0IG1heGltYWwgZm9yIE9SZSwgICAgICovCiAgICAgIC8qIG5lZ2F0aXZlIGxpdGVyYWxzIG11c3QgYmUgZWl0aGVyIHNlbGVjdGVkIG9yIG1heGltYWwuICovCiAgICAgIExJU1QgVGVybUxpc3Q7CiAgICAgIEJPT0wgU3dhcHBlZDsKCiAgICAgIFN3YXBwZWQgPSBGQUxTRTsKCiAgICAgIC8qIFRoZSAnZW5kbGVzcycgbG9vcCBtYXkgcnVuIHR3aWNlIGZvciBlcXVhdGlvbnMsIG9uY2UgZm9yIG90aGVyIGF0b21zICovCiAgICAgIHdoaWxlIChUUlVFKSB7CglUZXJtTGlzdCA9IHN0X0dldFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCBzaGFyaW5nX0luZGV4KFNoSW5kZXgpLAoJCQkJIGNvbnRfUmlnaHRDb250ZXh0KCksIEF0b20pOwoJCglmb3IgKCA7ICFsaXN0X0VtcHR5KFRlcm1MaXN0KTsgVGVybUxpc3QgPSBsaXN0X1BvcChUZXJtTGlzdCkpIHsKCSAgTElTVCBMaXRMaXN0OwoJICBURVJNIFBhcnRuZXJBdG9tOwoJICAKCSAgUGFydG5lckF0b20gPSBsaXN0X0ZpcnN0KFRlcm1MaXN0KTsKCSAgCgkgIGlmICghdGVybV9Jc1ZhcmlhYmxlKFBhcnRuZXJBdG9tKSkgewkgIAoJICAgIExJVEVSQUwgUGFydG5lckxpdDsKCSAgICBpbnQgICAgIGo7CgkgICAgQ0xBVVNFICBQYXJ0bmVyQ2xhdXNlOwoJICAgIAoJICAgIGZvciAoTGl0TGlzdCA9ICBzaGFyaW5nX05BdG9tRGF0YUxpc3QoUGFydG5lckF0b20pOyAKCQkgIWxpc3RfRW1wdHkoTGl0TGlzdCk7ICBMaXRMaXN0ID0gbGlzdF9DZHIoTGl0TGlzdCkpIHsKCSAgICAgIFBhcnRuZXJMaXQgICAgPSBsaXN0X0NhcihMaXRMaXN0KTsKCSAgICAgIGogICAgICAgICAgICAgPSBjbGF1c2VfTGl0ZXJhbEdldEluZGV4KFBhcnRuZXJMaXQpOwoJICAgICAgUGFydG5lckNsYXVzZSA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKFBhcnRuZXJMaXQpOwoJICAgICAgCgkgICAgICBpZiAoY2xhdXNlX0xpdGVyYWxzQXJlQ29tcGxlbWVudGFyeShQYXJ0bmVyTGl0LEFjdExpdCkgJiYKCQkgIGNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KFBhcnRuZXJDbGF1c2UpICYmCgkJICAvKiBOZWdhdGl2ZSBsaXRlcmFscyBtdXN0IGJlIGZyb20gdGhlIGFudGVjZWRlbnQgKi8KCQkgIChjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgfHwKCQkgICBjbGF1c2VfTGl0ZXJhbElzRnJvbUFudGVjZWRlbnQoUGFydG5lckxpdCkpICYmCgkJICAvKiBDaGVjayB3aGV0aGVyIGxpdGVyYWwgaXMgc2VsZWN0ZWQgb3IgbWF4aW1hbCAqLwoJCSAgKGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhQYXJ0bmVyTGl0LExJVFNFTEVDVCkgfHwKCQkgICAoIWNsYXVzZV9HZXRGbGFnKFBhcnRuZXJDbGF1c2UsQ0xBVVNFU0VMRUNUKSAmJgoJCSAgICAoIU9yZGVyZWQgfHwgY2xhdXNlX0xpdGVyYWxJc01heGltYWwoUGFydG5lckxpdCkpKSkgJiYKCQkgIC8qIFBvc2l0aXZlIGxpdGVyYWxzIG11c3QgYmUgc3RyaWN0IG1heGltYWwgZm9yIE9SZSAqLyAKCQkgICghT3JkZXJlZCB8fCBjbGF1c2VfTGl0ZXJhbElzTmVnYXRpdmUoUGFydG5lckxpdCkgfHwgCgkJICAgY2xhdXNlX0xpdGVyYWxHZXRGbGFnKFBhcnRuZXJMaXQsU1RSSUNUTUFYSU1BTCkpICYmCgkJICAvKiBBdm9pZCBkdXBsaWNhdGUgc2VsZi1pbmZlcmVuY2VzICovCgkJICAoY2xhdXNlX0xpdGVyYWxJc1Bvc2l0aXZlKFBhcnRuZXJMaXQpIHx8CgkJICAgY2xhdXNlX051bWJlcihHaXZlbkNsYXVzZSkgIT0gY2xhdXNlX051bWJlcihQYXJ0bmVyQ2xhdXNlKSkpIHsKCQlTVUJTVCAgU3Vic3QsIFBhcnRuZXJTdWJzdDsKCQlTWU1CT0wgTWF4VmFyOwoJCQoJCU1heFZhciA9IGNsYXVzZV9NYXhWYXIoUGFydG5lckNsYXVzZSk7CgkJY2xhdXNlX1JlbmFtZVZhcnNCaWdnZXJUaGFuKEdpdmVuQ29weSwgTWF4VmFyKTsKCgkJY29udF9DaGVjaygpOwoJCWlmICghdW5pZnlfVW5pZnlOb09DKGNvbnRfTGVmdENvbnRleHQoKSwgQXRvbSwgY29udF9SaWdodENvbnRleHQoKSwKCQkJCSAgICAgUGFydG5lckF0b20pKSB7CgkJICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKCQkgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZW5lcmFsUmVzb2x1dGlvbjogVW5pZmljYXRpb24gZmFpbGVkLiIpOwoJCSAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwoJCX0KCQlzdWJzdF9FeHRyYWN0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksICZTdWJzdCwKCQkJCSAgICAgY29udF9SaWdodENvbnRleHQoKSwgJlBhcnRuZXJTdWJzdCk7CgkJY29udF9SZXNldCgpOwoJCQoJCWlmICghT3JkZXJlZCB8fAoJCSAgICBpbmZfTGl0ZXJhbHNNYXgoR2l2ZW5Db3B5LCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgaiwKCQkJCSAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJCSAgaWYgKGNsYXVzZV9MaXRlcmFsSXNOZWdhdGl2ZShQYXJ0bmVyTGl0KSkKCQkgICAgUmVzdWx0ID0gbGlzdF9Db25zKGluZl9BcHBseUdlblJlcyhBY3RMaXQsUGFydG5lckxpdCxTdWJzdCwKCQkJCQkJICAgICAgIFBhcnRuZXJTdWJzdCwKCQkJCQkJICAgICAgIEZsYWdzLCBQcmVjZWRlbmNlKSwKCQkJCSAgICAgICBSZXN1bHQpOwoJCSAgZWxzZQoJCSAgICBSZXN1bHQgPSBsaXN0X0NvbnMoaW5mX0FwcGx5R2VuUmVzKFBhcnRuZXJMaXQsIEFjdExpdCwgCgkJCQkJCSAgICAgICBQYXJ0bmVyU3Vic3QsU3Vic3QsCgkJCQkJCSAgICAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCQkgICAgICAgUmVzdWx0KTsKCQl9CgkJc3Vic3RfRGVsZXRlKFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCSAgICAgIH0KCSAgICB9IC8qIGVuZCBvZiBmb3IgKExpdExpc3QgPSBzaGFyaW5nX05BdG9tRGF0YUxpc3QgLi4uKS4gKi8KCSAgfSAvKiBlbmQgb2YgaWYgKCF0ZXJtX0lzVmFyaWFibGUoUGFydG5lckF0b20pKS4gKi8KCX0gLyogZW5kIG9mIGZvciAoVGVybUxpc3QgPSBzdF9HZXRVbmlmaWVyLi4uKS4gKi8KCWlmICghU3dhcHBlZCAmJiBmb2xfSXNFcXVhbGl0eShBdG9tKSkgewoJICB0ZXJtX0VxdWFsaXR5U3dhcChBdG9tKTsgICAgICAgICAvKiBBdG9tIGlzIGZyb20gY29waWVkIGNsYXVzZSAqLwoJICBTd2FwcGVkID0gVFJVRTsKCX0gZWxzZQoJICBicmVhazsKICAgICAgfSAvKiBlbmQgb2YgJ2VuZGxlc3MnIGxvb3AgKi8KICAgIH0gLyogZW5kIG9mIGlmIChjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChBY3RMaXQpKS4gKi8KICB9IC8qIGVuZCBvZiBmb3IgJ2FsbCBhbnRlY2VkZW50IGFuZCBzdWNjZWRlbnQgbGl0ZXJhbHMnLiAqLwogIAogIGNsYXVzZV9EZWxldGUoR2l2ZW5Db3B5KTsKICAKICByZXR1cm4gUmVzdWx0Owp9CgoKTElTVCBpbmZfVW5pdFJlc29sdXRpb24oQ0xBVVNFIEdpdmVuQ2xhdXNlLCBTSEFSRURfSU5ERVggU2hJbmRleCwKCQkJQk9PTCBFcXVhdGlvbnMsIEZMQUdTVE9SRSBGbGFncywKCQkJUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSBhbmQgYW4gSW5kZXgsIHVzdWFsbHkgdGhlIFdvcmtlZE9mZkluZGV4LAogICAgICAgICAgIGEgYm9vbGVhbiBmbGFnLCBhIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIGxpc3Qgb2YgY2xhdXNlcyBkZXJpdmFibGUgZnJvbSB0aGUgR2l2ZW5jbGF1c2UgYnkgCiAgICAgICAgICAgVW5pdCBSZXNvbHV0aW9uIHdydC4gdGhlIEluZGV4LgoJICAgVGhpcyBmdW5jdGlvbiBkb2VzIHRoZSBzYW1lIGluZmVyZW5jZXMgYXMgc3RhbmRhcmQgcmVzb2x1dGlvbiwKCSAgIGV4Y2VwdCB0aGF0IGF0IGxlYXN0IG9uZSBvZiB0aGUgY2xhdXNlcyBtdXN0IGJlIGEgdW5pdCBjbGF1c2UuCgkgICBUaGUgaW52b2x2ZWQgbGl0ZXJhbHMgZG9uJ3QgaGF2ZSB0byBiZSBtYXhpbWFsLgoJICAgSWYgPEVxdWF0aW9ucz49VFJVRSwgZXF1YXRpb25zIGFyZSBhbGxvd2VkIGZvciBpbmZlcmVuY2VzLAoJICAgZWxzZSBubyBpbmZlcmVuY2VzIHdpdGggZXF1YXRpb25zIGFyZSBtYWRlLiBUaGUKCSAgIGRlZmF1bHQgaXMgPEVxdWF0aW9ucz49RkFMU0UuLgogIE1FTU9SWTogIEEgbGlzdCBvZiBjbGF1c2VzIGlzIHByb2R1Y2VkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZSBsaXN0CiAgICAgICAgICAgYW5kIHRoZSBjbGF1c2VzIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgQ0xBVVNFICAgR2l2ZW5Db3B5OwogIExJU1QgICAgIFJlc3VsdDsKICBMSVRFUkFMICBBY3RMaXQ7CiAgVEVSTSAgICAgQXRvbTsKICBCT09MICAgICBHaXZlbklzVW5pdDsKICBpbnQgICAgICBpLG47CgojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9Vbml0UmVzb2x1dGlvbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBpZiAoIWNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KEdpdmVuQ2xhdXNlKSkKICAgIHJldHVybiBsaXN0X05pbCgpOwogICAgCiAgUmVzdWx0ID0gbGlzdF9OaWwoKTsKICAKICBHaXZlbkNvcHkgICA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICBHaXZlbklzVW5pdCA9IChjbGF1c2VfTGVuZ3RoKEdpdmVuQ29weSkgPT0gMSk7CiAgCiAgaWYgKGNsYXVzZV9HZXRGbGFnKEdpdmVuQ29weSxDTEFVU0VTRUxFQ1QpKQogICAgbiA9IGNsYXVzZV9MYXN0QW50ZWNlZGVudExpdEluZGV4KEdpdmVuQ29weSk7CiAgZWxzZQogICAgbiA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoR2l2ZW5Db3B5KTsKICAKICBmb3IgKGk9Y2xhdXNlX0ZpcnN0QW50ZWNlZGVudExpdEluZGV4KEdpdmVuQ29weSk7IGkgPD0gbjsgaSsrKSB7CiAgICAKICAgIEFjdExpdCA9IGNsYXVzZV9HZXRMaXRlcmFsKEdpdmVuQ29weSwgaSk7CiAgICBBdG9tICAgPSBjbGF1c2VfTGl0ZXJhbEF0b20oQWN0TGl0KTsKICAgIAogICAgaWYgKChFcXVhdGlvbnMgfHwgIWZvbF9Jc0VxdWFsaXR5KEF0b20pKSAmJgoJKGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhBY3RMaXQsTElUU0VMRUNUKSB8fAoJICFjbGF1c2VfR2V0RmxhZyhHaXZlbkNvcHksQ0xBVVNFU0VMRUNUKSkpIHsKICAgICAgTElTVCBUZXJtTGlzdDsKICAgICAgQk9PTCBTd2FwcGVkOwogICAgICAKICAgICAgU3dhcHBlZCA9IEZBTFNFOwoKICAgICAgLyogVGhlICdlbmRsZXNzJyBsb29wIHJ1bnMgdHdpY2UgZm9yIGVxdWF0aW9ucywgb25jZSBmb3Igb3RoZXIgYXRvbXMgKi8KICAgICAgd2hpbGUgKFRSVUUpIHsKCVRlcm1MaXN0ID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksIHNoYXJpbmdfSW5kZXgoU2hJbmRleCksCgkJCQkgY29udF9SaWdodENvbnRleHQoKSwgQXRvbSk7CgkKCWZvciAoIDsgIWxpc3RfRW1wdHkoVGVybUxpc3QpOyBUZXJtTGlzdCA9IGxpc3RfUG9wKFRlcm1MaXN0KSkgewoJICBMSVNUIExpdExpc3Q7CgkgIFRFUk0gUGFydG5lckF0b207CgkgIAoJICBQYXJ0bmVyQXRvbSA9IGxpc3RfRmlyc3QoVGVybUxpc3QpOwoJICAKCSAgaWYgKCF0ZXJtX0lzVmFyaWFibGUoUGFydG5lckF0b20pKSB7CgkgICAgTElURVJBTCBQYXJ0bmVyTGl0OwoJICAgIENMQVVTRSAgUGFydG5lckNsYXVzZTsKCSAgICAKCSAgICBmb3IgKExpdExpc3QgPSAgc2hhcmluZ19OQXRvbURhdGFMaXN0KFBhcnRuZXJBdG9tKTsgCgkJICFsaXN0X0VtcHR5KExpdExpc3QpOyAgTGl0TGlzdCA9IGxpc3RfQ2RyKExpdExpc3QpKSB7CgkgICAgICBQYXJ0bmVyTGl0ICAgID0gbGlzdF9DYXIoTGl0TGlzdCk7CgkgICAgICBQYXJ0bmVyQ2xhdXNlID0gY2xhdXNlX0xpdGVyYWxPd25pbmdDbGF1c2UoUGFydG5lckxpdCk7CgkgICAgICAKCSAgICAgIGlmICgoR2l2ZW5Jc1VuaXQgfHwgY2xhdXNlX0xlbmd0aChQYXJ0bmVyQ2xhdXNlKSA9PSAxKSAmJgoJCSAgY2xhdXNlX0xpdGVyYWxzQXJlQ29tcGxlbWVudGFyeShQYXJ0bmVyTGl0LEFjdExpdCkgJiYKCQkgIGNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KFBhcnRuZXJDbGF1c2UpICYmCgkJICAvKiBOZWdhdGl2ZSBsaXRlcmFscyBtdXN0IGJlIGZyb20gdGhlIGFudGVjZWRlbnQgKi8KCQkgIChjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgfHwKCQkgICBjbGF1c2VfTGl0ZXJhbElzRnJvbUFudGVjZWRlbnQoUGFydG5lckxpdCkpICYmCgkJICAvKiBFaXRoZXIgdGhlIGxpdGVyYWwgaXMgc2VsZWN0ZWQgb3Igbm8gbGl0ZXJhbCBpcyBzZWxlY3RlZCAqLwoJCSAgKGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhQYXJ0bmVyTGl0LExJVFNFTEVDVCkgfHwKCQkgICAhY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSxDTEFVU0VTRUxFQ1QpKSkgewoJCS8qIFNlbGYtaW5mZXJlbmNlcyBhcmVuJ3QgcG9zc2libGUsIHNpbmNlIHRoZW4gdGhlIGNsYXVzZSBtdXN0ICovCgkJLyogYmUgYSB1bml0IGFuZCBhIHNpbmdsZSBsaXRlcmFsIGNhbid0IGJlIGJvdGggcG9zaXRpdmUgYW5kICAgKi8KCQkvKiBuZWdhdGl2ZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoJCVNVQlNUICBTdWJzdCwgUGFydG5lclN1YnN0OwoJCVNZTUJPTCBNYXhWYXI7CgkJCgkJTWF4VmFyID0gY2xhdXNlX01heFZhcihQYXJ0bmVyQ2xhdXNlKTsKCQljbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oR2l2ZW5Db3B5LCBNYXhWYXIpOwoJCQoJCWNvbnRfQ2hlY2soKTsKCQlpZiAoIXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIEF0b20sCgkJCQkgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksIFBhcnRuZXJBdG9tKSkgewoJCSAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CgkJICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfVW5pdFJlc29sdXRpb246IFVuaWZpY2F0aW9uIGZhaWxlZC4iKTsKCQkgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKCQl9CgkJc3Vic3RfRXh0cmFjdFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCAmU3Vic3QsCgkJCQkgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksICZQYXJ0bmVyU3Vic3QpOwoJCWNvbnRfUmVzZXQoKTsKCQkKCQlpZiAoY2xhdXNlX0xpdGVyYWxJc05lZ2F0aXZlKFBhcnRuZXJMaXQpKQoJCSAgUmVzdWx0ID0gbGlzdF9Db25zKGluZl9BcHBseUdlblJlcyhBY3RMaXQsIFBhcnRuZXJMaXQsIFN1YnN0LAoJCQkJCQkgICAgIFBhcnRuZXJTdWJzdCwKCQkJCQkJICAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCQkgICAgIFJlc3VsdCk7CgkJZWxzZQoJCSAgUmVzdWx0ID0gbGlzdF9Db25zKGluZl9BcHBseUdlblJlcyhQYXJ0bmVyTGl0LCBBY3RMaXQsIAoJCQkJCQkgICAgIFBhcnRuZXJTdWJzdCxTdWJzdCwKCQkJCQkJICAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCQkgICAgIFJlc3VsdCk7CgkJc3Vic3RfRGVsZXRlKFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCSAgICAgIH0KCSAgICB9IC8qIGVuZCBvZiBmb3IgKExpdExpc3QgPSBzaGFyaW5nX05BdG9tRGF0YUxpc3QgLi4uKS4gKi8KCSAgfSAvKiBlbmQgb2YgaWYgKCF0ZXJtX0lzVmFyaWFibGUoUGFydG5lckF0b20pKS4gKi8KCX0gLyogZW5kIG9mIGZvciAoVGVybUxpc3QgPSBzdF9HZXRVbmlmaWVyLi4uKS4gKi8KCWlmICghU3dhcHBlZCAmJiBmb2xfSXNFcXVhbGl0eShBdG9tKSkgewoJICB0ZXJtX0VxdWFsaXR5U3dhcChBdG9tKTsgICAgICAgIC8qIEF0b20gaXMgZnJvbSBjb3BpZWQgY2xhdXNlICovCgkgIFN3YXBwZWQgPSBUUlVFOwoJfSBlbHNlCgkgIGJyZWFrOwogICAgICB9IC8qIGVuZCBvZiAnZW5kbGVzcycgbG9vcCAqLwogICAgfSAvKiBlbmQgb2YgaWYgKGNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKEFjdExpdCkpLiAqLwogIH0gLyogZW5kIG9mIGZvciAnYWxsIGFudGVjZWRlbnQgYW5kIHN1Y2NlZGVudCBsaXRlcmFscycuICovCiAgCiAgY2xhdXNlX0RlbGV0ZShHaXZlbkNvcHkpOwogIAogIHJldHVybiBSZXN1bHQ7Cn0KCkxJU1QgaW5mX0JvdW5kZWREZXB0aFVuaXRSZXNvbHV0aW9uKENMQVVTRSBHaXZlbkNsYXVzZSwgU0hBUkVEX0lOREVYIFNoSW5kZXgsCgkJCQkgICAgQk9PTCBDb25DbGF1c2UsIEZMQUdTVE9SRSBGbGFncywKCQkJCSAgICBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlIGFuZCBhbiBJbmRleCwgdXN1YWxseSB0aGUgV29ya2VkT2ZmSW5kZXgsCiAgICAgICAgICAgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgcGFydG5lciBjbGF1c2UgbXVzdCBiZQoJICAgYSBjb25qZWN0dXJlIGNsYXVzZSwgYSBmbGFnIHN0b3JlIGFuZCBhIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gdGhlIEdpdmVuY2xhdXNlIGJ5IAogICAgICAgICAgIGJvdW5kZWQgZGVwdGggdW5pdCByZXNvbHV0aW9uIHdydC4gdGhlIEluZGV4LgoJICAgVGhpcyBhY3RzIHNpbWlsYXIgdG8gaW5mX1VuaXRSZXNvbHV0aW9uLCBleGNlcHQgdGhhdAoJICAgaXQgbGltaXRzIHRoZSBkZXB0aCBvZiByZXNvbHZlbnRzIHRvIHRoZSBtYXhpbXVtIAoJICAgZGVwdGggb2YgaXRzIHBhcmVudCBjbGF1c2VzLgogIE1FTU9SWTogIEEgbGlzdCBvZiBjbGF1c2VzIGlzIHByb2R1Y2VkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZSAKICAgICAgICAgICBsaXN0IGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAvKiBHaXZlbkNsYXVzZSBpcyBhbHdheXMgYSBDT05DTEFVU0UgKi8KewogIENMQVVTRSAgR2l2ZW5Db3B5OwogIExJU1QgICAgUmVzdWx0OwogIExJVEVSQUwgQWN0TGl0OwogIFRFUk0gICAgQXRvbTsKICBpbnQgICAgIGksbixkZXB0aDsKCiNpZmRlZiBDSEVDSwogIGlmICghY2xhdXNlX0lzQ2xhdXNlKEdpdmVuQ2xhdXNlLCBGbGFncywgUHJlY2VkZW5jZSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0JvdW5kZWREZXB0aFVuaXRSZXNvbHV0aW9uOiBJbGxlZ2FsIGlucHV0LiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KICBjb250X0NoZWNrKCk7CiNlbmRpZgoKICBSZXN1bHQgICAgPSBsaXN0X05pbCgpOwogIEdpdmVuQ29weSA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICBuICAgICAgICAgPSBjbGF1c2VfTGFzdExpdEluZGV4KEdpdmVuQ29weSk7CiAgZGVwdGggICAgID0gY2xhdXNlX0NvbXB1dGVUZXJtRGVwdGgoR2l2ZW5Db3B5KTsKCiAgZm9yIChpID0gY2xhdXNlX0ZpcnN0TGl0SW5kZXgoKTsgaSA8PSBuOyBpKyspIHsKICAgIExJU1QgVGVybUxpc3Q7CiAgICBCT09MIFN3YXBwZWQ7CgogICAgQWN0TGl0ICAgPSBjbGF1c2VfR2V0TGl0ZXJhbChHaXZlbkNvcHksIGkpOwogICAgQXRvbSAgICAgPSBjbGF1c2VfTGl0ZXJhbEF0b20oQWN0TGl0KTsKICAgIFN3YXBwZWQgID0gRkFMU0U7CgogICAgLyogVGhlICdlbmRsZXNzJyBsb29wIHJ1bnMgdHdpY2UgZm9yIGVxdWF0aW9ucywgb25jZSBmb3Igb3RoZXIgYXRvbXMgKi8KICAgIHdoaWxlIChUUlVFKSB7CiAgICAgIFRlcm1MaXN0ID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksIHNoYXJpbmdfSW5kZXgoU2hJbmRleCksCgkJCSAgICAgICBjb250X1JpZ2h0Q29udGV4dCgpLCBBdG9tKTsKCiAgICAgIGZvciAoIDsgIWxpc3RfRW1wdHkoVGVybUxpc3QpOyBUZXJtTGlzdCA9IGxpc3RfUG9wKFRlcm1MaXN0KSkgewoJTElTVCBMaXRMaXN0OwoJVEVSTSBQYXJ0bmVyQXRvbTsKCQoJUGFydG5lckF0b20gPSBsaXN0X0ZpcnN0KFRlcm1MaXN0KTsKCQoJaWYgKCF0ZXJtX0lzVmFyaWFibGUoUGFydG5lckF0b20pKSB7CgkgIExJVEVSQUwgUGFydG5lckxpdDsKCSAgQ0xBVVNFICBQYXJ0bmVyQ2xhdXNlOwoJICAKCSAgZm9yIChMaXRMaXN0ID0gc2hhcmluZ19OQXRvbURhdGFMaXN0KFBhcnRuZXJBdG9tKTsKCSAgICAgICAhbGlzdF9FbXB0eShMaXRMaXN0KTsgTGl0TGlzdCA9IGxpc3RfQ2RyKExpdExpc3QpKSB7CgkgICAgUGFydG5lckxpdCAgICA9IGxpc3RfQ2FyKExpdExpc3QpOwoJICAgIFBhcnRuZXJDbGF1c2UgPSBjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShQYXJ0bmVyTGl0KTsKCSAgICAKCSAgICBpZiAoY2xhdXNlX0xpdGVyYWxzQXJlQ29tcGxlbWVudGFyeShQYXJ0bmVyTGl0LEFjdExpdCkgJiYKCQkoY2xhdXNlX0xlbmd0aChHaXZlbkNvcHkpPT0xIHx8IGNsYXVzZV9MZW5ndGgoUGFydG5lckNsYXVzZSk9PTEpICYmCgkJKGNsYXVzZV9HZXRGbGFnKEdpdmVuQ29weSxDT05DTEFVU0UpIHx8CgkJIGNsYXVzZV9HZXRGbGFnKFBhcnRuZXJDbGF1c2UsQ09OQ0xBVVNFKSkgJiYKCQkoIUNvbkNsYXVzZSB8fCBjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLENPTkNMQVVTRSkpKSB7CgkgICAgICBTVUJTVCAgU3Vic3QsIFBhcnRuZXJTdWJzdDsKCSAgICAgIFNZTUJPTCBNYXhWYXI7CgkgICAgICBpbnQgICAgbWF4ZGVwdGg7CgkgICAgICBDTEFVU0UgUmVzb2x2ZW50OwoJICAgICAgCgkgICAgICBtYXhkZXB0aCA9IG1pc2NfTWF4KGRlcHRoLCBjbGF1c2VfQ29tcHV0ZVRlcm1EZXB0aChQYXJ0bmVyQ2xhdXNlKSk7CgkgICAgICBNYXhWYXIgICA9IGNsYXVzZV9NYXhWYXIoUGFydG5lckNsYXVzZSk7CgkgICAgICBjbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oR2l2ZW5Db3B5LCBNYXhWYXIpOwoJICAgICAgCgkgICAgICBjb250X0NoZWNrKCk7CgkgICAgICBpZiAoIXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIEF0b20sCgkJCQkgICBjb250X1JpZ2h0Q29udGV4dCgpLCBQYXJ0bmVyQXRvbSkpIHsKCQltaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKCQltaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfQm91bmRlZERlcHRoVW5pdFJlc29sdXRpb246IFVuaWZpY2F0aW9uIGZhaWxlZC4iKTsKCQltaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CgkgICAgICB9CgkgICAgICBzdWJzdF9FeHRyYWN0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksICZTdWJzdCwKCQkJCSAgIGNvbnRfUmlnaHRDb250ZXh0KCksICZQYXJ0bmVyU3Vic3QpOwoJICAgICAgY29udF9SZXNldCgpOwoJICAgICAgCgkgICAgICBpZiAoY2xhdXNlX0xpdGVyYWxJc05lZ2F0aXZlKFBhcnRuZXJMaXQpKQoJCVJlc29sdmVudCA9IGluZl9BcHBseUdlblJlcyhBY3RMaXQsIFBhcnRuZXJMaXQsIFN1YnN0LAoJCQkJCSAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKTsKCSAgICAgIGVsc2UKCQlSZXNvbHZlbnQgPSBpbmZfQXBwbHlHZW5SZXMoUGFydG5lckxpdCwgQWN0TGl0LCBQYXJ0bmVyU3Vic3QsCgkJCQkJICAgIFN1YnN0LCBGbGFncywgUHJlY2VkZW5jZSk7CgoJICAgICAgaWYgKGNsYXVzZV9Db21wdXRlVGVybURlcHRoKFJlc29sdmVudCkgPiBtYXhkZXB0aCkKCQljbGF1c2VfRGVsZXRlKFJlc29sdmVudCk7CgkgICAgICBlbHNlIHsKCQlSZXN1bHQgPSBsaXN0X0NvbnMoUmVzb2x2ZW50LFJlc3VsdCk7CgkgICAgICB9CgkgICAgICBzdWJzdF9EZWxldGUoU3Vic3QpOwoJICAgICAgc3Vic3RfRGVsZXRlKFBhcnRuZXJTdWJzdCk7CgkgICAgfQoJICB9Cgl9CiAgICAgIH0KICAgICAgaWYgKCFTd2FwcGVkICYmIGZvbF9Jc0VxdWFsaXR5KEF0b20pKSB7Cgl0ZXJtX0VxdWFsaXR5U3dhcChBdG9tKTsgICAgICAgICAgICAgIC8qIEdpdmVuIENsYXVzZSBpcyBhIGNvcHkgKi8KCVN3YXBwZWQgPSBUUlVFOwogICAgICB9IGVsc2UKCWJyZWFrOwogICAgfSAvKiBlbmQgb2YgJ2VuZGxlc3MnIGxvb3AgKi8gCiAgfQoKICBjbGF1c2VfRGVsZXRlKEdpdmVuQ29weSk7CgogIHJldHVybihSZXN1bHQpOwp9CgpzdGF0aWMgQ0xBVVNFIGluZl9BcHBseUdlbmVyYWxGYWN0b3JpbmcoQ0xBVVNFIENsYXVzZSwgTkFUIGksIE5BVCBqLAoJCQkJCVNVQlNUIFN1YnN0LCBGTEFHU1RPUkUgRmxhZ3MsCgkJCQkJUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSBhbiBpbmRleCBpbiB0aGUgY2xhdXNlLCBhIHN1YnN0aXR1dGlvbiBhIAogICAgICAgICAgIGZsYWcgc3RvcmUgYW5kIGEgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIG5ldyBjbGF1c2Ugb2J0YWluZWQgZnJvbSA8Q2xhdXNlPiBieSBhcHBseWluZyA8U3Vic3Q+CiAgICAgICAgICAgYW5kIGRlbGV0aW5nIGxpdGVyYWwgPGo+IGtlZXBpbmcgbGl0ZXJhbCA8aT4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgQ0xBVVNFIE5ld0NsYXVzZTsKCiAgTmV3Q2xhdXNlID0gY2xhdXNlX0NvcHkoQ2xhdXNlKTsKICBjbGF1c2VfQ2xlYXJGbGFncyhOZXdDbGF1c2UpOwogIGNsYXVzZV9TdWJzdEFwcGx5KFN1YnN0LCBOZXdDbGF1c2UpOyAKCiAgY2xhdXNlX0RlbGV0ZUxpdGVyYWwoTmV3Q2xhdXNlLCBpLCBGbGFncywgUHJlY2VkZW5jZSk7CgogIGxpc3RfRGVsZXRlKGNsYXVzZV9QYXJlbnRDbGF1c2VzKE5ld0NsYXVzZSkpOyAKICBsaXN0X0RlbGV0ZShjbGF1c2VfUGFyZW50TGl0ZXJhbHMoTmV3Q2xhdXNlKSk7CiAgY2xhdXNlX1NldFBhcmVudExpdGVyYWxzKE5ld0NsYXVzZSxsaXN0X05pbCgpKTsKICBjbGF1c2VfU2V0UGFyZW50Q2xhdXNlcyhOZXdDbGF1c2UsbGlzdF9OaWwoKSk7CgogIGNsYXVzZV9TZXREYXRhRnJvbUZhdGhlcihOZXdDbGF1c2UsIENsYXVzZSwgaiwgRmxhZ3MsIFByZWNlZGVuY2UpOwogIGNsYXVzZV9TZXRGcm9tR2VuZXJhbEZhY3RvcmluZyhOZXdDbGF1c2UpOwoKICBjbGF1c2VfQWRkUGFyZW50Q2xhdXNlKE5ld0NsYXVzZSwgY2xhdXNlX051bWJlcihDbGF1c2UpKTsKICBjbGF1c2VfQWRkUGFyZW50TGl0ZXJhbChOZXdDbGF1c2UsIGkpOwoKICBjbGF1c2VfTmV3TnVtYmVyKE5ld0NsYXVzZSk7CgogIHJldHVybiBOZXdDbGF1c2U7Cn0KCgpMSVNUIGluZl9HZW5lcmFsRmFjdG9yaW5nKENMQVVTRSBHaXZlbkNsYXVzZSwgQk9PTCBPcmRlcmVkLCBCT09MIExlZnQsCgkJCSAgQk9PTCBFcXVhdGlvbnMsIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSwgdGhyZWUgYm9vbGVhbiBmbGFncywgYSBmbGFnIHN0b3JlIGFuZCBhCiAgICAgICAgICAgcHJlY2VkZW5jZS4KICAgICAgICAgICBJZiA8T3JkZXJlZD49VFJVRSwgdGhpcyBmdW5jdGlvbiBnZW5lcmF0ZXMgb3JkZXJlZAoJICAgZmFjdG9yaW5nIGluZmVyZW5jZXMsIG90aGVyd2lzZSBzdGFuZGFyZCBmYWN0b3JpbmcKCSAgIGluZmVyZW5jZXMuCgkgICBJZiA8TGVmdD4gaXMgRkFMU0UsIHRoaXMgZnVuY3Rpb24gb25seSBtYWtlcyBmYWN0b3JpbmcKCSAgIHJpZ2h0IGluZmVyZW5jZXMsIG90aGVyd2lzZSBpdCBhbHNvIG1ha2VzIGZhY3RvcmluZyBsZWZ0CgkgICBpbmZlcmVuY2VzLgoJICAgSWYgPEVxdWF0aW9ucz49VFJVRSwgZXF1YXRpb25zIGFyZSBhbGxvd2VkIGZvciBpbmZlcmVuY2VzLAoJICAgZWxzZSBubyBpbmZlcmVuY2VzIHdpdGggZXF1YXRpb25zIGFyZSBnZW5lcmF0ZWQuIFRoZQoJICAgZGVmYXVsdCBpcyA8RXF1YXRpb25zPj1UUlVFLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIDxHaXZlbkNsYXVzZT4gYnkgR0YuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgICAgUmVzdWx0OwogIExJVEVSQUwgQWN0TGl0OwogIGludCAgICAgaSxqLGxhc3Q7CgojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZW5lcmFsRmFjdG9yaW5nOiBJbGxlZ2FsIGlucHV0LiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KI2VuZGlmCgogIGlmICghY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoR2l2ZW5DbGF1c2UpKQogICAgcmV0dXJuIGxpc3RfTmlsKCk7CgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CgogIC8qIEFsd2F5cyB0cnkgRmFjdG9yaW5nIFJpZ2h0IGluZmVyZW5jZXMgKi8KICBsYXN0ID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChHaXZlbkNsYXVzZSk7CiAgaWYgKCFjbGF1c2VfR2V0RmxhZyhHaXZlbkNsYXVzZSxDTEFVU0VTRUxFQ1QpKSB7CiAgICBmb3IgKGkgPSBjbGF1c2VfRmlyc3RTdWNjZWRlbnRMaXRJbmRleChHaXZlbkNsYXVzZSk7IGkgPD0gbGFzdDsgaSsrKSB7CiAgICAgIEFjdExpdCA9IGNsYXVzZV9HZXRMaXRlcmFsKEdpdmVuQ2xhdXNlLCBpKTsKICAgICAgaWYgKCghT3JkZXJlZCB8fCBjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChBY3RMaXQpKSAmJgoJICAoRXF1YXRpb25zIHx8ICFjbGF1c2VfTGl0ZXJhbElzRXF1YWxpdHkoQWN0TGl0KSkpIHsKCVRFUk0gICAgQXRvbSwgUGFydG5lckF0b207CglMSVRFUkFMIFBhcnRuZXJMaXQ7CglBdG9tID0gY2xhdXNlX0xpdGVyYWxBdG9tKEFjdExpdCk7Cglmb3IgKGogPSBjbGF1c2VfRmlyc3RTdWNjZWRlbnRMaXRJbmRleChHaXZlbkNsYXVzZSk7IGogPD0gbGFzdDsgaisrKSB7CgkgIGlmIChpICE9IGopIHsKCSAgICBQYXJ0bmVyTGl0ID0gY2xhdXNlX0dldExpdGVyYWwoR2l2ZW5DbGF1c2UsIGopOwoJICAgIFBhcnRuZXJBdG9tID0gY2xhdXNlX0xpdGVyYWxBdG9tKFBhcnRuZXJMaXQpOwoJICAgIGlmICgoaj5pIHx8KE9yZGVyZWQgJiYgIWNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKFBhcnRuZXJMaXQpKSkgJiYKCQl0ZXJtX0VxdWFsVG9wU3ltYm9scyhBdG9tLCBQYXJ0bmVyQXRvbSkpIHsKCSAgICAgIC8qIFRoaXMgY29uZGl0aW9uIGF2b2lkcyBkdXBsaWNhdGUgaW5mZXJlbmNlcyAqLwoJICAgICAgY29udF9DaGVjaygpOwoJICAgICAgaWYgKHVuaWZ5X1VuaWZ5Q29tKGNvbnRfTGVmdENvbnRleHQoKSwgQXRvbSwgUGFydG5lckF0b20pKSB7CgkJU1VCU1QgbWd1OwoJCXN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJm1ndSk7CgkJaWYgKCFPcmRlcmVkIHx8IGluZl9MaXRNYXgoR2l2ZW5DbGF1c2UsaSxqLG1ndSxGQUxTRSwKCQkJCQkgICBGbGFncywgUHJlY2VkZW5jZSkpCgkJICBSZXN1bHQgPSBsaXN0X0NvbnMoaW5mX0FwcGx5R2VuZXJhbEZhY3RvcmluZyhHaXZlbkNsYXVzZSxpLGosCgkJCQkJCQkgICAgICAgbWd1LEZsYWdzLCAKCQkJCQkJCSAgICAgICBQcmVjZWRlbmNlKSwKCQkJCSAgICAgUmVzdWx0KTsKCQlzdWJzdF9EZWxldGUobWd1KTsKCSAgICAgIH0KCSAgICAgIGNvbnRfUmVzZXQoKTsKCSAgICAgIGlmIChmb2xfSXNFcXVhbGl0eShBdG9tKSAmJiAgLyogUGFydG5lckF0b20gaXMgZXF1YWxpdHksIHRvbyAqLwoJCSAgdW5pZnlfVW5pZnlDb20oY29udF9MZWZ0Q29udGV4dCgpLAoJCQkJIHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSksIAoJCQkJIHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyQXRvbSkpICYmCgkJICB1bmlmeV9VbmlmeUNvbShjb250X0xlZnRDb250ZXh0KCksCgkJCQkgdGVybV9GaXJzdEFyZ3VtZW50KEF0b20pLCAKCQkJCSB0ZXJtX1NlY29uZEFyZ3VtZW50KFBhcnRuZXJBdG9tKSkpIHsKCQlTVUJTVCBtZ3U7CgkJc3Vic3RfRXh0cmFjdFVuaWZpZXJDb20oY29udF9MZWZ0Q29udGV4dCgpLCAmbWd1KTsKCQlpZiAoIU9yZGVyZWQgfHwgaW5mX0xpdE1heChHaXZlbkNsYXVzZSxpLGosbWd1LEZBTFNFLAoJCQkJCSAgIEZsYWdzLCBQcmVjZWRlbmNlKSkKCQkgIFJlc3VsdCA9IGxpc3RfQ29ucyhpbmZfQXBwbHlHZW5lcmFsRmFjdG9yaW5nKEdpdmVuQ2xhdXNlLGksaiwKCQkJCQkJCSAgICAgICBtZ3UsRmxhZ3MsIAoJCQkJCQkJICAgICAgIFByZWNlZGVuY2UpLAoJCQkJICAgICBSZXN1bHQpOwoJCXN1YnN0X0RlbGV0ZShtZ3UpOwoJICAgICAgfQoJICAgICAgY29udF9SZXNldCgpOwoJICAgIH0KCSAgfSAKCX0KICAgICAgfQogICAgfQogIH0KICAvKiBUcnkgRmFjdG9yaW5nIExlZnQgaW5mZXJlbmNlcyBvbmx5IGlmIDxMZWZ0Pj09VFJVRSAqLwogIGlmIChMZWZ0KSB7CiAgICBsYXN0ID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoR2l2ZW5DbGF1c2UpOwogICAgZm9yIChpID0gY2xhdXNlX0ZpcnN0QW50ZWNlZGVudExpdEluZGV4KEdpdmVuQ2xhdXNlKTsgaSA8PSBsYXN0OyBpKyspIHsKICAgICAgQWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoR2l2ZW5DbGF1c2UsIGkpOwogICAgICBpZiAoKEVxdWF0aW9ucyB8fCAhY2xhdXNlX0xpdGVyYWxJc0VxdWFsaXR5KEFjdExpdCkpICYmCgkgIChjbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LExJVFNFTEVDVCkgfHwKCSAgICghY2xhdXNlX0dldEZsYWcoR2l2ZW5DbGF1c2UsQ0xBVVNFU0VMRUNUKSAmJgoJICAgICghT3JkZXJlZCB8fCBjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChBY3RMaXQpKSkpKSB7CglURVJNICAgIEF0b20sIFBhcnRuZXJBdG9tOwoJTElURVJBTCBQYXJ0bmVyTGl0OwoJQXRvbSA9IGNsYXVzZV9MaXRlcmFsQXRvbShBY3RMaXQpOwoJZm9yIChqID0gY2xhdXNlX0ZpcnN0QW50ZWNlZGVudExpdEluZGV4KEdpdmVuQ2xhdXNlKTtqIDw9IGxhc3Q7IGorKykgewoJICBpZiAoaSAhPSBqKSB7CgkgICAgUGFydG5lckxpdCA9IGNsYXVzZV9HZXRMaXRlcmFsKEdpdmVuQ2xhdXNlLCBqKTsKCSAgICBQYXJ0bmVyQXRvbSA9IGNsYXVzZV9MaXRlcmFsQXRvbShQYXJ0bmVyTGl0KTsKCSAgICAvKiBJbiBvcmRlciB0byBhdm9pZCBkdXBsaWNhdGUgaW5mZXJlbmNlcywgd2UgZG8gdGhlIGZvbGxvd2luZyAgKi8KCSAgICAvKiBzb21ld2hhdCAidHJpY2t5IiB0ZXN0LiBXaGF0IHdlIHdhbnQgaXMgc29tZXRoaW5nIGxpa2UgICAgICAgKi8KCSAgICAvKiAiaWYgKGo+aSB8fCBqIHdhc24ndCBjb25zaWRlcmVkIHdpdGhpbiB0aGUgb3V0ZXIgbG9vcCkgey4uLn0gKi8KCSAgICAvKiBUaGlzIGxlbmd0aHkgY29uZGl0aW9uIGNhbiBiZSB0cmFuc2Zvcm1lZCBpbnRvIHRoZSBmb2xsb3dpbmcgKi8KCSAgICAvKiBjb25kaXRpb24sIGJlY2F1c2Ugb25seSBvbmUgbmVnYXRpdmUgbGl0ZXJhbCBpcyBzZWxlY3RlZC4gICAgKi8KCSAgICAvKiBUaGlzIGltcGxpZXMgdGhhdCB0aGUgbGl0ZXJhbCBhdCBpbmRleCBqIGNhbid0IGJlIHNlbGVjdGVkLiAgKi8KCSAgICBpZiAoKGo+aSB8fCBjbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LExJVFNFTEVDVCkgfHwKCQkoT3JkZXJlZCAmJiAhY2xhdXNlX0xpdGVyYWxJc01heGltYWwoUGFydG5lckxpdCkpKSAmJgoJCXRlcm1fRXF1YWxUb3BTeW1ib2xzKEF0b20sIFBhcnRuZXJBdG9tKSkgewoJICAgICAgUGFydG5lckF0b20gPSBjbGF1c2VfTGl0ZXJhbEF0b20oUGFydG5lckxpdCk7CgkgICAgICBjb250X0NoZWNrKCk7CgkgICAgICBpZiAodW5pZnlfVW5pZnlDb20oY29udF9MZWZ0Q29udGV4dCgpLCBBdG9tLCBQYXJ0bmVyQXRvbSkpIHsKCQlTVUJTVCBtZ3U7CgkJc3Vic3RfRXh0cmFjdFVuaWZpZXJDb20oY29udF9MZWZ0Q29udGV4dCgpLCAmbWd1KTsKCQlpZiAoIU9yZGVyZWQgfHwgY2xhdXNlX0xpdGVyYWxHZXRGbGFnKEFjdExpdCxMSVRTRUxFQ1QpIHx8CgkJICAgIGluZl9MaXRNYXgoR2l2ZW5DbGF1c2UsaSxqLG1ndSxGQUxTRSxGbGFncywgUHJlY2VkZW5jZSkpCgkJICBSZXN1bHQgPSBsaXN0X0NvbnMoaW5mX0FwcGx5R2VuZXJhbEZhY3RvcmluZyhHaXZlbkNsYXVzZSxpLGosCgkJCQkJCQkgICAgICAgbWd1LEZsYWdzLAoJCQkJCQkJICAgICAgIFByZWNlZGVuY2UpLAoJCQkJICAgICBSZXN1bHQpOwoJCXN1YnN0X0RlbGV0ZShtZ3UpOwoJICAgICAgfQoJICAgICAgY29udF9SZXNldCgpOwoJICAgICAgaWYgKGZvbF9Jc0VxdWFsaXR5KEF0b20pICYmIC8qIFBhcnRuZXJBdG9tIGlzIGVxdWFsaXR5LCB0b28gKi8KCQkgIHVuaWZ5X1VuaWZ5Q29tKGNvbnRfTGVmdENvbnRleHQoKSwKCQkJCSB0ZXJtX1NlY29uZEFyZ3VtZW50KEF0b20pLCAKCQkJCSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckF0b20pKSAmJgoJCSAgdW5pZnlfVW5pZnlDb20oY29udF9MZWZ0Q29udGV4dCgpLAoJCQkJIHRlcm1fRmlyc3RBcmd1bWVudChBdG9tKSwgCgkJCQkgdGVybV9TZWNvbmRBcmd1bWVudChQYXJ0bmVyQXRvbSkpKSB7CgkJU1VCU1QgbWd1OwoJCXN1YnN0X0V4dHJhY3RVbmlmaWVyQ29tKGNvbnRfTGVmdENvbnRleHQoKSwgJm1ndSk7CgkJaWYgKCFPcmRlcmVkIHx8IGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhBY3RMaXQsTElUU0VMRUNUKSB8fAoJCSAgICBpbmZfTGl0TWF4KEdpdmVuQ2xhdXNlLGksaixtZ3UsRkFMU0UsRmxhZ3MsIFByZWNlZGVuY2UpKQoJCSAgUmVzdWx0ID0gbGlzdF9Db25zKGluZl9BcHBseUdlbmVyYWxGYWN0b3JpbmcoR2l2ZW5DbGF1c2UsaSxqLAoJCQkJCQkJICAgICAgIG1ndSxGbGFncywKCQkJCQkJCSAgICAgICBQcmVjZWRlbmNlKSwKCQkJCSAgICAgUmVzdWx0KTsKCQlzdWJzdF9EZWxldGUobWd1KTsKCSAgICAgIH0KCSAgICAgIGNvbnRfUmVzZXQoKTsKCSAgICB9CgkgIH0gCgl9CiAgICAgIH0KICAgIH0KICB9CiAgY29udF9DaGVjaygpOwoKICByZXR1cm4gUmVzdWx0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogU1RBUlQgb2YgY29kZSBmb3IgbmV3IFN1cGVycG9zaXRpb24gTGVmdCBydWxlICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgpzdGF0aWMgTElTVCBpbmZfR2VuTGl0U1BMZWZ0KENMQVVTRSBDbGF1c2UsIFRFUk0gTGVmdCwgVEVSTSBSaWdodCwgaW50IGksCgkJCSAgICAgU0hBUkVEX0lOREVYIFNoSW5kZXgsQk9PTCBPcmRQYXJhLCBCT09MIE1heFBhcmEsCgkJCSAgICAgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlICh1bnNoYXJlZCkgd2l0aCBhIHBvc2l0aXZlIGVxdWFsaXR5IGxpdGVyYWwKICAgICAgICAgICBhdCBwb3NpdGlvbiA8aT4gd2hlcmUgPExlZnQ+IGFuZCA8UmlnaHQ+IGFyZSB0aGUgCgkgICBhcmd1bWVudHMgb2YganVzdCB0aGF0IGxpdGVyYWwsIHR3byBib29sZWFuIGZsYWdzLCAKCSAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgoJICAgRm9yIE9yZGVyZWQgUGFyYW1vZHVsYXRpb24gYW5kIFN1cGVycG9zaXRpb24gPFJpZ2h0PgogICAgICAgICAgIG11c3RuJ3QgYmUgZ3JlYXRlciB3cnQuIHRoZSBvcmRlcmluZyB0aGFuIDxMZWZ0Pi4KCSAgIEZvciBTdXBlcnBvc2l0aW9uIHRoZSBsaXRlcmFsIG11c3QgYmUgc3RyaWN0bHkgbWF4aW1hbC4KICBSRVRVUk5TOiBBIGxpc3Qgb2YgY2xhdXNlcyBkZXJpdmFibGUgd2l0aCB0aGUgbGl0ZXJhbHMgb3duaW5nCiAgICAgICAgICAgY2xhdXNlIGJ5IFN1cGVycG9zaXRpb24gTGVmdCB3cnQuIHRoZSBJbmRleC4KICBNRU1PUlk6ICBUaGUgbGlzdCBvZiBjbGF1c2VzIGlzIGV4dGVuZGVkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZQogICAgICAgICAgIGxpc3QgYW5kIHRoZSBjbGF1c2VzIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgTElTVCBSZXN1bHQsIFRlcm1zOwoKI2lmZGVmIENIRUNLCiAgaWYgKGNsYXVzZV9HZXRGbGFnKENsYXVzZSwgQ0xBVVNFU0VMRUNUKSB8fAogICAgICAoT3JkUGFyYSAmJgogICAgICAgY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpKSAmJgogICAgICAgTGVmdCA9PSB0ZXJtX1NlY29uZEFyZ3VtZW50KGNsYXVzZV9HZXRMaXRlcmFsQXRvbShDbGF1c2UsaSkpKSB8fAogICAgICAoTWF4UGFyYSAmJgogICAgICAgIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSksIFNUUklDVE1BWElNQUwpKSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuTGl0U1BMZWZ0OiBJbGxlZ2FsIGlucHV0LiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KI2VuZGlmCgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CiAgVGVybXMgID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksIHNoYXJpbmdfSW5kZXgoU2hJbmRleCksCgkJCSBjb250X1JpZ2h0Q29udGV4dCgpLCBMZWZ0KTsKCiAgZm9yICggOyAhbGlzdF9FbXB0eShUZXJtcyk7IFRlcm1zID0gbGlzdF9Qb3AoVGVybXMpKSB7CiAgICBMSVNUIExpdHM7CiAgICBURVJNIFRlcm07CgogICAgVGVybSA9IChURVJNKWxpc3RfRmlyc3QoVGVybXMpOwoKICAgIGlmICghdGVybV9Jc1ZhcmlhYmxlKFRlcm0pICYmICFzeW1ib2xfSXNQcmVkaWNhdGUodGVybV9Ub3BTeW1ib2woVGVybSkpKSB7CgogICAgICBMaXRzID0gc2hhcmluZ19HZXREYXRhTGlzdChUZXJtLCBTaEluZGV4KTsKCiAgICAgIGZvciAoIDsgIWxpc3RfRW1wdHkoTGl0cyk7IExpdHMgPSBsaXN0X1BvcChMaXRzKSl7CgoJTElURVJBTCBQYXJ0bmVyTGl0OwoJVEVSTSAgICBQYXJ0bmVyQXRvbTsKCUNMQVVTRSAgUGFydG5lckNsYXVzZTsKCWludCAgICAgcGxpOwoKCVBhcnRuZXJMaXQgICAgICAgID0gKExJVEVSQUwpbGlzdF9DYXIoTGl0cyk7IC8qIEFudGVjZWRlbnQgTGl0ZXJhbCAhICovCglQYXJ0bmVyQXRvbSAgICAgICA9IGNsYXVzZV9MaXRlcmFsQXRvbShQYXJ0bmVyTGl0KTsgIAoJcGxpICAgICAgICAgICAgICAgPSBjbGF1c2VfTGl0ZXJhbEdldEluZGV4KFBhcnRuZXJMaXQpOwoJUGFydG5lckNsYXVzZSAgICAgPSBjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShQYXJ0bmVyTGl0KTsKCglpZiAoKGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhQYXJ0bmVyTGl0LExJVFNFTEVDVCkgfHwKCSAgICAgKCFjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLENMQVVTRVNFTEVDVCkgJiYKCSAgICAgICghTWF4UGFyYSB8fCBjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChQYXJ0bmVyTGl0KSkpKSAmJgoJICAgIGNsYXVzZV9MaXRlcmFsSXNOZWdhdGl2ZShQYXJ0bmVyTGl0KSAmJgoJICAgICFjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLE5PUEFSQUlOVE8pICYmCgkgICAgY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoUGFydG5lckNsYXVzZSkpIHsKCSAgLyogSWYgPFBhcnRuZXJDbGF1c2U+IGhhcyBhIHNvbHZlZCBjb25zdHJhaW50IGFuZCA8UGFydG5lckxpdD4gKi8KCSAgLyogaXMgbmVnYXRpdmUgdGhlbiA8UGFydG5lckxpdD4gaXMgZnJvbSB0aGUgYW50ZWNlZGVudC4gICAgICAgKi8KCgkgIFNVQlNUICBTdWJzdCwgUGFydG5lclN1YnN0OwoJICBURVJNICAgTmV3TGVmdCxOZXdSaWdodDsKCSAgU1lNQk9MIFBhcnRuZXJNYXhWYXI7CgkgIFRFUk0gICBTdXBBdG9tOyAKCgkgIFN1cEF0b20gPSAoVEVSTSlOVUxMOwoJICBQYXJ0bmVyTWF4VmFyID0gY2xhdXNlX01heFZhcihQYXJ0bmVyQ2xhdXNlKTsKCSAgTmV3TGVmdCAgICAgICA9IExlZnQ7CgkgIGNsYXVzZV9SZW5hbWVWYXJzQmlnZ2VyVGhhbihDbGF1c2UsIFBhcnRuZXJNYXhWYXIpOwoKCSAgY29udF9DaGVjaygpOwoJICB1bmlmeV9VbmlmeU5vT0MoY29udF9MZWZ0Q29udGV4dCgpLCBMZWZ0LCBjb250X1JpZ2h0Q29udGV4dCgpLCBUZXJtKTsKCSAgc3Vic3RfRXh0cmFjdFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCAmU3Vic3QsCgkJCSAgICAgICBjb250X1JpZ2h0Q29udGV4dCgpLCAmUGFydG5lclN1YnN0KTsKCSAgY29udF9SZXNldCgpOwoKCSAgaWYgKCFNYXhQYXJhIHx8CgkgICAgICBpbmZfTGl0ZXJhbHNNYXgoQ2xhdXNlLCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgcGxpLAoJCQkgICAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJICAgIE5ld1JpZ2h0ID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShSaWdodCkpOwoJICAgIGlmIChPcmRQYXJhICYmCgkJIWNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKSkpCgkgICAgICBOZXdMZWZ0ICA9IHN1YnN0X0FwcGx5KFN1YnN0LCB0ZXJtX0NvcHkoTGVmdCkpOwoJICAgIGlmICghT3JkUGFyYSB8fAoJCU5ld0xlZnQgPT0gTGVmdCB8fAoJCW9yZF9Db21wYXJlKE5ld0xlZnQsTmV3UmlnaHQsRmxhZ3MsIFByZWNlZGVuY2UpICE9IG9yZF9TbWFsbGVyVGhhbigpKSB7CgkgICAgICBpZiAoIU1heFBhcmEgfHwgY2xhdXNlX0xpdGVyYWxJc1ByZWRpY2F0ZShQYXJ0bmVyTGl0KSkgewoJCVN1cEF0b20gPSBpbmZfQWxsVGVybXNScGxhYyhQYXJ0bmVyQXRvbSxUZXJtLE5ld1JpZ2h0LAoJCQkJCSAgICBQYXJ0bmVyU3Vic3QpOwoJICAgICAgfSBlbHNlIHsKCQkvKiBTdXBlcnBvc2l0aW9uIGFuZCA8UGFydG5lckxpdD4gaXMgZXF1YWxpdHkgKi8KCQlpZiAoY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkpCgkJICBTdXBBdG9tID0gaW5mX0FsbFRlcm1zTGVmdFJwbGFjKFBhcnRuZXJBdG9tLFRlcm0sTmV3UmlnaHQsCgkJCQkJCSAgIFBhcnRuZXJTdWJzdCk7CgkJZWxzZSB7CgkJICBURVJNIE5ld1BhcnRuZXJMZWZ0LE5ld1BhcnRuZXJSaWdodDsKCQkgIE5ld1BhcnRuZXJMZWZ0ICA9IHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwgCgkJICAgICAgIAkgICAgdGVybV9Db3B5KHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyQXRvbSkpKTsKCQkgIE5ld1BhcnRuZXJSaWdodCA9IHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwgCgkJCSAgICB0ZXJtX0NvcHkodGVybV9TZWNvbmRBcmd1bWVudChQYXJ0bmVyQXRvbSkpKTsKCQkgIHN3aXRjaCAob3JkX0NvbXBhcmUoTmV3UGFydG5lckxlZnQsTmV3UGFydG5lclJpZ2h0LAoJCQkJICAgICAgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CgkJICBjYXNlIG9yZF9TTUFMTEVSX1RIQU46CgkJICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNSaWdodFJwbGFjKFBhcnRuZXJBdG9tLFRlcm0sCgkJCQkJCSAgICAgIE5ld1JpZ2h0LFBhcnRuZXJTdWJzdCk7CgkJICAgIGJyZWFrOwoJCSAgY2FzZSBvcmRfR1JFQVRFUl9USEFOOgoJCSAgICBTdXBBdG9tID0gaW5mX0FsbFRlcm1zTGVmdFJwbGFjKFBhcnRuZXJBdG9tLFRlcm0sCgkJCQkJCSAgICAgTmV3UmlnaHQsUGFydG5lclN1YnN0KTsKCQkgICAgYnJlYWs7CgkJICBkZWZhdWx0OgoJCSAgICBTdXBBdG9tID0gaW5mX0FsbFRlcm1zUnBsYWMoUGFydG5lckF0b20sVGVybSwKCQkJCQkJIE5ld1JpZ2h0LFBhcnRuZXJTdWJzdCk7CgkJICB9CgkJICB0ZXJtX0RlbGV0ZShOZXdQYXJ0bmVyTGVmdCk7CgkJICB0ZXJtX0RlbGV0ZShOZXdQYXJ0bmVyUmlnaHQpOwoJCX0KCSAgICAgIH0KCgkgICAgICBpZiAoU3VwQXRvbSAhPSBOVUxMKQoJCVJlc3VsdCA9IGxpc3RfQ29ucyhpbmZfQXBwbHlHZW5TdXBlcnBvc2l0aW9uKENsYXVzZSwgaSwgU3Vic3QsIAoJCQkJCQkJICAgICBQYXJ0bmVyQ2xhdXNlLCBwbGksCgkJCQkJCQkgICAgIFBhcnRuZXJTdWJzdCwgCgkJCQkJCQkgICAgIFN1cEF0b20sIEZBTFNFLAoJCQkJCQkJICAgICBPcmRQYXJhLCBNYXhQYXJhLAoJCQkJCQkJICAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJCQkgICBSZXN1bHQpOwoJICAgIH0KCSAgICBpZiAoTmV3TGVmdCAhPSBMZWZ0KQoJICAgICAgdGVybV9EZWxldGUoTmV3TGVmdCk7CgkgICAgdGVybV9EZWxldGUoTmV3UmlnaHQpOwoJICB9CgkgIHN1YnN0X0RlbGV0ZShTdWJzdCk7CgkgIHN1YnN0X0RlbGV0ZShQYXJ0bmVyU3Vic3QpOwoJfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBSZXN1bHQ7Cn0KCgpzdGF0aWMgTElTVCBpbmZfR2VuU1BMZWZ0RXFUb0dpdmVuKENMQVVTRSBDbGF1c2UsIGludCBpLCBCT09MIExlZnQsCgkJCQkgICBTSEFSRURfSU5ERVggU2hJbmRleCwgQk9PTCBPcmRQYXJhLAoJCQkJICAgQk9PTCBNYXhQYXJhLCBCT09MIFVuaXQsIEZMQUdTVE9SRSBGbGFncywKCQkJCSAgIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQW4gdW5zaGFyZWQgY2xhdXNlLCB0aGUgaW5kZXggb2YgYW4gYW50ZWNlZGVudCAKICAgICAgICAgICBsaXRlcmFsIHRoYXQgaXMgYW4gZXF1YWxpdHkgbGl0ZXJhbCwgYSBib29sZWFuIAoJICAgdmFsdWUsIGEgc2hhcmVkIGluZGV4LCB0aHJlZSBib29sZWFuIGZsYWdzIAoJICAgY29udHJvbGxpbmcgaW5mZXJlbmNlIHByZWNvbmRpdGlvbnMsIGEgZmxhZyBzdG9yZSAKCSAgIGFuZCBhIHByZWNlZGVuY2UuCiAgICAgICAgICAgSWYgTGVmdD09VFJVRSB0aGVuIHRoZSBsZWZ0IGFyZ3VtZW50IG9mIHRoZSBsaXRlcmFsIGlzIHVzZWQKCSAgIG90aGVyd2lzZSB0aGUgcmlnaHQgYXJndW1lbnQuCgkgICBPcmRQYXJhIGFuZCBNYXhQYXJhIGNvbnRyb2wgaW5mZXJlbmNlIGNvbmRpdGlvbnMuCgkgICBJZiA8VW5pdD49PVRSVUUgdGhlIGNsYXVzZSB3aXRoIHRoZSBtYXhpbWFsLCBwb3NpdGl2ZQoJICAgZXF1YWxpdHkgbXVzdCBiZSBhIHVuaXQgY2xhdXNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIGdlbmVyYWxpemVkIAogICAgICAgICAgIHN1cGVycG9zaXRpb24gTGVmdCBvbiB0aGUKICAgICAgICAgICBHaXZlbkNvcHkgIHdydC4gdGhlIEluZGV4LiBTZWUgR2VuU3VwZXJwb3NpdGlvbkxlZnQKCSAgIGZvciBlZmZlY3RzIG9mIE9yZFBhcmEgYW5kIE1heFBhcmEKICBNRU1PUlk6ICBBIGxpc3Qgb2YgY2xhdXNlcyBpcyBwcm9kdWNlZCwgd2hlcmUgbWVtb3J5IGZvciB0aGUgbGlzdAogICAgICAgICAgIGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgICAgUmVzdWx0LCBUZXJtTGlzdCwgUGFyZW50TGlzdDsKICBpbnQgICAgIEJvdHRvbTsKICBMSVRFUkFMIExpdDsKICBURVJNICAgIEF0b20sIFRlcm0sIFBhcnRuZXJUZXJtLCBQYXJ0bmVyRXE7CgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CiAgTGl0ICAgID0gY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpOyAvKiBJcyBhbiBhbnRlY2VkZW50IExpdGVyYWwgISAqLwogIEF0b20gICA9IGNsYXVzZV9MaXRlcmFsQXRvbShMaXQpOwoKI2lmZGVmIENIRUNLCiAgaWYgKGNsYXVzZV9HZXRGbGFnKENsYXVzZSwgTk9QQVJBSU5UTykgfHwKICAgICAgIWNsYXVzZV9MaXRlcmFsSXNFcXVhbGl0eShMaXQpIHx8CiAgICAgICFjbGF1c2VfTGl0ZXJhbElzRnJvbUFudGVjZWRlbnQoTGl0KSB8fAogICAgICAoTWF4UGFyYSAmJiBjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShMaXQpICYmICFMZWZ0KSB8fAogICAgICAoIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSksTElUU0VMRUNUKSAmJgogICAgICAgKGNsYXVzZV9HZXRGbGFnKENsYXVzZSwgQ0xBVVNFU0VMRUNUKSB8fAoJKE1heFBhcmEgJiYgIWNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKSkpKSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0dlblNQTGVmdEVxVG9HaXZlbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBCb3R0b20gPSBzdGFja19Cb3R0b20oKTsKICBpZiAoTGVmdCkgCiAgICBzaGFyaW5nX1B1c2hPblN0YWNrKHRlcm1fRmlyc3RBcmd1bWVudChBdG9tKSk7CiAgZWxzZQogICAgc2hhcmluZ19QdXNoT25TdGFjayh0ZXJtX1NlY29uZEFyZ3VtZW50KEF0b20pKTsKCiAgd2hpbGUgKCFzdGFja19FbXB0eShCb3R0b20pKSB7CiAgICBUZXJtID0gKFRFUk0pc3RhY2tfUG9wUmVzdWx0KCk7CiAgICBpZiAoIXRlcm1fSXNWYXJpYWJsZShUZXJtKSkgewogICAgICAvKiBTdXBlcnBvc2l0aW9uIGludG8gdmFyaWFibGVzIGlzIG5vdCBuZWNlc3NhcnkgKi8KICAgICAgVGVybUxpc3QgPSBzdF9HZXRVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSwgc2hhcmluZ19JbmRleChTaEluZGV4KSwKCQkJICAgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksIFRlcm0pOwogICAgICBmb3IgKCA7IWxpc3RfRW1wdHkoVGVybUxpc3QpOyBUZXJtTGlzdCA9IGxpc3RfUG9wKFRlcm1MaXN0KSkgewoJUGFydG5lclRlcm0gPSAoVEVSTSlsaXN0X0NhcihUZXJtTGlzdCk7Cglmb3IgKFBhcmVudExpc3QgPSB0ZXJtX1N1cGVydGVybUxpc3QoUGFydG5lclRlcm0pOwoJICAgICAhbGlzdF9FbXB0eShQYXJlbnRMaXN0KTsgUGFyZW50TGlzdCA9IGxpc3RfQ2RyKFBhcmVudExpc3QpKSB7CgkgIFBhcnRuZXJFcSA9IChURVJNKWxpc3RfQ2FyKFBhcmVudExpc3QpOwoJICBpZiAoZm9sX0lzRXF1YWxpdHkoUGFydG5lckVxKSkgewoJICAgIENMQVVTRSAgUGFydG5lckNsYXVzZTsKCSAgICBMSVRFUkFMIFBhcnRuZXJMaXQ7CgkgICAgTElTVCAgICBTY2w7CgkgICAgaW50ICAgICBqOwoJICAgIGZvciAoU2NsID0gc2hhcmluZ19OQXRvbURhdGFMaXN0KFBhcnRuZXJFcSk7CgkJICFsaXN0X0VtcHR5KFNjbCk7IFNjbCA9IGxpc3RfQ2RyKFNjbCkpIHsKCSAgICAgIFBhcnRuZXJMaXQgICAgPSAoTElURVJBTClsaXN0X0NhcihTY2wpOwoJICAgICAgaiAgICAgICAgICAgICA9IGNsYXVzZV9MaXRlcmFsR2V0SW5kZXgoUGFydG5lckxpdCk7CgkgICAgICBQYXJ0bmVyQ2xhdXNlID0gY2xhdXNlX0xpdGVyYWxPd25pbmdDbGF1c2UoUGFydG5lckxpdCk7CgoJICAgICAgaWYgKCFjbGF1c2VfR2V0RmxhZyhQYXJ0bmVyQ2xhdXNlLENMQVVTRVNFTEVDVCkgJiYKCQkgICghTWF4UGFyYSB8fAoJCSAgIGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhQYXJ0bmVyTGl0LFNUUklDVE1BWElNQUwpKSAmJgoJCSAgKCFPcmRQYXJhIHx8CgkJICAgUGFydG5lclRlcm0gPT0gdGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJFcSkgfHwKCQkgICAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkpICYmCgkJICBjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgJiYKCQkgIGNsYXVzZV9OdW1iZXIoUGFydG5lckNsYXVzZSkgIT0gY2xhdXNlX051bWJlcihDbGF1c2UpICYmCgkJICAoIVVuaXQgfHwgY2xhdXNlX0xlbmd0aChQYXJ0bmVyQ2xhdXNlKSA9PSAxKSAmJgoJCSAgY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoUGFydG5lckNsYXVzZSkpIHsKCQlTWU1CT0wgTWF4VmFyOwoJCVNVQlNUICBTdWJzdCwgUGFydG5lclN1YnN0OwoKCQlNYXhWYXIgICAgICA9IGNsYXVzZV9NYXhWYXIoUGFydG5lckNsYXVzZSk7CgkJY2xhdXNlX1JlbmFtZVZhcnNCaWdnZXJUaGFuKENsYXVzZSxNYXhWYXIpOwoJCWNvbnRfQ2hlY2soKTsKCQl1bmlmeV9VbmlmeU5vT0MoY29udF9MZWZ0Q29udGV4dCgpLCBUZXJtLAoJCQkJY29udF9SaWdodENvbnRleHQoKSxQYXJ0bmVyVGVybSk7CgkJc3Vic3RfRXh0cmFjdFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCAmU3Vic3QsCgkJCQkgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksJlBhcnRuZXJTdWJzdCk7CgkJY29udF9SZXNldCgpOwoJCWlmICghTWF4UGFyYSB8fAoJCSAgICBpbmZfTGl0ZXJhbHNNYXgoQ2xhdXNlLCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgaiwKCQkJCSAgICBQYXJ0bmVyU3Vic3QsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewoJCSAgVEVSTSBQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQ7CgkJICBCT09MIENoZWNrLCBQYXJ0bmVyQ2hlY2s7CgkJICBQYXJ0bmVyTGVmdCA9IFBhcnRuZXJSaWdodCA9IE5VTEw7CgkJICBQYXJ0bmVyQ2hlY2sgPSBDaGVjayA9IFRSVUU7CgkJICBpZiAoT3JkUGFyYSAmJgoJCSAgICAgICFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShQYXJ0bmVyTGl0KSkgewoJCSAgICAvKiBDaGVjayBwb3N0IGNvbmRpdGlvbiBmb3IgcGFydG5lciBsaXRlcmFsICovCgkJICAgIGlmIChQYXJ0bmVyVGVybSA9PSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckVxKSkKCQkgICAgICBQYXJ0bmVyUmlnaHQgPSB0ZXJtX1NlY29uZEFyZ3VtZW50KFBhcnRuZXJFcSk7CgkJICAgIGVsc2UKCQkgICAgICBQYXJ0bmVyUmlnaHQgPSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckVxKTsKCQkgICAgUGFydG5lckxlZnQgID0gc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJCQkJCSAgICAgICB0ZXJtX0NvcHkoUGFydG5lclRlcm0pKTsKCQkgICAgUGFydG5lclJpZ2h0ID0gc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJCQkJCSAgICAgICB0ZXJtX0NvcHkoUGFydG5lclJpZ2h0KSk7CgkJICAgIFBhcnRuZXJDaGVjayA9IChvcmRfQ29tcGFyZShQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQsCgkJCQkJCUZsYWdzLCBQcmVjZWRlbmNlKQoJCQkJICAgICE9IG9yZF9TbWFsbGVyVGhhbigpKTsKCQkgIH0KCQkgIGlmIChQYXJ0bmVyQ2hlY2sgJiYKCQkgICAgICBNYXhQYXJhICYmICFjbGF1c2VfTGl0ZXJhbElzT3JpZW50ZWRFcXVhbGl0eShMaXQpKSB7CgkJICAgIC8qIENoZWNrIHBvc3QgY29uZGl0aW9uIGZvciBsaXRlcmFsIGluIGdpdmVuIGNsYXVzZSAqLwoJCSAgICBURVJNIE5ld0xlZnQsIE5ld1JpZ2h0OwoJCSAgICBpZiAoTGVmdCkgewoJCSAgICAgIE5ld0xlZnQgID0gdGVybV9GaXJzdEFyZ3VtZW50KEF0b20pOwoJCSAgICAgIE5ld1JpZ2h0ID0gdGVybV9TZWNvbmRBcmd1bWVudChBdG9tKTsKCQkgICAgfSBlbHNlIHsKCQkgICAgICBOZXdMZWZ0ICA9IHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSk7CgkJICAgICAgTmV3UmlnaHQgPSB0ZXJtX0ZpcnN0QXJndW1lbnQoQXRvbSk7CgkJICAgIH0KCQkgICAgTmV3TGVmdCAgPSBzdWJzdF9BcHBseShTdWJzdCwgdGVybV9Db3B5KE5ld0xlZnQpKTsKCQkgICAgTmV3UmlnaHQgPSBzdWJzdF9BcHBseShTdWJzdCwgdGVybV9Db3B5KE5ld1JpZ2h0KSk7CgkJICAgIENoZWNrID0gKG9yZF9Db21wYXJlKE5ld0xlZnQsIE5ld1JpZ2h0LCBGbGFncywgUHJlY2VkZW5jZSkKCQkJICAgICAhPSBvcmRfU21hbGxlclRoYW4oKSk7CgkJICAgIHRlcm1fRGVsZXRlKE5ld0xlZnQpOwoJCSAgICB0ZXJtX0RlbGV0ZShOZXdSaWdodCk7CgkJICB9CgkJICBpZiAoQ2hlY2sgJiYgUGFydG5lckNoZWNrKSB7CgkJICAgIC8qIE1ha2UgaW5mZXJlbmNlIG9ubHkgaWYgYm90aCB0ZXN0cyB3ZXJlIHN1Y2Nlc3NmdWwgKi8KCQkgICAgVEVSTSBTdXBBdG9tOwoJCSAgICBTdXBBdG9tID0gTlVMTDsKCQkgICAgaWYgKFBhcnRuZXJSaWdodCA9PSBOVUxMKSB7CgkJICAgICAgaWYgKFBhcnRuZXJUZXJtPT10ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckVxKSkKCQkJUGFydG5lclJpZ2h0ID0gdGVybV9TZWNvbmRBcmd1bWVudChQYXJ0bmVyRXEpOwoJCSAgICAgIGVsc2UKCQkJUGFydG5lclJpZ2h0ID0gdGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJFcSk7CgkJICAgICAgUGFydG5lclJpZ2h0ID0gc3Vic3RfQXBwbHkoUGFydG5lclN1YnN0LAoJCQkJCQkgdGVybV9Db3B5KFBhcnRuZXJSaWdodCkpOwoJCSAgICB9CgkJICAgIGlmIChMZWZ0KQoJCSAgICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNMZWZ0UnBsYWMoQXRvbSwgVGVybSwKCQkJCQkJICAgICAgUGFydG5lclJpZ2h0LCBTdWJzdCk7CgkJICAgIGVsc2UgCgkJICAgICAgU3VwQXRvbSA9IGluZl9BbGxUZXJtc1JpZ2h0UnBsYWMoQXRvbSwgVGVybSwKCQkJCQkJICAgICAgIFBhcnRuZXJSaWdodCwgU3Vic3QpOwojaWZkZWYgQ0hFQ0sKCQkgICAgaWYgKFN1cEF0b20gPT0gTlVMTCkgewoJCSAgICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwoJCSAgICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZW5TUExlZnRFcVRvR2l2ZW46Iik7CgkJICAgICAgbWlzY19FcnJvclJlcG9ydCgiIHJlcGxhY2VtZW50IHdhc24ndCBwb3NzaWJsZS4iKTsKCQkgICAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CgkJICAgIH0KI2VuZGlmCgkJICAgIFJlc3VsdCA9CgkJICAgICAgbGlzdF9Db25zKGluZl9BcHBseUdlblN1cGVycG9zaXRpb24oUGFydG5lckNsYXVzZSwgaiwKCQkJCQkJCSAgUGFydG5lclN1YnN0LENsYXVzZSwKCQkJCQkJCSAgaSxTdWJzdCxTdXBBdG9tLAoJCQkJCQkJICBGQUxTRSxPcmRQYXJhLAoJCQkJCQkJICBNYXhQYXJhLEZsYWdzLAoJCQkJCQkJICBQcmVjZWRlbmNlKSwgCgkJCQlSZXN1bHQpOwoJCSAgfQoJCSAgaWYgKFBhcnRuZXJMZWZ0ICE9IHRlcm1fTnVsbCgpKQoJCSAgICB0ZXJtX0RlbGV0ZShQYXJ0bmVyTGVmdCk7CgkJICBpZiAoUGFydG5lclJpZ2h0ICE9IHRlcm1fTnVsbCgpKQoJCSAgICB0ZXJtX0RlbGV0ZShQYXJ0bmVyUmlnaHQpOwoJCX0KCQlzdWJzdF9EZWxldGUoU3Vic3QpOwoJCXN1YnN0X0RlbGV0ZShQYXJ0bmVyU3Vic3QpOwoJICAgICAgfQoJICAgIH0KCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBSZXN1bHQ7Cn0KCgpzdGF0aWMgTElTVCBpbmZfR2VuU1BMZWZ0TGl0VG9HaXZlbihDTEFVU0UgQ2xhdXNlLCBpbnQgaSwgVEVSTSBBdG9tLAoJCQkJICAgIFNIQVJFRF9JTkRFWCBTaEluZGV4LCBCT09MIE9yZFBhcmEsCgkJCQkgICAgQk9PTCBNYXhQYXJhLCBCT09MIFVuaXQsIEZMQUdTVE9SRSBGbGFncywKCQkJCSAgICBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEFuIHVuc2hhcmVkIGNsYXVzZSwgdGhlIGluZGV4IG9mIGFuIGFudGVjZWRlbnQgCiAgICAgICAgICAgbGl0ZXJhbCB0aGF0IGlzIG5vdCBhbiBlcXVhbGl0eSBsaXRlcmFsIGFuZCBpdHMgCgkgICBhdG9tLCBhIHNoYXJlZCBpbmRleCwgdGhyZWUgYm9vbGVhbiBmbGFncyAKCSAgIGNvbnRyb2xsaW5nIGluZmVyZW5jZSBwcmVjb25kaXRpb25zIChzZWUgYWxzbyAKCSAgIGluZl9HZW5TdXBlcnBvc2l0aW9uTGVmdCksIGEgZmxhZyBzdG9yZSBhbmQgYQoJICAgcHJlY2VkZW5jZS4KICBSRVRVUk5TOiBBIGxpc3Qgb2YgY2xhdXNlcyBkZXJpdmFibGUgZnJvbSBzdXBlcnBvc2l0aW9uIGxlZnQgb24gdGhlCiAgICAgICAgICAgR2l2ZW5Db3B5ICB3cnQuIHRoZSBJbmRleC4KICBNRU1PUlk6ICBBIGxpc3Qgb2YgY2xhdXNlcyBpcyBwcm9kdWNlZCwgd2hlcmUgbWVtb3J5IGZvciB0aGUgbGlzdAogICAgICAgICAgIGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgICAgUmVzdWx0LCBUZXJtTGlzdCwgUGFyZW50TGlzdDsKICBpbnQgICAgIEJvdHRvbTsKICBMSVRFUkFMIExpdDsKICBURVJNICAgIFRlcm0sIFBhcnRuZXJUZXJtLCBQYXJ0bmVyRXE7CgogIFJlc3VsdCA9IGxpc3RfTmlsKCk7CiAgTGl0ICAgID0gY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLGkpOwoKI2lmZGVmIENIRUNLCiAgaWYgKGNsYXVzZV9MaXRlcmFsSXNFcXVhbGl0eShMaXQpIHx8ICFjbGF1c2VfTGl0ZXJhbElzRnJvbUFudGVjZWRlbnQoTGl0KSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BMZWZ0TGl0VG9HaXZlbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBCb3R0b20gPSBzdGFja19Cb3R0b20oKTsKICBzaGFyaW5nX1B1c2hMaXN0T25TdGFjayh0ZXJtX0FyZ3VtZW50TGlzdChBdG9tKSk7CgogIHdoaWxlICghc3RhY2tfRW1wdHkoQm90dG9tKSkgewogICAgVGVybSA9IChURVJNKXN0YWNrX1BvcFJlc3VsdCgpOwogICAgaWYgKCF0ZXJtX0lzVmFyaWFibGUoVGVybSkpIHsKICAgICAgLyogU3VwZXJwb3NpdGlvbiBpbnRvIHZhcmlhYmxlcyBpcyBub3QgbmVjZXNzYXJ5ICovCiAgICAgIFRlcm1MaXN0ID0gc3RfR2V0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksCgkJCSAgICAgICBzaGFyaW5nX0luZGV4KFNoSW5kZXgpLAoJCQkgICAgICAgY29udF9SaWdodENvbnRleHQoKSwKCQkJICAgICAgIFRlcm0pOwogICAgICBmb3IgKCA7ICFsaXN0X0VtcHR5KFRlcm1MaXN0KTsgVGVybUxpc3Q9bGlzdF9Qb3AoVGVybUxpc3QpKSB7CglQYXJ0bmVyVGVybSA9IChURVJNKWxpc3RfQ2FyKFRlcm1MaXN0KTsKCWZvciAoUGFyZW50TGlzdCA9IHRlcm1fU3VwZXJ0ZXJtTGlzdChQYXJ0bmVyVGVybSk7CgkgICAgICFsaXN0X0VtcHR5KFBhcmVudExpc3QpOyBQYXJlbnRMaXN0ID0gbGlzdF9DZHIoUGFyZW50TGlzdCkpIHsKCSAgUGFydG5lckVxID0gKFRFUk0pbGlzdF9DYXIoUGFyZW50TGlzdCk7CgkgIGlmIChmb2xfSXNFcXVhbGl0eShQYXJ0bmVyRXEpKSB7CgkgICAgQ0xBVVNFICBQYXJ0bmVyQ2xhdXNlOwoJICAgIExJVEVSQUwgUGFydG5lckxpdDsKCSAgICBURVJNICAgIFBhcnRuZXJBdG9tOwoJICAgIExJU1QgICAgU2NsOwoJICAgIGludCAgICAgajsKCSAgICBmb3IgKFNjbCA9IHNoYXJpbmdfTkF0b21EYXRhTGlzdChQYXJ0bmVyRXEpOwoJCSAhbGlzdF9FbXB0eShTY2wpOyBTY2wgPSBsaXN0X0NkcihTY2wpKSB7CgkgICAgICBQYXJ0bmVyTGl0ICAgID0gKExJVEVSQUwpbGlzdF9DYXIoU2NsKTsKCSAgICAgIGogICAgICAgICAgICAgPSBjbGF1c2VfTGl0ZXJhbEdldEluZGV4KFBhcnRuZXJMaXQpOwoJICAgICAgUGFydG5lckNsYXVzZSA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKFBhcnRuZXJMaXQpOwoJICAgICAgUGFydG5lckF0b20gICA9IGNsYXVzZV9MaXRlcmFsQXRvbShQYXJ0bmVyTGl0KTsKCSAgICAgIGlmICghY2xhdXNlX0dldEZsYWcoUGFydG5lckNsYXVzZSxDTEFVU0VTRUxFQ1QpICYmCgkJICAoIU1heFBhcmEgfHwKCQkgICBjbGF1c2VfTGl0ZXJhbEdldEZsYWcoUGFydG5lckxpdCxTVFJJQ1RNQVhJTUFMKSkgJiYKCQkgICghT3JkUGFyYSB8fAoJCSAgIFBhcnRuZXJUZXJtID09IHRlcm1fRmlyc3RBcmd1bWVudChQYXJ0bmVyQXRvbSkgfHwKCQkgICAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoUGFydG5lckxpdCkpICYmCgkJICBjbGF1c2VfTGl0ZXJhbElzUG9zaXRpdmUoUGFydG5lckxpdCkgJiYKCQkgIGNsYXVzZV9OdW1iZXIoUGFydG5lckNsYXVzZSkgIT0gY2xhdXNlX051bWJlcihDbGF1c2UpICYmCgkJICAoIVVuaXQgfHwgY2xhdXNlX0xlbmd0aChQYXJ0bmVyQ2xhdXNlKSA9PSAxKSAmJgoJCSAgY2xhdXNlX0hhc1NvbHZlZENvbnN0cmFpbnQoUGFydG5lckNsYXVzZSkpIHsKCQlTWU1CT0wgTWF4VmFyOwoJCVRFUk0gICBQYXJ0bmVyTGVmdCxQYXJ0bmVyUmlnaHQ7CgkJU1VCU1QgIFN1YnN0LCBQYXJ0bmVyU3Vic3Q7CgkJVEVSTSAgIFN1cEF0b207CgoJCVN1cEF0b20gPSAoVEVSTSlOVUxMOwoJCU1heFZhciAgICAgID0gY2xhdXNlX01heFZhcihQYXJ0bmVyQ2xhdXNlKTsKCQljbGF1c2VfUmVuYW1lVmFyc0JpZ2dlclRoYW4oQ2xhdXNlLE1heFZhcik7CgkJY29udF9DaGVjaygpOwoJCXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksVGVybSxjb250X1JpZ2h0Q29udGV4dCgpLFBhcnRuZXJUZXJtKTsKCQlzdWJzdF9FeHRyYWN0VW5pZmllcihjb250X0xlZnRDb250ZXh0KCksJlN1YnN0LGNvbnRfUmlnaHRDb250ZXh0KCksJlBhcnRuZXJTdWJzdCk7CgkJY29udF9SZXNldCgpOwoJCWlmICghTWF4UGFyYSB8fAoJCSAgICBpbmZfTGl0ZXJhbHNNYXgoQ2xhdXNlLCBpLCBTdWJzdCwgUGFydG5lckNsYXVzZSwgaiwKCQkJCSAgICAgUGFydG5lclN1YnN0LCBGbGFncywgUHJlY2VkZW5jZSkpIHsKCQkgIFBhcnRuZXJMZWZ0ICA9IHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCQkJCSB0ZXJtX0NvcHkoUGFydG5lclRlcm0pKTsKCQkgIGlmIChQYXJ0bmVyVGVybSA9PSB0ZXJtX0ZpcnN0QXJndW1lbnQoUGFydG5lckF0b20pKQoJCSAgICBQYXJ0bmVyUmlnaHQgPSBzdWJzdF9BcHBseShQYXJ0bmVyU3Vic3QsCgkJCQkgdGVybV9Db3B5KHRlcm1fU2Vjb25kQXJndW1lbnQoUGFydG5lckF0b20pKSk7CgkJICBlbHNlCgkJICAgIFBhcnRuZXJSaWdodCA9IHN1YnN0X0FwcGx5KFBhcnRuZXJTdWJzdCwKCQkJCSB0ZXJtX0NvcHkodGVybV9GaXJzdEFyZ3VtZW50KFBhcnRuZXJBdG9tKSkpOwoKCQkgIGlmICghT3JkUGFyYSB8fAoJCSAgICAgIGNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KFBhcnRuZXJMaXQpIHx8CgkJICAgICAgb3JkX0NvbXBhcmUoUGFydG5lckxlZnQsUGFydG5lclJpZ2h0LEZsYWdzLCBQcmVjZWRlbmNlKQoJCSAgICAgICE9IG9yZF9TbWFsbGVyVGhhbigpKSB7CgkJICAgIFN1cEF0b20gPSBpbmZfQWxsVGVybXNScGxhYyhBdG9tLFRlcm0sUGFydG5lclJpZ2h0LFN1YnN0KTsKI2lmZGVmIENIRUNLCgkJICAgIGlmIChTdXBBdG9tID09IE5VTEwpIHsKCQkgICAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKCQkgICAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BSaWdodExpdFRvR2l2ZW46Iik7CgkJICAgICAgbWlzY19FcnJvclJlcG9ydCgiIHJlcGxhY2VtZW50IHdhc24ndCBwb3NzaWJsZS4iKTsKCQkgICAgICBtaXNjX0ZpbmlzaEVycm9yUmVwb3J0KCk7CgkJICAgIH0KI2VuZGlmCgkJICAgIFJlc3VsdCA9CgkJICAgICAgbGlzdF9Db25zKGluZl9BcHBseUdlblN1cGVycG9zaXRpb24oUGFydG5lckNsYXVzZSwgaiwKCQkJCQkJCSAgUGFydG5lclN1YnN0LCBDbGF1c2UsCgkJCQkJCQkgIGksIFN1YnN0LCBTdXBBdG9tLAoJCQkJCQkJICBGQUxTRSwgT3JkUGFyYSwKCQkJCQkJCSAgTWF4UGFyYSwgRmxhZ3MsCgkJCQkJCQkgIFByZWNlZGVuY2UpLCAKCQkJCVJlc3VsdCk7CgoJCSAgfQoJCSAgdGVybV9EZWxldGUoUGFydG5lckxlZnQpOwoJCSAgdGVybV9EZWxldGUoUGFydG5lclJpZ2h0KTsKCQl9CgkJc3Vic3RfRGVsZXRlKFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUGFydG5lclN1YnN0KTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUmVzdWx0Owp9CgoKc3RhdGljIExJU1QgaW5mX0dlblNQTGVmdFRvR2l2ZW4oQ0xBVVNFIENsYXVzZSwgaW50IGksIFNIQVJFRF9JTkRFWCBTaEluZGV4LCAKCQkJCSBCT09MIE9yZFBhcmEsIEJPT0wgTWF4UGFyYSwgQk9PTCBVbml0LAoJCQkJIEZMQUdTVE9SRSBGbGFncywgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBbiB1bnNoYXJlZCBjbGF1c2UsIHRoZSBpbmRleCBvZiBhbiBhbnRlY2VkZW50CiAgICAgICAgICAgbGl0ZXJhbCwgYW4gaW5kZXggb2Ygc2hhcmVkIGNsYXVzZXMsIHRocmVlIGJvb2xlYW4KCSAgIGZsYWdzIGZvciBjb250cm9sbGluZyBpbmZlcmVuY2UgcHJlY29uZGl0aW9ucyAoc2VlCgkgICBpbmZfR2VuU3VwZXJwb3NpdGlvbkxlZnQpLCBhIGZsYWcgc3RvcmUgYW5kIGEKCSAgIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gU3VwZXJwb3NpdGlvbiBMZWZ0CiAgICAgICAgICAgb24gdGhlIEdpdmVuQ29weSAgd3J0LiB0aGUgSW5kZXguCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlCiAgICAgICAgICAgbGlzdCBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBURVJNIEF0b207CiAgTElTVCBSZXN1bHQ7CgojaWZkZWYgQ0hFQ0sKICBpZiAoY2xhdXNlX0dldEZsYWcoQ2xhdXNlLCBOT1BBUkFJTlRPKSB8fAogICAgICAoIWNsYXVzZV9MaXRlcmFsR2V0RmxhZyhjbGF1c2VfR2V0TGl0ZXJhbChDbGF1c2UsaSksTElUU0VMRUNUKSAmJgogICAgICAgKGNsYXVzZV9HZXRGbGFnKENsYXVzZSwgQ0xBVVNFU0VMRUNUKSB8fAoJKE1heFBhcmEgJiYgIWNsYXVzZV9MaXRlcmFsSXNNYXhpbWFsKGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKSkpKSkpIHsKICAgICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU1BMZWZ0VG9HaXZlbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBSZXN1bHQgID0gbGlzdF9OaWwoKTsKICBBdG9tICAgID0gY2xhdXNlX0xpdGVyYWxBdG9tKGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKSk7CgogIGlmIChmb2xfSXNFcXVhbGl0eShBdG9tKSkgewogICAgUmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfR2VuU1BMZWZ0RXFUb0dpdmVuKENsYXVzZSxpLCBUUlVFLFNoSW5kZXgsIE9yZFBhcmEsCgkJCQkJICAgICAgIE1heFBhcmEsIFVuaXQsIEZsYWdzLFByZWNlZGVuY2UpLCAKCQkJUmVzdWx0KTsKICAgIGlmICghTWF4UGFyYSB8fAoJIWNsYXVzZV9MaXRlcmFsSXNPcmllbnRlZEVxdWFsaXR5KGNsYXVzZV9HZXRMaXRlcmFsKENsYXVzZSxpKSkpCiAgICAgIC8qIEZvciBTUG0gYW5kIE9QbSBhbHdheXMgdHJ5IG90aGVyIGRpcmVjdGlvbiwgZm9yIFNwUiB0cnkgaXQgKi8KICAgICAgLyogb25seSBpZiB0aGUgbGl0ZXJhbCBpcyBub3Qgb3JpZW50ZWQuICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICBSZXN1bHQgPSBsaXN0X05jb25jKGluZl9HZW5TUExlZnRFcVRvR2l2ZW4oQ2xhdXNlLGksRkFMU0UsU2hJbmRleCxPcmRQYXJhLAoJCQkJCQkgTWF4UGFyYSxVbml0LEZsYWdzLFByZWNlZGVuY2UpLAoJCQkgIFJlc3VsdCk7CiAgfSBlbHNlCiAgICBSZXN1bHQgPSBsaXN0X05jb25jKGluZl9HZW5TUExlZnRMaXRUb0dpdmVuKENsYXVzZSxpLEF0b20sU2hJbmRleCxPcmRQYXJhLAoJCQkJCQlNYXhQYXJhLFVuaXQsRmxhZ3MsUHJlY2VkZW5jZSksCgkJCVJlc3VsdCk7CgogIHJldHVybiBSZXN1bHQ7Cn0KCgpMSVNUIGluZl9HZW5TdXBlcnBvc2l0aW9uTGVmdChDTEFVU0UgR2l2ZW5DbGF1c2UsIFNIQVJFRF9JTkRFWCBTaEluZGV4LCAKCQkJICAgICAgQk9PTCBPcmRQYXJhLCBCT09MIE1heFBhcmEsIEJPT0wgVW5pdCwKCQkJICAgICAgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlIGFuZCBhbiBJbmRleCwgdXN1YWxseSB0aGUgV29ya2VkT2ZmSW5kZXgsCiAgICAgICAgICAgdHdvIGJvb2xlYW4gZmxhZ3MgZm9yIGNvbnRyb2xsaW5nIGluZmVyZW5jZQogICAgICAgICAgIHByZWNvbmRpdGlvbnMsIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tIHRoZSBHaXZlbmNsYXVzZSBieSAKICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZyBpbmZlcmVuY2UgcnVsZXMgd3J0LiB0aGUgSW5kZXg6CgoJICAgT3JkUGFyYT1UUlVFLCBNYXhQYXJhPVRSVUUgCgkgICAtPiBTdXBlcnBvc2l0aW9uIExlZnQKCgkgICBPcmRQYXJhPVRSVUUsIE1heFBhcmE9RkFMU0UKCSAgIC0+IG9yZGVyZWQgUGFyYW1vZHVsYXRpb24KCgkgICBPcmRQYXJhPUZBTFNFLCBNYXhQYXJhPUZBTFNFCgkgICAtPiBzaW1wbGUgUGFyYW1vZHVsYXRpb24KCgkgICBPcmRQYXJhPUZBTFNFLCBNYXhQYXJhPVRSVUUKCSAgIC0+IG5vdCBkZWZpbmVkCgoJICAgSWYgPFVuaXQ+PT1UUlVFIHRoZSBjbGF1c2Ugd2l0aCB0aGUgbWF4aW1hbCBlcXVhbGl0eSAKCSAgIGFkZGl0aW9uYWxseSBtdXN0IGJlIGEgdW5pdCBjbGF1c2UuCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgIFJlc3VsdDsKICBURVJNICAgIEF0b207CiAgQ0xBVVNFICBDb3B5OwogIGludCAgICAgaSwgbjsKICBMSVRFUkFMIEFjdExpdDsKCiNpZmRlZiBDSEVDSwogIGlmICghY2xhdXNlX0lzQ2xhdXNlKEdpdmVuQ2xhdXNlLCBGbGFncywgUHJlY2VkZW5jZSkpIHsKICAgIG1pc2NfU3RhcnRFcnJvclJlcG9ydCgpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0dlblN1cGVycG9zaXRpb25MZWZ0OiBJbGxlZ2FsIGlucHV0LiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KICBpZiAoIU9yZFBhcmEgJiYgTWF4UGFyYSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfR2VuU3VwZXJwb3NpdGlvbkxlZnQ6IElsbGVnYWwgaW5mZXJlbmNlIHJ1bGUgc2VsZWN0aW9uLCIpOwogICAgbWlzY19FcnJvclJlcG9ydCgiXG4gT3JkUGFyYT1GQUxTRSAmIE1heFBhcmE9VFJVRS4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBSZXN1bHQgPSBsaXN0X05pbCgpOwoKICBpZiAoIWNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KEdpdmVuQ2xhdXNlKSkKICAgIHJldHVybiBSZXN1bHQ7CiAgCiAgQ29weSA9IGNsYXVzZV9Db3B5KEdpdmVuQ2xhdXNlKTsKICBuICAgID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChDb3B5KTsKICAKICBpZiAoIWNsYXVzZV9HZXRGbGFnKENvcHksIENMQVVTRVNFTEVDVCkgJiYKICAgICAgKCFVbml0IHx8IGNsYXVzZV9MZW5ndGgoQ29weSkgPT0gMSkpIHsKICAgIGZvciAoaSA9IGNsYXVzZV9GaXJzdFN1Y2NlZGVudExpdEluZGV4KENvcHkpOyBpIDw9IG47IGkrKykgewogICAgICBBY3RMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChDb3B5LCBpKTsKICAgICAgQXRvbSAgID0gY2xhdXNlX0xpdGVyYWxTaWduZWRBdG9tKEFjdExpdCk7CiAgICAgIAogICAgICBpZiAoZm9sX0lzRXF1YWxpdHkoQXRvbSkgJiYKCSAgKCFNYXhQYXJhIHx8CgkgICBjbGF1c2VfTGl0ZXJhbEdldEZsYWcoQWN0TGl0LFNUUklDVE1BWElNQUwpKSkgewoJCglSZXN1bHQgPQoJICBsaXN0X05jb25jKGluZl9HZW5MaXRTUExlZnQoQ29weSwgdGVybV9GaXJzdEFyZ3VtZW50KEF0b20pLCAKCQkJCSAgICAgIHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSksIGksIFNoSW5kZXgsCgkJCQkgICAgICBPcmRQYXJhLCBNYXhQYXJhLCBGbGFncywgUHJlY2VkZW5jZSksIAoJCSAgICAgUmVzdWx0KTsKCWlmICghT3JkUGFyYSB8fCAhY2xhdXNlX0xpdGVyYWxJc09yaWVudGVkRXF1YWxpdHkoQWN0TGl0KSkKCSAgLyogRm9yIFNQbSBhbHdheXMgdHJ5IHRoZSBvdGhlciBkaXJlY3Rpb24sIGZvciBPUG0gYW5kIFNwTCAqLwoJICAvKiBvbmx5IHRyeSBpdCBpZiB0aGUgbGl0ZXJhbCBpcyBub3Qgb3JpZW50ZWQuICAgICAgICAgICAgICovCgkgIFJlc3VsdCA9CgkgICAgbGlzdF9OY29uYyhpbmZfR2VuTGl0U1BMZWZ0KENvcHksIHRlcm1fU2Vjb25kQXJndW1lbnQoQXRvbSksIAoJCQkJCXRlcm1fRmlyc3RBcmd1bWVudChBdG9tKSwgaSwgU2hJbmRleCwKCQkJCQlPcmRQYXJhLCBNYXhQYXJhLCBGbGFncywgUHJlY2VkZW5jZSksIAoJCSAgICAgICBSZXN1bHQpOwogICAgICB9CiAgICB9CiAgfQoKICBuID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoQ29weSk7ICAKICBpZiAoIWNsYXVzZV9HZXRGbGFnKENvcHksTk9QQVJBSU5UTykpIHsKICAgIGZvciAoaSA9IGNsYXVzZV9GaXJzdEFudGVjZWRlbnRMaXRJbmRleChDb3B5KTsgaSA8PSBuOyBpKyspIHsKICAgICAgQWN0TGl0ID0gY2xhdXNlX0dldExpdGVyYWwoQ29weSwgaSk7CiAgICAgIAogICAgICBpZiAoY2xhdXNlX0xpdGVyYWxHZXRGbGFnKEFjdExpdCwgTElUU0VMRUNUKSB8fAoJICAoIWNsYXVzZV9HZXRGbGFnKENvcHksIENMQVVTRVNFTEVDVCkgJiYKCSAgICghTWF4UGFyYSB8fCBjbGF1c2VfTGl0ZXJhbElzTWF4aW1hbChBY3RMaXQpKSkpCglSZXN1bHQgPSBsaXN0X05jb25jKGluZl9HZW5TUExlZnRUb0dpdmVuKENvcHksIGksIFNoSW5kZXgsIE9yZFBhcmEsCgkJCQkJCSBNYXhQYXJhLFVuaXQsRmxhZ3MsUHJlY2VkZW5jZSksCgkJCSAgICBSZXN1bHQpOwogICAgfQogIH0KICBjbGF1c2VfRGVsZXRlKENvcHkpOwoKICByZXR1cm4oUmVzdWx0KTsKfQoKCgpMSVNUIGluZl9BcHBseURlZmluaXRpb24oUFJPT0ZTRUFSQ0ggU2VhcmNoLCBDTEFVU0UgQ2xhdXNlLAoJCQkgRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgcHJvb2Ygc2VhcmNoIG9iamVjdCwgYSBjbGF1c2UsIGEgZmxhZyBzdG9yZSBhbmQgYQogICAgICAgICAgIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgZGVyaXZhYmxlIGZyb20gdGhlIGdpdmVuIGNsYXVzZSBieSAKICAgICAgICAgICBhcHBseWluZyB0aGUgKHBvdGVudGlhbCkgZGVmaW5pdGlvbnMgaW4gPFNlYXJjaD4uCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUIFJlc3VsdCwgRGVmczsKICBERUYgIERlZjsKICAKICBSZXN1bHQgPSBsaXN0X05pbCgpOwogIGZvciAoRGVmcz1wcmZzX0RlZmluaXRpb25zKFNlYXJjaCk7ICFsaXN0X0VtcHR5KERlZnMpOyBEZWZzPWxpc3RfQ2RyKERlZnMpKSB7CiAgICBEZWYgPSAoREVGKWxpc3RfQ2FyKERlZnMpOwogICAgUmVzdWx0ID0gbGlzdF9OY29uYyhkZWZfQXBwbHlEZWZUb0NsYXVzZU9uY2UoRGVmLCBDbGF1c2UsIEZsYWdzLCBQcmVjZWRlbmNlKSwKCQkJUmVzdWx0KTsKICB9CiAgcmV0dXJuIFJlc3VsdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIGJsb2NrIHdpdGggaHlwZXJyZXNvbHV0aW9uIGNvZGUgc3RhcnRzIGhlcmUKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIExJVEVSQUwgTnVjbGV1c0xpdDsKICBMSVRFUkFMIEVsZWN0cm9uTGl0OwogIFNVQlNUICAgRWxlY3Ryb25TdWJzdDsKfSBJTkZfTUFQTk9ERSwgKklORl9NQVBJVEVNOwoKCnN0YXRpYyB2b2lkIGluZl9Db3B5SHlwZXJFbGVjdHJvbihDTEFVU0UgQ2xhdXNlLCBTVUJTVCBTdWJzdDIsIFNVQlNUIFN1YnN0MSwKCQkJCSAgaW50IFBMaXRJbmQsIExJU1QqIENvbnN0cmFpbnQsCgkJCQkgIExJU1QqIFN1Y2NlZGVudCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQW4gZWxlY3Ryb24gY2xhdXNlLCBhIHN1YnN0aXR1dGlvbiwgYW4gaW5kZXggb2YgYQogICAgICAgICAgIHN1Y2NlZGVudCBsaXRlcmFsIGluIHRoaXMgY2xhdXNlICh0aGUgbWF0Y2hlZCBvbmUpLAoJICAgYW5kIHR3byBsaXN0cyBieSByZWZlcmVuY2UuCiAgUkVUVVJOUzogTm90aGluZy4KICBFRkZFQ1RTOiBUaGUgY29uc3RyYWludCBhbmQgc3VjY2VkZW50IGxpdGVyYWxzIGFyZSBjb3BpZWQgaW50bwogICAgICAgICAgIHRoZSBjb3JyZXNwb25kaW5nIGxpc3RzIGV4Y2VwdCBmb3IgdGhlIGxpdGVyYWwgd2l0aAoJICAgdGhlIGdpdmVuIGluZGV4LiBUaGUgY29tcG9zaXRpb24gPFN1YnN0Mj4gsCA8U3Vic3QxPgoJICAgaXMgYXBwbGllZCB0byBhbGwgY29waWVkIGxpdGVyYWxzLgoJICAgVGhlIGFudGVjZWRlbnQgb2YgdGhlIGVsZWN0cm9uIGNsYXVzZSBpcyBlbXB0eSwgc28KCSAgIHRoZXJlJ3Mgbm8gbmVlZCBmb3IgYSB0aGlyZCBsaXN0IGJ5IHJlZmVyZW5jZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgVEVSTSBBdG9tOwogIGludCAgbiwgbGMsIGo7CgojaWZkZWYgQ0hFQ0sKICBpZiAoY2xhdXNlX051bU9mQW50ZUxpdHMoQ2xhdXNlKSAhPSAwKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9Db3B5SHlwZXJFbGVjdHJvbjogRWxlY3Ryb24gY29udGFpbnMgYW50ZWNlZGVudCBsaXRlcmFscy4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBuICA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoQ2xhdXNlKTsKICBsYyA9IGNsYXVzZV9MYXN0Q29uc3RyYWludExpdEluZGV4KENsYXVzZSk7CgogIGZvciAoaiA9IGNsYXVzZV9GaXJzdENvbnN0cmFpbnRMaXRJbmRleChDbGF1c2UpOyBqIDw9IG47IGorKykgewogICAgaWYgKGogIT0gUExpdEluZCkgewogICAgICBBdG9tID0gc3Vic3RfQXBwbHkoU3Vic3QxLCB0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxBdG9tKENsYXVzZSwgaikpKTsKICAgICAgQXRvbSA9IHN1YnN0X0FwcGx5KFN1YnN0MiwgQXRvbSk7CiAgICAgIGlmIChqIDw9IGxjKSAKCSpDb25zdHJhaW50ID0gbGlzdF9Db25zKEF0b20sICpDb25zdHJhaW50KTsKICAgICAgZWxzZSAvKiBMaXRlcmFsIG11c3QgYmUgZnJvbSBzdWNjZWRlbnQgKi8KCSpTdWNjZWRlbnQgID0gbGlzdF9Db25zKEF0b20sICpTdWNjZWRlbnQpOwogICAgfQogIH0KfQoKCnN0YXRpYyBDTEFVU0UgaW5mX0J1aWxkSHlwZXJSZXNvbHZlbnQoQ0xBVVNFIE51Y2xldXMsIFNVQlNUIFN1YnN0LAoJCQkJICAgICAgTElTVCBGb3VuZE1hcCwgQk9PTCBTdHJpY3RseU1heGltYWwsCgkJCQkgICAgICBGTEFHU1RPUkUgRmxhZ3MsIFBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2UgPE51Y2xldXM+IHdpdGggc29sdmVkIHNvcnQgY29uc3RyYWludCwKCSAgIHRoZSBzdWJzdGl0dXRpb24gPFN1YnN0PiBmb3IgPE51Y2xldXM+LCBhIG1hcHBpbmcKCSAgIDxGb3VuZE1hcD4gb2YgbGl0ZXJhbHMgb2YgYWxyZWFkeSBmb3VuZCBwYXJ0bmVyCgkgICBjbGF1c2VzLCBhIGJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBpcwoJICAgYSBvcmRlcmVkIG9yIGEgc3RhbmRhcmQgaHlwZXIgcmVzb2x1dGlvbiBpbmZlcmVuY2UKCSAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IFRoZSBuZXdseSBjcmVhdGVkIGh5cGVyIHJlc29sdmVudC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgQ0xBVVNFICBOZXdDbGF1c2U7CiAgTElTVCAgICBDb25zdHJhaW50LCBTdWNjZWRlbnQsIFBhcmVudHMsIFBhcmVudE51bSwgUGFyZW50TGl0cywgU2NhbjsKICBpbnQgICAgIGksIGJvdW5kLCBEZXB0aDsKICBMSVRFUkFMIExpdDsKICBTVUJTVCAgIEVTdWJzdDsKICBJTkZfTUFQSVRFTSBNYXBJdGVtOwoKICBQYXJlbnRzICAgID0gbGlzdF9MaXN0KE51Y2xldXMpOyAgICAgIC8qIHBhcmVudCBjbGF1c2VzICAqLwogIFBhcmVudE51bSAgPSBsaXN0X05pbCgpOyAgICAgICAgICAgICAgLyogcGFyZW50IGNsYXVzZSBudW1iZXJzICovCiAgUGFyZW50TGl0cyA9IGxpc3RfTmlsKCk7ICAgICAgICAgICAgICAvKiBsaXRlcmFsIGluZGljZXMgKi8KICBDb25zdHJhaW50ID0gU3VjY2VkZW50ID0gbGlzdF9OaWwoKTsgIC8qIGxpdGVyYWxzIG9mIHRoZSBuZXcgY2xhdXNlICovCiAgCiAgLyogR2V0IGNvbnN0cmFpbnQgbGl0ZXJhbHMgZnJvbSBudWNsZXVzICovCiAgYm91bmQgPSBjbGF1c2VfTGFzdENvbnN0cmFpbnRMaXRJbmRleChOdWNsZXVzKTsKICBmb3IgKGkgPSBjbGF1c2VfRmlyc3RDb25zdHJhaW50TGl0SW5kZXgoTnVjbGV1cyk7IGkgPD0gYm91bmQ7IGkrKykKICAgIENvbnN0cmFpbnQgPQogICAgICBsaXN0X0NvbnMoc3Vic3RfQXBwbHkoU3Vic3QsdGVybV9Db3B5KGNsYXVzZV9HZXRMaXRlcmFsQXRvbShOdWNsZXVzLGkpKSksCgkJQ29uc3RyYWludCk7CiAgLyogR2V0IHN1Y2NlZGVudCBsaXRlcmFscyBmcm9tIG51Y2xldXMgKi8KICBib3VuZCA9IGNsYXVzZV9MYXN0U3VjY2VkZW50TGl0SW5kZXgoTnVjbGV1cyk7CiAgZm9yIChpID0gY2xhdXNlX0ZpcnN0U3VjY2VkZW50TGl0SW5kZXgoTnVjbGV1cyk7IGkgPD0gYm91bmQ7IGkrKykKICAgIFN1Y2NlZGVudCA9CiAgICAgIGxpc3RfQ29ucyhzdWJzdF9BcHBseShTdWJzdCx0ZXJtX0NvcHkoY2xhdXNlX0dldExpdGVyYWxBdG9tKE51Y2xldXMsaSkpKSwKCQlTdWNjZWRlbnQpOwoKICAvKiBOb3cgZ2V0IHRoZSByZW1haW5pbmcgZGF0YSBmb3IgdGhlIHJlc29sdmVudCAqLwogIERlcHRoID0gY2xhdXNlX0RlcHRoKE51Y2xldXMpOwogIGJvdW5kID0gY2xhdXNlX0xhc3RBbnRlY2VkZW50TGl0SW5kZXgoTnVjbGV1cyk7CiAgZm9yIChpID0gY2xhdXNlX0ZpcnN0QW50ZWNlZGVudExpdEluZGV4KE51Y2xldXMpOyBpIDw9IGJvdW5kOyBpKyspIHsKICAgIC8qIFNlYXJjaCA8Rm91bmRNYXA+IGZvciB0aGUgbnVjbGV1cyBsaXRlcmFsIHdpdGggaW5kZXggPGk+ICovCiAgICBMaXQgPSBjbGF1c2VfR2V0TGl0ZXJhbChOdWNsZXVzLCBpKTsKICAgIGZvciAoU2NhbiA9IEZvdW5kTWFwLCBNYXBJdGVtID0gTlVMTDsgIWxpc3RfRW1wdHkoU2Nhbik7CgkgU2NhbiA9IGxpc3RfQ2RyKFNjYW4pKSB7CiAgICAgIE1hcEl0ZW0gPSBsaXN0X0NhcihTY2FuKTsKICAgICAgaWYgKE1hcEl0ZW0tPk51Y2xldXNMaXQgPT0gTGl0KQoJYnJlYWs7CiAgICB9CgogICAgaWYgKE1hcEl0ZW0gPT0gTlVMTCB8fCBNYXBJdGVtLT5OdWNsZXVzTGl0ICE9IExpdCkgewogICAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgICAgbWlzY19FcnJvclJlcG9ydCgiXG4gSW4gaW5mX0J1aWxkSHlwZXJSZXNvbHZlbnQ6IE1hcCBlbnRyeSBub3QgZm91bmQuIik7CiAgICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICAgIH0KCiAgICBMaXQgICAgICAgPSBNYXBJdGVtLT5FbGVjdHJvbkxpdDsKICAgIE5ld0NsYXVzZSA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKExpdCk7CiAgICBFU3Vic3QgICAgPSBNYXBJdGVtLT5FbGVjdHJvblN1YnN0OwoKICAgIERlcHRoICAgICAgPSBtaXNjX01heChEZXB0aCwgY2xhdXNlX0RlcHRoKE5ld0NsYXVzZSkpOwogICAgUGFyZW50cyAgICA9IGxpc3RfQ29ucyhOZXdDbGF1c2UsIFBhcmVudHMpOwogICAgUGFyZW50TnVtICA9IGxpc3RfQ29ucygoUE9JTlRFUikgY2xhdXNlX051bWJlcihOdWNsZXVzKSwgUGFyZW50TnVtKTsKICAgIFBhcmVudExpdHMgPSBsaXN0X0NvbnMoKFBPSU5URVIpIGksIFBhcmVudExpdHMpOwogICAgUGFyZW50TnVtICA9IGxpc3RfQ29ucygoUE9JTlRFUikgY2xhdXNlX051bWJlcihOZXdDbGF1c2UpLCBQYXJlbnROdW0pOwogICAgUGFyZW50TGl0cyA9IGxpc3RfQ29ucygoUE9JTlRFUikgY2xhdXNlX0xpdGVyYWxHZXRJbmRleChMaXQpLCBQYXJlbnRMaXRzKTsKCiAgICAvKiBHZXQgdGhlIHJlbWFpbmluZyBjb25zdHJhaW50IGFuZCBzdWNjZWRlbnQgbGl0ZXJhbHMgZnJvbSBlbGVjdHJvbiAqLwogICAgaW5mX0NvcHlIeXBlckVsZWN0cm9uKE5ld0NsYXVzZSxTdWJzdCxFU3Vic3QsY2xhdXNlX0xpdGVyYWxHZXRJbmRleChMaXQpLAoJCQkgICZDb25zdHJhaW50LCAmU3VjY2VkZW50KTsKICB9CgogIC8qIGNyZWF0ZSBuZXcgY2xhdXNlIGFuZCBzZXQgY2xhdXNlIGRhdGEgKi8KICBOZXdDbGF1c2UgPSBjbGF1c2VfQ3JlYXRlKENvbnN0cmFpbnQsIGxpc3RfTmlsKCksIFN1Y2NlZGVudCwgRmxhZ3MsUHJlY2VkZW5jZSk7CgogIGlmIChTdHJpY3RseU1heGltYWwpCiAgICBjbGF1c2VfU2V0RnJvbU9yZGVyZWRIeXBlclJlc29sdXRpb24oTmV3Q2xhdXNlKTsKICBlbHNlCiAgICBjbGF1c2VfU2V0RnJvbVNpbXBsZUh5cGVyUmVzb2x1dGlvbihOZXdDbGF1c2UpOwoKICBjbGF1c2VfU2V0RGVwdGgoTmV3Q2xhdXNlLCBEZXB0aCArIDEpOwoKICBjbGF1c2VfU2V0U3BsaXREYXRhRnJvbUxpc3QoTmV3Q2xhdXNlLCBQYXJlbnRzKTsKCiAgY2xhdXNlX1NldFBhcmVudENsYXVzZXMoTmV3Q2xhdXNlLCBsaXN0X05SZXZlcnNlKFBhcmVudE51bSkpOwogIGNsYXVzZV9TZXRQYXJlbnRMaXRlcmFscyhOZXdDbGF1c2UsIGxpc3RfTlJldmVyc2UoUGFyZW50TGl0cykpOwoKICAvKiBjbGVhbiB1cCAqLwogIGxpc3RfRGVsZXRlKFBhcmVudHMpOwogIGxpc3RfRGVsZXRlKENvbnN0cmFpbnQpOwogIGxpc3RfRGVsZXRlKFN1Y2NlZGVudCk7CgogIHJldHVybiBOZXdDbGF1c2U7Cn0KCgpzdGF0aWMgTElTVCBpbmZfR2V0SHlwZXJSZXNvbHV0aW9uUGFydG5lckxpdHMoVEVSTSBBdG9tLCBTSEFSRURfSU5ERVggSW5kZXgsCgkJCQkJICAgICAgQk9PTCBTdHJpY3RseU1heGltYWwpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEFuIGF0b20sIGEgY2xhdXNlIGluZGV4LCBhbmQgYSBib29sZWFuIGZsYWcuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGxpdGVyYWxzIGZyb20gcHVyZWx5IHBvc2l0aXZlIGNsYXVzZXMKICAgICAgICAgICBmcm9tIHRoZSBpbmRleCB3aGVyZSBlaXRoZXIgPFN0cmljdGx5TWF4aW1hbD4gaXMKCSAgIGZhbHNlIG9yIHRoZSBsaXRlcmFscyBhcmUgc3RyaWN0bHkgbWF4aW1hbCBpbiB0aGVpcgoJICAgcmVzcGVjdGl2ZSBjbGF1c2VzLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgIFJlc3VsdCwgVGVybUxpc3QsIExpdFNjYW47CiAgTElURVJBTCBOZXh0TGl0OwogIENMQVVTRSAgQ2xhdXNlOwoKI2lmZGVmIENIRUNLICAKICBpZiAoIXRlcm1fSXNBdG9tKEF0b20pKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9HZXRIeXBlclJlc29sdXRpb25QYXJ0bmVyTGl0czogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgoKICBSZXN1bHQgICA9IGxpc3RfTmlsKCk7CiAgVGVybUxpc3QgPSBzdF9HZXRVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSwgc2hhcmluZ19JbmRleChJbmRleCksCgkJCSAgIGNvbnRfUmlnaHRDb250ZXh0KCksIEF0b20pOwogIAogIGZvciAoOyAhbGlzdF9FbXB0eShUZXJtTGlzdCk7IFRlcm1MaXN0ID0gbGlzdF9Qb3AoVGVybUxpc3QpKSB7CiAgICBpZiAoIXRlcm1fSXNWYXJpYWJsZShsaXN0X0NhcihUZXJtTGlzdCkpKSB7CiAgICAgIGZvciAoTGl0U2NhbiA9IHNoYXJpbmdfTkF0b21EYXRhTGlzdChsaXN0X0NhcihUZXJtTGlzdCkpOyAKCSAgICFsaXN0X0VtcHR5KExpdFNjYW4pOyAKCSAgIExpdFNjYW4gPSBsaXN0X0NkcihMaXRTY2FuKSkgewoJTmV4dExpdCA9IGxpc3RfQ2FyKExpdFNjYW4pOwoJQ2xhdXNlICA9IGNsYXVzZV9MaXRlcmFsT3duaW5nQ2xhdXNlKE5leHRMaXQpOwoJaWYgKGNsYXVzZV9MaXRlcmFsSXNGcm9tU3VjY2VkZW50KE5leHRMaXQpICYmCgkgICAgKCFTdHJpY3RseU1heGltYWwgfHwgY2xhdXNlX0xpdGVyYWxHZXRGbGFnKE5leHRMaXQsIFNUUklDVE1BWElNQUwpKSAmJgoJICAgIGNsYXVzZV9IYXNTb2x2ZWRDb25zdHJhaW50KENsYXVzZSkgJiYKCSAgICBjbGF1c2VfSGFzRW1wdHlBbnRlY2VkZW50KENsYXVzZSkpIAoJICBSZXN1bHQgPSBsaXN0X0NvbnMoTmV4dExpdCwgUmVzdWx0KTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gUmVzdWx0Owp9CgpzdGF0aWMgTElTVCBpbmZfSHlwZXJSZXNvbHZlbnRzKENMQVVTRSBDbGF1c2UsIFNVQlNUIFN1YnN0LCBMSVNUIFJlc3RsaXRzLAoJCQkJaW50IEdsb2JhbE1heFZhciwgTElTVCBGb3VuZE1hcCwgCgkJCQlCT09MIFN0cmljdGx5TWF4aW1hbCwgU0hBUkVEX0lOREVYIEluZGV4LAoJCQkJRkxBR1NUT1JFIEZsYWdzLCBQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgbnVjbGV1cyA8Q2xhdXNlPiB3aGVyZSB0aGUgc29ydCBjb25zdHJhaW50IGlzCiAgICAgICAgICAgc29sdmVkLAogICAgICAgICAgIGEgc3Vic3RpdHV0aW9uLCB0aGF0IGhhcyB0byBiZSBhcHBsaWVkIHRvIHRoZQoJICAgbnVjbGV1cywKCSAgIGEgbGlzdCA8UmVzdGxpdHM+IG9mIGFudGVjZWRlbnQgbGl0ZXJhbHMgZm9yIHdoaWNoCgkgICBhIHBhcnRuZXIgY2xhdXNlIGlzIHNlYXJjaGVkLAoJICAgYSBsaXN0IDxGb3VuZE1hcD4gb2YgbWFwIGl0ZW1zIChuLGUscyksIHdoZXJlCgkgICBuIGlzIGFuIGFudGVjZWRlbnQgbGl0ZXJhbCBmcm9tIHRoZSBudWNsZXVzLAoJICAgZSBpcyBhIHBvc2l0aXZlIGxpdGVyYWwgZnJvbSBhbiBlbGVjdHJvbiBjbGF1c2UsCgkgICB0aGF0IGlzIHVuaWZpYWJsZSB3aXRoIG4gYW5kIHMgaXMgYSBzdWJzdGl0dXRpb24KCSAgIHRoYXQgaGFzIHRvIGJlIGFwcGxpZWQgdG8gdGhlIGVsZWN0cm9uIGNsYXVzZSwKCSAgIGEgZmxhZyBzdG9yZSBhbmQKCSAgIGEgcHJlY2VkZW5jZS4KCSAgIEEgbWFpbiBpbnZhcmlhbnQgb2Ygb3VyIGFsZ29yaXRobSBpcyB0aGF0IGFsbCBpbnZvbHZlZAoJICAgY2xhdXNlcyBhcmUgcGFpcndpc2UgdmFyaWFibGUgZGlzam9pbnQuIEZvciB0aGF0IHJlYXNvbgoJICAgd2UgbmVlZCwgd2hlbiBidWlsZGluZyB0aGUgcmVzb2x2ZW50LCBvbmx5IGFwcGx5IHRoZSBlbGVjdHJvbgoJICAgc3BlY2lmaWMgc3Vic3RpdHV0aW9uIGFuZCB0aGUgY29tcG9zZWQgc3Vic3RpdHV0aW9uIDxTdWJzdD4KCSAgIHRvIHRoZSBlbGVjdHJvbiBjbGF1c2VzLCBhbmQgb25seSA8U3Vic3Q+IHRvIHRoZSBudWNsZXVzIGNsYXVzZS4KICBSRVRVUk5TOiBUaGUgbGlzdCBvZiBoeXBlci1yZXNvbHZlbnRzLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVRFUkFMIExpdCwgUExpdDsKCiAgaWYgKGxpc3RfRW1wdHkoUmVzdGxpdHMpKSB7CiAgICAvKiBUaGlzIGNhc2Ugc3RvcHMgdGhlIHJlY3Vyc2lvbiAqLwogICAgTElTVCAgICAgICAgU2NhbjsKICAgIElORl9NQVBJVEVNIE1hcEl0ZW07CgogICAgLyogQSBwb3N0ZXJpb3JpIHRlc3QgZm9yIHRoZSBlbGVjdHJvbiBsaXRlcmFscyAqLwogICAgaWYgKFN0cmljdGx5TWF4aW1hbCkgeyAvKiBvbmx5IGZvciBvcmRlcmVkIGh5cGVyIHJlc29sdXRpb24gKi8KICAgICAgZm9yIChTY2FuID0gRm91bmRNYXA7ICFsaXN0X0VtcHR5KFNjYW4pOyBTY2FuID0gbGlzdF9DZHIoU2NhbikpIHsKCU1hcEl0ZW0gPSBsaXN0X0NhcihTY2FuKTsKCUxpdCA9IE1hcEl0ZW0tPkVsZWN0cm9uTGl0OwoJaWYgKCFpbmZfTGl0TWF4V2l0aDJTdWJzdChjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShMaXQpLAoJCQkJICBjbGF1c2VfTGl0ZXJhbEdldEluZGV4KExpdCksIC0xLCBTdWJzdCwKCQkJCSAgTWFwSXRlbS0+RWxlY3Ryb25TdWJzdCxUUlVFLEZsYWdzLFByZWNlZGVuY2UpKQoJICByZXR1cm4gbGlzdF9OaWwoKTsKICAgICAgfQogICAgfQogICAgLyogQnVpbGQgdGhlIHJlc29sdmVudCAqLwogICAgcmV0dXJuIGxpc3RfTGlzdChpbmZfQnVpbGRIeXBlclJlc29sdmVudChDbGF1c2UsIFN1YnN0LCBGb3VuZE1hcCwKCQkJCQkgICAgIFN0cmljdGx5TWF4aW1hbCxGbGFncyxQcmVjZWRlbmNlKSk7CiAgfQogIGVsc2UgewogICAgQ0xBVVNFICAgICAgUGFydG5lckNvcHk7CiAgICBMSVNUICAgICAgICBSZXN1bHQsIE5leHRMaXRzOwogICAgVEVSTSAgICAgICAgQXRvbUNvcHk7CiAgICBTVUJTVCAgICAgICBOZXdTdWJzdCwgUmlnaHRTdWJzdCwgSGVscFN1YnN0OwogICAgU1lNQk9MICAgICAgTmV3TWF4VmFyOwogICAgaW50ICAgICAgICAgUExpdEluZDsKICAgIEJPT0wgICAgICAgIFN3YXBwZWQ7CiAgICBJTkZfTUFQTk9ERSBNYXBOb2RlOwoKICAgIFJlc3VsdCAgID0gbGlzdF9OaWwoKTsKICAgIFJlc3RsaXRzID0gY2xhdXNlX01vdmVCZXN0TGl0ZXJhbFRvRnJvbnQobGlzdF9Db3B5KFJlc3RsaXRzKSwgU3Vic3QsCgkJCQkJICAgICBHbG9iYWxNYXhWYXIsCgkJCQkJICAgICBjbGF1c2VfSHlwZXJMaXRlcmFsSXNCZXR0ZXIpOwogICAgTGl0ICAgICAgPSBsaXN0X0NhcihSZXN0bGl0cyk7CiAgICBSZXN0bGl0cyA9IGxpc3RfUG9wKFJlc3RsaXRzKTsKICAgIEF0b21Db3B5ID0gc3Vic3RfQXBwbHkoU3Vic3QsIHRlcm1fQ29weShjbGF1c2VfTGl0ZXJhbEF0b20oTGl0KSkpOwoKICAgIFN3YXBwZWQgPSBGQUxTRTsKICAgIAogICAgLyogVGhlICdlbmRsZXNzJyBsb29wIG1heSBydW4gdHdpY2UgZm9yIGVxdWF0aW9ucywgb25jZSBmb3Igb3RoZXIgYXRvbXMgKi8KICAgIHdoaWxlIChUUlVFKSB7CiAgICAgIE5leHRMaXRzID0gaW5mX0dldEh5cGVyUmVzb2x1dGlvblBhcnRuZXJMaXRzKEF0b21Db3B5LEluZGV4LAoJCQkJCQkgICBTdHJpY3RseU1heGltYWwpOwogICAgICAKICAgICAgZm9yICggOyAhbGlzdF9FbXB0eShOZXh0TGl0cyk7IE5leHRMaXRzID0gbGlzdF9Qb3AoTmV4dExpdHMpKSB7CgkKCVBMaXQgICAgICAgID0gbGlzdF9DYXIoTmV4dExpdHMpOwoJUExpdEluZCAgICAgPSBjbGF1c2VfTGl0ZXJhbEdldEluZGV4KFBMaXQpOwoJUGFydG5lckNvcHkgPSBjbGF1c2VfQ29weShjbGF1c2VfTGl0ZXJhbE93bmluZ0NsYXVzZShQTGl0KSk7CgkKCWNsYXVzZV9SZW5hbWVWYXJzQmlnZ2VyVGhhbihQYXJ0bmVyQ29weSwgR2xvYmFsTWF4VmFyKTsKCVBMaXQgICAgICAgID0gY2xhdXNlX0dldExpdGVyYWwoUGFydG5lckNvcHksIFBMaXRJbmQpOwoJCglOZXdNYXhWYXIgICA9IHRlcm1fTWF4VmFyKGNsYXVzZV9MaXRlcmFsQXRvbShQTGl0KSk7CglOZXdNYXhWYXIgICA9IHN5bWJvbF9HcmVhdGVyVmFyaWFibGUoR2xvYmFsTWF4VmFyLCBOZXdNYXhWYXIpID8KCSAgR2xvYmFsTWF4VmFyIDogTmV3TWF4VmFyOwoJCgljb250X0NoZWNrKCk7CglpZiAoIXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIEF0b21Db3B5LCBjb250X1JpZ2h0Q29udGV4dCgpLAoJCQkgICAgIGNsYXVzZV9MaXRlcmFsQXRvbShQTGl0KSkpIHsKCSAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CgkgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9IeXBlclJlc29sdmVudHM6IFVuaWZpY2F0aW9uIGZhaWxlZC4iKTsKCSAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwoJfQoJc3Vic3RfRXh0cmFjdFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCAmTmV3U3Vic3QsCgkJCSAgICAgY29udF9SaWdodENvbnRleHQoKSwgJlJpZ2h0U3Vic3QpOwoJY29udF9SZXNldCgpOwoJCglIZWxwU3Vic3QgPSBOZXdTdWJzdDsKCU5ld1N1YnN0ICA9IHN1YnN0X0NvbXBvc2UoTmV3U3Vic3QsIHN1YnN0X0NvcHkoU3Vic3QpKTsKCXN1YnN0X0RlbGV0ZShIZWxwU3Vic3QpOwoJCglNYXBOb2RlLk51Y2xldXNMaXQgICAgPSBMaXQ7CglNYXBOb2RlLkVsZWN0cm9uTGl0ICAgPSBQTGl0OwoJTWFwTm9kZS5FbGVjdHJvblN1YnN0ID0gUmlnaHRTdWJzdDsKCUZvdW5kTWFwID0gbGlzdF9Db25zKCZNYXBOb2RlLCBGb3VuZE1hcCk7CgkKCVJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0h5cGVyUmVzb2x2ZW50cyhDbGF1c2UsIE5ld1N1YnN0LCBSZXN0bGl0cywKCQkJCQkJTmV3TWF4VmFyLCBGb3VuZE1hcCwKCQkJCQkJU3RyaWN0bHlNYXhpbWFsLCBJbmRleCwgRmxhZ3MsCgkJCQkJCVByZWNlZGVuY2UpLAoJCQkgICAgUmVzdWx0KTsKCQoJc3Vic3RfRGVsZXRlKE5ld1N1YnN0KTsKCXN1YnN0X0RlbGV0ZShSaWdodFN1YnN0KTsKCWNsYXVzZV9EZWxldGUoUGFydG5lckNvcHkpOwoJRm91bmRNYXAgPSBsaXN0X1BvcChGb3VuZE1hcCk7CiAgICAgIH0KICAgICAgaWYgKCFTd2FwcGVkICYmIGZvbF9Jc0VxdWFsaXR5KEF0b21Db3B5KSkgewoJdGVybV9FcXVhbGl0eVN3YXAoQXRvbUNvcHkpOwoJU3dhcHBlZCA9IFRSVUU7CiAgICAgIH0gZWxzZQoJYnJlYWs7CiAgICB9IC8qIGVuZCBvZiAnZW5kbGVzcycgbG9vcCAqLwoKICAgIGxpc3RfRGVsZXRlKFJlc3RsaXRzKTsKICAgIHRlcm1fRGVsZXRlKEF0b21Db3B5KTsKCiAgICByZXR1cm4gUmVzdWx0OwogIH0KfQoKCnN0YXRpYyBMSVNUIGluZl9HZXRBbnRlY2VkZW50TGl0ZXJhbHMoQ0xBVVNFIENsYXVzZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2UgCiAgUkVUVVJOUzogVGhlIGxpc3Qgb2YgYWxsIGFudGVjZWRlbnQgbGl0ZXJhbHMgb2YgdGhlIGNsYXVzZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7IAogIGludCAgbGMsIGk7CiAgTElTVCBSZXN1bHQ7CiAgCiAgUmVzdWx0ID0gbGlzdF9OaWwoKTsKICBsYyAgICAgPSBjbGF1c2VfTGFzdEFudGVjZWRlbnRMaXRJbmRleChDbGF1c2UpOwogIGZvciAoaSA9IGNsYXVzZV9GaXJzdEFudGVjZWRlbnRMaXRJbmRleChDbGF1c2UpOyBpIDw9IGxjIDsgaSsrKSB7CiAgICBSZXN1bHQgPSBsaXN0X0NvbnMoY2xhdXNlX0dldExpdGVyYWwoQ2xhdXNlLCBpKSwgUmVzdWx0KTsKICB9CiAgcmV0dXJuIFJlc3VsdDsKfQoKCnN0YXRpYyBMSVNUIGluZl9Gb3J3YXJkSHlwZXJSZXNvbHV0aW9uKENMQVVTRSBHaXZlbkNsYXVzZSwgU0hBUkVEX0lOREVYIEluZGV4LAoJCQkJICAgICAgIEJPT0wgU3RyaWN0bHlNYXhpbWFsLCBGTEFHU1RPUkUgRmxhZ3MsCgkJCQkgICAgICAgUFJFQ0VERU5DRSBQcmVjZWRlbmNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSB3aXRoIGFuIHNvbHZlZCBzb3J0IGNvbnN0cmFpbnQsIGFuICdJbmRleCcKICAgICAgICAgICBvZiBjbGF1c2VzLCBhIGJvb2xlYW4gZmxhZywgYSBmbGFnIHN0b3JlIGFuZCBhCgkgICBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGluZmVycmVkIGZyb20gIDxHaXZlbkNsYXVzZT4gYnkKICAgICAgICAgICBoeXBlciByZXNvbHV0aW9uIHdydC4gdGhlIGluZGV4LiAKICBNRU1PUlk6ICBBIGxpc3Qgb2YgY2xhdXNlcyBpcyBwcm9kdWNlZCwgd2hlcmUgbWVtb3J5IGZvciB0aGUgbGlzdAogICAgICAgICAgIGFuZCB0aGUgY2xhdXNlcyBpcyBhbGxvY2F0ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogIExJU1QgUmVzdWx0LCBSZXN0TGl0czsKOwoKI2lmZGVmIENIRUNLCiAgaWYgKCFjbGF1c2VfSXNDbGF1c2UoR2l2ZW5DbGF1c2UsIEZsYWdzLCBQcmVjZWRlbmNlKSkgewogICAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CiAgICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfRm9yd2FyZEh5cGVyUmVzb2x1dGlvbjogSWxsZWdhbCBpbnB1dC4iKTsKICAgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKICB9CiNlbmRpZgogIAogIGlmIChjbGF1c2VfSGFzRW1wdHlBbnRlY2VkZW50KEdpdmVuQ2xhdXNlKSkKICAgIHJldHVybiBsaXN0X05pbCgpOwoKICBSZXN1bHQgPSBsaXN0X05pbCgpOwogIAogIC8qIEJ1aWxkIHVwIGxpc3Qgb2YgYWxsIGFudGVjZWRlbnQgbGl0ZXJhbHMuICovCiAgUmVzdExpdHMgPSBpbmZfR2V0QW50ZWNlZGVudExpdGVyYWxzKEdpdmVuQ2xhdXNlKTsKICAKICBSZXN1bHQgPSAgbGlzdF9OY29uYyhpbmZfSHlwZXJSZXNvbHZlbnRzKEdpdmVuQ2xhdXNlLCBzdWJzdF9OaWwoKSwKCQkJCQkgICBSZXN0TGl0cyxjbGF1c2VfTWF4VmFyKEdpdmVuQ2xhdXNlKSwKCQkJCQkgICBsaXN0X05pbCgpLFN0cmljdGx5TWF4aW1hbCxJbmRleCwKCQkJCQkgICBGbGFncywgUHJlY2VkZW5jZSksIAoJCSAgICAgICBSZXN1bHQpOwogIGxpc3RfRGVsZXRlKFJlc3RMaXRzKTsKCiAgcmV0dXJuIFJlc3VsdDsKfQoKCnN0YXRpYyBMSVNUIGluZl9CYWNrd2FyZEh5cGVyUmVzb2x1dGlvbihDTEFVU0UgRWxlY3Ryb24sIFNIQVJFRF9JTkRFWCBJbmRleCwKCQkJCQlCT09MIFN0cmljdGx5TWF4aW1hbCwgRkxBR1NUT1JFIEZsYWdzLAoJCQkJCVBSRUNFREVOQ0UgUHJlY2VkZW5jZSkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgSU5QVVQ6ICAgQSBjbGF1c2Ugd2l0aCBhbiBzb2x2ZWQgc29ydCBjb25zdHJhaW50LAogICAgICAgICAgIGFuICdJbmRleCcgb2YgY2xhdXNlcywgYSBib29sZWFuIGZsYWcsIGEgZmxhZyBzdG9yZSwKCSAgIGFuZCBhIHByZWNlZGVuY2UuCiAgUkVUVVJOUzogQSBsaXN0IG9mIGNsYXVzZXMgaW5mZXJyZWQgYnkgaHlwZXIgcmVzb2x1dGlvbiAKICAgICAgICAgICB3cnQuIHRoZSBpbmRleCB3aXRoIDxFbGVjdHJvbj4gYXMgYW4gZWxlY3Ryb24uCiAgTUVNT1JZOiAgQSBsaXN0IG9mIGNsYXVzZXMgaXMgcHJvZHVjZWQsIHdoZXJlIG1lbW9yeSBmb3IgdGhlIGxpc3QKICAgICAgICAgICBhbmQgdGhlIGNsYXVzZXMgaXMgYWxsb2NhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBDTEFVU0UgRWxlY3Ryb25Db3B5OwogIExJU1QgICBSZXN1bHQ7CiAgaW50ICAgIGksIGxzOwoKICBpZiAoIWNsYXVzZV9IYXNFbXB0eUFudGVjZWRlbnQoRWxlY3Ryb24pIHx8CiAgICAgIGNsYXVzZV9IYXNFbXB0eVN1Y2NlZGVudChFbGVjdHJvbikpCiAgICByZXR1cm4gbGlzdF9OaWwoKTsKCiAgUmVzdWx0ID0gbGlzdF9OaWwoKTsKCiAgRWxlY3Ryb25Db3B5ID0gY2xhdXNlX0NvcHkoRWxlY3Ryb24pOwoKICAvKiBTZWFyY2ggc3VjY2VkZW50IGxpdGVyYWwgaW4gPEVsZWN0cm9uPiAqLwogIGxzID0gY2xhdXNlX0xhc3RTdWNjZWRlbnRMaXRJbmRleChFbGVjdHJvbkNvcHkpOwogIGZvciAoaSA9IGNsYXVzZV9GaXJzdFN1Y2NlZGVudExpdEluZGV4KEVsZWN0cm9uKTsgaSA8PSBsczsgaSsrKSB7CiAgICBMSVRFUkFMIEVsZWNMaXQ7CiAgICBURVJNICAgIEVsZWNBdG9tOwoKICAgIEVsZWNMaXQgID0gY2xhdXNlX0dldExpdGVyYWwoRWxlY3Ryb25Db3B5LCBpKTsKICAgIEVsZWNBdG9tID0gY2xhdXNlX0xpdGVyYWxBdG9tKEVsZWNMaXQpOwoKICAgIGlmICghU3RyaWN0bHlNYXhpbWFsIHx8IGNsYXVzZV9MaXRlcmFsR2V0RmxhZyhFbGVjTGl0LCBTVFJJQ1RNQVhJTUFMKSkgewogICAgICBMSVNUIENhbmRBdG9tczsKICAgICAgQk9PTCBTd2FwcGVkOwoKICAgICAgU3dhcHBlZCA9IEZBTFNFOwoKICAgICAgLyogVGhlICdlbmRsZXNzJyBsb29wIG1heSBydW4gdHdpY2UgZm9yIGVxdWF0aW9ucywgb25jZSBmb3Igb3RoZXIgYXRvbXMgKi8KICAgICAgd2hpbGUgKFRSVUUpIHsKCS8qIEdldCB1bmlmaWFibGUgYW50ZWNlZGVudCBsaXRlcmFscyBpbiBudWNsZXVzICovCglDYW5kQXRvbXMgPSBzdF9HZXRVbmlmaWVyKGNvbnRfTGVmdENvbnRleHQoKSwgc2hhcmluZ19JbmRleChJbmRleCksCgkJCQkgIGNvbnRfUmlnaHRDb250ZXh0KCksIEVsZWNBdG9tKTsKCQoJZm9yICggOyAhbGlzdF9FbXB0eShDYW5kQXRvbXMpOyBDYW5kQXRvbXMgPSBsaXN0X1BvcChDYW5kQXRvbXMpKSB7CgkgIGlmICghdGVybV9Jc1ZhcmlhYmxlKGxpc3RfQ2FyKENhbmRBdG9tcykpKSB7CgkgICAgTElTVCBDYW5kTGl0czsKCSAgICAKCSAgICBDYW5kTGl0cyA9IHNoYXJpbmdfTkF0b21EYXRhTGlzdChsaXN0X0NhcihDYW5kQXRvbXMpKTsKCSAgICAKCSAgICBmb3IgKDsgIWxpc3RfRW1wdHkoQ2FuZExpdHMpOyBDYW5kTGl0cyA9IGxpc3RfQ2RyKENhbmRMaXRzKSkgewoJICAgICAgTElURVJBTCAgIE51Y0xpdDsKCSAgICAgIFRFUk0gICAgICBOdWNBdG9tOwoJICAgICAgQ0xBVVNFICAgIE51Y2xldXM7CgkgICAgICAKCSAgICAgIE51Y0xpdCAgICA9IGxpc3RfQ2FyKENhbmRMaXRzKTsKCSAgICAgIE51Y0F0b20gICA9IGNsYXVzZV9MaXRlcmFsQXRvbShOdWNMaXQpOwoJICAgICAgTnVjbGV1cyAgID0gY2xhdXNlX0xpdGVyYWxPd25pbmdDbGF1c2UoTnVjTGl0KTsKCSAgICAgIAoJICAgICAgaWYgKGNsYXVzZV9MaXRlcmFsSXNGcm9tQW50ZWNlZGVudChOdWNMaXQpICYmCgkJICBjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChOdWNsZXVzKSkgewoJCUxJU1QgICAgRm91bmRNYXAsIFJlc3RMaXRzOwoJCVNVQlNUICAgTGVmdFN1YnN0LCBSaWdodFN1YnN0OwoJCVNZTUJPTCAgR2xvYmFsTWF4VmFyLCBNYXhWYXI7CgkJSU5GX01BUE5PREUgTWFwTm9kZTsKCQkKCQlHbG9iYWxNYXhWYXIgPSBjbGF1c2VfTWF4VmFyKE51Y2xldXMpOwoJCWNsYXVzZV9SZW5hbWVWYXJzQmlnZ2VyVGhhbihFbGVjdHJvbkNvcHksIEdsb2JhbE1heFZhcik7CgkJTWF4VmFyICAgICAgID0gY2xhdXNlX1NlYXJjaE1heFZhcihFbGVjdHJvbkNvcHkpOwoJCUdsb2JhbE1heFZhciA9IHN5bWJvbF9HcmVhdGVyVmFyaWFibGUoR2xvYmFsTWF4VmFyLCBNYXhWYXIpID8KCQkgIEdsb2JhbE1heFZhciA6IE1heFZhcjsKCQkvKiBOb3cgRWxlY0xpdCBpcyByZW5hbWVkLCB0b28gKi8KCgkJUmVzdExpdHMgICAgID0gaW5mX0dldEFudGVjZWRlbnRMaXRlcmFscyhOdWNsZXVzKTsKCQlSZXN0TGl0cyAgICAgPSBsaXN0X1BvaW50ZXJEZWxldGVFbGVtZW50KFJlc3RMaXRzLCBOdWNMaXQpOwoKCQkvKiBHZXQgdW5pZmllciAqLwoJCWNvbnRfQ2hlY2soKTsKCQlpZiAoIXVuaWZ5X1VuaWZ5Tm9PQyhjb250X0xlZnRDb250ZXh0KCksIE51Y0F0b20sCgkJCQkgICAgIGNvbnRfUmlnaHRDb250ZXh0KCksIEVsZWNBdG9tKSkgewoJCSAgbWlzY19TdGFydEVycm9yUmVwb3J0KCk7CgkJICBtaXNjX0Vycm9yUmVwb3J0KCJcbiBJbiBpbmZfQmFja3dhcmRIeXBlclJlc29sdXRpb246IFVuaWZpY2F0aW9uIGZhaWxlZC4iKTsKCQkgIG1pc2NfRmluaXNoRXJyb3JSZXBvcnQoKTsKCQl9CgkJc3Vic3RfRXh0cmFjdFVuaWZpZXIoY29udF9MZWZ0Q29udGV4dCgpLCAmTGVmdFN1YnN0LAoJCQkJICAgICBjb250X1JpZ2h0Q29udGV4dCgpLCAmUmlnaHRTdWJzdCk7CgkJY29udF9SZXNldCgpOwoJCQoJCU1hcE5vZGUuTnVjbGV1c0xpdCAgICA9IE51Y0xpdDsKCQlNYXBOb2RlLkVsZWN0cm9uTGl0ICAgPSBFbGVjTGl0OwoJCU1hcE5vZGUuRWxlY3Ryb25TdWJzdCA9IFJpZ2h0U3Vic3Q7CgkJRm91bmRNYXAgPSBsaXN0X0xpc3QoJk1hcE5vZGUpOwoJCQoJCVJlc3VsdCA9IGxpc3RfTmNvbmMoaW5mX0h5cGVyUmVzb2x2ZW50cyhOdWNsZXVzLCBMZWZ0U3Vic3QsCgkJCQkJCQlSZXN0TGl0cywgR2xvYmFsTWF4VmFyLAoJCQkJCQkJRm91bmRNYXAsU3RyaWN0bHlNYXhpbWFsLAoJCQkJCQkJSW5kZXgsIEZsYWdzLFByZWNlZGVuY2UpLAoJCQkJICAgIFJlc3VsdCk7CgkJCgkJLyogY2xlYW4gdXAgKi8KCQlzdWJzdF9EZWxldGUoTGVmdFN1YnN0KTsKCQlzdWJzdF9EZWxldGUoUmlnaHRTdWJzdCk7CgkJbGlzdF9EZWxldGUoUmVzdExpdHMpOwoJCWxpc3RfRnJlZShGb3VuZE1hcCk7CSAgICAKCSAgICAgIH0gLyogaWYgYSBudWNsZXVzIGhhcyBiZWVuIGZvdW5kICovCgkgICAgfSAvKiBmb3IgYWxsIG51Y2xldXMgY2FuZGlkYXRlIGxpdGVyYWxzICovCgkgIH0gLyogaWYgdGVybSBpcyBhdG9tICovCgl9IC8qIGZvciBhbGwgbnVjbGV1cyBjYW5kaWRhdGUgYXRvbXMgKi8KICAgICAgCWlmICghU3dhcHBlZCAmJiBmb2xfSXNFcXVhbGl0eShFbGVjQXRvbSkpIHsKCSAgdGVybV9FcXVhbGl0eVN3YXAoRWxlY0F0b20pOyAgICAvKiBBdG9tIGlzIGZyb20gY29waWVkIGNsYXVzZSAqLwoJICBTd2FwcGVkID0gVFJVRTsKCX0gZWxzZQoJICBicmVhazsKICAgICAgfSAvKiBlbmQgb2YgJ2VuZGxlc3MnIGxvb3AgKi8KICAgIH0gLyogZm9yIGFsbCBsaXRzIHVzYWJsZSBpbiBlbGVjdHJvbiBmb3IgaHlwZXIgcmVzb2x1dGlvbiAqLwogIH0gLyogZm9yIGFsbCBsaXRzIGluIHN1Y2NlZGVudCAqLwogIGNsYXVzZV9EZWxldGUoRWxlY3Ryb25Db3B5KTsKICAgIAogIHJldHVybiBSZXN1bHQ7Cn0KCgpMSVNUIGluZl9HZW5lcmFsSHlwZXJSZXNvbHV0aW9uKENMQVVTRSBHaXZlbkNsYXVzZSwgU0hBUkVEX0lOREVYIEluZGV4LAoJCQkJQk9PTCBPcmRlcmVkLCBGTEFHU1RPUkUgRmxhZ3MsCgkJCQlQUkVDRURFTkNFIFByZWNlZGVuY2UpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogIElOUFVUOiAgIEEgY2xhdXNlLCBhbiAnSW5kZXgnIG9mIGNsYXVzZXMsIGEgYm9vbGVhbiBmbGFnLAogICAgICAgICAgIGEgZmxhZyBzdG9yZSBhbmQgYSBwcmVjZWRlbmNlLgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGluZmVycmVkIGJ5CiAgICAgICAgICAgKG9yZGVyZWQpIGh5cGVyIHJlc29sdXRpb24gd3J0LiB0aGUgaW5kZXguCgkgICBJZiA8T3JkZXJlZD49VFJVRSB0aGVuIG9yZGVyZWQgaHlwZXIgcmVzb2x1dGlvbgoJICAgaW5mZXJlbmNlcyBhcmUgbWFkZSwgZWxzZSBzdGFuZGFyZCBoeXBlciByZXNvbHV0aW9uCgkgICBpbmZlcmVuY2VzLgogIE1FTU9SWTogIEEgbGlzdCBvZiBjbGF1c2VzIGlzIHByb2R1Y2VkLCB3aGVyZSBtZW1vcnkgZm9yIHRoZSBsaXN0CiAgICAgICAgICAgYW5kIHRoZSBjbGF1c2VzIGlzIGFsbG9jYXRlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7IAogIExJU1QgUmVzdWx0OwoKICBSZXN1bHQgPSBsaXN0X05pbCgpOwogIGlmIChjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChHaXZlbkNsYXVzZSkpIHsKICAgIFJlc3VsdCA9IGluZl9Gb3J3YXJkSHlwZXJSZXNvbHV0aW9uKEdpdmVuQ2xhdXNlLCBJbmRleCwgT3JkZXJlZCwKCQkJCQlGbGFncywgUHJlY2VkZW5jZSk7IAogICAgUmVzdWx0ID0gbGlzdF9OY29uYyhpbmZfQmFja3dhcmRIeXBlclJlc29sdXRpb24oR2l2ZW5DbGF1c2UsIEluZGV4LCBPcmRlcmVkLAoJCQkJCQkgICAgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCQlSZXN1bHQpOyAKICB9CiAgcmV0dXJuIFJlc3VsdDsKfSAKCgpMSVNUIGluZl9EZXJpdmFibGVDbGF1c2VzKFBST09GU0VBUkNIIFNlYXJjaCwgQ0xBVVNFIEdpdmVuQ2xhdXNlKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICBJTlBVVDogICBBIGNsYXVzZSBhbmQgYW4gSW5kZXgsIHVzdWFsbHkgdGhlIFdvcmtlZE9mZkluZGV4LgogIFJFVFVSTlM6IEEgbGlzdCBvZiBjbGF1c2VzIGRlcml2YWJsZSBmcm9tICdHaXZlbkNsYXVzZScgd3J0IGluZGV4LgogIEVGRkVDVDogIEFsbG9jYXRlcyBtZW1vcnkgZm9yIHRoZSBjbGF1c2VsaXN0bm9kZXMgYW5kIG5ldyBjbGF1c2VzLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICBMSVNUICAgICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXM7CiAgU0hBUkVEX0lOREVYIFNoSW5kZXg7CiAgU09SVFRIRU9SWSAgIER5bmFtaWM7CiAgRkxBR1NUT1JFICAgIEZsYWdzOwogIFBSRUNFREVOQ0UgICBQcmVjZWRlbmNlOwoKICBGbGFncyAgICAgICAgPSBwcmZzX1N0b3JlKFNlYXJjaCk7CiAgUHJlY2VkZW5jZSAgID0gcHJmc19QcmVjZWRlbmNlKFNlYXJjaCk7CgojaWZkZWYgQ0hFQ0sKICBpZiAoIWNsYXVzZV9Jc0NsYXVzZShHaXZlbkNsYXVzZSwgRmxhZ3MsIFByZWNlZGVuY2UpKSB7CiAgICBtaXNjX1N0YXJ0RXJyb3JSZXBvcnQoKTsKICAgIG1pc2NfRXJyb3JSZXBvcnQoIlxuIEluIGluZl9EZXJpdmFibGVDbGF1c2VzOiBJbGxlZ2FsIGlucHV0LiIpOwogICAgbWlzY19GaW5pc2hFcnJvclJlcG9ydCgpOwogIH0KI2VuZGlmCgogIExpc3RPZkRlcml2ZWRDbGF1c2VzID0gbGlzdF9OaWwoKTsKICBTaEluZGV4ICAgICAgICAgICAgICA9IHByZnNfV29ya2VkT2ZmU2hhcmluZ0luZGV4KFNlYXJjaCk7CiAgRHluYW1pYyAgICAgICAgICAgICAgPSBwcmZzX0R5bmFtaWNTb3J0VGhlb3J5KFNlYXJjaCk7CgogIGlmIChEeW5hbWljICYmICFjbGF1c2VfSGFzU29sdmVkQ29uc3RyYWludChHaXZlbkNsYXVzZSkpIHsKCiAgICBpZiAoY2xhdXNlX0hhc1Rlcm1Tb3J0Q29uc3RyYWludExpdHMoR2l2ZW5DbGF1c2UpKSB7CiAgICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JU09SKSkKCUxpc3RPZkRlcml2ZWRDbGF1c2VzID0KCSAgbGlzdF9OY29uYyhpbmZfRm9yd2FyZFNvcnRSZXNvbHV0aW9uKEdpdmVuQ2xhdXNlLAoJCQkJCSAgICAgICBzb3J0X1RoZW9yeUluZGV4KER5bmFtaWMpLAoJCQkJCSAgICAgICBEeW5hbWljLCBGQUxTRSwgRmxhZ3MsUHJlY2VkZW5jZSksCgkJICAgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyk7CiAgICB9CiAgICBlbHNlCiAgICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JRU1TKSkJCglMaXN0T2ZEZXJpdmVkQ2xhdXNlcyA9CgkgIGxpc3RfTmNvbmMoaW5mX0ZvcndhcmRFbXB0eVNvcnQoR2l2ZW5DbGF1c2UsCgkJCQkJICBzb3J0X1RoZW9yeUluZGV4KER5bmFtaWMpLCBEeW5hbWljLAoJCQkJCSAgRkFMU0UsIEZsYWdzLCBQcmVjZWRlbmNlKSwgCgkJICAgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyk7IAogIH0gZWxzZSB7IC8qIEdpdmVuIHdpdGggc29sdmVkIENvbnN0cmFpbnQhICovCgogICAgaWYgKER5bmFtaWMgJiYgZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSUVNUykpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0JhY2t3YXJkRW1wdHlTb3J0KEdpdmVuQ2xhdXNlLCBzaGFyaW5nX0luZGV4KFNoSW5kZXgpLAoJCQkJCSBEeW5hbWljLCBGQUxTRSwgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsgCgogICAgaWYgKER5bmFtaWMgJiYgZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSVNPUikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0JhY2t3YXJkU29ydFJlc29sdXRpb24oR2l2ZW5DbGF1c2UsCgkJCQkJICAgICAgc2hhcmluZ19JbmRleChTaEluZGV4KSwgRHluYW1pYywKCQkJCQkgICAgICBGQUxTRSwgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSUVRUikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0VxdWFsaXR5UmVzb2x1dGlvbihHaXZlbkNsYXVzZSwgVFJVRSwgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSUVSUikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0VxdWFsaXR5UmVzb2x1dGlvbihHaXZlbkNsYXVzZSwgRkFMU0UsIEZsYWdzLCBQcmVjZWRlbmNlKSwKCQkgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyk7CgogICAgaWYgKGZsYWdfR2V0RmxhZ1ZhbHVlKEZsYWdzLCBmbGFnX0lNUE0pKQogICAgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyA9CglsaXN0X05jb25jKGluZl9NZXJnaW5nUGFyYW1vZHVsYXRpb24oR2l2ZW5DbGF1c2UsIFNoSW5kZXgsIEZsYWdzLAoJCQkJCSAgICAgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JRVFGKSkKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQoJbGlzdF9OY29uYyhpbmZfRXF1YWxpdHlGYWN0b3JpbmcoR2l2ZW5DbGF1c2UsRmxhZ3MsIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBzd2l0Y2ggKGZsYWdfR2V0RmxhZ1ZhbHVlKEZsYWdzLCBmbGFnX0lPRkMpKSB7CiAgICBjYXNlIGZsYWdfRkFDVE9SSU5HT0ZGOgogICAgICBicmVhazsgLyogRG8gbm90aGluZyAqLwogICAgY2FzZSBmbGFnX0ZBQ1RPUklOR09OTFlSSUdIVDoKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQoJbGlzdF9OY29uYyhpbmZfR2VuZXJhbEZhY3RvcmluZyhHaXZlbkNsYXVzZSwgVFJVRSwgRkFMU0UsVFJVRSwgRmxhZ3MsCgkJCQkJUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogICAgICBicmVhazsKICAgIGNhc2UgZmxhZ19GQUNUT1JJTkdSSUdIVEFORExFRlQ6CiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0dlbmVyYWxGYWN0b3JpbmcoR2l2ZW5DbGF1c2UsIFRSVUUsIFRSVUUsIFRSVUUsIEZsYWdzLAoJCQkJCVByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBtaXNjX1N0YXJ0VXNlckVycm9yUmVwb3J0KCk7CiAgICAgIG1pc2NfVXNlckVycm9yUmVwb3J0KCJcbiBFcnJvcjogRmxhZyBcIklPRkNcIiBoYXMgaW52YWxpZCB2YWx1ZS5cbiIpOwogICAgICBtaXNjX0ZpbmlzaFVzZXJFcnJvclJlcG9ydCgpOwogICAgfQoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JU0ZDKSkKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQoJbGlzdF9OY29uYyhpbmZfR2VuZXJhbEZhY3RvcmluZyhHaXZlbkNsYXVzZSwgRkFMU0UsIFRSVUUsIFRSVUUsIEZsYWdzLAoJCQkJCVByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSVNQUikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX1N1cGVycG9zaXRpb25SaWdodChHaXZlbkNsYXVzZSxTaEluZGV4LEZsYWdzLFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSVNQTSkpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX1BhcmFtb2R1bGF0aW9uKEdpdmVuQ2xhdXNlLCBTaEluZGV4LCBGbGFncywgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JT1BNKSkKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQoJbGlzdF9OY29uYyhpbmZfT3JkZXJlZFBhcmFtb2R1bGF0aW9uKEdpdmVuQ2xhdXNlLCBTaEluZGV4LCBGbGFncywKCQkJCQkgICAgIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsgIAoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JU1BMKSkgCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX1N1cGVycG9zaXRpb25MZWZ0KEdpdmVuQ2xhdXNlLCBTaEluZGV4LCBGbGFncyxQcmVjZWRlbmNlKSwKCQkgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyk7ICAKCiAgICBzd2l0Y2ggKGZsYWdfR2V0RmxhZ1ZhbHVlKEZsYWdzLCBmbGFnX0lPUkUpKSB7CiAgICBjYXNlIGZsYWdfT1JERVJFRFJFU09MVVRJT05PRkY6CiAgICAgIGJyZWFrOyAgIC8qIERvIG5vdGhpbmcgKi8KICAgIGNhc2UgZmxhZ19PUkRFUkVEUkVTT0xVVElPTk5PRVFVQVRJT05TOiAgLyogbm8gZXF1YXRpb25zICovCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0dlbmVyYWxSZXNvbHV0aW9uKEdpdmVuQ2xhdXNlLFNoSW5kZXgsVFJVRSxGQUxTRSxGbGFncywKCQkJCQkgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogICAgICBicmVhazsKCiAgICBjYXNlIGZsYWdfT1JERVJFRFJFU09MVVRJT05XSVRIRVFVQVRJT05TOiAgLyogYWxsb3cgZXF1YXRpb25zICovCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0dlbmVyYWxSZXNvbHV0aW9uKEdpdmVuQ2xhdXNlLFNoSW5kZXgsVFJVRSxUUlVFLCBGbGFncywKCQkJCQkgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIG1pc2NfU3RhcnRVc2VyRXJyb3JSZXBvcnQoKTsKICAgICAgbWlzY19Vc2VyRXJyb3JSZXBvcnQoIlxuIEVycm9yOiBGbGFnIFwiSU9SRVwiIGhhcyBpbnZhbGlkIHZhbHVlLlxuIik7CiAgICAgIG1pc2NfRmluaXNoVXNlckVycm9yUmVwb3J0KCk7CiAgICB9CiAgICAgIAoKICAgIHN3aXRjaCAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSVNSRSkpIHsKICAgIGNhc2UgZmxhZ19TVEFOREFSRFJFU09MVVRJT05PRkY6CiAgICAgIGJyZWFrOyAgIC8qIERvIG5vdGhpbmcgKi8KICAgIGNhc2UgZmxhZ19TVEFOREFSRFJFU09MVVRJT05OT0VRVUFUSU9OUzogIC8qIG5vIGVxdWF0aW9ucyAqLwogICAgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyA9CglsaXN0X05jb25jKGluZl9HZW5lcmFsUmVzb2x1dGlvbihHaXZlbkNsYXVzZSxTaEluZGV4LEZBTFNFLEZBTFNFLEZsYWdzLAogUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogICAgICBicmVhazsKICAgIGNhc2UgZmxhZ19TVEFOREFSRFJFU09MVVRJT05XSVRIRVFVQVRJT05TOiAgLyogYWxsb3cgZXF1YXRpb25zICovCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0dlbmVyYWxSZXNvbHV0aW9uKEdpdmVuQ2xhdXNlLFNoSW5kZXgsRkFMU0UsVFJVRSxGbGFncywKCQkJCQkgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIG1pc2NfU3RhcnRVc2VyRXJyb3JSZXBvcnQoKTsKICAgICAgbWlzY19Vc2VyRXJyb3JSZXBvcnQoIlxuIEVycm9yOiBGbGFnIFwiSVNSRVwiIGhhcyBpbnZhbGlkIHZhbHVlLlxuIik7CiAgICAgIG1pc2NfRmluaXNoVXNlckVycm9yUmVwb3J0KCk7CiAgICB9CgogICAgaWYgKGZsYWdfR2V0RmxhZ1ZhbHVlKEZsYWdzLCBmbGFnX0lVTlIpKQogICAgICBMaXN0T2ZEZXJpdmVkQ2xhdXNlcyA9CglsaXN0X05jb25jKGluZl9Vbml0UmVzb2x1dGlvbihHaXZlbkNsYXVzZSwgU2hJbmRleCwgRkFMU0UsCgkJCQkgICAgICBGbGFncywgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JQlVSKSkKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQoJbGlzdF9OY29uYyhpbmZfQm91bmRlZERlcHRoVW5pdFJlc29sdXRpb24oR2l2ZW5DbGF1c2UsU2hJbmRleCxGQUxTRSwKCQkJCQkJICBGbGFncywgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwoKICAgIGlmIChmbGFnX0dldEZsYWdWYWx1ZShGbGFncywgZmxhZ19JU0hZKSkKICAgICAgTGlzdE9mRGVyaXZlZENsYXVzZXMgPQogICAgICAJbGlzdF9OY29uYyhpbmZfR2VuZXJhbEh5cGVyUmVzb2x1dGlvbihHaXZlbkNsYXVzZSxTaEluZGV4LEZBTFNFLEZsYWdzLAoJCQkJCSAgICAgIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSU9IWSkpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KICAgICAgCWxpc3RfTmNvbmMoaW5mX0dlbmVyYWxIeXBlclJlc29sdXRpb24oR2l2ZW5DbGF1c2UsU2hJbmRleCxUUlVFLEZsYWdzLAoJCQkJCSAgICAgIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSVVSUikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX1VSUmVzb2x1dGlvbihHaXZlbkNsYXVzZSwgU2hJbmRleCwgRmxhZ3MsIFByZWNlZGVuY2UpLAoJCSAgIExpc3RPZkRlcml2ZWRDbGF1c2VzKTsKCiAgICBpZiAoZmxhZ19HZXRGbGFnVmFsdWUoRmxhZ3MsIGZsYWdfSURFRikpCiAgICAgIExpc3RPZkRlcml2ZWRDbGF1c2VzID0KCWxpc3RfTmNvbmMoaW5mX0FwcGx5RGVmaW5pdGlvbihTZWFyY2gsIEdpdmVuQ2xhdXNlLCBGbGFncywgUHJlY2VkZW5jZSksCgkJICAgTGlzdE9mRGVyaXZlZENsYXVzZXMpOwogIH0KCiAgcmV0dXJuIExpc3RPZkRlcml2ZWRDbGF1c2VzOwp9Cg==