LyoKICogV2luZWZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAsIDIwMDMsIDIwMDQsIDIwMDUgTWFydGluIEZ1Y2hzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZmRlZiBfX1dJTkVfXwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2VuZGlmCgojaW5jbHVkZSAid2luZWZpbGUuaCIKI2luY2x1ZGUgInJlc291cmNlLmgiCgovKiBmb3IgcmVhZF9kaXJlY3RvcnlfdW5peCgpICovCiNpZiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykKI2luY2x1ZGUgPGRpcmVudC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDx0aW1lLmg+CiNlbmRpZgoKI2lmZGVmIF9OT19FWFRFTlNJT05TCiN1bmRlZiBfTEVGVF9GSUxFUwojZW5kaWYKCiNpZm5kZWYgX01BWF9QQVRICiNkZWZpbmUgX01BWF9EUklWRSAgICAgICAgICAzCiNkZWZpbmUgX01BWF9GTkFNRSAgICAgICAgICAyNTYKI2RlZmluZSBfTUFYX0RJUiAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX0VYVCAgICAgICAgICAgIF9NQVhfRk5BTUUKI2RlZmluZSBfTUFYX1BBVEggICAgICAgICAgIDI2MAojZW5kaWYKCiNpZmRlZiBOT05BTUVMRVNTVU5JT04KI2RlZmluZQlVTklPTl9NRU1CRVIoeCkgRFVNTVlVTklPTk5BTUUueAojZWxzZQojZGVmaW5lCVVOSU9OX01FTUJFUih4KSB4CiNlbmRpZgoKCiNpZmRlZiBfU0hFTExfRk9MREVSUwojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTMwMAojZWxzZQojZGVmaW5lCURFRkFVTFRfU1BMSVRfUE9TCTIwMAojZW5kaWYKCgplbnVtIEVOVFJZX1RZUEUgewoJRVRfV0lORE9XUywKCUVUX1VOSVgsCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJRVRfU0hFTEwKI2VuZGlmCn07Cgp0eXBlZGVmIHN0cnVjdCBfRW50cnkgewoJc3RydWN0IF9FbnRyeSoJbmV4dDsKCXN0cnVjdCBfRW50cnkqCWRvd247CglzdHJ1Y3QgX0VudHJ5Kgl1cDsKCglCT09MCQkJZXhwYW5kZWQ7CglCT09MCQkJc2Nhbm5lZDsKCWludAkJCQlsZXZlbDsKCglXSU4zMl9GSU5EX0RBVEEJZGF0YTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CglCT09MCQkJYmhmaV92YWxpZDsKCWVudW0gRU5UUllfVFlQRQlldHlwZTsKI2VuZGlmCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJTFBJVEVNSURMSVNUCXBpZGw7CglJU2hlbGxGb2xkZXIqCWZvbGRlcjsKCUhJQ09OCQkJaGljb247CiNlbmRpZgp9IEVudHJ5OwoKdHlwZWRlZiBzdHJ1Y3QgewoJRW50cnkJZW50cnk7CglUQ0hBUglwYXRoW01BWF9QQVRIXTsKCVRDSEFSCXZvbG5hbWVbX01BWF9GTkFNRV07CglUQ0hBUglmc1tfTUFYX0RJUl07CglEV09SRAlkcml2ZV90eXBlOwoJRFdPUkQJZnNfZmxhZ3M7Cn0gUm9vdDsKCmVudW0gQ09MVU1OX0ZMQUdTIHsKCUNPTF9TSVpFCQk9IDB4MDEsCglDT0xfREFURQkJPSAweDAyLAoJQ09MX1RJTUUJCT0gMHgwNCwKCUNPTF9BVFRSSUJVVEVTCT0gMHgwOCwKCUNPTF9ET1NOQU1FUwk9IDB4MTAsCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJQ09MX0FMTCA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTfENPTF9ET1NOQU1FUwojZWxzZQoJQ09MX0lOREVYCQk9IDB4MjAsCglDT0xfTElOS1MJCT0gMHg0MCwKCUNPTF9BTEwgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfRE9TTkFNRVN8Q09MX0lOREVYfENPTF9MSU5LUwojZW5kaWYKfTsKCnR5cGVkZWYgZW51bSB7CglTT1JUX05BTUUsCglTT1JUX0VYVCwKCVNPUlRfU0laRSwKCVNPUlRfREFURQp9IFNPUlRfT1JERVI7Cgp0eXBlZGVmIHN0cnVjdCB7CglIV05ECWh3bmQ7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhXTkQJaHduZEhlYWRlcjsKI2VuZGlmCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNkZWZpbmUJQ09MVU1OUwkxMAojZWxzZQojZGVmaW5lCUNPTFVNTlMJNQojZW5kaWYKCWludAkJd2lkdGhzW0NPTFVNTlNdOwoJaW50CQlwb3NpdGlvbnNbQ09MVU1OUysxXTsKCglCT09MCXRyZWVQYW5lOwoJaW50CQl2aXNpYmxlX2NvbHM7CglFbnRyeSoJcm9vdDsKCUVudHJ5KgljdXI7Cn0gUGFuZTsKCnR5cGVkZWYgc3RydWN0IHsKCUhXTkQJaHduZDsKCVBhbmUJbGVmdDsKCVBhbmUJcmlnaHQ7CglpbnQJCWZvY3VzX3BhbmU7CQkvKiAwOiBsZWZ0ICAxOiByaWdodCAqLwoJV0lORE9XUExBQ0VNRU5UIHBvczsKCWludAkJc3BsaXRfcG9zOwoJQk9PTAloZWFkZXJfd2R0aHNfb2s7CgoJVENIQVIJcGF0aFtNQVhfUEFUSF07CglUQ0hBUglmaWx0ZXJfcGF0dGVybltNQVhfUEFUSF07CglpbnQJCWZpbHRlcl9mbGFnczsKCVJvb3QJcm9vdDsKCglTT1JUX09SREVSIHNvcnRPcmRlcjsKfSBDaGlsZFduZDsKCgpleHRlcm4gdm9pZCBXaW5lTGljZW5zZShIV05EIGh3bmQpOwpleHRlcm4gdm9pZCBXaW5lV2FycmFudHkoSFdORCBod25kKTsKCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeShFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpOwpzdGF0aWMgdm9pZCBzZXRfY3VyZGlyKENoaWxkV25kKiBjaGlsZCwgRW50cnkqIGVudHJ5LCBpbnQgaWR4LCBIV05EIGh3bmQpOwpzdGF0aWMgdm9pZCByZWZyZXNoX2NoaWxkKENoaWxkV25kKiBjaGlsZCk7CnN0YXRpYyB2b2lkIHJlZnJlc2hfZHJpdmVzKCk7CnN0YXRpYyB2b2lkIGdldF9wYXRoKEVudHJ5KiBkaXIsIFBUU1RSIHBhdGgpOwpzdGF0aWMgdm9pZCBmb3JtYXRfZGF0ZShjb25zdCBGSUxFVElNRSogZnQsIFRDSEFSKiBidWZmZXIsIGludCB2aXNpYmxlX2NvbHMpOwoKTFJFU1VMVCBDQUxMQkFDSyBGcmFtZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwpMUkVTVUxUIENBTExCQUNLIENoaWxkV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSk7CkxSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pOwoKCi8qIGdsb2JhbHMgKi8KV0lORUZJTEVfR0xPQkFMUyBHbG9iYWxzOwoKc3RhdGljIGludCBsYXN0X3NwbGl0OwoKLyogc29tZSBjb21tb24gc3RyaW5nIGNvbnN0YW50cyAqLwpjb25zdCBzdGF0aWMgVENIQVIgc0VtcHR5W10gPSB7J1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzU3BhY2VbXSA9IHsnICcsICdcMCd9Owpjb25zdCBzdGF0aWMgVENIQVIgc051bUZtdFtdID0geyclJywnZCcsJ1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzUU1hcmtzW10gPSB7Jz8nLCc/JywnPycsJ1wwJ307CgovKiB3aW5kb3cgY2xhc3MgbmFtZXMgKi8KY29uc3Qgc3RhdGljIFRDSEFSIHNXSU5FRklMRUZSQU1FW10gPSB7J1cnLCdGJywnUycsJ18nLCdGJywncicsJ2EnLCdtJywnZScsJ1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzV0lORUZJTEVUUkVFW10gPSB7J1cnLCdGJywnUycsJ18nLCdUJywncicsJ2UnLCdlJywnXDAnfTsKCiNpZmRlZiBfTVNDX1ZFUgovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJJNjQiKSAqLwpjb25zdCBzdGF0aWMgVENIQVIgc0xvbmdIZXhGbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ1gnLCdcMCd9Owpjb25zdCBzdGF0aWMgVENIQVIgc0xvbmdOdW1GbXRbXSA9IHsnJScsJ0knLCc2JywnNCcsJ2QnLCdcMCd9OwojZWxzZQovKiAjZGVmaW5lIExPTkdMT05HQVJHIF9UKCJMIikgKi8KY29uc3Qgc3RhdGljIFRDSEFSIHNMb25nSGV4Rm10W10gPSB7JyUnLCdMJywnWCcsJ1wwJ307CmNvbnN0IHN0YXRpYyBUQ0hBUiBzTG9uZ051bUZtdFtdID0geyclJywnTCcsJ2QnLCdcMCd9OwojZW5kaWYKCgovKiBsb2FkIHJlc291cmNlIHN0cmluZyAqLwpzdGF0aWMgTFBUU1RSIGxvYWRfc3RyaW5nKExQVFNUUiBidWZmZXIsIFVJTlQgaWQpCnsKCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIGlkLCBidWZmZXIsIEJVRkZFUl9MRU4pOwoKCXJldHVybiBidWZmZXI7Cn0KCiNkZWZpbmUgUlMoYiwgaSkgbG9hZF9zdHJpbmcoYiwgaSkKCgovKiBkaXNwbGF5IGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBzcGVjaWZpZWQgV0lOMzIgZXJyb3IgY29kZSAqLwpzdGF0aWMgdm9pZCBkaXNwbGF5X2Vycm9yKEhXTkQgaHduZCwgRFdPUkQgZXJyb3IpCnsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCVBUU1RSIG1zZzsKCglpZiAoRm9ybWF0TWVzc2FnZShGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVJ8Rk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0sCgkJMCwgZXJyb3IsIE1BS0VMQU5HSUQoTEFOR19ORVVUUkFMLFNVQkxBTkdfREVGQVVMVCksIChQVFNUUikmbXNnLCAwLCBOVUxMKSkKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoJZWxzZQoJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjEsSURTX0VSUk9SKSwgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwoKCUxvY2FsRnJlZShtc2cpOwp9CgoKLyogZGlzcGxheSBuZXR3b3JrIGVycm9yIG1lc3NhZ2UgdXNpbmcgV05ldEdldExhc3RFcnJvcigpICovCnN0YXRpYyB2b2lkIGRpc3BsYXlfbmV0d29ya19lcnJvcihIV05EIGh3bmQpCnsKCVRDSEFSIG1zZ1tCVUZGRVJfTEVOXSwgcHJvdmlkZXJbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoJRFdPUkQgZXJyb3I7CgoJaWYgKFdOZXRHZXRMYXN0RXJyb3IoJmVycm9yLCBtc2csIEJVRkZFUl9MRU4sIHByb3ZpZGVyLCBCVUZGRVJfTEVOKSA9PSBOT19FUlJPUikKCQlNZXNzYWdlQm94KGh3bmQsIG1zZywgUlMoYjIsSURTX1dJTkVGSUxFKSwgTUJfT0spOwp9CgoKLyogYWxsb2NhdGUgYW5kIGluaXRpYWxpc2UgYSBkaXJlY3RvcnkgZW50cnkgKi8Kc3RhdGljIEVudHJ5KiBhbGxvY19lbnRyeSgpCnsKCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIG1hbGxvYyhzaXplb2YoRW50cnkpKTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJZW50cnktPnBpZGwgPSBOVUxMOwoJZW50cnktPmZvbGRlciA9IE5VTEw7CgllbnRyeS0+aGljb24gPSAwOwojZW5kaWYKCglyZXR1cm4gZW50cnk7Cn0KCi8qIGZyZWUgYSBkaXJlY3RvcnkgZW50cnkgKi8Kc3RhdGljIHZvaWQgZnJlZV9lbnRyeShFbnRyeSogZW50cnkpCnsKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAoZW50cnktPmhpY29uICYmIGVudHJ5LT5oaWNvbiE9KEhJQ09OKS0xKQoJCURlc3Ryb3lJY29uKGVudHJ5LT5oaWNvbik7CgoJaWYgKGVudHJ5LT5mb2xkZXIgJiYgZW50cnktPmZvbGRlciE9R2xvYmFscy5pRGVza3RvcCkKCQkoKmVudHJ5LT5mb2xkZXItPmxwVnRibC0+UmVsZWFzZSkoZW50cnktPmZvbGRlcik7CgoJaWYgKGVudHJ5LT5waWRsKQoJCSgqR2xvYmFscy5pTWFsbG9jLT5scFZ0YmwtPkZyZWUpKEdsb2JhbHMuaU1hbGxvYywgZW50cnktPnBpZGwpOwojZW5kaWYKCglmcmVlKGVudHJ5KTsKfQoKLyogcmVjdXJzaXZlbHkgZnJlZSBhbGwgY2hpbGQgZW50cmllcyAqLwpzdGF0aWMgdm9pZCBmcmVlX2VudHJpZXMoRW50cnkqIGRpcikKewoJRW50cnkgKmVudHJ5LCAqbmV4dD1kaXItPmRvd247CgoJaWYgKG5leHQpIHsKCQlkaXItPmRvd24gPSAwOwoKCQlkbyB7CgkJCWVudHJ5ID0gbmV4dDsKCQkJbmV4dCA9IGVudHJ5LT5uZXh0OwoKCQkJZnJlZV9lbnRyaWVzKGVudHJ5KTsKCQkJZnJlZV9lbnRyeShlbnRyeSk7CgkJfSB3aGlsZShuZXh0KTsKCX0KfQoKCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3dpbihFbnRyeSogZGlyLCBMUENUU1RSIHBhdGgpCnsKCUVudHJ5KiBmaXJzdF9lbnRyeSA9IE5VTEw7CglFbnRyeSogbGFzdCA9IE5VTEw7CglFbnRyeSogZW50cnk7CgoJaW50IGxldmVsID0gZGlyLT5sZXZlbCArIDE7CglXSU4zMl9GSU5EX0RBVEEgdzMyZmQ7CglIQU5ETEUgaEZpbmQ7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhBTkRMRSBoRmlsZTsKI2VuZGlmCgoJVENIQVIgYnVmZmVyW01BWF9QQVRIXSwgKnA7Cglmb3IocD1idWZmZXI7ICpwYXRoOyApCgkJKnArKyA9ICpwYXRoKys7CgoJKnArKyA9ICdcXCc7CglwWzBdID0gJyonOwoJcFsxXSA9ICdcMCc7CgoJaEZpbmQgPSBGaW5kRmlyc3RGaWxlKGJ1ZmZlciwgJnczMmZkKTsKCglpZiAoaEZpbmQgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKCQlkbyB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkvKiBoaWRlIGRpcmVjdG9yeSBlbnRyeSAiLiIgKi8KCQkJaWYgKHczMmZkLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCUxQQ1RTVFIgbmFtZSA9IHczMmZkLmNGaWxlTmFtZTsKCgkJCQlpZiAobmFtZVswXT09Jy4nICYmIG5hbWVbMV09PSdcMCcpCgkJCQkJY29udGludWU7CgkJCX0KI2VuZGlmCgkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCWlmICghZmlyc3RfZW50cnkpCgkJCQlmaXJzdF9lbnRyeSA9IGVudHJ5OwoKCQkJaWYgKGxhc3QpCgkJCQlsYXN0LT5uZXh0ID0gZW50cnk7CgoJCQltZW1jcHkoJmVudHJ5LT5kYXRhLCAmdzMyZmQsIHNpemVvZihXSU4zMl9GSU5EX0RBVEEpKTsKCQkJZW50cnktPmRvd24gPSBOVUxMOwoJCQllbnRyeS0+dXAgPSBkaXI7CgkJCWVudHJ5LT5leHBhbmRlZCA9IEZBTFNFOwoJCQllbnRyeS0+c2Nhbm5lZCA9IEZBTFNFOwoJCQllbnRyeS0+bGV2ZWwgPSBsZXZlbDsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQkJZW50cnktPmV0eXBlID0gRVRfV0lORE9XUzsKCQkJZW50cnktPmJoZmlfdmFsaWQgPSBGQUxTRTsKCgkJCWxzdHJjcHkocCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCgkJCWhGaWxlID0gQ3JlYXRlRmlsZShidWZmZXIsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFEfEZJTEVfU0hBUkVfV1JJVEV8RklMRV9TSEFSRV9ERUxFVEUsCgkJCQkJCQkJMCwgT1BFTl9FWElTVElORywgRklMRV9GTEFHX0JBQ0tVUF9TRU1BTlRJQ1MsIDApOwoKCQkJaWYgKGhGaWxlICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CgkJCQlpZiAoR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaEZpbGUsICZlbnRyeS0+YmhmaSkpCgkJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBUUlVFOwoKCQkJCUNsb3NlSGFuZGxlKGhGaWxlKTsKCQkJfQojZW5kaWYKCgkJCWxhc3QgPSBlbnRyeTsKCQl9IHdoaWxlKEZpbmROZXh0RmlsZShoRmluZCwgJnczMmZkKSk7CgoJCWlmIChsYXN0KQoJCQlsYXN0LT5uZXh0ID0gTlVMTDsKCgkJRmluZENsb3NlKGhGaW5kKTsKCX0KCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCgpzdGF0aWMgRW50cnkqIGZpbmRfZW50cnlfd2luKEVudHJ5KiBkaXIsIExQQ1RTVFIgbmFtZSkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCUxQQ1RTVFIgcCA9IG5hbWU7CgkJTFBDVFNUUiBxID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnA9PVRFWFQoJ1xcJykgfHwgKnA9PVRFWFQoJy8nKSkKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKHRvbG93ZXIoKnArKykgPT0gdG9sb3dlcigqcSsrKSk7CgoJCXAgPSBuYW1lOwoJCXEgPSBlbnRyeS0+ZGF0YS5jQWx0ZXJuYXRlRmlsZU5hbWU7CgoJCWRvIHsKCQkJaWYgKCEqcCB8fCAqcD09VEVYVCgnXFwnKSB8fCAqcD09VEVYVCgnLycpKQoJCQkJcmV0dXJuIGVudHJ5OwoJCX0gd2hpbGUodG9sb3dlcigqcCsrKSA9PSB0b2xvd2VyKCpxKyspKTsKCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlX3dpbihSb290KiByb290LCBMUENUU1RSIHBhdGgsIFNPUlRfT1JERVIgc29ydE9yZGVyLCBIV05EIGh3bmQpCnsKCVRDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CglFbnRyeSogZW50cnkgPSAmcm9vdC0+ZW50cnk7CglMUENUU1RSIHMgPSBwYXRoOwoJUFRTVFIgZCA9IGJ1ZmZlcjsKCglIQ1VSU09SIG9sZF9jdXJzb3IgPSBTZXRDdXJzb3IoTG9hZEN1cnNvcigwLCBJRENfV0FJVCkpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJZW50cnktPmV0eXBlID0gRVRfV0lORE9XUzsKI2VuZGlmCgoJd2hpbGUoZW50cnkpIHsKCQl3aGlsZSgqcyAmJiAqcyE9VEVYVCgnXFwnKSAmJiAqcyE9VEVYVCgnLycpKQoJCQkqZCsrID0gKnMrKzsKCgkJd2hpbGUoKnM9PVRFWFQoJ1xcJykgfHwgKnM9PVRFWFQoJy8nKSkKCQkJcysrOwoKCQkqZCsrID0gVEVYVCgnXFwnKTsKCQkqZCA9IFRFWFQoJ1wwJyk7CgoJCXJlYWRfZGlyZWN0b3J5KGVudHJ5LCBidWZmZXIsIHNvcnRPcmRlciwgaHduZCk7CgoJCWlmIChlbnRyeS0+ZG93bikKCQkJZW50cnktPmV4cGFuZGVkID0gVFJVRTsKCgkJaWYgKCEqcykKCQkJYnJlYWs7CgoJCWVudHJ5ID0gZmluZF9lbnRyeV93aW4oZW50cnksIHMpOwoJfQoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKCglyZXR1cm4gZW50cnk7Cn0KCgojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCgpzdGF0aWMgQk9PTCB0aW1lX3RvX2ZpbGV0aW1lKGNvbnN0IHRpbWVfdCogdCwgRklMRVRJTUUqIGZ0aW1lKQp7CglzdHJ1Y3QgdG0qIHRtID0gZ210aW1lKHQpOwoJU1lTVEVNVElNRSBzdGltZTsKCglpZiAoIXRtKQoJCXJldHVybiBGQUxTRTsKCglzdGltZS53WWVhciA9IHRtLT50bV95ZWFyKzE5MDA7CglzdGltZS53TW9udGggPSB0bS0+dG1fbW9uKzE7CgkvKglzdGltZS53RGF5T2ZXZWVrICovCglzdGltZS53RGF5ID0gdG0tPnRtX21kYXk7CglzdGltZS53SG91ciA9IHRtLT50bV9ob3VyOwoJc3RpbWUud01pbnV0ZSA9IHRtLT50bV9taW47CglzdGltZS53U2Vjb25kID0gdG0tPnRtX3NlYzsKCglyZXR1cm4gU3lzdGVtVGltZVRvRmlsZVRpbWUoJnN0aW1lLCBmdGltZSk7Cn0KCnN0YXRpYyB2b2lkIHJlYWRfZGlyZWN0b3J5X3VuaXgoRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoKQp7CglFbnRyeSogZmlyc3RfZW50cnkgPSBOVUxMOwoJRW50cnkqIGxhc3QgPSBOVUxMOwoJRW50cnkqIGVudHJ5OwoKCWludCBsZXZlbCA9IGRpci0+bGV2ZWwgKyAxOwoKCURJUiogcGRpciA9IG9wZW5kaXIocGF0aCk7CgoJaWYgKHBkaXIpIHsKCQlzdHJ1Y3Qgc3RhdCBzdDsKCQlzdHJ1Y3QgZGlyZW50KiBlbnQ7CgkJVENIQVIgYnVmZmVyW01BWF9QQVRIXSwgKnA7CgoJCWZvcihwPWJ1ZmZlcjsgKnBhdGg7ICkKCQkJKnArKyA9ICpwYXRoKys7CgoJCWlmIChwPT1idWZmZXIgfHwgcFstMV0hPScvJykKCQkJKnArKyA9ICcvJzsKCgkJd2hpbGUoKGVudD1yZWFkZGlyKHBkaXIpKSkgewoJCQllbnRyeSA9IGFsbG9jX2VudHJ5KCk7CgoJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJZmlyc3RfZW50cnkgPSBlbnRyeTsKCgkJCWlmIChsYXN0KQoJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJZW50cnktPmV0eXBlID0gRVRfVU5JWDsKCgkJCWxzdHJjcHkoZW50cnktPmRhdGEuY0ZpbGVOYW1lLCBlbnQtPmRfbmFtZSk7CgkJCWVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgPSBlbnQtPmRfbmFtZVswXT09Jy4nPyBGSUxFX0FUVFJJQlVURV9ISURERU46IDA7CgoJCQlzdHJjcHkocCwgZW50LT5kX25hbWUpOwoKCQkJaWYgKCFzdGF0KGJ1ZmZlciwgJnN0KSkgewoJCQkJaWYgKFNfSVNESVIoc3Quc3RfbW9kZSkpCgkJCQkJZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyB8PSBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk7CgoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplTG93ID0gc3Quc3Rfc2l6ZSAmIDB4RkZGRkZGRkY7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVIaWdoID0gc3Quc3Rfc2l6ZSA+PiAzMjsKCgkJCQltZW1zZXQoJmVudHJ5LT5kYXRhLmZ0Q3JlYXRpb25UaW1lLCAwLCBzaXplb2YoRklMRVRJTUUpKTsKCQkJCXRpbWVfdG9fZmlsZXRpbWUoJnN0LnN0X2F0aW1lLCAmZW50cnktPmRhdGEuZnRMYXN0QWNjZXNzVGltZSk7CgkJCQl0aW1lX3RvX2ZpbGV0aW1lKCZzdC5zdF9tdGltZSwgJmVudHJ5LT5kYXRhLmZ0TGFzdFdyaXRlVGltZSk7CgoJCQkJZW50cnktPmJoZmkubkZpbGVJbmRleExvdyA9IGVudC0+ZF9pbm87CgkJCQllbnRyeS0+YmhmaS5uRmlsZUluZGV4SGlnaCA9IDA7CgoJCQkJZW50cnktPmJoZmkubk51bWJlck9mTGlua3MgPSBzdC5zdF9ubGluazsKCgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IFRSVUU7CgkJCX0gZWxzZSB7CgkJCQllbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3cgPSAwOwoJCQkJZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA9IDA7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwoJCQl9CgoJCQllbnRyeS0+ZG93biA9IE5VTEw7CgkJCWVudHJ5LT51cCA9IGRpcjsKCQkJZW50cnktPmV4cGFuZGVkID0gRkFMU0U7CgkJCWVudHJ5LT5zY2FubmVkID0gRkFMU0U7CgkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKCQkJbGFzdCA9IGVudHJ5OwoJCX0KCgkJaWYgKGxhc3QpCgkJCWxhc3QtPm5leHQgPSBOVUxMOwoKCQljbG9zZWRpcihwZGlyKTsKCX0KCglkaXItPmRvd24gPSBmaXJzdF9lbnRyeTsKCWRpci0+c2Nhbm5lZCA9IFRSVUU7Cn0KCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV91bml4KEVudHJ5KiBkaXIsIExQQ1RTVFIgbmFtZSkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCUxQQ1RTVFIgcCA9IG5hbWU7CgkJTFBDVFNUUiBxID0gZW50cnktPmRhdGEuY0ZpbGVOYW1lOwoKCQlkbyB7CgkJCWlmICghKnAgfHwgKnA9PVRFWFQoJy8nKSkKCQkJCXJldHVybiBlbnRyeTsKCQl9IHdoaWxlKCpwKysgPT0gKnErKyk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBFbnRyeSogcmVhZF90cmVlX3VuaXgoUm9vdCogcm9vdCwgTFBDVFNUUiBwYXRoLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJRW50cnkqIGVudHJ5ID0gJnJvb3QtPmVudHJ5OwoJTFBDVFNUUiBzID0gcGF0aDsKCVBUU1RSIGQgPSBidWZmZXI7CgoJSENVUlNPUiBvbGRfY3Vyc29yID0gU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1dBSVQpKTsKCgllbnRyeS0+ZXR5cGUgPSBFVF9VTklYOwoKCXdoaWxlKGVudHJ5KSB7CgkJd2hpbGUoKnMgJiYgKnMhPVRFWFQoJy8nKSkKCQkJKmQrKyA9ICpzKys7CgoJCXdoaWxlKCpzID09IFRFWFQoJy8nKSkKCQkJcysrOwoKCQkqZCsrID0gVEVYVCgnLycpOwoJCSpkID0gVEVYVCgnXDAnKTsKCgkJcmVhZF9kaXJlY3RvcnkoZW50cnksIGJ1ZmZlciwgc29ydE9yZGVyLCBod25kKTsKCgkJaWYgKGVudHJ5LT5kb3duKQoJCQllbnRyeS0+ZXhwYW5kZWQgPSBUUlVFOwoKCQlpZiAoISpzKQoJCQlicmVhazsKCgkJZW50cnkgPSBmaW5kX2VudHJ5X3VuaXgoZW50cnksIHMpOwoJfQoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKCglyZXR1cm4gZW50cnk7Cn0KCiNlbmRpZiAvKiAhZGVmaW5lZChfTk9fRVhURU5TSU9OUykgJiYgZGVmaW5lZChfX1dJTkVfXykgKi8KCgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCiNpZmRlZiBVTklDT0RFCiNkZWZpbmUJdGNzY3B5biBzdHJjcHluCiNkZWZpbmUJZ2V0X3N0cnJldCBnZXRfc3RycmV0VwojZGVmaW5lCXBhdGhfZnJvbV9waWRsIHBhdGhfZnJvbV9waWRsVwojZWxzZQojZGVmaW5lCXRjc2NweW4gd2NzY3B5bgojZGVmaW5lCWdldF9zdHJyZXQgZ2V0X3N0cnJldEEKI2RlZmluZQlwYXRoX2Zyb21fcGlkbCBwYXRoX2Zyb21fcGlkbEEKI2VuZGlmCgoKc3RhdGljIExQU1RSIHN0cmNweW4oTFBTVFIgZGVzdCwgTFBDU1RSIHNvdXJjZSwgc2l6ZV90IGNvdW50KQp7CiBMUENTVFIgczsKIExQU1RSIGQgPSBkZXN0OwoKIGZvcihzPXNvdXJjZTsgY291bnQmJigqZCsrPSpzKyspOyApCiAgY291bnQtLTsKCiByZXR1cm4gZGVzdDsKfQoKc3RhdGljIExQV1NUUiB3Y3NjcHluKExQV1NUUiBkZXN0LCBMUENXU1RSIHNvdXJjZSwgc2l6ZV90IGNvdW50KQp7CiBMUENXU1RSIHM7CiBMUFdTVFIgZCA9IGRlc3Q7CgogZm9yKHM9c291cmNlOyBjb3VudCYmKCpkKys9KnMrKyk7ICkKICBjb3VudC0tOwoKIHJldHVybiBkZXN0Owp9CgoKc3RhdGljIHZvaWQgZ2V0X3N0cnJldEEoU1RSUkVUKiBzdHIsIGNvbnN0IFNISVRFTUlEKiBzaGlpZCwgTFBTVFIgYnVmZmVyLCBpbnQgbGVuKQp7CiBzd2l0Y2goc3RyLT51VHlwZSkgewogIGNhc2UgU1RSUkVUX1dTVFI6CglXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3RyLT5VTklPTl9NRU1CRVIocE9sZVN0ciksIC0xLCBidWZmZXIsIGxlbiwgTlVMTCwgTlVMTCk7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfT0ZGU0VUOgoJc3RyY3B5bihidWZmZXIsIChMUENTVFIpc2hpaWQrc3RyLT5VTklPTl9NRU1CRVIodU9mZnNldCksIGxlbik7CglicmVhazsKCiAgY2FzZSBTVFJSRVRfQ1NUUjoKCXN0cmNweW4oYnVmZmVyLCBzdHItPlVOSU9OX01FTUJFUihjU3RyKSwgbGVuKTsKIH0KfQoKc3RhdGljIHZvaWQgZ2V0X3N0cnJldFcoU1RSUkVUKiBzdHIsIGNvbnN0IFNISVRFTUlEKiBzaGlpZCwgTFBXU1RSIGJ1ZmZlciwgaW50IGxlbikKewogc3dpdGNoKHN0ci0+dVR5cGUpIHsKICBjYXNlIFNUUlJFVF9XU1RSOgoJd2NzY3B5bihidWZmZXIsIHN0ci0+VU5JT05fTUVNQkVSKHBPbGVTdHIpLCBsZW4pOwoJYnJlYWs7CgogIGNhc2UgU1RSUkVUX09GRlNFVDoKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCAoTFBDU1RSKXNoaWlkK3N0ci0+VU5JT05fTUVNQkVSKHVPZmZzZXQpLCAtMSwgYnVmZmVyLCBsZW4pOwoJYnJlYWs7CgogIGNhc2UgU1RSUkVUX0NTVFI6CglNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3RyLT5VTklPTl9NRU1CRVIoY1N0ciksIC0xLCBidWZmZXIsIGxlbik7CiB9Cn0KCgpzdGF0aWMgdm9pZCBmcmVlX3N0cnJldChTVFJSRVQqIHN0cikKewoJaWYgKHN0ci0+dVR5cGUgPT0gU1RSUkVUX1dTVFIpCgkJKCpHbG9iYWxzLmlNYWxsb2MtPmxwVnRibC0+RnJlZSkoR2xvYmFscy5pTWFsbG9jLCBzdHItPlVOSU9OX01FTUJFUihwT2xlU3RyKSk7Cn0KCgpIUkVTVUxUIG5hbWVfZnJvbV9waWRsKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBUU1RSIGJ1ZmZlciwgaW50IGxlbiwgU0hHRE5GIGZsYWdzKQp7CglTVFJSRVQgc3RyOwoKCUhSRVNVTFQgaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5HZXREaXNwbGF5TmFtZU9mKShmb2xkZXIsIHBpZGwsIGZsYWdzLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXQoJnN0ciwgJnBpZGwtPm1raWQsIGJ1ZmZlciwgbGVuKTsKCQlmcmVlX3N0cnJldCgmc3RyKTsKCX0gZWxzZQoJCWJ1ZmZlclswXSA9ICdcMCc7CgoJcmV0dXJuIGhyOwp9CgoKSFJFU1VMVCBwYXRoX2Zyb21fcGlkbEEoSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQSVRFTUlETElTVCBwaWRsLCBMUFNUUiBidWZmZXIsIGludCBsZW4pCnsKCVNUUlJFVCBzdHI7CgoJIC8qIFNIR0ROX0ZPUlBBUlNJTkc6IGdldCBmdWxsIHBhdGggb2YgaWQgbGlzdCAqLwoJSFJFU1VMVCBociA9ICgqZm9sZGVyLT5scFZ0YmwtPkdldERpc3BsYXlOYW1lT2YpKGZvbGRlciwgcGlkbCwgU0hHRE5fRk9SUEFSU0lORywgJnN0cik7CgoJaWYgKFNVQ0NFRURFRChocikpIHsKCQlnZXRfc3RycmV0QSgmc3RyLCAmcGlkbC0+bWtpZCwgYnVmZmVyLCBsZW4pOwoJCWZyZWVfc3RycmV0KCZzdHIpOwoJfSBlbHNlCgkJYnVmZmVyWzBdID0gJ1wwJzsKCglyZXR1cm4gaHI7Cn0KCkhSRVNVTFQgcGF0aF9mcm9tX3BpZGxXKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUElURU1JRExJU1QgcGlkbCwgTFBXU1RSIGJ1ZmZlciwgaW50IGxlbikKewoJU1RSUkVUIHN0cjsKCgkgLyogU0hHRE5fRk9SUEFSU0lORzogZ2V0IGZ1bGwgcGF0aCBvZiBpZCBsaXN0ICovCglIUkVTVUxUIGhyID0gKCpmb2xkZXItPmxwVnRibC0+R2V0RGlzcGxheU5hbWVPZikoZm9sZGVyLCBwaWRsLCBTSEdETl9GT1JQQVJTSU5HLCAmc3RyKTsKCglpZiAoU1VDQ0VFREVEKGhyKSkgewoJCWdldF9zdHJyZXRXKCZzdHIsICZwaWRsLT5ta2lkLCBidWZmZXIsIGxlbik7CgkJZnJlZV9zdHJyZXQoJnN0cik7Cgl9IGVsc2UKCQlidWZmZXJbMF0gPSAnXDAnOwoKCXJldHVybiBocjsKfQoKCiAvKiBjcmVhdGUgYW4gaXRlbSBpZCBsaXN0IGZyb20gYSBmaWxlIHN5c3RlbSBwYXRoICovCgpzdGF0aWMgTFBJVEVNSURMSVNUIGdldF9wYXRoX3BpZGwoTFBUU1RSIHBhdGgsIEhXTkQgaHduZCkKewoJTFBJVEVNSURMSVNUIHBpZGw7CglIUkVTVUxUIGhyOwoJVUxPTkcgbGVuOwoKI2lmZGVmIFVOSUNPREUKCUxQV1NUUiBidWZmZXIgPSBwYXRoOwojZWxzZQoJV0NIQVIgYnVmZmVyW01BWF9QQVRIXTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwYXRoLCAtMSwgYnVmZmVyLCBNQVhfUEFUSCk7CiNlbmRpZgoKCWhyID0gKCpHbG9iYWxzLmlEZXNrdG9wLT5scFZ0YmwtPlBhcnNlRGlzcGxheU5hbWUpKEdsb2JhbHMuaURlc2t0b3AsIGh3bmQsIE5VTEwsIGJ1ZmZlciwgJmxlbiwgJnBpZGwsIE5VTEwpOwoJaWYgKEZBSUxFRChocikpCgkJcmV0dXJuIE5VTEw7CgoJcmV0dXJuIHBpZGw7Cn0KCgogLyogY29udmVydCBhbiBpdGVtIGlkIGxpc3QgZnJvbSByZWxhdGl2ZSB0byBhYnNvbHV0ZSAoPXJlbGF0aXZlIHRvIHRoZSBkZXNrdG9wKSBmb3JtYXQgKi8KCnN0YXRpYyBMUElURU1JRExJU1QgZ2V0X3RvX2Fic29sdXRlX3BpZGwoRW50cnkqIGVudHJ5LCBIV05EIGh3bmQpCnsKCWlmIChlbnRyeS0+dXAgJiYgZW50cnktPnVwLT5ldHlwZT09RVRfU0hFTEwpIHsKCQlJU2hlbGxGb2xkZXIqIGZvbGRlciA9IGVudHJ5LT51cC0+Zm9sZGVyOwoJCVdDSEFSIGJ1ZmZlcltNQVhfUEFUSF07CgoJCUhSRVNVTFQgaHIgPSBwYXRoX2Zyb21fcGlkbFcoZm9sZGVyLCBlbnRyeS0+cGlkbCwgYnVmZmVyLCBNQVhfUEFUSCk7CgoJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCUxQSVRFTUlETElTVCBwaWRsOwoJCQlVTE9ORyBsZW47CgoJCQlociA9ICgqR2xvYmFscy5pRGVza3RvcC0+bHBWdGJsLT5QYXJzZURpc3BsYXlOYW1lKShHbG9iYWxzLmlEZXNrdG9wLCBod25kLCBOVUxMLCBidWZmZXIsICZsZW4sICZwaWRsLCBOVUxMKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKQoJCQkJcmV0dXJuIHBpZGw7CgkJfQoJfSBlbHNlIGlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfV0lORE9XUykgewoJCVRDSEFSIHBhdGhbTUFYX1BBVEhdOwoKCQlnZXRfcGF0aChlbnRyeSwgcGF0aCk7CgoJCXJldHVybiBnZXRfcGF0aF9waWRsKHBhdGgsIGh3bmQpOwoJfSBlbHNlIGlmIChlbnRyeS0+cGlkbCkKCQlyZXR1cm4gSUxDbG9uZShlbnRyeS0+cGlkbCk7CgoJcmV0dXJuIE5VTEw7Cn0KCgpISUNPTiBleHRyYWN0X2ljb24oSVNoZWxsRm9sZGVyKiBmb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCkKewoJSUV4dHJhY3RJY29uKiBwRXh0cmFjdDsKCglpZiAoU1VDQ0VFREVEKCgqZm9sZGVyLT5scFZ0YmwtPkdldFVJT2JqZWN0T2YpKGZvbGRlciwgMCwgMSwgKExQQ0lURU1JRExJU1QqKSZwaWRsLCAmSUlEX0lFeHRyYWN0SWNvbiwgMCwgKExQVk9JRCopJnBFeHRyYWN0KSkpIHsKCQlUQ0hBUiBwYXRoW19NQVhfUEFUSF07CgkJdW5zaWduZWQgZmxhZ3M7CgkJSElDT04gaGljb247CgkJaW50IGlkeDsKCgkJaWYgKFNVQ0NFRURFRCgoKnBFeHRyYWN0LT5scFZ0YmwtPkdldEljb25Mb2NhdGlvbikocEV4dHJhY3QsIEdJTF9GT1JTSEVMTCwgcGF0aCwgX01BWF9QQVRILCAmaWR4LCAmZmxhZ3MpKSkgewoJCQlpZiAoIShmbGFncyAmIEdJTF9OT1RGSUxFTkFNRSkpIHsKCQkJCWlmIChpZHggPT0gLTEpCgkJCQkJaWR4ID0gMDsJLyogc3BlY2lhbCBjYXNlIGZvciBzb21lIGNvbnRyb2wgcGFuZWwgYXBwbGljYXRpb25zICovCgoJCQkJaWYgKChpbnQpRXh0cmFjdEljb25FeChwYXRoLCBpZHgsIDAsICZoaWNvbiwgMSkgPiAwKQoJCQkJCWZsYWdzICY9IH5HSUxfRE9OVENBQ0hFOwoJCQl9IGVsc2UgewoJCQkJSElDT04gaEljb25MYXJnZSA9IDA7CgoJCQkJSFJFU1VMVCBociA9ICgqcEV4dHJhY3QtPmxwVnRibC0+RXh0cmFjdCkocEV4dHJhY3QsIHBhdGgsIGlkeCwgJmhJY29uTGFyZ2UsICZoaWNvbiwgTUFLRUxPTkcoMC8qR2V0U3lzdGVtTWV0cmljcyhTTV9DWElDT04pKi8sR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTikpKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkKCQkJCQlEZXN0cm95SWNvbihoSWNvbkxhcmdlKTsKCQkJfQoKCQkJcmV0dXJuIGhpY29uOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBFbnRyeSogZmluZF9lbnRyeV9zaGVsbChFbnRyeSogZGlyLCBMUElURU1JRExJU1QgcGlkbCkKewoJRW50cnkqIGVudHJ5OwoKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkgewoJCWlmIChlbnRyeS0+cGlkbC0+bWtpZC5jYiA9PSBwaWRsLT5ta2lkLmNiICYmCgkJCSFtZW1jbXAoZW50cnktPnBpZGwsIHBpZGwsIGVudHJ5LT5waWRsLT5ta2lkLmNiKSkKCQkJcmV0dXJuIGVudHJ5OwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgRW50cnkqIHJlYWRfdHJlZV9zaGVsbChSb290KiByb290LCBMUElURU1JRExJU1QgcGlkbCwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewoJRW50cnkqIGVudHJ5ID0gJnJvb3QtPmVudHJ5OwoJRW50cnkqIG5leHQ7CglMUElURU1JRExJU1QgbmV4dF9waWRsID0gcGlkbDsKCUlTaGVsbEZvbGRlciogZm9sZGVyOwoJSVNoZWxsRm9sZGVyKiBjaGlsZCA9IE5VTEw7CglIUkVTVUxUIGhyOwoKCUhDVVJTT1Igb2xkX2N1cnNvciA9IFNldEN1cnNvcihMb2FkQ3Vyc29yKDAsIElEQ19XQUlUKSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgllbnRyeS0+ZXR5cGUgPSBFVF9TSEVMTDsKI2VuZGlmCgoJZm9sZGVyID0gR2xvYmFscy5pRGVza3RvcDsKCgl3aGlsZShlbnRyeSkgewoJCWVudHJ5LT5waWRsID0gbmV4dF9waWRsOwoJCWVudHJ5LT5mb2xkZXIgPSBmb2xkZXI7CgoJCWlmICghcGlkbC0+bWtpZC5jYikKCQkJYnJlYWs7CgoJCSAvKiBjb3B5IGZpcnN0IGVsZW1lbnQgb2YgaXRlbSBpZGxpc3QgKi8KCQluZXh0X3BpZGwgPSAoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5BbGxvYykoR2xvYmFscy5pTWFsbG9jLCBwaWRsLT5ta2lkLmNiK3NpemVvZihVU0hPUlQpKTsKCQltZW1jcHkobmV4dF9waWRsLCBwaWRsLCBwaWRsLT5ta2lkLmNiKTsKCQkoKExQSVRFTUlETElTVCkoKExQQllURSluZXh0X3BpZGwrcGlkbC0+bWtpZC5jYikpLT5ta2lkLmNiID0gMDsKCgkJaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5CaW5kVG9PYmplY3QpKGZvbGRlciwgbmV4dF9waWRsLCAwLCAmSUlEX0lTaGVsbEZvbGRlciwgKHZvaWQqKikmY2hpbGQpOwoJCWlmICghU1VDQ0VFREVEKGhyKSkKCQkJYnJlYWs7CgoJCXJlYWRfZGlyZWN0b3J5KGVudHJ5LCBOVUxMLCBzb3J0T3JkZXIsIGh3bmQpOwoKCQlpZiAoZW50cnktPmRvd24pCgkJCWVudHJ5LT5leHBhbmRlZCA9IFRSVUU7CgoJCW5leHQgPSBmaW5kX2VudHJ5X3NoZWxsKGVudHJ5LCBuZXh0X3BpZGwpOwoJCWlmICghbmV4dCkKCQkJYnJlYWs7CgoJCWZvbGRlciA9IGNoaWxkOwoJCWVudHJ5ID0gbmV4dDsKCgkJIC8qIGdvIHRvIG5leHQgZWxlbWVudCAqLwoJCXBpZGwgPSAoTFBJVEVNSURMSVNUKSAoKExQQllURSlwaWRsK3BpZGwtPm1raWQuY2IpOwoJfQoKCVNldEN1cnNvcihvbGRfY3Vyc29yKTsKCglyZXR1cm4gZW50cnk7Cn0KCgpzdGF0aWMgdm9pZCBmaWxsX3czMmZkYXRhX3NoZWxsKElTaGVsbEZvbGRlciogZm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGwsIFNGR0FPRiBhdHRyaWJzLCBXSU4zMl9GSU5EX0RBVEEqIHczMmZkYXRhKQp7CglpZiAoIShhdHRyaWJzICYgU0ZHQU9fRklMRVNZU1RFTSkgfHwKCQkgIEZBSUxFRChTSEdldERhdGFGcm9tSURMaXN0KGZvbGRlciwgcGlkbCwgU0hHREZJTF9GSU5EREFUQSwgdzMyZmRhdGEsIHNpemVvZihXSU4zMl9GSU5EX0RBVEEpKSkpIHsKCQlXSU4zMl9GSUxFX0FUVFJJQlVURV9EQVRBIGZhZDsKCQlJRGF0YU9iamVjdCogcERhdGFPYmo7CgoJCVNUR01FRElVTSBtZWRpdW0gPSB7MCwgezB9LCAwfTsKCQlGT1JNQVRFVEMgZm10ID0ge0dsb2JhbHMuY2ZTdHJGTmFtZSwgMCwgRFZBU1BFQ1RfQ09OVEVOVCwgLTEsIFRZTUVEX0hHTE9CQUx9OwoKCQlIUkVTVUxUIGhyID0gKCpmb2xkZXItPmxwVnRibC0+R2V0VUlPYmplY3RPZikoZm9sZGVyLCAwLCAxLCAmcGlkbCwgJklJRF9JRGF0YU9iamVjdCwgMCwgKExQVk9JRCopJnBEYXRhT2JqKTsKCgkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJaHIgPSAoKnBEYXRhT2JqLT5scFZ0YmwtPkdldERhdGEpKHBEYXRhT2JqLCAmZm10LCAmbWVkaXVtKTsKCgkJCSgqcERhdGFPYmotPmxwVnRibC0+UmVsZWFzZSkocERhdGFPYmopOwoKCQkJaWYgKFNVQ0NFRURFRChocikpIHsKCQkJCUxQQ1RTVFIgcGF0aCA9IChMUENUU1RSKUdsb2JhbExvY2sobWVkaXVtLlVOSU9OX01FTUJFUihoR2xvYmFsKSk7CgkJCQlVSU5UIHNlbV9vcmcgPSBTZXRFcnJvck1vZGUoU0VNX0ZBSUxDUklUSUNBTEVSUk9SUyk7CgoJCQkJaWYgKEdldEZpbGVBdHRyaWJ1dGVzRXgocGF0aCwgR2V0RmlsZUV4SW5mb1N0YW5kYXJkLCAmZmFkKSkgewoJCQkJCXczMmZkYXRhLT5kd0ZpbGVBdHRyaWJ1dGVzID0gZmFkLmR3RmlsZUF0dHJpYnV0ZXM7CgkJCQkJdzMyZmRhdGEtPmZ0Q3JlYXRpb25UaW1lID0gZmFkLmZ0Q3JlYXRpb25UaW1lOwoJCQkJCXczMmZkYXRhLT5mdExhc3RBY2Nlc3NUaW1lID0gZmFkLmZ0TGFzdEFjY2Vzc1RpbWU7CgkJCQkJdzMyZmRhdGEtPmZ0TGFzdFdyaXRlVGltZSA9IGZhZC5mdExhc3RXcml0ZVRpbWU7CgoJCQkJCWlmICghKGZhZC5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKSkgewoJCQkJCQl3MzJmZGF0YS0+bkZpbGVTaXplTG93ID0gZmFkLm5GaWxlU2l6ZUxvdzsKCQkJCQkJdzMyZmRhdGEtPm5GaWxlU2l6ZUhpZ2ggPSBmYWQubkZpbGVTaXplSGlnaDsKCQkJCQl9CgkJCQl9CgoJCQkJU2V0RXJyb3JNb2RlKHNlbV9vcmcpOwoKCQkJCUdsb2JhbFVubG9jayhtZWRpdW0uVU5JT05fTUVNQkVSKGhHbG9iYWwpKTsKCQkJCUdsb2JhbEZyZWUobWVkaXVtLlVOSU9OX01FTUJFUihoR2xvYmFsKSk7CgkJCX0KCQl9Cgl9CgoJaWYgKGF0dHJpYnMgJiAoU0ZHQU9fRk9MREVSfFNGR0FPX0hBU1NVQkZPTERFUikpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZOwoKCWlmIChhdHRyaWJzICYgU0ZHQU9fUkVBRE9OTFkpCgkJdzMyZmRhdGEtPmR3RmlsZUF0dHJpYnV0ZXMgfD0gRklMRV9BVFRSSUJVVEVfUkVBRE9OTFk7CgoJaWYgKGF0dHJpYnMgJiBTRkdBT19DT01QUkVTU0VEKQoJCXczMmZkYXRhLT5kd0ZpbGVBdHRyaWJ1dGVzIHw9IEZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQ7Cn0KCgpzdGF0aWMgdm9pZCByZWFkX2RpcmVjdG9yeV9zaGVsbChFbnRyeSogZGlyLCBIV05EIGh3bmQpCnsKCUlTaGVsbEZvbGRlciogZm9sZGVyID0gZGlyLT5mb2xkZXI7CglpbnQgbGV2ZWwgPSBkaXItPmxldmVsICsgMTsKCUhSRVNVTFQgaHI7CgoJSVNoZWxsRm9sZGVyKiBjaGlsZDsKCUlFbnVtSURMaXN0KiBpZGxpc3Q7CgoJRW50cnkqIGZpcnN0X2VudHJ5ID0gTlVMTDsKCUVudHJ5KiBsYXN0ID0gTlVMTDsKCUVudHJ5KiBlbnRyeTsKCglpZiAoIWZvbGRlcikKCQlyZXR1cm47CgoJaHIgPSAoKmZvbGRlci0+bHBWdGJsLT5FbnVtT2JqZWN0cykoZm9sZGVyLCBod25kLCBTSENPTlRGX0ZPTERFUlN8U0hDT05URl9OT05GT0xERVJTfFNIQ09OVEZfSU5DTFVERUhJRERFTnxTSENPTlRGX1NIQVJFQUJMRXxTSENPTlRGX1NUT1JBR0UsICZpZGxpc3QpOwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJZm9yKDs7KSB7CiNkZWZpbmUJRkVUQ0hfSVRFTV9DT1VOVAkzMgoJCQlMUElURU1JRExJU1QgcGlkbHNbRkVUQ0hfSVRFTV9DT1VOVF07CgkJCVNGR0FPRiBhdHRyaWJzOwoJCQlVTE9ORyBjbnQgPSAwOwoJCQlVTE9ORyBuOwoKCQkJbWVtc2V0KHBpZGxzLCAwLCBzaXplb2YocGlkbHMpKTsKCgkJCWhyID0gKCppZGxpc3QtPmxwVnRibC0+TmV4dCkoaWRsaXN0LCBGRVRDSF9JVEVNX0NPVU5ULCBwaWRscywgJmNudCk7CgkJCWlmICghU1VDQ0VFREVEKGhyKSkKCQkJCWJyZWFrOwoKCQkJaWYgKGhyID09IFNfRkFMU0UpCgkJCQlicmVhazsKCgkJCWZvcihuPTA7IG48Y250OyArK24pIHsKCQkJCWVudHJ5ID0gYWxsb2NfZW50cnkoKTsKCgkJCQlpZiAoIWZpcnN0X2VudHJ5KQoJCQkJCWZpcnN0X2VudHJ5ID0gZW50cnk7CgoJCQkJaWYgKGxhc3QpCgkJCQkJbGFzdC0+bmV4dCA9IGVudHJ5OwoKCQkJCW1lbXNldCgmZW50cnktPmRhdGEsIDAsIHNpemVvZihXSU4zMl9GSU5EX0RBVEEpKTsKCQkJCWVudHJ5LT5iaGZpX3ZhbGlkID0gRkFMU0U7CgoJCQkJYXR0cmlicyA9IH5TRkdBT19GSUxFU1lTVEVNOwkvKlNGR0FPX0hBU1NVQkZPTERFUnxTRkdBT19GT0xERVI7IFNGR0FPX0ZJTEVTWVNURU0gc29yZ3QgZGFm/HIsIGRh3yAiTXkgRG9jdW1lbnRzIiBhbnN0YXR0IHZvbiAiTWFydGluJ3MgRG9jdW1lbnRzIiBhbmdlemVpZ3Qgd2lyZCAqLwoKCQkJCWhyID0gKCpmb2xkZXItPmxwVnRibC0+R2V0QXR0cmlidXRlc09mKShmb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmcGlkbHNbbl0sICZhdHRyaWJzKTsKCgkJCQlpZiAoU1VDQ0VFREVEKGhyKSkgewoJCQkJCWlmIChhdHRyaWJzICE9IChTRkdBT0YpflNGR0FPX0ZJTEVTWVNURU0pIHsKCQkJCQkJZmlsbF93MzJmZGF0YV9zaGVsbChmb2xkZXIsIHBpZGxzW25dLCBhdHRyaWJzLCAmZW50cnktPmRhdGEpOwoKCQkJCQkJZW50cnktPmJoZmlfdmFsaWQgPSBUUlVFOwoJCQkJCX0gZWxzZQoJCQkJCQlhdHRyaWJzID0gMDsKCQkJCX0gZWxzZQoJCQkJCWF0dHJpYnMgPSAwOwoKCQkJCWVudHJ5LT5waWRsID0gcGlkbHNbbl07CgoJCQkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCQlociA9ICgqZm9sZGVyLT5scFZ0YmwtPkJpbmRUb09iamVjdCkoZm9sZGVyLCBwaWRsc1tuXSwgMCwgJklJRF9JU2hlbGxGb2xkZXIsICh2b2lkKiopJmNoaWxkKTsKCgkJCQkJaWYgKFNVQ0NFRURFRChocikpCgkJCQkJCWVudHJ5LT5mb2xkZXIgPSBjaGlsZDsKCQkJCQllbHNlCgkJCQkJCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoJCQkJfQoJCQkJZWxzZQoJCQkJCWVudHJ5LT5mb2xkZXIgPSBOVUxMOwoKCQkJCWlmICghZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdKQoJCQkJCS8qaHIgPSAqL25hbWVfZnJvbV9waWRsKGZvbGRlciwgcGlkbHNbbl0sIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgTUFYX1BBVEgsIC8qU0hHRE5fSU5GT0xERVIqLzB4MjAwMC8qMHgyMDAwPVNIR0ROX0lOQ0xVREVfTk9ORklMRVNZUyovKTsKCgkJCQkgLyogZ2V0IGRpc3BsYXkgaWNvbnMgZm9yIGZpbGVzIGFuZCB2aXJ0dWFsIG9iamVjdHMgKi8KCQkJCWlmICghKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHx8CgkJCQkJIShhdHRyaWJzICYgU0ZHQU9fRklMRVNZU1RFTSkpIHsKCQkJCQllbnRyeS0+aGljb24gPSBleHRyYWN0X2ljb24oZm9sZGVyLCBwaWRsc1tuXSk7CgoJCQkJCWlmICghZW50cnktPmhpY29uKQoJCQkJCQllbnRyeS0+aGljb24gPSAoSElDT04pLTE7CS8qIGRvbid0IHRyeSBhZ2FpbiBsYXRlciAqLwoJCQkJfQoKCQkJCWVudHJ5LT5kb3duID0gTlVMTDsKCQkJCWVudHJ5LT51cCA9IGRpcjsKCQkJCWVudHJ5LT5leHBhbmRlZCA9IEZBTFNFOwoJCQkJZW50cnktPnNjYW5uZWQgPSBGQUxTRTsKCQkJCWVudHJ5LT5sZXZlbCA9IGxldmVsOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJZW50cnktPmV0eXBlID0gRVRfU0hFTEw7CgkJCQllbnRyeS0+YmhmaV92YWxpZCA9IEZBTFNFOwojZW5kaWYKCgkJCQlsYXN0ID0gZW50cnk7CgkJCX0KCQl9CgoJCSgqaWRsaXN0LT5scFZ0YmwtPlJlbGVhc2UpKGlkbGlzdCk7Cgl9CgoJaWYgKGxhc3QpCgkJbGFzdC0+bmV4dCA9IE5VTEw7CgoJZGlyLT5kb3duID0gZmlyc3RfZW50cnk7CglkaXItPnNjYW5uZWQgPSBUUlVFOwp9CgojZW5kaWYgLyogX1NIRUxMX0ZPTERFUlMgKi8KCgovKiBzb3J0IG9yZGVyIGZvciBkaWZmZXJlbnQgZGlyZWN0b3J5L2ZpbGUgdHlwZXMgKi8KZW51bSBUWVBFX09SREVSIHsKCVRPX0RJUiA9IDAsCglUT19ET1QgPSAxLAoJVE9fRE9URE9UID0gMiwKCVRPX09USEVSX0RJUiA9IDMsCglUT19GSUxFID0gNAp9OwoKLyogZGlzdGluZ3Vpc2ggYmV0d2VlbiAiLiIsICIuLiIgYW5kIGFueSBvdGhlciBkaXJlY3RvcnkgbmFtZXMgKi8Kc3RhdGljIGludCBUeXBlT3JkZXJGcm9tRGlybmFtZShMUENUU1RSIG5hbWUpCnsKCWlmIChuYW1lWzBdID09ICcuJykgewoJCWlmIChuYW1lWzFdID09ICdcMCcpCgkJCXJldHVybiBUT19ET1Q7CS8qICIuIiAqLwoKCQlpZiAobmFtZVsxXT09Jy4nICYmIG5hbWVbMl09PSdcMCcpCgkJCXJldHVybiBUT19ET1RET1Q7CS8qICIuLiIgKi8KCX0KCglyZXR1cm4gVE9fT1RIRVJfRElSOwkvKiBhbnl0aGluZyBlbHNlICovCn0KCi8qIGRpcmVjdG9yaWVzIGZpcnN0Li4uICovCnN0YXRpYyBpbnQgY29tcGFyZVR5cGUoY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEsIGNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyKQp7CglpbnQgb3JkZXIxID0gZmQxLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CglpbnQgb3JkZXIyID0gZmQyLT5kd0ZpbGVBdHRyaWJ1dGVzICYgRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZPyBUT19ESVI6IFRPX0ZJTEU7CgoJLyogSGFuZGxlICIuIiBhbmQgIi4uIiBhcyBzcGVjaWFsIGNhc2UgYW5kIG1vdmUgdGhlbSBhdCB0aGUgdmVyeSBmaXJzdCBiZWdpbm5pbmcuICovCglpZiAob3JkZXIxPT1UT19ESVIgJiYgb3JkZXIyPT1UT19ESVIpIHsKCQlvcmRlcjEgPSBUeXBlT3JkZXJGcm9tRGlybmFtZShmZDEtPmNGaWxlTmFtZSk7CgkJb3JkZXIyID0gVHlwZU9yZGVyRnJvbURpcm5hbWUoZmQyLT5jRmlsZU5hbWUpOwoJfQoKCXJldHVybiBvcmRlcjI9PW9yZGVyMT8gMDogb3JkZXIxPG9yZGVyMj8gLTE6IDE7Cn0KCgpzdGF0aWMgaW50IGNvbXBhcmVOYW1lKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKGZkMS0+Y0ZpbGVOYW1lLCBmZDItPmNGaWxlTmFtZSk7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZUV4dChjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKQp7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMSA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzEpLT5kYXRhOwoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDIgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcyKS0+ZGF0YTsKCWNvbnN0IFRDSEFSICpuYW1lMSwgKm5hbWUyLCAqZXh0MSwgKmV4dDI7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgluYW1lMSA9IGZkMS0+Y0ZpbGVOYW1lOwoJbmFtZTIgPSBmZDItPmNGaWxlTmFtZTsKCglleHQxID0gX3Rjc3JjaHIobmFtZTEsIFRFWFQoJy4nKSk7CglleHQyID0gX3Rjc3JjaHIobmFtZTIsIFRFWFQoJy4nKSk7CgoJaWYgKGV4dDEpCgkJZXh0MSsrOwoJZWxzZQoJCWV4dDEgPSBzRW1wdHk7CgoJaWYgKGV4dDIpCgkJZXh0MisrOwoJZWxzZQoJCWV4dDIgPSBzRW1wdHk7CgoJY21wID0gbHN0cmNtcGkoZXh0MSwgZXh0Mik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIGxzdHJjbXBpKG5hbWUxLCBuYW1lMik7Cn0KCnN0YXRpYyBpbnQgY29tcGFyZVNpemUoY29uc3Qgdm9pZCogYXJnMSwgY29uc3Qgdm9pZCogYXJnMikKewoJY29uc3QgV0lOMzJfRklORF9EQVRBKiBmZDEgPSAmKCooY29uc3QgRW50cnkqIGNvbnN0KilhcmcxKS0+ZGF0YTsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQyID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMiktPmRhdGE7CgoJaW50IGNtcCA9IGNvbXBhcmVUeXBlKGZkMSwgZmQyKTsKCWlmIChjbXApCgkJcmV0dXJuIGNtcDsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUhpZ2ggLSBmZDEtPm5GaWxlU2l6ZUhpZ2g7CgoJaWYgKGNtcCA8IDApCgkJcmV0dXJuIC0xOwoJZWxzZSBpZiAoY21wID4gMCkKCQlyZXR1cm4gMTsKCgljbXAgPSBmZDItPm5GaWxlU2l6ZUxvdyAtIGZkMS0+bkZpbGVTaXplTG93OwoKCXJldHVybiBjbXA8MD8gLTE6IGNtcD4wPyAxOiAwOwp9CgpzdGF0aWMgaW50IGNvbXBhcmVEYXRlKGNvbnN0IHZvaWQqIGFyZzEsIGNvbnN0IHZvaWQqIGFyZzIpCnsKCWNvbnN0IFdJTjMyX0ZJTkRfREFUQSogZmQxID0gJigqKGNvbnN0IEVudHJ5KiBjb25zdCopYXJnMSktPmRhdGE7Cgljb25zdCBXSU4zMl9GSU5EX0RBVEEqIGZkMiA9ICYoKihjb25zdCBFbnRyeSogY29uc3QqKWFyZzIpLT5kYXRhOwoKCWludCBjbXAgPSBjb21wYXJlVHlwZShmZDEsIGZkMik7CglpZiAoY21wKQoJCXJldHVybiBjbXA7CgoJcmV0dXJuIENvbXBhcmVGaWxlVGltZSgmZmQyLT5mdExhc3RXcml0ZVRpbWUsICZmZDEtPmZ0TGFzdFdyaXRlVGltZSk7Cn0KCgpzdGF0aWMgaW50ICgqc29ydEZ1bmN0aW9uc1tdKShjb25zdCB2b2lkKiBhcmcxLCBjb25zdCB2b2lkKiBhcmcyKSA9IHsKCWNvbXBhcmVOYW1lLAkvKiBTT1JUX05BTUUgKi8KCWNvbXBhcmVFeHQsCQkvKiBTT1JUX0VYVCAqLwoJY29tcGFyZVNpemUsCS8qIFNPUlRfU0laRSAqLwoJY29tcGFyZURhdGUJCS8qIFNPUlRfREFURSAqLwp9OwoKCnN0YXRpYyB2b2lkIFNvcnREaXJlY3RvcnkoRW50cnkqIGRpciwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCUVudHJ5KiBlbnRyeSA9IGRpci0+ZG93bjsKCUVudHJ5KiogYXJyYXksICoqcDsKCWludCBsZW47CgoJbGVuID0gMDsKCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQlsZW4rKzsKCglpZiAobGVuKSB7CgkJYXJyYXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihFbnRyeSopKTsKCgkJcCA9IGFycmF5OwoJCWZvcihlbnRyeT1kaXItPmRvd247IGVudHJ5OyBlbnRyeT1lbnRyeS0+bmV4dCkKCQkJKnArKyA9IGVudHJ5OwoKCQkvKiBjYWxsIHFzb3J0IHdpdGggdGhlIGFwcHJvcHJpYXRlIGNvbXBhcmUgZnVuY3Rpb24gKi8KCQlxc29ydChhcnJheSwgbGVuLCBzaXplb2YoYXJyYXlbMF0pLCBzb3J0RnVuY3Rpb25zW3NvcnRPcmRlcl0pOwoKCQlkaXItPmRvd24gPSBhcnJheVswXTsKCgkJZm9yKHA9YXJyYXk7IC0tbGVuOyBwKyspCgkJCXBbMF0tPm5leHQgPSBwWzFdOwoKCQkoKnApLT5uZXh0ID0gMDsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcnJheSApOwoJfQp9CgoKc3RhdGljIHZvaWQgcmVhZF9kaXJlY3RvcnkoRW50cnkqIGRpciwgTFBDVFNUUiBwYXRoLCBTT1JUX09SREVSIHNvcnRPcmRlciwgSFdORCBod25kKQp7CglUQ0hBUiBidWZmZXJbTUFYX1BBVEhdOwoJRW50cnkqIGVudHJ5OwoJTFBDVFNUUiBzOwoJUFRTVFIgZDsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGRpci0+ZXR5cGUgPT0gRVRfU0hFTEwpCgl7CgkJcmVhZF9kaXJlY3Rvcnlfc2hlbGwoZGlyLCBod25kKTsKCgkJaWYgKEdsb2JhbHMucHJlc2Nhbl9ub2RlKSB7CgkJCXMgPSBwYXRoOwoJCQlkID0gYnVmZmVyOwoKCQkJd2hpbGUoKnMpCgkJCQkqZCsrID0gKnMrKzsKCgkJCSpkKysgPSBURVhUKCdcXCcpOwoKCQkJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCQkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCQlyZWFkX2RpcmVjdG9yeV9zaGVsbChlbnRyeSwgaHduZCk7CgkJCQkJU29ydERpcmVjdG9yeShlbnRyeSwgc29ydE9yZGVyKTsKCQkJCX0KCQl9Cgl9CgllbHNlCiNlbmRpZgojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCglpZiAoZGlyLT5ldHlwZSA9PSBFVF9VTklYKQoJewoJCXJlYWRfZGlyZWN0b3J5X3VuaXgoZGlyLCBwYXRoKTsKCgkJaWYgKEdsb2JhbHMucHJlc2Nhbl9ub2RlKSB7CgkJCXMgPSBwYXRoOwoJCQlkID0gYnVmZmVyOwoKCQkJd2hpbGUoKnMpCgkJCQkqZCsrID0gKnMrKzsKCgkJCSpkKysgPSBURVhUKCcvJyk7CgoJCQlmb3IoZW50cnk9ZGlyLT5kb3duOyBlbnRyeTsgZW50cnk9ZW50cnktPm5leHQpCgkJCQlpZiAoZW50cnktPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQkJCWxzdHJjcHkoZCwgZW50cnktPmRhdGEuY0ZpbGVOYW1lKTsKCQkJCQlyZWFkX2RpcmVjdG9yeV91bml4KGVudHJ5LCBidWZmZXIpOwoJCQkJCVNvcnREaXJlY3RvcnkoZW50cnksIHNvcnRPcmRlcik7CgkJCQl9CgkJfQoJfQoJZWxzZQojZW5kaWYKCXsKCQlyZWFkX2RpcmVjdG9yeV93aW4oZGlyLCBwYXRoKTsKCgkJaWYgKEdsb2JhbHMucHJlc2Nhbl9ub2RlKSB7CgkJCXMgPSBwYXRoOwoJCQlkID0gYnVmZmVyOwoKCQkJd2hpbGUoKnMpCgkJCQkqZCsrID0gKnMrKzsKCgkJCSpkKysgPSBURVhUKCdcXCcpOwoKCQkJZm9yKGVudHJ5PWRpci0+ZG93bjsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KQoJCQkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJCQlsc3RyY3B5KGQsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgkJCQkJcmVhZF9kaXJlY3Rvcnlfd2luKGVudHJ5LCBidWZmZXIpOwoJCQkJCVNvcnREaXJlY3RvcnkoZW50cnksIHNvcnRPcmRlcik7CgkJCQl9CgkJfQoJfQoKCVNvcnREaXJlY3RvcnkoZGlyLCBzb3J0T3JkZXIpOwp9CgoKc3RhdGljIEVudHJ5KiByZWFkX3RyZWUoUm9vdCogcm9vdCwgTFBDVFNUUiBwYXRoLCBMUElURU1JRExJU1QgcGlkbCwgTFBUU1RSIGRydiwgU09SVF9PUkRFUiBzb3J0T3JkZXIsIEhXTkQgaHduZCkKewojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCgljb25zdCBzdGF0aWMgVENIQVIgc1NsYXNoW10gPSB7Jy8nLCAnXDAnfTsKI2VuZGlmCgljb25zdCBzdGF0aWMgVENIQVIgc0JhY2tzbGFzaFtdID0geydcXCcsICdcMCd9OwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAocGlkbCkKCXsKCQkgLyogcmVhZCBzaGVsbCBuYW1lc3BhY2UgdHJlZSAqLwoJCXJvb3QtPmRyaXZlX3R5cGUgPSBEUklWRV9VTktOT1dOOwoJCWRydlswXSA9ICdcXCc7CgkJZHJ2WzFdID0gJ1wwJzsKCQlsb2FkX3N0cmluZyhyb290LT52b2xuYW1lLCBJRFNfREVTS1RPUCk7CgkJcm9vdC0+ZnNfZmxhZ3MgPSAwOwoJCWxvYWRfc3RyaW5nKHJvb3QtPmZzLCBJRFNfU0hFTEwpOwoKCQlyZXR1cm4gcmVhZF90cmVlX3NoZWxsKHJvb3QsIHBpZGwsIHNvcnRPcmRlciwgaHduZCk7Cgl9CgllbHNlCiNlbmRpZgojaWYgIWRlZmluZWQoX05PX0VYVEVOU0lPTlMpICYmIGRlZmluZWQoX19XSU5FX18pCglpZiAoKnBhdGggPT0gJy8nKQoJewoJCSAvKiByZWFkIHVuaXggZmlsZSBzeXN0ZW0gdHJlZSAqLwoJCXJvb3QtPmRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGUocGF0aCk7CgoJCWxzdHJjYXQoZHJ2LCBzU2xhc2gpOwoJCWxvYWRfc3RyaW5nKHJvb3QtPnZvbG5hbWUsIElEU19ST09UX0ZTKTsKCQlyb290LT5mc19mbGFncyA9IDA7CgkJbG9hZF9zdHJpbmcocm9vdC0+ZnMsIElEU19VTklYRlMpOwoKCQlsc3RyY3B5KHJvb3QtPnBhdGgsIHNTbGFzaCk7CgoJCXJldHVybiByZWFkX3RyZWVfdW5peChyb290LCBwYXRoLCBzb3J0T3JkZXIsIGh3bmQpOwoJfQojZW5kaWYKCgkgLyogcmVhZCBXSU4zMiBmaWxlIHN5c3RlbSB0cmVlICovCglyb290LT5kcml2ZV90eXBlID0gR2V0RHJpdmVUeXBlKHBhdGgpOwoKCWxzdHJjYXQoZHJ2LCBzQmFja3NsYXNoKTsKCUdldFZvbHVtZUluZm9ybWF0aW9uKGRydiwgcm9vdC0+dm9sbmFtZSwgX01BWF9GTkFNRSwgMCwgMCwgJnJvb3QtPmZzX2ZsYWdzLCByb290LT5mcywgX01BWF9ESVIpOwoKCWxzdHJjcHkocm9vdC0+cGF0aCwgZHJ2KTsKCglyZXR1cm4gcmVhZF90cmVlX3dpbihyb290LCBwYXRoLCBzb3J0T3JkZXIsIGh3bmQpOwp9CgoKLyogZmxhZ3MgdG8gZmlsdGVyIGRpZmZlcmVudCBmaWxlIHR5cGVzICovCmVudW0gVFlQRV9GSUxURVIgewoJVEZfRElSRUNUT1JJRVMJPSAweDAxLAoJVEZfUFJPR1JBTVMJCT0gMHgwMiwKCVRGX0RPQ1VNRU5UUwk9IDB4MDQsCglURl9PVEhFUlMJCT0gMHgwOCwKCVRGX0hJRERFTgkJPSAweDEwLAoJVEZfQUxMCQkJPSAweDFGCn07CgoKc3RhdGljIENoaWxkV25kKiBhbGxvY19jaGlsZF93aW5kb3coTFBDVFNUUiBwYXRoLCBMUElURU1JRExJU1QgcGlkbCwgSFdORCBod25kKQp7CglUQ0hBUiBkcnZbX01BWF9EUklWRSsxXSwgZGlyW19NQVhfRElSXSwgbmFtZVtfTUFYX0ZOQU1FXSwgZXh0W19NQVhfRVhUXTsKCVRDSEFSIGIxW0JVRkZFUl9MRU5dOwoJY29uc3Qgc3RhdGljIFRDSEFSIHNBc3Rlcmljc1tdID0geycqJywgJ1wwJ307CgoJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgbWFsbG9jKHNpemVvZihDaGlsZFduZCkpOwoJUm9vdCogcm9vdCA9ICZjaGlsZC0+cm9vdDsKCUVudHJ5KiBlbnRyeTsKCgltZW1zZXQoY2hpbGQsIDAsIHNpemVvZihDaGlsZFduZCkpOwoKCWNoaWxkLT5sZWZ0LnRyZWVQYW5lID0gVFJVRTsKCWNoaWxkLT5sZWZ0LnZpc2libGVfY29scyA9IDA7CgoJY2hpbGQtPnJpZ2h0LnRyZWVQYW5lID0gRkFMU0U7CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWNoaWxkLT5yaWdodC52aXNpYmxlX2NvbHMgPSBDT0xfU0laRXxDT0xfREFURXxDT0xfVElNRXxDT0xfQVRUUklCVVRFU3xDT0xfSU5ERVh8Q09MX0xJTktTOwojZWxzZQoJY2hpbGQtPnJpZ2h0LnZpc2libGVfY29scyA9IENPTF9TSVpFfENPTF9EQVRFfENPTF9USU1FfENPTF9BVFRSSUJVVEVTOwojZW5kaWYKCgljaGlsZC0+cG9zLmxlbmd0aCA9IHNpemVvZihXSU5ET1dQTEFDRU1FTlQpOwoJY2hpbGQtPnBvcy5mbGFncyA9IDA7CgljaGlsZC0+cG9zLnNob3dDbWQgPSBTV19TSE9XTk9STUFMOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQgPSBDV19VU0VERUZBVUxUOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcCA9IENXX1VTRURFRkFVTFQ7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQgPSBDV19VU0VERUZBVUxUOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbSA9IENXX1VTRURFRkFVTFQ7CgoJY2hpbGQtPmZvY3VzX3BhbmUgPSAwOwoJY2hpbGQtPnNwbGl0X3BvcyA9IERFRkFVTFRfU1BMSVRfUE9TOwoJY2hpbGQtPnNvcnRPcmRlciA9IFNPUlRfTkFNRTsKCWNoaWxkLT5oZWFkZXJfd2R0aHNfb2sgPSBGQUxTRTsKCglpZiAocGF0aCkKCXsKCQlsc3RyY3B5KGNoaWxkLT5wYXRoLCBwYXRoKTsKCgkJX3RzcGxpdHBhdGgocGF0aCwgZHJ2LCBkaXIsIG5hbWUsIGV4dCk7Cgl9CgoJX3Rjc2NweShjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIHNBc3Rlcmljcyk7CgljaGlsZC0+ZmlsdGVyX2ZsYWdzID0gVEZfQUxMOwoKCXJvb3QtPmVudHJ5LmxldmVsID0gMDsKCgllbnRyeSA9IHJlYWRfdHJlZShyb290LCBwYXRoLCBwaWRsLCBkcnYsIGNoaWxkLT5zb3J0T3JkZXIsIGh3bmQpOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCglpZiAocm9vdC0+ZW50cnkuZXR5cGUgPT0gRVRfU0hFTEwpCgkJbG9hZF9zdHJpbmcocm9vdC0+ZW50cnkuZGF0YS5jRmlsZU5hbWUsIElEU19ERVNLVE9QKTsKCWVsc2UKI2VuZGlmCgkJd3NwcmludGYocm9vdC0+ZW50cnkuZGF0YS5jRmlsZU5hbWUsIFJTKGIxLElEU19USVRMRUZNVCksIGRydiwgcm9vdC0+ZnMpOwoKCXJvb3QtPmVudHJ5LmRhdGEuZHdGaWxlQXR0cmlidXRlcyA9IEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWTsKCgljaGlsZC0+bGVmdC5yb290ID0gJnJvb3QtPmVudHJ5OwoJY2hpbGQtPnJpZ2h0LnJvb3QgPSBOVUxMOwoKCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCAwLCBod25kKTsKCglyZXR1cm4gY2hpbGQ7Cn0KCgovKiBmcmVlIGFsbCBtZW1vcnkgYXNzb2NpYXRlZCB3aXRoIGEgY2hpbGQgd2luZG93ICovCnN0YXRpYyB2b2lkIGZyZWVfY2hpbGRfd2luZG93KENoaWxkV25kKiBjaGlsZCkKewoJZnJlZV9lbnRyaWVzKCZjaGlsZC0+cm9vdC5lbnRyeSk7CglmcmVlKGNoaWxkKTsKfQoKCi8qIGdldCBmdWxsIHBhdGggb2Ygc3BlY2lmaWVkIGRpcmVjdG9yeSBlbnRyeSAqLwpzdGF0aWMgdm9pZCBnZXRfcGF0aChFbnRyeSogZGlyLCBQVFNUUiBwYXRoKQp7CglFbnRyeSogZW50cnk7CglpbnQgbGVuID0gMDsKCWludCBsZXZlbCA9IDA7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCWlmIChkaXItPmV0eXBlID09IEVUX1NIRUxMKQoJewoJCVNGR0FPRiBhdHRyaWJzOwoJCUhSRVNVTFQgaHIgPSBTX09LOwoKCQlwYXRoWzBdID0gVEVYVCgnXDAnKTsKCgkJYXR0cmlicyA9IDA7CgoJCWlmIChkaXItPmZvbGRlcikKCQkJaHIgPSAoKmRpci0+Zm9sZGVyLT5scFZ0YmwtPkdldEF0dHJpYnV0ZXNPZikoZGlyLT5mb2xkZXIsIDEsIChMUENJVEVNSURMSVNUKikmZGlyLT5waWRsLCAmYXR0cmlicyk7CgoJCWlmIChTVUNDRUVERUQoaHIpICYmIChhdHRyaWJzJlNGR0FPX0ZJTEVTWVNURU0pKSB7CgkJCUlTaGVsbEZvbGRlciogcGFyZW50ID0gZGlyLT51cD8gZGlyLT51cC0+Zm9sZGVyOiBHbG9iYWxzLmlEZXNrdG9wOwoKCQkJaHIgPSBwYXRoX2Zyb21fcGlkbChwYXJlbnQsIGRpci0+cGlkbCwgcGF0aCwgTUFYX1BBVEgpOwoJCX0KCX0KCWVsc2UKI2VuZGlmCgl7CgkJZm9yKGVudHJ5PWRpcjsgZW50cnk7IGxldmVsKyspIHsKCQkJTFBDVFNUUiBuYW1lOwoJCQlpbnQgbDsKCgkJCXsKCQkJCUxQQ1RTVFIgczsKCQkJCW5hbWUgPSBlbnRyeS0+ZGF0YS5jRmlsZU5hbWU7CgkJCQlzID0gbmFtZTsKCgkJCQlmb3IobD0wOyAqcyAmJiAqcyE9VEVYVCgnLycpICYmICpzIT1URVhUKCdcXCcpOyBzKyspCgkJCQkJbCsrOwoJCQl9CgoJCQlpZiAoZW50cnktPnVwKSB7CgkJCQlpZiAobCA+IDApIHsKCQkJCQltZW1tb3ZlKHBhdGgrbCsxLCBwYXRoLCBsZW4qc2l6ZW9mKFRDSEFSKSk7CgkJCQkJbWVtY3B5KHBhdGgrMSwgbmFtZSwgbCpzaXplb2YoVENIQVIpKTsKCQkJCQlsZW4gKz0gbCsxOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCQkJcGF0aFswXSA9IFRFWFQoJy8nKTsKCQkJCQllbHNlCiNlbmRpZgoJCQkJCXBhdGhbMF0gPSBURVhUKCdcXCcpOwoJCQkJfQoKCQkJCWVudHJ5ID0gZW50cnktPnVwOwoJCQl9IGVsc2UgewoJCQkJbWVtbW92ZShwYXRoK2wsIHBhdGgsIGxlbipzaXplb2YoVENIQVIpKTsKCQkJCW1lbWNweShwYXRoLCBuYW1lLCBsKnNpemVvZihUQ0hBUikpOwoJCQkJbGVuICs9IGw7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJaWYgKCFsZXZlbCkgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWlmIChlbnRyeS0+ZXR5cGUgPT0gRVRfVU5JWCkKCQkJCXBhdGhbbGVuKytdID0gVEVYVCgnLycpOwoJCQllbHNlCiNlbmRpZgoJCQkJcGF0aFtsZW4rK10gPSBURVhUKCdcXCcpOwoJCX0KCgkJcGF0aFtsZW5dID0gVEVYVCgnXDAnKTsKCX0KfQoKCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZV9yZWN0KEhXTkQgaHduZCwgUFJFQ1QgcHJlY3QpCnsKCWludCBuZXdfdG9wOwoJUkVDVCBydDsKCglpZiAoSXNXaW5kb3dWaXNpYmxlKEdsb2JhbHMuaHRvb2xiYXIpKSB7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5odG9vbGJhciwgV01fU0laRSwgMCwgMCk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmh0b29sYmFyLCAmcnQpOwoJCXByZWN0LT50b3AgPSBydC5ib3R0b20rMzsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbSszOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oZHJpdmViYXIpKSB7CgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFdNX1NJWkUsIDAsIDApOwoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oZHJpdmViYXIsICZydCk7CgkJbmV3X3RvcCA9IC0tcHJlY3QtPnRvcCArIHJ0LmJvdHRvbSszOwoJCU1vdmVXaW5kb3coR2xvYmFscy5oZHJpdmViYXIsIDAsIHByZWN0LT50b3AsIHJ0LnJpZ2h0LCBuZXdfdG9wLCBUUlVFKTsKCQlwcmVjdC0+dG9wID0gbmV3X3RvcDsKCQlwcmVjdC0+Ym90dG9tIC09IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oc3RhdHVzYmFyKSkgewoJCWludCBwYXJ0c1tdID0gezMwMCwgNTAwfTsKCgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oc3RhdHVzYmFyLCBXTV9TSVpFLCAwLCAwKTsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhzdGF0dXNiYXIsIFNCX1NFVFBBUlRTLCAyLCAoTFBBUkFNKSZwYXJ0cyk7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhzdGF0dXNiYXIsICZydCk7CgkJcHJlY3QtPmJvdHRvbSAtPSBydC5ib3R0b207Cgl9CgoJTW92ZVdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsIHByZWN0LT5sZWZ0LTEscHJlY3QtPnRvcC0xLHByZWN0LT5yaWdodCsyLHByZWN0LT5ib3R0b20rMSwgVFJVRSk7Cn0KCnN0YXRpYyB2b2lkIHJlc2l6ZV9mcmFtZShIV05EIGh3bmQsIGludCBjeCwgaW50IGN5KQp7CglSRUNUIHJlY3Q7CgoJcmVjdC5sZWZ0ICAgPSAwOwoJcmVjdC50b3AgICAgPSAwOwoJcmVjdC5yaWdodCAgPSBjeDsKCXJlY3QuYm90dG9tID0gY3k7CgoJcmVzaXplX2ZyYW1lX3JlY3QoaHduZCwgJnJlY3QpOwp9CgpzdGF0aWMgdm9pZCByZXNpemVfZnJhbWVfY2xpZW50KEhXTkQgaHduZCkKewoJUkVDVCByZWN0OwoKCUdldENsaWVudFJlY3QoaHduZCwgJnJlY3QpOwoKCXJlc2l6ZV9mcmFtZV9yZWN0KGh3bmQsICZyZWN0KTsKfQoKCnN0YXRpYyBISE9PSyBoY2J0aG9vazsKc3RhdGljIENoaWxkV25kKiBuZXdjaGlsZCA9IE5VTEw7CgpMUkVTVUxUIENBTExCQUNLIENCVFByb2MoaW50IGNvZGUsIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCWlmIChjb2RlPT1IQ0JUX0NSRUFURVdORCAmJiBuZXdjaGlsZCkgewoJCUNoaWxkV25kKiBjaGlsZCA9IG5ld2NoaWxkOwoJCW5ld2NoaWxkID0gTlVMTDsKCgkJY2hpbGQtPmh3bmQgPSAoSFdORCkgd3BhcmFtOwoJCVNldFdpbmRvd0xvbmcoY2hpbGQtPmh3bmQsIEdXTF9VU0VSREFUQSwgKExQQVJBTSljaGlsZCk7Cgl9CgoJcmV0dXJuIENhbGxOZXh0SG9va0V4KGhjYnRob29rLCBjb2RlLCB3cGFyYW0sIGxwYXJhbSk7Cn0KCnN0YXRpYyBIV05EIGNyZWF0ZV9jaGlsZF93aW5kb3coQ2hpbGRXbmQqIGNoaWxkKQp7CglNRElDUkVBVEVTVFJVQ1QgbWNzOwoJaW50IGlkeDsKCgltY3Muc3pDbGFzcyA9IHNXSU5FRklMRVRSRUU7CgltY3Muc3pUaXRsZSA9IChMUFRTVFIpY2hpbGQtPnBhdGg7CgltY3MuaE93bmVyICA9IEdsb2JhbHMuaEluc3RhbmNlOwoJbWNzLnggICAgICAgPSBjaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ubGVmdDsKCW1jcy55ICAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcDsKCW1jcy5jeCAgICAgID0gY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnJpZ2h0LWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi5sZWZ0OwoJbWNzLmN5ICAgICAgPSBjaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tLWNoaWxkLT5wb3MucmNOb3JtYWxQb3NpdGlvbi50b3A7CgltY3Muc3R5bGUgICA9IDA7CgltY3MubFBhcmFtICA9IDA7CgoJaGNidGhvb2sgPSBTZXRXaW5kb3dzSG9va0V4KFdIX0NCVCwgQ0JUUHJvYywgMCwgR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCW5ld2NoaWxkID0gY2hpbGQ7CgljaGlsZC0+aHduZCA9IChIV05EKSBTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUNSRUFURSwgMCwgKExQQVJBTSkmbWNzKTsKCWlmICghY2hpbGQtPmh3bmQpIHsKCQlVbmhvb2tXaW5kb3dzSG9va0V4KGhjYnRob29rKTsKCQlyZXR1cm4gMDsKCX0KCglVbmhvb2tXaW5kb3dzSG9va0V4KGhjYnRob29rKTsKCglMaXN0Qm94X1NldEl0ZW1IZWlnaHQoY2hpbGQtPmxlZnQuaHduZCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CglMaXN0Qm94X1NldEl0ZW1IZWlnaHQoY2hpbGQtPnJpZ2h0Lmh3bmQsIDEsIG1heChHbG9iYWxzLnNwYWNlU2l6ZS5jeSxJTUFHRV9IRUlHSFQrMykpOwoKCWlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIDAsIGNoaWxkLT5sZWZ0LmN1cik7CglMaXN0Qm94X1NldEN1clNlbChjaGlsZC0+bGVmdC5od25kLCBpZHgpOwoKCXJldHVybiBjaGlsZC0+aHduZDsKfQoKCnN0cnVjdCBFeGVjdXRlRGlhbG9nIHsKCVRDSEFSCWNtZFtNQVhfUEFUSF07CglpbnQJCWNtZHNob3c7Cn07CgpzdGF0aWMgSU5UX1BUUiBDQUxMQkFDSyBFeGVjdXRlRGlhbG9nV25kUHJvZyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJc3RhdGljIHN0cnVjdCBFeGVjdXRlRGlhbG9nKiBkbGc7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCWRsZyA9IChzdHJ1Y3QgRXhlY3V0ZURpYWxvZyopIGxwYXJhbTsKCQkJcmV0dXJuIDE7CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlpbnQgaWQgPSAoaW50KXdwYXJhbTsKCgkJCWlmIChpZCA9PSBJRE9LKSB7CgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgMjAxKSwgZGxnLT5jbWQsIE1BWF9QQVRIKTsKCQkJCWRsZy0+Y21kc2hvdyA9IEJ1dHRvbl9HZXRTdGF0ZShHZXREbGdJdGVtKGh3bmQsMjE0KSkmQlNUX0NIRUNLRUQ/CgkJCQkJCQkJCQkJCVNXX1NIT1dNSU5JTUlaRUQ6IFNXX1NIT1dOT1JNQUw7CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9IGVsc2UgaWYgKGlkID09IElEQ0FOQ0VMKQoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCgkJCXJldHVybiAxO30KCX0KCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIERlc3RpbmF0aW9uRGxnUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJVENIQVIgYjFbQlVGRkVSX0xFTl0sIGIyW0JVRkZFUl9MRU5dOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOgoJCQlTZXRXaW5kb3dMb25nKGh3bmQsIEdXTF9VU0VSREFUQSwgbHBhcmFtKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIChMUENUU1RSKWxwYXJhbSk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goaWQpIHsKCQkJICBjYXNlIElET0s6IHsKCQkJCUxQVFNUUiBkZXN0ID0gKExQVFNUUikgR2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEpOwoJCQkJR2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIDIwMSksIGRlc3QsIE1BWF9QQVRIKTsKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgkJCQlicmVhazt9CgoJCQkgIGNhc2UgSURDQU5DRUw6CgkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQkJYnJlYWs7CgoJCQkgIGNhc2UgMjU0OgoJCQkJTWVzc2FnZUJveChod25kLCBSUyhiMSxJRFNfTk9fSU1QTCksIFJTKGIyLElEU19XSU5FRklMRSksIE1CX09LKTsKCQkJCWJyZWFrOwoJCQl9CgoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdHJ1Y3QgRmlsdGVyRGlhbG9nIHsKCVRDSEFSCXBhdHRlcm5bTUFYX1BBVEhdOwoJaW50CQlmbGFnczsKfTsKCnN0YXRpYyBJTlRfUFRSIENBTExCQUNLIEZpbHRlckRpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgRmlsdGVyRGlhbG9nKiBkbGc7CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0lOSVRESUFMT0c6CgkJCWRsZyA9IChzdHJ1Y3QgRmlsdGVyRGlhbG9nKikgbHBhcmFtOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1ZJRVdfUEFUVEVSTiksIGRsZy0+cGF0dGVybik7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUyksIChkbGctPmZsYWdzJlRGX0RJUkVDVE9SSUVTPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfUFJPR1JBTVMpLCBkbGctPmZsYWdzJlRGX1BST0dSQU1TPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCk7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ET0NVTUVOVFMpLCBkbGctPmZsYWdzJlRGX0RPQ1VNRU5UUz8gQlNUX0NIRUNLRUQ6IEJTVF9VTkNIRUNLRUQpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfT1RIRVJTKSwgZGxnLT5mbGFncyZURl9PVEhFUlM/IEJTVF9DSEVDS0VEOiBCU1RfVU5DSEVDS0VEKTsKCQkJQnV0dG9uX1NldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfVklFV19UWVBFX0hJRERFTiksIGRsZy0+ZmxhZ3MmVEZfSElEREVOPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCk7CgkJCXJldHVybiAxOwoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlpZiAoaWQgPT0gSURPSykgewoJCQkJaW50IGZsYWdzID0gMDsKCgkJCQlHZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1ZJRVdfUEFUVEVSTiksIGRsZy0+cGF0dGVybiwgTUFYX1BBVEgpOwoKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ESVJFQ1RPUklFUykpJkJTVF9DSEVDS0VEPyBURl9ESVJFQ1RPUklFUzogMDsKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9QUk9HUkFNUykpJkJTVF9DSEVDS0VEPyBURl9QUk9HUkFNUzogMDsKCQkJCWZsYWdzIHw9IEJ1dHRvbl9HZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX1ZJRVdfVFlQRV9ET0NVTUVOVFMpKSZCU1RfQ0hFQ0tFRD8gVEZfRE9DVU1FTlRTOiAwOwoJCQkJZmxhZ3MgfD0gQnV0dG9uX0dldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfVklFV19UWVBFX09USEVSUykpJkJTVF9DSEVDS0VEPyBURl9PVEhFUlM6IDA7CgkJCQlmbGFncyB8PSBCdXR0b25fR2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19WSUVXX1RZUEVfSElEREVOKSkmQlNUX0NIRUNLRUQ/IFRGX0hJRERFTjogMDsKCgkJCQlkbGctPmZsYWdzID0gZmxhZ3M7CgoJCQkJRW5kRGlhbG9nKGh3bmQsIGlkKTsKCQkJfSBlbHNlIGlmIChpZCA9PSBJRENBTkNFTCkKCQkJCUVuZERpYWxvZyhod25kLCBpZCk7CgoJCQlyZXR1cm4gMTt9Cgl9CgoJcmV0dXJuIDA7Cn0KCgpzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyB7CglUQ0hBUglwYXRoW01BWF9QQVRIXTsKCUVudHJ5CWVudHJ5OwoJdm9pZCoJcFZlcnNpb25EYXRhOwp9OwoKLyogU3RydWN0dXJlIHVzZWQgdG8gc3RvcmUgZW51bWVyYXRlZCBsYW5ndWFnZXMgYW5kIGNvZGUgcGFnZXMuICovCnN0cnVjdCBMQU5HQU5EQ09ERVBBR0UgewoJV09SRCB3TGFuZ3VhZ2U7CglXT1JEIHdDb2RlUGFnZTsKfSAqbHBUcmFuc2xhdGU7CgpzdGF0aWMgTFBDU1RSIEluZm9TdHJpbmdzW10gPSB7CgkiQ29tbWVudHMiLAoJIkNvbXBhbnlOYW1lIiwKCSJGaWxlRGVzY3JpcHRpb24iLAoJIkZpbGVWZXJzaW9uIiwKCSJJbnRlcm5hbE5hbWUiLAoJIkxlZ2FsQ29weXJpZ2h0IiwKCSJMZWdhbFRyYWRlbWFya3MiLAoJIk9yaWdpbmFsRmlsZW5hbWUiLAoJIlByaXZhdGVCdWlsZCIsCgkiUHJvZHVjdE5hbWUiLAoJIlByb2R1Y3RWZXJzaW9uIiwKCSJTcGVjaWFsQnVpbGQiLAoJTlVMTAp9OwoKc3RhdGljIHZvaWQgUHJvcERsZ19EaXNwbGF5VmFsdWUoSFdORCBobGJveCwgSFdORCBoZWRpdCkKewoJaW50IGlkeCA9IExpc3RCb3hfR2V0Q3VyU2VsKGhsYm94KTsKCglpZiAoaWR4ICE9IExCX0VSUikgewoJCUxQQ1RTVFIgcFZhbHVlID0gKExQQ1RTVFIpIExpc3RCb3hfR2V0SXRlbURhdGEoaGxib3gsIGlkeCk7CgoJCWlmIChwVmFsdWUpCgkJCVNldFdpbmRvd1RleHQoaGVkaXQsIHBWYWx1ZSk7Cgl9Cn0KCnN0YXRpYyB2b2lkIENoZWNrRm9yRmlsZUluZm8oc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqIGRsZywgSFdORCBod25kLCBMUENUU1RSIHN0ckZpbGVuYW1lKQp7CglzdGF0aWMgVENIQVIgc0JhY2tTbGFzaFtdID0geydcXCcsJ1wwJ307CglzdGF0aWMgVENIQVIgc1RyYW5zbGF0aW9uW10gPSB7J1xcJywnVicsJ2EnLCdyJywnRicsJ2knLCdsJywnZScsJ0knLCduJywnZicsJ28nLCdcXCcsJ1QnLCdyJywnYScsJ24nLCdzJywnbCcsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnfTsKCXN0YXRpYyBUQ0hBUiBzU3RyaW5nRmlsZUluZm9bXSA9IHsnXFwnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdGJywnaScsJ2wnLCdlJywnSScsJ24nLCdmJywnbycsJ1xcJywKCQkJCQkJCQkJCSclJywnMCcsJzQnLCd4JywnJScsJzAnLCc0JywneCcsJ1xcJywnJScsJ3MnLCdcMCd9OwoJRFdPUkQgZHdWZXJzaW9uRGF0YUxlbiA9IEdldEZpbGVWZXJzaW9uSW5mb1NpemUoc3RyRmlsZW5hbWUsIE5VTEwpOwoKCWlmIChkd1ZlcnNpb25EYXRhTGVuKSB7CgkJZGxnLT5wVmVyc2lvbkRhdGEgPSBtYWxsb2MoZHdWZXJzaW9uRGF0YUxlbik7CgoJCWlmIChHZXRGaWxlVmVyc2lvbkluZm8oc3RyRmlsZW5hbWUsIDAsIGR3VmVyc2lvbkRhdGFMZW4sIGRsZy0+cFZlcnNpb25EYXRhKSkgewoJCQlMUFZPSUQgcFZhbDsKCQkJVUlOVCBuVmFsTGVuOwoKCQkJaWYgKFZlclF1ZXJ5VmFsdWUoZGxnLT5wVmVyc2lvbkRhdGEsIHNCYWNrU2xhc2gsICZwVmFsLCAmblZhbExlbikpIHsKCQkJCWlmIChuVmFsTGVuID09IHNpemVvZihWU19GSVhFREZJTEVJTkZPKSkgewoJCQkJCVZTX0ZJWEVERklMRUlORk8qIHBGaXhlZEZpbGVJbmZvID0gKFZTX0ZJWEVERklMRUlORk8qKXBWYWw7CgkJCQkJY2hhciBidWZmZXJbQlVGRkVSX0xFTl07CgoJCQkJCXNwcmludGYoYnVmZmVyLCAiJWQuJWQuJWQuJWQiLAoJCQkJCQlISVdPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25NUyksIExPV09SRChwRml4ZWRGaWxlSW5mby0+ZHdGaWxlVmVyc2lvbk1TKSwKCQkJCQkJSElXT1JEKHBGaXhlZEZpbGVJbmZvLT5kd0ZpbGVWZXJzaW9uTFMpLCBMT1dPUkQocEZpeGVkRmlsZUluZm8tPmR3RmlsZVZlcnNpb25MUykpOwoKCQkJCQlTZXREbGdJdGVtVGV4dEEoaHduZCwgSURDX1NUQVRJQ19QUk9QX1ZFUlNJT04sIGJ1ZmZlcik7CgkJCQl9CgkJCX0KCgkJCS8qIFJlYWQgdGhlIGxpc3Qgb2YgbGFuZ3VhZ2VzIGFuZCBjb2RlIHBhZ2VzLiAqLwoJCQlpZiAoVmVyUXVlcnlWYWx1ZShkbGctPnBWZXJzaW9uRGF0YSwgc1RyYW5zbGF0aW9uLCAmcFZhbCwgJm5WYWxMZW4pKSB7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwVHJhbnNsYXRlID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKXBWYWw7CgkJCQlzdHJ1Y3QgTEFOR0FORENPREVQQUdFKiBwRW5kID0gKHN0cnVjdCBMQU5HQU5EQ09ERVBBR0UqKSgoTFBCWVRFKXBWYWwrblZhbExlbik7CgoJCQkJSFdORCBobGJveCA9IEdldERsZ0l0ZW0oaHduZCwgSURDX0xJU1RfUFJPUF9WRVJTSU9OX1RZUEVTKTsKCgkJCQkvKiBSZWFkIHRoZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBlYWNoIGxhbmd1YWdlIGFuZCBjb2RlIHBhZ2UuICovCgkJCQlmb3IoOyBwVHJhbnNsYXRlPHBFbmQ7ICsrcFRyYW5zbGF0ZSkgewoJCQkJCUxQQ1NUUiogcDsKCgkJCQkJZm9yKHA9SW5mb1N0cmluZ3M7ICpwOyArK3ApIHsKCQkJCQkJVENIQVIgc3ViYmxvY2tbMjAwXTsKI2lmZGVmIFVOSUNPREUKCQkJCQkJVENIQVIgaW5mb1N0clsxMDBdOwojZW5kaWYKCQkJCQkJTFBDVFNUUiBwVHh0OwoJCQkJCQlVSU5UIG5WYWxMZW47CgoJCQkJCQlMUENTVFIgcEluZm9TdHJpbmcgPSAqcDsKI2lmZGVmIFVOSUNPREUKCQkJCQkJTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBJbmZvU3RyaW5nLCAtMSwgaW5mb1N0ciwgMTAwKTsKI2Vsc2UKI2RlZmluZQlpbmZvU3RyIHBJbmZvU3RyaW5nCiNlbmRpZgoJCQkJCQl3c3ByaW50ZihzdWJibG9jaywgc1N0cmluZ0ZpbGVJbmZvLCBwVHJhbnNsYXRlLT53TGFuZ3VhZ2UsIHBUcmFuc2xhdGUtPndDb2RlUGFnZSwgaW5mb1N0cik7CgoJCQkJCQkvKiBSZXRyaWV2ZSBmaWxlIGRlc2NyaXB0aW9uIGZvciBsYW5ndWFnZSBhbmQgY29kZSBwYWdlICovCgkJCQkJCWlmIChWZXJRdWVyeVZhbHVlKGRsZy0+cFZlcnNpb25EYXRhLCBzdWJibG9jaywgKFBWT0lEKSZwVHh0LCAmblZhbExlbikpIHsKCQkJCQkJCWludCBpZHggPSBMaXN0Qm94X0FkZFN0cmluZyhobGJveCwgaW5mb1N0cik7CgkJCQkJCQlMaXN0Qm94X1NldEl0ZW1EYXRhKGhsYm94LCBpZHgsIHBUeHQpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCUxpc3RCb3hfU2V0Q3VyU2VsKGhsYm94LCAwKTsKCgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCXN0YXRpYyBzdHJ1Y3QgUHJvcGVydGllc0RpYWxvZyogZGxnOwoKCXN3aXRjaChubXNnKSB7CgkJY2FzZSBXTV9JTklURElBTE9HOiB7CgkJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzQnl0ZUZtdFtdID0geyclJywncycsJyAnLCdCJywneScsJ3QnLCdlJywncycsJ1wwJ307CgkJCVRDSEFSIGIxW0JVRkZFUl9MRU5dLCBiMltCVUZGRVJfTEVOXTsKCQkJTFBXSU4zMl9GSU5EX0RBVEEgcFdGRDsKCQkJVUxPTkdMT05HIHNpemU7CgoJCQlkbGcgPSAoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cqKSBscGFyYW07CgkJCXBXRkQgPSAoTFBXSU4zMl9GSU5EX0RBVEEpICZkbGctPmVudHJ5LmRhdGE7CgoJCQlHZXRXaW5kb3dUZXh0KGh3bmQsIGIxLCBNQVhfUEFUSCk7CgkJCXdzcHJpbnRmKGIyLCBiMSwgcFdGRC0+Y0ZpbGVOYW1lKTsKCQkJU2V0V2luZG93VGV4dChod25kLCBiMik7CgoJCQlmb3JtYXRfZGF0ZSgmcFdGRC0+ZnRMYXN0V3JpdGVUaW1lLCBiMSwgQ09MX0RBVEV8Q09MX1RJTUUpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX0xBU1RDSEFOR0UpLCBiMSk7CgoJCQlzaXplID0gKChVTE9OR0xPTkcpcFdGRC0+bkZpbGVTaXplSGlnaCA8PCAzMikgfCBwV0ZELT5uRmlsZVNpemVMb3c7CgkJCXdzcHJpbnRmKGIxLCBzTG9uZ051bUZtdCwgc2l6ZSk7CgkJCXdzcHJpbnRmKGIyLCBzQnl0ZUZtdCwgYjEpOwoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX1NJWkUpLCBiMik7CgoJCQlTZXRXaW5kb3dUZXh0KEdldERsZ0l0ZW0oaHduZCwgSURDX1NUQVRJQ19QUk9QX0ZJTEVOQU1FKSwgcFdGRC0+Y0ZpbGVOYW1lKTsKCQkJU2V0V2luZG93VGV4dChHZXREbGdJdGVtKGh3bmQsIElEQ19TVEFUSUNfUFJPUF9QQVRIKSwgZGxnLT5wYXRoKTsKCgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX0NIRUNLX1JFQURPTkxZKSwgKHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfUkVBRE9OTFk/IEJTVF9DSEVDS0VEOiBCU1RfVU5DSEVDS0VEKSk7CgkJCUJ1dHRvbl9TZXRDaGVjayhHZXREbGdJdGVtKGh3bmQsSURDX0NIRUNLX0FSQ0hJVkUpLCAocFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9BUkNISVZFPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19DSEVDS19DT01QUkVTU0VEKSwgKHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfQ09NUFJFU1NFRD8gQlNUX0NIRUNLRUQ6IEJTVF9VTkNIRUNLRUQpKTsKCQkJQnV0dG9uX1NldENoZWNrKEdldERsZ0l0ZW0oaHduZCxJRENfQ0hFQ0tfSElEREVOKSwgKHBXRkQtPmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfSElEREVOPyBCU1RfQ0hFQ0tFRDogQlNUX1VOQ0hFQ0tFRCkpOwoJCQlCdXR0b25fU2V0Q2hlY2soR2V0RGxnSXRlbShod25kLElEQ19DSEVDS19TWVNURU0pLCAocFdGRC0+ZHdGaWxlQXR0cmlidXRlcyZGSUxFX0FUVFJJQlVURV9TWVNURU0/IEJTVF9DSEVDS0VEOiBCU1RfVU5DSEVDS0VEKSk7CgoJCQlDaGVja0ZvckZpbGVJbmZvKGRsZywgaHduZCwgZGxnLT5wYXRoKTsKCQkJcmV0dXJuIDE7fQoKCQljYXNlIFdNX0NPTU1BTkQ6IHsKCQkJaW50IGlkID0gKGludCl3cGFyYW07CgoJCQlzd2l0Y2goSElXT1JEKHdwYXJhbSkpIHsKCQkJICBjYXNlIExCTl9TRUxDSEFOR0U6IHsKCQkJCUhXTkQgaGxib3ggPSBHZXREbGdJdGVtKGh3bmQsIElEQ19MSVNUX1BST1BfVkVSU0lPTl9UWVBFUyk7CgkJCQlQcm9wRGxnX0Rpc3BsYXlWYWx1ZShobGJveCwgR2V0RGxnSXRlbShod25kLElEQ19MSVNUX1BST1BfVkVSU0lPTl9WQUxVRVMpKTsKCQkJCWJyZWFrOwoJCQkgIH0KCgkJCSAgY2FzZSBCTl9DTElDS0VEOgoJCQkJaWYgKGlkPT1JRE9LIHx8IGlkPT1JRENBTkNFTCkKCQkJCQlFbmREaWFsb2coaHduZCwgaWQpOwoJCQl9CgoJCQlyZXR1cm4gMTt9CgoJCWNhc2UgV01fTkNERVNUUk9ZOgoJCQlmcmVlKGRsZy0+cFZlcnNpb25EYXRhKTsKCQkJZGxnLT5wVmVyc2lvbkRhdGEgPSBOVUxMOwoJCQlicmVhazsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2hvd19wcm9wZXJ0aWVzX2RsZyhFbnRyeSogZW50cnksIEhXTkQgaHduZCkKewoJc3RydWN0IFByb3BlcnRpZXNEaWFsb2cgZGxnOwoKCW1lbXNldCgmZGxnLCAwLCBzaXplb2Yoc3RydWN0IFByb3BlcnRpZXNEaWFsb2cpKTsKCWdldF9wYXRoKGVudHJ5LCBkbGcucGF0aCk7CgltZW1jcHkoJmRsZy5lbnRyeSwgZW50cnksIHNpemVvZihFbnRyeSkpOwoKCURpYWxvZ0JveFBhcmFtKEdsb2JhbHMuaEluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSUREX0RJQUxPR19QUk9QRVJUSUVTKSwgaHduZCwgUHJvcGVydGllc0RpYWxvZ0RsZ1Byb2MsIChMUEFSQU0pJmRsZyk7Cn0KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgc3RydWN0IEZ1bGxTY3JlZW5QYXJhbWV0ZXJzIHsKCUJPT0wJbW9kZTsKCVJFQ1QJb3JnUG9zOwoJQk9PTAl3YXNab29tZWQ7Cn0gZ19mdWxsc2NyZWVuID0gewogICAgRkFMU0UsCS8qIG1vZGUgKi8KCXswLCAwLCAwLCAwfSwKCUZBTFNFCn07Cgp2b2lkIGZyYW1lX2dldF9jbGllbnRzcGFjZShIV05EIGh3bmQsIFBSRUNUIHByZWN0KQp7CglSRUNUIHJ0OwoKCWlmICghSXNJY29uaWMoaHduZCkpCgkJR2V0Q2xpZW50UmVjdChod25kLCBwcmVjdCk7CgllbHNlIHsKCQlXSU5ET1dQTEFDRU1FTlQgd3A7CgoJCUdldFdpbmRvd1BsYWNlbWVudChod25kLCAmd3ApOwoKCQlwcmVjdC0+bGVmdCA9IHByZWN0LT50b3AgPSAwOwoJCXByZWN0LT5yaWdodCA9IHdwLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQtd3AucmNOb3JtYWxQb3NpdGlvbi5sZWZ0LQoJCQkJCQkyKihHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRUZSQU1FKStHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSkpOwoJCXByZWN0LT5ib3R0b20gPSB3cC5yY05vcm1hbFBvc2l0aW9uLmJvdHRvbS13cC5yY05vcm1hbFBvc2l0aW9uLnRvcC0KCQkJCQkJMiooR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkVGUkFNRSkrR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpKS0KCQkJCQkJR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VU0laRSk7Cgl9CgoJaWYgKElzV2luZG93VmlzaWJsZShHbG9iYWxzLmh0b29sYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5odG9vbGJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oZHJpdmViYXIpKSB7CgkJR2V0Q2xpZW50UmVjdChHbG9iYWxzLmhkcml2ZWJhciwgJnJ0KTsKCQlwcmVjdC0+dG9wICs9IHJ0LmJvdHRvbSsyOwoJfQoKCWlmIChJc1dpbmRvd1Zpc2libGUoR2xvYmFscy5oc3RhdHVzYmFyKSkgewoJCUdldENsaWVudFJlY3QoR2xvYmFscy5oc3RhdHVzYmFyLCAmcnQpOwoJCXByZWN0LT5ib3R0b20gLT0gcnQuYm90dG9tOwoJfQp9CgpzdGF0aWMgQk9PTCB0b2dnbGVfZnVsbHNjcmVlbihIV05EIGh3bmQpCnsKCVJFQ1QgcnQ7CgoJaWYgKChnX2Z1bGxzY3JlZW4ubW9kZT0hZ19mdWxsc2NyZWVuLm1vZGUpKSB7CgkJR2V0V2luZG93UmVjdChod25kLCAmZ19mdWxsc2NyZWVuLm9yZ1Bvcyk7CgkJZ19mdWxsc2NyZWVuLndhc1pvb21lZCA9IElzWm9vbWVkKGh3bmQpOwoKCQlGcmFtZV9DYWxjRnJhbWVDbGllbnQoaHduZCwgJnJ0KTsKCQlDbGllbnRUb1NjcmVlbihod25kLCAoTFBQT0lOVCkmcnQubGVmdCk7CgkJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCgkJcnQubGVmdCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MubGVmdC1ydC5sZWZ0OwoJCXJ0LnRvcCA9IGdfZnVsbHNjcmVlbi5vcmdQb3MudG9wLXJ0LnRvcDsKCQlydC5yaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pK2dfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtcnQucmlnaHQ7CgkJcnQuYm90dG9tID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikrZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tcnQuYm90dG9tOwoKCQlNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cgl9IGVsc2UgewoJCU1vdmVXaW5kb3coaHduZCwgZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LCBnX2Z1bGxzY3JlZW4ub3JnUG9zLnRvcCwKCQkJCQkJCWdfZnVsbHNjcmVlbi5vcmdQb3MucmlnaHQtZ19mdWxsc2NyZWVuLm9yZ1Bvcy5sZWZ0LAoJCQkJCQkJZ19mdWxsc2NyZWVuLm9yZ1Bvcy5ib3R0b20tZ19mdWxsc2NyZWVuLm9yZ1Bvcy50b3AsIFRSVUUpOwoKCQlpZiAoZ19mdWxsc2NyZWVuLndhc1pvb21lZCkKCQkJU2hvd1dpbmRvdyhod25kLCBXU19NQVhJTUlaRSk7Cgl9CgoJcmV0dXJuIGdfZnVsbHNjcmVlbi5tb2RlOwp9CgpzdGF0aWMgdm9pZCBmdWxsc2NyZWVuX21vdmUoSFdORCBod25kKQp7CglSRUNUIHJ0LCBwb3M7CglHZXRXaW5kb3dSZWN0KGh3bmQsICZwb3MpOwoKCUZyYW1lX0NhbGNGcmFtZUNsaWVudChod25kLCAmcnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LmxlZnQpOwoJQ2xpZW50VG9TY3JlZW4oaHduZCwgKExQUE9JTlQpJnJ0LnJpZ2h0KTsKCglydC5sZWZ0ID0gcG9zLmxlZnQtcnQubGVmdDsKCXJ0LnRvcCA9IHBvcy50b3AtcnQudG9wOwoJcnQucmlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKStwb3MucmlnaHQtcnQucmlnaHQ7CglydC5ib3R0b20gPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKStwb3MuYm90dG9tLXJ0LmJvdHRvbTsKCglNb3ZlV2luZG93KGh3bmQsIHJ0LmxlZnQsIHJ0LnRvcCwgcnQucmlnaHQtcnQubGVmdCwgcnQuYm90dG9tLXJ0LnRvcCwgVFJVRSk7Cn0KCiNlbmRpZgoKCnN0YXRpYyB2b2lkIHRvZ2dsZV9jaGlsZChIV05EIGh3bmQsIFVJTlQgY21kLCBIV05EIGhjaGlsZCkKewoJQk9PTCB2aXMgPSBJc1dpbmRvd1Zpc2libGUoaGNoaWxkKTsKCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBjbWQsIHZpcz9NRl9CWUNPTU1BTkQ6TUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKCVNob3dXaW5kb3coaGNoaWxkLCB2aXM/U1dfSElERTpTV19TSE9XKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCWlmIChnX2Z1bGxzY3JlZW4ubW9kZSkKCQlmdWxsc2NyZWVuX21vdmUoaHduZCk7CiNlbmRpZgoKCXJlc2l6ZV9mcmFtZV9jbGllbnQoaHduZCk7Cn0KCkJPT0wgYWN0aXZhdGVfZHJpdmVfd2luZG93KExQQ1RTVFIgcGF0aCkKewoJVENIQVIgZHJ2MVtfTUFYX0RSSVZFXSwgZHJ2MltfTUFYX0RSSVZFXTsKCUhXTkQgY2hpbGRfd25kOwoKCV90c3BsaXRwYXRoKHBhdGgsIGRydjEsIDAsIDAsIDApOwoKCS8qIHNlYXJjaCBmb3IgYSBhbHJlYWR5IG9wZW4gd2luZG93IGZvciB0aGUgc2FtZSBkcml2ZSAqLwoJZm9yKGNoaWxkX3duZD1HZXROZXh0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkX3duZDsgY2hpbGRfd25kPUdldE5leHRXaW5kb3coY2hpbGRfd25kLCBHV19IV05ETkVYVCkpIHsKCQlDaGlsZFduZCogY2hpbGQgPSAoQ2hpbGRXbmQqKSBHZXRXaW5kb3dMb25nKGNoaWxkX3duZCwgR1dMX1VTRVJEQVRBKTsKCgkJaWYgKGNoaWxkKSB7CgkJCV90c3BsaXRwYXRoKGNoaWxkLT5yb290LnBhdGgsIGRydjIsIDAsIDAsIDApOwoKCQkJaWYgKCFsc3RyY21waShkcnYyLCBkcnYxKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc01pbmltaXplZChjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkJPT0wgYWN0aXZhdGVfZnNfd2luZG93KExQQ1RTVFIgZmlsZXN5cykKewoJSFdORCBjaGlsZF93bmQ7CgoJLyogc2VhcmNoIGZvciBhIGFscmVhZHkgb3BlbiB3aW5kb3cgb2YgdGhlIGdpdmVuIGZpbGUgc3lzdGVtIG5hbWUgKi8KCWZvcihjaGlsZF93bmQ9R2V0TmV4dFdpbmRvdyhHbG9iYWxzLmhtZGljbGllbnQsR1dfQ0hJTEQpOyBjaGlsZF93bmQ7IGNoaWxkX3duZD1HZXROZXh0V2luZG93KGNoaWxkX3duZCwgR1dfSFdORE5FWFQpKSB7CgkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZyhjaGlsZF93bmQsIEdXTF9VU0VSREFUQSk7CgoJCWlmIChjaGlsZCkgewoJCQlpZiAoIWxzdHJjbXBpKGNoaWxkLT5yb290LmZzLCBmaWxlc3lzKSkgewoJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElBQ1RJVkFURSwgKFdQQVJBTSljaGlsZF93bmQsIDApOwoKCQkJCWlmIChJc01pbmltaXplZChjaGlsZF93bmQpKQoJCQkJCVNob3dXaW5kb3coY2hpbGRfd25kLCBTV19TSE9XTk9STUFMKTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkxSRVNVTFQgQ0FMTEJBQ0sgRnJhbWVXbmRQcm9jKEhXTkQgaHduZCwgVUlOVCBubXNnLCBXUEFSQU0gd3BhcmFtLCBMUEFSQU0gbHBhcmFtKQp7CglUQ0hBUiBiMVtCVUZGRVJfTEVOXSwgYjJbQlVGRkVSX0xFTl07CgoJc3dpdGNoKG5tc2cpIHsKCQljYXNlIFdNX0NMT1NFOgoJCQlEZXN0cm95V2luZG93KGh3bmQpOwoKCQkJIC8qIGNsZWFyIGhhbmRsZSB2YXJpYWJsZXMgKi8KCQkJR2xvYmFscy5oTWVudUZyYW1lID0gMDsKCQkJR2xvYmFscy5oTWVudVZpZXcgPSAwOwoJCQlHbG9iYWxzLmhNZW51T3B0aW9ucyA9IDA7CgkJCUdsb2JhbHMuaE1haW5XbmQgPSAwOwoJCQlHbG9iYWxzLmhtZGljbGllbnQgPSAwOwoJCQlHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RFU1RST1k6CgkJCSAvKiBkb24ndCBleGl0IGRlc2t0b3Agd2hlbiBjbG9zaW5nIGZpbGUgbWFuYWdlciB3aW5kb3cgKi8KCQkJaWYgKCFHbG9iYWxzLmh3bmRQYXJlbnQpCgkJCQlQb3N0UXVpdE1lc3NhZ2UoMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0lOSVRNRU5VUE9QVVA6IHsKCQkJSFdORCBod25kQ2xpZW50ID0gKEhXTkQpIFNlbmRNZXNzYWdlKEdsb2JhbHMuaG1kaWNsaWVudCwgV01fTURJR0VUQUNUSVZFLCAwLCAwKTsKCgkJCWlmICghU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fSU5JVE1FTlVQT1BVUCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJcmV0dXJuIDA7CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9DT01NQU5EOiB7CgkJCVVJTlQgY21kID0gTE9XT1JEKHdwYXJhbSk7CgkJCUhXTkQgaHduZENsaWVudCA9IChIV05EKSBTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESUdFVEFDVElWRSwgMCwgMCk7CgoJCQlpZiAoU2VuZE1lc3NhZ2UoaHduZENsaWVudCwgV01fRElTUEFUQ0hfQ09NTUFORCwgd3BhcmFtLCBscGFyYW0pKQoJCQkJYnJlYWs7CgoJCQlpZiAoY21kPj1JRF9EUklWRV9GSVJTVCAmJiBjbWQ8PUlEX0RSSVZFX0ZJUlNUKzB4RkYpIHsKCQkJCVRDSEFSIGRydltfTUFYX0RSSVZFXSwgcGF0aFtNQVhfUEFUSF07CgkJCQlDaGlsZFduZCogY2hpbGQ7CgkJCQlMUENUU1RSIHJvb3QgPSBHbG9iYWxzLmRyaXZlczsKCQkJCWludCBpOwoKCQkJCWZvcihpPWNtZC1JRF9EUklWRV9GSVJTVDsgaS0tOyByb290KyspCgkJCQkJd2hpbGUoKnJvb3QpCgkJCQkJCXJvb3QrKzsKCgkJCQlpZiAoYWN0aXZhdGVfZHJpdmVfd2luZG93KHJvb3QpKQoJCQkJCXJldHVybiAwOwoKCQkJCV90c3BsaXRwYXRoKHJvb3QsIGRydiwgMCwgMCwgMCk7CgoJCQkJaWYgKCFTZXRDdXJyZW50RGlyZWN0b3J5KGRydikpIHsKCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQlyZXR1cm4gMDsKCQkJCX0KCgkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsgLypUT0RPOiBzdG9yZSBsYXN0IGRpcmVjdG9yeSBwZXIgZHJpdmUgKi8KCQkJCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIGh3bmQpOwoKCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJCQkJZnJlZShjaGlsZCk7CgkJCX0gZWxzZSBzd2l0Y2goY21kKSB7CgkJCQljYXNlIElEX0ZJTEVfRVhJVDoKCQkJCQlTZW5kTWVzc2FnZShod25kLCBXTV9DTE9TRSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfUkVGUkVTSDoKCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX0NBU0NBREU6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElDQVNDQURFLCAwLCAwKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1dJTkRPV19USUxFX0hPUlo6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElUSUxFLCBNRElUSUxFX0hPUklaT05UQUwsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX1RJTEVfVkVSVDoKCQkJCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhtZGljbGllbnQsIFdNX01ESVRJTEUsIE1ESVRJTEVfVkVSVElDQUwsIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfV0lORE9XX0FSUkFOR0U6CgkJCQkJU2VuZE1lc3NhZ2UoR2xvYmFscy5obWRpY2xpZW50LCBXTV9NRElJQ09OQVJSQU5HRSwgMCwgMCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9TRUxFQ1RfRk9OVDogewoJCQkJCVRDSEFSIGRsZ19uYW1lW0JVRkZFUl9MRU5dLCBkbGdfaW5mb1tCVUZGRVJfTEVOXTsKCQkJCQlDSE9PU0VGT05UIGNoRm9udDsKCQkJCQlMT0dGT05UIGxGb250OwoKCQkJCQlIREMgaGRjID0gR2V0REMoaHduZCk7CgkJCQkJY2hGb250LmxTdHJ1Y3RTaXplID0gc2l6ZW9mKENIT09TRUZPTlQpOwoJCQkJCWNoRm9udC5od25kT3duZXIgPSBod25kOwoJCQkJCWNoRm9udC5oREMgPSBOVUxMOwoJCQkJCWNoRm9udC5scExvZ0ZvbnQgPSAmbEZvbnQ7CgkJCQkJY2hGb250LkZsYWdzID0gQ0ZfU0NSRUVORk9OVFMgfCBDRl9GT1JDRUZPTlRFWElTVCB8IENGX0xJTUlUU0laRSB8IENGX05PU0NSSVBUU0VMOwoJCQkJCWNoRm9udC5yZ2JDb2xvcnMgPSBSR0IoMCwwLDApOwoJCQkJCWNoRm9udC5sQ3VzdERhdGEgPSAwOwoJCQkJCWNoRm9udC5scGZuSG9vayA9IE5VTEw7CgkJCQkJY2hGb250LmxwVGVtcGxhdGVOYW1lID0gTlVMTDsKCQkJCQljaEZvbnQuaEluc3RhbmNlID0gR2xvYmFscy5oSW5zdGFuY2U7CgkJCQkJY2hGb250Lmxwc3pTdHlsZSA9IE5VTEw7CgkJCQkJY2hGb250Lm5Gb250VHlwZSA9IFNJTVVMQVRFRF9GT05UVFlQRTsKCQkJCQljaEZvbnQublNpemVNaW4gPSAwOwoJCQkJCWNoRm9udC5uU2l6ZU1heCA9IDI0OwoKCQkJCQlpZiAoQ2hvb3NlRm9udCgmY2hGb250KSkgewoJCQkJCQlIV05EIGNoaWxkV25kOwoKCQkJCQkJR2xvYmFscy5oZm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdCgmbEZvbnQpOwoJCQkJCQlTZWxlY3RGb250KGhkYywgR2xvYmFscy5oZm9udCk7CgkJCQkJCUdldFRleHRFeHRlbnRQb2ludDMyKGhkYywgc1NwYWNlLCAxLCAmR2xvYmFscy5zcGFjZVNpemUpOwoKCQkJCQkJLyogY2hhbmdlIGZvbnQgaW4gYWxsIG9wZW4gY2hpbGQgd2luZG93cyAqLwoJCQkJCQlmb3IoY2hpbGRXbmQ9R2V0V2luZG93KEdsb2JhbHMuaG1kaWNsaWVudCxHV19DSElMRCk7IGNoaWxkV25kOyBjaGlsZFduZD1HZXROZXh0V2luZG93KGNoaWxkV25kLEdXX0hXTkRORVhUKSkgewoJCQkJCQkJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZyhjaGlsZFduZCwgR1dMX1VTRVJEQVRBKTsKCQkJCQkJCVNldFdpbmRvd0ZvbnQoY2hpbGQtPmxlZnQuaHduZCwgR2xvYmFscy5oZm9udCwgVFJVRSk7CgkJCQkJCQlTZXRXaW5kb3dGb250KGNoaWxkLT5yaWdodC5od25kLCBHbG9iYWxzLmhmb250LCBUUlVFKTsKCQkJCQkJCUxpc3RCb3hfU2V0SXRlbUhlaWdodChjaGlsZC0+bGVmdC5od25kLCAxLCBtYXgoR2xvYmFscy5zcGFjZVNpemUuY3ksSU1BR0VfSEVJR0hUKzMpKTsKCQkJCQkJCUxpc3RCb3hfU2V0SXRlbUhlaWdodChjaGlsZC0+cmlnaHQuaHduZCwgMSwgbWF4KEdsb2JhbHMuc3BhY2VTaXplLmN5LElNQUdFX0hFSUdIVCszKSk7CgkJCQkJCQlJbnZhbGlkYXRlUmVjdChjaGlsZC0+bGVmdC5od25kLCBOVUxMLCBUUlVFKTsKCQkJCQkJCUludmFsaWRhdGVSZWN0KGNoaWxkLT5yaWdodC5od25kLCBOVUxMLCBUUlVFKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIGlmIChDb21tRGxnRXh0ZW5kZWRFcnJvcigpKSB7CgkJCQkJCUxvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIElEU19GT05UX1NFTF9ETEdfTkFNRSwgZGxnX25hbWUsIEJVRkZFUl9MRU4pOwoJCQkJCQlMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCBJRFNfRk9OVF9TRUxfRVJST1IsIGRsZ19pbmZvLCBCVUZGRVJfTEVOKTsKCQkJCQkJTWVzc2FnZUJveChod25kLCBkbGdfaW5mbywgZGxnX25hbWUsIE1CX09LKTsKCQkJCQl9CgoJCQkJCVJlbGVhc2VEQyhod25kLCBoZGMpOwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWNhc2UgSURfVklFV19UT09MX0JBUjoKCQkJCQl0b2dnbGVfY2hpbGQoaHduZCwgY21kLCBHbG9iYWxzLmh0b29sYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfRFJJVkVfQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaGRyaXZlYmFyKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU1RBVFVTQkFSOgoJCQkJCXRvZ2dsZV9jaGlsZChod25kLCBjbWQsIEdsb2JhbHMuaHN0YXR1c2Jhcik7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9FWEVDVVRFOiB7CgkJCQkJc3RydWN0IEV4ZWN1dGVEaWFsb2cgZGxnOwoKCQkJCQltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBFeGVjdXRlRGlhbG9nKSk7CgoJCQkJCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9FWEVDVVRFKSwgaHduZCwgRXhlY3V0ZURpYWxvZ1duZFByb2csIChMUEFSQU0pJmRsZykgPT0gSURPSykgewoJCQkJCQlISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGUoaHduZCwgTlVMTC8qb3BlcmF0aW9uKi8sIGRsZy5jbWQvKmZpbGUqLywgTlVMTC8qcGFyYW1ldGVycyovLCBOVUxMLypkaXIqLywgZGxnLmNtZHNob3cpOwoKCQkJCQkJaWYgKChpbnQpaGluc3QgPD0gMzIpCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfQ09OTkVDVF9ORVRXT1JLX0RSSVZFOiB7CgkJCQkJRFdPUkQgcmV0ID0gV05ldENvbm5lY3Rpb25EaWFsb2coaHduZCwgUkVTT1VSQ0VUWVBFX0RJU0spOwoJCQkJCWlmIChyZXQgPT0gTk9fRVJST1IpCgkJCQkJCXJlZnJlc2hfZHJpdmVzKCk7CgkJCQkJZWxzZSBpZiAocmV0ICE9IChEV09SRCktMSkgewoJCQkJCQlpZiAocmV0ID09IEVSUk9SX0VYVEVOREVEX0VSUk9SKQoJCQkJCQkJZGlzcGxheV9uZXR3b3JrX2Vycm9yKGh3bmQpOwoJCQkJCQllbHNlCgkJCQkJCQlkaXNwbGF5X2Vycm9yKGh3bmQsIHJldCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX0RJU0NPTk5FQ1RfTkVUV09SS19EUklWRTogewoJCQkJCURXT1JEIHJldCA9IFdOZXREaXNjb25uZWN0RGlhbG9nKGh3bmQsIFJFU09VUkNFVFlQRV9ESVNLKTsKCQkJCQlpZiAocmV0ID09IE5PX0VSUk9SKQoJCQkJCQlyZWZyZXNoX2RyaXZlcygpOwoJCQkJCWVsc2UgaWYgKHJldCAhPSAoRFdPUkQpLTEpIHsKCQkJCQkJaWYgKHJldCA9PSBFUlJPUl9FWFRFTkRFRF9FUlJPUikKCQkJCQkJCWRpc3BsYXlfbmV0d29ya19lcnJvcihod25kKTsKCQkJCQkJZWxzZQoJCQkJCQkJZGlzcGxheV9lcnJvcihod25kLCByZXQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GT1JNQVRfRElTSzogewoJCQkJCVVJTlQgc2VtX29yZyA9IFNldEVycm9yTW9kZSgwKTsgLyogR2V0IHRoZSBjdXJyZW50IEVycm9yIE1vZGUgc2V0dGluZ3MuICovCgkJCQkJU2V0RXJyb3JNb2RlKHNlbV9vcmcgJiB+U0VNX0ZBSUxDUklUSUNBTEVSUk9SUyk7IC8qIEZvcmNlIE8vUyB0byBoYW5kbGUgKi8KCQkJCQlTSEZvcm1hdERyaXZlKGh3bmQsIDAgLyogQTogKi8sIFNIRk1UX0lEX0RFRkFVTFQsIDApOwoJCQkJCVNldEVycm9yTW9kZShzZW1fb3JnKTsgLyogUHV0IGl0IGJhY2sgdGhlIHdheSBpdCB3YXMuICovCgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfSEVMUDoKCQkJCQlXaW5IZWxwKGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIEhFTFBfSU5ERVgsIDApOwoJCQkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJY2FzZSBJRF9WSUVXX0ZVTExTQ1JFRU46CgkJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgY21kLCB0b2dnbGVfZnVsbHNjcmVlbihod25kKT9NRl9DSEVDS0VEOjApOwoJCQkJCWJyZWFrOwoKI2lmZGVmIF9fV0lORV9fCgkJCQljYXNlIElEX0RSSVZFX1VOSVhfRlM6IHsKCQkJCQlUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCQkJCQlDaGlsZFduZCogY2hpbGQ7CgoJCQkJCWlmIChhY3RpdmF0ZV9mc193aW5kb3coUlMoYjEsSURTX1VOSVhGUykpKQoJCQkJCQlicmVhazsKCgkJCQkJZ2V0Y3dkKHBhdGgsIE1BWF9QQVRIKTsKCQkJCQljaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhwYXRoLCBOVUxMLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQojZW5kaWYKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCQljYXNlIElEX0RSSVZFX1NIRUxMX05TOiB7CgkJCQkJVENIQVIgcGF0aFtNQVhfUEFUSF07CgkJCQkJQ2hpbGRXbmQqIGNoaWxkOwoKCQkJCQlpZiAoYWN0aXZhdGVfZnNfd2luZG93KFJTKGIxLElEU19TSEVMTCkpKQoJCQkJCQlicmVhazsKCgkJCQkJR2V0Q3VycmVudERpcmVjdG9yeShNQVhfUEFUSCwgcGF0aCk7CgkJCQkJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLGh3bmQpLCBod25kKTsKCgkJCQkJaWYgKCFjcmVhdGVfY2hpbGRfd2luZG93KGNoaWxkKSkKCQkJCQkJZnJlZShjaGlsZCk7CgkJCQkJYnJlYWs7fQojZW5kaWYKI2VuZGlmCgoJCQkJLypUT0RPOiBUaGVyZSBhcmUgZXZlbiBtb3JlIG1lbnUgaXRlbXMhICovCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCiNpZmRlZiBfX1dJTkVfXwoJCQkJY2FzZSBJRF9MSUNFTlNFOgoJCQkJCVdpbmVMaWNlbnNlKEdsb2JhbHMuaE1haW5XbmQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfTk9fV0FSUkFOVFk6CgkJCQkJV2luZVdhcnJhbnR5KEdsb2JhbHMuaE1haW5XbmQpOwoJCQkJCWJyZWFrOwojZW5kaWYKCgkJCQljYXNlIElEX0FCT1VUX1dJTkU6CgkJCQkJU2hlbGxBYm91dChod25kLCBSUyhiMixJRFNfV0lORSksIFJTKGIxLElEU19XSU5FRklMRSksIDApOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfQUJPVVQ6CS8qSURfQUJPVVRfV0lORTogKi8KCQkJCQlTaGVsbEFib3V0KGh3bmQsIFJTKGIxLElEU19XSU5FRklMRSksIE5VTEwsIDApOwoJCQkJCWJyZWFrOwojZW5kaWYJLyogX05PX0VYVEVOU0lPTlMgKi8KCgkJCQlkZWZhdWx0OgoJCQkJCS8qVE9ETzogaWYgKHdQYXJhbSA+PSBQTV9GSVJTVF9MQU5HVUFHRSAmJiB3UGFyYW0gPD0gUE1fTEFTVF9MQU5HVUFHRSkKCQkJCQkJU1RSSU5HX1NlbGVjdExhbmd1YWdlQnlOdW1iZXIod1BhcmFtIC0gUE1fRklSU1RfTEFOR1VBR0UpOwoJCQkJCWVsc2UgKi9pZiAoKGNtZDxJRFdfRklSU1RfQ0hJTEQgfHwgY21kPj1JRFdfRklSU1RfQ0hJTEQrMHgxMDApICYmCgkJCQkJCShjbWQ8U0NfU0laRSB8fCBjbWQ+U0NfUkVTVE9SRSkpCgkJCQkJCU1lc3NhZ2VCb3goaHduZCwgUlMoYjIsSURTX05PX0lNUEwpLCBSUyhiMSxJRFNfV0lORUZJTEUpLCBNQl9PSyk7CgoJCQkJCXJldHVybiBEZWZGcmFtZVByb2MoaHduZCwgR2xvYmFscy5obWRpY2xpZW50LCBubXNnLCB3cGFyYW0sIGxwYXJhbSk7CgkJCX0KCQkJYnJlYWs7fQoKCQljYXNlIFdNX1NJWkU6CgkJCXJlc2l6ZV9mcmFtZShod25kLCBMT1dPUkQobHBhcmFtKSwgSElXT1JEKGxwYXJhbSkpOwoJCQlicmVhazsJLyogZG8gbm90IHBhc3MgbWVzc2FnZSB0byBEZWZGcmFtZVByb2MgKi8KCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQljYXNlIFdNX0dFVE1JTk1BWElORk86IHsKCQkJTFBNSU5NQVhJTkZPIGxwbW1pID0gKExQTUlOTUFYSU5GTylscGFyYW07CgoJCQlscG1taS0+cHRNYXhUcmFja1NpemUueCA8PD0gMTsvKjIqR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgLyBTTV9DWFZJUlRVQUxTQ1JFRU4gKi8KCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnkgPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pIC8gU01fQ1lWSVJUVUFMU0NSRUVOICovCgkJCWJyZWFrO30KCgkJY2FzZSBGUk1fQ0FMQ19DTElFTlQ6CgkJCWZyYW1lX2dldF9jbGllbnRzcGFjZShod25kLCAoUFJFQ1QpbHBhcmFtKTsKCQkJcmV0dXJuIFRSVUU7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQlkZWZhdWx0OgoJCQlyZXR1cm4gRGVmRnJhbWVQcm9jKGh3bmQsIEdsb2JhbHMuaG1kaWNsaWVudCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoJfQoKCXJldHVybiAwOwp9CgoKc3RhdGljIFRDSEFSIGdfcG9zX25hbWVzW0NPTFVNTlNdWzIwXSA9IHsKCXsnXDAnfQkvKiBzeW1ib2wgKi8KfTsKCnN0YXRpYyBjb25zdCBpbnQgZ19wb3NfYWxpZ25bXSA9IHsKCTAsCglIREZfTEVGVCwJLyogTmFtZSAqLwoJSERGX1JJR0hULAkvKiBTaXplICovCglIREZfTEVGVCwJLyogQ0RhdGUgKi8KI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJSERGX0xFRlQsCS8qIEFEYXRlICovCglIREZfTEVGVCwJLyogTURhdGUgKi8KCUhERl9MRUZULAkvKiBJbmRleCAqLwoJSERGX0NFTlRFUiwJLyogTGlua3MgKi8KI2VuZGlmCglIREZfQ0VOVEVSLAkvKiBBdHRyaWJ1dGVzICovCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCUhERl9MRUZUCS8qIFNlY3VyaXR5ICovCiNlbmRpZgp9OwoKc3RhdGljIHZvaWQgcmVzaXplX3RyZWUoQ2hpbGRXbmQqIGNoaWxkLCBpbnQgY3gsIGludCBjeSkKewoJSERXUCBoZHdwID0gQmVnaW5EZWZlcldpbmRvd1Bvcyg0KTsKCVJFQ1QgcnQ7CgoJcnQubGVmdCAgID0gMDsKCXJ0LnRvcCAgICA9IDA7CglydC5yaWdodCAgPSBjeDsKCXJ0LmJvdHRvbSA9IGN5OwoKCWN4ID0gY2hpbGQtPnNwbGl0X3BvcyArIFNQTElUX1dJRFRILzI7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgl7CgkJV0lORE9XUE9TIHdwOwoJCUhEX0xBWU9VVCBoZGw7CgoJCWhkbC5wcmMgICA9ICZydDsKCQloZGwucHdwb3MgPSAmd3A7CgoJCUhlYWRlcl9MYXlvdXQoY2hpbGQtPmxlZnQuaHduZEhlYWRlciwgJmhkbCk7CgoJCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5sZWZ0Lmh3bmRIZWFkZXIsIHdwLmh3bmRJbnNlcnRBZnRlciwKCQkJCQkJd3AueC0xLCB3cC55LCBjaGlsZC0+c3BsaXRfcG9zLVNQTElUX1dJRFRILzIrMSwgd3AuY3ksIHdwLmZsYWdzKTsKCQlEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+cmlnaHQuaHduZEhlYWRlciwgd3AuaHduZEluc2VydEFmdGVyLAoJCQkJCQlydC5sZWZ0K2N4KzEsIHdwLnksIHdwLmN4LWN4KzIsIHdwLmN5LCB3cC5mbGFncyk7Cgl9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCURlZmVyV2luZG93UG9zKGhkd3AsIGNoaWxkLT5sZWZ0Lmh3bmQsIDAsIHJ0LmxlZnQsIHJ0LnRvcCwgY2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yLXJ0LmxlZnQsIHJ0LmJvdHRvbS1ydC50b3AsIFNXUF9OT1pPUkRFUnxTV1BfTk9BQ1RJVkFURSk7CglEZWZlcldpbmRvd1BvcyhoZHdwLCBjaGlsZC0+cmlnaHQuaHduZCwgMCwgcnQubGVmdCtjeCsxLCBydC50b3AsIHJ0LnJpZ2h0LWN4LCBydC5ib3R0b20tcnQudG9wLCBTV1BfTk9aT1JERVJ8U1dQX05PQUNUSVZBVEUpOwoKCUVuZERlZmVyV2luZG93UG9zKGhkd3ApOwp9CgoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoKc3RhdGljIEhXTkQgY3JlYXRlX2hlYWRlcihIV05EIHBhcmVudCwgUGFuZSogcGFuZSwgaW50IGlkKQp7CglIRF9JVEVNIGhkaTsKCWludCBpZHg7CgoJSFdORCBod25kID0gQ3JlYXRlV2luZG93KFdDX0hFQURFUiwgMCwgV1NfQ0hJTER8V1NfVklTSUJMRXxIRFNfSE9SWi8qVE9ETzogfEhEU19CVVRUT05TICsgc29ydCBvcmRlcnMqLywKCQkJCQkJCQkwLCAwLCAwLCAwLCBwYXJlbnQsIChITUVOVSlpZCwgR2xvYmFscy5oSW5zdGFuY2UsIDApOwoJaWYgKCFod25kKQoJCXJldHVybiAwOwoKCVNldFdpbmRvd0ZvbnQoaHduZCwgR2V0U3RvY2tPYmplY3QoREVGQVVMVF9HVUlfRk9OVCksIEZBTFNFKTsKCgloZGkubWFzayA9IEhESV9URVhUfEhESV9XSURUSHxIRElfRk9STUFUOwoKCWZvcihpZHg9MDsgaWR4PENPTFVNTlM7IGlkeCsrKSB7CgkJaGRpLnBzelRleHQgPSBnX3Bvc19uYW1lc1tpZHhdOwoJCWhkaS5mbXQgPSBIREZfU1RSSU5HIHwgZ19wb3NfYWxpZ25baWR4XTsKCQloZGkuY3h5ID0gcGFuZS0+d2lkdGhzW2lkeF07CgkJSGVhZGVyX0luc2VydEl0ZW0oaHduZCwgaWR4LCAmaGRpKTsKCX0KCglyZXR1cm4gaHduZDsKfQoKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgoKc3RhdGljIHZvaWQgaW5pdF9vdXRwdXQoSFdORCBod25kKQp7Cgljb25zdCBzdGF0aWMgVENIQVIgczEwMDBbXSA9IHsnMScsJzAnLCcwJywnMCcsJ1wwJ307CgoJVENIQVIgYlsxNl07CglIRk9OVCBvbGRfZm9udDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglpZiAoR2V0TnVtYmVyRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIDAsIHMxMDAwLCAwLCBiLCAxNikgPiA0KQoJCUdsb2JhbHMubnVtX3NlcCA9IGJbMV07CgllbHNlCgkJR2xvYmFscy5udW1fc2VwID0gVEVYVCgnLicpOwoKCW9sZF9mb250ID0gU2VsZWN0Rm9udChoZGMsIEdsb2JhbHMuaGZvbnQpOwoJR2V0VGV4dEV4dGVudFBvaW50MzIoaGRjLCBzU3BhY2UsIDEsICZHbG9iYWxzLnNwYWNlU2l6ZSk7CglTZWxlY3RGb250KGhkYywgb2xkX2ZvbnQpOwoJUmVsZWFzZURDKGh3bmQsIGhkYyk7Cn0KCnN0YXRpYyB2b2lkIGRyYXdfaXRlbShQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgRW50cnkqIGVudHJ5LCBpbnQgY2FsY1dpZHRoQ29sKTsKCgovKiBjYWxjdWxhdGUgcHJlZmVycmVkIHdpZHRoIGZvciBhbGwgdmlzaWJsZSBjb2x1bW5zICovCgpzdGF0aWMgQk9PTCBjYWxjX3dpZHRocyhQYW5lKiBwYW5lLCBCT09MIGFueXdheSkKewoJaW50IGNvbCwgeCwgY3gsIHNwYz0zKkdsb2JhbHMuc3BhY2VTaXplLmN4OwoJaW50IGVudHJpZXMgPSBMaXN0Qm94X0dldENvdW50KHBhbmUtPmh3bmQpOwoJaW50IG9yZ1dpZHRoc1tDT0xVTU5TXTsKCWludCBvcmdQb3NpdGlvbnNbQ09MVU1OUysxXTsKCUhGT05UIGhmb250T2xkOwoJSERDIGhkYzsKCWludCBjbnQ7CgoJaWYgKCFhbnl3YXkpIHsKCQltZW1jcHkob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKTsKCQltZW1jcHkob3JnUG9zaXRpb25zLCBwYW5lLT5wb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCX0KCglmb3IoY29sPTA7IGNvbDxDT0xVTU5TOyBjb2wrKykKCQlwYW5lLT53aWR0aHNbY29sXSA9IDA7CgoJaGRjID0gR2V0REMocGFuZS0+aHduZCk7CgloZm9udE9sZCA9IFNlbGVjdEZvbnQoaGRjLCBHbG9iYWxzLmhmb250KTsKCglmb3IoY250PTA7IGNudDxlbnRyaWVzOyBjbnQrKykgewoJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgY250KTsKCgkJRFJBV0lURU1TVFJVQ1QgZGlzOwoKCQlkaXMuQ3RsVHlwZQkJICA9IDA7CgkJZGlzLkN0bElECQkgID0gMDsKCQlkaXMuaXRlbUlECQkgID0gMDsKCQlkaXMuaXRlbUFjdGlvbgkgID0gMDsKCQlkaXMuaXRlbVN0YXRlCSAgPSAwOwoJCWRpcy5od25kSXRlbQkgID0gcGFuZS0+aHduZDsKCQlkaXMuaERDCQkJICA9IGhkYzsKCQlkaXMucmNJdGVtLmxlZnQJICA9IDA7CgkJZGlzLnJjSXRlbS50b3AgICAgPSAwOwoJCWRpcy5yY0l0ZW0ucmlnaHQgID0gMDsKCQlkaXMucmNJdGVtLmJvdHRvbSA9IDA7CgkJLypkaXMuaXRlbURhdGEJICA9IDA7ICovCgoJCWRyYXdfaXRlbShwYW5lLCAmZGlzLCBlbnRyeSwgQ09MVU1OUyk7Cgl9CgoJU2VsZWN0T2JqZWN0KGhkYywgaGZvbnRPbGQpOwoJUmVsZWFzZURDKHBhbmUtPmh3bmQsIGhkYyk7CgoJeCA9IDA7Cglmb3IoY29sPTA7IGNvbDxDT0xVTU5TOyBjb2wrKykgewoJCXBhbmUtPnBvc2l0aW9uc1tjb2xdID0geDsKCQljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCQlpZiAoY3gpIHsKCQkJY3ggKz0gc3BjOwoKCQkJaWYgKGN4IDwgSU1BR0VfV0lEVEgpCgkJCQljeCA9IElNQUdFX1dJRFRIOwoKCQkJcGFuZS0+d2lkdGhzW2NvbF0gPSBjeDsKCQl9CgoJCXggKz0gY3g7Cgl9CgoJcGFuZS0+cG9zaXRpb25zW0NPTFVNTlNdID0geDsKCglMaXN0Qm94X1NldEhvcml6b250YWxFeHRlbnQocGFuZS0+aHduZCwgeCk7CgoJLyogbm8gY2hhbmdlPyAqLwoJaWYgKCFtZW1jbXAob3JnV2lkdGhzLCBwYW5lLT53aWR0aHMsIHNpemVvZihvcmdXaWR0aHMpKSkKCQlyZXR1cm4gRkFMU0U7CgoJLyogZG9uJ3QgbW92ZSwgaWYgb25seSBjb2xsYXBzaW5nIGFuIGVudHJ5ICovCglpZiAoIWFueXdheSAmJiBwYW5lLT53aWR0aHNbMF08b3JnV2lkdGhzWzBdICYmCgkJIW1lbWNtcChvcmdXaWR0aHMrMSwgcGFuZS0+d2lkdGhzKzEsIHNpemVvZihvcmdXaWR0aHMpLXNpemVvZihpbnQpKSkgewoJCXBhbmUtPndpZHRoc1swXSA9IG9yZ1dpZHRoc1swXTsKCQltZW1jcHkocGFuZS0+cG9zaXRpb25zLCBvcmdQb3NpdGlvbnMsIHNpemVvZihvcmdQb3NpdGlvbnMpKTsKCgkJcmV0dXJuIEZBTFNFOwoJfQoKCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoKCXJldHVybiBUUlVFOwp9CgoKLyogY2FsY3VsYXRlIG9uZSBwcmVmZXJyZWQgY29sdW1uIHdpZHRoICovCgpzdGF0aWMgdm9pZCBjYWxjX3NpbmdsZV93aWR0aChQYW5lKiBwYW5lLCBpbnQgY29sKQp7CglIRk9OVCBoZm9udE9sZDsKCWludCB4LCBjeDsKCWludCBlbnRyaWVzID0gTGlzdEJveF9HZXRDb3VudChwYW5lLT5od25kKTsKCWludCBjbnQ7CglIREMgaGRjOwoKCXBhbmUtPndpZHRoc1tjb2xdID0gMDsKCgloZGMgPSBHZXREQyhwYW5lLT5od25kKTsKCWhmb250T2xkID0gU2VsZWN0Rm9udChoZGMsIEdsb2JhbHMuaGZvbnQpOwoKCWZvcihjbnQ9MDsgY250PGVudHJpZXM7IGNudCsrKSB7CgkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBjbnQpOwoJCURSQVdJVEVNU1RSVUNUIGRpczsKCgkJZGlzLkN0bFR5cGUJCSAgPSAwOwoJCWRpcy5DdGxJRAkJICA9IDA7CgkJZGlzLml0ZW1JRAkJICA9IDA7CgkJZGlzLml0ZW1BY3Rpb24JICA9IDA7CgkJZGlzLml0ZW1TdGF0ZQkgID0gMDsKCQlkaXMuaHduZEl0ZW0JICA9IHBhbmUtPmh3bmQ7CgkJZGlzLmhEQwkJCSAgPSBoZGM7CgkJZGlzLnJjSXRlbS5sZWZ0CSAgPSAwOwoJCWRpcy5yY0l0ZW0udG9wICAgID0gMDsKCQlkaXMucmNJdGVtLnJpZ2h0ICA9IDA7CgkJZGlzLnJjSXRlbS5ib3R0b20gPSAwOwoJCS8qZGlzLml0ZW1EYXRhCSAgPSAwOyAqLwoKCQlkcmF3X2l0ZW0ocGFuZSwgJmRpcywgZW50cnksIGNvbCk7Cgl9CgoJU2VsZWN0T2JqZWN0KGhkYywgaGZvbnRPbGQpOwoJUmVsZWFzZURDKHBhbmUtPmh3bmQsIGhkYyk7CgoJY3ggPSBwYW5lLT53aWR0aHNbY29sXTsKCglpZiAoY3gpIHsKCQljeCArPSAzKkdsb2JhbHMuc3BhY2VTaXplLmN4OwoKCQlpZiAoY3ggPCBJTUFHRV9XSURUSCkKCQkJY3ggPSBJTUFHRV9XSURUSDsKCX0KCglwYW5lLT53aWR0aHNbY29sXSA9IGN4OwoKCXggPSBwYW5lLT5wb3NpdGlvbnNbY29sXSArIGN4OwoKCWZvcig7IGNvbDxDT0xVTU5TOyApIHsKCQlwYW5lLT5wb3NpdGlvbnNbKytjb2xdID0geDsKCQl4ICs9IHBhbmUtPndpZHRoc1tjb2xdOwoJfQoKCUxpc3RCb3hfU2V0SG9yaXpvbnRhbEV4dGVudChwYW5lLT5od25kLCB4KTsKfQoKCnN0YXRpYyBCT09MIHBhdHRlcm5fbWF0Y2goTFBDVFNUUiBzdHIsIExQQ1RTVFIgcGF0dGVybikKewoJZm9yKCA7ICpzdHImJipwYXR0ZXJuOyBzdHIrKyxwYXR0ZXJuKyspIHsKCQlpZiAoKnBhdHRlcm4gPT0gJyonKSB7CgkJCWRvIHBhdHRlcm4rKzsKCQkJd2hpbGUoKnBhdHRlcm4gPT0gJyonKTsKCgkJCWlmICghKnBhdHRlcm4pCgkJCQlyZXR1cm4gVFJVRTsKCgkJCWZvcig7ICpzdHI7IHN0cisrKQoJCQkJaWYgKF90b3R1cHBlcigqc3RyKT09X3RvdHVwcGVyKCpwYXR0ZXJuKSAmJiBwYXR0ZXJuX21hdGNoKHN0ciwgcGF0dGVybikpCgkJCQkJcmV0dXJuIFRSVUU7CgoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCWVsc2UgaWYgKF90b3R1cHBlcigqc3RyKSE9X3RvdHVwcGVyKCpwYXR0ZXJuKSAmJiAqcGF0dGVybiE9Jz8nKQoJCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYgKCpzdHIgfHwgKnBhdHRlcm4pCgkJaWYgKCpwYXR0ZXJuIT0nKicgfHwgcGF0dGVyblsxXSE9J1wwJykKCQkJcmV0dXJuIEZBTFNFOwoKCXJldHVybiBUUlVFOwp9CgoKZW51bSBGSUxFX1RZUEUgewoJRlRfT1RIRVIJCT0gMCwKCUZUX0VYRUNVVEFCTEUJPSAxLAoJRlRfRE9DVU1FTlQJCT0gMgp9OwoKc3RhdGljIGVudW0gRklMRV9UWVBFIGdldF9maWxlX3R5cGUoTFBDVFNUUiBmaWxlbmFtZSk7CgoKLyogaW5zZXJ0IGxpc3Rib3ggZW50cmllcyBhZnRlciBpbmRleCBpZHggKi8KCnN0YXRpYyBpbnQgaW5zZXJ0X2VudHJpZXMoUGFuZSogcGFuZSwgRW50cnkqIGRpciwgTFBDVFNUUiBwYXR0ZXJuLCBpbnQgZmlsdGVyX2ZsYWdzLCBpbnQgaWR4KQp7CglFbnRyeSogZW50cnkgPSBkaXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm4gaWR4OwoKCVNob3dXaW5kb3cocGFuZS0+aHduZCwgU1dfSElERSk7CgoJZm9yKDsgZW50cnk7IGVudHJ5PWVudHJ5LT5uZXh0KSB7CiNpZm5kZWYgX0xFRlRfRklMRVMKCQlpZiAocGFuZS0+dHJlZVBhbmUgJiYgIShlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCgkJCWNvbnRpbnVlOwojZW5kaWYKCgkJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQkJLyogZG9uJ3QgZGlzcGxheSBlbnRyaWVzICIuIiBhbmQgIi4uIiBpbiB0aGUgbGVmdCBwYW5lICovCgkJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMF09PVRFWFQoJy4nKSkKCQkJCWlmICgKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnXDAnKSB8fAojZW5kaWYKCQkJCQkoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT1URVhUKCdcMCcpKSkKCQkJCQljb250aW51ZTsKCgkJCS8qIGZpbHRlciBkaXJlY3RvcmllcyBpbiByaWdodCBwYW5lICovCgkJCWlmICghcGFuZS0+dHJlZVBhbmUgJiYgIShmaWx0ZXJfZmxhZ3MmVEZfRElSRUNUT1JJRVMpKQoJCQkJY29udGludWU7CgkJfQoKCQkvKiBmaWx0ZXIgdXNpbmcgdGhlIGZpbGUgbmFtZSBwYXR0ZXJuICovCgkJaWYgKHBhdHRlcm4pCgkJCWlmICghcGF0dGVybl9tYXRjaChlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIHBhdHRlcm4pKQoJCQkJY29udGludWU7CgoJCS8qIGZpbHRlciBzeXN0ZW0gYW5kIGhpZGRlbiBmaWxlcyAqLwoJCWlmICghKGZpbHRlcl9mbGFncyZURl9ISURERU4pICYmIChlbnRyeS0+ZGF0YS5kd0ZpbGVBdHRyaWJ1dGVzJihGSUxFX0FUVFJJQlVURV9ISURERU58RklMRV9BVFRSSUJVVEVfU1lTVEVNKSkpCgkJCWNvbnRpbnVlOwoKCQkvKiBmaWx0ZXIgbG9va2luZyBhdCB0aGUgZmlsZSB0eXBlICovCgkJaWYgKChmaWx0ZXJfZmxhZ3MmKFRGX1BST0dSQU1TfFRGX0RPQ1VNRU5UU3xURl9PVEhFUlMpKSAhPSAoVEZfUFJPR1JBTVN8VEZfRE9DVU1FTlRTfFRGX09USEVSUykpCgkJCXN3aXRjaChnZXRfZmlsZV90eXBlKGVudHJ5LT5kYXRhLmNGaWxlTmFtZSkpIHsKCQkJICBjYXNlIEZUX0VYRUNVVEFCTEU6CgkJCSAgCWlmICghKGZpbHRlcl9mbGFncyAmIFRGX1BST0dSQU1TKSkKCQkJCQljb250aW51ZTsKCQkJCWJyZWFrOwoKCQkJICBjYXNlIEZUX0RPQ1VNRU5UOgoJCQkJaWYgKCEoZmlsdGVyX2ZsYWdzICYgVEZfRE9DVU1FTlRTKSkKCQkJCQljb250aW51ZTsKCQkJCWJyZWFrOwoKCQkJICBkZWZhdWx0OiAvKiBURl9PVEhFUlMgKi8KCQkJCWlmICghKGZpbHRlcl9mbGFncyAmIFRGX09USEVSUykpCgkJCQkJY29udGludWU7CgkJCX0KCgkJaWYgKGlkeCAhPSAtMSkKCQkJaWR4Kys7CgoJCUxpc3RCb3hfSW5zZXJ0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4LCBlbnRyeSk7CgoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeS0+ZXhwYW5kZWQpCgkJCWlkeCA9IGluc2VydF9lbnRyaWVzKHBhbmUsIGVudHJ5LT5kb3duLCBwYXR0ZXJuLCBmaWx0ZXJfZmxhZ3MsIGlkeCk7Cgl9CgoJU2hvd1dpbmRvdyhwYW5lLT5od25kLCBTV19TSE9XKTsKCglyZXR1cm4gaWR4Owp9CgoKc3RhdGljIHZvaWQgZm9ybWF0X2J5dGVzKExQVFNUUiBidWZmZXIsIExPTkdMT05HIGJ5dGVzKQp7Cgljb25zdCBzdGF0aWMgVENIQVIgc0ZtdEdCW10gPSB7JyUnLCAnLicsICcxJywgJ2YnLCAnICcsICdHJywgJ0InLCAnXDAnfTsKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzRm10TUJbXSA9IHsnJScsICcuJywgJzEnLCAnZicsICcgJywgJ00nLCAnQicsICdcMCd9OwoJY29uc3Qgc3RhdGljIFRDSEFSIHNGbXRrQltdID0geyclJywgJy4nLCAnMScsICdmJywgJyAnLCAnaycsICdCJywgJ1wwJ307CgoJZmxvYXQgZkJ5dGVzID0gKGZsb2F0KWJ5dGVzOwoKCWlmIChieXRlcyA+PSAxMDczNzQxODI0KQkvKiAxIEdCICovCgkJX3N0cHJpbnRmKGJ1ZmZlciwgc0ZtdEdCLCBmQnl0ZXMvMTA3Mzc0MTgyNC5mKy41Zik7CgllbHNlIGlmIChieXRlcyA+PSAxMDQ4NTc2KQkvKiAxIE1CICovCgkJX3N0cHJpbnRmKGJ1ZmZlciwgc0ZtdE1CLCBmQnl0ZXMvMTA0ODU3Ni5mKy41Zik7CgllbHNlIGlmIChieXRlcyA+PSAxMDI0KQkJLyogMSBrQiAqLwoJCV9zdHByaW50ZihidWZmZXIsIHNGbXRrQiwgZkJ5dGVzLzEwMjQuZisuNWYpOwoJZWxzZQoJCV9zdHByaW50ZihidWZmZXIsIHNMb25nTnVtRm10LCBieXRlcyk7Cn0KCnN0YXRpYyB2b2lkIHNldF9zcGFjZV9zdGF0dXMoKQp7CglVTEFSR0VfSU5URUdFUiB1bEZyZWVCeXRlc1RvQ2FsbGVyLCB1bFRvdGFsQnl0ZXMsIHVsRnJlZUJ5dGVzOwoJVENIQVIgZm10WzY0XSwgYjFbNjRdLCBiMls2NF0sIGJ1ZmZlcltCVUZGRVJfTEVOXTsKCglpZiAoR2V0RGlza0ZyZWVTcGFjZUV4KE5VTEwsICZ1bEZyZWVCeXRlc1RvQ2FsbGVyLCAmdWxUb3RhbEJ5dGVzLCAmdWxGcmVlQnl0ZXMpKSB7CgkJZm9ybWF0X2J5dGVzKGIxLCB1bEZyZWVCeXRlc1RvQ2FsbGVyLlF1YWRQYXJ0KTsKCQlmb3JtYXRfYnl0ZXMoYjIsIHVsVG90YWxCeXRlcy5RdWFkUGFydCk7CgkJX3N0cHJpbnRmKGJ1ZmZlciwgUlMoZm10LElEU19GUkVFX1NQQUNFX0ZNVCksIGIxLCBiMik7Cgl9IGVsc2UKCQlfdGNzY3B5KGJ1ZmZlciwgc1FNYXJrcyk7CgoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oc3RhdHVzYmFyLCBTQl9TRVRURVhULCAwLCAoTFBBUkFNKWJ1ZmZlcik7Cn0KCgpzdGF0aWMgV05EUFJPQyBnX29yZ1RyZWVXbmRQcm9jOwoKc3RhdGljIHZvaWQgY3JlYXRlX3RyZWVfd2luZG93KEhXTkQgcGFyZW50LCBQYW5lKiBwYW5lLCBpbnQgaWQsIGludCBpZF9oZWFkZXIsIExQQ1RTVFIgcGF0dGVybiwgaW50IGZpbHRlcl9mbGFncykKewoJY29uc3Qgc3RhdGljIFRDSEFSIHNMaXN0Qm94W10gPSB7J0wnLCdpJywncycsJ3QnLCdCJywnbycsJ3gnLCdcMCd9OwoKCXN0YXRpYyBpbnQgc19pbml0ID0gMDsKCUVudHJ5KiBlbnRyeSA9IHBhbmUtPnJvb3Q7CgoJcGFuZS0+aHduZCA9IENyZWF0ZVdpbmRvdyhzTGlzdEJveCwgc0VtcHR5LCBXU19DSElMRHxXU19WSVNJQkxFfFdTX0hTQ1JPTEx8V1NfVlNDUk9MTHwKCQkJCQkJCQlMQlNfRElTQUJMRU5PU0NST0xMfExCU19OT0lOVEVHUkFMSEVJR0hUfExCU19PV05FUkRSQVdGSVhFRHxMQlNfTk9USUZZLAoJCQkJCQkJCTAsIDAsIDAsIDAsIHBhcmVudCwgKEhNRU5VKWlkLCBHbG9iYWxzLmhJbnN0YW5jZSwgMCk7CgoJU2V0V2luZG93TG9uZyhwYW5lLT5od25kLCBHV0xfVVNFUkRBVEEsIChMUEFSQU0pcGFuZSk7CglnX29yZ1RyZWVXbmRQcm9jID0gU3ViY2xhc3NXaW5kb3cocGFuZS0+aHduZCwgVHJlZVduZFByb2MpOwoKCVNldFdpbmRvd0ZvbnQocGFuZS0+aHduZCwgR2xvYmFscy5oZm9udCwgRkFMU0UpOwoKCS8qIGluc2VydCBlbnRyaWVzIGludG8gbGlzdGJveCAqLwoJaWYgKGVudHJ5KQoJCWluc2VydF9lbnRyaWVzKHBhbmUsIGVudHJ5LCBwYXR0ZXJuLCBmaWx0ZXJfZmxhZ3MsIC0xKTsKCgkvKiBjYWxjdWxhdGUgY29sdW1uIHdpZHRocyAqLwoJaWYgKCFzX2luaXQpIHsKCQlzX2luaXQgPSAxOwoJCWluaXRfb3V0cHV0KHBhbmUtPmh3bmQpOwoJfQoKCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJcGFuZS0+aHduZEhlYWRlciA9IGNyZWF0ZV9oZWFkZXIocGFyZW50LCBwYW5lLCBpZF9oZWFkZXIpOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIEluaXRDaGlsZFdpbmRvdyhDaGlsZFduZCogY2hpbGQpCnsKCWNyZWF0ZV90cmVlX3dpbmRvdyhjaGlsZC0+aHduZCwgJmNoaWxkLT5sZWZ0LCBJRFdfVFJFRV9MRUZULCBJRFdfSEVBREVSX0xFRlQsIE5VTEwsIFRGX0FMTCk7CgljcmVhdGVfdHJlZV93aW5kb3coY2hpbGQtPmh3bmQsICZjaGlsZC0+cmlnaHQsIElEV19UUkVFX1JJR0hULCBJRFdfSEVBREVSX1JJR0hULCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4sIGNoaWxkLT5maWx0ZXJfZmxhZ3MpOwp9CgoKc3RhdGljIHZvaWQgZm9ybWF0X2RhdGUoY29uc3QgRklMRVRJTUUqIGZ0LCBUQ0hBUiogYnVmZmVyLCBpbnQgdmlzaWJsZV9jb2xzKQp7CglTWVNURU1USU1FIHN5c3RpbWU7CglGSUxFVElNRSBsZnQ7CglpbnQgbGVuID0gMDsKCgkqYnVmZmVyID0gVEVYVCgnXDAnKTsKCglpZiAoIWZ0LT5kd0xvd0RhdGVUaW1lICYmICFmdC0+ZHdIaWdoRGF0ZVRpbWUpCgkJcmV0dXJuOwoKCWlmICghRmlsZVRpbWVUb0xvY2FsRmlsZVRpbWUoZnQsICZsZnQpKQoJCXtlcnI6IF90Y3NjcHkoYnVmZmVyLHNRTWFya3MpOyByZXR1cm47fQoKCWlmICghRmlsZVRpbWVUb1N5c3RlbVRpbWUoJmxmdCwgJnN5c3RpbWUpKQoJCWdvdG8gZXJyOwoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfREFURSkgewoJCWxlbiA9IEdldERhdGVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgMCwgJnN5c3RpbWUsIDAsIGJ1ZmZlciwgQlVGRkVSX0xFTik7CgkJaWYgKCFsZW4pCgkJCWdvdG8gZXJyOwoJfQoKCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfVElNRSkgewoJCWlmIChsZW4pCgkJCWJ1ZmZlcltsZW4tMV0gPSAnICc7CgoJCWJ1ZmZlcltsZW4rK10gPSAnICc7CgoJCWlmICghR2V0VGltZUZvcm1hdChMT0NBTEVfVVNFUl9ERUZBVUxULCAwLCAmc3lzdGltZSwgMCwgYnVmZmVyK2xlbiwgQlVGRkVSX0xFTi1sZW4pKQoJCQlidWZmZXJbbGVuXSA9IFRFWFQoJ1wwJyk7Cgl9Cn0KCgpzdGF0aWMgdm9pZCBjYWxjX3dpZHRoKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJUkVDVCBydCA9IHswLCAwLCAwLCAwfTsKCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVgpOwoKCWlmIChydC5yaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gcnQucmlnaHQ7Cn0KCnN0YXRpYyB2b2lkIGNhbGNfdGFiYmVkX3dpZHRoKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJUkVDVCBydCA9IHswLCAwLCAwLCAwfTsKCi8qCURSQVdURVhUUEFSQU1TIGR0cCA9IHtzaXplb2YoRFJBV1RFWFRQQVJBTVMpLCAyfTsKCURyYXdUZXh0RXgoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9DQUxDUkVDVHxEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfERUX0VYUEFORFRBQlN8RFRfVEFCU1RPUCwgJmR0cCk7Ki8KCglEcmF3VGV4dChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX0NBTENSRUNUfERUX1NJTkdMRUxJTkV8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QfCgyPDw4KSk7CgkvKkZJWE1FIHJ0ICgwLDApID8/PyAqLwoKCWlmIChydC5yaWdodCA+IHBhbmUtPndpZHRoc1tjb2xdKQoJCXBhbmUtPndpZHRoc1tjb2xdID0gcnQucmlnaHQ7Cn0KCgpzdGF0aWMgdm9pZCBvdXRwdXRfdGV4dChQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIsIERXT1JEIGZsYWdzKQp7CglpbnQgeCA9IGRpcy0+cmNJdGVtLmxlZnQ7CglSRUNUIHJ0OwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJRHJhd1RleHQoZGlzLT5oREMsIChMUFRTVFIpc3RyLCAtMSwgJnJ0LCBEVF9TSU5HTEVMSU5FfERUX05PUFJFRklYfGZsYWdzKTsKfQoKc3RhdGljIHZvaWQgb3V0cHV0X3RhYmJlZF90ZXh0KFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBpbnQgY29sLCBMUENUU1RSIHN0cikKewoJaW50IHggPSBkaXMtPnJjSXRlbS5sZWZ0OwoJUkVDVCBydDsKCglydC5sZWZ0ICAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2xdK0dsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJcnQucmlnaHQgID0geCtwYW5lLT5wb3NpdGlvbnNbY29sKzFdLUdsb2JhbHMuc3BhY2VTaXplLmN4OwoJcnQuYm90dG9tID0gZGlzLT5yY0l0ZW0uYm90dG9tOwoKLyoJRFJBV1RFWFRQQVJBTVMgZHRwID0ge3NpemVvZihEUkFXVEVYVFBBUkFNUyksIDJ9OwoJRHJhd1RleHRFeChkaXMtPmhEQywgKExQVFNUUilzdHIsIC0xLCAmcnQsIERUX1NJTkdMRUxJTkV8RFRfTk9QUkVGSVh8RFRfRVhQQU5EVEFCU3xEVF9UQUJTVE9QLCAmZHRwKTsqLwoKCURyYXdUZXh0KGRpcy0+aERDLCAoTFBUU1RSKXN0ciwgLTEsICZydCwgRFRfU0lOR0xFTElORXxEVF9FWFBBTkRUQUJTfERUX1RBQlNUT1B8KDI8PDgpKTsKfQoKc3RhdGljIHZvaWQgb3V0cHV0X251bWJlcihQYW5lKiBwYW5lLCBMUERSQVdJVEVNU1RSVUNUIGRpcywgaW50IGNvbCwgTFBDVFNUUiBzdHIpCnsKCWludCB4ID0gZGlzLT5yY0l0ZW0ubGVmdDsKCVJFQ1QgcnQ7CglMUENUU1RSIHMgPSBzdHI7CglUQ0hBUiBiWzEyOF07CglMUFRTVFIgZCA9IGI7CglpbnQgcG9zOwoKCXJ0LmxlZnQgICA9IHgrcGFuZS0+cG9zaXRpb25zW2NvbF0rR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC50b3AgICAgPSBkaXMtPnJjSXRlbS50b3A7CglydC5yaWdodCAgPSB4K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0tR2xvYmFscy5zcGFjZVNpemUuY3g7CglydC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJaWYgKCpzKQoJCSpkKysgPSAqcysrOwoKCS8qIGluc2VydCBudW1iZXIgc2VwYXJhdG9yIGNoYXJhY3RlcnMgKi8KCXBvcyA9IGxzdHJsZW4ocykgJSAzOwoKCXdoaWxlKCpzKQoJCWlmIChwb3MtLSkKCQkJKmQrKyA9ICpzKys7CgkJZWxzZSB7CgkJCSpkKysgPSBHbG9iYWxzLm51bV9zZXA7CgkJCXBvcyA9IDM7CgkJfQoKCURyYXdUZXh0KGRpcy0+aERDLCBiLCBkLWIsICZydCwgRFRfUklHSFR8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWHxEVF9FTkRfRUxMSVBTSVMpOwp9CgoKc3RhdGljIEJPT0wgaXNfZXhlX2ZpbGUoTFBDVFNUUiBleHQpCnsKCXN0YXRpYyBjb25zdCBUQ0hBUiBleGVjdXRhYmxlX2V4dGVuc2lvbnNbXVs0XSA9IHsKCQl7J0MnLCdPJywnTScsJ1wwJ30sCgkJeydFJywnWCcsJ0UnLCdcMCd9LAoJCXsnQicsJ0EnLCdUJywnXDAnfSwKCQl7J0MnLCdNJywnRCcsJ1wwJ30sCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQl7J0MnLCdNJywnTScsJ1wwJ30sCgkJeydCJywnVCcsJ00nLCdcMCd9LAoJCXsnQScsJ1cnLCdLJywnXDAnfSwKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJeydcMCd9Cgl9OwoKCVRDSEFSIGV4dF9idWZmZXJbX01BWF9FWFRdOwoJY29uc3QgVENIQVIgKCpwKVs0XTsKCUxQQ1RTVFIgczsKCUxQVFNUUiBkOwoKCWZvcihzPWV4dCsxLGQ9ZXh0X2J1ZmZlcjsgKCpkPXRvbG93ZXIoKnMpKTsgcysrKQoJCWQrKzsKCglmb3IocD1leGVjdXRhYmxlX2V4dGVuc2lvbnM7ICgqcClbMF07IHArKykKCQlpZiAoIV90Y3NpY21wKGV4dF9idWZmZXIsICpwKSkKCQkJcmV0dXJuIFRSVUU7CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBpc19yZWdpc3RlcmVkX3R5cGUoTFBDVFNUUiBleHQpCnsKCS8qIGNoZWNrIGlmIHRoZXJlIGV4aXN0cyBhIGNsYXNzbmFtZSBmb3IgdGhpcyBmaWxlIGV4dGVuc2lvbiBpbiB0aGUgcmVnaXN0cnkgKi8KCWlmICghUmVnUXVlcnlWYWx1ZShIS0VZX0NMQVNTRVNfUk9PVCwgZXh0LCBOVUxMLCBOVUxMKSkKCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBlbnVtIEZJTEVfVFlQRSBnZXRfZmlsZV90eXBlKExQQ1RTVFIgZmlsZW5hbWUpCnsKCUxQQ1RTVFIgZXh0ID0gX3Rjc3JjaHIoZmlsZW5hbWUsICcuJyk7CglpZiAoIWV4dCkKCQlleHQgPSBzRW1wdHk7CgoJaWYgKGlzX2V4ZV9maWxlKGV4dCkpCgkJcmV0dXJuIEZUX0VYRUNVVEFCTEU7CgllbHNlIGlmIChpc19yZWdpc3RlcmVkX3R5cGUoZXh0KSkKCQlyZXR1cm4gRlRfRE9DVU1FTlQ7CgllbHNlCgkJcmV0dXJuIEZUX09USEVSOwp9CgoKc3RhdGljIHZvaWQgZHJhd19pdGVtKFBhbmUqIHBhbmUsIExQRFJBV0lURU1TVFJVQ1QgZGlzLCBFbnRyeSogZW50cnksIGludCBjYWxjV2lkdGhDb2wpCnsKCVRDSEFSIGJ1ZmZlcltCVUZGRVJfTEVOXTsKCURXT1JEIGF0dHJzOwoJaW50IHZpc2libGVfY29scyA9IHBhbmUtPnZpc2libGVfY29sczsKCUNPTE9SUkVGIGJrY29sb3IsIHRleHRjb2xvcjsKCVJFQ1QgZm9jdXNSZWN0ID0gZGlzLT5yY0l0ZW07CglIQlJVU0ggaGJydXNoOwoJZW51bSBJTUFHRSBpbWc7CglpbnQgaW1nX3BvcywgY3g7CglpbnQgY29sID0gMDsKCglpZiAoZW50cnkpIHsKCQlhdHRycyA9IGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXM7CgoJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgewoJCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT1URVhUKCcuJykgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT1URVhUKCcuJykKCQkJCQkmJiBlbnRyeS0+ZGF0YS5jRmlsZU5hbWVbMl09PVRFWFQoJ1wwJykpCgkJCQlpbWcgPSBJTUdfRk9MREVSX1VQOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCWVsc2UgaWYgKGVudHJ5LT5kYXRhLmNGaWxlTmFtZVswXT09VEVYVCgnLicpICYmIGVudHJ5LT5kYXRhLmNGaWxlTmFtZVsxXT09VEVYVCgnXDAnKSkKCQkJCWltZyA9IElNR19GT0xERVJfQ1VSOwojZW5kaWYKCQkJZWxzZSBpZiAoCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCSBlbnRyeS0+ZXhwYW5kZWQgfHwKI2VuZGlmCgkJCQkJIChwYW5lLT50cmVlUGFuZSAmJiAoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSkpCgkJCQlpbWcgPSBJTUdfT1BFTl9GT0xERVI7CgkJCWVsc2UKCQkJCWltZyA9IElNR19GT0xERVI7CgkJfSBlbHNlIHsKCQkJc3dpdGNoKGdldF9maWxlX3R5cGUoZW50cnktPmRhdGEuY0ZpbGVOYW1lKSkgewoJCQkgIGNhc2UgRlRfRVhFQ1VUQUJMRToJaW1nID0gSU1HX0VYRUNVVEFCTEU7CWJyZWFrOwoJCQkgIGNhc2UgRlRfRE9DVU1FTlQ6CQlpbWcgPSBJTUdfRE9DVU1FTlQ7CQlicmVhazsKCQkJICBkZWZhdWx0OgkJCQlpbWcgPSBJTUdfRklMRTsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJYXR0cnMgPSAwOwoJCWltZyA9IElNR19OT05FOwoJfQoKCWlmIChwYW5lLT50cmVlUGFuZSkgewoJCWlmIChlbnRyeSkgewoJCQlpbWdfcG9zID0gZGlzLT5yY0l0ZW0ubGVmdCArIGVudHJ5LT5sZXZlbCooSU1BR0VfV0lEVEgrVFJFRV9MSU5FX0RYKTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpIHsKCQkJCWludCB4OwoJCQkJaW50IHkgPSBkaXMtPnJjSXRlbS50b3AgKyBJTUFHRV9IRUlHSFQvMjsKCQkJCUVudHJ5KiB1cDsKCQkJCVJFQ1QgcnRfY2xpcDsKCQkJCUhSR04gaHJnbl9vcmcgPSBDcmVhdGVSZWN0UmduKDAsIDAsIDAsIDApOwoJCQkJSFJHTiBocmduOwoKCQkJCXJ0X2NsaXAubGVmdCAgID0gZGlzLT5yY0l0ZW0ubGVmdDsKCQkJCXJ0X2NsaXAudG9wICAgID0gZGlzLT5yY0l0ZW0udG9wOwoJCQkJcnRfY2xpcC5yaWdodCAgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPndpZHRoc1tjb2xdOwoJCQkJcnRfY2xpcC5ib3R0b20gPSBkaXMtPnJjSXRlbS5ib3R0b207CgoJCQkJaHJnbiA9IENyZWF0ZVJlY3RSZ25JbmRpcmVjdCgmcnRfY2xpcCk7CgoJCQkJaWYgKCFHZXRDbGlwUmduKGRpcy0+aERDLCBocmduX29yZykpIHsKCQkJCQlEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJCWhyZ25fb3JnID0gMDsKCQkJCX0KCgkJCQkvKiBIR0RJT0JKIGhvbGRQZW4gPSBTZWxlY3RPYmplY3QoZGlzLT5oREMsIEdldFN0b2NrT2JqZWN0KEJMQUNLX1BFTikpOyAqLwoJCQkJRXh0U2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbiwgUkdOX0FORCk7CgkJCQlEZWxldGVPYmplY3QoaHJnbik7CgoJCQkJaWYgKCh1cD1lbnRyeS0+dXApICE9IE5VTEwpIHsKCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgaW1nX3Bvcy1JTUFHRV9XSURUSC8yLCB5LCAwKTsKCQkJCQlMaW5lVG8oZGlzLT5oREMsIGltZ19wb3MtMiwgeSk7CgoJCQkJCXggPSBpbWdfcG9zIC0gSU1BR0VfV0lEVEgvMjsKCgkJCQkJZG8gewoJCQkJCQl4IC09IElNQUdFX1dJRFRIK1RSRUVfTElORV9EWDsKCgkJCQkJCWlmICh1cC0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJCQkmJiAodXAtPm5leHQtPmRhdGEuZHdGaWxlQXR0cmlidXRlcyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkKI2VuZGlmCgkJCQkJCQkpIHsKCQkJCQkJCU1vdmVUb0V4KGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS50b3AsIDApOwoJCQkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoJCQkJCQl9CgkJCQkJfSB3aGlsZSgodXA9dXAtPnVwKSAhPSBOVUxMKTsKCQkJCX0KCgkJCQl4ID0gaW1nX3BvcyAtIElNQUdFX1dJRFRILzI7CgoJCQkJTW92ZVRvRXgoZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLnRvcCwgMCk7CgkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIHkpOwoKCQkJCWlmIChlbnRyeS0+bmV4dAojaWZuZGVmIF9MRUZUX0ZJTEVTCgkJCQkJJiYgKGVudHJ5LT5uZXh0LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMmRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZKQojZW5kaWYKCQkJCQkpCgkJCQkJTGluZVRvKGRpcy0+aERDLCB4LCBkaXMtPnJjSXRlbS5ib3R0b20pOwoKCQkJCWlmIChlbnRyeS0+ZG93biAmJiBlbnRyeS0+ZXhwYW5kZWQpIHsKCQkJCQl4ICs9IElNQUdFX1dJRFRIK1RSRUVfTElORV9EWDsKCQkJCQlNb3ZlVG9FeChkaXMtPmhEQywgeCwgZGlzLT5yY0l0ZW0udG9wK0lNQUdFX0hFSUdIVCsyLCAwKTsKCQkJCQlMaW5lVG8oZGlzLT5oREMsIHgsIGRpcy0+cmNJdGVtLmJvdHRvbSk7CgkJCQl9CgoJCQkJU2VsZWN0Q2xpcFJnbihkaXMtPmhEQywgaHJnbl9vcmcpOwoJCQkJaWYgKGhyZ25fb3JnKSBEZWxldGVPYmplY3QoaHJnbl9vcmcpOwoJCQkJLyogU2VsZWN0T2JqZWN0KGRpcy0+aERDLCBob2xkUGVuKTsgKi8KCQkJfSBlbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpIHsKCQkJCWludCByaWdodCA9IGltZ19wb3MgKyBJTUFHRV9XSURUSCAtIFRSRUVfTElORV9EWDsKCgkJCQlpZiAocmlnaHQgPiBwYW5lLT53aWR0aHNbY29sXSkKCQkJCQlwYW5lLT53aWR0aHNbY29sXSA9IHJpZ2h0OwoJCQl9CgkJfSBlbHNlICB7CgkJCWltZ19wb3MgPSBkaXMtPnJjSXRlbS5sZWZ0OwoJCX0KCX0gZWxzZSB7CgkJaW1nX3BvcyA9IGRpcy0+cmNJdGVtLmxlZnQ7CgoJCWlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCXBhbmUtPndpZHRoc1tjb2xdID0gSU1BR0VfV0lEVEg7Cgl9CgoJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkgewoJCWZvY3VzUmVjdC5sZWZ0ID0gaW1nX3BvcyAtMjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmIChwYW5lLT50cmVlUGFuZSAmJiBlbnRyeSkgewoJCQlSRUNUIHJ0ID0gezB9OwoKCQkJRHJhd1RleHQoZGlzLT5oREMsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSwgLTEsICZydCwgRFRfQ0FMQ1JFQ1R8RFRfU0lOR0xFTElORXxEVF9OT1BSRUZJWCk7CgoJCQlmb2N1c1JlY3QucmlnaHQgPSBkaXMtPnJjSXRlbS5sZWZ0K3BhbmUtPnBvc2l0aW9uc1tjb2wrMV0rVFJFRV9MSU5FX0RYICsgcnQucmlnaHQgKzI7CgkJfQojZWxzZQoKCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9DT01QUkVTU0VEKQoJCQl0ZXh0Y29sb3IgPSBDT0xPUl9DT01QUkVTU0VEOwoJCWVsc2UKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJCXRleHRjb2xvciA9IFJHQigwLDAsMCk7CgoJCWlmIChkaXMtPml0ZW1TdGF0ZSAmIE9EU19GT0NVUykgewoJCQl0ZXh0Y29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCQlia2NvbG9yID0gQ09MT1JfU0VMRUNUSU9OOwoJCX0gZWxzZSB7CgkJCWJrY29sb3IgPSBSR0IoMjU1LDI1NSwyNTUpOwoJCX0KCgkJaGJydXNoID0gQ3JlYXRlU29saWRCcnVzaChia2NvbG9yKTsKCQlGaWxsUmVjdChkaXMtPmhEQywgJmZvY3VzUmVjdCwgaGJydXNoKTsKCQlEZWxldGVPYmplY3QoaGJydXNoKTsKCgkJU2V0QmtNb2RlKGRpcy0+aERDLCBUUkFOU1BBUkVOVCk7CgkJU2V0VGV4dENvbG9yKGRpcy0+aERDLCB0ZXh0Y29sb3IpOwoKCQljeCA9IHBhbmUtPndpZHRoc1tjb2xdOwoKCQlpZiAoY3ggJiYgaW1nIT1JTUdfTk9ORSkgewoKCQkJaWYgKGN4ID4gSU1BR0VfV0lEVEgpCgkJCQljeCA9IElNQUdFX1dJRFRIOwoKI2lmZGVmIF9TSEVMTF9GT0xERVJTCgkJCWlmIChlbnRyeS0+aGljb24gJiYgZW50cnktPmhpY29uIT0oSElDT04pLTEpCgkJCQlEcmF3SWNvbkV4KGRpcy0+aERDLCBpbWdfcG9zLCBkaXMtPnJjSXRlbS50b3AsIGVudHJ5LT5oaWNvbiwgY3gsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pLCAwLCAwLCBESV9OT1JNQUwpOwoJCQllbHNlCiNlbmRpZgoJCQkJSW1hZ2VMaXN0X0RyYXdFeChHbG9iYWxzLmhpbWwsIGltZywgZGlzLT5oREMsCgkJCQkJCQkJIGltZ19wb3MsIGRpcy0+cmNJdGVtLnRvcCwgY3gsCgkJCQkJCQkJIElNQUdFX0hFSUdIVCwgYmtjb2xvciwgQ0xSX0RFRkFVTFQsIElMRF9OT1JNQUwpOwoJCX0KCX0KCglpZiAoIWVudHJ5KQoJCXJldHVybjsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGltZyA+PSBJTUdfRk9MREVSX1VQKQoJCXJldHVybjsKI2VuZGlmCgoJY29sKys7CgoJLyogb3VwdXQgZmlsZSBuYW1lICovCglpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBlbnRyeS0+ZGF0YS5jRmlsZU5hbWUsIDApOwoJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGVudHJ5LT5kYXRhLmNGaWxlTmFtZSk7CgoJY29sKys7CgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICBpZiAoIXBhbmUtPnRyZWVQYW5lKSB7CiNlbmRpZgoKICAgICAgICAvKiBkaXNwbGF5IGZpbGUgc2l6ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9TSVpFKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWlmICghKGF0dHJzJkZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkpCiNlbmRpZgoJCXsKCQkJVUxPTkdMT05HIHNpemU7CgogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gKChVTE9OR0xPTkcpZW50cnktPmRhdGEubkZpbGVTaXplSGlnaCA8PCAzMikgfCBlbnRyeS0+ZGF0YS5uRmlsZVNpemVMb3c7CgoJCQlfc3RwcmludGYoYnVmZmVyLCBzTG9uZ051bUZtdCwgc2l6ZSk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X251bWJlcihwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsvKlRPRE86IG5vdCBldmVyIHRpbWUgZW5vdWdoICovCgkJfQoKCQljb2wrKzsKCX0KCgkvKiBkaXNwbGF5IGZpbGUgZGF0ZSAqLwoJaWYgKHZpc2libGVfY29scyAmIChDT0xfREFURXxDT0xfVElNRSkpIHsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWZvcm1hdF9kYXRlKCZlbnRyeS0+ZGF0YS5mdENyZWF0aW9uVGltZSwgYnVmZmVyLCB2aXNpYmxlX2NvbHMpOwoJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCW91dHB1dF90ZXh0KHBhbmUsIGRpcywgY29sLCBidWZmZXIsIDApOwoJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCQljb2wrKzsKCgkJZm9ybWF0X2RhdGUoJmVudHJ5LT5kYXRhLmZ0TGFzdEFjY2Vzc1RpbWUsIGJ1ZmZlciwgdmlzaWJsZV9jb2xzKTsKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCAwKTsKCQllbHNlIGlmIChjYWxjV2lkdGhDb2w9PWNvbCB8fCBjYWxjV2lkdGhDb2w9PUNPTFVNTlMpCgkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJY29sKys7CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQlmb3JtYXRfZGF0ZSgmZW50cnktPmRhdGEuZnRMYXN0V3JpdGVUaW1lLCBidWZmZXIsIHZpc2libGVfY29scyk7CgkJaWYgKGNhbGNXaWR0aENvbCA9PSAtMSkKCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgMCk7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3dpZHRoKHBhbmUsIGRpcywgY29sLCBidWZmZXIpOwoJCWNvbCsrOwoJfQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJaWYgKGVudHJ5LT5iaGZpX3ZhbGlkKSB7CiAgICAgICAgICAgIFVMT05HTE9ORyBpbmRleCA9ICgoVUxPTkdMT05HKWVudHJ5LT5iaGZpLm5GaWxlSW5kZXhIaWdoIDw8IDMyKSB8IGVudHJ5LT5iaGZpLm5GaWxlSW5kZXhMb3c7CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfSU5ERVgpIHsKCQkJX3N0cHJpbnRmKGJ1ZmZlciwgc0xvbmdIZXhGbXQsIGluZGV4KTsKCgkJCWlmIChjYWxjV2lkdGhDb2wgPT0gLTEpCgkJCQlvdXRwdXRfdGV4dChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyLCBEVF9SSUdIVCk7CgkJCWVsc2UgaWYgKGNhbGNXaWR0aENvbD09Y29sIHx8IGNhbGNXaWR0aENvbD09Q09MVU1OUykKCQkJCWNhbGNfd2lkdGgocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgoJCQljb2wrKzsKCQl9CgoJCWlmICh2aXNpYmxlX2NvbHMgJiBDT0xfTElOS1MpIHsKCQkJd3NwcmludGYoYnVmZmVyLCBzTnVtRm10LCBlbnRyeS0+YmhmaS5uTnVtYmVyT2ZMaW5rcyk7CgoJCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQkJb3V0cHV0X3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlciwgRFRfQ0VOVEVSKTsKCQkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQkJY2FsY193aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJCWNvbCsrOwoJCX0KCX0gZWxzZQoJCWNvbCArPSAyOwojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgkvKiBzaG93IGZpbGUgYXR0cmlidXRlcyAqLwoJaWYgKHZpc2libGVfY29scyAmIENPTF9BVFRSSUJVVEVTKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzNFRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJX3Rjc2NweShidWZmZXIsIHM0VGFicyk7CiNlbHNlCgkJY29uc3Qgc3RhdGljIFRDSEFSIHMxMVRhYnNbXSA9IHsnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsJ1wwJ307CgkJX3Rjc2NweShidWZmZXIsIHMxMVRhYnMpOwojZW5kaWYKCgkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9STUFMKQkJCQkJYnVmZmVyWyAwXSA9ICdOJzsKCQllbHNlIHsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfUkVBRE9OTFkpCQkJYnVmZmVyWyAyXSA9ICdSJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfSElEREVOKQkJCQlidWZmZXJbIDRdID0gJ0gnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TWVNURU0pCQkJCWJ1ZmZlclsgNl0gPSAnUyc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0FSQ0hJVkUpCQkJCWJ1ZmZlclsgOF0gPSAnQSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX0NPTVBSRVNTRUQpCQkJYnVmZmVyWzEwXSA9ICdDJzsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpCQkJYnVmZmVyWzEyXSA9ICdEJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfRU5DUllQVEVEKQkJCWJ1ZmZlclsxNF0gPSAnRSc7CgkJCWlmIChhdHRycyAmIEZJTEVfQVRUUklCVVRFX1RFTVBPUkFSWSkJCQlidWZmZXJbMTZdID0gJ1QnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9TUEFSU0VfRklMRSkJCQlidWZmZXJbMThdID0gJ1AnOwoJCQlpZiAoYXR0cnMgJiBGSUxFX0FUVFJJQlVURV9SRVBBUlNFX1BPSU5UKQkJYnVmZmVyWzIwXSA9ICdRJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfT0ZGTElORSkJCQkJYnVmZmVyWzIyXSA9ICdPJzsKCQkJaWYgKGF0dHJzICYgRklMRV9BVFRSSUJVVEVfTk9UX0NPTlRFTlRfSU5ERVhFRCkJYnVmZmVyWzI0XSA9ICdYJzsKI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCgkJfQoKCQlpZiAoY2FsY1dpZHRoQ29sID09IC0xKQoJCQlvdXRwdXRfdGFiYmVkX3RleHQocGFuZSwgZGlzLCBjb2wsIGJ1ZmZlcik7CgkJZWxzZSBpZiAoY2FsY1dpZHRoQ29sPT1jb2wgfHwgY2FsY1dpZHRoQ29sPT1DT0xVTU5TKQoJCQljYWxjX3RhYmJlZF93aWR0aChwYW5lLCBkaXMsIGNvbCwgYnVmZmVyKTsKCgkJY29sKys7Cgl9CgovKlRPRE8KCWlmIChmbGFncy5zZWN1cml0eSkgewoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzU2VjVGFic1tdID0gewoJCQknICcsJ1x0JywnICcsJ1x0JywnICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywKCQkJJyAnLCdcdCcsJyAnLCdcdCcsJyAnLCdcdCcsJyAnLAoJCQknICcsJ1x0JywnICcsCgkJCScgJywnXHQnLCcgJywnXHQnLCcgJywnXHQnLCcgJywKCQkJJ1wwJwoJCX07CgoJCURXT1JEIHJpZ2h0cyA9IGdldF9hY2Nlc3NfbWFzaygpOwoKCQl0Y3NjcHkoYnVmZmVyLCBzU2VjVGFicyk7CgoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfREFUQSkJCQlidWZmZXJbIDBdID0gJ1InOwoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0RBVEEpCQkJYnVmZmVyWyAyXSA9ICdXJzsKCQlpZiAocmlnaHRzICYgRklMRV9BUFBFTkRfREFUQSkJCQlidWZmZXJbIDRdID0gJ0EnOwoJCWlmIChyaWdodHMgJiBGSUxFX1JFQURfRUEpCQkJCXtidWZmZXJbNl0gPSAnZW50cnknOyBidWZmZXJbIDddID0gJ1InO30KCQlpZiAocmlnaHRzICYgRklMRV9XUklURV9FQSkJCQkJe2J1ZmZlcls5XSA9ICdlbnRyeSc7IGJ1ZmZlclsxMF0gPSAnVyc7fQoJCWlmIChyaWdodHMgJiBGSUxFX0VYRUNVVEUpCQkJCWJ1ZmZlclsxMl0gPSAnWCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfREVMRVRFX0NISUxEKQkJCWJ1ZmZlclsxNF0gPSAnRCc7CgkJaWYgKHJpZ2h0cyAmIEZJTEVfUkVBRF9BVFRSSUJVVEVTKQkJe2J1ZmZlclsxNl0gPSAnYSc7IGJ1ZmZlclsxN10gPSAnUic7fQoJCWlmIChyaWdodHMgJiBGSUxFX1dSSVRFX0FUVFJJQlVURVMpCQl7YnVmZmVyWzE5XSA9ICdhJzsgYnVmZmVyWzIwXSA9ICdXJzt9CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX0RBQykJCQkJCWJ1ZmZlclsyMl0gPSAnQyc7CgkJaWYgKHJpZ2h0cyAmIFdSSVRFX09XTkVSKQkJCQlidWZmZXJbMjRdID0gJ08nOwoJCWlmIChyaWdodHMgJiBTWU5DSFJPTklaRSkJCQkJYnVmZmVyWzI2XSA9ICdTJzsKCgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCBEVF9MRUZULCAzLCBwc2l6ZSk7Cgl9CgoJaWYgKGZsYWdzLmRlc2NyaXB0aW9uKSB7CgkJZ2V0X2Rlc2NyaXB0aW9uKGJ1ZmZlcik7CgkJb3V0cHV0X3RleHQoZGlzLCBjb2wrKywgYnVmZmVyLCAwLCBwc2l6ZSk7Cgl9CiovCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKICB9CgogICAgICAgIC8qIGRyYXcgZm9jdXMgZnJhbWUgKi8KCWlmICgoZGlzLT5pdGVtU3RhdGUmT0RTX0ZPQ1VTKSAmJiBjYWxjV2lkdGhDb2w9PS0xKSB7CgkgICAgICAgIC8qIEN1cnJlbnRseSBbMDQvMjAwMF0gV2luZSBuZWl0aGVyIGJlaGF2ZXMgZXhhY3RseSB0aGUgc2FtZSAqLwoJICAgICAgICAvKiB3YXkgYXMgV0lOIDk1IG5vciBsaWtlIFdpbmRvd3MgTlQuLi4gKi8KCQlIR0RJT0JKIGxhc3RCcnVzaDsKCQlIUEVOIGxhc3RQZW47CgkJSFBFTiBocGVuOwoKCQlpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgewkvKiBXaW5kb3dzIE5UPyAqLwoJCQlMT0dCUlVTSCBsYiA9IHtQU19TT0xJRCwgUkdCKDI1NSwyNTUsMjU1KX07CgkJCWhwZW4gPSBFeHRDcmVhdGVQZW4oUFNfQ09TTUVUSUN8UFNfQUxURVJOQVRFLCAxLCAmbGIsIDAsIDApOwoJCX0gZWxzZQoJCQlocGVuID0gQ3JlYXRlUGVuKFBTX0RPVCwgMCwgUkdCKDI1NSwyNTUsMjU1KSk7CgoJCWxhc3RQZW4gPSBTZWxlY3RQZW4oZGlzLT5oREMsIGhwZW4pOwoJCWxhc3RCcnVzaCA9IFNlbGVjdE9iamVjdChkaXMtPmhEQywgR2V0U3RvY2tPYmplY3QoSE9MTE9XX0JSVVNIKSk7CgkJU2V0Uk9QMihkaXMtPmhEQywgUjJfWE9SUEVOKTsKCQlSZWN0YW5nbGUoZGlzLT5oREMsIGZvY3VzUmVjdC5sZWZ0LCBmb2N1c1JlY3QudG9wLCBmb2N1c1JlY3QucmlnaHQsIGZvY3VzUmVjdC5ib3R0b20pOwoJCVNlbGVjdE9iamVjdChkaXMtPmhEQywgbGFzdEJydXNoKTsKCQlTZWxlY3RPYmplY3QoZGlzLT5oREMsIGxhc3RQZW4pOwoJCURlbGV0ZU9iamVjdChocGVuKTsKCX0KI2VuZGlmIC8qIF9OT19FWFRFTlNJT05TICovCn0KCgojaWZkZWYgX05PX0VYVEVOU0lPTlMKCnN0YXRpYyB2b2lkIGRyYXdfc3BsaXRiYXIoSFdORCBod25kLCBpbnQgeCkKewoJUkVDVCBydDsKCUhEQyBoZGMgPSBHZXREQyhod25kKTsKCglHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJcnQubGVmdCA9IHggLSBTUExJVF9XSURUSC8yOwoJcnQucmlnaHQgPSB4ICsgU1BMSVRfV0lEVEgvMisxOwoKCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCVJlbGVhc2VEQyhod25kLCBoZGMpOwp9CgojZW5kaWYgLyogX05PX0VYVEVOU0lPTlMgKi8KCgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgpzdGF0aWMgdm9pZCBzZXRfaGVhZGVyKFBhbmUqIHBhbmUpCnsKCUhEX0lURU0gaXRlbTsKCWludCBzY3JvbGxfcG9zID0gR2V0U2Nyb2xsUG9zKHBhbmUtPmh3bmQsIFNCX0hPUlopOwoJaW50IGk9MCwgeD0wOwoKCWl0ZW0ubWFzayA9IEhESV9XSURUSDsKCWl0ZW0uY3h5ID0gMDsKCglmb3IoOyB4K3BhbmUtPndpZHRoc1tpXTxzY3JvbGxfcG9zICYmIGk8Q09MVU1OUzsgaSsrKSB7CgkJeCArPSBwYW5lLT53aWR0aHNbaV07CgkJSGVhZGVyX1NldEl0ZW0ocGFuZS0+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+cmlnaHQpOwojZW5kaWYKfQoKc3RhdGljIHZvaWQgc2V0X2N1cmRpcihDaGlsZFduZCogY2hpbGQsIEVudHJ5KiBlbnRyeSwgaW50IGlkeCwgSFdORCBod25kKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCglwYXRoWzBdID0gJ1wwJzsKCgljaGlsZC0+bGVmdC5jdXIgPSBlbnRyeTsKCgljaGlsZC0+cmlnaHQucm9vdCA9IGVudHJ5LT5kb3duPyBlbnRyeS0+ZG93bjogZW50cnk7CgljaGlsZC0+cmlnaHQuY3VyID0gZW50cnk7CgoJaWYgKCFlbnRyeS0+c2Nhbm5lZCkKCQlzY2FuX2VudHJ5KGNoaWxkLCBlbnRyeSwgaWR4LCBod25kKTsKCWVsc2UKCQlyZWZyZXNoX3JpZ2h0X3BhbmUoY2hpbGQpOwoKCWdldF9wYXRoKGVudHJ5LCBwYXRoKTsKCWxzdHJjcHkoY2hpbGQtPnBhdGgsIHBhdGgpOwoKCWlmIChjaGlsZC0+aHduZCkJLyogb25seSBjaGFuZ2Ugd2luZG93IHRpdGxlLCBpZiB0aGUgd2luZG93IGFscmVhZHkgZXhpc3RzICovCgkJU2V0V2luZG93VGV4dChjaGlsZC0+aHduZCwgcGF0aCk7CgoJaWYgKHBhdGhbMF0pCgkJaWYgKFNldEN1cnJlbnREaXJlY3RvcnkocGF0aCkpCgkJCXNldF9zcGFjZV9zdGF0dXMoKTsKfQoKCnN0YXRpYyB2b2lkIHJlZnJlc2hfY2hpbGQoQ2hpbGRXbmQqIGNoaWxkKQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXSwgZHJ2W19NQVhfRFJJVkUrMV07CglFbnRyeSogZW50cnk7CglpbnQgaWR4OwoKCWdldF9wYXRoKGNoaWxkLT5sZWZ0LmN1ciwgcGF0aCk7CglfdHNwbGl0cGF0aChwYXRoLCBkcnYsIE5VTEwsIE5VTEwsIE5VTEwpOwoKCWNoaWxkLT5yaWdodC5yb290ID0gTlVMTDsKCglzY2FuX2VudHJ5KGNoaWxkLCAmY2hpbGQtPnJvb3QuZW50cnksIDAsIGNoaWxkLT5od25kKTsKCgllbnRyeSA9IHJlYWRfdHJlZSgmY2hpbGQtPnJvb3QsIHBhdGgsIE5VTEwsIGRydiwgY2hpbGQtPnNvcnRPcmRlciwgY2hpbGQtPmh3bmQpOwoKCWluc2VydF9lbnRyaWVzKCZjaGlsZC0+bGVmdCwgY2hpbGQtPnJvb3QuZW50cnkuZG93biwgTlVMTCwgVEZfQUxMLCAwKTsKCglzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgMCwgY2hpbGQtPmh3bmQpOwoKCWlkeCA9IExpc3RCb3hfRmluZEl0ZW1EYXRhKGNoaWxkLT5sZWZ0Lmh3bmQsIDAsIGNoaWxkLT5sZWZ0LmN1cik7CglMaXN0Qm94X1NldEN1clNlbChjaGlsZC0+bGVmdC5od25kLCBpZHgpOwp9CgoKc3RhdGljIHZvaWQgY3JlYXRlX2RyaXZlX2JhcigpCnsKCVRCQlVUVE9OIGRyaXZlYmFyQnRuID0gezAsIDAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH07CiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCVRDSEFSIGIxW0JVRkZFUl9MRU5dOwojZW5kaWYKCWludCBidG4gPSAxOwoJUFRTVFIgcDsKCglHZXRMb2dpY2FsRHJpdmVTdHJpbmdzKEJVRkZFUl9MRU4sIEdsb2JhbHMuZHJpdmVzKTsKCglHbG9iYWxzLmhkcml2ZWJhciA9IENyZWF0ZVRvb2xiYXJFeChHbG9iYWxzLmhNYWluV25kLCBXU19DSElMRHxXU19WSVNJQkxFfENDU19OT01PVkVZfFRCU1RZTEVfTElTVCwKCQkJCUlEV19EUklWRUJBUiwgMiwgR2xvYmFscy5oSW5zdGFuY2UsIElEQl9EUklWRUJBUiwgJmRyaXZlYmFyQnRuLAoJCQkJMSwgMTYsIDEzLCAxNiwgMTMsIHNpemVvZihUQkJVVFRPTikpOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwojaWZkZWYgX19XSU5FX18KCS8qIGluc2VydCB1bml4IGZpbGUgc3lzdGVtIGJ1dHRvbiAqLwoJYjFbMF0gPSAnLyc7CgliMVsxXSA9ICdcMCc7CgliMVsyXSA9ICdcMCc7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWIxKTsKCglkcml2ZWJhckJ0bi5pZENvbW1hbmQgPSBJRF9EUklWRV9VTklYX0ZTOwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCWRyaXZlYmFyQnRuLmlTdHJpbmcrKzsKI2VuZGlmCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJLyogaW5zZXJ0IHNoZWxsIG5hbWVzcGFjZSBidXR0b24gKi8KCWxvYWRfc3RyaW5nKGIxLCBJRFNfU0hFTEwpOwoJYjFbbHN0cmxlbihiMSkrMV0gPSAnXDAnOwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSliMSk7CgoJZHJpdmViYXJCdG4uaWRDb21tYW5kID0gSURfRFJJVkVfU0hFTExfTlM7CglTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfSU5TRVJUQlVUVE9OLCBidG4rKywgKExQQVJBTSkmZHJpdmViYXJCdG4pOwoJZHJpdmViYXJCdG4uaVN0cmluZysrOwojZW5kaWYKCgkvKiByZWdpc3RlciB3aW5kb3dzIGRyaXZlIHJvb3Qgc3RyaW5ncyAqLwoJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0FERFNUUklORywgMCwgKExQQVJBTSlHbG9iYWxzLmRyaXZlcyk7CiNlbmRpZgoKCWRyaXZlYmFyQnRuLmlkQ29tbWFuZCA9IElEX0RSSVZFX0ZJUlNUOwoKCWZvcihwPUdsb2JhbHMuZHJpdmVzOyAqcDsgKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCS8qIGluc2VydCBkcml2ZSBsZXR0ZXIgKi8KCQlUQ0hBUiBiWzNdID0ge3RvbG93ZXIoKnApfTsKCQlTZW5kTWVzc2FnZShHbG9iYWxzLmhkcml2ZWJhciwgVEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKWIpOwojZW5kaWYKCQlzd2l0Y2goR2V0RHJpdmVUeXBlKHApKSB7CgkJCWNhc2UgRFJJVkVfUkVNT1ZBQkxFOglkcml2ZWJhckJ0bi5pQml0bWFwID0gMTsJYnJlYWs7CgkJCWNhc2UgRFJJVkVfQ0RST006CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gMzsJYnJlYWs7CgkJCWNhc2UgRFJJVkVfUkVNT1RFOgkJZHJpdmViYXJCdG4uaUJpdG1hcCA9IDQ7CWJyZWFrOwoJCQljYXNlIERSSVZFX1JBTURJU0s6CQlkcml2ZWJhckJ0bi5pQml0bWFwID0gNTsJYnJlYWs7CgkJCWRlZmF1bHQ6LypEUklWRV9GSVhFRCovCWRyaXZlYmFyQnRuLmlCaXRtYXAgPSAyOwoJCX0KCgkJU2VuZE1lc3NhZ2UoR2xvYmFscy5oZHJpdmViYXIsIFRCX0lOU0VSVEJVVFRPTiwgYnRuKyssIChMUEFSQU0pJmRyaXZlYmFyQnRuKTsKCQlkcml2ZWJhckJ0bi5pZENvbW1hbmQrKzsKCQlkcml2ZWJhckJ0bi5pU3RyaW5nKys7CgoJCXdoaWxlKCpwKyspOwoJfQp9CgpzdGF0aWMgdm9pZCByZWZyZXNoX2RyaXZlcygpCnsKCVJFQ1QgcmVjdDsKCgkvKiBkZXN0cm95IGRyaXZlIGJhciAqLwoJRGVzdHJveVdpbmRvdyhHbG9iYWxzLmhkcml2ZWJhcik7CglHbG9iYWxzLmhkcml2ZWJhciA9IDA7CgoJLyogcmUtY3JlYXRlIGRyaXZlIGJhciAqLwoJY3JlYXRlX2RyaXZlX2JhcigpOwoKCS8qIHVwZGF0ZSB3aW5kb3cgbGF5b3V0ICovCglHZXRDbGllbnRSZWN0KEdsb2JhbHMuaE1haW5XbmQsICZyZWN0KTsKCVNlbmRNZXNzYWdlKEdsb2JhbHMuaE1haW5XbmQsIFdNX1NJWkUsIDAsIE1BS0VMT05HKHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKSk7Cn0KCgpCT09MIGxhdW5jaF9maWxlKEhXTkQgaHduZCwgTFBDVFNUUiBjbWQsIFVJTlQgbkNtZFNob3cpCnsKCUhJTlNUQU5DRSBoaW5zdCA9IFNoZWxsRXhlY3V0ZShod25kLCBOVUxMLypvcGVyYXRpb24qLywgY21kLCBOVUxMLypwYXJhbWV0ZXJzKi8sIE5VTEwvKmRpciovLCBuQ21kU2hvdyk7CgoJaWYgKChpbnQpaGluc3QgPD0gMzIpIHsKCQlkaXNwbGF5X2Vycm9yKGh3bmQsIEdldExhc3RFcnJvcigpKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCiNpZmRlZiBVTklDT0RFCkJPT0wgbGF1bmNoX2ZpbGVBKEhXTkQgaHduZCwgTFBTVFIgY21kLCBVSU5UIG5DbWRTaG93KQp7CglISU5TVEFOQ0UgaGluc3QgPSBTaGVsbEV4ZWN1dGVBKGh3bmQsIE5VTEwvKm9wZXJhdGlvbiovLCBjbWQsIE5VTEwvKnBhcmFtZXRlcnMqLywgTlVMTC8qZGlyKi8sIG5DbWRTaG93KTsKCglpZiAoKGludCloaW5zdCA8PSAzMikgewoJCWRpc3BsYXlfZXJyb3IoaHduZCwgR2V0TGFzdEVycm9yKCkpOwoJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQojZW5kaWYKCgpCT09MIGxhdW5jaF9lbnRyeShFbnRyeSogZW50cnksIEhXTkQgaHduZCwgVUlOVCBuQ21kU2hvdykKewoJVENIQVIgY21kW01BWF9QQVRIXTsKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJaWYgKGVudHJ5LT5ldHlwZSA9PSBFVF9TSEVMTCkgewoJCUJPT0wgcmV0ID0gVFJVRTsKCgkJU0hFTExFWEVDVVRFSU5GTyBzaGV4aW5mbzsKCgkJc2hleGluZm8uY2JTaXplID0gc2l6ZW9mKFNIRUxMRVhFQ1VURUlORk8pOwoJCXNoZXhpbmZvLmZNYXNrID0gU0VFX01BU0tfSURMSVNUOwoJCXNoZXhpbmZvLmh3bmQgPSBod25kOwoJCXNoZXhpbmZvLmxwVmVyYiA9IE5VTEw7CgkJc2hleGluZm8ubHBGaWxlID0gTlVMTDsKCQlzaGV4aW5mby5scFBhcmFtZXRlcnMgPSBOVUxMOwoJCXNoZXhpbmZvLmxwRGlyZWN0b3J5ID0gTlVMTDsKCQlzaGV4aW5mby5uU2hvdyA9IG5DbWRTaG93OwoJCXNoZXhpbmZvLmxwSURMaXN0ID0gZ2V0X3RvX2Fic29sdXRlX3BpZGwoZW50cnksIGh3bmQpOwoKCQlpZiAoIVNoZWxsRXhlY3V0ZUV4KCZzaGV4aW5mbykpIHsKCQkJZGlzcGxheV9lcnJvcihod25kLCBHZXRMYXN0RXJyb3IoKSk7CgkJCXJldCA9IEZBTFNFOwoJCX0KCgkJaWYgKHNoZXhpbmZvLmxwSURMaXN0ICE9IGVudHJ5LT5waWRsKQoJCQkoKkdsb2JhbHMuaU1hbGxvYy0+bHBWdGJsLT5GcmVlKShHbG9iYWxzLmlNYWxsb2MsIHNoZXhpbmZvLmxwSURMaXN0KTsKCgkJcmV0dXJuIHJldDsKCX0KI2VuZGlmCgoJZ2V0X3BhdGgoZW50cnksIGNtZCk7CgoJIC8qIHN0YXJ0IHByb2dyYW0sIG9wZW4gZG9jdW1lbnQuLi4gKi8KCXJldHVybiBsYXVuY2hfZmlsZShod25kLCBjbWQsIG5DbWRTaG93KTsKfQoKCnN0YXRpYyB2b2lkIGFjdGl2YXRlX2VudHJ5KENoaWxkV25kKiBjaGlsZCwgUGFuZSogcGFuZSwgSFdORCBod25kKQp7CglFbnRyeSogZW50cnkgPSBwYW5lLT5jdXI7CgoJaWYgKCFlbnRyeSkKCQlyZXR1cm47CgoJaWYgKGVudHJ5LT5kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKCQlpbnQgc2Nhbm5lZF9vbGQgPSBlbnRyeS0+c2Nhbm5lZDsKCgkJaWYgKCFzY2FubmVkX29sZCkKCQkJc2Nhbl9lbnRyeShjaGlsZCwgZW50cnksIExpc3RCb3hfR2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQpLCBod25kKTsKCiNpZm5kZWYgX05PX0VYVEVOU0lPTlMKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nXDAnKQoJCQlyZXR1cm47CiNlbmRpZgoKCQlpZiAoZW50cnktPmRhdGEuY0ZpbGVOYW1lWzBdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzFdPT0nLicgJiYgZW50cnktPmRhdGEuY0ZpbGVOYW1lWzJdPT0nXDAnKSB7CgkJCWVudHJ5ID0gY2hpbGQtPmxlZnQuY3VyLT51cDsKCQkJY29sbGFwc2VfZW50cnkoJmNoaWxkLT5sZWZ0LCBlbnRyeSk7CgkJCWdvdG8gZm9jdXNfZW50cnk7CgkJfSBlbHNlIGlmIChlbnRyeS0+ZXhwYW5kZWQpCgkJCWNvbGxhcHNlX2VudHJ5KHBhbmUsIGNoaWxkLT5sZWZ0LmN1cik7CgkJZWxzZSB7CgkJCWV4cGFuZF9lbnRyeShjaGlsZCwgY2hpbGQtPmxlZnQuY3VyKTsKCgkJCWlmICghcGFuZS0+dHJlZVBhbmUpIGZvY3VzX2VudHJ5OiB7CgkJCQlpbnQgaWR4ID0gTGlzdEJveF9GaW5kSXRlbURhdGEoY2hpbGQtPmxlZnQuaHduZCwgTGlzdEJveF9HZXRDdXJTZWwoY2hpbGQtPmxlZnQuaHduZCksIGVudHJ5KTsKCQkJCUxpc3RCb3hfU2V0Q3VyU2VsKGNoaWxkLT5sZWZ0Lmh3bmQsIGlkeCk7CgkJCQlzZXRfY3VyZGlyKGNoaWxkLCBlbnRyeSwgaWR4LCBod25kKTsKCQkJfQoJCX0KCgkJaWYgKCFzY2FubmVkX29sZCkgewoJCQljYWxjX3dpZHRocyhwYW5lLCBGQUxTRSk7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCXNldF9oZWFkZXIocGFuZSk7CiNlbmRpZgoJCX0KCX0gZWxzZSB7CgkJaWYgKEdldEtleVN0YXRlKFZLX01FTlUpIDwgMCkKCQkJc2hvd19wcm9wZXJ0aWVzX2RsZyhlbnRyeSwgY2hpbGQtPmh3bmQpOwoJCWVsc2UKCQkJbGF1bmNoX2VudHJ5KGVudHJ5LCBjaGlsZC0+aHduZCwgU1dfU0hPV05PUk1BTCk7Cgl9Cn0KCgpzdGF0aWMgQk9PTCBwYW5lX2NvbW1hbmQoUGFuZSogcGFuZSwgVUlOVCBjbWQpCnsKCXN3aXRjaChjbWQpIHsKCQljYXNlIElEX1ZJRVdfTkFNRToKCQkJaWYgKHBhbmUtPnZpc2libGVfY29scykgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gMDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7CgkJCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX0FMTF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIElEX1ZJRVdfQUxMX0FUVFJJQlVURVM6CgkJCWlmIChwYW5lLT52aXNpYmxlX2NvbHMgIT0gQ09MX0FMTCkgewoJCQkJcGFuZS0+dmlzaWJsZV9jb2xzID0gQ09MX0FMTDsKCQkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJCQlzZXRfaGVhZGVyKHBhbmUpOwojZW5kaWYKCQkJCUludmFsaWRhdGVSZWN0KHBhbmUtPmh3bmQsIDAsIFRSVUUpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19OQU1FLCBNRl9CWUNPTU1BTkQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19BTExfQVRUUklCVVRFUywgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoJCQkJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TRUxFQ1RFRF9BVFRSSUJVVEVTLCBNRl9CWUNPTU1BTkQpOwoJCQl9CgkJCWJyZWFrOwoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgSURfUFJFRkVSUkVEX1NJWkVTOiB7CgkJCWNhbGNfd2lkdGhzKHBhbmUsIFRSVUUpOwoJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQlJbnZhbGlkYXRlUmVjdChwYW5lLT5od25kLCAwLCBUUlVFKTsKCQkJYnJlYWs7fQojZW5kaWYKCgkJICAgICAgICAvKiBUT0RPOiBtb3JlIGNvbW1hbmQgaWRzLi4uICovCgoJCWRlZmF1bHQ6CgkJCXJldHVybiBGQUxTRTsKCX0KCglyZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyB2b2lkIHNldF9zb3J0X29yZGVyKENoaWxkV25kKiBjaGlsZCwgU09SVF9PUkRFUiBzb3J0T3JkZXIpCnsKCWlmIChjaGlsZC0+c29ydE9yZGVyICE9IHNvcnRPcmRlcikgewoJCWNoaWxkLT5zb3J0T3JkZXIgPSBzb3J0T3JkZXI7CgkJcmVmcmVzaF9jaGlsZChjaGlsZCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHVwZGF0ZV92aWV3X21lbnUoQ2hpbGRXbmQqIGNoaWxkKQp7CglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVWaWV3LCBJRF9WSUVXX1NPUlRfTkFNRSwgY2hpbGQtPnNvcnRPcmRlcj09U09SVF9OQU1FPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX1RZUEUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfRVhUPyBNRl9DSEVDS0VEOiBNRl9VTkNIRUNLRUQpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51VmlldywgSURfVklFV19TT1JUX1NJWkUsIGNoaWxkLT5zb3J0T3JkZXI9PVNPUlRfU0laRT8gTUZfQ0hFQ0tFRDogTUZfVU5DSEVDS0VEKTsKCUNoZWNrTWVudUl0ZW0oR2xvYmFscy5oTWVudVZpZXcsIElEX1ZJRVdfU09SVF9EQVRFLCBjaGlsZC0+c29ydE9yZGVyPT1TT1JUX0RBVEU/IE1GX0NIRUNLRUQ6IE1GX1VOQ0hFQ0tFRCk7Cn0KCgpzdGF0aWMgQk9PTCBpc19kaXJlY3RvcnkoTFBDVFNUUiB0YXJnZXQpCnsKCS8qVE9ETyBjb3JyZWN0bHkgaGFuZGxlIFVOSVggcGF0aHMgKi8KCURXT1JEIHRhcmdldF9hdHRyID0gR2V0RmlsZUF0dHJpYnV0ZXModGFyZ2V0KTsKCglpZiAodGFyZ2V0X2F0dHIgPT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpCgkJcmV0dXJuIEZBTFNFOwoKCXJldHVybiB0YXJnZXRfYXR0ciZGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlk/IFRSVUU6IEZBTFNFOwp9CgkKc3RhdGljIEJPT0wgcHJvbXB0X3RhcmdldChQYW5lKiBwYW5lLCBMUFRTVFIgc291cmNlLCBMUFRTVFIgdGFyZ2V0KQp7CglUQ0hBUiBwYXRoW01BWF9QQVRIXTsKCWludCBsZW47CgoJZ2V0X3BhdGgocGFuZS0+Y3VyLCBwYXRoKTsKCglpZiAoRGlhbG9nQm94UGFyYW0oR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJRERfU0VMRUNUX0RFU1RJTkFUSU9OKSwgcGFuZS0+aHduZCwgRGVzdGluYXRpb25EbGdQcm9jLCAoTFBBUkFNKXBhdGgpICE9IElET0spCgkJcmV0dXJuIEZBTFNFOwoKCWdldF9wYXRoKHBhbmUtPmN1ciwgc291cmNlKTsKCgkvKiBjb252ZXJ0IHJlbGF0aXZlIHRhcmdldHMgdG8gYWJzb2x1dGUgcGF0aHMgKi8KCWlmIChwYXRoWzBdIT0nLycgJiYgcGF0aFsxXSE9JzonKSB7CgkJZ2V0X3BhdGgocGFuZS0+Y3VyLT51cCwgdGFyZ2V0KTsKCQlsZW4gPSBsc3RybGVuKHRhcmdldCk7CgoJCWlmICh0YXJnZXRbbGVuLTFdIT0nXFwnICYmIHRhcmdldFtsZW4tMV0hPScvJykKCQkJdGFyZ2V0W2xlbisrXSA9ICcvJzsKCgkJbHN0cmNweSh0YXJnZXQrbGVuLCBwYXRoKTsKCX0gZWxzZQoJCWxzdHJjcHkodGFyZ2V0LCBwYXRoKTsKCgkvKiBJZiB0aGUgdGFyZ2V0IGFscmVhZHkgZXhpc3RzIGFzIGRpcmVjdG9yeSwgY3JlYXRlIGEgbmV3IHRhcmdldCBiZWxvdyB0aGlzLiAqLwoJaWYgKGlzX2RpcmVjdG9yeShwYXRoKSkgewoJCVRDSEFSIGZuYW1lW19NQVhfRk5BTUVdLCBleHRbX01BWF9FWFRdOwoJCWNvbnN0IHN0YXRpYyBUQ0hBUiBzQXBwZW5kW10gPSB7JyUnLCdzJywnLycsJyUnLCdzJywnJScsJ3MnLCdcMCd9OwoKCQlfdHNwbGl0cGF0aChzb3VyY2UsIE5VTEwsIE5VTEwsIGZuYW1lLCBleHQpOwoKCQl3c3ByaW50Zih0YXJnZXQsIHNBcHBlbmQsIHBhdGgsIGZuYW1lLCBleHQpOwoJfQoKCXJldHVybiBUUlVFOwp9CgoKc3RhdGljIElDb250ZXh0TWVudTIqIHNfcGN0eG1lbnUyID0gTlVMTDsKc3RhdGljIElDb250ZXh0TWVudTMqIHNfcGN0eG1lbnUzID0gTlVMTDsKCnN0YXRpYyB2b2lkIEN0eE1lbnVfcmVzZXQoKQp7CglzX3BjdHhtZW51MiA9IE5VTEw7CglzX3BjdHhtZW51MyA9IE5VTEw7Cn0KCklDb250ZXh0TWVudSogQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKElDb250ZXh0TWVudSogcGNtMSkKewoJSUNvbnRleHRNZW51KiBwY20gPSBOVUxMOwoKCUN0eE1lbnVfcmVzZXQoKTsKCglpZiAoKCpwY20xLT5scFZ0YmwtPlF1ZXJ5SW50ZXJmYWNlKShwY20xLCAmSUlEX0lDb250ZXh0TWVudTMsICh2b2lkKiopJnBjbSkgPT0gTk9FUlJPUikKCQlzX3BjdHhtZW51MyA9IChMUENPTlRFWFRNRU5VMylwY207CgllbHNlIGlmICgoKnBjbTEtPmxwVnRibC0+UXVlcnlJbnRlcmZhY2UpKHBjbTEsICZJSURfSUNvbnRleHRNZW51MiwgKHZvaWQqKikmcGNtKSA9PSBOT0VSUk9SKQoJCXNfcGN0eG1lbnUyID0gKExQQ09OVEVYVE1FTlUyKXBjbTsKCglpZiAocGNtKSB7CgkJKCpwY20xLT5scFZ0YmwtPlJlbGVhc2UpKHBjbTEpOwoJCXJldHVybiBwY207Cgl9IGVsc2UKCQlyZXR1cm4gcGNtMTsKfQoKc3RhdGljIEJPT0wgQ3R4TWVudV9IYW5kbGVNZW51TXNnKFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJaWYgKHNfcGN0eG1lbnUzKSB7CgkJaWYgKFNVQ0NFRURFRCgoKnNfcGN0eG1lbnUzLT5scFZ0YmwtPkhhbmRsZU1lbnVNc2cpKHNfcGN0eG1lbnUzLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCX0KCglpZiAoc19wY3R4bWVudTIpCgkJaWYgKFNVQ0NFRURFRCgoKnNfcGN0eG1lbnUyLT5scFZ0YmwtPkhhbmRsZU1lbnVNc2cpKHNfcGN0eG1lbnUyLCBubXNnLCB3cGFyYW0sIGxwYXJhbSkpKQoJCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCgpzdGF0aWMgSFJFU1VMVCBTaGVsbEZvbGRlckNvbnRleHRNZW51KElTaGVsbEZvbGRlciogc2hlbGxfZm9sZGVyLCBIV05EIGh3bmRQYXJlbnQsIGludCBjaWRsLCBMUENJVEVNSURMSVNUKiBhcGlkbCwgaW50IHgsIGludCB5KQp7CglJQ29udGV4dE1lbnUqIHBjbTsKCUJPT0wgZXhlY3V0ZWQgPSBGQUxTRTsKCglIUkVTVUxUIGhyID0gKCpzaGVsbF9mb2xkZXItPmxwVnRibC0+R2V0VUlPYmplY3RPZikoc2hlbGxfZm9sZGVyLCBod25kUGFyZW50LCBjaWRsLCBhcGlkbCwgJklJRF9JQ29udGV4dE1lbnUsIE5VTEwsIChMUFZPSUQqKSZwY20pOwovKglIUkVTVUxUIGhyID0gQ0RlZkZvbGRlck1lbnVfQ3JlYXRlMihkaXI/ZGlyLT5fcGlkbDpEZXNrdG9wRm9sZGVyKCksIGh3bmRQYXJlbnQsIDEsICZwaWRsLCBzaGVsbF9mb2xkZXIsIE5VTEwsIDAsIE5VTEwsICZwY20pOyAqLwoKCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJSE1FTlUgaG1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKTsKCgkJcGNtID0gQ3R4TWVudV9xdWVyeV9pbnRlcmZhY2VzKHBjbSk7CgoJCWlmIChobWVudSkgewoJCQlociA9ICgqcGNtLT5scFZ0YmwtPlF1ZXJ5Q29udGV4dE1lbnUpKHBjbSwgaG1lbnUsIDAsIEZDSURNX1NIVklFV0ZJUlNULCBGQ0lETV9TSFZJRVdMQVNULCBDTUZfTk9STUFMKTsKCgkJCWlmIChTVUNDRUVERUQoaHIpKSB7CgkJCQlVSU5UIGlkQ21kID0gVHJhY2tQb3B1cE1lbnUoaG1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1JFVFVSTkNNRHxUUE1fUklHSFRCVVRUT04sIHgsIHksIDAsIGh3bmRQYXJlbnQsIE5VTEwpOwoKCQkJCUN0eE1lbnVfcmVzZXQoKTsKCgkJCQlpZiAoaWRDbWQpIHsKCQkJCSAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbWk7CgoJCQkJICBjbWkuY2JTaXplID0gc2l6ZW9mKENNSU5WT0tFQ09NTUFORElORk8pOwoJCQkJICBjbWkuZk1hc2sgPSAwOwoJCQkJICBjbWkuaHduZCA9IGh3bmRQYXJlbnQ7CgkJCQkgIGNtaS5scFZlcmIgPSAoTFBDU1RSKShJTlRfUFRSKShpZENtZCAtIEZDSURNX1NIVklFV0ZJUlNUKTsKCQkJCSAgY21pLmxwUGFyYW1ldGVycyA9IE5VTEw7CgkJCQkgIGNtaS5scERpcmVjdG9yeSA9IE5VTEw7CgkJCQkgIGNtaS5uU2hvdyA9IFNXX1NIT1dOT1JNQUw7CgkJCQkgIGNtaS5kd0hvdEtleSA9IDA7CgkJCQkgIGNtaS5oSWNvbiA9IDA7CgoJCQkJICBociA9ICgqcGNtLT5scFZ0YmwtPkludm9rZUNvbW1hbmQpKHBjbSwgJmNtaSk7CgkJCQkJZXhlY3V0ZWQgPSBUUlVFOwoJCQkJfQoJCQl9CgkJfQoKCQkoKnBjbS0+bHBWdGJsLT5SZWxlYXNlKShwY20pOwoJfQoKCXJldHVybiBGQUlMRUQoaHIpPyBocjogZXhlY3V0ZWQ/IFNfT0s6IFNfRkFMU0U7Cn0KCgpMUkVTVUxUIENBTExCQUNLIENoaWxkV25kUHJvYyhIV05EIGh3bmQsIFVJTlQgbm1zZywgV1BBUkFNIHdwYXJhbSwgTFBBUkFNIGxwYXJhbSkKewoJQ2hpbGRXbmQqIGNoaWxkID0gKENoaWxkV25kKikgR2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEpOwoJQVNTRVJUKGNoaWxkKTsKCglzd2l0Y2gobm1zZykgewoJCWNhc2UgV01fRFJBV0lURU06IHsKCQkJTFBEUkFXSVRFTVNUUlVDVCBkaXMgPSAoTFBEUkFXSVRFTVNUUlVDVClscGFyYW07CgkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIGRpcy0+aXRlbURhdGE7CgoJCQlpZiAoZGlzLT5DdGxJRCA9PSBJRFdfVFJFRV9MRUZUKQoJCQkJZHJhd19pdGVtKCZjaGlsZC0+bGVmdCwgZGlzLCBlbnRyeSwgLTEpOwoJCQllbHNlIGlmIChkaXMtPkN0bElEID09IElEV19UUkVFX1JJR0hUKQoJCQkJZHJhd19pdGVtKCZjaGlsZC0+cmlnaHQsIGRpcywgZW50cnksIC0xKTsKCQkJZWxzZQoJCQkJZ290byBkcmF3X21lbnVfaXRlbTsKCgkJCXJldHVybiBUUlVFO30KCgkJY2FzZSBXTV9DUkVBVEU6CgkJCUluaXRDaGlsZFdpbmRvdyhjaGlsZCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX05DREVTVFJPWToKCQkJZnJlZV9jaGlsZF93aW5kb3coY2hpbGQpOwoJCQlTZXRXaW5kb3dMb25nKGh3bmQsIEdXTF9VU0VSREFUQSwgMCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX1BBSU5UOiB7CgkJCVBBSU5UU1RSVUNUIHBzOwoJCQlIQlJVU0ggbGFzdEJydXNoOwoJCQlSRUNUIHJ0OwoJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgkJCUJlZ2luUGFpbnQoaHduZCwgJnBzKTsKCQkJcnQubGVmdCA9IGNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMjsKCQkJcnQucmlnaHQgPSBjaGlsZC0+c3BsaXRfcG9zK1NQTElUX1dJRFRILzIrMTsKCQkJbGFzdEJydXNoID0gU2VsZWN0QnJ1c2gocHMuaGRjLCAoSEJSVVNIKUdldFN0b2NrT2JqZWN0KENPTE9SX1NQTElUQkFSKSk7CgkJCVJlY3RhbmdsZShwcy5oZGMsIHJ0LmxlZnQsIHJ0LnRvcC0xLCBydC5yaWdodCwgcnQuYm90dG9tKzEpOwoJCQlTZWxlY3RPYmplY3QocHMuaGRjLCBsYXN0QnJ1c2gpOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJcnQudG9wID0gcnQuYm90dG9tIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJCQlGaWxsUmVjdChwcy5oZGMsICZydCwgR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpKTsKI2VuZGlmCgkJCUVuZFBhaW50KGh3bmQsICZwcyk7CgkJCWJyZWFrO30KCgkJY2FzZSBXTV9TRVRDVVJTT1I6CgkJCWlmIChMT1dPUkQobHBhcmFtKSA9PSBIVENMSUVOVCkgewoJCQkJUE9JTlQgcHQ7CgkJCQlHZXRDdXJzb3JQb3MoJnB0KTsKCQkJCVNjcmVlblRvQ2xpZW50KGh3bmQsICZwdCk7CgoJCQkJaWYgKHB0Lng+PWNoaWxkLT5zcGxpdF9wb3MtU1BMSVRfV0lEVEgvMiAmJiBwdC54PGNoaWxkLT5zcGxpdF9wb3MrU1BMSVRfV0lEVEgvMisxKSB7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX1NJWkVXRSkpOwoJCQkJCXJldHVybiBUUlVFOwoJCQkJfQoJCQl9CgkJCWdvdG8gZGVmOwoKCQljYXNlIFdNX0xCVVRUT05ET1dOOiB7CgkJCVJFQ1QgcnQ7CgkJCWludCB4ID0gR0VUX1hfTFBBUkFNKGxwYXJhbSk7CgoJCQlHZXRDbGllbnRSZWN0KGh3bmQsICZydCk7CgoJCQlpZiAoeD49Y2hpbGQtPnNwbGl0X3Bvcy1TUExJVF9XSURUSC8yICYmIHg8Y2hpbGQtPnNwbGl0X3BvcytTUExJVF9XSURUSC8yKzEpIHsKCQkJCWxhc3Rfc3BsaXQgPSBjaGlsZC0+c3BsaXRfcG9zOwojaWZkZWYgX05PX0VYVEVOU0lPTlMKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbmRpZgoJCQkJU2V0Q2FwdHVyZShod25kKTsKCQkJfQoKCQkJYnJlYWs7fQoKCQljYXNlIFdNX0xCVVRUT05VUDoKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJUkVDVCBydDsKCQkJCWludCB4ID0gTE9XT1JEKGxwYXJhbSk7CgkJCQlkcmF3X3NwbGl0YmFyKGh3bmQsIGxhc3Rfc3BsaXQpOwoJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IHg7CgkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CiNlbmRpZgoJCQkJUmVsZWFzZUNhcHR1cmUoKTsKCQkJfQoJCQlicmVhazsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fQ0FQVFVSRUNIQU5HRUQ6CgkJCWlmIChHZXRDYXB0dXJlKCk9PWh3bmQgJiYgbGFzdF9zcGxpdD49MCkKCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CgkJCWJyZWFrOwojZW5kaWYKCgkJY2FzZSBXTV9LRVlET1dOOgoJCQlpZiAod3BhcmFtID09IFZLX0VTQ0FQRSkKCQkJCWlmIChHZXRDYXB0dXJlKCkgPT0gaHduZCkgewoJCQkJCVJFQ1QgcnQ7CiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJCWRyYXdfc3BsaXRiYXIoaHduZCwgbGFzdF9zcGxpdCk7CiNlbHNlCgkJCQkJY2hpbGQtPnNwbGl0X3BvcyA9IGxhc3Rfc3BsaXQ7CiNlbmRpZgoJCQkJCUdldENsaWVudFJlY3QoaHduZCwgJnJ0KTsKCQkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CgkJCQkJbGFzdF9zcGxpdCA9IC0xOwoJCQkJCVJlbGVhc2VDYXB0dXJlKCk7CgkJCQkJU2V0Q3Vyc29yKExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKSk7CgkJCQl9CgkJCWJyZWFrOwoKCQljYXNlIFdNX01PVVNFTU9WRToKCQkJaWYgKEdldENhcHR1cmUoKSA9PSBod25kKSB7CgkJCQlSRUNUIHJ0OwoJCQkJaW50IHggPSBMT1dPUkQobHBhcmFtKTsKCiNpZmRlZiBfTk9fRVhURU5TSU9OUwoJCQkJSERDIGhkYyA9IEdldERDKGh3bmQpOwoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJCXJ0LmxlZnQgPSBsYXN0X3NwbGl0LVNQTElUX1dJRFRILzI7CgkJCQlydC5yaWdodCA9IGxhc3Rfc3BsaXQrU1BMSVRfV0lEVEgvMisxOwoJCQkJSW52ZXJ0UmVjdChoZGMsICZydCk7CgoJCQkJbGFzdF9zcGxpdCA9IHg7CgkJCQlydC5sZWZ0ID0geC1TUExJVF9XSURUSC8yOwoJCQkJcnQucmlnaHQgPSB4K1NQTElUX1dJRFRILzIrMTsKCQkJCUludmVydFJlY3QoaGRjLCAmcnQpOwoKCQkJCVJlbGVhc2VEQyhod25kLCBoZGMpOwojZWxzZQoJCQkJR2V0Q2xpZW50UmVjdChod25kLCAmcnQpOwoKCQkJCWlmICh4Pj0wICYmIHg8cnQucmlnaHQpIHsKCQkJCQljaGlsZC0+c3BsaXRfcG9zID0geDsKCQkJCQlyZXNpemVfdHJlZShjaGlsZCwgcnQucmlnaHQsIHJ0LmJvdHRvbSk7CgkJCQkJcnQubGVmdCA9IHgtU1BMSVRfV0lEVEgvMjsKCQkJCQlydC5yaWdodCA9IHgrU1BMSVRfV0lEVEgvMisxOwoJCQkJCUludmFsaWRhdGVSZWN0KGh3bmQsICZydCwgRkFMU0UpOwoJCQkJCVVwZGF0ZVdpbmRvdyhjaGlsZC0+bGVmdC5od25kKTsKCQkJCQlVcGRhdGVXaW5kb3coaHduZCk7CgkJCQkJVXBkYXRlV2luZG93KGNoaWxkLT5yaWdodC5od25kKTsKCQkJCX0KI2VuZGlmCgkJCX0KCQkJYnJlYWs7CgojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9HRVRNSU5NQVhJTkZPOgoJCQlEZWZNRElDaGlsZFByb2MoaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwoKCQkJe0xQTUlOTUFYSU5GTyBscG1taSA9IChMUE1JTk1BWElORk8pbHBhcmFtOwoKCQkJbHBtbWktPnB0TWF4VHJhY2tTaXplLnggPDw9IDE7LyoyKkdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pIC8gU01fQ1hWSVJUVUFMU0NSRUVOICovCgkJCWxwbW1pLT5wdE1heFRyYWNrU2l6ZS55IDw8PSAxOy8qMipHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSAvIFNNX0NZVklSVFVBTFNDUkVFTiAqLwoJCQlicmVhazt9CiNlbmRpZiAvKiBfTk9fRVhURU5TSU9OUyAqLwoKCQljYXNlIFdNX1NFVEZPQ1VTOgoJCQlpZiAoU2V0Q3VycmVudERpcmVjdG9yeShjaGlsZC0+cGF0aCkpCgkJCQlzZXRfc3BhY2Vfc3RhdHVzKCk7CgkJCVNldEZvY3VzKGNoaWxkLT5mb2N1c19wYW5lPyBjaGlsZC0+cmlnaHQuaHduZDogY2hpbGQtPmxlZnQuaHduZCk7CgkJCWJyZWFrOwoKCQljYXNlIFdNX0RJU1BBVENIX0NPTU1BTkQ6IHsKCQkJUGFuZSogcGFuZSA9IEdldEZvY3VzKCk9PWNoaWxkLT5sZWZ0Lmh3bmQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodDsKCgkJCXN3aXRjaChMT1dPUkQod3BhcmFtKSkgewoJCQkJY2FzZSBJRF9XSU5ET1dfTkVXOiB7CgkJCQkJQ2hpbGRXbmQqIG5ld19jaGlsZCA9IGFsbG9jX2NoaWxkX3dpbmRvdyhjaGlsZC0+cGF0aCwgTlVMTCwgaHduZCk7CgoJCQkJCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhuZXdfY2hpbGQpKQoJCQkJCQlmcmVlKG5ld19jaGlsZCk7CgoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1JFRlJFU0g6CgkJCQkJcmVmcmVzaF9kcml2ZXMoKTsKCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0FDVElWQVRFOgoJCQkJCWFjdGl2YXRlX2VudHJ5KGNoaWxkLCBwYW5lLCBod25kKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX0ZJTEVfTU9WRTogewoJCQkJCVRDSEFSIHNvdXJjZVtCVUZGRVJfTEVOXSwgdGFyZ2V0W0JVRkZFUl9MRU5dOwoKCQkJCQlpZiAocHJvbXB0X3RhcmdldChwYW5lLCBzb3VyY2UsIHRhcmdldCkpIHsKCQkJCQkJU0hGSUxFT1BTVFJVQ1Qgc2hmbyA9IHtod25kLCBGT19NT1ZFLCBzb3VyY2UsIHRhcmdldH07CgoJCQkJCQlzb3VyY2VbbHN0cmxlbihzb3VyY2UpKzFdID0gJ1wwJzsKCQkJCQkJdGFyZ2V0W2xzdHJsZW4odGFyZ2V0KSsxXSA9ICdcMCc7CgoJCQkJCQlpZiAoIVNIRmlsZU9wZXJhdGlvbigmc2hmbykpCgkJCQkJCQlyZWZyZXNoX2NoaWxkKGNoaWxkKTsKCQkJCQl9CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgSURfRklMRV9DT1BZOiB7CgkJCQkJVENIQVIgc291cmNlW0JVRkZFUl9MRU5dLCB0YXJnZXRbQlVGRkVSX0xFTl07CgoJCQkJCWlmIChwcm9tcHRfdGFyZ2V0KHBhbmUsIHNvdXJjZSwgdGFyZ2V0KSkgewoJCQkJCQlTSEZJTEVPUFNUUlVDVCBzaGZvID0ge2h3bmQsIEZPX0NPUFksIHNvdXJjZSwgdGFyZ2V0fTsKCgkJCQkJCXNvdXJjZVtsc3RybGVuKHNvdXJjZSkrMV0gPSAnXDAnOwoJCQkJCQl0YXJnZXRbbHN0cmxlbih0YXJnZXQpKzFdID0gJ1wwJzsKCgkJCQkJCWlmICghU0hGaWxlT3BlcmF0aW9uKCZzaGZvKSkKCQkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9GSUxFX0RFTEVURTogewoJCQkJCVRDSEFSIHBhdGhbQlVGRkVSX0xFTl07CgkJCQkJU0hGSUxFT1BTVFJVQ1Qgc2hmbyA9IHtod25kLCBGT19ERUxFVEUsIHBhdGh9OwoKCQkJCQlnZXRfcGF0aChwYW5lLT5jdXIsIHBhdGgpOwoKCQkJCQlwYXRoW2xzdHJsZW4ocGF0aCkrMV0gPSAnXDAnOwoKCQkJCQlpZiAoIVNIRmlsZU9wZXJhdGlvbigmc2hmbykpCgkJCQkJCXJlZnJlc2hfY2hpbGQoY2hpbGQpOwoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1ZJRVdfU09SVF9OQU1FOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX05BTUUpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX1RZUEU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfRVhUKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIElEX1ZJRVdfU09SVF9TSVpFOgoJCQkJCXNldF9zb3J0X29yZGVyKGNoaWxkLCBTT1JUX1NJWkUpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURfVklFV19TT1JUX0RBVEU6CgkJCQkJc2V0X3NvcnRfb3JkZXIoY2hpbGQsIFNPUlRfREFURSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBJRF9WSUVXX0ZJTFRFUjogewoJCQkJCXN0cnVjdCBGaWx0ZXJEaWFsb2cgZGxnOwoKCQkJCQltZW1zZXQoJmRsZywgMCwgc2l6ZW9mKHN0cnVjdCBGaWx0ZXJEaWFsb2cpKTsKCQkJCQlfdGNzY3B5KGRsZy5wYXR0ZXJuLCBjaGlsZC0+ZmlsdGVyX3BhdHRlcm4pOwoJCQkJCWRsZy5mbGFncyA9IGNoaWxkLT5maWx0ZXJfZmxhZ3M7CgoJCQkJCWlmIChEaWFsb2dCb3hQYXJhbShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElERF9ESUFMT0dfVklFV19UWVBFKSwgaHduZCwgRmlsdGVyRGlhbG9nRGxnUHJvYywgKExQQVJBTSkmZGxnKSA9PSBJRE9LKSB7CgkJCQkJCV90Y3NjcHkoY2hpbGQtPmZpbHRlcl9wYXR0ZXJuLCBkbGcucGF0dGVybik7CgkJCQkJCWNoaWxkLT5maWx0ZXJfZmxhZ3MgPSBkbGcuZmxhZ3M7CgkJCQkJCXJlZnJlc2hfcmlnaHRfcGFuZShjaGlsZCk7CgkJCQkJfQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIElEX1ZJRVdfU1BMSVQ6IHsKCQkJCQlsYXN0X3NwbGl0ID0gY2hpbGQtPnNwbGl0X3BvczsKI2lmZGVmIF9OT19FWFRFTlNJT05TCgkJCQkJZHJhd19zcGxpdGJhcihod25kLCBsYXN0X3NwbGl0KTsKI2VuZGlmCgkJCQkJU2V0Q2FwdHVyZShod25kKTsKCQkJCQlicmVhazt9CgoJCQkJY2FzZSBJRF9FRElUX1BST1BFUlRJRVM6CgkJCQkJc2hvd19wcm9wZXJ0aWVzX2RsZyhwYW5lLT5jdXIsIGNoaWxkLT5od25kKTsKCQkJCQlicmVhazsKCgkJCQlkZWZhdWx0OgoJCQkJCXJldHVybiBwYW5lX2NvbW1hbmQocGFuZSwgTE9XT1JEKHdwYXJhbSkpOwoJCQl9CgoJCQlyZXR1cm4gVFJVRTt9CgoJCWNhc2UgV01fQ09NTUFORDogewoJCQlQYW5lKiBwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoKCQkJc3dpdGNoKEhJV09SRCh3cGFyYW0pKSB7CgkJCQljYXNlIExCTl9TRUxDSEFOR0U6IHsKCQkJCQlpbnQgaWR4ID0gTGlzdEJveF9HZXRDdXJTZWwocGFuZS0+aHduZCk7CgkJCQkJRW50cnkqIGVudHJ5ID0gKEVudHJ5KikgTGlzdEJveF9HZXRJdGVtRGF0YShwYW5lLT5od25kLCBpZHgpOwoKCQkJCQlpZiAocGFuZSA9PSAmY2hpbGQtPmxlZnQpCgkJCQkJCXNldF9jdXJkaXIoY2hpbGQsIGVudHJ5LCBpZHgsIGh3bmQpOwoJCQkJCWVsc2UKCQkJCQkJcGFuZS0+Y3VyID0gZW50cnk7CgkJCQkJYnJlYWs7fQoKCQkJCWNhc2UgTEJOX0RCTENMSzoKCQkJCQlhY3RpdmF0ZV9lbnRyeShjaGlsZCwgcGFuZSwgaHduZCk7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7fQoKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJCWNhc2UgV01fTk9USUZZOiB7CgkJCU5NSERSKiBwbm1oID0gKE5NSERSKikgbHBhcmFtOwoJCQlyZXR1cm4gcGFuZV9ub3RpZnkocG5taC0+aWRGcm9tPT1JRFdfSEVBREVSX0xFRlQ/ICZjaGlsZC0+bGVmdDogJmNoaWxkLT5yaWdodCwgcG5taCk7fQojZW5kaWYKCiNpZmRlZiBfU0hFTExfRk9MREVSUwoJCWNhc2UgV01fQ09OVEVYVE1FTlU6IHsKCQkJUE9JTlQgcHQsIHB0X2NsbnQ7CgkJCVBhbmUqIHBhbmU7CgkJCWludCBpZHg7CgoJCQkgLyogZmlyc3Qgc2VsZWN0IHRoZSBjdXJyZW50IGl0ZW0gaW4gdGhlIGxpc3Rib3ggKi8KCQkJSFdORCBocGFuZWwgPSAoSFdORCkgd3BhcmFtOwoJCQlwdF9jbG50LnggPSBwdC54ID0gKHNob3J0KUxPV09SRChscGFyYW0pOwoJCQlwdF9jbG50LnkgPSBwdC55ID0gKHNob3J0KUhJV09SRChscGFyYW0pOwoJCQlTY3JlZW5Ub0NsaWVudChocGFuZWwsICZwdF9jbG50KTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9ORE9XTiwgMCwgTUFLRUxPTkcocHRfY2xudC54LCBwdF9jbG50LnkpKTsKCQkJU2VuZE1lc3NhZ2UoaHBhbmVsLCBXTV9MQlVUVE9OVVAsIDAsIE1BS0VMT05HKHB0X2NsbnQueCwgcHRfY2xudC55KSk7CgoJCQkgLyogbm93IGNyZWF0ZSB0aGUgcG9wdXAgbWVudSB1c2luZyBzaGVsbCBuYW1lc3BhY2UgYW5kIElDb250ZXh0TWVudSAqLwoJCQlwYW5lID0gR2V0Rm9jdXMoKT09Y2hpbGQtPmxlZnQuaHduZD8gJmNoaWxkLT5sZWZ0OiAmY2hpbGQtPnJpZ2h0OwoJCQlpZHggPSBMaXN0Qm94X0dldEN1clNlbChwYW5lLT5od25kKTsKCgkJCWlmIChpZHggIT0gLTEpIHsKCQkJCUVudHJ5KiBlbnRyeSA9IChFbnRyeSopIExpc3RCb3hfR2V0SXRlbURhdGEocGFuZS0+aHduZCwgaWR4KTsKCgkJCQlMUElURU1JRExJU1QgcGlkbF9hYnMgPSBnZXRfdG9fYWJzb2x1dGVfcGlkbChlbnRyeSwgaHduZCk7CgoJCQkJaWYgKHBpZGxfYWJzKSB7CgkJCQkJSVNoZWxsRm9sZGVyKiBwYXJlbnRGb2xkZXI7CgkJCQkJTFBDSVRFTUlETElTVCBwaWRsTGFzdDsKCgkJCQkJIC8qIGdldCBhbmQgdXNlIHRoZSBwYXJlbnQgZm9sZGVyIHRvIGRpc3BsYXkgY29ycmVjdCBjb250ZXh0IG1lbnUgaW4gYWxsIGNhc2VzICovCgkJCQkJaWYgKFNVQ0NFRURFRChTSEJpbmRUb1BhcmVudChwaWRsX2FicywgJklJRF9JU2hlbGxGb2xkZXIsIChMUFZPSUQqKSZwYXJlbnRGb2xkZXIsICZwaWRsTGFzdCkpKSB7CgkJCQkJCWlmIChTaGVsbEZvbGRlckNvbnRleHRNZW51KHBhcmVudEZvbGRlciwgaHduZCwgMSwgJnBpZGxMYXN0LCBwdC54LCBwdC55KSA9PSBTX09LKQoJCQkJCQkJcmVmcmVzaF9jaGlsZChjaGlsZCk7CgoJCQkJCQkoKnBhcmVudEZvbGRlci0+bHBWdGJsLT5SZWxlYXNlKShwYXJlbnRGb2xkZXIpOwoJCQkJCX0KCgkJCQkJKCpHbG9iYWxzLmlNYWxsb2MtPmxwVnRibC0+RnJlZSkoR2xvYmFscy5pTWFsbG9jLCBwaWRsX2Ficyk7CgkJCQl9CgkJCX0KCQkJYnJlYWs7fQojZW5kaWYKCgkJICBjYXNlIFdNX01FQVNVUkVJVEVNOgoJCSAgZHJhd19tZW51X2l0ZW06CgkJCWlmICghd3BhcmFtKQkvKiBJcyB0aGUgbWVzc2FnZSBtZW51LXJlbGF0ZWQ/ICovCgkJCQlpZiAoQ3R4TWVudV9IYW5kbGVNZW51TXNnKG5tc2csIHdwYXJhbSwgbHBhcmFtKSkKCQkJCQlyZXR1cm4gVFJVRTsKCgkJCWJyZWFrOwoKCQkgIGNhc2UgV01fSU5JVE1FTlVQT1BVUDoKCQkJaWYgKEN0eE1lbnVfSGFuZGxlTWVudU1zZyhubXNnLCB3cGFyYW0sIGxwYXJhbSkpCgkJCQlyZXR1cm4gMDsKCgkJCXVwZGF0ZV92aWV3X21lbnUoY2hpbGQpOwoJCQlicmVhazsKCgkJICBjYXNlIFdNX01FTlVDSEFSOgkvKiBvbmx5IHN1cHBvcnRlZCBieSBJQ29udGV4dE1lbnUzICovCgkJICAgaWYgKHNfcGN0eG1lbnUzKSB7CgkJCSAgIExSRVNVTFQgbFJlc3VsdCA9IDA7CgoJCQkgICAoKnNfcGN0eG1lbnUzLT5scFZ0YmwtPkhhbmRsZU1lbnVNc2cyKShzX3BjdHhtZW51Mywgbm1zZywgd3BhcmFtLCBscGFyYW0sICZsUmVzdWx0KTsKCgkJCSAgIHJldHVybiBsUmVzdWx0OwoJCSAgIH0KCgkJICAgYnJlYWs7CgoJCWNhc2UgV01fU0laRToKCQkJaWYgKHdwYXJhbSAhPSBTSVpFX01JTklNSVpFRCkKCQkJCXJlc2l6ZV90cmVlKGNoaWxkLCBMT1dPUkQobHBhcmFtKSwgSElXT1JEKGxwYXJhbSkpOwoJCQkvKiBmYWxsIHRocm91Z2ggKi8KCgkJZGVmYXVsdDogZGVmOgoJCQlyZXR1cm4gRGVmTURJQ2hpbGRQcm9jKGh3bmQsIG5tc2csIHdwYXJhbSwgbHBhcmFtKTsKCX0KCglyZXR1cm4gMDsKfQoKCkxSRVNVTFQgQ0FMTEJBQ0sgVHJlZVduZFByb2MoSFdORCBod25kLCBVSU5UIG5tc2csIFdQQVJBTSB3cGFyYW0sIExQQVJBTSBscGFyYW0pCnsKCUNoaWxkV25kKiBjaGlsZCA9IChDaGlsZFduZCopIEdldFdpbmRvd0xvbmcoR2V0UGFyZW50KGh3bmQpLCBHV0xfVVNFUkRBVEEpOwoJUGFuZSogcGFuZSA9IChQYW5lKikgR2V0V2luZG93TG9uZyhod25kLCBHV0xfVVNFUkRBVEEpOwoJQVNTRVJUKGNoaWxkKTsKCglzd2l0Y2gobm1zZykgewojaWZuZGVmIF9OT19FWFRFTlNJT05TCgkJY2FzZSBXTV9IU0NST0xMOgoJCQlzZXRfaGVhZGVyKHBhbmUpOwoJCQlicmVhazsKI2VuZGlmCgoJCWNhc2UgV01fU0VURk9DVVM6CgkJCWNoaWxkLT5mb2N1c19wYW5lID0gcGFuZT09JmNoaWxkLT5yaWdodD8gMTogMDsKCQkJTGlzdEJveF9TZXRTZWwoaHduZCwgVFJVRSwgMSk7CgkJCS8qVE9ETzogY2hlY2sgbWVudSBpdGVtcyAqLwoJCQlicmVhazsKCgkJY2FzZSBXTV9LRVlET1dOOgoJCQlpZiAod3BhcmFtID09IFZLX1RBQikgewoJCQkJLypUT0RPOiBTZXRGb2N1cyhHbG9iYWxzLmhkcml2ZWJhcikgKi8KCQkJCVNldEZvY3VzKGNoaWxkLT5mb2N1c19wYW5lPyBjaGlsZC0+bGVmdC5od25kOiBjaGlsZC0+cmlnaHQuaHduZCk7CgkJCX0KCX0KCglyZXR1cm4gQ2FsbFdpbmRvd1Byb2MoZ19vcmdUcmVlV25kUHJvYywgaHduZCwgbm1zZywgd3BhcmFtLCBscGFyYW0pOwp9CgoKc3RhdGljIHZvaWQgSW5pdEluc3RhbmNlKEhJTlNUQU5DRSBoaW5zdGFuY2UpCnsKCWNvbnN0IHN0YXRpYyBUQ0hBUiBzRm9udFtdID0geydNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCcgJywnUycsJ2EnLCduJywncycsJyAnLCdTJywnZScsJ3InLCdpJywnZicsJ1wwJ307CgoJV05EQ0xBU1NFWCB3Y0ZyYW1lOwoJV05EQ0xBU1Mgd2NDaGlsZDsKCUFUT00gaENoaWxkQ2xhc3M7CglpbnQgY29sOwoKCUlOSVRDT01NT05DT05UUk9MU0VYIGljYyA9IHsKCQlzaXplb2YoSU5JVENPTU1PTkNPTlRST0xTRVgpLAoJCUlDQ19CQVJfQ0xBU1NFUwoJfTsKCglIREMgaGRjID0gR2V0REMoMCk7CgoJc2V0bG9jYWxlKExDX0NPTExBVEUsICIiKTsJLyogc2V0IGNvbGxhdGluZyBydWxlcyB0byBsb2NhbCBzZXR0aW5ncyBmb3IgY29tcGFyZU5hbWUgKi8KCglJbml0Q29tbW9uQ29udHJvbHNFeCgmaWNjKTsKCgoJLyogcmVnaXN0ZXIgZnJhbWUgd2luZG93IGNsYXNzICovCgoJd2NGcmFtZS5jYlNpemUgICAgICAgID0gc2l6ZW9mKFdORENMQVNTRVgpOwoJd2NGcmFtZS5zdHlsZSAgICAgICAgID0gMDsKCXdjRnJhbWUubHBmblduZFByb2MgICA9IEZyYW1lV25kUHJvYzsKCXdjRnJhbWUuY2JDbHNFeHRyYSAgICA9IDA7Cgl3Y0ZyYW1lLmNiV25kRXh0cmEgICAgPSAwOwoJd2NGcmFtZS5oSW5zdGFuY2UgICAgID0gaGluc3RhbmNlOwoJd2NGcmFtZS5oSWNvbiAgICAgICAgID0gTG9hZEljb24oaGluc3RhbmNlLCBNQUtFSU5UUkVTT1VSQ0UoSURJX1dJTkVGSUxFKSk7Cgl3Y0ZyYW1lLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7Cgl3Y0ZyYW1lLmhickJhY2tncm91bmQgPSAwOwoJd2NGcmFtZS5scHN6TWVudU5hbWUgID0gMDsKCXdjRnJhbWUubHBzekNsYXNzTmFtZSA9IHNXSU5FRklMRUZSQU1FOwoJd2NGcmFtZS5oSWNvblNtICAgICAgID0gKEhJQ09OKUxvYWRJbWFnZShoaW5zdGFuY2UsCgkJCQkJCQkJCQkJIE1BS0VJTlRSRVNPVVJDRShJRElfV0lORUZJTEUpLAoJCQkJCQkJCQkJCSBJTUFHRV9JQ09OLAoJCQkJCQkJCQkJCSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSwKCQkJCQkJCQkJCQkgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksCgkJCQkJCQkJCQkJIExSX1NIQVJFRCk7CgoJR2xvYmFscy5oZnJhbWVDbGFzcyA9IFJlZ2lzdGVyQ2xhc3NFeCgmd2NGcmFtZSk7CgoKCS8qIHJlZ2lzdGVyIHRyZWUgd2luZG93cyBjbGFzcyAqLwoKCXdjQ2hpbGQuc3R5bGUgICAgICAgICA9IENTX0NMQVNTREN8Q1NfREJMQ0xLU3xDU19WUkVEUkFXOwoJd2NDaGlsZC5scGZuV25kUHJvYyAgID0gQ2hpbGRXbmRQcm9jOwoJd2NDaGlsZC5jYkNsc0V4dHJhICAgID0gMDsKCXdjQ2hpbGQuY2JXbmRFeHRyYSAgICA9IDA7Cgl3Y0NoaWxkLmhJbnN0YW5jZSAgICAgPSBoaW5zdGFuY2U7Cgl3Y0NoaWxkLmhJY29uICAgICAgICAgPSAwOwoJd2NDaGlsZC5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvcigwLCBJRENfQVJST1cpOwoJd2NDaGlsZC5oYnJCYWNrZ3JvdW5kID0gMDsKCXdjQ2hpbGQubHBzek1lbnVOYW1lICA9IDA7Cgl3Y0NoaWxkLmxwc3pDbGFzc05hbWUgPSBzV0lORUZJTEVUUkVFOwoKCWhDaGlsZENsYXNzID0gUmVnaXN0ZXJDbGFzcygmd2NDaGlsZCk7CgoKCUdsb2JhbHMuaGFjY2VsID0gTG9hZEFjY2VsZXJhdG9ycyhoaW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREFfV0lORUZJTEUpKTsKCglHbG9iYWxzLmhmb250ID0gQ3JlYXRlRm9udCgtTXVsRGl2KDgsR2V0RGV2aWNlQ2FwcyhoZGMsTE9HUElYRUxTWSksNzIpLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCBzRm9udCk7CgoJUmVsZWFzZURDKDAsIGhkYyk7CgoJR2xvYmFscy5oSW5zdGFuY2UgPSBoaW5zdGFuY2U7CgojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCUNvSW5pdGlhbGl6ZShOVUxMKTsKCUNvR2V0TWFsbG9jKE1FTUNUWF9UQVNLLCAmR2xvYmFscy5pTWFsbG9jKTsKCVNIR2V0RGVza3RvcEZvbGRlcigmR2xvYmFscy5pRGVza3RvcCk7CiNpZmRlZiBfX1dJTkVfXwoJR2xvYmFscy5jZlN0ckZOYW1lID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXRBKENGU1RSX0ZJTEVOQU1FKTsKI2Vsc2UKCUdsb2JhbHMuY2ZTdHJGTmFtZSA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0KENGU1RSX0ZJTEVOQU1FKTsKI2VuZGlmCiNlbmRpZgoKCS8qIGxvYWQgY29sdW1uIHN0cmluZ3MgKi8KCWNvbCA9IDE7CgoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX05BTUUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX1NJWkUpOwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0NEQVRFKTsKI2lmbmRlZiBfTk9fRVhURU5TSU9OUwoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0FEQVRFKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9NREFURSk7Cglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfSURYKTsKCWxvYWRfc3RyaW5nKGdfcG9zX25hbWVzW2NvbCsrXSwgSURTX0NPTF9MSU5LUyk7CiNlbmRpZgoJbG9hZF9zdHJpbmcoZ19wb3NfbmFtZXNbY29sKytdLCBJRFNfQ09MX0FUVFIpOwojaWZuZGVmIF9OT19FWFRFTlNJT05TCglsb2FkX3N0cmluZyhnX3Bvc19uYW1lc1tjb2wrK10sIElEU19DT0xfU0VDKTsKI2VuZGlmCn0KCgp2b2lkIHNob3dfZnJhbWUoSFdORCBod25kUGFyZW50LCBpbnQgY21kc2hvdykKewoJY29uc3Qgc3RhdGljIFRDSEFSIHNNRElDTElFTlRbXSA9IHsnTScsJ0QnLCdJJywnQycsJ0wnLCdJJywnRScsJ04nLCdUJywnXDAnfTsKCglUQ0hBUiBwYXRoW01BWF9QQVRIXSwgYjFbQlVGRkVSX0xFTl07CglDaGlsZFduZCogY2hpbGQ7CglITUVOVSBoTWVudUZyYW1lLCBoTWVudVdpbmRvdzsKCglDTElFTlRDUkVBVEVTVFJVQ1QgY2NzOwoKCWlmIChHbG9iYWxzLmhNYWluV25kKQoJCXJldHVybjsKCglHbG9iYWxzLmh3bmRQYXJlbnQgPSBod25kUGFyZW50OwoKCWhNZW51RnJhbWUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKElETV9XSU5FRklMRSkpOwoJaE1lbnVXaW5kb3cgPSBHZXRTdWJNZW51KGhNZW51RnJhbWUsIEdldE1lbnVJdGVtQ291bnQoaE1lbnVGcmFtZSktMik7CgoJR2xvYmFscy5oTWVudUZyYW1lID0gaE1lbnVGcmFtZTsKCUdsb2JhbHMuaE1lbnVWaWV3ID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCAzKTsKCUdsb2JhbHMuaE1lbnVPcHRpb25zID0gR2V0U3ViTWVudShoTWVudUZyYW1lLCA0KTsKCgljY3MuaFdpbmRvd01lbnUgID0gaE1lbnVXaW5kb3c7CgljY3MuaWRGaXJzdENoaWxkID0gSURXX0ZJUlNUX0NISUxEOwoKCgkvKiBjcmVhdGUgbWFpbiB3aW5kb3cgKi8KCUdsb2JhbHMuaE1haW5XbmQgPSBDcmVhdGVXaW5kb3dFeCgwLCAoTFBDVFNUUikoaW50KUdsb2JhbHMuaGZyYW1lQ2xhc3MsIFJTKGIxLElEU19XSU5FX0ZJTEUpLCBXU19PVkVSTEFQUEVEV0lORE9XLAoJCQkJCUNXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsCgkJCQkJaHduZFBhcmVudCwgR2xvYmFscy5oTWVudUZyYW1lLCBHbG9iYWxzLmhJbnN0YW5jZSwgMC8qbHBQYXJhbSovKTsKCgoJR2xvYmFscy5obWRpY2xpZW50ID0gQ3JlYXRlV2luZG93RXgoMCwgc01ESUNMSUVOVCwgTlVMTCwKCQkJCQlXU19DSElMRHxXU19DTElQQ0hJTERSRU58V1NfVlNDUk9MTHxXU19IU0NST0xMfFdTX1ZJU0lCTEV8V1NfQk9SREVSLAoJCQkJCTAsIDAsIDAsIDAsCgkJCQkJR2xvYmFscy5oTWFpblduZCwgMCwgR2xvYmFscy5oSW5zdGFuY2UsICZjY3MpOwoKCglDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX0RSSVZFX0JBUiwgTUZfQllDT01NQU5EfE1GX0NIRUNLRUQpOwoKCWNyZWF0ZV9kcml2ZV9iYXIoKTsKCgl7CgkJVEJCVVRUT04gdG9vbGJhckJ0bnNbXSA9IHsKCQkJezAsIDAsIDAsIEJUTlNfU0VQLCB7MCwgMH0sIDAsIDB9LAoJCQl7MCwgSURfV0lORE9XX05FVywgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezEsIElEX1dJTkRPV19DQVNDQURFLCBUQlNUQVRFX0VOQUJMRUQsIEJUTlNfQlVUVE9OLCB7MCwgMH0sIDAsIDB9LAoJCQl7MiwgSURfV0lORE9XX1RJTEVfSE9SWiwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezMsIElEX1dJTkRPV19USUxFX1ZFUlQsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCi8qVE9ETwoJCQl7NCwgSURfLi4uICwgVEJTVEFURV9FTkFCTEVELCBCVE5TX0JVVFRPTiwgezAsIDB9LCAwLCAwfSwKCQkJezUsIElEXy4uLiAsIFRCU1RBVEVfRU5BQkxFRCwgQlROU19CVVRUT04sIHswLCAwfSwgMCwgMH0sCiovCQl9OwoKCQlHbG9iYWxzLmh0b29sYmFyID0gQ3JlYXRlVG9vbGJhckV4KEdsb2JhbHMuaE1haW5XbmQsIFdTX0NISUxEfFdTX1ZJU0lCTEUsCgkJCUlEV19UT09MQkFSLCAyLCBHbG9iYWxzLmhJbnN0YW5jZSwgSURCX1RPT0xCQVIsIHRvb2xiYXJCdG5zLAoJCQlzaXplb2YodG9vbGJhckJ0bnMpL3NpemVvZihUQkJVVFRPTiksIDE2LCAxNSwgMTYsIDE1LCBzaXplb2YoVEJCVVRUT04pKTsKCQlDaGVja01lbnVJdGVtKEdsb2JhbHMuaE1lbnVPcHRpb25zLCBJRF9WSUVXX1RPT0xfQkFSLCBNRl9CWUNPTU1BTkR8TUZfQ0hFQ0tFRCk7Cgl9CgoJR2xvYmFscy5oc3RhdHVzYmFyID0gQ3JlYXRlU3RhdHVzV2luZG93KFdTX0NISUxEfFdTX1ZJU0lCTEUsIDAsIEdsb2JhbHMuaE1haW5XbmQsIElEV19TVEFUVVNCQVIpOwoJQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhNZW51T3B0aW9ucywgSURfVklFV19TVEFUVVNCQVIsIE1GX0JZQ09NTUFORHxNRl9DSEVDS0VEKTsKCi8qIENyZWF0ZVN0YXR1c1dpbmRvdyBkb2VzIG5vdCBhY2NlcHQgV1NfQk9SREVSCglHbG9iYWxzLmhzdGF0dXNiYXIgPSBDcmVhdGVXaW5kb3dFeChXU19FWF9OT1BBUkVOVE5PVElGWSwgU1RBVFVTQ0xBU1NOQU1FLCAwLAoJCQkJCVdTX0NISUxEfFdTX1ZJU0lCTEV8V1NfQ0xJUFNJQkxJTkdTfFdTX0JPUkRFUnxDQ1NfTk9ESVZJREVSLCAwLDAsMCwwLAoJCQkJCUdsb2JhbHMuaE1haW5XbmQsIChITUVOVSlJRFdfU1RBVFVTQkFSLCBoaW5zdGFuY2UsIDApOyovCgoJLypUT0RPOiByZWFkIHBhdGhzIGFuZCB3aW5kb3cgcGxhY2VtZW50cyBmcm9tIHJlZ2lzdHJ5ICovCglHZXRDdXJyZW50RGlyZWN0b3J5KE1BWF9QQVRILCBwYXRoKTsKCglTaG93V2luZG93KEdsb2JhbHMuaE1haW5XbmQsIGNtZHNob3cpOwoKI2lmIGRlZmluZWQoX1NIRUxMX0ZPTERFUlMpICYmICFkZWZpbmVkKF9fV0lORV9fKQoJIC8qIFNoZWxsIE5hbWVzcGFjZSBhcyBkZWZhdWx0OiAqLwoJY2hpbGQgPSBhbGxvY19jaGlsZF93aW5kb3cocGF0aCwgZ2V0X3BhdGhfcGlkbChwYXRoLEdsb2JhbHMuaE1haW5XbmQpLCBHbG9iYWxzLmhNYWluV25kKTsKI2Vsc2UKCWNoaWxkID0gYWxsb2NfY2hpbGRfd2luZG93KHBhdGgsIE5VTEwsIEdsb2JhbHMuaE1haW5XbmQpOwojZW5kaWYKCgljaGlsZC0+cG9zLnNob3dDbWQgPSBTV19TSE9XTUFYSU1JWkVEOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLmxlZnQgPSAwOwoJY2hpbGQtPnBvcy5yY05vcm1hbFBvc2l0aW9uLnRvcCA9IDA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24ucmlnaHQgPSAzMjA7CgljaGlsZC0+cG9zLnJjTm9ybWFsUG9zaXRpb24uYm90dG9tID0gMjgwOwoKCWlmICghY3JlYXRlX2NoaWxkX3dpbmRvdyhjaGlsZCkpCgkJZnJlZShjaGlsZCk7CgoJU2V0V2luZG93UGxhY2VtZW50KGNoaWxkLT5od25kLCAmY2hpbGQtPnBvcyk7CgoJR2xvYmFscy5oaW1sID0gSW1hZ2VMaXN0X0xvYWRCaXRtYXAoR2xvYmFscy5oSW5zdGFuY2UsIE1BS0VJTlRSRVNPVVJDRShJREJfSU1BR0VTKSwgMTYsIDAsIFJHQigwLDI1NSwwKSk7CgoJR2xvYmFscy5wcmVzY2FuX25vZGUgPSBGQUxTRTsKCglVcGRhdGVXaW5kb3coR2xvYmFscy5oTWFpblduZCk7Cn0KCnZvaWQgRXhpdEluc3RhbmNlKCkKewojaWZkZWYgX1NIRUxMX0ZPTERFUlMKCSgqR2xvYmFscy5pRGVza3RvcC0+bHBWdGJsLT5SZWxlYXNlKShHbG9iYWxzLmlEZXNrdG9wKTsKCSgqR2xvYmFscy5pTWFsbG9jLT5scFZ0YmwtPlJlbGVhc2UpKEdsb2JhbHMuaU1hbGxvYyk7CglDb1VuaW5pdGlhbGl6ZSgpOwojZW5kaWYKCglJbWFnZUxpc3RfRGVzdHJveShHbG9iYWxzLmhpbWwpOwp9CgoKLyogc2VhcmNoIGZvciBhbHJlYWR5IHJ1bm5pbmcgd2luW2VdZmlsZXMgKi8KCnN0YXRpYyBpbnQgZ19mb3VuZFByZXZJbnN0YW5jZSA9IDA7CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBFbnVtV25kUHJvYyhIV05EIGh3bmQsIExQQVJBTSBscGFyYW0pCnsKCVRDSEFSIGNsc1sxMjhdOwoKCUdldENsYXNzTmFtZShod25kLCBjbHMsIDEyOCk7CgoJaWYgKCFsc3RyY21wKGNscywgKExQQ1RTVFIpbHBhcmFtKSkgewoJCWdfZm91bmRQcmV2SW5zdGFuY2UrKzsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qIHNlYXJjaCBmb3Igd2luZG93IG9mIGdpdmVuIGNsYXNzIG5hbWUgdG8gYWxsb3cgb25seSBvbmUgcnVubmluZyBpbnN0YW5jZSAqLwppbnQgZmluZF93aW5kb3dfY2xhc3MoTFBDVFNUUiBjbGFzc25hbWUpCnsKCUVudW1XaW5kb3dzKEVudW1XbmRQcm9jLCAoTFBBUkFNKWNsYXNzbmFtZSk7CgoJaWYgKGdfZm91bmRQcmV2SW5zdGFuY2UpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCgppbnQgd2luZWZpbGVfbWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLCBIV05EIGh3bmRQYXJlbnQsIGludCBjbWRzaG93KQp7CglNU0cgbXNnOwoKCUluaXRJbnN0YW5jZShoaW5zdGFuY2UpOwoKCWlmIChjbWRzaG93ID09IFNXX1NIT1dOT1JNQUwpCgkgICAgICAgIC8qVE9ETzogcmVhZCB3aW5kb3cgcGxhY2VtZW50IGZyb20gcmVnaXN0cnkgKi8KCQljbWRzaG93ID0gU1dfTUFYSU1JWkU7CgoJc2hvd19mcmFtZShod25kUGFyZW50LCBjbWRzaG93KTsKCgl3aGlsZShHZXRNZXNzYWdlKCZtc2csIDAsIDAsIDApKSB7CgkJaWYgKEdsb2JhbHMuaG1kaWNsaWVudCAmJiBUcmFuc2xhdGVNRElTeXNBY2NlbChHbG9iYWxzLmhtZGljbGllbnQsICZtc2cpKQoJCQljb250aW51ZTsKCgkJaWYgKEdsb2JhbHMuaE1haW5XbmQgJiYgVHJhbnNsYXRlQWNjZWxlcmF0b3IoR2xvYmFscy5oTWFpblduZCwgR2xvYmFscy5oYWNjZWwsICZtc2cpKQoJCQljb250aW51ZTsKCgkJVHJhbnNsYXRlTWVzc2FnZSgmbXNnKTsKCQlEaXNwYXRjaE1lc3NhZ2UoJm1zZyk7Cgl9CgoJRXhpdEluc3RhbmNlKCk7CgoJcmV0dXJuIG1zZy53UGFyYW07Cn0KCgppbnQgQVBJRU5UUlkgV2luTWFpbihISU5TVEFOQ0UgaGluc3RhbmNlLAoJCQkJCSBISU5TVEFOQ0UgcHJldmluc3RhbmNlLAoJCQkJCSBMUFNUUgkgICBjbWRsaW5lLAoJCQkJCSBpbnQJICAgY21kc2hvdykKewojaWZkZWYgX05PX0VYVEVOU0lPTlMKCWlmIChmaW5kX3dpbmRvd19jbGFzcyhzV0lORUZJTEVGUkFNRSkpCgkJcmV0dXJuIDE7CiNlbmRpZgoKCXdpbmVmaWxlX21haW4oaGluc3RhbmNlLCAwLCBjbWRzaG93KTsKCglyZXR1cm4gMDsKfQo=