LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9zdnguaHh4IgoKI2RlZmluZSBfU1ZYX1VTRV9VTk9HTE9CQUxTXwojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2RvY3VtZW50L0V2ZW50T2JqZWN0LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9sYW5nL0Rpc3Bvc2VkRXhjZXB0aW9uLmhwcD4KI2luY2x1ZGUgPHZvcy9tdXRleC5oeHg+CiNpbmNsdWRlIDxvc2wvbXV0ZXguaHh4PgojaW5jbHVkZSA8c2Z4Mi9kaXNwYXRjaC5oeHg+CiNpbmNsdWRlIDxzb3QvY2xzaWRzLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvc2VydmljZWluZm9oZWxwZXIuaHh4PgoKI2luY2x1ZGUgPHJ0bC91dWlkLmg+CiNpbmNsdWRlIDxydGwvbWVtb3J5Lmg+CiNpbmNsdWRlIDxzZngyL29ianNoLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRwb29sLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRvYmouaHh4PgojaW5jbHVkZSA8c3Z4L3N2ZG9vbGUyLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRwYWdlLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRtb2RlbC5oeHg+CiNpbmNsdWRlIDxzdngvc3Zkdmlldy5oeHg+CiNpbmNsdWRlIDxzdngvc3ZkcGFndi5oeHg+CiNpbmNsdWRlIDxzdngvdW5vcGFnZS5oeHg+CiNpbmNsdWRlICJzaGFwZWltcGwuaHh4IgojaW5jbHVkZSAic3Z4L2dsb2JsM2QuaHh4IgojaW5jbHVkZSA8c3Z4L3BvbHlzYzNkLmh4eD4KI2luY2x1ZGUgPHN2eC91bm9wcm92Lmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRvcGF0aC5oeHg+CiNpbmNsdWRlICJzdngvdW5vYXBpLmh4eCIKI2luY2x1ZGUgPHN2eC9zdmRvbWVhcy5oeHg+CiNpbmNsdWRlIDxzdngvZXh0cnVkM2QuaHh4PgojaW5jbHVkZSA8c3Z4L2xhdGhlM2QuaHh4PgojaW5jbHVkZSA8dmNsL3N2YXBwLmh4eD4KI2luY2x1ZGUgPHRvb2xzL2RpYWdub3NlX2V4Lmg+Cgp1c2luZyA6OnJ0bDo6T1VTdHJpbmc7CnVzaW5nIG5hbWVzcGFjZSA6OnZvczsKdXNpbmcgbmFtZXNwYWNlIDo6Y3BwdTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6ZHJhd2luZzsKCiNkZWZpbmUgSU5URVJGQUNFX1RZUEUoIHhpbnQgKSBcCgk6OmdldENwcHVUeXBlKChjb25zdCBSZWZlcmVuY2U8IHhpbnQgPiopMCkKCiNkZWZpbmUgUVVFUllJTlQoIHhpbnQgKSBcCglpZiggclR5cGUgPT0gOjpnZXRDcHB1VHlwZSgoY29uc3QgUmVmZXJlbmNlPCB4aW50ID4qKTApICkgXAoJCWFBbnkgPDw9IFJlZmVyZW5jZTwgeGludCA+KHRoaXMpCgpERUNMQVJFX0xJU1QoIFN2eERyYXdQYWdlTGlzdCwgU3Z4RHJhd1BhZ2UgKiApCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBjbGFzcyBTdnhEcmF3UGFnZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KClVOTzNfR0VUSU1QTEVNRU5UQVRJT05fSU1QTCggU3Z4RHJhd1BhZ2UgKTsKREJHX05BTUUoU3Z4RHJhd1BhZ2UpClN2eERyYXdQYWdlOjpTdnhEcmF3UGFnZSggU2RyUGFnZSogcEluUGFnZSApIHRocm93KCkKOiBtckJIZWxwZXIoIGdldE11dGV4KCkgKQosIG1wUGFnZSggcEluUGFnZSApCiwgbXBNb2RlbCggMCApCnsKICAgIERCR19DVE9SKFN2eERyYXdQYWdlLE5VTEwpOwoJLy8gQW0gQnJvYWRjYXN0ZXIgYW5tZWxkZW4KCWlmKCBtcFBhZ2UgKQoJCW1wTW9kZWwgPSBtcFBhZ2UtPkdldE1vZGVsKCk7CglpZiggbXBNb2RlbCApCgkJU3RhcnRMaXN0ZW5pbmcoICptcE1vZGVsICk7CgoKCS8vIEVyemV1Z2VuIGRlciAoaGlkZGVuKSA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjeDo6VmlldwoJbXBWaWV3ID0gbmV3IFNkclZpZXcoIG1wTW9kZWwgKTsKCWlmKCBtcFZpZXcgKQoJCW1wVmlldy0+U2V0RGVzaWduTW9kZShzYWxfVHJ1ZSk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBDdG9yIGZ1ZXIgU3Z4RHJhd1BhZ2VfTmV3SW5zdGFuY2UoKQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU3Z4RHJhd1BhZ2U6OlN2eERyYXdQYWdlKCkgdGhyb3coKQo6IG1yQkhlbHBlciggZ2V0TXV0ZXgoKSApCiwgbXBQYWdlKCBOVUxMICkKLCBtcE1vZGVsKCBOVUxMICkKLCBtcFZpZXcoIE5VTEwgKQp7CiAgICBEQkdfQ1RPUihTdnhEcmF3UGFnZSxOVUxMKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClN2eERyYXdQYWdlOjp+U3Z4RHJhd1BhZ2UoKSB0aHJvdygpCnsKCURCR19BU1NFUlQoIG1yQkhlbHBlci5iRGlzcG9zZWQsICJTdnhEcmF3UGFnZSBtdXN0IGJlIGRpc3Bvc2VkISIgKTsKCWlmKCAhbXJCSGVscGVyLmJEaXNwb3NlZCApCiAgICB7CiAgICAgICAgYWNxdWlyZSgpOwoJCWRpc3Bvc2UoKTsKICAgIH0KICAgIERCR19EVE9SKFN2eERyYXdQYWdlLE5VTEwpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIFhJbnRlcmZhY2UKdm9pZCBTdnhEcmF3UGFnZTo6cmVsZWFzZSgpIHRocm93KCkKewovKgoJdW5vOjpSZWZlcmVuY2U8IHVubzo6WEludGVyZmFjZSA+IHgoIHhEZWxlZ2F0b3IgKTsKCWlmICghIHguaXMoKSkKCXsKCQlpZiAob3NsX2RlY3JlbWVudEludGVybG9ja2VkQ291bnQoICZtX3JlZkNvdW50ICkgPT0gMCkKCQl7CgkJCWlmICghIG1yQkhlbHBlci5iRGlzcG9zZWQpCgkJCXsKCQkJCXVubzo6UmVmZXJlbmNlPCB1bm86OlhJbnRlcmZhY2UgPiB4SG9sZEFsaXZlKCAodW5vOjpYV2VhayopdGhpcyApOwoJCQkJLy8gRmlyc3QgZGlzcG9zZQoJCQkJdHJ5CgkJCQl7CgkJCQkJZGlzcG9zZSgpOwoJCQkJfQoJCQkJY2F0Y2goOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpFeGNlcHRpb24mKQoJCQkJewoJCQkJCS8vIHJlbGVhc2Ugc2hvdWxkIG5vdCB0aHJvdyBleGNlcHRpb25zCgkJCQl9CgoJCQkJLy8gb25seSB0aGUgYWxpdmUgcmVmIGhvbGRzIHRoZSBvYmplY3QKCQkJCU9TTF9BU1NFUlQoIG1fcmVmQ291bnQgPT0gMSApOwoJCQkJLy8gZGVzdHJveSB0aGUgb2JqZWN0IGlmIHhIb2xkQWxpdmUgZGVjcmVtZW50IHRoZSByZWZjb3VudCB0byAwCgkJCQlyZXR1cm47CgkJCX0KCQl9CgkJLy8gcmVzdG9yZSB0aGUgcmVmZXJlbmNlIGNvdW50CgkJb3NsX2luY3JlbWVudEludGVybG9ja2VkQ291bnQoICZtX3JlZkNvdW50ICk7Cgl9CiovCglPV2Vha0FnZ09iamVjdDo6cmVsZWFzZSgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClN2eERyYXdQYWdlKiBTdnhEcmF3UGFnZTo6R2V0UGFnZUZvclNkclBhZ2UoIFNkclBhZ2UqIG1wUGFnZSApIHRocm93KCkKewoJcmV0dXJuIGdldEltcGxlbWVudGF0aW9uKCBtcFBhZ2UtPmdldFVub1BhZ2UoKSApOwp9CgovLyBYQ29tcG9uZW50CnZvaWQgU3Z4RHJhd1BhZ2U6OmRpc3Bvc2luZygpIHRocm93KCkKewoJaWYoIG1wTW9kZWwgKQoJewoJCUVuZExpc3RlbmluZyggKm1wTW9kZWwgKTsKCQltcE1vZGVsID0gTlVMTDsKCX0KCglpZiggbXBWaWV3ICkKCXsKCQlkZWxldGUgbXBWaWV3OwoJCW1wVmlldyA9IE5VTEw7Cgl9CgltcFBhZ2UgPSAwOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gWENvbXBvbmVudAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3Z4RHJhd1BhZ2U6OmRpc3Bvc2UoKQoJdGhyb3coOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CglPR3VhcmQgYVNvbGFyR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCgkvLyBBbiBmcmVxdWVudGx5IHByb2dyYW1taW5nIGVycm9yIGlzIHRvIHJlbGVhc2UgdGhlIGxhc3QKCS8vIHJlZmVyZW5jZSB0byB0aGlzIG9iamVjdCBpbiB0aGUgZGlzcG9zaW5nIG1lc3NhZ2UuCgkvLyBNYWtlIGl0IHJ1YnVzdCwgaG9sZCBhIHNlbGYgUmVmZXJlbmNlLgoJdW5vOjpSZWZlcmVuY2U8IGxhbmc6OlhDb21wb25lbnQgPiB4U2VsZiggdGhpcyApOwoKCS8vIEd1YXJkIGRpc3Bvc2UgYWdhaW5zdCBtdWx0aWJsZSB0aHJlYWRpbmcKCS8vIFJlbWFyazogSXQgaXMgYW4gZXJyb3IgdG8gY2FsbCBkaXNwb3NlIG1vcmUgdGhhbiBvbmNlCglzYWxfQm9vbCBiRG9EaXNwb3NlID0gc2FsX0ZhbHNlOwoJewoJb3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbXJCSGVscGVyLnJNdXRleCApOwoJaWYoICFtckJIZWxwZXIuYkRpc3Bvc2VkICYmICFtckJIZWxwZXIuYkluRGlzcG9zZSApCgl7CgkJLy8gb25seSBvbmUgY2FsbCBnbyBpbnRvIHRoaXMgc2VjdGlvbgoJCW1yQkhlbHBlci5iSW5EaXNwb3NlID0gc2FsX1RydWU7CgkJYkRvRGlzcG9zZSA9IHNhbF9UcnVlOwoJfQoJfQoKCS8vIERvIG5vdCBob2xkIHRoZSBtdXRleCBiZWNhdXNlIHdlIGFyZSBicm9hZGNhc3RpbmcKCWlmKCBiRG9EaXNwb3NlICkKCXsKCQkvLyBDcmVhdGUgYW4gZXZlbnQgd2l0aCB0aGlzIGFzIHNlbmRlcgoJCXRyeQoJCXsKCQkJdW5vOjpSZWZlcmVuY2U8IHVubzo6WEludGVyZmFjZSA+IHhTb3VyY2UoIHVubzo6UmVmZXJlbmNlPCB1bm86OlhJbnRlcmZhY2UgPjo6cXVlcnkoIChsYW5nOjpYQ29tcG9uZW50ICopdGhpcyApICk7CgkJCTo6Y29tOjpzdW46OnN0YXI6OmRvY3VtZW50OjpFdmVudE9iamVjdCBhRXZ0OwoJCQlhRXZ0LlNvdXJjZSA9IHhTb3VyY2U7CgkJCS8vIGluZm9ybSBhbGwgbGlzdGVuZXJzIHRvIHJlbGVhc2UgdGhpcyBvYmplY3QKCQkJLy8gVGhlIGxpc3RlbmVyIGNvbnRhaW5lciBhcmUgYXV0b21hdGljYWxseSBjbGVhcmVkCgkJCW1yQkhlbHBlci5hTEMuZGlzcG9zZUFuZENsZWFyKCBhRXZ0ICk7CgkJCS8vIG5vdGlmeSBzdWJjbGFzc2VzIHRvIGRvIHRoZWlyIGRpc3Bvc2UKCQkJZGlzcG9zaW5nKCk7CgkJfQoJCWNhdGNoKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6RXhjZXB0aW9uJiBlKQoJCXsKCQkJLy8gY2F0Y2ggZXhjZXB0aW9uIGFuZCB0aHJvdyBhZ2FpbiBidXQgc2lnbmFsIHRoYXQKCQkJLy8gdGhlIG9iamVjdCB3YXMgZGlzcG9zZWQuIERpc3Bvc2Ugc2hvdWxkIGJlIGNhbGxlZAoJCQkvLyBvbmx5IG9uY2UuCgkJCW1yQkhlbHBlci5iRGlzcG9zZWQgPSBzYWxfVHJ1ZTsKCQkJbXJCSGVscGVyLmJJbkRpc3Bvc2UgPSBzYWxfRmFsc2U7CgkJCXRocm93IGU7CgkJfQoKCQkvLyB0aGUgdmFsdWVzIGJEaXNwb3NlIGFuZCBiSW5EaXNwb3NpbmcgbXVzdCBzZXQgaW4gdGhpcyBvcmRlci4KCQkvLyBObyBtdWx0aXRocmVhZCBjYWxsIG92ZXJjb21lIHRoZSAiIXJCSGVscGVyLmJEaXNwb3NlZCAmJiAhckJIZWxwZXIuYkluRGlzcG9zZSIgZ3VhcmQuCgkJbXJCSGVscGVyLmJEaXNwb3NlZCA9IHNhbF9UcnVlOwoJCW1yQkhlbHBlci5iSW5EaXNwb3NlID0gc2FsX0ZhbHNlOwoJfQoKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIFN2eERyYXdQYWdlOjphZGRFdmVudExpc3RlbmVyKCBjb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6WEV2ZW50TGlzdGVuZXIgPiYgYUxpc3RlbmVyICkgdGhyb3coOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYoIG1wTW9kZWwgPT0gMCApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCgltckJIZWxwZXIuYWRkTGlzdGVuZXIoIDo6Z2V0Q3BwdVR5cGUoICZhTGlzdGVuZXIgKSAsIGFMaXN0ZW5lciApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OnJlbW92ZUV2ZW50TGlzdGVuZXIoIGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpYRXZlbnRMaXN0ZW5lciA+JiBhTGlzdGVuZXIgKSB0aHJvdyg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggbXBNb2RlbCA9PSAwICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCW1yQkhlbHBlci5yZW1vdmVMaXN0ZW5lciggOjpnZXRDcHB1VHlwZSggJmFMaXN0ZW5lciApICwgYUxpc3RlbmVyICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTZnhMaXN0ZW5lcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3Z4RHJhd1BhZ2U6Ok5vdGlmeSggU2Z4QnJvYWRjYXN0ZXImLCBjb25zdCBTZnhIaW50JiAvKnJIaW50Ki8gKQp7Ci8qCiAgICBpZiggbXBNb2RlbCApCgl7CgkJY29uc3QgU2RySGludCogcFNkckhpbnQgPSBQVFJfQ0FTVCggU2RySGludCwgJnJIaW50ICk7CgkJaWYoIHBTZHJIaW50ICkKCQl7CgkJCXN3aXRjaCggcFNkckhpbnQtPkdldEtpbmQoKSApCgkJCXsKCQkJY2FzZSBISU5UX01PREVMQ0xFQVJFRDoKCQkJCWRpc3Bvc2UoKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CiovCn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyA6OmNvbTo6c3VuOjpzdGFyOjpkcmF3aW5nOjpYU2hhcGVzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6YWRkKCBjb25zdCB1bm86OlJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlID4mIHhTaGFwZSApCgl0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmICggKCBtcE1vZGVsID09IE5VTEwgKSB8fCAoIG1wUGFnZSA9PSBOVUxMICkgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJU3Z4U2hhcGUqIHBTaGFwZSA9IFN2eFNoYXBlOjpnZXRJbXBsZW1lbnRhdGlvbiggeFNoYXBlICk7CgoJaWYoIE5VTEwgPT0gcFNoYXBlICkKCQlyZXR1cm47CgoJU2RyT2JqZWN0ICpwT2JqID0gcFNoYXBlLT5HZXRTZHJPYmplY3QoKTsKCglpZighcE9iaikKCXsKCQlwT2JqID0gQ3JlYXRlU2RyT2JqZWN0KCB4U2hhcGUgKTsKICAgICAgICBFTlNVUkVfT1JfUkVUVVJOX1ZPSUQoIHBPYmogIT0gTlVMTCwgIlN2eERyYXdQYWdlOjphZGQ6IG5vIFNkck9iamVjdCB3YXMgY3JlYXRlZCEiICk7Cgl9CgllbHNlIGlmICggIXBPYmotPklzSW5zZXJ0ZWQoKSApCgl7CgkJcE9iai0+U2V0TW9kZWwobXBNb2RlbCk7CgkJbXBQYWdlLT5JbnNlcnRPYmplY3QoIHBPYmogKTsKCX0KCglwU2hhcGUtPkNyZWF0ZSggcE9iaiwgdGhpcyApOwogICAgT1NMX0VOU1VSRSggcFNoYXBlLT5HZXRTZHJPYmplY3QoKSA9PSBwT2JqLCAiU3Z4RHJhd1BhZ2U6OmFkZDogc2hhcGUgZG9lcyBub3Qga25vdyBhYm91dCBpdHMgbmV3bHkgY3JlYXRlZCBTZHJPYmplY3QhIiApOwoKCW1wTW9kZWwtPlNldENoYW5nZWQoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OnJlbW92ZSggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiYgeFNoYXBlICkKCXRocm93KCB1bm86OlJ1bnRpbWVFeGNlcHRpb24gKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYoIChtcE1vZGVsID09IDApIHx8IChtcFBhZ2UgPT0gMCkgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJU3Z4U2hhcGUqIHBTaGFwZSA9IFN2eFNoYXBlOjpnZXRJbXBsZW1lbnRhdGlvbiggeFNoYXBlICk7CgoJaWYocFNoYXBlKQoJewoJCVNkck9iamVjdCoJcE9iaiA9IHBTaGFwZS0+R2V0U2RyT2JqZWN0KCk7CgkJaWYocE9iaikKCQl7CgkJCS8vIFNkck9iamVjdCBhdXMgZGVyIFBhZ2UgbG9lc2NoZW4KCQkJc2FsX3VJbnQzMiBuQ291bnQgPSBtcFBhZ2UtPkdldE9iakNvdW50KCk7CgkJCWZvciggc2FsX3VJbnQzMiBuTnVtID0gMDsgbk51bSA8IG5Db3VudDsgbk51bSsrICkKCQkJewoJCQkJaWYobXBQYWdlLT5HZXRPYmoobk51bSkgPT0gcE9iaikKCQkJCXsKICAgICAgICAgICAgICAgICAgICBPU0xfVkVSSUZZKCBtcFBhZ2UtPlJlbW92ZU9iamVjdCggbk51bSApID09IHBPYmogKTsKCQkJCQlTZHJPYmplY3Q6OkZyZWUoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KCglpZiggbXBNb2RlbCApCgkJbXBNb2RlbC0+U2V0Q2hhbmdlZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOjpYSW5kZXhBY2Nlc3MKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzYWxfSW50MzIgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OmdldENvdW50KCkKCXRocm93KCB1bm86OlJ1bnRpbWVFeGNlcHRpb24gKQp7CglPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYoIChtcE1vZGVsID09IDApIHx8IChtcFBhZ2UgPT0gMCkgKQoJCXRocm93IGxhbmc6OkRpc3Bvc2VkRXhjZXB0aW9uKCk7CgoJcmV0dXJuKCAoc2FsX0ludDMyKSBtcFBhZ2UtPkdldE9iakNvdW50KCkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnVubzo6QW55IFNBTF9DQUxMIFN2eERyYXdQYWdlOjpnZXRCeUluZGV4KCBzYWxfSW50MzIgSW5kZXggKQoJdGhyb3coIGxhbmc6OkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24sIGxhbmc6OldyYXBwZWRUYXJnZXRFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmKCAobXBNb2RlbCA9PSAwKSB8fCAobXBQYWdlID09IDApICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCWlmICggSW5kZXggPCAwIHx8IEluZGV4ID49IChzYWxfSW50MzIpbXBQYWdlLT5HZXRPYmpDb3VudCgpICkKCQl0aHJvdyBsYW5nOjpJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CgoJU2RyT2JqZWN0KiBwT2JqID0gbXBQYWdlLT5HZXRPYmooIEluZGV4ICk7CglpZiggcE9iaiA9PSBOVUxMICkKCQl0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oKTsKCgoJcmV0dXJuIG1ha2VBbnkoUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiggcE9iai0+Z2V0VW5vU2hhcGUoKSwgdW5vOjpVTk9fUVVFUlkgKSk7Cn0KCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOjpYRWxlbWVudEFjY2VzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnVubzo6VHlwZSBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6Z2V0RWxlbWVudFR5cGUoKQoJdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCXJldHVybiBJTlRFUkZBQ0VfVFlQRSggZHJhd2luZzo6WFNoYXBlICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6aGFzRWxlbWVudHMoKQoJdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggKG1wTW9kZWwgPT0gMCkgfHwgKG1wUGFnZSA9PSAwKSApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCglyZXR1cm4gbXBQYWdlICYmIG1wUGFnZS0+R2V0T2JqQ291bnQoKT4wOwp9CgpuYW1lc3BhY2UKewogICAgdm9pZCBsY2xfbWFya1Nkck9iamVjdE9mU2hhcGUoIGNvbnN0IFJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlID4mIF9yeFNoYXBlLCBTZHJWaWV3JiBfclZpZXcsIFNkclBhZ2VWaWV3JiBfclBhZ2VWaWV3ICkKICAgIHsKCQlTdnhTaGFwZSogcFNoYXBlID0gU3Z4U2hhcGU6OmdldEltcGxlbWVudGF0aW9uKCBfcnhTaGFwZSApOwogICAgICAgIGlmICggIXBTaGFwZSApCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgU2RyT2JqZWN0KiBwT2JqID0gcFNoYXBlLT5HZXRTZHJPYmplY3QoKTsKICAgICAgICBpZiAoICFwT2JqICkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBfclZpZXcuTWFya09iaiggcE9iaiwgJl9yUGFnZVZpZXcgKTsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEFDSFRVTkc6IF9TZWxlY3RPYmplY3RzSW5WaWV3IHNlbGVrdGllcnQgZGllIDo6Y29tOjpzdW46OnN0YXI6OmRyYXdpbmc6OlNoYXBlcyBudXIgaW4gZGVyIGFuZ2VnZWJlbm5lbgovLyAgICAgICAgIFNkclBhZ2VWaWV3LiBEaWVzIG113yBuaWNodCBkaWUgc2ljaHRiYXJlIFNkclBhZ2VWaWV3IHNlaW4uCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFN2eERyYXdQYWdlOjpfU2VsZWN0T2JqZWN0c0luVmlldyggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGVzID4gJiBhU2hhcGVzLCBTZHJQYWdlVmlldyogcFBhZ2VWaWV3ICkgdGhyb3cgKCkKewoJREJHX0FTU0VSVChwUGFnZVZpZXcsIlNkclBhZ2VWaWV3IGlzdCBOVUxMISBbQ0xdIik7CglEQkdfQVNTRVJUKG1wVmlldywgIlNkclZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCglpZihwUGFnZVZpZXchPU5VTEwgJiYgbXBWaWV3IT1OVUxMKQoJewoJCW1wVmlldy0+VW5tYXJrQWxsT2JqKCBwUGFnZVZpZXcgKTsKCgkJbG9uZyBuQ291bnQgPSBhU2hhcGVzLT5nZXRDb3VudCgpOwoJCWZvciggbG9uZyBpID0gMDsgaSA8IG5Db3VudDsgaSsrICkKCQl7CgkJCXVubzo6QW55IGFBbnkoIGFTaGFwZXMtPmdldEJ5SW5kZXgoaSkgKTsKCQkJUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiB4U2hhcGU7CgkJCWlmKCBhQW55ID4+PSB4U2hhcGUgKQogICAgICAgICAgICAgICAgbGNsX21hcmtTZHJPYmplY3RPZlNoYXBlKCB4U2hhcGUsICptcFZpZXcsICpwUGFnZVZpZXcgKTsKCQl9Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBBQ0hUVU5HOiBfU2VsZWN0T2JqZWN0SW5WaWV3IHNlbGVrdGllcnQgZGFzIFNoYXBlICpudXIqIGluIGRlciBhbmdlZ2ViZW5uZW4KLy8gICAgICAgICBTZHJQYWdlVmlldy4gRGllcyBtdd8gbmljaHQgZGllIHNpY2h0YmFyZSBTZHJQYWdlVmlldyBzZWluLgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTdnhEcmF3UGFnZTo6X1NlbGVjdE9iamVjdEluVmlldyggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiAmIHhTaGFwZSwgU2RyUGFnZVZpZXcqIHBQYWdlVmlldyApIHRocm93KCkKewoJREJHX0FTU0VSVChwUGFnZVZpZXcsIlNkclBhZ2VWaWV3IGlzdCBOVUxMISBbQ0xdIik7CglEQkdfQVNTRVJUKG1wVmlldywgIlNkclZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCglpZihwUGFnZVZpZXchPU5VTEwgJiYgbXBWaWV3ICE9IE5VTEwpCgl7CgkJbXBWaWV3LT5Vbm1hcmtBbGxPYmooIHBQYWdlVmlldyApOwogICAgICAgIGxjbF9tYXJrU2RyT2JqZWN0T2ZTaGFwZSggeFNoYXBlLCAqbXBWaWV3LCAqcFBhZ2VWaWV3ICk7Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZUdyb3VwID4gU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6Omdyb3VwKCBjb25zdCBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZXMgPiYgeFNoYXBlcyApCgl0aHJvdyggdW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewoJT0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCWlmKCAobXBNb2RlbCA9PSAwKSB8fCAobXBQYWdlID09IDApICkKCQl0aHJvdyBsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbigpOwoKCURCR19BU1NFUlQobXBQYWdlLCJTZHJQYWdlIGlzdCBOVUxMISBbQ0xdIik7CglEQkdfQVNTRVJUKG1wVmlldywgIlNkclZpZXcgaXN0IE5VTEwhIFtDTF0iKTsKCglSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmRyYXdpbmc6OlhTaGFwZUdyb3VwID4gIHhTaGFwZUdyb3VwOwoJaWYobXBQYWdlPT1OVUxMfHxtcFZpZXc9PU5VTEx8fCF4U2hhcGVzLmlzKCkpCgkJcmV0dXJuIHhTaGFwZUdyb3VwOwoKCVNkclBhZ2VWaWV3KiBwUGFnZVZpZXcgPSBtcFZpZXctPlNob3dTZHJQYWdlKCBtcFBhZ2UgKTsKCglfU2VsZWN0T2JqZWN0c0luVmlldyggeFNoYXBlcywgcFBhZ2VWaWV3ICk7CgoJbXBWaWV3LT5Hcm91cE1hcmtlZCgpOwoKCW1wVmlldy0+QWRqdXN0TWFya0hkbCgpOwoJY29uc3QgU2RyTWFya0xpc3QmIHJNYXJrTGlzdCA9IG1wVmlldy0+R2V0TWFya2VkT2JqZWN0TGlzdCgpOwoJaWYoIHJNYXJrTGlzdC5HZXRNYXJrQ291bnQoKSA9PSAxICkKCXsKCQlTZHJPYmplY3QqIHBPYmogPSByTWFya0xpc3QuR2V0TWFyaygwKS0+R2V0TWFya2VkU2RyT2JqKCk7CgkJaWYoIHBPYmogKQoJCQkgeFNoYXBlR3JvdXAgPSBSZWZlcmVuY2U8IGRyYXdpbmc6OlhTaGFwZUdyb3VwID46OnF1ZXJ5KCBwT2JqLT5nZXRVbm9TaGFwZSgpICk7Cgl9CgoJbXBWaWV3LT5IaWRlU2RyUGFnZSgpOwoKCWlmKCBtcE1vZGVsICkKCQltcE1vZGVsLT5TZXRDaGFuZ2VkKCk7CgoJcmV0dXJuIHhTaGFwZUdyb3VwOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6dW5ncm91cCggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGVHcm91cCA+JiBhR3JvdXAgKQoJdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCU9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglpZiggKG1wTW9kZWwgPT0gMCkgfHwgKG1wUGFnZSA9PSAwKSApCgkJdGhyb3cgbGFuZzo6RGlzcG9zZWRFeGNlcHRpb24oKTsKCglEQkdfQVNTRVJUKG1wUGFnZSwiU2RyUGFnZSBpc3QgTlVMTCEgW0NMXSIpOwoJREJHX0FTU0VSVChtcFZpZXcsICJTZHJWaWV3IGlzdCBOVUxMISBbQ0xdIik7CgoJaWYobXBQYWdlPT1OVUxMfHxtcFZpZXc9PU5VTEx8fCFhR3JvdXAuaXMoKSkKCQlyZXR1cm47CgoJU2RyUGFnZVZpZXcqIHBQYWdlVmlldyA9IG1wVmlldy0+U2hvd1NkclBhZ2UoIG1wUGFnZSApOwoKCVJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlID4geFNoYXBlKCBhR3JvdXAsIFVOT19RVUVSWSApOwoJX1NlbGVjdE9iamVjdEluVmlldyggeFNoYXBlLCBwUGFnZVZpZXcgKTsKCW1wVmlldy0+VW5Hcm91cE1hcmtlZCgpOwoKCW1wVmlldy0+SGlkZVNkclBhZ2UoKTsKCglpZiggbXBNb2RlbCApCgkJbXBNb2RlbC0+U2V0Q2hhbmdlZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2RyT2JqZWN0ICpTdnhEcmF3UGFnZTo6X0NyZWF0ZVNkck9iamVjdCggY29uc3QgUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiAmIHhTaGFwZSApIHRocm93KCkKewoJc2FsX3VJbnQxNiBuVHlwZTsKCXNhbF91SW50MzIgbkludmVudG9yOwoKCUdldFR5cGVBbmRJbnZlbnRvciggblR5cGUsIG5JbnZlbnRvciwgeFNoYXBlLT5nZXRTaGFwZVR5cGUoKSApOwoJU2RyT2JqZWN0KiBwTmV3T2JqID0gMDsKCglpZiggblR5cGUgIT0gMCApCgl7CgkJYXd0OjpTaXplIGFTaXplID0geFNoYXBlLT5nZXRTaXplKCk7CgkJYVNpemUuV2lkdGggKz0gMTsKCQlhU2l6ZS5IZWlnaHQgKz0gMTsKCQlhd3Q6OlBvaW50IGFQb3MgPSB4U2hhcGUtPmdldFBvc2l0aW9uKCk7CgkJUmVjdGFuZ2xlIGFSZWN0KCBQb2ludCggYVBvcy5YLCBhUG9zLlkgKSwgU2l6ZSggYVNpemUuV2lkdGgsIGFTaXplLkhlaWdodCApICk7CgoJCS8vIHNwZWNpYWwgY2FzZXMKCQlpZiggbkludmVudG9yID09IFNkckludmVudG9yICkKCQl7CgkJCXN3aXRjaCggblR5cGUgKQoJCQl7CgkJCWNhc2UgT0JKX01FQVNVUkU6CgkJCQl7CgkJCQkJcE5ld09iaiA9IG5ldyBTZHJNZWFzdXJlT2JqKCBhUmVjdC5Ub3BMZWZ0KCksIGFSZWN0LkJvdHRvbVJpZ2h0KCkgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSBPQkpfTElORToKCQkJCXsKCQkJCQliYXNlZ2Z4OjpCMkRQb2x5Z29uIGFQb2x5OwoJCQkJCWFQb2x5LmFwcGVuZChiYXNlZ2Z4OjpCMkRQb2ludChhUmVjdC5MZWZ0KCksIGFSZWN0LlRvcCgpKSk7CgkJCQkJYVBvbHkuYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KGFSZWN0LlJpZ2h0KCksIGFSZWN0LkJvdHRvbSgpKSk7CgkJCQkJcE5ld09iaiA9IG5ldyBTZHJQYXRoT2JqKE9CSl9MSU5FLCBiYXNlZ2Z4OjpCMkRQb2x5UG9seWdvbihhUG9seSkpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoKCQlpZiggcE5ld09iaiA9PSBOVUxMICkKCQkJcE5ld09iaiA9IFNkck9iakZhY3Rvcnk6Ok1ha2VOZXdPYmplY3QoIG5JbnZlbnRvciwgblR5cGUsIG1wUGFnZSApOwoKCQlpZihwTmV3T2JqKQoJCXsKCQkJcE5ld09iai0+U2V0U25hcFJlY3QoYVJlY3QpOwoKCQkJaWYoIHBOZXdPYmotPklTQShFM2RQb2x5U2NlbmUpKQoJCQl7CgkJCQkvLyBTemVuZSBpbml0aWFsaXNpZXJlbgoJCQkJRTNkU2NlbmUqIHBTY2VuZSA9IChFM2RTY2VuZSopcE5ld09iajsKCgkJCQlkb3VibGUgZlcgPSAoZG91YmxlKWFTaXplLldpZHRoOwoJCQkJZG91YmxlIGZIID0gKGRvdWJsZSlhU2l6ZS5IZWlnaHQ7CgoJCQkJQ2FtZXJhM0QgYUNhbShwU2NlbmUtPkdldENhbWVyYSgpKTsKCQkJCWFDYW0uU2V0QXV0b0FkanVzdFByb2plY3Rpb24oc2FsX0ZhbHNlKTsKCQkJCWFDYW0uU2V0Vmlld1dpbmRvdygtIGZXIC8gMiwgLSBmSCAvIDIsIGZXLCBmSCk7CgkJCQliYXNlZ2Z4OjpCM0RQb2ludCBhTG9va0F0OwoJCQkJYmFzZWdmeDo6QjNEUG9pbnQgYUNhbVBvcygwLjAsIDAuMCwgMTAwMDAuMCk7CgkJCQlhQ2FtLlNldFBvc0FuZExvb2tBdChhQ2FtUG9zLCBhTG9va0F0KTsKCQkJCWFDYW0uU2V0Rm9jYWxMZW5ndGgoMTAwLjApOwoJCQkJYUNhbS5TZXREZWZhdWx0cyhhQ2FtUG9zLCBhTG9va0F0LCAxMDAwMC4wKTsKCQkJCXBTY2VuZS0+U2V0Q2FtZXJhKGFDYW0pOwoKCQkJCXBTY2VuZS0+U2V0UmVjdHNEaXJ0eSgpOwoJCQl9CgkJCWVsc2UgaWYocE5ld09iai0+SVNBKEUzZEV4dHJ1ZGVPYmopKQoJCQl7CgkJCQlFM2RFeHRydWRlT2JqKiBwT2JqID0gKEUzZEV4dHJ1ZGVPYmoqKXBOZXdPYmo7CgkJCQliYXNlZ2Z4OjpCMkRQb2x5Z29uIGFOZXdQb2x5Z29uOwoJCQkJYU5ld1BvbHlnb24uYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KDAuMCwgMC4wKSk7CgkJCQlhTmV3UG9seWdvbi5hcHBlbmQoYmFzZWdmeDo6QjJEUG9pbnQoMC4wLCAxLjApKTsKCQkJCWFOZXdQb2x5Z29uLmFwcGVuZChiYXNlZ2Z4OjpCMkRQb2ludCgxLjAsIDAuMCkpOwoJCQkJYU5ld1BvbHlnb24uc2V0Q2xvc2VkKHRydWUpOwoJCQkJcE9iai0+U2V0RXh0cnVkZVBvbHlnb24oYmFzZWdmeDo6QjJEUG9seVBvbHlnb24oYU5ld1BvbHlnb24pKTsKCgkJCQkvLyAjMTA3MjQ1IyBwT2JqLT5TZXRFeHRydWRlQ2hhcmFjdGVyTW9kZShzYWxfVHJ1ZSk7CgkJCQlwT2JqLT5TZXRNZXJnZWRJdGVtKFN2eDNEQ2hhcmFjdGVyTW9kZUl0ZW0oc2FsX1RydWUpKTsKCQkJfQoJCQllbHNlIGlmKHBOZXdPYmotPklTQShFM2RMYXRoZU9iaikpCgkJCXsKCQkJCUUzZExhdGhlT2JqKiBwT2JqID0gKEUzZExhdGhlT2JqKilwTmV3T2JqOwoJCQkJYmFzZWdmeDo6QjJEUG9seWdvbiBhTmV3UG9seWdvbjsKCQkJCWFOZXdQb2x5Z29uLmFwcGVuZChiYXNlZ2Z4OjpCMkRQb2ludCgwLjAsIDAuMCkpOwoJCQkJYU5ld1BvbHlnb24uYXBwZW5kKGJhc2VnZng6OkIyRFBvaW50KDAuMCwgMS4wKSk7CgkJCQlhTmV3UG9seWdvbi5hcHBlbmQoYmFzZWdmeDo6QjJEUG9pbnQoMS4wLCAwLjApKTsKCQkJCWFOZXdQb2x5Z29uLnNldENsb3NlZCh0cnVlKTsKCQkJCXBPYmotPlNldFBvbHlQb2x5MkQoYmFzZWdmeDo6QjJEUG9seVBvbHlnb24oYU5ld1BvbHlnb24pKTsKCgkJCQkvLyAjMTA3MjQ1IyBwT2JqLT5TZXRMYXRoZUNoYXJhY3Rlck1vZGUoc2FsX1RydWUpOwoJCQkJcE9iai0+U2V0TWVyZ2VkSXRlbShTdngzRENoYXJhY3Rlck1vZGVJdGVtKHNhbF9UcnVlKSk7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIHBOZXdPYmo7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFN2eERyYXdQYWdlOjpHZXRUeXBlQW5kSW52ZW50b3IoIHNhbF91SW50MTYmIHJUeXBlLCBzYWxfdUludDMyJiBySW52ZW50b3IsIGNvbnN0IE9VU3RyaW5nJiBhTmFtZSApIGNvbnN0IHRocm93KCkKewoJc2FsX3VJbnQzMiBuVGVtcFR5cGUgPSBhU2RyU2hhcGVJZGVudGlmaWVyTWFwLmdldElkKCBhTmFtZSApOwoKCWlmKCBuVGVtcFR5cGUgPT0gVUhBU0hNQVBfTk9URk9VTkQgKQoJewoJCWlmKCBhTmFtZS5lcXVhbHNBc2NpaUwoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci5kcmF3aW5nLlRhYmxlU2hhcGUiKSkgfHwKCQkJYU5hbWUuZXF1YWxzQXNjaWlMKFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJjb20uc3VuLnN0YXIucHJlc2VudGF0aW9uLlRhYmxlU2hhcGUiKSkgKQoJCXsKCQkJckludmVudG9yID0gU2RySW52ZW50b3I7CgkJCXJUeXBlID0gT0JKX1RBQkxFOwoJCX0KCQllbHNlIGlmKCBhTmFtZS5lcXVhbHNBc2NpaUwoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci5wcmVzZW50YXRpb24uTWVkaWFTaGFwZSIgKSkgKQoJCXsKCQkJckludmVudG9yID0gU2RySW52ZW50b3I7CgkJCXJUeXBlID0gT0JKX01FRElBOwoJCX0KCX0KCWVsc2UgaWYoblRlbXBUeXBlICYgRTNEX0lOVkVOVE9SX0ZMQUcpCgl7CgkJckludmVudG9yID0gRTNkSW52ZW50b3I7CgkJclR5cGUgPSAoc2FsX3VJbnQxNikoblRlbXBUeXBlICYgfkUzRF9JTlZFTlRPUl9GTEFHKTsKCX0KCWVsc2UKCXsKCQlySW52ZW50b3IgPSBTZHJJbnZlbnRvcjsKCQlyVHlwZSA9IChzYWxfdUludDE2KW5UZW1wVHlwZTsKCgkJc3dpdGNoKCByVHlwZSApCgkJewoJCQljYXNlIE9CSl9GUkFNRToKCQkJY2FzZSBPQkpfT0xFMl9QTFVHSU46CgkJCWNhc2UgT0JKX09MRTJfQVBQTEVUOgoJCQkJclR5cGUgPSBPQkpfT0xFMjsKCQkJCWJyZWFrOwoJCX0KCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClN2eFNoYXBlKiBTdnhEcmF3UGFnZTo6Q3JlYXRlU2hhcGVCeVR5cGVBbmRJbnZlbnRvciggc2FsX3VJbnQxNiBuVHlwZSwgc2FsX3VJbnQzMiBuSW52ZW50b3IsIFNkck9iamVjdCAqcE9iaiwgU3Z4RHJhd1BhZ2UgKm1wUGFnZSApIHRocm93KCkKewoJU3Z4U2hhcGUqIHBSZXQgPSBOVUxMOwoJc3dpdGNoKCBuSW52ZW50b3IgKQoJewoJCWNhc2UgRTNkSW52ZW50b3I6CgkJewoJCQlzd2l0Y2goIG5UeXBlICkKCQkJewoJCQkJY2FzZSBFM0RfU0NFTkVfSUQgOgoJCQkJY2FzZSBFM0RfUE9MWVNDRU5FX0lEIDoKCQkJCQlwUmV0ID0gbmV3IFN2eDNEU2NlbmVPYmplY3QoIHBPYmosIG1wUGFnZSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFM0RfQ1VCRU9CSl9JRCA6CgkJCQkJcFJldCA9IG5ldyBTdngzREN1YmVPYmplY3QoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgRTNEX1NQSEVSRU9CSl9JRCA6CgkJCQkJcFJldCA9IG5ldyBTdngzRFNwaGVyZU9iamVjdCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFM0RfTEFUSEVPQkpfSUQgOgoJCQkJCXBSZXQgPSBuZXcgU3Z4M0RMYXRoZU9iamVjdCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFM0RfRVhUUlVERU9CSl9JRCA6CgkJCQkJcFJldCA9IG5ldyBTdngzREV4dHJ1ZGVPYmplY3QoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgRTNEX1BPTFlHT05PQkpfSUQgOgoJCQkJCXBSZXQgPSBuZXcgU3Z4M0RQb2x5Z29uT2JqZWN0KCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OiAvLyB1bmJla2FubnRlcyAzRC1PYmpla3QgYXVmIGRlciBQYWdlCgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQl9CgkJCWJyZWFrOwoJCX0KCQljYXNlIFNkckludmVudG9yOgoJCXsKCQkJc3dpdGNoKCBuVHlwZSApCgkJCXsKLy8JCQkJY2FzZSBPQkpfTk9ORToKLy8JCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfR1JVUDoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlR3JvdXAoIHBPYmosIG1wUGFnZSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfTElORToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb24oIHBPYmogLCBQb2x5Z29uS2luZF9MSU5FICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9SRUNUOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVSZWN0KCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9DSVJDOgoJCQkJY2FzZSBPQkpfU0VDVDoKCQkJCWNhc2UgT0JKX0NBUkM6CgkJCQljYXNlIE9CSl9DQ1VUOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVDaXJjbGUoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1BPTFk6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uKCBwT2JqICwgUG9seWdvbktpbmRfUE9MWSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfUExJTjoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb24oIHBPYmogLCBQb2x5Z29uS2luZF9QTElOICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9TUExOTElORToKCQkJCWNhc2UgT0JKX1BBVEhMSU5FOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbkJlemllciggcE9iaiAsIFBvbHlnb25LaW5kX1BBVEhMSU5FICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9TUExORklMTDoKCQkJCWNhc2UgT0JKX1BBVEhGSUxMOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbkJlemllciggcE9iaiAsIFBvbHlnb25LaW5kX1BBVEhGSUxMICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9GUkVFTElORToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlUG9seVBvbHlnb25CZXppZXIoIHBPYmogLCBQb2x5Z29uS2luZF9GUkVFTElORSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfRlJFRUZJTEw6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uQmV6aWVyKCBwT2JqICwgUG9seWdvbktpbmRfRlJFRUZJTEwgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0NBUFRJT046CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZUNhcHRpb24oIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1RJVExFVEVYVDoKCQkJCWNhc2UgT0JKX09VVExJTkVURVhUOgoJCQkJY2FzZSBPQkpfVEVYVDoKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlVGV4dCggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfR1JBRjoKCQkJCQlwUmV0ID0gbmV3IFN2eEdyYXBoaWNPYmplY3QoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0ZSQU1FOgoJCQkJCXBSZXQgPSBuZXcgU3Z4RnJhbWVTaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfT0xFMl9BUFBMRVQ6CgkJCQkJcFJldCA9IG5ldyBTdnhBcHBsZXRTaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfT0xFMl9QTFVHSU46CgkJCQkJcFJldCA9IG5ldyBTdnhQbHVnaW5TaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJIGNhc2UgT0JKX09MRTI6CgkJCQkJIHsKCQkJCQkJaWYoIHBPYmogJiYgIXBPYmotPklzRW1wdHlQcmVzT2JqKCkgJiYgbXBQYWdlICkKCQkJCQkJewoJCQkJCQkJU2RyUGFnZSogcFNkclBhZ2UgPSBtcFBhZ2UtPkdldFNkclBhZ2UoKTsKCQkJCQkJCWlmKCBwU2RyUGFnZSApCgkJCQkJCQl7CgkJCQkJCQkJU2RyTW9kZWwqIHBTZHJNb2RlbCA9IHBTZHJQYWdlLT5HZXRNb2RlbCgpOwoJCQkJCQkJCWlmKCBwU2RyTW9kZWwgKQoJCQkJCQkJCXsKCQkJCQkJCQkJOjpjb21waGVscGVyOjpJRW1iZWRkZWRIZWxwZXIgKnBQZXJzaXN0ID0gcFNkck1vZGVsLT5HZXRQZXJzaXN0KCk7CgkJCQkJCQkJCWlmKCBwUGVyc2lzdCApCgkJCQkJCQkJCXsKCQkJCQkJCQkJCXVubzo6UmVmZXJlbmNlIDwgZW1iZWQ6OlhFbWJlZGRlZE9iamVjdCA+IHhPYmplY3QgPSBwUGVyc2lzdC0+Z2V0RW1iZWRkZWRPYmplY3RDb250YWluZXIoKS4KCQkJCQkJCQkJCQkJR2V0RW1iZWRkZWRPYmplY3QoIHN0YXRpY19jYXN0PCBTZHJPbGUyT2JqKiA+KCBwT2JqICktPkdldFBlcnNpc3ROYW1lKCkgKTsKCgkJCQkJCQkJCQkvLyBUT0RPIENMLT5LQTogV2h5IGlzIHRoaXMgbm90IHdvcmtpbmcgYW55bW9yZT8KCQkJCQkJCQkJCWlmKCB4T2JqZWN0LmlzKCkgKQoJCQkJCQkJCQkJewoJCQkJCQkJCQkJCVN2R2xvYmFsTmFtZSBhQ2xhc3NJZCggeE9iamVjdC0+Z2V0Q2xhc3NJRCgpICk7CgoJCQkJCQkJCQkJCWNvbnN0IFN2R2xvYmFsTmFtZSBhQXBwbGV0Q2xhc3NJZCggU08zX0FQUExFVF9DTEFTU0lEICk7CgkJCQkJCQkJCQkJY29uc3QgU3ZHbG9iYWxOYW1lIGFQbHVnaW5DbGFzc0lkKCBTTzNfUExVR0lOX0NMQVNTSUQgKTsKCQkJCQkJCQkJCQljb25zdCBTdkdsb2JhbE5hbWUgYUlGcmFtZUNsYXNzSWQoIFNPM19JRlJBTUVfQ0xBU1NJRCApOwoKCQkJCQkJCQkJCQlpZiggYVBsdWdpbkNsYXNzSWQgPT0gYUNsYXNzSWQgKQoJCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQkJcFJldCA9IG5ldyBTdnhQbHVnaW5TaGFwZSggcE9iaiApOwoJCQkJCQkJCQkJCQluVHlwZSA9IE9CSl9PTEUyX1BMVUdJTjsKCQkJCQkJCQkJCQl9CgkJCQkJCQkJCQkJZWxzZSBpZiggYUFwcGxldENsYXNzSWQgPT0gYUNsYXNzSWQgKQoJCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQkJcFJldCA9IG5ldyBTdnhBcHBsZXRTaGFwZSggcE9iaiApOwoJCQkJCQkJCQkJCQluVHlwZSA9IE9CSl9PTEUyX0FQUExFVDsKCQkJCQkJCQkJCQl9CgkJCQkJCQkJCQkJZWxzZSBpZiggYUlGcmFtZUNsYXNzSWQgPT0gYUNsYXNzSWQgKQoJCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQkJcFJldCA9IG5ldyBTdnhGcmFtZVNoYXBlKCBwT2JqICk7CgkJCQkJCQkJCQkJCW5UeXBlID0gT0JKX0ZSQU1FOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlpZiggcFJldCA9PSBOVUxMICkKCQkJCQkJewoJCQkJCQkJcFJldCA9IG5ldyBTdnhPbGUyU2hhcGUoIHBPYmosIGFTdnhNYXBQcm92aWRlci5HZXRNYXAoU1ZYTUFQX09MRTIpLCAgYVN2eE1hcFByb3ZpZGVyLkdldFByb3BlcnR5U2V0KFNWWE1BUF9PTEUyLCBTZHJPYmplY3Q6OkdldEdsb2JhbERyYXdPYmplY3RJdGVtUG9vbCgpKSApOwoJCQkJCQl9CgkJCQkJIH0KCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0VER0U6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZUNvbm5lY3RvciggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfUEFUSFBPTFk6CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVBvbHlQb2x5Z29uKCBwT2JqICwgUG9seWdvbktpbmRfUEFUSFBPTFkgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX1BBVEhQTElOOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGVQb2x5UG9seWdvbiggcE9iaiAsIFBvbHlnb25LaW5kX1BBVEhQTElOICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9QQUdFOgoJCQkJCXBSZXQgPSBuZXcgU3Z4U2hhcGUoIHBPYmosIGFTdnhNYXBQcm92aWRlci5HZXRNYXAoU1ZYTUFQX1BBR0UpLCAgYVN2eE1hcFByb3ZpZGVyLkdldFByb3BlcnR5U2V0KFNWWE1BUF9QQUdFLCBTZHJPYmplY3Q6OkdldEdsb2JhbERyYXdPYmplY3RJdGVtUG9vbCgpKSApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfTUVBU1VSRToKCQkJCQlwUmV0ID0gbmV3IFN2eFNoYXBlRGltZW5zaW9uaW5nKCBwT2JqICk7CgkJCQkJYnJlYWs7Ci8vCQkJCWNhc2UgT0JKX0RVTU1ZOgovLwkJCQkJYnJlYWs7CgkJCQljYXNlIE9CSl9VTk86CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZUNvbnRyb2woIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX0NVU1RPTVNIQVBFOgoJCQkJCXBSZXQgPSBuZXcgU3Z4Q3VzdG9tU2hhcGUoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgT0JKX01FRElBOgoJCQkJCXBSZXQgPSBuZXcgU3Z4TWVkaWFTaGFwZSggcE9iaiApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBPQkpfVEFCTEU6CgkJCQkJcFJldCA9IG5ldyBTdnhUYWJsZVNoYXBlKCBwT2JqICk7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OiAvLyB1bmJla2FubnRlcyAyRC1PYmpla3QgYXVmIGRlciBQYWdlCgkJCQkJREJHX0VSUk9SKCJOaWNodCBpbXBsZW1lbnRpZXJ0ZXIgU3Rhcm9uZS1TaGFwZSBlcnpldWd0ISBbQ0xdIik7CgkJCQkJcFJldCA9IG5ldyBTdnhTaGFwZVRleHQoIHBPYmogKTsKCQkJCQlicmVhazsKCQkJfQoJCQlicmVhazsKCQl9CgkJZGVmYXVsdDogLy8gVW5iZWthbm50ZXIgSW52ZW50b3IKCQl7CgkJCURCR19FUlJPUigiQVc6IFVua25vd24gSW52ZW50b3IgaW4gU3Z4RHJhd1BhZ2U6Ol9DcmVhdGVTaGFwZSgpIik7CgkJCWJyZWFrOwoJCX0KCX0KCglpZihwUmV0KQoJewoJCXNhbF91SW50MzIgbk9iaklkID0gblR5cGU7CgoJCWlmKCBuSW52ZW50b3IgPT0gRTNkSW52ZW50b3IgKQoJCQluT2JqSWQgfD0gRTNEX0lOVkVOVE9SX0ZMQUc7CgoJCXN3aXRjaChuT2JqSWQpCgkJewoJCWNhc2UgT0JKX0NDVVQ6CQkJLy8gS3JlaXNhYnNjaG5pdHQKCQljYXNlIE9CSl9DQVJDOgkJCS8vIEtyZWlzYm9nZW4KCQljYXNlIE9CSl9TRUNUOgkJCS8vIEtyZWlzc2VrdG9yCgkJCW5PYmpJZCA9IE9CSl9DSVJDOwoJCQlicmVhazsKCgkJY2FzZSBFM0RfU0NFTkVfSUQgfCBFM0RfSU5WRU5UT1JfRkxBRzoKCQkJbk9iaklkID0gRTNEX1BPTFlTQ0VORV9JRCB8IEUzRF9JTlZFTlRPUl9GTEFHOwoJCQlicmVhazsKCgkJY2FzZSBPQkpfVElUTEVURVhUOgoJCWNhc2UgT0JKX09VVExJTkVURVhUOgoJCQluT2JqSWQgPSBPQkpfVEVYVDsKCQkJYnJlYWs7CgkJfQoKCQlwUmV0LT5zZXRTaGFwZUtpbmQobk9iaklkKTsKCX0KCglyZXR1cm4gcFJldDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlID4gIFN2eERyYXdQYWdlOjpfQ3JlYXRlU2hhcGUoIFNkck9iamVjdCAqcE9iaiApIGNvbnN0IHRocm93KCkKewoJUmVmZXJlbmNlPCBkcmF3aW5nOjpYU2hhcGUgPiB4U2hhcGUoIENyZWF0ZVNoYXBlQnlUeXBlQW5kSW52ZW50b3IocE9iai0+R2V0T2JqSWRlbnRpZmllcigpLAoJCQkJCQkJCQkJCSAgcE9iai0+R2V0T2JqSW52ZW50b3IoKSwKCQkJCQkJCQkJCQkgIHBPYmosCgkJCQkJCQkJCQkJICAoU3Z4RHJhd1BhZ2UqKXRoaXMpKTsKCXJldHVybiB4U2hhcGU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZHJPYmplY3QgKlN2eERyYXdQYWdlOjpDcmVhdGVTZHJPYmplY3QoIGNvbnN0IFJlZmVyZW5jZTwgZHJhd2luZzo6WFNoYXBlID4gJiB4U2hhcGUgKSB0aHJvdygpCnsKCVNkck9iamVjdCogcE9iaiA9IF9DcmVhdGVTZHJPYmplY3QoIHhTaGFwZSApOwoJaWYoIHBPYmogJiYgIXBPYmotPklzSW5zZXJ0ZWQoKSApCgkJbXBQYWdlLT5JbnNlcnRPYmplY3QoIHBPYmogKTsKCglyZXR1cm4gcE9iajsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OlhTZXJ2aWNlSW5mbwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1VTdHJpbmcgU0FMX0NBTEwgU3Z4RHJhd1BhZ2U6OmdldEltcGxlbWVudGF0aW9uTmFtZSgpIHRocm93KCB1bm86OlJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiU3Z4RHJhd1BhZ2UiKSk7Cn0KCnNhbF9Cb29sIFNBTF9DQUxMIFN2eERyYXdQYWdlOjpzdXBwb3J0c1NlcnZpY2UoIGNvbnN0IE9VU3RyaW5nJiBTZXJ2aWNlTmFtZSApCgl0aHJvdyg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKCXJldHVybiBjb21waGVscGVyOjpTZXJ2aWNlSW5mb0hlbHBlcjo6c3VwcG9ydHNTZXJ2aWNlKCBTZXJ2aWNlTmFtZSwgZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCkgKTsKfQoKdW5vOjpTZXF1ZW5jZTwgT1VTdHJpbmcgPiBTQUxfQ0FMTCBTdnhEcmF3UGFnZTo6Z2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCkgdGhyb3coIHVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKCXVubzo6U2VxdWVuY2U8IE9VU3RyaW5nID4gYVNlcSggMSApOwoJYVNlcS5nZXRBcnJheSgpWzBdID0gT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiY29tLnN1bi5zdGFyLmRyYXdpbmcuU2hhcGVDb2xsZWN0aW9uIiApKTsKCXJldHVybiBhU2VxOwp9CgpTdnhTaGFwZSogQ3JlYXRlU3Z4U2hhcGVCeVR5cGVBbmRJbnZlbnRvciggc2FsX3VJbnQxNiBuVHlwZSwgc2FsX3VJbnQzMiBuSW52ZW50b3IgKSB0aHJvdygpCnsKCXJldHVybiBTdnhEcmF3UGFnZTo6Q3JlYXRlU2hhcGVCeVR5cGVBbmRJbnZlbnRvciggblR5cGUsIG5JbnZlbnRvciApOwp9Cgp2b2lkIFN2eERyYXdQYWdlOjpDaGFuZ2VNb2RlbCggU2RyTW9kZWwqIHBOZXdNb2RlbCApCnsKCWlmKCBwTmV3TW9kZWwgIT0gbXBNb2RlbCApCgl7CgkJaWYoIG1wTW9kZWwgKQoJCQlFbmRMaXN0ZW5pbmcoICptcE1vZGVsICk7CgoJCWlmKCBwTmV3TW9kZWwgKQoJCQlTdGFydExpc3RlbmluZyggKnBOZXdNb2RlbCApOwoKCQltcE1vZGVsID0gcE5ld01vZGVsOwoKICAgICAgICBpZiggbXBWaWV3ICkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBtcFZpZXc7CgkgICAgICAgIG1wVmlldyA9IG5ldyBTZHJWaWV3KCBtcE1vZGVsICk7CgkgICAgICAgIGlmKCBtcFZpZXcgKQoJCSAgICAgICAgbXBWaWV3LT5TZXREZXNpZ25Nb2RlKHNhbF9UcnVlKTsKICAgICAgICB9Cgl9Cn0KCi8qKiByZXR1cm5zIGEgU3Rhck9mZmljZSBBUEkgd3JhcHBlciBmb3IgdGhlIGdpdmVuIFNkclBhZ2UgKi8KdW5vOjpSZWZlcmVuY2U8IGRyYXdpbmc6OlhEcmF3UGFnZSA+IEdldFhEcmF3UGFnZUZvclNkclBhZ2UoIFNkclBhZ2UqIHBQYWdlICkgdGhyb3cgKCkKewoJaWYocFBhZ2UpCgl7CgkJdW5vOjpSZWZlcmVuY2U8IGRyYXdpbmc6OlhEcmF3UGFnZSA+IHhEcmF3UGFnZSggcFBhZ2UtPmdldFVub1BhZ2UoKSwgdW5vOjpVTk9fUVVFUlkgKTsKCgkJcmV0dXJuIHhEcmF3UGFnZTsKCX0KCglyZXR1cm4gdW5vOjpSZWZlcmVuY2U8IGRyYXdpbmc6OlhEcmF3UGFnZSA+KCk7Cn0KCi8qKiByZXR1cm5zIHRoZSBTZHJPYmplY3QgZnJvbSB0aGUgZ2l2ZW4gU3Rhck9mZmljZSBBUEkgd3JhcHBlciAqLwpTZHJQYWdlKiBHZXRTZHJQYWdlRnJvbVhEcmF3UGFnZSggdW5vOjpSZWZlcmVuY2U8IGRyYXdpbmc6OlhEcmF3UGFnZSA+IHhEcmF3UGFnZSApIHRocm93KCkKewoJaWYoeERyYXdQYWdlLmlzKCkpCgl7CgkJU3Z4RHJhd1BhZ2UqIHBEcmF3UGFnZSA9IFN2eERyYXdQYWdlOjpnZXRJbXBsZW1lbnRhdGlvbiggeERyYXdQYWdlICk7CgoJCWlmKHBEcmF3UGFnZSkKCQl7CgkJCXJldHVybiBwRHJhd1BhZ2UtPkdldFNkclBhZ2UoKTsKCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCi8vIGVvZgo=