LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0yMDAxLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoKKiBGaWxlIGNvbGVpdHIuY3BwCioKKiAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA2LzIzLzk3ICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA4LzAzLzk4ICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhCiogMTIvMTAvOTkgICBhbGl1ICAgICAgICBQb3J0ZWQgVGhhaSBjb2xsYXRpb24gc3VwcG9ydCBmcm9tIEphdmEuCiogMDEvMjUvMDEgICBzd3F1ZWsgICAgICBNb2RpZmllZCB0byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29saXRlci5oKQoqIDAyLzE5LzAxICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBubyBjYWxscyBhcmUgbWFkZSB0byBpdAoqLwoKI2luY2x1ZGUgInVuaWNvZGUvY29sZWl0ci5oIgojaW5jbHVkZSAidWNvbF9pbXAuaCIKI2luY2x1ZGUgImNtZW1vcnkuaCIKI2luY2x1ZGUgInVuaWNvZGUvdXN0cmluZy5oIgoKCi8qIENvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfTkFNRVNQQUNFX0JFR0lOCgovKiBzeW53ZWUgOiBwdWJsaWMgY2FuJ3QgcmVtb3ZlICovCmludDMyX3QgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIgPSAweGZmZmZmZmZmOwoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc0RhdGFPd25lZF8oVFJVRSkKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvdGhlci5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIE5VTEwsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdHVzKTsKICAqdGhpcyA9IG90aGVyOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6On5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQp7CiAgaWYgKGlzRGF0YU93bmVkXykgewogICAgdWNvbF9jbG9zZUVsZW1lbnRzKG1fZGF0YV8pOwogIH0KfQoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVVRleHRPZmZzZXQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpnZXRPZmZzZXQoKSBjb25zdAp7CiAgcmV0dXJuIHVjb2xfZ2V0T2Zmc2V0KG1fZGF0YV8pOwp9CgovKioKKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLgoqIEByZXR1cm4gdGhlIG5leHQgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuIFJldHVybnMgTlVMTE9SREVSIGlmIGFuIGVycm9yIGhhcyAKKiAgICAgICAgIG9jY3VyZWQgb3IgaWYgdGhlIGVuZCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAoqLwppbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dChVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9uZXh0KG1fZGF0YV8sICZzdGF0dXMpOwp9CgpVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yIT0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdAp7CiAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwp9CgpVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yPT0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgdGhhdCkgY29uc3QKewogICAgVUJvb2wgcmVzdWx0ID0gVFJVRTsKCiAgICBpZiAodGhpcyA9PSAmdGhhdCkgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQogIAogICAgaWYgKG1fZGF0YV8gPT0gdGhhdC5tX2RhdGFfKSB7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLy8gb3B0aW9uIGNvbXBhcmlzb24KICAgIHJlc3VsdCA9IHRoaXMtPm1fZGF0YV8tPnJlc2V0XyA9PSB0aGF0Lm1fZGF0YV8tPnJlc2V0XyAmJiAgCiAgICAgICAgICAgICB0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwgPT0gCiAgICAgICAgICAgICB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbDsKCiAgICBpbnQgdGhpc2xlbmd0aCA9IDA7CiAgICBpZiAodGhpcy0+bV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5mbGFncyAmIFVDT0xfSVRFUl9IQVNMRU4pIHsKICAgICAgICB0aGlzbGVuZ3RoID0gdGhpcy0+bV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5lbmRwIC0KICAgICAgICAgICAgICAgICAgICAgdGhpcy0+bV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmc7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICB0aGlzbGVuZ3RoID0gdV9zdHJsZW4odGhpcy0+bV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcpOwogICAgfQogICAgaW50IHRoYXRsZW5ndGggPSAwOwogICAgaWYgKHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5lbmRwICE9IE5VTEwpIHsKICAgICAgICB0aGF0bGVuZ3RoID0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmVuZHAgLQogICAgICAgICAgICAgICAgICAgICB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdGhhdGxlbmd0aCA9IHVfc3RybGVuKHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcpOwogICAgfQoKICAgIGlmICh0aGlzbGVuZ3RoICE9IHRoYXRsZW5ndGgpIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmVzdWx0ID0gcmVzdWx0ICYmICh1cHJ2X21lbWNtcCh0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZywgCiAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNsZW5ndGggKiBzaXplb2YoVUNoYXIpKSA9PSAwKTsKICAgIHJlc3VsdCA9IHJlc3VsdCAmJiAodGhpcy0+Z2V0T2Zmc2V0KCkgPT0gdGhhdC5nZXRPZmZzZXQoKSk7CiAgCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioKKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgoqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgoqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgYW4gZXJyb3IgaGFzIAoqICAgICAgICAgb2NjdXJlZCBvciBpZiB0aGUgc3RhcnQgb2Ygc3RyaW5nIGhhcyBiZWVuIHJlYWNoZWQuCiovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9wcmV2aW91cyhtX2RhdGFfLCAmc3RhdHVzKTsKfQoKLyoqCiogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgoqLwp2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKQp7CiAgdWNvbF9yZXNldChtX2RhdGFfKTsKfQoKdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldE9mZnNldChVVGV4dE9mZnNldCBuZXdPZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogIHVjb2xfc2V0T2Zmc2V0KG1fZGF0YV8sIG5ld09mZnNldCwgJnN0YXR1cyk7Cn0KCi8qKgoqIFNldHMgdGhlIHNvdXJjZSB0byB0aGUgbmV3IHNvdXJjZSBzdHJpbmcuCiovCnZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIAkKICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZS5sZW5ndGgoKTsKICBVQ2hhciAqc3RyaW5nID0gTlVMTDsKICBpZiAobV9kYXRhXy0+aXNXcml0YWJsZSAmJiBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyAhPSBOVUxMKSB7CiAgICB1cHJ2X2ZyZWUobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcpOwogIH0KICBtX2RhdGFfLT5pc1dyaXRhYmxlID0gVFJVRTsKICBpZiAobGVuZ3RoID4gMCkgewogICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSAqIGxlbmd0aCk7CiAgICBzb3VyY2UuZXh0cmFjdCgwLCBsZW5ndGgsIHN0cmluZyk7CiAgfQogIGVsc2UgewogICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSk7CiAgICAqc3RyaW5nID0gMDsKICB9CiAgaW5pdF9jb2xsSXRlcmF0ZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIHN0cmluZywgbGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICZtX2RhdGFfLT5pdGVyYXRvcmRhdGFfKTsKCiAgbV9kYXRhXy0+cmVzZXRfICAgPSBUUlVFOwp9CgovLyBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IuCnZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIAogICAgcmV0dXJuOwogICAgCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2UuZ2V0TGVuZ3RoKCk7CiAgVUNoYXIgKmJ1ZmZlciA9IE5VTEw7CgogIGlmIChsZW5ndGggPT0gMCkgewogICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSk7CiAgICAqYnVmZmVyID0gMDsKICB9CiAgZWxzZSB7CiAgICAgIGJ1ZmZlciA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKHNpemVvZihVQ2hhcikgKiBsZW5ndGgpOwogICAgICAvKiAKICAgICAgVXNpbmcgdGhpcyBjb25zdHJ1Y3RvciB3aWxsIHByZXZlbnQgYnVmZmVyIGZyb20gYmVpbmcgcmVtb3ZlZCB3aGVuCiAgICAgIHN0cmluZyBnZXRzIHJlbW92ZWQKICAgICAgKi8KICAgICAgVW5pY29kZVN0cmluZyBzdHJpbmc7CiAgICAgIHNvdXJjZS5nZXRUZXh0KHN0cmluZyk7CiAgICAgIHN0cmluZy5leHRyYWN0KDAsIGxlbmd0aCwgYnVmZmVyKTsKICB9CiAgCiAgaWYgKG1fZGF0YV8tPmlzV3JpdGFibGUgJiYgbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcgIT0gTlVMTCkKICAgIHVwcnZfZnJlZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7CiAgaW5pdF9jb2xsSXRlcmF0ZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIGJ1ZmZlciwgbGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICZtX2RhdGFfLT5pdGVyYXRvcmRhdGFfKTsKICBtX2RhdGFfLT5yZXNldF8gICA9IFRSVUU7Cn0KCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICBVQ29sbGF0aW9uU3RyZW5ndGggcyA9IHVjb2xfZ2V0U3RyZW5ndGgobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5jb2xsKTsKICAvLyBNYXNrIG9mZiB0aGUgdW53YW50ZWQgZGlmZmVyZW5jZXMuCiAgaWYgKHMgPT0gVUNPTF9QUklNQVJZKQogICAgb3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWTsKICBlbHNlIAogICAgaWYgKHMgPT0gVUNPTF9TRUNPTkRBUlkpCiAgICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKICAgIAogIHJldHVybiBvcmRlcjsKfQoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgY29uc3RydWN0b3JzL2Rlc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tLSAqLwoKLyoqIAoqIFRoaXMgaXMgdGhlICJyZWFsIiBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzczsgaXQgY29uc3RydWN0cyBhbiBpdGVyYXRvcgoqIG92ZXIgdGhlIHNvdXJjZSB0ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWQgY29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogaXNEYXRhT3duZWRfKFRSVUUpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CiAKICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZVRleHQubGVuZ3RoKCk7CiAgVUNoYXIgKnN0cmluZyA9IE5VTEw7CiAgCiAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSAqIGxlbmd0aCk7CiAgICAgIC8qIAogICAgICBVc2luZyB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgcHJldmVudCBidWZmZXIgZnJvbSBiZWluZyByZW1vdmVkIHdoZW4KICAgICAgc3RyaW5nIGdldHMgcmVtb3ZlZAogICAgICAqLwogICAgICBzb3VyY2VUZXh0LmV4dHJhY3QoMCwgbGVuZ3RoLCBzdHJpbmcpOwogIH0KICBlbHNlIHsKICAgICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSk7CiAgICAgICpzdHJpbmcgPSAwOwogIH0KICBtX2RhdGFfID0gdWNvbF9vcGVuRWxlbWVudHMob3JkZXItPnVjb2xsYXRvciwgc3RyaW5nLCBsZW5ndGgsICZzdGF0dXMpOwogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwp9CgovKiogCiogVGhpcyBpcyB0aGUgInJlYWwiIGNvbnN0cnVjdG9yIGZvciB0aGlzIGNsYXNzOyBpdCBjb25zdHJ1Y3RzIGFuIGl0ZXJhdG9yIG92ZXIgCiogdGhlIHNvdXJjZSB0ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWQgY29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogaXNEYXRhT3duZWRfKFRSVUUpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CiAgICAKICAvLyAqKioqIHNob3VsZCBJIGp1c3QgZHJvcCB0aGlzIHRlc3Q/ICoqKioKICAvKgogIGlmICggc291cmNlVGV4dC5lbmRJbmRleCgpICE9IDAgKQogIHsKICAgIC8vIEEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGlzIHJlYWxseSBhIHR3by1sYXllcmVkIGJlYXN0LgogICAgLy8gSW50ZXJuYWxseSBpdCB1c2VzIGEgTm9ybWFsaXplciB0byBtdW5nZSB0aGUgc291cmNlIHRleHQgaW50byBhIGZvcm0gCiAgICAvLyB3aGVyZSBhbGwgImNvbXBvc2VkIiBVbmljb2RlIGNoYXJhY3RlcnMgKHN1Y2ggYXMg/CkgYXJlIHNwbGl0IGludG8gYSAKICAgIC8vIG5vcm1hbCBjaGFyYWN0ZXIgYW5kIGEgY29tYmluaW5nIGFjY2VudCBjaGFyYWN0ZXIuICAKICAgIC8vIEFmdGVyd2FyZCwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGRvZXMgaXRzIG93biBwcm9jZXNzaW5nIHRvIGhhbmRsZQogICAgLy8gZXhwYW5kaW5nIGFuZCBjb250cmFjdGluZyBjb2xsYXRpb24gc2VxdWVuY2VzLCBpZ25vcmFibGVzLCBhbmQgc28gb24uCiAgICAKICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcCA9IG9yZGVyLT5nZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gTm9ybWFsaXplcjo6Tk9fT1AgOiBvcmRlci0+Z2V0RGVjb21wb3NpdGlvbigpOwogICAgICAKICAgIHRleHQgPSBuZXcgTm9ybWFsaXplcihzb3VyY2VUZXh0LCBkZWNvbXApOwogICAgaWYgKHRleHQgPT0gTlVMTCkKICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsgICAgCiAgfQogICovCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2VUZXh0LmdldExlbmd0aCgpOwogIFVDaGFyICpidWZmZXI7CiAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSAqIGxlbmd0aCk7CiAgICAgIC8qIAogICAgICBVc2luZyB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgcHJldmVudCBidWZmZXIgZnJvbSBiZWluZyByZW1vdmVkIHdoZW4KICAgICAgc3RyaW5nIGdldHMgcmVtb3ZlZAogICAgICAqLwogICAgICBVbmljb2RlU3RyaW5nIHN0cmluZyhidWZmZXIsIGxlbmd0aCwgbGVuZ3RoKTsKICAgICAgKChDaGFyYWN0ZXJJdGVyYXRvciAmKXNvdXJjZVRleHQpLmdldFRleHQoc3RyaW5nKTsKICAgICAgc3RyaW5nLmV4dHJhY3QoMCwgbGVuZ3RoLCBidWZmZXIpOwogIH0KICBlbHNlIHsKICAgICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2Moc2l6ZW9mKFVDaGFyKSk7CiAgICAgICpidWZmZXIgPSAwOwogIH0KICBtX2RhdGFfID0gdWNvbF9vcGVuRWxlbWVudHMob3JkZXItPnVjb2xsYXRvciwgYnVmZmVyLCBsZW5ndGgsICZzdGF0dXMpOwogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwp9CgovKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCmNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpvcGVyYXRvcj0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikKewogIGlmICh0aGlzICE9ICZvdGhlcikKICB7CiAgICAgIFVDb2xsYXRpb25FbGVtZW50cyAqdWNvbGVsZW0gICAgICA9IHRoaXMtPm1fZGF0YV87CiAgICAgIFVDb2xsYXRpb25FbGVtZW50cyAqb3RoZXJ1Y29sZWxlbSA9IG90aGVyLm1fZGF0YV87CiAgICAgIGNvbGxJdGVyYXRlICAgICAgICAqY29saXRlciAgICAgICA9ICYodWNvbGVsZW0tPml0ZXJhdG9yZGF0YV8pOwogICAgICBjb2xsSXRlcmF0ZSAgICAgICAgKm90aGVyY29saXRlciAgPSAmKG90aGVydWNvbGVsZW0tPml0ZXJhdG9yZGF0YV8pOwogICAgICBpbnQgICAgICAgICAgICAgICAgbGVuZ3RoICAgICAgICAgPSAwOwogICAgICAKICAgICAgLy8gY2hlY2tpbmcgb25seSBVQ09MX0lURVJfSEFTTEVOIGlzIG5vdCBlbm91Z2ggaGVyZSBhcyB3ZSBtYXkgYmUgaW4gCiAgICAgIC8vIHRoZSBub3JtYWxpemF0aW9uIGJ1ZmZlcgogICAgICBpZiAob3RoZXJjb2xpdGVyLT5lbmRwICE9IE5VTEwpIHsKICAgICAgICAgIGxlbmd0aCA9IG90aGVyY29saXRlci0+ZW5kcCAtIG90aGVyY29saXRlci0+c3RyaW5nOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgICAgaWYgKG90aGVyY29saXRlci0+c3RyaW5nID09IE5VTEwpIHsKICAgICAgICAgICAgICBsZW5ndGggPSAwOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxlbmd0aCA9IHVfc3RybGVuKG90aGVyY29saXRlci0+c3RyaW5nKTsKICAgICAgICAgIH0KICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgdWNvbGVsZW0tPnJlc2V0XyAgICAgICAgID0gb3RoZXJ1Y29sZWxlbS0+cmVzZXRfOwogICAgICB1Y29sZWxlbS0+aXNXcml0YWJsZSAgICAgPSBUUlVFOwogICAgCiAgICAgIC8qIGNyZWF0ZSBhIGR1cGxpY2F0ZSBvZiBzdHJpbmcgKi8KICAgICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICAgIGNvbGl0ZXItPnN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKGxlbmd0aCAqIHNpemVvZihVQ2hhcikpOwogICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+c3RyaW5nLCBvdGhlcmNvbGl0ZXItPnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAqIHNpemVvZihVQ2hhcikpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgICAgY29saXRlci0+c3RyaW5nID0gTlVMTDsKICAgICAgfQoKICAgICAgLyogc3RhcnQgYW5kIGVuZCBvZiBzdHJpbmcgKi8KICAgICAgY29saXRlci0+ZW5kcCA9IGNvbGl0ZXItPnN0cmluZyArIGxlbmd0aDsKCiAgICAgIC8qIGhhbmRsZSB3cml0YWJsZSBidWZmZXIgaGVyZSAqLwogICAgICAKICAgICAgaWYgKG90aGVyY29saXRlci0+ZmxhZ3MgJiBVQ09MX0lURVJfSU5OT1JNQlVGKSB7CiAgICAgICAgICB1aW50MzJfdCB3bGVuZ3RoID0gdV9zdHJsZW4ob3RoZXJjb2xpdGVyLT53cml0YWJsZUJ1ZmZlcikgKyAxOwogICAgICAgICAgaWYgKHdsZW5ndGggPCBjb2xpdGVyLT53cml0YWJsZUJ1ZlNpemUpIHsKICAgICAgICAgICAgICB1cHJ2X21lbWNweShjb2xpdGVyLT5zdGFja1dyaXRhYmxlQnVmZmVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJjb2xpdGVyLT5zdGFja1dyaXRhYmxlQnVmZmVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJjb2xpdGVyLT53cml0YWJsZUJ1ZlNpemUgKiBzaXplb2YoVUNoYXIpKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIGlmIChjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciAhPSBjb2xpdGVyLT5zdGFja1dyaXRhYmxlQnVmZmVyKSB7CiAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb2xpdGVyLT53cml0YWJsZUJ1ZmZlcjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY29saXRlci0+d3JpdGFibGVCdWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bGVuZ3RoICogc2l6ZW9mKFVDaGFyKSk7CiAgICAgICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+d3JpdGFibGVCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgd2xlbmd0aCAqIHNpemVvZihVQ2hhcikpOwogICAgICAgICAgICAgIGNvbGl0ZXItPndyaXRhYmxlQnVmU2l6ZSA9IHdsZW5ndGg7CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgICAgCiAgICAgIC8qIGN1cnJlbnQgcG9zaXRpb24gKi8KICAgICAgaWYgKG90aGVyY29saXRlci0+cG9zID49IG90aGVyY29saXRlci0+c3RyaW5nICYmIAogICAgICAgICAgb3RoZXJjb2xpdGVyLT5wb3MgPD0gb3RoZXJjb2xpdGVyLT5lbmRwKSB7CiAgICAgICAgICBjb2xpdGVyLT5wb3MgPSBjb2xpdGVyLT5zdHJpbmcgKyAKICAgICAgICAgICAgICAgICAgICAgICAgKG90aGVyY29saXRlci0+cG9zIC0gb3RoZXJjb2xpdGVyLT5zdHJpbmcpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIGNvbGl0ZXItPnBvcyA9IGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyICsgCiAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPnBvcyAtIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIpOwogICAgICB9CgogICAgICAvKiBDRSBidWZmZXIgKi8KICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+Q0VzLCBvdGhlcmNvbGl0ZXItPkNFcywgCiAgICAgICAgICAgICAgICAgIFVDT0xfRVhQQU5EX0NFX0JVRkZFUl9TSVpFICogc2l6ZW9mKHVpbnQzMl90KSk7CiAgICAgIGNvbGl0ZXItPnRvUmV0dXJuID0gY29saXRlci0+Q0VzICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT50b1JldHVybiAtIG90aGVyY29saXRlci0+Q0VzKTsKICAgICAgY29saXRlci0+Q0Vwb3MgICAgPSBvdGhlcmNvbGl0ZXItPkNFcyArIAogICAgICAgICAgICAgICAgICAgICAgICAgKG90aGVyY29saXRlci0+Q0Vwb3MgLSBvdGhlcmNvbGl0ZXItPkNFcyk7CiAgICAKICAgICAgY29saXRlci0+ZmNkUG9zaXRpb24gPSBjb2xpdGVyLT5zdHJpbmcgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPmZjZFBvc2l0aW9uIC0gb3RoZXJjb2xpdGVyLT5zdHJpbmcpOwogICAgICBjb2xpdGVyLT5mbGFncyAgICAgICA9IG90aGVyY29saXRlci0+ZmxhZ3MgfCBVQ09MX0lURVJfSEFTTEVOOwogICAgICBjb2xpdGVyLT5vcmlnRmxhZ3MgICA9IG90aGVyY29saXRlci0+b3JpZ0ZsYWdzOwogICAgICBjb2xpdGVyLT5jb2xsID0gb3RoZXJjb2xpdGVyLT5jb2xsOwogICAgICB0aGlzLT5pc0RhdGFPd25lZF8gPSBUUlVFOwogIH0KCiAgcmV0dXJuICp0aGlzOwp9CgpVX05BTUVTUEFDRV9FTkQKCi8qIGVvZiAqLwo=