YC8qIEltcGxlbWVudGF0aW9uIG9mIHRoZSBUUkFOU1BPU0UgaW50cmluc2ljCiAgIENvcHlyaWdodCAyMDAzLCAyMDA1IEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgogICBDb250cmlidXRlZCBieSBUb2JpYXMgU2NobPx0ZXIKClRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBHTlUgRm9ydHJhbiA5NSBydW50aW1lIGxpYnJhcnkgKGxpYmdmb3J0cmFuKS4KCkxpYmdmb3J0cmFuIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgptb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCnZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCkluIGFkZGl0aW9uIHRvIHRoZSBwZXJtaXNzaW9ucyBpbiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIHRoZQpGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24gZ2l2ZXMgeW91IHVubGltaXRlZCBwZXJtaXNzaW9uIHRvIGxpbmsgdGhlCmNvbXBpbGVkIHZlcnNpb24gb2YgdGhpcyBmaWxlIGludG8gY29tYmluYXRpb25zIHdpdGggb3RoZXIgcHJvZ3JhbXMsCmFuZCB0byBkaXN0cmlidXRlIHRob3NlIGNvbWJpbmF0aW9ucyB3aXRob3V0IGFueSByZXN0cmljdGlvbiBjb21pbmcKZnJvbSB0aGUgdXNlIG9mIHRoaXMgZmlsZS4gIChUaGUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSByZXN0cmljdGlvbnMKZG8gYXBwbHkgaW4gb3RoZXIgcmVzcGVjdHM7IGZvciBleGFtcGxlLCB0aGV5IGNvdmVyIG1vZGlmaWNhdGlvbiBvZgp0aGUgZmlsZSwgYW5kIGRpc3RyaWJ1dGlvbiB3aGVuIG5vdCBsaW5rZWQgaW50byBhIGNvbWJpbmUKZXhlY3V0YWJsZS4pCgpMaWJnZm9ydHJhbiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLApidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCkdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgpZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKTGljZW5zZSBhbG9uZyB3aXRoIGxpYmdmb3J0cmFuOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwKd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLApCb3N0b24sIE1BIDAyMTExLTEzMDcsIFVTQS4gICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgImxpYmdmb3J0cmFuLmgiJwppbmNsdWRlKGlwYXJtLm00KWRubAoKZXh0ZXJuIHZvaWQgdHJhbnNwb3NlX2AncnR5cGVfY29kZSAocnR5cGUgKiByZXQsIHJ0eXBlICogc291cmNlKTsKZXhwb3J0X3Byb3RvKHRyYW5zcG9zZV9gJ3J0eXBlX2NvZGUpOwoKdm9pZAp0cmFuc3Bvc2VfYCdydHlwZV9jb2RlIChydHlwZSAqIHJldCwgcnR5cGUgKiBzb3VyY2UpCnsKICAvKiByLiogaW5kaWNhdGVzIHRoZSByZXR1cm4gYXJyYXkuICAqLwogIGluZGV4X3R5cGUgcnhzdHJpZGUsIHJ5c3RyaWRlOwogIHJ0eXBlX25hbWUgKnJwdHI7CiAgLyogcy4qIGluZGljYXRlcyB0aGUgc291cmNlIGFycmF5LiAgKi8KICBpbmRleF90eXBlIHN4c3RyaWRlLCBzeXN0cmlkZTsKICBjb25zdCBydHlwZV9uYW1lICpzcHRyOwoKICBpbmRleF90eXBlIHhjb3VudCwgeWNvdW50OwogIGluZGV4X3R5cGUgeCwgeTsKCiAgYXNzZXJ0IChHRkNfREVTQ1JJUFRPUl9SQU5LIChzb3VyY2UpID09IDIpOwoKICBpZiAocmV0LT5kYXRhID09IE5VTEwpCiAgICB7CiAgICAgIGFzc2VydCAoR0ZDX0RFU0NSSVBUT1JfUkFOSyAocmV0KSA9PSAyKTsKICAgICAgYXNzZXJ0IChyZXQtPmR0eXBlID09IHNvdXJjZS0+ZHR5cGUpOwoKICAgICAgcmV0LT5kaW1bMF0ubGJvdW5kID0gMDsKICAgICAgcmV0LT5kaW1bMF0udWJvdW5kID0gc291cmNlLT5kaW1bMV0udWJvdW5kIC0gc291cmNlLT5kaW1bMV0ubGJvdW5kOwogICAgICByZXQtPmRpbVswXS5zdHJpZGUgPSAxOwoKICAgICAgcmV0LT5kaW1bMV0ubGJvdW5kID0gMDsKICAgICAgcmV0LT5kaW1bMV0udWJvdW5kID0gc291cmNlLT5kaW1bMF0udWJvdW5kIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwogICAgICByZXQtPmRpbVsxXS5zdHJpZGUgPSByZXQtPmRpbVswXS51Ym91bmQrMTsKCiAgICAgIHJldC0+ZGF0YSA9IGludGVybmFsX21hbGxvY19zaXplIChzaXplb2YgKHJ0eXBlX25hbWUpICogc2l6ZTAgKHJldCkpOwogICAgICByZXQtPmJhc2UgPSAwOwogICAgfQoKICBpZiAocmV0LT5kaW1bMF0uc3RyaWRlID09IDApCiAgICByZXQtPmRpbVswXS5zdHJpZGUgPSAxOwogIGlmIChzb3VyY2UtPmRpbVswXS5zdHJpZGUgPT0gMCkKICAgIHNvdXJjZS0+ZGltWzBdLnN0cmlkZSA9IDE7CgogIHN4c3RyaWRlID0gc291cmNlLT5kaW1bMF0uc3RyaWRlOwogIHN5c3RyaWRlID0gc291cmNlLT5kaW1bMV0uc3RyaWRlOwogIHhjb3VudCA9IHNvdXJjZS0+ZGltWzBdLnVib3VuZCArIDEgLSBzb3VyY2UtPmRpbVswXS5sYm91bmQ7CiAgeWNvdW50ID0gc291cmNlLT5kaW1bMV0udWJvdW5kICsgMSAtIHNvdXJjZS0+ZGltWzFdLmxib3VuZDsKCiAgcnhzdHJpZGUgPSByZXQtPmRpbVswXS5zdHJpZGU7CiAgcnlzdHJpZGUgPSByZXQtPmRpbVsxXS5zdHJpZGU7CgogIHJwdHIgPSByZXQtPmRhdGE7CiAgc3B0ciA9IHNvdXJjZS0+ZGF0YTsKCiAgZm9yICh5PTA7IHkgPCB5Y291bnQ7IHkrKykKICAgIHsKICAgICAgZm9yICh4PTA7IHggPCB4Y291bnQ7IHgrKykKICAgICAgICB7CiAgICAgICAgICAqcnB0ciA9ICpzcHRyOwoKICAgICAgICAgIHNwdHIgKz0gc3hzdHJpZGU7CiAgICAgICAgICBycHRyICs9IHJ5c3RyaWRlOwogICAgICAgIH0KICAgICAgICBzcHRyICs9IHN5c3RyaWRlIC0gKHN4c3RyaWRlICogeGNvdW50KTsKICAgICAgICBycHRyICs9IHJ4c3RyaWRlIC0gKHJ5c3RyaWRlICogeGNvdW50KTsKICAgIH0KfQo=