I2lmbmRlZiBHSU1fQkFTSUNfR0VPTUVUUllfT1BFUkFUSU9OU19IX0lOQ0xVREVECiNkZWZpbmUgR0lNX0JBU0lDX0dFT01FVFJZX09QRVJBVElPTlNfSF9JTkNMVURFRAoKLyohIFxmaWxlIGdpbV9iYXNpY19nZW9tZXRyeV9vcGVyYXRpb25zLmgKKlxhdXRob3IgRnJhbmNpc2NvIExlf24gTt9qZXJhCnR5cGUgaW5kZXBlbmRhbnQgZ2VvbWV0cnkgcm91dGluZXMKCiovCi8qCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRoaXMgc291cmNlIGZpbGUgaXMgcGFydCBvZiBHSU1QQUNUIExpYnJhcnkuCgpGb3IgdGhlIGxhdGVzdCBpbmZvLCBzZWUgaHR0cDovL2dpbXBhY3Quc291cmNlZm9yZ2UubmV0LwoKQ29weXJpZ2h0IChjKSAyMDA2IEZyYW5jaXNjbyBMZW9uIE5hamVyYS4gQy5DLiA4MDA4NzM3MS4KZW1haWw6IHByb2plY3RpbGVtYW5AeWFob28uY29tCgogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiBFSVRIRVI6CiAgICgxKSBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZQogICAgICAgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQKICAgICAgIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4gVGhlIHRleHQgb2YgdGhlIEdOVSBMZXNzZXIKICAgICAgIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIGxpYnJhcnkgaW4gdGhlCiAgICAgICBmaWxlIEdJTVBBQ1QtTElDRU5TRS1MR1BMLlRYVC4KICAgKDIpIFRoZSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGlzIGluY2x1ZGVkIHdpdGggdGhpcyBsaWJyYXJ5IGluCiAgICAgICB0aGUgZmlsZSBHSU1QQUNULUxJQ0VOU0UtQlNELlRYVC4KICAgKDMpIFRoZSB6bGliL2xpYnBuZyBsaWNlbnNlIHRoYXQgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIGxpYnJhcnkgaW4KICAgICAgIHRoZSBmaWxlIEdJTVBBQ1QtTElDRU5TRS1aTElCLlRYVC4KCiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgZmlsZXMKIEdJTVBBQ1QtTElDRU5TRS1MR1BMLlRYVCwgR0lNUEFDVC1MSUNFTlNFLVpMSUIuVFhUIGFuZCBHSU1QQUNULUxJQ0VOU0UtQlNELlRYVCBmb3IgbW9yZSBkZXRhaWxzLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKi8KCgojaW5jbHVkZSAiZ2ltX2xpbmVhcl9tYXRoLmgiCgoKCgoKI2RlZmluZSBQTEFORURJUkVQU0lMT04gMC4wMDAwMDAxZgojZGVmaW5lIFBBUkFMRUxFTk9STUFMUyAwLjAwMDAwMWYKCgojZGVmaW5lIFRSSUFOR0xFX05PUk1BTCh2MSx2Mix2MyxuKVwKe1wKCXZlYzNmIF9kaWYxLF9kaWYyO1wKICAgIFZFQ19ESUZGKF9kaWYxLHYyLHYxKTtcCiAgICBWRUNfRElGRihfZGlmMix2Myx2MSk7XAogICAgVkVDX0NST1NTKG4sX2RpZjEsX2RpZjIpO1wKICAgIFZFQ19OT1JNQUxJWkUobik7XAp9XAoKI2RlZmluZSBUUklBTkdMRV9OT1JNQUxfRkFTVCh2MSx2Mix2MyxuKXtcCiAgICB2ZWMzZiBfZGlmMSxfZGlmMjsgXAogICAgVkVDX0RJRkYoX2RpZjEsdjIsdjEpOyBcCiAgICBWRUNfRElGRihfZGlmMix2Myx2MSk7IFwKICAgIFZFQ19DUk9TUyhuLF9kaWYxLF9kaWYyKTsgXAp9XAoKLy8vIHBsYW5lIGlzIGEgdmVjNGYKI2RlZmluZSBUUklBTkdMRV9QTEFORSh2MSx2Mix2MyxwbGFuZSkge1wKICAgIFRSSUFOR0xFX05PUk1BTCh2MSx2Mix2MyxwbGFuZSk7XAogICAgcGxhbmVbM10gPSBWRUNfRE9UKHYxLHBsYW5lKTtcCn1cCgovLy8gcGxhbmUgaXMgYSB2ZWM0ZgojZGVmaW5lIFRSSUFOR0xFX1BMQU5FX0ZBU1QodjEsdjIsdjMscGxhbmUpIHtcCiAgICBUUklBTkdMRV9OT1JNQUxfRkFTVCh2MSx2Mix2MyxwbGFuZSk7XAogICAgcGxhbmVbM10gPSBWRUNfRE9UKHYxLHBsYW5lKTtcCn1cCgovLy8gQ2FsYyBhIHBsYW5lIGZyb20gYW4gZWRnZSBhbiBhIG5vcm1hbC4gcGxhbmUgaXMgYSB2ZWM0ZgojZGVmaW5lIEVER0VfUExBTkUoZTEsZTIsbixwbGFuZSkge1wKICAgIHZlYzNmIF9kaWY7IFwKICAgIFZFQ19ESUZGKF9kaWYsZTIsZTEpOyBcCiAgICBWRUNfQ1JPU1MocGxhbmUsX2RpZixuKTsgXAogICAgVkVDX05PUk1BTElaRShwbGFuZSk7IFwKICAgIHBsYW5lWzNdID0gVkVDX0RPVChlMSxwbGFuZSk7XAp9XAoKI2RlZmluZSBESVNUQU5DRV9QTEFORV9QT0lOVChwbGFuZSxwb2ludCkgKFZFQ19ET1QocGxhbmUscG9pbnQpIC0gcGxhbmVbM10pCgojZGVmaW5lIFBST0pFQ1RfUE9JTlRfUExBTkUocG9pbnQscGxhbmUscHJvamVjdGVkKSB7XAoJR1JFQUwgX2RpcztcCglfZGlzID0gRElTVEFOQ0VfUExBTkVfUE9JTlQocGxhbmUscG9pbnQpO1wKCVZFQ19TQ0FMRShwcm9qZWN0ZWQsLV9kaXMscGxhbmUpO1wKCVZFQ19TVU0ocHJvamVjdGVkLHByb2plY3RlZCxwb2ludCk7CVwKfVwKCi8vISBWZXJpZmllcyBpZiBhIHBvaW50IGlzIGluIHRoZSBwbGFuZSBodWxsCnRlbXBsYXRlPHR5cGVuYW1lIENMQVNTX1BPSU5ULHR5cGVuYW1lIENMQVNTX1BMQU5FPgpTSU1EX0ZPUkNFX0lOTElORSBib29sIFBPSU5UX0lOX0hVTEwoCgljb25zdCBDTEFTU19QT0lOVCYgcG9pbnQsY29uc3QgQ0xBU1NfUExBTkUgKiBwbGFuZXMsR1VJTlQgcGxhbmVfY291bnQpCnsKCUdSRUFMIF9kaXM7Cglmb3IgKEdVSU5UIF9pID0gMDtfaTwgcGxhbmVfY291bnQ7KytfaSkKCXsKCQlfZGlzID0gRElTVEFOQ0VfUExBTkVfUE9JTlQocGxhbmVzW19pXSxwb2ludCk7CgkgICAgaWYoX2Rpcz4wLjBmKSByZXR1cm4gZmFsc2U7Cgl9CglyZXR1cm4gdHJ1ZTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgQ0xBU1NfUE9JTlQsdHlwZW5hbWUgQ0xBU1NfUExBTkU+ClNJTURfRk9SQ0VfSU5MSU5FIHZvaWQgUExBTkVfQ0xJUF9TRUdNRU5UKAoJY29uc3QgQ0xBU1NfUE9JTlQmIHMxLAoJY29uc3QgQ0xBU1NfUE9JTlQgJnMyLGNvbnN0IENMQVNTX1BMQU5FICZwbGFuZSxDTEFTU19QT0lOVCAmY2xpcHBlZCkKewoJR1JFQUwgX2RpczEsX2RpczI7CglfZGlzMSA9IERJU1RBTkNFX1BMQU5FX1BPSU5UKHBsYW5lLHMxKTsKCVZFQ19ESUZGKGNsaXBwZWQsczIsczEpOwoJX2RpczIgPSBWRUNfRE9UKGNsaXBwZWQscGxhbmUpOwoJVkVDX1NDQUxFKGNsaXBwZWQsLV9kaXMxL19kaXMyLGNsaXBwZWQpOwoJVkVDX1NVTShjbGlwcGVkLGNsaXBwZWQsczEpOwp9CgplbnVtIGVQTEFORV9JTlRFUlNFQ1RJT05fVFlQRQp7CglHX0JBQ0tfUExBTkUgPSAwLAoJR19DT0xMSURFX1BMQU5FLAoJR19GUk9OVF9QTEFORQp9OwoKZW51bSBlTElORV9QTEFORV9JTlRFUlNFQ1RJT05fVFlQRQp7CglHX0ZST05UX1BMQU5FX1MxID0gMCwKCUdfRlJPTlRfUExBTkVfUzIsCglHX0JBQ0tfUExBTkVfUzEsCglHX0JBQ0tfUExBTkVfUzIsCglHX0NPTExJREVfUExBTkVfUzEsCglHX0NPTExJREVfUExBTkVfUzIKfTsKCi8vISBDb25maXJtcyBpZiB0aGUgcGxhbmUgaW50ZXJzZWN0IHRoZSBlZGdlIG9yIG5vcgovKiEKaW50ZXJzZWN0aW9uIHR5cGUgbXVzdCBoYXZlIHRoZSBmb2xsb3dpbmcgdmFsdWVzCjx1bD4KPGxpPiAwIDogU2VnbWVudCBpbiBmcm9udCBvZiBwbGFuZSwgczEgY2xvc2VzdAo8bGk+IDEgOiBTZWdtZW50IGluIGZyb250IG9mIHBsYW5lLCBzMiBjbG9zZXN0CjxsaT4gMiA6IFNlZ21lbnQgaW4gYmFjayBvZiBwbGFuZSwgczEgY2xvc2VzdAo8bGk+IDMgOiBTZWdtZW50IGluIGJhY2sgb2YgcGxhbmUsIHMyIGNsb3Nlc3QKPGxpPiA0IDogU2VnbWVudCBjb2xsaWRlcyBwbGFuZSwgczEgaW4gYmFjawo8bGk+IDUgOiBTZWdtZW50IGNvbGxpZGVzIHBsYW5lLCBzMiBpbiBiYWNrCjwvdWw+CiovCgp0ZW1wbGF0ZTx0eXBlbmFtZSBDTEFTU19QT0lOVCx0eXBlbmFtZSBDTEFTU19QTEFORT4KU0lNRF9GT1JDRV9JTkxJTkUgZUxJTkVfUExBTkVfSU5URVJTRUNUSU9OX1RZUEUgUExBTkVfQ0xJUF9TRUdNRU5UMigKCWNvbnN0IENMQVNTX1BPSU5UJiBzMSwKCWNvbnN0IENMQVNTX1BPSU5UICZzMiwKCWNvbnN0IENMQVNTX1BMQU5FICZwbGFuZSxDTEFTU19QT0lOVCAmY2xpcHBlZCkKewoJR1JFQUwgX2RpczEgPSBESVNUQU5DRV9QTEFORV9QT0lOVChwbGFuZSxzMSk7CglHUkVBTCBfZGlzMiA9IERJU1RBTkNFX1BMQU5FX1BPSU5UKHBsYW5lLHMyKTsKCWlmKF9kaXMxID4tR19FUFNJTE9OICYmIF9kaXMyID4tR19FUFNJTE9OKQoJewoJICAgIGlmKF9kaXMxPF9kaXMyKSByZXR1cm4gR19GUk9OVF9QTEFORV9TMTsKCSAgICByZXR1cm4gR19GUk9OVF9QTEFORV9TMjsKCX0KCWVsc2UgaWYoX2RpczEgPEdfRVBTSUxPTiAmJiBfZGlzMiA8R19FUFNJTE9OKQoJewoJICAgIGlmKF9kaXMxPl9kaXMyKSByZXR1cm4gR19CQUNLX1BMQU5FX1MxOwoJICAgIHJldHVybiBHX0JBQ0tfUExBTkVfUzI7Cgl9CgoJVkVDX0RJRkYoY2xpcHBlZCxzMixzMSk7CglfZGlzMiA9IFZFQ19ET1QoY2xpcHBlZCxwbGFuZSk7CglWRUNfU0NBTEUoY2xpcHBlZCwtX2RpczEvX2RpczIsY2xpcHBlZCk7CglWRUNfU1VNKGNsaXBwZWQsY2xpcHBlZCxzMSk7CglpZihfZGlzMTxfZGlzMikgcmV0dXJuIEdfQ09MTElERV9QTEFORV9TMTsKCXJldHVybiBHX0NPTExJREVfUExBTkVfUzI7Cn0KCi8vISBDb25maXJtcyBpZiB0aGUgcGxhbmUgaW50ZXJzZWN0IHRoZSBlZGdlIG9yIG5vdAovKiEKY2xpcHBlZDEgYW5kIGNsaXBwZWQyIGFyZSB0aGUgdmVydGljZXMgYmVoaW5kIHRoZSBwbGFuZS4KY2xpcHBlZDEgaXMgdGhlIGNsb3Nlc3QKCmludGVyc2VjdGlvbl90eXBlIG11c3QgaGF2ZSB0aGUgZm9sbG93aW5nIHZhbHVlcwo8dWw+CjxsaT4gMCA6IFNlZ21lbnQgaW4gZnJvbnQgb2YgcGxhbmUsIHMxIGNsb3Nlc3QKPGxpPiAxIDogU2VnbWVudCBpbiBmcm9udCBvZiBwbGFuZSwgczIgY2xvc2VzdAo8bGk+IDIgOiBTZWdtZW50IGluIGJhY2sgb2YgcGxhbmUsIHMxIGNsb3Nlc3QKPGxpPiAzIDogU2VnbWVudCBpbiBiYWNrIG9mIHBsYW5lLCBzMiBjbG9zZXN0CjxsaT4gNCA6IFNlZ21lbnQgY29sbGlkZXMgcGxhbmUsIHMxIGluIGJhY2sKPGxpPiA1IDogU2VnbWVudCBjb2xsaWRlcyBwbGFuZSwgczIgaW4gYmFjawo8L3VsPgoqLwp0ZW1wbGF0ZTx0eXBlbmFtZSBDTEFTU19QT0lOVCx0eXBlbmFtZSBDTEFTU19QTEFORT4KU0lNRF9GT1JDRV9JTkxJTkUgZUxJTkVfUExBTkVfSU5URVJTRUNUSU9OX1RZUEUgUExBTkVfQ0xJUF9TRUdNRU5UX0NMT1NFU1QoCgljb25zdCBDTEFTU19QT0lOVCYgczEsCgljb25zdCBDTEFTU19QT0lOVCAmczIsCgljb25zdCBDTEFTU19QTEFORSAmcGxhbmUsCglDTEFTU19QT0lOVCAmY2xpcHBlZDEsQ0xBU1NfUE9JTlQgJmNsaXBwZWQyKQp7CgllTElORV9QTEFORV9JTlRFUlNFQ1RJT05fVFlQRSBpbnRlcnNlY3Rpb25fdHlwZSA9IFBMQU5FX0NMSVBfU0VHTUVOVDIoczEsczIscGxhbmUsY2xpcHBlZDEpOwoJc3dpdGNoKGludGVyc2VjdGlvbl90eXBlKQoJewoJY2FzZSBHX0ZST05UX1BMQU5FX1MxOgoJCVZFQ19DT1BZKGNsaXBwZWQxLHMxKTsKCSAgICBWRUNfQ09QWShjbGlwcGVkMixzMik7CgkJYnJlYWs7CgljYXNlIEdfRlJPTlRfUExBTkVfUzI6CgkJVkVDX0NPUFkoY2xpcHBlZDEsczIpOwoJICAgIFZFQ19DT1BZKGNsaXBwZWQyLHMxKTsKCQlicmVhazsKCWNhc2UgR19CQUNLX1BMQU5FX1MxOgoJCVZFQ19DT1BZKGNsaXBwZWQxLHMxKTsKCSAgICBWRUNfQ09QWShjbGlwcGVkMixzMik7CgkJYnJlYWs7CgljYXNlIEdfQkFDS19QTEFORV9TMjoKCQlWRUNfQ09QWShjbGlwcGVkMSxzMik7CgkgICAgVkVDX0NPUFkoY2xpcHBlZDIsczEpOwoJCWJyZWFrOwoJY2FzZSBHX0NPTExJREVfUExBTkVfUzE6CgkJVkVDX0NPUFkoY2xpcHBlZDIsczEpOwoJCWJyZWFrOwoJY2FzZSBHX0NPTExJREVfUExBTkVfUzI6CgkJVkVDX0NPUFkoY2xpcHBlZDIsczIpOwoJCWJyZWFrOwoJfQoJcmV0dXJuIGludGVyc2VjdGlvbl90eXBlOwp9CgoKLy8hIEZpbmRzIHRoZSAyIHNtYWxsZXN0IGNhcnRlc2lhbiBjb29yZGluYXRlcyBvZiBhIHBsYW5lIG5vcm1hbAojZGVmaW5lIFBMQU5FX01JTk9SX0FYRVMocGxhbmUsIGkwLCBpMSkgVkVDX01JTk9SX0FYRVMocGxhbmUsIGkwLCBpMSkKCi8vISBSYXkgcGxhbmUgY29sbGlzaW9uIGluIG9uZSB3YXkKLyohCkludGVyc2VjdHMgcGxhbmUgaW4gb25lIHdheSBvbmx5LiBUaGUgcmF5IG11c3QgZmFjZSB0aGUgcGxhbmUgKG5vcm1hbHMgbXVzdCBiZSBpbiBvcG9zc2l0ZSBkaXJlY3Rpb25zKS48YnIvPgpJdCB1c2VzIHRoZSBQTEFORURJUkVQU0lMT04gY29uc3RhbnQuCiovCnRlbXBsYXRlPHR5cGVuYW1lIFQsdHlwZW5hbWUgQ0xBU1NfUE9JTlQsdHlwZW5hbWUgQ0xBU1NfUExBTkU+ClNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgUkFZX1BMQU5FX0NPTExJU0lPTigKCWNvbnN0IENMQVNTX1BMQU5FICYgcGxhbmUsCgljb25zdCBDTEFTU19QT0lOVCAmIHZEaXIsCgljb25zdCBDTEFTU19QT0lOVCAmIHZQb2ludCwKCUNMQVNTX1BPSU5UICYgcG91dCxUICZ0cGFyYW0pCnsKCUdSRUFMIF9kaXMsX2RvdGRpcjsKCV9kb3RkaXIgPSBWRUNfRE9UKHBsYW5lLHZEaXIpOwoJaWYoX2RvdGRpcjxQTEFORURJUkVQU0lMT04pCgl7CgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJX2RpcyA9IERJU1RBTkNFX1BMQU5FX1BPSU5UKHBsYW5lLHZQb2ludCk7Cgl0cGFyYW0gPSAtX2Rpcy9fZG90ZGlyOwoJVkVDX1NDQUxFKHBvdXQsdHBhcmFtLHZEaXIpOwoJVkVDX1NVTShwb3V0LHZQb2ludCxwb3V0KTsKCXJldHVybiB0cnVlOwp9CgovLyEgbGluZSBjb2xsaXNpb24KLyohCipccmV0dXJuCgktMCAgaWYgdGhlIHJheSBuZXZlciBpbnRlcnNlY3RzCgktMSBpZiB0aGUgcmF5IGNvbGxpZGVzIGluIGZyb250CgktMiBpZiB0aGUgcmF5IGNvbGxpZGVzIGluIGJhY2sKKi8KdGVtcGxhdGU8dHlwZW5hbWUgVCx0eXBlbmFtZSBDTEFTU19QT0lOVCx0eXBlbmFtZSBDTEFTU19QTEFORT4KU0lNRF9GT1JDRV9JTkxJTkUgR1VJTlQgTElORV9QTEFORV9DT0xMSVNJT04oCgljb25zdCBDTEFTU19QTEFORSAmIHBsYW5lLAoJY29uc3QgQ0xBU1NfUE9JTlQgJiB2RGlyLAoJY29uc3QgQ0xBU1NfUE9JTlQgJiB2UG9pbnQsCglDTEFTU19QT0lOVCAmIHBvdXQsCglUICZ0cGFyYW0sCglUIHRtaW4sIFQgdG1heCkKewoJR1JFQUwgX2RpcyxfZG90ZGlyOwoJX2RvdGRpciA9IFZFQ19ET1QocGxhbmUsdkRpcik7CglpZihidEZhYnMoX2RvdGRpcik8UExBTkVESVJFUFNJTE9OKQoJewoJCXRwYXJhbSA9IHRtYXg7CgkgICAgcmV0dXJuIDA7Cgl9CglfZGlzID0gRElTVEFOQ0VfUExBTkVfUE9JTlQocGxhbmUsdlBvaW50KTsKCWNoYXIgcmV0dXJudmFsdWUgPSBfZGlzPDAuMGY/MjoxOwoJdHBhcmFtID0gLV9kaXMvX2RvdGRpcjsKCglpZih0cGFyYW08dG1pbikKCXsKCQlyZXR1cm52YWx1ZSA9IDA7CgkJdHBhcmFtID0gdG1pbjsKCX0KCWVsc2UgaWYodHBhcmFtPnRtYXgpCgl7CgkJcmV0dXJudmFsdWUgPSAwOwoJCXRwYXJhbSA9IHRtYXg7Cgl9CgoJVkVDX1NDQUxFKHBvdXQsdHBhcmFtLHZEaXIpOwoJVkVDX1NVTShwb3V0LHZQb2ludCxwb3V0KTsKCXJldHVybiByZXR1cm52YWx1ZTsKfQoKLyohIFxicmllZiBSZXR1cm5zIHRoZSBSYXkgb24gd2hpY2ggMiBwbGFuZXMgaW50ZXJzZWN0IGlmIHRoZXkgZG8uCiAgICBXcml0dGVuIGJ5IFJvZHJpZ28gSGVybmFuZGV6IG9uIE9ERSBjb252ZXggY29sbGlzaW9uCgogIFxwYXJhbSBwMSBQbGFuZSAxCiAgXHBhcmFtIHAyIFBsYW5lIDIKICBccGFyYW0gcCBDb250YWlucyB0aGUgb3JpZ2luIG9mIHRoZSByYXkgdXBvbiByZXR1cm5pbmcgaWYgcGxhbmVzIGludGVyc2VjdAogIFxwYXJhbSBkIENvbnRhaW5zIHRoZSBkaXJlY3Rpb24gb2YgdGhlIHJheSB1cG9uIHJldHVybmluZyBpZiBwbGFuZXMgaW50ZXJzZWN0CiAgXHJldHVybiB0cnVlIGlmIHRoZSBwbGFuZXMgaW50ZXJzZWN0LCAwIGlmIHBhcmFsZWxsLgoKKi8KdGVtcGxhdGU8dHlwZW5hbWUgQ0xBU1NfUE9JTlQsdHlwZW5hbWUgQ0xBU1NfUExBTkU+ClNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgSU5URVJTRUNUX1BMQU5FUygKCQljb25zdCBDTEFTU19QTEFORSAmcDEsCgkJY29uc3QgQ0xBU1NfUExBTkUgJnAyLAoJCUNMQVNTX1BPSU5UICZwLAoJCUNMQVNTX1BPSU5UICZkKQp7CglWRUNfQ1JPU1MoZCxwMSxwMik7CiAgCUdSRUFMIGRlbm9tID0gVkVDX0RPVChkLCBkKTsKICAJaWYoR0lNX0lTX1pFUk8oZGVub20pKSByZXR1cm4gZmFsc2U7Cgl2ZWMzZiBfbjsKCV9uWzBdPXAxWzNdKnAyWzBdIC0gcDJbM10qcDFbMF07CglfblsxXT1wMVszXSpwMlsxXSAtIHAyWzNdKnAxWzFdOwoJX25bMl09cDFbM10qcDJbMl0gLSBwMlszXSpwMVsyXTsKCVZFQ19DUk9TUyhwLF9uLGQpOwoJcFswXS89ZGVub207CglwWzFdLz1kZW5vbTsKCXBbMl0vPWRlbm9tOwoJcmV0dXJuIHRydWU7Cn0KCi8vKioqKioqKioqKioqKioqKiogU0VHTUVOVCBhbmQgTElORSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8vLwoKLyohIEZpbmRzIHRoZSBjbG9zZXN0IHBvaW50KGNwKSB0byAodikgb24gYSBzZWdtZW50IChlMSxlMikKICovCnRlbXBsYXRlPHR5cGVuYW1lIENMQVNTX1BPSU5UPgpTSU1EX0ZPUkNFX0lOTElORSB2b2lkIENMT1NFU1RfUE9JTlRfT05fU0VHTUVOVCgKCUNMQVNTX1BPSU5UICYgY3AsIGNvbnN0IENMQVNTX1BPSU5UICYgdiwKCWNvbnN0IENMQVNTX1BPSU5UICZlMSxjb25zdCBDTEFTU19QT0lOVCAmZTIpCnsKICAgIHZlYzNmIF9uOwogICAgVkVDX0RJRkYoX24sZTIsZTEpOwogICAgVkVDX0RJRkYoY3AsdixlMSk7CglHUkVBTCBfc2NhbGFyID0gVkVDX0RPVChjcCwgX24pOwoJX3NjYWxhci89IFZFQ19ET1QoX24sIF9uKTsKCWlmKF9zY2FsYXIgPDAuMGYpCgl7CgkgICAgVkVDX0NPUFkoY3AsZTEpOwoJfQoJZWxzZSBpZihfc2NhbGFyID4xLjBmKQoJewoJICAgIFZFQ19DT1BZKGNwLGUyKTsKCX0KCWVsc2UKCXsKICAgICAgICBWRUNfU0NBTEUoY3AsX3NjYWxhcixfbik7CiAgICAgICAgVkVDX1NVTShjcCxjcCxlMSk7Cgl9Cn0KCgovKiEgXGJyaWVmIEZpbmRzIHRoZSBsaW5lIHBhcmFtcyB3aGVyZSB0aGVzZSBsaW5lcyBpbnRlcnNlY3QuCgpccGFyYW0gZGlyMSBEaXJlY3Rpb24gb2YgbGluZSAxClxwYXJhbSBwb2ludDEgUG9pbnQgb2YgbGluZSAxClxwYXJhbSBkaXIyIERpcmVjdGlvbiBvZiBsaW5lIDIKXHBhcmFtIHBvaW50MiBQb2ludCBvZiBsaW5lIDIKXHBhcmFtIHQxIFJlc3VsdCBQYXJhbWV0ZXIgZm9yIGxpbmUgMQpccGFyYW0gdDIgUmVzdWx0IFBhcmFtZXRlciBmb3IgbGluZSAyClxwYXJhbSBkb2ludGVyc2VjdCAgMCAgaWYgdGhlIGxpbmVzIHdvbid0IGludGVyc2VjdCwgZWxzZSAxCgoqLwp0ZW1wbGF0ZTx0eXBlbmFtZSBULHR5cGVuYW1lIENMQVNTX1BPSU5UPgpTSU1EX0ZPUkNFX0lOTElORSBib29sIExJTkVfSU5URVJTRUNUSU9OX1BBUkFNUygKCWNvbnN0IENMQVNTX1BPSU5UICYgZGlyMSwKCUNMQVNTX1BPSU5UICYgcG9pbnQxLAoJY29uc3QgQ0xBU1NfUE9JTlQgJiBkaXIyLAoJQ0xBU1NfUE9JTlQgJiAgcG9pbnQyLAoJVCYgdDEsVCYgdDIpCnsKICAgIEdSRUFMIGRldDsKCUdSRUFMIGUxZTEgPSBWRUNfRE9UKGRpcjEsZGlyMSk7CglHUkVBTCBlMWUyID0gVkVDX0RPVChkaXIxLGRpcjIpOwoJR1JFQUwgZTJlMiA9IFZFQ19ET1QoZGlyMixkaXIyKTsKCXZlYzNmIHAxcDI7CiAgICBWRUNfRElGRihwMXAyLHBvaW50MSxwb2ludDIpOwogICAgR1JFQUwgcDFwMmUxID0gVkVDX0RPVChwMXAyLGRpcjEpOwoJR1JFQUwgcDFwMmUyID0gVkVDX0RPVChwMXAyLGRpcjIpOwoJZGV0ID0gZTFlMiplMWUyIC0gZTFlMSplMmUyOwoJaWYoR0lNX0lTX1pFUk8oZGV0KSkgcmV0dXJuIGZhbHNlOwoJdDEgPSAoZTFlMipwMXAyZTIgLSBlMmUyKnAxcDJlMSkvZGV0OwoJdDIgPSAoZTFlMSpwMXAyZTIgLSBlMWUyKnAxcDJlMSkvZGV0OwoJcmV0dXJuIHRydWU7Cn0KCi8vISBGaW5kIGNsb3Nlc3QgcG9pbnRzIG9uIHNlZ21lbnRzCnRlbXBsYXRlPHR5cGVuYW1lIENMQVNTX1BPSU5UPgpTSU1EX0ZPUkNFX0lOTElORSB2b2lkIFNFR01FTlRfQ09MTElTSU9OKAoJY29uc3QgQ0xBU1NfUE9JTlQgJiB2QTEsCgljb25zdCBDTEFTU19QT0lOVCAmIHZBMiwKCWNvbnN0IENMQVNTX1BPSU5UICYgdkIxLAoJY29uc3QgQ0xBU1NfUE9JTlQgJiB2QjIsCglDTEFTU19QT0lOVCAmIHZQb2ludEEsCglDTEFTU19QT0lOVCAmIHZQb2ludEIpCnsKICAgIENMQVNTX1BPSU5UIF9BRCxfQkQsX047CiAgICB2ZWM0ZiBfTTsvL3BsYW5lCiAgICBWRUNfRElGRihfQUQsdkEyLHZBMSk7CiAgICBWRUNfRElGRihfQkQsdkIyLHZCMSk7CiAgICBWRUNfQ1JPU1MoX04sX0FELF9CRCk7CiAgICBHUkVBTCBfdHAgPSBWRUNfRE9UKF9OLF9OKTsKICAgIGlmKF90cDxHX0VQU0lMT04pLy9BUkUgUEFSQUxFTEUKICAgIHsKICAgIAkvL3Byb2plY3QgQiBvdmVyIEEKICAgIAlib29sIGludmVydF9iX29yZGVyID0gZmFsc2U7CiAgICAJX01bMF0gPSBWRUNfRE9UKHZCMSxfQUQpOwogICAgCV9NWzFdID0gVkVDX0RPVCh2QjIsX0FEKTsKICAgIAlpZihfTVswXT5fTVsxXSkKICAgIAl7CiAgICAJCWludmVydF9iX29yZGVyICA9IHRydWU7CiAgICAJCUdJTV9TV0FQX05VTUJFUlMoX01bMF0sX01bMV0pOwogICAgCX0KICAgIAlfTVsyXSA9IFZFQ19ET1QodkExLF9BRCk7CiAgICAJX01bM10gPSBWRUNfRE9UKHZBMixfQUQpOwogICAgCS8vbWlkIHBvaW50cwogICAgCV9OWzBdID0gKF9NWzBdK19NWzFdKSowLjVmOwogICAgCV9OWzFdID0gKF9NWzJdK19NWzNdKSowLjVmOwoKICAgIAlpZihfTlswXTxfTlsxXSkKICAgIAl7CiAgICAJCWlmKF9NWzFdPF9NWzJdKQogICAgCQl7CiAgICAJCQl2UG9pbnRCID0gaW52ZXJ0X2Jfb3JkZXI/dkIxOnZCMjsKICAgIAkJCXZQb2ludEEgPSB2QTE7CiAgICAJCX0KICAgIAkJZWxzZSBpZihfTVsxXTxfTVszXSkKICAgIAkJewogICAgCQkJdlBvaW50QiA9IGludmVydF9iX29yZGVyP3ZCMTp2QjI7CiAgICAJCQlDTE9TRVNUX1BPSU5UX09OX1NFR01FTlQodlBvaW50QSx2UG9pbnRCLHZBMSx2QTIpOwogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJdlBvaW50QSA9IHZBMjsKICAgIAkJCUNMT1NFU1RfUE9JTlRfT05fU0VHTUVOVCh2UG9pbnRCLHZQb2ludEEsdkIxLHZCMik7CiAgICAJCX0KICAgIAl9CiAgICAJZWxzZQogICAgCXsKICAgIAkJaWYoX01bM108X01bMF0pCiAgICAJCXsKICAgIAkJCXZQb2ludEIgPSBpbnZlcnRfYl9vcmRlcj92QjI6dkIxOwogICAgCQkJdlBvaW50QSA9IHZBMjsKICAgIAkJfQogICAgCQllbHNlIGlmKF9NWzNdPF9NWzFdKQogICAgCQl7CiAgICAJCQl2UG9pbnRBID0gdkEyOwogICAgCQkJQ0xPU0VTVF9QT0lOVF9PTl9TRUdNRU5UKHZQb2ludEIsdlBvaW50QSx2QjEsdkIyKTsKICAgIAkJfQogICAgCQllbHNlCiAgICAJCXsKICAgIAkJCXZQb2ludEIgPSBpbnZlcnRfYl9vcmRlcj92QjE6dkIyOwogICAgCQkJQ0xPU0VTVF9QT0lOVF9PTl9TRUdNRU5UKHZQb2ludEEsdlBvaW50Qix2QTEsdkEyKTsKICAgIAkJfQogICAgCX0KICAgIAlyZXR1cm47CiAgICB9CgoKICAgIFZFQ19DUk9TUyhfTSxfTixfQkQpOwogICAgX01bM10gPSBWRUNfRE9UKF9NLHZCMSk7CgogICAgTElORV9QTEFORV9DT0xMSVNJT04oX00sX0FELHZBMSx2UG9pbnRBLF90cCxidFNjYWxhcigwKSwgYnRTY2FsYXIoMSkpOwogICAgLypDbG9zZXN0IHBvaW50IG9uIHNlZ21lbnQqLwogICAgVkVDX0RJRkYodlBvaW50Qix2UG9pbnRBLHZCMSk7CglfdHAgPSBWRUNfRE9UKHZQb2ludEIsIF9CRCk7CglfdHAvPSBWRUNfRE9UKF9CRCwgX0JEKTsKCV90cCA9IEdJTV9DTEFNUChfdHAsMC4wZiwxLjBmKTsKICAgIFZFQ19TQ0FMRSh2UG9pbnRCLF90cCxfQkQpOwogICAgVkVDX1NVTSh2UG9pbnRCLHZQb2ludEIsdkIxKTsKfQoKCgoKLy8hIExpbmUgYm94IGludGVyc2VjdGlvbiBpbiBvbmUgZGltZW5zaW9uCi8qIQoKKlxwYXJhbSBwb3MgUG9zaXRpb24gb2YgdGhlIHJheQoqXHBhcmFtIGRpciBQcm9qZWN0aW9uIG9mIHRoZSBEaXJlY3Rpb24gb2YgdGhlIHJheQoqXHBhcmFtIGJtaW4gTWluaW11bSBib3VuZCBvZiB0aGUgYm94CipccGFyYW0gYm1heCBNYXhpbXVtIGJvdW5kIG9mIHRoZSBib3gKKlxwYXJhbSB0Zmlyc3QgdGhlIG1pbmltdW0gcHJvamVjdGlvbi4gQXNzaWduIHRvIDAgYXQgZmlyc3QuCipccGFyYW0gdGxhc3QgdGhlIG1heGltdW0gcHJvamVjdGlvbi4gQXNzaWduIHRvIElORklOSVRZIGF0IGZpcnN0LgoqXHJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGFuIGludGVyc2VjdGlvbi4KKi8KdGVtcGxhdGU8dHlwZW5hbWUgVD4KU0lNRF9GT1JDRV9JTkxJTkUgYm9vbCBCT1hfQVhJU19JTlRFUlNFQ1QoVCBwb3MsIFQgZGlyLFQgYm1pbiwgVCBibWF4LCBUICYgdGZpcnN0LCBUICYgdGxhc3QpCnsKCWlmKEdJTV9JU19aRVJPKGRpcikpCgl7CiAgICAgICAgcmV0dXJuICEocG9zIDwgYm1pbiB8fCBwb3MgPiBibWF4KTsKCX0KCUdSRUFMIGEwID0gKGJtaW4gLSBwb3MpIC8gZGlyOwoJR1JFQUwgYTEgPSAoYm1heCAtIHBvcykgLyBkaXI7CglpZihhMCA+IGExKSAgIEdJTV9TV0FQX05VTUJFUlMoYTAsIGExKTsKCXRmaXJzdCA9IEdJTV9NQVgoYTAsIHRmaXJzdCk7Cgl0bGFzdCA9IEdJTV9NSU4oYTEsIHRsYXN0KTsKCWlmICh0bGFzdCA8IHRmaXJzdCkgcmV0dXJuIGZhbHNlOwoJcmV0dXJuIHRydWU7Cn0KCgovLyEgU29ydHMgMyBjb21wb25ldHMKdGVtcGxhdGU8dHlwZW5hbWUgVD4KU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBTT1JUXzNfSU5ESUNFUygKCQljb25zdCBUICogdmFsdWVzLAoJCUdVSU5UICogb3JkZXJfaW5kaWNlcykKewoJLy9nZXQgbWluaW11bQoJb3JkZXJfaW5kaWNlc1swXSA9IHZhbHVlc1swXSA8IHZhbHVlc1sxXSA/ICh2YWx1ZXNbMF0gPCB2YWx1ZXNbMl0gPyAwIDogMikgOiAodmFsdWVzWzFdIDwgdmFsdWVzWzJdID8gMSA6IDIpOwoKCS8vZ2V0IHNlY29uZCBhbmQgdGhpcmQKCUdVSU5UIGkwID0gKG9yZGVyX2luZGljZXNbMF0gKyAxKSUzOwoJR1VJTlQgaTEgPSAoaTAgKyAxKSUzOwoKCWlmKHZhbHVlc1tpMF0gPCB2YWx1ZXNbaTFdKQoJewoJCW9yZGVyX2luZGljZXNbMV0gPSBpMDsKCQlvcmRlcl9pbmRpY2VzWzJdID0gaTE7Cgl9CgllbHNlCgl7CgkJb3JkZXJfaW5kaWNlc1sxXSA9IGkxOwoJCW9yZGVyX2luZGljZXNbMl0gPSBpMDsKCX0KfQoKCgoKCiNlbmRpZiAvLyBHSU1fVkVDVE9SX0hfSU5DTFVERUQK