LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0yMDAzLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoKKiBGaWxlIGNvbGVpdHIuY3BwCioKKiAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA2LzIzLzk3ICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA4LzAzLzk4ICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhCiogMTIvMTAvOTkgICBhbGl1ICAgICAgICBQb3J0ZWQgVGhhaSBjb2xsYXRpb24gc3VwcG9ydCBmcm9tIEphdmEuCiogMDEvMjUvMDEgICBzd3F1ZWsgICAgICBNb2RpZmllZCB0byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29saXRlci5oKQoqIDAyLzE5LzAxICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBubyBjYWxscyBhcmUgbWFkZSB0byBpdAoqLwoKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCgojaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OCgojaW5jbHVkZSAidW5pY29kZS9jb2xlaXRyLmgiCiNpbmNsdWRlICJ1bmljb2RlL3VzdHJpbmcuaCIKI2luY2x1ZGUgInVjb2xfaW1wLmgiCiNpbmNsdWRlICJjbWVtb3J5LmgiCgoKLyogQ29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVV9OQU1FU1BBQ0VfQkVHSU4KClVPQkpFQ1RfREVGSU5FX1JUVElfSU1QTEVNRU5UQVRJT04oQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKQoKLyogc3lud2VlIDogcHVibGljIGNhbid0IHJlbW92ZSAqLwppbnQzMl90IGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSID0gMHhmZmZmZmZmZjsKCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwdWJsaWMgY29uc3RydWN0b3IvZGVzdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogVU9iamVjdChvdGhlciksIGlzRGF0YU93bmVkXyhUUlVFKQp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgbV9kYXRhXyA9IHVjb2xfb3BlbkVsZW1lbnRzKG90aGVyLm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbCwgTlVMTCwgMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGF0dXMpOwoKICAqdGhpcyA9IG90aGVyOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6On5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQp7CiAgaWYgKGlzRGF0YU93bmVkXykgewogICAgdWNvbF9jbG9zZUVsZW1lbnRzKG1fZGF0YV8pOwogIH0KfQoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE9mZnNldCgpIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRPZmZzZXQobV9kYXRhXyk7Cn0KCi8qKgoqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiogQHJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgYW4gZXJyb3IgaGFzIAoqICAgICAgICAgb2NjdXJlZCBvciBpZiB0aGUgZW5kIG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KFVFcnJvckNvZGUmIHN0YXR1cykKewogIHJldHVybiB1Y29sX25leHQobV9kYXRhXywgJnN0YXR1cyk7Cn0KClVCb29sIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3IhPSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIGNvbnN0CnsKICByZXR1cm4gISgqdGhpcyA9PSBvdGhlcik7Cn0KClVCb29sIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3I9PSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiB0aGF0KSBjb25zdAp7CiAgICBpZiAodGhpcyA9PSAmdGhhdCkgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQogIAogICAgaWYgKG1fZGF0YV8gPT0gdGhhdC5tX2RhdGFfKSB7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLy8gb3B0aW9uIGNvbXBhcmlzb24KICAgIGlmIChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwgIT0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8vIHRoZSBjb25zdHJ1Y3RvciBhbmQgc2V0VGV4dCBhbHdheXMgc2V0cyBhIGxlbmd0aAogICAgLy8gYW5kIHdlIG9ubHkgY29tcGFyZSB0aGUgc3RyaW5nIG5vdCB0aGUgY29udGVudHMgb2YgdGhlIG5vcm1hbGl6YXRpb24KICAgIC8vIGJ1ZmZlcgogICAgaW50IHRoaXNsZW5ndGggPSBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmVuZHAgLQogICAgICAgICAgICAgICAgICAgICBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZzsKICAgIGludCB0aGF0bGVuZ3RoID0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmVuZHAgLQogICAgICAgICAgICAgICAgICAgICB0aGF0Lm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nOwogICAgCiAgICBpZiAodGhpc2xlbmd0aCAhPSB0aGF0bGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICh1cHJ2X21lbWNtcChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZywgCiAgICAgICAgICAgICAgICAgICAgdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZywgCiAgICAgICAgICAgICAgICAgICAgdGhpc2xlbmd0aCAqIFVfU0laRU9GX1VDSEFSKSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYgKGdldE9mZnNldCgpICE9IHRoYXQuZ2V0T2Zmc2V0KCkpIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLy8gY2hlY2tpbmcgbm9ybWFsaXphdGlvbiBidWZmZXIKICAgIGlmICgobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5mbGFncyAmIFVDT0xfSVRFUl9IQVNMRU4pID09IDApIHsKICAgICAgICBpZiAoKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uZmxhZ3MgJiBVQ09MX0lURVJfSEFTTEVOKSAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICAgICAgLy8gYm90aCBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyCiAgICAgICAgaWYgKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8ucG9zIAogICAgICAgICAgICAtIG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8ud3JpdGFibGVCdWZmZXIgCiAgICAgICAgICAgICE9IHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5wb3MgCiAgICAgICAgICAgIC0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLndyaXRhYmxlQnVmZmVyKSB7CiAgICAgICAgICAgIC8vIG5vdCBpbiB0aGUgc2FtZSBwb3NpdGlvbiBpbiB0aGUgbm9ybWFsaXphdGlvbiBidWZmZXIKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKChtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmZsYWdzICYgVUNPTF9JVEVSX0hBU0xFTikgPT0gMCkgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIC8vIGNoZWNraW5nIGNlIHBvc2l0aW9uCiAgICByZXR1cm4gKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uQ0Vwb3MgLSBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLkNFcykKICAgICAgICAgICAgPT0gKHRoYXQubV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5DRXBvcyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdGhhdC5tX2RhdGFfLT5pdGVyYXRvcmRhdGFfLkNFcyk7Cn0KCi8qKgoqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIHByZXZpb3VzIGNvbGxhdGlvbiBlbGVtZW50IGluIHRoZSBzdHJpbmcuCiogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCdzIG9yZGVyaW5nLiBSZXR1cm5zIE5VTExPUkRFUiBpZiBhbiBlcnJvciBoYXMgCiogICAgICAgICBvY2N1cmVkIG9yIGlmIHRoZSBzdGFydCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZC4KKi8KaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cykKewogIHJldHVybiB1Y29sX3ByZXZpb3VzKG1fZGF0YV8sICZzdGF0dXMpOwp9CgovKioKKiBSZXNldHMgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiovCnZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpyZXNldCgpCnsKICB1Y29sX3Jlc2V0KG1fZGF0YV8pOwp9Cgp2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2V0T2Zmc2V0KGludDMyX3QgbmV3T2Zmc2V0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICB1Y29sX3NldE9mZnNldChtX2RhdGFfLCBuZXdPZmZzZXQsICZzdGF0dXMpOwp9CgovKioKKiBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBzb3VyY2Ugc3RyaW5nLgoqLwp2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KCiAgaW50MzJfdCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoKCk7CiAgVUNoYXIgKnN0cmluZyA9IE5VTEw7CiAgaWYgKG1fZGF0YV8tPmlzV3JpdGFibGUgJiYgbV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5zdHJpbmcgIT0gTlVMTCkgewogICAgdXBydl9mcmVlKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uc3RyaW5nKTsKICB9CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7CiAgaWYgKGxlbmd0aCA+IDApIHsKICAgIHN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSICogbGVuZ3RoKTsKICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgIGlmIChzdHJpbmcgPT0gTlVMTCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdV9tZW1jcHkoc3RyaW5nLCBzb3VyY2UuZ2V0QnVmZmVyKCksIGxlbmd0aCk7CiAgfQogIGVsc2UgewogICAgc3RyaW5nID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIpOwogICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgaWYgKHN0cmluZyA9PSBOVUxMKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAqc3RyaW5nID0gMDsKICB9CiAgdXBydl9pbml0X2NvbGxJdGVyYXRlKG1fZGF0YV8tPml0ZXJhdG9yZGF0YV8uY29sbCwgc3RyaW5nLCBsZW5ndGgsIAogICAgICAgICAgICAgICAgICAgJm1fZGF0YV8tPml0ZXJhdG9yZGF0YV8pOwoKICBtX2RhdGFfLT5yZXNldF8gICA9IFRSVUU7Cn0KCi8vIFNldHMgdGhlIHNvdXJjZSB0byB0aGUgbmV3IGNoYXJhY3RlciBpdGVyYXRvci4Kdm9pZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgCiAgICByZXR1cm47CiAgICAKICBpbnQzMl90IGxlbmd0aCA9IHNvdXJjZS5nZXRMZW5ndGgoKTsKICBVQ2hhciAqYnVmZmVyID0gTlVMTDsKCiAgaWYgKGxlbmd0aCA9PSAwKSB7CiAgICBidWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUik7CiAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgICpidWZmZXIgPSAwOwogIH0KICBlbHNlIHsKICAgICAgYnVmZmVyID0gKFVDaGFyICopdXBydl9tYWxsb2MoVV9TSVpFT0ZfVUNIQVIgKiBsZW5ndGgpOwogICAgICAvKiB0ZXN0IGZvciBOVUxMICovCiAgICAgIGlmIChidWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgIHJldHVybjsKICAgICAgfQogICAgICAvKiAKICAgICAgVXNpbmcgdGhpcyBjb25zdHJ1Y3RvciB3aWxsIHByZXZlbnQgYnVmZmVyIGZyb20gYmVpbmcgcmVtb3ZlZCB3aGVuCiAgICAgIHN0cmluZyBnZXRzIHJlbW92ZWQKICAgICAgKi8KICAgICAgVW5pY29kZVN0cmluZyBzdHJpbmc7CiAgICAgIHNvdXJjZS5nZXRUZXh0KHN0cmluZyk7CiAgICAgIHVfbWVtY3B5KGJ1ZmZlciwgc3RyaW5nLmdldEJ1ZmZlcigpLCBsZW5ndGgpOwogIH0KICAKICBpZiAobV9kYXRhXy0+aXNXcml0YWJsZSAmJiBtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyAhPSBOVUxMKSB7CiAgICAgIHVwcnZfZnJlZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLnN0cmluZyk7CiAgfQogIG1fZGF0YV8tPmlzV3JpdGFibGUgPSBUUlVFOwogIHVwcnZfaW5pdF9jb2xsSXRlcmF0ZShtX2RhdGFfLT5pdGVyYXRvcmRhdGFfLmNvbGwsIGJ1ZmZlciwgbGVuZ3RoLCAKICAgICAgICAgICAgICAgICAgICZtX2RhdGFfLT5pdGVyYXRvcmRhdGFfKTsKICBtX2RhdGFfLT5yZXNldF8gICA9IFRSVUU7Cn0KCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICBVQ29sbGF0aW9uU3RyZW5ndGggcyA9IHVjb2xfZ2V0U3RyZW5ndGgobV9kYXRhXy0+aXRlcmF0b3JkYXRhXy5jb2xsKTsKICAvLyBNYXNrIG9mZiB0aGUgdW53YW50ZWQgZGlmZmVyZW5jZXMuCiAgaWYgKHMgPT0gVUNPTF9QUklNQVJZKSB7CiAgICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFk7CiAgfQogIGVsc2UgaWYgKHMgPT0gVUNPTF9TRUNPTkRBUlkpIHsKICAgICAgb3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZOwogIH0KICAgIAogIHJldHVybiBvcmRlcjsKfQoKLyogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgY29uc3RydWN0b3JzL2Rlc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tLSAqLwoKLyoqIAoqIFRoaXMgaXMgdGhlICJyZWFsIiBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzczsgaXQgY29uc3RydWN0cyBhbiBpdGVyYXRvcgoqIG92ZXIgdGhlIHNvdXJjZSB0ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWQgY29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogaXNEYXRhT3duZWRfKFRSVUUpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgICAgcmV0dXJuOwogIH0KIAogIGludDMyX3QgbGVuZ3RoID0gc291cmNlVGV4dC5sZW5ndGgoKTsKICBVQ2hhciAqc3RyaW5nID0gTlVMTDsKICAKICBpZiAobGVuZ3RoID4gMCkgewogICAgICBzdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUiAqIGxlbmd0aCk7CiAgICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgICAgaWYgKHN0cmluZyA9PSBOVUxMKSB7CiAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIC8qIAogICAgICBVc2luZyB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgcHJldmVudCBidWZmZXIgZnJvbSBiZWluZyByZW1vdmVkIHdoZW4KICAgICAgc3RyaW5nIGdldHMgcmVtb3ZlZAogICAgICAqLwogICAgICB1X21lbWNweShzdHJpbmcsIHNvdXJjZVRleHQuZ2V0QnVmZmVyKCksIGxlbmd0aCk7CiAgfQogIGVsc2UgewogICAgICBzdHJpbmcgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUik7CiAgICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgICAgaWYgKHN0cmluZyA9PSBOVUxMKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgKnN0cmluZyA9IDA7CiAgfQogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvcmRlci0+dWNvbGxhdG9yLCBzdHJpbmcsIGxlbmd0aCwgJnN0YXR1cyk7CiAgCiAgLyogVGVzdCBmb3IgYnVmZmVyIG92ZXJmbG93cyAqLwogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICBtX2RhdGFfLT5pc1dyaXRhYmxlID0gVFJVRTsKfQoKLyoqIAoqIFRoaXMgaXMgdGhlICJyZWFsIiBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzczsgaXQgY29uc3RydWN0cyBhbiBpdGVyYXRvciBvdmVyIAoqIHRoZSBzb3VyY2UgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbGxhdG9yCiovCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzRGF0YU93bmVkXyhUUlVFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogICAgCiAgLy8gKioqKiBzaG91bGQgSSBqdXN0IGRyb3AgdGhpcyB0ZXN0PyAqKioqCiAgLyoKICBpZiAoIHNvdXJjZVRleHQuZW5kSW5kZXgoKSAhPSAwICkKICB7CiAgICAvLyBBIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpcyByZWFsbHkgYSB0d28tbGF5ZXJlZCBiZWFzdC4KICAgIC8vIEludGVybmFsbHkgaXQgdXNlcyBhIE5vcm1hbGl6ZXIgdG8gbXVuZ2UgdGhlIHNvdXJjZSB0ZXh0IGludG8gYSBmb3JtIAogICAgLy8gd2hlcmUgYWxsICJjb21wb3NlZCIgVW5pY29kZSBjaGFyYWN0ZXJzIChzdWNoIGFzIPwpIGFyZSBzcGxpdCBpbnRvIGEgCiAgICAvLyBub3JtYWwgY2hhcmFjdGVyIGFuZCBhIGNvbWJpbmluZyBhY2NlbnQgY2hhcmFjdGVyLiAgCiAgICAvLyBBZnRlcndhcmQsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBkb2VzIGl0cyBvd24gcHJvY2Vzc2luZyB0byBoYW5kbGUKICAgIC8vIGV4cGFuZGluZyBhbmQgY29udHJhY3RpbmcgY29sbGF0aW9uIHNlcXVlbmNlcywgaWdub3JhYmxlcywgYW5kIHNvIG9uLgogICAgCiAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXAgPSBvcmRlci0+Z2V0U3RyZW5ndGgoKSA9PSBDb2xsYXRvcjo6SURFTlRJQ0FMCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5vcm1hbGl6ZXI6Ok5PX09QIDogb3JkZXItPmdldERlY29tcG9zaXRpb24oKTsKICAgICAgCiAgICB0ZXh0ID0gbmV3IE5vcm1hbGl6ZXIoc291cmNlVGV4dCwgZGVjb21wKTsKICAgIGlmICh0ZXh0ID09IE5VTEwpCiAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7ICAgIAogIH0KICAqLwogIGludDMyX3QgbGVuZ3RoID0gc291cmNlVGV4dC5nZXRMZW5ndGgoKTsKICBVQ2hhciAqYnVmZmVyOwogIGlmIChsZW5ndGggPiAwKSB7CiAgICAgIGJ1ZmZlciA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKFVfU0laRU9GX1VDSEFSICogbGVuZ3RoKTsKICAgICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICAvKiAKICAgICAgVXNpbmcgdGhpcyBjb25zdHJ1Y3RvciB3aWxsIHByZXZlbnQgYnVmZmVyIGZyb20gYmVpbmcgcmVtb3ZlZCB3aGVuCiAgICAgIHN0cmluZyBnZXRzIHJlbW92ZWQKICAgICAgKi8KICAgICAgVW5pY29kZVN0cmluZyBzdHJpbmcoYnVmZmVyLCBsZW5ndGgsIGxlbmd0aCk7CiAgICAgICgoQ2hhcmFjdGVySXRlcmF0b3IgJilzb3VyY2VUZXh0KS5nZXRUZXh0KHN0cmluZyk7CiAgICAgIGNvbnN0IFVDaGFyICp0ZW1wID0gc3RyaW5nLmdldEJ1ZmZlcigpOwogICAgICB1X21lbWNweShidWZmZXIsIHRlbXAsIGxlbmd0aCk7CiAgfQogIGVsc2UgewogICAgICBidWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYyhVX1NJWkVPRl9VQ0hBUik7CiAgICAgIC8qIHRlc3QgZm9yIE5VTEwgKi8KICAgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgKmJ1ZmZlciA9IDA7CiAgfQogIG1fZGF0YV8gPSB1Y29sX29wZW5FbGVtZW50cyhvcmRlci0+dWNvbGxhdG9yLCBidWZmZXIsIGxlbmd0aCwgJnN0YXR1cyk7CgogIC8qIFRlc3QgZm9yIGJ1ZmZlciBvdmVyZmxvd3MgKi8KICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CiAgbV9kYXRhXy0+aXNXcml0YWJsZSA9IFRSVUU7Cn0KCi8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yPSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKQp7CiAgaWYgKHRoaXMgIT0gJm90aGVyKQogIHsKICAgICAgVUNvbGxhdGlvbkVsZW1lbnRzICp1Y29sZWxlbSAgICAgID0gdGhpcy0+bV9kYXRhXzsKICAgICAgVUNvbGxhdGlvbkVsZW1lbnRzICpvdGhlcnVjb2xlbGVtID0gb3RoZXIubV9kYXRhXzsKICAgICAgY29sbEl0ZXJhdGUgICAgICAgICpjb2xpdGVyICAgICAgID0gJih1Y29sZWxlbS0+aXRlcmF0b3JkYXRhXyk7CiAgICAgIGNvbGxJdGVyYXRlICAgICAgICAqb3RoZXJjb2xpdGVyICA9ICYob3RoZXJ1Y29sZWxlbS0+aXRlcmF0b3JkYXRhXyk7CiAgICAgIGludCAgICAgICAgICAgICAgICBsZW5ndGggICAgICAgICA9IDA7CiAgICAgIAogICAgICAvLyBjaGVja2luZyBvbmx5IFVDT0xfSVRFUl9IQVNMRU4gaXMgbm90IGVub3VnaCBoZXJlIGFzIHdlIG1heSBiZSBpbiAKICAgICAgLy8gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyCiAgICAgIGxlbmd0aCA9IG90aGVyY29saXRlci0+ZW5kcCAtIG90aGVyY29saXRlci0+c3RyaW5nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgdWNvbGVsZW0tPnJlc2V0XyAgICAgICAgID0gb3RoZXJ1Y29sZWxlbS0+cmVzZXRfOwogICAgICB1Y29sZWxlbS0+aXNXcml0YWJsZSAgICAgPSBUUlVFOwogICAgCiAgICAgIC8qIGNyZWF0ZSBhIGR1cGxpY2F0ZSBvZiBzdHJpbmcgKi8KICAgICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICAgIGNvbGl0ZXItPnN0cmluZyA9IChVQ2hhciAqKXVwcnZfbWFsbG9jKGxlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgIGlmKGNvbGl0ZXItPnN0cmluZyAhPSBOVUxMKSB7CiAgICAgICAgICAgIHVwcnZfbWVtY3B5KGNvbGl0ZXItPnN0cmluZywgb3RoZXJjb2xpdGVyLT5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCAqIFVfU0laRU9GX1VDSEFSKTsKICAgICAgICAgIH0gZWxzZSB7IC8vIEVycm9yOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkuIE5vIGNvcHlpbmcgc2hvdWxkIGJlIGRvbmUKICAgICAgICAgICAgbGVuZ3RoID0gMDsKICAgICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAgIGNvbGl0ZXItPnN0cmluZyA9IE5VTEw7CiAgICAgIH0KCiAgICAgIC8qIHN0YXJ0IGFuZCBlbmQgb2Ygc3RyaW5nICovCiAgICAgIGNvbGl0ZXItPmVuZHAgPSBjb2xpdGVyLT5zdHJpbmcgKyBsZW5ndGg7CgogICAgICAvKiBoYW5kbGUgd3JpdGFibGUgYnVmZmVyIGhlcmUgKi8KICAgICAgCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPmZsYWdzICYgVUNPTF9JVEVSX0lOTk9STUJVRikgewogICAgICAgICAgdWludDMyX3Qgd2xlbmd0aCA9IHVfc3RybGVuKG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIpICsgMTsKICAgICAgICAgIGlmICh3bGVuZ3RoIDwgY29saXRlci0+d3JpdGFibGVCdWZTaXplKSB7CiAgICAgICAgICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+c3RhY2tXcml0YWJsZUJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+c3RhY2tXcml0YWJsZUJ1ZmZlciwgCiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZTaXplICogVV9TSVpFT0ZfVUNIQVIpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyICE9IGNvbGl0ZXItPnN0YWNrV3JpdGFibGVCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgdXBydl9mcmVlKGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY29saXRlci0+d3JpdGFibGVCdWZmZXIgPSAoVUNoYXIgKil1cHJ2X21hbGxvYygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bGVuZ3RoICogVV9TSVpFT0ZfVUNIQVIpOwogICAgICAgICAgICAgIGlmKGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHVwcnZfbWVtY3B5KGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bGVuZ3RoICogVV9TSVpFT0ZfVUNIQVIpOwogICAgICAgICAgICAgICAgY29saXRlci0+d3JpdGFibGVCdWZTaXplID0gd2xlbmd0aDsKICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBFcnJvcjogY291bGRuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciB3cml0YWJsZUJ1ZmZlcgogICAgICAgICAgICAgICAgY29saXRlci0+d3JpdGFibGVCdWZTaXplID0gMDsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIGN1cnJlbnQgcG9zaXRpb24gKi8KICAgICAgaWYgKG90aGVyY29saXRlci0+cG9zID49IG90aGVyY29saXRlci0+c3RyaW5nICYmIAogICAgICAgICAgb3RoZXJjb2xpdGVyLT5wb3MgPD0gb3RoZXJjb2xpdGVyLT5lbmRwKSB7CiAgICAgICAgICBjb2xpdGVyLT5wb3MgPSBjb2xpdGVyLT5zdHJpbmcgKyAKICAgICAgICAgICAgICAgICAgICAgICAgKG90aGVyY29saXRlci0+cG9zIC0gb3RoZXJjb2xpdGVyLT5zdHJpbmcpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIGNvbGl0ZXItPnBvcyA9IGNvbGl0ZXItPndyaXRhYmxlQnVmZmVyICsgCiAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPnBvcyAtIG90aGVyY29saXRlci0+d3JpdGFibGVCdWZmZXIpOwogICAgICB9CgogICAgICAvKiBDRSBidWZmZXIgKi8KICAgICAgdXBydl9tZW1jcHkoY29saXRlci0+Q0VzLCBvdGhlcmNvbGl0ZXItPkNFcywgCiAgICAgICAgICAgICAgICAgIFVDT0xfRVhQQU5EX0NFX0JVRkZFUl9TSVpFICogc2l6ZW9mKHVpbnQzMl90KSk7CiAgICAgIGNvbGl0ZXItPnRvUmV0dXJuID0gY29saXRlci0+Q0VzICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAob3RoZXJjb2xpdGVyLT50b1JldHVybiAtIG90aGVyY29saXRlci0+Q0VzKTsKICAgICAgY29saXRlci0+Q0Vwb3MgICAgPSBjb2xpdGVyLT5DRXMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPkNFcG9zIC0gb3RoZXJjb2xpdGVyLT5DRXMpOwogICAgCiAgICAgIGlmIChvdGhlcmNvbGl0ZXItPmZjZFBvc2l0aW9uICE9IE5VTEwpIHsKICAgICAgICAgIGNvbGl0ZXItPmZjZFBvc2l0aW9uID0gY29saXRlci0+c3RyaW5nICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdGhlcmNvbGl0ZXItPmZjZFBvc2l0aW9uIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBvdGhlcmNvbGl0ZXItPnN0cmluZyk7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgICBjb2xpdGVyLT5mY2RQb3NpdGlvbiA9IE5VTEw7CiAgICAgIH0KICAgICAgY29saXRlci0+ZmxhZ3MgICAgICAgPSBvdGhlcmNvbGl0ZXItPmZsYWdzLyp8IFVDT0xfSVRFUl9IQVNMRU4qLzsKICAgICAgY29saXRlci0+b3JpZ0ZsYWdzICAgPSBvdGhlcmNvbGl0ZXItPm9yaWdGbGFnczsKICAgICAgY29saXRlci0+Y29sbCA9IG90aGVyY29saXRlci0+Y29sbDsKICAgICAgdGhpcy0+aXNEYXRhT3duZWRfID0gVFJVRTsKICB9CgogIHJldHVybiAqdGhpczsKfQoKVV9OQU1FU1BBQ0VfRU5ECgojZW5kaWYgLyogI2lmICFVQ09ORklHX05PX0NPTExBVElPTiAqLwoKLyogZW9mICovCg==