LyogRGlyZWN0RHJhd0dhbW1hQ29udHJvbCBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGRyYXdfdGh1bmspOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVVua25vd24gcGFydHMgZm9sbG93CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2w6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJ5SW50ZXJmYWNlLCB0aHVua3MgdG8gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHJpaWQ6IEludGVyZmFjZSBpZCBxdWVyaWVkIGZvcgogKiAgb2JqOiBSZXR1cm5zIHRoZSBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBSZXR1cm5zOgogKiAgU19PSyBvciBFX05PSU5URVJGQUNFOiBTZWUgSURpcmVjdERyYXdTdXJmYWNlNzo6UXVlcnlJbnRlcmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfUXVlcnlJbnRlcmZhY2UoSURpcmVjdERyYXdHYW1tYUNvbnRyb2wgKmlmYWNlLCBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXMsJXApOiBUaHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3XG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2U3X1F1ZXJ5SW50ZXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3R2FtbWFDb250cm9sOjpBZGRSZWYKICoKICogQWRkcmVmLCB0aHVua3MgdG8gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9BZGRSZWYoSURpcmVjdERyYXdHYW1tYUNvbnRyb2wgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgVGh1bmtpbmcgdG8gSURpcmVjdERyYXdTdXJmYWNlN1xuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2w6OlJlbGVhc2UKICoKICogUmVsZWFzZSwgdGh1bmtzIHRvIElEaXJlY3REcmF3U3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfUmVsZWFzZShJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSBUaHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3XG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2wKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbDo6R2V0R2FtbWFSYW1wCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgZ2FtbWEgcmFtcCBmb3IgYSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBJZ25vcmVkCiAqICBHYW1tYVJhbXA6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHJhbXAgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgR2FtbWFSYW1wIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfR2V0R2FtbWFSYW1wKElEaXJlY3REcmF3R2FtbWFDb250cm9sICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEREdBTU1BUkFNUCAqR2FtbWFSYW1wKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcyxGbGFncyxHYW1tYVJhbXApOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoIUdhbW1hUmFtcCkKICAgIHsKICAgICAgICBFUlIoIiglcCkgR2FtbWFSYW1wIGlzIE5VTEwsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkKICAgIHsKICAgICAgICAvKiBOb3RlOiBEREdBTU1BUkFNUCBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzREdBTU1BUkFNUCAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX0dldEdhbW1hUmFtcChUaGlzLT5kZHJhdy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTd2FwY2hhaW4gKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNER0FNTUFSQU1QICopIEdhbW1hUmFtcCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFVuaW1wbGVtZW50ZWQgZm9yIG5vbi1wcmltYXJ5IHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbDo6U2V0R2FtbWFSYW1wCiAqCiAqIFNldHMgdGhlIHJlZCwgZ3JlZW4gYW5kIGJsdWUgZ2FtbWEgcmFtcHMgZm9yCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBDYW4gYmUgRERTR1JfQ0FMSUJSQVRFIHRvIHJlcXVlc3QgY2FsaWJyYXRpb24KICogIEdhbW1hUmFtcDogU3RydWN0dXJlIGNvbnRhaW5pbmcgdGhlIG5ldyBnYW1tYSByYW1wCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEdhbW1hUmFtcCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdHYW1tYUNvbnRyb2xJbXBsX1NldEdhbW1hUmFtcChJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERHQU1NQVJBTVAgKkdhbW1hUmFtcCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdHYW1tYUNvbnRyb2wsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsRmxhZ3MsR2FtbWFSYW1wKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCFHYW1tYVJhbXApCiAgICB7CiAgICAgICAgRVJSKCIoJXApIEdhbW1hUmFtcCBpcyBOVUxMLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpCiAgICB7CgogICAgICAgIC8qIE5vdGU6IERER0FNTUFSQU1QIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNER0FNTUFSQU1QICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0R2FtbWFSYW1wKFRoaXMtPmRkcmF3LT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN3YXBjaGFpbiAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNER0FNTUFSQU1QICopIEdhbW1hUmFtcCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFVuaW1wbGVtZW50ZWQgZm9yIG5vbi1wcmltYXJ5IHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEREX09LOwp9Cgpjb25zdCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbFZ0YmwgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xfVnRibCA9CnsKICAgIElEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfUmVsZWFzZSwKICAgIElEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9HZXRHYW1tYVJhbXAsCiAgICBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfU2V0R2FtbWFSYW1wCn07Cg==