LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY21hdGNoLmMsdiAxLjIwIDIwMDIvMDgvMzEgMjI6MTc6MzIga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJmY2ludC5oIgojaW5jbHVkZSA8c3RkaW8uaD4KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlSW50ZWdlciAoY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlMSwgRmNWYWx1ZSB2YWx1ZTIpCnsKICAgIGludAl2OwogICAgCiAgICBpZiAodmFsdWUyLnR5cGUgIT0gRmNUeXBlSW50ZWdlciB8fCB2YWx1ZTEudHlwZSAhPSBGY1R5cGVJbnRlZ2VyKQoJcmV0dXJuIC0xLjA7CiAgICB2ID0gdmFsdWUyLnUuaSAtIHZhbHVlMS51Lmk7CiAgICBpZiAodiA8IDApCgl2ID0gLXY7CiAgICByZXR1cm4gKGRvdWJsZSkgdjsKfQoKc3RhdGljIGRvdWJsZQpGY0NvbXBhcmVTdHJpbmcgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKQp7CiAgICBpZiAodmFsdWUyLnR5cGUgIT0gRmNUeXBlU3RyaW5nIHx8IHZhbHVlMS50eXBlICE9IEZjVHlwZVN0cmluZykKCXJldHVybiAtMS4wOwogICAgcmV0dXJuIChkb3VibGUpIEZjU3RyQ21wSWdub3JlQ2FzZSAodmFsdWUxLnUucywgdmFsdWUyLnUucykgIT0gMDsKfQoKc3RhdGljIGRvdWJsZQpGY0NvbXBhcmVGYW1pbHkgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKQp7CiAgICBpZiAodmFsdWUyLnR5cGUgIT0gRmNUeXBlU3RyaW5nIHx8IHZhbHVlMS50eXBlICE9IEZjVHlwZVN0cmluZykKCXJldHVybiAtMS4wOwogICAgcmV0dXJuIChkb3VibGUpIEZjU3RyQ21wSWdub3JlQmxhbmtzQW5kQ2FzZSAodmFsdWUxLnUucywgdmFsdWUyLnUucykgIT0gMDsKfQoKc3RhdGljIGRvdWJsZQpGY0NvbXBhcmVMYW5nIChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgRmNMYW5nUmVzdWx0ICAgIHJlc3VsdDsKICAgIAogICAgc3dpdGNoICh2YWx1ZTEudHlwZSkgewogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJc3dpdGNoICh2YWx1ZTIudHlwZSkgewoJY2FzZSBGY1R5cGVMYW5nU2V0OgoJICAgIHJlc3VsdCA9IEZjTGFuZ1NldENvbXBhcmUgKHZhbHVlMS51LmwsIHZhbHVlMi51LmwpOwoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVTdHJpbmc6CgkgICAgcmVzdWx0ID0gRmNMYW5nU2V0SGFzTGFuZyAodmFsdWUxLnUubCwgdmFsdWUyLnUucyk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldHVybiAtMS4wOwoJfQoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXN3aXRjaCAodmFsdWUyLnR5cGUpIHsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICByZXN1bHQgPSBGY0xhbmdTZXRIYXNMYW5nICh2YWx1ZTIudS5sLCB2YWx1ZTEudS5zKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlU3RyaW5nOgoJICAgIHJlc3VsdCA9IEZjTGFuZ0NvbXBhcmUgKHZhbHVlMS51LnMsIHZhbHVlMi51LnMpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gLTEuMDsKCX0KCWJyZWFrOwogICAgZGVmYXVsdDoKCXJldHVybiAtMS4wOwogICAgfQogICAgc3dpdGNoIChyZXN1bHQpIHsKICAgIGNhc2UgRmNMYW5nRXF1YWw6CglyZXR1cm4gMDsKICAgIGNhc2UgRmNMYW5nRGlmZmVyZW50Q291bnRyeToKCXJldHVybiAxOwogICAgY2FzZSBGY0xhbmdEaWZmZXJlbnRMYW5nOgogICAgZGVmYXVsdDoKCXJldHVybiAyOwogICAgfQp9CgpzdGF0aWMgZG91YmxlCkZjQ29tcGFyZUJvb2wgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKQp7CiAgICBpZiAodmFsdWUyLnR5cGUgIT0gRmNUeXBlQm9vbCB8fCB2YWx1ZTEudHlwZSAhPSBGY1R5cGVCb29sKQoJcmV0dXJuIC0xLjA7CiAgICByZXR1cm4gKGRvdWJsZSkgdmFsdWUyLnUuYiAhPSB2YWx1ZTEudS5iOwp9CgpzdGF0aWMgZG91YmxlCkZjQ29tcGFyZUNoYXJTZXQgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKQp7CiAgICBpZiAodmFsdWUyLnR5cGUgIT0gRmNUeXBlQ2hhclNldCB8fCB2YWx1ZTEudHlwZSAhPSBGY1R5cGVDaGFyU2V0KQoJcmV0dXJuIC0xLjA7CiAgICByZXR1cm4gKGRvdWJsZSkgRmNDaGFyU2V0U3VidHJhY3RDb3VudCAodmFsdWUxLnUuYywgdmFsdWUyLnUuYyk7Cn0KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlU2l6ZSAoY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlMSwgRmNWYWx1ZSB2YWx1ZTIpCnsKICAgIGRvdWJsZSAgdjEsIHYyLCB2OwoKICAgIHN3aXRjaCAodmFsdWUxLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXYxID0gdmFsdWUxLnUuaTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVEb3VibGU6Cgl2MSA9IHZhbHVlMS51LmQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTE7CiAgICB9CiAgICBzd2l0Y2ggKHZhbHVlMi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6Cgl2MiA9IHZhbHVlMi51Lmk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJdjIgPSB2YWx1ZTIudS5kOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIC0xOwogICAgfQogICAgaWYgKHYyID09IDApCglyZXR1cm4gMDsKICAgIHYgPSB2MiAtIHYxOwogICAgaWYgKHYgPCAwKQoJdiA9IC12OwogICAgcmV0dXJuIHY7Cn0KCnR5cGVkZWYgc3RydWN0IF9GY01hdGNoZXIgewogICAgY2hhcgkgICAgKm9iamVjdDsKICAgIGRvdWJsZQkgICAgKCpjb21wYXJlKSAoY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlMSwgRmNWYWx1ZSB2YWx1ZTIpOwogICAgaW50CQkgICAgc3Ryb25nLCB3ZWFrOwp9IEZjTWF0Y2hlcjsKCi8qCiAqIE9yZGVyIGlzIHNpZ25pZmljYW50LCBpdCBkZWZpbmVzIHRoZSBwcmVjZWRlbmNlIG9mCiAqIGVhY2ggdmFsdWUsIGVhcmxpZXIgdmFsdWVzIGFyZSBtb3JlIHNpZ25pZmljYW50IHRoYW4KICogbGF0ZXIgdmFsdWVzCiAqLwpzdGF0aWMgRmNNYXRjaGVyIF9GY01hdGNoZXJzIFtdID0gewogICAgeyBGQ19GT1VORFJZLAlGY0NvbXBhcmVTdHJpbmcsCTAsIDAgfSwKI2RlZmluZSBNQVRDSF9GT1VORFJZCSAgICAwCiAgICAKICAgIHsgRkNfQ0hBUlNFVCwJRmNDb21wYXJlQ2hhclNldCwJMSwgMSB9LAojZGVmaW5lIE1BVENIX0NIQVJTRVQJICAgIDEKICAgIAogICAgeyBGQ19GQU1JTFksICAgIAlGY0NvbXBhcmVGYW1pbHksCTIsIDQgfSwKI2RlZmluZSBNQVRDSF9GQU1JTFkJICAgIDIKICAgIAogICAgeyBGQ19MQU5HLAkJRmNDb21wYXJlTGFuZywJCTMsIDMgfSwKI2RlZmluZSBNQVRDSF9MQU5HCSAgICAzCiAgICAKICAgIHsgRkNfU1BBQ0lORywJRmNDb21wYXJlSW50ZWdlciwJNSwgNSB9LAojZGVmaW5lIE1BVENIX1NQQUNJTkcJICAgIDQKICAgIAogICAgeyBGQ19QSVhFTF9TSVpFLAlGY0NvbXBhcmVTaXplLAkJNiwgNiB9LAojZGVmaW5lIE1BVENIX1BJWEVMX1NJWkUgICAgNQogICAgCiAgICB7IEZDX1NUWUxFLAkJRmNDb21wYXJlU3RyaW5nLAk3LCA3IH0sCiNkZWZpbmUgTUFUQ0hfU1RZTEUJICAgIDYKICAgIAogICAgeyBGQ19TTEFOVCwJCUZjQ29tcGFyZUludGVnZXIsCTgsIDggfSwKI2RlZmluZSBNQVRDSF9TTEFOVAkgICAgNwogICAgCiAgICB7IEZDX1dFSUdIVCwJRmNDb21wYXJlSW50ZWdlciwJOSwgOSB9LAojZGVmaW5lIE1BVENIX1dFSUdIVAkgICAgOAogICAgCiAgICB7IEZDX0FOVElBTElBUywJRmNDb21wYXJlQm9vbCwJCTEwLCAxMCB9LAojZGVmaW5lIE1BVENIX0FOVElBTElBUwkgICAgOQogICAgCiAgICB7IEZDX1JBU1RFUklaRVIsCUZjQ29tcGFyZVN0cmluZywJMTEsIDExIH0sCiNkZWZpbmUgTUFUQ0hfUkFTVEVSSVpFUiAgICAxMAogICAgCiAgICB7IEZDX09VVExJTkUsCUZjQ29tcGFyZUJvb2wsCQkxMiwgMTIgfSwKI2RlZmluZSBNQVRDSF9PVVRMSU5FCSAgICAxMQoKICAgIHsgRkNfRk9OVFZFUlNJT04sCUZjQ29tcGFyZUludGVnZXIsCTEzLCAxMyB9LAojZGVmaW5lIE1BVENIX0ZPTlRWRVJTSU9OICAgMTIKfTsKCiNkZWZpbmUgTlVNX01BVENIX1ZBTFVFUyAgICAxNAoKc3RhdGljIEZjQm9vbApGY0NvbXBhcmVWYWx1ZUxpc3QgKGNvbnN0IGNoYXIgICpvYmplY3QsCgkJICAgIEZjVmFsdWVMaXN0CSp2MW9yaWcsCS8qIHBhdHRlcm4gKi8KCQkgICAgRmNWYWx1ZUxpc3QgKnYyb3JpZywJLyogdGFyZ2V0ICovCgkJICAgIEZjVmFsdWUJKmJlc3RWYWx1ZSwKCQkgICAgZG91YmxlCSp2YWx1ZSwKCQkgICAgRmNSZXN1bHQJKnJlc3VsdCkKewogICAgRmNWYWx1ZUxpc3QgICAgKnYxLCAqdjI7CiAgICBkb3VibGUgICAgCSAgICB2LCBiZXN0LCBiZXN0U3Ryb25nLCBiZXN0V2VhazsKICAgIGludAkJICAgIGk7CiAgICBpbnQJCSAgICBqOwogICAgCiAgICAvKgogICAgICogTG9jYXRlIHRoZSBwb3NzaWJsZSBtYXRjaGluZyBlbnRyeSBieSBleGFtaW5pbmcgdGhlCiAgICAgKiBmaXJzdCBmZXcgY2hhcmFjdGVycyBpbiBvYmplY3QKICAgICAqLwogICAgaSA9IC0xOwogICAgc3dpdGNoIChGY1RvTG93ZXIgKG9iamVjdFswXSkpIHsKICAgIGNhc2UgJ2YnOgoJc3dpdGNoIChGY1RvTG93ZXIgKG9iamVjdFsxXSkpIHsKCWNhc2UgJ28nOgoJICAgIHN3aXRjaCAoRmNUb0xvd2VyIChvYmplY3RbMl0pKSB7CgkgICAgY2FzZSAndSc6CgkJaSA9IE1BVENIX0ZPVU5EUlk7IGJyZWFrOwoJICAgIGNhc2UgJ24nOgoJCWkgPSBNQVRDSF9GT05UVkVSU0lPTjsgYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSAnYSc6CgkgICAgaSA9IE1BVENIX0ZBTUlMWTsgYnJlYWs7Cgl9CglicmVhazsKICAgIGNhc2UgJ2MnOgoJaSA9IE1BVENIX0NIQVJTRVQ7IGJyZWFrOwogICAgY2FzZSAnYSc6CglpID0gTUFUQ0hfQU5USUFMSUFTOyBicmVhazsKICAgIGNhc2UgJ2wnOgoJaSA9IE1BVENIX0xBTkc7IGJyZWFrOwogICAgY2FzZSAncyc6Cglzd2l0Y2ggKEZjVG9Mb3dlciAob2JqZWN0WzFdKSkgewoJY2FzZSAncCc6CgkgICAgaSA9IE1BVENIX1NQQUNJTkc7IGJyZWFrOwoJY2FzZSAndCc6CgkgICAgaSA9IE1BVENIX1NUWUxFOyBicmVhazsKCWNhc2UgJ2wnOgoJICAgIGkgPSBNQVRDSF9TTEFOVDsgYnJlYWs7Cgl9CglicmVhazsKICAgIGNhc2UgJ3AnOgoJaSA9IE1BVENIX1BJWEVMX1NJWkU7IGJyZWFrOwogICAgY2FzZSAndyc6CglpID0gTUFUQ0hfV0VJR0hUOyBicmVhazsKICAgIGNhc2UgJ3InOgoJaSA9IE1BVENIX1JBU1RFUklaRVI7IGJyZWFrOwogICAgY2FzZSAnbyc6CglpID0gTUFUQ0hfT1VUTElORTsgYnJlYWs7CiAgICB9CiAgICBpZiAoaSA9PSAtMSB8fCAKCUZjU3RyQ21wSWdub3JlQ2FzZSAoKEZjQ2hhcjggKikgX0ZjTWF0Y2hlcnNbaV0ub2JqZWN0LAoJCQkgICAgKEZjQ2hhcjggKikgb2JqZWN0KSAhPSAwKQogICAgewoJaWYgKGJlc3RWYWx1ZSkKCSAgICAqYmVzdFZhbHVlID0gdjJvcmlnLT52YWx1ZTsKCXJldHVybiBGY1RydWU7CiAgICB9CiNpZiAwCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX01BVENIRVI7IGkrKykKICAgIHsKCWlmICghRmNTdHJDbXBJZ25vcmVDYXNlICgoRmNDaGFyOCAqKSBfRmNNYXRjaGVyc1tpXS5vYmplY3QsCgkJCQkgKEZjQ2hhcjggKikgb2JqZWN0KSkKCSAgICBicmVhazsKICAgIH0KICAgIGlmIChpID09IE5VTV9NQVRDSEVSKQogICAgewoJaWYgKGJlc3RWYWx1ZSkKCSAgICAqYmVzdFZhbHVlID0gdjJvcmlnLT52YWx1ZTsKCXJldHVybiBGY1RydWU7CiAgICB9CiNlbmRpZgogICAgYmVzdCA9IDFlOTk7CiAgICBiZXN0U3Ryb25nID0gMWU5OTsKICAgIGJlc3RXZWFrID0gMWU5OTsKICAgIGogPSAwOwogICAgZm9yICh2MSA9IHYxb3JpZzsgdjE7IHYxID0gdjEtPm5leHQpCiAgICB7Cglmb3IgKHYyID0gdjJvcmlnOyB2MjsgdjIgPSB2Mi0+bmV4dCkKCXsKCSAgICB2ID0gKCpfRmNNYXRjaGVyc1tpXS5jb21wYXJlKSAoX0ZjTWF0Y2hlcnNbaV0ub2JqZWN0LAoJCQkJCSAgICB2MS0+dmFsdWUsCgkJCQkJICAgIHYyLT52YWx1ZSk7CgkgICAgaWYgKHYgPCAwKQoJICAgIHsKCQkqcmVzdWx0ID0gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CgkJcmV0dXJuIEZjRmFsc2U7CgkgICAgfQoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIVikKCQlwcmludGYgKCIgdiAlZyBqICVkICIsIHYsIGopOwoJICAgIHYgPSB2ICogMTAwICsgajsKCSAgICBpZiAodiA8IGJlc3QpCgkgICAgewoJCWlmIChiZXN0VmFsdWUpCgkJICAgICpiZXN0VmFsdWUgPSB2Mi0+dmFsdWU7CgkJYmVzdCA9IHY7CgkgICAgfQoJICAgIGlmICh2MS0+YmluZGluZyA9PSBGY1ZhbHVlQmluZGluZ1N0cm9uZykKCSAgICB7CgkJaWYgKHYgPCBiZXN0U3Ryb25nKQoJCSAgICBiZXN0U3Ryb25nID0gdjsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlpZiAodiA8IGJlc3RXZWFrKQoJCSAgICBiZXN0V2VhayA9IHY7CgkgICAgfQoJfQoJaisrOwogICAgfQogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0hWKQogICAgewoJcHJpbnRmICgiICVzOiAlZyAiLCBvYmplY3QsIGJlc3QpOwoJRmNWYWx1ZUxpc3RQcmludCAodjFvcmlnKTsKCXByaW50ZiAoIiwgIik7CglGY1ZhbHVlTGlzdFByaW50ICh2Mm9yaWcpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIGlmICh2YWx1ZSkKICAgIHsKCWludCB3ZWFrICAgID0gX0ZjTWF0Y2hlcnNbaV0ud2VhazsKCWludCBzdHJvbmcgID0gX0ZjTWF0Y2hlcnNbaV0uc3Ryb25nOwoJaWYgKHdlYWsgPT0gc3Ryb25nKQoJICAgIHZhbHVlW3N0cm9uZ10gKz0gYmVzdDsKCWVsc2UKCXsKCSAgICB2YWx1ZVt3ZWFrXSArPSBiZXN0V2VhazsKCSAgICB2YWx1ZVtzdHJvbmddICs9IGJlc3RTdHJvbmc7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgovKgogKiBSZXR1cm4gYSB2YWx1ZSBpbmRpY2F0aW5nIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSB0d28gbGlzdHMgb2YKICogdmFsdWVzCiAqLwoKc3RhdGljIEZjQm9vbApGY0NvbXBhcmUgKEZjUGF0dGVybgkqcGF0LAoJICAgRmNQYXR0ZXJuCSpmbnQsCgkgICBkb3VibGUJKnZhbHVlLAoJICAgRmNSZXN1bHQJKnJlc3VsdCkKewogICAgaW50CQkgICAgaSwgaTEsIGkyOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX01BVENIX1ZBTFVFUzsgaSsrKQoJdmFsdWVbaV0gPSAwLjA7CiAgICAKICAgIGkxID0gMDsKICAgIGkyID0gMDsKICAgIHdoaWxlIChpMSA8IHBhdC0+bnVtICYmIGkyIDwgZm50LT5udW0pCiAgICB7CglpID0gc3RyY21wIChwYXQtPmVsdHNbaTFdLm9iamVjdCwgZm50LT5lbHRzW2kyXS5vYmplY3QpOwoJaWYgKGkgPiAwKQoJICAgIGkyKys7CgllbHNlIGlmIChpIDwgMCkKCSAgICBpMSsrOwoJZWxzZQoJewoJICAgIGlmICghRmNDb21wYXJlVmFsdWVMaXN0IChwYXQtPmVsdHNbaTFdLm9iamVjdCwKCQkJCSAgICAgcGF0LT5lbHRzW2kxXS52YWx1ZXMsCgkJCQkgICAgIGZudC0+ZWx0c1tpMl0udmFsdWVzLAoJCQkJICAgICAwLAoJCQkJICAgICB2YWx1ZSwKCQkJCSAgICAgcmVzdWx0KSkKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBpMSsrOwoJICAgIGkyKys7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwojaWYgMAogICAgZm9yIChpMSA9IDA7IGkxIDwgcGF0LT5udW07IGkxKyspCiAgICB7Cglmb3IgKGkyID0gMDsgaTIgPCBmbnQtPm51bTsgaTIrKykKCXsKCSAgICBpZiAoIXN0cmNtcCAocGF0LT5lbHRzW2kxXS5vYmplY3QsIGZudC0+ZWx0c1tpMl0ub2JqZWN0KSkKCSAgICB7CgkJYnJlYWs7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKI2VuZGlmCn0KCkZjUGF0dGVybiAqCkZjRm9udFJlbmRlclByZXBhcmUgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCSAgICAgRmNQYXR0ZXJuCSAgICAqcGF0LAoJCSAgICAgRmNQYXR0ZXJuCSAgICAqZm9udCkKewogICAgRmNQYXR0ZXJuCSAgICAqbmV3OwogICAgaW50CQkgICAgaTsKICAgIEZjUGF0dGVybkVsdCAgICAqZmUsICpwZTsKICAgIEZjVmFsdWUJICAgIHY7CiAgICBGY1Jlc3VsdAkgICAgcmVzdWx0OwogICAgCiAgICBuZXcgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIW5ldykKCXJldHVybiAwOwogICAgZm9yIChpID0gMDsgaSA8IGZvbnQtPm51bTsgaSsrKQogICAgewoJZmUgPSAmZm9udC0+ZWx0c1tpXTsKCXBlID0gRmNQYXR0ZXJuRmluZEVsdCAocGF0LCBmZS0+b2JqZWN0KTsKCWlmIChwZSkKCXsKCSAgICBpZiAoIUZjQ29tcGFyZVZhbHVlTGlzdCAocGUtPm9iamVjdCwgcGUtPnZhbHVlcywgCgkJCQkgICAgIGZlLT52YWx1ZXMsICZ2LCAwLCAmcmVzdWx0KSkKCSAgICB7CgkJRmNQYXR0ZXJuRGVzdHJveSAobmV3KTsKCQlyZXR1cm4gMDsKCSAgICB9Cgl9CgllbHNlCgkgICAgdiA9IGZlLT52YWx1ZXMtPnZhbHVlOwoJRmNQYXR0ZXJuQWRkIChuZXcsIGZlLT5vYmplY3QsIHYsIEZjRmFsc2UpOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IHBhdC0+bnVtOyBpKyspCiAgICB7CglwZSA9ICZwYXQtPmVsdHNbaV07CglmZSA9IEZjUGF0dGVybkZpbmRFbHQgKGZvbnQsIHBlLT5vYmplY3QpOwoJaWYgKCFmZSkKCSAgICBGY1BhdHRlcm5BZGQgKG5ldywgcGUtPm9iamVjdCwgcGUtPnZhbHVlcy0+dmFsdWUsIEZjVHJ1ZSk7CiAgICB9CiAgICBGY0NvbmZpZ1N1YnN0aXR1dGVXaXRoUGF0IChjb25maWcsIG5ldywgcGF0LCBGY01hdGNoRm9udCk7CiAgICByZXR1cm4gbmV3Owp9CgpGY1BhdHRlcm4gKgpGY0ZvbnRTZXRNYXRjaCAoRmNDb25maWcgICAgKmNvbmZpZywKCQlGY0ZvbnRTZXQgICAqKnNldHMsCgkJaW50CSAgICBuc2V0cywKCQlGY1BhdHRlcm4gICAqcCwKCQlGY1Jlc3VsdCAgICAqcmVzdWx0KQp7CiAgICBkb3VibGUgICAgCSAgICBzY29yZVtOVU1fTUFUQ0hfVkFMVUVTXSwgYmVzdHNjb3JlW05VTV9NQVRDSF9WQUxVRVNdOwogICAgaW50CQkgICAgZjsKICAgIEZjRm9udFNldAkgICAgKnM7CiAgICBGY1BhdHRlcm4JICAgICpiZXN0OwogICAgaW50CQkgICAgaTsKICAgIGludAkJICAgIHNldDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX01BVENIX1ZBTFVFUzsgaSsrKQoJYmVzdHNjb3JlW2ldID0gMDsKICAgIGJlc3QgPSAwOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0gpCiAgICB7CglwcmludGYgKCJNYXRjaCAiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICBmb3IgKHNldCA9IDA7IHNldCA8IG5zZXRzOyBzZXQrKykKICAgIHsKCXMgPSBzZXRzW3NldF07CglpZiAoIXMpCgkgICAgY29udGludWU7Cglmb3IgKGYgPSAwOyBmIDwgcy0+bmZvbnQ7IGYrKykKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSFYpCgkgICAgewoJCXByaW50ZiAoIkZvbnQgJWQgIiwgZik7CgkJRmNQYXR0ZXJuUHJpbnQgKHMtPmZvbnRzW2ZdKTsKCSAgICB9CgkgICAgaWYgKCFGY0NvbXBhcmUgKHAsIHMtPmZvbnRzW2ZdLCBzY29yZSwgcmVzdWx0KSkKCQlyZXR1cm4gMDsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSFYpCgkgICAgewoJCXByaW50ZiAoIlNjb3JlIik7CgkJZm9yIChpID0gMDsgaSA8IE5VTV9NQVRDSF9WQUxVRVM7IGkrKykKCQl7CgkJICAgIHByaW50ZiAoIiAlZyIsIHNjb3JlW2ldKTsKCQl9CgkJcHJpbnRmICgiXG4iKTsKCSAgICB9CgkgICAgZm9yIChpID0gMDsgaSA8IE5VTV9NQVRDSF9WQUxVRVM7IGkrKykKCSAgICB7CgkJaWYgKGJlc3QgJiYgYmVzdHNjb3JlW2ldIDwgc2NvcmVbaV0pCgkJICAgIGJyZWFrOwoJCWlmICghYmVzdCB8fCBzY29yZVtpXSA8IGJlc3RzY29yZVtpXSkKCQl7CgkJICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hfVkFMVUVTOyBpKyspCgkJCWJlc3RzY29yZVtpXSA9IHNjb3JlW2ldOwoJCSAgICBiZXN0ID0gcy0+Zm9udHNbZl07CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSCkKICAgIHsKCXByaW50ZiAoIkJlc3Qgc2NvcmUiKTsKCWZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hfVkFMVUVTOyBpKyspCgkgICAgcHJpbnRmICgiICVnIiwgYmVzdHNjb3JlW2ldKTsKCUZjUGF0dGVyblByaW50IChiZXN0KTsKICAgIH0KICAgIGlmICghYmVzdCkKICAgIHsKCSpyZXN1bHQgPSBGY1Jlc3VsdE5vTWF0Y2g7CglyZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBGY0ZvbnRSZW5kZXJQcmVwYXJlIChjb25maWcsIHAsIGJlc3QpOwp9CgpGY1BhdHRlcm4gKgpGY0ZvbnRNYXRjaCAoRmNDb25maWcJKmNvbmZpZywKCSAgICAgRmNQYXR0ZXJuCSpwLCAKCSAgICAgRmNSZXN1bHQJKnJlc3VsdCkKewogICAgRmNGb250U2V0CSpzZXRzWzJdOwogICAgaW50CQluc2V0czsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgbnNldHMgPSAwOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dKQoJc2V0c1tuc2V0cysrXSA9IGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRBcHBsaWNhdGlvbl0pCglzZXRzW25zZXRzKytdID0gY29uZmlnLT5mb250c1tGY1NldEFwcGxpY2F0aW9uXTsKICAgIHJldHVybiBGY0ZvbnRTZXRNYXRjaCAoY29uZmlnLCBzZXRzLCBuc2V0cywgcCwgcmVzdWx0KTsKfQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjU29ydE5vZGUgewogICAgRmNQYXR0ZXJuCSpwYXR0ZXJuOwogICAgZG91YmxlCXNjb3JlW05VTV9NQVRDSF9WQUxVRVNdOwp9IEZjU29ydE5vZGU7CgpzdGF0aWMgaW50CkZjU29ydENvbXBhcmUgKGNvbnN0IHZvaWQgKmFhLCBjb25zdCB2b2lkICphYikKewogICAgRmNTb3J0Tm9kZSAgKmEgPSAqKEZjU29ydE5vZGUgKiopIGFhOwogICAgRmNTb3J0Tm9kZSAgKmIgPSAqKEZjU29ydE5vZGUgKiopIGFiOwogICAgZG91YmxlCSphcyA9ICZhLT5zY29yZVswXTsKICAgIGRvdWJsZQkqYnMgPSAmYi0+c2NvcmVbMF07CiAgICBkb3VibGUJYWQgPSAwLCBiZCA9IDA7CiAgICBpbnQgICAgICAgICBpOwoKICAgIGkgPSBOVU1fTUFUQ0hfVkFMVUVTOwogICAgd2hpbGUgKGktLSAmJiAoYWQgPSAqYXMrKykgPT0gKGJkID0gKmJzKyspKQoJOwogICAgcmV0dXJuIGFkIDwgYmQgPyAtMSA6IGFkID4gYmQgPyAxIDogMDsKfQoKc3RhdGljIEZjQm9vbApGY1NvcnRXYWxrIChGY1NvcnROb2RlICoqbiwgaW50IG5ub2RlLCBGY0ZvbnRTZXQgKmZzLCBGY0NoYXJTZXQgKipjcywgRmNCb29sIHRyaW0pCnsKICAgIEZjQ2hhclNldAkqbmNzOwogICAgRmNTb3J0Tm9kZQkqbm9kZTsKCiAgICB3aGlsZSAobm5vZGUtLSkKICAgIHsKCW5vZGUgPSAqbisrOwoJaWYgKEZjUGF0dGVybkdldENoYXJTZXQgKG5vZGUtPnBhdHRlcm4sIEZDX0NIQVJTRVQsIDAsICZuY3MpID09IAoJICAgIEZjUmVzdWx0TWF0Y2gpCgl7CgkgICAgLyoKCSAgICAgKiBJZiB0aGlzIGZvbnQgaXNuJ3QgYSBzdWJzZXQgb2YgdGhlIHByZXZpb3VzIGZvbnRzLAoJICAgICAqIGFkZCBpdCB0byB0aGUgbGlzdAoJICAgICAqLwoJICAgIGlmICghdHJpbSB8fCAhKmNzIHx8ICFGY0NoYXJTZXRJc1N1YnNldCAobmNzLCAqY3MpKQoJICAgIHsKCQlpZiAoKmNzKQoJCXsKCQkgICAgbmNzID0gRmNDaGFyU2V0VW5pb24gKG5jcywgKmNzKTsKCQkgICAgaWYgKCFuY3MpCgkJCXJldHVybiBGY0ZhbHNlOwoJCSAgICBGY0NoYXJTZXREZXN0cm95ICgqY3MpOwoJCX0KCQllbHNlCgkJICAgIG5jcyA9IEZjQ2hhclNldENvcHkgKG5jcyk7CgkJKmNzID0gbmNzOwoJCUZjUGF0dGVyblJlZmVyZW5jZSAobm9kZS0+cGF0dGVybik7CgkJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0gpCgkJewoJCSAgICBwcmludGYgKCJBZGQgIik7CgkJICAgIEZjUGF0dGVyblByaW50IChub2RlLT5wYXR0ZXJuKTsKCQl9CgkJaWYgKCFGY0ZvbnRTZXRBZGQgKGZzLCBub2RlLT5wYXR0ZXJuKSkKCQl7CgkJICAgIEZjUGF0dGVybkRlc3Ryb3kgKG5vZGUtPnBhdHRlcm4pOwoJCSAgICByZXR1cm4gRmNGYWxzZTsKCQl9CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdm9pZApGY0ZvbnRTZXRTb3J0RGVzdHJveSAoRmNGb250U2V0ICpmcykKewogICAgRmNGb250U2V0RGVzdHJveSAoZnMpOwp9CgpGY0ZvbnRTZXQgKgpGY0ZvbnRTZXRTb3J0IChGY0NvbmZpZwkgICAgKmNvbmZpZywKCSAgICAgICBGY0ZvbnRTZXQgICAgKipzZXRzLAoJICAgICAgIGludAkgICAgbnNldHMsCgkgICAgICAgRmNQYXR0ZXJuICAgICpwLAoJICAgICAgIEZjQm9vbAkgICAgdHJpbSwKCSAgICAgICBGY0NoYXJTZXQgICAgKipjc3AsCgkgICAgICAgRmNSZXN1bHQJICAgICpyZXN1bHQpCnsKICAgIEZjRm9udFNldAkgICAgKnJldDsKICAgIEZjRm9udFNldAkgICAgKnM7CiAgICBGY1NvcnROb2RlCSAgICAqbm9kZXM7CiAgICBGY1NvcnROb2RlCSAgICAqKm5vZGVwcywgKipub2RlcDsKICAgIGludAkJICAgIG5ub2RlczsKICAgIEZjU29ydE5vZGUJICAgICpuZXc7CiAgICBGY0NoYXJTZXQJICAgICpjczsKICAgIGludAkJICAgIHNldDsKICAgIGludAkJICAgIGY7CiAgICBpbnQJCSAgICBpOwoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIKQogICAgewoJcHJpbnRmICgiU29ydCAiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIG5ub2RlcyA9IDA7CiAgICBmb3IgKHNldCA9IDA7IHNldCA8IG5zZXRzOyBzZXQrKykKICAgIHsKCXMgPSBzZXRzW3NldF07CglpZiAoIXMpCgkgICAgY29udGludWU7Cglubm9kZXMgKz0gcy0+bmZvbnQ7CiAgICB9CiAgICBpZiAoIW5ub2RlcykKCWdvdG8gYmFpbDA7CiAgICAvKiBmcmVlZCBiZWxvdyAqLwogICAgbm9kZXMgPSBtYWxsb2MgKG5ub2RlcyAqIHNpemVvZiAoRmNTb3J0Tm9kZSkgKyBubm9kZXMgKiBzaXplb2YgKEZjU29ydE5vZGUgKikpOwogICAgaWYgKCFub2RlcykKCWdvdG8gYmFpbDA7CiAgICBub2RlcHMgPSAoRmNTb3J0Tm9kZSAqKikgKG5vZGVzICsgbm5vZGVzKTsKICAgIAogICAgbmV3ID0gbm9kZXM7CiAgICBub2RlcCA9IG5vZGVwczsKICAgIGZvciAoc2V0ID0gMDsgc2V0IDwgbnNldHM7IHNldCsrKQogICAgewoJcyA9IHNldHNbc2V0XTsKCWlmICghcykKCSAgICBjb250aW51ZTsKCWZvciAoZiA9IDA7IGYgPCBzLT5uZm9udDsgZisrKQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIVikKCSAgICB7CgkJcHJpbnRmICgiRm9udCAlZCAiLCBmKTsKCQlGY1BhdHRlcm5QcmludCAocy0+Zm9udHNbZl0pOwoJICAgIH0KCSAgICBuZXctPnBhdHRlcm4gPSBzLT5mb250c1tmXTsKCSAgICBpZiAoIUZjQ29tcGFyZSAocCwgbmV3LT5wYXR0ZXJuLCBuZXctPnNjb3JlLCByZXN1bHQpKQoJCWdvdG8gYmFpbDE7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0hWKQoJICAgIHsKCQlwcmludGYgKCJTY29yZSIpOwoJCWZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hfVkFMVUVTOyBpKyspCgkJewoJCSAgICBwcmludGYgKCIgJWciLCBuZXctPnNjb3JlW2ldKTsKCQl9CgkJcHJpbnRmICgiXG4iKTsKCSAgICB9CgkgICAgKm5vZGVwID0gbmV3OwoJICAgIG5ldysrOwoJICAgIG5vZGVwKys7Cgl9CiAgICB9CgogICAgbm5vZGVzID0gbmV3IC0gbm9kZXM7CiAgICAKICAgIHFzb3J0IChub2RlcHMsIG5ub2Rlcywgc2l6ZW9mIChGY1NvcnROb2RlICopLAoJICAgRmNTb3J0Q29tcGFyZSk7CgogICAgcmV0ID0gRmNGb250U2V0Q3JlYXRlICgpOwogICAgaWYgKCFyZXQpCglnb3RvIGJhaWwxOwoKICAgIGNzID0gMDsKCiAgICBpZiAoIUZjU29ydFdhbGsgKG5vZGVwcywgbm5vZGVzLCByZXQsICZjcywgdHJpbSkpCglnb3RvIGJhaWwyOwoKICAgIGlmIChjc3ApCgkqY3NwID0gY3M7CiAgICBlbHNlCglGY0NoYXJTZXREZXN0cm95IChjcyk7CgogICAgZnJlZSAobm9kZXMpOwoKICAgIHJldHVybiByZXQ7CgpiYWlsMjoKICAgIGlmIChjcykKCUZjQ2hhclNldERlc3Ryb3kgKGNzKTsKICAgIEZjRm9udFNldERlc3Ryb3kgKHJldCk7CmJhaWwxOgogICAgZnJlZSAobm9kZXMpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpGY0ZvbnRTZXQgKgpGY0ZvbnRTb3J0IChGY0NvbmZpZwkqY29uZmlnLAoJICAgIEZjUGF0dGVybgkqcCwgCgkgICAgRmNCb29sCXRyaW0sCgkgICAgRmNDaGFyU2V0CSoqY3NwLAoJICAgIEZjUmVzdWx0CSpyZXN1bHQpCnsKICAgIEZjRm9udFNldAkqc2V0c1syXTsKICAgIGludAkJbnNldHM7CgogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIG5zZXRzID0gMDsKICAgIGlmIChjb25maWctPmZvbnRzW0ZjU2V0U3lzdGVtXSkKCXNldHNbbnNldHMrK10gPSBjb25maWctPmZvbnRzW0ZjU2V0U3lzdGVtXTsKICAgIGlmIChjb25maWctPmZvbnRzW0ZjU2V0QXBwbGljYXRpb25dKQoJc2V0c1tuc2V0cysrXSA9IGNvbmZpZy0+Zm9udHNbRmNTZXRBcHBsaWNhdGlvbl07CiAgICByZXR1cm4gRmNGb250U2V0U29ydCAoY29uZmlnLCBzZXRzLCBuc2V0cywgcCwgdHJpbSwgY3NwLCByZXN1bHQpOwp9Cg==