LyogSW1wbGVtZW50YXRpb24gb2YgdGhlIFRSQU5TUE9TRSBpbnRyaW5zaWMKICAgQ29weXJpZ2h0IDIwMDMsIDIwMDUsIDIwMDYsIDIwMDcsIDIwMDkgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCiAgIENvbnRyaWJ1dGVkIGJ5IFRvYmlhcyBTY2hs/HRlcgoKVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEdOVSBGb3J0cmFuIDk1IHJ1bnRpbWUgbGlicmFyeSAobGliZ2ZvcnRyYW4pLgoKTGliZ2ZvcnRyYW4gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCm1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwpMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKTGliZ2ZvcnRyYW4gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKVW5kZXIgU2VjdGlvbiA3IG9mIEdQTCB2ZXJzaW9uIDMsIHlvdSBhcmUgZ3JhbnRlZCBhZGRpdGlvbmFsCnBlcm1pc3Npb25zIGRlc2NyaWJlZCBpbiB0aGUgR0NDIFJ1bnRpbWUgTGlicmFyeSBFeGNlcHRpb24sIHZlcnNpb24KMy4xLCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFuZAphIGNvcHkgb2YgdGhlIEdDQyBSdW50aW1lIExpYnJhcnkgRXhjZXB0aW9uIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOwpzZWUgdGhlIGZpbGVzIENPUFlJTkczIGFuZCBDT1BZSU5HLlJVTlRJTUUgcmVzcGVjdGl2ZWx5LiAgSWYgbm90LCBzZWUKPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LiAgKi8KCiNpbmNsdWRlICJsaWJnZm9ydHJhbi5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgoKI2lmIGRlZmluZWQgKEhBVkVfR0ZDX0NPTVBMRVhfOCkKCmV4dGVybiB2b2lkIHRyYW5zcG9zZV9jOCAoZ2ZjX2FycmF5X2M4ICogY29uc3QgcmVzdHJpY3QgcmV0LCAKCWdmY19hcnJheV9jOCAqIGNvbnN0IHJlc3RyaWN0IHNvdXJjZSk7CmV4cG9ydF9wcm90byh0cmFuc3Bvc2VfYzgpOwoKdm9pZAp0cmFuc3Bvc2VfYzggKGdmY19hcnJheV9jOCAqIGNvbnN0IHJlc3RyaWN0IHJldCwgCglnZmNfYXJyYXlfYzggKiBjb25zdCByZXN0cmljdCBzb3VyY2UpCnsKICAvKiByLiogaW5kaWNhdGVzIHRoZSByZXR1cm4gYXJyYXkuICAqLwogIGluZGV4X3R5cGUgcnhzdHJpZGUsIHJ5c3RyaWRlOwogIEdGQ19DT01QTEVYXzggKiByZXN0cmljdCBycHRyOwogIC8qIHMuKiBpbmRpY2F0ZXMgdGhlIHNvdXJjZSBhcnJheS4gICovCiAgaW5kZXhfdHlwZSBzeHN0cmlkZSwgc3lzdHJpZGU7CiAgY29uc3QgR0ZDX0NPTVBMRVhfOCAqc3B0cjsKCiAgaW5kZXhfdHlwZSB4Y291bnQsIHljb3VudDsKICBpbmRleF90eXBlIHgsIHk7CgogIGFzc2VydCAoR0ZDX0RFU0NSSVBUT1JfUkFOSyAoc291cmNlKSA9PSAyKTsKCiAgaWYgKHJldC0+ZGF0YSA9PSBOVUxMKQogICAgewogICAgICBhc3NlcnQgKEdGQ19ERVNDUklQVE9SX1JBTksgKHJldCkgPT0gMik7CiAgICAgIGFzc2VydCAocmV0LT5kdHlwZSA9PSBzb3VyY2UtPmR0eXBlKTsKCiAgICAgIHJldC0+ZGltWzBdLmxib3VuZCA9IDA7CiAgICAgIHJldC0+ZGltWzBdLnVib3VuZCA9IHNvdXJjZS0+ZGltWzFdLnVib3VuZCAtIHNvdXJjZS0+ZGltWzFdLmxib3VuZDsKICAgICAgcmV0LT5kaW1bMF0uc3RyaWRlID0gMTsKCiAgICAgIHJldC0+ZGltWzFdLmxib3VuZCA9IDA7CiAgICAgIHJldC0+ZGltWzFdLnVib3VuZCA9IHNvdXJjZS0+ZGltWzBdLnVib3VuZCAtIHNvdXJjZS0+ZGltWzBdLmxib3VuZDsKICAgICAgcmV0LT5kaW1bMV0uc3RyaWRlID0gcmV0LT5kaW1bMF0udWJvdW5kKzE7CgogICAgICByZXQtPmRhdGEgPSBpbnRlcm5hbF9tYWxsb2Nfc2l6ZSAoc2l6ZW9mIChHRkNfQ09NUExFWF84KSAqIHNpemUwICgoYXJyYXlfdCAqKSByZXQpKTsKICAgICAgcmV0LT5vZmZzZXQgPSAwOwogICAgfSBlbHNlIGlmICh1bmxpa2VseSAoY29tcGlsZV9vcHRpb25zLmJvdW5kc19jaGVjaykpCiAgICB7CiAgICAgIGluZGV4X3R5cGUgcmV0X2V4dGVudCwgc3JjX2V4dGVudDsKCiAgICAgIHJldF9leHRlbnQgPSByZXQtPmRpbVswXS51Ym91bmQgKyAxIC0gcmV0LT5kaW1bMF0ubGJvdW5kOwogICAgICBzcmNfZXh0ZW50ID0gc291cmNlLT5kaW1bMV0udWJvdW5kICsgMSAtIHNvdXJjZS0+ZGltWzFdLmxib3VuZDsKCiAgICAgIGlmIChzcmNfZXh0ZW50ICE9IHJldF9leHRlbnQpCglydW50aW1lX2Vycm9yICgiSW5jb3JyZWN0IGV4dGVudCBpbiByZXR1cm4gdmFsdWUgb2YgVFJBTlNQT1NFIgoJCSAgICAgICAiIGludHJpbnNpYyBpbiBkaW1lbnNpb24gMTogaXMgJWxkLCIKCQkgICAgICAgIiBzaG91bGQgYmUgJWxkIiwgKGxvbmcgaW50KSBzcmNfZXh0ZW50LAoJCSAgICAgICAobG9uZyBpbnQpIHJldF9leHRlbnQpOwoKICAgICAgcmV0X2V4dGVudCA9IHJldC0+ZGltWzFdLnVib3VuZCArIDEgLSByZXQtPmRpbVsxXS5sYm91bmQ7CiAgICAgIHNyY19leHRlbnQgPSBzb3VyY2UtPmRpbVswXS51Ym91bmQgKyAxIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwoKICAgICAgaWYgKHNyY19leHRlbnQgIT0gcmV0X2V4dGVudCkKCXJ1bnRpbWVfZXJyb3IgKCJJbmNvcnJlY3QgZXh0ZW50IGluIHJldHVybiB2YWx1ZSBvZiBUUkFOU1BPU0UiCgkJICAgICAgICIgaW50cmluc2ljIGluIGRpbWVuc2lvbiAyOiBpcyAlbGQsIgoJCSAgICAgICAiIHNob3VsZCBiZSAlbGQiLCAobG9uZyBpbnQpIHNyY19leHRlbnQsCgkJICAgICAgIChsb25nIGludCkgcmV0X2V4dGVudCk7CgogICAgfQoKICBzeHN0cmlkZSA9IHNvdXJjZS0+ZGltWzBdLnN0cmlkZTsKICBzeXN0cmlkZSA9IHNvdXJjZS0+ZGltWzFdLnN0cmlkZTsKICB4Y291bnQgPSBzb3VyY2UtPmRpbVswXS51Ym91bmQgKyAxIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwogIHljb3VudCA9IHNvdXJjZS0+ZGltWzFdLnVib3VuZCArIDEgLSBzb3VyY2UtPmRpbVsxXS5sYm91bmQ7CgogIHJ4c3RyaWRlID0gcmV0LT5kaW1bMF0uc3RyaWRlOwogIHJ5c3RyaWRlID0gcmV0LT5kaW1bMV0uc3RyaWRlOwoKICBycHRyID0gcmV0LT5kYXRhOwogIHNwdHIgPSBzb3VyY2UtPmRhdGE7CgogIGZvciAoeT0wOyB5IDwgeWNvdW50OyB5KyspCiAgICB7CiAgICAgIGZvciAoeD0wOyB4IDwgeGNvdW50OyB4KyspCiAgICAgICAgewogICAgICAgICAgKnJwdHIgPSAqc3B0cjsKCiAgICAgICAgICBzcHRyICs9IHN4c3RyaWRlOwogICAgICAgICAgcnB0ciArPSByeXN0cmlkZTsKICAgICAgICB9CiAgICAgICAgc3B0ciArPSBzeXN0cmlkZSAtIChzeHN0cmlkZSAqIHhjb3VudCk7CiAgICAgICAgcnB0ciArPSByeHN0cmlkZSAtIChyeXN0cmlkZSAqIHhjb3VudCk7CiAgICB9Cn0KCiNlbmRpZgo=