LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0yMDAxLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoKKiBGaWxlIGNvbGVpdHIuY3BwCioKKiAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA2LzIzLzk3ICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA4LzAzLzk4ICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhCiogMTIvMTAvOTkgICBhbGl1ICAgICAgICBQb3J0ZWQgVGhhaSBjb2xsYXRpb24gc3VwcG9ydCBmcm9tIEphdmEuCiogMDEvMjUvMDEgICBzd3F1ZWsgICAgICBNb2RpZmllZCB0byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29saXRlci5oKQoqIDAyLzE5LzAxICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBubyBjYWxscyBhcmUgbWFkZSB0byBpdAoqLwoKI2luY2x1ZGUgInVuaWNvZGUvY29sZWl0ci5oIgojaW5jbHVkZSAidWNvbF9pbXAuaCIKI2luY2x1ZGUgImNtZW1vcnkuaCIKI2luY2x1ZGUgInVuaWNvZGUvdXN0cmluZy5oIgoKCi8qIENvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfTkFNRVNQQUNFX0JFR0lOCgovKiBzeW53ZWUgOiBwdWJsaWMgY2FuJ3QgcmVtb3ZlICovCmludDMyX3QgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIgPSAweGZmZmZmZmZmOwoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc0RhdGFPd25lZF8oVFJVRSkKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvdGhlci5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIE5VTEwsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdHVzKTsKICAqdGhpcyA9IG90aGVyOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6On5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQp7CiAgaWYgKGlzRGF0YU93bmVkXykgewogICAgdWNvbF9jbG9zZUVsZW1lbnRzKG1fZGF0YV8pOwogIH0KfQoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE9mZnNldCgpIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRPZmZzZXQobV9kYXRhXyk7Cn0KCi8qKgoqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiogQHJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgYW4gZXJyb3IgaGFzIAoqICAgICAgICAgb2NjdXJlZCBvciBpZiB0aGUgZW5kIG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KFVFcnJvckNvZGUmIHN0YXR1cykKewogIHJldHVybiB1Y29sX25leHQobV9kYXRhXywgJnN0YXR1cyk7Cn0KClVCb29sIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3IhPSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIGNvbnN0CnsKICByZXR1cm4gISgqdGhpcyA9PSBvdGhlcik7Cn0KClVCb29sIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3I9PSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiB0aGF0KSBjb25zdAp7CiAgICBVQm9vbCByZXN1bHQgPSBUUlVFOwoKICAgIGlmICh0aGlzID09ICZ0aGF0KSB7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgCiAgICBpZiAobV9kYXRhXyA9PSB0aGF0Lm1fZGF0YV8pIHsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICAvLyBvcHRpb24gY29tcGFyaXNvbgogICAgcmVzdWx0ID0gdGhpcy0+bV9kYXRhXy0+cmVzZXRfID09IHRoYXQubV9kYXRhXy0+cmVzZXRfICYmICAKICAgICAgICAgICAgIHRoaXMtPm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbCA9PSAKICAgICAgICAgICAgIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5jb2xsOwoKICAgIGludCB0aGlzbGVuZ3RoID0gMDsKICAgIGlmICh0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmZsYWdzICYgVUNPTF9JVEVSX0hBU0xFTikgewogICAgICAgIHRoaXNsZW5ndGggPSB0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmVuZHAgLQogICAgICAgICAgICAgICAgICAgICB0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZzsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHRoaXNsZW5ndGggPSB1X3N0cmxlbih0aGlzLT5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgICB9CiAgICBpbnQgdGhhdGxlbmd0aCA9IDA7CiAgICBpZiAodGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmVuZHAgIT0gTlVMTCkgewogICAgICAgIHRoYXRsZW5ndGggPSB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uZW5kcCAtCiAgICAgICAgICAgICAgICAgICAgIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmc7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICB0aGF0bGVuZ3RoID0gdV9zdHJsZW4odGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgICB9CgogICAgaWYgKHRoaXNsZW5ndGggIT0gdGhhdGxlbmd0aCkgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXN1bHQgPSByZXN1bHQgJiYgKHVwcnZfbWVtY21wKHRoaXMtPm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgdGhpc2xlbmd0aCAqIFVfU0laRU9GX1VDSEFSKSA9PSAwKTsKICAgIHJlc3VsdCA9IHJlc3VsdCAmJiAodGhpcy0+Z2V0T2Zmc2V0KCkgPT0gdGhhdC5nZXRPZmZzZXQoKSk7CiAgCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioKKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgoqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgoqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgYW4gZXJyb3IgaGFzIAoqICAgICAgICAgb2NjdXJlZCBvciBpZiB0aGUgc3RhcnQgb2Ygc3RyaW5nIGhhcyBiZWVuIHJlYWNoZWQuCiovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9wcmV2aW91cyhtX2RhdGFfLCAmc3RhdHVzKTsKfQoKLyoqCiogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgoqLwp2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKQp7CiAgdWNvbF9yZXNldChtX2RhdGFfKTsKfQoKdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldE9mZnNldChpbnQzMl90IG5ld09mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgdWNvbF9zZXRPZmZzZXQobV9kYXRhXywgbmV3T2Zmc2V0LCAmc3RhdHVzKTsKfQoKLyoqCiogU2V0cyB0aGUgc291cmNlIHRvIHRoZSBuZXcgc291cmNlIHN0cmluZy4KKi8Kdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CgogIGludDMyX3QgbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwogIFVDaGFyICpzdHJpbmcgPSBOVUxMOwogIGlmIChtX2RhdGFfLT5pc1dyaXRhYmxlICYmIG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nICE9IE5VTEwpIHsKICAgIHVwcnZfZnJlZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgfQogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwogIGlmIChsZW5ndGggPiAwKSB7CiAgICBzdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICB1X21lbWNweShzdHJpbmcsIHNvdXJjZS5nZXRCdWZmZXIoKSwgbGVuZ3RoKTsKICB9CiAgZWxzZSB7CiAgICBzdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUik7CiAgICAqc3RyaW5nID0gMDsKICB9CiAgaW5pdF9jb2xsSXRlcmF0ZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIHN0cmluZywgbGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICZtX2RhdGFfLT5pdGVyYXRvcmRhdGFfKTsKCiAgbV9kYXRhXy0+cmVzZXRfICAgPSBUUlVFOwp9CgovLyBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IuCnZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIAogICAgcmV0dXJuOwogICAgCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2UuZ2V0TGVuZ3RoKCk7CiAgVUNoYXIgKmJ1ZmZlciA9IE5VTEw7CgogIGlmIChsZW5ndGggPT0gMCkgewogICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIpOwogICAgKmJ1ZmZlciA9IDA7CiAgfQogIGVsc2UgewogICAgICBidWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICAgIC8qIAogICAgICBVc2luZyB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgcHJldmVudCBidWZmZXIgZnJvbSBiZWluZyByZW1vdmVkIHdoZW4KICAgICAgc3RyaW5nIGdldHMgcmVtb3ZlZAogICAgICAqLwogICAgICBVbmljb2RlU3RyaW5nIHN0cmluZzsKICAgICAgc291cmNlLmdldFRleHQoc3RyaW5nKTsKICAgICAgdV9tZW1jcHkoYnVmZmVyLCBzdHJpbmcuZ2V0QnVmZmVyKCksIGxlbmd0aCk7CiAgfQogIAogIGlmIChtX2RhdGFfLT5pc1dyaXRhYmxlICYmIG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nICE9IE5VTEwpCiAgICB1cHJ2X2ZyZWUobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcpOwogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwogIGluaXRfY29sbEl0ZXJhdGUobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5jb2xsLCBidWZmZXIsIGxlbmd0aCwgCiAgICAgICAgICAgICAgICAgICAmbV9kYXRhXy0+aXRlcmF0b3JkYXRhXyk7CiAgbV9kYXRhXy0+cmVzZXRfICAgPSBUUlVFOwp9CgppbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgVUNvbGxhdGlvblN0cmVuZ3RoIHMgPSB1Y29sX2dldFN0cmVuZ3RoKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbCk7CiAgLy8gTWFzayBvZmYgdGhlIHVud2FudGVkIGRpZmZlcmVuY2VzLgogIGlmIChzID09IFVDT0xfUFJJTUFSWSkKICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFk7CiAgZWxzZSAKICAgIGlmIChzID09IFVDT0xfU0VDT05EQVJZKQogICAgICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CiAgICAKICByZXR1cm4gb3JkZXI7Cn0KCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcml2YXRlIGNvbnN0cnVjdG9ycy9kZXN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0gKi8KCi8qKiAKKiBUaGlzIGlzIHRoZSAicmVhbCIgY29uc3RydWN0b3IgZm9yIHRoaXMgY2xhc3M7IGl0IGNvbnN0cnVjdHMgYW4gaXRlcmF0b3IKKiBvdmVyIHRoZSBzb3VyY2UgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbGxhdG9yCiovCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzRGF0YU93bmVkXyhUUlVFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2VUZXh0Lmxlbmd0aCgpOwogIFVDaGFyICpzdHJpbmcgPSBOVUxMOwogIAogIGlmIChsZW5ndGggPiAwKSB7CiAgICAgIHN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSICogbGVuZ3RoKTsKICAgICAgLyogCiAgICAgIFVzaW5nIHRoaXMgY29uc3RydWN0b3Igd2lsbCBwcmV2ZW50IGJ1ZmZlciBmcm9tIGJlaW5nIHJlbW92ZWQgd2hlbgogICAgICBzdHJpbmcgZ2V0cyByZW1vdmVkCiAgICAgICovCiAgICAgIHVfbWVtY3B5KHN0cmluZywgc291cmNlVGV4dC5nZXRCdWZmZXIoKSwgbGVuZ3RoKTsKICB9CiAgZWxzZSB7CiAgICAgIHN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSKTsKICAgICAgKnN0cmluZyA9IDA7CiAgfQogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvcmRlci0+dWNvbGxhdG9yLCBzdHJpbmcsIGxlbmd0aCwgJnN0YXR1cyk7CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7Cn0KCi8qKiAKKiBUaGlzIGlzIHRoZSAicmVhbCIgY29uc3RydWN0b3IgZm9yIHRoaXMgY2xhc3M7IGl0IGNvbnN0cnVjdHMgYW4gaXRlcmF0b3Igb3ZlciAKKiB0aGUgc291cmNlIHRleHQgdXNpbmcgdGhlIHNwZWNpZmllZCBjb2xsYXRvcgoqLwpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc0RhdGFPd25lZF8oVFJVRSkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKICAgIAogIC8vICoqKiogc2hvdWxkIEkganVzdCBkcm9wIHRoaXMgdGVzdD8gKioqKgogIC8qCiAgaWYgKCBzb3VyY2VUZXh0LmVuZEluZGV4KCkgIT0gMCApCiAgewogICAgLy8gQSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXMgcmVhbGx5IGEgdHdvLWxheWVyZWQgYmVhc3QuCiAgICAvLyBJbnRlcm5hbGx5IGl0IHVzZXMgYSBOb3JtYWxpemVyIHRvIG11bmdlIHRoZSBzb3VyY2UgdGV4dCBpbnRvIGEgZm9ybSAKICAgIC8vIHdoZXJlIGFsbCAiY29tcG9zZWQiIFVuaWNvZGUgY2hhcmFjdGVycyAoc3VjaCBhcyD8KSBhcmUgc3BsaXQgaW50byBhIAogICAgLy8gbm9ybWFsIGNoYXJhY3RlciBhbmQgYSBjb21iaW5pbmcgYWNjZW50IGNoYXJhY3Rlci4gIAogICAgLy8gQWZ0ZXJ3YXJkLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgZG9lcyBpdHMgb3duIHByb2Nlc3NpbmcgdG8gaGFuZGxlCiAgICAvLyBleHBhbmRpbmcgYW5kIGNvbnRyYWN0aW5nIGNvbGxhdGlvbiBzZXF1ZW5jZXMsIGlnbm9yYWJsZXMsIGFuZCBzbyBvbi4KICAgIAogICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wID0gb3JkZXItPmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBOb3JtYWxpemVyOjpOT19PUCA6IG9yZGVyLT5nZXREZWNvbXBvc2l0aW9uKCk7CiAgICAgIAogICAgdGV4dCA9IG5ldyBOb3JtYWxpemVyKHNvdXJjZVRleHQsIGRlY29tcCk7CiAgICBpZiAodGV4dCA9PSBOVUxMKQogICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOyAgICAKICB9CiAgKi8KICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZVRleHQuZ2V0TGVuZ3RoKCk7CiAgVUNoYXIgKmJ1ZmZlcjsKICBpZiAobGVuZ3RoID4gMCkgewogICAgICBidWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICAgIC8qIAogICAgICBVc2luZyB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgcHJldmVudCBidWZmZXIgZnJvbSBiZWluZyByZW1vdmVkIHdoZW4KICAgICAgc3RyaW5nIGdldHMgcmVtb3ZlZAogICAgICAqLwogICAgICBVbmljb2RlU3RyaW5nIHN0cmluZyhidWZmZXIsIGxlbmd0aCwgbGVuZ3RoKTsKICAgICAgKChDaGFyYWN0ZXJJdGVyYXRvciAmKXNvdXJjZVRleHQpLmdldFRleHQoc3RyaW5nKTsKICAgICAgY29uc3QgVUNoYXIgKnRlbXAgPSBzdHJpbmcuZ2V0QnVmZmVyKCk7CiAgICAgIHVfbWVtY3B5KGJ1ZmZlciwgdGVtcCwgbGVuZ3RoKTsKICB9CiAgZWxzZSB7CiAgICAgIGJ1ZmZlciA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSKTsKICAgICAgKmJ1ZmZlciA9IDA7CiAgfQogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvcmRlci0+dWNvbGxhdG9yLCBidWZmZXIsIGxlbmd0aCwgJnN0YXR1cyk7CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7Cn0KCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yPSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKQp7CiAgaWYgKHRoaXMgIT0gJm90aGVyKQogIHsKICAgICAgVUNvbGxhdGlvbkVsZW1lbnRzICp1Y29sZWxlbSAgICAgID0gdGhpcy0+bV9kYXRhXzsKICAgICAgVUNvbGxhdGlvbkVsZW1lbnRzICpvdGhlcnVjb2xlbGVtID0gb3RoZXIubV9kYXRhXzsKICAgICAgY29sbEl0ZXJhdGUgICAgICAgICpjb2xpdGVyICAgICAgID0gJih1Y29sZWxlbS0+aXRlcmF0b3JkYXRhXyk7CiAgICAgIGNvbGxJdGVyYXRlICAgICAgICAqb3RoZXJjb2xpdGVyICA9ICYob3RoZXJ1Y29sZWxlbS0+aXRlcmF0b3JkYXRhXyk7CiAgICAgIGludCAgICAgICAgICAgICAgICBsZW5ndGggICAgICAgICA9IDA7CiAgICAgIAogICAgICAvLyBjaGVja2luZyBvbmx5IFVDT0xfSVRFUl9IQVNMRU4gaXMgbm90IGVub3VnaCBoZXJlIGFzIHdlIG1heSBiZSBpbiAKICAgICAgLy8gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPmVuZHAgIT0gTlVMTCkgewogICAgICAgICAgbGVuZ3RoID0gb3RoZXJjb2xpdGVyLT5lbmRwIC0gb3RoZXJjb2xpdGVyLT5zdHJpbmc7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgICBpZiAob3RoZXJjb2xpdGVyLT5zdHJpbmcgPT0gTlVMTCkgewogICAgICAgICAgICAgIGxlbmd0aCA9IDA7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgbGVuZ3RoID0gdV9zdHJsZW4ob3RoZXJjb2xpdGVyLT5zdHJpbmcpOwogICAgICAgICAgfQogICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICB1Y29sZWxlbS0+cmVzZXRfICAgICAgICAgPSBvdGhlcnVjb2xlbGVtLT5yZXNldF87CiAgICAgIHVjb2xlbGVtLT5pc1dyaXRhYmxlICAgICA9IFRSVUU7CiAgICAKICAgICAgLyogY3JlYXRlIGEgZHVwbGljYXRlIG9mIHN0cmluZyAqLwogICAgICBpZiAobGVuZ3RoID4gMCkgewogICAgICAgICAgY29saXRlci0+c3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2MobGVuZ3RoICogVV9TSVpFT0ZfVUNIQVIpOwogICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+c3RyaW5nLCBvdGhlcmNvbGl0ZXItPnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAgIGNvbGl0ZXItPnN0cmluZyA9IE5VTEw7CiAgICAgIH0KCiAgICAgIC8qIHN0YXJ0IGFuZCBlbmQgb2Ygc3RyaW5nICovCiAgICAgIGNvbGl0ZXItPmVuZHAgPSBjb2xpdGVyLT5zdHJpbmcgKyBsZW5ndGg7CgogICAgICAvKiBoYW5kbGUgd3JpdGFibGUgYnVmZmVyIGhlcmUgKi8KICAgICAgCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPmZsYWdzICYgVUNPTF9JVEVSX0lOTk9STUJVRikgewogICAgICAgICAgdWludDMyX3Qgd2xlbmd0aCA9IHVfc3RybGVuKG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIpICsgMTsKICAgICAgICAgIGlmICh3bGVuZ3RoIDwgY29saXRlci0+d3JpdGFibGVCdWZTaXplKSB7CiAgICAgICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+c3RhY2tXcml0YWJsZUJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+c3RhY2tXcml0YWJsZUJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZTaXplICogVV9TSVpFT0ZfVUNIQVIpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyICE9IGNvbGl0ZXItPnN0YWNrV3JpdGFibGVCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdsZW5ndGggKiBVX1NJWkVPRl9VQ0hBUik7CiAgICAgICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+d3JpdGFibGVCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgd2xlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgICAgICBjb2xpdGVyLT53cml0YWJsZUJ1ZlNpemUgPSB3bGVuZ3RoOwogICAgICAgICAgfQogICAgICB9CiAgICAgICAgIAogICAgICAvKiBjdXJyZW50IHBvc2l0aW9uICovCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPnBvcyA+PSBvdGhlcmNvbGl0ZXItPnN0cmluZyAmJiAKICAgICAgICAgIG90aGVyY29saXRlci0+cG9zIDw9IG90aGVyY29saXRlci0+ZW5kcCkgewogICAgICAgICAgY29saXRlci0+cG9zID0gY29saXRlci0+c3RyaW5nICsgCiAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPnBvcyAtIG90aGVyY29saXRlci0+c3RyaW5nKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBjb2xpdGVyLT5wb3MgPSBjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciArIAogICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT5wb3MgLSBvdGhlcmNvbGl0ZXItPndyaXRhYmxlQnVmZmVyKTsKICAgICAgfQoKICAgICAgLyogQ0UgYnVmZmVyICovCiAgICAgIHVwcnZfbWVtY3B5KGNvbGl0ZXItPkNFcywgb3RoZXJjb2xpdGVyLT5DRXMsIAogICAgICAgICAgICAgICAgICBVQ09MX0VYUEFORF9DRV9CVUZGRVJfU0laRSAqIHNpemVvZih1aW50MzJfdCkpOwogICAgICBjb2xpdGVyLT50b1JldHVybiA9IGNvbGl0ZXItPkNFcyArIAogICAgICAgICAgICAgICAgICAgICAgICAgKG90aGVyY29saXRlci0+dG9SZXR1cm4gLSBvdGhlcmNvbGl0ZXItPkNFcyk7CiAgICAgIGNvbGl0ZXItPkNFcG9zICAgID0gb3RoZXJjb2xpdGVyLT5DRXMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPkNFcG9zIC0gb3RoZXJjb2xpdGVyLT5DRXMpOwogICAgCiAgICAgIGNvbGl0ZXItPmZjZFBvc2l0aW9uID0gY29saXRlci0+c3RyaW5nICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT5mY2RQb3NpdGlvbiAtIG90aGVyY29saXRlci0+c3RyaW5nKTsKICAgICAgY29saXRlci0+ZmxhZ3MgICAgICAgPSBvdGhlcmNvbGl0ZXItPmZsYWdzIHwgVUNPTF9JVEVSX0hBU0xFTjsKICAgICAgY29saXRlci0+b3JpZ0ZsYWdzICAgPSBvdGhlcmNvbGl0ZXItPm9yaWdGbGFnczsKICAgICAgY29saXRlci0+Y29sbCA9IG90aGVyY29saXRlci0+Y29sbDsKICAgICAgdGhpcy0+aXNEYXRhT3duZWRfID0gVFJVRTsKICB9CgogIHJldHVybiAqdGhpczsKfQoKVV9OQU1FU1BBQ0VfRU5ECgovKiBlb2YgKi8K