LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3Z4Lmh4eCIKCiNkZWZpbmUgX1NWWF9VU0VfVU5PR0xPQkFMU18KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9kb2N1bWVudC9FdmVudE9iamVjdC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvbGFuZy9EaXNwb3NlZEV4Y2VwdGlvbi5ocHA+CiNpbmNsdWRlIDx2b3MvbXV0ZXguaHh4PgojaW5jbHVkZSA8b3NsL211dGV4Lmh4eD4KI2luY2x1ZGUgPHNmeDIvZGlzcGF0Y2guaHh4PgojaW5jbHVkZSA8c290L2Nsc2lkcy5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3NlcnZpY2VpbmZvaGVscGVyLmh4eD4KCiNpbmNsdWRlIDxydGwvdXVpZC5oPgojaW5jbHVkZSA8cnRsL21lbW9yeS5oPgojaW5jbHVkZSA8c2Z4Mi9vYmpzaC5oeHg+CiNpbmNsdWRlIDxzdngvc3ZkcG9vbC5oeHg+CiNpbmNsdWRlIDxzdngvc3Zkb2JqLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRvb2xlMi5oeHg+CiNpbmNsdWRlIDxzdngvc3ZkcGFnZS5oeHg+CiNpbmNsdWRlIDxzdngvc3ZkbW9kZWwuaHh4PgojaW5jbHVkZSA8c3Z4L3N2ZHZpZXcuaHh4PgojaW5jbHVkZSA8c3Z4L3N2ZHBhZ3YuaHh4PgojaW5jbHVkZSA8c3Z4L3Vub3BhZ2UuaHh4PgojaW5jbHVkZSAic2hhcGVpbXBsLmh4eCIKI2luY2x1ZGUgInN2eC9nbG9ibDNkLmh4eCIKI2luY2x1ZGUgPHN2eC9wb2x5c2MzZC5oeHg+CiNpbmNsdWRlIDxzdngvdW5vcHJvdi5oeHg+CiNpbmNsdWRlIDxzdngvc3Zkb3BhdGguaHh4PgojaW5jbHVkZSAic3Z4L3Vub2FwaS5oeHgiCiNpbmNsdWRlIDxzdngvc3Zkb21lYXMuaHh4PgojaW5jbHVkZSA8c3Z4L2V4dHJ1ZDNkLmh4eD4KI2luY2x1ZGUgPHN2eC9sYXRoZTNkLmh4eD4KI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+CiNpbmNsdWRlIDx0b29scy9kaWFnbm9zZV9leC5oPgoKdXNpbmcgOjpydGw6Ok9VU3RyaW5nOwp1c2luZyBuYW1lc3BhY2UgOjp2b3M7CnVzaW5nIG5hbWVzcGFjZSA6OmNwcHU7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmRyYXdpbmc7CgojZGVmaW5lIElOVEVSRkFDRV9UWVBFKCB4aW50ICkgXAoJOjpnZXRDcHB1VHlwZSgoY29uc3QgUmVmZXJlbmNlPCB4aW50ID4qKTApCgojZGVmaW5lIFFVRVJZSU5UKCB4aW50ICkgXAoJaWYoIHJUeXBlID09IDo6Z2V0Q3BwdVR5cGUoKGNvbnN0IFJlZmVyZW5jZTwgeGludCA+KikwKSApIFwKCQlhQW55IDw8PSBSZWZlcmVuY2U8IHhpbnQgPih0aGlzKQoKREVDTEFSRV9MSVNUKCBTdnhEcmF3UGFnZUxpc3QsIFN2eERyYXdQYWdlICogKQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogY2xhc3MgU3Z4RHJhd1BhZ2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpVTk8zX0dFVElNUExFTUVOVEFUSU9OX0lNUEwoIFN2eERyYXdQYWdlICk7CkRCR19OQU1FKFN2eERyYXdQYWdlKQpTdnhEcmF3UGFnZTo6U3Z4RHJhd1BhZ2UoIFNkclBhZ2UqIHBJblBhZ2UgKSB0aHJvdygpCjogbXJCSGVscGVyKCBnZXRNdXRleCgpICkKLCBtcFBhZ2UoIHBJblBhZ2UgKQosIG1wTW9kZWwoIDAgKQp7CiAgICBEQkdfQ1RPUihTdnhEcmF3UGFnZSxOVUxMKTsgICAgCgkvLyBBbSBCcm9hZGNhc3RlciBhbm1lbGRlbgoJaWYoIG1wUGFnZSApCgkJbXBNb2RlbCA9IG1wUGFnZS0+R2V0TW9kZWwoKTsKCWlmKCBtcE1vZGVsICkKCQlTdGFydExpc3RlbmluZyggKm1wTW9kZWwgKTsKCgoJLy8gRXJ6ZXVnZW4gZGVyIChoaWRkZW4pIDo6Y29tOjpzdW46OnN0YXI6OnNkYmN4OjpWaWV3CgltcFZpZXcgPSBuZXcgU2RyVmlldyggbXBNb2RlbCApOwoJaWYoIG1wVmlldyApCgkJbXBWaWV3LT5TZXREZXNpZ25Nb2RlKHNhbF9UcnVlKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEN0b3IgZnVlciBTdnhEcmF3UGFnZV9OZXdJbnN0YW5jZSgpCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTdnhEcmF3UGFnZTo6U3Z4RHJhd1BhZ2UoKSB0aHJvdygpCjogbXJCSGVscGVyKCBnZXRNdXRleCgpICkKLCBtcFBhZ2UoIE5VTEwgKQosIG1wTW9kZWwoIE5VTEwgKQosIG1wVmlldyggTlVMTCApCnsKICAgIERCR19DVE9SKFN2eERyYXdQYWdlLE5VTEwpOyAgICAKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClN2eERyYXdQYWdlOjp+U3Z4RHJhd1BhZ2UoKSB0aHJvdygpCnsKCURCR19BU1NFUlQoIG1yQkhlbHBlci5iRGlzcG9zZWQsICJTdnhEcmF3UGFnZSBtdXN0IGJlIGRpc3Bvc2VkISIgKTsKCWlmKCAhbXJCSGVscGVyLmJEaXNwb3NlZCApCiAgICB7CiAgICAgICAgYWNxdWlyZSgpOwoJCWRpc3Bvc2UoKTsKICAgIH0KICAgIERCR19EVE9SKFN2eERyYXdQYWdlLE5VTEwpOyAgICAKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBYSW50ZXJmYWNlCnZvaWQgU3Z4RHJhd1BhZ2U6OnJlbGVhc2UoKSB0aHJvdygpCnsKLyoKCXVubzo6UmVmZXJlbmNlPCB1bm86OlhJbnRlcmZhY2UgPiB4KCB4RGVsZWdhdG9yICk7CglpZiAoISB4LmlzKCkpCgl7CgkJaWYgKG9zbF9kZWNyZW1lbnRJbnRlcmxvY2tlZENvdW50KCAmbV9yZWZDb3VudCApID09IDApCgkJewoJCQlpZiAoISBtckJIZWxwZXIuYkRpc3Bvc2VkKQoJCQl7CgkJCQl1bm86OlJlZmVyZW5jZTwgdW5vOjpYSW50ZXJmYWNlID4geEhvbGRBbGl2ZSggKHVubzo6WFdlYWsqKXRoaXMgKTsKCQkJCS8vIEZpcnN0IGRpc3Bvc2UKCQkJCXRyeQoJCQkJewoJCQkJCWRpc3Bvc2UoKTsKCQkJCX0KCQkJCWNhdGNoKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6RXhjZXB0aW9uJikKCQkJCXsKCQkJCQkvLyByZWxlYXNlIHNob3VsZCBub3QgdGhyb3cgZXhjZXB0aW9ucwoJCQkJfQoKCQkJCS8vIG9ubHkgdGhlIGFsaXZlIHJlZiBob2xkcyB0aGUgb2JqZWN0CgkJCQlPU0xfQVNTRVJUKCBtX3JlZkNvdW50ID09IDEgKTsKCQkJCS8vIGRlc3Ryb3kgdGhlIG9iamVjdCBpZiB4SG9sZEFsaXZlIGRlY3JlbWVudCB0aGUgcmVmY291bnQgdG8gMAoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJCS8vIHJlc3RvcmUgdGhlIHJlZmVyZW5jZSBjb3VudAoJCW9zbF9pbmNyZW1lbnRJbnRlcmxvY2tlZENvdW50KCAmbV9yZWZDb3VudCApOwoJfQoqLwoJT1dlYWtBZ2dPYmplY3Q6OnJlbGVhc2UoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTdnhEcmF3UGFnZSogU3Z4RHJhd1BhZ2U6OkdldFBhZ2VGb3JTZHJQYWdlKCBTZHJQYWdlKiBtcFBhZ2UgKSB0aHJvdygpCnsKCXJldHVybiBnZXRJbXBsZW1lbnRhdGlvbiggbXBQYWdlLT5nZXRVbm9QYWdlKCkgKTsKfQoKLy8gWENvbXBvbmVudAp2b2lkIFN2eERyYXdQYWdlOjpkaXNwb3NpbmcoKSB0aHJvdygpCnsKCWlmKCBtcE1vZGVsICkKCXsKCQlFbmRMaXN0ZW5pbmcoICptcE1vZGVsICk7CgkJbXBNb2RlbCA9IE5VTEw7Cgl9CgoJaWYoIG1wVmlldyApCgl7CgkJZGVsZXRlIG1wVmlldzsKCQltcFZpZXcgPSBOVUxMOwoJfQoJbXBQYWdlID0gMDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFhDb21wb25lbnQKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFN2eERyYXdQYWdlOjpkaXNwb3NlKCkKCXRocm93KDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikKewoJT0d1YXJkIGFTb2xhckd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJLy8gQW4gZnJlcXVlbnRseSBwcm9ncmFtbWluZyBlcnJvciBpcyB0byByZWxlYXNlIHRoZSBsYXN0CgkvLyByZWZlcmVuY2UgdG8gdGhpcyBvYmplY3QgaW4gdGhlIGRpc3Bvc2luZyBtZXNzYWdlLgoJLy8gTWFrZSBpdCBydWJ1c3QsIGhvbGQgYSBzZWxmIFJlZmVyZW5jZS4KCXVubzo6UmVmZXJlbmNlPCBsYW5nOjpYQ29tcG9uZW50ID4geFNlbGYoIHRoaXMgKTsKCgkvLyBHdWFyZCBkaXNwb3NlIGFnYWluc3QgbXVsdGlibGUgdGhyZWFkaW5nCgkvLyBSZW1hcms6IEl0IGlzIGFuIGVycm9yIHRvIGNhbGwgZGlzcG9zZSBtb3JlIHRoYW4gb25jZQoJc2FsX0Jvb2wgYkRvRGlzcG9zZSA9IHNhbF9GYWxzZTsKCXsKCW9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1yQkhlbHBlci5yTXV0ZXggKTsKCWlmKCAhbXJCSGVscGVyLmJEaXNwb3NlZCAmJiAhbXJCSGVscGVyLmJJbkRpc3Bvc2UgKQoJewoJCS8vIG9ubHkgb25lIGNhbGwgZ28gaW50byB0aGlzIHNlY3Rpb24KCQltckJIZWxwZXIuYkluRGlzcG9zZSA9IHNhbF9UcnVlOwoJCWJEb0Rpc3Bvc2UgPSBzYWxfVHJ1ZTsKCX0KCX0KCgkvLyBEbyBub3QgaG9sZCB0aGUgbXV0ZXggYmVjYXVzZSB3ZSBhcmUgYnJvYWRjYXN0aW5nCglpZiggYkRvRGlzcG9zZSApCgl7CgkJLy8gQ3JlYXRlIGFuIGV2ZW50IHdpdGggdGhpcyBhcyBzZW5kZXIKCQl0cnkKCQl7CgkJCXVubzo6UmVmZXJlbmNlPCB1bm86OlhJbnRlcmZhY2UgPiB4U291cmNlKCB1bm86OlJlZmVyZW5jZTwgdW5vOjpYSW50ZXJmYWNlID46OnF1ZXJ5KCAobGFuZzo6WENvbXBvbmVudCAqKXRoaXMgKSApOwoJCQk6OmNvbTo6c3VuOjpzdGFyOjpkb2N1bWVudDo6RXZlbnRPYmplY3QgYUV2dDsKCQkJYUV2dC5Tb3VyY2UgPSB4U291cmNlOwoJCQkvLyBpbmZvcm0gYWxsIGxpc3RlbmVycyB0byByZWxlYXNlIHRoaXMgb2JqZWN0CgkJCS8vIFRoZSBsaXN0ZW5lciBjb250YWluZXIgYXJlIGF1dG9tYXRpY2x5IGNsZWFyZWQKCQkJbXJCSGVscGVyLmFMQy5kaXNwb3NlQW5kQ2xlYXIoIGFFdnQgKTsKCQkJLy8gbm90aWZ5IHN1YmNsYXNzZXMgdG8gZG8gdGhlaXIgZGlzcG9zZQoJCQlkaXNwb3NpbmcoKTsKCQl9CgkJY2F0Y2goOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpFeGNlcHRpb24mIGUpCgkJewoJCQkvLyBjYXRjaCBleGNlcHRpb24gYW5kIHRocm93IGFnYWluIGJ1dCBzaWduYWwgdGhhdAoJCQkvLyB0aGUgb2JqZWN0IHdhcyBkaXNwb3NlZC4gRGlzcG9zZSBzaG91bGQgYmUgY2FsbGVkCgkJCS8vIG9ubHkgb25jZS4KCQkJbXJCSGVscGVyLmJEaXNwb3NlZCA9IHNhbF9UcnVlOwoJCQltckJIZWxwZXIuYkluRGlzcG9zZSA9IHNhbF9GYWxzZTsKCQkJdGhyb3cgZTsKCQl9CgoJCS8vIHRoZSB2YWx1ZXMgYkRpc3Bvc2UgYW5kIGJJbkRpc3Bvc2luZyBtdXN0IHNldCBpbiB0aGlzIG9yZGVyLgoJCS8vIE5vIG11bHRpdGhyZWFkIGNhbGwgb3ZlcmNvbWUgdGhlICIhckJIZWxwZXIuYkRpc3Bvc2VkICYmICFyQkhlbHBlci5iSW5EaXNwb3NlIiBndWFyZC4KCQltckJIZWxwZXIuYkRpc3Bvc2VkID0gc2FsX1RydWU7CgkJbXJCSGVscGVyLmJJbkRpc3Bvc2UgPSBzYWxfRmFsc2U7Cgl9Cgp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OmFkZEV2ZW50TGlzdGVuZXIoIGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpYRXZlbnRMaXN0ZW5lciA+JiBhTGlzdGVuZXIgKSB0aHJvdyg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggbXBNb2RlbCA9PSAwICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCW1yQkhlbHBlci5hZGRMaXN0ZW5lciggOjpnZXRDcHB1VHlwZSggJmFMaXN0ZW5lciApICwgYUxpc3RlbmVyICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6cmVtb3ZlRXZlbnRMaXN0ZW5lciggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OlhFdmVudExpc3RlbmVyID4mIGFMaXN0ZW5lciApIHRocm93KDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmKCBtcE1vZGVsID09IDAgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJbXJCSGVscGVyLnJlbW92ZUxpc3RlbmVyKCA6OmdldENwcHVUeXBlKCAmYUxpc3RlbmVyICkgLCBhTGlzdGVuZXIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNmeExpc3RlbmVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTdnhEcmF3UGFnZTo6Tm90aWZ5KCBTZnhCcm9hZGNhc3RlciYsIGNvbnN0IFNmeEhpbnQmIC8qckhpbnQqLyApCnsKLyoKICAgIGlmKCBtcE1vZGVsICkKCXsKCQljb25zdCBTZHJIaW50KiBwU2RySGludCA9IFBUUl9DQVNUKCBTZHJIaW50LCAmckhpbnQgKTsKCQlpZiggcFNkckhpbnQgKQoJCXsKCQkJc3dpdGNoKCBwU2RySGludC0+R2V0S2luZCgpICkKCQkJewoJCQljYXNlIEhJTlRfTU9ERUxDTEVBUkVEOgoJCQkJZGlzcG9zZSgpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlicmVhazsKCQkJfQoJCX0KCX0KKi8KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIDo6Y29tOjpzdW46OnN0YXI6OmRyYXdpbmc6OlhTaGFwZXMKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIFN2eERyYXdQYWdlOjphZGQoIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiYgeFNoYXBlICkKCXRocm93KCB1bm86OlJ1bnRpbWVFeGNlcHRpb24gKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYgKCAoIG1wTW9kZWwgPT0gTlVMTCApIHx8ICggbXBQYWdlID09IE5VTEwgKSApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCglTdnhTaGFwZSogcFNoYXBlID0gU3Z4U2hhcGU6OmdldEltcGxlbWVudGF0aW9uKCB4U2hhcGUgKTsKCglpZiggTlVMTCA9PSBwU2hhcGUgKQoJCXJldHVybjsKCglTZHJPYmplY3QgKnBPYmogPSBwU2hhcGUtPkdldFNkck9iamVjdCgpOwoKCWlmKCFwT2JqKQoJewoJCXBPYmogPSBDcmVhdGVTZHJPYmplY3QoIHhTaGFwZSApOwogICAgICAgIEVOU1VSRV9PUl9SRVRVUk5fVk9JRCggcE9iaiAhPSBOVUxMLCAiU3Z4RHJhd1BhZ2U6OmFkZDogbm8gU2RyT2JqZWN0IHdhcyBjcmVhdGVkISIgKTsKCX0KCWVsc2UgaWYgKCAhcE9iai0+SXNJbnNlcnRlZCgpICkKCXsKCQlwT2JqLT5TZXRNb2RlbChtcE1vZGVsKTsKCQltcFBhZ2UtPkluc2VydE9iamVjdCggcE9iaiApOwoJfQoKCXBTaGFwZS0+Q3JlYXRlKCBwT2JqLCB0aGlzICk7CiAgICBPU0xfRU5TVVJFKCBwU2hhcGUtPkdldFNkck9iamVjdCgpID09IHBPYmosICJTdnhEcmF3UGFnZTo6YWRkOiBzaGFwZSBkb2VzIG5vdCBrbm93IGFib3V0IGl0cyBuZXdseSBjcmVhdGVkIFNkck9iamVjdCEiICk7CgoJbXBNb2RlbC0+U2V0Q2hhbmdlZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6cmVtb3ZlKCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+JiB4U2hhcGUgKQoJdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggKG1wTW9kZWwgPT0gMCkgfHwgKG1wUGFnZSA9PSAwKSApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCglTdnhTaGFwZSogcFNoYXBlID0gU3Z4U2hhcGU6OmdldEltcGxlbWVudGF0aW9uKCB4U2hhcGUgKTsKCglpZihwU2hhcGUpCgl7CgkJU2RyT2JqZWN0KglwT2JqID0gcFNoYXBlLT5HZXRTZHJPYmplY3QoKTsKCQlpZihwT2JqKQoJCXsKCQkJLy8gU2RyT2JqZWN0IGF1cyBkZXIgUGFnZSBsb2VzY2hlbgoJCQlzYWxfdUludDMyIG5Db3VudCA9IG1wUGFnZS0+R2V0T2JqQ291bnQoKTsKCQkJZm9yKCBzYWxfdUludDMyIG5OdW0gPSAwOyBuTnVtIDwgbkNvdW50OyBuTnVtKysgKQoJCQl7CgkJCQlpZihtcFBhZ2UtPkdldE9iaihuTnVtKSA9PSBwT2JqKQoJCQkJewogICAgICAgICAgICAgICAgICAgIE9TTF9WRVJJRlkoIG1wUGFnZS0+UmVtb3ZlT2JqZWN0KCBuTnVtICkgPT0gcE9iaiApOwoJCQkJCVNkck9iamVjdDo6RnJlZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJfQoKCWlmKCBtcE1vZGVsICkKCQltcE1vZGVsLT5TZXRDaGFuZ2VkKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI6OlhJbmRleEFjY2VzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnNhbF9JbnQzMiBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6Z2V0Q291bnQoKQoJdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggKG1wTW9kZWwgPT0gMCkgfHwgKG1wUGFnZSA9PSAwKSApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCglyZXR1cm4oIChzYWxfSW50MzIpIG1wUGFnZS0+R2V0T2JqQ291bnQoKSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdW5vOjpBbnkgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OmdldEJ5SW5kZXgoIHNhbF9JbnQzMiBJbmRleCApCgl0aHJvdyggbGFuZzo6SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiwgbGFuZzo6V3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgdW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYoIChtcE1vZGVsID09IDApIHx8IChtcFBhZ2UgPT0gMCkgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJaWYgKCBJbmRleCA8IDAgfHwgSW5kZXggPj0gKHNhbF9JbnQzMiltcFBhZ2UtPkdldE9iakNvdW50KCkgKQoJCXRocm93IGxhbmc6OkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKCglTZHJPYmplY3QqIHBPYmogPSBtcFBhZ2UtPkdldE9iaiggSW5kZXggKTsKCWlmKCBwT2JqID09IE5VTEwgKQoJCXRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbigpOwoKCglyZXR1cm4gbWFrZUFueShSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+KCBwT2JqLT5nZXRVbm9TaGFwZSgpLCB1bm86OlVOT19RVUVSWSApKTsKfQoKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI6OlhFbGVtZW50QWNjZXNzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdW5vOjpUeXBlIFNBTF9DQUxMIFN2eERyYXdQYWdlOjpnZXRFbGVtZW50VHlwZSgpCgl0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJcmV0dXJuIElOVEVSRkFDRV9UWVBFKCBkcmF3aW5nOjpYU2hhcGUgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIFNBTF9DQUxMIFN2eERyYXdQYWdlOjpoYXNFbGVtZW50cygpCgl0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmKCAobXBNb2RlbCA9PSAwKSB8fCAobXBQYWdlID09IDApICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCXJldHVybiBtcFBhZ2UgJiYgbXBQYWdlLT5HZXRPYmpDb3VudCgpPjA7Cn0KCm5hbWVzcGFjZQp7CiAgICB2b2lkIGxjbF9tYXJrU2RyT2JqZWN0T2ZTaGFwZSggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiYgX3J4U2hhcGUsIFNkclZpZXcmIF9yVmlldywgU2RyUGFnZVZpZXcmIF9yUGFnZVZpZXcgKQogICAgewoJCVN2eFNoYXBlKiBwU2hhcGUgPSBTdnhTaGFwZTo6Z2V0SW1wbGVtZW50YXRpb24oIF9yeFNoYXBlICk7CiAgICAgICAgaWYgKCAhcFNoYXBlICkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBTZHJPYmplY3QqIHBPYmogPSBwU2hhcGUtPkdldFNkck9iamVjdCgpOwogICAgICAgIGlmICggIXBPYmogKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIF9yVmlldy5NYXJrT2JqKCBwT2JqLCAmX3JQYWdlVmlldyApOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQUNIVFVORzogX1NlbGVjdE9iamVjdHNJblZpZXcgc2VsZWt0aWVydCBkaWUgOjpjb206OnN1bjo6c3Rhcjo6ZHJhd2luZzo6U2hhcGVzIG51ciBpbiBkZXIgYW5nZWdlYmVubmVuCi8vICAgICAgICAgU2RyUGFnZVZpZXcuIERpZXMgbXXfIG5pY2h0IGRpZSBzaWNodGJhcmUgU2RyUGFnZVZpZXcgc2Vpbi4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU3Z4RHJhd1BhZ2U6Ol9TZWxlY3RPYmplY3RzSW5WaWV3KCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZXMgPiAmIGFTaGFwZXMsIFNkclBhZ2VWaWV3KiBwUGFnZVZpZXcgKSB0aHJvdyAoKQp7CglEQkdfQVNTRVJUKHBQYWdlVmlldywiU2RyUGFnZVZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCURCR19BU1NFUlQobXBWaWV3LCAiU2RyVmlldyBpc3QgTlVMTCEgW0NMXSIpOwoKCWlmKHBQYWdlVmlldyE9TlVMTCAmJiBtcFZpZXchPU5VTEwpCgl7CgkJbXBWaWV3LT5Vbm1hcmtBbGxPYmooIHBQYWdlVmlldyApOwoKCQlsb25nIG5Db3VudCA9IGFTaGFwZXMtPmdldENvdW50KCk7CgkJZm9yKCBsb25nIGkgPSAwOyBpIDwgbkNvdW50OyBpKysgKQoJCXsKCQkJdW5vOjpBbnkgYUFueSggYVNoYXBlcy0+Z2V0QnlJbmRleChpKSApOwoJCQlSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+IHhTaGFwZTsKCQkJaWYoIGFBbnkgPj49IHhTaGFwZSApCiAgICAgICAgICAgICAgICBsY2xfbWFya1Nkck9iamVjdE9mU2hhcGUoIHhTaGFwZSwgKm1wVmlldywgKnBQYWdlVmlldyApOwoJCX0KCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEFDSFRVTkc6IF9TZWxlY3RPYmplY3RJblZpZXcgc2VsZWt0aWVydCBkYXMgU2hhcGUgKm51ciogaW4gZGVyIGFuZ2VnZWJlbm5lbgovLyAgICAgICAgIFNkclBhZ2VWaWV3LiBEaWVzIG113yBuaWNodCBkaWUgc2ljaHRiYXJlIFNkclBhZ2VWaWV3IHNlaW4uCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFN2eERyYXdQYWdlOjpfU2VsZWN0T2JqZWN0SW5WaWV3KCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+ICYgeFNoYXBlLCBTZHJQYWdlVmlldyogcFBhZ2VWaWV3ICkgdGhyb3coKQp7CglEQkdfQVNTRVJUKHBQYWdlVmlldywiU2RyUGFnZVZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCURCR19BU1NFUlQobXBWaWV3LCAiU2RyVmlldyBpc3QgTlVMTCEgW0NMXSIpOwoKCWlmKHBQYWdlVmlldyE9TlVMTCAmJiBtcFZpZXcgIT0gTlVMTCkKCXsKCQltcFZpZXctPlVubWFya0FsbE9iaiggcFBhZ2VWaWV3ICk7CiAgICAgICAgbGNsX21hcmtTZHJPYmplY3RPZlNoYXBlKCB4U2hhcGUsICptcFZpZXcsICpwUGFnZVZpZXcgKTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlR3JvdXAgPiBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6Z3JvdXAoIGNvbnN0IFJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlcyA+JiB4U2hhcGVzICkKCXRocm93KCB1bm86OlJ1bnRpbWVFeGNlcHRpb24gKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYoIChtcE1vZGVsID09IDApIHx8IChtcFBhZ2UgPT0gMCkgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJREJHX0FTU0VSVChtcFBhZ2UsIlNkclBhZ2UgaXN0IE5VTEwhIFtDTF0iKTsKCURCR19BU1NFUlQobXBWaWV3LCAiU2RyVmlldyBpc3QgTlVMTCEgW0NMXSIpOwoKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZHJhd2luZzo6WFNoYXBlR3JvdXAgPiAgeFNoYXBlR3JvdXA7CglpZihtcFBhZ2U9PU5VTEx8fG1wVmlldz09TlVMTHx8IXhTaGFwZXMuaXMoKSkKCQlyZXR1cm4geFNoYXBlR3JvdXA7CgoJU2RyUGFnZVZpZXcqIHBQYWdlVmlldyA9IG1wVmlldy0+U2hvd1NkclBhZ2UoIG1wUGFnZSApOwoKCV9TZWxlY3RPYmplY3RzSW5WaWV3KCB4U2hhcGVzLCBwUGFnZVZpZXcgKTsKCgltcFZpZXctPkdyb3VwTWFya2VkKCk7CgoJbXBWaWV3LT5BZGp1c3RNYXJrSGRsKCk7Cgljb25zdCBTZHJNYXJrTGlzdCYgck1hcmtMaXN0ID0gbXBWaWV3LT5HZXRNYXJrZWRPYmplY3RMaXN0KCk7CglpZiggck1hcmtMaXN0LkdldE1hcmtDb3VudCgpID09IDEgKQoJewoJCVNkck9iamVjdCogcE9iaiA9IHJNYXJrTGlzdC5HZXRNYXJrKDApLT5HZXRNYXJrZWRTZHJPYmooKTsKCQlpZiggcE9iaiApCgkJCSB4U2hhcGVHcm91cCA9IFJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlR3JvdXAgPjo6cXVlcnkoIHBPYmotPmdldFVub1NoYXBlKCkgKTsKCX0KCgltcFZpZXctPkhpZGVTZHJQYWdlKCk7CgoJaWYoIG1wTW9kZWwgKQoJCW1wTW9kZWwtPlNldENoYW5nZWQoKTsKCglyZXR1cm4geFNoYXBlR3JvdXA7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIFN2eERyYXdQYWdlOjp1bmdyb3VwKCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZUdyb3VwID4mIGFHcm91cCApCgl0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmKCAobXBNb2RlbCA9PSAwKSB8fCAobXBQYWdlID09IDApICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCURCR19BU1NFUlQobXBQYWdlLCJTZHJQYWdlIGlzdCBOVUxMISBbQ0xdIik7CglEQkdfQVNTRVJUKG1wVmlldywgIlNkclZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCglpZihtcFBhZ2U9PU5VTEx8fG1wVmlldz09TlVMTHx8IWFHcm91cC5pcygpKQoJCXJldHVybjsKCglTZHJQYWdlVmlldyogcFBhZ2VWaWV3ID0gbXBWaWV3LT5TaG93U2RyUGFnZSggbXBQYWdlICk7CgoJUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiB4U2hhcGUoIGFHcm91cCwgVU5PX1FVRVJZICk7CglfU2VsZWN0T2JqZWN0SW5WaWV3KCB4U2hhcGUsIHBQYWdlVmlldyApOwoJbXBWaWV3LT5Vbkdyb3VwTWFya2VkKCk7CgoJbXBWaWV3LT5IaWRlU2RyUGFnZSgpOwoKCWlmKCBtcE1vZGVsICkKCQltcE1vZGVsLT5TZXRDaGFuZ2VkKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZHJPYmplY3QgKlN2eERyYXdQYWdlOjpfQ3JlYXRlU2RyT2JqZWN0KCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+ICYgeFNoYXBlICkgdGhyb3coKQp7CglzYWxfdUludDE2IG5UeXBlOwoJc2FsX3VJbnQzMiBuSW52ZW50b3I7CgoJR2V0VHlwZUFuZEludmVudG9yKCBuVHlwZSwgbkludmVudG9yLCB4U2hhcGUtPmdldFNoYXBlVHlwZSgpICk7CglTZHJPYmplY3QqIHBOZXdPYmogPSAwOwoKCWlmKCBuVHlwZSAhPSAwICkKCXsKCQlhd3Q6OlNpemUgYVNpemUgPSB4U2hhcGUtPmdldFNpemUoKTsKCQlhU2l6ZS5XaWR0aCArPSAxOwoJCWFTaXplLkhlaWdodCArPSAxOwoJCWF3dDo6UG9pbnQgYVBvcyA9IHhTaGFwZS0+Z2V0UG9zaXRpb24oKTsKCQlSZWN0YW5nbGUgYVJlY3QoIFBvaW50KCBhUG9zLlgsIGFQb3MuWSApLCBTaXplKCBhU2l6ZS5XaWR0aCwgYVNpemUuSGVpZ2h0ICkgKTsKCgkJLy8gc3BlY2lhbCBjYXNlcwoJCWlmKCBuSW52ZW50b3IgPT0gU2RySW52ZW50b3IgKQoJCXsKCQkJc3dpdGNoKCBuVHlwZSApCgkJCXsKCQkJY2FzZSBPQkpfTUVBU1VSRToKCQkJCXsKCQkJCQlwTmV3T2JqID0gbmV3IFNkck1lYXN1cmVPYmooIGFSZWN0LlRvcExlZnQoKSwgYVJlY3QuQm90dG9tUmlnaHQoKSApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlIE9CSl9MSU5FOgoJCQkJewoJCQkJCWJhc2VnZng6OkIyRFBvbHlnb24gYVBvbHk7CgkJCQkJYVBvbHkuYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KGFSZWN0LkxlZnQoKSwgYVJlY3QuVG9wKCkpKTsKCQkJCQlhUG9seS5hcHBlbmQoYmFzZWdmeDo6QjJEUG9pbnQoYVJlY3QuUmlnaHQoKSwgYVJlY3QuQm90dG9tKCkpKTsKCQkJCQlwTmV3T2JqID0gbmV3IFNkclBhdGhPYmooT0JKX0xJTkUsIGJhc2VnZng6OkIyRFBvbHlQb2x5Z29uKGFQb2x5KSk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCWlmKCBwTmV3T2JqID09IE5VTEwgKQoJCQlwTmV3T2JqID0gU2RyT2JqRmFjdG9yeTo6TWFrZU5ld09iamVjdCggbkludmVudG9yLCBuVHlwZSwgbXBQYWdlICk7CgoJCWlmKHBOZXdPYmopCgkJewoJCQlwTmV3T2JqLT5TZXRTbmFwUmVjdChhUmVjdCk7CgoJCQlpZiggcE5ld09iai0+SVNBKEUzZFBvbHlTY2VuZSkpCgkJCXsKCQkJCS8vIFN6ZW5lIGluaXRpYWxpc2llcmVuCgkJCQlFM2RTY2VuZSogcFNjZW5lID0gKEUzZFNjZW5lKilwTmV3T2JqOwoKCQkJCWRvdWJsZSBmVyA9IChkb3VibGUpYVNpemUuV2lkdGg7CgkJCQlkb3VibGUgZkggPSAoZG91YmxlKWFTaXplLkhlaWdodDsKCgkJCQlDYW1lcmEzRCBhQ2FtKHBTY2VuZS0+R2V0Q2FtZXJhKCkpOwoJCQkJYUNhbS5TZXRBdXRvQWRqdXN0UHJvamVjdGlvbihzYWxfRmFsc2UpOwoJCQkJYUNhbS5TZXRWaWV3V2luZG93KC0gZlcgLyAyLCAtIGZIIC8gMiwgZlcsIGZIKTsKCQkJCWJhc2VnZng6OkIzRFBvaW50IGFMb29rQXQ7CgkJCQliYXNlZ2Z4OjpCM0RQb2ludCBhQ2FtUG9zKDAuMCwgMC4wLCAxMDAwMC4wKTsKCQkJCWFDYW0uU2V0UG9zQW5kTG9va0F0KGFDYW1Qb3MsIGFMb29rQXQpOwoJCQkJYUNhbS5TZXRGb2NhbExlbmd0aCgxMDAuMCk7CgkJCQlhQ2FtLlNldERlZmF1bHRzKGFDYW1Qb3MsIGFMb29rQXQsIDEwMDAwLjApOwoJCQkJcFNjZW5lLT5TZXRDYW1lcmEoYUNhbSk7CgoJCQkJcFNjZW5lLT5TZXRSZWN0c0RpcnR5KCk7CgkJCX0KCQkJZWxzZSBpZihwTmV3T2JqLT5JU0EoRTNkRXh0cnVkZU9iaikpCgkJCXsKCQkJCUUzZEV4dHJ1ZGVPYmoqIHBPYmogPSAoRTNkRXh0cnVkZU9iaiopcE5ld09iajsKCQkJCWJhc2VnZng6OkIyRFBvbHlnb24gYU5ld1BvbHlnb247CgkJCQlhTmV3UG9seWdvbi5hcHBlbmQoYmFzZWdmeDo6QjJEUG9pbnQoMC4wLCAwLjApKTsKCQkJCWFOZXdQb2x5Z29uLmFwcGVuZChiYXNlZ2Z4OjpCMkRQb2ludCgwLjAsIDEuMCkpOwoJCQkJYU5ld1BvbHlnb24uYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KDEuMCwgMC4wKSk7CgkJCQlhTmV3UG9seWdvbi5zZXRDbG9zZWQodHJ1ZSk7CgkJCQlwT2JqLT5TZXRFeHRydWRlUG9seWdvbihiYXNlZ2Z4OjpCMkRQb2x5UG9seWdvbihhTmV3UG9seWdvbikpOwoKCQkJCS8vICMxMDcyNDUjIHBPYmotPlNldEV4dHJ1ZGVDaGFyYWN0ZXJNb2RlKHNhbF9UcnVlKTsKCQkJCXBPYmotPlNldE1lcmdlZEl0ZW0oU3Z4M0RDaGFyYWN0ZXJNb2RlSXRlbShzYWxfVHJ1ZSkpOwoJCQl9CgkJCWVsc2UgaWYocE5ld09iai0+SVNBKEUzZExhdGhlT2JqKSkKCQkJewoJCQkJRTNkTGF0aGVPYmoqIHBPYmogPSAoRTNkTGF0aGVPYmoqKXBOZXdPYmo7CgkJCQliYXNlZ2Z4OjpCMkRQb2x5Z29uIGFOZXdQb2x5Z29uOwoJCQkJYU5ld1BvbHlnb24uYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KDAuMCwgMC4wKSk7CgkJCQlhTmV3UG9seWdvbi5hcHBlbmQoYmFzZWdmeDo6QjJEUG9pbnQoMC4wLCAxLjApKTsKCQkJCWFOZXdQb2x5Z29uLmFwcGVuZChiYXNlZ2Z4OjpCMkRQb2ludCgxLjAsIDAuMCkpOwoJCQkJYU5ld1BvbHlnb24uc2V0Q2xvc2VkKHRydWUpOwoJCQkJcE9iai0+U2V0UG9seVBvbHkyRChiYXNlZ2Z4OjpCMkRQb2x5UG9seWdvbihhTmV3UG9seWdvbikpOwoKCQkJCS8vICMxMDcyNDUjIHBPYmotPlNldExhdGhlQ2hhcmFjdGVyTW9kZShzYWxfVHJ1ZSk7CgkJCQlwT2JqLT5TZXRNZXJnZWRJdGVtKFN2eDNEQ2hhcmFjdGVyTW9kZUl0ZW0oc2FsX1RydWUpKTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gcE5ld09iajsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU3Z4RHJhd1BhZ2U6OkdldFR5cGVBbmRJbnZlbnRvciggc2FsX3VJbnQxNiYgclR5cGUsIHNhbF91SW50MzImIHJJbnZlbnRvciwgY29uc3QgT1VTdHJpbmcmIGFOYW1lICkgY29uc3QgdGhyb3coKQp7CglzYWxfdUludDMyIG5UZW1wVHlwZSA9IGFTZHJTaGFwZUlkZW50aWZpZXJNYXAuZ2V0SWQoIGFOYW1lICk7CgoJaWYoIG5UZW1wVHlwZSA9PSBVSEFTSE1BUF9OT1RGT1VORCApCgl7CgkJaWYoIGFOYW1lLmVxdWFsc0FzY2lpTChSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiY29tLnN1bi5zdGFyLmRyYXdpbmcuVGFibGVTaGFwZSIpKSB8fAoJCQlhTmFtZS5lcXVhbHNBc2NpaUwoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci5wcmVzZW50YXRpb24uVGFibGVTaGFwZSIpKSApCgkJewoJCQlySW52ZW50b3IgPSBTZHJJbnZlbnRvcjsKCQkJclR5cGUgPSBPQkpfVEFCTEU7CgkJfQoJCWVsc2UgaWYoIGFOYW1lLmVxdWFsc0FzY2lpTChSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiY29tLnN1bi5zdGFyLnByZXNlbnRhdGlvbi5NZWRpYVNoYXBlIiApKSApCgkJewoJCQlySW52ZW50b3IgPSBTZHJJbnZlbnRvcjsKCQkJclR5cGUgPSBPQkpfTUVESUE7CgkJfQoJfQoJZWxzZSBpZihuVGVtcFR5cGUgJiBFM0RfSU5WRU5UT1JfRkxBRykKCXsKCQlySW52ZW50b3IgPSBFM2RJbnZlbnRvcjsKCQlyVHlwZSA9IChzYWxfdUludDE2KShuVGVtcFR5cGUgJiB+RTNEX0lOVkVOVE9SX0ZMQUcpOwoJfQoJZWxzZQoJewoJCXJJbnZlbnRvciA9IFNkckludmVudG9yOwoJCXJUeXBlID0gKHNhbF91SW50MTYpblRlbXBUeXBlOwoKCQlzd2l0Y2goIHJUeXBlICkKCQl7CgkJCWNhc2UgT0JKX0ZSQU1FOgoJCQljYXNlIE9CSl9PTEUyX1BMVUdJTjoKCQkJY2FzZSBPQkpfT0xFMl9BUFBMRVQ6CgkJCQlyVHlwZSA9IE9CSl9PTEUyOwoJCQkJYnJlYWs7CgkJfQoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU3Z4U2hhcGUqIFN2eERyYXdQYWdlOjpDcmVhdGVTaGFwZUJ5VHlwZUFuZEludmVudG9yKCBzYWxfdUludDE2IG5UeXBlLCBzYWxfdUludDMyIG5JbnZlbnRvciwgU2RyT2JqZWN0ICpwT2JqLCBTdnhEcmF3UGFnZSAqbXBQYWdlICkgdGhyb3coKQp7CglTdnhTaGFwZSogcFJldCA9IE5VTEw7Cglzd2l0Y2goIG5JbnZlbnRvciApCgl7CgkJY2FzZSBFM2RJbnZlbnRvcjoKCQl7CgkJCXN3aXRjaCggblR5cGUgKQoJCQl7CgkJCQljYXNlIEUzRF9TQ0VORV9JRCA6CgkJCQljYXNlIEUzRF9QT0xZU0NFTkVfSUQgOgoJCQkJCXBSZXQgPSBuZXcgU3Z4M0RTY2VuZU9iamVjdCggcE9iaiwgbXBQYWdlICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEUzRF9DVUJFT0JKX0lEIDoKCQkJCQlwUmV0ID0gbmV3IFN2eDNEQ3ViZU9iamVjdCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFM0RfU1BIRVJFT0JKX0lEIDoKCQkJCQlwUmV0ID0gbmV3IFN2eDNEU3BoZXJlT2JqZWN0KCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEUzRF9MQVRIRU9CSl9JRCA6CgkJCQkJcFJldCA9IG5ldyBTdngzRExhdGhlT2JqZWN0KCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEUzRF9FWFRSVURFT0JKX0lEIDoKCQkJCQlwUmV0ID0gbmV3IFN2eDNERXh0cnVkZU9iamVjdCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFM0RfUE9MWUdPTk9CSl9JRCA6CgkJCQkJcFJldCA9IG5ldyBTdngzRFBvbHlnb25PYmplY3QoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6IC8vIHVuYmVrYW5udGVzIDNELU9iamVrdCBhdWYgZGVyIFBhZ2UKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7CgkJfQoJCWNhc2UgU2RySW52ZW50b3I6CgkJewoJCQlzd2l0Y2goIG5UeXBlICkKCQkJewovLwkJCQljYXNlIE9CSl9OT05FOgovLwkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9HUlVQOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVHcm91cCggcE9iaiwgbXBQYWdlICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9MSU5FOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbiggcE9iaiAsIFBvbHlnb25LaW5kX0xJTkUgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1JFQ1Q6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVJlY3QoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0NJUkM6CgkJCQljYXNlIE9CSl9TRUNUOgoJCQkJY2FzZSBPQkpfQ0FSQzoKCQkJCWNhc2UgT0JKX0NDVVQ6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZUNpcmNsZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfUE9MWToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb24oIHBPYmogLCBQb2x5Z29uS2luZF9QT0xZICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9QTElOOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbiggcE9iaiAsIFBvbHlnb25LaW5kX1BMSU4gKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1NQTE5MSU5FOgoJCQkJY2FzZSBPQkpfUEFUSExJTkU6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uQmV6aWVyKCBwT2JqICwgUG9seWdvbktpbmRfUEFUSExJTkUgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1NQTE5GSUxMOgoJCQkJY2FzZSBPQkpfUEFUSEZJTEw6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uQmV6aWVyKCBwT2JqICwgUG9seWdvbktpbmRfUEFUSEZJTEwgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0ZSRUVMSU5FOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbkJlemllciggcE9iaiAsIFBvbHlnb25LaW5kX0ZSRUVMSU5FICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9GUkVFRklMTDoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb25CZXppZXIoIHBPYmogLCBQb2x5Z29uS2luZF9GUkVFRklMTCApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfQ0FQVElPTjoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlQ2FwdGlvbiggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfVElUTEVURVhUOgoJCQkJY2FzZSBPQkpfT1VUTElORVRFWFQ6CgkJCQljYXNlIE9CSl9URVhUOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVUZXh0KCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9HUkFGOgoJCQkJCXBSZXQgPSBuZXcgU3Z4R3JhcGhpY09iamVjdCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfRlJBTUU6CgkJCQkJcFJldCA9IG5ldyBTdnhGcmFtZVNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9PTEUyX0FQUExFVDoKCQkJCQlwUmV0ID0gbmV3IFN2eEFwcGxldFNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9PTEUyX1BMVUdJTjoKCQkJCQlwUmV0ID0gbmV3IFN2eFBsdWdpblNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQkgY2FzZSBPQkpfT0xFMjoKCQkJCQkgewoJCQkJCQlpZiggcE9iaiAmJiAhcE9iai0+SXNFbXB0eVByZXNPYmooKSAmJiBtcFBhZ2UgKQoJCQkJCQl7CgkJCQkJCQlTZHJQYWdlKiBwU2RyUGFnZSA9IG1wUGFnZS0+R2V0U2RyUGFnZSgpOwoJCQkJCQkJaWYoIHBTZHJQYWdlICkKCQkJCQkJCXsKCQkJCQkJCQlTZHJNb2RlbCogcFNkck1vZGVsID0gcFNkclBhZ2UtPkdldE1vZGVsKCk7CgkJCQkJCQkJaWYoIHBTZHJNb2RlbCApCgkJCQkJCQkJewoJCQkJCQkJCQk6OmNvbXBoZWxwZXI6OklFbWJlZGRlZEhlbHBlciAqcFBlcnNpc3QgPSBwU2RyTW9kZWwtPkdldFBlcnNpc3QoKTsKCQkJCQkJCQkJaWYoIHBQZXJzaXN0ICkKCQkJCQkJCQkJewoJCQkJCQkJCQkJdW5vOjpSZWZlcmVuY2UgPCBlbWJlZDo6WEVtYmVkZGVkT2JqZWN0ID4geE9iamVjdCA9IHBQZXJzaXN0LT5nZXRFbWJlZGRlZE9iamVjdENvbnRhaW5lcigpLgoJCQkJCQkJCQkJCQlHZXRFbWJlZGRlZE9iamVjdCggc3RhdGljX2Nhc3Q8IFNkck9sZTJPYmoqID4oIHBPYmogKS0+R2V0UGVyc2lzdE5hbWUoKSApOwoKCQkJCQkJCQkJCS8vIFRPRE8gQ0wtPktBOiBXaHkgaXMgdGhpcyBub3Qgd29ya2luZyBhbnltb3JlPwoJCQkJCQkJCQkJaWYoIHhPYmplY3QuaXMoKSApCgkJCQkJCQkJCQl7CgkJCQkJCQkJCQkJU3ZHbG9iYWxOYW1lIGFDbGFzc0lkKCB4T2JqZWN0LT5nZXRDbGFzc0lEKCkgKTsKCgkJCQkJCQkJCQkJY29uc3QgU3ZHbG9iYWxOYW1lIGFBcHBsZXRDbGFzc0lkKCBTTzNfQVBQTEVUX0NMQVNTSUQgKTsKCQkJCQkJCQkJCQljb25zdCBTdkdsb2JhbE5hbWUgYVBsdWdpbkNsYXNzSWQoIFNPM19QTFVHSU5fQ0xBU1NJRCApOwoJCQkJCQkJCQkJCWNvbnN0IFN2R2xvYmFsTmFtZSBhSUZyYW1lQ2xhc3NJZCggU08zX0lGUkFNRV9DTEFTU0lEICk7CgoJCQkJCQkJCQkJCWlmKCBhUGx1Z2luQ2xhc3NJZCA9PSBhQ2xhc3NJZCApCgkJCQkJCQkJCQkJewoJCQkJCQkJCQkJCQlwUmV0ID0gbmV3IFN2eFBsdWdpblNoYXBlKCBwT2JqICk7CgkJCQkJCQkJCQkJCW5UeXBlID0gT0JKX09MRTJfUExVR0lOOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCQllbHNlIGlmKCBhQXBwbGV0Q2xhc3NJZCA9PSBhQ2xhc3NJZCApCgkJCQkJCQkJCQkJewoJCQkJCQkJCQkJCQlwUmV0ID0gbmV3IFN2eEFwcGxldFNoYXBlKCBwT2JqICk7CgkJCQkJCQkJCQkJCW5UeXBlID0gT0JKX09MRTJfQVBQTEVUOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCQllbHNlIGlmKCBhSUZyYW1lQ2xhc3NJZCA9PSBhQ2xhc3NJZCApCgkJCQkJCQkJCQkJewoJCQkJCQkJCQkJCQlwUmV0ID0gbmV3IFN2eEZyYW1lU2hhcGUoIHBPYmogKTsKCQkJCQkJCQkJCQkJblR5cGUgPSBPQkpfRlJBTUU7CgkJCQkJCQkJCQkJfQoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWlmKCBwUmV0ID09IE5VTEwgKQoJCQkJCQl7CgkJCQkJCQlwUmV0ID0gbmV3IFN2eE9sZTJTaGFwZSggcE9iaiwgYVN2eE1hcFByb3ZpZGVyLkdldE1hcChTVlhNQVBfT0xFMiksICBhU3Z4TWFwUHJvdmlkZXIuR2V0UHJvcGVydHlTZXQoU1ZYTUFQX09MRTIsIFNkck9iamVjdDo6R2V0R2xvYmFsRHJhd09iamVjdEl0ZW1Qb29sKCkpICk7CgkJCQkJCX0KCQkJCQkgfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfRURHRToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlQ29ubmVjdG9yKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9QQVRIUE9MWToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb24oIHBPYmogLCBQb2x5Z29uS2luZF9QQVRIUE9MWSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfUEFUSFBMSU46CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uKCBwT2JqICwgUG9seWdvbktpbmRfUEFUSFBMSU4gKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1BBR0U6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZSggcE9iaiwgYVN2eE1hcFByb3ZpZGVyLkdldE1hcChTVlhNQVBfUEFHRSksICBhU3Z4TWFwUHJvdmlkZXIuR2V0UHJvcGVydHlTZXQoU1ZYTUFQX1BBR0UsIFNkck9iamVjdDo6R2V0R2xvYmFsRHJhd09iamVjdEl0ZW1Qb29sKCkpICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9NRUFTVVJFOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVEaW1lbnNpb25pbmcoIHBPYmogKTsKCQkJCQlicmVhazsKLy8JCQkJY2FzZSBPQkpfRFVNTVk6Ci8vCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1VOTzoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlQ29udHJvbCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfQ1VTVE9NU0hBUEU6CgkJCQkJcFJldCA9IG5ldyBTdnhDdXN0b21TaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfTUVESUE6CgkJCQkJcFJldCA9IG5ldyBTdnhNZWRpYVNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9UQUJMRToKCQkJCQlwUmV0ID0gbmV3IFN2eFRhYmxlU2hhcGUoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6IC8vIHVuYmVrYW5udGVzIDJELU9iamVrdCBhdWYgZGVyIFBhZ2UKCQkJCQlEQkdfRVJST1IoIk5pY2h0IGltcGxlbWVudGllcnRlciBTdGFyb25lLVNoYXBlIGVyemV1Z3QhIFtDTF0iKTsKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlVGV4dCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQl9CgkJCWJyZWFrOwoJCX0KCQlkZWZhdWx0OiAvLyBVbmJla2FubnRlciBJbnZlbnRvcgoJCXsKCQkJREJHX0VSUk9SKCJBVzogVW5rbm93biBJbnZlbnRvciBpbiBTdnhEcmF3UGFnZTo6X0NyZWF0ZVNoYXBlKCkiKTsKCQkJYnJlYWs7CgkJfQoJfQoKCWlmKHBSZXQpCgl7CgkJc2FsX3VJbnQzMiBuT2JqSWQgPSBuVHlwZTsKCgkJaWYoIG5JbnZlbnRvciA9PSBFM2RJbnZlbnRvciApCgkJCW5PYmpJZCB8PSBFM0RfSU5WRU5UT1JfRkxBRzsKCgkJc3dpdGNoKG5PYmpJZCkKCQl7CgkJY2FzZSBPQkpfQ0NVVDoJCQkvLyBLcmVpc2Fic2Nobml0dAoJCWNhc2UgT0JKX0NBUkM6CQkJLy8gS3JlaXNib2dlbgoJCWNhc2UgT0JKX1NFQ1Q6CQkJLy8gS3JlaXNzZWt0b3IKCQkJbk9iaklkID0gT0JKX0NJUkM7CgkJCWJyZWFrOwoKCQljYXNlIEUzRF9TQ0VORV9JRCB8IEUzRF9JTlZFTlRPUl9GTEFHOgoJCQluT2JqSWQgPSBFM0RfUE9MWVNDRU5FX0lEIHwgRTNEX0lOVkVOVE9SX0ZMQUc7CgkJCWJyZWFrOwoKCQljYXNlIE9CSl9USVRMRVRFWFQ6CgkJY2FzZSBPQkpfT1VUTElORVRFWFQ6CgkJCW5PYmpJZCA9IE9CSl9URVhUOwoJCQlicmVhazsKCQl9CgoJCXBSZXQtPnNldFNoYXBlS2luZChuT2JqSWQpOwoJfQoKCXJldHVybiBwUmV0Owp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiAgU3Z4RHJhd1BhZ2U6Ol9DcmVhdGVTaGFwZSggU2RyT2JqZWN0ICpwT2JqICkgY29uc3QgdGhyb3coKQp7CglSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZSA+IHhTaGFwZSggQ3JlYXRlU2hhcGVCeVR5cGVBbmRJbnZlbnRvcihwT2JqLT5HZXRPYmpJZGVudGlmaWVyKCksCgkJCQkJCQkJCQkJICBwT2JqLT5HZXRPYmpJbnZlbnRvcigpLAoJCQkJCQkJCQkJCSAgcE9iaiwKCQkJCQkJCQkJCQkgIChTdnhEcmF3UGFnZSopdGhpcykpOwoJcmV0dXJuIHhTaGFwZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNkck9iamVjdCAqU3Z4RHJhd1BhZ2U6OkNyZWF0ZVNkck9iamVjdCggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiAmIHhTaGFwZSApIHRocm93KCkKewoJU2RyT2JqZWN0KiBwT2JqID0gX0NyZWF0ZVNkck9iamVjdCggeFNoYXBlICk7CglpZiggcE9iaiAmJiAhcE9iai0+SXNJbnNlcnRlZCgpICkKCQltcFBhZ2UtPkluc2VydE9iamVjdCggcE9iaiApOwoKCXJldHVybiBwT2JqOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6WFNlcnZpY2VJbmZvCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPVVN0cmluZyBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6Z2V0SW1wbGVtZW50YXRpb25OYW1lKCkgdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCXJldHVybiBPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJTdnhEcmF3UGFnZSIpKTsKfQoKc2FsX0Jvb2wgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OnN1cHBvcnRzU2VydmljZSggY29uc3QgT1VTdHJpbmcmIFNlcnZpY2VOYW1lICkKCXRocm93KDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikKewoJcmV0dXJuIGNvbXBoZWxwZXI6OlNlcnZpY2VJbmZvSGVscGVyOjpzdXBwb3J0c1NlcnZpY2UoIFNlcnZpY2VOYW1lLCBnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXMoKSApOwp9Cgp1bm86OlNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIFN2eERyYXdQYWdlOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXMoKSB0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJdW5vOjpTZXF1ZW5jZTwgT1VTdHJpbmcgPiBhU2VxKCAxICk7CglhU2VxLmdldEFycmF5KClbMF0gPSBPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJjb20uc3VuLnN0YXIuZHJhd2luZy5TaGFwZUNvbGxlY3Rpb24iICkpOwoJcmV0dXJuIGFTZXE7Cn0KClN2eFNoYXBlKiBDcmVhdGVTdnhTaGFwZUJ5VHlwZUFuZEludmVudG9yKCBzYWxfdUludDE2IG5UeXBlLCBzYWxfdUludDMyIG5JbnZlbnRvciApIHRocm93KCkKewoJcmV0dXJuIFN2eERyYXdQYWdlOjpDcmVhdGVTaGFwZUJ5VHlwZUFuZEludmVudG9yKCBuVHlwZSwgbkludmVudG9yICk7Cn0KCnZvaWQgU3Z4RHJhd1BhZ2U6OkNoYW5nZU1vZGVsKCBTZHJNb2RlbCogcE5ld01vZGVsICkKewoJaWYoIHBOZXdNb2RlbCAhPSBtcE1vZGVsICkKCXsKCQlpZiggbXBNb2RlbCApCgkJCUVuZExpc3RlbmluZyggKm1wTW9kZWwgKTsKCgkJaWYoIHBOZXdNb2RlbCApCgkJCVN0YXJ0TGlzdGVuaW5nKCAqcE5ld01vZGVsICk7CgoJCW1wTW9kZWwgPSBwTmV3TW9kZWw7CgogICAgICAgIGlmKCBtcFZpZXcgKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIG1wVmlldzsKCSAgICAgICAgbXBWaWV3ID0gbmV3IFNkclZpZXcoIG1wTW9kZWwgKTsKCSAgICAgICAgaWYoIG1wVmlldyApCgkJICAgICAgICBtcFZpZXctPlNldERlc2lnbk1vZGUoc2FsX1RydWUpOwogICAgICAgIH0KCX0KfQoKLyoqIHJldHVybnMgYSBTdGFyT2ZmaWNlIEFQSSB3cmFwcGVyIGZvciB0aGUgZ2l2ZW4gU2RyUGFnZSAqLwp1bm86OlJlZmVyZW5jZTwgZHJhd2luZzo6WERyYXdQYWdlID4gR2V0WERyYXdQYWdlRm9yU2RyUGFnZSggU2RyUGFnZSogcFBhZ2UgKSB0aHJvdyAoKQp7CglpZihwUGFnZSkKCXsKCQl1bm86OlJlZmVyZW5jZTwgZHJhd2luZzo6WERyYXdQYWdlID4geERyYXdQYWdlKCBwUGFnZS0+Z2V0VW5vUGFnZSgpLCB1bm86OlVOT19RVUVSWSApOwoKCQlyZXR1cm4geERyYXdQYWdlOwoJfQoKCXJldHVybiB1bm86OlJlZmVyZW5jZTwgZHJhd2luZzo6WERyYXdQYWdlID4oKTsKfQoKLyoqIHJldHVybnMgdGhlIFNkck9iamVjdCBmcm9tIHRoZSBnaXZlbiBTdGFyT2ZmaWNlIEFQSSB3cmFwcGVyICovClNkclBhZ2UqIEdldFNkclBhZ2VGcm9tWERyYXdQYWdlKCB1bm86OlJlZmVyZW5jZTwgZHJhd2luZzo6WERyYXdQYWdlID4geERyYXdQYWdlICkgdGhyb3coKQp7CglpZih4RHJhd1BhZ2UuaXMoKSkKCXsKCQlTdnhEcmF3UGFnZSogcERyYXdQYWdlID0gU3Z4RHJhd1BhZ2U6OmdldEltcGxlbWVudGF0aW9uKCB4RHJhd1BhZ2UgKTsKCQkKCQlpZihwRHJhd1BhZ2UpCgkJewoJCQlyZXR1cm4gcERyYXdQYWdlLT5HZXRTZHJQYWdlKCk7CgkJfQoJfQoKCXJldHVybiBOVUxMOwp9CgovLyBlb2YK