LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQsIDIwMDUgTWFydGluIEZ1Y2hzCiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCi8qIGZvciB1bml4IGZpbGVzeXN0ZW0gZnVuY3Rpb24gY2FsbHMgKi8KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGRpcmVudC5oPgojZW5kaWYKCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmVmaWxlLmgiCiNpbmNsdWRlICJyZXNvdXJjZS5oIgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCnN0YXRpYyBjb25zdCBXQ0hBUiByZWdpc3RyeV9rZXlbXSA9IHsgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnRicsJ2knLCdsJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfc3RhcnRfeFtdID0geyAncycsJ3QnLCdhJywncicsJ3QnLCdYJywnXDAnfTsKc3RhdGljIGNvbnN0IFdDSEFSIHJlZ19zdGFydF95W10gPSB7ICdzJywndCcsJ2EnLCdyJywndCcsJ1knLCdcMCd9OwpzdGF0aWMgY29uc3QgV0NIQVIgcmVnX3dpZHRoW10gPSB7ICd3JywnaScsJ2QnLCd0JywnaCcsJ1wwJ307CnN0YXRpYyBjb25zdCBXQ0hBUiByZWdfaGVpZ2h0W10gPSB7ICdoJywnZScsJ2knLCdnJywnaCcsJ3QnLCdcMCd9OwoKZW51bSBFTlRSWV9UWVBFIHsKCUVUX1dJTkRPV1MsCglFVF9VTklYLAojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUVUX1NIRUxMCiNlbmRpZgp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0VudHJ5IHsKCXN0cnVjdCBfRW50cnkqCW5leHQ7CglzdHJ1Y3QgX0VudHJ5Kglkb3duOwoJc3RydWN0IF9FbnRyeSoJdXA7CgoJQk9PTAkJCWV4cGFuZGVkOwoJQk9PTAkJCXNjYW5uZWQ7CglpbnQJCQkJbGV2ZWw7CgoJV0lOMzJfRklORF9EQVRBCWRhdGE7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwoJQk9PTAkJCWJoZmlfdmFsaWQ7CgllbnVtIEVOVFJZX1RZUEUJZXR5cGU7CiNlbmRpZgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUxQSVRFTUlETElTVAlwaWRsOwoJSVNoZWxsRm9sZGVyKglmb2xkZXI7CglISUNPTgkJCWhpY29uOwojZW5kaWYKfSBFbnRyeTsKCnR5cGVkZWYgc3RydWN0IHsKCUVudHJ5CWVudHJ5OwoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglUQ0hBUgl2b2xuYW1lW19NQVhfRk5BTUVdOwoJVENIQVIJZnNbX01BWF9ESVJdOwoJRFdPUkQJZHJpdmVfdHlwZTsKCURXT1JECWZzX2ZsYWdzOwp9IFJvb3Q7CgplbnVtIENPTFVNTl9GTEFHUyB7CglDT0xfU0laRQkJPSAweDAxLAoJQ09MX0RBVEUJCT0gMHgwMiwKCUNPTF9USU1FCQk9IDB4MDQsCglDT0xfQVRUUklCVVRFUwk9IDB4MDgsCglDT0xfRE9TTkFNRVMJPSAweDEwLAojaWZkZWYgX05PX0VYVEVOU0lPTlMKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVMKI2Vsc2UKCUNPTF9JTkRFWAkJPSAweDIwLAoJQ09MX0xJTktTCQk9IDB4NDAsCglDT0xfQUxMID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVN8Q09MX0RPU05BTUVTfENPTF9JTkRFWHxDT0xfTElOS1MKI2VuZGlmCn07Cgp0eXBlZGVmIGVudW0gewoJU09SVF9OQU1FLAoJU09SVF9FWFQsCglTT1JUX1NJWkUsCglTT1JUX0RBVEUKfSBTT1JUX09SREVSOwoKdHlwZWRlZiBzdHJ1Y3QgewoJSFdORAlod25kOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIV05ECWh3bmRIZWFkZXI7CiNlbmRpZgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojZGVmaW5lCUNPTFVNTlMJMTAKI2Vsc2UKI2RlZmluZQlDT0xVTU5TCTUKI2VuZGlmCglpbnQJCXdpZHRoc1tDT0xVTU5TXTsKCWludAkJcG9zaXRpb25zW0NPTFVNTlMrMV07CgoJQk9PTAl0cmVlUGFuZTsKCWludAkJdmlzaWJsZV9jb2xzOwoJRW50cnkqCXJvb3Q7CglFbnRyeSoJY3VyOwp9IFBhbmU7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CglQYW5lCWxlZnQ7CglQYW5lCXJpZ2h0OwoJaW50CQlmb2N1c19wYW5lOwkJLyogMDogbGVmdCAgMTogcmlnaHQgKi8KCVdJTkRPV1BMQUNFTUVOVCBwb3M7CglpbnQJCXNwbGl0X3BvczsKCUJPT0wJaGVhZGVyX3dkdGhzX29rOwoKCVRDSEFSCXBhdGhbTUFYX1BBVEhdOwoJVENIQVIJZmlsdGVyX3BhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmaWx0ZXJfZmxhZ3M7CglSb290CXJvb3Q7CgoJU09SVF9PUkRFUiBzb3J0T3JkZXI7Cn0gQ2hpbGRXbmQ7CgoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5KEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHNldF9jdXJkaXIoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZW50cnksIGludCBpZHgsIEhXTkQgaHduZCk7CnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKTsKc3RhdGljIHZvaWQgcmVmcmVzaF9kcml2ZXModm9pZCk7CnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpOwpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpOwoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgQ2hpbGRXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKTsKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwoKCi8qIGdsb2JhbHMgKi8KV0lORUZJTEVfR0xPQkFMUyBHbG9iYWxzOwoKc3RhdGljIGludCBsYXN0X3NwbGl0OwoKLyogc29tZSBjb21tb24gc3RyaW5nIGNvbnN0YW50cyAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0VtcHR5W10gPSB7J1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzU3BhY2VbXSA9IHsnICcsICdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc051bUZtdFtdID0geyclJywnZCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzUU1hcmtzW10gPSB7Jz8nLCc/JywnPycsJ1wwJ307CgovKiB3aW5kb3cgY2xhc3MgbmFtZXMgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNXSU5FRklMRUZSQU1FW10gPSB7J1cnLCdGJywnUycsJ18nLCdGJywncicsJ2EnLCdtJywnZScsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzV0lORUZJTEVUUkVFW10gPSB7J1cnLCdGJywnUycsJ18nLCdUJywncicsJ2UnLCdlJywnXDAnfTsKCiNpZmRlZiBfTVNDX1ZFUgovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJJNjQiKSAqLwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdIZXhGbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ1gnLCdcMCd9OwpzdGF0aWMgY29uc3QgVENIQVIgc0xvbmdOdW1GbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ2QnLCdcMCd9OwojZWxzZQovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJMIikgKi8Kc3RhdGljIGNvbnN0IFRDSEFSIHNMb25nSGV4Rm10W10gPSB7JyUnLCdMJywnWCcsJ1wwJ307CnN0YXRpYyBjb25zdCBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnTCcsJ2QnLCdcMCd9OwojZW5kaWYKCgovKiBsb2FkIHJlc291cmNlIHN0cmluZyAqLwpzdGF0aWMgTFBUU1RSIGxvYWRfc3RyaW5nKExQVFNUUiBidWZmZXIsIFVJTlQgaWQpCnsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoKCXJldHVybiBidWZmZXI7Cn0KCiNkZWZpbmUgUlMoYiwgaSkgbG9hZF9zdHJpbmcoYiwgaSkKCgovKiBkaXNwbGF5IGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgV0lOMzIgZXJyb3IgY29kZSAqLwpzdGF0aWMgdm9pZCBkaXNwbGF5X2Vycm9yKEhXTkQgaHduZCwgRFdPUkQgZXJyb3IpCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCVBUU1RSIG1zZzsKCglpZiAoRm9ybWF0TWVzc2FnZShGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVJ8Rk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0sCgkJMCwgZXJyb3IsIE1BS0VMQU5HSUQoTEFOR19ORVVUUkFMLFNVQkxBTkdfREVGQVVMVCksIChQVFNUUikmbXNnLCAwLCBOVUxMKSkKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoJZWxzZQoJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX0VSUk9SKSwgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoKCUxvY2FsRnJlZShtc2cpOwp9CgoKLyogZGlzcGxheSBuZXR3b3JrIGVycm9yIG1lc3NhZ2UgdXNpbmcgV05ldEdldExhc3RFcnJvcigpICovCnN0YXRpYyB2b2lkIGRpc3BsYXlfbmV0d29ya19lcnJvcihIV05EIGh3bmQpCnsKCVRDSEFSIG1zZ1tCVUZGRVJfTEVOXSwgcHJvdmlkZXJbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoJRFdPUkQgZXJyb3I7CgoJaWYgKFdOZXRHZXRMYXN0RXJyb3IoJmVycm9yLCBtc2csIEJVRkZFUl9MRU4sIHByb3ZpZGVyLCBCVUZGRVJfTEVOKSA9PSBOT19FUlJPUikKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lTGljZW5zZShIV05EIFduZCkKewoJVENIQVIgY2FwWzIwXSwgdGV4dFsxMDI0XTsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MSUNFTlNFLCB0ZXh0LCAxMDI0KTsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19MSUNFTlNFX0NBUFRJT04sIGNhcCwgMjApOwoJTWVzc2FnZUJveChXbmQsIHRleHQsIGNhcCwgTUJfSUNPTklORk9STUFUSU9OIHwgTUJfT0spOwp9CgpzdGF0aWMgVk9JRCBXaW5lV2FycmFudHkoSFdORCBXbmQpCnsKCVRDSEFSIGNhcFsyMF0sIHRleHRbMTAyNF07CglMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfV0FSUkFOVFksIHRleHQsIDEwMjQpOwoJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX1dBUlJBTlRZX0NBUFRJT04sIGNhcCwgMjApOwoJTWVzc2FnZUJveChXbmQsIHRleHQsIGNhcCwgTUJfSUNPTkVYQ0xBTUFUSU9OIHwgTUJfT0spOwp9CgoKI2lmZGVmIF9fV0lORV9fCgojaWZkZWYgVU5JQ09ERQoKLyogY2FsbCB2c3dwcmludGYoKSBpbiBtc3ZjcnQuZGxsICovCi8qVE9ETzogZml4IHN3cHJpbnRmKCkgaW4gbm9uLW1zdmNydCBtb2RlLCBzbyB0aGF0IHRoaXMgZHluYW1pYyBsaW5raW5nIGZ1bmN0aW9uIGNhbiBiZSByZW1vdmVkICovCnN0YXRpYyBpbnQgbXN2Y3J0X3N3cHJpbnRmKFdDSEFSKiBidWZmZXIsIGNvbnN0IFdDSEFSKiBmbXQsIC4uLikKewoJc3RhdGljIGludCAoX19jZGVjbCAqcHZzd3ByaW50ZikoV0NIQVIqLCBjb25zdCBXQ0hBUiosIHZhX2xpc3QpID0gTlVMTDsKCXZhX2xpc3QgYXA7CglpbnQgcmV0OwoKCWlmICghcHZzd3ByaW50ZikgewoJCUhNT0RVTEUgaE1vZE1zdmNydCA9IExvYWRMaWJyYXJ5QSgibXN2Y3J0Iik7CgkJcHZzd3ByaW50ZiA9IChpbnQoX19jZGVjbCopKFdDSEFSKixjb25zdCBXQ0hBUiosdmFfbGlzdCkpIEdldFByb2NBZGRyZXNzKGhNb2RNc3ZjcnQsICJ2c3dwcmludGYiKTsKCX0KCgl2YV9zdGFydChhcCwgZm10KTsKCXJldCA9ICgqcHZzd3ByaW50ZikoYnVmZmVyLCBmbXQsIGFwKTsKCXZhX2VuZChhcCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQQ1dTVFIgbXlfd2NzcmNocihMUENXU1RSIHN0ciwgV0NIQVIgYykKewoJTFBDV1NUUiBwID0gc3RyOwoKCXdoaWxlKCpwKQoJCSsrcDsKCglkbyB7CgkJaWYgKC0tcCA8IHN0cikKCQkJcmV0dXJuIE5VTEw7Cgl9IHdoaWxlKCpwICE9IGMpOwoKCXJldHVybiBwOwp9CgojZGVmaW5lIF90Y3NyY2hyIG15X3djc3JjaHIKI2Vsc2UJLyogVU5JQ09ERSAqLwojZGVmaW5lIF90Y3NyY2hyIHN0cnJjaHIKI2VuZGlmCS8qIFVOSUNPREUgKi8KCiNlbmRpZgkvKiBfX1dJTkVfXyAqLwoKCi8qIGFsbG9jYXRlIGFuZCBpbml0aWFsaXNlIGEgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyBFbnRyeSogYWxsb2NfZW50cnkodm9pZCkKewoJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgbWFsbG9jKHNpemVvZihFbnRyeSkpOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgllbnRyeS0+cGlkbCA9IE5VTEw7CgllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCWVudHJ5LT5oaWNvbiA9IDA7CiNlbmRpZgoKCXJldHVybiBlbnRyeTsKfQoKLyogZnJlZSBhIGRpcmVjdG9yeSBlbnRyeSAqLwpzdGF0aWMgdm9pZCBmcmVlX2VudHJ5KEVudHJ5KiBlbnRyeSkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJRGVzdHJveUljb24oZW50cnktPmhpY29uKTsKCglpZiAoZW50cnktPmZvbGRlciAmJiBlbnRyeS0+Zm9sZGVyIT1HbG9iYWxzLmlEZXNrdG9wKQoJCUlTaGVsbEZvbGRlcl9SZWxlYXNlKGVudHJ5LT5mb2xkZXIpOwoKCWlmIChlbnRyeS0+cGlkbCkKCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBlbnRyeS0+cGlkbCk7CiNlbmRpZgoKCWZyZWUoZW50cnkpOwp9CgovKiByZWN1cnNpdmVseSBmcmVlIGFsbCBjaGlsZCBlbnRyaWVzICovCnN0YXRpYyB2b2lkIGZyZWVfZW50cmllcyhFbnRyeSogZGlyKQp7CglFbnRyeSAqZW50cnksICpuZXh0PWRpci0+ZG93bjsKCglpZiAobmV4dCkgewoJCWRpci0+ZG93biA9IDA7CgoJCWRvIHsKCQkJZW50cnkgPSBuZXh0OwoJCQluZXh0ID0gZW50cnktPm5leHQ7CgoJCQlmcmVlX2VudHJpZXMoZW50cnkpOwoJCQlmcmVlX2VudHJ5KGVudHJ5KTsKCQl9IHdoaWxlKG5leHQpOwoJfQp9CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3Rvcnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgcGF0aCkKewoJRW50cnkqIGZpcnN0X2VudHJ5ID0gTlVMTDsKCUVudHJ5KiBsYXN0ID0gTlVMTDsKCUVudHJ5KiBlbnRyeTsKCglpbnQgbGV2ZWwgPSBkaXItPmxldmVsICsgMTsKCVdJTjMyX0ZJTkRfREFUQSB3MzJmZDsKCUhBTkRMRSBoRmluZDsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSEFORExFIGhGaWxlOwojZW5kaWYKCglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdLCAqcDsKCWZvcihwPWJ1ZmZlcjsgKnBhdGg7ICkKCQkqcCsrID0gKnBhdGgrKzsKCgkqcCsrID0gJ1xcJzsKCXBbMF0gPSAnKic7CglwWzFdID0gJ1wwJzsKCgloRmluZCA9IEZpbmRGaXJzdEZpbGUoYnVmZmVyLCAmdzMyZmQpOwoKCWlmIChoRmluZCAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewoJCWRvIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCS8qIGhpZGUgZGlyZWN0b3J5IGVudHJ5ICIuIiAqLwoJCQlpZiAodzMyZmQuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJTFBDVFNUUiBuYW1lID0gdzMyZmQuY0ZpbGVOYW1lOwoKCQkJCWlmIChuYW1lWzBdPT0nLicgJiYgbmFtZVsxXT09J1wwJykKCQkJCQljb250aW51ZTsKCQkJfQojZW5kaWYKCQkJZW50cnkgPSBhbGxvY19lbnRyeSgpOwoKCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQlpZiAobGFzdCkKCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCW1lbWNweSgmZW50cnktPmRhdGEsICZ3MzJmZCwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpOwoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwoJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJbHN0cmNweShwLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoKCQkJaEZpbGUgPSBDcmVhdGVGaWxlKGJ1ZmZlciwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUR8RklMRV9TSEFSRV9XUklURXxGSUxFX1NIQVJFX0RFTEVURSwKCQkJCQkJCQkwLCBPUEVOX0VYSVNUSU5HLCBGSUxFX0ZMQUdfQkFDS1VQX1NFTUFOVElDUywgMCk7CgoJCQlpZiAoaEZpbGUgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKCQkJCWlmIChHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoRmlsZSwgJmVudHJ5LT5iaGZpKSkKCQkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgoJCQkJQ2xvc2VIYW5kbGUoaEZpbGUpOwoJCQl9CiNlbmRpZgoKCQkJbGFzdCA9IGVudHJ5OwoJCX0gd2hpbGUoRmluZE5leHRGaWxlKGhGaW5kLCAmdzMyZmQpKTsKCgkJaWYgKGxhc3QpCgkJCWxhc3QtPm5leHQgPSBOVUxMOwoKCQlGaW5kQ2xvc2UoaEZpbmQpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV93aW4oRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnXFwnKSB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUodG9sb3dlcigqcCsrKSA9PSB0b2xvd2VyKCpxKyspKTsKCgkJcCA9IG5hbWU7CgkJcSA9IGVudHJ5LT5kYXRhLmNBbHRlcm5hdGVGaWxlTmFtZTsKCgkJZG8gewoJCQlpZiAoISpwIHx8ICpwPT1URVhUKCdcXCcpIHx8ICpwPT1URVhUKCcvJykpCgkJCQlyZXR1cm4gZW50cnk7CgkJfSB3aGlsZSh0b2xvd2VyKCpwKyspID09IHRvbG93ZXIoKnErKykpOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfd2luKFJvb3QqIHJvb3QsIExQQ1RTVFIgcGF0aCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJVENIQVIgYnVmZmVyW01BWF9QQVRIXTsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUxQQ1RTVFIgcyA9IHBhdGg7CglQVFNUUiBkID0gYnVmZmVyOwoKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgllbnRyeS0+ZXR5cGUgPSBFVF9XSU5ET1dTOwojZW5kaWYKCgl3aGlsZShlbnRyeSkgewoJCXdoaWxlKCpzICYmICpzIT1URVhUKCdcXCcpICYmICpzIT1URVhUKCcvJykpCgkJCSpkKysgPSAqcysrOwoKCQl3aGlsZSgqcz09VEVYVCgnXFwnKSB8fCAqcz09VEVYVCgnLycpKQoJCQlzKys7CgoJCSpkKysgPSBURVhUKCdcXCcpOwoJCSpkID0gVEVYVCgnXDAnKTsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIGJ1ZmZlciwgc29ydE9yZGVyLCBod25kKTsKCgkJaWYgKGVudHJ5LT5kb3duKQoJCQllbnRyeS0+ZXhwYW5kZWQgPSBUUlVFOwoKCQlpZiAoISpzKQoJCQlicmVhazsKCgkJZW50cnkgPSBmaW5kX2VudHJ5X3dpbihlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCnN0YXRpYyBCT09MIHRpbWVfdG9fZmlsZXRpbWUoY29uc3QgdGltZV90KiB0LCBGSUxFVElNRSogZnRpbWUpCnsKCXN0cnVjdCB0bSogdG0gPSBnbXRpbWUodCk7CglTWVNURU1USU1FIHN0aW1lOwoKCWlmICghdG0pCgkJcmV0dXJuIEZBTFNFOwoKCXN0aW1lLndZZWFyID0gdG0tPnRtX3llYXIrMTkwMDsKCXN0aW1lLndNb250aCA9IHRtLT50bV9tb24rMTsKCS8qCXN0aW1lLndEYXlPZldlZWsgKi8KCXN0aW1lLndEYXkgPSB0bS0+dG1fbWRheTsKCXN0aW1lLndIb3VyID0gdG0tPnRtX2hvdXI7CglzdGltZS53TWludXRlID0gdG0tPnRtX21pbjsKCXN0aW1lLndTZWNvbmQgPSB0bS0+dG1fc2VjOwoKCXJldHVybiBTeXN0ZW1UaW1lVG9GaWxlVGltZSgmc3RpbWUsIGZ0aW1lKTsKfQoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3RvcnlfdW5peChFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgpCnsKCUVudHJ5KiBmaXJzdF9lbnRyeSA9IE5VTEw7CglFbnRyeSogbGFzdCA9IE5VTEw7CglFbnRyeSogZW50cnk7CglESVIqIHBkaXI7CgoJaW50IGxldmVsID0gZGlyLT5sZXZlbCArIDE7CiNpZmRlZiBVTklDT0RFCgljaGFyIGNwYXRoW01BWF9QQVRIXTsKCglXaWRlQ2hhclRvTXVsdGlCeXRlKENQX1VOSVhDUCwgMCwgcGF0aCwgLTEsIGNwYXRoLCBNQVhfUEFUSCwgTlVMTCwgTlVMTCk7CiNlbHNlCgljb25zdCBjaGFyKiBjcGF0aCA9IHBhdGg7CiNlbmRpZgoKCXBkaXIgPSBvcGVuZGlyKGNwYXRoKTsKCglpZiAocGRpcikgewoJCXN0cnVjdCBzdGF0IHN0OwoJCXN0cnVjdCBkaXJlbnQqIGVudDsKCQljaGFyIGJ1ZmZlcltNQVhfUEFUSF0sICpwOwoJCWNvbnN0IGNoYXIqIHM7CgoJCWZvcihwPWJ1ZmZlcixzPWNwYXRoOyAqczsgKQoJCQkqcCsrID0gKnMrKzsKCgkJaWYgKHA9PWJ1ZmZlciB8fCBwWy0xXSE9Jy8nKQoJCQkqcCsrID0gJy8nOwoKCQl3aGlsZSgoZW50PXJlYWRkaXIocGRpcikpKSB7CgkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCWlmICghZmlyc3RfZW50cnkpCgkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJaWYgKGxhc3QpCgkJCQlsYXN0LT5uZXh0ID0gZW50cnk7CgoJCQllbnRyeS0+ZXR5cGUgPSBFVF9VTklYOwoKCQkJc3RyY3B5KHAsIGVudC0+ZF9uYW1lKTsKI2lmZGVmIFVOSUNPREUKCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9VTklYQ1AsIDAsIHAsIC0xLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIE1BWF9QQVRIKTsKI2Vsc2UKCQkJbHN0cmNweShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIHApOwojZW5kaWYKCgkJCWlmICghc3RhdChidWZmZXIsICZzdCkpIHsKCQkJCWVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBwWzBdPT0nLic/IEZJTEVfQVRUUklCVVRFX0hJRERFTjogMDsKCgkJCQlpZiAoU19JU0RJUihzdC5zdF9tb2RlKSkKCQkJCQllbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzIHw9IEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWTsKCgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3cgPSBzdC5zdF9zaXplICYgMHhGRkZGRkZGRjsKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUhpZ2ggPSBzdC5zdF9zaXplID4+IDMyOwoKCQkJCW1lbXNldCgmZW50cnktPmRhdGEuZnRDcmVhdGlvblRpbWUsIDAsIHNpemVvZihGSUxFVElNRSkpOwoJCQkJdGltZV90b19maWxldGltZSgmc3Quc3RfYXRpbWUsICZlbnRyeS0+ZGF0YS5mdExhc3RBY2Nlc3NUaW1lKTsKCQkJCXRpbWVfdG9fZmlsZXRpbWUoJnN0LnN0X210aW1lLCAmZW50cnktPmRhdGEuZnRMYXN0V3JpdGVUaW1lKTsKCgkJCQllbnRyeS0+YmhmaS5uRmlsZUluZGV4TG93ID0gZW50LT5kX2lubzsKCQkJCWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhIaWdoID0gMDsKCgkJCQllbnRyeS0+YmhmaS5uTnVtYmVyT2ZMaW5rcyA9IHN0LnN0X25saW5rOwoKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCQkJfSBlbHNlIHsKCQkJCWVudHJ5LT5kYXRhLm5GaWxlU2l6ZUxvdyA9IDA7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoID0gMDsKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CgkJCX0KCgkJCWVudHJ5LT5kb3duID0gTlVMTDsKCQkJZW50cnktPnVwID0gZGlyOwoJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJZW50cnktPnNjYW5uZWQgPSBGQUxTRTsKCQkJZW50cnktPmxldmVsID0gbGV2ZWw7CgoJCQlsYXN0ID0gZW50cnk7CgkJfQoKCQlpZiAobGFzdCkKCQkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJCWNsb3NlZGlyKHBkaXIpOwoJfQoKCWRpci0+ZG93biA9IGZpcnN0X2VudHJ5OwoJZGlyLT5zY2FubmVkID0gVFJVRTsKfQoKc3RhdGljIEVudHJ5KiBmaW5kX2VudHJ5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBuYW1lKQp7CglFbnRyeSogZW50cnk7CgoJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CgkJTFBDVFNUUiBwID0gbmFtZTsKCQlMUENUU1RSIHEgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUoKnArKyA9PSAqcSsrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfdW5peChSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKCWVudHJ5LT5ldHlwZSA9IEVUX1VOSVg7CgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyE9VEVYVCgnLycpKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnMgPT0gVEVYVCgnLycpKQoJCQlzKys7CgoJCSpkKysgPSBURVhUKCcvJyk7CgkJKmQgPSBURVhUKCdcMCcpOwoKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgYnVmZmVyLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCWlmICghKnMpCgkJCWJyZWFrOwoKCQllbnRyeSA9IGZpbmRfZW50cnlfdW5peChlbnRyeSwgcyk7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKI2VuZGlmIC8qICFkZWZpbmVkKF9OT19FWFRFTlNJT05TKSAmJiBkZWZpbmVkKF9fV0lORV9fKSAqLwoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoKI2lmZGVmIFVOSUNPREUKI2RlZmluZQlnZXRfc3RycmV0IGdldF9zdHJyZXRXCiNkZWZpbmUJcGF0aF9mcm9tX3BpZGwgcGF0aF9mcm9tX3BpZGxXCiNlbHNlCiNkZWZpbmUJZ2V0X3N0cnJldCBnZXRfc3RycmV0QQojZGVmaW5lCXBhdGhfZnJvbV9waWRsIHBhdGhfZnJvbV9waWRsQQojZW5kaWYKCgpzdGF0aWMgdm9pZCBmcmVlX3N0cnJldChTVFJSRVQqIHN0cikKewoJaWYgKHN0ci0+dVR5cGUgPT0gU1RSUkVUX1dTVFIpCgkJSU1hbGxvY19GcmVlKEdsb2JhbHMuaU1hbGxvYywgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0cikpOwp9CgoKI2lmbmRlZiBVTklDT0RFCgpzdGF0aWMgTFBTVFIgc3RyY3B5bihMUFNUUiBkZXN0LCBMUENTVFIgc291cmNlLCBzaXplX3QgY291bnQpCnsKIExQQ1NUUiBzOwogTFBTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0QShTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKIHN3aXRjaChzdHItPnVUeXBlKSB7CiAgY2FzZSBTVFJSRVRfV1NUUjoKCVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSwgLTEsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9PRkZTRVQ6CglzdHJjcHluKGJ1ZmZlciwgKExQQ1NUUilzaGlpZCtzdHItPlVOSU9OX01FTUJFUih1T2Zmc2V0KSwgbGVuKTsKCWJyZWFrOwoKICBjYXNlIFNUUlJFVF9DU1RSOgoJc3RyY3B5bihidWZmZXIsIHN0ci0+VU5JT05fTUVNQkVSKGNTdHIpLCBsZW4pOwogfQp9CgpzdGF0aWMgSFJFU1VMVCBwYXRoX2Zyb21fcGlkbEEoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKCVNUUlJFVCBzdHI7CgoJIC8qIFNIR0ROX0ZPUlBBUlNJTkc6IGdldCBmdWxsIHBhdGggb2YgaWQgbGlzdCAqLwoJSFJFU1VMVCBociA9IElTaGVsbEZvbGRlcl9HZXREaXNwbGF5TmFtZU9mKGZvbGRlciwgcGlkbCwgU0hHRE5fRk9SUEFSU0lORywgJnN0cik7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlnZXRfc3RycmV0QSgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCiNlbmRpZgoKc3RhdGljIExQV1NUUiB3Y3NjcHluKExQV1NUUiBkZXN0LCBMUENXU1RSIHNvdXJjZSwgc2l6ZV90IGNvdW50KQp7CiBMUENXU1RSIHM7CiBMUFdTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgpzdGF0aWMgdm9pZCBnZXRfc3RycmV0VyhTVFJSRVQqIHN0ciwgY29uc3QgU0hJVEVNSUQqIHNoaWlkLCBMUFdTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CiBzd2l0Y2goc3RyLT51VHlwZSkgewogIGNhc2UgU1RSUkVUX1dTVFI6Cgl3Y3NjcHluKGJ1ZmZlciwgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0ciksIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfT0ZGU0VUOgoJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChMUENTVFIpc2hpaWQrc3RyLT5VTklPTl9NRU1CRVIodU9mZnNldCksIC0xLCBidWZmZXIsIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfQ1NUUjoKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHItPlVOSU9OX01FTUJFUihjU3RyKSwgLTEsIGJ1ZmZlciwgbGVuKTsKIH0KfQoKCnN0YXRpYyBIUkVTVUxUIG5hbWVfZnJvbV9waWRsKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBUU1RSIGJ1ZmZlciwgaW50IGxlbiwgU0hHRE5GIGZsYWdzKQp7CglTVFJSRVQgc3RyOwoKCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0RGlzcGxheU5hbWVPZihmb2xkZXIsIHBpZGwsIGZsYWdzLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXQoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKc3RhdGljIEhSRVNVTFQgcGF0aF9mcm9tX3BpZGxXKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBXU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gSVNoZWxsRm9sZGVyX0dldERpc3BsYXlOYW1lT2YoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRXKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKCiAvKiBjcmVhdGUgYW4gaXRlbSBpZCBsaXN0IGZyb20gYSBmaWxlIHN5c3RlbSBwYXRoICovCgpzdGF0aWMgTFBJVEVNSURMSVNUIGdldF9wYXRoX3BpZGwoTFBUU1RSIHBhdGgsIEhXTkQgaHduZCkKewoJTFBJVEVNSURMSVNUIHBpZGw7CglIUkVTVUxUIGhyOwoJVUxPTkcgbGVuOwoKI2lmZGVmIFVOSUNPREUKCUxQV1NUUiBidWZmZXIgPSBwYXRoOwojZWxzZQoJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwYXRoLCAtMSwgYnVmZmVyLCBNQVhfUEFUSCk7CiNlbmRpZgoKCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CglpZiAoRkFJTEVEKGhyKSkKCQlyZXR1cm4gTlVMTDsKCglyZXR1cm4gcGlkbDsKfQoKCiAvKiBjb252ZXJ0IGFuIGl0ZW0gaWQgbGlzdCBmcm9tIHJlbGF0aXZlIHRvIGFic29sdXRlICg9cmVsYXRpdmUgdG8gdGhlIGRlc2t0b3ApIGZvcm1hdCAqLwoKc3RhdGljIExQSVRFTUlETElTVCBnZXRfdG9fYWJzb2x1dGVfcGlkbChFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJaWYgKGVudHJ5LT51cCAmJiBlbnRyeS0+dXAtPmV0eXBlPT1FVF9TSEVMTCkgewoJCUlTaGVsbEZvbGRlciogZm9sZGVyID0gZW50cnktPnVwLT5mb2xkZXI7CgkJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCgkJSFJFU1VMVCBociA9IHBhdGhfZnJvbV9waWRsVyhmb2xkZXIsIGVudHJ5LT5waWRsLCBidWZmZXIsIE1BWF9QQVRIKTsKCgkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJTFBJVEVNSURMSVNUIHBpZGw7CgkJCVVMT05HIGxlbjsKCgkJCWhyID0gSVNoZWxsRm9sZGVyX1BhcnNlRGlzcGxheU5hbWUoR2xvYmFscy5pRGVza3RvcCwgaHduZCwgTlVMTCwgYnVmZmVyLCAmbGVuLCAmcGlkbCwgTlVMTCk7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCXJldHVybiBwaWRsOwoJCX0KCX0gZWxzZSBpZiAoZW50cnktPmV0eXBlID09IEVUX1dJTkRPV1MpIHsKCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCgkJZ2V0X3BhdGgoZW50cnksIHBhdGgpOwoKCQlyZXR1cm4gZ2V0X3BhdGhfcGlkbChwYXRoLCBod25kKTsKCX0gZWxzZSBpZiAoZW50cnktPnBpZGwpCgkJcmV0dXJuIElMQ2xvbmUoZW50cnktPnBpZGwpOwoKCXJldHVybiBOVUxMOwp9CgoKc3RhdGljIEhJQ09OIGV4dHJhY3RfaWNvbihJU2hlbGxGb2xkZXIqIGZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CglJRXh0cmFjdEljb24qIHBFeHRyYWN0OwoKCWlmIChTVUNDRUVERUQoSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YoZm9sZGVyLCAwLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGwsICZJSURfSUV4dHJhY3RJY29uLCAwLCAoTFBWT0lEKikmcEV4dHJhY3QpKSkgewoJCVRDSEFSIHBhdGhbX01BWF9QQVRIXTsKCQl1bnNpZ25lZCBmbGFnczsKCQlISUNPTiBoaWNvbjsKCQlpbnQgaWR4OwoKCQlpZiAoU1VDQ0VFREVEKElFeHRyYWN0SWNvbldfR2V0SWNvbkxvY2F0aW9uKHBFeHRyYWN0LCBHSUxfRk9SU0hFTEwsIHBhdGgsIF9NQVhfUEFUSCwgJmlkeCwgJmZsYWdzKSkpIHsKCQkJaWYgKCEoZmxhZ3MgJiBHSUxfTk9URklMRU5BTUUpKSB7CgkJCQlpZiAoaWR4ID09IC0xKQoJCQkJCWlkeCA9IDA7CS8qIHNwZWNpYWwgY2FzZSBmb3Igc29tZSBjb250cm9sIHBhbmVsIGFwcGxpY2F0aW9ucyAqLwoKCQkJCWlmICgoaW50KUV4dHJhY3RJY29uRXgocGF0aCwgaWR4LCAwLCAmaGljb24sIDEpID4gMCkKCQkJCQlmbGFncyAmPSB+R0lMX0RPTlRDQUNIRTsKCQkJfSBlbHNlIHsKCQkJCUhJQ09OIGhJY29uTGFyZ2UgPSAwOwoKCQkJCUhSRVNVTFQgaHIgPSBJRXh0cmFjdEljb25XX0V4dHJhY3QocEV4dHJhY3QsIHBhdGgsIGlkeCwgJmhJY29uTGFyZ2UsICZoaWNvbiwgTUFLRUxPTkcoMC8qR2V0U3lzdGVtTWV0cmljcyhTTV9DWElDT04pKi8sR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTikpKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCQlEZXN0cm95SWNvbihoSWNvbkxhcmdlKTsKCQkJfQoKCQkJcmV0dXJuIGhpY29uOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV9zaGVsbChFbnRyeSogZGlyLCBMUENJVEVNSURMSVNUIHBpZGwpCnsKCUVudHJ5KiBlbnRyeTsKCglmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpIHsKCQlpZiAoZW50cnktPnBpZGwtPm1raWQuY2IgPT0gcGlkbC0+bWtpZC5jYiAmJgoJCQkhbWVtY21wKGVudHJ5LT5waWRsLCBwaWRsLCBlbnRyeS0+cGlkbC0+bWtpZC5jYikpCgkJCXJldHVybiBlbnRyeTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWVfc2hlbGwoUm9vdCogcm9vdCwgTFBJVEVNSURMSVNUIHBpZGwsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCUVudHJ5KiBlbnRyeSA9ICZyb290LT5lbnRyeTsKCUVudHJ5KiBuZXh0OwoJTFBJVEVNSURMSVNUIG5leHRfcGlkbCA9IHBpZGw7CglJU2hlbGxGb2xkZXIqIGZvbGRlcjsKCUlTaGVsbEZvbGRlciogY2hpbGQgPSBOVUxMOwoJSFJFU1VMVCBocjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJZW50cnktPmV0eXBlID0gRVRfU0hFTEw7CiNlbmRpZgoKCWZvbGRlciA9IEdsb2JhbHMuaURlc2t0b3A7CgoJd2hpbGUoZW50cnkpIHsKCQllbnRyeS0+cGlkbCA9IG5leHRfcGlkbDsKCQllbnRyeS0+Zm9sZGVyID0gZm9sZGVyOwoKCQlpZiAoIXBpZGwtPm1raWQuY2IpCgkJCWJyZWFrOwoKCQkgLyogY29weSBmaXJzdCBlbGVtZW50IG9mIGl0ZW0gaWRsaXN0ICovCgkJbmV4dF9waWRsID0gSU1hbGxvY19BbGxvYyhHbG9iYWxzLmlNYWxsb2MsIHBpZGwtPm1raWQuY2Irc2l6ZW9mKFVTSE9SVCkpOwoJCW1lbWNweShuZXh0X3BpZGwsIHBpZGwsIHBpZGwtPm1raWQuY2IpOwoJCSgoTFBJVEVNSURMSVNUKSgoTFBCWVRFKW5leHRfcGlkbCtwaWRsLT5ta2lkLmNiKSktPm1raWQuY2IgPSAwOwoKCQlociA9IElTaGVsbEZvbGRlcl9CaW5kVG9PYmplY3QoZm9sZGVyLCBuZXh0X3BpZGwsIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgkJaWYgKCFTVUNDRUVERUQoaHIpKQoJCQlicmVhazsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIE5VTEwsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJbmV4dCA9IGZpbmRfZW50cnlfc2hlbGwoZW50cnksIG5leHRfcGlkbCk7CgkJaWYgKCFuZXh0KQoJCQlicmVhazsKCgkJZm9sZGVyID0gY2hpbGQ7CgkJZW50cnkgPSBuZXh0OwoKCQkgLyogZ28gdG8gbmV4dCBlbGVtZW50ICovCgkJcGlkbCA9IChMUElURU1JRExJU1QpICgoTFBCWVRFKXBpZGwrcGlkbC0+bWtpZC5jYik7Cgl9CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwoKCXJldHVybiBlbnRyeTsKfQoKCnN0YXRpYyB2b2lkIGZpbGxfdzMyZmRhdGFfc2hlbGwoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCwgU0ZHQU9GIGF0dHJpYnMsIFdJTjMyX0ZJTkRfREFUQSogdzMyZmRhdGEpCnsKCWlmICghKGF0dHJpYnMgJiBTRkdBT19GSUxFU1lTVEVNKSB8fAoJCSAgRkFJTEVEKFNIR2V0RGF0YUZyb21JRExpc3QoZm9sZGVyLCBwaWRsLCBTSEdERklMX0ZJTkREQVRBLCB3MzJmZGF0YSwgc2l6ZW9mKFdJTjMyX0ZJTkRfREFUQSkpKSkgewoJCVdJTjMyX0ZJTEVfQVRUUklCVVRFX0RBVEEgZmFkOwoJCUlEYXRhT2JqZWN0KiBwRGF0YU9iajsKCgkJU1RHTUVESVVNIG1lZGl1bSA9IHswLCB7MH0sIDB9OwoJCUZPUk1BVEVUQyBmbXQgPSB7R2xvYmFscy5jZlN0ckZOYW1lLCAwLCBEVkFTUEVDVF9DT05URU5ULCAtMSwgVFlNRURfSEdMT0JBTH07CgoJCUhSRVNVTFQgaHIgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihmb2xkZXIsIDAsIDEsICZwaWRsLCAmSUlEX0lEYXRhT2JqZWN0LCAwLCAoTFBWT0lEKikmcERhdGFPYmopOwoKCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQlociA9IElEYXRhT2JqZWN0X0dldERhdGEocERhdGFPYmosICZmbXQsICZtZWRpdW0pOwoKCQkJSURhdGFPYmplY3RfUmVsZWFzZShwRGF0YU9iaik7CgoJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJTFBDVFNUUiBwYXRoID0gKExQQ1RTVFIpR2xvYmFsTG9jayhtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCgkJCQlpZiAoR2V0RmlsZUF0dHJpYnV0ZXNFeChwYXRoLCBHZXRGaWxlRXhJbmZvU3RhbmRhcmQsICZmYWQpKSB7CgkJCQkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgPSBmYWQuZHdGaWxlQXR0cmlidXRlczsKCQkJCQl3MzJmZGF0YS0+ZnRDcmVhdGlvblRpbWUgPSBmYWQuZnRDcmVhdGlvblRpbWU7CgkJCQkJdzMyZmRhdGEtPmZ0TGFzdEFjY2Vzc1RpbWUgPSBmYWQuZnRMYXN0QWNjZXNzVGltZTsKCQkJCQl3MzJmZGF0YS0+ZnRMYXN0V3JpdGVUaW1lID0gZmFkLmZ0TGFzdFdyaXRlVGltZTsKCgkJCQkJaWYgKCEoZmFkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpKSB7CgkJCQkJCXczMmZkYXRhLT5uRmlsZVNpemVMb3cgPSBmYWQubkZpbGVTaXplTG93OwoJCQkJCQl3MzJmZGF0YS0+bkZpbGVTaXplSGlnaCA9IGZhZC5uRmlsZVNpemVIaWdoOwoJCQkJCX0KCQkJCX0KCgkJCQlTZXRFcnJvck1vZGUoc2VtX29yZyk7CgoJCQkJR2xvYmFsVW5sb2NrKG1lZGl1bS5VTklPTl9NRU1CRVIoaEdsb2JhbCkpOwoJCQkJR2xvYmFsRnJlZShtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJfQoJCX0KCX0KCglpZiAoYXR0cmlicyAmIChTRkdBT19GT0xERVJ8U0ZHQU9fSEFTU1VCRk9MREVSKSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJaWYgKGF0dHJpYnMgJiBTRkdBT19SRUFET05MWSkKCQl3MzJmZGF0YS0+ZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9SRUFET05MWTsKCglpZiAoYXR0cmlicyAmIFNGR0FPX0NPTVBSRVNTRUQpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRDsKfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3NoZWxsKEVudHJ5KiBkaXIsIEhXTkQgaHduZCkKewoJSVNoZWxsRm9sZGVyKiBmb2xkZXIgPSBkaXItPmZvbGRlcjsKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoJSFJFU1VMVCBocjsKCglJU2hlbGxGb2xkZXIqIGNoaWxkOwoJSUVudW1JRExpc3QqIGlkbGlzdDsKCglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWlmICghZm9sZGVyKQoJCXJldHVybjsKCglociA9IElTaGVsbEZvbGRlcl9FbnVtT2JqZWN0cyhmb2xkZXIsIGh3bmQsIFNIQ09OVEZfRk9MREVSU3xTSENPTlRGX05PTkZPTERFUlN8U0hDT05URl9JTkNMVURFSElEREVOfFNIQ09OVEZfU0hBUkVBQkxFfFNIQ09OVEZfU1RPUkFHRSwgJmlkbGlzdCk7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlmb3IoOzspIHsKI2RlZmluZQlGRVRDSF9JVEVNX0NPVU5UCTMyCgkJCUxQSVRFTUlETElTVCBwaWRsc1tGRVRDSF9JVEVNX0NPVU5UXTsKCQkJU0ZHQU9GIGF0dHJpYnM7CgkJCVVMT05HIGNudCA9IDA7CgkJCVVMT05HIG47CgoJCQltZW1zZXQocGlkbHMsIDAsIHNpemVvZihwaWRscykpOwoKCQkJaHIgPSBJRW51bUlETGlzdF9OZXh0KGlkbGlzdCwgRkVUQ0hfSVRFTV9DT1VOVCwgcGlkbHMsICZjbnQpOwoJCQlpZiAoIVNVQ0NFRURFRChocikpCgkJCQlicmVhazsKCgkJCWlmIChociA9PSBTX0ZBTFNFKQoJCQkJYnJlYWs7CgoJCQlmb3Iobj0wOyBuPGNudDsgKytuKSB7CgkJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQkJaWYgKCFmaXJzdF9lbnRyeSkKCQkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJCWlmIChsYXN0KQoJCQkJCWxhc3QtPm5leHQgPSBlbnRyeTsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLCAwLCBzaXplb2YoV0lOMzJfRklORF9EQVRBKSk7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoKCQkJCWF0dHJpYnMgPSB+U0ZHQU9fRklMRVNZU1RFTTsJLypTRkdBT19IQVNTVUJGT0xERVJ8U0ZHQU9fRk9MREVSOyBTRkdBT19GSUxFU1lTVEVNIHNvcmd0IGRhZvxyLCBkYd8gIk15IERvY3VtZW50cyIgYW5zdGF0dCB2b24gIk1hcnRpbidzIERvY3VtZW50cyIgYW5nZXplaWd0IHdpcmQgKi8KCgkJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZm9sZGVyLCAxLCAoTFBDSVRFTUlETElTVCopJnBpZGxzW25dLCAmYXR0cmlicyk7CgoJCQkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJCQlpZiAoYXR0cmlicyAhPSAoU0ZHQU9GKX5TRkdBT19GSUxFU1lTVEVNKSB7CgkJCQkJCWZpbGxfdzMyZmRhdGFfc2hlbGwoZm9sZGVyLCBwaWRsc1tuXSwgYXR0cmlicywgJmVudHJ5LT5kYXRhKTsKCgkJCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gVFJVRTsKCQkJCQl9IGVsc2UKCQkJCQkJYXR0cmlicyA9IDA7CgkJCQl9IGVsc2UKCQkJCQlhdHRyaWJzID0gMDsKCgkJCQllbnRyeS0+cGlkbCA9IHBpZGxzW25dOwoKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJaHIgPSBJU2hlbGxGb2xkZXJfQmluZFRvT2JqZWN0KGZvbGRlciwgcGlkbHNbbl0sIDAsICZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCoqKSZjaGlsZCk7CgoJCQkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gY2hpbGQ7CgkJCQkJZWxzZQoJCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCQkJCX0KCQkJCWVsc2UKCQkJCQllbnRyeS0+Zm9sZGVyID0gTlVMTDsKCgkJCQlpZiAoIWVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXSkKCQkJCQkvKmhyID0gKi9uYW1lX2Zyb21fcGlkbChmb2xkZXIsIHBpZGxzW25dLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIE1BWF9QQVRILCAvKlNIR0ROX0lORk9MREVSKi8weDIwMDAvKjB4MjAwMD1TSEdETl9JTkNMVURFX05PTkZJTEVTWVMqLyk7CgoJCQkJIC8qIGdldCBkaXNwbGF5IGljb25zIGZvciBmaWxlcyBhbmQgdmlydHVhbCBvYmplY3RzICovCgkJCQlpZiAoIShlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB8fAoJCQkJCSEoYXR0cmlicyAmIFNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCQkJZW50cnktPmhpY29uID0gZXh0cmFjdF9pY29uKGZvbGRlciwgcGlkbHNbbl0pOwoKCQkJCQlpZiAoIWVudHJ5LT5oaWNvbikKCQkJCQkJZW50cnktPmhpY29uID0gKEhJQ09OKS0xOwkvKiBkb24ndCB0cnkgYWdhaW4gbGF0ZXIgKi8KCQkJCX0KCgkJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCQllbnRyeS0+dXAgPSBkaXI7CgkJCQllbnRyeS0+ZXhwYW5kZWQgPSBGQUxTRTsKCQkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJCWVudHJ5LT5ldHlwZSA9IEVUX1NIRUxMOwoJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKI2VuZGlmCgoJCQkJbGFzdCA9IGVudHJ5OwoJCQl9CgkJfQoKCQlJRW51bUlETGlzdF9SZWxlYXNlKGlkbGlzdCk7Cgl9CgoJaWYgKGxhc3QpCgkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJZGlyLT5kb3duID0gZmlyc3RfZW50cnk7CglkaXItPnNjYW5uZWQgPSBUUlVFOwp9CgojZW5kaWYgLyogX1NIRUxMX0ZPTERFUlMgKi8KCgovKiBzb3J0IG9yZGVyIGZvciBkaWZmZXJlbnQgZGlyZWN0b3J5L2ZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX09SREVSIHsKCVRPX0RJUiA9IDAsCglUT19ET1QgPSAxLAoJVE9fRE9URE9UID0gMiwKCVRPX09USEVSX0RJUiA9IDMsCglUT19GSUxFID0gNAp9OwoKLyogZGlzdGluZ3Vpc2ggYmV0d2VlbiAiLiIsICIuLiIgYW5kIGFueSBvdGhlciBkaXJlY3RvcnkgbmFtZXMgKi8Kc3RhdGljIGludCBUeXBlT3JkZXJGcm9tRGlybmFtZShMUENUU1RSIG5hbWUpCnsKCWlmIChuYW1lWzBdID09ICcuJykgewoJCWlmIChuYW1lWzFdID09ICdcMCcpCgkJCXJldHVybiBUT19ET1Q7CS8qICIuIiAqLwoKCQlpZiAobmFtZVsxXT09Jy4nICYmIG5hbWVbMl09PSdcMCcpCgkJCXJldHVybiBUT19ET1RET1Q7CS8qICIuLiIgKi8KCX0KCglyZXR1cm4gVE9fT1RIRVJfRElSOwkvKiBhbnl0aGluZyBlbHNlICovCn0KCi8qIGRpcmVjdG9yaWVzIGZpcnN0Li4uICovCnN0YXRpYyBpbnQgY29tcGFyZVR5cGUoY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEsIGNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyKQp7CglpbnQgb3JkZXIxID0gZmQxLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CglpbnQgb3JkZXIyID0gZmQyLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CgoJLyogSGFuZGxlICIuIiBhbmQgIi4uIiBhcyBzcGVjaWFsIGNhc2UgYW5kIG1vdmUgdGhlbSBhdCB0aGUgdmVyeSBmaXJzdCBiZWdpbm5pbmcuICovCglpZiAob3JkZXIxPT1UT19ESVIgJiYgb3JkZXIyPT1UT19ESVIpIHsKCQlvcmRlcjEgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDEtPmNGaWxlTmFtZSk7CgkJb3JkZXIyID0gVHlwZU9yZGVyRnJvbURpcm5hbWUoZmQyLT5jRmlsZU5hbWUpOwoJfQoKCXJldHVybiBvcmRlcjI9PW9yZGVyMT8gMDogb3JkZXIxPG9yZGVyMj8gLTE6IDE7Cn0KCgpzdGF0aWMgaW50IGNvbXBhcmVOYW1lKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKGZkMS0+Y0ZpbGVOYW1lLCBmZDItPmNGaWxlTmFtZSk7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZUV4dChjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCWNvbnN0IFRDSEFSICpuYW1lMSwgKm5hbWUyLCAqZXh0MSwgKmV4dDI7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgluYW1lMSA9IGZkMS0+Y0ZpbGVOYW1lOwoJbmFtZTIgPSBmZDItPmNGaWxlTmFtZTsKCglleHQxID0gX3Rjc3JjaHIobmFtZTEsIFRFWFQoJy4nKSk7CglleHQyID0gX3Rjc3JjaHIobmFtZTIsIFRFWFQoJy4nKSk7CgoJaWYgKGV4dDEpCgkJZXh0MSsrOwoJZWxzZQoJCWV4dDEgPSBzRW1wdHk7CgoJaWYgKGV4dDIpCgkJZXh0MisrOwoJZWxzZQoJCWV4dDIgPSBzRW1wdHk7CgoJY21wID0gbHN0cmNtcGkoZXh0MSwgZXh0Mik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKG5hbWUxLCBuYW1lMik7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZVNpemUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUhpZ2ggLSBmZDEtPm5GaWxlU2l6ZUhpZ2g7CgoJaWYgKGNtcCA8IDApCgkJcmV0dXJuIC0xOwoJZWxzZSBpZiAoY21wID4gMCkKCQlyZXR1cm4gMTsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUxvdyAtIGZkMS0+bkZpbGVTaXplTG93OwoKCXJldHVybiBjbXA8MD8gLTE6IGNtcD4wPyAxOiAwOwp9CgpzdGF0aWMgaW50IGNvbXBhcmVEYXRlKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIENvbXBhcmVGaWxlVGltZSgmZmQyLT5mdExhc3RXcml0ZVRpbWUsICZmZDEtPmZ0TGFzdFdyaXRlVGltZSk7Cn0KCgpzdGF0aWMgaW50ICgqc29ydEZ1bmN0aW9uc1tdKShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKSA9IHsKCWNvbXBhcmVOYW1lLAkvKiBTT1JUX05BTUUgKi8KCWNvbXBhcmVFeHQsCQkvKiBTT1JUX0VYVCAqLwoJY29tcGFyZVNpemUsCS8qIFNPUlRfU0laRSAqLwoJY29tcGFyZURhdGUJCS8qIFNPUlRfREFURSAqLwp9OwoKCnN0YXRpYyB2b2lkIFNvcnREaXJlY3RvcnkoRW50cnkqIGRpciwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCUVudHJ5KiBlbnRyeSA9IGRpci0+ZG93bjsKCUVudHJ5KiogYXJyYXksICoqcDsKCWludCBsZW47CgoJbGVuID0gMDsKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQlsZW4rKzsKCglpZiAobGVuKSB7CgkJYXJyYXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihFbnRyeSopKTsKCgkJcCA9IGFycmF5OwoJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJKnArKyA9IGVudHJ5OwoKCQkvKiBjYWxsIHFzb3J0IHdpdGggdGhlIGFwcHJvcHJpYXRlIGNvbXBhcmUgZnVuY3Rpb24gKi8KCQlxc29ydChhcnJheSwgbGVuLCBzaXplb2YoYXJyYXlbMF0pLCBzb3J0RnVuY3Rpb25zW3NvcnRPcmRlcl0pOwoKCQlkaXItPmRvd24gPSBhcnJheVswXTsKCgkJZm9yKHA9YXJyYXk7IC0tbGVuOyBwKyspCgkJCXBbMF0tPm5leHQgPSBwWzFdOwoKCQkoKnApLT5uZXh0ID0gMDsKCiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcnJheSk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeShFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnk7CglMUENUU1RSIHM7CglQVFNUUiBkOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeV9zaGVsbChkaXIsIGh3bmQpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCXJlYWRfZGlyZWN0b3J5X3NoZWxsKGVudHJ5LCBod25kKTsKCQkJCQlTb3J0RGlyZWN0b3J5KGVudHJ5LCBzb3J0T3JkZXIpOwoJCQkJfQoJCX0KCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmIChkaXItPmV0eXBlID09IEVUX1VOSVgpCgl7CgkJcmVhZF9kaXJlY3RvcnlfdW5peChkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJy8nKTsKCgkJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJCWlmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCQkJbHN0cmNweShkLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpOwoJCQkJCXJlYWRfZGlyZWN0b3J5X3VuaXgoZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgllbHNlCiNlbmRpZgoJewoJCXJlYWRfZGlyZWN0b3J5X3dpbihkaXIsIHBhdGgpOwoKCQlpZiAoR2xvYmFscy5wcmVzY2FuX25vZGUpIHsKCQkJcyA9IHBhdGg7CgkJCWQgPSBidWZmZXI7CgoJCQl3aGlsZSgqcykKCQkJCSpkKysgPSAqcysrOwoKCQkJKmQrKyA9IFRFWFQoJ1xcJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWxzdHJjcHkoZCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCQkJCQlyZWFkX2RpcmVjdG9yeV93aW4oZW50cnksIGJ1ZmZlcik7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgoJU29ydERpcmVjdG9yeShkaXIsIHNvcnRPcmRlcik7Cn0KCgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZShSb290KiByb290LCBMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBMUFRTVFIgZHJ2LCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCXN0YXRpYyBjb25zdCBUQ0hBUiBzU2xhc2hbXSA9IHsnLycsICdcMCd9OwojZW5kaWYKCXN0YXRpYyBjb25zdCBUQ0hBUiBzQmFja3NsYXNoW10gPSB7J1xcJywgJ1wwJ307CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChwaWRsKQoJewoJCSAvKiByZWFkIHNoZWxsIG5hbWVzcGFjZSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IERSSVZFX1VOS05PV047CgkJZHJ2WzBdID0gJ1xcJzsKCQlkcnZbMV0gPSAnXDAnOwoJCWxvYWRfc3RyaW5nKHJvb3QtPnZvbG5hbWUsIElEU19ERVNLVE9QKTsKCQlyb290LT5mc19mbGFncyA9IDA7CgkJbG9hZF9zdHJpbmcocm9vdC0+ZnMsIElEU19TSEVMTCk7CgoJCXJldHVybiByZWFkX3RyZWVfc2hlbGwocm9vdCwgcGlkbCwgc29ydE9yZGVyLCBod25kKTsKCX0KCWVsc2UKI2VuZGlmCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKCWlmICgqcGF0aCA9PSAnLycpCgl7CgkJIC8qIHJlYWQgdW5peCBmaWxlIHN5c3RlbSB0cmVlICovCgkJcm9vdC0+ZHJpdmVfdHlwZSA9IEdldERyaXZlVHlwZShwYXRoKTsKCgkJbHN0cmNhdChkcnYsIHNTbGFzaCk7CgkJbG9hZF9zdHJpbmcocm9vdC0+dm9sbmFtZSwgSURTX1JPT1RfRlMpOwoJCXJvb3QtPmZzX2ZsYWdzID0gMDsKCQlsb2FkX3N0cmluZyhyb290LT5mcywgSURTX1VOSVhGUyk7CgoJCWxzdHJjcHkocm9vdC0+cGF0aCwgc1NsYXNoKTsKCgkJcmV0dXJuIHJlYWRfdHJlZV91bml4KHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cgl9CiNlbmRpZgoKCSAvKiByZWFkIFdJTjMyIGZpbGUgc3lzdGVtIHRyZWUgKi8KCXJvb3QtPmRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGUocGF0aCk7CgoJbHN0cmNhdChkcnYsIHNCYWNrc2xhc2gpOwoJR2V0Vm9sdW1lSW5mb3JtYXRpb24oZHJ2LCByb290LT52b2xuYW1lLCBfTUFYX0ZOQU1FLCAwLCAwLCAmcm9vdC0+ZnNfZmxhZ3MsIHJvb3QtPmZzLCBfTUFYX0RJUik7CgoJbHN0cmNweShyb290LT5wYXRoLCBkcnYpOwoKCXJldHVybiByZWFkX3RyZWVfd2luKHJvb3QsIHBhdGgsIHNvcnRPcmRlciwgaHduZCk7Cn0KCgovKiBmbGFncyB0byBmaWx0ZXIgZGlmZmVyZW50IGZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX0ZJTFRFUiB7CglURl9ESVJFQ1RPUklFUwk9IDB4MDEsCglURl9QUk9HUkFNUwkJPSAweDAyLAoJVEZfRE9DVU1FTlRTCT0gMHgwNCwKCVRGX09USEVSUwkJPSAweDA4LAoJVEZfSElEREVOCQk9IDB4MTAsCglURl9BTEwJCQk9IDB4MUYKfTsKCgpzdGF0aWMgQ2hpbGRXbmQqIGFsbG9jX2NoaWxkX3dpbmRvdyhMUENUU1RSIHBhdGgsIExQSVRFTUlETElTVCBwaWRsLCBIV05EIGh3bmQpCnsKCVRDSEFSIGRydltfTUFYX0RSSVZFKzFdLCBkaXJbX01BWF9ESVJdLCBuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJVENIQVIgZGlyX3BhdGhbTUFYX1BBVEhdOwoJVENIQVIgYjFbQlVGRkVSX0xFTl07CglzdGF0aWMgY29uc3QgVENIQVIgc0FzdGVyaWNzW10gPSB7JyonLCAnXDAnfTsKCglDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBtYWxsb2Moc2l6ZW9mKENoaWxkV25kKSk7CglSb290KiByb290ID0gJmNoaWxkLT5yb290OwoJRW50cnkqIGVudHJ5OwoKCW1lbXNldChjaGlsZCwgMCwgc2l6ZW9mKENoaWxkV25kKSk7CgoJY2hpbGQtPmxlZnQudHJlZVBhbmUgPSBUUlVFOwoJY2hpbGQtPmxlZnQudmlzaWJsZV9jb2xzID0gMDsKCgljaGlsZC0+cmlnaHQudHJlZVBhbmUgPSBGQUxTRTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJY2hpbGQtPnJpZ2h0LnZpc2libGVfY29scyA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTfENPTF9JTkRFWHxDT0xfTElOS1M7CiNlbHNlCgljaGlsZC0+cmlnaHQudmlzaWJsZV9jb2xzID0gQ09MX1NJWkV8Q09MX0RBVEV8Q09MX1RJTUV8Q09MX0FUVFJJQlVURVM7CiNlbmRpZgoKCWNoaWxkLT5wb3MubGVuZ3RoID0gc2l6ZW9mKFdJTkRPV1BMQUNFTUVOVCk7CgljaGlsZC0+cG9zLmZsYWdzID0gMDsKCWNoaWxkLT5wb3Muc2hvd0NtZCA9IFNXX1NIT1dOT1JNQUw7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wID0gQ1dfVVNFREVGQVVMVDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gQ1dfVVNFREVGQVVMVDsKCgljaGlsZC0+Zm9jdXNfcGFuZSA9IDA7CgljaGlsZC0+c3BsaXRfcG9zID0gREVGQVVMVF9TUExJVF9QT1M7CgljaGlsZC0+c29ydE9yZGVyID0gU09SVF9OQU1FOwoJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IEZBTFNFOwoKCWlmIChwYXRoKQoJewoJCWxzdHJjcHkoY2hpbGQtPnBhdGgsIHBhdGgpOwoKCQlfdHNwbGl0cGF0aChwYXRoLCBkcnYsIGRpciwgbmFtZSwgZXh0KTsKCX0KCglsc3RyY3B5KGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgc0FzdGVyaWNzKTsKCWNoaWxkLT5maWx0ZXJfZmxhZ3MgPSBURl9BTEw7CgoJcm9vdC0+ZW50cnkubGV2ZWwgPSAwOwoKCWxzdHJjcHkoZGlyX3BhdGgsIGRydik7Cglsc3RyY2F0KGRpcl9wYXRoLCBkaXIpOwoJZW50cnkgPSByZWFkX3RyZWUocm9vdCwgZGlyX3BhdGgsIHBpZGwsIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChyb290LT5lbnRyeS5ldHlwZSA9PSBFVF9TSEVMTCkKCQlsb2FkX3N0cmluZyhyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgSURTX0RFU0tUT1ApOwoJZWxzZQojZW5kaWYKCQl3c3ByaW50Zihyb290LT5lbnRyeS5kYXRhLmNGaWxlTmFtZSwgUlMoYjEsSURTX1RJVExFRk1UKSwgZHJ2LCByb290LT5mcyk7CgoJcm9vdC0+ZW50cnkuZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzID0gRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZOwoKCWNoaWxkLT5sZWZ0LnJvb3QgPSAmcm9vdC0+ZW50cnk7CgljaGlsZC0+cmlnaHQucm9vdCA9IE5VTEw7CgoJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIDAsIGh3bmQpOwoKCXJldHVybiBjaGlsZDsKfQoKCi8qIGZyZWUgYWxsIG1lbW9yeSBhc3NvY2lhdGVkIHdpdGggYSBjaGlsZCB3aW5kb3cgKi8Kc3RhdGljIHZvaWQgZnJlZV9jaGlsZF93aW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CglmcmVlX2VudHJpZXMoJmNoaWxkLT5yb290LmVudHJ5KTsKCWZyZWUoY2hpbGQpOwp9CgoKLyogZ2V0IGZ1bGwgcGF0aCBvZiBzcGVjaWZpZWQgZGlyZWN0b3J5IGVudHJ5ICovCnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpCnsKCUVudHJ5KiBlbnRyeTsKCWludCBsZW4gPSAwOwoJaW50IGxldmVsID0gMDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGRpci0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJU0ZHQU9GIGF0dHJpYnM7CgkJSFJFU1VMVCBociA9IFNfT0s7CgoJCXBhdGhbMF0gPSBURVhUKCdcMCcpOwoKCQlhdHRyaWJzID0gMDsKCgkJaWYgKGRpci0+Zm9sZGVyKQoJCQlociA9IElTaGVsbEZvbGRlcl9HZXRBdHRyaWJ1dGVzT2YoZGlyLT5mb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmZGlyLT5waWRsLCAmYXR0cmlicyk7CgoJCWlmIChTVUNDRUVERUQoaHIpICYmIChhdHRyaWJzJlNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCUlTaGVsbEZvbGRlciogcGFyZW50ID0gZGlyLT51cD8gZGlyLT51cC0+Zm9sZGVyOiBHbG9iYWxzLmlEZXNrdG9wOwoKCQkJaHIgPSBwYXRoX2Zyb21fcGlkbChwYXJlbnQsIGRpci0+cGlkbCwgcGF0aCwgTUFYX1BBVEgpOwoJCX0KCX0KCWVsc2UKI2VuZGlmCgl7CgkJZm9yKGVudHJ5PWRpcjsgZW50cnk7IGxldmVsKyspIHsKCQkJTFBDVFNUUiBuYW1lOwoJCQlpbnQgbDsKCgkJCXsKCQkJCUxQQ1RTVFIgczsKCQkJCW5hbWUgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgkJCQlzID0gbmFtZTsKCgkJCQlmb3IobD0wOyAqcyAmJiAqcyE9VEVYVCgnLycpICYmICpzIT1URVhUKCdcXCcpOyBzKyspCgkJCQkJbCsrOwoJCQl9CgoJCQlpZiAoZW50cnktPnVwKSB7CgkJCQlpZiAobCA+IDApIHsKCQkJCQltZW1tb3ZlKHBhdGgrbCsxLCBwYXRoLCBsZW4qc2l6ZW9mKFRDSEFSKSk7CgkJCQkJbWVtY3B5KHBhdGgrMSwgbmFtZSwgbCpzaXplb2YoVENIQVIpKTsKCQkJCQlsZW4gKz0gbCsxOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCQkJcGF0aFswXSA9IFRFWFQoJy8nKTsKCQkJCQllbHNlCiNlbmRpZgoJCQkJCXBhdGhbMF0gPSBURVhUKCdcXCcpOwoJCQkJfQoKCQkJCWVudHJ5ID0gZW50cnktPnVwOwoJCQl9IGVsc2UgewoJCQkJbWVtbW92ZShwYXRoK2wsIHBhdGgsIGxlbipzaXplb2YoVENIQVIpKTsKCQkJCW1lbWNweShwYXRoLCBuYW1lLCBsKnNpemVvZihUQ0hBUikpOwoJCQkJbGVuICs9IGw7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCFsZXZlbCkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCXBhdGhbbGVuKytdID0gVEVYVCgnLycpOwoJCQllbHNlCiNlbmRpZgoJCQkJcGF0aFtsZW4rK10gPSBURVhUKCdcXCcpOwoJCX0KCgkJcGF0aFtsZW5dID0gVEVYVCgnXDAnKTsKCX0KfQoKc3RhdGljIHdpbmRvd09wdGlvbnMgbG9hZF9yZWdpc3RyeV9zZXR0aW5ncyh2b2lkKQp7CglEV09SRCBzaXplOwoJRFdPUkQgdHlwZTsKCUhLRVkgaEtleTsKCXdpbmRvd09wdGlvbnMgb3B0czsKCglSZWdPcGVuS2V5RXgoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCgkgICAgICAgICAgICAgIDAsIEtFWV9RVUVSWV9WQUxVRSwgJmhLZXkgKTsKCglzaXplID0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3N0YXJ0X3gsIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLnN0YXJ0X3gsICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5zdGFydF94ID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3N0YXJ0X3ksIE5VTEwsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpICZvcHRzLnN0YXJ0X3ksICZzaXplICkgIT0gRVJST1JfU1VDQ0VTUyApCgkJb3B0cy5zdGFydF95ID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX3dpZHRoLCBOVUxMLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSAmb3B0cy53aWR0aCwgJnNpemUgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQlvcHRzLndpZHRoID0gQ1dfVVNFREVGQVVMVDsKCiAgICAgICAgaWYoIFJlZ1F1ZXJ5VmFsdWVFeCggaEtleSwgcmVnX2hlaWdodCwgTlVMTCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkgJm9wdHMuaGVpZ2h0LCAmc2l6ZSApICE9IEVSUk9SX1NVQ0NFU1MgKQoJCW9wdHMuaGVpZ2h0ID0gQ1dfVVNFREVGQVVMVDsKCglSZWdDbG9zZUtleSggaEtleSApOwoKCXJldHVybiBvcHRzOwp9CgpzdGF0aWMgdm9pZCBzYXZlX3JlZ2lzdHJ5X3NldHRpbmdzKHZvaWQpCnsKCVdJTkRPV0lORk8gd2k7CglIS0VZIGhLZXk7CglJTlQgd2lkdGgsIGhlaWdodDsKCgl3aS5jYlNpemUgPSBzaXplb2YoIFdJTkRPV0lORk8gKTsKCUdldFdpbmRvd0luZm8oR2xvYmFscy5oTWFpblduZCwgJndpKTsKCXdpZHRoID0gd2kucmNXaW5kb3cucmlnaHQgLSB3aS5yY1dpbmRvdy5sZWZ0OwoJaGVpZ2h0ID0gd2kucmNXaW5kb3cuYm90dG9tIC0gd2kucmNXaW5kb3cudG9wOwoKCWlmICggUmVnT3BlbktleUV4KCBIS0VZX0NVUlJFTlRfVVNFUiwgcmVnaXN0cnlfa2V5LAoJICAgICAgICAgICAgICAgICAgIDAsIEtFWV9TRVRfVkFMVUUsICZoS2V5ICkgIT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJLyogVW5hYmxlIHRvIHNhdmUgcmVnaXN0cnkgc2V0dGluZ3MgLSB0cnkgdG8gY3JlYXRlIGtleSAqLwoJCWlmICggUmVnQ3JlYXRlS2V5RXgoIEhLRVlfQ1VSUkVOVF9VU0VSLCByZWdpc3RyeV9rZXksCgkJICAgICAgICAgICAgICAgICAgICAgMCwgTlVMTCwgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsCgkJICAgICAgICAgICAgICAgICAgICAgS0VZX1NFVF9WQUxVRSwgTlVMTCwgJmhLZXksIE5VTEwgKSAhPSBFUlJPUl9TVUNDRVNTICkKCQl7CgkJCS8qIEZJWE1FOiBDYW5ub3QgY3JlYXRlIGtleSAqLwoJCQlyZXR1cm47CgkJfQoJfQoJLyogU2F2ZSBhbGwgb2YgdGhlIHNldHRpbmdzICovCglSZWdTZXRWYWx1ZUV4KCBoS2V5LCByZWdfc3RhcnRfeCwgMCwgUkVHX0RXT1JELAoJICAgICAgICAgICAgICAgKExQQllURSkgJndpLnJjV2luZG93LmxlZnQsIHNpemVvZihEV09SRCkgKTsKCVJlZ1NldFZhbHVlRXgoIGhLZXksIHJlZ19zdGFydF95LCAwLCBSRUdfRFdPUkQsCgkgICAgICAgICAgICAgICAoTFBCWVRFKSAmd2kucmNXaW5kb3cudG9wLCBzaXplb2YoRFdPUkQpICk7CglSZWdTZXRWYWx1ZUV4KCBoS2V5LCByZWdfd2lkdGgsIDAsIFJFR19EV09SRCwKCSAgICAgICAgICAgICAgIChMUEJZVEUpICZ3aWR0aCwgc2l6ZW9mKERXT1JEKSApOwoJUmVnU2V0VmFsdWVFeCggaEtleSwgcmVnX2hlaWdodCwgMCwgUkVHX0RXT1JELAoJICAgICAgICAgICAgICAgKExQQllURSkgJmhlaWdodCwgc2l6ZW9mKERXT1JEKSApOwoKCS8qIFRPRE86IFNhdmUgbW9yZSBzZXR0aW5ncyBoZXJlIChMaXN0IHZzLiBEZXRhaWxlZCBWaWV3LCBldGMuKSAqLwoJUmVnQ2xvc2VLZXkoIGhLZXkgKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lX3JlY3QoSFdORCBod25kLCBQUkVDVCBwcmVjdCkKewoJaW50IG5ld190b3A7CglSRUNUIHJ0OwoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5odG9vbGJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmh0b29sYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHRvb2xiYXIsICZydCk7CgkJcHJlY3QtPnRvcCA9IHJ0LmJvdHRvbSszOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzM7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhkcml2ZWJhcikpIHsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgV01fU0laRSwgMCwgMCk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQluZXdfdG9wID0gLS1wcmVjdC0+dG9wICsgcnQuYm90dG9tKzM7CgkJTW92ZVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhciwgMCwgcHJlY3QtPnRvcCwgcnQucmlnaHQsIG5ld190b3AsIFRSVUUpOwoJCXByZWN0LT50b3AgPSBuZXdfdG9wOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhzdGF0dXNiYXIpKSB7CgkJaW50IHBhcnRzW10gPSB7MzAwLCA1MDB9OwoKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFdNX1NJWkUsIDAsIDApOwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgU0JfU0VUUEFSVFMsIDIsIChMUEFSQU0pJnBhcnRzKTsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaHN0YXR1c2JhciwgJnJ0KTsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbTsKCX0KCglNb3ZlV2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCwgcHJlY3QtPmxlZnQtMSxwcmVjdC0+dG9wLTEscHJlY3QtPnJpZ2h0KzIscHJlY3QtPmJvdHRvbSsxLCBUUlVFKTsKfQoKc3RhdGljIHZvaWQgcmVzaXplX2ZyYW1lKEhXTkQgaHduZCwgaW50IGN4LCBpbnQgY3kpCnsKCVJFQ1QgcmVjdDsKCglyZWN0LmxlZnQgICA9IDA7CglyZWN0LnRvcCAgICA9IDA7CglyZWN0LnJpZ2h0ICA9IGN4OwoJcmVjdC5ib3R0b20gPSBjeTsKCglyZXNpemVfZnJhbWVfcmVjdChod25kLCAmcmVjdCk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZV9jbGllbnQoSFdORCBod25kKQp7CglSRUNUIHJlY3Q7CgoJR2V0Q2xpZW50UmVjdChod25kLCAmcmVjdCk7CgoJcmVzaXplX2ZyYW1lX3JlY3QoaHduZCwgJnJlY3QpOwp9CgoKc3RhdGljIEhIT09LIGhjYnRob29rOwpzdGF0aWMgQ2hpbGRXbmQqIG5ld2NoaWxkID0gTlVMTDsKCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIENCVFByb2MoaW50IGNvZGUsIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCWlmIChjb2RlPT1IQ0JUX0NSRUFURVdORCAmJiBuZXdjaGlsZCkgewoJCUNoaWxkV25kKiBjaGlsZCA9IG5ld2NoaWxkOwoJCW5ld2NoaWxkID0gTlVMTDsKCgkJY2hpbGQtPmh3bmQgPSAoSFdORCkgd3BhcmFtOwoJCVNldFdpbmRvd0xvbmdQdHIoY2hpbGQtPmh3bmQsIEdXTFBfVVNFUkRBVEEsIChMUEFSQU0pY2hpbGQpOwoJfQoKCXJldHVybiBDYWxsTmV4dEhvb2tFeChoY2J0aG9vaywgY29kZSwgd3BhcmFtLCBscGFyYW0pOwp9CgpzdGF0aWMgSFdORCBjcmVhdGVfY2hpbGRfd2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJTURJQ1JFQVRFU1RSVUNUIG1jczsKCWludCBpZHg7CgoJbWNzLnN6Q2xhc3MgPSBzV0lORUZJTEVUUkVFOwoJbWNzLnN6VGl0bGUgPSAoTFBUU1RSKWNoaWxkLT5wYXRoOwoJbWNzLmhPd25lciAgPSBHbG9iYWxzLmhJbnN0YW5jZTsKCW1jcy54ICAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQ7CgltY3MueSAgICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3A7CgltY3MuY3ggICAgICA9IGNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5yaWdodC1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdDsKCW1jcy5jeSAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS1jaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24udG9wOwoJbWNzLnN0eWxlICAgPSAwOwoJbWNzLmxQYXJhbSAgPSAwOwoKCWhjYnRob29rID0gU2V0V2luZG93c0hvb2tFeChXSF9DQlQsIENCVFByb2MsIDAsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCgluZXdjaGlsZCA9IGNoaWxkOwoJY2hpbGQtPmh3bmQgPSAoSFdORCkgU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDUkVBVEUsIDAsIChMUEFSQU0pJm1jcyk7CglpZiAoIWNoaWxkLT5od25kKSB7CgkJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgkJcmV0dXJuIDA7Cgl9CgoJVW5ob29rV2luZG93c0hvb2tFeChoY2J0aG9vayk7CgoJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5sZWZ0Lmh3bmQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoJTGlzdEJveF9TZXRJdGVtSGVpZ2h0KGNoaWxkLT5yaWdodC5od25kLCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCglpZHggPSBMaXN0Qm94X0ZpbmRJdGVtRGF0YShjaGlsZC0+bGVmdC5od25kLCAwLCBjaGlsZC0+bGVmdC5jdXIpOwoJTGlzdEJveF9TZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCwgaWR4KTsKCglyZXR1cm4gY2hpbGQtPmh3bmQ7Cn0KCgpzdHJ1Y3QgRXhlY3V0ZURpYWxvZyB7CglUQ0hBUgljbWRbTUFYX1BBVEhdOwoJaW50CQljbWRzaG93Owp9OwoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgRXhlY3V0ZURpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgRXhlY3V0ZURpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlkbGcgPSAoc3RydWN0IEV4ZWN1dGVEaWFsb2cqKSBscGFyYW07CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlpZiAoaWQgPT0gSURPSykgewoJCQkJR2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIGRsZy0+Y21kLCBNQVhfUEFUSCk7CgkJCQlkbGctPmNtZHNob3cgPSBCdXR0b25fR2V0U3RhdGUoR2V0RGxnSXRlbShod25kLDIxNCkpJkJTVF9DSEVDS0VEPwoJCQkJCQkJCQkJCQlTV19TSE9XTUlOSU1JWkVEOiBTV19TSE9XTk9STUFMOwoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfSBlbHNlIGlmIChpZCA9PSBJRENBTkNFTCkKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgoJCQlyZXR1cm4gMTt9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBEZXN0aW5hdGlvbkRsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fSU5JVERJQUxPRzoKCQkJU2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBLCBscGFyYW0pOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgMjAxKSwgKExQQ1RTVFIpbHBhcmFtKTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCXN3aXRjaChpZCkgewoJCQkgIGNhc2UgSURPSzogewoJCQkJTFBUU1RSIGRlc3QgPSAoTFBUU1RSKSBHZXRXaW5kb3dMb25nUHRyKGh3bmQsIEdXTFBfVVNFUkRBVEEpOwoJCQkJR2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIGRlc3QsIE1BWF9QQVRIKTsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCQlicmVhazt9CgoJCQkgIGNhc2UgSURDQU5DRUw6CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQkJYnJlYWs7CgoJCQkgIGNhc2UgMjU0OgoJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMSxJRFNfTk9fSU1QTCksIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKCQkJCWJyZWFrOwoJCQl9CgoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdHJ1Y3QgRmlsdGVyRGlhbG9nIHsKCVRDSEFSCXBhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmbGFnczsKfTsKCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIEZpbHRlckRpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgRmlsdGVyRGlhbG9nKiBkbGc7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCWRsZyA9IChzdHJ1Y3QgRmlsdGVyRGlhbG9nKikgbHBhcmFtOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1ZJRVdfUEFUVEVSTiksIGRsZy0+cGF0dGVybik7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUyksIChkbGctPmZsYWdzJlRGX0RJUkVDVE9SSUVTPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfUFJPR1JBTVMpLCBkbGctPmZsYWdzJlRGX1BST0dSQU1TPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCk7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ET0NVTUVOVFMpLCBkbGctPmZsYWdzJlRGX0RPQ1VNRU5UUz8gQlNUX0NIRUNLRUQ6IEJTVF9VTkNIRUNLRUQpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfT1RIRVJTKSwgZGxnLT5mbGFncyZURl9PVEhFUlM/IEJTVF9DSEVDS0VEOiBCU1RfVU5DSEVDS0VEKTsKCQkJQnV0dG9uX1NldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfVklFV19UWVBFX0hJRERFTiksIGRsZy0+ZmxhZ3MmVEZfSElEREVOPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlpZiAoaWQgPT0gSURPSykgewoJCQkJaW50IGZsYWdzID0gMDsKCgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1ZJRVdfUEFUVEVSTiksIGRsZy0+cGF0dGVybiwgTUFYX1BBVEgpOwoKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUykpJkJTVF9DSEVDS0VEPyBURl9ESVJFQ1RPUklFUzogMDsKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9QUk9HUkFNUykpJkJTVF9DSEVDS0VEPyBURl9QUk9HUkFNUzogMDsKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ET0NVTUVOVFMpKSZCU1RfQ0hFQ0tFRD8gVEZfRE9DVU1FTlRTOiAwOwoJCQkJZmxhZ3MgfD0gQnV0dG9uX0dldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfVklFV19UWVBFX09USEVSUykpJkJTVF9DSEVDS0VEPyBURl9PVEhFUlM6IDA7CgkJCQlmbGFncyB8PSBCdXR0b25fR2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfSElEREVOKSkmQlNUX0NIRUNLRUQ/IFRGX0hJRERFTjogMDsKCgkJCQlkbGctPmZsYWdzID0gZmxhZ3M7CgoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfSBlbHNlIGlmIChpZCA9PSBJRENBTkNFTCkKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgoJCQlyZXR1cm4gMTt9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyB7CglUQ0hBUglwYXRoW01BWF9QQVRIXTsKCUVudHJ5CWVudHJ5OwoJdm9pZCoJcFZlcnNpb25EYXRhOwp9OwoKLyogU3RydWN0dXJlIHVzZWQgdG8gc3RvcmUgZW51bWVyYXRlZCBsYW5ndWFnZXMgYW5kIGNvZGUgcGFnZXMuICovCnN0cnVjdCBMQU5HQU5EQ09ERVBBR0UgewoJV09SRCB3TGFuZ3VhZ2U7CglXT1JEIHdDb2RlUGFnZTsKfSAqbHBUcmFuc2xhdGU7CgpzdGF0aWMgTFBDU1RSIEluZm9TdHJpbmdzW10gPSB7CgkiQ29tbWVudHMiLAoJIkNvbXBhbnlOYW1lIiwKCSJGaWxlRGVzY3JpcHRpb24iLAoJIkZpbGVWZXJzaW9uIiwKCSJJbnRlcm5hbE5hbWUiLAoJIkxlZ2FsQ29weXJpZ2h0IiwKCSJMZWdhbFRyYWRlbWFya3MiLAoJIk9yaWdpbmFsRmlsZW5hbWUiLAoJIlByaXZhdGVCdWlsZCIsCgkiUHJvZHVjdE5hbWUiLAoJIlByb2R1Y3RWZXJzaW9uIiwKCSJTcGVjaWFsQnVpbGQiLAoJTlVMTAp9OwoKc3RhdGljIHZvaWQgUHJvcERsZ19EaXNwbGF5VmFsdWUoSFdORCBobGJveCwgSFdORCBoZWRpdCkKewoJaW50IGlkeCA9IExpc3RCb3hfR2V0Q3VyU2VsKGhsYm94KTsKCglpZiAoaWR4ICE9IExCX0VSUikgewoJCUxQQ1RTVFIgcFZhbHVlID0gKExQQ1RTVFIpIExpc3RCb3hfR2V0SXRlbURhdGEoaGxib3gsIGlkeCk7CgoJCWlmIChwVmFsdWUpCgkJCVNldFdpbmRvd1RleHQoaGVkaXQsIHBWYWx1ZSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIENoZWNrRm9yRmlsZUluZm8oc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqIGRsZywgSFdORCBod25kLCBMUENUU1RSIHN0ckZpbGVuYW1lKQp7CglzdGF0aWMgVENIQVIgc0JhY2tTbGFzaFtdID0geydcXCcsJ1wwJ307CglzdGF0aWMgVENIQVIgc1RyYW5zbGF0aW9uW10gPSB7J1xcJywnVicsJ2EnLCdyJywnRicsJ2knLCdsJywnZScsJ0knLCduJywnZicsJ28nLCdcXCcsJ1QnLCdyJywnYScsJ24nLCdzJywnbCcsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnfTsKCXN0YXRpYyBUQ0hBUiBzU3RyaW5nRmlsZUluZm9bXSA9IHsnXFwnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdGJywnaScsJ2wnLCdlJywnSScsJ24nLCdmJywnbycsJ1xcJywKCQkJCQkJCQkJCSclJywnMCcsJzQnLCd4JywnJScsJzAnLCc0JywneCcsJ1xcJywnJScsJ3MnLCdcMCd9OwoJRFdPUkQgZHdWZXJzaW9uRGF0YUxlbiA9IEdldEZpbGVWZXJzaW9uSW5mb1NpemUoc3RyRmlsZW5hbWUsIE5VTEwpOwoKCWlmIChkd1ZlcnNpb25EYXRhTGVuKSB7CgkJZGxnLT5wVmVyc2lvbkRhdGEgPSBtYWxsb2MoZHdWZXJzaW9uRGF0YUxlbik7CgoJCWlmIChHZXRGaWxlVmVyc2lvbkluZm8oc3RyRmlsZW5hbWUsIDAsIGR3VmVyc2lvbkRhdGFMZW4sIGRsZy0+cFZlcnNpb25EYXRhKSkgewoJCQlMUFZPSUQgcFZhbDsKCQkJVUlOVCBuVmFsTGVuOwoKCQkJaWYgKFZlclF1ZXJ5VmFsdWUoZGxnLT5wVmVyc2lvbkRhdGEsIHNCYWNrU2xhc2gsICZwVmFsLCAmblZhbExlbikpIHsKCQkJCWlmIChuVmFsTGVuID09IHNpemVvZihWU19GSVhFREZJTEVJTkZPKSkgewoJCQkJCVZTX0ZJWEVERklMRUlORk8qIHBGaXhlZEZpbGVJbmZvID0gKFZTX0ZJWEVERklMRUlORk8qKXBWYWw7CgkJCQkJY2hhciBidWZmZXJbQlVGRkVSX0xFTl07CgoJCQkJCXNwcmludGYoYnVmZmVyLCAiJWQuJWQuJWQuJWQiLAoJCQkJCQlISVdPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25NUyksIExPV09SRChwRml4ZWRGaWxlSW5mby0+ZHdGaWxlVmVyc2lvbk1TKSwKCQkJCQkJSElXT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTFMpLCBMT1dPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25MUykpOwoKCQkJCQlTZXREbGdJdGVtVGV4dEEoaHduZCwgSURDX1NUQVRJQ19QUk9QX1ZFUlNJT04sIGJ1ZmZlcik7CgkJCQl9CgkJCX0KCgkJCS8qIFJlYWQgdGhlIGxpc3Qgb2YgbGFuZ3VhZ2VzIGFuZCBjb2RlIHBhZ2VzLiAqLwoJCQlpZiAoVmVyUXVlcnlWYWx1ZShkbGctPnBWZXJzaW9uRGF0YSwgc1RyYW5zbGF0aW9uLCAmcFZhbCwgJm5WYWxMZW4pKSB7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwVHJhbnNsYXRlID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKXBWYWw7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwRW5kID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKSgoTFBCWVRFKXBWYWwrblZhbExlbik7CgoJCQkJSFdORCBobGJveCA9IEdldERsZ0l0ZW0oaHduZCwgSURDX0xJU1RfUFJPUF9WRVJTSU9OX1RZUEVTKTsKCgkJCQkvKiBSZWFkIHRoZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBlYWNoIGxhbmd1YWdlIGFuZCBjb2RlIHBhZ2UuICovCgkJCQlmb3IoOyBwVHJhbnNsYXRlPHBFbmQ7ICsrcFRyYW5zbGF0ZSkgewoJCQkJCUxQQ1NUUiogcDsKCgkJCQkJZm9yKHA9SW5mb1N0cmluZ3M7ICpwOyArK3ApIHsKCQkJCQkJVENIQVIgc3ViYmxvY2tbMjAwXTsKI2lmZGVmIFVOSUNPREUKCQkJCQkJVENIQVIgaW5mb1N0clsxMDBdOwojZW5kaWYKCQkJCQkJTFBDVFNUUiBwVHh0OwoJCQkJCQlVSU5UIG5WYWxMZW47CgoJCQkJCQlMUENTVFIgcEluZm9TdHJpbmcgPSAqcDsKI2lmZGVmIFVOSUNPREUKCQkJCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBJbmZvU3RyaW5nLCAtMSwgaW5mb1N0ciwgMTAwKTsKI2Vsc2UKI2RlZmluZQlpbmZvU3RyIHBJbmZvU3RyaW5nCiNlbmRpZgoJCQkJCQl3c3ByaW50ZihzdWJibG9jaywgc1N0cmluZ0ZpbGVJbmZvLCBwVHJhbnNsYXRlLT53TGFuZ3VhZ2UsIHBUcmFuc2xhdGUtPndDb2RlUGFnZSwgaW5mb1N0cik7CgoJCQkJCQkvKiBSZXRyaWV2ZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBsYW5ndWFnZSBhbmQgY29kZSBwYWdlICovCgkJCQkJCWlmIChWZXJRdWVyeVZhbHVlKGRsZy0+cFZlcnNpb25EYXRhLCBzdWJibG9jaywgKFBWT0lEKSZwVHh0LCAmblZhbExlbikpIHsKCQkJCQkJCWludCBpZHggPSBMaXN0Qm94X0FkZFN0cmluZyhobGJveCwgaW5mb1N0cik7CgkJCQkJCQlMaXN0Qm94X1NldEl0ZW1EYXRhKGhsYm94LCBpZHgsIHBUeHQpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCUxpc3RCb3hfU2V0Q3VyU2VsKGhsYm94LCAwKTsKCgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOiB7CgkJCXN0YXRpYyBjb25zdCBUQ0hBUiBzQnl0ZUZtdFtdID0geyclJywncycsJyAnLCdCJywneScsJ3QnLCdlJywncycsJ1wwJ307CgkJCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCQkJTFBXSU4zMl9GSU5EX0RBVEEgcFdGRDsKCQkJVUxPTkdMT05HIHNpemU7CgoJCQlkbGcgPSAoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqKSBscGFyYW07CgkJCXBXRkQgPSAoTFBXSU4zMl9GSU5EX0RBVEEpICZkbGctPmVudHJ5LmRhdGE7CgoJCQlHZXRXaW5kb3dUZXh0KGh3bmQsIGIxLCBNQVhfUEFUSCk7CgkJCXdzcHJpbnRmKGIyLCBiMSwgcFdGRC0+Y0ZpbGVOYW1lKTsKCQkJU2V0V2luZG93VGV4dChod25kLCBiMik7CgoJCQlmb3JtYXRfZGF0ZSgmcFdGRC0+ZnRMYXN0V3JpdGVUaW1lLCBiMSwgQ09MX0RBVEV8Q09MX1RJTUUpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX0xBU1RDSEFOR0UpLCBiMSk7CgoJCQlzaXplID0gKChVTE9OR0xPTkcpcFdGRC0+bkZpbGVTaXplSGlnaCA8PCAzMikgfCBwV0ZELT5uRmlsZVNpemVMb3c7CgkJCV9zdHByaW50ZihiMSwgc0xvbmdOdW1GbXQsIHNpemUpOwoJCQl3c3ByaW50ZihiMiwgc0J5dGVGbXQsIGIxKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9TSVpFKSwgYjIpOwoKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9GSUxFTkFNRSksIHBXRkQtPmNGaWxlTmFtZSk7CgkJCVNldFdpbmRvd1RleHQoR2V0RGxnSXRlbShod25kLCBJRENfU1RBVElDX1BST1BfUEFUSCksIGRsZy0+cGF0aCk7CgoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19DSEVDS19SRUFET05MWSksIChwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX1JFQURPTkxZPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19DSEVDS19BUkNISVZFKSwgKHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfQVJDSElWRT8gQlNUX0NIRUNLRUQ6IEJTVF9VTkNIRUNLRUQpKTsKCQkJQnV0dG9uX1NldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfQ0hFQ0tfQ09NUFJFU1NFRCksIChwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQ/IEJTVF9DSEVDS0VEOiBCU1RfVU5DSEVDS0VEKSk7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX0NIRUNLX0hJRERFTiksIChwV0ZELT5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0hJRERFTj8gQlNUX0NIRUNLRUQ6IEJTVF9VTkNIRUNLRUQpKTsKCQkJQnV0dG9uX1NldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfQ0hFQ0tfU1lTVEVNKSwgKHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfU1lTVEVNPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoKCQkJQ2hlY2tGb3JGaWxlSW5mbyhkbGcsIGh3bmQsIGRsZy0+cGF0aCk7CgkJCXJldHVybiAxO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCWludCBpZCA9IChpbnQpd3BhcmFtOwoKCQkJc3dpdGNoKEhJV09SRCh3cGFyYW0pKSB7CgkJCSAgY2FzZSBMQk5fU0VMQ0hBTkdFOiB7CgkJCQlIV05EIGhsYm94ID0gR2V0RGxnSXRlbShod25kLCBJRENfTElTVF9QUk9QX1ZFUlNJT05fVFlQRVMpOwoJCQkJUHJvcERsZ19EaXNwbGF5VmFsdWUoaGxib3gsIEdldERsZ0l0ZW0oaHduZCxJRENfTElTVF9QUk9QX1ZFUlNJT05fVkFMVUVTKSk7CgkJCQlicmVhazsKCQkJICB9CgoJCQkgIGNhc2UgQk5fQ0xJQ0tFRDoKCQkJCWlmIChpZD09SURPSyB8fCBpZD09SURDQU5DRUwpCgkJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfQoKCQkJcmV0dXJuIDE7fQoKCQljYXNlIFdNX05DREVTVFJPWToKCQkJZnJlZShkbGctPnBWZXJzaW9uRGF0YSk7CgkJCWRsZy0+cFZlcnNpb25EYXRhID0gTlVMTDsKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHNob3dfcHJvcGVydGllc19kbGcoRW50cnkqIGVudHJ5LCBIV05EIGh3bmQpCnsKCXN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nIGRsZzsKCgltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBQcm9wZXJ0aWVzRGlhbG9nKSk7CglnZXRfcGF0aChlbnRyeSwgZGxnLnBhdGgpOwoJbWVtY3B5KCZkbGcuZW50cnksIGVudHJ5LCBzaXplb2YoRW50cnkpKTsKCglEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9ESUFMT0dfUFJPUEVSVElFUyksIGh3bmQsIFByb3BlcnRpZXNEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpOwp9CgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIHN0cnVjdCBGdWxsU2NyZWVuUGFyYW1ldGVycyB7CglCT09MCW1vZGU7CglSRUNUCW9yZ1BvczsKCUJPT0wJd2FzWm9vbWVkOwp9IGdfZnVsbHNjcmVlbiA9IHsKICAgIEZBTFNFLAkvKiBtb2RlICovCgl7MCwgMCwgMCwgMH0sCglGQUxTRQp9OwoKc3RhdGljIHZvaWQgZnJhbWVfZ2V0X2NsaWVudHNwYWNlKEhXTkQgaHduZCwgUFJFQ1QgcHJlY3QpCnsKCVJFQ1QgcnQ7CgoJaWYgKCFJc0ljb25pYyhod25kKSkKCQlHZXRDbGllbnRSZWN0KGh3bmQsIHByZWN0KTsKCWVsc2UgewoJCVdJTkRPV1BMQUNFTUVOVCB3cDsKCgkJR2V0V2luZG93UGxhY2VtZW50KGh3bmQsICZ3cCk7CgoJCXByZWN0LT5sZWZ0ID0gcHJlY3QtPnRvcCA9IDA7CgkJcHJlY3QtPnJpZ2h0ID0gd3AucmNOb3JtYWxQb3NpdGlvbi5yaWdodC13cC5yY05vcm1hbFBvc2l0aW9uLmxlZnQtCgkJCQkJCTIqKEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFRlJBTUUpK0dldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKSk7CgkJcHJlY3QtPmJvdHRvbSA9IHdwLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tLXdwLnJjTm9ybWFsUG9zaXRpb24udG9wLQoJCQkJCQkyKihHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRUZSQU1FKStHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpLQoJCQkJCQlHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTiktR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlVTSVpFKTsKCX0KCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHRvb2xiYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmh0b29sYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgKz0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhkcml2ZWJhcikpIHsKCQlHZXRDbGllbnRSZWN0KEdsb2JhbHMuaGRyaXZlYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgKz0gcnQuYm90dG9tKzI7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmhzdGF0dXNiYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhzdGF0dXNiYXIsICZydCk7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b207Cgl9Cn0KCnN0YXRpYyBCT09MIHRvZ2dsZV9mdWxsc2NyZWVuKEhXTkQgaHduZCkKewoJUkVDVCBydDsKCglpZiAoKGdfZnVsbHNjcmVlbi5tb2RlPSFnX2Z1bGxzY3JlZW4ubW9kZSkpIHsKCQlHZXRXaW5kb3dSZWN0KGh3bmQsICZnX2Z1bGxzY3JlZW4ub3JnUG9zKTsKCQlnX2Z1bGxzY3JlZW4ud2FzWm9vbWVkID0gSXNab29tZWQoaHduZCk7CgoJCUZyYW1lX0NhbGNGcmFtZUNsaWVudChod25kLCAmcnQpOwoJCUNsaWVudFRvU2NyZWVuKGh3bmQsIChMUFBPSU5UKSZydC5sZWZ0KTsKCQlDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQucmlnaHQpOwoKCQlydC5sZWZ0ID0gZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LXJ0LmxlZnQ7CgkJcnQudG9wID0gZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AtcnQudG9wOwoJCXJ0LnJpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikrZ19mdWxsc2NyZWVuLm9yZ1Bvcy5yaWdodC1ydC5yaWdodDsKCQlydC5ib3R0b20gPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKStnX2Z1bGxzY3JlZW4ub3JnUG9zLmJvdHRvbS1ydC5ib3R0b207CgoJCU1vdmVXaW5kb3coaHduZCwgcnQubGVmdCwgcnQudG9wLCBydC5yaWdodC1ydC5sZWZ0LCBydC5ib3R0b20tcnQudG9wLCBUUlVFKTsKCX0gZWxzZSB7CgkJTW92ZVdpbmRvdyhod25kLCBnX2Z1bGxzY3JlZW4ub3JnUG9zLmxlZnQsIGdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLAoJCQkJCQkJZ19mdWxsc2NyZWVuLm9yZ1Bvcy5yaWdodC1nX2Z1bGxzY3JlZW4ub3JnUG9zLmxlZnQsCgkJCQkJCQlnX2Z1bGxzY3JlZW4ub3JnUG9zLmJvdHRvbS1nX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcCwgVFJVRSk7CgoJCWlmIChnX2Z1bGxzY3JlZW4ud2FzWm9vbWVkKQoJCQlTaG93V2luZG93KGh3bmQsIFdTX01BWElNSVpFKTsKCX0KCglyZXR1cm4gZ19mdWxsc2NyZWVuLm1vZGU7Cn0KCnN0YXRpYyB2b2lkIGZ1bGxzY3JlZW5fbW92ZShIV05EIGh3bmQpCnsKCVJFQ1QgcnQsIHBvczsKCUdldFdpbmRvd1JlY3QoaHduZCwgJnBvcyk7CgoJRnJhbWVfQ2FsY0ZyYW1lQ2xpZW50KGh3bmQsICZydCk7CglDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQubGVmdCk7CglDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQucmlnaHQpOwoKCXJ0LmxlZnQgPSBwb3MubGVmdC1ydC5sZWZ0OwoJcnQudG9wID0gcG9zLnRvcC1ydC50b3A7CglydC5yaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pK3Bvcy5yaWdodC1ydC5yaWdodDsKCXJ0LmJvdHRvbSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pK3Bvcy5ib3R0b20tcnQuYm90dG9tOwoKCU1vdmVXaW5kb3coaHduZCwgcnQubGVmdCwgcnQudG9wLCBydC5yaWdodC1ydC5sZWZ0LCBydC5ib3R0b20tcnQudG9wLCBUUlVFKTsKfQoKI2VuZGlmCgoKc3RhdGljIHZvaWQgdG9nZ2xlX2NoaWxkKEhXTkQgaHduZCwgVUlOVCBjbWQsIEhXTkQgaGNoaWxkKQp7CglCT09MIHZpcyA9IElzV2luZG93VmlzaWJsZShoY2hpbGQpOwoKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIGNtZCwgdmlzP01GX0JZQ09NTUFORDpNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgoJU2hvd1dpbmRvdyhoY2hpbGQsIHZpcz9TV19ISURFOlNXX1NIT1cpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGdfZnVsbHNjcmVlbi5tb2RlKQoJCWZ1bGxzY3JlZW5fbW92ZShod25kKTsKI2VuZGlmCgoJcmVzaXplX2ZyYW1lX2NsaWVudChod25kKTsKfQoKc3RhdGljIEJPT0wgYWN0aXZhdGVfZHJpdmVfd2luZG93KExQQ1RTVFIgcGF0aCkKewoJVENIQVIgZHJ2MVtfTUFYX0RSSVZFXSwgZHJ2MltfTUFYX0RSSVZFXTsKCUhXTkQgY2hpbGRfd25kOwoKCV90c3BsaXRwYXRoKHBhdGgsIGRydjEsIDAsIDAsIDApOwoKCS8qIHNlYXJjaCBmb3IgYSBhbHJlYWR5IG9wZW4gd2luZG93IGZvciB0aGUgc2FtZSBkcml2ZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGNoaWxkX3duZCwgR1dMUF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlfdHNwbGl0cGF0aChjaGlsZC0+cm9vdC5wYXRoLCBkcnYyLCAwLCAwLCAwKTsKCgkJCWlmICghbHN0cmNtcGkoZHJ2MiwgZHJ2MSkpIHsKCQkJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJQUNUSVZBVEUsIChXUEFSQU0pY2hpbGRfd25kLCAwKTsKCgkJCQlpZiAoSXNNaW5pbWl6ZWQoY2hpbGRfd25kKSkKCQkJCQlTaG93V2luZG93KGNoaWxkX3duZCwgU1dfU0hPV05PUk1BTCk7CgoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBhY3RpdmF0ZV9mc193aW5kb3coTFBDVFNUUiBmaWxlc3lzKQp7CglIV05EIGNoaWxkX3duZDsKCgkvKiBzZWFyY2ggZm9yIGEgYWxyZWFkeSBvcGVuIHdpbmRvdyBvZiB0aGUgZ2l2ZW4gZmlsZSBzeXN0ZW0gbmFtZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGNoaWxkX3duZCwgR1dMUF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlpZiAoIWxzdHJjbXBpKGNoaWxkLT5yb290LmZzLCBmaWxlc3lzKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc01pbmltaXplZChjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIEZyYW1lV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9DTE9TRToKCQkJaWYgKEdsb2JhbHMuc2F2ZVNldHRpbmdzID09IFRSVUUpICAKCQkJCXNhdmVfcmVnaXN0cnlfc2V0dGluZ3MoKTsgIAoJCQkKCQkJRGVzdHJveVdpbmRvdyhod25kKTsKCgkJCSAvKiBjbGVhciBoYW5kbGUgdmFyaWFibGVzICovCgkJCUdsb2JhbHMuaE1lbnVGcmFtZSA9IDA7CgkJCUdsb2JhbHMuaE1lbnVWaWV3ID0gMDsKCQkJR2xvYmFscy5oTWVudU9wdGlvbnMgPSAwOwoJCQlHbG9iYWxzLmhNYWluV25kID0gMDsKCQkJR2xvYmFscy5obWRpY2xpZW50ID0gMDsKCQkJR2xvYmFscy5oZHJpdmViYXIgPSAwOwoJCQlicmVhazsKCgkJY2FzZSBXTV9ERVNUUk9ZOgoJCQlQb3N0UXVpdE1lc3NhZ2UoMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0lOSVRNRU5VUE9QVVA6IHsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmICghU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fSU5JVE1FTlVQT1BVUCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJcmV0dXJuIDA7CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVVJTlQgY21kID0gTE9XT1JEKHdwYXJhbSk7CgkJCUhXTkQgaHduZENsaWVudCA9IChIV05EKSBTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUdFVEFDVElWRSwgMCwgMCk7CgoJCQlpZiAoU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fRElTUEFUQ0hfQ09NTUFORCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJYnJlYWs7CgoJCQlpZiAoY21kPj1JRF9EUklWRV9GSVJTVCAmJiBjbWQ8PUlEX0RSSVZFX0ZJUlNUKzB4RkYpIHsKCQkJCVRDSEFSIGRydltfTUFYX0RSSVZFXSwgcGF0aFtNQVhfUEFUSF07CgkJCQlDaGlsZFduZCogY2hpbGQ7CgkJCQlMUENUU1RSIHJvb3QgPSBHbG9iYWxzLmRyaXZlczsKCQkJCWludCBpOwoKCQkJCWZvcihpPWNtZC1JRF9EUklWRV9GSVJTVDsgaS0tOyByb290KyspCgkJCQkJd2hpbGUoKnJvb3QpCgkJCQkJCXJvb3QrKzsKCgkJCQlpZiAoYWN0aXZhdGVfZHJpdmVfd2luZG93KHJvb3QpKQoJCQkJCXJldHVybiAwOwoKCQkJCV90c3BsaXRwYXRoKHJvb3QsIGRydiwgMCwgMCwgMCk7CgoJCQkJaWYgKCFTZXRDdXJyZW50RGlyZWN0b3J5KGRydikpIHsKCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQlyZXR1cm4gMDsKCQkJCX0KCgkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsgLypUT0RPOiBzdG9yZSBsYXN0IGRpcmVjdG9yeSBwZXIgZHJpdmUgKi8KCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJZnJlZShjaGlsZCk7CgkJCX0gZWxzZSBzd2l0Y2goY21kKSB7CgkJCQljYXNlIElEX0ZJTEVfRVhJVDoKCQkJCQlTZW5kTWVzc2FnZShod25kLCBXTV9DTE9TRSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfUkVGUkVTSDoKCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX0NBU0NBREU6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDQVNDQURFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19USUxFX0hPUlo6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElUSUxFLCBNRElUSUxFX0hPUklaT05UQUwsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX1RJTEVfVkVSVDoKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESVRJTEUsIE1ESVRJTEVfVkVSVElDQUwsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX0FSUkFOR0U6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElJQ09OQVJSQU5HRSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9TRUxFQ1RfRk9OVDogewoJCQkJCVRDSEFSIGRsZ19uYW1lW0JVRkZFUl9MRU5dLCBkbGdfaW5mb1tCVUZGRVJfTEVOXTsKCQkJCQlDSE9PU0VGT05UIGNoRm9udDsKCQkJCQlMT0dGT05UIGxGb250OwoKCQkJCQlIREMgaGRjID0gR2V0REMoaHduZCk7CgkJCQkJY2hGb250LmxTdHJ1Y3RTaXplID0gc2l6ZW9mKENIT09TRUZPTlQpOwoJCQkJCWNoRm9udC5od25kT3duZXIgPSBod25kOwoJCQkJCWNoRm9udC5oREMgPSBOVUxMOwoJCQkJCWNoRm9udC5scExvZ0ZvbnQgPSAmbEZvbnQ7CgkJCQkJY2hGb250LkZsYWdzID0gQ0ZfU0NSRUVORk9OVFMgfCBDRl9GT1JDRUZPTlRFWElTVCB8IENGX0xJTUlUU0laRSB8IENGX05PU0NSSVBUU0VMOwoJCQkJCWNoRm9udC5yZ2JDb2xvcnMgPSBSR0IoMCwwLDApOwoJCQkJCWNoRm9udC5sQ3VzdERhdGEgPSAwOwoJCQkJCWNoRm9udC5scGZuSG9vayA9IE5VTEw7CgkJCQkJY2hGb250LmxwVGVtcGxhdGVOYW1lID0gTlVMTDsKCQkJCQljaEZvbnQuaEluc3RhbmNlID0gR2xvYmFscy5oSW5zdGFuY2U7CgkJCQkJY2hGb250Lmxwc3pTdHlsZSA9IE5VTEw7CgkJCQkJY2hGb250Lm5Gb250VHlwZSA9IFNJTVVMQVRFRF9GT05UVFlQRTsKCQkJCQljaEZvbnQublNpemVNaW4gPSAwOwoJCQkJCWNoRm9udC5uU2l6ZU1heCA9IDI0OwoKCQkJCQlpZiAoQ2hvb3NlRm9udCgmY2hGb250KSkgewoJCQkJCQlIV05EIGNoaWxkV25kOwoJCQkJCQlIRk9OVCBoRm9udE9sZDsKCgkJCQkJCURlbGV0ZU9iamVjdChHbG9iYWxzLmhmb250KTsKCQkJCQkJR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdCgmbEZvbnQpOwoJCQkJCQloRm9udE9sZCA9IFNlbGVjdEZvbnQoaGRjLCBHbG9iYWxzLmhmb250KTsKCQkJCQkJR2V0VGV4dEV4dGVudFBvaW50MzIoaGRjLCBzU3BhY2UsIDEsICZHbG9iYWxzLnNwYWNlU2l6ZSk7CgoJCQkJCQkvKiBjaGFuZ2UgZm9udCBpbiBhbGwgb3BlbiBjaGlsZCB3aW5kb3dzICovCgkJCQkJCWZvcihjaGlsZFduZD1HZXRXaW5kb3coR2xvYmFscy5obWRpY2xpZW50LEdXX0NISUxEKTsgY2hpbGRXbmQ7IGNoaWxkV25kPUdldE5leHRXaW5kb3coY2hpbGRXbmQsR1dfSFdORE5FWFQpKSB7CgkJCQkJCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nUHRyKGNoaWxkV25kLCBHV0xQX1VTRVJEQVRBKTsKCQkJCQkJCVNldFdpbmRvd0ZvbnQoY2hpbGQtPmxlZnQuaHduZCwgR2xvYmFscy5oZm9udCwgVFJVRSk7CgkJCQkJCQlTZXRXaW5kb3dGb250KGNoaWxkLT5yaWdodC5od25kLCBHbG9iYWxzLmhmb250LCBUUlVFKTsKCQkJCQkJCUxpc3RCb3hfU2V0SXRlbUhlaWdodChjaGlsZC0+bGVmdC5od25kLCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCQkJCQkJCUxpc3RCb3hfU2V0SXRlbUhlaWdodChjaGlsZC0+cmlnaHQuaHduZCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CgkJCQkJCQlJbnZhbGlkYXRlUmVjdChjaGlsZC0+bGVmdC5od25kLCBOVUxMLCBUUlVFKTsKCQkJCQkJCUludmFsaWRhdGVSZWN0KGNoaWxkLT5yaWdodC5od25kLCBOVUxMLCBUUlVFKTsKCQkJCQkJfQoKCQkJCQkJU2VsZWN0Rm9udChoZGMsIGhGb250T2xkKTsKCQkJCQl9CgkJCQkJZWxzZSBpZiAoQ29tbURsZ0V4dGVuZGVkRXJyb3IoKSkgewoJCQkJCQlMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfRk9OVF9TRUxfRExHX05BTUUsIGRsZ19uYW1lLCBCVUZGRVJfTEVOKTsKCQkJCQkJTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgSURTX0ZPTlRfU0VMX0VSUk9SLCBkbGdfaW5mbywgQlVGRkVSX0xFTik7CgkJCQkJCU1lc3NhZ2VCb3goaHduZCwgZGxnX2luZm8sIGRsZ19uYW1lLCBNQl9PSyk7CgkJCQkJfQoKCQkJCQlSZWxlYXNlREMoaHduZCwgaGRjKTsKCQkJCQlicmVhazsKCQkJCX0KCgkJCQljYXNlIElEX1ZJRVdfVE9PTF9CQVI6CgkJCQkJdG9nZ2xlX2NoaWxkKGh3bmQsIGNtZCwgR2xvYmFscy5odG9vbGJhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX0RSSVZFX0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmhkcml2ZWJhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NUQVRVU0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmhzdGF0dXNiYXIpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TQVZFU0VUVElOR1M6CgkJCQkJR2xvYmFscy5zYXZlU2V0dGluZ3MgPSAhR2xvYmFscy5zYXZlU2V0dGluZ3M7CgkJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TQVZFU0VUVElOR1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdsb2JhbHMuc2F2ZVNldHRpbmdzID09IFRSVUUgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEICk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9FWEVDVVRFOiB7CgkJCQkJc3RydWN0IEV4ZWN1dGVEaWFsb2cgZGxnOwoKCQkJCQltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBFeGVjdXRlRGlhbG9nKSk7CgoJCQkJCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9FWEVDVVRFKSwgaHduZCwgRXhlY3V0ZURpYWxvZ0RsZ1Byb2MsIChMUEFSQU0pJmRsZykgPT0gSURPSykgewoJCQkJCQlISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGRsZy5jbWQvKmZpbGUqLywgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgZGxnLmNtZHNob3cpOwoKCQkJCQkJaWYgKChpbnQpaGluc3QgPD0gMzIpCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfQ09OTkVDVF9ORVRXT1JLX0RSSVZFOiB7CgkJCQkJRFdPUkQgcmV0ID0gV05ldENvbm5lY3Rpb25EaWFsb2coaHduZCwgUkVTT1VSQ0VUWVBFX0RJU0spOwoJCQkJCWlmIChyZXQgPT0gTk9fRVJST1IpCgkJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJZWxzZSBpZiAocmV0ICE9IChEV09SRCktMSkgewoJCQkJCQlpZiAocmV0ID09IEVSUk9SX0VYVEVOREVEX0VSUk9SKQoJCQkJCQkJZGlzcGxheV9uZXR3b3JrX2Vycm9yKGh3bmQpOwoJCQkJCQllbHNlCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIHJldCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0RJU0NPTk5FQ1RfTkVUV09SS19EUklWRTogewoJCQkJCURXT1JEIHJldCA9IFdOZXREaXNjb25uZWN0RGlhbG9nKGh3bmQsIFJFU09VUkNFVFlQRV9ESVNLKTsKCQkJCQlpZiAocmV0ID09IE5PX0VSUk9SKQoJCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWVsc2UgaWYgKHJldCAhPSAoRFdPUkQpLTEpIHsKCQkJCQkJaWYgKHJldCA9PSBFUlJPUl9FWFRFTkRFRF9FUlJPUikKCQkJCQkJCWRpc3BsYXlfbmV0d29ya19lcnJvcihod25kKTsKCQkJCQkJZWxzZQoJCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCByZXQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GT1JNQVRfRElTSzogewoJCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZSgwKTsgLyogR2V0IHRoZSBjdXJyZW50IEVycm9yIE1vZGUgc2V0dGluZ3MuICovCgkJCQkJU2V0RXJyb3JNb2RlKHNlbV9vcmcgJiB+U0VNX0ZBSUxDUklUSUNBTEVSUk9SUyk7IC8qIEZvcmNlIE8vUyB0byBoYW5kbGUgKi8KCQkJCQlTSEZvcm1hdERyaXZlKGh3bmQsIDAgLyogQTogKi8sIFNIRk1UX0lEX0RFRkFVTFQsIDApOwoJCQkJCVNldEVycm9yTW9kZShzZW1fb3JnKTsgLyogUHV0IGl0IGJhY2sgdGhlIHdheSBpdCB3YXMuICovCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfSEVMUDoKCQkJCQlXaW5IZWxwKGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIEhFTFBfSU5ERVgsIDApOwoJCQkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJY2FzZSBJRF9WSUVXX0ZVTExTQ1JFRU46CgkJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgY21kLCB0b2dnbGVfZnVsbHNjcmVlbihod25kKT9NRl9DSEVDS0VEOjApOwoJCQkJCWJyZWFrOwoKI2lmZGVmIF9fV0lORV9fCgkJCQljYXNlIElEX0RSSVZFX1VOSVhfRlM6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKI2lmZGVmIFVOSUNPREUKCQkJCQljaGFyIGNwYXRoW01BWF9QQVRIXTsKI2VuZGlmCgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlpZiAoYWN0aXZhdGVfZnNfd2luZG93KFJTKGIxLElEU19VTklYRlMpKSkKCQkJCQkJYnJlYWs7CgojaWZkZWYgVU5JQ09ERQoJCQkJCWdldGN3ZChjcGF0aCwgTUFYX1BBVEgpOwoJCQkJCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfVU5JWENQLCAwLCBjcGF0aCwgLTEsIHBhdGgsIE1BWF9QQVRIKTsKI2Vsc2UKCQkJCQlnZXRjd2QocGF0aCwgTUFYX1BBVEgpOwojZW5kaWYKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCQljYXNlIElEX0RSSVZFX1NIRUxMX05TOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlpZiAoYWN0aXZhdGVfZnNfd2luZG93KFJTKGIxLElEU19TSEVMTCkpKQoJCQkJCQlicmVhazsKCgkJCQkJR2V0Q3VycmVudERpcmVjdG9yeShNQVhfUEFUSCwgcGF0aCk7CgkJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLGh3bmQpLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQojZW5kaWYKI2VuZGlmCgoJCQkJLypUT0RPOiBUaGVyZSBhcmUgZXZlbiBtb3JlIG1lbnUgaXRlbXMhICovCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNpZmRlZiBfX1dJTkVfXwoJCQkJY2FzZSBJRF9MSUNFTlNFOgoJCQkJCVdpbmVMaWNlbnNlKEdsb2JhbHMuaE1haW5XbmQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfTk9fV0FSUkFOVFk6CgkJCQkJV2luZVdhcnJhbnR5KEdsb2JhbHMuaE1haW5XbmQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfQUJPVVRfV0lORToKCQkJCQlTaGVsbEFib3V0KGh3bmQsIFJTKGIyLElEU19XSU5FKSwgUlMoYjEsSURTX1dJTkVGSUxFKSwgMCk7CgkJCQkJYnJlYWs7CiNlbmRpZgoKCQkJCWNhc2UgSURfQUJPVVQ6CgkJCQkJU2hlbGxBYm91dChod25kLCBSUyhiMSxJRFNfV0lORUZJTEUpLCBOVUxMLCAwKTsKCQkJCQlicmVhazsKI2VuZGlmCS8qIF9OT19FWFRFTlNJT05TICovCgoJCQkJZGVmYXVsdDoKCQkJCQkvKlRPRE86IGlmICh3UGFyYW0gPj0gUE1fRklSU1RfTEFOR1VBR0UgJiYgd1BhcmFtIDw9IFBNX0xBU1RfTEFOR1VBR0UpCgkJCQkJCVNUUklOR19TZWxlY3RMYW5ndWFnZUJ5TnVtYmVyKHdQYXJhbSAtIFBNX0ZJUlNUX0xBTkdVQUdFKTsKCQkJCQllbHNlICovaWYgKChjbWQ8SURXX0ZJUlNUX0NISUxEIHx8IGNtZD49SURXX0ZJUlNUX0NISUxEKzB4MTAwKSAmJgoJCQkJCQkoY21kPFNDX1NJWkUgfHwgY21kPlNDX1JFU1RPUkUpKQoJCQkJCQlNZXNzYWdlQm94KGh3bmQsIFJTKGIyLElEU19OT19JTVBMKSwgUlMoYjEsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoKCQkJCQlyZXR1cm4gRGVmRnJhbWVQcm9jKGh3bmQsIEdsb2JhbHMuaG1kaWNsaWVudCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJCQl9CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9TSVpFOgoJCQlyZXNpemVfZnJhbWUoaHduZCwgTE9XT1JEKGxwYXJhbSksIEhJV09SRChscGFyYW0pKTsKCQkJYnJlYWs7CS8qIGRvIG5vdCBwYXNzIG1lc3NhZ2UgdG8gRGVmRnJhbWVQcm9jICovCgoJCWNhc2UgV01fREVWSUNFQ0hBTkdFOgoJCQlTZW5kTWVzc2FnZShod25kLCBXTV9DT01NQU5ELCBNQUtFTE9ORyhJRF9SRUZSRVNILDApLCAwKTsKCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9HRVRNSU5NQVhJTkZPOiB7CgkJCUxQTUlOTUFYSU5GTyBscG1taSA9IChMUE1JTk1BWElORk8pbHBhcmFtOwoKCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnggPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pIC8gU01fQ1hWSVJUVUFMU0NSRUVOICovCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS55IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSAvIFNNX0NZVklSVFVBTFNDUkVFTiAqLwoJCQlicmVhazt9CgoJCWNhc2UgRlJNX0NBTENfQ0xJRU5UOgoJCQlmcmFtZV9nZXRfY2xpZW50c3BhY2UoaHduZCwgKFBSRUNUKWxwYXJhbSk7CgkJCXJldHVybiBUUlVFOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJZGVmYXVsdDoKCQkJcmV0dXJuIERlZkZyYW1lUHJvYyhod25kLCBHbG9iYWxzLmhtZGljbGllbnQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBUQ0hBUiBnX3Bvc19uYW1lc1tDT0xVTU5TXVsyMF0gPSB7Cgl7J1wwJ30JLyogc3ltYm9sICovCn07CgpzdGF0aWMgY29uc3QgaW50IGdfcG9zX2FsaWduW10gPSB7CgkwLAoJSERGX0xFRlQsCS8qIE5hbWUgKi8KCUhERl9SSUdIVCwJLyogU2l6ZSAqLwoJSERGX0xFRlQsCS8qIENEYXRlICovCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhERl9MRUZULAkvKiBBRGF0ZSAqLwoJSERGX0xFRlQsCS8qIE1EYXRlICovCglIREZfTEVGVCwJLyogSW5kZXggKi8KCUhERl9DRU5URVIsCS8qIExpbmtzICovCiNlbmRpZgoJSERGX0NFTlRFUiwJLyogQXR0cmlidXRlcyAqLwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglIREZfTEVGVAkvKiBTZWN1cml0eSAqLwojZW5kaWYKfTsKCnN0YXRpYyB2b2lkIHJlc2l6ZV90cmVlKENoaWxkV25kKiBjaGlsZCwgaW50IGN4LCBpbnQgY3kpCnsKCUhEV1AgaGR3cCA9IEJlZ2luRGVmZXJXaW5kb3dQb3MoNCk7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IDA7CglydC50b3AgICAgPSAwOwoJcnQucmlnaHQgID0gY3g7CglydC5ib3R0b20gPSBjeTsKCgljeCA9IGNoaWxkLT5zcGxpdF9wb3MgKyBTUExJVF9XSURUSC8yOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJewoJCVdJTkRPV1BPUyB3cDsKCQlIRF9MQVlPVVQgaGRsOwoKCQloZGwucHJjICAgPSAmcnQ7CgkJaGRsLnB3cG9zID0gJndwOwoKCQlIZWFkZXJfTGF5b3V0KGNoaWxkLT5sZWZ0Lmh3bmRIZWFkZXIsICZoZGwpOwoKCQlEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+bGVmdC5od25kSGVhZGVyLCB3cC5od25kSW5zZXJ0QWZ0ZXIsCgkJCQkJCXdwLngtMSwgd3AueSwgY2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yKzEsIHdwLmN5LCB3cC5mbGFncyk7CgkJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPnJpZ2h0Lmh3bmRIZWFkZXIsIHdwLmh3bmRJbnNlcnRBZnRlciwKCQkJCQkJcnQubGVmdCtjeCsxLCB3cC55LCB3cC5jeC1jeCsyLCB3cC5jeSwgd3AuZmxhZ3MpOwoJfQojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCglEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+bGVmdC5od25kLCAwLCBydC5sZWZ0LCBydC50b3AsIGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMi1ydC5sZWZ0LCBydC5ib3R0b20tcnQudG9wLCBTV1BfTk9aT1JERVJ8U1dQX05PQUNUSVZBVEUpOwoJRGVmZXJXaW5kb3dQb3MoaGR3cCwgY2hpbGQtPnJpZ2h0Lmh3bmQsIDAsIHJ0LmxlZnQrY3grMSwgcnQudG9wLCBydC5yaWdodC1jeCwgcnQuYm90dG9tLXJ0LnRvcCwgU1dQX05PWk9SREVSfFNXUF9OT0FDVElWQVRFKTsKCglFbmREZWZlcldpbmRvd1BvcyhoZHdwKTsKfQoKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyBIV05EIGNyZWF0ZV9oZWFkZXIoSFdORCBwYXJlbnQsIFBhbmUqIHBhbmUsIGludCBpZCkKewoJSERfSVRFTSBoZGk7CglpbnQgaWR4OwoKCUhXTkQgaHduZCA9IENyZWF0ZVdpbmRvdyhXQ19IRUFERVIsIDAsIFdTX0NISUxEfFdTX1ZJU0lCTEV8SERTX0hPUlovKlRPRE86IHxIRFNfQlVUVE9OUyArIHNvcnQgb3JkZXJzKi8sCgkJCQkJCQkJMCwgMCwgMCwgMCwgcGFyZW50LCAoSE1FTlUpaWQsIEdsb2JhbHMuaEluc3RhbmNlLCAwKTsKCWlmICghaHduZCkKCQlyZXR1cm4gMDsKCglTZXRXaW5kb3dGb250KGh3bmQsIEdldFN0b2NrT2JqZWN0KERFRkFVTFRfR1VJX0ZPTlQpLCBGQUxTRSk7CgoJaGRpLm1hc2sgPSBIRElfVEVYVHxIRElfV0lEVEh8SERJX0ZPUk1BVDsKCglmb3IoaWR4PTA7IGlkeDxDT0xVTU5TOyBpZHgrKykgewoJCWhkaS5wc3pUZXh0ID0gZ19wb3NfbmFtZXNbaWR4XTsKCQloZGkuZm10ID0gSERGX1NUUklORyB8IGdfcG9zX2FsaWduW2lkeF07CgkJaGRpLmN4eSA9IHBhbmUtPndpZHRoc1tpZHhdOwoJCUhlYWRlcl9JbnNlcnRJdGVtKGh3bmQsIGlkeCwgJmhkaSk7Cgl9CgoJcmV0dXJuIGh3bmQ7Cn0KCiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCnN0YXRpYyB2b2lkIGluaXRfb3V0cHV0KEhXTkQgaHduZCkKewoJc3RhdGljIGNvbnN0IFRDSEFSIHMxMDAwW10gPSB7JzEnLCcwJywnMCcsJzAnLCdcMCd9OwoKCVRDSEFSIGJbMTZdOwoJSEZPTlQgb2xkX2ZvbnQ7CglIREMgaGRjID0gR2V0REMoaHduZCk7CgoJaWYgKEdldE51bWJlckZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCBzMTAwMCwgMCwgYiwgMTYpID4gNCkKCQlHbG9iYWxzLm51bV9zZXAgPSBiWzFdOwoJZWxzZQoJCUdsb2JhbHMubnVtX3NlcCA9IFRFWFQoJy4nKTsKCglvbGRfZm9udCA9IFNlbGVjdEZvbnQoaGRjLCBHbG9iYWxzLmhmb250KTsKCUdldFRleHRFeHRlbnRQb2ludDMyKGhkYywgc1NwYWNlLCAxLCAmR2xvYmFscy5zcGFjZVNpemUpOwoJU2VsZWN0Rm9udChoZGMsIG9sZF9mb250KTsKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgpzdGF0aWMgdm9pZCBkcmF3X2l0ZW0oUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIEVudHJ5KiBlbnRyeSwgaW50IGNhbGNXaWR0aENvbCk7CgoKLyogY2FsY3VsYXRlIHByZWZlcnJlZCB3aWR0aCBmb3IgYWxsIHZpc2libGUgY29sdW1ucyAqLwoKc3RhdGljIEJPT0wgY2FsY193aWR0aHMoUGFuZSogcGFuZSwgQk9PTCBhbnl3YXkpCnsKCWludCBjb2wsIHgsIGN4LCBzcGM9MypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCWludCBlbnRyaWVzID0gTGlzdEJveF9HZXRDb3VudChwYW5lLT5od25kKTsKCWludCBvcmdXaWR0aHNbQ09MVU1OU107CglpbnQgb3JnUG9zaXRpb25zW0NPTFVNTlMrMV07CglIRk9OVCBoZm9udE9sZDsKCUhEQyBoZGM7CglpbnQgY250OwoKCWlmICghYW55d2F5KSB7CgkJbWVtY3B5KG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSk7CgkJbWVtY3B5KG9yZ1Bvc2l0aW9ucywgcGFuZS0+cG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7Cgl9CgoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSAwOwoKCWhkYyA9IEdldERDKHBhbmUtPmh3bmQpOwoJaGZvbnRPbGQgPSBTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CgoJZm9yKGNudD0wOyBjbnQ8ZW50cmllczsgY250KyspIHsKCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBMaXN0Qm94X0dldEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGNudCk7CgoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIENPTFVNTlMpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCXggPSAwOwoJZm9yKGNvbD0wOyBjb2w8Q09MVU1OUzsgY29sKyspIHsKCQlwYW5lLT5wb3NpdGlvbnNbY29sXSA9IHg7CgkJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCgkJaWYgKGN4KSB7CgkJCWN4ICs9IHNwYzsKCgkJCWlmIChjeCA8IElNQUdFX1dJRFRIKQoJCQkJY3ggPSBJTUFHRV9XSURUSDsKCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gY3g7CgkJfQoKCQl4ICs9IGN4OwoJfQoKCXBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSA9IHg7CgoJTGlzdEJveF9TZXRIb3Jpem9udGFsRXh0ZW50KHBhbmUtPmh3bmQsIHgpOwoKCS8qIG5vIGNoYW5nZT8gKi8KCWlmICghbWVtY21wKG9yZ1dpZHRocywgcGFuZS0+d2lkdGhzLCBzaXplb2Yob3JnV2lkdGhzKSkpCgkJcmV0dXJuIEZBTFNFOwoKCS8qIGRvbid0IG1vdmUsIGlmIG9ubHkgY29sbGFwc2luZyBhbiBlbnRyeSAqLwoJaWYgKCFhbnl3YXkgJiYgcGFuZS0+d2lkdGhzWzBdPG9yZ1dpZHRoc1swXSAmJgoJCSFtZW1jbXAob3JnV2lkdGhzKzEsIHBhbmUtPndpZHRocysxLCBzaXplb2Yob3JnV2lkdGhzKS1zaXplb2YoaW50KSkpIHsKCQlwYW5lLT53aWR0aHNbMF0gPSBvcmdXaWR0aHNbMF07CgkJbWVtY3B5KHBhbmUtPnBvc2l0aW9ucywgb3JnUG9zaXRpb25zLCBzaXplb2Yob3JnUG9zaXRpb25zKSk7CgoJCXJldHVybiBGQUxTRTsKCX0KCglJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCglyZXR1cm4gVFJVRTsKfQoKCi8qIGNhbGN1bGF0ZSBvbmUgcHJlZmVycmVkIGNvbHVtbiB3aWR0aCAqLwoKc3RhdGljIHZvaWQgY2FsY19zaW5nbGVfd2lkdGgoUGFuZSogcGFuZSwgaW50IGNvbCkKewoJSEZPTlQgaGZvbnRPbGQ7CglpbnQgeCwgY3g7CglpbnQgZW50cmllcyA9IExpc3RCb3hfR2V0Q291bnQocGFuZS0+aHduZCk7CglpbnQgY250OwoJSERDIGhkYzsKCglwYW5lLT53aWR0aHNbY29sXSA9IDA7CgoJaGRjID0gR2V0REMocGFuZS0+aHduZCk7CgloZm9udE9sZCA9IFNlbGVjdEZvbnQoaGRjLCBHbG9iYWxzLmhmb250KTsKCglmb3IoY250PTA7IGNudDxlbnRyaWVzOyBjbnQrKykgewoJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgY250KTsKCQlEUkFXSVRFTVNUUlVDVCBkaXM7CgoJCWRpcy5DdGxUeXBlCQkgID0gMDsKCQlkaXMuQ3RsSUQJCSAgPSAwOwoJCWRpcy5pdGVtSUQJCSAgPSAwOwoJCWRpcy5pdGVtQWN0aW9uCSAgPSAwOwoJCWRpcy5pdGVtU3RhdGUJICA9IDA7CgkJZGlzLmh3bmRJdGVtCSAgPSBwYW5lLT5od25kOwoJCWRpcy5oREMJCQkgID0gaGRjOwoJCWRpcy5yY0l0ZW0ubGVmdAkgID0gMDsKCQlkaXMucmNJdGVtLnRvcCAgICA9IDA7CgkJZGlzLnJjSXRlbS5yaWdodCAgPSAwOwoJCWRpcy5yY0l0ZW0uYm90dG9tID0gMDsKCQkvKmRpcy5pdGVtRGF0YQkgID0gMDsgKi8KCgkJZHJhd19pdGVtKHBhbmUsICZkaXMsIGVudHJ5LCBjb2wpOwoJfQoKCVNlbGVjdE9iamVjdChoZGMsIGhmb250T2xkKTsKCVJlbGVhc2VEQyhwYW5lLT5od25kLCBoZGMpOwoKCWN4ID0gcGFuZS0+d2lkdGhzW2NvbF07CgoJaWYgKGN4KSB7CgkJY3ggKz0gMypHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCgkJaWYgKGN4IDwgSU1BR0VfV0lEVEgpCgkJCWN4ID0gSU1BR0VfV0lEVEg7Cgl9CgoJcGFuZS0+d2lkdGhzW2NvbF0gPSBjeDsKCgl4ID0gcGFuZS0+cG9zaXRpb25zW2NvbF0gKyBjeDsKCglmb3IoOyBjb2w8Q09MVU1OUzsgKSB7CgkJcGFuZS0+cG9zaXRpb25zWysrY29sXSA9IHg7CgkJeCArPSBwYW5lLT53aWR0aHNbY29sXTsKCX0KCglMaXN0Qm94X1NldEhvcml6b250YWxFeHRlbnQocGFuZS0+aHduZCwgeCk7Cn0KCgpzdGF0aWMgQk9PTCBwYXR0ZXJuX21hdGNoKExQQ1RTVFIgc3RyLCBMUENUU1RSIHBhdHRlcm4pCnsKCWZvciggOyAqc3RyJiYqcGF0dGVybjsgc3RyKysscGF0dGVybisrKSB7CgkJaWYgKCpwYXR0ZXJuID09ICcqJykgewoJCQlkbyBwYXR0ZXJuKys7CgkJCXdoaWxlKCpwYXR0ZXJuID09ICcqJyk7CgoJCQlpZiAoISpwYXR0ZXJuKQoJCQkJcmV0dXJuIFRSVUU7CgoJCQlmb3IoOyAqc3RyOyBzdHIrKykKCQkJCWlmICgqc3RyPT0qcGF0dGVybiAmJiBwYXR0ZXJuX21hdGNoKHN0ciwgcGF0dGVybikpCgkJCQkJcmV0dXJuIFRSVUU7CgoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCWVsc2UgaWYgKCpzdHIhPSpwYXR0ZXJuICYmICpwYXR0ZXJuIT0nPycpCgkJCXJldHVybiBGQUxTRTsKCX0KCglpZiAoKnN0ciB8fCAqcGF0dGVybikKCQlpZiAoKnBhdHRlcm4hPScqJyB8fCBwYXR0ZXJuWzFdIT0nXDAnKQoJCQlyZXR1cm4gRkFMU0U7CgoJcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIHBhdHRlcm5faW1hdGNoKExQQ1RTVFIgc3RyLCBMUENUU1RSIHBhdHRlcm4pCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCglsc3RyY3B5KGIxLCBzdHIpOwoJbHN0cmNweShiMiwgcGF0dGVybik7CglDaGFyVXBwZXIoYjEpOwoJQ2hhclVwcGVyKGIyKTsKCglyZXR1cm4gcGF0dGVybl9tYXRjaChiMSwgYjIpOwp9CgoKZW51bSBGSUxFX1RZUEUgewoJRlRfT1RIRVIJCT0gMCwKCUZUX0VYRUNVVEFCTEUJPSAxLAoJRlRfRE9DVU1FTlQJCT0gMgp9OwoKc3RhdGljIGVudW0gRklMRV9UWVBFIGdldF9maWxlX3R5cGUoTFBDVFNUUiBmaWxlbmFtZSk7CgoKLyogaW5zZXJ0IGxpc3Rib3ggZW50cmllcyBhZnRlciBpbmRleCBpZHggKi8KCnN0YXRpYyBpbnQgaW5zZXJ0X2VudHJpZXMoUGFuZSogcGFuZSwgRW50cnkqIGRpciwgTFBDVFNUUiBwYXR0ZXJuLCBpbnQgZmlsdGVyX2ZsYWdzLCBpbnQgaWR4KQp7CglFbnRyeSogZW50cnkgPSBkaXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm4gaWR4OwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfSElERSk7CgoJZm9yKDsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CiNpZm5kZWYgX0xFRlRfRklMRVMKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgIShlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCgkJCWNvbnRpbnVlOwojZW5kaWYKCgkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJLyogZG9uJ3QgZGlzcGxheSBlbnRyaWVzICIuIiBhbmQgIi4uIiBpbiB0aGUgbGVmdCBwYW5lICovCgkJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSkKCQkJCWlmICgKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnXDAnKSB8fAojZW5kaWYKCQkJCQkoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT1URVhUKCdcMCcpKSkKCQkJCQljb250aW51ZTsKCgkJCS8qIGZpbHRlciBkaXJlY3RvcmllcyBpbiByaWdodCBwYW5lICovCgkJCWlmICghcGFuZS0+dHJlZVBhbmUgJiYgIShmaWx0ZXJfZmxhZ3MmVEZfRElSRUNUT1JJRVMpKQoJCQkJY29udGludWU7CgkJfQoKCQkvKiBmaWx0ZXIgdXNpbmcgdGhlIGZpbGUgbmFtZSBwYXR0ZXJuICovCgkJaWYgKHBhdHRlcm4pCgkJCWlmICghcGF0dGVybl9pbWF0Y2goZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBwYXR0ZXJuKSkKCQkJCWNvbnRpbnVlOwoKCQkvKiBmaWx0ZXIgc3lzdGVtIGFuZCBoaWRkZW4gZmlsZXMgKi8KCQlpZiAoIShmaWx0ZXJfZmxhZ3MmVEZfSElEREVOKSAmJiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyYoRklMRV9BVFRSSUJVVEVfSElEREVOfEZJTEVfQVRUUklCVVRFX1NZU1RFTSkpKQoJCQljb250aW51ZTsKCgkJLyogZmlsdGVyIGxvb2tpbmcgYXQgdGhlIGZpbGUgdHlwZSAqLwoJCWlmICgoZmlsdGVyX2ZsYWdzJihURl9QUk9HUkFNU3xURl9ET0NVTUVOVFN8VEZfT1RIRVJTKSkgIT0gKFRGX1BST0dSQU1TfFRGX0RPQ1VNRU5UU3xURl9PVEhFUlMpKQoJCQlzd2l0Y2goZ2V0X2ZpbGVfdHlwZShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpKSB7CgkJCSAgY2FzZSBGVF9FWEVDVVRBQkxFOgoJCQkgIAlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9QUk9HUkFNUykpCgkJCQkJY29udGludWU7CgkJCQlicmVhazsKCgkJCSAgY2FzZSBGVF9ET0NVTUVOVDoKCQkJCWlmICghKGZpbHRlcl9mbGFncyAmIFRGX0RPQ1VNRU5UUykpCgkJCQkJY29udGludWU7CgkJCQlicmVhazsKCgkJCSAgZGVmYXVsdDogLyogVEZfT1RIRVJTICovCgkJCQlpZiAoIShmaWx0ZXJfZmxhZ3MgJiBURl9PVEhFUlMpKQoJCQkJCWNvbnRpbnVlOwoJCQl9CgoJCWlmIChpZHggIT0gLTEpCgkJCWlkeCsrOwoKCQlMaXN0Qm94X0luc2VydEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGlkeCwgZW50cnkpOwoKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgZW50cnktPmV4cGFuZGVkKQoJCQlpZHggPSBpbnNlcnRfZW50cmllcyhwYW5lLCBlbnRyeS0+ZG93biwgcGF0dGVybiwgZmlsdGVyX2ZsYWdzLCBpZHgpOwoJfQoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfU0hPVyk7CgoJcmV0dXJuIGlkeDsKfQoKCnN0YXRpYyB2b2lkIGZvcm1hdF9ieXRlcyhMUFRTVFIgYnVmZmVyLCBMT05HTE9ORyBieXRlcykKewoJc3RhdGljIGNvbnN0IFRDSEFSIHNGbXRHQltdID0geyclJywgJy4nLCAnMScsICdmJywgJyAnLCAnRycsICdCJywgJ1wwJ307CglzdGF0aWMgY29uc3QgVENIQVIgc0ZtdE1CW10gPSB7JyUnLCAnLicsICcxJywgJ2YnLCAnICcsICdNJywgJ0InLCAnXDAnfTsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzRm10a0JbXSA9IHsnJScsICcuJywgJzEnLCAnZicsICcgJywgJ2snLCAnQicsICdcMCd9OwoKCWZsb2F0IGZCeXRlcyA9IChmbG9hdClieXRlczsKCglpZiAoYnl0ZXMgPj0gMTA3Mzc0MTgyNCkJLyogMSBHQiAqLwoJCXdzcHJpbnRmKGJ1ZmZlciwgc0ZtdEdCLCBmQnl0ZXMvMTA3Mzc0MTgyNC5mKy41Zik7CgllbHNlIGlmIChieXRlcyA+PSAxMDQ4NTc2KQkvKiAxIE1CICovCgkJd3NwcmludGYoYnVmZmVyLCBzRm10TUIsIGZCeXRlcy8xMDQ4NTc2LmYrLjVmKTsKCWVsc2UgaWYgKGJ5dGVzID49IDEwMjQpCQkvKiAxIGtCICovCgkJd3NwcmludGYoYnVmZmVyLCBzRm10a0IsIGZCeXRlcy8xMDI0LmYrLjVmKTsKCWVsc2UKCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ051bUZtdCwgYnl0ZXMpOwp9CgpzdGF0aWMgdm9pZCBzZXRfc3BhY2Vfc3RhdHVzKHZvaWQpCnsKCVVMQVJHRV9JTlRFR0VSIHVsRnJlZUJ5dGVzVG9DYWxsZXIsIHVsVG90YWxCeXRlcywgdWxGcmVlQnl0ZXM7CglUQ0hBUiBmbXRbNjRdLCBiMVs2NF0sIGIyWzY0XSwgYnVmZmVyW0JVRkZFUl9MRU5dOwoKCWlmIChHZXREaXNrRnJlZVNwYWNlRXgoTlVMTCwgJnVsRnJlZUJ5dGVzVG9DYWxsZXIsICZ1bFRvdGFsQnl0ZXMsICZ1bEZyZWVCeXRlcykpIHsKCQlmb3JtYXRfYnl0ZXMoYjEsIHVsRnJlZUJ5dGVzVG9DYWxsZXIuUXVhZFBhcnQpOwoJCWZvcm1hdF9ieXRlcyhiMiwgdWxUb3RhbEJ5dGVzLlF1YWRQYXJ0KTsKCQl3c3ByaW50ZihidWZmZXIsIFJTKGZtdCxJRFNfRlJFRV9TUEFDRV9GTVQpLCBiMSwgYjIpOwoJfSBlbHNlCgkJbHN0cmNweShidWZmZXIsIHNRTWFya3MpOwoKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaHN0YXR1c2JhciwgU0JfU0VUVEVYVCwgMCwgKExQQVJBTSlidWZmZXIpOwp9CgoKc3RhdGljIFdORFBST0MgZ19vcmdUcmVlV25kUHJvYzsKCnN0YXRpYyB2b2lkIGNyZWF0ZV90cmVlX3dpbmRvdyhIV05EIHBhcmVudCwgUGFuZSogcGFuZSwgaW50IGlkLCBpbnQgaWRfaGVhZGVyLCBMUENUU1RSIHBhdHRlcm4sIGludCBmaWx0ZXJfZmxhZ3MpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBzTGlzdEJveFtdID0geydMJywnaScsJ3MnLCd0JywnQicsJ28nLCd4JywnXDAnfTsKCglzdGF0aWMgaW50IHNfaW5pdCA9IDA7CglFbnRyeSogZW50cnkgPSBwYW5lLT5yb290OwoKCXBhbmUtPmh3bmQgPSBDcmVhdGVXaW5kb3coc0xpc3RCb3gsIHNFbXB0eSwgV1NfQ0hJTER8V1NfVklTSUJMRXxXU19IU0NST0xMfFdTX1ZTQ1JPTEx8CgkJCQkJCQkJTEJTX0RJU0FCTEVOT1NDUk9MTHxMQlNfTk9JTlRFR1JBTEhFSUdIVHxMQlNfT1dORVJEUkFXRklYRUR8TEJTX05PVElGWSwKCQkJCQkJCQkwLCAwLCAwLCAwLCBwYXJlbnQsIChITUVOVSlpZCwgR2xvYmFscy5oSW5zdGFuY2UsIDApOwoKCVNldFdpbmRvd0xvbmdQdHIocGFuZS0+aHduZCwgR1dMUF9VU0VSREFUQSwgKExQQVJBTSlwYW5lKTsKCWdfb3JnVHJlZVduZFByb2MgPSBTdWJjbGFzc1dpbmRvdyhwYW5lLT5od25kLCBUcmVlV25kUHJvYyk7CgoJU2V0V2luZG93Rm9udChwYW5lLT5od25kLCBHbG9iYWxzLmhmb250LCBGQUxTRSk7CgoJLyogaW5zZXJ0IGVudHJpZXMgaW50byBsaXN0Ym94ICovCglpZiAoZW50cnkpCgkJaW5zZXJ0X2VudHJpZXMocGFuZSwgZW50cnksIHBhdHRlcm4sIGZpbHRlcl9mbGFncywgLTEpOwoKCS8qIGNhbGN1bGF0ZSBjb2x1bW4gd2lkdGhzICovCglpZiAoIXNfaW5pdCkgewoJCXNfaW5pdCA9IDE7CgkJaW5pdF9vdXRwdXQocGFuZS0+aHduZCk7Cgl9CgoJY2FsY193aWR0aHMocGFuZSwgVFJVRSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglwYW5lLT5od25kSGVhZGVyID0gY3JlYXRlX2hlYWRlcihwYXJlbnQsIHBhbmUsIGlkX2hlYWRlcik7CiNlbmRpZgp9CgoKc3RhdGljIHZvaWQgSW5pdENoaWxkV2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJY3JlYXRlX3RyZWVfd2luZG93KGNoaWxkLT5od25kLCAmY2hpbGQtPmxlZnQsIElEV19UUkVFX0xFRlQsIElEV19IRUFERVJfTEVGVCwgTlVMTCwgVEZfQUxMKTsKCWNyZWF0ZV90cmVlX3dpbmRvdyhjaGlsZC0+aHduZCwgJmNoaWxkLT5yaWdodCwgSURXX1RSRUVfUklHSFQsIElEV19IRUFERVJfUklHSFQsIGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgY2hpbGQtPmZpbHRlcl9mbGFncyk7Cn0KCgpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpCnsKCVNZU1RFTVRJTUUgc3lzdGltZTsKCUZJTEVUSU1FIGxmdDsKCWludCBsZW4gPSAwOwoKCSpidWZmZXIgPSBURVhUKCdcMCcpOwoKCWlmICghZnQtPmR3TG93RGF0ZVRpbWUgJiYgIWZ0LT5kd0hpZ2hEYXRlVGltZSkKCQlyZXR1cm47CgoJaWYgKCFGaWxlVGltZVRvTG9jYWxGaWxlVGltZShmdCwgJmxmdCkpCgkJe2VycjogbHN0cmNweShidWZmZXIsc1FNYXJrcyk7IHJldHVybjt9CgoJaWYgKCFGaWxlVGltZVRvU3lzdGVtVGltZSgmbGZ0LCAmc3lzdGltZSkpCgkJZ290byBlcnI7CgoJaWYgKHZpc2libGVfY29scyAmIENPTF9EQVRFKSB7CgkJbGVuID0gR2V0RGF0ZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCAmc3lzdGltZSwgMCwgYnVmZmVyLCBCVUZGRVJfTEVOKTsKCQlpZiAoIWxlbikKCQkJZ290byBlcnI7Cgl9CgoJaWYgKHZpc2libGVfY29scyAmIENPTF9USU1FKSB7CgkJaWYgKGxlbikKCQkJYnVmZmVyW2xlbi0xXSA9ICcgJzsKCgkJYnVmZmVyW2xlbisrXSA9ICcgJzsKCgkJaWYgKCFHZXRUaW1lRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsICZzeXN0aW1lLCAwLCBidWZmZXIrbGVuLCBCVUZGRVJfTEVOLWxlbikpCgkJCWJ1ZmZlcltsZW5dID0gVEVYVCgnXDAnKTsKCX0KfQoKCnN0YXRpYyB2b2lkIGNhbGNfd2lkdGgoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglSRUNUIHJ0ID0gezAsIDAsIDAsIDB9OwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKc3RhdGljIHZvaWQgY2FsY190YWJiZWRfd2lkdGgoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglSRUNUIHJ0ID0gezAsIDAsIDAsIDB9OwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1B8KDI8PDgpKTsKCS8qRklYTUUgcnQgKDAsMCkgPz8/ICovCgoJaWYgKHJ0LnJpZ2h0ID4gcGFuZS0+d2lkdGhzW2NvbF0pCgkJcGFuZS0+d2lkdGhzW2NvbF0gPSBydC5yaWdodDsKfQoKCnN0YXRpYyB2b2lkIG91dHB1dF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0ciwgRFdPUkQgZmxhZ3MpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8ZmxhZ3MpOwp9CgpzdGF0aWMgdm9pZCBvdXRwdXRfdGFiYmVkX3RleHQoUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIGludCBjb2wsIExQQ1RTVFIgc3RyKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgovKglEUkFXVEVYVFBBUkFNUyBkdHAgPSB7c2l6ZW9mKERSQVdURVhUUEFSQU1TKSwgMn07CglEcmF3VGV4dEV4KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1AsICZkdHApOyovCgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUHwoMjw8OCkpOwp9CgpzdGF0aWMgdm9pZCBvdXRwdXRfbnVtYmVyKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCUxQQ1RTVFIgcyA9IHN0cjsKCVRDSEFSIGJbMTI4XTsKCUxQVFNUUiBkID0gYjsKCWludCBwb3M7CgoJcnQubGVmdCAgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sXStHbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LnRvcCAgICA9IGRpcy0+cmNJdGVtLnRvcDsKCXJ0LnJpZ2h0ICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbCsxXS1HbG9iYWxzLnNwYWNlU2l6ZS5jeDsKCXJ0LmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCglpZiAoKnMpCgkJKmQrKyA9ICpzKys7CgoJLyogaW5zZXJ0IG51bWJlciBzZXBhcmF0b3IgY2hhcmFjdGVycyAqLwoJcG9zID0gbHN0cmxlbihzKSAlIDM7CgoJd2hpbGUoKnMpCgkJaWYgKHBvcy0tKQoJCQkqZCsrID0gKnMrKzsKCQllbHNlIHsKCQkJKmQrKyA9IEdsb2JhbHMubnVtX3NlcDsKCQkJcG9zID0gMzsKCQl9CgoJRHJhd1RleHQoZGlzLT5oREMsIGIsIGQtYiwgJnJ0LCBEVF9SSUdIVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VORF9FTExJUFNJUyk7Cn0KCgpzdGF0aWMgQk9PTCBpc19leGVfZmlsZShMUENUU1RSIGV4dCkKewoJc3RhdGljIGNvbnN0IFRDSEFSIGV4ZWN1dGFibGVfZXh0ZW5zaW9uc1tdWzRdID0gewoJCXsnQycsJ08nLCdNJywnXDAnfSwKCQl7J0UnLCdYJywnRScsJ1wwJ30sCgkJeydCJywnQScsJ1QnLCdcMCd9LAoJCXsnQycsJ00nLCdEJywnXDAnfSwKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCXsnQycsJ00nLCdNJywnXDAnfSwKCQl7J0InLCdUJywnTScsJ1wwJ30sCgkJeydBJywnVycsJ0snLCdcMCd9LAojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQl7J1wwJ30KCX07CgoJVENIQVIgZXh0X2J1ZmZlcltfTUFYX0VYVF07Cgljb25zdCBUQ0hBUiAoKnApWzRdOwoJTFBDVFNUUiBzOwoJTFBUU1RSIGQ7CgoJZm9yKHM9ZXh0KzEsZD1leHRfYnVmZmVyOyAoKmQ9dG9sb3dlcigqcykpOyBzKyspCgkJZCsrOwoKCWZvcihwPWV4ZWN1dGFibGVfZXh0ZW5zaW9uczsgKCpwKVswXTsgcCsrKQoJCWlmICghbHN0cmNtcGkoZXh0X2J1ZmZlciwgKnApKQoJCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIGlzX3JlZ2lzdGVyZWRfdHlwZShMUENUU1RSIGV4dCkKewoJLyogY2hlY2sgaWYgdGhlcmUgZXhpc3RzIGEgY2xhc3NuYW1lIGZvciB0aGlzIGZpbGUgZXh0ZW5zaW9uIGluIHRoZSByZWdpc3RyeSAqLwoJaWYgKCFSZWdRdWVyeVZhbHVlKEhLRVlfQ0xBU1NFU19ST09ULCBleHQsIE5VTEwsIE5VTEwpKQoJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIGVudW0gRklMRV9UWVBFIGdldF9maWxlX3R5cGUoTFBDVFNUUiBmaWxlbmFtZSkKewoJTFBDVFNUUiBleHQgPSBfdGNzcmNocihmaWxlbmFtZSwgJy4nKTsKCWlmICghZXh0KQoJCWV4dCA9IHNFbXB0eTsKCglpZiAoaXNfZXhlX2ZpbGUoZXh0KSkKCQlyZXR1cm4gRlRfRVhFQ1VUQUJMRTsKCWVsc2UgaWYgKGlzX3JlZ2lzdGVyZWRfdHlwZShleHQpKQoJCXJldHVybiBGVF9ET0NVTUVOVDsKCWVsc2UKCQlyZXR1cm4gRlRfT1RIRVI7Cn0KCgpzdGF0aWMgdm9pZCBkcmF3X2l0ZW0oUGFuZSogcGFuZSwgTFBEUkFXSVRFTVNUUlVDVCBkaXMsIEVudHJ5KiBlbnRyeSwgaW50IGNhbGNXaWR0aENvbCkKewoJVENIQVIgYnVmZmVyW0JVRkZFUl9MRU5dOwoJRFdPUkQgYXR0cnM7CglpbnQgdmlzaWJsZV9jb2xzID0gcGFuZS0+dmlzaWJsZV9jb2xzOwoJQ09MT1JSRUYgYmtjb2xvciwgdGV4dGNvbG9yOwoJUkVDVCBmb2N1c1JlY3QgPSBkaXMtPnJjSXRlbTsKCUhCUlVTSCBoYnJ1c2g7CgllbnVtIElNQUdFIGltZzsKCWludCBpbWdfcG9zLCBjeDsKCWludCBjb2wgPSAwOwoKCWlmIChlbnRyeSkgewoJCWF0dHJzID0gZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlczsKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSB7CgkJCWlmIChlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMV09PVRFWFQoJy4nKQoJCQkJCSYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsyXT09VEVYVCgnXDAnKSkKCQkJCWltZyA9IElNR19GT0xERVJfVVA7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJZWxzZSBpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCdcMCcpKQoJCQkJaW1nID0gSU1HX0ZPTERFUl9DVVI7CiNlbmRpZgoJCQllbHNlIGlmICgKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJIGVudHJ5LT5leHBhbmRlZCB8fAojZW5kaWYKCQkJCQkgKHBhbmUtPnRyZWVQYW5lICYmIChkaXMtPml0ZW1TdGF0ZSZPRFNfRk9DVVMpKSkKCQkJCWltZyA9IElNR19PUEVOX0ZPTERFUjsKCQkJZWxzZQoJCQkJaW1nID0gSU1HX0ZPTERFUjsKCQl9IGVsc2UgewoJCQlzd2l0Y2goZ2V0X2ZpbGVfdHlwZShlbnRyeS0+ZGF0YS5jRmlsZU5hbWUpKSB7CgkJCSAgY2FzZSBGVF9FWEVDVVRBQkxFOglpbWcgPSBJTUdfRVhFQ1VUQUJMRTsJYnJlYWs7CgkJCSAgY2FzZSBGVF9ET0NVTUVOVDoJCWltZyA9IElNR19ET0NVTUVOVDsJCWJyZWFrOwoJCQkgIGRlZmF1bHQ6CQkJCWltZyA9IElNR19GSUxFOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQlhdHRycyA9IDA7CgkJaW1nID0gSU1HX05PTkU7Cgl9CgoJaWYgKHBhbmUtPnRyZWVQYW5lKSB7CgkJaWYgKGVudHJ5KSB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0ICsgZW50cnktPmxldmVsKihJTUFHRV9XSURUSCtUUkVFX0xJTkVfRFgpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCQkJaW50IHg7CgkJCQlpbnQgeSA9IGRpcy0+cmNJdGVtLnRvcCArIElNQUdFX0hFSUdIVC8yOwoJCQkJRW50cnkqIHVwOwoJCQkJUkVDVCBydF9jbGlwOwoJCQkJSFJHTiBocmduX29yZyA9IENyZWF0ZVJlY3RSZ24oMCwgMCwgMCwgMCk7CgkJCQlIUkdOIGhyZ247CgoJCQkJcnRfY2xpcC5sZWZ0ICAgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCQkJcnRfY2xpcC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CgkJCQlydF9jbGlwLnJpZ2h0ICA9IGRpcy0+cmNJdGVtLmxlZnQrcGFuZS0+d2lkdGhzW2NvbF07CgkJCQlydF9jbGlwLmJvdHRvbSA9IGRpcy0+cmNJdGVtLmJvdHRvbTsKCgkJCQlocmduID0gQ3JlYXRlUmVjdFJnbkluZGlyZWN0KCZydF9jbGlwKTsKCgkJCQlpZiAoIUdldENsaXBSZ24oZGlzLT5oREMsIGhyZ25fb3JnKSkgewoJCQkJCURlbGV0ZU9iamVjdChocmduX29yZyk7CgkJCQkJaHJnbl9vcmcgPSAwOwoJCQkJfQoKCQkJCS8qIEhHRElPQkogaG9sZFBlbiA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoQkxBQ0tfUEVOKSk7ICovCgkJCQlFeHRTZWxlY3RDbGlwUmduKGRpcy0+aERDLCBocmduLCBSR05fQU5EKTsKCQkJCURlbGV0ZU9iamVjdChocmduKTsKCgkJCQlpZiAoKHVwPWVudHJ5LT51cCkgIT0gTlVMTCkgewoJCQkJCU1vdmVUb0V4KGRpcy0+aERDLCBpbWdfcG9zLUlNQUdFX1dJRFRILzIsIHksIDApOwoJCQkJCUxpbmVUbyhkaXMtPmhEQywgaW1nX3Bvcy0yLCB5KTsKCgkJCQkJeCA9IGltZ19wb3MgLSBJTUFHRV9XSURUSC8yOwoKCQkJCQlkbyB7CgkJCQkJCXggLT0gSU1BR0VfV0lEVEgrVFJFRV9MSU5FX0RYOwoKCQkJCQkJaWYgKHVwLT5uZXh0CiNpZm5kZWYgX0xFRlRfRklMRVMKCQkJCQkJCSYmICh1cC0+bmV4dC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQojZW5kaWYKCQkJCQkJCSkgewoJCQkJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCwgMCk7CgkJCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgkJCQkJCX0KCQkJCQl9IHdoaWxlKCh1cD11cC0+dXApICE9IE5VTEwpOwoJCQkJfQoKCQkJCXggPSBpbWdfcG9zIC0gSU1BR0VfV0lEVEgvMjsKCgkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wLCAwKTsKCQkJCUxpbmVUbyhkaXMtPmhEQywgeCwgeSk7CgoJCQkJaWYgKGVudHJ5LT5uZXh0CiNpZm5kZWYgX0xFRlRfRklMRVMKCQkJCQkmJiAoZW50cnktPm5leHQtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCiNlbmRpZgoJCQkJCSkKCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgoJCQkJU2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpOwoJCQkJaWYgKGhyZ25fb3JnKSBEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJLyogU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBob2xkUGVuKTsgKi8KCQkJfSBlbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpIHsKCQkJCWludCByaWdodCA9IGltZ19wb3MgKyBJTUFHRV9XSURUSCAtIFRSRUVfTElORV9EWDsKCgkJCQlpZiAocmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQkJCQlwYW5lLT53aWR0aHNbY29sXSA9IHJpZ2h0OwoJCQl9CgkJfSBlbHNlICB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCX0KCX0gZWxzZSB7CgkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQ7CgoJCWlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gSU1BR0VfV0lEVEg7Cgl9CgoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCWZvY3VzUmVjdC5sZWZ0ID0gaW1nX3BvcyAtMjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeSkgewoJCQlSRUNUIHJ0ID0gezB9OwoKCQkJRHJhd1RleHQoZGlzLT5oREMsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJCQlmb2N1c1JlY3QucmlnaHQgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0rVFJFRV9MSU5FX0RYICsgcnQucmlnaHQgKzI7CgkJfQojZWxzZQoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQoJCQl0ZXh0Y29sb3IgPSBDT0xPUl9DT01QUkVTU0VEOwoJCWVsc2UKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJCXRleHRjb2xvciA9IFJHQigwLDAsMCk7CgoJCWlmIChkaXMtPml0ZW1TdGF0ZSAmIE9EU19GT0NVUykgewoJCQl0ZXh0Y29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCQlia2NvbG9yID0gQ09MT1JfU0VMRUNUSU9OOwoJCX0gZWxzZSB7CgkJCWJrY29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCX0KCgkJaGJydXNoID0gQ3JlYXRlU29saWRCcnVzaChia2NvbG9yKTsKCQlGaWxsUmVjdChkaXMtPmhEQywgJmZvY3VzUmVjdCwgaGJydXNoKTsKCQlEZWxldGVPYmplY3QoaGJydXNoKTsKCgkJU2V0QmtNb2RlKGRpcy0+aERDLCBUUkFOU1BBUkVOVCk7CgkJU2V0VGV4dENvbG9yKGRpcy0+aERDLCB0ZXh0Y29sb3IpOwoKCQljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCQlpZiAoY3ggJiYgaW1nIT1JTUdfTk9ORSkgewoJCQlpZiAoY3ggPiBJTUFHRV9XSURUSCkKCQkJCWN4ID0gSU1BR0VfV0lEVEg7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCQkJaWYgKGVudHJ5LT5oaWNvbiAmJiBlbnRyeS0+aGljb24hPShISUNPTiktMSkKCQkJCURyYXdJY29uRXgoZGlzLT5oREMsIGltZ19wb3MsIGRpcy0+cmNJdGVtLnRvcCwgZW50cnktPmhpY29uLCBjeCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksIDAsIDAsIERJX05PUk1BTCk7CgkJCWVsc2UKI2VuZGlmCgkJCQlJbWFnZUxpc3RfRHJhd0V4KEdsb2JhbHMuaGltbCwgaW1nLCBkaXMtPmhEQywKCQkJCQkJCQkgaW1nX3BvcywgZGlzLT5yY0l0ZW0udG9wLCBjeCwKCQkJCQkJCQkgSU1BR0VfSEVJR0hULCBia2NvbG9yLCBDTFJfREVGQVVMVCwgSUxEX05PUk1BTCk7CgkJfQoJfQoKCWlmICghZW50cnkpCgkJcmV0dXJuOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCglpZiAoaW1nID49IElNR19GT0xERVJfVVApCgkJcmV0dXJuOwojZW5kaWYKCgljb2wrKzsKCgkvKiBvdXB1dCBmaWxlIG5hbWUgKi8KCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgMCk7CgllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCgljb2wrKzsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwogIGlmICghcGFuZS0+dHJlZVBhbmUpIHsKI2VuZGlmCgogICAgICAgIC8qIGRpc3BsYXkgZmlsZSBzaXplICovCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX1NJWkUpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJaWYgKCEoYXR0cnMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkKI2VuZGlmCgkJewoJCQlVTE9OR0xPTkcgc2l6ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAoKFVMT05HTE9ORyllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoIDw8IDMyKSB8IGVudHJ5LT5kYXRhLm5GaWxlU2l6ZUxvdzsKCgkJCV9zdHByaW50ZihidWZmZXIsIHNMb25nTnVtRm10LCBzaXplKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfbnVtYmVyKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOy8qVE9ETzogbm90IGV2ZXIgdGltZSBlbm91Z2ggKi8KCQl9CgoJCWNvbCsrOwoJfQoKCS8qIGRpc3BsYXkgZmlsZSBkYXRlICovCglpZiAodmlzaWJsZV9jb2xzICYgKENPTF9EQVRFfENPTF9USU1FKSkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0Q3JlYXRpb25UaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwoKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRMYXN0QWNjZXNzVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdExhc3RXcml0ZVRpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7Cgl9CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglpZiAoZW50cnktPmJoZmlfdmFsaWQpIHsKICAgICAgICAgICAgVUxPTkdMT05HIGluZGV4ID0gKChVTE9OR0xPTkcpZW50cnktPmJoZmkubkZpbGVJbmRleEhpZ2ggPDwgMzIpIHwgZW50cnktPmJoZmkubkZpbGVJbmRleExvdzsKCgkJaWYgKHZpc2libGVfY29scyAmIENPTF9JTkRFWCkgewoJCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ0hleEZtdCwgaW5kZXgpOwoKCQkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIERUX1JJR0hUKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJCWNvbCsrOwoJCX0KCgkJaWYgKHZpc2libGVfY29scyAmIENPTF9MSU5LUykgewoJCQl3c3ByaW50ZihidWZmZXIsIHNOdW1GbXQsIGVudHJ5LT5iaGZpLm5OdW1iZXJPZkxpbmtzKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCBEVF9DRU5URVIpOwoJCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQkJY29sKys7CgkJfQoJfSBlbHNlCgkJY29sICs9IDI7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCS8qIHNob3cgZmlsZSBhdHRyaWJ1dGVzICovCglpZiAodmlzaWJsZV9jb2xzICYgQ09MX0FUVFJJQlVURVMpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJc3RhdGljIGNvbnN0IFRDSEFSIHM0VGFic1tdID0geycgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXDAnfTsKCQlsc3RyY3B5KGJ1ZmZlciwgczRUYWJzKTsKI2Vsc2UKCQlzdGF0aWMgY29uc3QgVENIQVIgczExVGFic1tdID0geycgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywnXDAnfTsKCQlsc3RyY3B5KGJ1ZmZlciwgczExVGFicyk7CiNlbmRpZgoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9OT1JNQUwpCQkJCQlidWZmZXJbIDBdID0gJ04nOwoJCWVsc2UgewoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9SRUFET05MWSkJCQlidWZmZXJbIDJdID0gJ1InOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ISURERU4pCQkJCWJ1ZmZlclsgNF0gPSAnSCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1NZU1RFTSkJCQkJYnVmZmVyWyA2XSA9ICdTJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQVJDSElWRSkJCQkJYnVmZmVyWyA4XSA9ICdBJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRCkJCQlidWZmZXJbMTBdID0gJ0MnOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkJCQlidWZmZXJbMTJdID0gJ0QnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9FTkNSWVBURUQpCQkJYnVmZmVyWzE0XSA9ICdFJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfVEVNUE9SQVJZKQkJCWJ1ZmZlclsxNl0gPSAnVCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1NQQVJTRV9GSUxFKQkJCWJ1ZmZlclsxOF0gPSAnUCc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1JFUEFSU0VfUE9JTlQpCQlidWZmZXJbMjBdID0gJ1EnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9PRkZMSU5FKQkJCQlidWZmZXJbMjJdID0gJ08nOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9OT1RfQ09OVEVOVF9JTkRFWEVEKQlidWZmZXJbMjRdID0gJ1gnOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCQl9CgoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90YWJiZWRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfdGFiYmVkX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoKCQljb2wrKzsKCX0KCi8qVE9ETwoJaWYgKGZsYWdzLnNlY3VyaXR5KSB7CgkJc3RhdGljIGNvbnN0IFRDSEFSIHNTZWNUYWJzW10gPSB7CgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknXDAnCgkJfTsKCgkJRFdPUkQgcmlnaHRzID0gZ2V0X2FjY2Vzc19tYXNrKCk7CgoJCWxzdHJjcHkoYnVmZmVyLCBzU2VjVGFicyk7CgoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfREFUQSkJCQlidWZmZXJbIDBdID0gJ1InOwoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0RBVEEpCQkJYnVmZmVyWyAyXSA9ICdXJzsKCQlpZiAocmlnaHRzICYgRklMRV9BUFBFTkRfREFUQSkJCQlidWZmZXJbIDRdID0gJ0EnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfRUEpCQkJCXtidWZmZXJbNl0gPSAnZW50cnknOyBidWZmZXJbIDddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9FQSkJCQkJe2J1ZmZlcls5XSA9ICdlbnRyeSc7IGJ1ZmZlclsxMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBGSUxFX0VYRUNVVEUpCQkJCWJ1ZmZlclsxMl0gPSAnWCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfREVMRVRFX0NISUxEKQkJCWJ1ZmZlclsxNF0gPSAnRCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxNl0gPSAnYSc7IGJ1ZmZlclsxN10gPSAnUic7fQoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0FUVFJJQlVURVMpCQl7YnVmZmVyWzE5XSA9ICdhJzsgYnVmZmVyWzIwXSA9ICdXJzt9CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX0RBQykJCQkJCWJ1ZmZlclsyMl0gPSAnQyc7CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX09XTkVSKQkJCQlidWZmZXJbMjRdID0gJ08nOwoJCWlmIChyaWdodHMgJiBTWU5DSFJPTklaRSkJCQkJYnVmZmVyWzI2XSA9ICdTJzsKCgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCBEVF9MRUZULCAzLCBwc2l6ZSk7Cgl9CgoJaWYgKGZsYWdzLmRlc2NyaXB0aW9uKSB7CgkJZ2V0X2Rlc2NyaXB0aW9uKGJ1ZmZlcik7CgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCAwLCBwc2l6ZSk7Cgl9CiovCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICB9CgogICAgICAgIC8qIGRyYXcgZm9jdXMgZnJhbWUgKi8KCWlmICgoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSAmJiBjYWxjV2lkdGhDb2w9PS0xKSB7CgkgICAgICAgIC8qIEN1cnJlbnRseSBbMDQvMjAwMF0gV2luZSBuZWl0aGVyIGJlaGF2ZXMgZXhhY3RseSB0aGUgc2FtZSAqLwoJICAgICAgICAvKiB3YXkgYXMgV0lOIDk1IG5vciBsaWtlIFdpbmRvd3MgTlQuLi4gKi8KCQlIR0RJT0JKIGxhc3RCcnVzaDsKCQlIUEVOIGxhc3RQZW47CgkJSFBFTiBocGVuOwoKCQlpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgewkvKiBXaW5kb3dzIE5UPyAqLwoJCQlMT0dCUlVTSCBsYiA9IHtQU19TT0xJRCwgUkdCKDI1NSwyNTUsMjU1KX07CgkJCWhwZW4gPSBFeHRDcmVhdGVQZW4oUFNfQ09TTUVUSUN8UFNfQUxURVJOQVRFLCAxLCAmbGIsIDAsIDApOwoJCX0gZWxzZQoJCQlocGVuID0gQ3JlYXRlUGVuKFBTX0RPVCwgMCwgUkdCKDI1NSwyNTUsMjU1KSk7CgoJCWxhc3RQZW4gPSBTZWxlY3RQZW4oZGlzLT5oREMsIGhwZW4pOwoJCWxhc3RCcnVzaCA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoSE9MTE9XX0JSVVNIKSk7CgkJU2V0Uk9QMihkaXMtPmhEQywgUjJfWE9SUEVOKTsKCQlSZWN0YW5nbGUoZGlzLT5oREMsIGZvY3VzUmVjdC5sZWZ0LCBmb2N1c1JlY3QudG9wLCBmb2N1c1JlY3QucmlnaHQsIGZvY3VzUmVjdC5ib3R0b20pOwoJCVNlbGVjdE9iamVjdChkaXMtPmhEQywgbGFzdEJydXNoKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RQZW4pOwoJCURlbGV0ZU9iamVjdChocGVuKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCn0KCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyB2b2lkIGRyYXdfc3BsaXRiYXIoSFdORCBod25kLCBpbnQgeCkKewoJUkVDVCBydDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJcnQubGVmdCA9IHggLSBTUExJVF9XSURUSC8yOwoJcnQucmlnaHQgPSB4ICsgU1BMSVRfV0lEVEgvMisxOwoKCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBzZXRfaGVhZGVyKFBhbmUqIHBhbmUpCnsKCUhEX0lURU0gaXRlbTsKCWludCBzY3JvbGxfcG9zID0gR2V0U2Nyb2xsUG9zKHBhbmUtPmh3bmQsIFNCX0hPUlopOwoJaW50IGk9MCwgeD0wOwoKCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCWl0ZW0uY3h5ID0gMDsKCglmb3IoOyB4K3BhbmUtPndpZHRoc1tpXTxzY3JvbGxfcG9zICYmIGk8Q09MVU1OUzsgaSsrKSB7CgkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSwgJml0ZW0pOwoJfQoKCWlmIChpIDwgQ09MVU1OUykgewoJCXggKz0gcGFuZS0+d2lkdGhzW2ldOwoJCWl0ZW0uY3h5ID0geCAtIHNjcm9sbF9wb3M7CgkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSsrLCAmaXRlbSk7CgoJCWZvcig7IGk8Q09MVU1OUzsgaSsrKSB7CgkJCWl0ZW0uY3h5ID0gcGFuZS0+d2lkdGhzW2ldOwoJCQl4ICs9IHBhbmUtPndpZHRoc1tpXTsKCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaSwgJml0ZW0pOwoJCX0KCX0KfQoKc3RhdGljIExSRVNVTFQgcGFuZV9ub3RpZnkoUGFuZSogcGFuZSwgTk1IRFIqIHBubWgpCnsKCXN3aXRjaChwbm1oLT5jb2RlKSB7CgkJY2FzZSBIRE5fVFJBQ0s6CgkJY2FzZSBIRE5fRU5EVFJBQ0s6IHsKCQkJSERfTk9USUZZKiBwaGRuID0gKEhEX05PVElGWSopIHBubWg7CgkJCWludCBpZHggPSBwaGRuLT5pSXRlbTsKCQkJaW50IGR4ID0gcGhkbi0+cGl0ZW0tPmN4eSAtIHBhbmUtPndpZHRoc1tpZHhdOwoJCQlpbnQgaTsKCgkJCVJFQ1QgY2xudDsKCQkJR2V0Q2xpZW50UmVjdChwYW5lLT5od25kLCAmY2xudCk7CgoJCQkvKiBtb3ZlIGltbWVkaWF0ZSB0byBzaW11bGF0ZSBIRFNfRlVMTERSQUcgKGZvciBub3cgWzA0LzIwMDBdIG5vdCByZWFsbHkgbmVlZGVkIHdpdGggV0lORUxJQikgKi8KCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgaWR4LCBwaGRuLT5waXRlbSk7CgoJCQlwYW5lLT53aWR0aHNbaWR4XSArPSBkeDsKCgkJCWZvcihpPWlkeDsgKytpPD1DT0xVTU5TOyApCgkJCQlwYW5lLT5wb3NpdGlvbnNbaV0gKz0gZHg7CgoJCQl7CgkJCQlpbnQgc2Nyb2xsX3BvcyA9IEdldFNjcm9sbFBvcyhwYW5lLT5od25kLCBTQl9IT1JaKTsKCQkJCVJFQ1QgcnRfc2NyOwoJCQkJUkVDVCBydF9jbGlwOwoKCQkJCXJ0X3Njci5sZWZ0ICAgPSBwYW5lLT5wb3NpdGlvbnNbaWR4KzFdLXNjcm9sbF9wb3M7CgkJCQlydF9zY3IudG9wICAgID0gMDsKCQkJCXJ0X3Njci5yaWdodCAgPSBjbG50LnJpZ2h0OwoJCQkJcnRfc2NyLmJvdHRvbSA9IGNsbnQuYm90dG9tOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gcGFuZS0+cG9zaXRpb25zW2lkeF0tc2Nyb2xsX3BvczsKCQkJCXJ0X2NsaXAudG9wICAgID0gMDsKCQkJCXJ0X2NsaXAucmlnaHQgID0gY2xudC5yaWdodDsKCQkJCXJ0X2NsaXAuYm90dG9tID0gY2xudC5ib3R0b207CgoJCQkJaWYgKHJ0X3Njci5sZWZ0IDwgMCkgcnRfc2NyLmxlZnQgPSAwOwoJCQkJaWYgKHJ0X2NsaXAubGVmdCA8IDApIHJ0X2NsaXAubGVmdCA9IDA7CgoJCQkJU2Nyb2xsV2luZG93RXgocGFuZS0+aHduZCwgZHgsIDAsICZydF9zY3IsICZydF9jbGlwLCAwLCAwLCBTV19JTlZBTElEQVRFKTsKCgkJCQlydF9jbGlwLnJpZ2h0ID0gcGFuZS0+cG9zaXRpb25zW2lkeCsxXTsKCQkJCVJlZHJhd1dpbmRvdyhwYW5lLT5od25kLCAmcnRfY2xpcCwgMCwgUkRXX0lOVkFMSURBVEV8UkRXX1VQREFURU5PVyk7CgoJCQkJaWYgKHBubWgtPmNvZGUgPT0gSEROX0VORFRSQUNLKSB7CgkJCQkJTGlzdEJveF9TZXRIb3Jpem9udGFsRXh0ZW50KHBhbmUtPmh3bmQsIHBhbmUtPnBvc2l0aW9uc1tDT0xVTU5TXSk7CgoJCQkJCWlmIChHZXRTY3JvbGxQb3MocGFuZS0+aHduZCwgU0JfSE9SWikgIT0gc2Nyb2xsX3BvcykKCQkJCQkJc2V0X2hlYWRlcihwYW5lKTsKCQkJCX0KCQkJfQoKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJY2FzZSBIRE5fRElWSURFUkRCTENMSUNLOiB7CgkJCUhEX05PVElGWSogcGhkbiA9IChIRF9OT1RJRlkqKSBwbm1oOwoJCQlIRF9JVEVNIGl0ZW07CgoJCQljYWxjX3NpbmdsZV93aWR0aChwYW5lLCBwaGRuLT5pSXRlbSk7CgkJCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCQkJaXRlbS5jeHkgPSBwYW5lLT53aWR0aHNbcGhkbi0+aUl0ZW1dOwoKCQkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+aHduZEhlYWRlciwgcGhkbi0+aUl0ZW0sICZpdGVtKTsKCQkJSW52YWxpZGF0ZVJlY3QocGFuZS0+aHduZCwgMCwgVFJVRSk7CgkJCWJyZWFrO30KCX0KCglyZXR1cm4gMDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgc2Nhbl9lbnRyeShDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgaW50IGlkeCwgSFdORCBod25kKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgoJLyogZGVsZXRlIHN1YiBlbnRyaWVzIGluIGxlZnQgcGFuZSAqLwoJZm9yKDs7KSB7CgkJTFJFU1VMVCByZXMgPSBMaXN0Qm94X0dldEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIGlkeCsxKTsKCQlFbnRyeSogc3ViID0gKEVudHJ5KikgcmVzOwoKCQlpZiAocmVzPT1MQl9FUlIgfHwgIXN1YiB8fCBzdWItPmxldmVsPD1lbnRyeS0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlMaXN0Qm94X0RlbGV0ZVN0cmluZyhjaGlsZC0+bGVmdC5od25kLCBpZHgrMSk7Cgl9CgoJLyogZW1wdHkgcmlnaHQgcGFuZSAqLwoJTGlzdEJveF9SZXNldENvbnRlbnQoY2hpbGQtPnJpZ2h0Lmh3bmQpOwoKCS8qIHJlbGVhc2UgbWVtb3J5ICovCglmcmVlX2VudHJpZXMoZW50cnkpOwoKCS8qIHJlYWQgY29udGVudHMgZnJvbSBkaXNrICovCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkKCXsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgTlVMTCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgllbHNlCiNlbmRpZgoJewoJCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCQlyZWFkX2RpcmVjdG9yeShlbnRyeSwgcGF0aCwgY2hpbGQtPnNvcnRPcmRlciwgaHduZCk7Cgl9CgoJLyogaW5zZXJ0IGZvdW5kIGVudHJpZXMgaW4gcmlnaHQgcGFuZSAqLwoJaW5zZXJ0X2VudHJpZXMoJmNoaWxkLT5yaWdodCwgZW50cnktPmRvd24sIGNoaWxkLT5maWx0ZXJfcGF0dGVybiwgY2hpbGQtPmZpbHRlcl9mbGFncywgLTEpOwoJY2FsY193aWR0aHMoJmNoaWxkLT5yaWdodCwgRkFMU0UpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglzZXRfaGVhZGVyKCZjaGlsZC0+cmlnaHQpOwojZW5kaWYKCgljaGlsZC0+aGVhZGVyX3dkdGhzX29rID0gRkFMU0U7CgoJU2V0Q3Vyc29yKG9sZF9jdXJzb3IpOwp9CgoKLyogZXhwYW5kIGEgZGlyZWN0b3J5IGVudHJ5ICovCgpzdGF0aWMgQk9PTCBleHBhbmRfZW50cnkoQ2hpbGRXbmQqIGNoaWxkLCBFbnRyeSogZGlyKQp7CglpbnQgaWR4OwoJRW50cnkqIHA7CgoJaWYgKCFkaXIgfHwgZGlyLT5leHBhbmRlZCB8fCAhZGlyLT5kb3duKQoJCXJldHVybiBGQUxTRTsKCglwID0gZGlyLT5kb3duOwoKCWlmIChwLT5kYXRhLmNGaWxlTmFtZVswXT09Jy4nICYmIHAtPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnICYmIHAtPm5leHQpIHsKCQlwID0gcC0+bmV4dDsKCgkJaWYgKHAtPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgcC0+ZGF0YS5jRmlsZU5hbWVbMV09PScuJyAmJgoJCQkJcC0+ZGF0YS5jRmlsZU5hbWVbMl09PSdcMCcgJiYgcC0+bmV4dCkKCQkJcCA9IHAtPm5leHQ7Cgl9CgoJLyogbm8gc3ViZGlyZWN0b3JpZXMgPyAqLwoJaWYgKCEocC0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCgkJcmV0dXJuIEZBTFNFOwoKCWlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIDAsIGRpcik7CgoJZGlyLT5leHBhbmRlZCA9IFRSVUU7CgoJLyogaW5zZXJ0IGVudHJpZXMgaW4gbGVmdCBwYW5lICovCglpbnNlcnRfZW50cmllcygmY2hpbGQtPmxlZnQsIHAsIE5VTEwsIFRGX0FMTCwgaWR4KTsKCglpZiAoIWNoaWxkLT5oZWFkZXJfd2R0aHNfb2spIHsKCQlpZiAoY2FsY193aWR0aHMoJmNoaWxkLT5sZWZ0LCBGQUxTRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlzZXRfaGVhZGVyKCZjaGlsZC0+bGVmdCk7CiNlbmRpZgoKCQkJY2hpbGQtPmhlYWRlcl93ZHRoc19vayA9IFRSVUU7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIHZvaWQgY29sbGFwc2VfZW50cnkoUGFuZSogcGFuZSwgRW50cnkqIGRpcikKewoJaW50IGlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKHBhbmUtPmh3bmQsIDAsIGRpcik7CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19ISURFKTsKCgkvKiBoaWRlIHN1YiBlbnRyaWVzICovCglmb3IoOzspIHsKCQlMUkVTVUxUIHJlcyA9IExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4KzEpOwoJCUVudHJ5KiBzdWIgPSAoRW50cnkqKSByZXM7CgoJCWlmIChyZXM9PUxCX0VSUiB8fCAhc3ViIHx8IHN1Yi0+bGV2ZWw8PWRpci0+bGV2ZWwpCgkJCWJyZWFrOwoKCQlMaXN0Qm94X0RlbGV0ZVN0cmluZyhwYW5lLT5od25kLCBpZHgrMSk7Cgl9CgoJZGlyLT5leHBhbmRlZCA9IEZBTFNFOwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfU0hPVyk7Cn0KCgpzdGF0aWMgdm9pZCByZWZyZXNoX3JpZ2h0X3BhbmUoQ2hpbGRXbmQqIGNoaWxkKQp7CglMaXN0Qm94X1Jlc2V0Q29udGVudChjaGlsZC0+cmlnaHQuaHduZCk7CglpbnNlcnRfZW50cmllcygmY2hpbGQtPnJpZ2h0LCBjaGlsZC0+cmlnaHQucm9vdCwgY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBjaGlsZC0+ZmlsdGVyX2ZsYWdzLCAtMSk7CgljYWxjX3dpZHRocygmY2hpbGQtPnJpZ2h0LCBGQUxTRSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCglzZXRfaGVhZGVyKCZjaGlsZC0+cmlnaHQpOwojZW5kaWYKfQoKc3RhdGljIHZvaWQgc2V0X2N1cmRpcihDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgaW50IGlkeCwgSFdORCBod25kKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCglwYXRoWzBdID0gJ1wwJzsKCgljaGlsZC0+bGVmdC5jdXIgPSBlbnRyeTsKCgljaGlsZC0+cmlnaHQucm9vdCA9IGVudHJ5LT5kb3duPyBlbnRyeS0+ZG93bjogZW50cnk7CgljaGlsZC0+cmlnaHQuY3VyID0gZW50cnk7CgoJaWYgKCFlbnRyeS0+c2Nhbm5lZCkKCQlzY2FuX2VudHJ5KGNoaWxkLCBlbnRyeSwgaWR4LCBod25kKTsKCWVsc2UKCQlyZWZyZXNoX3JpZ2h0X3BhbmUoY2hpbGQpOwoKCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCWxzdHJjcHkoY2hpbGQtPnBhdGgsIHBhdGgpOwoKCWlmIChjaGlsZC0+aHduZCkJLyogb25seSBjaGFuZ2Ugd2luZG93IHRpdGxlLCBpZiB0aGUgd2luZG93IGFscmVhZHkgZXhpc3RzICovCgkJU2V0V2luZG93VGV4dChjaGlsZC0+aHduZCwgcGF0aCk7CgoJaWYgKHBhdGhbMF0pCgkJaWYgKFNldEN1cnJlbnREaXJlY3RvcnkocGF0aCkpCgkJCXNldF9zcGFjZV9zdGF0dXMoKTsKfQoKCnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXSwgZHJ2W19NQVhfRFJJVkUrMV07CglFbnRyeSogZW50cnk7CglpbnQgaWR4OwoKCWdldF9wYXRoKGNoaWxkLT5sZWZ0LmN1ciwgcGF0aCk7CglfdHNwbGl0cGF0aChwYXRoLCBkcnYsIE5VTEwsIE5VTEwsIE5VTEwpOwoKCWNoaWxkLT5yaWdodC5yb290ID0gTlVMTDsKCglzY2FuX2VudHJ5KGNoaWxkLCAmY2hpbGQtPnJvb3QuZW50cnksIDAsIGNoaWxkLT5od25kKTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGNoaWxkLT5yb290LmVudHJ5LmV0eXBlID09IEVUX1NIRUxMKQoJCWVudHJ5ID0gcmVhZF90cmVlKCZjaGlsZC0+cm9vdCwgTlVMTCwgZ2V0X3BhdGhfcGlkbChwYXRoLGNoaWxkLT5od25kKSwgZHJ2LCBjaGlsZC0+c29ydE9yZGVyLCBjaGlsZC0+aHduZCk7CgllbHNlCiNlbmRpZgoJCWVudHJ5ID0gcmVhZF90cmVlKCZjaGlsZC0+cm9vdCwgcGF0aCwgTlVMTCwgZHJ2LCBjaGlsZC0+c29ydE9yZGVyLCBjaGlsZC0+aHduZCk7CgoJaWYgKCFlbnRyeSkKCQllbnRyeSA9ICZjaGlsZC0+cm9vdC5lbnRyeTsKCglpbnNlcnRfZW50cmllcygmY2hpbGQtPmxlZnQsIGNoaWxkLT5yb290LmVudHJ5LmRvd24sIE5VTEwsIFRGX0FMTCwgMCk7CgoJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIDAsIGNoaWxkLT5od25kKTsKCglpZHggPSBMaXN0Qm94X0ZpbmRJdGVtRGF0YShjaGlsZC0+bGVmdC5od25kLCAwLCBjaGlsZC0+bGVmdC5jdXIpOwoJTGlzdEJveF9TZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCwgaWR4KTsKfQoKCnN0YXRpYyB2b2lkIGNyZWF0ZV9kcml2ZV9iYXIodm9pZCkKewoJVEJCVVRUT04gZHJpdmViYXJCdG4gPSB7MCwgMCwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJVENIQVIgYjFbQlVGRkVSX0xFTl07CiNlbmRpZgoJaW50IGJ0biA9IDE7CglQVFNUUiBwOwoKCUdldExvZ2ljYWxEcml2ZVN0cmluZ3MoQlVGRkVSX0xFTiwgR2xvYmFscy5kcml2ZXMpOwoKCUdsb2JhbHMuaGRyaXZlYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEV8Q0NTX05PTU9WRVl8VEJTVFlMRV9MSVNULAoJCQkJSURXX0RSSVZFQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX0RSSVZFQkFSLCAmZHJpdmViYXJCdG4sCgkJCQkwLCAxNiwgMTMsIDE2LCAxMywgc2l6ZW9mKFRCQlVUVE9OKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNpZmRlZiBfX1dJTkVfXwoJLyogaW5zZXJ0IHVuaXggZmlsZSBzeXN0ZW0gYnV0dG9uICovCgliMVswXSA9ICcvJzsKCWIxWzFdID0gJ1wwJzsKCWIxWzJdID0gJ1wwJzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYjEpOwoKCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX1VOSVhfRlM7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfSU5TRVJUQlVUVE9OLCBidG4rKywgKExQQVJBTSkmZHJpdmViYXJCdG4pOwoJZHJpdmViYXJCdG4uaVN0cmluZysrOwojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkvKiBpbnNlcnQgc2hlbGwgbmFtZXNwYWNlIGJ1dHRvbiAqLwoJbG9hZF9zdHJpbmcoYjEsIElEU19TSEVMTCk7CgliMVtsc3RybGVuKGIxKSsxXSA9ICdcMCc7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWIxKTsKCglkcml2ZWJhckJ0bi5pZENvbW1hbmQgPSBJRF9EUklWRV9TSEVMTF9OUzsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9JTlNFUlRCVVRUT04sIGJ0bisrLCAoTFBBUkFNKSZkcml2ZWJhckJ0bik7Cglkcml2ZWJhckJ0bi5pU3RyaW5nKys7CiNlbmRpZgoKCS8qIHJlZ2lzdGVyIHdpbmRvd3MgZHJpdmUgcm9vdCBzdHJpbmdzICovCglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKUdsb2JhbHMuZHJpdmVzKTsKI2VuZGlmCgoJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfRklSU1Q7CgoJZm9yKHA9R2xvYmFscy5kcml2ZXM7ICpwOyApIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJLyogaW5zZXJ0IGRyaXZlIGxldHRlciAqLwoJCVRDSEFSIGJbM10gPSB7dG9sb3dlcigqcCl9OwoJCVNlbmRNZXNzYWdlKEdsb2JhbHMuaGRyaXZlYmFyLCBUQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pYik7CiNlbmRpZgoJCXN3aXRjaChHZXREcml2ZVR5cGUocCkpIHsKCQkJY2FzZSBEUklWRV9SRU1PVkFCTEU6CWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAxOwlicmVhazsKCQkJY2FzZSBEUklWRV9DRFJPTToJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAzOwlicmVhazsKCQkJY2FzZSBEUklWRV9SRU1PVEU6CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gNDsJYnJlYWs7CgkJCWNhc2UgRFJJVkVfUkFNRElTSzoJCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSA1OwlicmVhazsKCQkJZGVmYXVsdDovKkRSSVZFX0ZJWEVEKi8JZHJpdmViYXJCdG4uaUJpdG1hcCA9IDI7CgkJfQoKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfSU5TRVJUQlVUVE9OLCBidG4rKywgKExQQVJBTSkmZHJpdmViYXJCdG4pOwoJCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCsrOwoJCWRyaXZlYmFyQnRuLmlTdHJpbmcrKzsKCgkJd2hpbGUoKnArKyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHJlZnJlc2hfZHJpdmVzKHZvaWQpCnsKCVJFQ1QgcmVjdDsKCgkvKiBkZXN0cm95IGRyaXZlIGJhciAqLwoJRGVzdHJveVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhcik7CglHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgoJLyogcmUtY3JlYXRlIGRyaXZlIGJhciAqLwoJY3JlYXRlX2RyaXZlX2JhcigpOwoKCS8qIHVwZGF0ZSB3aW5kb3cgbGF5b3V0ICovCglHZXRDbGllbnRSZWN0KEdsb2JhbHMuaE1haW5XbmQsICZyZWN0KTsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaE1haW5XbmQsIFdNX1NJWkUsIDAsIE1BS0VMT05HKHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKSk7Cn0KCgpzdGF0aWMgQk9PTCBsYXVuY2hfZmlsZShIV05EIGh3bmQsIExQQ1RTVFIgY21kLCBVSU5UIG5DbWRTaG93KQp7CglISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGNtZCwgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgbkNtZFNob3cpOwoKCWlmICgoaW50KWhpbnN0IDw9IDMyKSB7CgkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIEJPT0wgbGF1bmNoX2VudHJ5KEVudHJ5KiBlbnRyeSwgSFdORCBod25kLCBVSU5UIG5DbWRTaG93KQp7CglUQ0hBUiBjbWRbTUFYX1BBVEhdOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZW50cnktPmV0eXBlID09IEVUX1NIRUxMKSB7CgkJQk9PTCByZXQgPSBUUlVFOwoKCQlTSEVMTEVYRUNVVEVJTkZPIHNoZXhpbmZvOwoKCQlzaGV4aW5mby5jYlNpemUgPSBzaXplb2YoU0hFTExFWEVDVVRFSU5GTyk7CgkJc2hleGluZm8uZk1hc2sgPSBTRUVfTUFTS19JRExJU1Q7CgkJc2hleGluZm8uaHduZCA9IGh3bmQ7CgkJc2hleGluZm8ubHBWZXJiID0gTlVMTDsKCQlzaGV4aW5mby5scEZpbGUgPSBOVUxMOwoJCXNoZXhpbmZvLmxwUGFyYW1ldGVycyA9IE5VTEw7CgkJc2hleGluZm8ubHBEaXJlY3RvcnkgPSBOVUxMOwoJCXNoZXhpbmZvLm5TaG93ID0gbkNtZFNob3c7CgkJc2hleGluZm8ubHBJRExpc3QgPSBnZXRfdG9fYWJzb2x1dGVfcGlkbChlbnRyeSwgaHduZCk7CgoJCWlmICghU2hlbGxFeGVjdXRlRXgoJnNoZXhpbmZvKSkgewoJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJcmV0ID0gRkFMU0U7CgkJfQoKCQlpZiAoc2hleGluZm8ubHBJRExpc3QgIT0gZW50cnktPnBpZGwpCgkJCUlNYWxsb2NfRnJlZShHbG9iYWxzLmlNYWxsb2MsIHNoZXhpbmZvLmxwSURMaXN0KTsKCgkJcmV0dXJuIHJldDsKCX0KI2VuZGlmCgoJZ2V0X3BhdGgoZW50cnksIGNtZCk7CgoJIC8qIHN0YXJ0IHByb2dyYW0sIG9wZW4gZG9jdW1lbnQuLi4gKi8KCXJldHVybiBsYXVuY2hfZmlsZShod25kLCBjbWQsIG5DbWRTaG93KTsKfQoKCnN0YXRpYyB2b2lkIGFjdGl2YXRlX2VudHJ5KENoaWxkV25kKiBjaGlsZCwgUGFuZSogcGFuZSwgSFdORCBod25kKQp7CglFbnRyeSogZW50cnkgPSBwYW5lLT5jdXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgoJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQlpbnQgc2Nhbm5lZF9vbGQgPSBlbnRyeS0+c2Nhbm5lZDsKCgkJaWYgKCFzY2FubmVkX29sZCkKCQkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIExpc3RCb3hfR2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQpLCBod25kKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnKQoJCQlyZXR1cm47CiNlbmRpZgoKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnKSB7CgkJCWVudHJ5ID0gY2hpbGQtPmxlZnQuY3VyLT51cDsKCQkJY29sbGFwc2VfZW50cnkoJmNoaWxkLT5sZWZ0LCBlbnRyeSk7CgkJCWdvdG8gZm9jdXNfZW50cnk7CgkJfSBlbHNlIGlmIChlbnRyeS0+ZXhwYW5kZWQpCgkJCWNvbGxhcHNlX2VudHJ5KHBhbmUsIGNoaWxkLT5sZWZ0LmN1cik7CgkJZWxzZSB7CgkJCWV4cGFuZF9lbnRyeShjaGlsZCwgY2hpbGQtPmxlZnQuY3VyKTsKCgkJCWlmICghcGFuZS0+dHJlZVBhbmUpIGZvY3VzX2VudHJ5OiB7CgkJCQlpbnQgaWR4ID0gTGlzdEJveF9GaW5kSXRlbURhdGEoY2hpbGQtPmxlZnQuaHduZCwgTGlzdEJveF9HZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCksIGVudHJ5KTsKCQkJCUxpc3RCb3hfU2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQsIGlkeCk7CgkJCQlzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaWR4LCBod25kKTsKCQkJfQoJCX0KCgkJaWYgKCFzY2FubmVkX29sZCkgewoJCQljYWxjX3dpZHRocyhwYW5lLCBGQUxTRSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCXNldF9oZWFkZXIocGFuZSk7CiNlbmRpZgoJCX0KCX0gZWxzZSB7CgkJaWYgKEdldEtleVN0YXRlKFZLX01FTlUpIDwgMCkKCQkJc2hvd19wcm9wZXJ0aWVzX2RsZyhlbnRyeSwgY2hpbGQtPmh3bmQpOwoJCWVsc2UKCQkJbGF1bmNoX2VudHJ5KGVudHJ5LCBjaGlsZC0+aHduZCwgU1dfU0hPV05PUk1BTCk7Cgl9Cn0KCgpzdGF0aWMgQk9PTCBwYW5lX2NvbW1hbmQoUGFuZSogcGFuZSwgVUlOVCBjbWQpCnsKCXN3aXRjaChjbWQpIHsKCQljYXNlIElEX1ZJRVdfTkFNRToKCQkJaWYgKHBhbmUtPnZpc2libGVfY29scykgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gMDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIElEX1ZJRVdfQUxMX0FUVFJJQlVURVM6CgkJCWlmIChwYW5lLT52aXNpYmxlX2NvbHMgIT0gQ09MX0FMTCkgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gQ09MX0FMTDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19BTExfQVRUUklCVVRFUywgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgSURfUFJFRkVSUkVEX1NJWkVTOiB7CgkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJYnJlYWs7fQojZW5kaWYKCgkJICAgICAgICAvKiBUT0RPOiBtb3JlIGNvbW1hbmQgaWRzLi4uICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyB2b2lkIHNldF9zb3J0X29yZGVyKENoaWxkV25kKiBjaGlsZCwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCWlmIChjaGlsZC0+c29ydE9yZGVyICE9IHNvcnRPcmRlcikgewoJCWNoaWxkLT5zb3J0T3JkZXIgPSBzb3J0T3JkZXI7CgkJcmVmcmVzaF9jaGlsZChjaGlsZCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHVwZGF0ZV92aWV3X21lbnUoQ2hpbGRXbmQqIGNoaWxkKQp7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NPUlRfTkFNRSwgY2hpbGQtPnNvcnRPcmRlcj09U09SVF9OQU1FPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX1RZUEUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfRVhUPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX1NJWkUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfU0laRT8gTUZfQ0hFQ0tFRDogTUZfVU5DSEVDS0VEKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU09SVF9EQVRFLCBjaGlsZC0+c29ydE9yZGVyPT1TT1JUX0RBVEU/IE1GX0NIRUNLRUQ6IE1GX1VOQ0hFQ0tFRCk7Cn0KCgpzdGF0aWMgQk9PTCBpc19kaXJlY3RvcnkoTFBDVFNUUiB0YXJnZXQpCnsKCS8qVE9ETyBjb3JyZWN0bHkgaGFuZGxlIFVOSVggcGF0aHMgKi8KCURXT1JEIHRhcmdldF9hdHRyID0gR2V0RmlsZUF0dHJpYnV0ZXModGFyZ2V0KTsKCglpZiAodGFyZ2V0X2F0dHIgPT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpCgkJcmV0dXJuIEZBTFNFOwoKCXJldHVybiB0YXJnZXRfYXR0ciZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRSVUU6IEZBTFNFOwp9CgkKc3RhdGljIEJPT0wgcHJvbXB0X3RhcmdldChQYW5lKiBwYW5lLCBMUFRTVFIgc291cmNlLCBMUFRTVFIgdGFyZ2V0KQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCWludCBsZW47CgoJZ2V0X3BhdGgocGFuZS0+Y3VyLCBwYXRoKTsKCglpZiAoRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfU0VMRUNUX0RFU1RJTkFUSU9OKSwgcGFuZS0+aHduZCwgRGVzdGluYXRpb25EbGdQcm9jLCAoTFBBUkFNKXBhdGgpICE9IElET0spCgkJcmV0dXJuIEZBTFNFOwoKCWdldF9wYXRoKHBhbmUtPmN1ciwgc291cmNlKTsKCgkvKiBjb252ZXJ0IHJlbGF0aXZlIHRhcmdldHMgdG8gYWJzb2x1dGUgcGF0aHMgKi8KCWlmIChwYXRoWzBdIT0nLycgJiYgcGF0aFsxXSE9JzonKSB7CgkJZ2V0X3BhdGgocGFuZS0+Y3VyLT51cCwgdGFyZ2V0KTsKCQlsZW4gPSBsc3RybGVuKHRhcmdldCk7CgoJCWlmICh0YXJnZXRbbGVuLTFdIT0nXFwnICYmIHRhcmdldFtsZW4tMV0hPScvJykKCQkJdGFyZ2V0W2xlbisrXSA9ICcvJzsKCgkJbHN0cmNweSh0YXJnZXQrbGVuLCBwYXRoKTsKCX0gZWxzZQoJCWxzdHJjcHkodGFyZ2V0LCBwYXRoKTsKCgkvKiBJZiB0aGUgdGFyZ2V0IGFscmVhZHkgZXhpc3RzIGFzIGRpcmVjdG9yeSwgY3JlYXRlIGEgbmV3IHRhcmdldCBiZWxvdyB0aGlzLiAqLwoJaWYgKGlzX2RpcmVjdG9yeShwYXRoKSkgewoJCVRDSEFSIGZuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJCXN0YXRpYyBjb25zdCBUQ0hBUiBzQXBwZW5kW10gPSB7JyUnLCdzJywnLycsJyUnLCdzJywnJScsJ3MnLCdcMCd9OwoKCQlfdHNwbGl0cGF0aChzb3VyY2UsIE5VTEwsIE5VTEwsIGZuYW1lLCBleHQpOwoKCQl3c3ByaW50Zih0YXJnZXQsIHNBcHBlbmQsIHBhdGgsIGZuYW1lLCBleHQpOwoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIElDb250ZXh0TWVudTIqIHNfcGN0eG1lbnUyID0gTlVMTDsKc3RhdGljIElDb250ZXh0TWVudTMqIHNfcGN0eG1lbnUzID0gTlVMTDsKCnN0YXRpYyB2b2lkIEN0eE1lbnVfcmVzZXQodm9pZCkKewoJc19wY3R4bWVudTIgPSBOVUxMOwoJc19wY3R4bWVudTMgPSBOVUxMOwp9CgpzdGF0aWMgSUNvbnRleHRNZW51KiBDdHhNZW51X3F1ZXJ5X2ludGVyZmFjZXMoSUNvbnRleHRNZW51KiBwY20xKQp7CglJQ29udGV4dE1lbnUqIHBjbSA9IE5VTEw7CgoJQ3R4TWVudV9yZXNldCgpOwoKCWlmIChJQ29udGV4dE1lbnVfUXVlcnlJbnRlcmZhY2UocGNtMSwgJklJRF9JQ29udGV4dE1lbnUzLCAodm9pZCoqKSZwY20pID09IE5PRVJST1IpCgkJc19wY3R4bWVudTMgPSAoTFBDT05URVhUTUVOVTMpcGNtOwoJZWxzZSBpZiAoSUNvbnRleHRNZW51X1F1ZXJ5SW50ZXJmYWNlKHBjbTEsICZJSURfSUNvbnRleHRNZW51MiwgKHZvaWQqKikmcGNtKSA9PSBOT0VSUk9SKQoJCXNfcGN0eG1lbnUyID0gKExQQ09OVEVYVE1FTlUyKXBjbTsKCglpZiAocGNtKSB7CgkJSUNvbnRleHRNZW51X1JlbGVhc2UocGNtMSk7CgkJcmV0dXJuIHBjbTsKCX0gZWxzZQoJCXJldHVybiBwY20xOwp9CgpzdGF0aWMgQk9PTCBDdHhNZW51X0hhbmRsZU1lbnVNc2coVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglpZiAoc19wY3R4bWVudTMpIHsKCQlpZiAoU1VDQ0VFREVEKElDb250ZXh0TWVudTNfSGFuZGxlTWVudU1zZyhzX3BjdHhtZW51Mywgbm1zZywgd3BhcmFtLCBscGFyYW0pKSkKCQkJcmV0dXJuIFRSVUU7Cgl9CgoJaWYgKHNfcGN0eG1lbnUyKQoJCWlmIChTVUNDRUVERUQoSUNvbnRleHRNZW51Ml9IYW5kbGVNZW51TXNnKHNfcGN0eG1lbnUyLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCgpzdGF0aWMgSFJFU1VMVCBTaGVsbEZvbGRlckNvbnRleHRNZW51KElTaGVsbEZvbGRlciogc2hlbGxfZm9sZGVyLCBIV05EIGh3bmRQYXJlbnQsIGludCBjaWRsLCBMUENJVEVNSURMSVNUKiBhcGlkbCwgaW50IHgsIGludCB5KQp7CglJQ29udGV4dE1lbnUqIHBjbTsKCUJPT0wgZXhlY3V0ZWQgPSBGQUxTRTsKCglIUkVTVUxUIGhyID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2Yoc2hlbGxfZm9sZGVyLCBod25kUGFyZW50LCBjaWRsLCBhcGlkbCwgJklJRF9JQ29udGV4dE1lbnUsIE5VTEwsIChMUFZPSUQqKSZwY20pOwovKglIUkVTVUxUIGhyID0gQ0RlZkZvbGRlck1lbnVfQ3JlYXRlMihkaXI/ZGlyLT5fcGlkbDpEZXNrdG9wRm9sZGVyKCksIGh3bmRQYXJlbnQsIDEsICZwaWRsLCBzaGVsbF9mb2xkZXIsIE5VTEwsIDAsIE5VTEwsICZwY20pOyAqLwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJSE1FTlUgaG1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKTsKCgkJcGNtID0gQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKHBjbSk7CgoJCWlmIChobWVudSkgewoJCQlociA9IElDb250ZXh0TWVudV9RdWVyeUNvbnRleHRNZW51KHBjbSwgaG1lbnUsIDAsIEZDSURNX1NIVklFV0ZJUlNULCBGQ0lETV9TSFZJRVdMQVNULCBDTUZfTk9STUFMKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCQlVSU5UIGlkQ21kID0gVHJhY2tQb3B1cE1lbnUoaG1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1JFVFVSTkNNRHxUUE1fUklHSFRCVVRUT04sIHgsIHksIDAsIGh3bmRQYXJlbnQsIE5VTEwpOwoKCQkJCUN0eE1lbnVfcmVzZXQoKTsKCgkJCQlpZiAoaWRDbWQpIHsKCQkJCSAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbWk7CgoJCQkJICBjbWkuY2JTaXplID0gc2l6ZW9mKENNSU5WT0tFQ09NTUFORElORk8pOwoJCQkJICBjbWkuZk1hc2sgPSAwOwoJCQkJICBjbWkuaHduZCA9IGh3bmRQYXJlbnQ7CgkJCQkgIGNtaS5scFZlcmIgPSAoTFBDU1RSKShJTlRfUFRSKShpZENtZCAtIEZDSURNX1NIVklFV0ZJUlNUKTsKCQkJCSAgY21pLmxwUGFyYW1ldGVycyA9IE5VTEw7CgkJCQkgIGNtaS5scERpcmVjdG9yeSA9IE5VTEw7CgkJCQkgIGNtaS5uU2hvdyA9IFNXX1NIT1dOT1JNQUw7CgkJCQkgIGNtaS5kd0hvdEtleSA9IDA7CgkJCQkgIGNtaS5oSWNvbiA9IDA7CgoJCQkJICBociA9IElDb250ZXh0TWVudV9JbnZva2VDb21tYW5kKHBjbSwgJmNtaSk7CgkJCQkJZXhlY3V0ZWQgPSBUUlVFOwoJCQkJfQoJCQl9IGVsc2UKCQkJCUN0eE1lbnVfcmVzZXQoKTsKCQl9CgoJCUlDb250ZXh0TWVudV9SZWxlYXNlKHBjbSk7Cgl9CgoJcmV0dXJuIEZBSUxFRChocik/IGhyOiBleGVjdXRlZD8gU19PSzogU19GQUxTRTsKfQoKCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIENoaWxkV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBKTsKCUFTU0VSVChjaGlsZCk7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0RSQVdJVEVNOiB7CgkJCUxQRFJBV0lURU1TVFJVQ1QgZGlzID0gKExQRFJBV0lURU1TVFJVQ1QpbHBhcmFtOwoJCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBkaXMtPml0ZW1EYXRhOwoKCQkJaWYgKGRpcy0+Q3RsSUQgPT0gSURXX1RSRUVfTEVGVCkKCQkJCWRyYXdfaXRlbSgmY2hpbGQtPmxlZnQsIGRpcywgZW50cnksIC0xKTsKCQkJZWxzZSBpZiAoZGlzLT5DdGxJRCA9PSBJRFdfVFJFRV9SSUdIVCkKCQkJCWRyYXdfaXRlbSgmY2hpbGQtPnJpZ2h0LCBkaXMsIGVudHJ5LCAtMSk7CgkJCWVsc2UKCQkJCWdvdG8gZHJhd19tZW51X2l0ZW07CgoJCQlyZXR1cm4gVFJVRTt9CgoJCWNhc2UgV01fQ1JFQVRFOgoJCQlJbml0Q2hpbGRXaW5kb3coY2hpbGQpOwoJCQlicmVhazsKCgkJY2FzZSBXTV9OQ0RFU1RST1k6CgkJCWZyZWVfY2hpbGRfd2luZG93KGNoaWxkKTsKCQkJU2V0V2luZG93TG9uZ1B0cihod25kLCBHV0xQX1VTRVJEQVRBLCAwKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fUEFJTlQ6IHsKCQkJUEFJTlRTVFJVQ1QgcHM7CgkJCUhCUlVTSCBsYXN0QnJ1c2g7CgkJCVJFQ1QgcnQ7CgkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJQmVnaW5QYWludChod25kLCAmcHMpOwoJCQlydC5sZWZ0ID0gY2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yOwoJCQlydC5yaWdodCA9IGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxOwoJCQlsYXN0QnJ1c2ggPSBTZWxlY3RCcnVzaChwcy5oZGMsIChIQlJVU0gpR2V0U3RvY2tPYmplY3QoQ09MT1JfU1BMSVRCQVIpKTsKCQkJUmVjdGFuZ2xlKHBzLmhkYywgcnQubGVmdCwgcnQudG9wLTEsIHJ0LnJpZ2h0LCBydC5ib3R0b20rMSk7CgkJCVNlbGVjdE9iamVjdChwcy5oZGMsIGxhc3RCcnVzaCk7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQlydC50b3AgPSBydC5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CgkJCUZpbGxSZWN0KHBzLmhkYywgJnJ0LCBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCkpOwojZW5kaWYKCQkJRW5kUGFpbnQoaHduZCwgJnBzKTsKCQkJYnJlYWs7fQoKCQljYXNlIFdNX1NFVENVUlNPUjoKCQkJaWYgKExPV09SRChscGFyYW0pID09IEhUQ0xJRU5UKSB7CgkJCQlQT0lOVCBwdDsKCQkJCUdldEN1cnNvclBvcygmcHQpOwoJCQkJU2NyZWVuVG9DbGllbnQoaHduZCwgJnB0KTsKCgkJCQlpZiAocHQueD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHB0Lng8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfU0laRVdFKSk7CgkJCQkJcmV0dXJuIFRSVUU7CgkJCQl9CgkJCX0KCQkJZ290byBkZWY7CgoJCWNhc2UgV01fTEJVVFRPTkRPV046IHsKCQkJUkVDVCBydDsKCQkJaW50IHggPSBHRVRfWF9MUEFSQU0obHBhcmFtKTsKCgkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCgkJCWlmICh4Pj1jaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzIgJiYgeDxjaGlsZC0+c3BsaXRfcG9zK1NQTElUX1dJRFRILzIrMSkgewoJCQkJbGFzdF9zcGxpdCA9IGNoaWxkLT5zcGxpdF9wb3M7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2VuZGlmCgkJCQlTZXRDYXB0dXJlKGh3bmQpOwoJCQl9CgoJCQlicmVhazt9CgoJCWNhc2UgV01fTEJVVFRPTlVQOgoJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlSRUNUIHJ0OwoJCQkJaW50IHggPSBMT1dPUkQobHBhcmFtKTsKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCQljaGlsZC0+c3BsaXRfcG9zID0geDsKCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKI2VuZGlmCgkJCQlSZWxlYXNlQ2FwdHVyZSgpOwoJCQl9CgkJCWJyZWFrOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKCQkJaWYgKEdldENhcHR1cmUoKT09aHduZCAmJiBsYXN0X3NwbGl0Pj0wKQoJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKCQkJYnJlYWs7CiNlbmRpZgoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfRVNDQVBFKQoJCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQkJUkVDVCBydDsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2Vsc2UKCQkJCQljaGlsZC0+c3BsaXRfcG9zID0gbGFzdF9zcGxpdDsKI2VuZGlmCgkJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlsYXN0X3NwbGl0ID0gLTE7CgkJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJCQlTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfQVJST1cpKTsKCQkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgV01fTU9VU0VNT1ZFOgoJCQlpZiAoR2V0Q2FwdHVyZSgpID09IGh3bmQpIHsKCQkJCVJFQ1QgcnQ7CgkJCQlpbnQgeCA9IExPV09SRChscGFyYW0pOwoKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQlIREMgaGRjID0gR2V0REMoaHduZCk7CgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJcnQubGVmdCA9IGxhc3Rfc3BsaXQtU1BMSVRfV0lEVEgvMjsKCQkJCXJ0LnJpZ2h0ID0gbGFzdF9zcGxpdCtTUExJVF9XSURUSC8yKzE7CgkJCQlJbnZlcnRSZWN0KGhkYywgJnJ0KTsKCgkJCQlsYXN0X3NwbGl0ID0geDsKCQkJCXJ0LmxlZnQgPSB4LVNQTElUX1dJRFRILzI7CgkJCQlydC5yaWdodCA9IHgrU1BMSVRfV0lEVEgvMisxOwoJCQkJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJCQkJUmVsZWFzZURDKGh3bmQsIGhkYyk7CiNlbHNlCgkJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQkJaWYgKHg+PTAgJiYgeDxydC5yaWdodCkgewoJCQkJCWNoaWxkLT5zcGxpdF9wb3MgPSB4OwoJCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBydC5yaWdodCwgcnQuYm90dG9tKTsKCQkJCQlydC5sZWZ0ID0geC1TUExJVF9XSURUSC8yOwoJCQkJCXJ0LnJpZ2h0ID0geCtTUExJVF9XSURUSC8yKzE7CgkJCQkJSW52YWxpZGF0ZVJlY3QoaHduZCwgJnJ0LCBGQUxTRSk7CgkJCQkJVXBkYXRlV2luZG93KGNoaWxkLT5sZWZ0Lmh3bmQpOwoJCQkJCVVwZGF0ZVdpbmRvdyhod25kKTsKCQkJCQlVcGRhdGVXaW5kb3coY2hpbGQtPnJpZ2h0Lmh3bmQpOwoJCQkJfQojZW5kaWYKCQkJfQoJCQlicmVhazsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0dFVE1JTk1BWElORk86CgkJCURlZk1ESUNoaWxkUHJvYyhod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7CgoJCQl7TFBNSU5NQVhJTkZPIGxwbW1pID0gKExQTUlOTUFYSU5GTylscGFyYW07CgoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueCA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgLyBTTV9DWFZJUlRVQUxTQ1JFRU4gKi8KCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnkgPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pIC8gU01fQ1lWSVJUVUFMU0NSRUVOICovCgkJCWJyZWFrO30KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoJCWNhc2UgV01fU0VURk9DVVM6CgkJCWlmIChTZXRDdXJyZW50RGlyZWN0b3J5KGNoaWxkLT5wYXRoKSkKCQkJCXNldF9zcGFjZV9zdGF0dXMoKTsKCQkJU2V0Rm9jdXMoY2hpbGQtPmZvY3VzX3BhbmU/IGNoaWxkLT5yaWdodC5od25kOiBjaGlsZC0+bGVmdC5od25kKTsKCQkJYnJlYWs7CgoJCWNhc2UgV01fRElTUEFUQ0hfQ09NTUFORDogewoJCQlQYW5lKiBwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoKCQkJc3dpdGNoKExPV09SRCh3cGFyYW0pKSB7CgkJCQljYXNlIElEX1dJTkRPV19ORVc6IHsKCQkJCQlDaGlsZFduZCogbmV3X2NoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KGNoaWxkLT5wYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KG5ld19jaGlsZCkpCgkJCQkJCWZyZWUobmV3X2NoaWxkKTsKCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfUkVGUkVTSDoKCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfQUNUSVZBVEU6CgkJCQkJYWN0aXZhdGVfZW50cnkoY2hpbGQsIHBhbmUsIGh3bmQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfRklMRV9NT1ZFOiB7CgkJCQkJVENIQVIgc291cmNlW0JVRkZFUl9MRU5dLCB0YXJnZXRbQlVGRkVSX0xFTl07CgoJCQkJCWlmIChwcm9tcHRfdGFyZ2V0KHBhbmUsIHNvdXJjZSwgdGFyZ2V0KSkgewoJCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX01PVkUsIHNvdXJjZSwgdGFyZ2V0fTsKCgkJCQkJCXNvdXJjZVtsc3RybGVuKHNvdXJjZSkrMV0gPSAnXDAnOwoJCQkJCQl0YXJnZXRbbHN0cmxlbih0YXJnZXQpKzFdID0gJ1wwJzsKCgkJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GSUxFX0NPUFk6IHsKCQkJCQlUQ0hBUiBzb3VyY2VbQlVGRkVSX0xFTl0sIHRhcmdldFtCVUZGRVJfTEVOXTsKCgkJCQkJaWYgKHByb21wdF90YXJnZXQocGFuZSwgc291cmNlLCB0YXJnZXQpKSB7CgkJCQkJCVNIRklMRU9QU1RSVUNUIHNoZm8gPSB7aHduZCwgRk9fQ09QWSwgc291cmNlLCB0YXJnZXR9OwoKCQkJCQkJc291cmNlW2xzdHJsZW4oc291cmNlKSsxXSA9ICdcMCc7CgkJCQkJCXRhcmdldFtsc3RybGVuKHRhcmdldCkrMV0gPSAnXDAnOwoKCQkJCQkJaWYgKCFTSEZpbGVPcGVyYXRpb24oJnNoZm8pKQoJCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0ZJTEVfREVMRVRFOiB7CgkJCQkJVENIQVIgcGF0aFtCVUZGRVJfTEVOXTsKCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX0RFTEVURSwgcGF0aH07CgoJCQkJCWdldF9wYXRoKHBhbmUtPmN1ciwgcGF0aCk7CgoJCQkJCXBhdGhbbHN0cmxlbihwYXRoKSsxXSA9ICdcMCc7CgoJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfVklFV19TT1JUX05BTUU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfTkFNRSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfVFlQRToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9FWFQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX1NJWkU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfU0laRSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX1NPUlRfREFURToKCQkJCQlzZXRfc29ydF9vcmRlcihjaGlsZCwgU09SVF9EQVRFKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfRklMVEVSOiB7CgkJCQkJc3RydWN0IEZpbHRlckRpYWxvZyBkbGc7CgoJCQkJCW1lbXNldCgmZGxnLCAwLCBzaXplb2Yoc3RydWN0IEZpbHRlckRpYWxvZykpOwoJCQkJCWxzdHJjcHkoZGxnLnBhdHRlcm4sIGNoaWxkLT5maWx0ZXJfcGF0dGVybik7CgkJCQkJZGxnLmZsYWdzID0gY2hpbGQtPmZpbHRlcl9mbGFnczsKCgkJCQkJaWYgKERpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX0RJQUxPR19WSUVXX1RZUEUpLCBod25kLCBGaWx0ZXJEaWFsb2dEbGdQcm9jLCAoTFBBUkFNKSZkbGcpID09IElET0spIHsKCQkJCQkJbHN0cmNweShjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGRsZy5wYXR0ZXJuKTsKCQkJCQkJY2hpbGQtPmZpbHRlcl9mbGFncyA9IGRsZy5mbGFnczsKCQkJCQkJcmVmcmVzaF9yaWdodF9wYW5lKGNoaWxkKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfVklFV19TUExJVDogewoJCQkJCWxhc3Rfc3BsaXQgPSBjaGlsZC0+c3BsaXRfcG9zOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwojZW5kaWYKCQkJCQlTZXRDYXB0dXJlKGh3bmQpOwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0VESVRfUFJPUEVSVElFUzoKCQkJCQlzaG93X3Byb3BlcnRpZXNfZGxnKHBhbmUtPmN1ciwgY2hpbGQtPmh3bmQpOwoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJcmV0dXJuIHBhbmVfY29tbWFuZChwYW5lLCBMT1dPUkQod3BhcmFtKSk7CgkJCX0KCgkJCXJldHVybiBUUlVFO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVBhbmUqIHBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJCWNhc2UgTEJOX1NFTENIQU5HRTogewoJCQkJCWludCBpZHggPSBMaXN0Qm94X0dldEN1clNlbChwYW5lLT5od25kKTsKCQkJCQlFbnRyeSogZW50cnkgPSAoRW50cnkqKSBMaXN0Qm94X0dldEl0ZW1EYXRhKHBhbmUtPmh3bmQsIGlkeCk7CgoJCQkJCWlmIChwYW5lID09ICZjaGlsZC0+bGVmdCkKCQkJCQkJc2V0X2N1cmRpcihjaGlsZCwgZW50cnksIGlkeCwgaHduZCk7CgkJCQkJZWxzZQoJCQkJCQlwYW5lLT5jdXIgPSBlbnRyeTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBMQk5fREJMQ0xLOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCQkJfQoJCQlicmVhazt9CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9OT1RJRlk6IHsKCQkJTk1IRFIqIHBubWggPSAoTk1IRFIqKSBscGFyYW07CgkJCXJldHVybiBwYW5lX25vdGlmeShwbm1oLT5pZEZyb209PUlEV19IRUFERVJfTEVGVD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0LCBwbm1oKTt9CiNlbmRpZgoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJY2FzZSBXTV9DT05URVhUTUVOVTogewoJCQlQT0lOVCBwdCwgcHRfY2xudDsKCQkJUGFuZSogcGFuZTsKCQkJaW50IGlkeDsKCgkJCSAvKiBmaXJzdCBzZWxlY3QgdGhlIGN1cnJlbnQgaXRlbSBpbiB0aGUgbGlzdGJveCAqLwoJCQlIV05EIGhwYW5lbCA9IChIV05EKSB3cGFyYW07CgkJCXB0X2NsbnQueCA9IHB0LnggPSAoc2hvcnQpTE9XT1JEKGxwYXJhbSk7CgkJCXB0X2NsbnQueSA9IHB0LnkgPSAoc2hvcnQpSElXT1JEKGxwYXJhbSk7CgkJCVNjcmVlblRvQ2xpZW50KGhwYW5lbCwgJnB0X2NsbnQpOwoJCQlTZW5kTWVzc2FnZShocGFuZWwsIFdNX0xCVVRUT05ET1dOLCAwLCBNQUtFTE9ORyhwdF9jbG50LngsIHB0X2NsbnQueSkpOwoJCQlTZW5kTWVzc2FnZShocGFuZWwsIFdNX0xCVVRUT05VUCwgMCwgTUFLRUxPTkcocHRfY2xudC54LCBwdF9jbG50LnkpKTsKCgkJCSAvKiBub3cgY3JlYXRlIHRoZSBwb3B1cCBtZW51IHVzaW5nIHNoZWxsIG5hbWVzcGFjZSBhbmQgSUNvbnRleHRNZW51ICovCgkJCXBhbmUgPSBHZXRGb2N1cygpPT1jaGlsZC0+bGVmdC5od25kPyAmY2hpbGQtPmxlZnQ6ICZjaGlsZC0+cmlnaHQ7CgkJCWlkeCA9IExpc3RCb3hfR2V0Q3VyU2VsKHBhbmUtPmh3bmQpOwoKCQkJaWYgKGlkeCAhPSAtMSkgewoJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBpZHgpOwoKCQkJCUxQSVRFTUlETElTVCBwaWRsX2FicyA9IGdldF90b19hYnNvbHV0ZV9waWRsKGVudHJ5LCBod25kKTsKCgkJCQlpZiAocGlkbF9hYnMpIHsKCQkJCQlJU2hlbGxGb2xkZXIqIHBhcmVudEZvbGRlcjsKCQkJCQlMUENJVEVNSURMSVNUIHBpZGxMYXN0OwoKCQkJCQkgLyogZ2V0IGFuZCB1c2UgdGhlIHBhcmVudCBmb2xkZXIgdG8gZGlzcGxheSBjb3JyZWN0IGNvbnRleHQgbWVudSBpbiBhbGwgY2FzZXMgKi8KCQkJCQlpZiAoU1VDQ0VFREVEKFNIQmluZFRvUGFyZW50KHBpZGxfYWJzLCAmSUlEX0lTaGVsbEZvbGRlciwgKExQVk9JRCopJnBhcmVudEZvbGRlciwgJnBpZGxMYXN0KSkpIHsKCQkJCQkJaWYgKFNoZWxsRm9sZGVyQ29udGV4dE1lbnUocGFyZW50Rm9sZGVyLCBod25kLCAxLCAmcGlkbExhc3QsIHB0LngsIHB0LnkpID09IFNfT0spCgkJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCgkJCQkJCUlTaGVsbEZvbGRlcl9SZWxlYXNlKHBhcmVudEZvbGRlcik7CgkJCQkJfQoKCQkJCQlJTWFsbG9jX0ZyZWUoR2xvYmFscy5pTWFsbG9jLCBwaWRsX2Ficyk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7fQojZW5kaWYKCgkJICBjYXNlIFdNX01FQVNVUkVJVEVNOgoJCSAgZHJhd19tZW51X2l0ZW06CgkJCWlmICghd3BhcmFtKQkvKiBJcyB0aGUgbWVzc2FnZSBtZW51LXJlbGF0ZWQ/ICovCgkJCQlpZiAoQ3R4TWVudV9IYW5kbGVNZW51TXNnKG5tc2csIHdwYXJhbSwgbHBhcmFtKSkKCQkJCQlyZXR1cm4gVFJVRTsKCgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCQkJaWYgKEN0eE1lbnVfSGFuZGxlTWVudU1zZyhubXNnLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCgkJCXVwZGF0ZV92aWV3X21lbnUoY2hpbGQpOwoJCQlicmVhazsKCgkJICBjYXNlIFdNX01FTlVDSEFSOgkvKiBvbmx5IHN1cHBvcnRlZCBieSBJQ29udGV4dE1lbnUzICovCgkJICAgaWYgKHNfcGN0eG1lbnUzKSB7CgkJCSAgIExSRVNVTFQgbFJlc3VsdCA9IDA7CgoJCQkgICBJQ29udGV4dE1lbnUzX0hhbmRsZU1lbnVNc2cyKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSwgJmxSZXN1bHQpOwoKCQkJICAgcmV0dXJuIGxSZXN1bHQ7CgkJICAgfQoKCQkgICBicmVhazsKCgkJY2FzZSBXTV9TSVpFOgoJCQlpZiAod3BhcmFtICE9IFNJWkVfTUlOSU1JWkVEKQoJCQkJcmVzaXplX3RyZWUoY2hpbGQsIExPV09SRChscGFyYW0pLCBISVdPUkQobHBhcmFtKSk7CgkJCS8qIGZhbGwgdGhyb3VnaCAqLwoKCQlkZWZhdWx0OiBkZWY6CgkJCXJldHVybiBEZWZNRElDaGlsZFByb2MoaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmdQdHIoR2V0UGFyZW50KGh3bmQpLCBHV0xQX1VTRVJEQVRBKTsKCVBhbmUqIHBhbmUgPSAoUGFuZSopIEdldFdpbmRvd0xvbmdQdHIoaHduZCwgR1dMUF9VU0VSREFUQSk7CglBU1NFUlQoY2hpbGQpOwoKCXN3aXRjaChubXNnKSB7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0hTQ1JPTEw6CgkJCXNldF9oZWFkZXIocGFuZSk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9TRVRGT0NVUzoKCQkJY2hpbGQtPmZvY3VzX3BhbmUgPSBwYW5lPT0mY2hpbGQtPnJpZ2h0PyAxOiAwOwoJCQlMaXN0Qm94X1NldFNlbChod25kLCBUUlVFLCAxKTsKCQkJLypUT0RPOiBjaGVjayBtZW51IGl0ZW1zICovCgkJCWJyZWFrOwoKCQljYXNlIFdNX0tFWURPV046CgkJCWlmICh3cGFyYW0gPT0gVktfVEFCKSB7CgkJCQkvKlRPRE86IFNldEZvY3VzKEdsb2JhbHMuaGRyaXZlYmFyKSAqLwoJCQkJU2V0Rm9jdXMoY2hpbGQtPmZvY3VzX3BhbmU/IGNoaWxkLT5sZWZ0Lmh3bmQ6IGNoaWxkLT5yaWdodC5od25kKTsKCQkJfQoJfQoKCXJldHVybiBDYWxsV2luZG93UHJvYyhnX29yZ1RyZWVXbmRQcm9jLCBod25kLCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7Cn0KCgpzdGF0aWMgdm9pZCBJbml0SW5zdGFuY2UoSElOU1RBTkNFIGhpbnN0YW5jZSkKewoJc3RhdGljIGNvbnN0IFRDSEFSIHNGb250W10gPSB7J00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJyAnLCdTJywnYScsJ24nLCdzJywnICcsJ1MnLCdlJywncicsJ2knLCdmJywnXDAnfTsKCglXTkRDTEFTU0VYIHdjRnJhbWU7CglXTkRDTEFTUyB3Y0NoaWxkOwoJQVRPTSBoQ2hpbGRDbGFzczsKCWludCBjb2w7CgoJSU5JVENPTU1PTkNPTlRST0xTRVggaWNjID0gewoJCXNpemVvZihJTklUQ09NTU9OQ09OVFJPTFNFWCksCgkJSUNDX0JBUl9DTEFTU0VTCgl9OwoKCUhEQyBoZGMgPSBHZXREQygwKTsKCglzZXRsb2NhbGUoTENfQ09MTEFURSwgIiIpOwkvKiBzZXQgY29sbGF0aW5nIHJ1bGVzIHRvIGxvY2FsIHNldHRpbmdzIGZvciBjb21wYXJlTmFtZSAqLwoKCUluaXRDb21tb25Db250cm9sc0V4KCZpY2MpOwoKCgkvKiByZWdpc3RlciBmcmFtZSB3aW5kb3cgY2xhc3MgKi8KCgl3Y0ZyYW1lLmNiU2l6ZSAgICAgICAgPSBzaXplb2YoV05EQ0xBU1NFWCk7Cgl3Y0ZyYW1lLnN0eWxlICAgICAgICAgPSAwOwoJd2NGcmFtZS5scGZuV25kUHJvYyAgID0gRnJhbWVXbmRQcm9jOwoJd2NGcmFtZS5jYkNsc0V4dHJhICAgID0gMDsKCXdjRnJhbWUuY2JXbmRFeHRyYSAgICA9IDA7Cgl3Y0ZyYW1lLmhJbnN0YW5jZSAgICAgPSBoaW5zdGFuY2U7Cgl3Y0ZyYW1lLmhJY29uICAgICAgICAgPSBMb2FkSWNvbihoaW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpKTsKCXdjRnJhbWUuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKCXdjRnJhbWUuaGJyQmFja2dyb3VuZCA9IDA7Cgl3Y0ZyYW1lLmxwc3pNZW51TmFtZSAgPSAwOwoJd2NGcmFtZS5scHN6Q2xhc3NOYW1lID0gc1dJTkVGSUxFRlJBTUU7Cgl3Y0ZyYW1lLmhJY29uU20gICAgICAgPSAoSElDT04pTG9hZEltYWdlKGhpbnN0YW5jZSwKCQkJCQkJCQkJCQkgTUFLRUlOVFJFU09VUkNFKElESV9XSU5FRklMRSksCgkJCQkJCQkJCQkJIElNQUdFX0lDT04sCgkJCQkJCQkJCQkJIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTTUlDT04pLAoJCQkJCQkJCQkJCSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwKCQkJCQkJCQkJCQkgTFJfU0hBUkVEKTsKCglHbG9iYWxzLmhmcmFtZUNsYXNzID0gUmVnaXN0ZXJDbGFzc0V4KCZ3Y0ZyYW1lKTsKCgoJLyogcmVnaXN0ZXIgdHJlZSB3aW5kb3dzIGNsYXNzICovCgoJd2NDaGlsZC5zdHlsZSAgICAgICAgID0gQ1NfQ0xBU1NEQ3xDU19EQkxDTEtTfENTX1ZSRURSQVc7Cgl3Y0NoaWxkLmxwZm5XbmRQcm9jICAgPSBDaGlsZFduZFByb2M7Cgl3Y0NoaWxkLmNiQ2xzRXh0cmEgICAgPSAwOwoJd2NDaGlsZC5jYlduZEV4dHJhICAgID0gMDsKCXdjQ2hpbGQuaEluc3RhbmNlICAgICA9IGhpbnN0YW5jZTsKCXdjQ2hpbGQuaEljb24gICAgICAgICA9IDA7Cgl3Y0NoaWxkLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7Cgl3Y0NoaWxkLmhickJhY2tncm91bmQgPSAwOwoJd2NDaGlsZC5scHN6TWVudU5hbWUgID0gMDsKCXdjQ2hpbGQubHBzekNsYXNzTmFtZSA9IHNXSU5FRklMRVRSRUU7CgoJaENoaWxkQ2xhc3MgPSBSZWdpc3RlckNsYXNzKCZ3Y0NoaWxkKTsKCgoJR2xvYmFscy5oYWNjZWwgPSBMb2FkQWNjZWxlcmF0b3JzKGhpbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElEQV9XSU5FRklMRSkpOwoKCUdsb2JhbHMuaGZvbnQgPSBDcmVhdGVGb250KC1NdWxEaXYoOCxHZXREZXZpY2VDYXBzKGhkYyxMT0dQSVhFTFNZKSw3MiksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNGb250KTsKCglSZWxlYXNlREMoMCwgaGRjKTsKCglHbG9iYWxzLmhJbnN0YW5jZSA9IGhpbnN0YW5jZTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJQ29Jbml0aWFsaXplKE5VTEwpOwoJQ29HZXRNYWxsb2MoTUVNQ1RYX1RBU0ssICZHbG9iYWxzLmlNYWxsb2MpOwoJU0hHZXREZXNrdG9wRm9sZGVyKCZHbG9iYWxzLmlEZXNrdG9wKTsKI2lmZGVmIF9fV0lORV9fCglHbG9iYWxzLmNmU3RyRk5hbWUgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdEEoQ0ZTVFJfRklMRU5BTUUpOwojZWxzZQoJR2xvYmFscy5jZlN0ckZOYW1lID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXQoQ0ZTVFJfRklMRU5BTUUpOwojZW5kaWYKI2VuZGlmCgoJLyogbG9hZCBjb2x1bW4gc3RyaW5ncyAqLwoJY29sID0gMTsKCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfTkFNRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfU0laRSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQ0RBVEUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQURBVEUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX01EQVRFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9JRFgpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0xJTktTKTsKI2VuZGlmCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfQVRUUik7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9TRUMpOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIHNob3dfZnJhbWUoSFdORCBod25kUGFyZW50LCBpbnQgY21kc2hvdywgTFBDVFNUUiBwYXRoKQp7CglzdGF0aWMgY29uc3QgVENIQVIgc01ESUNMSUVOVFtdID0geydNJywnRCcsJ0knLCdDJywnTCcsJ0knLCdFJywnTicsJ1QnLCdcMCd9OwoKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF0sIGIxW0JVRkZFUl9MRU5dOwoJQ2hpbGRXbmQqIGNoaWxkOwoJSE1FTlUgaE1lbnVGcmFtZSwgaE1lbnVXaW5kb3c7Cgl3aW5kb3dPcHRpb25zIG9wdHM7CgoJQ0xJRU5UQ1JFQVRFU1RSVUNUIGNjczsKCglpZiAoR2xvYmFscy5oTWFpblduZCkKCQlyZXR1cm47CgoJb3B0cyA9IGxvYWRfcmVnaXN0cnlfc2V0dGluZ3MoKTsKCWhNZW51RnJhbWUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElETV9XSU5FRklMRSkpOwoJaE1lbnVXaW5kb3cgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIEdldE1lbnVJdGVtQ291bnQoaE1lbnVGcmFtZSktMik7CgoJR2xvYmFscy5oTWVudUZyYW1lID0gaE1lbnVGcmFtZTsKCUdsb2JhbHMuaE1lbnVWaWV3ID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCAzKTsKCUdsb2JhbHMuaE1lbnVPcHRpb25zID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCA0KTsKCgljY3MuaFdpbmRvd01lbnUgID0gaE1lbnVXaW5kb3c7CgljY3MuaWRGaXJzdENoaWxkID0gSURXX0ZJUlNUX0NISUxEOwoKCgkvKiBjcmVhdGUgbWFpbiB3aW5kb3cgKi8KCUdsb2JhbHMuaE1haW5XbmQgPSBDcmVhdGVXaW5kb3dFeCgwLCAoTFBDVFNUUikoaW50KUdsb2JhbHMuaGZyYW1lQ2xhc3MsIFJTKGIxLElEU19XSU5FX0ZJTEUpLCBXU19PVkVSTEFQUEVEV0lORE9XLAoJCQkJCW9wdHMuc3RhcnRfeCwgb3B0cy5zdGFydF95LCBvcHRzLndpZHRoLCBvcHRzLmhlaWdodCwKCQkJCQlod25kUGFyZW50LCBHbG9iYWxzLmhNZW51RnJhbWUsIEdsb2JhbHMuaEluc3RhbmNlLCAwLypscFBhcmFtKi8pOwoKCglHbG9iYWxzLmhtZGljbGllbnQgPSBDcmVhdGVXaW5kb3dFeCgwLCBzTURJQ0xJRU5ULCBOVUxMLAoJCQkJCVdTX0NISUxEfFdTX0NMSVBDSElMRFJFTnxXU19WU0NST0xMfFdTX0hTQ1JPTEx8V1NfVklTSUJMRXxXU19CT1JERVIsCgkJCQkJMCwgMCwgMCwgMCwKCQkJCQlHbG9iYWxzLmhNYWluV25kLCAwLCBHbG9iYWxzLmhJbnN0YW5jZSwgJmNjcyk7CiAgCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX0RSSVZFX0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TQVZFU0VUVElOR1MsIE1GX0JZQ09NTUFORCk7CgoJY3JlYXRlX2RyaXZlX2JhcigpOwoKCXsKCQlUQkJVVFRPTiB0b29sYmFyQnRuc1tdID0gewoJCQl7MCwgMCwgMCwgQlROU19TRVAsIHswLCAwfSwgMCwgMH0sCgkJCXswLCBJRF9XSU5ET1dfTkVXLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MSwgSURfV0lORE9XX0NBU0NBREUsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCgkJCXsyLCBJRF9XSU5ET1dfVElMRV9IT1JaLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MywgSURfV0lORE9XX1RJTEVfVkVSVCwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKLypUT0RPCgkJCXs0LCBJRF8uLi4gLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7NSwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKKi8JCX07CgoJCUdsb2JhbHMuaHRvb2xiYXIgPSBDcmVhdGVUb29sYmFyRXgoR2xvYmFscy5oTWFpblduZCwgV1NfQ0hJTER8V1NfVklTSUJMRSwKCQkJSURXX1RPT0xCQVIsIDIsIEdsb2JhbHMuaEluc3RhbmNlLCBJREJfVE9PTEJBUiwgdG9vbGJhckJ0bnMsCgkJCXNpemVvZih0b29sYmFyQnRucykvc2l6ZW9mKFRCQlVUVE9OKSwgMTYsIDE1LCAxNiwgMTUsIHNpemVvZihUQkJVVFRPTikpOwoJCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudU9wdGlvbnMsIElEX1ZJRVdfVE9PTF9CQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCX0KCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVTdGF0dXNXaW5kb3coV1NfQ0hJTER8V1NfVklTSUJMRSwgMCwgR2xvYmFscy5oTWFpblduZCwgSURXX1NUQVRVU0JBUik7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1NUQVRVU0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKLyogQ3JlYXRlU3RhdHVzV2luZG93IGRvZXMgbm90IGFjY2VwdCBXU19CT1JERVIKCUdsb2JhbHMuaHN0YXR1c2JhciA9IENyZWF0ZVdpbmRvd0V4KFdTX0VYX05PUEFSRU5UTk9USUZZLCBTVEFUVVNDTEFTU05BTUUsIDAsCgkJCQkJV1NfQ0hJTER8V1NfVklTSUJMRXxXU19DTElQU0lCTElOR1N8V1NfQk9SREVSfENDU19OT0RJVklERVIsIDAsMCwwLDAsCgkJCQkJR2xvYmFscy5oTWFpblduZCwgKEhNRU5VKUlEV19TVEFUVVNCQVIsIGhpbnN0YW5jZSwgMCk7Ki8KCgkvKlRPRE86IHJlYWQgcGF0aHMgZnJvbSByZWdpc3RyeSAqLwoKCWlmICghcGF0aCB8fCAhKnBhdGgpIHsKCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBidWZmZXIpOwoJCXBhdGggPSBidWZmZXI7Cgl9CgoJU2hvd1dpbmRvdyhHbG9iYWxzLmhNYWluV25kLCBjbWRzaG93KTsKCiNpZiBkZWZpbmVkKF9TSEVMTF9GT0xERVJTKSAmJiAhZGVmaW5lZChfX1dJTkVfXykKCSAvKiBTaGVsbCBOYW1lc3BhY2UgYXMgZGVmYXVsdDogKi8KCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIGdldF9wYXRoX3BpZGwocGF0aCxHbG9iYWxzLmhNYWluV25kKSwgR2xvYmFscy5oTWFpblduZCk7CiNlbHNlCgljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBHbG9iYWxzLmhNYWluV25kKTsKI2VuZGlmCgoJY2hpbGQtPnBvcy5zaG93Q21kID0gU1dfU0hPV01BWElNSVpFRDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0ID0gMDsKCWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3AgPSAwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0ID0gMzIwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbSA9IDI4MDsKCglpZiAoIWNyZWF0ZV9jaGlsZF93aW5kb3coY2hpbGQpKQoJCWZyZWUoY2hpbGQpOwoKCVNldFdpbmRvd1BsYWNlbWVudChjaGlsZC0+aHduZCwgJmNoaWxkLT5wb3MpOwoKCUdsb2JhbHMuaGltbCA9IEltYWdlTGlzdF9Mb2FkQml0bWFwKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURCX0lNQUdFUyksIDE2LCAwLCBSR0IoMCwyNTUsMCkpOwoKCUdsb2JhbHMucHJlc2Nhbl9ub2RlID0gRkFMU0U7CgoJVXBkYXRlV2luZG93KEdsb2JhbHMuaE1haW5XbmQpOwoKCWlmIChwYXRoICYmIHBhdGhbMF0pCgl7CgkJaW50IGluZGV4LGNvdW50OwoJCVRDSEFSIGRydltfTUFYX0RSSVZFKzFdLCBkaXJbX01BWF9ESVJdLCBuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJCVRDSEFSIGZ1bGxuYW1lW19NQVhfRk5BTUUrX01BWF9FWFQrMV07CgoJCW1lbXNldChuYW1lLDAsc2l6ZW9mKG5hbWUpKTsKCQltZW1zZXQobmFtZSwwLHNpemVvZihleHQpKTsKCQlfdHNwbGl0cGF0aChwYXRoLCBkcnYsIGRpciwgbmFtZSwgZXh0KTsKCQlpZiAobmFtZVswXSkKCQl7CgkJCWNvdW50ID0gTGlzdEJveF9HZXRDb3VudChjaGlsZC0+cmlnaHQuaHduZCk7CgkJCWxzdHJjcHkoZnVsbG5hbWUsbmFtZSk7CgkJCWxzdHJjYXQoZnVsbG5hbWUsZXh0KTsKCgkJCWZvciAoaW5kZXggPSAwOyBpbmRleCA8IGNvdW50OyBpbmRleCArKykKCQkJewoJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShjaGlsZC0+cmlnaHQuaHduZCwKCQkJCQkJaW5kZXgpOwoJCQkJaWYgKGxzdHJjbXAoZW50cnktPmRhdGEuY0ZpbGVOYW1lLGZ1bGxuYW1lKT09MCB8fAoJCQkJCQlsc3RyY21wKGVudHJ5LT5kYXRhLmNBbHRlcm5hdGVGaWxlTmFtZSxmdWxsbmFtZSk9PTApCgkJCQl7CgkJCQkJTGlzdEJveF9TZXRDdXJTZWwoY2hpbGQtPnJpZ2h0Lmh3bmQsIGluZGV4KTsKCQkJCQlTZXRGb2N1cyhjaGlsZC0+cmlnaHQuaHduZCk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkIEV4aXRJbnN0YW5jZSh2b2lkKQp7CiNpZmRlZiBfU0hFTExfRk9MREVSUwoJSVNoZWxsRm9sZGVyX1JlbGVhc2UoR2xvYmFscy5pRGVza3RvcCk7CglJTWFsbG9jX1JlbGVhc2UoR2xvYmFscy5pTWFsbG9jKTsKCUNvVW5pbml0aWFsaXplKCk7CiNlbmRpZgoKCURlbGV0ZU9iamVjdChHbG9iYWxzLmhmb250KTsKCUltYWdlTGlzdF9EZXN0cm95KEdsb2JhbHMuaGltbCk7Cn0KCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoKLyogc2VhcmNoIGZvciBhbHJlYWR5IHJ1bm5pbmcgd2luW2VdZmlsZXMgKi8KCnN0YXRpYyBpbnQgZ19mb3VuZFByZXZJbnN0YW5jZSA9IDA7CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBFbnVtV25kUHJvYyhIV05EIGh3bmQsIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGNsc1sxMjhdOwoKCUdldENsYXNzTmFtZShod25kLCBjbHMsIDEyOCk7CgoJaWYgKCFsc3RyY21wKGNscywgKExQQ1RTVFIpbHBhcmFtKSkgewoJCWdfZm91bmRQcmV2SW5zdGFuY2UrKzsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qIHNlYXJjaCBmb3Igd2luZG93IG9mIGdpdmVuIGNsYXNzIG5hbWUgdG8gYWxsb3cgb25seSBvbmUgcnVubmluZyBpbnN0YW5jZSAqLwpzdGF0aWMgaW50IGZpbmRfd2luZG93X2NsYXNzKExQQ1RTVFIgY2xhc3NuYW1lKQp7CglFbnVtV2luZG93cyhFbnVtV25kUHJvYywgKExQQVJBTSljbGFzc25hbWUpOwoKCWlmIChnX2ZvdW5kUHJldkluc3RhbmNlKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgojZW5kaWYKCnN0YXRpYyBpbnQgd2luZWZpbGVfbWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBpbnQgY21kc2hvdywgTFBDVFNUUiBwYXRoKQp7CglNU0cgbXNnOwogIAoJSW5pdEluc3RhbmNlKGhpbnN0YW5jZSk7CgoJc2hvd19mcmFtZSgwLCBjbWRzaG93LCBwYXRoKTsKCgl3aGlsZShHZXRNZXNzYWdlKCZtc2csIDAsIDAsIDApKSB7CgkJaWYgKEdsb2JhbHMuaG1kaWNsaWVudCAmJiBUcmFuc2xhdGVNRElTeXNBY2NlbChHbG9iYWxzLmhtZGljbGllbnQsICZtc2cpKQoJCQljb250aW51ZTsKCgkJaWYgKEdsb2JhbHMuaE1haW5XbmQgJiYgVHJhbnNsYXRlQWNjZWxlcmF0b3IoR2xvYmFscy5oTWFpblduZCwgR2xvYmFscy5oYWNjZWwsICZtc2cpKQoJCQljb250aW51ZTsKCgkJVHJhbnNsYXRlTWVzc2FnZSgmbXNnKTsKCQlEaXNwYXRjaE1lc3NhZ2UoJm1zZyk7Cgl9CgoJRXhpdEluc3RhbmNlKCk7CgoJcmV0dXJuIG1zZy53UGFyYW07Cn0KCgojaWYgZGVmaW5lZChVTklDT0RFKSAmJiBkZWZpbmVkKF9NU0NfVkVSKQppbnQgQVBJRU5UUlkgd1dpbk1haW4oSElOU1RBTkNFIGhpbnN0YW5jZSwgSElOU1RBTkNFIHByZXZpbnN0YW5jZSwgTFBXU1RSIGNtZGxpbmUsIGludCBjbWRzaG93KQojZWxzZQppbnQgQVBJRU5UUlkgV2luTWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBISU5TVEFOQ0UgcHJldmluc3RhbmNlLCBMUFNUUiBjbWRsaW5lLCBpbnQgY21kc2hvdykKI2VuZGlmCnsKI2lmZGVmIF9OT19FWFRFTlNJT05TCglpZiAoZmluZF93aW5kb3dfY2xhc3Moc1dJTkVGSUxFRlJBTUUpKQoJCXJldHVybiAxOwojZW5kaWYKCiNpZiBkZWZpbmVkKFVOSUNPREUpICYmICFkZWZpbmVkKF9NU0NfVkVSKQoJeyAvKiBjb252ZXJ0IEFOU0kgY21kbGluZSBpbnRvIFdDUyBwYXRoIHN0cmluZyAqLwoJVENIQVIgYnVmZmVyW01BWF9QQVRIXTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBjbWRsaW5lLCAtMSwgYnVmZmVyLCBNQVhfUEFUSCk7Cgl3aW5lZmlsZV9tYWluKGhpbnN0YW5jZSwgY21kc2hvdywgYnVmZmVyKTsKCX0KI2Vsc2UKCXdpbmVmaWxlX21haW4oaGluc3RhbmNlLCBjbWRzaG93LCBjbWRsaW5lKTsKI2VuZGlmCgoJcmV0dXJuIDA7Cn0K