LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4gKHdpdGggc29tZSBoZWxwIGZyb20gTWFyY3VzIE1laXNzbmVyKQogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJ2Z2EuaCIKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgpzdGF0aWMgSURpcmVjdERyYXcgKmxwZGRyYXcgPSBOVUxMOwpzdGF0aWMgSURpcmVjdERyYXdTdXJmYWNlICpscGRkc3VyZjsKc3RhdGljIElEaXJlY3REcmF3UGFsZXR0ZSAqbHBkZHBhbDsKc3RhdGljIEREU1VSRkFDRURFU0Mgc2Rlc2M7CgpzdGF0aWMgQk9PTCB2Z2FfcmV0cmFjZV92ZXJ0aWNhbDsKc3RhdGljIEJPT0wgdmdhX3JldHJhY2VfaG9yaXpvbnRhbDsKCi8qCiAqIFNpemUgYW5kIGxvY2F0aW9uIG9mIFZHQSBjb250cm9sbGVyIHdpbmRvdyB0byBmcmFtZWJ1ZmZlci4KICoKICogTm90ZTogV2Ugc3VwcG9ydCBvbmx5IHNpbmdsZSB3aW5kb3cgZXZlbiB0aG91Z2ggc29tZQogKiAgICAgICBjb250cm9sbGVycyBzdXBwb3J0IHR3by4gVGhpcyBzaG91bGQgbm90IGJlIGNoYW5nZWQgdW5sZXNzCiAqICAgICAgIHRoZXJlIGFyZSBwcm9ncmFtcyB0aGF0IGRlcGVuZCBvbiBoYXZpbmcgdHdvIHdpbmRvd3MuCiAqLwojZGVmaW5lIFZHQV9XSU5ET1dfU0laRSAgKDY0ICogMTAyNCkKI2RlZmluZSBWR0FfV0lORE9XX1NUQVJUICgoY2hhciAqKTB4YTAwMDApCgovKgogKiBWR0EgY29udHJvbGxlciBtZW1vcnkgaXMgZW11bGF0ZWQgdXNpbmcgbGluZWFyIGZyYW1lYnVmZmVyLgogKiBUaGlzIGZyYW1idWZmZXIgYWxzbyBhY3RzIGFzIGFuIGludGVyZmFjZQogKiBiZXR3ZWVuIFZHQSBjb250cm9sbGVyIGVtdWxhdGlvbiBhbmQgRGlyZWN0RHJhdy4KICoKICogdmdhX2ZiX3dpZHRoOiBEaXNwbGF5IHdpZHRoIGluIHBpeGVscy4gQ2FuIGJlIG1vZGlmaWVkIHdoZW4KICogICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2hlaWdodDogRGlzcGxheSBoZWlnaHQgaW4gcGl4ZWxzLiBDYW4gYmUgbW9kaWZpZWQgd2hlbgogKiAgICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2RlcHRoOiBOdW1iZXIgb2YgYml0cyB1c2VkIHRvIHN0b3JlIHNpbmdsZSBwaXhlbCBjb2xvciBpbmZvcm1hdGlvbi4KICogICAgICAgICAgICAgICBFYWNoIHBpeGVsIHVzZXMgKHZnYV9mYl9kZXB0aCs3KS84IGJ5dGVzIGJlY2F1c2UKICogICAgICAgICAgICAgICAxLTE2IGNvbG9yIG1vZGVzIGFyZSBtYXBwZWQgdG8gMjU2IGNvbG9yIG1vZGUuCiAqICAgICAgICAgICAgICAgQ2FuIGJlIG1vZGlmaWVkIHdoZW4gZGlzcGxheSBtb2RlIGlzIGNoYW5nZWQuCiAqIHZnYV9mYl9waXRjaDogSG93IG1hbnkgYnl0ZXMgdG8gYWRkIHRvIHBvaW50ZXIgaW4gb3JkZXIgdG8gbW92ZQogKiAgICAgICAgICAgICAgIGZyb20gb25lIHJvdyB0byBhbm90aGVyLiBUaGlzIGlzIGZpeGVkIGluIFZHQSBtb2RlcywKICogICAgICAgICAgICAgICBidXQgY2FuIGJlIG1vZGlmaWVkIGluIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9vZmZzZXQ6IE9mZnNldCBhZGRlZCB0byBmcmFtZWJ1ZmZlciBzdGFydCBhZGRyZXNzIGluIG9yZGVyCiAqICAgICAgICAgICAgICAgIHRvIGZpbmQgdGhlIGRpc3BsYXkgb3JpZ2luLiBQcm9ncmFtcyB1c2UgdGhpcyB0byBkbwogKiAgICAgICAgICAgICAgICBkb3VibGUgYnVmZmVyaW5nIGFuZCB0byBzY3JvbGwgZGlzcGxheS4gVGhlIHZhbHVlIGNhbgogKiAgICAgICAgICAgICAgICBiZSBtb2RpZmllZCBpbiBWR0EgYW5kIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9zaXplOiBIb3cgbWFueSBieXRlcyBhcmUgYWxsb2NhdGVkIHRvIGZyYW1lYnVmZmVyLgogKiAgICAgICAgICAgICAgVkdBIGZyYW1lYnVmZmVycyBhcmUgYWx3YXlzIGxhcmdlciB0aGFuIGRpc3BsYXkgc2l6ZSBhbmQKICogICAgICAgICAgICAgIFNWR0EgZnJhbWVidWZmZXJzIG1heSBhbHNvIGJlLgogKiB2Z2FfZmJfZGF0YTogUG9pbnRlciB0byBmcmFtZWJ1ZmZlciBzdGFydC4KICogdmdhX2ZiX3dpbmRvdzogT2Zmc2V0IG9mIDY0ayB3aW5kb3cgMHhhMDAwMCBpbiBieXRlcyBmcm9tIGZyYW1lYnVmZmVyIHN0YXJ0LgogKiAgICAgICAgICAgICAgICBUaGlzIHZhbHVlIGlzID49IDAsIGlmIG1vZGUgdXNlcyBsaW5lYXIgZnJhbWVidWZmZXIgYW5kCiAqICAgICAgICAgICAgICAgIC0xLCBpZiBtb2RlIHVzZXMgY29sb3IgcGxhbmVzLiBUaGlzIHZhbHVlIGlzIGZpeGVkCiAqICAgICAgICAgICAgICAgIGluIGFsbCBtb2RlcyBleGNlcHQgMHgxMyAoMjU2IGNvbG9yIFZHQSkgd2hlcmUKICogICAgICAgICAgICAgICAgMCBtZWFucyBub3JtYWwgbW9kZSBhbmQgLTEgbWVhbnMgTW9kZS1YICh1bmNoYWluZWQgbW9kZSkuCiAqLwpzdGF0aWMgaW50ICAgdmdhX2ZiX3dpZHRoOwpzdGF0aWMgaW50ICAgdmdhX2ZiX2hlaWdodDsKc3RhdGljIGludCAgIHZnYV9mYl9kZXB0aDsKc3RhdGljIGludCAgIHZnYV9mYl9waXRjaDsKc3RhdGljIGludCAgIHZnYV9mYl9vZmZzZXQ7CnN0YXRpYyBpbnQgICB2Z2FfZmJfc2l6ZSA9IDA7CnN0YXRpYyBjaGFyICp2Z2FfZmJfZGF0YSA9IDA7CnN0YXRpYyBpbnQgICB2Z2FfZmJfd2luZG93ID0gMDsKCi8qCiAqIFZHQSB0ZXh0IG1vZGUgZGF0YS4KICoKICogdmdhX3RleHRfYXR0cjogQ3VycmVudCBhY3RpdmUgYXR0cmlidXRlLgogKiB2Z2FfdGV4dF9vbGQ6IExhc3QgZGF0YSBzZW50IHRvIGNvbnNvbGUuIAogKiAgICAgICAgICAgICAgIFRoaXMgaXMgdXNlZCB0byBvcHRpbWl6ZSBjb25zb2xlIHVwZGF0ZXMuCiAqIHZnYV90ZXh0X3dpZHRoOiAgV2lkdGggb2YgdGhlIHRleHQgZGlzcGxheSBpbiBjaGFyYWN0ZXJzLgogKiB2Z2FfdGV4dF9oZWlnaHQ6IEhlaWdodCBvZiB0aGUgdGV4dCBkaXNwbGF5IGluIGNoYXJhY3RlcnMuCiAqIHZnYV90ZXh0X3g6IEN1cnJlbnQgY3Vyc29yIFgtcG9zaXRpb24uIFN0YXJ0cyBmcm9tIHplcm8uCiAqIHZnYV90ZXh0X3k6IEN1cnJlbnQgY3Vyc29yIFktcG9zaXRpb24uIFN0YXJ0cyBmcm9tIHplcm8uCiAqIHZnYV90ZXh0X2NvbnNvbGU6IFRSVUUgaWYgc3Rkb3V0IGlzIGNvbnNvbGUsIAogKiAgICAgICAgICAgICAgICAgICBGQUxTRSBpZiBpdCBpcyByZWd1bGFyIGZpbGUuCiAqLwpzdGF0aWMgQllURSAgdmdhX3RleHRfYXR0cjsKc3RhdGljIGNoYXIgKnZnYV90ZXh0X29sZCA9IE5VTEw7CnN0YXRpYyBCWVRFICB2Z2FfdGV4dF93aWR0aDsKc3RhdGljIEJZVEUgIHZnYV90ZXh0X2hlaWdodDsKc3RhdGljIEJZVEUgIHZnYV90ZXh0X3g7CnN0YXRpYyBCWVRFICB2Z2FfdGV4dF95OwpzdGF0aWMgQk9PTCAgdmdhX3RleHRfY29uc29sZTsKCi8qCiAqIFZHQSBjb250cm9sbGVyIHBvcnRzIDB4M2MwLCAweDNjNCwgMHgzY2UgYW5kIDB4M2Q0IGFyZQogKiBpbmRleGVkIHJlZ2lzdGVycy4gVGhlc2UgcG9ydHMgYXJlIHVzZWQgdG8gc2VsZWN0IFZHQSBjb250cm9sbGVyCiAqIHN1YnJlZ2lzdGVyIHRoYXQgY2FuIGJlIHdyaXR0ZW4gdG8gb3IgcmVhZCBmcm9tIHVzaW5nIHBvcnRzIDB4M2MxLAogKiAweDNjNSwgMHgzY2Ygb3IgMHgzZDUuIFNlbGVjdGVkIHN1YnJlZ2lzdGVyIGluZGV4ZXMgYXJlCiAqIHN0b3JlZCBpbiB2YXJpYWJsZXMgdmdhX2luZGV4XyouCiAqCiAqIFBvcnQgMHgzYzAgaXMgc3BlY2lhbCBiZWNhdXNlIGl0IGlzIGJvdGggaW5kZXggYW5kCiAqIGRhdGEtd3JpdGUgcmVnaXN0ZXIuIEZsaXAtZmxvcCB2Z2FfYWRkcmVzc18zYzAgdGVsbHMgd2hldGhlcgogKiB0aGUgcG9ydCBhY3RzIGN1cnJlbnRseSBhcyBhbiBhZGRyZXNzIHJlZ2lzdGVyLiBSZWFkaW5nIGZyb20gcG9ydAogKiAweDNkYSByZXNldHMgdGhlIGZsaXAtZmxvcCB0byBhZGRyZXNzIG1vZGUuCiAqLwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2MwOwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2M0OwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2NlOwpzdGF0aWMgQllURSB2Z2FfaW5kZXhfM2Q0OwpzdGF0aWMgQk9PTCB2Z2FfYWRkcmVzc18zYzAgPSBUUlVFOwoKLyoKICogVGhpcyBtdXRleCBpcyB1c2VkIHRvIHByb3RlY3QgVkdBIHN0YXRlIGR1cmluZyBhc3luY2hyb25vdXMKICogc2NyZWVuIHVwZGF0ZXMgKHNlZSBWR0FfUG9sbCkuIEl0IG1ha2VzIHN1cmUgdGhhdCBWR0Egc3RhdGUgY2hhbmdlcwogKiBhcmUgYXRvbWljIGFuZCB0aGUgdXNlciBpbnRlcmZhY2UgaXMgcHJvdGVjdGVkIGZyb20gZmxpY2tlciBhbmQKICogY29ycnVwdGlvbi4KICoKICogVGhlIG11dGV4IGFjdHVhbGx5IHNlcmlhbGl6ZXMgVkdBIG9wZXJhdGlvbnMgYW5kIHRoZSBzY3JlZW4gdXBkYXRlLiAKICogV2hpY2ggbWVhbnMgdGhhdCB3aGVuZXZlciBWR0FfUG9sbCBvY2N1cnMsIGFwcGxpY2F0aW9uIHN0YWxscyBpZiBpdCAKICogdHJpZXMgdG8gbW9kaWZ5IFZHQSBzdGF0ZS4gVGhpcyBpcyBub3QgaG93IHJlYWwgVkdBIGFkYXB0ZXJzIHdvcmssCiAqIGJ1dCBpdCBtYWtlcyB0aW1pbmcgYW5kIGNvcnJlY3RuZXNzIGlzc3VlcyBtdWNoIGVhc2llciB0byBkZWFsIHdpdGguCiAqLwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiB2Z2FfbG9jazsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgY3JpdHNlY3RfZGVidWcgPQp7CiAgICAwLCAwLCAmdmdhX2xvY2ssCiAgICB7ICZjcml0c2VjdF9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IDAsIChEV09SRCkoX19GSUxFX18gIjogdmdhX2xvY2siKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHZnYV9sb2NrID0geyAmY3JpdHNlY3RfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGlyZWN0RHJhd0NyZWF0ZVByb2MpKExQR1VJRCxMUERJUkVDVERSQVcgKixMUFVOS05PV04pOwpzdGF0aWMgRGlyZWN0RHJhd0NyZWF0ZVByb2MgcERpcmVjdERyYXdDcmVhdGU7CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBWR0FfUG9sbCggTFBWT0lEIGFyZywgRFdPUkQgbG93LCBEV09SRCBoaWdoICk7CgpzdGF0aWMgSFdORCB2Z2FfaHduZCA9IE5VTEw7CgovKgogKiBGb3Igc2ltcGxpY2l0eSwgSSdtIGNyZWF0aW5nIGEgc2Vjb25kIHBhbGV0dGUuCiAqIDE2IGNvbG9yIGFjY2Vzc2VzIHdpbGwgdXNlIHRoZXNlIHBvaW50ZXJzIGFuZCBpbnNlcnQKICogZW50cmllcyBmcm9tIHRoZSA2NC1jb2xvciBwYWxldHRlIGludG8gdGhlIGRlZmF1bHQKICogcGFsZXR0ZS4gICAtLVJvYmVydCAnQWRtaXJhbCcgQ29leW1hbgogKi8KCnN0YXRpYyBjaGFyIHZnYV8xNl9wYWxldHRlWzE3XT17CiAgMHgwMCwgIC8qIDAgLSBCbGFjayAgICAgICAgICovCiAgMHgwMSwgIC8qIDEgLSBCbHVlICAgICAgICAgICovCiAgMHgwMiwgIC8qIDIgLSBHcmVlbiAgICAgICAgICovCiAgMHgwMywgIC8qIDMgLSBDeWFuICAgICAgICAgICovCiAgMHgwNCwgIC8qIDQgLSBSZWQgICAgICAgICAgICovCiAgMHgwNSwgIC8qIDUgLSBNYWdlbnRhICAgICAgICovCiAgMHgxNCwgIC8qIDYgLSBCcm93biAgICAgICAgICovCiAgMHgwNywgIC8qIDcgLSBMaWdodCBncmF5ICAgICovCiAgMHgzOCwgIC8qIDggLSBEYXJrIGdyYXkgICAgICovCiAgMHgzOSwgIC8qIDkgLSBMaWdodCBibHVlICAgICovCiAgMHgzYSwgIC8qIEEgLSBMaWdodCBncmVlbiAgICovCiAgMHgzYiwgIC8qIEIgLSBMaWdodCBjeWFuICAgICovCiAgMHgzYywgIC8qIEMgLSBMaWdodCByZWQgICAgICovCiAgMHgzZCwgIC8qIEQgLSBMaWdodCBtYWdlbnRhICovCiAgMHgzZSwgIC8qIEUgLSBZZWxsb3cgICAgICAgICovCiAgMHgzZiwgIC8qIEYgLSBXaGl0ZSAgICAgICAgICovCiAgMHgwMCAgIC8qIEJvcmRlciBDb2xvciAgICAgICovCn07CgpzdGF0aWMgUEFMRVRURUVOVFJZIHZnYV9kZWZfcGFsZXR0ZVsyNTZdPXsKLyogcmVkICBncmVlbiAgYmx1ZSAqLwogIHsweDAwLCAweDAwLCAweDAwfSwgLyogMCAtIEJsYWNrICovCiAgezB4MDAsIDB4MDAsIDB4ODB9LCAvKiAxIC0gQmx1ZSAqLwogIHsweDAwLCAweDgwLCAweDAwfSwgLyogMiAtIEdyZWVuICovCiAgezB4MDAsIDB4ODAsIDB4ODB9LCAvKiAzIC0gQ3lhbiAqLwogIHsweDgwLCAweDAwLCAweDAwfSwgLyogNCAtIFJlZCAqLwogIHsweDgwLCAweDAwLCAweDgwfSwgLyogNSAtIE1hZ2VudGEgKi8KICB7MHg4MCwgMHg4MCwgMHgwMH0sIC8qIDYgLSBCcm93biAqLwogIHsweEMwLCAweEMwLCAweEMwfSwgLyogNyAtIExpZ2h0IGdyYXkgKi8KICB7MHg4MCwgMHg4MCwgMHg4MH0sIC8qIDggLSBEYXJrIGdyYXkgKi8KICB7MHgwMCwgMHgwMCwgMHhGRn0sIC8qIDkgLSBMaWdodCBibHVlICovCiAgezB4MDAsIDB4RkYsIDB4MDB9LCAvKiBBIC0gTGlnaHQgZ3JlZW4gKi8KICB7MHgwMCwgMHhGRiwgMHhGRn0sIC8qIEIgLSBMaWdodCBjeWFuICovCiAgezB4RkYsIDB4MDAsIDB4MDB9LCAvKiBDIC0gTGlnaHQgcmVkICovCiAgezB4RkYsIDB4MDAsIDB4RkZ9LCAvKiBEIC0gTGlnaHQgbWFnZW50YSAqLwogIHsweEZGLCAweEZGLCAweDAwfSwgLyogRSAtIFllbGxvdyAqLwogIHsweEZGLCAweEZGLCAweEZGfSwgLyogRiAtIFdoaXRlICovCiAgezAsMCwwfSAvKiBGSVhNRTogYSBzZXJpZXMgb2YgY29udGludW91cyByYWluYm93IGh1ZXMgc2hvdWxkIGZvbGxvdyAqLwp9OwoKLyoKICogICBUaGlzIHBhbGV0dGUgaXMgdGhlIGRvcyBkZWZhdWx0LCBjb252ZXJ0ZWQgZnJvbSAxOCBiaXQgY29sb3IgdG8gMjQuCiAqICAgICAgSXQgY29udGFpbnMgb25seSA2NCBlbnRyaWVzIG9mIGNvbG9ycy0tYWxsIG90aGVycyBhcmUgemVyb3MuCiAqICAgICAgICAgIC0tUm9iZXJ0ICdBZG1pcmFsJyBDb2V5bWFuCiAqLwpzdGF0aWMgUEFMRVRURUVOVFJZIHZnYV9kZWY2NF9wYWxldHRlWzI1Nl09ewovKiByZWQgIGdyZWVuICBibHVlICovCiAgezB4MDAsIDB4MDAsIDB4MDB9LCAvKiAweDAwICAgICAgQmxhY2sgICAgICAqLwogIHsweDAwLCAweDAwLCAweGFhfSwgLyogMHgwMSAgICAgIEJsdWUgICAgICAgKi8KICB7MHgwMCwgMHhhYSwgMHgwMH0sIC8qIDB4MDIgICAgICBHcmVlbiAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4YWF9LCAvKiAweDAzICAgICAgQ3lhbiAgICAgICAqLwogIHsweGFhLCAweDAwLCAweDAwfSwgLyogMHgwNCAgICAgIFJlZCAgICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHhhYX0sIC8qIDB4MDUgICAgICBNYWdlbnRhICAgICovCiAgezB4YWEsIDB4YWEsIDB4MDB9LCAvKiAweDA2ICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhhYX0sIC8qIDB4MDcgICAgICBMaWdodCBHcmF5ICovCiAgezB4MDAsIDB4MDAsIDB4NTV9LCAvKiAweDA4ICAgICAgKi8KICB7MHgwMCwgMHgwMCwgMHhmZn0sIC8qIDB4MDkgICAgICAqLwogIHsweDAwLCAweGFhLCAweDU1fSwgLyogMHgwYSAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4ZmZ9LCAvKiAweDBiICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHg1NX0sIC8qIDB4MGMgICAgICAqLwogIHsweGFhLCAweDAwLCAweGZmfSwgLyogMHgwZCAgICAgICovCiAgezB4YWEsIDB4YWEsIDB4NTV9LCAvKiAweDBlICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhmZn0sIC8qIDB4MGYgICAgICAqLwogIHsweDAwLCAweDU1LCAweDAwfSwgLyogMHgxMCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4YWF9LCAvKiAweDExICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHgwMH0sIC8qIDB4MTIgICAgICAqLwogIHsweDAwLCAweGZmLCAweGFhfSwgLyogMHgxMyAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4MDB9LCAvKiAweDE0ICAgICAgQnJvd24gICAgICAqLwogIHsweGFhLCAweDU1LCAweGFhfSwgLyogMHgxNSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4MDB9LCAvKiAweDE2ICAgICAgKi8KICB7MHhhYSwgMHhmZiwgMHhhYX0sIC8qIDB4MTcgICAgICAqLwogIHsweDAwLCAweDU1LCAweDU1fSwgLyogMHgxOCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4ZmZ9LCAvKiAweDE5ICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHg1NX0sIC8qIDB4MWEgICAgICAqLwogIHsweDAwLCAweGZmLCAweGZmfSwgLyogMHgxYiAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4NTV9LCAvKiAweDFjICAgICAgKi8KICB7MHhhYSwgMHg1NSwgMHhmZn0sIC8qIDB4MWQgICAgICAqLwogIHsweGFhLCAweGZmLCAweDU1fSwgLyogMHgxZSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4ZmZ9LCAvKiAweDFmICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHgwMH0sIC8qIDB4MjAgICAgICAqLwogIHsweDU1LCAweDAwLCAweGFhfSwgLyogMHgyMSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4MDB9LCAvKiAweDIyICAgICAgKi8KICB7MHg1NSwgMHhhYSwgMHhhYX0sIC8qIDB4MjMgICAgICAqLwogIHsweGZmLCAweDAwLCAweDAwfSwgLyogMHgyNCAgICAgICovCiAgezB4ZmYsIDB4MDAsIDB4YWF9LCAvKiAweDI1ICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHgwMH0sIC8qIDB4MjYgICAgICAqLwogIHsweGZmLCAweGFhLCAweGFhfSwgLyogMHgyNyAgICAgICovCiAgezB4NTUsIDB4MDAsIDB4NTV9LCAvKiAweDI4ICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHhmZn0sIC8qIDB4MjkgICAgICAqLwogIHsweDU1LCAweGFhLCAweDU1fSwgLyogMHgyYSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4ZmZ9LCAvKiAweDJiICAgICAgKi8KICB7MHhmZiwgMHgwMCwgMHg1NX0sIC8qIDB4MmMgICAgICAqLwogIHsweGZmLCAweDAwLCAweGZmfSwgLyogMHgyZCAgICAgICovCiAgezB4ZmYsIDB4YWEsIDB4NTV9LCAvKiAweDJlICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHhmZn0sIC8qIDB4MmYgICAgICAqLwogIHsweDU1LCAweDU1LCAweDAwfSwgLyogMHgzMCAgICAgICovCiAgezB4NTUsIDB4NTUsIDB4YWF9LCAvKiAweDMxICAgICAgKi8KICB7MHg1NSwgMHhmZiwgMHgwMH0sIC8qIDB4MzIgICAgICAqLwogIHsweDU1LCAweGZmLCAweGFhfSwgLyogMHgzMyAgICAgICovCiAgezB4ZmYsIDB4NTUsIDB4MDB9LCAvKiAweDM0ICAgICAgKi8KICB7MHhmZiwgMHg1NSwgMHhhYX0sIC8qIDB4MzUgICAgICAqLwogIHsweGZmLCAweGZmLCAweDAwfSwgLyogMHgzNiAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4YWF9LCAvKiAweDM3ICAgICAgKi8KICB7MHg1NSwgMHg1NSwgMHg1NX0sIC8qIDB4MzggICAgICBEYXJrIEdyYXkgICAgICovCiAgezB4NTUsIDB4NTUsIDB4ZmZ9LCAvKiAweDM5ICAgICAgTGlnaHQgQmx1ZSAgICAqLwogIHsweDU1LCAweGZmLCAweDU1fSwgLyogMHgzYSAgICAgIExpZ2h0IEdyZWVuICAgKi8KICB7MHg1NSwgMHhmZiwgMHhmZn0sIC8qIDB4M2IgICAgICBMaWdodCBDeWFuICAgICovCiAgezB4ZmYsIDB4NTUsIDB4NTV9LCAvKiAweDNjICAgICAgTGlnaHQgUmVkICAgICAqLwogIHsweGZmLCAweDU1LCAweGZmfSwgLyogMHgzZCAgICAgIExpZ2h0IE1hZ2VudGEgKi8KICB7MHhmZiwgMHhmZiwgMHg1NX0sIC8qIDB4M2UgICAgICBZZWxsb3cgICAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4ZmZ9LCAvKiAweDNmICAgICAgV2hpdGUgICAgICAgICAqLwogIHswLDAsMH0gLyogVGhlIG5leHQgMTkyIGVudHJpZXMgYXJlIGFsbCB6ZXJvcyAgKi8KfTsKCnN0YXRpYyBIQU5ETEUgVkdBX3RpbWVyOwpzdGF0aWMgSEFORExFIFZHQV90aW1lcl90aHJlYWQ7CgovKiBzZXQgdGhlIHRpbWVyIHJhdGU7IGNhbGxlZCBpbiB0aGUgcG9sbGluZyB0aHJlYWQgY29udGV4dCAqLwpzdGF0aWMgdm9pZCBDQUxMQkFDSyBzZXRfdGltZXJfcmF0ZSggVUxPTkdfUFRSIGFyZyApCnsKICAgIExBUkdFX0lOVEVHRVIgd2hlbjsKCiAgICB3aGVuLnUuTG93UGFydCA9IHdoZW4udS5IaWdoUGFydCA9IDA7CiAgICBTZXRXYWl0YWJsZVRpbWVyKCBWR0FfdGltZXIsICZ3aGVuLCBhcmcsIFZHQV9Qb2xsLCAwLCBGQUxTRSApOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgVkdBX1RpbWVyVGhyZWFkKCB2b2lkICpkdW1teSApCnsKICAgIGZvciAoOzspIFNsZWVwRXgoIElORklOSVRFLCBUUlVFICk7Cn0KCnN0YXRpYyB2b2lkIFZHQV9EZWluc3RhbGxUaW1lcih2b2lkKQp7CiAgICBpZiAoVkdBX3RpbWVyX3RocmVhZCkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIE1ha2Ugc3VyZSB0aGUgdXBkYXRlIHRocmVhZCBpcyBub3QgaG9sZGluZwogICAgICAgICAqIHN5c3RlbSByZXNvdXJjZXMgd2hlbiB3ZSBraWxsIGl0LgogICAgICAgICAqCiAgICAgICAgICogTm93LCB3ZSBvbmx5IG5lZWQgdG8gd29ycnkgYWJvdXQgdXBkYXRlIHRocmVhZAogICAgICAgICAqIGdldHRpbmcgdGVybWluYXRlZCB3aGlsZSBpbiBFbnRlckNyaXRpY2FsU2VjdGlvbiAKICAgICAgICAgKiBvciBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXguCiAgICAgICAgICoKICAgICAgICAgKiBGSVhNRTogSXMgdGhpcyBhIHByb2JsZW0/CiAgICAgICAgICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICAgICAgQ2FuY2VsV2FpdGFibGVUaW1lciggVkdBX3RpbWVyICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIFZHQV90aW1lciApOwogICAgICAgIFRlcm1pbmF0ZVRocmVhZCggVkdBX3RpbWVyX3RocmVhZCwgMCApOwogICAgICAgIENsb3NlSGFuZGxlKCBWR0FfdGltZXJfdGhyZWFkICk7CiAgICAgICAgVkdBX3RpbWVyX3RocmVhZCA9IDA7CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgICAgIC8qCiAgICAgICAgICogU3luY2hyb25pemUgZGlzcGxheS4gVGhpcyBtYWtlcyBzdXJlIHRoYXQKICAgICAgICAgKiBjaGFuZ2VzIHRvIGRpc3BsYXkgYmVjb21lIHZpc2libGUgZXZlbiBpZiBwcm9ncmFtIAogICAgICAgICAqIHRlcm1pbmF0ZXMgYmVmb3JlIHVwZGF0ZSB0aHJlYWQgaGFkIHRpbWUgdG8gcnVuLgogICAgICAgICAqLwogICAgICAgIFZHQV9Qb2xsKCAwLCAwLCAwICk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIFZHQV9JbnN0YWxsVGltZXIodW5zaWduZWQgUmF0ZSkKewogICAgaWYgKCFWR0FfdGltZXJfdGhyZWFkKQogICAgewogICAgICAgIFZHQV90aW1lciA9IENyZWF0ZVdhaXRhYmxlVGltZXJBKCBOVUxMLCBGQUxTRSwgTlVMTCApOwogICAgICAgIFZHQV90aW1lcl90aHJlYWQgPSBDcmVhdGVUaHJlYWQoIE5VTEwsIDAsIFZHQV9UaW1lclRocmVhZCwgTlVMTCwgMCwgTlVMTCApOwogICAgfQogICAgUXVldWVVc2VyQVBDKCBzZXRfdGltZXJfcmF0ZSwgVkdBX3RpbWVyX3RocmVhZCwgKFVMT05HX1BUUilSYXRlICk7Cn0KCnN0YXRpYyBCT09MIFZHQV9Jc1RpbWVyUnVubmluZyh2b2lkKQp7CiAgICByZXR1cm4gVkdBX3RpbWVyX3RocmVhZCA/IFRSVUUgOiBGQUxTRTsKfQoKSEFORExFIFZHQV9BbHBoYUNvbnNvbGUodm9pZCkKewogICAgLyogdGhpcyBhc3N1bWVzIHRoYXQgbm8gV2luMzIgcmVkaXJlY3Rpb24gaGFzIHRha2VuIHBsYWNlLCBidXQgdGhlbiBhZ2FpbiwKICAgICAqIG9ubHkgMTYtYml0IGFwcHMgYXJlIGxpa2VseSB0byB1c2UgdGhpcyBwYXJ0IG9mIFdpbmUuLi4gKi8KICAgIHJldHVybiBHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwp9CgpjaGFyKlZHQV9BbHBoYUJ1ZmZlcih2b2lkKQp7CiAgICByZXR1cm4gKGNoYXIgKikweGI4MDAwOwp9CgovKioqIEdSQVBISUNTIE1PREUgKioqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIHVuc2lnbmVkIFhyZXMsIFlyZXMsIERlcHRoOwogIGludCByZXQ7Cn0gTW9kZVNldDsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgIFZHQV9TeW5jV2luZG93CiAqCiAqIENvcHkgVkdBIHdpbmRvdyBpbnRvIGZyYW1lYnVmZmVyIChpZiBhcmd1bWVudCBpcyBUUlVFKSBvcgogKiBwYXJ0IG9mIGZyYW1lYnVmZmVyIGludG8gVkdBIHdpbmRvdyAoaWYgYXJndW1lbnQgaXMgRkFMU0UpLgogKi8Kc3RhdGljIHZvaWQgVkdBX1N5bmNXaW5kb3coIEJPT0wgdGFyZ2V0X2lzX2ZiICkKewogICAgaW50IHNpemUgPSBWR0FfV0lORE9XX1NJWkU7CgogICAgLyogV2luZG93IGRvZXMgbm90IG92ZXJsYXAgZnJhbWVidWZmZXIuICovCiAgICBpZiAodmdhX2ZiX3dpbmRvdyA+PSB2Z2FfZmJfc2l6ZSkKICAgICAgICByZXR1cm47CgogICAgLyogQ2hlY2sgaWYgd2luZG93IG92ZXJsYXBzIGZyYW1lYnVmZmVyIG9ubHkgcGFydGlhbGx5LiAqLwogICAgaWYgKHZnYV9mYl9zaXplIC0gdmdhX2ZiX3dpbmRvdyA8IFZHQV9XSU5ET1dfU0laRSkKICAgICAgICBzaXplID0gdmdhX2ZiX3NpemUgLSB2Z2FfZmJfd2luZG93OwoKICAgIGlmICh0YXJnZXRfaXNfZmIpCiAgICAgICAgbWVtbW92ZSggdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCBWR0FfV0lORE9XX1NUQVJULCBzaXplICk7CiAgICBlbHNlCiAgICAgICAgbWVtbW92ZSggVkdBX1dJTkRPV19TVEFSVCwgdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCBzaXplICk7Cn0KCgpzdGF0aWMgdm9pZCBXSU5BUEkgVkdBX0RvRXhpdChVTE9OR19QVFIgYXJnKQp7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLE5VTEwpOwogICAgSURpcmVjdERyYXdTdXJmYWNlX1JlbGVhc2UobHBkZHN1cmYpOwogICAgbHBkZHN1cmY9TlVMTDsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKGxwZGRwYWwpOwogICAgbHBkZHBhbD1OVUxMOwogICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgIGxwZGRyYXc9TlVMTDsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFZHQV9Eb1NldE1vZGUoVUxPTkdfUFRSIGFyZykKewogICAgTFJFU1VMVAlyZXM7CiAgICBNb2RlU2V0ICpwYXIgPSAoTW9kZVNldCAqKWFyZzsKICAgIHBhci0+cmV0PTE7CgogICAgaWYgKGxwZGRyYXcpIFZHQV9Eb0V4aXQoMCk7CiAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICBpZiAoIXBEaXJlY3REcmF3Q3JlYXRlKQogICAgICAgIHsKICAgICAgICAgICAgSE1PRFVMRSBobW9kID0gTG9hZExpYnJhcnlBKCAiZGRyYXcuZGxsIiApOwogICAgICAgICAgICBpZiAoaG1vZCkgcERpcmVjdERyYXdDcmVhdGUgPSAoRGlyZWN0RHJhd0NyZWF0ZVByb2MpR2V0UHJvY0FkZHJlc3MoIGhtb2QsICJEaXJlY3REcmF3Q3JlYXRlIiApOwoJICAgIGlmICghcERpcmVjdERyYXdDcmVhdGUpIHsKCQlFUlIoIkNhbid0IGxvb2t1cCBEaXJlY3REcmF3Q3JlYXRlIGZyb20gZGRyYXcuZGxsLlxuIik7CgkJcmV0dXJuOwoJICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzID0gcERpcmVjdERyYXdDcmVhdGUoTlVMTCwmbHBkZHJhdyxOVUxMKTsKICAgICAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICAgICAgRVJSKCJEaXJlY3REcmF3IGlzIG5vdCBhdmFpbGFibGUgKHJlcyA9ICVseClcbiIscmVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgIHZnYV9od25kID0gQ3JlYXRlV2luZG93RXhBKDAsIlNUQVRJQyIsIldJTkVET1MgVkdBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfUE9QVVB8V1NfVklTSUJMRXxTU19OT1RJRlksMCwwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXItPlhyZXMscGFyLT5ZcmVzLDAsMCwwLE5VTEwpOwogICAgICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgdXNlciB3aW5kb3cuXG4iKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3X1JlbGVhc2UobHBkZHJhdyk7CiAgICAgICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBTZXRXaW5kb3dQb3ModmdhX2h3bmQsMCwwLDAscGFyLT5YcmVzLHBhci0+WXJlcyxTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUik7CgogICAgICAgIGlmICgocmVzPUlEaXJlY3REcmF3X1NldENvb3BlcmF0aXZlTGV2ZWwobHBkZHJhdyx2Z2FfaHduZCxERFNDTF9GVUxMU0NSRUVOfEREU0NMX0VYQ0xVU0lWRSkpKSB7CgkgICAgRVJSKCJDb3VsZCBub3Qgc2V0IGNvb3BlcmF0aXZlIGxldmVsIHRvIGV4Y2x1c2l2ZSAoJWx4KVxuIixyZXMpOwoJfQoKICAgICAgICBpZiAoKHJlcz1JRGlyZWN0RHJhd19TZXREaXNwbGF5TW9kZShscGRkcmF3LHBhci0+WHJlcyxwYXItPllyZXMscGFyLT5EZXB0aCkpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBkb2VzIG5vdCBzdXBwb3J0IHJlcXVlc3RlZCBkaXNwbGF5IG1vZGUgKCVkeCVkeCVkKSwgcmVzID0gJWx4IVxuIixwYXItPlhyZXMscGFyLT5ZcmVzLHBhci0+RGVwdGgscmVzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXM9SURpcmVjdERyYXdfQ3JlYXRlUGFsZXR0ZShscGRkcmF3LEREUENBUFNfOEJJVCxOVUxMLCZscGRkcGFsLE5VTEwpOwogICAgICAgIGlmIChyZXMpIHsKCSAgICBFUlIoIkNvdWxkIG5vdCBjcmVhdGUgcGFsZXR0ZSAocmVzID0gJWx4KVxuIixyZXMpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKChyZXM9SURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLDAsMjU2LHZnYV9kZWZfcGFsZXR0ZSkpKSB7CiAgICAgICAgICAgIEVSUigiQ291bGQgbm90IHNldCBkZWZhdWx0IHBhbGV0dGUgZW50cmllcyAocmVzID0gJWx4KVxuIiwgcmVzKTsKICAgICAgICB9CgogICAgICAgIG1lbXNldCgmc2Rlc2MsMCxzaXplb2Yoc2Rlc2MpKTsKICAgICAgICBzZGVzYy5kd1NpemU9c2l6ZW9mKHNkZXNjKTsKCXNkZXNjLmR3RmxhZ3MgPSBERFNEX0NBUFM7CglzZGVzYy5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICAgICAgaWYgKElEaXJlY3REcmF3X0NyZWF0ZVN1cmZhY2UobHBkZHJhdywmc2Rlc2MsJmxwZGRzdXJmLE5VTEwpfHwoIWxwZGRzdXJmKSkgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgc3VyZmFjZSBpcyBub3QgYXZhaWxhYmxlXG4iKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwogICAgICAgIHZnYV9yZXRyYWNlX3ZlcnRpY2FsID0gdmdhX3JldHJhY2VfaG9yaXpvbnRhbCA9IEZBTFNFOwogICAgICAgIC8qIHBvbGwgZXZlcnkgMjBtcyAoNTBmcHMgc2hvdWxkIHByb3ZpZGUgYWRlcXVhdGUgcmVzcG9uc2l2ZW5lc3MpICovCiAgICAgICAgVkdBX0luc3RhbGxUaW1lcigyMCk7CiAgICB9CiAgICBwYXItPnJldD0wOwogICAgcmV0dXJuOwp9CgppbnQgVkdBX1NldE1vZGUodW5zaWduZWQgWHJlcyx1bnNpZ25lZCBZcmVzLHVuc2lnbmVkIERlcHRoKQp7CiAgICBNb2RlU2V0IHBhcjsKICAgIGludCAgICAgbmV3U2l6ZTsKCiAgICB2Z2FfZmJfd2lkdGggPSBYcmVzOwogICAgdmdhX2ZiX2hlaWdodCA9IFlyZXM7CiAgICB2Z2FfZmJfZGVwdGggPSBEZXB0aDsKICAgIHZnYV9mYl9vZmZzZXQgPSAwOwogICAgdmdhX2ZiX3BpdGNoID0gWHJlcyAqICgoRGVwdGggKyA3KSAvIDgpOwoKICAgIG5ld1NpemUgPSBYcmVzICogWXJlcyAqICgoRGVwdGggKyA3KSAvIDgpOwogICAgaWYobmV3U2l6ZSA8IDI1NiAqIDEwMjQpCiAgICAgIG5ld1NpemUgPSAyNTYgKiAxMDI0OwoKICAgIGlmKHZnYV9mYl9zaXplIDwgbmV3U2l6ZSkgewogICAgICBpZih2Z2FfZmJfZGF0YSkKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB2Z2FfZmJfZGF0YSk7CiAgICAgIHZnYV9mYl9kYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG5ld1NpemUpOwogICAgICB2Z2FfZmJfc2l6ZSA9IG5ld1NpemU7CiAgICB9CgogICAgaWYoWHJlcyA+PSA2NDAgfHwgWXJlcyA+PSA0ODApIHsKICAgICAgcGFyLlhyZXMgPSBYcmVzOwogICAgICBwYXIuWXJlcyA9IFlyZXM7CiAgICB9IGVsc2UgewogICAgICBwYXIuWHJlcyA9IDY0MDsKICAgICAgcGFyLllyZXMgPSA0ODA7CiAgICB9CgogICAgVkdBX1NldFdpbmRvd1N0YXJ0KChEZXB0aCA8IDgpID8gLTEgOiAwKTsKCiAgICBwYXIuRGVwdGggPSAoRGVwdGggPCA4KSA/IDggOiBEZXB0aDsKCiAgICBNWl9SdW5JblRocmVhZChWR0FfRG9TZXRNb2RlLCAoVUxPTkdfUFRSKSZwYXIpOwogICAgcmV0dXJuIHBhci5yZXQ7Cn0KCmludCBWR0FfR2V0TW9kZSh1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIDE7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gMTsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfRXhpdCh2b2lkKQp7CiAgICBpZiAobHBkZHJhdykgTVpfUnVuSW5UaHJlYWQoVkdBX0RvRXhpdCwgMCk7Cn0KCnZvaWQgVkdBX1NldFBhbGV0dGUoUEFMRVRURUVOVFJZKnBhbCxpbnQgc3RhcnQsaW50IGxlbikKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCi8qIHNldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwp2b2lkIFZHQV9TZXRDb2xvcjE2KGludCByZWcsaW50IGNvbG9yKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKCXBhbD0gJnZnYV9kZWY2NF9wYWxldHRlW2NvbG9yXTsKICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAscmVnLDEscGFsKTsKCXZnYV8xNl9wYWxldHRlW3JlZ109KGNoYXIpY29sb3I7Cn0KCi8qIEdldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwpjaGFyIFZHQV9HZXRDb2xvcjE2KGludCByZWcpCnsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybiAwOwoJcmV0dXJuIChjaGFyKXZnYV8xNl9wYWxldHRlW3JlZ107Cn0KCi8qIHNldCBhbGwgMTcgW2NoYXIgd2lkZV0gY29sb3JzIGF0IG9uY2UgaW4gMTYgY29sb3IgbW9kZS4gKi8Kdm9pZCBWR0FfU2V0MTZQYWxldHRlKGNoYXIgKlRhYmxlKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCWludCBjOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOyAgICAgICAgIC8qIHJldHVybiBpZiB3ZSdyZSBpbiB0ZXh0IG9ubHkgbW9kZSAqLwogICAgbWVtY3B5KCBUYWJsZSwgJnZnYV8xNl9wYWxldHRlLCAxNyApOyAvKiBjb3B5IHRoZSBlbnRyaWVzIGludG8gdGhlIHRhYmxlICovCgogICAgZm9yIChjPTA7IGM8MTc7IGMrKykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogMTcgZW50cmllcyAqLwoJcGFsPSAmdmdhX2RlZjY0X3BhbGV0dGVbKGludCl2Z2FfMTZfcGFsZXR0ZVtjXV07ICAvKiBnZXQgY29sb3IgICovCiAgICAgICAgSURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLGMsMSxwYWwpOyAvKiBzZXQgZW50cnkgICovCglUUkFDRSgiUGFsZXR0ZSByZWdpc3RlciAlZCBzZXQgdG8gJWRcbiIsYywoaW50KXZnYV8xNl9wYWxldHRlW2NdKTsKICAgfSAvKiBlbmQgb2YgdGhlIGNvdW50aW5nIGxvb3AgKi8KfQoKLyogR2V0IGFsbCAxNyBbIGNoYXIgd2lkZSBdIGNvbG9ycyBhdCBvbmNlIGluIDE2IGNvbG9yIG1vZGUuICovCnZvaWQgVkdBX0dldDE2UGFsZXR0ZShjaGFyICpUYWJsZSkKewoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOyAgICAgICAgIC8qIHJldHVybiBpZiB3ZSdyZSBpbiB0ZXh0IG9ubHkgbW9kZSAqLwogICAgbWVtY3B5KCAmdmdhXzE2X3BhbGV0dGUsIFRhYmxlLCAxNyApOyAvKiBjb3B5IHRoZSBlbnRyaWVzIGludG8gdGhlIHRhYmxlICovCn0KCnZvaWQgVkdBX1NldFF1YWRQYWxldHRlKFJHQlFVQUQqY29sb3IsaW50IHN0YXJ0LGludCBsZW4pCnsKICAgIFBBTEVUVEVFTlRSWSBwYWxbMjU2XTsKICAgIGludCBjOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOwogICAgZm9yIChjPTA7IGM8bGVuOyBjKyspIHsKICAgICAgICBwYWxbY10ucGVSZWQgID1jb2xvcltjXS5yZ2JSZWQ7CiAgICAgICAgcGFsW2NdLnBlR3JlZW49Y29sb3JbY10ucmdiR3JlZW47CiAgICAgICAgcGFsW2NdLnBlQmx1ZSA9Y29sb3JbY10ucmdiQmx1ZTsKICAgICAgICBwYWxbY10ucGVGbGFncz0wOwogICAgfQogICAgSURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLHN0YXJ0LGxlbixwYWwpOwp9CgpMUFNUUiBWR0FfTG9jayh1bnNpZ25lZCpQaXRjaCx1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIE5VTEw7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gTlVMTDsKICAgIGlmIChJRGlyZWN0RHJhd1N1cmZhY2VfTG9jayhscGRkc3VyZixOVUxMLCZzZGVzYywwLDApKSB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbG9jayBzdXJmYWNlIVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZiAoUGl0Y2gpICpQaXRjaD1zZGVzYy51MS5sUGl0Y2g7CiAgICBpZiAoSGVpZ2h0KSAqSGVpZ2h0PXNkZXNjLmR3SGVpZ2h0OwogICAgaWYgKFdpZHRoKSAqV2lkdGg9c2Rlc2MuZHdXaWR0aDsKICAgIGlmIChEZXB0aCkgKkRlcHRoPXNkZXNjLmRkcGZQaXhlbEZvcm1hdC51MS5kd1JHQkJpdENvdW50OwogICAgcmV0dXJuIHNkZXNjLmxwU3VyZmFjZTsKfQoKdm9pZCBWR0FfVW5sb2NrKHZvaWQpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9VbmxvY2sobHBkZHN1cmYsc2Rlc2MubHBTdXJmYWNlKTsKfQoKLyoKICogU2V0IHN0YXJ0IG9mIDY0ayB3aW5kb3cgYXQgMHhhMDAwMCBpbiBieXRlcy4KICogSWYgdmFsdWUgaXMgLTEsIGluaXRpYWxpemUgY29sb3IgcGxhbmUgc3VwcG9ydC4KICogSWYgdmFsdWUgaXMgPj0gMCwgd2luZG93IGNvbnRhaW5zIGRpcmVjdCBjb3B5IG9mIGZyYW1lYnVmZmVyLgogKi8Kdm9pZCBWR0FfU2V0V2luZG93U3RhcnQoaW50IHN0YXJ0KQp7CiAgICBpZihzdGFydCA9PSB2Z2FfZmJfd2luZG93KQogICAgICAgIHJldHVybjsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIlJlbW92ZSBWR0EgbWVtb3J5IGVtdWxhdGlvbi5cbiIpOwogICAgZWxzZQogICAgICAgIFZHQV9TeW5jV2luZG93KCBUUlVFICk7CgogICAgdmdhX2ZiX3dpbmRvdyA9IHN0YXJ0OwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIkluc3RhbGwgVkdBIG1lbW9yeSBlbXVsYXRpb24uXG4iKTsKICAgIGVsc2UKICAgICAgICBWR0FfU3luY1dpbmRvdyggRkFMU0UgKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9CgovKgogKiBHZXQgc3RhcnQgb2YgNjRrIHdpbmRvdyBhdCAweGEwMDAwIGluIGJ5dGVzLgogKiBWYWx1ZSBpcyAtMSBpbiBjb2xvciBwbGFuZSBtb2Rlcy4KICovCmludCBWR0FfR2V0V2luZG93U3RhcnQoKQp7CiAgICByZXR1cm4gdmdhX2ZiX3dpbmRvdzsKfQoKLyoqKiBURVhUIE1PREUgKioqLwoKLyogcHJlcGFyZSB0aGUgdGV4dCBtb2RlIHZpZGVvIG1lbW9yeSBjb3B5IHRoYXQgaXMgdXNlZCB0byBvbmx5CiAqIHVwZGF0ZSB0aGUgdmlkZW8gbWVtb3J5IGxpbmUgdGhhdCBkaWQgZ2V0IHVwZGF0ZWQuICovCnZvaWQgVkdBX1ByZXBhcmVWaWRlb01lbUNvcHkodW5zaWduZWQgWHJlcywgdW5zaWduZWQgWXJlcykKewogICAgY2hhciAqcCwgKnAyOwogICAgaW50IGk7CgogICAgLyoKICAgICAqIEFsbG9jYXRlIHNwYWNlIGZvciBjaGFyICsgYXR0ci4KICAgICAqLwoKICAgIGlmICh2Z2FfdGV4dF9vbGQpCiAgICAgICAgdmdhX3RleHRfb2xkID0gSGVhcFJlQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZnYV90ZXh0X29sZCwgWHJlcyAqIFlyZXMgKiAyICk7CiAgICBlbHNlCiAgICAgICAgdmdhX3RleHRfb2xkID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWHJlcyAqIFlyZXMgKiAyICk7CiAgICBwID0gVkdBX0FscGhhQnVmZmVyKCk7CiAgICBwMiA9IHZnYV90ZXh0X29sZDsKCiAgICAvKiBtYWtlIHN1cmUgdGhlIHZpZGVvIG1lbSBjb3B5IGNvbnRhaW5zIHRoZSBleGFjdCBvcHBvc2l0ZSBvZiBvdXIKICAgICAqIGFjdHVhbCB0ZXh0IG1vZGUgbWVtb3J5IGFyZWEgdG8gbWFrZSBzdXJlIHRoZSBzY3JlZW4KICAgICAqIGRvZXMgZ2V0IHVwZGF0ZWQgZnVsbHkgaW5pdGlhbGx5ICovCiAgICBmb3IgKGk9MDsgaSA8IFhyZXMqWXJlcyoyOyBpKyspCgkqcDIrKyA9ICpwKysgXiAweGZmOyAvKiBYT1IgaXQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICBWR0FfU2V0QWxwaGFNb2RlCiAqCiAqIFNldCBWR0EgZW11bGF0aW9uIHRvIHRleHQgbW9kZS4KICovCnZvaWQgVkdBX1NldEFscGhhTW9kZSh1bnNpZ25lZCBYcmVzLHVuc2lnbmVkIFlyZXMpCnsKICAgIFZHQV9FeGl0KCk7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKICAgIAogICAgVkdBX1ByZXBhcmVWaWRlb01lbUNvcHkoWHJlcywgWXJlcyk7CiAgICB2Z2FfdGV4dF93aWR0aCA9IFhyZXM7CiAgICB2Z2FfdGV4dF9oZWlnaHQgPSBZcmVzOwoKICAgIGlmICh2Z2FfdGV4dF94ID49IHZnYV90ZXh0X3dpZHRoIHx8IHZnYV90ZXh0X3kgPj0gdmdhX3RleHRfaGVpZ2h0KQogICAgICAgIFZHQV9TZXRDdXJzb3JQb3MoMCwwKTsKCiAgICBpZih2Z2FfdGV4dF9jb25zb2xlKSB7CiAgICAgICAgQ09PUkQgc2l6ZTsKICAgICAgICBzaXplLlggPSBYcmVzOwogICAgICAgIHNpemUuWSA9IFlyZXM7CiAgICAgICAgU2V0Q29uc29sZVNjcmVlbkJ1ZmZlclNpemUoIFZHQV9BbHBoYUNvbnNvbGUoKSwgc2l6ZSApOwoKICAgICAgICAvKiBwb2xsIGV2ZXJ5IDMwbXMgKDMzZnBzIHNob3VsZCBwcm92aWRlIGFkZXF1YXRlIHJlc3BvbnNpdmVuZXNzKSAqLwogICAgICAgIFZHQV9JbnN0YWxsVGltZXIoMzApOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgIFZHQV9Jbml0QWxwaGFNb2RlCiAqCiAqIEluaXRpYWxpemUgVkdBIHRleHQgbW9kZSBoYW5kbGluZyBhbmQgcmV0dXJuIGRlZmF1bHQgdGV4dCBtb2RlLgogKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHNldCBWR0EgZW11bGF0aW9uIHRvIHRleHQgbW9kZS4KICovCnZvaWQgVkdBX0luaXRBbHBoYU1vZGUodW5zaWduZWQqWHJlcyx1bnNpZ25lZCpZcmVzKQp7CiAgICBDT05TT0xFX1NDUkVFTl9CVUZGRVJfSU5GTyBpbmZvOwoKICAgIGlmKEdldENvbnNvbGVTY3JlZW5CdWZmZXJJbmZvKCBWR0FfQWxwaGFDb25zb2xlKCksICZpbmZvICkpCiAgICB7CiAgICAgICAgdmdhX3RleHRfY29uc29sZSA9IFRSVUU7CiAgICAgICAgdmdhX3RleHRfeCA9IGluZm8uZHdDdXJzb3JQb3NpdGlvbi5YOwogICAgICAgIHZnYV90ZXh0X3kgPSBpbmZvLmR3Q3Vyc29yUG9zaXRpb24uWTsKICAgICAgICB2Z2FfdGV4dF9hdHRyID0gaW5mby53QXR0cmlidXRlczsKICAgICAgICAqWHJlcyA9IGluZm8uZHdTaXplLlg7CiAgICAgICAgKllyZXMgPSBpbmZvLmR3U2l6ZS5ZOwogICAgfSAKICAgIGVsc2UKICAgIHsKICAgICAgICB2Z2FfdGV4dF9jb25zb2xlID0gRkFMU0U7CiAgICAgICAgdmdhX3RleHRfeCA9IDA7CiAgICAgICAgdmdhX3RleHRfeSA9IDA7CiAgICAgICAgdmdhX3RleHRfYXR0ciA9IDB4MGY7CiAgICAgICAgKlhyZXMgPSA4MDsKICAgICAgICAqWXJlcyA9IDI1OwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgIFZHQV9HZXRBbHBoYU1vZGUKICoKICogR2V0IGN1cnJlbnQgdGV4dCBtb2RlLiBSZXR1cm5zIFRSVUUgYW5kIHNldHMgcmVzb2x1dGlvbiBpZgogKiBhbnkgVkdBIHRleHQgbW9kZSBoYXMgYmVlbiBpbml0aWFsaXplZC4KICovCkJPT0wgVkdBX0dldEFscGhhTW9kZSh1bnNpZ25lZCpYcmVzLHVuc2lnbmVkKllyZXMpCnsKICAgIGlmICh2Z2FfdGV4dF93aWR0aCAhPSAwICYmIHZnYV90ZXh0X2hlaWdodCAhPSAwKSB7CiAgICAgICAgKlhyZXMgPSB2Z2FfdGV4dF93aWR0aDsKICAgICAgICAqWXJlcyA9IHZnYV90ZXh0X2hlaWdodDsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0gZWxzZQogICAgICAgIHJldHVybiBGQUxTRTsKfQoKdm9pZCBWR0FfU2V0Q3Vyc29yU2hhcGUodW5zaWduZWQgY2hhciBzdGFydF9vcHRpb25zLCB1bnNpZ25lZCBjaGFyIGVuZCkKewogICAgQ09OU09MRV9DVVJTT1JfSU5GTyBjY2k7CgogICAgLyogc3RhbmRhcmQgY3Vyc29yIHNldHRpbmdzOgogICAgICogMHgwNjA3ID09IENHQSwgMHgwYjBjID09IG1vbm9jaHJvbWUsIDB4MGQwZSA9PSBFR0EvVkdBICovCgogICAgLyogY2FsY3VsYXRlIHBlcmNlbnRhZ2UgZnJvbSBib3R0b20gLSBhc3N1bWluZyBWR0EgKGJvdHRvbSAweDBlKSAqLwogICAgY2NpLmR3U2l6ZSA9ICgoZW5kICYgMHgxZikgLSAoc3RhcnRfb3B0aW9ucyAmIDB4MWYpKS8weDBlICogMTAwOwogICAgaWYgKCFjY2kuZHdTaXplKSBjY2kuZHdTaXplKys7IC8qIE5VTEwgY3Vyc29yIHdvdWxkIG1ha2UgU0NDSSgpIGZhaWwgISAqLwogICAgY2NpLmJWaXNpYmxlID0gKChzdGFydF9vcHRpb25zICYgMHg2MCkgIT0gMHgyMCk7IC8qIGludmlzaWJsZSA/ICovCgogICAgU2V0Q29uc29sZUN1cnNvckluZm8oVkdBX0FscGhhQ29uc29sZSgpLCZjY2kpOwp9Cgp2b2lkIFZHQV9TZXRDdXJzb3JQb3ModW5zaWduZWQgWCx1bnNpZ25lZCBZKQp7CiAgICB2Z2FfdGV4dF94ID0gWDsKICAgIHZnYV90ZXh0X3kgPSBZOwp9Cgp2b2lkIFZHQV9HZXRDdXJzb3JQb3ModW5zaWduZWQqWCx1bnNpZ25lZCpZKQp7CiAgICBpZiAoWCkgKlggPSB2Z2FfdGV4dF94OwogICAgaWYgKFkpICpZID0gdmdhX3RleHRfeTsKfQoKc3RhdGljIHZvaWQgVkdBX1B1dENoYXJBdCh1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCBCWVRFIGFzY2lpLCBpbnQgYXR0cikKewogICAgY2hhciAqZGF0ID0gVkdBX0FscGhhQnVmZmVyKCkgKyAoKHZnYV90ZXh0X3dpZHRoICogeSArIHgpICogMik7CiAgICBkYXRbMF0gPSBhc2NpaTsKICAgIGlmIChhdHRyPj0wKQogICAgICAgIGRhdFsxXSA9IGF0dHI7Cn0KCnZvaWQgVkdBX1dyaXRlQ2hhcnModW5zaWduZWQgWCx1bnNpZ25lZCBZLHVuc2lnbmVkIGNoLGludCBhdHRyLGludCBjb3VudCkKewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICB3aGlsZSAoY291bnQtLSkgCiAgICAgICAgVkdBX1B1dENoYXJBdChYICsgY291bnQsIFksIGNoLCBhdHRyKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9Cgp2b2lkIFZHQV9QdXRDaGFyKEJZVEUgYXNjaWkpCnsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgc3dpdGNoKGFzY2lpKSB7CiAgICBjYXNlICdcYic6CiAgICAgICAgaWYgKHZnYV90ZXh0X3gpCiAgICAgICAgewogICAgICAgICAgICB2Z2FfdGV4dF94LS07CiAgICAgICAgICAgIFZHQV9QdXRDaGFyQXQodmdhX3RleHRfeCwgdmdhX3RleHRfeSwgJyAnLCAwKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXHQnOgogICAgICAgIHZnYV90ZXh0X3ggKz0gKCh2Z2FfdGV4dF94ICsgOCkgJiB+NykgLSB2Z2FfdGV4dF94OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ1xuJzoKICAgICAgICB2Z2FfdGV4dF95Kys7CiAgICAgICAgdmdhX3RleHRfeCA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXGEnOgogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ1xyJzoKICAgICAgICB2Z2FfdGV4dF94ID0gMDsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIFZHQV9QdXRDaGFyQXQodmdhX3RleHRfeCwgdmdhX3RleHRfeSwgYXNjaWksIHZnYV90ZXh0X2F0dHIpOwogICAgICAgIHZnYV90ZXh0X3grKzsKICAgIH0KCiAgICBpZiAodmdhX3RleHRfeCA+PSB2Z2FfdGV4dF93aWR0aCkKICAgIHsKICAgICAgICB2Z2FfdGV4dF94ID0gMDsKICAgICAgICB2Z2FfdGV4dF95Kys7CiAgICB9CgogICAgaWYgKHZnYV90ZXh0X3kgPj0gdmdhX3RleHRfaGVpZ2h0KQogICAgewogICAgICAgIHZnYV90ZXh0X3kgPSB2Z2FfdGV4dF9oZWlnaHQgLSAxOwogICAgICAgIFZHQV9TY3JvbGxVcFRleHQoIDAsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHZnYV90ZXh0X2hlaWdodCAtIDEsIHZnYV90ZXh0X3dpZHRoIC0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgdmdhX3RleHRfYXR0ciApOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgY29uc29sZSwgd3JpdGUgZGlyZWN0bHkgdG8gc3RhbmRhcmQgb3V0cHV0LgogICAgICovCiAgICBpZighdmdhX3RleHRfY29uc29sZSkKICAgICAgICBXcml0ZUZpbGUoVkdBX0FscGhhQ29uc29sZSgpLCAmYXNjaWksIDEsIE5VTEwsIE5VTEwpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7Cn0KCnZvaWQgVkdBX1NldFRleHRBdHRyaWJ1dGUoQllURSBhdHRyKQp7CiAgICB2Z2FfdGV4dF9hdHRyID0gYXR0cjsKfQoKdm9pZCBWR0FfQ2xlYXJUZXh0KHVuc2lnbmVkIHJvdzEsIHVuc2lnbmVkIGNvbDEsCiAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCB1bnNpZ25lZCBjb2wyLAogICAgICAgICAgICAgICAgICAgQllURSBhdHRyKQp7CiAgICB1bnNpZ25lZCB4LCB5OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgZm9yKHk9cm93MTsgeTw9cm93MjsgeSsrKQogICAgICAgIGZvcih4PWNvbDE7IHg8PWNvbDI7IHgrKykKICAgICAgICAgICAgVkdBX1B1dENoYXJBdCh4LCB5LCAweDIwLCBhdHRyKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9Cgp2b2lkIFZHQV9TY3JvbGxVcFRleHQodW5zaWduZWQgcm93MSwgIHVuc2lnbmVkIGNvbDEsCiAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCAgdW5zaWduZWQgY29sMiwKICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxpbmVzLCBCWVRFIGF0dHIpCnsKICAgIGNoYXIgICAgKmJ1ZmZlciA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgdW5zaWduZWQgeTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIC8qCiAgICAgKiBTY3JvbGwgYnVmZmVyLgogICAgICovCiAgICBmb3IgKHkgPSByb3cxOyB5IDw9IHJvdzIgLSBsaW5lczsgeSsrKQogICAgICAgIG1lbW1vdmUoIGJ1ZmZlciArIGNvbDEgKyB5ICogdmdhX3RleHRfd2lkdGggKiAyLAogICAgICAgICAgICAgICAgIGJ1ZmZlciArIGNvbDEgKyAoeSArIGxpbmVzKSAqIHZnYV90ZXh0X3dpZHRoICogMiwKICAgICAgICAgICAgICAgICAoY29sMiAtIGNvbDEgKyAxKSAqIDIgKTsKCiAgICAvKgogICAgICogRmlsbCBleHBvc2VkIGxpbmVzLgogICAgICovCiAgICBmb3IgKHkgPSBtYXgocm93MSwgcm93MiAtIGxpbmVzICsgMSk7IHkgPD0gcm93MjsgeSsrKQogICAgICAgIFZHQV9Xcml0ZUNoYXJzKCBjb2wxLCB5LCAnICcsIGF0dHIsIGNvbDIgLSBjb2wxICsgMSApOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7Cn0KCnZvaWQgVkdBX1Njcm9sbERvd25UZXh0KHVuc2lnbmVkIHJvdzEsICB1bnNpZ25lZCBjb2wxLAogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCAgdW5zaWduZWQgY29sMiwKICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbGluZXMsIEJZVEUgYXR0cikKewogICAgY2hhciAgICAqYnVmZmVyID0gVkdBX0FscGhhQnVmZmVyKCk7CiAgICB1bnNpZ25lZCB5OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgLyoKICAgICAqIFNjcm9sbCBidWZmZXIuCiAgICAgKi8KICAgIGZvciAoeSA9IHJvdzI7IHkgPj0gcm93MSArIGxpbmVzOyB5LS0pCiAgICAgICAgbWVtbW92ZSggYnVmZmVyICsgY29sMSArIHkgKiB2Z2FfdGV4dF93aWR0aCAqIDIsCiAgICAgICAgICAgICAgICAgYnVmZmVyICsgY29sMSArICh5IC0gbGluZXMpICogdmdhX3RleHRfd2lkdGggKiAyLAogICAgICAgICAgICAgICAgIChjb2wyIC0gY29sMSArIDEpICogMiApOwoKICAgIC8qCiAgICAgKiBGaWxsIGV4cG9zZWQgbGluZXMuCiAgICAgKi8KICAgIGZvciAoeSA9IHJvdzE7IHkgPD0gbWluKHJvdzEgKyBsaW5lcyAtIDEsIHJvdzIpOyB5KyspCiAgICAgICAgVkdBX1dyaXRlQ2hhcnMoIGNvbDEsIHksICcgJywgYXR0ciwgY29sMiAtIGNvbDEgKyAxICk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKdm9pZCBWR0FfR2V0Q2hhcmFjdGVyQXRDdXJzb3IoQllURSAqYXNjaWksIEJZVEUgKmF0dHIpCnsKICAgIGNoYXIgKmRhdDsKCiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKSArICgodmdhX3RleHRfd2lkdGggKiB2Z2FfdGV4dF95ICsgdmdhX3RleHRfeCkgKiAyKTsKCiAgICAqYXNjaWkgPSBkYXRbMF07CiAgICAqYXR0ciA9IGRhdFsxXTsKfQoKCi8qKiogQ09OVFJPTCAqKiovCgovKiBGSVhNRTogb3B0aW1pemUgYnkgZG9pbmcgdGhpcyBvbmx5IGlmIHRoZSBkYXRhIGhhcyBhY3R1YWxseSBjaGFuZ2VkCiAqICAgICAgICAoaW4gYSB3YXkgc2ltaWxhciB0byBESUJTZWN0aW9uLCBwZXJoYXBzKSAqLwpzdGF0aWMgdm9pZCBWR0FfUG9sbF9HcmFwaGljcyh2b2lkKQp7CiAgdW5zaWduZWQgaW50IFBpdGNoLCBIZWlnaHQsIFdpZHRoLCBYLCBZOwogIGNoYXIgKnN1cmY7CiAgY2hhciAqZGF0ID0gdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfb2Zmc2V0OwogIGludCAgIGJwcCA9ICh2Z2FfZmJfZGVwdGggKyA3KSAvIDg7CgogIHN1cmYgPSBWR0FfTG9jaygmUGl0Y2gsJkhlaWdodCwmV2lkdGgsTlVMTCk7CiAgaWYgKCFzdXJmKSByZXR1cm47CgogIC8qCiAgICogU3luY2hyb25pemUgZnJhbWVidWZmZXIgY29udGVudHMuCiAgICovCiAgaWYgKHZnYV9mYl93aW5kb3cgIT0gLTEpCiAgICAgIFZHQV9TeW5jV2luZG93KCBUUlVFICk7CgogIC8qCiAgICogRG91YmxlIFZHQSBmcmFtZWJ1ZmZlciAoMzIweDIwMCAtPiA2NDB4NDAwKSwgaWYgbmVlZGVkLgogICAqLwogIGlmKEhlaWdodCA+PSAyICogdmdhX2ZiX2hlaWdodCAmJiBXaWR0aCA+PSAyICogdmdhX2ZiX3dpZHRoICYmIGJwcCA9PSAxKQogICAgZm9yIChZPTA7IFk8dmdhX2ZiX2hlaWdodDsgWSsrLHN1cmYrPVBpdGNoKjIsZGF0Kz12Z2FfZmJfcGl0Y2gpCiAgICAgIGZvciAoWD0wOyBYPHZnYV9mYl93aWR0aDsgWCsrKSB7CiAgICAgICBCWVRFIHZhbHVlID0gZGF0W1hdOwogICAgICAgc3VyZltYKjJdID0gdmFsdWU7CiAgICAgICBzdXJmW1gqMisxXSA9IHZhbHVlOwogICAgICAgc3VyZltYKjIrUGl0Y2hdID0gdmFsdWU7CiAgICAgICBzdXJmW1gqMitQaXRjaCsxXSA9IHZhbHVlOwogICAgICB9CiAgZWxzZQogICAgZm9yIChZPTA7IFk8dmdhX2ZiX2hlaWdodDsgWSsrLHN1cmYrPVBpdGNoLGRhdCs9dmdhX2ZiX3BpdGNoKQogICAgICBtZW1jcHkoc3VyZiwgZGF0LCB2Z2FfZmJfd2lkdGggKiBicHApOwoKICBWR0FfVW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIFZHQV9Qb2xsX1RleHQodm9pZCkKewogICAgY2hhciAqZGF0LCAqb2xkLCAqcF9saW5lOwogICAgdW5zaWduZWQgaW50IFgsIFk7CiAgICBDSEFSX0lORk8gY2hbMjU2XTsgLyogdGhhdCBzaG91bGQgc3VmZmljZSBmb3IgdGhlIGxhcmdlc3QgdGV4dCB3aWR0aCAqLwogICAgQ09PUkQgc2l6LCBvZmY7CiAgICBTTUFMTF9SRUNUIGRlc3Q7CiAgICBIQU5ETEUgY29uID0gVkdBX0FscGhhQ29uc29sZSgpOwogICAgQk9PTCBsaW5lY2hhbmdlZCA9IEZBTFNFOyAvKiB2aWRlbyBtZW1vcnkgYXJlYSBkaWZmZXJzIGZyb20gc3RvcmVkIGNvcHk/ICovCgogICAgLyogU3luY2hyb25pemUgY3Vyc29yIHBvc2l0aW9uLiAqLwogICAgb2ZmLlggPSB2Z2FfdGV4dF94OwogICAgb2ZmLlkgPSB2Z2FfdGV4dF95OwogICAgU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGNvbixvZmYpOwoKICAgIGRhdCA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgb2xkID0gdmdhX3RleHRfb2xkOyAvKiBwb2ludGVyIHRvIHN0b3JlZCB2aWRlbyBtZW0gY29weSAqLwogICAgc2l6LlggPSB2Z2FfdGV4dF93aWR0aDsgc2l6LlkgPSAxOwogICAgb2ZmLlggPSAwOyBvZmYuWSA9IDA7CgogICAgLyogY29weSBmcm9tIHZpcnR1YWwgVkdBIGZyYW1lIGJ1ZmZlciB0byBjb25zb2xlICovCiAgICBmb3IgKFk9MDsgWTx2Z2FfdGV4dF9oZWlnaHQ7IFkrKykgewoJbGluZWNoYW5nZWQgPSBtZW1jbXAoZGF0LCBvbGQsIHZnYV90ZXh0X3dpZHRoKjIpOwoJaWYgKGxpbmVjaGFuZ2VkKQoJewoJICAgIC8qVFJBQ0UoImxpbmUgJWQgY2hhbmdlZFxuIiwgWSk7Ki8KCSAgICBwX2xpbmUgPSBkYXQ7CiAgICAgICAgICAgIGZvciAoWD0wOyBYPHZnYV90ZXh0X3dpZHRoOyBYKyspIHsKICAgICAgICAgICAgICAgIGNoW1hdLkNoYXIuQXNjaWlDaGFyID0gKnBfbGluZSsrOwogICAgICAgICAgICAgICAgLyogV3JpdGVDb25zb2xlT3V0cHV0QSBkb2Vzbid0IGxpa2UgImRlYWQiIGNoYXJzICovCiAgICAgICAgICAgICAgICBpZiAoY2hbWF0uQ2hhci5Bc2NpaUNoYXIgPT0gJ1wwJykKICAgICAgICAgICAgICAgICAgICBjaFtYXS5DaGFyLkFzY2lpQ2hhciA9ICcgJzsKICAgICAgICAgICAgICAgIGNoW1hdLkF0dHJpYnV0ZXMgPSAqcF9saW5lKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdC5Ub3A9WTsgZGVzdC5Cb3R0b209WTsKICAgICAgICAgICAgZGVzdC5MZWZ0PTA7IGRlc3QuUmlnaHQ9dmdhX3RleHRfd2lkdGgrMTsKICAgICAgICAgICAgV3JpdGVDb25zb2xlT3V0cHV0QShjb24sIGNoLCBzaXosIG9mZiwgJmRlc3QpOwoJICAgIG1lbWNweShvbGQsIGRhdCwgdmdhX3RleHRfd2lkdGgqMik7Cgl9CgkvKiBhZHZhbmNlIHRvIG5leHQgdGV4dCBsaW5lICovCglkYXQgKz0gdmdhX3RleHRfd2lkdGgqMjsKCW9sZCArPSB2Z2FfdGV4dF93aWR0aCoyOwogICAgfQp9CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBWR0FfUG9sbCggTFBWT0lEIGFyZywgRFdPUkQgbG93LCBEV09SRCBoaWdoICkKewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICBpZiAobHBkZHJhdykKICAgICAgICBWR0FfUG9sbF9HcmFwaGljcygpOwogICAgZWxzZQogICAgICAgIFZHQV9Qb2xsX1RleHQoKTsKCiAgICAvKgogICAgICogRmFrZSBzdGFydCBvZiByZXRyYWNlLgogICAgICovCiAgICB2Z2FfcmV0cmFjZV92ZXJ0aWNhbCA9IFRSVUU7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKc3RhdGljIEJZVEUgcGFscmVnLHBhbGNudDsKc3RhdGljIFBBTEVUVEVFTlRSWSBwYWxkYXQ7Cgp2b2lkIFZHQV9pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsICkKewogICAgc3dpdGNoIChwb3J0KSB7CiAgICAgICAgY2FzZSAweDNjMDoKICAgICAgICAgICBpZiAodmdhX2FkZHJlc3NfM2MwKQogICAgICAgICAgICAgICB2Z2FfaW5kZXhfM2MwID0gdmFsOwogICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjMDogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgICAgICB2Z2FfaW5kZXhfM2MwLCB2YWwpOwogICAgICAgICAgIHZnYV9hZGRyZXNzXzNjMCA9ICF2Z2FfYWRkcmVzc18zYzA7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjNDoKICAgICAgICAgICB2Z2FfaW5kZXhfM2M0ID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzYzU6CiAgICAgICAgICBzd2l0Y2godmdhX2luZGV4XzNjNCkgewogICAgICAgICAgICAgICBjYXNlIDB4MDQ6IC8qIFNlcXVlbmNlcjogTWVtb3J5IE1vZGUgUmVnaXN0ZXIgKi8KICAgICAgICAgICAgICAgICAgaWYodmdhX2ZiX2RlcHRoID09IDgpCiAgICAgICAgICAgICAgICAgICAgICBWR0FfU2V0V2luZG93U3RhcnQoKHZhbCAmIDgpID8gMCA6IC0xKTsKICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgRklYTUUoIk1lbW9yeSBNb2RlIFJlZ2lzdGVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBtb2RlLlxuIik7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2M0OiAweCUwMnggKHZhbHVlIDB4JTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzQsIHZhbCk7CiAgICAgICAgICAgfQogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzYzg6CiAgICAgICAgICAgIHBhbHJlZz12YWw7IHBhbGNudD0wOyBicmVhazsKICAgICAgICBjYXNlIDB4M2M5OgogICAgICAgICAgICAoKEJZVEUqKSZwYWxkYXQpW3BhbGNudCsrXT12YWwgPDwgMjsKICAgICAgICAgICAgaWYgKHBhbGNudD09MykgewogICAgICAgICAgICAgICAgVkdBX1NldFBhbGV0dGUoJnBhbGRhdCxwYWxyZWcrKywxKTsKICAgICAgICAgICAgICAgIHBhbGNudD0wOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzY2U6CiAgICAgICAgICAgIHZnYV9pbmRleF8zY2UgPSB2YWw7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjZjoKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2NlOiAweCUwMnggKHZhbHVlIDB4JTAyeClcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjZSwgdmFsKTsKICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2Q0OgogICAgICAgICAgIHZnYV9pbmRleF8zZDQgPSB2YWw7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNkNToKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2Q0OiAweCUwMnggKHZhbHVlIDB4JTAyeClcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNkNCwgdmFsKTsKICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgVkdBIHJlZ2lzdGVyOiAweCUwNHggKHZhbHVlIDB4JTAyeClcbiIsIHBvcnQsIHZhbCk7CiAgICB9Cn0KCkJZVEUgVkdBX2lvcG9ydF9pbiggV09SRCBwb3J0ICkKewogICAgQllURSByZXQ7CgogICAgc3dpdGNoIChwb3J0KSB7CiAgICAgICAgY2FzZSAweDNjMToKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2MwOiAweCUwMnhcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjMCk7CiAgICAgICAgICAgcmV0dXJuIDB4ZmY7CiAgICAgICAgY2FzZSAweDNjNToKICAgICAgICAgICBzd2l0Y2godmdhX2luZGV4XzNjNCkgewogICAgICAgICAgICAgICBjYXNlIDB4MDQ6IC8qIFNlcXVlbmNlcjogTWVtb3J5IE1vZGUgUmVnaXN0ZXIgKi8KICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFZHQV9HZXRXaW5kb3dTdGFydCgpID09IC0xKSA/IDB4ZjcgOiAweGZmOwogICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjNDogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjNCk7CiAgICAgICAgICAgICAgICAgICByZXR1cm4gMHhmZjsKICAgICAgICAgICB9CiAgICAgICAgY2FzZSAweDNjZjoKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2NlOiAweCUwMnhcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjZSk7CiAgICAgICAgICAgcmV0dXJuIDB4ZmY7CiAgICAgICAgY2FzZSAweDNkNToKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2Q0OiAweCUwMnhcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNkNCk7CiAgICAgICAgICAgcmV0dXJuIDB4ZmY7CgogICAgICAgIGNhc2UgMHgzZGE6CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFJlYWQgZnJvbSB0aGlzIHJlZ2lzdGVyIHJlc2V0cyByZWdpc3RlciAweDNjMCBhZGRyZXNzIGZsaXAtZmxvcC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHZnYV9hZGRyZXNzXzNjMCA9IFRSVUU7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBSZWFkIGZyb20gdGhpcyByZWdpc3RlciByZXR1cm5zIGZvbGxvd2luZyBiaXRzOgogICAgICAgICAgICAgKiAgIHh4eHgxeHh4ID0gVmVydGljYWwgcmV0cmFjZSBpbiBwcm9ncmVzcyBpZiBzZXQuCiAgICAgICAgICAgICAqICAgeHh4eHgxeHggPSBMaWdodCBwZW4gc3dpdGNoZWQgb24uCiAgICAgICAgICAgICAqICAgeHh4eHh4MXggPSBMaWdodCBwZW4gdHJpZ2dlciBzZXQuCiAgICAgICAgICAgICAqICAgeHh4eHh4eDEgPSBFaXRoZXIgdmVydGljYWwgb3IgaG9yaXpvbnRhbCByZXRyYWNlIAogICAgICAgICAgICAgKiAgICAgICAgICAgICAgaW4gcHJvZ3Jlc3MgaWYgc2V0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0ID0gMDsKICAgICAgICAgICAgaWYgKHZnYV9yZXRyYWNlX3ZlcnRpY2FsKQogICAgICAgICAgICAgICAgcmV0IHw9IDk7CiAgICAgICAgICAgIGlmICh2Z2FfcmV0cmFjZV9ob3Jpem9udGFsKQogICAgICAgICAgICAgICAgcmV0IHw9IDM7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJZiBWR0EgbW9kZSBoYXMgYmVlbiBzZXQsIHZlcnRpY2FsIHJldHJhY2UgaXMKICAgICAgICAgICAgICogdHVybmVkIG9uIG9uY2UgYSBmcmFtZSBhbmQgY2xlYXJlZCBhZnRlciBlYWNoIHJlYWQuCiAgICAgICAgICAgICAqIFRoaXMgbWlnaHQgY2F1c2UgYXBwbGljYXRpb25zIHRoYXQgc3luY2hyb25pemUgd2l0aAogICAgICAgICAgICAgKiB2ZXJ0aWNhbCByZXRyYWNlIHRvIGFjdHVhbGx5IHNraXAgb25lIGZyYW1lIGJ1dCB0aGF0CiAgICAgICAgICAgICAqIGlzIHByb2JhYmx5IG5vdCBhIHByb2JsZW0uCiAgICAgICAgICAgICAqIAogICAgICAgICAgICAgKiBJZiBubyBWR0EgbW9kZSBoYXMgYmVlbiBzZXQsIHZlcnRpY2FsIHJldHJhY2UgaXMgZmFrZWQKICAgICAgICAgICAgICogYnkgdG9nZ2xpbmcgdGhlIHZhbHVlIGFmdGVyIGV2ZXJ5IHJlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoVkdBX0lzVGltZXJSdW5uaW5nKCkpCiAgICAgICAgICAgICAgICB2Z2FfcmV0cmFjZV92ZXJ0aWNhbCA9IEZBTFNFOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB2Z2FfcmV0cmFjZV92ZXJ0aWNhbCA9ICF2Z2FfcmV0cmFjZV92ZXJ0aWNhbDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRvZ2dsZSBob3Jpem9udGFsIHJldHJhY2UuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB2Z2FfcmV0cmFjZV9ob3Jpem9udGFsID0gIXZnYV9yZXRyYWNlX2hvcml6b250YWw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXQ9MHhmZjsKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFZHQSByZWdpc3RlcjogMHglMDR4XG4iLCBwb3J0KTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQgVkdBX0NsZWFuKHZvaWQpCnsKICAgIFZHQV9FeGl0KCk7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKfQo=