LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4gKHdpdGggc29tZSBoZWxwIGZyb20gTWFyY3VzIE1laXNzbmVyKQogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJ2Z2EuaCIKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgpzdGF0aWMgSURpcmVjdERyYXcgKmxwZGRyYXcgPSBOVUxMOwpzdGF0aWMgSURpcmVjdERyYXdTdXJmYWNlICpscGRkc3VyZjsKc3RhdGljIElEaXJlY3REcmF3UGFsZXR0ZSAqbHBkZHBhbDsKc3RhdGljIEREU1VSRkFDRURFU0Mgc2Rlc2M7CnN0YXRpYyBMT05HIHZnYV9yZWZyZXNoOwpzdGF0aWMgSEFORExFIHBvbGxfdGltZXI7CgovKgogKiBWR0EgY29udHJvbGxlciBtZW1vcnkgaXMgZW11bGF0ZWQgdXNpbmcgbGluZWFyIGZyYW1lYnVmZmVyLgogKiBUaGlzIGZyYW1idWZmZXIgYWxzbyBhY3RzIGFzIGFuIGludGVyZmFjZQogKiBiZXR3ZWVuIFZHQSBjb250cm9sbGVyIGVtdWxhdGlvbiBhbmQgRGlyZWN0RHJhdy4KICoKICogdmdhX2ZiX3dpZHRoOiBEaXNwbGF5IHdpZHRoIGluIHBpeGVscy4gQ2FuIGJlIG1vZGlmaWVkIHdoZW4KICogICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2hlaWdodDogRGlzcGxheSBoZWlnaHQgaW4gcGl4ZWxzLiBDYW4gYmUgbW9kaWZpZWQgd2hlbgogKiAgICAgICAgICAgICAgICBkaXNwbGF5IG1vZGUgaXMgY2hhbmdlZC4KICogdmdhX2ZiX2RlcHRoOiBOdW1iZXIgb2YgYml0cyB1c2VkIHRvIHN0b3JlIHNpbmdsZSBwaXhlbCBjb2xvciBpbmZvcm1hdGlvbi4KICogICAgICAgICAgICAgICBFYWNoIHBpeGVsIHVzZXMgKHZnYV9mYl9kZXB0aCs3KS84IGJ5dGVzIGJlY2F1c2UKICogICAgICAgICAgICAgICAxLTE2IGNvbG9yIG1vZGVzIGFyZSBtYXBwZWQgdG8gMjU2IGNvbG9yIG1vZGUuCiAqICAgICAgICAgICAgICAgQ2FuIGJlIG1vZGlmaWVkIHdoZW4gZGlzcGxheSBtb2RlIGlzIGNoYW5nZWQuCiAqIHZnYV9mYl9waXRjaDogSG93IG1hbnkgYnl0ZXMgdG8gYWRkIHRvIHBvaW50ZXIgaW4gb3JkZXIgdG8gbW92ZQogKiAgICAgICAgICAgICAgIGZyb20gb25lIHJvdyB0byBhbm90aGVyLiBUaGlzIGlzIGZpeGVkIGluIFZHQSBtb2RlcywKICogICAgICAgICAgICAgICBidXQgY2FuIGJlIG1vZGlmaWVkIGluIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9vZmZzZXQ6IE9mZnNldCBhZGRlZCB0byBmcmFtZWJ1ZmZlciBzdGFydCBhZGRyZXNzIGluIG9yZGVyCiAqICAgICAgICAgICAgICAgIHRvIGZpbmQgdGhlIGRpc3BsYXkgb3JpZ2luLiBQcm9ncmFtcyB1c2UgdGhpcyB0byBkbwogKiAgICAgICAgICAgICAgICBkb3VibGUgYnVmZmVyaW5nIGFuZCB0byBzY3JvbGwgZGlzcGxheS4gVGhlIHZhbHVlIGNhbgogKiAgICAgICAgICAgICAgICBiZSBtb2RpZmllZCBpbiBWR0EgYW5kIFNWR0EgbW9kZXMuCiAqIHZnYV9mYl9zaXplOiBIb3cgbWFueSBieXRlcyBhcmUgYWxsb2NhdGVkIHRvIGZyYW1lYnVmZmVyLgogKiAgICAgICAgICAgICAgVkdBIGZyYW1lYnVmZmVycyBhcmUgYWx3YXlzIGxhcmdlciB0aGFuIGRpc3BsYXkgc2l6ZSBhbmQKICogICAgICAgICAgICAgIFNWR0EgZnJhbWVidWZmZXJzIG1heSBhbHNvIGJlLgogKiB2Z2FfZmJfZGF0YTogUG9pbnRlciB0byBmcmFtZWJ1ZmZlciBzdGFydC4KICogdmdhX2ZiX3dpbmRvdzogT2Zmc2V0IG9mIDY0ayB3aW5kb3cgMHhhMDAwMCBpbiBieXRlcyBmcm9tIGZyYW1lYnVmZmVyIHN0YXJ0LgogKiAgICAgICAgICAgICAgICBUaGlzIHZhbHVlIGlzID49IDAsIGlmIG1vZGUgdXNlcyBsaW5lYXIgZnJhbWVidWZmZXIgYW5kCiAqICAgICAgICAgICAgICAgIC0xLCBpZiBtb2RlIHVzZXMgY29sb3IgcGxhbmVzLiBUaGlzIHZhbHVlIGlzIGZpeGVkCiAqICAgICAgICAgICAgICAgIGluIGFsbCBtb2RlcyBleGNlcHQgMHgxMyAoMjU2IGNvbG9yIFZHQSkgd2hlcmUKICogICAgICAgICAgICAgICAgMCBtZWFucyBub3JtYWwgbW9kZSBhbmQgLTEgbWVhbnMgTW9kZS1YICh1bmNoYWluZWQgbW9kZSkuCiAqLwpzdGF0aWMgaW50ICAgdmdhX2ZiX3dpZHRoOwpzdGF0aWMgaW50ICAgdmdhX2ZiX2hlaWdodDsKc3RhdGljIGludCAgIHZnYV9mYl9kZXB0aDsKc3RhdGljIGludCAgIHZnYV9mYl9waXRjaDsKc3RhdGljIGludCAgIHZnYV9mYl9vZmZzZXQ7CnN0YXRpYyBpbnQgICB2Z2FfZmJfc2l6ZSA9IDA7CnN0YXRpYyB2b2lkICp2Z2FfZmJfZGF0YSA9IDA7CnN0YXRpYyBpbnQgICB2Z2FfZmJfd2luZG93ID0gMDsKCnN0YXRpYyBCWVRFIHZnYV90ZXh0X2F0dHI7CnN0YXRpYyBjaGFyICp0ZXh0YnVmX29sZCA9IE5VTEw7CgovKgogKiBWR0EgY29udHJvbGxlciBwb3J0cyAweDNjMCwgMHgzYzQsIDB4M2NlIGFuZCAweDNkNCBhcmUKICogaW5kZXhlZCByZWdpc3RlcnMuIFRoZXNlIHBvcnRzIGFyZSB1c2VkIHRvIHNlbGVjdCBWR0EgY29udHJvbGxlcgogKiBzdWJyZWdpc3RlciB0aGF0IGNhbiBiZSB3cml0dGVuIHRvIG9yIHJlYWQgZnJvbSB1c2luZyBwb3J0cyAweDNjMSwKICogMHgzYzUsIDB4M2NmIG9yIDB4M2Q1LiBTZWxlY3RlZCBzdWJyZWdpc3RlciBpbmRleGVzIGFyZQogKiBzdG9yZWQgaW4gdmFyaWFibGVzIHZnYV9pbmRleF8qLgogKgogKiBQb3J0IDB4M2MwIGlzIHNwZWNpYWwgYmVjYXVzZSBpdCBpcyBib3RoIGluZGV4IGFuZAogKiBkYXRhLXdyaXRlIHJlZ2lzdGVyLiBGbGlwLWZsb3AgdmdhX2FkZHJlc3NfM2MwIHRlbGxzIHdoZXRoZXIKICogdGhlIHBvcnQgYWN0cyBjdXJyZW50bHkgYXMgYW4gYWRkcmVzcyByZWdpc3Rlci4gUmVhZGluZyBmcm9tIHBvcnQKICogMHgzZGEgcmVzZXRzIHRoZSBmbGlwLWZsb3AgdG8gYWRkcmVzcyBtb2RlLgogKi8Kc3RhdGljIEJZVEUgdmdhX2luZGV4XzNjMDsKc3RhdGljIEJZVEUgdmdhX2luZGV4XzNjNDsKc3RhdGljIEJZVEUgdmdhX2luZGV4XzNjZTsKc3RhdGljIEJZVEUgdmdhX2luZGV4XzNkNDsKc3RhdGljIEJPT0wgdmdhX2FkZHJlc3NfM2MwID0gVFJVRTsKCnN0YXRpYyBCT09MIHZnYV9tb2RlX2luaXRpYWxpemVkID0gRkFMU0U7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiB2Z2FfbG9jayA9IENSSVRJQ0FMX1NFQ1RJT05fSU5JVCgiVkdBIik7Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGlyZWN0RHJhd0NyZWF0ZVByb2MpKExQR1VJRCxMUERJUkVDVERSQVcgKixMUFVOS05PV04pOwpzdGF0aWMgRGlyZWN0RHJhd0NyZWF0ZVByb2MgcERpcmVjdERyYXdDcmVhdGU7CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBWR0FfUG9sbCggTFBWT0lEIGFyZywgRFdPUkQgbG93LCBEV09SRCBoaWdoICk7CgpzdGF0aWMgSFdORCB2Z2FfaHduZCA9IChIV05EKSBOVUxMOwoKLyoKICogRm9yIHNpbXBsaWNpdHksIEknbSBjcmVhdGluZyBhIHNlY29uZCBwYWxldHRlLgogKiAxNiBjb2xvciBhY2Nlc3NlcyB3aWxsIHVzZSB0aGVzZSBwb2ludGVycyBhbmQgaW5zZXJ0CiAqIGVudHJpZXMgZnJvbSB0aGUgNjQtY29sb3IgcGFsZXR0ZSBpbnRvIHRoZSBkZWZhdWx0CiAqIHBhbGV0dGUuICAgLS1Sb2JlcnQgJ0FkbWlyYWwnIENvZXltYW4KICovCgpzdGF0aWMgY2hhciB2Z2FfMTZfcGFsZXR0ZVsxN109ewogIDB4MDAsICAvKiAwIC0gQmxhY2sgICAgICAgICAqLwogIDB4MDEsICAvKiAxIC0gQmx1ZSAgICAgICAgICAqLwogIDB4MDIsICAvKiAyIC0gR3JlZW4gICAgICAgICAqLwogIDB4MDMsICAvKiAzIC0gQ3lhbiAgICAgICAgICAqLwogIDB4MDQsICAvKiA0IC0gUmVkICAgICAgICAgICAqLwogIDB4MDUsICAvKiA1IC0gTWFnZW50YSAgICAgICAqLwogIDB4MTQsICAvKiA2IC0gQnJvd24gICAgICAgICAqLwogIDB4MDcsICAvKiA3IC0gTGlnaHQgZ3JheSAgICAqLwogIDB4MzgsICAvKiA4IC0gRGFyayBncmF5ICAgICAqLwogIDB4MzksICAvKiA5IC0gTGlnaHQgYmx1ZSAgICAqLwogIDB4M2EsICAvKiBBIC0gTGlnaHQgZ3JlZW4gICAqLwogIDB4M2IsICAvKiBCIC0gTGlnaHQgY3lhbiAgICAqLwogIDB4M2MsICAvKiBDIC0gTGlnaHQgcmVkICAgICAqLwogIDB4M2QsICAvKiBEIC0gTGlnaHQgbWFnZW50YSAqLwogIDB4M2UsICAvKiBFIC0gWWVsbG93ICAgICAgICAqLwogIDB4M2YsICAvKiBGIC0gV2hpdGUgICAgICAgICAqLwogIDB4MDAgICAvKiBCb3JkZXIgQ29sb3IgICAgICAqLwp9OwoKc3RhdGljIFBBTEVUVEVFTlRSWSB2Z2FfZGVmX3BhbGV0dGVbMjU2XT17Ci8qIHJlZCAgZ3JlZW4gIGJsdWUgKi8KICB7MHgwMCwgMHgwMCwgMHgwMH0sIC8qIDAgLSBCbGFjayAqLwogIHsweDAwLCAweDAwLCAweDgwfSwgLyogMSAtIEJsdWUgKi8KICB7MHgwMCwgMHg4MCwgMHgwMH0sIC8qIDIgLSBHcmVlbiAqLwogIHsweDAwLCAweDgwLCAweDgwfSwgLyogMyAtIEN5YW4gKi8KICB7MHg4MCwgMHgwMCwgMHgwMH0sIC8qIDQgLSBSZWQgKi8KICB7MHg4MCwgMHgwMCwgMHg4MH0sIC8qIDUgLSBNYWdlbnRhICovCiAgezB4ODAsIDB4ODAsIDB4MDB9LCAvKiA2IC0gQnJvd24gKi8KICB7MHhDMCwgMHhDMCwgMHhDMH0sIC8qIDcgLSBMaWdodCBncmF5ICovCiAgezB4ODAsIDB4ODAsIDB4ODB9LCAvKiA4IC0gRGFyayBncmF5ICovCiAgezB4MDAsIDB4MDAsIDB4RkZ9LCAvKiA5IC0gTGlnaHQgYmx1ZSAqLwogIHsweDAwLCAweEZGLCAweDAwfSwgLyogQSAtIExpZ2h0IGdyZWVuICovCiAgezB4MDAsIDB4RkYsIDB4RkZ9LCAvKiBCIC0gTGlnaHQgY3lhbiAqLwogIHsweEZGLCAweDAwLCAweDAwfSwgLyogQyAtIExpZ2h0IHJlZCAqLwogIHsweEZGLCAweDAwLCAweEZGfSwgLyogRCAtIExpZ2h0IG1hZ2VudGEgKi8KICB7MHhGRiwgMHhGRiwgMHgwMH0sIC8qIEUgLSBZZWxsb3cgKi8KICB7MHhGRiwgMHhGRiwgMHhGRn0sIC8qIEYgLSBXaGl0ZSAqLwogIHswLDAsMH0gLyogRklYTUU6IGEgc2VyaWVzIG9mIGNvbnRpbnVvdXMgcmFpbmJvdyBodWVzIHNob3VsZCBmb2xsb3cgKi8KfTsKCi8qCiAqICAgVGhpcyBwYWxldHRlIGlzIHRoZSBkb3MgZGVmYXVsdCwgY29udmVydGVkIGZyb20gMTggYml0IGNvbG9yIHRvIDI0LgogKiAgICAgIEl0IGNvbnRhaW5zIG9ubHkgNjQgZW50cmllcyBvZiBjb2xvcnMtLWFsbCBvdGhlcnMgYXJlIHplcm9zLgogKiAgICAgICAgICAtLVJvYmVydCAnQWRtaXJhbCcgQ29leW1hbgogKi8Kc3RhdGljIFBBTEVUVEVFTlRSWSB2Z2FfZGVmNjRfcGFsZXR0ZVsyNTZdPXsKLyogcmVkICBncmVlbiAgYmx1ZSAqLwogIHsweDAwLCAweDAwLCAweDAwfSwgLyogMHgwMCAgICAgIEJsYWNrICAgICAgKi8KICB7MHgwMCwgMHgwMCwgMHhhYX0sIC8qIDB4MDEgICAgICBCbHVlICAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4MDB9LCAvKiAweDAyICAgICAgR3JlZW4gICAgICAqLwogIHsweDAwLCAweGFhLCAweGFhfSwgLyogMHgwMyAgICAgIEN5YW4gICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHgwMH0sIC8qIDB4MDQgICAgICBSZWQgICAgICAgICovCiAgezB4YWEsIDB4MDAsIDB4YWF9LCAvKiAweDA1ICAgICAgTWFnZW50YSAgICAqLwogIHsweGFhLCAweGFhLCAweDAwfSwgLyogMHgwNiAgICAgICovCiAgezB4YWEsIDB4YWEsIDB4YWF9LCAvKiAweDA3ICAgICAgTGlnaHQgR3JheSAqLwogIHsweDAwLCAweDAwLCAweDU1fSwgLyogMHgwOCAgICAgICovCiAgezB4MDAsIDB4MDAsIDB4ZmZ9LCAvKiAweDA5ICAgICAgKi8KICB7MHgwMCwgMHhhYSwgMHg1NX0sIC8qIDB4MGEgICAgICAqLwogIHsweDAwLCAweGFhLCAweGZmfSwgLyogMHgwYiAgICAgICovCiAgezB4YWEsIDB4MDAsIDB4NTV9LCAvKiAweDBjICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHhmZn0sIC8qIDB4MGQgICAgICAqLwogIHsweGFhLCAweGFhLCAweDU1fSwgLyogMHgwZSAgICAgICovCiAgezB4YWEsIDB4YWEsIDB4ZmZ9LCAvKiAweDBmICAgICAgKi8KICB7MHgwMCwgMHg1NSwgMHgwMH0sIC8qIDB4MTAgICAgICAqLwogIHsweDAwLCAweDU1LCAweGFhfSwgLyogMHgxMSAgICAgICovCiAgezB4MDAsIDB4ZmYsIDB4MDB9LCAvKiAweDEyICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHhhYX0sIC8qIDB4MTMgICAgICAqLwogIHsweGFhLCAweDU1LCAweDAwfSwgLyogMHgxNCAgICAgIEJyb3duICAgICAgKi8KICB7MHhhYSwgMHg1NSwgMHhhYX0sIC8qIDB4MTUgICAgICAqLwogIHsweGFhLCAweGZmLCAweDAwfSwgLyogMHgxNiAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4YWF9LCAvKiAweDE3ICAgICAgKi8KICB7MHgwMCwgMHg1NSwgMHg1NX0sIC8qIDB4MTggICAgICAqLwogIHsweDAwLCAweDU1LCAweGZmfSwgLyogMHgxOSAgICAgICovCiAgezB4MDAsIDB4ZmYsIDB4NTV9LCAvKiAweDFhICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHhmZn0sIC8qIDB4MWIgICAgICAqLwogIHsweGFhLCAweDU1LCAweDU1fSwgLyogMHgxYyAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4ZmZ9LCAvKiAweDFkICAgICAgKi8KICB7MHhhYSwgMHhmZiwgMHg1NX0sIC8qIDB4MWUgICAgICAqLwogIHsweGFhLCAweGZmLCAweGZmfSwgLyogMHgxZiAgICAgICovCiAgezB4NTUsIDB4MDAsIDB4MDB9LCAvKiAweDIwICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHhhYX0sIC8qIDB4MjEgICAgICAqLwogIHsweDU1LCAweGFhLCAweDAwfSwgLyogMHgyMiAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4YWF9LCAvKiAweDIzICAgICAgKi8KICB7MHhmZiwgMHgwMCwgMHgwMH0sIC8qIDB4MjQgICAgICAqLwogIHsweGZmLCAweDAwLCAweGFhfSwgLyogMHgyNSAgICAgICovCiAgezB4ZmYsIDB4YWEsIDB4MDB9LCAvKiAweDI2ICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHhhYX0sIC8qIDB4MjcgICAgICAqLwogIHsweDU1LCAweDAwLCAweDU1fSwgLyogMHgyOCAgICAgICovCiAgezB4NTUsIDB4MDAsIDB4ZmZ9LCAvKiAweDI5ICAgICAgKi8KICB7MHg1NSwgMHhhYSwgMHg1NX0sIC8qIDB4MmEgICAgICAqLwogIHsweDU1LCAweGFhLCAweGZmfSwgLyogMHgyYiAgICAgICovCiAgezB4ZmYsIDB4MDAsIDB4NTV9LCAvKiAweDJjICAgICAgKi8KICB7MHhmZiwgMHgwMCwgMHhmZn0sIC8qIDB4MmQgICAgICAqLwogIHsweGZmLCAweGFhLCAweDU1fSwgLyogMHgyZSAgICAgICovCiAgezB4ZmYsIDB4YWEsIDB4ZmZ9LCAvKiAweDJmICAgICAgKi8KICB7MHg1NSwgMHg1NSwgMHgwMH0sIC8qIDB4MzAgICAgICAqLwogIHsweDU1LCAweDU1LCAweGFhfSwgLyogMHgzMSAgICAgICovCiAgezB4NTUsIDB4ZmYsIDB4MDB9LCAvKiAweDMyICAgICAgKi8KICB7MHg1NSwgMHhmZiwgMHhhYX0sIC8qIDB4MzMgICAgICAqLwogIHsweGZmLCAweDU1LCAweDAwfSwgLyogMHgzNCAgICAgICovCiAgezB4ZmYsIDB4NTUsIDB4YWF9LCAvKiAweDM1ICAgICAgKi8KICB7MHhmZiwgMHhmZiwgMHgwMH0sIC8qIDB4MzYgICAgICAqLwogIHsweGZmLCAweGZmLCAweGFhfSwgLyogMHgzNyAgICAgICovCiAgezB4NTUsIDB4NTUsIDB4NTV9LCAvKiAweDM4ICAgICAgRGFyayBHcmF5ICAgICAqLwogIHsweDU1LCAweDU1LCAweGZmfSwgLyogMHgzOSAgICAgIExpZ2h0IEJsdWUgICAgKi8KICB7MHg1NSwgMHhmZiwgMHg1NX0sIC8qIDB4M2EgICAgICBMaWdodCBHcmVlbiAgICovCiAgezB4NTUsIDB4ZmYsIDB4ZmZ9LCAvKiAweDNiICAgICAgTGlnaHQgQ3lhbiAgICAqLwogIHsweGZmLCAweDU1LCAweDU1fSwgLyogMHgzYyAgICAgIExpZ2h0IFJlZCAgICAgKi8KICB7MHhmZiwgMHg1NSwgMHhmZn0sIC8qIDB4M2QgICAgICBMaWdodCBNYWdlbnRhICovCiAgezB4ZmYsIDB4ZmYsIDB4NTV9LCAvKiAweDNlICAgICAgWWVsbG93ICAgICAgICAqLwogIHsweGZmLCAweGZmLCAweGZmfSwgLyogMHgzZiAgICAgIFdoaXRlICAgICAgICAgKi8KICB7MCwwLDB9IC8qIFRoZSBuZXh0IDE5MiBlbnRyaWVzIGFyZSBhbGwgemVyb3MgICovCn07CgpzdGF0aWMgSEFORExFIFZHQV90aW1lcjsKc3RhdGljIEhBTkRMRSBWR0FfdGltZXJfdGhyZWFkOwoKLyogc2V0IHRoZSB0aW1lciByYXRlOyBjYWxsZWQgaW4gdGhlIHBvbGxpbmcgdGhyZWFkIGNvbnRleHQgKi8Kc3RhdGljIHZvaWQgQ0FMTEJBQ0sgc2V0X3RpbWVyX3JhdGUoIFVMT05HX1BUUiBhcmcgKQp7CiAgICBMQVJHRV9JTlRFR0VSIHdoZW47CgogICAgd2hlbi5zLkxvd1BhcnQgPSB3aGVuLnMuSGlnaFBhcnQgPSAwOwogICAgU2V0V2FpdGFibGVUaW1lciggVkdBX3RpbWVyLCAmd2hlbiwgYXJnLCBWR0FfUG9sbCwgMCwgRkFMU0UgKTsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFZHQV9UaW1lclRocmVhZCggdm9pZCAqZHVtbXkgKQp7CiAgICBmb3IgKDs7KSBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXgoIDAsIE5VTEwsIEZBTFNFLCBJTkZJTklURSwgVFJVRSApOwp9CgpzdGF0aWMgdm9pZCBWR0FfRGVpbnN0YWxsVGltZXIodm9pZCkKewogICAgaWYgKFZHQV90aW1lcl90aHJlYWQpCiAgICB7CiAgICAgICAgQ2FuY2VsV2FpdGFibGVUaW1lciggVkdBX3RpbWVyICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIFZHQV90aW1lciApOwogICAgICAgIFRlcm1pbmF0ZVRocmVhZCggVkdBX3RpbWVyX3RocmVhZCwgMCApOwogICAgICAgIENsb3NlSGFuZGxlKCBWR0FfdGltZXJfdGhyZWFkICk7CiAgICAgICAgVkdBX3RpbWVyX3RocmVhZCA9IDA7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIFZHQV9JbnN0YWxsVGltZXIodW5zaWduZWQgUmF0ZSkKewogICAgaWYgKCFWR0FfdGltZXJfdGhyZWFkKQogICAgewogICAgICAgIFZHQV90aW1lciA9IENyZWF0ZVdhaXRhYmxlVGltZXJBKCBOVUxMLCBGQUxTRSwgTlVMTCApOwogICAgICAgIFZHQV90aW1lcl90aHJlYWQgPSBDcmVhdGVUaHJlYWQoIE5VTEwsIDAsIFZHQV9UaW1lclRocmVhZCwgTlVMTCwgMCwgTlVMTCApOwogICAgfQogICAgUXVldWVVc2VyQVBDKCBzZXRfdGltZXJfcmF0ZSwgVkdBX3RpbWVyX3RocmVhZCwgKFVMT05HX1BUUilSYXRlICk7Cn0KCkhBTkRMRSBWR0FfQWxwaGFDb25zb2xlKHZvaWQpCnsKICAgIC8qIHRoaXMgYXNzdW1lcyB0aGF0IG5vIFdpbjMyIHJlZGlyZWN0aW9uIGhhcyB0YWtlbiBwbGFjZSwgYnV0IHRoZW4gYWdhaW4sCiAgICAgKiBvbmx5IDE2LWJpdCBhcHBzIGFyZSBsaWtlbHkgdG8gdXNlIHRoaXMgcGFydCBvZiBXaW5lLi4uICovCiAgICByZXR1cm4gR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKTsKfQoKY2hhcipWR0FfQWxwaGFCdWZmZXIodm9pZCkKewogICAgcmV0dXJuIERPU01FTV9NYXBEb3NUb0xpbmVhcigweGI4MDAwKTsKfQoKLyoqKiBHUkFQSElDUyBNT0RFICoqKi8KCnR5cGVkZWYgc3RydWN0IHsKICB1bnNpZ25lZCBYcmVzLCBZcmVzLCBEZXB0aDsKICBpbnQgcmV0Owp9IE1vZGVTZXQ7CgpzdGF0aWMgdm9pZCBXSU5BUEkgVkdBX0RvRXhpdChVTE9OR19QVFIgYXJnKQp7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLE5VTEwpOwogICAgSURpcmVjdERyYXdTdXJmYWNlX1JlbGVhc2UobHBkZHN1cmYpOwogICAgbHBkZHN1cmY9TlVMTDsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKGxwZGRwYWwpOwogICAgbHBkZHBhbD1OVUxMOwogICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgIGxwZGRyYXc9TlVMTDsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFZHQV9Eb1NldE1vZGUoVUxPTkdfUFRSIGFyZykKewogICAgTFJFU1VMVAlyZXM7CiAgICBNb2RlU2V0ICpwYXIgPSAoTW9kZVNldCAqKWFyZzsKICAgIHBhci0+cmV0PTE7CgogICAgaWYgKGxwZGRyYXcpIFZHQV9Eb0V4aXQoMCk7CiAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICBpZiAoIXBEaXJlY3REcmF3Q3JlYXRlKQogICAgICAgIHsKICAgICAgICAgICAgSE1PRFVMRSBobW9kID0gTG9hZExpYnJhcnlBKCAiZGRyYXcuZGxsIiApOwogICAgICAgICAgICBpZiAoaG1vZCkgcERpcmVjdERyYXdDcmVhdGUgPSAoRGlyZWN0RHJhd0NyZWF0ZVByb2MpR2V0UHJvY0FkZHJlc3MoIGhtb2QsICJEaXJlY3REcmF3Q3JlYXRlIiApOwoJICAgIGlmICghcERpcmVjdERyYXdDcmVhdGUpIHsKCQlFUlIoIkNhbid0IGxvb2t1cCBEaXJlY3REcmF3Q3JlYXRlIGZyb20gZGRyYXcuZGxsLlxuIik7CgkJcmV0dXJuOwoJICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzID0gcERpcmVjdERyYXdDcmVhdGUoTlVMTCwmbHBkZHJhdyxOVUxMKTsKICAgICAgICBpZiAoIWxwZGRyYXcpIHsKICAgICAgICAgICAgRVJSKCJEaXJlY3REcmF3IGlzIG5vdCBhdmFpbGFibGUgKHJlcyA9ICVseClcbiIscmVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgIHZnYV9od25kID0gQ3JlYXRlV2luZG93RXhBKDAsIlNUQVRJQyIsIldJTkVET1MgVkdBIixXU19QT1BVUHxXU19WSVNJQkxFLDAsMCxwYXItPlhyZXMscGFyLT5ZcmVzLDAsMCwwLE5VTEwpOwogICAgICAgICAgICBpZiAoIXZnYV9od25kKSB7CiAgICAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgdXNlciB3aW5kb3cuXG4iKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3X1JlbGVhc2UobHBkZHJhdyk7CiAgICAgICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBTZXRXaW5kb3dQb3ModmdhX2h3bmQsMCwwLDAscGFyLT5YcmVzLHBhci0+WXJlcyxTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUik7CgogICAgICAgIGlmICgocmVzPUlEaXJlY3REcmF3X1NldENvb3BlcmF0aXZlTGV2ZWwobHBkZHJhdyx2Z2FfaHduZCxERFNDTF9GVUxMU0NSRUVOfEREU0NMX0VYQ0xVU0lWRSkpKSB7CgkgICAgRVJSKCJDb3VsZCBub3Qgc2V0IGNvb3BlcmF0aXZlIGxldmVsIHRvIGV4Y2x1c2l2ZSAoJWx4KVxuIixyZXMpOwoJfQoKICAgICAgICBpZiAoKHJlcz1JRGlyZWN0RHJhd19TZXREaXNwbGF5TW9kZShscGRkcmF3LHBhci0+WHJlcyxwYXItPllyZXMscGFyLT5EZXB0aCkpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBkb2VzIG5vdCBzdXBwb3J0IHJlcXVlc3RlZCBkaXNwbGF5IG1vZGUgKCVkeCVkeCVkKSwgcmVzID0gJWx4IVxuIixwYXItPlhyZXMscGFyLT5ZcmVzLHBhci0+RGVwdGgscmVzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXM9SURpcmVjdERyYXdfQ3JlYXRlUGFsZXR0ZShscGRkcmF3LEREUENBUFNfOEJJVCxOVUxMLCZscGRkcGFsLE5VTEwpOwogICAgICAgIGlmIChyZXMpIHsKCSAgICBFUlIoIkNvdWxkIG5vdCBjcmVhdGUgcGFsZXR0ZSAocmVzID0gJWx4KVxuIixyZXMpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKChyZXM9SURpcmVjdERyYXdQYWxldHRlX1NldEVudHJpZXMobHBkZHBhbCwwLDAsMjU2LHZnYV9kZWZfcGFsZXR0ZSkpKSB7CiAgICAgICAgICAgIEVSUigiQ291bGQgbm90IHNldCBkZWZhdWx0IHBhbGV0dGUgZW50cmllcyAocmVzID0gJWx4KVxuIiwgcmVzKTsKICAgICAgICB9CgogICAgICAgIG1lbXNldCgmc2Rlc2MsMCxzaXplb2Yoc2Rlc2MpKTsKICAgICAgICBzZGVzYy5kd1NpemU9c2l6ZW9mKHNkZXNjKTsKCXNkZXNjLmR3RmxhZ3MgPSBERFNEX0NBUFM7CglzZGVzYy5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICAgICAgaWYgKElEaXJlY3REcmF3X0NyZWF0ZVN1cmZhY2UobHBkZHJhdywmc2Rlc2MsJmxwZGRzdXJmLE5VTEwpfHwoIWxwZGRzdXJmKSkgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgc3VyZmFjZSBpcyBub3QgYXZhaWxhYmxlXG4iKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwogICAgICAgIHZnYV9yZWZyZXNoPTA7CiAgICAgICAgLyogcG9sbCBldmVyeSAyMG1zICg1MGZwcyBzaG91bGQgcHJvdmlkZSBhZGVxdWF0ZSByZXNwb25zaXZlbmVzcykgKi8KICAgICAgICBWR0FfSW5zdGFsbFRpbWVyKDIwKTsKICAgIH0KICAgIHBhci0+cmV0PTA7CiAgICByZXR1cm47Cn0KCmludCBWR0FfU2V0TW9kZSh1bnNpZ25lZCBYcmVzLHVuc2lnbmVkIFlyZXMsdW5zaWduZWQgRGVwdGgpCnsKICAgIE1vZGVTZXQgcGFyOwogICAgaW50ICAgICBuZXdTaXplOwoKICAgIHZnYV9mYl93aWR0aCA9IFhyZXM7CiAgICB2Z2FfZmJfaGVpZ2h0ID0gWXJlczsKICAgIHZnYV9mYl9kZXB0aCA9IERlcHRoOwogICAgdmdhX2ZiX29mZnNldCA9IDA7CiAgICB2Z2FfZmJfcGl0Y2ggPSBYcmVzICogKChEZXB0aCArIDcpIC8gOCk7CgogICAgbmV3U2l6ZSA9IFhyZXMgKiBZcmVzICogKChEZXB0aCArIDcpIC8gOCk7CiAgICBpZihuZXdTaXplIDwgMjU2ICogMTAyNCkKICAgICAgbmV3U2l6ZSA9IDI1NiAqIDEwMjQ7CgogICAgaWYodmdhX2ZiX3NpemUgPCBuZXdTaXplKSB7CiAgICAgIGlmKHZnYV9mYl9kYXRhKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHZnYV9mYl9kYXRhKTsKICAgICAgdmdhX2ZiX2RhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbmV3U2l6ZSk7CiAgICAgIHZnYV9mYl9zaXplID0gbmV3U2l6ZTsKICAgIH0KCiAgICBpZihYcmVzID49IDY0MCB8fCBZcmVzID49IDQ4MCkgewogICAgICBwYXIuWHJlcyA9IFhyZXM7CiAgICAgIHBhci5ZcmVzID0gWXJlczsKICAgIH0gZWxzZSB7CiAgICAgIHBhci5YcmVzID0gNjQwOwogICAgICBwYXIuWXJlcyA9IDQ4MDsKICAgIH0KCiAgICBWR0FfU2V0V2luZG93U3RhcnQoKERlcHRoIDwgOCkgPyAtMSA6IDApOwoKICAgIHBhci5EZXB0aCA9IChEZXB0aCA8IDgpID8gOCA6IERlcHRoOwoKICAgIHZnYV9tb2RlX2luaXRpYWxpemVkID0gVFJVRTsKCiAgICBNWl9SdW5JblRocmVhZChWR0FfRG9TZXRNb2RlLCAoVUxPTkdfUFRSKSZwYXIpOwogICAgcmV0dXJuIHBhci5yZXQ7Cn0KCmludCBWR0FfR2V0TW9kZSh1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIDE7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gMTsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfRXhpdCh2b2lkKQp7CiAgICBpZiAobHBkZHJhdykgTVpfUnVuSW5UaHJlYWQoVkdBX0RvRXhpdCwgMCk7Cn0KCnZvaWQgVkdBX1NldFBhbGV0dGUoUEFMRVRURUVOVFJZKnBhbCxpbnQgc3RhcnQsaW50IGxlbikKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCi8qIHNldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwp2b2lkIFZHQV9TZXRDb2xvcjE2KGludCByZWcsaW50IGNvbG9yKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKCXBhbD0gJnZnYV9kZWY2NF9wYWxldHRlW2NvbG9yXTsKICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAscmVnLDEscGFsKTsKCXZnYV8xNl9wYWxldHRlW3JlZ109KGNoYXIpY29sb3I7Cn0KCi8qIEdldCBhIHNpbmdsZSBbY2hhciB3aWRlXSBjb2xvciBpbiAxNiBjb2xvciBtb2RlLiAqLwpjaGFyIFZHQV9HZXRDb2xvcjE2KGludCByZWcpCnsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybiAwOwoJcmV0dXJuIChjaGFyKXZnYV8xNl9wYWxldHRlW3JlZ107Cn0KCi8qIHNldCBhbGwgMTcgW2NoYXIgd2lkZV0gY29sb3JzIGF0IG9uY2UgaW4gMTYgY29sb3IgbW9kZS4gKi8Kdm9pZCBWR0FfU2V0MTZQYWxldHRlKGNoYXIgKlRhYmxlKQp7CglQQUxFVFRFRU5UUlkgKnBhbDsKCWludCBjOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOyAgICAgICAgIC8qIHJldHVybiBpZiB3ZSdyZSBpbiB0ZXh0IG9ubHkgbW9kZSAqLwoJYmNvcHkoKHZvaWQgKikmdmdhXzE2X3BhbGV0dGUsKHZvaWQgKilUYWJsZSwxNyk7CgkJICAgICAgICAgICAgICAgICAgICAvKiBjb3B5IHRoZSBlbnRyaWVzIGludG8gdGhlIHRhYmxlICovCiAgICBmb3IgKGM9MDsgYzwxNzsgYysrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAxNyBlbnRyaWVzICovCglwYWw9ICZ2Z2FfZGVmNjRfcGFsZXR0ZVsoaW50KXZnYV8xNl9wYWxldHRlW2NdXTsgIC8qIGdldCBjb2xvciAgKi8KICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsYywxLHBhbCk7IC8qIHNldCBlbnRyeSAgKi8KCVRSQUNFKCJQYWxldHRlIHJlZ2lzdGVyICVkIHNldCB0byAlZFxuIixjLChpbnQpdmdhXzE2X3BhbGV0dGVbY10pOwogICB9IC8qIGVuZCBvZiB0aGUgY291bnRpbmcgbG9vcCAqLwp9CgovKiBHZXQgYWxsIDE3IFsgY2hhciB3aWRlIF0gY29sb3JzIGF0IG9uY2UgaW4gMTYgY29sb3IgbW9kZS4gKi8Kdm9pZCBWR0FfR2V0MTZQYWxldHRlKGNoYXIgKlRhYmxlKQp7CgogICAgaWYgKCFscGRkcmF3KSByZXR1cm47ICAgICAgICAgLyogcmV0dXJuIGlmIHdlJ3JlIGluIHRleHQgb25seSBtb2RlICovCgliY29weSgodm9pZCAqKVRhYmxlLCh2b2lkICopJnZnYV8xNl9wYWxldHRlLDE3KTsKCQkgICAgICAgICAgICAgICAgICAgIC8qIGNvcHkgdGhlIGVudHJpZXMgaW50byB0aGUgdGFibGUgKi8KfQoKdm9pZCBWR0FfU2V0UXVhZFBhbGV0dGUoUkdCUVVBRCpjb2xvcixpbnQgc3RhcnQsaW50IGxlbikKewogICAgUEFMRVRURUVOVFJZIHBhbFsyNTZdOwogICAgaW50IGM7CgogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBmb3IgKGM9MDsgYzxsZW47IGMrKykgewogICAgICAgIHBhbFtjXS5wZVJlZCAgPWNvbG9yW2NdLnJnYlJlZDsKICAgICAgICBwYWxbY10ucGVHcmVlbj1jb2xvcltjXS5yZ2JHcmVlbjsKICAgICAgICBwYWxbY10ucGVCbHVlID1jb2xvcltjXS5yZ2JCbHVlOwogICAgICAgIHBhbFtjXS5wZUZsYWdzPTA7CiAgICB9CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCkxQU1RSIFZHQV9Mb2NrKHVuc2lnbmVkKlBpdGNoLHVuc2lnbmVkKkhlaWdodCx1bnNpZ25lZCpXaWR0aCx1bnNpZ25lZCpEZXB0aCkKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm4gTlVMTDsKICAgIGlmICghbHBkZHN1cmYpIHJldHVybiBOVUxMOwogICAgaWYgKElEaXJlY3REcmF3U3VyZmFjZV9Mb2NrKGxwZGRzdXJmLE5VTEwsJnNkZXNjLDAsMCkpIHsKICAgICAgICBFUlIoImNvdWxkIG5vdCBsb2NrIHN1cmZhY2UhXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGlmIChQaXRjaCkgKlBpdGNoPXNkZXNjLnUxLmxQaXRjaDsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gc2Rlc2MubHBTdXJmYWNlOwp9Cgp2b2lkIFZHQV9VbmxvY2sodm9pZCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlX1VubG9jayhscGRkc3VyZixzZGVzYy5scFN1cmZhY2UpOwp9CgovKgogKiBTZXQgc3RhcnQgb2YgNjRrIHdpbmRvdyBhdCAweGEwMDAwIGluIGJ5dGVzLgogKiBJZiB2YWx1ZSBpcyAtMSwgaW5pdGlhbGl6ZSBjb2xvciBwbGFuZSBzdXBwb3J0LgogKiBJZiB2YWx1ZSBpcyA+PSAwLCB3aW5kb3cgY29udGFpbnMgZGlyZWN0IGNvcHkgb2YgZnJhbWVidWZmZXIuCiAqLwp2b2lkIFZHQV9TZXRXaW5kb3dTdGFydChpbnQgc3RhcnQpCnsKICAgIGlmKHN0YXJ0ID09IHZnYV9mYl93aW5kb3cpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIlJlbW92ZSBWR0EgbWVtb3J5IGVtdWxhdGlvbi5cbiIpOwogICAgZWxzZQogICAgICAgIG1lbW1vdmUodmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCBET1NNRU1fTWFwRG9zVG9MaW5lYXIoMHhhMDAwMCksIDY0ICogMTAyNCk7CgogICAgdmdhX2ZiX3dpbmRvdyA9IHN0YXJ0OwoKICAgIGlmKHZnYV9mYl93aW5kb3cgPT0gLTEpCiAgICAgICAgRklYTUUoIkluc3RhbGwgVkdBIG1lbW9yeSBlbXVsYXRpb24uXG4iKTsKICAgIGVsc2UKICAgICAgICBtZW1tb3ZlKERPU01FTV9NYXBEb3NUb0xpbmVhcigweGEwMDAwKSwgdmdhX2ZiX2RhdGEgKyB2Z2FfZmJfd2luZG93LCA2NCAqIDEwMjQpOwp9CgovKgogKiBHZXQgc3RhcnQgb2YgNjRrIHdpbmRvdyBhdCAweGEwMDAwIGluIGJ5dGVzLgogKiBWYWx1ZSBpcyAtMSBpbiBjb2xvciBwbGFuZSBtb2Rlcy4KICovCmludCBWR0FfR2V0V2luZG93U3RhcnQoKQp7CiAgICByZXR1cm4gdmdhX2ZiX3dpbmRvdzsKfQoKLyoqKiBURVhUIE1PREUgKioqLwoKLyogcHJlcGFyZSB0aGUgdGV4dCBtb2RlIHZpZGVvIG1lbW9yeSBjb3B5IHRoYXQgaXMgdXNlZCB0byBvbmx5CiAqIHVwZGF0ZSB0aGUgdmlkZW8gbWVtb3J5IGxpbmUgdGhhdCBkaWQgZ2V0IHVwZGF0ZWQuICovCnZvaWQgVkdBX1ByZXBhcmVWaWRlb01lbUNvcHkodW5zaWduZWQgWHJlcywgdW5zaWduZWQgWXJlcykKewogICAgY2hhciAqcCwgKnAyOwogICAgaW50IGk7CgogICAgdGV4dGJ1Zl9vbGQgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCB0ZXh0YnVmX29sZCwgWHJlcyAqIFlyZXMgKiAyKTsgLyogY2hhciArIGF0dHIgKi8KCiAgICBwID0gVkdBX0FscGhhQnVmZmVyKCk7CiAgICBwMiA9IHRleHRidWZfb2xkOwoKICAgIC8qIG1ha2Ugc3VyZSB0aGUgdmlkZW8gbWVtIGNvcHkgY29udGFpbnMgdGhlIGV4YWN0IG9wcG9zaXRlIG9mIG91cgogICAgICogYWN0dWFsIHRleHQgbW9kZSBtZW1vcnkgYXJlYSB0byBtYWtlIHN1cmUgdGhlIHNjcmVlbgogICAgICogZG9lcyBnZXQgdXBkYXRlZCBmdWxseSBpbml0aWFsbHkgKi8KICAgIGZvciAoaT0wOyBpIDwgWHJlcypZcmVzKjI7IGkrKykKCSpwMisrIF49ICpwKys7IC8qIFhPUiBpdCAqLwp9CgppbnQgVkdBX1NldEFscGhhTW9kZSh1bnNpZ25lZCBYcmVzLHVuc2lnbmVkIFlyZXMpCnsKICAgIENPT1JEIHNpejsKCiAgICBpZiAobHBkZHJhdykgVkdBX0V4aXQoKTsKCiAgICAvKiBGSVhNRTogV2hlcmUgdG8gaW5pdGlhbGl6ZSB0ZXh0IGF0dHJpYnV0ZXM/ICovCiAgICBWR0FfU2V0VGV4dEF0dHJpYnV0ZSgweGYpOwoKICAgIFZHQV9QcmVwYXJlVmlkZW9NZW1Db3B5KFhyZXMsIFlyZXMpOwoKICAgIC8qIHBvbGwgZXZlcnkgMzBtcyAoMzNmcHMgc2hvdWxkIHByb3ZpZGUgYWRlcXVhdGUgcmVzcG9uc2l2ZW5lc3MpICovCiAgICBWR0FfSW5zdGFsbFRpbWVyKDMwKTsKCiAgICBzaXouWCA9IFhyZXM7CiAgICBzaXouWSA9IFlyZXM7CiAgICBTZXRDb25zb2xlU2NyZWVuQnVmZmVyU2l6ZShWR0FfQWxwaGFDb25zb2xlKCksc2l6KTsKICAgIHJldHVybiAwOwp9CgpCT09MIFZHQV9HZXRBbHBoYU1vZGUodW5zaWduZWQqWHJlcyx1bnNpZ25lZCpZcmVzKQp7CiAgICBDT05TT0xFX1NDUkVFTl9CVUZGRVJfSU5GTyBpbmZvOwogICAgaWYoIUdldENvbnNvbGVTY3JlZW5CdWZmZXJJbmZvKFZHQV9BbHBoYUNvbnNvbGUoKSwmaW5mbykpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoWHJlcykgKlhyZXM9aW5mby5kd1NpemUuWDsKICAgICAgICBpZiAoWXJlcykgKllyZXM9aW5mby5kd1NpemUuWTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KfQoKdm9pZCBWR0FfU2V0Q3Vyc29yU2hhcGUodW5zaWduZWQgY2hhciBzdGFydF9vcHRpb25zLCB1bnNpZ25lZCBjaGFyIGVuZCkKewogICAgQ09OU09MRV9DVVJTT1JfSU5GTyBjY2k7CgogICAgLyogc3RhbmRhcmQgY3Vyc29yIHNldHRpbmdzOgogICAgICogMHgwNjA3ID09IENHQSwgMHgwYjBjID09IG1vbm9jaHJvbWUsIDB4MGQwZSA9PSBFR0EvVkdBICovCgogICAgLyogY2FsY3VsYXRlIHBlcmNlbnRhZ2UgZnJvbSBib3R0b20gLSBhc3N1bWluZyBWR0EgKGJvdHRvbSAweDBlKSAqLwogICAgY2NpLmR3U2l6ZSA9ICgoZW5kICYgMHgxZikgLSAoc3RhcnRfb3B0aW9ucyAmIDB4MWYpKS8weDBlICogMTAwOwogICAgaWYgKCFjY2kuZHdTaXplKSBjY2kuZHdTaXplKys7IC8qIE5VTEwgY3Vyc29yIHdvdWxkIG1ha2UgU0NDSSgpIGZhaWwgISAqLwogICAgY2NpLmJWaXNpYmxlID0gKChzdGFydF9vcHRpb25zICYgMHg2MCkgIT0gMHgyMCk7IC8qIGludmlzaWJsZSA/ICovCgogICAgU2V0Q29uc29sZUN1cnNvckluZm8oVkdBX0FscGhhQ29uc29sZSgpLCZjY2kpOwp9Cgp2b2lkIFZHQV9TZXRDdXJzb3JQb3ModW5zaWduZWQgWCx1bnNpZ25lZCBZKQp7CiAgICBDT09SRCBwb3M7CgogICAgaWYgKCFwb2xsX3RpbWVyKSBWR0FfU2V0QWxwaGFNb2RlKDgwLCAyNSk7CiAgICBwb3MuWCA9IFg7CiAgICBwb3MuWSA9IFk7CiAgICBTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oVkdBX0FscGhhQ29uc29sZSgpLHBvcyk7Cn0KCnZvaWQgVkdBX0dldEN1cnNvclBvcyh1bnNpZ25lZCpYLHVuc2lnbmVkKlkpCnsKICAgIENPTlNPTEVfU0NSRUVOX0JVRkZFUl9JTkZPIGluZm87CiAgICBHZXRDb25zb2xlU2NyZWVuQnVmZmVySW5mbyhWR0FfQWxwaGFDb25zb2xlKCksJmluZm8pOwogICAgaWYgKFgpICpYPWluZm8uZHdDdXJzb3JQb3NpdGlvbi5YOwogICAgaWYgKFkpICpZPWluZm8uZHdDdXJzb3JQb3NpdGlvbi5ZOwp9Cgp2b2lkIFZHQV9Xcml0ZUNoYXJzKHVuc2lnbmVkIFgsdW5zaWduZWQgWSx1bnNpZ25lZCBjaCxpbnQgYXR0cixpbnQgY291bnQpCnsKICAgIENIQVJfSU5GTyBpbmZvOwogICAgQ09PUkQgc2l6LCBvZmY7CiAgICBTTUFMTF9SRUNUIGRlc3Q7CiAgICB1bnNpZ25lZCBYUiwgWVI7CiAgICBjaGFyICpkYXQ7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICBpbmZvLkNoYXIuQXNjaWlDaGFyID0gY2g7CiAgICBpbmZvLkF0dHJpYnV0ZXMgPSAoV09SRClhdHRyOwogICAgc2l6LlggPSAxOwogICAgc2l6LlkgPSAxOwogICAgb2ZmLlggPSAwOwogICAgb2ZmLlkgPSAwOwogICAgZGVzdC5Ub3A9WTsKICAgIGRlc3QuQm90dG9tPVk7CgogICAgVkdBX0dldEFscGhhTW9kZSgmWFIsICZZUik7CiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKSArICgoWFIqWSArIFgpICogMik7CiAgICB3aGlsZSAoY291bnQtLSkgewogICAgICAgIGRlc3QuTGVmdCA9IFggKyBjb3VudDsKICAgICAgIGRlc3QuUmlnaHQgPSBYICsgY291bnQ7CgogICAgICAgICpkYXQrKyA9IGNoOwogICAgICAgIGlmIChhdHRyPj0wKQogICAgICAgICAqZGF0ID0gYXR0cjsKICAgICAgIGVsc2UKICAgICAgICAgaW5mby5BdHRyaWJ1dGVzID0gKmRhdDsKICAgICAgICBkYXQrKzsKCiAgICAgICBXcml0ZUNvbnNvbGVPdXRwdXRBKFZHQV9BbHBoYUNvbnNvbGUoKSwgJmluZm8sIHNpeiwgb2ZmLCAmZGVzdCk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKc3RhdGljIHZvaWQgVkdBX1B1dENoYXJBdChCWVRFIGFzY2lpLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5KQp7CiAgICB1bnNpZ25lZCB3aWR0aCwgaGVpZ2h0OwogICAgY2hhciAqZGF0OwoKICAgIFZHQV9HZXRBbHBoYU1vZGUoJndpZHRoLCAmaGVpZ2h0KTsKICAgIGRhdCA9IFZHQV9BbHBoYUJ1ZmZlcigpICsgKCh3aWR0aCp5ICsgeCkgKiAyKTsKICAgIGRhdFswXSA9IGFzY2lpOwogICAgZGF0WzFdID0gdmdhX3RleHRfYXR0cjsKfQoKdm9pZCBWR0FfUHV0Q2hhcihCWVRFIGFzY2lpKQp7CiAgICB1bnNpZ25lZCB3aWR0aCwgaGVpZ2h0LCB4LCB5LCBueCwgbnk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICBWR0FfR2V0QWxwaGFNb2RlKCZ3aWR0aCwgJmhlaWdodCk7CiAgICBWR0FfR2V0Q3Vyc29yUG9zKCZ4LCAmeSk7CgogICAgc3dpdGNoKGFzY2lpKSB7CiAgICBjYXNlICdcYic6CiAgICAgICAgVkdBX1B1dENoYXJBdCgnICcsIHgsIHkpOwogICAgICAgeC0tOwogICAgICAgYnJlYWs7CgogICAgY2FzZSAnXHQnOgogICAgICAgeCArPSAoKHggKyA4KSAmIH43KSAtIHg7CiAgICAgICBicmVhazsKCiAgICBjYXNlICdcbic6CiAgICAgICAgeSsrOwogICAgICAgeCA9IDA7CiAgICAgICBicmVhazsKCiAgICBjYXNlICdcYSc6CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXHInOgogICAgICAgIHggPSAwOwogICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBWR0FfUHV0Q2hhckF0KGFzY2lpLCB4LCB5KTsKICAgICAgIHgrKzsKICAgIH0KCiAgICAvKgogICAgICogRklYTUU6IGFkZCBsaW5lIHdyYXBwaW5nIGFuZCBzY3JvbGxpbmcKICAgICAqLwoKICAgIFdyaXRlRmlsZShWR0FfQWxwaGFDb25zb2xlKCksICZhc2NpaSwgMSwgTlVMTCwgTlVMTCk7CgogICAgLyoKICAgICAqIFRoZSBmb2xsb3dpbmcgaXMganVzdCBhIHNhbml0eSBjaGVjay4KICAgICAqLwogICAgVkdBX0dldEN1cnNvclBvcygmbngsICZueSk7CiAgICBpZihueCAhPSB4IHx8IG55ICE9IHkpCiAgICAgIFdBUk4oIlZHQSBlbXVsYXRvciBhbmQgdGV4dCBjb25zb2xlIGhhdmUgYmVjb21lIHVuc3luY2hyb25pemVkLlxuIik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKdm9pZCBWR0FfU2V0VGV4dEF0dHJpYnV0ZShCWVRFIGF0dHIpCnsKICAgIHZnYV90ZXh0X2F0dHIgPSBhdHRyOwogICAgU2V0Q29uc29sZVRleHRBdHRyaWJ1dGUoVkdBX0FscGhhQ29uc29sZSgpLCBhdHRyKTsKfQoKQk9PTCBWR0FfQ2xlYXJUZXh0KHVuc2lnbmVkIHJvdzEsIHVuc2lnbmVkIGNvbDEsCiAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHJvdzIsIHVuc2lnbmVkIGNvbDIsCiAgICAgICAgICAgICAgICAgIEJZVEUgYXR0cikKewogICAgdW5zaWduZWQgd2lkdGgsIGhlaWdodCwgeCwgeTsKICAgIENPT1JEIG9mZjsKICAgIGNoYXIgKmRhdCA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgSEFORExFIGNvbiA9IFZHQV9BbHBoYUNvbnNvbGUoKTsKCiAgICAvKiByZXR1cm4gaWYgd2UgZmFpbCB0byBnZXQgdGhlIGhlaWdodCBhbmQgd2lkdGggb2YgdGhlIHdpbmRvdyAqLwogICAgaWYoIVZHQV9HZXRBbHBoYU1vZGUoJndpZHRoLCAmaGVpZ2h0KSkKICAgIHsKICAgICAgICBFUlIoImZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJkYXQgPSAlcCwgd2lkdGggPSAlZCwgaGVpZ2h0ID0gJWRcbiIsIGRhdCwgd2lkdGgsIGhlaWdodCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICBmb3IoeT1yb3cxOyB5PD1yb3cyOyB5KyspIHsKICAgICAgICBvZmYuWCA9IGNvbDE7CiAgICAgICBvZmYuWSA9IHk7CiAgICAgICBGaWxsQ29uc29sZU91dHB1dENoYXJhY3RlckEoY29uLCAnICcsIGNvbDItY29sMSsxLCBvZmYsIE5VTEwpOwogICAgICAgRmlsbENvbnNvbGVPdXRwdXRBdHRyaWJ1dGUoY29uLCBhdHRyLCBjb2wyLWNvbDErMSwgb2ZmLCBOVUxMKTsKCiAgICAgICBmb3IoeD1jb2wxOyB4PD1jb2wyOyB4KyspIHsKICAgICAgICAgICBjaGFyICpwdHIgPSBkYXQgKyAoKHdpZHRoKnkgKyB4KSAqIDIpOwogICAgICAgICAgIHB0clswXSA9ICcgJzsKICAgICAgICAgICBwdHJbMV0gPSBhdHRyOwogICAgICAgfQogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfbG9jayk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnZvaWQgVkdBX1Njcm9sbFVwVGV4dCh1bnNpZ25lZCByb3cxLCB1bnNpZ25lZCBjb2wxLAogICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCB1bnNpZ25lZCBjb2wyLAogICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsaW5lcywgQllURSBhdHRyKQp7CiAgICBGSVhNRSgibm90IGltcGxlbWVudGVkXG4iKTsKfQoKdm9pZCBWR0FfU2Nyb2xsRG93blRleHQodW5zaWduZWQgcm93MSwgdW5zaWduZWQgY29sMSwKICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCB1bnNpZ25lZCBjb2wyLAogICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxpbmVzLCBCWVRFIGF0dHIpCnsKICAgIEZJWE1FKCJub3QgaW1wbGVtZW50ZWRcbiIpOwp9Cgp2b2lkIFZHQV9HZXRDaGFyYWN0ZXJBdEN1cnNvcihCWVRFICphc2NpaSwgQllURSAqYXR0cikKewogICAgdW5zaWduZWQgd2lkdGgsIGhlaWdodCwgeCwgeTsKICAgIGNoYXIgKmRhdDsKCiAgICBWR0FfR2V0QWxwaGFNb2RlKCZ3aWR0aCwgJmhlaWdodCk7CiAgICBWR0FfR2V0Q3Vyc29yUG9zKCZ4LCAmeSk7CiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKSArICgod2lkdGgqeSArIHgpICogMik7CgogICAgKmFzY2lpID0gZGF0WzBdOwogICAgKmF0dHIgPSBkYXRbMV07Cn0KCgovKioqIENPTlRST0wgKioqLwoKLyogRklYTUU6IG9wdGltaXplIGJ5IGRvaW5nIHRoaXMgb25seSBpZiB0aGUgZGF0YSBoYXMgYWN0dWFsbHkgY2hhbmdlZAogKiAgICAgICAgKGluIGEgd2F5IHNpbWlsYXIgdG8gRElCU2VjdGlvbiwgcGVyaGFwcykgKi8Kc3RhdGljIHZvaWQgVkdBX1BvbGxfR3JhcGhpY3Modm9pZCkKewogIHVuc2lnbmVkIGludCBQaXRjaCwgSGVpZ2h0LCBXaWR0aCwgWCwgWTsKICBjaGFyICpzdXJmOwogIGNoYXIgKmRhdCA9IHZnYV9mYl9kYXRhICsgdmdhX2ZiX29mZnNldDsKICBpbnQgICBicHAgPSAodmdhX2ZiX2RlcHRoICsgNykgLyA4OwoKICBzdXJmID0gVkdBX0xvY2soJlBpdGNoLCZIZWlnaHQsJldpZHRoLE5VTEwpOwogIGlmICghc3VyZikgcmV0dXJuOwoKICAvKgogICAqIFN5bmNocm9uaXplIGZyYW1lYnVmZmVyIGNvbnRlbnRzLgogICAqLwogIGlmKHZnYV9mYl93aW5kb3cgIT0gLTEpCiAgICBtZW1tb3ZlKHZnYV9mYl9kYXRhICsgdmdhX2ZiX3dpbmRvdywgRE9TTUVNX01hcERvc1RvTGluZWFyKDB4YTAwMDApLCA2NCAqIDEwMjQpOwoKICAvKgogICAqIERvdWJsZSBWR0EgZnJhbWVidWZmZXIgKDMyMHgyMDAgLT4gNjQweDQwMCksIGlmIG5lZWRlZC4KICAgKi8KICBpZihIZWlnaHQgPj0gMiAqIHZnYV9mYl9oZWlnaHQgJiYgV2lkdGggPj0gMiAqIHZnYV9mYl93aWR0aCAmJiBicHAgPT0gMSkKICAgIGZvciAoWT0wOyBZPHZnYV9mYl9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCoyLGRhdCs9dmdhX2ZiX3BpdGNoKQogICAgICBmb3IgKFg9MDsgWDx2Z2FfZmJfd2lkdGg7IFgrKykgewogICAgICAgQllURSB2YWx1ZSA9IGRhdFtYXTsKICAgICAgIHN1cmZbWCoyXSA9IHZhbHVlOwogICAgICAgc3VyZltYKjIrMV0gPSB2YWx1ZTsKICAgICAgIHN1cmZbWCoyK1BpdGNoXSA9IHZhbHVlOwogICAgICAgc3VyZltYKjIrUGl0Y2grMV0gPSB2YWx1ZTsKICAgICAgfQogIGVsc2UKICAgIGZvciAoWT0wOyBZPHZnYV9mYl9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCxkYXQrPXZnYV9mYl9waXRjaCkKICAgICAgbWVtY3B5KHN1cmYsIGRhdCwgdmdhX2ZiX3dpZHRoICogYnBwKTsKCiAgVkdBX1VubG9jaygpOwp9CgpzdGF0aWMgdm9pZCBWR0FfUG9sbF9UZXh0KHZvaWQpCnsKICAgIGNoYXIgKmRhdCwgKm9sZCwgKnBfbGluZTsKICAgIHVuc2lnbmVkIGludCBIZWlnaHQsV2lkdGgsWSxYOwogICAgQ0hBUl9JTkZPIGNoWzI1Nl07IC8qIHRoYXQgc2hvdWxkIHN1ZmZpY2UgZm9yIHRoZSBsYXJnZXN0IHRleHQgd2lkdGggKi8KICAgIENPT1JEIHNpeiwgb2ZmOwogICAgU01BTExfUkVDVCBkZXN0OwogICAgSEFORExFIGNvbiA9IFZHQV9BbHBoYUNvbnNvbGUoKTsKICAgIEJPT0wgbGluZWNoYW5nZWQgPSBGQUxTRTsgLyogdmlkZW8gbWVtb3J5IGFyZWEgZGlmZmVycyBmcm9tIHN0b3JlZCBjb3B5ID8gKi8KCiAgICBWR0FfR2V0QWxwaGFNb2RlKCZXaWR0aCwmSGVpZ2h0KTsKICAgIGRhdCA9IFZHQV9BbHBoYUJ1ZmZlcigpOwogICAgb2xkID0gdGV4dGJ1Zl9vbGQ7IC8qIHBvaW50ZXIgdG8gc3RvcmVkIHZpZGVvIG1lbSBjb3B5ICovCiAgICBzaXouWCA9IFdpZHRoOyBzaXouWSA9IDE7CiAgICBvZmYuWCA9IDA7IG9mZi5ZID0gMDsKICAgIC8qIGNvcHkgZnJvbSB2aXJ0dWFsIFZHQSBmcmFtZSBidWZmZXIgdG8gY29uc29sZSAqLwogICAgZm9yIChZPTA7IFk8SGVpZ2h0OyBZKyspIHsKCWxpbmVjaGFuZ2VkID0gbWVtY21wKGRhdCwgb2xkLCBXaWR0aCoyKTsKCWlmIChsaW5lY2hhbmdlZCkKCXsKCSAgICAvKlRSQUNFKCJsaW5lICVkIGNoYW5nZWRcbiIsIFkpOyovCgkgICAgcF9saW5lID0gZGF0OwogICAgICAgICAgICBmb3IgKFg9MDsgWDxXaWR0aDsgWCsrKSB7CiAgICAgICAgICAgICAgICBjaFtYXS5DaGFyLkFzY2lpQ2hhciA9ICpwX2xpbmUrKzsKICAgICAgICAgICAgICAgIC8qIFdyaXRlQ29uc29sZU91dHB1dEEgZG9lc24ndCBsaWtlICJkZWFkIiBjaGFycyAqLwogICAgICAgICAgICAgICAgaWYgKGNoW1hdLkNoYXIuQXNjaWlDaGFyID09ICdcMCcpCiAgICAgICAgICAgICAgICAgICAgY2hbWF0uQ2hhci5Bc2NpaUNoYXIgPSAnICc7CiAgICAgICAgICAgICAgICBjaFtYXS5BdHRyaWJ1dGVzID0gKnBfbGluZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc3QuVG9wPVk7IGRlc3QuQm90dG9tPVk7CiAgICAgICAgICAgIGRlc3QuTGVmdD0wOyBkZXN0LlJpZ2h0PVdpZHRoKzE7CiAgICAgICAgICAgIFdyaXRlQ29uc29sZU91dHB1dEEoY29uLCBjaCwgc2l6LCBvZmYsICZkZXN0KTsKCSAgICBtZW1jcHkob2xkLCBkYXQsIFdpZHRoKjIpOwoJfQoJLyogYWR2YW5jZSB0byBuZXh0IHRleHQgbGluZSAqLwoJZGF0ICs9IFdpZHRoKjI7CglvbGQgKz0gV2lkdGgqMjsKICAgIH0KfQoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgVkdBX1BvbGwoIExQVk9JRCBhcmcsIERXT1JEIGxvdywgRFdPUkQgaGlnaCApCnsKICAgIGlmKCFUcnlFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spKQogICAgICAgIHJldHVybjsKCiAgICBpZiAobHBkZHJhdykgewogICAgICAgIFZHQV9Qb2xsX0dyYXBoaWNzKCk7CiAgICB9IGVsc2UgewogICAgICAgIFZHQV9Qb2xsX1RleHQoKTsKICAgIH0KCiAgICB2Z2FfcmVmcmVzaD0xOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKc3RhdGljIEJZVEUgcGFscmVnLHBhbGNudDsKc3RhdGljIFBBTEVUVEVFTlRSWSBwYWxkYXQ7Cgp2b2lkIFZHQV9pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsICkKewogICAgc3dpdGNoIChwb3J0KSB7CiAgICAgICAgY2FzZSAweDNjMDoKICAgICAgICAgICBpZiAodmdhX2FkZHJlc3NfM2MwKQogICAgICAgICAgICAgICB2Z2FfaW5kZXhfM2MwID0gdmFsOwogICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjMDogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgICAgICB2Z2FfaW5kZXhfM2MwLCB2YWwpOwogICAgICAgICAgIHZnYV9hZGRyZXNzXzNjMCA9ICF2Z2FfYWRkcmVzc18zYzA7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjNDoKICAgICAgICAgICB2Z2FfaW5kZXhfM2M0ID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzYzU6CiAgICAgICAgICBzd2l0Y2godmdhX2luZGV4XzNjNCkgewogICAgICAgICAgICAgICBjYXNlIDB4MDQ6IC8qIFNlcXVlbmNlcjogTWVtb3J5IE1vZGUgUmVnaXN0ZXIgKi8KICAgICAgICAgICAgICAgICAgaWYodmdhX2ZiX2RlcHRoID09IDgpCiAgICAgICAgICAgICAgICAgICAgICBWR0FfU2V0V2luZG93U3RhcnQoKHZhbCAmIDgpID8gMCA6IC0xKTsKICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgRklYTUUoIk1lbW9yeSBNb2RlIFJlZ2lzdGVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBtb2RlLlxuIik7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2M0OiAweCUwMnggKHZhbHVlIDB4JTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzQsIHZhbCk7CiAgICAgICAgICAgfQogICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgaW5kZXgsIHJlZ2lzdGVyIDB4M2M0OiAweCUwMnggKHZhbHVlIDB4JTAyeClcbiIsCiAgICAgICAgICAgICAgICAgdmdhX2luZGV4XzNjNCwgdmFsKTsKICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2M4OgogICAgICAgICAgICBwYWxyZWc9dmFsOyBwYWxjbnQ9MDsgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjOToKICAgICAgICAgICAgKChCWVRFKikmcGFsZGF0KVtwYWxjbnQrK109dmFsIDw8IDI7CiAgICAgICAgICAgIGlmIChwYWxjbnQ9PTMpIHsKICAgICAgICAgICAgICAgIFZHQV9TZXRQYWxldHRlKCZwYWxkYXQscGFscmVnKyssMSk7CiAgICAgICAgICAgICAgICBwYWxjbnQ9MDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDB4M2NlOgogICAgICAgICAgICB2Z2FfaW5kZXhfM2NlID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzY2Y6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjZTogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zY2UsIHZhbCk7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAweDNkNDoKICAgICAgICAgICB2Z2FfaW5kZXhfM2Q0ID0gdmFsOwogICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMHgzZDU6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNkNDogMHglMDJ4ICh2YWx1ZSAweCUwMngpXG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zZDQsIHZhbCk7CiAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFZHQSByZWdpc3RlcjogMHglMDR4ICh2YWx1ZSAweCUwMngpXG4iLCBwb3J0LCB2YWwpOwogICAgfQp9CgpCWVRFIFZHQV9pb3BvcnRfaW4oIFdPUkQgcG9ydCApCnsKICAgIEJZVEUgcmV0OwoKICAgIHN3aXRjaCAocG9ydCkgewogICAgICAgIGNhc2UgMHgzYzE6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjMDogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzApOwogICAgICAgICAgIHJldHVybiAweGZmOwogICAgICAgIGNhc2UgMHgzYzU6CiAgICAgICAgICAgc3dpdGNoKHZnYV9pbmRleF8zYzQpIHsKICAgICAgICAgICAgICAgY2FzZSAweDA0OiAvKiBTZXF1ZW5jZXI6IE1lbW9yeSBNb2RlIFJlZ2lzdGVyICovCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChWR0FfR2V0V2luZG93U3RhcnQoKSA9PSAtMSkgPyAweGY3IDogMHhmZjsKICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBpbmRleCwgcmVnaXN0ZXIgMHgzYzQ6IDB4JTAyeFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zYzQpOwogICAgICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmY7CiAgICAgICAgICAgfQogICAgICAgIGNhc2UgMHgzY2Y6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNjZTogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zY2UpOwogICAgICAgICAgIHJldHVybiAweGZmOwogICAgICAgIGNhc2UgMHgzZDU6CiAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGluZGV4LCByZWdpc3RlciAweDNkNDogMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgIHZnYV9pbmRleF8zZDQpOwogICAgICAgICAgIHJldHVybiAweGZmOwogICAgICAgIGNhc2UgMHgzZGE6CiAgICAgICAgICAgLyoKICAgICAgICAgICAgKiBSZWFkIGZyb20gdGhpcyByZWdpc3RlciByZXNldHMgcmVnaXN0ZXIgMHgzYzAgYWRkcmVzcyBmbGlwLWZsb3AuCiAgICAgICAgICAgICovCiAgICAgICAgICAgdmdhX2FkZHJlc3NfM2MwID0gVFJVRTsKICAgICAgICAgICAgLyogc2luY2Ugd2UgZG9uJ3QgKHlldD8pIHNlcnZlIERPUyBWTSByZXF1ZXN0cyB3aGlsZSBWR0FfUG9sbCBpcyBydW5uaW5nLAogICAgICAgICAgICAgICB3ZSBuZWVkIHRvIGZha2UgdGhlIG9jY3VycmVuY2Ugb2YgdGhlIHZlcnRpY2FsIHJlZnJlc2ggKi8KICAgICAgICAgICAgcmV0PXZnYV9yZWZyZXNoPzB4MDA6MHgwYjsgLyogdG9nZ2xlIHZpZGVvIFJBTSBhbmQgbGlnaHRwZW4gYW5kIFZHQSByZWZyZXNoIGJpdHMgISAqLwogICAgICAgICAgICBpZiAodmdhX21vZGVfaW5pdGlhbGl6ZWQpCiAgICAgICAgICAgICAgICB2Z2FfcmVmcmVzaD0wOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAvKiBBbHNvIGZha2UgdGhlIG9jY3VyZW5jZSBvZiB0aGUgdmVydGljYWwgcmVmcmVzaCB3aGVuIG5vIGdyYXBoaWMKICAgICAgICAgICAgICAgICAgIG1vZGUgaGFzIGJlZW4gc2V0ICovCiAgICAgICAgICAgICAgICB2Z2FfcmVmcmVzaD0hdmdhX3JlZnJlc2g7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldD0weGZmOwogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgVkdBIHJlZ2lzdGVyOiAweCUwNHhcbiIsIHBvcnQpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKdm9pZCBWR0FfQ2xlYW4odm9pZCkKewogICAgVkdBX0V4aXQoKTsKICAgIFZHQV9EZWluc3RhbGxUaW1lcigpOwp9Cg==