LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAiZGJnaGVscF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRiZ2hlbHApOwoKZW51bSBzdF9tb2RlIHtzdG1fc3RhcnQsIHN0bV8zMmJpdCwgc3RtXzE2Yml0LCBzdG1fZG9uZX07CgpzdGF0aWMgY29uc3QgY2hhciogd2luZV9kYmdzdHJfYWRkcihjb25zdCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoIWFkZHIpIHJldHVybiAiKG51bGwpIjsKICAgIHN3aXRjaCAoYWRkci0+TW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCJmbGF0PCUwOGx4PiIsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYxNjwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlMTYzMjoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiMTYzMjwlMDR4OiUwOGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigicmVhbDwlMDR4OiUwNGx4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAidW5rbm93biI7CiAgICB9Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIHJlYWRfbWVtKEhBTkRMRSBoUHJvY2VzcywgRFdPUkQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBzaXplLCBMUERXT1JEIG5yZWFkKQp7CiAgICByZXR1cm4gUmVhZFByb2Nlc3NNZW1vcnkoaFByb2Nlc3MsICh2b2lkKilhZGRyLCBidWZmZXIsIHNpemUsIG5yZWFkKTsKfQoKLyogaW5kZXhlcyBpbiBSZXNlcnZlZCBhcnJheSAqLwojZGVmaW5lIF9fQ3VycmVudE1vZGUgICAgIDAKI2RlZmluZSBfX0N1cnJlbnRTd2l0Y2ggICAxCiNkZWZpbmUgX19OZXh0U3dpdGNoICAgICAgMgoKI2RlZmluZSBjdXJyX21vZGUgICAoZnJhbWUtPlJlc2VydmVkW19fQ3VycmVudE1vZGVdKQojZGVmaW5lIGN1cnJfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50U3dpdGNoXSkKI2RlZmluZSBuZXh0X3N3aXRjaCAoZnJhbWUtPlJlc2VydmVkW19fTmV4dFN3aXRjaF0pCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVN0YWNrV2FsayAoREJHSEVMUC5AKQogKi8KQk9PTCBXSU5BUEkgU3RhY2tXYWxrKERXT1JEIE1hY2hpbmVUeXBlLCBIQU5ETEUgaFByb2Nlc3MsIEhBTkRMRSBoVGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgTFBTVEFDS0ZSQU1FIGZyYW1lLCBMUFZPSUQgY3R4LAogICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORSBmX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FIEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkUgZl94bGF0X2FkcikKewogICAgU1RBQ0szMkZSQU1FICAgICAgICBmcmFtZTMyOwogICAgU1RBQ0sxNkZSQU1FICAgICAgICBmcmFtZTE2OwogICAgY2hhciAgICAgICAgICAgICAgICBjaDsKICAgIEFERFJFU1MgICAgICAgICAgICAgdG1wOwogICAgRFdPUkQgICAgICAgICAgICAgICBwOwogICAgV09SRCAgICAgICAgICAgICAgICB2YWw7CiAgICBCT09MICAgICAgICAgICAgICAgIGRvX3N3aXRjaDsKCiAgICBUUkFDRSgiKCVsZCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwKVxuIiwKICAgICAgICAgIE1hY2hpbmVUeXBlLCBoUHJvY2VzcywgaFRocmVhZCwgZnJhbWUsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBzYW5pdHkgY2hlY2sgKi8KICAgIGlmIChjdXJyX21vZGUgPj0gc3RtX2RvbmUpIHJldHVybiBGQUxTRTsKCiAgICAvKiBzaWdoLi4uIE1TIGlzbid0IGV2ZW4gY29uc2lzdGVudCBpbiB0aGUgZnVuYyBwcm90b3R5cGVzICovCiAgICBpZiAoIWZfcmVhZF9tZW0pIGZfcmVhZF9tZW0gPSByZWFkX21lbTsKICAgIGlmICghZl94bGF0X2FkcikgZl94bGF0X2FkciA9IGFkZHJfdG9fbGluZWFyOwoKICAgIFRSQUNFKCJFbnRlcjogUEM9JXMgRnJhbWU9JXMgUmV0dXJuPSVzIFN0YWNrPSVzIE1vZGU9JXMgY1N3aXRjaD0lMDhseCBuU3dpdGNoPSUwOGx4XG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJQQyksIAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclJldHVybiksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclN0YWNrKSwgCiAgICAgICAgICBjdXJyX21vZGUgPT0gc3RtX3N0YXJ0ID8gInN0YXJ0IiA6IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0ID8gIjE2Yml0IiA6ICIzMmJpdCIpLAogICAgICAgICAgY3Vycl9zd2l0Y2gsIG5leHRfc3dpdGNoKTsKCiAgICBpZiAoY3Vycl9tb2RlID09IHN0bV9zdGFydCkKICAgIHsKICAgICAgICBUSFJFQURfQkFTSUNfSU5GT1JNQVRJT04gaW5mbzsKCiAgICAgICAgaWYgKChmcmFtZS0+QWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSAmJgogICAgICAgICAgICAoZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJCYWQgQWRkclBDLk1vZGUgLyBBZGRyRnJhbWUuTW9kZSBjb21iaW5hdGlvblxuIik7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQoKICAgICAgICAvKiBJbml0IGRvbmUgKi8KICAgICAgICBjdXJyX21vZGUgPSAoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgPyAKICAgICAgICAgICAgc3RtXzMyYml0IDogc3RtXzE2Yml0OwoKICAgICAgICAvKiBjdXJfc3dpdGNoIGhvbGRzIGFkZHJlc3Mgb2YgV09XMzJSZXNlcnZlZCBmaWVsZCBpbiBURUIgaW4gZGVidWdnZWUKICAgICAgICAgKiBhZGRyZXNzIHNwYWNlCiAgICAgICAgICovCiAgICAgICAgaWYgKE50UXVlcnlJbmZvcm1hdGlvblRocmVhZChoVGhyZWFkLCBUaHJlYWRCYXNpY0luZm9ybWF0aW9uLCAmaW5mbywgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoaW5mbyksIE5VTEwpID09IFNUQVRVU19TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAodW5zaWduZWQgbG9uZylpbmZvLlRlYkJhc2VBZGRyZXNzICsgRklFTERfT0ZGU0VUKFRFQiwgV09XMzJSZXNlcnZlZCk7CiAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgY3Vycl9zd2l0Y2gsICZuZXh0X3N3aXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5leHRfc3dpdGNoKSwgTlVMTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOldPVzMyUmVzZXJ2ZWRcbiIpOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGZyYW1lMzIpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKTsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBjdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyB3aWxsIGFsbG93IHRvIHdvcmsgd2hlbiB3ZSdyZSBub3QgYXR0YWNoZWQgdG8gYSBsaXZlIHRhcmdldCwgCiAgICAgICAgICAgICAqIGJ1dCB0aGUgMTYgPD0+IDMyIHN3aXRjaCBmYWNpbGl0eSB3b24ndCBiZSBhdmFpbGFibGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDA7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSA9IGZyYW1lLT5BZGRyU3RhY2suTW9kZSA9IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KSA/IEFkZHJNb2RlMTYxNiA6IEFkZHJNb2RlRmxhdDsKICAgICAgICAvKiBkb24ndCBzZXQgdXAgQWRkclN0YWNrIG9uIGZpcnN0IGNhbGwuIEVpdGhlciB0aGUgY2FsbGVyIGhhcyBzZXQgaXQgdXAsIG9yCiAgICAgICAgICogd2Ugd2lsbCBnZXQgaXQgaW4gdGhlIG5leHQgZnJhbWUKICAgICAgICAgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPT0gMCkgZ290byBkb25lX2VycjsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5Nb2RlID09IEFkZHJNb2RlRmxhdCkKICAgICAgICB7CiAgICAgICAgICAgIGFzc2VydChjdXJyX21vZGUgPT0gc3RtXzMyYml0KTsKICAgICAgICAgICAgZG9fc3dpdGNoID0gY3Vycl9zd2l0Y2ggJiYgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPj0gY3Vycl9zd2l0Y2g7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGFzc2VydChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KTsKICAgICAgICAgICAgZG9fc3dpdGNoID0gY3Vycl9zd2l0Y2ggJiYgCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgPT0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCkgJiYKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICB9CgkgICAKICAgICAgICBpZiAoZG9fc3dpdGNoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZnJhbWUzMiksIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk1vZGUgICAgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgID0gZnJhbWUzMi5yZXRhZGRyOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgICA9IGZyYW1lMzIuZWJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gMDsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKICAgICAgICAgICAgICAgIGN1cnJfbW9kZSA9IHN0bV8zMmJpdDsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGEgMTYgYml0IHN0YWNrIHN3aXRjaDoiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGZyYW1lMzI6ICUwOGx4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlZHg6JTA4bHggZWN4OiUwOGx4IGVicDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZHM6JTA0eCBlczolMDR4IGZzOiUwNHggZ3M6JTA0eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0Y2FsbF9mcm9tX2lwOiUwOGx4IG1vZHVsZV9jczolMDRseCByZWxheT0lMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZW50cnlfaXA6JTA0eCBlbnRyeV9wb2ludDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0YnA6JTA0eCBpcDolMDR4IGNzOiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylmcmFtZTE2LmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVkeCwgZnJhbWUxNi5lY3gsIGZyYW1lMTYuZWJwLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5kcywgZnJhbWUxNi5lcywgZnJhbWUxNi5mcywgZnJhbWUxNi5ncywKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuY2FsbGZyb21faXAsIGZyYW1lMTYubW9kdWxlX2NzLCBmcmFtZTE2LnJlbGF5LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lbnRyeV9pcCwgZnJhbWUxNi5lbnRyeV9wb2ludCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuYnAsIGZyYW1lMTYuaXAsIGZyYW1lMTYuY3MpOwoKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgID0gZnJhbWUxNi5jczsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICA9IGZyYW1lMTYuaXA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgPSBmcmFtZTE2LmJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gZnJhbWUxNi5jczsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBuZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihmcmFtZTMyKSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2gsIHNpemVvZihjaCksIE5VTEwpKQogICAgICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMDsKICAgICAgICAgICAgICAgIGN1cnJfbW9kZSA9IHN0bV8xNmJpdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBmcmFtZS0+QWRkclBDID0gZnJhbWUtPkFkZHJSZXR1cm47CiAgICAgICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk9mZnNldCA9IGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgMiAqIHNpemVvZihXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEJQIHZhbHVlICovCiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEVCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgewogICAgICAgIGludCAgICAgaTsKCiAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKTsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsIHAgKyBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0ID0gdmFsOwogICAgICAgIC8qIGdldCBwb3RlbnRpYWwgY3MgaWYgYSBmYXIgY2FsbCB3YXMgdXNlZCAqLwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgcCArIDIgKiBzaXplb2YoV09SRCksIAogICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmIDEpCiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSB2YWw7IC8qIGZhciBjYWxsIGFzc3VtZWQgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsIAogICAgICAgICAgICAgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgodmFsICYgNykgPT0gNyAmJiB2YWwgIT0gZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTERUX0VOVFJZCWxlOwoKICAgICAgICAgICAgICAgIGlmIChHZXRUaHJlYWRTZWxlY3RvckVudHJ5KGhUaHJlYWQsIHZhbCwgJmxlKSAmJgogICAgICAgICAgICAgICAgICAgIChsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgLyogY29kZSBzZWdtZW50ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCiAgICAgICAgICAgICAgICAgICAgICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCX0KICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmPSB+MTsKICAgICAgICAvKiB3ZSAicG9wIiBwYXJhbWV0ZXJzIGFzIDE2IGJpdCBlbnRpdGllcy4uLiBvZiBjb3Vyc2UsIHRoaXMgd29uJ3QKICAgICAgICAgKiB3b3JrIGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW4gZmFjdCBiaWdnZXIgdGhhbiAxNmJpdCwgYnV0CiAgICAgICAgICogdGhlcmUncyBubyB3YXkgdG8ga25vdyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpIC8gc2l6ZW9mKGZyYW1lLT5QYXJhbXNbMF0pOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBmX3JlYWRfbWVtKGhQcm9jZXNzLCBwICsgKDIgKyBpKSAqIHNpemVvZihXT1JEKSwgCiAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKHZhbCksIE5VTEwpOwogICAgICAgICAgICBmcmFtZS0+UGFyYW1zW2ldID0gdmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIHNpemVvZihEV09SRCksCiAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkclJldHVybi5PZmZzZXQsIHNpemVvZihEV09SRCksIE5VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQ2Fubm90IHJlYWQgbmV3IGZyYW1lIG9mZnNldCAlMDhseFxuIiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICB9CiAgICAgICAgZl9yZWFkX21lbShoUHJvY2VzcywgCiAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpLCAKICAgICAgICAgICAgICAgICAgIGZyYW1lLT5QYXJhbXMsIHNpemVvZihmcmFtZS0+UGFyYW1zKSwgTlVMTCk7CiAgICB9CgogICAgZnJhbWUtPkZhciA9IEZBTFNFOwogICAgZnJhbWUtPlZpcnR1YWwgPSBGQUxTRTsKCiAgICBUUkFDRSgiTGVhdmU6IFBDPSVzIEZyYW1lPSVzIFJldHVybj0lcyBTdGFjaz0lcyBNb2RlPSVzIGNTd2l0Y2g9JTA4bHggblN3aXRjaD0lMDhseFxuIiwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUEMpLCAKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJSZXR1cm4pLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJTdGFjayksIAogICAgICAgICAgY3Vycl9tb2RlID09IHN0bV9zdGFydCA/ICJzdGFydCIgOiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCA/ICIxNmJpdCIgOiAiMzJiaXQiKSwKICAgICAgICAgIGN1cnJfc3dpdGNoLCBuZXh0X3N3aXRjaCk7CgogICAgcmV0dXJuIFRSVUU7CmRvbmVfZXJyOgogICAgY3Vycl9tb2RlID0gc3RtX2RvbmU7CiAgICByZXR1cm4gRkFMU0U7Cn0K