Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgoKc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CglBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CgoJcmV0dXJuIHBSdW50aW1lLT5HZXRJc29sYXRlKCk7Cn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfUHVibGljTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBET1VCTEVfQ09SUkVDVAkwLjAwMDAwMDAwMDAwMDAwMQoKQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oQ0pTX1B1YmxpY01ldGhvZHMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk51bWJlcl9Gb3JtYXQsNikKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTnVtYmVyX0tleXN0cm9rZSw2KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0Zvcm1hdCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0tleXN0cm9rZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0Zvcm1hdEV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9Gb3JtYXQsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9LZXlzdHJva2UsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXRFeCwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZUV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlLDMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1ha2VOdW1iZXIsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlX0NhbGN1bGF0ZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZSYW5nZV9WYWxpZGF0ZSw0KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZNZXJnZUNoYW5nZSwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQYXJzZURhdGVFeCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZFeHRyYWN0TnVtcywxKQpFTkRfSlNfU1RBVElDX0dMT0JBTF9GVU4oKQoKSU1QTEVNRU5UX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQoKc3RydWN0IHN0cnVfVGJDb252ZXJ0CnsKCUZYX0xQQ1NUUiBscHN6SlNNYXJrOwoJRlhfTFBDU1RSIGxwc3pDcHBNYXJrOwp9OwoKc3RhdGljIGNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsibW1tbSIsIiVCIiwKCSJtbW0iLCAiJWIiLAoJIm1tIiwgICIlbSIsCgkvLyJtIgoJImRkZGQiLCIlQSIsCgkiZGRkIiwgIiVhIiwKCSJkZCIsICAiJWQiLAoJLy8iZCIsICAgIiV3IiwKCSJ5eXl5IiwiJVkiLAoJInl5IiwgICIleSIsCgkiSEgiLCAgIiVIIiwKCS8vIkgiCgkiaGgiLCAgIiVJIiwKCS8vImgiCgkiTU0iLCAgIiVNIiwKCS8vIk0iCgkic3MiLCAgIiVTIiwKCS8vInMKCSJ0dCIsICAiJXAiCgkvLyJ0Igp9OwoKc3RhdGljIEZYX0xQQ1dTVFIgbW9udGhzW10gPQp7CgkoRlhfTFBDV1NUUilMIkphbiIsIChGWF9MUENXU1RSKUwiRmViIiwgKEZYX0xQQ1dTVFIpTCJNYXIiLCAoRlhfTFBDV1NUUilMIkFwciIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW4iLCAoRlhfTFBDV1NUUilMIkp1bCIsIChGWF9MUENXU1RSKUwiQXVnIiwgKEZYX0xQQ1dTVFIpTCJTZXAiLCAoRlhfTFBDV1NUUilMIk9jdCIsIChGWF9MUENXU1RSKUwiTm92IiwgKEZYX0xQQ1dTVFIpTCJEZWMiCn07CgpzdGF0aWMgRlhfTFBDV1NUUiBmdWxsbW9udGhzW10gPSAKeyAKCShGWF9MUENXU1RSKUwiSmFudWFyeSIsIChGWF9MUENXU1RSKUwiRmVicnVhcnkiLCAoRlhfTFBDV1NUUilMIk1hcmNoIiwgKEZYX0xQQ1dTVFIpTCJBcHJpbCIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW5lIiwgKEZYX0xQQ1dTVFIpTCJKdWx5IiwgKEZYX0xQQ1dTVFIpTCJBdWd1c3QiLCAoRlhfTFBDV1NUUilMIlNlcHRlbWJlciIsIChGWF9MUENXU1RSKUwiT2N0b2JlciIsIChGWF9MUENXU1RSKUwiTm92ZW1iZXIiLCAoRlhfTFBDV1NUUilMIkRlY2VtYmVyIiAKfTsKCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzTnVtYmVyKEZYX0xQQ1dTVFIgc3RyaW5nKQp7CglDRlhfV2lkZVN0cmluZyBzVHJpbSA9IFN0clRyaW0oc3RyaW5nKTsKCUZYX0xQQ1dTVFIgcFRyaW0gPSBzVHJpbTsKCUZYX0xQQ1dTVFIgcCA9IHBUcmltOwoKCglGWF9CT09MIGJEb3QgPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCgl3Y2hhcl90IGM7Cgl3aGlsZSAoKGMgPSAqcCkpCgl7CgkJaWYgKGMgPT0gJy4nIHx8IGMgPT0gJywnKQoJCXsKCQkJaWYgKGJEb3QpIHJldHVybiBGQUxTRTsKCQkJYkRvdCA9IFRSVUU7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJy0nIHx8IGMgPT0gJysnKQoJCXsKCQkJaWYgKHAgIT0gcFRyaW0pCgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJ2UnIHx8IGMgPT0gJ0UnKQoJCXsKCQkJaWYgKGJLWEpTKSByZXR1cm4gRkFMU0U7CgoJCQlwKys7CgkJCWMgPSAqcDsKCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQoJCQl7CgkJCQliS1hKUyA9IFRSVUU7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9CgkJZWxzZSBpZiAoIUlzRGlnaXQoYykpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCXArKzsKCX0KCglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNEaWdpdCh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKGNoID49IEwnMCcgJiYgY2ggPD0gTCc5Jyk7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzRGlnaXQoY2hhciBjaCkKewoJcmV0dXJuIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNBbHBoYWJldGljKHdjaGFyX3QgY2gpCnsKCXJldHVybiAoKGNoID49IEwnYScgJiYgY2ggPD0gTCd6JykgfHwgKGNoID49IEwnQScgJiYgY2ggPD0gTCdaJykpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0FscGhhTnVtZXJpYyh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKElzRGlnaXQoY2gpIHx8IElzQWxwaGFiZXRpYyhjaCkpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjptYXNrU2F0aXNmaWVkKHdjaGFyX3QgY19DaGFuZ2Usd2NoYXJfdCBjX01hc2spCnsKCXN3aXRjaCAoY19NYXNrKQoJewoJY2FzZSBMJzknOgogICAgICAgIHJldHVybiBJc0RpZ2l0KGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ0EnOgogICAgICAgIHJldHVybiBJc0FscGhhYmV0aWMoY19DaGFuZ2UpOwkJCiAgICBjYXNlIEwnTyc6CiAgICAgICAgcmV0dXJuIElzQWxwaGFOdW1lcmljKGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ1gnOgogICAgICAgIHJldHVybiBUUlVFOwkJCglkZWZhdWx0OgogICAgICAgIHJldHVybiAoY19DaGFuZ2UgPT0gY19NYXNrKTsKCX0KfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6aXNSZXNlcnZlZE1hc2tDaGFyKHdjaGFyX3QgY2gpCnsKCXJldHVybiBjaCA9PSBMJzknIHx8IGNoID09IEwnQScgfHwgY2ggPT0gTCdPJyB8fCBjaCA9PSBMJ1gnOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OkFGX1NpbXBsZShGWF9MUENXU1RSIHNGdWN0aW9uLCBkb3VibGUgZFZhbHVlMSwgZG91YmxlIGRWYWx1ZTIpCnsKCWlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiQVZHIikgPT0gMCB8fCBGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiU1VNIikgPT0gMCkKCXsKCQlyZXR1cm4gZFZhbHVlMSArIGRWYWx1ZTI7Cgl9CgllbHNlIGlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLCAoRlhfTFBDV1NUUilMIlBSRCIpID09IDApCgl7CgkJcmV0dXJuIGRWYWx1ZTEgKiBkVmFsdWUyOwoJfQoJZWxzZSBpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIk1JTiIpID09IDApCgl7CgkJcmV0dXJuIEZYX01JTihkVmFsdWUxLCBkVmFsdWUyKTsKCX0KCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNQVgiKSA9PSAwKQoJewoJCXJldHVybiBGWF9NQVgoZFZhbHVlMSwgZFZhbHVlMik7Cgl9CgoJcmV0dXJuIGRWYWx1ZTE7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJMVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSBMJyAnKSBwU3RyKys7CgoJcmV0dXJuIHBTdHI7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCUZYX0xQQ1dTVFIgcCA9IHBTdHI7CgoJd2hpbGUgKCpwKSBwKys7CglwLS07CglpZiAocCA+PSBwU3RyKQoJewkJCgkJd2hpbGUgKCpwICYmICpwID09IEwnICcpIHAtLTsKCQlwKys7CgkJcmV0dXJuIENGWF9XaWRlU3RyaW5nKHBTdHIscC1wU3RyKTsKCX0KCXJldHVybiBMIiI7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1dTVFIgcFN0cikKewoJcmV0dXJuIFN0clJUcmltKFN0ckxUcmltKHBTdHIpKTsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0ckxUcmltKEZYX0xQQ1NUUiBwU3RyKQp7Cgl3aGlsZSAoKnBTdHIgJiYgKnBTdHIgPT0gJyAnKSBwU3RyKys7CgogICAgcmV0dXJuIHBTdHI7Cn0KCkNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENTVFIgcFN0cikKewoJRlhfTFBDU1RSIHAgPSBwU3RyOwoKCXdoaWxlICgqcCkgcCsrOwoJcC0tOwoJaWYgKHAgPj0gcFN0cikKCXsJCQoJCXdoaWxlICgqcCAmJiAqcCA9PSAnICcpIHAtLTsKCQlwKys7CgkJcmV0dXJuIENGWF9CeXRlU3RyaW5nKHBTdHIscC1wU3RyKTsKCX0KCXJldHVybiAiIjsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0clRyaW0oRlhfTFBDU1RSIHBTdHIpCnsKCXJldHVybiBTdHJSVHJpbShTdHJMVHJpbShwU3RyKSk7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VOdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSwgRlhfQk9PTCYgYkFsbERpZ2l0cywgRlhfQk9PTCYgYkRvdCwgRlhfQk9PTCYgYlNpZ24sIEZYX0JPT0wmIGJLWEpTKQp7CgliRG90ID0gRkFMU0U7CgliU2lnbiA9IEZBTFNFOwoJYktYSlMgPSBGQUxTRTsKCglGWF9CT09MIGJEaWdpdEV4aXN0ID0gRkFMU0U7CgoJRlhfTFBDV1NUUiBwID0gc3dTb3VyY2U7Cgl3Y2hhcl90IGM7CgoJRlhfTFBDV1NUUiBwU3RhcnQgPSBOVUxMOwoJRlhfTFBDV1NUUiBwRW5kID0gTlVMTDsKCgl3aGlsZSAoKGMgPSAqcCkpCgl7CgkJaWYgKCFwU3RhcnQgJiYgYyAhPSBMJyAnKQoJCXsKCQkJcFN0YXJ0ID0gcDsKCQl9CgoJCXBFbmQgPSBwOwoJCXArKzsKCX0KCglpZiAoIXBTdGFydCkKCXsKCQliQWxsRGlnaXRzID0gRkFMU0U7CgkJcmV0dXJuIDA7Cgl9CgoJd2hpbGUgKHBFbmQgIT0gcFN0YXJ0KQoJewoJCWlmICgqcEVuZCA9PSBMJyAnKQoJCQlwRW5kIC0tOwoJCWVsc2UKCQkJYnJlYWs7Cgl9CgoJZG91YmxlIGRSZXQgPSAwOwoJcCA9IHBTdGFydDsKCWJBbGxEaWdpdHMgPSBUUlVFOwoJQ0ZYX1dpZGVTdHJpbmcgc3dEaWdpdHM7CgoJd2hpbGUgKHAgPD0gcEVuZCkKCXsJCgkJYyA9ICpwOwoKCQlpZiAoSXNEaWdpdChjKSkKCQl7CgkJCXN3RGlnaXRzICs9IGM7CgkJCWJEaWdpdEV4aXN0ID0gVFJVRTsKCQl9CgkJZWxzZSAKCQl7CgkJCXN3aXRjaCAoYykKCQkJewoJCQljYXNlIEwnICc6CgkJCQliQWxsRGlnaXRzID0gRkFMU0U7CgkJCQlicmVhazsKCQkJY2FzZSBMJy4nOgoJCQljYXNlIEwnLCc6CgkJCQlpZiAoIWJEb3QpCgkJCQl7CgkJCQkJaWYgKGJEaWdpdEV4aXN0KQoJCQkJCXsKCQkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCXsKCQkJCQkJc3dEaWdpdHMgKz0gTCcwJzsKCQkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKCQkJCQkJYkRpZ2l0RXhpc3QgPSBUUlVFOwoJCQkJCX0KCgkJCQkJYkRvdCA9IFRSVUU7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgJ2UnOgoJCQljYXNlICdFJzoKCQkJCWlmICghYktYSlMpCgkJCQl7CgkJCQkJcCsrOwoJCQkJCWMgPSAqcDsKCQkJCQlpZiAoYyA9PSAnKycgfHwgYyA9PSAnLScpCgkJCQkJewoJCQkJCQliS1hKUyA9IFRSVUU7CgkJCQkJCXN3RGlnaXRzICs9ICdlJzsKCQkJCQkJc3dEaWdpdHMgKz0gYzsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgTCctJzoKCQkJCWlmICghYkRpZ2l0RXhpc3QgJiYgIWJTaWduKQoJCQkJewoJCQkJCXN3RGlnaXRzICs9IGM7CgkJCQkJYlNpZ24gPSBUUlVFOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQlkZWZhdWx0OgoJCQkJYkFsbERpZ2l0cyA9IEZBTFNFOwoKCQkJCWlmIChwICE9IHBTdGFydCAmJiAhYkRvdCAmJiBiRGlnaXRFeGlzdCkKCQkJCXsKCQkJCQlzd0RpZ2l0cyArPSBMJy4nOwoJCQkJCWJEb3QgPSBUUlVFOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWJEb3QgPSBGQUxTRTsKCQkJCQliRGlnaXRFeGlzdCA9IEZBTFNFOwoJCQkJCXN3RGlnaXRzID0gTCIiOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXArKzsKCX0KCglpZiAoc3dEaWdpdHMuR2V0TGVuZ3RoKCkgPiAwICYmIHN3RGlnaXRzLkdldExlbmd0aCgpIDwgMTcpCgl7CgkJQ0ZYX0J5dGVTdHJpbmcgc0RpZ2l0cyA9IHN3RGlnaXRzLlVURjhFbmNvZGUoKTsKCgkJaWYgKGJLWEpTKQoJCXsKCQkJZFJldCA9IGF0b2Yoc0RpZ2l0cyk7CgkJfQoJCWVsc2UKCQl7CgkJCWlmIChiRG90KQoJCQl7CgkJCQljaGFyKiBwU3RvcFN0cmluZzsKCQkJCWRSZXQgPSA6OnN0cnRvZChzRGlnaXRzLCAmcFN0b3BTdHJpbmcpOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJZFJldCA9IGF0b2woc0RpZ2l0cyk7CgkJCX0KCQl9CgoJfQoKCXJldHVybiBkUmV0Owp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nVG9OdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSkKewoJRlhfQk9PTCBiQWxsRGlnaXRzID0gRkFMU0U7CglGWF9CT09MIGJEb3QgPSBGQUxTRTsKCUZYX0JPT0wgYlNpZ24gPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCglyZXR1cm4gUGFyc2VOdW1iZXIoc3dTb3VyY2UsIGJBbGxEaWdpdHMsIGJEb3QsIGJTaWduLCBiS1hKUyk7Cn0KCkZYX0JPT0wJQ0pTX1B1YmxpY01ldGhvZHM6OkNvbnZlcnRTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlLCBkb3VibGUgJiBkUmV0LCBGWF9CT09MICYgYkRvdCkKewoJRlhfQk9PTCBiQWxsRGlnaXRzID0gRkFMU0U7CglGWF9CT09MIGJTaWduID0gRkFMU0U7CglGWF9CT09MIGJLWEpTID0gRkFMU0U7CgoJZFJldCA9IFBhcnNlTnVtYmVyKHN3U291cmNlLCBiQWxsRGlnaXRzLCBiRG90LCBiU2lnbiwgYktYSlMpOwoKCXJldHVybiBiQWxsRGlnaXRzOwp9CgpDSlNfQXJyYXkgQ0pTX1B1YmxpY01ldGhvZHM6OkFGX01ha2VBcnJheUZyb21MaXN0KHY4OjpJc29sYXRlKiBpc29sYXRlLCBDSlNfVmFsdWUgdmFsKQp7CglDSlNfQXJyYXkgU3RyQXJyYXkoaXNvbGF0ZSk7CglpZih2YWwuSXNBcnJheU9iamVjdCgpKQoJewoJCXZhbC5Db252ZXJ0VG9BcnJheShTdHJBcnJheSk7CgkJcmV0dXJuIFN0ckFycmF5OwoJfQoJQ0ZYX1dpZGVTdHJpbmcgd3NTdHIgPSB2YWwub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCUNGWF9CeXRlU3RyaW5nIHQgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUod3NTdHIpOwoJY29uc3QgY2hhciAqIHAgPSAoY29uc3QgY2hhciAqKXQ7CgoKCWludCBjaCA9ICcsJyA7CglpbnQgbkluZGV4ID0gMDsKCgl3aGlsZSAoKnApCgl7CgkJY29uc3QgY2hhciAqIHBUZW1wID0gc3RyY2hyKHAsIGNoKTsKCQlpZiAocFRlbXAgPT0gTlVMTCkKCQl7CgkJCVN0ckFycmF5LlNldEVsZW1lbnQobkluZGV4LCBDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDU1RSKVN0clRyaW0ocCkpKTsKCQkJYnJlYWs7CgkJfQoJCWVsc2UKCQl7CgkJCWNoYXIgKiBwU3ViID0gbmV3IGNoYXJbcFRlbXAgLSBwICsgMV07CgkJCXN0cm5jcHkocFN1YiwgcCwgcFRlbXAgLSBwKTsKCQkJKihwU3ViICsgKHBUZW1wIC0gcCkpID0gJ1wwJzsKCgkJCVN0ckFycmF5LlNldEVsZW1lbnQobkluZGV4LCBDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDU1RSKVN0clRyaW0ocFN1YikpKTsKCQkJZGVsZXRlIFtdcFN1YjsKCQkJCgkJCW5JbmRleCArKzsKCQkJcCA9ICsrcFRlbXA7CgkJfQoJCQoJfQoJcmV0dXJuIFN0ckFycmF5Owp9CgppbnQgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nSW50ZWdlcihjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLGludCBuU3RhcnQsaW50JiBuU2tpcCwgaW50IG5NYXhTdGVwKQp7CglpbnQgblJldCA9IDA7CgluU2tpcCA9IDA7Cglmb3IgKGludCBpPW5TdGFydCwgc3o9c3RyaW5nLkdldExlbmd0aCgpOyBpIDwgc3o7IGkrKykKCXsKCQlpZiAoaS1uU3RhcnQgPiAxMCkKCQkJYnJlYWs7CgoJCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7CgkJaWYgKElzRGlnaXQoKHdjaGFyX3QpYykpCgkJewoJCQluUmV0ID0gblJldCAqIDEwICsgKGMgLSAnMCcpOwoJCQluU2tpcCA9IGkgLSBuU3RhcnQgKyAxOwoJCQlpZiAoblNraXAgPj0gbk1heFN0ZXApIAoJCQkJYnJlYWs7CgkJfQoJCWVsc2UKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIG5SZXQ7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ1N0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLCBpbnQgblN0YXJ0LCBpbnQmIG5Ta2lwKQp7CglDRlhfV2lkZVN0cmluZyBzd1JldDsKCW5Ta2lwID0gMDsKCWZvciAoaW50IGk9blN0YXJ0LCBzej1zdHJpbmcuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQoJewoJCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7CgkJaWYgKChjID49IEwnYScgJiYgYyA8PSBMJ3onKSB8fCAoYyA+PSBMJ0EnICYmIGMgPD0gTCdaJykpCgkJewoJCQlzd1JldCArPSBjOwoJCQluU2tpcCA9IGkgLSBuU3RhcnQgKyAxOwoJCX0KCQllbHNlCgkJCWJyZWFrOwoJfQoKCXJldHVybiBzd1JldDsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZU5vcm1hbERhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgRlhfQk9PTCYgYldyb25nRm9ybWF0KQp7Cglkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOwoKCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7CglpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkdCkgKyAxOwoJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkdCk7CglpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOwoJaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkdCk7CglpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGR0KTsKCglpbnQgbnVtYmVyWzNdOwoKCWludCBuU2tpcCA9IDA7CglpbnQgbkxlbiA9IHZhbHVlLkdldExlbmd0aCgpOwoJaW50IG5JbmRleCA9IDA7CglpbnQgaSA9IDA7Cgl3aGlsZSAoaSA8IG5MZW4pCgl7CgkJaWYgKG5JbmRleCA+IDIpIGJyZWFrOwoKCQlGWF9XQ0hBUiBjID0gdmFsdWUuR2V0QXQoaSk7CgkJaWYgKElzRGlnaXQoKHdjaGFyX3QpYykpCgkJewoJCQludW1iZXJbbkluZGV4KytdID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBpLCBuU2tpcCwgNCk7CgkJCWkgKz0gblNraXA7CQkJCgkJfQoJCWVsc2UKCQl7CgkJCWkgKys7CgkJfQoJfQoKCWlmIChuSW5kZXggPT0gMikKCXsKCQkvLyBjYXNlMjogbW9udGgvZGF5CgkJLy8gY2FzZTM6IGRheS9tb250aAoJCWlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSkKCQl7CgkJCW5Nb250aCA9IG51bWJlclswXTsKCQkJbkRheSA9IG51bWJlclsxXTsKCQl9CgkJZWxzZSBpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAzMSkgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikpCgkJewoJCQluRGF5ID0gbnVtYmVyWzBdOwoJCQluTW9udGggPSBudW1iZXJbMV07CgkJfQoKCQliV3JvbmdGb3JtYXQgPSBGQUxTRTsKCX0KCWVsc2UgaWYgKG5JbmRleCA9PSAzKQoJewoJCS8vIGNhc2UxOiB5ZWFyL21vbnRoL2RheQoJCS8vIGNhc2UyOiBtb250aC9kYXkveWVhcgoJCS8vIGNhc2UzOiBkYXkvbW9udGgveWVhcgoKCQlpZiAobnVtYmVyWzBdID4gMTIgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikgJiYgKG51bWJlclsyXSA+PSAxICYmIG51bWJlclsyXSA8PSAzMSkpCgkJewoJCQluWWVhciA9IG51bWJlclswXTsKCQkJbk1vbnRoID0gbnVtYmVyWzFdOwoJCQluRGF5ID0gbnVtYmVyWzJdOwoJCX0KCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSAmJiBudW1iZXJbMl0gPiAzMSkKCQl7CgkJCW5Nb250aCA9IG51bWJlclswXTsKCQkJbkRheSA9IG51bWJlclsxXTsKCQkJblllYXIgPSBudW1iZXJbMl07CgkJfQoJCWVsc2UgaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMzEpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpICYmIG51bWJlclsyXSA+IDMxKQoJCXsKCQkJbkRheSA9IG51bWJlclswXTsKCQkJbk1vbnRoID0gbnVtYmVyWzFdOwoJCQluWWVhciA9IG51bWJlclsyXTsKCQl9CgoJCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJfQoJZWxzZQoJewoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJcmV0dXJuIGR0OwoJfQoKCUNGWF9XaWRlU3RyaW5nIHN3VGVtcDsKCXN3VGVtcC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZC8lZC8lZCAlZDolZDolZCIsbk1vbnRoLG5EYXksblllYXIsbkhvdXIsbk1pbixuU2VjKTsKCXJldHVybiBKU19EYXRlUGFyc2Uoc3dUZW1wKTsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpNYWtlUmVndWxhckRhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQsIEZYX0JPT0wmIGJXcm9uZ0Zvcm1hdCkKewoJZG91YmxlIGR0ID0gSlNfR2V0RGF0ZVRpbWUoKTsKCglpZiAoZm9ybWF0LklzRW1wdHkoKSB8fCB2YWx1ZS5Jc0VtcHR5KCkpCgkJcmV0dXJuIGR0OwoKCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7CglpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkdCkgKyAxOwoJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkdCk7CglpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOwoJaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkdCk7CglpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGR0KTsKCglpbnQgblllYXJTdWIgPSA5OTsgLy9uWWVhciAtIDIwMDA7CgoJRlhfQk9PTCBiUG0gPSBGQUxTRTsKCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoKCWludCBpPTA7CglpbnQgaj0wOwoKCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQoJewoJCWlmIChiRXhpdCkgYnJlYWs7CgoJCUZYX1dDSEFSIGMgPSBmb3JtYXQuR2V0QXQoaSk7CgkJc3dpdGNoIChjKQoJCXsKCQkJY2FzZSAnOic6CgkJCWNhc2UgJy4nOgoJCQljYXNlICctJzoKCQkJY2FzZSAnXFwnOgoJCQljYXNlICcvJzoKCQkJCWkrKzsKCQkJCWorKzsKCQkJCWJyZWFrOwoKCQkJY2FzZSAneSc6CgkJCWNhc2UgJ20nOgoJCQljYXNlICdkJzoKCQkJY2FzZSAnSCc6CgkJCWNhc2UgJ2gnOgoJCQljYXNlICdNJzoKCQkJY2FzZSAncyc6CgkJCWNhc2UgJ3QnOgoJCQkJewoJCQkJCWludCBvbGRqID0gajsKCQkJCQlpbnQgblNraXAgPSAwOwoJCQkJCWludCByZW1haW5pbmcgPSBmb3JtYXQuR2V0TGVuZ3RoKCkgLSBpIC0gMTsKCgkJCQkJaWYgKHJlbWFpbmluZyA9PSAwIHx8IGZvcm1hdC5HZXRBdChpKzEpICE9IGMpCgkJCQkJewoJCQkJCQlzd2l0Y2ggKGMpCgkJCQkJCXsKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqKys7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdtJzoKCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJCW5EYXkgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdoJzoKCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnTSc6CgkJCQkJCQkJbk1pbiA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAncyc6CgkJCQkJCQkJblNlYyA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAndCc6CgkJCQkJCQkJYlBtID0gKGogPCB2YWx1ZS5HZXRMZW5ndGgoKSAmJiB2YWx1ZS5HZXRBdChqKSA9PSAncCcpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqKys7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDEgfHwgZm9ybWF0LkdldEF0KGkrMikgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoJCQkJCQkJY2FzZSAneSc6CgkJCQkJCQkJblllYXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJCW5Nb250aCA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQkJbkRheSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnSCc6CgkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdNJzoKCQkJCQkJCQluTWluID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdzJzoKCQkJCQkJCQluU2VjID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICd0JzoKCQkJCQkJCQliUG0gPSAoaiArIDEgPCB2YWx1ZS5HZXRMZW5ndGgoKSAmJiB2YWx1ZS5HZXRBdChqKSA9PSAncCcgJiYgdmFsdWUuR2V0QXQoaisxKSA9PSAnbScpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IDI7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDIgfHwgZm9ybWF0LkdldEF0KGkrMykgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJewoJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOwoJCQkJCQkJCQlGWF9CT09MIGJGaW5kID0gRkFMU0U7CgkJCQkJCQkJCWZvciAoaW50IG0gPSAwOyBtIDwgMTI7IG0rKykKCQkJCQkJCQkJewoJCQkJCQkJCQkJaWYgKHNNb250aC5Db21wYXJlTm9DYXNlKG1vbnRoc1ttXSkgPT0gMCkKCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsKCQkJCQkJCQkJCQlpKz0zOwoJCQkJCQkJCQkJCWorPW5Ta2lwOwoJCQkJCQkJCQkJCWJGaW5kID0gVFJVRTsKCQkJCQkJCQkJCQlicmVhazsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoKCQkJCQkJCQkJaWYgKCFiRmluZCkKCQkJCQkJCQkJewoJCQkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMyk7CgkJCQkJCQkJCQlpKz0zOwoJCQkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJZGVmYXVsdDoKCQkJCQkJCQlpKz0zOwoJCQkJCQkJCWorPTM7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDMgfHwgZm9ybWF0LkdldEF0KGkrNCkgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoKCgkJCQkJCQljYXNlICd5JzoKCQkJCQkJCQluWWVhciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDQpOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJaSArPSA0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJewoJCQkJCQkJCQlGWF9CT09MIGJGaW5kID0gRkFMU0U7CgoJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOwoJCQkJCQkJCQlzTW9udGguTWFrZUxvd2VyKCk7CgoJCQkJCQkJCQlmb3IgKGludCBtID0gMDsgbSA8IDEyOyBtKyspCgkJCQkJCQkJCXsKCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nIHNGdWxsTW9udGhzID0gZnVsbG1vbnRoc1ttXTsKCQkJCQkJCQkJCXNGdWxsTW9udGhzLk1ha2VMb3dlcigpOwoKCQkJCQkJCQkJCWlmIChzRnVsbE1vbnRocy5GaW5kKHNNb250aCwgMCkgIT0gLTEpCgkJCQkJCQkJCQl7CgkJCQkJCQkJCQkJbk1vbnRoID0gbSArIDE7CgkJCQkJCQkJCQkJaSArPSA0OwoJCQkJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJCQkJYkZpbmQgPSBUUlVFOwoJCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgoJCQkJCQkJCQlpZiAoIWJGaW5kKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKCQkJCQkJCQkJCWkrPTQ7CgkJCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJZGVmYXVsdDoKCQkJCQkJCQlpICs9IDQ7CgkJCQkJCQkJaiArPSA0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCWlmIChqID49IHZhbHVlLkdldExlbmd0aCgpIHx8IGZvcm1hdC5HZXRBdChpKSAhPSB2YWx1ZS5HZXRBdChqKSkKCQkJCQkJewoJCQkJCQkJYldyb25nRm9ybWF0ID0gVFJVRTsKCQkJCQkJCWJFeGl0ID0gVFJVRTsKCQkJCQkJfQoJCQkJCQlpKys7CgkJCQkJCWorKzsKCQkJCQl9CgoJCQkJCWlmIChvbGRqID09IGopCgkJCQkJewoJCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoJCQkJCQliRXhpdCA9IFRSVUU7CgkJCQkJfQoJCQkJfQoKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWYgKHZhbHVlLkdldExlbmd0aCgpIDw9IGopCgkJCQl7CgkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJfQoJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQoJCQkJewoJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJfQoKCQkJCWkrKzsKCQkJCWorKzsKCQkJCWJyZWFrOwoJCX0KCX0KCglpZiAoYlBtKSBuSG91ciArPSAxMjsKCglpZiAoblllYXIgPj0gMCAmJiBuWWVhciA8PSBuWWVhclN1YikKCQluWWVhciArPSAyMDAwOwoKCWlmIChuTW9udGggPCAxIHx8IG5Nb250aCA+IDEyKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJaWYgKG5EYXkgPCAxIHx8IG5EYXkgPiAzMSkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuSG91ciA8IDAgfHwgbkhvdXIgPiAyNCkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuTWluIDwgMCB8fCBuTWluID4gNjApCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglpZiAoblNlYyA8IDAgfHwgblNlYyA+IDYwKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJZG91YmxlIGRSZXQgPSAwOwoKCWlmIChiV3JvbmdGb3JtYXQpCgl7CgkJZFJldCA9IFBhcnNlTm9ybWFsRGF0ZSh2YWx1ZSwgYldyb25nRm9ybWF0KTsKCX0KCWVsc2UKCXsKCQlkUmV0ID0gSlNfTWFrZURhdGUoSlNfTWFrZURheShuWWVhcixuTW9udGggLSAxLG5EYXkpLEpTX01ha2VUaW1lKG5Ib3VyLCBuTWluLCBuU2VjLCAwKSk7CgoJCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCgkJewoJCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHZhbHVlKTsKCQl9Cgl9CgoJaWYgKEpTX1BvcnRJc05hbihkUmV0KSkKCXsKCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOwoJfQoKCXJldHVybiBkUmV0OwoKfQoKQ0ZYX1dpZGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6Ok1ha2VGb3JtYXREYXRlKGRvdWJsZSBkRGF0ZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQpCnsKCUNGWF9XaWRlU3RyaW5nIHNSZXQgPSBMIiIsc1BhcnQgPSBMIiI7CgoJaW50IG5ZZWFyID0gSlNfR2V0WWVhckZyb21UaW1lKGREYXRlKTsKCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGREYXRlKSArIDE7CglpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGREYXRlKTsKCWludCBuSG91ciA9IEpTX0dldEhvdXJGcm9tVGltZShkRGF0ZSk7CglpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGREYXRlKTsKCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZERhdGUpOwoKCWludCBpID0gMDsKCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQoJewoJICAgICAgICBGWF9XQ0hBUiBjID0gZm9ybWF0LkdldEF0KGkpOwogICAgICAgICAgICAgICAgaW50IHJlbWFpbmluZyA9IGZvcm1hdC5HZXRMZW5ndGgoKSAtIGkgLSAxOwoJCXNQYXJ0ID0gTCIiOwoJCXN3aXRjaCAoYykKCQl7CgkJCWNhc2UgJ3knOgoJCQljYXNlICdtJzoKCQkJY2FzZSAnZCc6CgkJCWNhc2UgJ0gnOgoJCQljYXNlICdoJzoKCQkJY2FzZSAnTSc6CgkJCWNhc2UgJ3MnOgoJCQljYXNlICd0JzoKCQkJCWlmIChyZW1haW5pbmcgPT0gMCB8fCBmb3JtYXQuR2V0QXQoaSsxKSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdtJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTW9udGgpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5EYXkpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdoJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdNJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTWluKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdzJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuU2VjKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICd0JzoKCQkJCQkJCXNQYXJ0ICs9IG5Ib3VyPjEyPydwJzonYSc7CgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJaSsrOwoJCQkJfQoJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDEgfHwgZm9ybWF0LkdldEF0KGkrMikgIT0gYykKCQkJCXsKCQkJCQlzd2l0Y2ggKGMpCgkJCQkJewoJCQkJCQljYXNlICd5JzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5ZZWFyIC0gKG5ZZWFyIC8gMTAwKSAqIDEwMCk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuTW9udGgpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkRheSk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnSCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuSG91cik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnaCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdNJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5NaW4pOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ3MnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsblNlYyk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAndCc6CgkJCQkJCQlzUGFydCA9IG5Ib3VyPjEyPyAoRlhfTFBDV1NUUilMInBtIjogKEZYX0xQQ1dTVFIpTCJhbSI7CgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJaSs9MjsKCQkJCX0KCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAyIHx8IGZvcm1hdC5HZXRBdChpKzMpICE9IGMpCgkJCQl7CgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQlpKz0zOwoJCQkJCQkJaWYgKG5Nb250aCA+IDAmJm5Nb250aCA8PSAxMikKCQkJCQkJCQlzUGFydCArPSBtb250aHNbbk1vbnRoIC0gMV07CgkJCQkJCQlicmVhazsKCQkJCQkJZGVmYXVsdDoKCQkJCQkJCWkrPTM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMyB8fCBmb3JtYXQuR2V0QXQoaSs0KSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTA0ZCIsblllYXIpOwoJCQkJCQkJaSArPSA0OwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJaSs9NDsKCQkJCQkJCWlmIChuTW9udGggPiAwJiZuTW9udGggPD0gMTIpCgkJCQkJCQkJc1BhcnQgKz0gZnVsbG1vbnRoc1tuTW9udGggLSAxXTsKCQkJCQkJCWJyZWFrOwoJCQkJCQlkZWZhdWx0OgoJCQkJCQkJaSArPSA0OwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQlpKys7CgkJCQkJc1BhcnQgKz0gYzsKCQkJCX0KCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaSsrOwoJCQkJc1BhcnQgKz0gYzsKCQkJCWJyZWFrOwoJCX0KCgkJc1JldCArPSBzUGFydDsKCX0KCglyZXR1cm4gc1JldDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8vZnVuY3Rpb24gQUZOdW1iZXJfRm9ybWF0KG5EZWMsIHNlcFN0eWxlLCBuZWdTdHlsZSwgY3VyclN0eWxlLCBzdHJDdXJyZW5jeSwgYkN1cnJlbmN5UHJlcGVuZCkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZOdW1iZXJfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQp7CiNpZiBfRlhfT1NfICE9IF9GWF9BTkRST0lEXwoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDYpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CQoJQ0ZYX0J5dGVTdHJpbmcgc3RyVmFsdWUgPSBTdHJUcmltKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSkpOwoJCglpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsKCQoJaW50IGlEZWMgPSBwYXJhbXNbMF07CglpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOwoJaW50IGlOZWdTdHlsZSA9IHBhcmFtc1syXTsKCWludCBpY3VyclN0eWxlID0gcGFyYW1zWzNdOyAvL2l0J3Mgbm8gdXNlIQoJc3RkOjp3c3RyaW5nIHdzdHJDdXJyZW5jeShwYXJhbXNbNF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7CglGWF9CT09MIGJDdXJyZW5jeVByZXBlbmQgPSBwYXJhbXNbNV07CgkKCWlmIChpRGVjIDwgMCkgaURlYyA9IC1pRGVjOwoJCglpZiAoaVNlcFN0eWxlIDwgMCB8fCBpU2VwU3R5bGUgPiAzKQoJCWlTZXBTdHlsZSA9IDA7CgkKCWlmIChpTmVnU3R5bGUgPCAwIHx8IGlOZWdTdHlsZSA+IDMpCgkJaU5lZ1N0eWxlID0gMDsKCQoJCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCS8vZm9yIHByb2Nlc3NpbmcgZGVjaW1hbCBwbGFjZXMKCXN0clZhbHVlLlJlcGxhY2UoIiwiLCAiLiIpOwoJZG91YmxlIGRWYWx1ZSA9IGF0b2Yoc3RyVmFsdWUpOwoJaWYgKGlEZWMgPiAwKQoJCWRWYWx1ZSArPSBET1VCTEVfQ09SUkVDVDsvLwoJCSAgICAKCWludCBpRGVjMjsKCUZYX0JPT0wgYk5hZ2F0aXZlID0gRkFMU0U7CgoJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpCgl7CgkJZFZhbHVlID0gMDsKCQlzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOwoJCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpCgkJewoJCQlzdHJWYWx1ZSA9ICIwIjsKCQkJaURlYzIgPSAxOwoJCX0KCgl9CgoJaWYgKGlEZWMyIDwgMCkKCXsKCQlmb3IgKGludCBpTnVtID0gMDtpTnVtIDwgYWJzKGlEZWMyKTtpTnVtKyspCgkJewoJCQlzdHJWYWx1ZSA9ICIwIiArIHN0clZhbHVlOwoJCX0KCQlpRGVjMiA9IDA7CgkJCgl9CglpbnQgaU1heCA9IHN0clZhbHVlLkdldExlbmd0aCgpOwoJaWYgKGlEZWMyID4gaU1heCkKCXsKCQlmb3IgKGludCBpTnVtID0gMDtpTnVtIDw9IGlEZWMyIC0gaU1heCA7aU51bSsrKQoJCXsKCQkJc3RyVmFsdWUgKz0gIjAiOwoJCX0KCQlpTWF4ID0gaURlYzIrMTsJCQkKCX0KCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vZm9yIHByb2Nlc3Npbmcgc2VwZXJhdG9yIHN0eWxlCglpZiAoaURlYzIgPCBpTWF4KQoJewoJCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMSkKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJy4nKTsKCQkJaU1heCsrOwoJCX0KCQllbHNlIGlmIChpU2VwU3R5bGUgPT0gMiB8fCBpU2VwU3R5bGUgPT0gMykKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJywnKTsKCQkJaU1heCsrOwoJCX0KCQkKCQlpZiAoaURlYzIgPT0gMCkKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnMCcpOwoJfQoJaWYgKGlTZXBTdHlsZSA9PSAwIHx8IGlTZXBTdHlsZSA9PSAyKQoJewoJCWNoYXIgY1NlcGVyYXRvcjsKCQlpZiAoaVNlcFN0eWxlID09IDApCgkJCWNTZXBlcmF0b3IgPSAnLCc7CgkJZWxzZQoJCQljU2VwZXJhdG9yID0gJy4nOwoJCQoJCWludCBpRGVjUG9zaXRpdmUsaURlY05hZ2F0aXZlOwoJCWlEZWNQb3NpdGl2ZSA9IGlEZWMyOwoJCWlEZWNOYWdhdGl2ZSA9IGlEZWMyOwkJCgkJCgkJZm9yIChpRGVjUG9zaXRpdmUgPSBpRGVjMiAtMzsgaURlY1Bvc2l0aXZlID4gMDtpRGVjUG9zaXRpdmUgLT0gMykKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjUG9zaXRpdmUsIGNTZXBlcmF0b3IpOwoJCQlpTWF4Kys7CgkJfQoJfQoJCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvL2ZvciBwcm9jZXNzaW5nIGN1cnJlbmN5IHN0cmluZwoKCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJWYWx1ZSk7CgkKCXN0ZDo6d3N0cmluZyBzdHJWYWx1ZTIoVmFsdWUpOwoKCWlmIChiQ3VycmVuY3lQcmVwZW5kKQoJCXN0clZhbHVlMiA9IHdzdHJDdXJyZW5jeSArIHN0clZhbHVlMjsKCWVsc2UKCQlzdHJWYWx1ZTIgPSBzdHJWYWx1ZTIgKyB3c3RyQ3VycmVuY3k7CgkKCQoJCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgkvL2ZvciBwcm9jZXNzaW5nIG5lZ2F0aXZlIHN0eWxlCglpZiAoYk5hZ2F0aXZlKQoJewoJCWlmIChpTmVnU3R5bGUgPT0gMCkKCQl7CgkJCXN0clZhbHVlMi5pbnNlcnQoMCxMIi0iKTsKCQl9CgkJaWYgKGlOZWdTdHlsZSA9PSAyIHx8IGlOZWdTdHlsZSA9PSAzKQoJCXsKCQkJc3RyVmFsdWUyLmluc2VydCgwLEwiKCIpOwoJCQlzdHJWYWx1ZTIuaW5zZXJ0KHN0clZhbHVlMi5sZW5ndGgoKSxMIikiKTsKCQl9CgkJaWYgKGlOZWdTdHlsZSA9PSAxIHx8IGlOZWdTdHlsZSA9PSAzKQoJCXsKCQkJaWYgKEZpZWxkICogZlRhcmdldCA9IHBFdmVudC0+VGFyZ2V0X0ZpZWxkKCkpCgkJCXsKCQkJCUNKU19BcnJheSBhckNvbG9yKGlzb2xhdGUpOwoJCQkJQ0pTX1ZhbHVlIHZDb2xFbG0oaXNvbGF0ZSk7CgkJCQl2Q29sRWxtID0gTCJSR0IiOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDAsdkNvbEVsbSk7CgkJCQl2Q29sRWxtID0gMTsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgxLHZDb2xFbG0pOwoJCQkJdkNvbEVsbSA9IDA7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMix2Q29sRWxtKTsKCQkJCQoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDMsdkNvbEVsbSk7CgkJCQkKCQkJCUNKU19Qcm9wVmFsdWUgdlByb3AoaXNvbGF0ZSk7CgkJCQl2UHJvcC5TdGFydEdldHRpbmcoKTsKCQkJCXZQcm9wPDxhckNvbG9yOwoJCQkJdlByb3AuU3RhcnRTZXR0aW5nKCk7CgkJCQlmVGFyZ2V0LT50ZXh0Q29sb3IoY2MsdlByb3Asc0Vycm9yKTsvLyByZWQKCQkJfQoJCX0KCX0KCWVsc2UKCXsKCQlpZiAoaU5lZ1N0eWxlID09IDEgfHwgaU5lZ1N0eWxlID09IDMpCgkJewoJCQlpZiAoRmllbGQgKmZUYXJnZXQgPSBwRXZlbnQtPlRhcmdldF9GaWVsZCgpKQoJCQl7CgkJCQlDSlNfQXJyYXkgYXJDb2xvcihpc29sYXRlKTsKCQkJCUNKU19WYWx1ZSB2Q29sRWxtKGlzb2xhdGUpOwoJCQkJdkNvbEVsbSA9IEwiUkdCIjsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgwLHZDb2xFbG0pOwoJCQkJdkNvbEVsbSA9IDA7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMSx2Q29sRWxtKTsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgyLHZDb2xFbG0pOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDMsdkNvbEVsbSk7CgkJCQkKCQkJCUNKU19Qcm9wVmFsdWUgdlByb3AoaXNvbGF0ZSk7CgkJCQl2UHJvcC5TdGFydEdldHRpbmcoKTsKCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcCxzRXJyb3IpOwoJCQkJCgkJCQlDSlNfQXJyYXkgYVByb3AoaXNvbGF0ZSk7CgkJCQl2UHJvcC5Db252ZXJ0VG9BcnJheShhUHJvcCk7CgoJCQkJQ1BXTF9Db2xvciBjclByb3A7CgkJCQlDUFdMX0NvbG9yIGNyQ29sb3I7CgkJCQljb2xvcjo6Q29udmVydEFycmF5VG9QV0xDb2xvcihhUHJvcCwgY3JQcm9wKTsKCQkJCWNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFyQ29sb3IsIGNyQ29sb3IpOwoKCQkJCWlmIChjckNvbG9yICE9IGNyUHJvcCkKCQkJCXsKCQkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wMihpc29sYXRlKTsKCQkJCQl2UHJvcDIuU3RhcnRHZXR0aW5nKCk7CgkJCQkJdlByb3AyPDxhckNvbG9yOwoJCQkJCXZQcm9wMi5TdGFydFNldHRpbmcoKTsKICAgICAJCQkJZlRhcmdldC0+dGV4dENvbG9yKGNjLHZQcm9wMixzRXJyb3IpOwoJCQkJfQoJCQl9CgkJfQoJfQoJVmFsdWUgPSBzdHJWYWx1ZTIuY19zdHIoKTsKI2VuZGlmCglyZXR1cm4gVFJVRTsKfQoKLy9mdW5jdGlvbiBBRk51bWJlcl9LZXlzdHJva2UobkRlYywgc2VwU3R5bGUsIG5lZ1N0eWxlLCBjdXJyU3R5bGUsIHN0ckN1cnJlbmN5LCBiQ3VycmVuY3lQcmVwZW5kKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk51bWJlcl9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCQoJaWYocGFyYW1zLnNpemUoKSA8IDIpCgkJcmV0dXJuIEZBTFNFOwoJaW50IGlTZXBTdHlsZSA9IHBhcmFtc1sxXTsKCQoJaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykKCQlpU2VwU3R5bGUgPSAwOwoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcgJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7CQoJQ0ZYX1dpZGVTdHJpbmcgJiB3X3N0ckNoYW5nZSA9IHBFdmVudC0+Q2hhbmdlKCk7CiAgICBDRlhfV2lkZVN0cmluZyB3X3N0clZhbHVlID0gdmFsOwoKCWlmIChwRXZlbnQtPldpbGxDb21taXQoKSkKCXsKCQlDRlhfV2lkZVN0cmluZyB3c3RyQ2hhbmdlID0gd19zdHJDaGFuZ2U7CgkJQ0ZYX1dpZGVTdHJpbmcgd3N0clZhbHVlID0gU3RyTFRyaW0od19zdHJWYWx1ZSk7CgkJaWYgKHdzdHJWYWx1ZS5Jc0VtcHR5KCkpCgkJCXJldHVybiBUUlVFOwoJCQoJCUNGWF9XaWRlU3RyaW5nIHN3VGVtcCA9IHdzdHJWYWx1ZTsKCQlzd1RlbXAuUmVwbGFjZSgoRlhfTFBDV1NUUilMIiwiLCAoRlhfTFBDV1NUUilMIi4iKTsKCQlpZiAoIUlzTnVtYmVyKHN3VGVtcCkpIC8vIShJc051bWJlcih3c3RyQ2hhbmdlKSAmJiAKCQl7CgkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU0FGTlVNQkVSX0tFWVNUUk9LRSk7CgkJCUFsZXJ0KHBDb250ZXh0LCBzRXJyb3IpOwoJCQlyZXR1cm4gVFJVRTsKCQl9CgkJcmV0dXJuIFRSVUU7IC8vIGl0IGhhcHBlbnMgYWZ0ZXIgdGhlIGxhc3Qga2V5c3Ryb2tlIGFuZCBiZWZvcmUgdmFsaWRhdGluZywKCX0KCQoJc3RkOjp3c3RyaW5nIHdfc3RyVmFsdWUyICh3X3N0clZhbHVlKTsKCXN0ZDo6d3N0cmluZyB3X3N0ckNoYW5nZTIod19zdHJDaGFuZ2UpOwoJCglzdGQ6OndzdHJpbmcgd19zdHJTZWxlY3RlZDsKCWlmKC0xICE9IHBFdmVudC0+U2VsU3RhcnQoKSkKCQl3X3N0clNlbGVjdGVkID0gd19zdHJWYWx1ZTIuc3Vic3RyKHBFdmVudC0+U2VsU3RhcnQoKSwocEV2ZW50LT5TZWxFbmQoKSAtIHBFdmVudC0+U2VsU3RhcnQoKSkpOwoJRlhfQk9PTCBiSGFzU2lnbiA9ICh3X3N0clZhbHVlMi5maW5kKCctJykgIT0gLTEpICYmICh3X3N0clNlbGVjdGVkLmZpbmQoJy0nKSA9PSAtMSk7CglpZiAoYkhhc1NpZ24pCgl7CgkJLy9jYW4ndCBpbnNlcnQgImNoYW5nZSIgaW4gZnJvbnQgdG8gc2lnbiBwb3N0aW9uLgoJCWlmIChwRXZlbnQtPlNlbFN0YXJ0KCkgPT0gMCkKCQl7CiAgICAgICAgICAgIEZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJYlJjID0gRkFMU0U7CgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCgljaGFyIGNTZXAgPSBMJy4nOwoKCXN3aXRjaCAoaVNlcFN0eWxlKQoJewoJY2FzZSAwOgoJY2FzZSAxOgoJCWNTZXAgPSBMJy4nOwoJCWJyZWFrOwoJY2FzZSAyOgoJY2FzZSAzOgoJCWNTZXAgPSBMJywnOwoJCWJyZWFrOwoJfQoJCglGWF9CT09MIGJIYXNTZXAgPSAod19zdHJWYWx1ZTIuZmluZChjU2VwKSAhPSAtMSk7Cglmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3X3N0ckNoYW5nZTIuYmVnaW4oKTsgaXQgIT0gd19zdHJDaGFuZ2UyLmVuZCgpOyBpdCsrKQoJewoJCWlmICgqaXQgPT0gY1NlcCkKCQl7CgkJCWlmIChiSGFzU2VwKQoJCQl7CgkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCQliUmMgPSBGQUxTRTsKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJYkhhc1NlcCA9IFRSVUU7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlpZiAoKml0ID09IEwnLScpCgkJewoJCQlpZiAoYkhhc1NpZ24pCgkJCXsKCQkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJCWJSYyA9IEZBTFNFOwoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQkJZWxzZSBpZiAoaXQgIT0gd19zdHJDaGFuZ2UyLmJlZ2luKCkpIC8vc2lnbidzIHBvc2l0aW9uIGlzIG5vdCBjb3JyZWN0CgkJCXsKCQkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJCWJSYyA9IEZBTFNFOwoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQkJZWxzZSBpZiAocEV2ZW50LT5TZWxTdGFydCgpICE9IDApCgkJCXsKCQkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJCWJSYyA9IEZBTFNFOwoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQkJYkhhc1NpZ24gPSBUUlVFOwoJCQljb250aW51ZTsKCQl9CgkJCgkJaWYgKCFJc0RpZ2l0KCppdCkpCgkJewkJCQoJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCWJSYyA9IEZBTFNFOwoJCQlyZXR1cm4gVFJVRTsKCQl9Cgl9CgkKCQoJc3RkOjp3c3RyaW5nIHdfcHJlZml4ID0gd19zdHJWYWx1ZTIuc3Vic3RyKDAscEV2ZW50LT5TZWxTdGFydCgpKTsKCXN0ZDo6d3N0cmluZyB3X3Bvc3RmaXg7CglpZiAocEV2ZW50LT5TZWxFbmQoKTwoaW50KXdfc3RyVmFsdWUyLmxlbmd0aCgpKQoJCXdfcG9zdGZpeCAgPSB3X3N0clZhbHVlMi5zdWJzdHIocEV2ZW50LT5TZWxFbmQoKSk7Cgl3X3N0clZhbHVlMiA9IHdfcHJlZml4ICsgd19zdHJDaGFuZ2UyICsgd19wb3N0Zml4OwoJd19zdHJWYWx1ZSA9IHdfc3RyVmFsdWUyLmNfc3RyKCk7Cgl2YWwgPSB3X3N0clZhbHVlOwoJcmV0dXJuIFRSVUU7CQkKCQp9CgovL2Z1bmN0aW9uIEFGUGVyY2VudF9Gb3JtYXQobkRlYywgc2VwU3R5bGUpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGUGVyY2VudF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCnsKI2lmIF9GWF9PU18gIT0gX0ZYX0FORFJPSURfCglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgogICAgaWYgKHBhcmFtcy5zaXplKCkgIT0gMikKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nJiBWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsKCQovLyAgICAgSFdORCBoTWFpbkZyYW1lID0gTlVMTDsKLy8gCQovLyAJQ1BERlNES19Gb3JtRmlsbEFwcCAqcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsKLy8gCUFTU0VSVChwQXBwKTsKLy8gCWhNYWluRnJhbWUgPSBwQXBwLT5HZXRNYWluRnJhbWVXbmQoKTsKCQkKCUNGWF9CeXRlU3RyaW5nIHN0clZhbHVlID0gU3RyVHJpbShDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoVmFsdWUpKTsKCQoJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkKCQlyZXR1cm4gVFJVRTsKCQoJaW50IGlEZWMgPSBwYXJhbXNbMF07CglpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOwoJCgkvL0FTU0VSVChpRGVjID4gMCk7CglpZiAoaURlYyA8IDApCgkJaURlYyA9IC1pRGVjOwoJCglpZiAoaVNlcFN0eWxlIDwgMCB8fCBpU2VwU3R5bGUgPiAzKQoJCWlTZXBTdHlsZSA9IDA7CgkKCQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgkvL2ZvciBwcm9jZXNzaW5nIGRlY2ltYWwgcGxhY2VzCglkb3VibGUgZFZhbHVlID0gYXRvZihzdHJWYWx1ZSk7CglkVmFsdWUgKj0gMTAwOwoJaWYgKGlEZWMgPiAwKQoJCWRWYWx1ZSArPSBET1VCTEVfQ09SUkVDVDsvL9Cj1f0KCglpbnQgaURlYzI7CglGWF9CT09MIGJOYWdhdGl2ZSA9IEZBTFNFOwoJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKICAgIGlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpCgl7CgkJZFZhbHVlID0gMDsKCQlzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOwoJfQoKCWlmIChpRGVjMiA8IDApCgl7CgkJZm9yIChpbnQgaU51bSA9IDA7IGlOdW0gPCBhYnMoaURlYzIpOyBpTnVtKyspCgkJewoJCQlzdHJWYWx1ZSA9ICIwIiArIHN0clZhbHVlOwoJCX0KCQlpRGVjMiA9IDA7CgkJCgl9CglpbnQgaU1heCA9IHN0clZhbHVlLkdldExlbmd0aCgpOwoJaWYgKGlEZWMyID4gaU1heCkKCXsKCQlmb3IgKGludCBpTnVtID0gMDsgaU51bSA8PSBpRGVjMiAtIGlNYXg7IGlOdW0rKykKCQl7CgkJCXN0clZhbHVlICs9ICIwIjsKCQl9CgkJaU1heCA9IGlEZWMyKzE7CQkJCgl9CgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvL2ZvciBwcm9jZXNzaW5nIHNlcGVyYXRvciBzdHlsZQoJaWYgKGlEZWMyIDwgaU1heCkKCXsKCQlpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDEpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcuJyk7CgkJCWlNYXgrKzsKCQl9CgkJZWxzZSBpZiAoaVNlcFN0eWxlID09IDIgfHwgaVNlcFN0eWxlID09IDMpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcsJyk7CgkJCWlNYXgrKzsKCQl9CgkJCgkJaWYgKGlEZWMyID09IDApCgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJzAnKTsKCX0KCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMikKCXsKCQljaGFyIGNTZXBlcmF0b3I7CgkJaWYgKGlTZXBTdHlsZSA9PSAwKQoJCQljU2VwZXJhdG9yID0gJywnOwoJCWVsc2UKCQkJY1NlcGVyYXRvciA9ICcuJzsKCQkKCQlpbnQgaURlY1Bvc2l0aXZlLGlEZWNOYWdhdGl2ZTsKCQlpRGVjUG9zaXRpdmUgPSBpRGVjMjsKCQlpRGVjTmFnYXRpdmUgPSBpRGVjMjsKCQkJCgkJZm9yIChpRGVjUG9zaXRpdmUgPSBpRGVjMiAtMzsgaURlY1Bvc2l0aXZlID4gMDsgaURlY1Bvc2l0aXZlIC09IDMpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlY1Bvc2l0aXZlLGNTZXBlcmF0b3IpOwoJCQlpTWF4Kys7CgkJfQoJfQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCS8vbmFnYXRpdmUgbWFyawoJaWYoYk5hZ2F0aXZlKQoJCXN0clZhbHVlID0gIi0iICsgc3RyVmFsdWU7CglzdHJWYWx1ZSArPSAiJSI7CglWYWx1ZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoc3RyVmFsdWUpOwojZW5kaWYKCXJldHVybiBUUlVFOwp9Ci8vQUZQZXJjZW50X0tleXN0cm9rZShuRGVjLCBzZXBTdHlsZSkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQZXJjZW50X0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKewoJcmV0dXJuIEFGTnVtYmVyX0tleXN0cm9rZShjYyxwYXJhbXMsdlJldCxzRXJyb3IpOwp9CgovL2Z1bmN0aW9uIEFGRGF0ZV9Gb3JtYXRFeChjRm9ybWF0KQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQkKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7CgkKCUNGWF9XaWRlU3RyaW5nIHN0clZhbHVlID0gdmFsOwkKCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOwkJCgoJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoKCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7Cglkb3VibGUgZERhdGUgPSAwLjBmOwoKCWlmKHN0clZhbHVlLkZpbmQoTCJHTVQiKSAhPSAtMSkKCXsKCQkvL2ZvciBHTVQgZm9ybWF0IHRpbWUKCQkvL3N1Y2ggYXMgIlR1ZSBBdWcgMTEgMTQ6MjQ6MTYgR01UKzA4MDAyMDA5IgoJCWREYXRlID0gTWFrZUludGVyRGF0ZShzdHJWYWx1ZSk7Cgl9CgllbHNlCgl7CgkJZERhdGUgPSBNYWtlUmVndWxhckRhdGUoc3RyVmFsdWUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOwoJfQoKCWlmIChKU19Qb3J0SXNOYW4oZERhdGUpKQoJewoJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOwoJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUlNFREFURSksIChGWF9MUENXU1RSKXNGb3JtYXQpOwoJCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJCgl2YWwgPSAgTWFrZUZvcm1hdERhdGUoZERhdGUsc0Zvcm1hdCk7CgoJcmV0dXJuIFRSVUU7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6TWFrZUludGVyRGF0ZShDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSkKewoJaW50IG5Ib3VyOwoJaW50IG5NaW47CglpbnQgblNlYzsKCWludCBuWWVhcjsKCWludCBuTW9udGg7CglpbnQgbkRheTsKCglDRlhfV2lkZVN0cmluZ0FycmF5IHdzQXJyYXk7CglDRlhfV2lkZVN0cmluZyBzTW9udGggPSBMIiI7CglDRlhfV2lkZVN0cmluZyBzVGVtcCA9IEwiIjsKCWludCBuU2l6ZSA9IHN0clZhbHVlLkdldExlbmd0aCgpOwoKCWZvcihpbnQgaSA9IDA7IGkgPCBuU2l6ZTsgaSsrKQoJewoJCUZYX1dDSEFSIGMgPSBzdHJWYWx1ZS5HZXRBdChpKTsKCQlpZihjID09IEwnICcgfHwgYyA9PSBMJzonKQoJCXsJCgkJCXdzQXJyYXkuQWRkKHNUZW1wKTsKCQkJc1RlbXAgPSBMIiI7CgkJCWNvbnRpbnVlOwoJCX0KCgkJc1RlbXAgKz0gYzsKCX0KCQoJd3NBcnJheS5BZGQoc1RlbXApOwoJaWYod3NBcnJheS5HZXRTaXplKCkgIT0gOClyZXR1cm4gMDsKCglzVGVtcCA9IHdzQXJyYXlbMV07CglpZihzVGVtcC5Db21wYXJlKEwiSmFuIikgPT0gMCkgbk1vbnRoID0gMTsKCWlmKHNUZW1wLkNvbXBhcmUoTCJGZWIiKSA9PSAwKSBuTW9udGggPSAyOwoJaWYoc1RlbXAuQ29tcGFyZShMIk1hciIpID09IDApIG5Nb250aCA9IDM7CglpZihzVGVtcC5Db21wYXJlKEwiQXByIikgPT0gMCkgbk1vbnRoID0gNDsKCWlmKHNUZW1wLkNvbXBhcmUoTCJNYXkiKSA9PSAwKSBuTW9udGggPSA1OwoJaWYoc1RlbXAuQ29tcGFyZShMIkp1biIpID09IDApIG5Nb250aCA9IDY7CglpZihzVGVtcC5Db21wYXJlKEwiSnVsIikgPT0gMCkgbk1vbnRoID0gNzsKCWlmKHNUZW1wLkNvbXBhcmUoTCJBdWciKSA9PSAwKSBuTW9udGggPSA4OwoJaWYoc1RlbXAuQ29tcGFyZShMIlNlcCIpID09IDApIG5Nb250aCA9IDk7CglpZihzVGVtcC5Db21wYXJlKEwiT2N0IikgPT0gMCkgbk1vbnRoID0gMTA7CglpZihzVGVtcC5Db21wYXJlKEwiTm92IikgPT0gMCkgbk1vbnRoID0gMTE7CglpZihzVGVtcC5Db21wYXJlKEwiRGVjIikgPT0gMCkgbk1vbnRoID0gMTI7CgoJbkRheSA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzJdKTsKCW5Ib3VyID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbM10pOwoJbk1pbiA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzRdKTsKCW5TZWMgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVs1XSk7CgluWWVhciA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzddKTsKCglkb3VibGUgZFJldCA9IEpTX01ha2VEYXRlKEpTX01ha2VEYXkoblllYXIsbk1vbnRoIC0gMSxuRGF5KSxKU19NYWtlVGltZShuSG91ciwgbk1pbiwgblNlYywgMCkpOwoKCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCgl7CgkJZFJldCA9IEpTX0RhdGVQYXJzZShzdHJWYWx1ZSk7Cgl9CgkKCXJldHVybiBkUmV0Owp9CgovL0FGRGF0ZV9LZXlzdHJva2VFeChjRm9ybWF0KQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCXNFcnJvciA9IEwiQUZEYXRlX0tleXN0cm9rZUV4J3MgcGFyYW1ldGVycycgc2l6ZSByIG5vdCBjb3JyZWN0IjsKCQlyZXR1cm4gRkFMU0U7Cgl9CQoJCglpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpCgl7CgkJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJCXJldHVybiBGQUxTRTsKCQlDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsKCQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsKCgkJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoKCQlGWF9CT09MIGJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJCWRvdWJsZSBkUmV0ID0gTWFrZVJlZ3VsYXJEYXRlKHN0clZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsKCQlpZiAoYldyb25nRm9ybWF0IHx8IEpTX1BvcnRJc05hbihkUmV0KSkKCQl7CgkJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOwoJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKCQkJQWxlcnQocENvbnRleHQsIHN3TXNnKTsKCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9ICB7KEZYX0xQQ1dTVFIpTCJtL2QiLCAoRlhfTFBDV1NUUilMIm0vZC95eSIsIChGWF9MUENXU1RSKUwibW0vZGQveXkiLCAoRlhfTFBDV1NUUilMIm1tL3l5IiwgKEZYX0xQQ1dTVFIpTCJkLW1tbSIsIChGWF9MUENXU1RSKUwiZC1tbW0teXkiLCAoRlhfTFBDV1NUUilMImRkLW1tbS15eSIsCgkJKEZYX0xQQ1dTVFIpTCJ5eS1tbS1kZCIsIChGWF9MUENXU1RSKUwibW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW0gZCwgeXl5eSIsIChGWF9MUENXU1RSKUwibW1tbSBkLCB5eXl5IiwKCQkoRlhfTFBDV1NUUilMIm0vZC95eSBoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJtL2QveXkgSEg6TU0iIH07CgoJQVNTRVJUKGlJbmRleCA8IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKCglpZiAoaUluZGV4IDwgMCkKCQlpSW5kZXggPSAwOwoJaWYgKGlJbmRleCA+PSBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSkKCQlpSW5kZXggPSAwOwoJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOwoJQ0pTX1ZhbHVlIHZhbChpc29sYXRlLGNGb3JtYXRzW2lJbmRleF0pOwoJbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOwoJcmV0dXJuIEFGRGF0ZV9Gb3JtYXRFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOwp9CgovL0FGRGF0ZV9LZXlzdHJva2VFeChjRm9ybWF0KQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9ICB7KEZYX0xQQ1dTVFIpTCJtL2QiLCAoRlhfTFBDV1NUUilMIm0vZC95eSIsIChGWF9MUENXU1RSKUwibW0vZGQveXkiLCAoRlhfTFBDV1NUUilMIm1tL3l5IiwgKEZYX0xQQ1dTVFIpTCJkLW1tbSIsIChGWF9MUENXU1RSKUwiZC1tbW0teXkiLCAoRlhfTFBDV1NUUilMImRkLW1tbS15eSIsCgkJKEZYX0xQQ1dTVFIpTCJ5eS1tbS1kZCIsIChGWF9MUENXU1RSKUwibW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW0gZCwgeXl5eSIsIChGWF9MUENXU1RSKUwibW1tbSBkLCB5eXl5IiwKCQkoRlhfTFBDV1NUUilMIm0vZC95eSBoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJtL2QveXkgSEg6TU0iIH07CgoJQVNTRVJUKGlJbmRleDxzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSk7CgoJaWYgKGlJbmRleCA8IDApCgkJaUluZGV4ID0gMDsKCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCgkJaUluZGV4ID0gMDsKCUNKU19QYXJhbWV0ZXJzIG5ld1BhcmFtczsKCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsKCXJldHVybiBBRkRhdGVfS2V5c3Ryb2tlRXgoY2MsbmV3UGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKLy9mdW5jdGlvbiBBRlRpbWVfRm9ybWF0KHB0ZikKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9IHsoRlhfTFBDV1NUUilMIkhIOk1NIiwgKEZYX0xQQ1dTVFIpTCJoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJISDpNTTpzcyIsIChGWF9MUENXU1RSKUwiaDpNTTpzcyB0dCJ9OwoKCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOwoKCWlmIChpSW5kZXggPCAwKQoJCWlJbmRleCA9IDA7CglpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQoJCWlJbmRleCA9IDA7CglDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7CglDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7CgluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CglyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9IHsoRlhfTFBDV1NUUilMIkhIOk1NIiwgKEZYX0xQQ1dTVFIpTCJoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJISDpNTTpzcyIsIChGWF9MUENXU1RSKUwiaDpNTTpzcyB0dCJ9OwoKCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOwoKCWlmIChpSW5kZXggPCAwKQoJCWlJbmRleCA9IDA7CglpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQoJCWlJbmRleCA9IDA7CglDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7CglDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7CgluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CglyZXR1cm4gQUZEYXRlX0tleXN0cm9rZUV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9Gb3JtYXRFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJcmV0dXJuIEFGRGF0ZV9Gb3JtYXRFeChjYyxwYXJhbXMsdlJldCxzRXJyb3IpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXJldHVybiBBRkRhdGVfS2V5c3Ryb2tlRXgoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKLy9mdW5jdGlvbiBBRlNwZWNpYWxfRm9ybWF0KHBzZikKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglzdGQ6OnN0cmluZyBjRm9ybWF0OwoJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKCglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nJiBWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsJCglzdGQ6OnN0cmluZyBzdHJTcmMgPSAoRlhfTFBDU1RSKUNGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSk7CgkKCXN3aXRjaCAoaUluZGV4KSAKCXsKCWNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgCgkJY0Zvcm1hdCA9ICI5OTk5OSI7CgkJYnJlYWs7CgljYXNlIDE6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCWNGb3JtYXQgPSAiOTk5OTktOTk5OSI7CgkJYnJlYWs7CgljYXNlIDI6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCXsKCQkJc3RkOjpzdHJpbmcgTnVtYmVyU3RyOwoJCQl1dGlsOjpwcmludHgoIjk5OTk5OTk5OTkiLCBzdHJTcmMsTnVtYmVyU3RyKTsgCgkJCWlmIChOdW1iZXJTdHIubGVuZ3RoKCkgPj0gMTAgKQoJCQkJY0Zvcm1hdCA9ICIoOTk5KSA5OTktOTk5OSI7CgkJCWVsc2UgCgkJCQljRm9ybWF0ID0gIjk5OS05OTk5IjsKCQkJYnJlYWs7CgkJfQoJY2FzZSAzOgoJCWNGb3JtYXQgPSAiOTk5LTk5LTk5OTkiOwoJCWJyZWFrOwoJfQoJCglzdGQ6OnN0cmluZyBzdHJEZXM7Cgl1dGlsOjpwcmludHgoY0Zvcm1hdCxzdHJTcmMsc3RyRGVzKTsKCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJEZXMuY19zdHIoKSk7CglyZXR1cm4gVFJVRTsKfQoKCi8vZnVuY3Rpb24gQUZTcGVjaWFsX0tleXN0cm9rZUV4KG1hc2spCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU3BlY2lhbF9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CgoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSA8IDEpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcmIHZhbEV2ZW50ID0gcEV2ZW50LT5WYWx1ZSgpOwoKCUNGWF9XaWRlU3RyaW5nIHdzdHJNYXNrID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CglpZiAod3N0ck1hc2suSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsKCQoJc3RkOjp3c3RyaW5nIHdzdHJWYWx1ZSh2YWxFdmVudCk7CgkKCWlmIChwRXZlbnQtPldpbGxDb21taXQoKSkKCXsKCQlpZiAod3N0clZhbHVlLmVtcHR5KCkpCgkJCXJldHVybiBUUlVFOwoJCWludCBpSW5kZXhNYXNrID0gMDsKCQlmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3c3RyVmFsdWUuYmVnaW4oKTsgaXQgIT0gd3N0clZhbHVlLmVuZCgpOyBpdCsrKQoJCXsKCQkJd2NoYXJfdCB3X1ZhbHVlID0gKml0OwogICAgICAgICAgICBpZiAoIW1hc2tTYXRpc2ZpZWQod19WYWx1ZSx3c3RyTWFza1tpSW5kZXhNYXNrXSkpCgkJCQlicmVhazsKCQkJaUluZGV4TWFzaysrOwoJCX0KCgkJaWYgKGlJbmRleE1hc2sgIT0gd3N0ck1hc2suR2V0TGVuZ3RoKCkgfHwgKGlJbmRleE1hc2sgIT0gd3N0clZhbHVlLnNpemUoKSAmJiB3c3RyTWFzay5HZXRMZW5ndGgoKSAhPSAwKSkKCQl7CgkJCUFsZXJ0KHBDb250ZXh0LCBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU0FGTlVNQkVSX0tFWVNUUk9LRSkpOwoJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQl9CgkJcmV0dXJuIFRSVUU7Cgl9CgoJCglDRlhfV2lkZVN0cmluZyAmd2lkZUNoYW5nZSA9IHBFdmVudC0+Q2hhbmdlKCk7CglzdGQ6OndzdHJpbmcgd0NoYW5nZSh3aWRlQ2hhbmdlKTsKCQoJaWYgKHdDaGFuZ2UuZW1wdHkoKSkKCQlyZXR1cm4gVFJVRTsKICAgIGludCBpSW5kZXhNYXNrID0gcEV2ZW50LT5TZWxTdGFydCgpOwoJLy9pSW5kZXhNYXNrKys7CgkKCQoJaWYgKHdzdHJWYWx1ZS5sZW5ndGgoKSAtIChwRXZlbnQtPlNlbEVuZCgpLXBFdmVudC0+U2VsU3RhcnQoKSkgKyB3Q2hhbmdlLmxlbmd0aCgpID4gKEZYX0RXT1JEKXdzdHJNYXNrLkdldExlbmd0aCgpKQoJewoJCUFsZXJ0KHBDb250ZXh0LCBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNX1RPT0xPTkcpKTsKCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQlyZXR1cm4gVFJVRTsKCX0KCQoJCglpZiAoaUluZGV4TWFzayA+PSB3c3RyTWFzay5HZXRMZW5ndGgoKSAmJiAoIXdDaGFuZ2UuZW1wdHkoKSkpCgl7CgkJQWxlcnQocENvbnRleHQsIEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1fVE9PTE9ORykpOwoJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCXJldHVybiBUUlVFOwoJfQoJCglmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3Q2hhbmdlLmJlZ2luKCk7IGl0ICE9IHdDaGFuZ2UuZW5kKCk7IGl0KyspCgl7CgkJaWYgKGlJbmRleE1hc2sgPj0gd3N0ck1hc2suR2V0TGVuZ3RoKCkpCgkJewoJCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7CgkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCQlyZXR1cm4gVFJVRTsKCQl9CgkJd2NoYXJfdCB3X01hc2sgPSB3c3RyTWFza1tpSW5kZXhNYXNrXTsKCQlpZiAoIWlzUmVzZXJ2ZWRNYXNrQ2hhcih3X01hc2spKQoJCXsKCQkJLy93Q2hhbmdlLmluc2VydChpdCx3X01hc2spOwkJCQkKCQkJKml0ID0gd19NYXNrOwoJCX0KCQl3Y2hhcl90IHdfQ2hhbmdlID0gKml0OwoJCQogICAgICAgIGlmICghbWFza1NhdGlzZmllZCh3X0NoYW5nZSx3X01hc2spKQoJCXsKCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJCXJldHVybiBUUlVFOwoJCX0KCQlpSW5kZXhNYXNrKys7Cgl9CgkKCXdpZGVDaGFuZ2UgPSB3Q2hhbmdlLmNfc3RyKCk7CQoJCglyZXR1cm4gVFJVRTsKfQoKCi8vZnVuY3Rpb24gQUZTcGVjaWFsX0tleXN0cm9rZShwc2YpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU3BlY2lhbF9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglzdGQ6OnN0cmluZyBjRm9ybWF0OwoJaW50IGlJbmRleCA9IChpbnQpcGFyYW1zWzBdOwkKCglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CgkvL0NKU19WYWx1ZSB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7CglDRlhfV2lkZVN0cmluZyYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOwoJc3RkOjpzdHJpbmcgc3RyU3JjID0gKEZYX0xQQ1NUUilDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUodmFsKTsKCXN0ZDo6d3N0cmluZyB3c3RyQ2hhbmdlKHBFdmVudC0+Q2hhbmdlKCkpOwoJCglzd2l0Y2ggKGlJbmRleCkgCgl7CgljYXNlIDA6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCWNGb3JtYXQgPSAiOTk5OTkiOwoJCWJyZWFrOwoJY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQkvL2NGb3JtYXQgPSAiOTk5OTktOTk5OSI7CgkJY0Zvcm1hdCA9ICI5OTk5OTk5OTkiOwoJCWJyZWFrOwoJY2FzZSAyOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQl7CgkJCXN0ZDo6c3RyaW5nIE51bWJlclN0cjsKCQkJdXRpbDo6cHJpbnR4KCI5OTk5OTk5OTk5Iiwgc3RyU3JjLE51bWJlclN0cik7IAoJCQlpZiAoc3RyU3JjLmxlbmd0aCgpICsgd3N0ckNoYW5nZS5sZW5ndGgoKSA+IDcgKQoJCQkJLy9jRm9ybWF0ID0gIig5OTkpIDk5OS05OTk5IjsKCQkJCWNGb3JtYXQgPSAiOTk5OTk5OTk5OSI7CgkJCWVsc2UgCgkJCQkvL2NGb3JtYXQgPSAiOTk5LTk5OTkiOwoJCQkJY0Zvcm1hdCA9ICI5OTk5OTk5IjsKCQkJYnJlYWs7CgkJfQoJY2FzZSAzOgoJCS8vY0Zvcm1hdCA9ICI5OTktOTktOTk5OSI7CgkJY0Zvcm1hdCA9ICI5OTk5OTk5OTkiOwoJCWJyZWFrOwoJfQogICAgCglDSlNfUGFyYW1ldGVycyBwYXJhbXMyOwoJQ0pTX1ZhbHVlIHZNYXNrKGlzb2xhdGUsIGNGb3JtYXQuY19zdHIoKSk7CglwYXJhbXMyLnB1c2hfYmFjayh2TWFzayk7CgkKICAgIHJldHVybiBBRlNwZWNpYWxfS2V5c3Ryb2tlRXgoY2MscGFyYW1zMix2UmV0LHNFcnJvcik7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTWVyZ2VDaGFuZ2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50SGFuZGxlciA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnRIYW5kbGVyICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZTsKCWlmIChwRXZlbnRIYW5kbGVyLT5tX3BWYWx1ZSAhPSBOVUxMKQoJCXN3VmFsdWUgPSBwRXZlbnRIYW5kbGVyLT5WYWx1ZSgpOwoKCWlmIChwRXZlbnRIYW5kbGVyLT5XaWxsQ29tbWl0KCkpCgl7CgkJdlJldCA9IHN3VmFsdWU7CgkJcmV0dXJuIFRSVUU7Cgl9CgoJQ0ZYX1dpZGVTdHJpbmcgcHJlZml4LHBvc3RmaXg7CgoJaWYgKHBFdmVudEhhbmRsZXItPlNlbFN0YXJ0KCkgPj0gMCkKCQlwcmVmaXggPSBzd1ZhbHVlLk1pZCgwLHBFdmVudEhhbmRsZXItPlNlbFN0YXJ0KCkpOwoJZWxzZQoJCXByZWZpeCA9IEwiIjsKCgoJaWYgKHBFdmVudEhhbmRsZXItPlNlbEVuZCgpID49IDAgJiYgcEV2ZW50SGFuZGxlci0+U2VsRW5kKCkgPD0gc3dWYWx1ZS5HZXRMZW5ndGgoKSkKCQlwb3N0Zml4ID0gc3dWYWx1ZS5NaWQocEV2ZW50SGFuZGxlci0+U2VsRW5kKCksIHN3VmFsdWUuR2V0TGVuZ3RoKCkgLSBwRXZlbnRIYW5kbGVyLT5TZWxFbmQoKSk7CgllbHNlIHBvc3RmaXggPSBMIiI7CgoJdlJldCA9IHByZWZpeCArIHBFdmVudEhhbmRsZXItPkNoYW5nZSgpICsgcG9zdGZpeDsKCglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQYXJzZURhdGVFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMikKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCUNGWF9XaWRlU3RyaW5nIHNGb3JtYXQgPSBwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCglGWF9CT09MIGJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJZG91YmxlIGREYXRlID0gTWFrZVJlZ3VsYXJEYXRlKHNWYWx1ZSxzRm9ybWF0LGJXcm9uZ0Zvcm1hdCk7CgoJaWYgKEpTX1BvcnRJc05hbihkRGF0ZSkpCgl7CgkJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7CgkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSU0VEQVRFKSwgKEZYX0xQQ1dTVFIpc0Zvcm1hdCk7CgkJQWxlcnQoKENKU19Db250ZXh0ICopY2MsIHN3TXNnKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgkKCXZSZXQgPSBkRGF0ZTsKCglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTaW1wbGUoT0JKX01FVEhPRF9QQVJBTVMpCnsKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDMpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCgl2UmV0ID0gKGRvdWJsZSlBRl9TaW1wbGUocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCksIChkb3VibGUpcGFyYW1zWzFdLCAoZG91YmxlKXBhcmFtc1syXSk7CglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZNYWtlTnVtYmVyKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CiAgICB2UmV0ID0gUGFyc2VTdHJpbmdUb051bWJlcihwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7CglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTaW1wbGVfQ2FsY3VsYXRlKE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CgoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMikKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglDSlNfVmFsdWUgcGFyYW1zMSA9IHBhcmFtc1sxXTsKCglpZiAoIXBhcmFtczEuSXNBcnJheU9iamVjdCgpICYmIHBhcmFtczEuR2V0VHlwZSgpICE9IFZUX3N0cmluZykKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCQoJQ1BERlNES19Eb2N1bWVudCogcFJlYWRlckRvYyA9IHBDb250ZXh0LT5HZXRSZWFkZXJEb2N1bWVudCgpOwogICAgQVNTRVJUKHBSZWFkZXJEb2MgIT0gTlVMTCk7CgoJQ1BERlNES19JbnRlckZvcm0qIHBSZWFkZXJJbnRlckZvcm0gPSBwUmVhZGVyRG9jLT5HZXRJbnRlckZvcm0oKTsKCUFTU0VSVChwUmVhZGVySW50ZXJGb3JtICE9IE5VTEwpOwoKCUNQREZfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gcFJlYWRlckludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7CglBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKCglkb3VibGUgZFZhbHVlOwoJQ0ZYX1dpZGVTdHJpbmcgc0Z1bmN0aW9uID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CglpZiAod2NzY21wKHNGdW5jdGlvbiwgTCJQUkQiKSA9PSAwKQogICAgCWRWYWx1ZSA9IDEuMDsKCWVsc2UKCQlkVmFsdWUgPSAwLjA7CgoJQ0pTX0FycmF5IEZpZWxkTmFtZUFycmF5ID0gQUZfTWFrZUFycmF5RnJvbUxpc3QoaXNvbGF0ZSxwYXJhbXMxKTsKCglpbnQgbkZpZWxkc0NvdW50ID0gMDsKCglmb3IgKGludCBpPTAsaXN6PUZpZWxkTmFtZUFycmF5LkdldExlbmd0aCgpOyBpPGlzejsgaSsrKQoJewoJCUNKU19WYWx1ZSBqc1ZhbHVlKGlzb2xhdGUpOwoJCUZpZWxkTmFtZUFycmF5LkdldEVsZW1lbnQoaSxqc1ZhbHVlKTsKICAgICAgICBDRlhfV2lkZVN0cmluZyB3c0ZpZWxkTmFtZSA9IGpzVmFsdWUub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCiAgICAgICAgZm9yIChpbnQgaj0wLGpzej1wSW50ZXJGb3JtLT5Db3VudEZpZWxkcyh3c0ZpZWxkTmFtZSk7IGo8anN6OyBqKyspCgkJewoJCQlpZiAoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBwSW50ZXJGb3JtLT5HZXRGaWVsZChqLCB3c0ZpZWxkTmFtZSkpCgkJCXsKCQkJCWRvdWJsZSBkVGVtcCA9IDAuMDsKCgkJCQlzd2l0Y2ggKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpKQoJCQkJewoJCQkJY2FzZSBGSUVMRFRZUEVfVEVYVEZJRUxEOgoJCQkJY2FzZSBGSUVMRFRZUEVfQ09NQk9CT1g6CgkJCQkJewoJCQkJCQlkVGVtcCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046CgkJCQkJewoJCQkJCQlkVGVtcCA9IDAuMDsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6CgkJCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoKCQkJCQl7CgkJCQkJCWRUZW1wID0gMC4wOwoJCQkJCQlmb3IgKGludCBjPTAsY3N6PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgYzxjc3o7IGMrKykKCQkJCQkJewoJCQkJCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woYykpCgkJCQkJCQl7CgkJCQkJCQkJaWYgKHBGb3JtQ3RybC0+SXNDaGVja2VkKCkpCgkJCQkJCQkJewoJCQkJCQkJCQlkVGVtcCArPSBQYXJzZVN0cmluZ1RvTnVtYmVyKHBGb3JtQ3RybC0+R2V0RXhwb3J0VmFsdWUoKSk7CgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCX0KCQkJCQkJCQllbHNlCgkJCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCWNhc2UgRklFTERUWVBFX0xJU1RCT1g6CgkJCQkJewoJCQkJCQlkVGVtcCA9IDAuMDsKCQkJCQkJaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID4gMSkKCQkJCQkJCWJyZWFrOwoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCWRUZW1wID0gUGFyc2VTdHJpbmdUb051bWJlcihwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJZGVmYXVsdDoKCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoaSA9PSAwICYmIGogPT0gMCAmJiAod2NzY21wKHNGdW5jdGlvbixMIk1JTiIpID09IDAgfHwgd2NzY21wKHNGdW5jdGlvbiwgTCJNQVgiKSA9PSAwKSkKCQkJCQlkVmFsdWUgPSBkVGVtcDsKCgkJCQlkVmFsdWUgPSBBRl9TaW1wbGUoc0Z1bmN0aW9uLCBkVmFsdWUsIGRUZW1wKTsKCgkJCQluRmllbGRzQ291bnQrKzsKCQkJfQoJCX0KCX0KCglpZiAod2NzY21wKHNGdW5jdGlvbiwgTCJBVkciKSA9PSAwICYmIG5GaWVsZHNDb3VudCA+IDApCgkJZFZhbHVlIC89IG5GaWVsZHNDb3VudDsKCglkVmFsdWUgPSAoZG91YmxlKWZsb29yKGRWYWx1ZSAqIEZYU1lTX3BvdygoZG91YmxlKTEwLChkb3VibGUpNikgKyAwLjQ5KSAvIEZYU1lTX3BvdygoZG91YmxlKTEwLChkb3VibGUpNik7CglDSlNfVmFsdWUganNWYWx1ZShpc29sYXRlLGRWYWx1ZSk7CglpZigoQ0pTX0V2ZW50SGFuZGxlciopcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpLT5tX3BWYWx1ZSkKCQkoKENKU19FdmVudEhhbmRsZXIqKXBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKSktPlZhbHVlKCkgPSBqc1ZhbHVlOwoKCXJldHVybiBUUlVFOwp9CgovKiBUaGlzIGZ1bmN0aW9uIHZhbGlkYXRlcyB0aGUgY3VycmVudCBldmVudCB0byBlbnN1cmUgdGhhdCBpdHMgdmFsdWUgaXMgCioqIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHJhbmdlLiAqLwoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZSYW5nZV9WYWxpZGF0ZShPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDQpIAoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCWlmIChwRXZlbnQtPlZhbHVlKCkuSXNFbXB0eSgpICkKCQlyZXR1cm4gVFJVRTsKCWRvdWJsZSBkRWVudFZhbHVlID0gYXRvZihDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUocEV2ZW50LT5WYWx1ZSgpKSk7CglGWF9CT09MIGJHcmVhdGVyVGhhbiwgYkxlc3NUaGFuOwoJZG91YmxlICBkR3JlYXRlclRoYW4sIGRMZXNzVGhhbjsKICAgIGJHcmVhdGVyVGhhbiA9IChGWF9CT09MKXBhcmFtc1swXTsKCUNGWF9XaWRlU3RyaW5nIHN3TXNnOwoJZEdyZWF0ZXJUaGFuID0gKGRvdWJsZSlwYXJhbXNbMV07CgliTGVzc1RoYW4gPSAoRlhfQk9PTClwYXJhbXNbMl07CglkTGVzc1RoYW4gPSAoZG91YmxlKXBhcmFtc1szXTsKCglpZiAoYkdyZWF0ZXJUaGFuICYmIGJMZXNzVGhhbikKCXsKCQlpZiAoZEVlbnRWYWx1ZSA8IGRHcmVhdGVyVGhhbiB8fCBkRWVudFZhbHVlID4gZExlc3NUaGFuKQoJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTEpLChGWF9MUENXU1RSKXBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpLCAoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7Cgl9CgllbHNlIGlmIChiR3JlYXRlclRoYW4pCgl7CgkJaWYgKGRFZW50VmFsdWUgPCBkR3JlYXRlclRoYW4pCgkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1JBTkdFMiksIChGWF9MUENXU1RSKXBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKCX0KCWVsc2UgaWYgKGJMZXNzVGhhbikKCXsKCQlpZiAoZEVlbnRWYWx1ZSA+IGRMZXNzVGhhbikKCQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUkFOR0UzKSwgKEZYX0xQQ1dTVFIpcGFyYW1zWzNdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOwoJfQoKCWlmICghc3dNc2cuSXNFbXB0eSgpKQoJewoJCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7CgkJcEV2ZW50LT5SYygpID0gRkFMU0U7Cgl9CglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZFeHRyYWN0TnVtcyhPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKSAKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglDSlNfQXJyYXkgbnVtcyhpc29sYXRlKTsKCglDRlhfV2lkZVN0cmluZyBzdHIgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCUNGWF9XaWRlU3RyaW5nIHNQYXJ0OwoKCWlmIChzdHIuR2V0QXQoMCkgPT0gTCcuJyB8fCBzdHIuR2V0QXQoMCkgPT0gTCcsJykKCQlzdHIgPSBMIjAiICsgc3RyOwoKCWludCBuSW5kZXggPSAwOwoJZm9yIChpbnQgaT0wLCBzej1zdHIuR2V0TGVuZ3RoKCk7IGk8c3o7IGkrKykKCXsKCQlGWF9XQ0hBUiB3YyA9IHN0ci5HZXRBdChpKTsKCQlpZiAoSXNEaWdpdCgod2NoYXJfdCl3YykpCgkJewoJCQlzUGFydCArPSB3YzsKCQl9CgkJZWxzZQoJCXsKCQkJaWYgKHNQYXJ0LkdldExlbmd0aCgpID4gMCkKCQkJewoJCQkJbnVtcy5TZXRFbGVtZW50KG5JbmRleCxDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDV1NUUilzUGFydCkpOwoJCQkJc1BhcnQgPSBMIiI7CgkJCQluSW5kZXggKys7CgkJCX0KCQl9Cgl9CgoJaWYgKHNQYXJ0LkdldExlbmd0aCgpID4gMCkKCXsKCQludW1zLlNldEVsZW1lbnQobkluZGV4LENKU19WYWx1ZShpc29sYXRlLChGWF9MUENXU1RSKXNQYXJ0KSk7CQoJfQoKCWlmIChudW1zLkdldExlbmd0aCgpID4gMCkKCQl2UmV0ID0gbnVtczsKCWVsc2UKCQl2UmV0LlNldE51bGwoKTsKCglyZXR1cm4gVFJVRTsKfQo=