LyoKICogU2NhbkNuY25Pc1NtLmMKICoKICogQ29weXJpZ2h0KGMpIDE5OTggLSAyMDEwIFRleGFzIEluc3RydW1lbnRzLiBBbGwgcmlnaHRzIHJlc2VydmVkLiAgICAgIAogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0ICAgIAogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgICAgCiAqIGFyZSBtZXQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogKiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCAgICAgCiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gICAgICAKICogICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgIAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gICAgCiAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgICAgICAgICAKICogICAgZGlzdHJpYnV0aW9uLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogKiAgKiBOZWl0aGVyIHRoZSBuYW1lIFRleGFzIEluc3RydW1lbnRzIG5vciB0aGUgbmFtZXMgb2YgaXRzICAgICAgICAgICAgCiAqICAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCAgICAKICogICAgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiAgICAgIAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgICAKICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgICAgIAogKiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgCiAqIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUICAKICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIAogKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UICAgICAgCiAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCAKICogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIAogKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUICAgCiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSAKICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KICovCgovKiogXGZpbGUgIFNjYW5DbmNuT3NTbS5jCiAqICBcYnJpZWYgU2NhbiBjb25jZW50cmF0b3IgT1Mgc2NhbiBzdGF0ZSBtYWNoaW5lIGltcGxlbWVudGF0aW9uCiAqCiAqICBcc2VlICAgU2NhbkNuY25BcHAuYwogKi8KCgojZGVmaW5lIF9fRklMRV9JRF9fICBGSUxFX0lEXzc4CiNpbmNsdWRlICJvc1RJVHlwZS5oIgojaW5jbHVkZSAiR2VuU00uaCIKI2luY2x1ZGUgIlNjYW5DbmNuT3NTbS5oIgojaW5jbHVkZSAiU2NhbkNuY24uaCIKI2luY2x1ZGUgIlNjYW5DbmNuUHJpdmF0ZS5oIgojaW5jbHVkZSAicmVwb3J0LmgiCiNpbmNsdWRlICJvc0FwaS5oIgojaW5jbHVkZSAic2l0ZU1nckFwaS5oIgojaW5jbHVkZSAicmVndWxhdG9yeURvbWFpbkFwaS5oIgojaW5jbHVkZSAic2NhblJlc3VsdFRhYmxlLmgiCgojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfUFJPQkVfUkVRVUVTVF9SQVRFX0cgICAgICAgICAgICAgICAgICAgICAgIFJBVEVfTUFTS19VTlNQRUNJRklFRCAgLyogTGV0IHRoZSBGVyBzZWxlY3QgKi8KI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX1BST0JFX1JFUVVFU1RfUkFURV9BICAgICAgICAgICAgICAgICAgICAgICBSQVRFX01BU0tfVU5TUEVDSUZJRUQgIC8qIExldCB0aGUgRlcgc2VsZWN0ICovCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9QUk9CRV9SRVFVRVNUX05VTUJFUl9HICAgICAgICAgICAgICAgICAgICAgMwojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfUFJPQkVfUkVRVUVTVF9OVU1CRVJfQSAgICAgICAgICAgICAgICAgICAgIDMKI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX01BWF9EV0VMTF9USU1FX1BBU1NJVkVfRyAgICAgICAgICAgICAgICAgICAxMDAwMDAKI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX01BWF9EV0VMTF9USU1FX1BBU1NJVkVfQSAgICAgICAgICAgICAgICAgICAxMDAwMDAKI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX01BWF9EV0VMTF9USU1FX0FDVElWRV9HICAgICAgICAgICAgICAgICAgICAzMDAwMAojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfTUFYX0RXRUxMX1RJTUVfQUNUSVZFX0EgICAgICAgICAgICAgICAgICAgIDMwMDAwCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9NSU5fRFdFTExfVElNRV9QQVNTSVZFX0cgICAgICAgICAgICAgICAgICAgMTAwMDAwCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9NSU5fRFdFTExfVElNRV9QQVNTSVZFX0EgICAgICAgICAgICAgICAgICAgMTAwMDAwCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9NSU5fRFdFTExfVElNRV9BQ1RJVkVfRyAgICAgICAgICAgICAgICAgICAgMTUwMDAKI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX01JTl9EV0VMTF9USU1FX0FDVElWRV9BICAgICAgICAgICAgICAgICAgICAxNTAwMAojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfRUFSTFlfVEVSTUlOQVRJT05fRVZFTlRfUEFTU0lWRV9HICAgICAgICAgIFNDQU5fRVRfQ09ORF9CRUFDT04KI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX0VBUkxZX1RFUk1JTkFUSU9OX0VWRU5UX1BBU1NJVkVfQSAgICAgICAgICBTQ0FOX0VUX0NPTkRfQkVBQ09OCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9FVkVOVF9BQ1RJVkVfRyAgICAgICAgICAgU0NBTl9FVF9DT05EX0FOWV9GUkFNRQojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfRUFSTFlfVEVSTUlOQVRJT05fRVZFTlRfQUNUSVZFX0EgICAgICAgICAgIFNDQU5fRVRfQ09ORF9BTllfRlJBTUUKCi8qIEZvciBXaUZpICBXUEEgT09CIHNjZW5hcmlvLCA0IEFQcyBuZWVkIHRvIGJlIGNvbmZpZ3VyZSBvbiB0aGUgc2FtZSBjaGFubmVsICovCiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9DT1VOVF9QQVNTSVZFX0cgICAgICAgICAgNCAKI2RlZmluZSBTQ0FOX09JRF9ERUZBVUxUX0VBUkxZX1RFUk1JTkFUSU9OX0NPVU5UX1BBU1NJVkVfQSAgICAgICAgICA0CiNkZWZpbmUgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9DT1VOVF9BQ1RJVkVfRyAgICAgICAgICAgNAojZGVmaW5lIFNDQU5fT0lEX0RFRkFVTFRfRUFSTFlfVEVSTUlOQVRJT05fQ09VTlRfQUNUSVZFX0EgICAgICAgICAgIDQKCnN0YXRpYyB2b2lkIHNjYW5DbmNuT3NTbV9BY3Rpb25TdGFydEdTY2FuIChUSV9IQU5ETEUgaFNjYW5DbmNuKTsKc3RhdGljIHZvaWQgc2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0QVNjYW4gKFRJX0hBTkRMRSBoU2NhbkNuY24pOwpzdGF0aWMgdm9pZCBzY2FuQ25jbk9zU21fQWN0aW9uQ29tcGxldGVTY2FuIChUSV9IQU5ETEUgaFNjYW5DbmNuKTsKc3RhdGljIHZvaWQgc2NhbkNuY25Pc1NtX0FjdGlvblVuZXhwZWN0ZWQgKFRJX0hBTkRMRSBoU2NhbkNuY24pOwpUSV9VSU5UMzIgICBzY2FuQ25jbk9zU21fRmlsbEFsbEF2YWlsYWJsZUNoYW5uZWxzIChUSV9IQU5ETEUgaFNjYW5DbmNuLCBFUmFkaW9CYW5kIGVCYW5kLCBFU2NhblR5cGUgZVNjYW5UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUU2NhbkNoYW5uZWxFbnRyeSAqcENoYW5uZWxBcnJheSwgVElfVUlOVDMyIHVNYXhEd2VsbFRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRJX1VJTlQzMiB1TWluQ2hhbm5lbFRpbWUsIEVTY2FuRXRDb25kaXRpb24gZUVUQ29uZGl0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUSV9VSU5UOCB1RVRGcmFtZU51bWJlcik7CgoKc3RhdGljIFRHZW5TTV9hY3Rpb25DZWxsIHRTbU1hdHJpeFsgU0NBTl9DTkNOX09TX1NNX05VTUJFUl9PRl9TVEFURVMgXVsgU0NBTl9DTkNOX09TX1NNX05VTUJFUl9PRl9FVkVOVFMgXSA9IAogICAgewogICAgICAgIHsgLyogU0NBTl9DTkNOX09TX1NNX1NUQVRFX0lETEUgKi8KICAgICAgICAgICAgeyBTQ0FOX0NOQ05fT1NfU01fU1RBVEVfU0NBTl9PTl9HLCAgc2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0R1NjYW4gfSwgICAgLyogU0NBTl9DTkNOX09TX1NNX0VWRU5UX1NUQVJUX1NDQU4gKi8KICAgICAgICAgICAgeyBTQ0FOX0NOQ05fT1NfU01fU1RBVEVfSURMRSwgICAgICAgc2NhbkNuY25Pc1NtX0FjdGlvblVuZXhwZWN0ZWQgfSwgICAgLyogU0NBTl9DTkNOX09TX1NNX0VWRU5UX1NDQU5fQ09NUExFVEUgKi8KICAgICAgICB9LAogICAgICAgIHsgLyogU0NBTl9DTkNOX09TX1NNX1NUQVRFX1NDQU5fT05fRyAqLwogICAgICAgICAgICB7IFNDQU5fQ05DTl9PU19TTV9TVEFURV9TQ0FOX09OX0csICBzY2FuQ25jbk9zU21fQWN0aW9uVW5leHBlY3RlZCB9LCAgICAvKiBTQ0FOX0NOQ05fT1NfU01fRVZFTlRfU1RBUlRfU0NBTiAqLwogICAgICAgICAgICB7IFNDQU5fQ05DTl9PU19TTV9TVEFURV9TQ0FOX09OX0EsICBzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRBU2NhbiB9LCAgICAvKiBTQ0FOX0NOQ05fT1NfU01fRVZFTlRfU0NBTl9DT01QTEVURSAqLwogICAgICAgIH0sCiAgICAgICAgeyAvKiBTQ0FOX0NOQ05fT1NfU01fU1RBVEVfU0NBTl9PTl9BICovCiAgICAgICAgICAgIHsgU0NBTl9DTkNOX09TX1NNX1NUQVRFX1NDQU5fT05fQSwgIHNjYW5DbmNuT3NTbV9BY3Rpb25VbmV4cGVjdGVkIH0sICAgIC8qIFNDQU5fQ05DTl9PU19TTV9FVkVOVF9TVEFSVF9TQ0FOICovCiAgICAgICAgICAgIHsgU0NBTl9DTkNOX09TX1NNX1NUQVRFX0lETEUsICAgICAgIHNjYW5DbmNuT3NTbV9BY3Rpb25Db21wbGV0ZVNjYW4gfSwgIC8qIFNDQU5fQ05DTl9PU19TTV9FVkVOVF9TQ0FOX0NPTVBMRVRFICovCiAgICAgICAgfQogICAgfTsKCnN0YXRpYyBUSV9JTlQ4ICAqdVN0YXRlRGVzY3JpcHRpb25bXSA9IAogICAgewogICAgICAgICJJRExFIiwKICAgICAgICAiU0NBTl9PTl9HIiwKICAgICAgICAiU0NBTl9PTl9BIgogICAgfTsKCnN0YXRpYyBUSV9JTlQ4ICAqdUV2ZW50RGVzY3JpcHRpb25bXSA9IAogICAgewogICAgICAgICJTVEFSVCIsCiAgICAgICAgIlNDQU5fQ09NUExFVEUiCiAgICB9OwoKLyoqIAogKiBcZm4gICAgIHNjYW5DbmNuT3NTbV9DcmVhdGUKICogXGJyaWVmICBDcmVhdGVzIHRoZSBPUyBzY2FuIHN0YXRlLW1hY2hpbmUKICogCiAqIGNyZWF0ZXMgdGhlIE9TIHNjYW4gc3RhdGUtbWFjaGluZQogKiAKICogXHBhcmFtICBoU2NhbkNuY24gLSBoYW5kbGUgdG8gdGhlIHNjYW4gY29uY2VudHJhdG9yIG9iamVjdAogKiBccmV0dXJuIEhhbmRsZSB0byB0aGUgbmV3bHkgY3JlYXRlZCBPUyBzYW4gU00sIE5VTEwgaWYgYW4gZXJyb3Igb2NjdXJlZAogKiBcc2EgICAgIHNjYW5DbmNuT3NTbV9DcmVhdGUsIHNjYW5DbmNuT3NTbV9EZXN0cm95CiAqLwpUSV9IQU5ETEUgc2NhbkNuY25Pc1NtX0NyZWF0ZSAoVElfSEFORExFIGhTY2FuQ25jbikKewogICAgVFNjYW5DbmNuICAgICAgICpwU2NhbkNuY24gPSAoVFNjYW5DbmNuKiloU2NhbkNuY247CgogICAgcmV0dXJuIGdlblNNX0NyZWF0ZSAocFNjYW5DbmNuLT5oT1MpOwp9CgovKiogCiAqIFxmbiAgICAgc2NhbkNuY25Pc1NtX0luaXQKICogXGJyaWVmICBJbml0aWFsaXplIHRoZSBPUyBzY2FuIHN0YXRlLW1hY2hpbmUKICogCiAqIEluaXRpYWxpemUgdGhlIE9TIHNjYW4gc3RhdGUtbWFjaGluZQogKiAKICogXHBhcmFtICBoU2NhbkNuY24gLSBoYW5kbGUgdG8gdGhlIHNjYW4gY29uY2VudHJhdG9yIG9iamVjdAogKiBccmV0dXJuIE5vbmUKICogXHNhICAgICBzY2FuQ25jbk9zU21fQ3JlYXRlCiAqLwp2b2lkIHNjYW5DbmNuT3NTbV9Jbml0IChUSV9IQU5ETEUgaFNjYW5DbmNuKQp7CiAgICBUU2NhbkNuY24gICAgICAgKnBTY2FuQ25jbiA9IChUU2NhbkNuY24qKWhTY2FuQ25jbjsKCiAgICAvKiBpbml0aWFsaXplIHRoZSBzdGF0ZS1tYWNoaW5lICovCiAgICBnZW5TTV9Jbml0IChwU2NhbkNuY24tPmhPU1NjYW5TbSwgcFNjYW5DbmNuLT5oUmVwb3J0KTsKICAgIGdlblNNX1NldERlZmF1bHRzIChwU2NhbkNuY24tPmhPU1NjYW5TbSwgU0NBTl9DTkNOX09TX1NNX05VTUJFUl9PRl9TVEFURVMsIFNDQU5fQ05DTl9PU19TTV9OVU1CRVJfT0ZfRVZFTlRTLAogICAgICAgICAgICAgICAgICAgICAgIChUR2VuU01fbWF0cml4KXRTbU1hdHJpeCwgU0NBTl9DTkNOX09TX1NNX1NUQVRFX0lETEUsICJPUyBzY2FuIFNNIiwgdVN0YXRlRGVzY3JpcHRpb24sIAogICAgICAgICAgICAgICAgICAgICAgIHVFdmVudERlc2NyaXB0aW9uLCBfX0ZJTEVfSURfXyk7Cn0KCi8qKiAKICogXGZuICAgICBzY2FuQ25jbk9zU21fRGVzdHJveQogKiBcYnJpZWYgIERlc3Ryb3lzIHRoZSBPUyBzY2FuIHN0YXRlLW1hY2hpbmUKICogCiAqIERlc3Ryb3lzIHRoZSBPUyBzY2FuIHN0YXRlLW1hY2hpbmUKICogCiAqIFxwYXJhbSAgaFNjYW5DbmNuIC0gaGFuZGxlIHRvIHRoZSBzY2FuIGNvbmNlbnRyYXRvciBvYmplY3QKICogXHJldHVybiBOb25lCiAqIFxzYSAgICAgc2NhbkNuY25Pc1NtX0NyZWF0ZQogKi8Kdm9pZCBzY2FuQ25jbk9zU21fRGVzdHJveSAoVElfSEFORExFIGhTY2FuQ25jbikKewogICAgVFNjYW5DbmNuICAgICAgICpwU2NhbkNuY24gPSAoVFNjYW5DbmNuKiloU2NhbkNuY247CgogICAgZ2VuU01fVW5sb2FkIChwU2NhbkNuY24tPmhPU1NjYW5TbSk7Cn0KCi8qKiAKICogXGZuICAgICBzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRHU2NhbgogKiBcYnJpZWYgIFNjYW4gY29uY2VudGFydG9yIE9TIHN0YXRlIG1hY2hpbmUgc3RhcnQgc2NhbiBvbiBHIGFjdGlvbiBmdW5jdGlvbgogKiAKICogU2NhbiBjb25jZW50YXJ0b3IgT1Mgc3RhdGUgbWFjaGluZSBzdGFydCBzY2FuIG9uIEcgYWN0aW9uIGZ1bmN0aW9uLgogKiBTdGFydHMgYSBzYWNuIG9uIEcgdXNpbmcgYWxsIGFsbG93ZWQgY2hhbm5lbHMKICogCiAqIFxwYXJhbSAgaFNjYW5DbmNuIC0gaGFuZGxlIHRvIHRoZSBzY2FuIGNvbmNlbnRhcnRvciBvYmplY3QKICogXHJldHVybiBOb25lCiAqLyAKdm9pZCBzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRHU2NhbiAoVElfSEFORExFIGhTY2FuQ25jbikKewogICAgVFNjYW5DbmNuICAgICAgICpwU2NhbkNuY24gPSAoVFNjYW5DbmNuKiloU2NhbkNuY247CiAgICBwYXJhbUluZm9fdCAgICAgdFBhcmFtOwogICAgVElfVUlOVDMyICAgICAgIHVWYWxpZENoYW5uZWxzQ291bnQ7CiAgICBUSV9CT09MICAgICAgICAgYlJlZ3VsYXRvcnlEb21haW5FbmFibGVkOwoKICAgIC8qIGlmIHRoZSBTVEEgaXMgbm90IGNvbmZpZ3VyZWQgZm9yIEcgYmFuZCBvciBkdWFsIGJhbmQsIHNlbmQgYSBzY2FuIGNvbXBsZXRlIGV2ZW50IHRvIHRoZSBTTSAqLwogICAgdFBhcmFtLnBhcmFtVHlwZSA9IFNJVEVfTUdSX0RFU0lSRURfRE9UMTFfTU9ERV9QQVJBTTsKICAgIHNpdGVNZ3JfZ2V0UGFyYW0gKHBTY2FuQ25jbi0+aFNpdGVNYW5hZ2VyLCAmdFBhcmFtKTsKICAgIGlmICgoRE9UMTFfR19NT0RFICE9IHRQYXJhbS5jb250ZW50LnNpdGVNZ3JEb3QxMU1vZGUpICYmIChET1QxMV9EVUFMX01PREUgIT0gdFBhcmFtLmNvbnRlbnQuc2l0ZU1nckRvdDExTW9kZSkpCiAgICB7CiAgICAgICAgVFJBQ0UwKHBTY2FuQ25jbi0+aFJlcG9ydCAsIFJFUE9SVF9TRVZFUklUWV9JTkZPUk1BVElPTiAsICJzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRHU2NhbjogU1RBIGRvZXMgbm90IHdvcmsgb24gMi40IEdIeiwgY29udGludWluZyB0byA1LjAgR0h6IHNjYW5cbiIpOwogICAgICAgIGdlblNNX0V2ZW50IChwU2NhbkNuY24tPmhPU1NjYW5TbSwgU0NBTl9DTkNOX09TX1NNX0VWRU5UX1NDQU5fQ09NUExFVEUsIGhTY2FuQ25jbik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIGJ1aWxkIHNjYW4gY29tbWFuZCBoZWFkZXIgKi8KICAgIHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5iYW5kID0gUkFESU9fQkFORF8yXzRfR0haOwogICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLlRpZCA9IDI1NTsKCiAgICAvKiBxdWVyeSB0aGUgcmVndWxhdG9yeSBkb21haW4gaWYgODAyLjExZCBpcyBpbiB1c2UgKi8KICAgIHRQYXJhbS5wYXJhbVR5cGUgPSBSRUdVTEFUT1JZX0RPTUFJTl9FTkFCTEVEX1BBUkFNOwogICAgcmVndWxhdG9yeURvbWFpbl9nZXRQYXJhbSAocFNjYW5DbmNuLT5oUmVndWxhdG9yeURvbWFpbiwgJnRQYXJhbSApOwogICAgYlJlZ3VsYXRvcnlEb21haW5FbmFibGVkID0gdFBhcmFtLmNvbnRlbnQucmVndWxhdG9yeURvbWFpbkVuYWJsZWQ7CgogICAgLyogR2V0IGNvdW50cnkgY29kZSBzdGF0dXMgKi8KICAgIHRQYXJhbS5wYXJhbVR5cGUgICAgICAgICAgPSBSRUdVTEFUT1JZX0RPTUFJTl9JU19DT1VOVFJZX0ZPVU5EOwogICAgdFBhcmFtLmNvbnRlbnQuZVJhZGlvQmFuZCA9IFJBRElPX0JBTkRfMl80X0dIWjsKICAgIHJlZ3VsYXRvcnlEb21haW5fZ2V0UGFyYW0gKHBTY2FuQ25jbi0+aFJlZ3VsYXRvcnlEb21haW4sICZ0UGFyYW0pOwoKICAgIC8qIHNjYW4gdHlwZSBpcyBwYXNzaXZlIGlmIDgwMi4xMWQgaXMgZW5hYmxlZCBhbmQgY291bnRyeSBJRSB3YXMgbm90IHlldCBmb3VuZCwgYWN0aXZlIG90aGVyd2lzZSAqLwogICAgaWYgKCgoVElfVFJVRSA9PSBiUmVndWxhdG9yeURvbWFpbkVuYWJsZWQpICYmIChUSV9GQUxTRSA9PSB0UGFyYW0uY29udGVudC5iSXNDb3VudHJ5Rm91bmQpKSB8fCBTQ0FOX1RZUEVfVFJJR0dFUkVEX1BBU1NJVkUgPT0gcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLnNjYW5UeXBlKQogICAgewoJCXBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5zY2FuVHlwZSA9IFNDQU5fVFlQRV9UUklHR0VSRURfUEFTU0lWRTsKICAgIH0KCS8qIEFsbCBwYXJhbXRlcnMgaW4gdGhlIGZ1bmMgYXJlIGhhcmQgY29kZWQsIGR1ZSB0byB0aGF0IHdlIHNldCB0byBhY3RpdmUgaWYgbm90IHBhc3NpdmUgKi8KICAgIGVsc2UKICAgIHsKICAgICAgICBwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMuc2NhblR5cGUgPSBTQ0FOX1RZUEVfVFJJR0dFUkVEX0FDVElWRTsKICAgICAgICAvKiBhbHNvIHNldCBudW1iZXIgYW5kIHJhdGUgb2YgcHJvYmUgcmVxdWVzdHMgKi8KICAgICAgICBwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMucHJvYmVSZXFOdW1iZXIgPSBTQ0FOX09JRF9ERUZBVUxUX1BST0JFX1JFUVVFU1RfTlVNQkVSX0c7CiAgICAgICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLnByb2JlUmVxdWVzdFJhdGUgPSAoRVJhdGVNYXNrKVNDQU5fT0lEX0RFRkFVTFRfUFJPQkVfUkVRVUVTVF9SQVRFX0c7CiAgICB9CiAgICAKICAgIC8qIGFkZCBzdXBwb3J0ZWQgY2hhbm5lbHMgb24gRyAqLwogICAgaWYgKFNDQU5fVFlQRV9OT1JNQUxfUEFTU0lWRSA9PSBwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMuc2NhblR5cGUgKQogICAgewogICAgICAgIHVWYWxpZENoYW5uZWxzQ291bnQgPSBzY2FuQ25jbk9zU21fRmlsbEFsbEF2YWlsYWJsZUNoYW5uZWxzIChoU2NhbkNuY24sIFJBRElPX0JBTkRfMl80X0dIWiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDQU5fVFlQRV9OT1JNQUxfUEFTU0lWRSwgJihwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMuY2hhbm5lbEVudHJ5WzBdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9NQVhfRFdFTExfVElNRV9QQVNTSVZFX0csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDQU5fT0lEX0RFRkFVTFRfTUlOX0RXRUxMX1RJTUVfUEFTU0lWRV9HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX0VBUkxZX1RFUk1JTkFUSU9OX0VWRU5UX1BBU1NJVkVfRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9DT1VOVF9QQVNTSVZFX0cpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHVWYWxpZENoYW5uZWxzQ291bnQgPSBzY2FuQ25jbk9zU21fRmlsbEFsbEF2YWlsYWJsZUNoYW5uZWxzIChoU2NhbkNuY24sIFJBRElPX0JBTkRfMl80X0dIWiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDQU5fVFlQRV9OT1JNQUxfQUNUSVZFLCAmKHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5jaGFubmVsRW50cnlbMF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX01BWF9EV0VMTF9USU1FX0FDVElWRV9HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX01JTl9EV0VMTF9USU1FX0FDVElWRV9HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX0VBUkxZX1RFUk1JTkFUSU9OX0VWRU5UX0FDVElWRV9HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX0VBUkxZX1RFUk1JTkFUSU9OX0NPVU5UX0FDVElWRV9HKTsKICAgIH0KICAgIHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5udW1PZkNoYW5uZWxzID0gdVZhbGlkQ2hhbm5lbHNDb3VudDsKCiAgICAvKiBjaGVjayB0aGF0IHNvbWUgY2hhbm5lbHMgYXJlIGF2YWlsYWJsZSAqLwogICAgaWYgKCB1VmFsaWRDaGFubmVsc0NvdW50ID4gMCApCiAgICB7CiAgICAgICAgRVNjYW5DbmNuUmVzdWx0U3RhdHVzICAgZVJlc3VsdDsKICAgICAgICAKICAgICAgICAvKiBzZW5kIGNvbW1hbmQgdG8gc2NhbiBjb25jZW50cmF0b3IgQVBQIFNNICovCiAgICAgICAgZVJlc3VsdCA9IHNjYW5DbmNuX1N0YXJ0MVNob3RTY2FuIChoU2NhbkNuY24sIFNDQU5fU0NDX0FQUF9PTkVfU0hPVCwgJihwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMpKTsKCiAgICAgICAgLyogaWYgc2NhbiBmYWlsZWQsIHNlbmQgc2NhbiBjb21wbGV0ZSBldmVudCB0byB0aGUgU00gKi8KICAgICAgICBpZiAoU0NBTl9DUlNfU0NBTl9SVU5OSU5HICE9IGVSZXN1bHQpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRTAocFNjYW5DbmNuLT5oUmVwb3J0LCBSRVBPUlRfU0VWRVJJVFlfRVJST1IgLCAic2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0R1NjYW46IHNjYW4gZmFpbGVkIG9uIDIuNCBHSHosIGNvbnRpbnVpbmcgdG8gNS4wIEdIeiBzY2FuXG4iKTsKICAgICAgICAgICAgZ2VuU01fRXZlbnQgKHBTY2FuQ25jbi0+aE9TU2NhblNtLCBTQ0FOX0NOQ05fT1NfU01fRVZFTlRfU0NBTl9DT01QTEVURSwgaFNjYW5DbmNuKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UwKHBTY2FuQ25jbi0+aFJlcG9ydCwgUkVQT1JUX1NFVkVSSVRZX0VSUk9SICwgInNjYW5DbmNuT3NTbV9BY3Rpb25TdGFydEdTY2FuOiBubyB2YWxpZCBjYWhubmVscyBvbiAyLjQgR0h6LCBjb250aW51aW5nIHRvIDUuMCBHSHogc2NhblxuIik7CiAgICAgICAgLyogbm8gY2hhbm5lbHMgdG8gc2Nhbiwgc2VuZCBhIHNjYW4gY29tcGxldGUgZXZlbnQgKi8KICAgICAgICBnZW5TTV9FdmVudCAocFNjYW5DbmNuLT5oT1NTY2FuU20sIFNDQU5fQ05DTl9PU19TTV9FVkVOVF9TQ0FOX0NPTVBMRVRFLCBoU2NhbkNuY24pOwogICAgfQp9CgovKiogCiAqIFxmbiAgICAgc2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0QVNjYW4KICogXGJyaWVmICBTY2FuIGNvbmNlbnRhcnRvciBPUyBzdGF0ZSBtYWNoaW5lIHN0YXJ0IHNjYW4gb24gQSBhY3Rpb24gZnVuY3Rpb24KICogCiAqIFNjYW4gY29uY2VudGFydG9yIE9TIHN0YXRlIG1hY2hpbmUgc3RhcnQgc2NhbiBvbiBBIGFjdGlvbiBmdW5jdGlvbi4KICogU3RhcnRzIGEgc2FjbiBvbiBBIHVzaW5nIGFsbCBhbGxvd2VkIGNoYW5uZWxzCiAqIAogKiBccGFyYW0gIGhTY2FuQ25jbiAtIGhhbmRsZSB0byB0aGUgc2NhbiBjb25jZW50YXJ0b3Igb2JqZWN0CiAqIFxyZXR1cm4gTm9uZQogKi8gCnZvaWQgc2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0QVNjYW4gKFRJX0hBTkRMRSBoU2NhbkNuY24pCnsKICAgIFRTY2FuQ25jbiAgICAgICAqcFNjYW5DbmNuID0gKFRTY2FuQ25jbiopaFNjYW5DbmNuOwogICAgcGFyYW1JbmZvX3QgICAgIHRQYXJhbTsKICAgIFRJX1VJTlQzMiAgICAgICB1VmFsaWRDaGFubmVsc0NvdW50OwogICAgVElfQk9PTCAgICAgICAgIGJSZWd1bGF0b3J5RG9tYWluRW5hYmxlZDsKCiAgICAvKiBpZiB0aGUgU1RBIGlzIG5vdCBjb25maWd1cmVkIGZvciBHIGJhbmQgb3IgZHVhbCBiYW5kLCBzZW5kIGEgc2NhbiBjb21wbGV0ZSBldmVudCB0byB0aGUgU00gKi8KICAgIHRQYXJhbS5wYXJhbVR5cGUgPSBTSVRFX01HUl9ERVNJUkVEX0RPVDExX01PREVfUEFSQU07CiAgICBzaXRlTWdyX2dldFBhcmFtIChwU2NhbkNuY24tPmhTaXRlTWFuYWdlciwgJnRQYXJhbSk7CiAgICBpZiAoKERPVDExX0FfTU9ERSAhPSB0UGFyYW0uY29udGVudC5zaXRlTWdyRG90MTFNb2RlKSAmJiAoRE9UMTFfRFVBTF9NT0RFICE9IHRQYXJhbS5jb250ZW50LnNpdGVNZ3JEb3QxMU1vZGUpKQogICAgewogICAgICAgIFRSQUNFMChwU2NhbkNuY24tPmhSZXBvcnQsIFJFUE9SVF9TRVZFUklUWV9JTkZPUk1BVElPTiAsICJzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRBU2NhbjogU1RBIGRvZXMgbm90IHdvcmsgb24gNS4wIEdIeiwgcXVpdHRpbmdcbiIpOwogICAgICAgIGdlblNNX0V2ZW50IChwU2NhbkNuY24tPmhPU1NjYW5TbSwgU0NBTl9DTkNOX09TX1NNX0VWRU5UX1NDQU5fQ09NUExFVEUsIGhTY2FuQ25jbik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIGJ1aWxkIHNjYW4gY29tbWFuZCBoZWFkZXIgKi8KICAgIHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5iYW5kID0gUkFESU9fQkFORF81XzBfR0haOwogICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLlRpZCA9IDA7CgogICAgLyogcXVlcnkgdGhlIHJlZ3VsYXRvcnkgZG9tYWluIGlmIDgwMi4xMWQgaXMgaW4gdXNlICovCiAgICB0UGFyYW0ucGFyYW1UeXBlID0gUkVHVUxBVE9SWV9ET01BSU5fRU5BQkxFRF9QQVJBTTsKICAgIHJlZ3VsYXRvcnlEb21haW5fZ2V0UGFyYW0gKHBTY2FuQ25jbi0+aFJlZ3VsYXRvcnlEb21haW4sICZ0UGFyYW0gKTsKICAgIGJSZWd1bGF0b3J5RG9tYWluRW5hYmxlZCA9IHRQYXJhbS5jb250ZW50LnJlZ3VsYXRvcnlEb21haW5FbmFibGVkOwoKICAgIC8qIEdldCBjb3VudHJ5IGNvZGUgc3RhdHVzICovCiAgICB0UGFyYW0ucGFyYW1UeXBlICAgICAgICAgID0gUkVHVUxBVE9SWV9ET01BSU5fSVNfQ09VTlRSWV9GT1VORDsKICAgIHRQYXJhbS5jb250ZW50LmVSYWRpb0JhbmQgPSBSQURJT19CQU5EXzVfMF9HSFo7CiAgICByZWd1bGF0b3J5RG9tYWluX2dldFBhcmFtIChwU2NhbkNuY24tPmhSZWd1bGF0b3J5RG9tYWluLCAmdFBhcmFtKTsKCiAgICAvKiBzY2FuIHR5cGUgaXMgcGFzc2l2ZSBpZiA4MDIuMTFkIGlzIGVuYWJsZWQgYW5kIGNvdW50cnkgSUUgd2FzIG5vdCB5ZXQgZm91bmQsIGFjdGl2ZSBvdGhlcndpc2UgKi8KICAgIGlmICgoKFRJX1RSVUUgPT0gYlJlZ3VsYXRvcnlEb21haW5FbmFibGVkKSAmJiAoVElfRkFMU0UgPT0gdFBhcmFtLmNvbnRlbnQuYklzQ291bnRyeUZvdW5kKSkgfHwgU0NBTl9UWVBFX1RSSUdHRVJFRF9QQVNTSVZFID09IHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5zY2FuVHlwZSkKICAgIHsKICAgICAgICBwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMuc2NhblR5cGUgPSBTQ0FOX1RZUEVfVFJJR0dFUkVEX1BBU1NJVkU7CiAgICB9CiAgICAvKiBBbGwgcGFyYW10ZXJzIGluIHRoZSBmdW5jIGFyZSBoYXJkIGNvZGVkLCBkdWUgdG8gdGhhdCB3ZSBzZXQgdG8gYWN0aXZlIGlmIG5vdCBwYXNzaXZlICovCgllbHNlCiAgICB7CiAgICAgICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLnNjYW5UeXBlID0gU0NBTl9UWVBFX1RSSUdHRVJFRF9BQ1RJVkU7CiAgICAgICAgLyogYWxzbyBzZXQgbnVtYmVyIGFuZCByYXRlIG9mIHByb2JlIHJlcXVlc3RzICovCiAgICAgICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLnByb2JlUmVxTnVtYmVyID0gU0NBTl9PSURfREVGQVVMVF9QUk9CRV9SRVFVRVNUX05VTUJFUl9BOwogICAgICAgIHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcy5wcm9iZVJlcXVlc3RSYXRlID0gKEVSYXRlTWFzaylTQ0FOX09JRF9ERUZBVUxUX1BST0JFX1JFUVVFU1RfUkFURV9BOwogICAgfQogICAgCiAgICAvKiBhZGQgc3VwcG9ydGVkIGNoYW5uZWxzIG9uIEcgKi8KICAgIGlmIChTQ0FOX1RZUEVfTk9STUFMX1BBU1NJVkUgPT0gcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLnNjYW5UeXBlICkKICAgIHsKICAgICAgICB1VmFsaWRDaGFubmVsc0NvdW50ID0gc2NhbkNuY25Pc1NtX0ZpbGxBbGxBdmFpbGFibGVDaGFubmVscyAoaFNjYW5DbmNuLCBSQURJT19CQU5EXzVfMF9HSFosIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX1RZUEVfTk9STUFMX1BBU1NJVkUsICYocFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLmNoYW5uZWxFbnRyeVswXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDQU5fT0lEX0RFRkFVTFRfTUFYX0RXRUxMX1RJTUVfUEFTU0lWRV9BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09JRF9ERUZBVUxUX01JTl9EV0VMTF9USU1FX1BBU1NJVkVfQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9FVkVOVF9QQVNTSVZFX0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDQU5fT0lEX0RFRkFVTFRfRUFSTFlfVEVSTUlOQVRJT05fQ09VTlRfUEFTU0lWRV9BICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdVZhbGlkQ2hhbm5lbHNDb3VudCA9IHNjYW5DbmNuT3NTbV9GaWxsQWxsQXZhaWxhYmxlQ2hhbm5lbHMgKGhTY2FuQ25jbiwgUkFESU9fQkFORF81XzBfR0haLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX1RZUEVfTk9STUFMX0FDVElWRSwgJihwU2NhbkNuY24tPnRPc1NjYW5QYXJhbXMuY2hhbm5lbEVudHJ5WzBdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9NQVhfRFdFTExfVElNRV9BQ1RJVkVfQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9NSU5fRFdFTExfVElNRV9BQ1RJVkVfQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9FVkVOVF9BQ1RJVkVfQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NBTl9PSURfREVGQVVMVF9FQVJMWV9URVJNSU5BVElPTl9DT1VOVF9BQ1RJVkVfQSApOwogICAgfQogICAgcFNjYW5DbmNuLT50T3NTY2FuUGFyYW1zLm51bU9mQ2hhbm5lbHMgPSB1VmFsaWRDaGFubmVsc0NvdW50OwoKICAgIC8qIGNoZWNrIHRoYXQgc29tZSBjaGFubmVscyBhcmUgYXZhaWxhYmxlICovCiAgICBpZiAoIHVWYWxpZENoYW5uZWxzQ291bnQgPiAwICkKICAgIHsKICAgICAgICBFU2NhbkNuY25SZXN1bHRTdGF0dXMgICBlUmVzdWx0OwoKICAgICAgIC8qIHNlbmQgY29tbWFuZCB0byBzY2FuIGNvbmNlbnRyYXRvciBBUFAgU00gKi8KICAgICAgICBlUmVzdWx0ID0gc2NhbkNuY25fU3RhcnQxU2hvdFNjYW4gKGhTY2FuQ25jbiwgU0NBTl9TQ0NfQVBQX09ORV9TSE9ULCAmKHBTY2FuQ25jbi0+dE9zU2NhblBhcmFtcykpOwoKICAgICAgICAvKiBpZiBzY2FuIGZhaWxlZCwgc2VuZCBzY2FuIGNvbXBsZXRlIGV2ZW50IHRvIHRoZSBTTSAqLwogICAgICAgIGlmIChTQ0FOX0NSU19TQ0FOX1JVTk5JTkcgIT0gZVJlc3VsdCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFMChwU2NhbkNuY24tPmhSZXBvcnQsIFJFUE9SVF9TRVZFUklUWV9FUlJPUiAsICJzY2FuQ25jbk9zU21fQWN0aW9uU3RhcnRBU2Nhbjogc2NhbiBmYWlsZWQgb24gNS4wIEdIeiwgcXVpdHRpbmdcbiIpOwogICAgICAgICAgICBnZW5TTV9FdmVudCAocFNjYW5DbmNuLT5oT1NTY2FuU20sIFNDQU5fQ05DTl9PU19TTV9FVkVOVF9TQ0FOX0NPTVBMRVRFLCBoU2NhbkNuY24pOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRTAocFNjYW5DbmNuLT5oUmVwb3J0LCBSRVBPUlRfU0VWRVJJVFlfRVJST1IgLCAic2NhbkNuY25Pc1NtX0FjdGlvblN0YXJ0R1NjYW46IG5vIHZhbGlkIGNhaG5uZWxzIG9uIDUuMCBHSHosIHF1aXR0aW5nXG4iKTsKICAgICAgICAvKiBubyBjaGFubmVscyB0byBzY2FuLCBzZW5kIGEgc2NhbiBjb21wbGV0ZSBldmVudCAqLwogICAgICAgIGdlblNNX0V2ZW50IChwU2NhbkNuY24tPmhPU1NjYW5TbSwgU0NBTl9DTkNOX09TX1NNX0VWRU5UX1NDQU5fQ09NUExFVEUsIGhTY2FuQ25jbik7CiAgICB9Cn0KCi8qKiAKICogXGZuICAgICBzY2FuQ25jbk9zU21fQWN0aW9uQ29tcGxldGVTY2FuCiAqIFxicmllZiAgU2NhbiBjb25jZW50YXJ0b3IgT1Mgc3RhdGUgbWFjaGluZSBjb21wbGV0ZSBzY2FuIGFjdGlvbiBmdW5jdGlvbgogKiAKICogU2NhbiBjb25jZW50YXJ0b3IgT1Mgc3RhdGUgbWFjaGluZSBjb21wbGV0ZSBzY2FuIGFjdGlvbiBmdW5jdGlvbi4KICogQ2xlYW5zIHVwIGFmdGVyIGFuIE9TIHNjYW4gY3ljbGUgLSBzdGFiaWxpemUgdGhlIHNjYW4gcmVzdWx0IHRhYmxlCiAqIAogKiBccGFyYW0gIGhTY2FuQ25jbiAtIGhhbmRsZSB0byB0aGUgc2NhbiBjb25jZW50YXJ0b3Igb2JqZWN0CiAqIFxyZXR1cm4gTm9uZQogKi8gCnZvaWQgc2NhbkNuY25Pc1NtX0FjdGlvbkNvbXBsZXRlU2NhbiAoVElfSEFORExFIGhTY2FuQ25jbikKewogICAgVFNjYW5DbmNuICAgICAgICpwU2NhbkNuY24gPSAoVFNjYW5DbmNuKiloU2NhbkNuY247CgoKCSAvKlVwZGF0ZSB0aGUgdGFibGUgb25seSBpZiBzY2FuIHdhcyBub3QgcmVqZWN0ZWQqLwoJIGlmICggIXBTY2FuQ25jbi0+cFNjYW5DbGllbnRzWyBwU2NhbkNuY24tPmVDdXJyZW50UnVubmluZ0FwcFNjYW5DbGllbnQgXS0+YlNjYW5SZWplY3RlZE9uMl80KQoJIHsKICAgIC8qIAogICAgICogc2V0IHRoZSByZXN1bHQgdGFibGUgdG8gc3RhYmxlIHN0YXRlLiBOb3RlOiBPSUQgc2NhbnMgYXJlIGFsd2F5cyBkb25lIGZvciB0aGUgYXBwbGljYXRpb24sIHNvIHRoZQogICAgICogcmVzdWx0cyB3aWxsIGFsd2F5cyBiZSBzZW50IHRvIHRoZSBzY2FuIGNvbmNlbnRhcnRvciBhcHAgc2NhbiByZXN1bHQgdGFibGUsIHJlZ2FyZGxlc3Mgb2YgdGhlCiAgICAgKiBTTUUgY29ubmVjdGlvbiBtb2RlLiBIb3dldmVyLCBpdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBTTUUgd2lsbCBOT1QgYXR0ZW1wdCB0byBjb25uZWN0IHdoZW4gYW4gT0lECiAgICAgKiBzY2FuIHJlcXVlc3Qgd2lsbCBiZSByZWNlaXZlZAogICAgICovCgkJICBzY2FuUmVzdWx0VGFibGVfU2V0U3RhYmxlU3RhdGUgKHBTY2FuQ25jbi0+aFNjYW5SZXN1bHRUYWJsZSk7CgkgfQoJIGVsc2UKCSB7CgkJICBwU2NhbkNuY24tPnBTY2FuQ2xpZW50c1sgcFNjYW5DbmNuLT5lQ3VycmVudFJ1bm5pbmdBcHBTY2FuQ2xpZW50IF0tPmJTY2FuUmVqZWN0ZWRPbjJfNCA9IFRJX0ZBTFNFOwoJIH0KCiAgICAvKiBtYXJrIHRoYXQgT0lEIHNjYW4gcHJvY2VzcyBpcyBubyBsb25nZXIgcnVubmluZyAqLwogICAgcFNjYW5DbmNuLT5iT1NTY2FuUnVubmluZyA9IFRJX0ZBTFNFOwogICAgLyogYWxzbyBtYXJrIHRoYXQgbm8gYXBwIHNjYW4gY2xpZW50IGlzIHJ1bm5pbmcgKi8KICAgIHBTY2FuQ25jbi0+ZUN1cnJlbnRSdW5uaW5nQXBwU2NhbkNsaWVudCA9IFNDQU5fU0NDX05PX0NMSUVOVDsKIAoKICAgIC8qIG5vIG5lZWQgdG8gc2VuZCBzY2FuIGNvbXBsZXRlIGV2ZW50IC0gV1pDIChvciBlcXVpdmFsZW50IG90aGVyIE9TIGFwcHMpIHdpbGwgcXVlcnkgZm9yIHRoZSByZXN1bHRzICovCn0KCi8qKiAKICogXGZuICAgICBzY2FuQ25jbk9zU21fRmlsbEFsbEF2YWlsYWJsZUNoYW5uZWxzCiAqIFxicmllZiAgRmlsbHMgYSBjaGhhbmVsIGFycmF5IHdpdGggdmFsaWQgY2hhbm5lbHMgKGFuZCB0aGVpciBwYXJhbXMpIGFjY29yZGluZyB0byBiYW5kIGFuZCBzY2FuIHR5cGUKICogCiAqIEZpbGxzIGEgY2hoYW5lbCBhcnJheSB3aXRoIHZhbGlkIGNoYW5uZWxzIChhbmQgdGhlaXIgcGFyYW1zKSBhY2NvcmRpbmcgdG8gYmFuZCBhbmQgc2NhbiB0eXBlCiAqIAogKiBccGFyYW0gIGhTY2FuQ25jbiAtIGhhbmRsZSB0byB0aGUgc2NhbiBjb25jZW50cmF0b3Igb2JqZWN0CiAqIFxwYXJhbSAgZUJhbmQgLSBiYW5kIHRvIGV4dHJhY3QgY2hhbm5lbHMgZm9yCiAqIFxwYXJhbSAgZVNjYW5UeXBlIC0gc2NhbiB0eXBlIHRwIGVjdHJhY3QgY2hhbm5lbHMgZm9yCiAqIFxwYXJhbSAgcENoYW5uZWxBcnJheSAtIHdoZXJlIHRvIHN0b3JlIGFsbG93ZWQgY2hhbm5lbHMgaW5mb3JtYXRpb24KICogXHBhcmFtICB1TWF4RHdlbGxUaW1lIC0gbWF4aW11bSBkd2VsbCB0aW1lIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGVhY2ggY2hhbm5lbAogKiBccGFyYW0gIHVNaW5Ed2VsbFRpbWUgLSBtaW5pbXVtIGR3ZWxsIHRpbWUgdmFsdWUgdG8gYmUgdXNlZCBmb3IgZWFjaCBjaGFubmVsCiAqIFxwYXJhbSAgZUVUQ29uZGl0aW9uIC0gZWFybHkgdGVybWluYXRpb24gY29uZGl0aW9uIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGVhY2ggY2hhbm5lbAogKiBccGFyYW0gIHVFVEZyYW1lTnVtYmVyIC0gZWFybHkgdGVybWluYXRpb24gZnJhbWUgbnVtYmVyIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGVhY2ggY2hhbm5lbAogKiBccmV0dXJuIE51bWJlciBvZiBhbGxvd2VkIGNoYW5uZWxzICh0aGF0IHdlcmUgcGxhY2VkIGluIHRoZSBnaXZlbiBjaGFubmVscyBhcnJheSkKICovIApUSV9VSU5UMzIgc2NhbkNuY25Pc1NtX0ZpbGxBbGxBdmFpbGFibGVDaGFubmVscyAoVElfSEFORExFIGhTY2FuQ25jbiwgRVJhZGlvQmFuZCBlQmFuZCwgRVNjYW5UeXBlIGVTY2FuVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRTY2FuQ2hhbm5lbEVudHJ5ICpwQ2hhbm5lbEFycmF5LCBUSV9VSU5UMzIgdU1heER3ZWxsVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRJX1VJTlQzMiB1TWluQ2hhbm5lbFRpbWUsIEVTY2FuRXRDb25kaXRpb24gZUVUQ29uZGl0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVElfVUlOVDggdUVURnJhbWVOdW1iZXIpCnsKICAgIFRTY2FuQ25jbiAgICAgICAqcFNjYW5DbmNuID0gKFRTY2FuQ25jbiopaFNjYW5DbmNuOwogICAgVElfVUlOVDMyICAgICAgIGksIGosIHVBbGxvd2VkQ2hhbm5lbHNDb3VudCwgdVZhbGlkQ2hhbm5lbHNDbnQgPSAwOwogICAgcGFyYW1JbmZvX3QgICAgIHRQYXJhbTsKICAgIFRJX1VJTlQ4ICAgICAgICB1VGVtcENoYW5uZWxMaXN0WyBTQ0FOX01BWF9OVU1fT0ZfTk9STUFMX0NIQU5ORUxTX1BFUl9DT01NQU5EIF07CiAKICAgIC8qIGdldCB0aGUgbnVtbmJlciBvZiBzdXBwb3J0ZWQgY2hhbm5lbHMgZm9yIHRoaXMgYmFuZCAqLwogICAgdFBhcmFtLnBhcmFtVHlwZSA9IFJFR1VMQVRPUllfRE9NQUlOX0FMTF9TVVBQT1JURURfQ0hBTk5FTFM7CiAgICB0UGFyYW0uY29udGVudC5zaXRlTWdyUmFkaW9CYW5kID0gZUJhbmQ7CiAgICByZWd1bGF0b3J5RG9tYWluX2dldFBhcmFtIChwU2NhbkNuY24tPmhSZWd1bGF0b3J5RG9tYWluLCAmdFBhcmFtKTsKICAgIHVBbGxvd2VkQ2hhbm5lbHNDb3VudCA9IHRQYXJhbS5jb250ZW50LnN1cHBvcnRlZENoYW5uZWxzLnNpemVPZkxpc3Q7CgogICAgLyogZm9yIHRoZSB0aW1lIGJlaW5nIGRvbid0IHNjYW4gbW9yZSBjaGFubmVscyB0aGFuIGZpdCBpbiBvbmUgY29tbWFuZCAqLwogICAgaWYgKHVBbGxvd2VkQ2hhbm5lbHNDb3VudCA+IFNDQU5fTUFYX05VTV9PRl9OT1JNQUxfQ0hBTk5FTFNfUEVSX0NPTU1BTkQpCiAgICB7CiAgICAgICAgdUFsbG93ZWRDaGFubmVsc0NvdW50ID0gU0NBTl9NQVhfTlVNX09GX05PUk1BTF9DSEFOTkVMU19QRVJfQ09NTUFORDsKICAgIH0KCiAgICAvKiBDb3B5IGFsbG93ZWQgY2hhbm5lbHMgdG8gcmV1c2UgcGFyYW0gdmFyICovCiAgICBvc19tZW1vcnlDb3B5IChwU2NhbkNuY24tPmhPUywgdVRlbXBDaGFubmVsTGlzdCwKICAgICAgICAgICAgdFBhcmFtLmNvbnRlbnQuc3VwcG9ydGVkQ2hhbm5lbHMubGlzdE9mQ2hhbm5lbHMsIHVBbGxvd2VkQ2hhbm5lbHNDb3VudCApOwoKICAgIC8qIHByZWFwcmUgdGhlIHBhcmFtIHZhciB0byByZXF1ZXN0IGNoYW5uZWwgYWxsb3dhbmNlIGZvciB0aGUgcmVxdWVzdGVkIHNjYW4gdHlwZSAqLwogICAgdFBhcmFtLnBhcmFtVHlwZSA9IFJFR1VMQVRPUllfRE9NQUlOX0dFVF9TQ0FOX0NBUEFCSUxJVElFUzsKICAgIHRQYXJhbS5jb250ZW50LmNoYW5uZWxDYXBhYmlsaXR5UmVxLmJhbmQgPSBlQmFuZDsKCiAgICAvKiBhZGQgZGVmYXVsdCB2YWx1ZXMgdG8gY2hhbm5lbHMgYWxsb3dlZCBmb3IgdGhlIHJlcXVlc3RlZCBzY2FuIHR5cGUgYW5kIGJhbmQgKi8KICAgIGZvciAoaSA9IDA7IGkgPCB1QWxsb3dlZENoYW5uZWxzQ291bnQ7IGkrKykKICAgIHsKICAgICAgICAvKiBnZXQgc3BlY2lmaWMgY2hhbm5lbCBhbGxvd2FuY2UgZm9yIHNjYW4gdHlwZSAqLwogICAgICAgIGlmICgoZVNjYW5UeXBlID09IFNDQU5fVFlQRV9OT1JNQUxfUEFTU0lWRSkgfHwKICAgICAgICAgICAgKGVTY2FuVHlwZSA9PSBTQ0FOX1RZUEVfVFJJR0dFUkVEX1BBU1NJVkUpIHx8CiAgICAgICAgICAgIChlU2NhblR5cGUgPT0gU0NBTl9UWVBFX1NQUykpCiAgICAgICAgewogICAgICAgICAgICB0UGFyYW0uY29udGVudC5jaGFubmVsQ2FwYWJpbGl0eVJlcS5zY2FuT3B0aW9uID0gUEFTU0lWRV9TQ0FOTklORzsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdFBhcmFtLmNvbnRlbnQuY2hhbm5lbENhcGFiaWxpdHlSZXEuc2Nhbk9wdGlvbiA9IEFDVElWRV9TQ0FOTklORzsKICAgICAgICB9CiAgICAgICAgdFBhcmFtLmNvbnRlbnQuY2hhbm5lbENhcGFiaWxpdHlSZXEuY2hhbm5lbE51bSA9IHVUZW1wQ2hhbm5lbExpc3RbIGkgXTsKCiAgICAgICAgcmVndWxhdG9yeURvbWFpbl9nZXRQYXJhbSggcFNjYW5DbmNuLT5oUmVndWxhdG9yeURvbWFpbiwgJnRQYXJhbSApOwogICAgICAgIGlmIChUSV9UUlVFID09IHRQYXJhbS5jb250ZW50LmNoYW5uZWxDYXBhYmlsaXR5UmV0LmNoYW5uZWxWYWxpZGl0eSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGFkZCB0aGUgY2hhbm5lbCBJRCAqLwogICAgICAgICAgICBwQ2hhbm5lbEFycmF5WyB1VmFsaWRDaGFubmVsc0NudCBdLm5vcm1hbENoYW5uZWxFbnRyeS5jaGFubmVsID0gdVRlbXBDaGFubmVsTGlzdFsgaSBdOwoKICAgICAgICAgICAgLyogYWRkIG90aGVyIGRlZmF1bHQgcGFyYW1ldGVycyAqLwogICAgICAgICAgICBwQ2hhbm5lbEFycmF5WyB1VmFsaWRDaGFubmVsc0NudCBdLm5vcm1hbENoYW5uZWxFbnRyeS5taW5DaGFubmVsRHdlbGxUaW1lID0gdU1pbkNoYW5uZWxUaW1lOwogICAgICAgICAgICBwQ2hhbm5lbEFycmF5WyB1VmFsaWRDaGFubmVsc0NudCBdLm5vcm1hbENoYW5uZWxFbnRyeS5tYXhDaGFubmVsRHdlbGxUaW1lID0gdU1heER3ZWxsVGltZTsKICAgICAgICAgICAgcENoYW5uZWxBcnJheVsgdVZhbGlkQ2hhbm5lbHNDbnQgXS5ub3JtYWxDaGFubmVsRW50cnkuZWFybHlUZXJtaW5hdGlvbkV2ZW50ID0gZUVUQ29uZGl0aW9uOwogICAgICAgICAgICBwQ2hhbm5lbEFycmF5WyB1VmFsaWRDaGFubmVsc0NudCBdLm5vcm1hbENoYW5uZWxFbnRyeS5FVE1heE51bU9mQVBmcmFtZXMgPSB1RVRGcmFtZU51bWJlcjsKICAgICAgICAgICAgcENoYW5uZWxBcnJheVsgdVZhbGlkQ2hhbm5lbHNDbnQgXS5ub3JtYWxDaGFubmVsRW50cnkudHhQb3dlckRibSAgPSAKICAgICAgICAgICAgICAgIHRQYXJhbS5jb250ZW50LmNoYW5uZWxDYXBhYmlsaXR5UmV0Lm1heFR4UG93ZXJEYm07CgogICAgICAgICAgICAvKiBGaWxsIGJyb2FkY2FzdCBCU1NJRCAqLwogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgNjsgaisrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwQ2hhbm5lbEFycmF5WyB1VmFsaWRDaGFubmVsc0NudCBdLm5vcm1hbENoYW5uZWxFbnRyeS5ic3NJZFsgaiBdID0gMHhmZjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1VmFsaWRDaGFubmVsc0NudCsrOwogICAgICAgIH0KICAgIH0KCiAgICAvKiByZXR1cm4gdGhlIG51bWJlciBvZiBjaGFubmVscyB0aGF0IGFyZSBhY3R1YWxseSBhbGxvd2VkIGZvciB0aGUgcmVxdWVzdGVkIHNjYW4gdHlwZSBvbiB0aGUgcmVxdWVzdGVkIGJhbmQgKi8KICAgIHJldHVybiB1VmFsaWRDaGFubmVsc0NudDsKfQoKLyoqIAogKiBcZm4gICAgIEZ1bmN0aW9uIGRlY2xhcmF0aW9uIAogKiBcYnJpZWYgIEZ1bmN0aW9uIGJyaWVmIGRlc2NyaXB0aW9uIGdvZXMgaGVyZSAKICogCiAqIEZ1bmN0aW9uIGRldGFpbGVkIGRlc2NyaXB0aW9uIGdvZXMgaGVyZSAKICogCiAqIFxub3RlICAgTm90ZSBpcyBpbmRpY2F0ZWQgaGVyZSAKICogXHBhcmFtICBQYXJhbWV0ZXIgbmFtZSAtIHBhcmFtZXRlciBkZXNjcmlwdGlvbgogKiBccGFyYW0gIIUgCiAqIFxyZXR1cm4gUmV0dXJuIGNvZGUgaXMgZGV0YWlsZWQgaGVyZSAKICogXHNhICAgICBSZWZlcmVuY2UgdG8gb3RoZXIgcmVsZXZhbnQgZnVuY3Rpb25zIAogKi8gCi8qKgogKiBcXG4KICogXGRhdGUgMTEtSmFuLTIwMDVcbgogKiBcYnJpZWYgSGFuZGxlcyBhbiB1bmV4cGVjdGVkIGV2ZW50LlxuCgogKgogKiBGdW5jdGlvbiBTY29wZSBcZSBQcml2YXRlLlxuCiAqIFxwYXJhbSBoU2NhbkNuY24gLSBoYW5kbGUgdG8gdGhlIHNjYW4gY29uY2VudHJhdG9yIG9iamVjdC5cbgogKiBccmV0dXJuIGFsd2F5cyBPSy5cbgogKi8Kdm9pZCBzY2FuQ25jbk9zU21fQWN0aW9uVW5leHBlY3RlZCAoVElfSEFORExFIGhTY2FuQ25jbikgCnsKICAgIFRTY2FuQ25jbiAgICAgICAqcFNjYW5DbmNuID0gKFRTY2FuQ25jbiopaFNjYW5DbmNuOwoKICAgIFRSQUNFMChwU2NhbkNuY24tPmhSZXBvcnQsIFJFUE9SVF9TRVZFUklUWV9FUlJPUiAsICJzY2FuQ25jbk9zU21fQWN0aW9uVW5leHBlY3RlZDogVW5leHBldGVkIGFjdGlvbiBmb3IgY3VycmVudCBzdGF0ZVxuIik7Cn0KCg==