LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDEzLCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZiBkZWZpbmVkKEhBVkVfS1JCNCkgfHwgZGVmaW5lZChIQVZFX0dTU0FQSSkKCiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgoKI2lmZGVmIEhBVkVfTElNSVRTX0gKI2luY2x1ZGUgPGxpbWl0cy5oPgojZW5kaWYKCiNpbmNsdWRlICJ1cmxkYXRhLmgiCiNpbmNsdWRlICJjdXJsX2Jhc2U2NC5oIgojaW5jbHVkZSAiY3VybF9tZW1vcnkuaCIKI2luY2x1ZGUgImtyYjQuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgInJhd3N0ci5oIgojaW5jbHVkZSAid2Fybmxlc3MuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbDsKICBjb25zdCBjaGFyICpuYW1lOwp9IGxldmVsX25hbWVzW10gPSB7CiAgeyBQUk9UX0NMRUFSLCAiY2xlYXIiIH0sCiAgeyBQUk9UX1NBRkUsICJzYWZlIiB9LAogIHsgUFJPVF9DT05GSURFTlRJQUwsICJjb25maWRlbnRpYWwiIH0sCiAgeyBQUk9UX1BSSVZBVEUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsCm5hbWVfdG9fbGV2ZWwoY29uc3QgY2hhciAqbmFtZSkKewogIGludCBpOwogIGZvcihpID0gMDsgaSA8IChpbnQpc2l6ZW9mKGxldmVsX25hbWVzKS8oaW50KXNpemVvZihsZXZlbF9uYW1lc1swXSk7IGkrKykKICAgIGlmKGNoZWNrcHJlZml4KG5hbWUsIGxldmVsX25hbWVzW2ldLm5hbWUpKQogICAgICByZXR1cm4gbGV2ZWxfbmFtZXNbaV0ubGV2ZWw7CiAgcmV0dXJuIFBST1RfTk9ORTsKfQoKLyogQ29udmVydCBhIHByb3RvY29sIHxsZXZlbHwgdG8gaXRzIGNoYXIgcmVwcmVzZW50YXRpb24uCiAgIFdlIHRha2UgYW4gaW50IHRvIGNhdGNoIHByb2dyYW1taW5nIG1pc3Rha2VzLiAqLwpzdGF0aWMgY2hhciBsZXZlbF90b19jaGFyKGludCBsZXZlbCkgewogIHN3aXRjaChsZXZlbCkgewogIGNhc2UgUFJPVF9DTEVBUjoKICAgIHJldHVybiAnQyc7CiAgY2FzZSBQUk9UX1NBRkU6CiAgICByZXR1cm4gJ1MnOwogIGNhc2UgUFJPVF9DT05GSURFTlRJQUw6CiAgICByZXR1cm4gJ0UnOwogIGNhc2UgUFJPVF9QUklWQVRFOgogICAgcmV0dXJuICdQJzsKICBjYXNlIFBST1RfQ01EOgogICAgLyogRmFsbCB0aHJvdWdoICovCiAgZGVmYXVsdDoKICAgIC8qIFRob3NlIDIgY2FzZXMgc2hvdWxkIG5vdCBiZSByZWFjaGVkISAqLwogICAgYnJlYWs7CiAgfQogIERFQlVHQVNTRVJUKDApOwogIC8qIERlZmF1bHQgdG8gdGhlIG1vc3Qgc2VjdXJlIGFsdGVybmF0aXZlLiAqLwogIHJldHVybiAnUCc7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggKiBjb25zdCBtZWNoc1tdID0gewojaWYgZGVmaW5lZChIQVZFX0dTU0FQSSkKICAmQ3VybF9rcmI1X2NsaWVudF9tZWNoLAojZW5kaWYKI2lmIGRlZmluZWQoSEFWRV9LUkI0KQogICZDdXJsX2tyYjRfY2xpZW50X21lY2gsCiNlbmRpZgogIE5VTEwKfTsKCi8qIFNlbmQgYW4gRlRQIGNvbW1hbmQgZGVmaW5lZCBieSB8bWVzc2FnZXwgYW5kIHRoZSBvcHRpb25hbCBhcmd1bWVudHMuIFRoZQogICBmdW5jdGlvbiByZXR1cm5zIHRoZSBmdHBfY29kZS4gSWYgYW4gZXJyb3Igb2NjdXJzLCAtMSBpcyByZXR1cm5lZC4gKi8Kc3RhdGljIGludCBmdHBfc2VuZF9jb21tYW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY29uc3QgY2hhciAqbWVzc2FnZSwgLi4uKQp7CiAgaW50IGZ0cF9jb2RlOwogIHNzaXplX3QgbnJlYWQ7CiAgdmFfbGlzdCBhcmdzOwogIGNoYXIgcHJpbnRfYnVmZmVyWzUwXTsKCiAgdmFfc3RhcnQoYXJncywgbWVzc2FnZSk7CiAgdnNucHJpbnRmKHByaW50X2J1ZmZlciwgc2l6ZW9mKHByaW50X2J1ZmZlciksIG1lc3NhZ2UsIGFyZ3MpOwogIHZhX2VuZChhcmdzKTsKCiAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCBwcmludF9idWZmZXIpICE9IENVUkxFX09LKSB7CiAgICBmdHBfY29kZSA9IC0xOwogIH0KICBlbHNlIHsKICAgIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCAmZnRwX2NvZGUpICE9IENVUkxFX09LKQogICAgICBmdHBfY29kZSA9IC0xOwogIH0KCiAgKHZvaWQpbnJlYWQ7IC8qIFVudXNlZCAqLwogIHJldHVybiBmdHBfY29kZTsKfQoKLyogUmVhZCB8bGVufCBmcm9tIHRoZSBzb2NrZXQgfGZkfCBhbmQgc3RvcmUgaXQgaW4gfHRvfC4gUmV0dXJuIGEgQ1VSTGNvZGUKICAgc2F5aW5nIHdoZXRoZXIgYW4gZXJyb3Igb2NjdXJyZWQgb3IgQ1VSTEVfT0sgaWYgfGxlbnwgd2FzIHJlYWQuICovCnN0YXRpYyBDVVJMY29kZQpzb2NrZXRfcmVhZChjdXJsX3NvY2tldF90IGZkLCB2b2lkICp0bywgc2l6ZV90IGxlbikKewogIGNoYXIgKnRvX3AgPSB0bzsKICBDVVJMY29kZSBjb2RlOwogIHNzaXplX3QgbnJlYWQ7CgogIHdoaWxlKGxlbiA+IDApIHsKICAgIGNvZGUgPSBDdXJsX3JlYWRfcGxhaW4oZmQsIHRvX3AsIGxlbiwgJm5yZWFkKTsKICAgIGlmKGNvZGUgPT0gQ1VSTEVfT0spIHsKICAgICAgbGVuIC09IG5yZWFkOwogICAgICB0b19wICs9IG5yZWFkOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIEZJWE1FOiBXZSBhcmUgZG9pbmcgYSBidXN5IHdhaXQgKi8KICAgICAgaWYoY29kZSA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIGNvZGU7CiAgICB9CiAgfQogIHJldHVybiBDVVJMRV9PSzsKfQoKCi8qIFdyaXRlIHxsZW58IGJ5dGVzIGZyb20gdGhlIGJ1ZmZlciB8dG98IHRvIHRoZSBzb2NrZXQgfGZkfC4gUmV0dXJuIGEKICAgQ1VSTGNvZGUgc2F5aW5nIHdoZXRoZXIgYW4gZXJyb3Igb2NjdXJyZWQgb3IgQ1VSTEVfT0sgaWYgfGxlbnwgd2FzCiAgIHdyaXR0ZW4uICovCnN0YXRpYyBDVVJMY29kZQpzb2NrZXRfd3JpdGUoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLCBjb25zdCB2b2lkICp0bywKICAgICAgICAgICAgIHNpemVfdCBsZW4pCnsKICBjb25zdCBjaGFyICp0b19wID0gdG87CiAgQ1VSTGNvZGUgY29kZTsKICBzc2l6ZV90IHdyaXR0ZW47CgogIHdoaWxlKGxlbiA+IDApIHsKICAgIGNvZGUgPSBDdXJsX3dyaXRlX3BsYWluKGNvbm4sIGZkLCB0b19wLCBsZW4sICZ3cml0dGVuKTsKICAgIGlmKGNvZGUgPT0gQ1VSTEVfT0spIHsKICAgICAgbGVuIC09IHdyaXR0ZW47CiAgICAgIHRvX3AgKz0gd3JpdHRlbjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKGNvZGUgPT0gQ1VSTEVfQUdBSU4pCiAgICAgICAgY29udGludWU7CiAgICAgIHJldHVybiBjb2RlOwogICAgfQogIH0KICByZXR1cm4gQ1VSTEVfT0s7Cn0KCnN0YXRpYyBDVVJMY29kZSByZWFkX2RhdGEoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGtyYjRidWZmZXIgKmJ1ZikKewogIGludCBsZW47CiAgdm9pZCogdG1wOwogIENVUkxjb2RlIHJldDsKCiAgcmV0ID0gc29ja2V0X3JlYWQoZmQsICZsZW4sIHNpemVvZihsZW4pKTsKICBpZihyZXQgIT0gQ1VSTEVfT0spCiAgICByZXR1cm4gcmV0OwoKICBsZW4gPSBudG9obChsZW4pOwogIHRtcCA9IHJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIGlmKHRtcCA9PSBOVUxMKQogICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CgogIGJ1Zi0+ZGF0YSA9IHRtcDsKICByZXQgPSBzb2NrZXRfcmVhZChmZCwgYnVmLT5kYXRhLCBsZW4pOwogIGlmKHJldCAhPSBDVVJMRV9PSykKICAgIHJldHVybiByZXQ7CiAgYnVmLT5zaXplID0gY29ubi0+bWVjaC0+ZGVjb2RlKGNvbm4tPmFwcF9kYXRhLCBidWYtPmRhdGEsIGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+ZGF0YV9wcm90LCBjb25uKTsKICBidWYtPmluZGV4ID0gMDsKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCnN0YXRpYyBzaXplX3QKYnVmZmVyX3JlYWQoc3RydWN0IGtyYjRidWZmZXIgKmJ1Ziwgdm9pZCAqZGF0YSwgc2l6ZV90IGxlbikKewogIGlmKGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXggPCBsZW4pCiAgICBsZW4gPSBidWYtPnNpemUgLSBidWYtPmluZGV4OwogIG1lbWNweShkYXRhLCAoY2hhciopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgbGVuKTsKICBidWYtPmluZGV4ICs9IGxlbjsKICByZXR1cm4gbGVuOwp9CgovKiBNYXRjaGVzIEN1cmxfcmVjdiBzaWduYXR1cmUgKi8Kc3RhdGljIHNzaXplX3Qgc2VjX3JlY3Yoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgc29ja2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpidWZmZXIsIHNpemVfdCBsZW4sIENVUkxjb2RlICplcnIpCnsKICBzaXplX3QgYnl0ZXNfcmVhZDsKICBzaXplX3QgdG90YWxfcmVhZCA9IDA7CiAgY3VybF9zb2NrZXRfdCBmZCA9IGNvbm4tPnNvY2tbc29ja2luZGV4XTsKCiAgKmVyciA9IENVUkxFX09LOwoKICAvKiBIYW5kbGUgY2xlYXIgdGV4dCByZXNwb25zZS4gKi8KICBpZihjb25uLT5zZWNfY29tcGxldGUgPT0gMCB8fCBjb25uLT5kYXRhX3Byb3QgPT0gUFJPVF9DTEVBUikKICAgICAgcmV0dXJuIHJlYWQoZmQsIGJ1ZmZlciwgbGVuKTsKCiAgaWYoY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnKSB7CiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogICAgcmV0dXJuIDA7CiAgfQoKICBieXRlc19yZWFkID0gYnVmZmVyX3JlYWQoJmNvbm4tPmluX2J1ZmZlciwgYnVmZmVyLCBsZW4pOwogIGxlbiAtPSBieXRlc19yZWFkOwogIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICBidWZmZXIgKz0gYnl0ZXNfcmVhZDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgaWYocmVhZF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSAhPSBDVVJMRV9PSykKICAgICAgcmV0dXJuIC0xOwogICAgaWYoY29ubi0+aW5fYnVmZmVyLnNpemUgPT0gMCkgewogICAgICBpZihieXRlc19yZWFkID4gMCkKICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICByZXR1cm4gYnl0ZXNfcmVhZDsKICAgIH0KICAgIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgICBsZW4gLT0gYnl0ZXNfcmVhZDsKICAgIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICAgIGJ1ZmZlciArPSBieXRlc19yZWFkOwogIH0KICAvKiBGSVhNRTogQ2hlY2sgZm9yIG92ZXJmbG93ICovCiAgcmV0dXJuIHRvdGFsX3JlYWQ7Cn0KCi8qIFNlbmQgfGxlbmd0aHwgYnl0ZXMgZnJvbSB8ZnJvbXwgdG8gdGhlIHxmZHwgc29ja2V0IHRha2luZyBjYXJlIG9mIGVuY29kaW5nCiAgIGFuZCBuZWdvY2lhdGluZyB3aXRoIHRoZSBzZXJ2ZXIuIHxmcm9tfCBjYW4gYmUgTlVMTC4gKi8KLyogRklYTUU6IFdlIGRvbid0IGNoZWNrIGZvciBlcnJvcnMgbm9yIHJlcG9ydCBhbnkhICovCnN0YXRpYyB2b2lkIGRvX3NlY19zZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlcywgaHRvbmxfYnl0ZXM7IC8qIDMyLWJpdCBpbnRlZ2VycyBmb3IgaHRvbmwgKi8KICBjaGFyICpidWZmZXIgPSBOVUxMOwogIGNoYXIgKmNtZF9idWZmZXI7CiAgc2l6ZV90IGNtZF9zaXplID0gMDsKICBDVVJMY29kZSBlcnJvcjsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgcHJvdF9sZXZlbCA9IGNvbm4tPmRhdGFfcHJvdDsKICBib29sIGlzY21kID0gKHByb3RfbGV2ZWwgPT0gUFJPVF9DTUQpP1RSVUU6RkFMU0U7CgogIERFQlVHQVNTRVJUKHByb3RfbGV2ZWwgPiBQUk9UX05PTkUgJiYgcHJvdF9sZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKGlzY21kKSB7CiAgICBpZighc3RybmNtcChmcm9tLCAiUEFTUyAiLCA1KSB8fCAhc3RybmNtcChmcm9tLCAiQUNDVCAiLCA1KSkKICAgICAgcHJvdF9sZXZlbCA9IFBST1RfUFJJVkFURTsKICAgIGVsc2UKICAgICAgcHJvdF9sZXZlbCA9IGNvbm4tPmNvbW1hbmRfcHJvdDsKICB9CiAgYnl0ZXMgPSBjb25uLT5tZWNoLT5lbmNvZGUoY29ubi0+YXBwX2RhdGEsIGZyb20sIGxlbmd0aCwgcHJvdF9sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZidWZmZXIsIGNvbm4pOwogIGlmKCFidWZmZXIgfHwgYnl0ZXMgPD0gMCkKICAgIHJldHVybjsgLyogZXJyb3IgKi8KCiAgaWYoaXNjbWQpIHsKICAgIGVycm9yID0gQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIGJ1ZmZlciwgY3VybHhfc2l0b3V6KGJ5dGVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjbWRfYnVmZmVyLCAmY21kX3NpemUpOwogICAgaWYoZXJyb3IpIHsKICAgICAgZnJlZShidWZmZXIpOwogICAgICByZXR1cm47IC8qIGVycm9yICovCiAgICB9CiAgICBpZihjbWRfc2l6ZSA+IDApIHsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKmVuYyA9ICJFTkMgIjsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKm1pYyA9ICJNSUMgIjsKICAgICAgaWYocHJvdF9sZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBlbmMsIDQpOwogICAgICBlbHNlCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBtaWMsIDQpOwoKICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBjbWRfYnVmZmVyLCBjbWRfc2l6ZSk7CiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgIlxyXG4iLCAyKTsKICAgICAgaW5mb2YoY29ubi0+ZGF0YSwgIlNlbmQ6ICVzJXNcbiIsIHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFP2VuYzptaWMsCiAgICAgICAgICAgIGNtZF9idWZmZXIpOwogICAgICBmcmVlKGNtZF9idWZmZXIpOwogICAgfQogIH0KICBlbHNlIHsKICAgIGh0b25sX2J5dGVzID0gaHRvbmwoYnl0ZXMpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCAmaHRvbmxfYnl0ZXMsIHNpemVvZihodG9ubF9ieXRlcykpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcykpOwogIH0KICBmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyBzc2l6ZV90IHNlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpidWZmZXIsIHNpemVfdCBsZW5ndGgpCnsKICAvKiBGSVhNRTogQ2hlY2sgZm9yIG92ZXJmbG93ICovCiAgc3NpemVfdCB0eCA9IDAsIGxlbiA9IGNvbm4tPmJ1ZmZlcl9zaXplOwoKICBsZW4gLT0gY29ubi0+bWVjaC0+b3ZlcmhlYWQoY29ubi0+YXBwX2RhdGEsIGNvbm4tPmRhdGFfcHJvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VybHhfc3p0b3NpKGxlbikpOwogIGlmKGxlbiA8PSAwKQogICAgbGVuID0gbGVuZ3RoOwogIHdoaWxlKGxlbmd0aCkgewogICAgaWYobGVuID49IDAgfHwgbGVuZ3RoIDwgKHNpemVfdClsZW4pIHsKICAgICAgLyogRklYTUU6IENoZWNrIGZvciBvdmVyZmxvdy4gKi8KICAgICAgbGVuID0gbGVuZ3RoOwogICAgfQogICAgZG9fc2VjX3NlbmQoY29ubiwgZmQsIGJ1ZmZlciwgY3VybHhfc3p0b3NpKGxlbikpOwogICAgbGVuZ3RoIC09IGxlbjsKICAgIGJ1ZmZlciArPSBsZW47CiAgICB0eCArPSBsZW47CiAgfQogIHJldHVybiB0eDsKfQoKLyogTWF0Y2hlcyBDdXJsX3NlbmQgc2lnbmF0dXJlICovCnN0YXRpYyBzc2l6ZV90IHNlY19zZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IHNvY2tpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqYnVmZmVyLCBzaXplX3QgbGVuLCBDVVJMY29kZSAqZXJyKQp7CiAgY3VybF9zb2NrZXRfdCBmZCA9IGNvbm4tPnNvY2tbc29ja2luZGV4XTsKICAqZXJyID0gQ1VSTEVfT0s7CiAgcmV0dXJuIHNlY193cml0ZShjb25uLCBmZCwgYnVmZmVyLCBsZW4pOwp9CgppbnQgQ3VybF9zZWNfcmVhZF9tc2coc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjaGFyICpidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWwpCnsKICAvKiBkZWNvZGVkX2xlbiBzaG91bGQgYmUgc2l6ZV90IG9yIHNzaXplX3QgYnV0IGNvbm4tPm1lY2gtPmRlY29kZSByZXR1cm5zIGFuCiAgICAgaW50ICovCiAgaW50IGRlY29kZWRfbGVuOwogIGNoYXIgKmJ1ZjsKICBpbnQgcmV0X2NvZGU7CiAgc2l6ZV90IGRlY29kZWRfc3ogPSAwOwogIENVUkxjb2RlIGVycm9yOwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGVycm9yID0gQ3VybF9iYXNlNjRfZGVjb2RlKGJ1ZmZlciArIDQsICh1bnNpZ25lZCBjaGFyICoqKSZidWYsICZkZWNvZGVkX3N6KTsKICBpZihlcnJvciB8fCBkZWNvZGVkX3N6ID09IDApCiAgICByZXR1cm4gLTE7CgogIGlmKGRlY29kZWRfc3ogPiAoc2l6ZV90KUlOVF9NQVgpIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CiAgZGVjb2RlZF9sZW4gPSBjdXJseF91enRvc2koZGVjb2RlZF9zeik7CgogIGRlY29kZWRfbGVuID0gY29ubi0+bWVjaC0+ZGVjb2RlKGNvbm4tPmFwcF9kYXRhLCBidWYsIGRlY29kZWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsLCBjb25uKTsKICBpZihkZWNvZGVkX2xlbiA8PSAwKSB7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBpZihjb25uLT5kYXRhLT5zZXQudmVyYm9zZSkgewogICAgYnVmW2RlY29kZWRfbGVuXSA9ICdcbic7CiAgICBDdXJsX2RlYnVnKGNvbm4tPmRhdGEsIENVUkxJTkZPX0hFQURFUl9JTiwgYnVmLCBkZWNvZGVkX2xlbiArIDEsIGNvbm4pOwogIH0KCiAgYnVmW2RlY29kZWRfbGVuXSA9ICdcMCc7CiAgREVCVUdBU1NFUlQoZGVjb2RlZF9sZW4gPiAzKTsKICBpZihidWZbM10gPT0gJy0nKQogICAgcmV0X2NvZGUgPSAwOwogIGVsc2UgewogICAgLyogQ2hlY2sgZm9yIGVycm9yPyAqLwogICAgc3NjYW5mKGJ1ZiwgIiVkIiwgJnJldF9jb2RlKTsKICB9CgogIGlmKGJ1ZltkZWNvZGVkX2xlbiAtIDFdID09ICdcbicpCiAgICBidWZbZGVjb2RlZF9sZW4gLSAxXSA9ICdcMCc7CiAgLyogRklYTUU6IElzIHxidWZmZXJ8IGxlbmd0aCBhbHdheXMgZ3JlYXRlciB0aGFuIHxkZWNvZGVkX2xlbnw/ICovCiAgc3RyY3B5KGJ1ZmZlciwgYnVmKTsKICBmcmVlKGJ1Zik7CiAgcmV0dXJuIHJldF9jb2RlOwp9CgovKiBGSVhNRTogVGhlIGVycm9yIGNvZGUgcmV0dXJuZWQgaGVyZSBpcyBuZXZlciBjaGVja2VkLiAqLwpzdGF0aWMgaW50IHNlY19zZXRfcHJvdGVjdGlvbl9sZXZlbChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgY29kZTsKICBjaGFyKiBwYnN6OwogIHN0YXRpYyB1bnNpZ25lZCBpbnQgYnVmZmVyX3NpemUgPSAxIDw8IDIwOyAvKiAxMDQ4NTc2ICovCiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsID0gY29ubi0+cmVxdWVzdF9kYXRhX3Byb3Q7CgogIERFQlVHQVNTRVJUKGxldmVsID4gUFJPVF9OT05FICYmIGxldmVsIDwgUFJPVF9MQVNUKTsKCiAgaWYoIWNvbm4tPnNlY19jb21wbGV0ZSkgewogICAgaW5mb2YoY29ubi0+ZGF0YSwgIlRyeWluZyB0byBjaGFuZ2UgdGhlIHByb3RlY3Rpb24gbGV2ZWwgYWZ0ZXIgdGhlIgogICAgICAgICAgICAgICAgICAgICAgImNvbXBsZXRpb24gb2YgdGhlIGRhdGEgZXhjaGFuZ2UuXG4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIC8qIEJhaWwgb3V0IGlmIHdlIHRyeSB0byBzZXQgdXAgdGhlIHNhbWUgbGV2ZWwgKi8KICBpZihjb25uLT5kYXRhX3Byb3QgPT0gbGV2ZWwpCiAgICByZXR1cm4gMDsKCiAgaWYobGV2ZWwpIHsKICAgIGNvZGUgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJQQlNaICV1IiwgYnVmZmVyX3NpemUpOwogICAgaWYoY29kZSA8IDApCiAgICAgIHJldHVybiAtMTsKCiAgICBpZihjb2RlLzEwMCAhPSAyKSB7CiAgICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHRoZSBwcm90ZWN0aW9uJ3MgYnVmZmVyIHNpemUuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CgogICAgcGJzeiA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJQQlNaPSIpOwogICAgaWYocGJzeikgewogICAgICAvKiBGSVhNRTogQ2hlY2tzIGZvciBlcnJvcnMgaW4gc3NjYW5mPyAqLwogICAgICBzc2NhbmYocGJzeiwgIlBCU1o9JXUiLCAmYnVmZmVyX3NpemUpOwogICAgICBpZihidWZmZXJfc2l6ZSA8IGNvbm4tPmJ1ZmZlcl9zaXplKQogICAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CiAgICB9CiAgfQoKICAvKiBOb3cgdHJ5IHRvIG5lZ2lvY2lhdGUgdGhlIHByb3RlY3Rpb24gbGV2ZWwuICovCiAgY29kZSA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIlBST1QgJWMiLCBsZXZlbF90b19jaGFyKGxldmVsKSk7CgogIGlmKGNvZGUgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZihjb2RlLzEwMCAhPSAyKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbiBsZXZlbC4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIGNvbm4tPmRhdGFfcHJvdCA9IGxldmVsOwogIGlmKGxldmVsID09IFBST1RfUFJJVkFURSkKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IGxldmVsOwoKICByZXR1cm4gMDsKfQoKaW50CkN1cmxfc2VjX3JlcXVlc3RfcHJvdChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKmxldmVsKQp7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGwgPSBuYW1lX3RvX2xldmVsKGxldmVsKTsKICBpZihsID09IFBST1RfTk9ORSkKICAgIHJldHVybiAtMTsKICBERUJVR0FTU0VSVChsID4gUFJPVF9OT05FICYmIGwgPCBQUk9UX0xBU1QpOwogIGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90ID0gbDsKICByZXR1cm4gMDsKfQoKc3RhdGljIENVUkxjb2RlIGNob29zZV9tZWNoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogIGNvbnN0IHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqIGNvbnN0ICptZWNoOwogIHZvaWQgKnRtcF9hbGxvY2F0aW9uOwogIGNvbnN0IGNoYXIgKm1lY2hfbmFtZTsKCiAgZm9yKG1lY2ggPSBtZWNoczsgKCptZWNoKTsgKyttZWNoKSB7CiAgICBtZWNoX25hbWUgPSAoKm1lY2gpLT5uYW1lOwogICAgLyogV2UgaGF2ZSBubyBtZWNoYW5pc20gd2l0aCBhIE5VTEwgbmFtZSBidXQga2VlcCB0aGlzIGNoZWNrICovCiAgICBERUJVR0FTU0VSVChtZWNoX25hbWUgIT0gTlVMTCk7CiAgICBpZihtZWNoX25hbWUgPT0gTlVMTCkgewogICAgICBpbmZvZihkYXRhLCAiU2tpcHBpbmcgbWVjaGFuaXNtIHdpdGggZW1wdHkgbmFtZSAoJXApXG4iLCAodm9pZCAqKW1lY2gpOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIHRtcF9hbGxvY2F0aW9uID0gcmVhbGxvYyhjb25uLT5hcHBfZGF0YSwgKCptZWNoKS0+c2l6ZSk7CiAgICBpZih0bXBfYWxsb2NhdGlvbiA9PSBOVUxMKSB7CiAgICAgIGZhaWxmKGRhdGEsICJGYWlsZWQgcmVhbGxvYyBvZiBzaXplICV1IiwgKCptZWNoKS0+c2l6ZSk7CiAgICAgIG1lY2ggPSBOVUxMOwogICAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICAgIH0KICAgIGNvbm4tPmFwcF9kYXRhID0gdG1wX2FsbG9jYXRpb247CgogICAgaWYoKCptZWNoKS0+aW5pdCkgewogICAgICByZXQgPSAoKm1lY2gpLT5pbml0KGNvbm4tPmFwcF9kYXRhKTsKICAgICAgaWYocmV0ICE9IDApIHsKICAgICAgICBpbmZvZihkYXRhLCAiRmFpbGVkIGluaXRpYWxpemF0aW9uIGZvciAlcy4gU2tpcHBpbmcgaXQuXG4iLCBtZWNoX25hbWUpOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICB9CgogICAgaW5mb2YoZGF0YSwgIlRyeWluZyBtZWNoYW5pc20gJXMuLi5cbiIsIG1lY2hfbmFtZSk7CiAgICByZXQgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJBVVRIICVzIiwgbWVjaF9uYW1lKTsKICAgIGlmKHJldCA8IDApCiAgICAgIC8qIEZJWE1FOiBUaGlzIGVycm9yIGlzIHRvbyBnZW5lcmljIGJ1dCBpdCBpcyBPSyBmb3Igbm93LiAqLwogICAgICByZXR1cm4gQ1VSTEVfQ09VTEROVF9DT05ORUNUOwoKICAgIGlmKHJldC8xMDAgIT0gMykgewogICAgICBzd2l0Y2gocmV0KSB7CiAgICAgIGNhc2UgNTA0OgogICAgICAgIGluZm9mKGRhdGEsICJNZWNoYW5pc20gJXMgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgc2VydmVyIChzZXJ2ZXIgIgogICAgICAgICAgICAgICAgICAgICJyZXR1cm5lZCBmdHAgY29kZTogNTA0KS5cbiIsIG1lY2hfbmFtZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNTM0OgogICAgICAgIGluZm9mKGRhdGEsICJNZWNoYW5pc20gJXMgd2FzIHJlamVjdGVkIGJ5IHRoZSBzZXJ2ZXIgKHNlcnZlciByZXR1cm5lZCAiCiAgICAgICAgICAgICAgICAgICAgImZ0cCBjb2RlOiA1MzQpLlxuIiwgbWVjaF9uYW1lKTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBpZihyZXQvMTAwID09IDUpIHsKICAgICAgICAgIGluZm9mKGRhdGEsICJzZXJ2ZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgc2VjdXJpdHkgZXh0ZW5zaW9uc1xuIik7CiAgICAgICAgICByZXR1cm4gQ1VSTEVfVVNFX1NTTF9GQUlMRUQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIC8qIEF1dGhlbnRpY2F0ZSAqLwogICAgcmV0ID0gKCptZWNoKS0+YXV0aChjb25uLT5hcHBfZGF0YSwgY29ubik7CgogICAgaWYocmV0ID09IEFVVEhfQ09OVElOVUUpCiAgICAgIGNvbnRpbnVlOwogICAgZWxzZSBpZihyZXQgIT0gQVVUSF9PSykgewogICAgICAvKiBNZWNoYW5pc20gaGFzIGR1bXBlZCB0aGUgZXJyb3IgdG8gc3RkZXJyLCBkb24ndCBlcnJvciBoZXJlLiAqLwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBERUJVR0FTU0VSVChyZXQgPT0gQVVUSF9PSyk7CgogICAgY29ubi0+bWVjaCA9ICptZWNoOwogICAgY29ubi0+c2VjX2NvbXBsZXRlID0gMTsKICAgIGNvbm4tPnJlY3ZbRklSU1RTT0NLRVRdID0gc2VjX3JlY3Y7CiAgICBjb25uLT5zZW5kW0ZJUlNUU09DS0VUXSA9IHNlY19zZW5kOwogICAgY29ubi0+cmVjdltTRUNPTkRBUllTT0NLRVRdID0gc2VjX3JlY3Y7CiAgICBjb25uLT5zZW5kW1NFQ09OREFSWVNPQ0tFVF0gPSBzZWNfc2VuZDsKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IFBST1RfU0FGRTsKICAgIC8qIFNldCB0aGUgcmVxdWVzdGVkIHByb3RlY3Rpb24gbGV2ZWwgKi8KICAgIC8qIEJMT0NLSU5HICovCiAgICAodm9pZClzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoY29ubik7CiAgICBicmVhazsKICB9CgogIHJldHVybiBtZWNoICE9IE5VTEwgPyBDVVJMRV9PSyA6IENVUkxFX0ZBSUxFRF9JTklUOwp9CgpDVVJMY29kZQpDdXJsX3NlY19sb2dpbihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICByZXR1cm4gY2hvb3NlX21lY2goY29ubik7Cn0KCgp2b2lkCkN1cmxfc2VjX2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpZihjb25uLT5tZWNoICE9IE5VTEwgJiYgY29ubi0+bWVjaC0+ZW5kKQogICAgY29ubi0+bWVjaC0+ZW5kKGNvbm4tPmFwcF9kYXRhKTsKICBpZihjb25uLT5hcHBfZGF0YSkgewogICAgZnJlZShjb25uLT5hcHBfZGF0YSk7CiAgICBjb25uLT5hcHBfZGF0YSA9IE5VTEw7CiAgfQogIGlmKGNvbm4tPmluX2J1ZmZlci5kYXRhKSB7CiAgICBmcmVlKGNvbm4tPmluX2J1ZmZlci5kYXRhKTsKICAgIGNvbm4tPmluX2J1ZmZlci5kYXRhID0gTlVMTDsKICAgIGNvbm4tPmluX2J1ZmZlci5zaXplID0gMDsKICAgIGNvbm4tPmluX2J1ZmZlci5pbmRleCA9IDA7CiAgICAvKiBGSVhNRTogSXMgdGhpcyByZWFsbHkgbmVlZGVkPyAqLwogICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMDsKICB9CiAgY29ubi0+c2VjX2NvbXBsZXRlID0gMDsKICBjb25uLT5kYXRhX3Byb3QgPSBQUk9UX0NMRUFSOwogIGNvbm4tPm1lY2ggPSBOVUxMOwp9CgojZW5kaWYgLyogSEFWRV9LUkI0IHx8IEhBVkVfR1NTQVBJICovCgojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=