LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0yMDAxLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoKKiBGaWxlIGNvbGVpdHIuY3BwCioKKiAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA2LzIzLzk3ICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA4LzAzLzk4ICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhCiogMTIvMTAvOTkgICBhbGl1ICAgICAgICBQb3J0ZWQgVGhhaSBjb2xsYXRpb24gc3VwcG9ydCBmcm9tIEphdmEuCiogMDEvMjUvMDEgICBzd3F1ZWsgICAgICBNb2RpZmllZCB0byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29saXRlci5oKQoqIDAyLzE5LzAxICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBubyBjYWxscyBhcmUgbWFkZSB0byBpdAoqLwoKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCgojaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OCgojaW5jbHVkZSAidW5pY29kZS9jb2xlaXRyLmgiCiNpbmNsdWRlICJ1bmljb2RlL3VzdHJpbmcuaCIKI2luY2x1ZGUgInVjb2xfaW1wLmgiCiNpbmNsdWRlICJjbWVtb3J5LmgiCgoKLyogQ29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVV9OQU1FU1BBQ0VfQkVHSU4KCmNvbnN0IGNoYXIgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpmZ0NsYXNzSUQ9MDsKCi8qIHN5bndlZSA6IHB1YmxpYyBjYW4ndCByZW1vdmUgKi8KaW50MzJfdCBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiA9IDB4ZmZmZmZmZmY7CgovKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFVPYmplY3Qob3RoZXIpLCBpc0RhdGFPd25lZF8oVFJVRSkKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvdGhlci5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIE5VTEwsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdHVzKTsKCiAgKnRoaXMgPSBvdGhlcjsKfQoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp+Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCkKewogIGlmIChpc0RhdGFPd25lZF8pIHsKICAgIHVjb2xfY2xvc2VFbGVtZW50cyhtX2RhdGFfKTsKICB9Cn0KCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpnZXRPZmZzZXQoKSBjb25zdAp7CiAgcmV0dXJuIHVjb2xfZ2V0T2Zmc2V0KG1fZGF0YV8pOwp9CgovKioKKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLgoqIEByZXR1cm4gdGhlIG5leHQgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuIFJldHVybnMgTlVMTE9SREVSIGlmIGFuIGVycm9yIGhhcyAKKiAgICAgICAgIG9jY3VyZWQgb3IgaWYgdGhlIGVuZCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAoqLwppbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dChVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9uZXh0KG1fZGF0YV8sICZzdGF0dXMpOwp9CgpVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yIT0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdAp7CiAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwp9CgpVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yPT0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgdGhhdCkgY29uc3QKewogICAgaWYgKHRoaXMgPT0gJnRoYXQpIHsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KICAKICAgIGlmIChtX2RhdGFfID09IHRoYXQubV9kYXRhXykgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIC8vIG9wdGlvbiBjb21wYXJpc29uCiAgICBpZiAoIShtX2RhdGFfLT5yZXNldF8gPT0gdGhhdC5tX2RhdGFfLT5yZXNldF8gCiAgICAgICAgICAmJiBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwgPT0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvLyB0aGUgY29uc3RydWN0b3IgYW5kIHNldFRleHQgYWx3YXlzIHNldHMgYSBsZW5ndGgKICAgIC8vIGFuZCB3ZSBvbmx5IGNvbXBhcmUgdGhlIHN0cmluZyBub3QgdGhlIGNvbnRlbnRzIG9mIHRoZSBub3JtYWxpemF0aW9uCiAgICAvLyBidWZmZXIKICAgIGludCB0aGlzbGVuZ3RoID0gbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5lbmRwIC0KICAgICAgICAgICAgICAgICAgICAgbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmc7CiAgICBpbnQgdGhhdGxlbmd0aCA9IHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5lbmRwIC0KICAgICAgICAgICAgICAgICAgICAgdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZzsKICAgIAogICAgaWYgKHRoaXNsZW5ndGggIT0gdGhhdGxlbmd0aCkgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAodXBydl9tZW1jbXAobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcsIAogICAgICAgICAgICAgICAgICAgIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcsIAogICAgICAgICAgICAgICAgICAgIHRoaXNsZW5ndGggKiBVX1NJWkVPRl9VQ0hBUikgIT0gMCkgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmIChnZXRPZmZzZXQoKSAhPSB0aGF0LmdldE9mZnNldCgpKSB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8vIGNoZWNraW5nIG5vcm1hbGl6YXRpb24gYnVmZmVyCiAgICBpZiAoKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uZmxhZ3MgJiBVQ09MX0lURVJfSEFTTEVOKSA9PSAwKSB7CiAgICAgICAgaWYgKChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmZsYWdzICYgVUNPTF9JVEVSX0hBU0xFTikgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgICAgIC8vIGJvdGggYXJlIGluIHRoZSBub3JtYWxpemF0aW9uIGJ1ZmZlcgogICAgICAgIGlmIChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnBvcyAKICAgICAgICAgICAgLSBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLndyaXRhYmxlQnVmZmVyIAogICAgICAgICAgICAhPSB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8ucG9zIAogICAgICAgICAgICAtIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy53cml0YWJsZUJ1ZmZlcikgewogICAgICAgICAgICAvLyBub3QgaW4gdGhlIHNhbWUgcG9zaXRpb24gaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICgobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5mbGFncyAmIFVDT0xfSVRFUl9IQVNMRU4pID09IDApIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICAvLyBjaGVja2luZyBjZSBwb3NpdGlvbgogICAgcmV0dXJuIChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLkNFcG9zIC0gbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5DRXMpCiAgICAgICAgICAgID09ICh0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uQ0Vwb3MgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5DRXMpOwp9CgovKioKKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgoqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgoqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgYW4gZXJyb3IgaGFzIAoqICAgICAgICAgb2NjdXJlZCBvciBpZiB0aGUgc3RhcnQgb2Ygc3RyaW5nIGhhcyBiZWVuIHJlYWNoZWQuCiovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICByZXR1cm4gdWNvbF9wcmV2aW91cyhtX2RhdGFfLCAmc3RhdHVzKTsKfQoKLyoqCiogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgoqLwp2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKQp7CiAgdWNvbF9yZXNldChtX2RhdGFfKTsKfQoKdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldE9mZnNldChpbnQzMl90IG5ld09mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgdWNvbF9zZXRPZmZzZXQobV9kYXRhXywgbmV3T2Zmc2V0LCAmc3RhdHVzKTsKfQoKLyoqCiogU2V0cyB0aGUgc291cmNlIHRvIHRoZSBuZXcgc291cmNlIHN0cmluZy4KKi8Kdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CgogIGludDMyX3QgbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwogIFVDaGFyICpzdHJpbmcgPSBOVUxMOwogIGlmIChtX2RhdGFfLT5pc1dyaXRhYmxlICYmIG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nICE9IE5VTEwpIHsKICAgIHVwcnZfZnJlZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgfQogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwogIGlmIChsZW5ndGggPiAwKSB7CiAgICBzdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICBpZiAoc3RyaW5nID09IE5VTEwpIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHVfbWVtY3B5KHN0cmluZywgc291cmNlLmdldEJ1ZmZlcigpLCBsZW5ndGgpOwogIH0KICBlbHNlIHsKICAgIHN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSKTsKICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgIGlmIChzdHJpbmcgPT0gTlVMTCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgKnN0cmluZyA9IDA7CiAgfQogIHVwcnZfaW5pdF9jb2xsSXRlcmF0ZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIHN0cmluZywgbGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICZtX2RhdGFfLT5pdGVyYXRvcmRhdGFfKTsKCiAgbV9kYXRhXy0+cmVzZXRfICAgPSBUUlVFOwp9CgovLyBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IuCnZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIAogICAgcmV0dXJuOwogICAgCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2UuZ2V0TGVuZ3RoKCk7CiAgVUNoYXIgKmJ1ZmZlciA9IE5VTEw7CgogIGlmIChsZW5ndGggPT0gMCkgewogICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIpOwogICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAqYnVmZmVyID0gMDsKICB9CiAgZWxzZSB7CiAgICAgIGJ1ZmZlciA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSICogbGVuZ3RoKTsKICAgICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgLyogCiAgICAgIFVzaW5nIHRoaXMgY29uc3RydWN0b3Igd2lsbCBwcmV2ZW50IGJ1ZmZlciBmcm9tIGJlaW5nIHJlbW92ZWQgd2hlbgogICAgICBzdHJpbmcgZ2V0cyByZW1vdmVkCiAgICAgICovCiAgICAgIFVuaWNvZGVTdHJpbmcgc3RyaW5nOwogICAgICBzb3VyY2UuZ2V0VGV4dChzdHJpbmcpOwogICAgICB1X21lbWNweShidWZmZXIsIHN0cmluZy5nZXRCdWZmZXIoKSwgbGVuZ3RoKTsKICB9CiAgCiAgaWYgKG1fZGF0YV8tPmlzV3JpdGFibGUgJiYgbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcgIT0gTlVMTCkgewogICAgICB1cHJ2X2ZyZWUobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcpOwogIH0KICBtX2RhdGFfLT5pc1dyaXRhYmxlID0gVFJVRTsKICB1cHJ2X2luaXRfY29sbEl0ZXJhdGUobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5jb2xsLCBidWZmZXIsIGxlbmd0aCwgCiAgICAgICAgICAgICAgICAgICAmbV9kYXRhXy0+aXRlcmF0b3JkYXRhXyk7CiAgbV9kYXRhXy0+cmVzZXRfICAgPSBUUlVFOwp9CgppbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgVUNvbGxhdGlvblN0cmVuZ3RoIHMgPSB1Y29sX2dldFN0cmVuZ3RoKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbCk7CiAgLy8gTWFzayBvZmYgdGhlIHVud2FudGVkIGRpZmZlcmVuY2VzLgogIGlmIChzID09IFVDT0xfUFJJTUFSWSkgewogICAgICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWURJRkZFUkVOQ0VPTkxZOwogIH0KICBlbHNlIGlmIChzID09IFVDT0xfU0VDT05EQVJZKSB7CiAgICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKICB9CiAgICAKICByZXR1cm4gb3JkZXI7Cn0KCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcml2YXRlIGNvbnN0cnVjdG9ycy9kZXN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0gKi8KCi8qKiAKKiBUaGlzIGlzIHRoZSAicmVhbCIgY29uc3RydWN0b3IgZm9yIHRoaXMgY2xhc3M7IGl0IGNvbnN0cnVjdHMgYW4gaXRlcmF0b3IKKiBvdmVyIHRoZSBzb3VyY2UgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbGxhdG9yCiovCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzRGF0YU93bmVkXyhUUlVFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICAgIHJldHVybjsKICB9CiAKICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZVRleHQubGVuZ3RoKCk7CiAgVUNoYXIgKnN0cmluZyA9IE5VTEw7CiAgCiAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIgKiBsZW5ndGgpOwogICAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICAgIGlmIChzdHJpbmcgPT0gTlVMTCkgewogICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgIHJldHVybjsKICAgICAgfQogICAgICAvKiAKICAgICAgVXNpbmcgdGhpcyBjb25zdHJ1Y3RvciB3aWxsIHByZXZlbnQgYnVmZmVyIGZyb20gYmVpbmcgcmVtb3ZlZCB3aGVuCiAgICAgIHN0cmluZyBnZXRzIHJlbW92ZWQKICAgICAgKi8KICAgICAgdV9tZW1jcHkoc3RyaW5nLCBzb3VyY2VUZXh0LmdldEJ1ZmZlcigpLCBsZW5ndGgpOwogIH0KICBlbHNlIHsKICAgICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIpOwogICAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICAgIGlmIChzdHJpbmcgPT0gTlVMTCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgICpzdHJpbmcgPSAwOwogIH0KICBtX2RhdGFfID0gdWNvbF9vcGVuRWxlbWVudHMob3JkZXItPnVjb2xsYXRvciwgc3RyaW5nLCBsZW5ndGgsICZzdGF0dXMpOwogIAogIC8qIFRlc3QgZm9yIGJ1ZmZlciBvdmVyZmxvd3MgKi8KICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7Cn0KCi8qKiAKKiBUaGlzIGlzIHRoZSAicmVhbCIgY29uc3RydWN0b3IgZm9yIHRoaXMgY2xhc3M7IGl0IGNvbnN0cnVjdHMgYW4gaXRlcmF0b3Igb3ZlciAKKiB0aGUgc291cmNlIHRleHQgdXNpbmcgdGhlIHNwZWNpZmllZCBjb2xsYXRvcgoqLwpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc0RhdGFPd25lZF8oVFJVRSkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKICAgIAogIC8vICoqKiogc2hvdWxkIEkganVzdCBkcm9wIHRoaXMgdGVzdD8gKioqKgogIC8qCiAgaWYgKCBzb3VyY2VUZXh0LmVuZEluZGV4KCkgIT0gMCApCiAgewogICAgLy8gQSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXMgcmVhbGx5IGEgdHdvLWxheWVyZWQgYmVhc3QuCiAgICAvLyBJbnRlcm5hbGx5IGl0IHVzZXMgYSBOb3JtYWxpemVyIHRvIG11bmdlIHRoZSBzb3VyY2UgdGV4dCBpbnRvIGEgZm9ybSAKICAgIC8vIHdoZXJlIGFsbCAiY29tcG9zZWQiIFVuaWNvZGUgY2hhcmFjdGVycyAoc3VjaCBhcyD8KSBhcmUgc3BsaXQgaW50byBhIAogICAgLy8gbm9ybWFsIGNoYXJhY3RlciBhbmQgYSBjb21iaW5pbmcgYWNjZW50IGNoYXJhY3Rlci4gIAogICAgLy8gQWZ0ZXJ3YXJkLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgZG9lcyBpdHMgb3duIHByb2Nlc3NpbmcgdG8gaGFuZGxlCiAgICAvLyBleHBhbmRpbmcgYW5kIGNvbnRyYWN0aW5nIGNvbGxhdGlvbiBzZXF1ZW5jZXMsIGlnbm9yYWJsZXMsIGFuZCBzbyBvbi4KICAgIAogICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wID0gb3JkZXItPmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBOb3JtYWxpemVyOjpOT19PUCA6IG9yZGVyLT5nZXREZWNvbXBvc2l0aW9uKCk7CiAgICAgIAogICAgdGV4dCA9IG5ldyBOb3JtYWxpemVyKHNvdXJjZVRleHQsIGRlY29tcCk7CiAgICBpZiAodGV4dCA9PSBOVUxMKQogICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOyAgICAKICB9CiAgKi8KICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZVRleHQuZ2V0TGVuZ3RoKCk7CiAgVUNoYXIgKmJ1ZmZlcjsKICBpZiAobGVuZ3RoID4gMCkgewogICAgICBidWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgLyogCiAgICAgIFVzaW5nIHRoaXMgY29uc3RydWN0b3Igd2lsbCBwcmV2ZW50IGJ1ZmZlciBmcm9tIGJlaW5nIHJlbW92ZWQgd2hlbgogICAgICBzdHJpbmcgZ2V0cyByZW1vdmVkCiAgICAgICovCiAgICAgIFVuaWNvZGVTdHJpbmcgc3RyaW5nKGJ1ZmZlciwgbGVuZ3RoLCBsZW5ndGgpOwogICAgICAoKENoYXJhY3Rlckl0ZXJhdG9yICYpc291cmNlVGV4dCkuZ2V0VGV4dChzdHJpbmcpOwogICAgICBjb25zdCBVQ2hhciAqdGVtcCA9IHN0cmluZy5nZXRCdWZmZXIoKTsKICAgICAgdV9tZW1jcHkoYnVmZmVyLCB0ZW1wLCBsZW5ndGgpOwogIH0KICBlbHNlIHsKICAgICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIpOwogICAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICAgIGlmIChidWZmZXIgPT0gTlVMTCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgICpidWZmZXIgPSAwOwogIH0KICBtX2RhdGFfID0gdWNvbF9vcGVuRWxlbWVudHMob3JkZXItPnVjb2xsYXRvciwgYnVmZmVyLCBsZW5ndGgsICZzdGF0dXMpOwoKICAvKiBUZXN0IGZvciBidWZmZXIgb3ZlcmZsb3dzICovCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwp9CgovKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCmNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpvcGVyYXRvcj0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikKewogIGlmICh0aGlzICE9ICZvdGhlcikKICB7CiAgICAgIFVDb2xsYXRpb25FbGVtZW50cyAqdWNvbGVsZW0gICAgICA9IHRoaXMtPm1fZGF0YV87CiAgICAgIFVDb2xsYXRpb25FbGVtZW50cyAqb3RoZXJ1Y29sZWxlbSA9IG90aGVyLm1fZGF0YV87CiAgICAgIGNvbGxJdGVyYXRlICAgICAgICAqY29saXRlciAgICAgICA9ICYodWNvbGVsZW0tPml0ZXJhdG9yZGF0YV8pOwogICAgICBjb2xsSXRlcmF0ZSAgICAgICAgKm90aGVyY29saXRlciAgPSAmKG90aGVydWNvbGVsZW0tPml0ZXJhdG9yZGF0YV8pOwogICAgICBpbnQgICAgICAgICAgICAgICAgbGVuZ3RoICAgICAgICAgPSAwOwogICAgICAKICAgICAgLy8gY2hlY2tpbmcgb25seSBVQ09MX0lURVJfSEFTTEVOIGlzIG5vdCBlbm91Z2ggaGVyZSBhcyB3ZSBtYXkgYmUgaW4gCiAgICAgIC8vIHRoZSBub3JtYWxpemF0aW9uIGJ1ZmZlcgogICAgICBsZW5ndGggPSBvdGhlcmNvbGl0ZXItPmVuZHAgLSBvdGhlcmNvbGl0ZXItPnN0cmluZzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgIHVjb2xlbGVtLT5yZXNldF8gICAgICAgICA9IG90aGVydWNvbGVsZW0tPnJlc2V0XzsKICAgICAgdWNvbGVsZW0tPmlzV3JpdGFibGUgICAgID0gVFJVRTsKICAgIAogICAgICAvKiBjcmVhdGUgYSBkdXBsaWNhdGUgb2Ygc3RyaW5nICovCiAgICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgICBjb2xpdGVyLT5zdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhsZW5ndGggKiBVX1NJWkVPRl9VQ0hBUik7CiAgICAgICAgICBpZihjb2xpdGVyLT5zdHJpbmcgIT0gTlVMTCkgewogICAgICAgICAgICB1cHJ2X21lbWNweShjb2xpdGVyLT5zdHJpbmcsIG90aGVyY29saXRlci0+c3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggKiBVX1NJWkVPRl9VQ0hBUik7CiAgICAgICAgICB9IGVsc2UgeyAvLyBFcnJvcjogY291bGRuJ3QgYWxsb2NhdGUgbWVtb3J5LiBObyBjb3B5aW5nIHNob3VsZCBiZSBkb25lCiAgICAgICAgICAgIGxlbmd0aCA9IDA7CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgICBjb2xpdGVyLT5zdHJpbmcgPSBOVUxMOwogICAgICB9CgogICAgICAvKiBzdGFydCBhbmQgZW5kIG9mIHN0cmluZyAqLwogICAgICBjb2xpdGVyLT5lbmRwID0gY29saXRlci0+c3RyaW5nICsgbGVuZ3RoOwoKICAgICAgLyogaGFuZGxlIHdyaXRhYmxlIGJ1ZmZlciBoZXJlICovCiAgICAgIAogICAgICBpZiAob3RoZXJjb2xpdGVyLT5mbGFncyAmIFVDT0xfSVRFUl9JTk5PUk1CVUYpIHsKICAgICAgICAgIHVpbnQzMl90IHdsZW5ndGggPSB1X3N0cmxlbihvdGhlcmNvbGl0ZXItPndyaXRhYmxlQnVmZmVyKSArIDE7CiAgICAgICAgICBpZiAod2xlbmd0aCA8IGNvbGl0ZXItPndyaXRhYmxlQnVmU2l6ZSkgewogICAgICAgICAgICAgIHVwcnZfbWVtY3B5KGNvbGl0ZXItPnN0YWNrV3JpdGFibGVCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICBvdGhlcmNvbGl0ZXItPnN0YWNrV3JpdGFibGVCdWZmZXIsIAogICAgICAgICAgICAgICAgICAgICAgICBvdGhlcmNvbGl0ZXItPndyaXRhYmxlQnVmU2l6ZSAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIGlmIChjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciAhPSBjb2xpdGVyLT5zdGFja1dyaXRhYmxlQnVmZmVyKSB7CiAgICAgICAgICAgICAgICAgIHVwcnZfZnJlZShjb2xpdGVyLT53cml0YWJsZUJ1ZmZlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2MoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2xlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgICAgICBpZihjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB1cHJ2X21lbWNweShjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcmNvbGl0ZXItPndyaXRhYmxlQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2xlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgICAgICAgIGNvbGl0ZXItPndyaXRhYmxlQnVmU2l6ZSA9IHdsZW5ndGg7CiAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gRXJyb3I6IGNvdWxkbid0IGFsbG9jYXRlIG1lbW9yeSBmb3Igd3JpdGFibGVCdWZmZXIKICAgICAgICAgICAgICAgIGNvbGl0ZXItPndyaXRhYmxlQnVmU2l6ZSA9IDA7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CgogICAgICAvKiBjdXJyZW50IHBvc2l0aW9uICovCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPnBvcyA+PSBvdGhlcmNvbGl0ZXItPnN0cmluZyAmJiAKICAgICAgICAgIG90aGVyY29saXRlci0+cG9zIDw9IG90aGVyY29saXRlci0+ZW5kcCkgewogICAgICAgICAgY29saXRlci0+cG9zID0gY29saXRlci0+c3RyaW5nICsgCiAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPnBvcyAtIG90aGVyY29saXRlci0+c3RyaW5nKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBjb2xpdGVyLT5wb3MgPSBjb2xpdGVyLT53cml0YWJsZUJ1ZmZlciArIAogICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT5wb3MgLSBvdGhlcmNvbGl0ZXItPndyaXRhYmxlQnVmZmVyKTsKICAgICAgfQoKICAgICAgLyogQ0UgYnVmZmVyICovCiAgICAgIHVwcnZfbWVtY3B5KGNvbGl0ZXItPkNFcywgb3RoZXJjb2xpdGVyLT5DRXMsIAogICAgICAgICAgICAgICAgICBVQ09MX0VYUEFORF9DRV9CVUZGRVJfU0laRSAqIHNpemVvZih1aW50MzJfdCkpOwogICAgICBjb2xpdGVyLT50b1JldHVybiA9IGNvbGl0ZXItPkNFcyArIAogICAgICAgICAgICAgICAgICAgICAgICAgKG90aGVyY29saXRlci0+dG9SZXR1cm4gLSBvdGhlcmNvbGl0ZXItPkNFcyk7CiAgICAgIGNvbGl0ZXItPkNFcG9zICAgID0gY29saXRlci0+Q0VzICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT5DRXBvcyAtIG90aGVyY29saXRlci0+Q0VzKTsKICAgIAogICAgICBpZiAob3RoZXJjb2xpdGVyLT5mY2RQb3NpdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgICBjb2xpdGVyLT5mY2RQb3NpdGlvbiA9IGNvbGl0ZXItPnN0cmluZyArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT5mY2RQb3NpdGlvbiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gb3RoZXJjb2xpdGVyLT5zdHJpbmcpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgICAgY29saXRlci0+ZmNkUG9zaXRpb24gPSBOVUxMOwogICAgICB9CiAgICAgIGNvbGl0ZXItPmZsYWdzICAgICAgID0gb3RoZXJjb2xpdGVyLT5mbGFncy8qfCBVQ09MX0lURVJfSEFTTEVOKi87CiAgICAgIGNvbGl0ZXItPm9yaWdGbGFncyAgID0gb3RoZXJjb2xpdGVyLT5vcmlnRmxhZ3M7CiAgICAgIGNvbGl0ZXItPmNvbGwgPSBvdGhlcmNvbGl0ZXItPmNvbGw7CiAgICAgIHRoaXMtPmlzRGF0YU93bmVkXyA9IFRSVUU7CiAgfQoKICByZXR1cm4gKnRoaXM7Cn0KClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmIC8qICNpZiAhVUNPTkZJR19OT19DT0xMQVRJT04gKi8KCi8qIGVvZiAqLwo=