LyogQ29weXJpZ2h0IChDKSAyMDExLTIwMTIgSHVtYXggQ28uLCBMdGQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIEh1bWF4IENvLiwgTHRkLiAoIkh1bWF4IikgaGVyZWJ5IHByb3ZpZGVzIHBlcm1pc3Npb24sIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkKICogcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb3VyY2UgY29kZSwgdG8gdXNlIGFuZCByZWRpc3RyaWJ1dGUgdGhpcwogKiBzb3VyY2UgY29kZSB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2YgdGhpcyBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqIG5vdGljZSwgcGVybWlzc2lvbiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nCiAqIGRpc2NsYWltZXIuCiAqCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogcGVybWlzc2lvbiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KICogdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgSFVNQVggIkFTIElTIiBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAogKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQUNDVVJBQ1ksIENPTVBMRVRFTkVTUywKICogQ1VSUkVOQ1ksIEFWQUlMQUJJTElUWSwgVElUTEUgT1IgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgSFVNQVggT1IKICogQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsCiAqIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywKICogUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7CiAqIE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLAogKiBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUgogKiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSElTCiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKgogKiBUaGUgdmlld3MgYW5kIGNvbmNsdXNpb24gY29udGFpbmVkIGluIHRoZSBzb2Z0d2FyZSBhbmQgZG9jdW1lbnRhdGlvbiBhcmUKICogdGhvc2Ugb2YgdGhlIGF1dGhvcnMgYW5kIHNob3VsZCBub3QgYmUgaW50ZXJwcmV0ZWQgYXMgcmVwcmVzZW50aW5nIG9mZmljaWFsCiAqIHBvbGljaWVzLCBlaXRoZXIgZXhwcmVzc2VkIG9yIGltcGxpZWQsIG9mIEh1bWF4LgogKgogKiBOb3R3aXRoc3RhbmRpbmcgdGhlIGFib3ZlLCB1bmRlciBubyBjaXJjdW1zdGFuY2VzIG1heSB5b3UgY29tYmluZSB0aGlzCiAqIHNvZnR3YXJlIGluIGFueSB3YXkgd2l0aCBhbnkgb3RoZXIgSHVtYXi/cyBzb2Z0d2FyZSBwcm92aWRlZCB1bmRlciBhIGxpY2Vuc2UKICogb3RoZXIgdGhhbiB0aGUgYWJvdmUgbGljZW5zZSwgd2l0aG91dCBIdW1heCdzIGV4cHJlc3MgcHJpb3Igd3JpdHRlbiBjb25zZW50LgogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqIEZpbGUgRGVzY3JpcHRpb24gKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogRmlsZSBOYW1lOiAgICAgICAgICAgJFdvcmtmaWxlOiAgIGhteF91cHJhZGVfZmxhc2guYyAgJAogKiBWZXJzaW9uOiAgICAgICAgICAgICAkUmV2aXNpb246ICAgMS4wICAkCiAqIE9yaWdpbmFsIEF1dGhvcjogICAgIFlhbmcgSHl1biBVayAkCiAqIEN1cnJlbnQgQXV0aG9yOiAgICAgICRBdXRob3I6IGh1eWFuZ0BodW1heGRpZ2l0YWwuY29tICQKICogRGF0ZTogICAgICAgICAgICAgICAgJERhdGU6IDIwMTEuMDkuMzAKICogRmlsZSBEZXNjcmlwdGlvbjogICAgSHVtYXggVXBncmFkZSBBUElzCiAqIE1vZHVsZToKICogUmVtYXJrczoKICovCgovKioKICogQGRlZmdyb3VwIFVQR1JBREVfRkxBU0ggRmxhc2hpbmcgQVBJcyBmb3IgVXBncmFkZSBNb2R1bGUKICogQGluZ3JvdXAgVVBHUkFERQogKgogKi8KCi8qKgogKiBAYXV0aG9yIEh5dW51ayBZYW5nKGh1eWFuZ0BodW1heGRpZ2l0YWwuY29tKQogKiBAZGF0ZSAzMCBTZXB0IDIwMTEKICovCgogLypAeyovCgovKioKICogQGZpbGUgaG14X3VwZ3JhZGVfZmxhc2guYwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBIZWFkZXIgRmlsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IEluY2x1ZGluZyBIZWFkZXIgRmlsZXMgKi8KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDxzeXMvbW91bnQuaD4KI2luY2x1ZGUgPG10ZC9tdGQtdXNlci5oPgovKiBFbmQgSW5jbHVkaW5nIEhlYWRlcnMgKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBkZWZpbmUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBTdGFydCAjZGVmaW5lICovCiNkZWZpbmUgSE5WUkFNX1BBUlRJVElPTl9ERUZBVUxUICAgICAgICAiL2Rldi9tdGQvaG52cmFtIgovKiBFbmQgI2RlZmluZSAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogdHlwZWRlZiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogU3RhcnQgdHlwZWRlZiAqLwovKiBFbmQgdHlwZWRlZiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqIGdsb2JhbCB2YXJpYWJsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IGdsb2JhbCB2YXJpYWJsZSAqLwppbnQgbGlidXBncmFkZV92ZXJib3NlID0gMTsKLyogRW5kIGdsb2JhbCB2YXJpYWJsZSAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqIHN0YXRpYyB2YXJpYWJsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IHN0YXRpYyB2YXJpYWJsZSAqLwpzdGF0aWMgY29uc3QgY2hhciAqaG52cmFtX3BhcnRpdGlvbiA9IEhOVlJBTV9QQVJUSVRJT05fREVGQVVMVDsKLyogRW5kIHN0YXRpYyB2YXJpYWJsZSAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKiogc3RhdGljIGZ1bnRpb25zICoqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBITVhfVVBHUkFERV9OVlJBTV9Jbml0KGNvbnN0IGNoYXIgKiBsb2NhdGlvbikKewogIGlmIChsb2NhdGlvbiA9PSBOVUxMKSB7CiAgICBobnZyYW1fcGFydGl0aW9uID0gSE5WUkFNX1BBUlRJVElPTl9ERUZBVUxUOwogIH0gZWxzZSB7CiAgICBobnZyYW1fcGFydGl0aW9uID0gbG9jYXRpb247CiAgfQp9Cgpjb25zdCBjaGFyKiBITVhfVVBHUkFERV9OVlJBTV9HZXRfUGFydGl0aW9uX1BhdGgodm9pZCkKewogIHJldHVybiBobnZyYW1fcGFydGl0aW9uOwp9CgppbnQgSE1YX1VQR1JBREVfTlZSQU1fV3JpdGUodW5zaWduZWQgbG9uZyBvZmZzZXQsIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHNpemUgKQp7CiAgaW50IHJldDsKICB2b2lkICpidWY7CiAgY2hhciAqcnBhdGg7CiAgY2hhciAqcDsKICBpbnQgZmRfbnZyYW07CgogIGlmIChsaWJ1cGdyYWRlX3ZlcmJvc2UpIHByaW50ZigiWyVzXSBvZmZzZXQgJTA4bHgsIHNpemUgJWQsIGRhdGEgPSAlMDJ4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0ZVTkNUSU9OX18sIG9mZnNldCwgc2l6ZSwgZGF0YVswXSApOwoKICBidWYgPSBtYWxsb2Moc2l6ZSk7CiAgaWYgKCFidWYpIHsKICAgIHBlcnJvcigibWFsbG9jIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBycGF0aCA9IHJlYWxwYXRoKGhudnJhbV9wYXJ0aXRpb24sIE5VTEwpOwogIGlmICghcnBhdGgpIHsKICAgIHBlcnJvcigicmVhbHBhdGgiKTsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CgogIGZkX252cmFtID0gb3BlbihycGF0aCwgKE9fUkRXUiB8IE9fU1lOQykpOwogIGlmIChmZF9udnJhbSA8IDApIHsKICAgIHJldCA9IC0xOwogICAgcGVycm9yKHJwYXRoKTsKICAgIGdvdG8gb3V0X2ZyZWU7CiAgfQoKICByZXQgPSBsc2VlayhmZF9udnJhbSwgb2Zmc2V0LCBTRUVLX1NFVCk7CiAgaWYgKHJldCA8IDApIHsKICAgIHBlcnJvcigibHNlZWsiKTsKICAgIGdvdG8gb3V0X2Nsb3NlOwogIH0KCiAgcmV0ID0gcmVhZChmZF9udnJhbSwgYnVmLCBzaXplKTsKICBpZiAocmV0IDwgMCkgewogICAgcGVycm9yKCJyZWFkIik7CiAgICBnb3RvIG91dF9jbG9zZTsKICB9CgogIC8qIE9ubHkgd3JpdGUgdG8gZmxhc2ggaWYgZGF0YSBpcyBkaWZmZXJlbnQgZnJvbSB3aGF0IGlzIGFscmVhZHkgdGhlcmUuICovCiAgaWYgKCh1bnNpZ25lZCBpbnQpcmV0ID09IHNpemUgJiYgIW1lbWNtcChkYXRhLCBidWYsIHNpemUpKSB7CiAgICByZXQgPSAwOwogICAgZ290byBvdXRfY2xvc2U7CiAgfQoKICByZXQgPSBsc2VlayhmZF9udnJhbSwgb2Zmc2V0LCBTRUVLX1NFVCk7CiAgaWYgKHJldCA8IDApIHsKICAgIHBlcnJvcigibHNlZWsiKTsKICAgIGdvdG8gb3V0X2Nsb3NlOwogIH0KCiAgcmV0ID0gd3JpdGUoZmRfbnZyYW0sIGRhdGEsIHNpemUpOwogIGlmIChyZXQgPCAwKSB7CiAgICBwZXJyb3IoIndyaXRlIik7CiAgICBnb3RvIG91dF9jbG9zZTsKICB9CgogIC8qCiAgICogSWYgaG52cmFtIGlzIG9uIE1NQyBwYXJ0aXRpb24sIHdlIGNhbm5vdCBmbHVzaCB0aGUgcGFydGl0aW9uLgogICAqIEluc3RlYWQsIHdlIG5lZWQgdG8gZmx1c2ggdGhlIGVudGlyZSBNTUMgZGV2aWNlLgogICAqIEZvciBleGFtcGxlLCBHRkNIMTAwIGhudnJhbSBwYXJ0aXRpb24gaXMgYXQgL2Rldi9tbWNibGswcDEsCiAgICogc28gd2UgbmVlZCB0byBmbHVzaCAvZGV2L21tY2JsazAuCiAgICovCiAgcCA9IHN0cnN0cihycGF0aCwgIm1tY2JsayIpOwogIGlmIChwKSB7CiAgICBwID0gc3RyY2hyKHAgKyA2LCAncCcpOwogICAgaWYgKHApIHsKICAgICAgKnAgPSAnXDAnOwogICAgICBjbG9zZShmZF9udnJhbSk7CiAgICAgIGZkX252cmFtID0gb3BlbihycGF0aCwgKE9fUkRXUiB8IE9fU1lOQykpOwogICAgICBpZiAoZmRfbnZyYW0gPCAwKSB7CiAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgcGVycm9yKHJwYXRoKTsKICAgICAgICBnb3RvIG91dF9mcmVlOwogICAgICB9CiAgICB9CiAgfQoKICAvKgogICAqIEJMS0ZMU0JVRiB3aWxsIGZhaWwgaWYgd2UgYXJlIHdyaXRpbmcgdG8gYSBmaWxlICgtZikgaW5zdGVhZCBvZiBhIGRldmljZQogICAqIElmIHJlYWxwYXRoIGlzIHVuZGVyIC9kZXYsIHRoZW4gd2UgYXJlIHdyaXRpbmcgdG8gYSBkZXZpY2UgYW5kIGNhbiBwcm9jZWVkCiAgICovCiAgaWYgKHN0cm5jbXAocnBhdGgsICIvZGV2LyIsIDUpID09IDApIHsKICAgIC8qCiAgICAgKiBXcml0ZXMgdG8gL2Rldi9tdGRibG9ja1ggYXJlIGNhY2hlZCBpbmRlZmluaXRlbHkgdW50aWwgdGhlIGxhc3QgZmlsZQogICAgICogZGVzY3JpcHRvciBpcyBjbG9zZWQuIEZsdXNoIHRoaXMgY2FjaGUgYWZ0ZXIgd3JpdGluZy4gVGhlIHVzZXIgZGVwZW5kcyBvbgogICAgICogZGF0YSBiZWluZyBwaHlzaWNhbGx5IHdyaXR0ZW4gdG8gZmxhc2ggd2hlbiB0aGlzIGZ1bmN0aW9uIHJldHVybnMuCiAgICAgKiBSZXF1aXJlcyBDQVBfU1lTX0FETUlOLgogICAgICovCiAgICByZXQgPSBpb2N0bChmZF9udnJhbSwgQkxLRkxTQlVGLCAwKTsKICAgIGlmIChyZXQgPCAwKSB7CiAgICAgIHBlcnJvcigiaW9jdGwoaG52cmFtLCBCTEtGTFNCVUYsIDApIik7CiAgICAgIGdvdG8gb3V0X2Nsb3NlOwogICAgfQogIH0KCiAgcmV0ID0gMDsKCm91dF9jbG9zZToKICBjbG9zZShmZF9udnJhbSk7Cm91dF9mcmVlOgogIGZyZWUocnBhdGgpOwogIGZyZWUoYnVmKTsKICByZXR1cm4gcmV0Owp9CgppbnQgSE1YX1VQR1JBREVfTlZSQU1fUmVhZCh1bnNpZ25lZCBsb25nIG9mZnNldCwgdW5zaWduZWQgY2hhciAqIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBzaXplICkKewogIGNoYXIgKnJwYXRoOwogIGludCBmZF9udnJhbTsKICBpbnQgcmV0OwoKICBpZiAobGlidXBncmFkZV92ZXJib3NlKSBwcmludGYoIlslc10gb2Zmc2V0ICUwOGx4LCBzaXplICVkLCBkYXRhID0gJTAyeFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19GVU5DVElPTl9fLCBvZmZzZXQsIHNpemUsIGRhdGFbMF0gKTsKCiAgcnBhdGggPSByZWFscGF0aChobnZyYW1fcGFydGl0aW9uLCBOVUxMKTsKICBpZiAoIXJwYXRoKSB7CiAgICBwZXJyb3IoInJlYWxwYXRoIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBmZF9udnJhbSA9IG9wZW4ocnBhdGgsIChPX1JEV1IgfCBPX1NZTkMpKTsKICBpZiAoZmRfbnZyYW0gPCAwKSB7CiAgICByZXQgPSAtMTsKICAgIHBlcnJvcihycGF0aCk7CiAgICBnb3RvIG91dF9mcmVlOwogIH0KCiAgcmV0ID0gbHNlZWsoZmRfbnZyYW0sIG9mZnNldCwgU0VFS19TRVQpOwogIGlmIChyZXQgPCAwKSB7CiAgICBwZXJyb3IoImxzZWVrIik7CiAgICBnb3RvIG91dF9jbG9zZTsKICB9CgogIHJldCA9IHJlYWQoZmRfbnZyYW0sIGRhdGEsIHNpemUpOwogIGlmIChyZXQgPCAwKSB7CiAgICBwZXJyb3IoInJlYWQiKTsKICAgIGdvdG8gb3V0X2Nsb3NlOwogIH0KCiAgcmV0ID0gMDsKCm91dF9jbG9zZToKICBjbG9zZShmZF9udnJhbSk7Cm91dF9mcmVlOgogIGZyZWUocnBhdGgpOwogIHJldHVybiByZXQ7Cn0KCgovKkB9Ki8K