LyotCiAqIENvcHlyaWdodCAoYykgMTk4MCBUaGUgUmVnZW50cyBvZiB0aGUgVW5pdmVyc2l0eSBvZiBDYWxpZm9ybmlhLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICovCgovKiAqOmFlYiAqLwoKLyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICovCgojaW5jbHVkZSA8c3lzL3BhcmFtLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxkaXJlbnQuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgIm5scy5oIgoKdm9pZCB6ZXJvZih2b2lkKTsKdm9pZCBnZXRsaXN0KGludCAqLCBjaGFyICoqKiwgY2hhciAqKiosIGludCAqKTsKdm9pZCBsb29rdXAoY2hhciAqKTsKdm9pZCBsb29rc3JjKGNoYXIgKik7CnZvaWQgbG9va2JpbihjaGFyICopOwp2b2lkIGxvb2ttYW4oY2hhciAqKTsKdm9pZCBmaW5kdihjaGFyICoqLCBpbnQsIGNoYXIgKik7CnZvaWQgZmluZChjaGFyICoqLCBjaGFyICopOwp2b2lkIGZpbmRpbihjaGFyICosIGNoYXIgKik7CmludCBpdHNpdChjaGFyICosIGNoYXIgKik7CgpzdGF0aWMgY2hhciAqYmluZGlyc1tdID0gewogICAiL2JpbiIsCiAgICIvdXNyL2JpbiIsCiAgICIvc2JpbiIsCiAgICIvdXNyL3NiaW4iLAogICAiL2V0YyIsCiAgICIvdXNyL2V0YyIsCiAgICIvbGliIiwKICAgIi91c3IvbGliIiwKICAgIi9saWI2NCIsCiAgICIvdXNyL2xpYjY0IiwKICAgIi91c3IvZ2FtZXMiLAogICAiL3Vzci9nYW1lcy9iaW4iLAogICAiL3Vzci9nYW1lcy9saWIiLAogICAiL3Vzci9lbWFjcy9ldGMiLAogICAiL3Vzci9saWIvZW1hY3MvKi9ldGMiLAogICAiL3Vzci9UZVgvYmluIiwKICAgIi91c3IvdGV4L2JpbiIsCiAgICIvdXNyL2ludGVydmlld3MvYmluL0xJTlVYIiwKCiAgICIvdXNyL1gxMVI2L2JpbiIsCiAgICIvdXNyL1gzODYvYmluIiwKICAgIi91c3IvYmluL1gxMSIsCiAgICIvdXNyL1gxMS9iaW4iLAogICAiL3Vzci9YMTFSNS9iaW4iLAoKICAgIi91c3IvbG9jYWwvYmluIiwKICAgIi91c3IvbG9jYWwvc2JpbiIsCiAgICIvdXNyL2xvY2FsL2V0YyIsCiAgICIvdXNyL2xvY2FsL2xpYiIsCiAgICIvdXNyL2xvY2FsL2dhbWVzIiwKICAgIi91c3IvbG9jYWwvZ2FtZXMvYmluIiwKICAgIi91c3IvbG9jYWwvZW1hY3MvZXRjIiwKICAgIi91c3IvbG9jYWwvVGVYL2JpbiIsCiAgICIvdXNyL2xvY2FsL3RleC9iaW4iLAogICAiL3Vzci9sb2NhbC9iaW4vWDExIiwKCiAgICIvdXNyL2NvbnRyaWIiLAogICAiL3Vzci9ob3N0cyIsCiAgICIvdXNyL2luY2x1ZGUiLAoKICAgIi91c3IvZysrLWluY2x1ZGUiLAoKICAgIi91c3IvdWNiIiwKICAgIi91c3Ivb2xkIiwKICAgIi91c3IvbmV3IiwKICAgIi91c3IvbG9jYWwiLAogICAiL3Vzci9saWJleGVjIiwKICAgIi91c3Ivc2hhcmUiLAoKICAgIi9vcHQvKi9iaW4iLAoKCTAKfTsKCnN0YXRpYyBjaGFyICptYW5kaXJzW10gPSB7CgkiL3Vzci9tYW4vKiIsCgkiL3Vzci9zaGFyZS9tYW4vKiIsCgkiL3Vzci9YMzg2L21hbi8qIiwKCSIvdXNyL1gxMS9tYW4vKiIsCgkiL3Vzci9UZVgvbWFuLyoiLAoJIi91c3IvaW50ZXJ2aWV3cy9tYW4vbWFubiIsCgkwCn07CgpzdGF0aWMgY2hhciAqc3JjZGlyc1tdICA9IHsKCSIvdXNyL3NyYy8qIiwKCSIvdXNyL3NyYy9saWIvbGliYy8qIiwKCSIvdXNyL3NyYy9saWIvbGliYy9uZXQvKiIsCgkiL3Vzci9zcmMvdWNiL3Bhc2NhbCIsCgkiL3Vzci9zcmMvdWNiL3Bhc2NhbC91dGlsaXRpZXMiLAoJIi91c3Ivc3JjL3VuZG9jIiwKCTAKfTsKCmNoYXIJc2ZsYWcgPSAxOwpjaGFyCWJmbGFnID0gMTsKY2hhcgltZmxhZyA9IDE7CmNoYXIJKipTZmxhZzsKaW50CVNjbnQ7CmNoYXIJKipCZmxhZzsKaW50CUJjbnQ7CmNoYXIJKipNZmxhZzsKaW50CU1jbnQ7CmNoYXIJdWZsYWc7Ci8qCiAqIHdoZXJlaXMgbmFtZQogKiBsb29rIGZvciBzb3VyY2UsIGRvY3VtZW50YXRpb24gYW5kIGJpbmFyaWVzCiAqLwppbnQKbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpIHsKCXNldGxvY2FsZShMQ19BTEwsICIiKTsKCWJpbmR0ZXh0ZG9tYWluKFBBQ0tBR0UsIExPQ0FMRURJUik7Cgl0ZXh0ZG9tYWluKFBBQ0tBR0UpOwoKCWFyZ2MtLSwgYXJndisrOwoJaWYgKGFyZ2MgPT0gMCkgewp1c2FnZToKCQlmcHJpbnRmKHN0ZGVyciwgXygid2hlcmVpcyBbIC1zYm11IF0gWyAtU0JNIGRpciAuLi4gLWYgXSBuYW1lLi4uXG4iKSk7CgkJZXhpdCgxKTsKCX0KCWRvCgkJaWYgKGFyZ3ZbMF1bMF0gPT0gJy0nKSB7CgkJCXJlZ2lzdGVyIGNoYXIgKmNwID0gYXJndlswXSArIDE7CgkJCXdoaWxlICgqY3ApIHN3aXRjaCAoKmNwKyspIHsKCgkJCWNhc2UgJ2YnOgoJCQkJYnJlYWs7CgoJCQljYXNlICdTJzoKCQkJCWdldGxpc3QoJmFyZ2MsICZhcmd2LCAmU2ZsYWcsICZTY250KTsKCQkJCWJyZWFrOwoKCQkJY2FzZSAnQic6CgkJCQlnZXRsaXN0KCZhcmdjLCAmYXJndiwgJkJmbGFnLCAmQmNudCk7CgkJCQlicmVhazsKCgkJCWNhc2UgJ00nOgoJCQkJZ2V0bGlzdCgmYXJnYywgJmFyZ3YsICZNZmxhZywgJk1jbnQpOwoJCQkJYnJlYWs7CgoJCQljYXNlICdzJzoKCQkJCXplcm9mKCk7CgkJCQlzZmxhZysrOwoJCQkJY29udGludWU7CgoJCQljYXNlICd1JzoKCQkJCXVmbGFnKys7CgkJCQljb250aW51ZTsKCgkJCWNhc2UgJ2InOgoJCQkJemVyb2YoKTsKCQkJCWJmbGFnKys7CgkJCQljb250aW51ZTsKCgkJCWNhc2UgJ20nOgoJCQkJemVyb2YoKTsKCQkJCW1mbGFnKys7CgkJCQljb250aW51ZTsKCgkJCWRlZmF1bHQ6CgkJCQlnb3RvIHVzYWdlOwoJCQl9CgkJCWFyZ3YrKzsKCQl9IGVsc2UKCQkJbG9va3VwKCphcmd2KyspOwoJd2hpbGUgKC0tYXJnYyA+IDApOwoJcmV0dXJuIDA7Cn0KCnZvaWQKZ2V0bGlzdChpbnQgKmFyZ2NwLCBjaGFyICoqKmFyZ3ZwLCBjaGFyICoqKmZsYWdwLCBpbnQgKmNudHApIHsKCSgqYXJndnApKys7CgkqZmxhZ3AgPSAqYXJndnA7CgkqY250cCA9IDA7Cglmb3IgKCgqYXJnY3ApLS07ICphcmdjcCA+IDAgJiYgKCphcmd2cClbMF1bMF0gIT0gJy0nOyAoKmFyZ2NwKS0tKQoJCSgqY250cCkrKywgKCphcmd2cCkrKzsKCSgqYXJnY3ApKys7CgkoKmFyZ3ZwKS0tOwp9CgoKdm9pZAp6ZXJvZigpCnsKCWlmIChzZmxhZyAmJiBiZmxhZyAmJiBtZmxhZykKCQlzZmxhZyA9IGJmbGFnID0gbWZsYWcgPSAwOwp9CgppbnQJY291bnQ7CmludAlwcmludDsKCnZvaWQKbG9va3VwKGNoYXIgKmNwKSB7CglyZWdpc3RlciBjaGFyICpkcDsKCglmb3IgKGRwID0gY3A7ICpkcDsgZHArKykKCQljb250aW51ZTsKCWZvciAoOyBkcCA+IGNwOyBkcC0tKSB7CgkJaWYgKCpkcCA9PSAnLicpIHsKCQkJKmRwID0gMDsKCQkJYnJlYWs7CgkJfQoJfQoJZm9yIChkcCA9IGNwOyAqZHA7IGRwKyspCgkJaWYgKCpkcCA9PSAnLycpCgkJCWNwID0gZHAgKyAxOwoJaWYgKHVmbGFnKSB7CgkJcHJpbnQgPSAwOwoJCWNvdW50ID0gMDsKCX0gZWxzZQoJCXByaW50ID0gMTsKYWdhaW46CglpZiAocHJpbnQpCgkJcHJpbnRmKCIlczoiLCBjcCk7CglpZiAoc2ZsYWcpIHsKCQlsb29rc3JjKGNwKTsKCQlpZiAodWZsYWcgJiYgcHJpbnQgPT0gMCAmJiBjb3VudCAhPSAxKSB7CgkJCXByaW50ID0gMTsKCQkJZ290byBhZ2FpbjsKCQl9Cgl9Cgljb3VudCA9IDA7CglpZiAoYmZsYWcpIHsKCQlsb29rYmluKGNwKTsKCQlpZiAodWZsYWcgJiYgcHJpbnQgPT0gMCAmJiBjb3VudCAhPSAxKSB7CgkJCXByaW50ID0gMTsKCQkJZ290byBhZ2FpbjsKCQl9Cgl9Cgljb3VudCA9IDA7CglpZiAobWZsYWcpIHsKCQlsb29rbWFuKGNwKTsKCQlpZiAodWZsYWcgJiYgcHJpbnQgPT0gMCAmJiBjb3VudCAhPSAxKSB7CgkJCXByaW50ID0gMTsKCQkJZ290byBhZ2FpbjsKCQl9Cgl9CglpZiAocHJpbnQpCgkJcHJpbnRmKCJcbiIpOwp9Cgp2b2lkCmxvb2tzcmMoY2hhciAqY3ApIHsKCWlmIChTZmxhZyA9PSAwKSB7CgkJZmluZChzcmNkaXJzLCBjcCk7Cgl9IGVsc2UKCQlmaW5kdihTZmxhZywgU2NudCwgY3ApOwp9Cgp2b2lkCmxvb2tiaW4oY2hhciAqY3ApIHsKCWlmIChCZmxhZyA9PSAwKQoJCWZpbmQoYmluZGlycywgY3ApOwoJZWxzZQoJCWZpbmR2KEJmbGFnLCBCY250LCBjcCk7Cn0KCnZvaWQKbG9va21hbihjaGFyICpjcCkgewoJaWYgKE1mbGFnID09IDApIHsKCQlmaW5kKG1hbmRpcnMsIGNwKTsKCX0gZWxzZQoJCWZpbmR2KE1mbGFnLCBNY250LCBjcCk7Cn0KCnZvaWQKZmluZHYoY2hhciAqKmRpcnYsIGludCBkaXJjLCBjaGFyICpjcCkgewoJd2hpbGUgKGRpcmMgPiAwKQoJCWZpbmRpbigqZGlydisrLCBjcCksIGRpcmMtLTsKfQoKdm9pZApmaW5kKGNoYXIgKipkaXJzLCBjaGFyICpjcCkgewoJd2hpbGUgKCpkaXJzKQoJCWZpbmRpbigqZGlycysrLCBjcCk7Cn0KCnZvaWQKZmluZGluKGNoYXIgKmRpciwgY2hhciAqY3ApIHsKCURJUiAqZGlycDsKCXN0cnVjdCBkaXJlbnQgKmRwOwoJY2hhciAqZCwgKmRkOwoJaW50IGw7CgljaGFyIGRpcmJ1ZlsxMDI0XTsKCXN0cnVjdCBzdGF0IHN0YXRidWY7CgoJZGQgPSBzdHJjaHIoZGlyLCAnKicpOwoJaWYgKCFkZCkKCQlnb3RvIG5vZ2xvYjsKCglsID0gc3RybGVuKGRpcik7CglpZiAobCA8IHNpemVvZihkaXJidWYpKSB7CS8qIHJlZnVzZSBleGNlc3NpdmVseSBsb25nIG5hbWVzICovCgkJc3RyY3B5IChkaXJidWYsIGRpcik7CgkJZCA9IHN0cmNocihkaXJidWYsICcqJyk7CgkJKmQgPSAwOwoJCWRpcnAgPSBvcGVuZGlyKGRpcmJ1Zik7CgkJaWYgKGRpcnAgPT0gTlVMTCkKCQkJcmV0dXJuOwoJCXdoaWxlICgoZHAgPSByZWFkZGlyKGRpcnApKSAhPSBOVUxMKSB7CgkJCWlmICghc3RyY21wKGRwLT5kX25hbWUsICIuIikgfHwKCQkJICAgICFzdHJjbXAoZHAtPmRfbmFtZSwgIi4uIikpCgkJCQljb250aW51ZTsKCQkJaWYgKHN0cmxlbihkcC0+ZF9uYW1lKSArIGwgPiBzaXplb2YoZGlyYnVmKSkKCQkJCWNvbnRpbnVlOwoJCQlzcHJpbnRmKGQsICIlcyIsIGRwLT5kX25hbWUpOwoJCQlpZiAoc3RhdChkaXJidWYsICZzdGF0YnVmKSkKCQkJCWNvbnRpbnVlOwoJCQlpZiAoIVNfSVNESVIoc3RhdGJ1Zi5zdF9tb2RlKSkKCQkJCWNvbnRpbnVlOwoJCQlzdHJjYXQoZCwgZGQrMSk7CgkJCWZpbmRpbihkaXJidWYsIGNwKTsKCQl9CgkJY2xvc2VkaXIoZGlycCk7Cgl9CglyZXR1cm47CgogICAgbm9nbG9iOgoJZGlycCA9IG9wZW5kaXIoZGlyKTsKCWlmIChkaXJwID09IE5VTEwpCgkJcmV0dXJuOwoJd2hpbGUgKChkcCA9IHJlYWRkaXIoZGlycCkpICE9IE5VTEwpIHsKCQlpZiAoaXRzaXQoY3AsIGRwLT5kX25hbWUpKSB7CgkJCWNvdW50Kys7CgkJCWlmIChwcmludCkKCQkJCXByaW50ZigiICVzLyVzIiwgZGlyLCBkcC0+ZF9uYW1lKTsKCQl9Cgl9CgljbG9zZWRpcihkaXJwKTsKfQoKaW50Cml0c2l0KGNoYXIgKmNwLCBjaGFyICpkcCkgewoJaW50IGkgPSBzdHJsZW4oZHApOwoKCWlmIChkcFswXSA9PSAncycgJiYgZHBbMV0gPT0gJy4nICYmIGl0c2l0KGNwLCBkcCsyKSkKCQlyZXR1cm4gKDEpOwoJaWYgKCFzdHJjbXAoZHAraS0yLCAiLloiKSkKCQlpIC09IDI7CgllbHNlIGlmICghc3RyY21wKGRwK2ktMywgIi5neiIpKQoJCWkgLT0gMzsKCWVsc2UgaWYgKCFzdHJjbXAoZHAraS00LCAiLmJ6MiIpKQoJCWkgLT0gNDsKCXdoaWxlICgqY3AgJiYgKmRwICYmICpjcCA9PSAqZHApCgkJY3ArKywgZHArKywgaS0tOwoJaWYgKCpjcCA9PSAwICYmICpkcCA9PSAwKQoJCXJldHVybiAoMSk7Cgl3aGlsZSAoaXNkaWdpdCgqZHApKQoJCWRwKys7CglpZiAoKmNwID09IDAgJiYgKmRwKysgPT0gJy4nKSB7CgkJLS1pOwoJCXdoaWxlIChpID4gMCAmJiAqZHApCgkJCWlmICgtLWksICpkcCsrID09ICcuJykKCQkJCXJldHVybiAoKmRwKysgPT0gJ0MnICYmICpkcCsrID09IDApOwoJCXJldHVybiAoMSk7Cgl9CglyZXR1cm4gKDApOwp9Cg==