LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKiAKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuICh3aXRoIHNvbWUgaGVscCBmcm9tIE1hcmN1cyBNZWlzc25lcikKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5jb24uaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAidmdhLmgiCiNpbmNsdWRlICJkZHJhdy5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZGRyYXcpOwoKc3RhdGljIElEaXJlY3REcmF3ICpscGRkcmF3ID0gTlVMTDsKc3RhdGljIElEaXJlY3REcmF3U3VyZmFjZSAqbHBkZHN1cmY7CnN0YXRpYyBJRGlyZWN0RHJhd1BhbGV0dGUgKmxwZGRwYWw7CnN0YXRpYyBERFNVUkZBQ0VERVNDIHNkZXNjOwpzdGF0aWMgTE9ORyB2Z2FfcmVmcmVzaDsKc3RhdGljIEhBTkRMRSBwb2xsX3RpbWVyOwoKc3RhdGljIGludCB2Z2Ffd2lkdGg7CnN0YXRpYyBpbnQgdmdhX2hlaWdodDsKc3RhdGljIGludCB2Z2FfZGVwdGg7CnN0YXRpYyBCWVRFIHZnYV90ZXh0X2F0dHI7CgpzdGF0aWMgQk9PTCB2Z2FfbW9kZV9pbml0aWFsaXplZCA9IEZBTFNFOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gdmdhX2xvY2sgPSBDUklUSUNBTF9TRUNUSU9OX0lOSVQoIlZHQSIpOwoKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKkRpcmVjdERyYXdDcmVhdGVQcm9jKShMUEdVSUQsTFBESVJFQ1REUkFXICosTFBVTktOT1dOKTsKc3RhdGljIERpcmVjdERyYXdDcmVhdGVQcm9jIHBEaXJlY3REcmF3Q3JlYXRlOwoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgVkdBX1BvbGwoIExQVk9JRCBhcmcsIERXT1JEIGxvdywgRFdPUkQgaGlnaCApOwoKLyoKICogRm9yIHNpbXBsaWNpdHksIEknbSBjcmVhdGluZyBhIHNlY29uZCBwYWxldHRlLgogKiAxNiBjb2xvciBhY2Nlc3NlcyB3aWxsIHVzZSB0aGVzZSBwb2ludGVycyBhbmQgaW5zZXJ0CiAqIGVudHJpZXMgZnJvbSB0aGUgNjQtY29sb3IgcGFsZXR0ZSBpbnRvIHRoZSBkZWZhdWx0CiAqIHBhbGV0dGUuICAgLS1Sb2JlcnQgJ0FkbWlyYWwnIENvZXltYW4KICovCgpzdGF0aWMgY2hhciB2Z2FfMTZfcGFsZXR0ZVsxN109ewogIDB4MDAsICAvKiAwIC0gQmxhY2sgICAgICAgICAqLwogIDB4MDEsICAvKiAxIC0gQmx1ZSAgICAgICAgICAqLwogIDB4MDIsICAvKiAyIC0gR3JlZW4gICAgICAgICAqLwogIDB4MDMsICAvKiAzIC0gQ3lhbiAgICAgICAgICAqLwogIDB4MDQsICAvKiA0IC0gUmVkICAgICAgICAgICAqLwogIDB4MDUsICAvKiA1IC0gTWFnZW50YSAgICAgICAqLwogIDB4MTQsICAvKiA2IC0gQnJvd24gICAgICAgICAqLwogIDB4MDcsICAvKiA3IC0gTGlnaHQgZ3JheSAgICAqLwogIDB4MzgsICAvKiA4IC0gRGFyayBncmF5ICAgICAqLwogIDB4MzksICAvKiA5IC0gTGlnaHQgYmx1ZSAgICAqLwogIDB4M2EsICAvKiBBIC0gTGlnaHQgZ3JlZW4gICAqLwogIDB4M2IsICAvKiBCIC0gTGlnaHQgY3lhbiAgICAqLwogIDB4M2MsICAvKiBDIC0gTGlnaHQgcmVkICAgICAqLwogIDB4M2QsICAvKiBEIC0gTGlnaHQgbWFnZW50YSAqLwogIDB4M2UsICAvKiBFIC0gWWVsbG93ICAgICAgICAqLwogIDB4M2YsICAvKiBGIC0gV2hpdGUgICAgICAgICAqLwogIDB4MDAgICAvKiBCb3JkZXIgQ29sb3IgICAgICAqLwp9OwoKc3RhdGljIFBBTEVUVEVFTlRSWSB2Z2FfZGVmX3BhbGV0dGVbMjU2XT17Ci8qIHJlZCAgZ3JlZW4gIGJsdWUgKi8KICB7MHgwMCwgMHgwMCwgMHgwMH0sIC8qIDAgLSBCbGFjayAqLwogIHsweDAwLCAweDAwLCAweDgwfSwgLyogMSAtIEJsdWUgKi8KICB7MHgwMCwgMHg4MCwgMHgwMH0sIC8qIDIgLSBHcmVlbiAqLwogIHsweDAwLCAweDgwLCAweDgwfSwgLyogMyAtIEN5YW4gKi8KICB7MHg4MCwgMHgwMCwgMHgwMH0sIC8qIDQgLSBSZWQgKi8KICB7MHg4MCwgMHgwMCwgMHg4MH0sIC8qIDUgLSBNYWdlbnRhICovCiAgezB4ODAsIDB4ODAsIDB4MDB9LCAvKiA2IC0gQnJvd24gKi8KICB7MHhDMCwgMHhDMCwgMHhDMH0sIC8qIDcgLSBMaWdodCBncmF5ICovCiAgezB4ODAsIDB4ODAsIDB4ODB9LCAvKiA4IC0gRGFyayBncmF5ICovCiAgezB4MDAsIDB4MDAsIDB4RkZ9LCAvKiA5IC0gTGlnaHQgYmx1ZSAqLwogIHsweDAwLCAweEZGLCAweDAwfSwgLyogQSAtIExpZ2h0IGdyZWVuICovCiAgezB4MDAsIDB4RkYsIDB4RkZ9LCAvKiBCIC0gTGlnaHQgY3lhbiAqLwogIHsweEZGLCAweDAwLCAweDAwfSwgLyogQyAtIExpZ2h0IHJlZCAqLwogIHsweEZGLCAweDAwLCAweEZGfSwgLyogRCAtIExpZ2h0IG1hZ2VudGEgKi8KICB7MHhGRiwgMHhGRiwgMHgwMH0sIC8qIEUgLSBZZWxsb3cgKi8KICB7MHhGRiwgMHhGRiwgMHhGRn0sIC8qIEYgLSBXaGl0ZSAqLwogIHswLDAsMH0gLyogRklYTUU6IGEgc2VyaWVzIG9mIGNvbnRpbnVvdXMgcmFpbmJvdyBodWVzIHNob3VsZCBmb2xsb3cgKi8KfTsKCi8qIAogKiAgIFRoaXMgcGFsZXR0ZSBpcyB0aGUgZG9zIGRlZmF1bHQsIGNvbnZlcnRlZCBmcm9tIDE4IGJpdCBjb2xvciB0byAyNC4gCiAqICAgICAgSXQgY29udGFpbnMgb25seSA2NCBlbnRyaWVzIG9mIGNvbG9ycy0tYWxsIG90aGVycyBhcmUgemVyb3MuCiAqICAgICAgICAgIC0tUm9iZXJ0ICdBZG1pcmFsJyBDb2V5bWFuCiAqLwpzdGF0aWMgUEFMRVRURUVOVFJZIHZnYV9kZWY2NF9wYWxldHRlWzI1Nl09ewovKiByZWQgIGdyZWVuICBibHVlICovCiAgezB4MDAsIDB4MDAsIDB4MDB9LCAvKiAweDAwICAgICAgQmxhY2sgICAgICAqLwogIHsweDAwLCAweDAwLCAweGFhfSwgLyogMHgwMSAgICAgIEJsdWUgICAgICAgKi8KICB7MHgwMCwgMHhhYSwgMHgwMH0sIC8qIDB4MDIgICAgICBHcmVlbiAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4YWF9LCAvKiAweDAzICAgICAgQ3lhbiAgICAgICAqLwogIHsweGFhLCAweDAwLCAweDAwfSwgLyogMHgwNCAgICAgIFJlZCAgICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHhhYX0sIC8qIDB4MDUgICAgICBNYWdlbnRhICAgICovCiAgezB4YWEsIDB4YWEsIDB4MDB9LCAvKiAweDA2ICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhhYX0sIC8qIDB4MDcgICAgICBMaWdodCBHcmF5ICovCiAgezB4MDAsIDB4MDAsIDB4NTV9LCAvKiAweDA4ICAgICAgKi8KICB7MHgwMCwgMHgwMCwgMHhmZn0sIC8qIDB4MDkgICAgICAqLwogIHsweDAwLCAweGFhLCAweDU1fSwgLyogMHgwYSAgICAgICovCiAgezB4MDAsIDB4YWEsIDB4ZmZ9LCAvKiAweDBiICAgICAgKi8KICB7MHhhYSwgMHgwMCwgMHg1NX0sIC8qIDB4MGMgICAgICAqLwogIHsweGFhLCAweDAwLCAweGZmfSwgLyogMHgwZCAgICAgICovCiAgezB4YWEsIDB4YWEsIDB4NTV9LCAvKiAweDBlICAgICAgKi8KICB7MHhhYSwgMHhhYSwgMHhmZn0sIC8qIDB4MGYgICAgICAqLwogIHsweDAwLCAweDU1LCAweDAwfSwgLyogMHgxMCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4YWF9LCAvKiAweDExICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHgwMH0sIC8qIDB4MTIgICAgICAqLwogIHsweDAwLCAweGZmLCAweGFhfSwgLyogMHgxMyAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4MDB9LCAvKiAweDE0ICAgICAgQnJvd24gICAgICAqLwogIHsweGFhLCAweDU1LCAweGFhfSwgLyogMHgxNSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4MDB9LCAvKiAweDE2ICAgICAgKi8KICB7MHhhYSwgMHhmZiwgMHhhYX0sIC8qIDB4MTcgICAgICAqLwogIHsweDAwLCAweDU1LCAweDU1fSwgLyogMHgxOCAgICAgICovCiAgezB4MDAsIDB4NTUsIDB4ZmZ9LCAvKiAweDE5ICAgICAgKi8KICB7MHgwMCwgMHhmZiwgMHg1NX0sIC8qIDB4MWEgICAgICAqLwogIHsweDAwLCAweGZmLCAweGZmfSwgLyogMHgxYiAgICAgICovCiAgezB4YWEsIDB4NTUsIDB4NTV9LCAvKiAweDFjICAgICAgKi8KICB7MHhhYSwgMHg1NSwgMHhmZn0sIC8qIDB4MWQgICAgICAqLwogIHsweGFhLCAweGZmLCAweDU1fSwgLyogMHgxZSAgICAgICovCiAgezB4YWEsIDB4ZmYsIDB4ZmZ9LCAvKiAweDFmICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHgwMH0sIC8qIDB4MjAgICAgICAqLwogIHsweDU1LCAweDAwLCAweGFhfSwgLyogMHgyMSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4MDB9LCAvKiAweDIyICAgICAgKi8KICB7MHg1NSwgMHhhYSwgMHhhYX0sIC8qIDB4MjMgICAgICAqLwogIHsweGZmLCAweDAwLCAweDAwfSwgLyogMHgyNCAgICAgICovCiAgezB4ZmYsIDB4MDAsIDB4YWF9LCAvKiAweDI1ICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHgwMH0sIC8qIDB4MjYgICAgICAqLwogIHsweGZmLCAweGFhLCAweGFhfSwgLyogMHgyNyAgICAgICovCiAgezB4NTUsIDB4MDAsIDB4NTV9LCAvKiAweDI4ICAgICAgKi8KICB7MHg1NSwgMHgwMCwgMHhmZn0sIC8qIDB4MjkgICAgICAqLwogIHsweDU1LCAweGFhLCAweDU1fSwgLyogMHgyYSAgICAgICovCiAgezB4NTUsIDB4YWEsIDB4ZmZ9LCAvKiAweDJiICAgICAgKi8KICB7MHhmZiwgMHgwMCwgMHg1NX0sIC8qIDB4MmMgICAgICAqLwogIHsweGZmLCAweDAwLCAweGZmfSwgLyogMHgyZCAgICAgICovCiAgezB4ZmYsIDB4YWEsIDB4NTV9LCAvKiAweDJlICAgICAgKi8KICB7MHhmZiwgMHhhYSwgMHhmZn0sIC8qIDB4MmYgICAgICAqLwogIHsweDU1LCAweDU1LCAweDAwfSwgLyogMHgzMCAgICAgICovCiAgezB4NTUsIDB4NTUsIDB4YWF9LCAvKiAweDMxICAgICAgKi8KICB7MHg1NSwgMHhmZiwgMHgwMH0sIC8qIDB4MzIgICAgICAqLwogIHsweDU1LCAweGZmLCAweGFhfSwgLyogMHgzMyAgICAgICovCiAgezB4ZmYsIDB4NTUsIDB4MDB9LCAvKiAweDM0ICAgICAgKi8KICB7MHhmZiwgMHg1NSwgMHhhYX0sIC8qIDB4MzUgICAgICAqLwogIHsweGZmLCAweGZmLCAweDAwfSwgLyogMHgzNiAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4YWF9LCAvKiAweDM3ICAgICAgKi8KICB7MHg1NSwgMHg1NSwgMHg1NX0sIC8qIDB4MzggICAgICBEYXJrIEdyYXkgICAgICovCiAgezB4NTUsIDB4NTUsIDB4ZmZ9LCAvKiAweDM5ICAgICAgTGlnaHQgQmx1ZSAgICAqLwogIHsweDU1LCAweGZmLCAweDU1fSwgLyogMHgzYSAgICAgIExpZ2h0IEdyZWVuICAgKi8KICB7MHg1NSwgMHhmZiwgMHhmZn0sIC8qIDB4M2IgICAgICBMaWdodCBDeWFuICAgICovCiAgezB4ZmYsIDB4NTUsIDB4NTV9LCAvKiAweDNjICAgICAgTGlnaHQgUmVkICAgICAqLwogIHsweGZmLCAweDU1LCAweGZmfSwgLyogMHgzZCAgICAgIExpZ2h0IE1hZ2VudGEgKi8KICB7MHhmZiwgMHhmZiwgMHg1NX0sIC8qIDB4M2UgICAgICBZZWxsb3cgICAgICAgICovCiAgezB4ZmYsIDB4ZmYsIDB4ZmZ9LCAvKiAweDNmICAgICAgV2hpdGUgICAgICAgICAqLwogIHswLDAsMH0gLyogVGhlIG5leHQgMTkyIGVudHJpZXMgYXJlIGFsbCB6ZXJvcyAgKi8KfTsKCnN0YXRpYyBIQU5ETEUgVkdBX3RpbWVyOwpzdGF0aWMgSEFORExFIFZHQV90aW1lcl90aHJlYWQ7CgovKiBzZXQgdGhlIHRpbWVyIHJhdGU7IGNhbGxlZCBpbiB0aGUgcG9sbGluZyB0aHJlYWQgY29udGV4dCAqLwpzdGF0aWMgdm9pZCBDQUxMQkFDSyBzZXRfdGltZXJfcmF0ZSggVUxPTkdfUFRSIGFyZyApCnsKICAgIExBUkdFX0lOVEVHRVIgd2hlbjsKCiAgICB3aGVuLnMuTG93UGFydCA9IHdoZW4ucy5IaWdoUGFydCA9IDA7CiAgICBTZXRXYWl0YWJsZVRpbWVyKCBWR0FfdGltZXIsICZ3aGVuLCBhcmcsIFZHQV9Qb2xsLCAwLCBGQUxTRSApOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgVkdBX1RpbWVyVGhyZWFkKCB2b2lkICpkdW1teSApCnsKICAgIGZvciAoOzspIFdhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCggMCwgTlVMTCwgRkFMU0UsIElORklOSVRFLCBUUlVFICk7Cn0KCnN0YXRpYyB2b2lkIFZHQV9EZWluc3RhbGxUaW1lcih2b2lkKQp7CiAgICBpZiAoVkdBX3RpbWVyX3RocmVhZCkKICAgIHsKICAgICAgICBDYW5jZWxXYWl0YWJsZVRpbWVyKCBWR0FfdGltZXIgKTsKICAgICAgICBDbG9zZUhhbmRsZSggVkdBX3RpbWVyICk7CiAgICAgICAgVGVybWluYXRlVGhyZWFkKCBWR0FfdGltZXJfdGhyZWFkLCAwICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIFZHQV90aW1lcl90aHJlYWQgKTsKICAgICAgICBWR0FfdGltZXJfdGhyZWFkID0gMDsKICAgIH0KfQoKc3RhdGljIHZvaWQgVkdBX0luc3RhbGxUaW1lcih1bnNpZ25lZCBSYXRlKQp7CiAgICBpZiAoIVZHQV90aW1lcl90aHJlYWQpCiAgICB7CiAgICAgICAgVkdBX3RpbWVyID0gQ3JlYXRlV2FpdGFibGVUaW1lckEoIE5VTEwsIEZBTFNFLCBOVUxMICk7CiAgICAgICAgVkdBX3RpbWVyX3RocmVhZCA9IENyZWF0ZVRocmVhZCggTlVMTCwgMCwgVkdBX1RpbWVyVGhyZWFkLCBOVUxMLCAwLCBOVUxMICk7CiAgICB9CiAgICBRdWV1ZVVzZXJBUEMoIHNldF90aW1lcl9yYXRlLCBWR0FfdGltZXJfdGhyZWFkLCAoVUxPTkdfUFRSKVJhdGUgKTsKfQoKSEFORExFIFZHQV9BbHBoYUNvbnNvbGUodm9pZCkKewogICAgLyogdGhpcyBhc3N1bWVzIHRoYXQgbm8gV2luMzIgcmVkaXJlY3Rpb24gaGFzIHRha2VuIHBsYWNlLCBidXQgdGhlbiBhZ2FpbiwKICAgICAqIG9ubHkgMTYtYml0IGFwcHMgYXJlIGxpa2VseSB0byB1c2UgdGhpcyBwYXJ0IG9mIFdpbmUuLi4gKi8KICAgIHJldHVybiBHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwp9CgpjaGFyKlZHQV9BbHBoYUJ1ZmZlcih2b2lkKQp7CiAgICByZXR1cm4gRE9TTUVNX01hcERvc1RvTGluZWFyKDB4YjgwMDApOwp9CgovKioqIEdSQVBISUNTIE1PREUgKioqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIHVuc2lnbmVkIFhyZXMsIFlyZXMsIERlcHRoOwogIGludCByZXQ7Cn0gTW9kZVNldDsKCnN0YXRpYyB2b2lkIFdJTkFQSSBWR0FfRG9TZXRNb2RlKFVMT05HX1BUUiBhcmcpCnsKICAgIExSRVNVTFQJcmVzOwogICAgSFdORAlod25kOwogICAgTW9kZVNldCAqcGFyID0gKE1vZGVTZXQgKilhcmc7CiAgICBwYXItPnJldD0xOwoKICAgIGlmIChscGRkcmF3KSBWR0FfRXhpdCgpOwogICAgaWYgKCFscGRkcmF3KSB7CiAgICAgICAgaWYgKCFwRGlyZWN0RHJhd0NyZWF0ZSkKICAgICAgICB7CiAgICAgICAgICAgIEhNT0RVTEUgaG1vZCA9IExvYWRMaWJyYXJ5QSggImRkcmF3LmRsbCIgKTsKICAgICAgICAgICAgaWYgKGhtb2QpIHBEaXJlY3REcmF3Q3JlYXRlID0gKERpcmVjdERyYXdDcmVhdGVQcm9jKUdldFByb2NBZGRyZXNzKCBobW9kLCAiRGlyZWN0RHJhd0NyZWF0ZSIgKTsKCSAgICBpZiAoIXBEaXJlY3REcmF3Q3JlYXRlKSB7CgkJRVJSKCJDYW4ndCBsb29rdXAgRGlyZWN0RHJhd0NyZWF0ZSBmcm9tIGRkcmF3LmRsbC5cbiIpOwoJCXJldHVybjsKCSAgICB9CiAgICAgICAgfQogICAgICAgIHJlcyA9IHBEaXJlY3REcmF3Q3JlYXRlKE5VTEwsJmxwZGRyYXcsTlVMTCk7CiAgICAgICAgaWYgKCFscGRkcmF3KSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBpcyBub3QgYXZhaWxhYmxlIChyZXMgPSAlbHgpXG4iLHJlcyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9Cglod25kID0gQ3JlYXRlV2luZG93RXhBKDAsIlNUQVRJQyIsIldJTkVET1MgVkdBIixXU19QT1BVUHxXU19CT1JERVJ8V1NfQ0FQVElPTnxXU19TWVNNRU5VLDAsMCxwYXItPlhyZXMscGFyLT5ZcmVzLDAsMCwwLE5VTEwpOwoJaWYgKCFod25kKSB7CgkgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIHVzZXIgd2luZG93LlxuIik7Cgl9CiAgICAgICAgaWYgKChyZXM9SURpcmVjdERyYXdfU2V0Q29vcGVyYXRpdmVMZXZlbChscGRkcmF3LGh3bmQsRERTQ0xfRlVMTFNDUkVFTnxERFNDTF9FWENMVVNJVkUpKSkgewoJICAgIEVSUigiQ291bGQgbm90IHNldCBjb29wZXJhdGl2ZSBsZXZlbCB0byBleGNsdXNpdmUgKCVseClcbiIscmVzKTsKCX0KCiAgICAgICAgaWYgKChyZXM9SURpcmVjdERyYXdfU2V0RGlzcGxheU1vZGUobHBkZHJhdyxwYXItPlhyZXMscGFyLT5ZcmVzLHBhci0+RGVwdGgpKSkgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgZG9lcyBub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgZGlzcGxheSBtb2RlICglZHglZHglZCksIHJlcyA9ICVseCFcbiIscGFyLT5YcmVzLHBhci0+WXJlcyxwYXItPkRlcHRoLHJlcyk7CiAgICAgICAgICAgIElEaXJlY3REcmF3X1JlbGVhc2UobHBkZHJhdyk7CiAgICAgICAgICAgIGxwZGRyYXc9TlVMTDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcmVzPUlEaXJlY3REcmF3X0NyZWF0ZVBhbGV0dGUobHBkZHJhdyxERFBDQVBTXzhCSVQsTlVMTCwmbHBkZHBhbCxOVUxMKTsKICAgICAgICBpZiAocmVzKSB7CgkgICAgRVJSKCJDb3VsZCBub3QgY3JlYXRlIHBhbGV0dGUgKHJlcyA9ICVseClcbiIscmVzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfUmVsZWFzZShscGRkcmF3KTsKICAgICAgICAgICAgbHBkZHJhdz1OVUxMOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmICgocmVzPUlEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCwwLDI1Nix2Z2FfZGVmX3BhbGV0dGUpKSkgewogICAgICAgICAgICBFUlIoIkNvdWxkIG5vdCBzZXQgZGVmYXVsdCBwYWxldHRlIGVudHJpZXMgKHJlcyA9ICVseClcbiIsIHJlcyk7CiAgICAgICAgfQoKICAgICAgICBtZW1zZXQoJnNkZXNjLDAsc2l6ZW9mKHNkZXNjKSk7CiAgICAgICAgc2Rlc2MuZHdTaXplPXNpemVvZihzZGVzYyk7CglzZGVzYy5kd0ZsYWdzID0gRERTRF9DQVBTOwoJc2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX1BSSU1BUllTVVJGQUNFOwogICAgICAgIGlmIChJRGlyZWN0RHJhd19DcmVhdGVTdXJmYWNlKGxwZGRyYXcsJnNkZXNjLCZscGRkc3VyZixOVUxMKXx8KCFscGRkc3VyZikpIHsKICAgICAgICAgICAgRVJSKCJEaXJlY3REcmF3IHN1cmZhY2UgaXMgbm90IGF2YWlsYWJsZVxuIik7CiAgICAgICAgICAgIElEaXJlY3REcmF3X1JlbGVhc2UobHBkZHJhdyk7CiAgICAgICAgICAgIGxwZGRyYXc9TlVMTDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfU2V0UGFsZXR0ZShscGRkc3VyZixscGRkcGFsKTsKICAgICAgICB2Z2FfcmVmcmVzaD0wOwogICAgICAgIC8qIHBvbGwgZXZlcnkgMjBtcyAoNTBmcHMgc2hvdWxkIHByb3ZpZGUgYWRlcXVhdGUgcmVzcG9uc2l2ZW5lc3MpICovCiAgICAgICAgVkdBX0luc3RhbGxUaW1lcigyMCk7CiAgICB9CiAgICBwYXItPnJldD0wOwogICAgcmV0dXJuOwp9CgppbnQgVkdBX1NldE1vZGUodW5zaWduZWQgWHJlcyx1bnNpZ25lZCBZcmVzLHVuc2lnbmVkIERlcHRoKQp7CiAgICBNb2RlU2V0IHBhcjsKCiAgICB2Z2Ffd2lkdGggPSBYcmVzOwogICAgdmdhX2hlaWdodCA9IFlyZXM7CiAgICB2Z2FfZGVwdGggPSBEZXB0aDsKCiAgICBpZihYcmVzID49IDY0MCB8fCBZcmVzID49IDQ4MCkgewogICAgICBwYXIuWHJlcyA9IFhyZXM7CiAgICAgIHBhci5ZcmVzID0gWXJlczsKICAgIH0gZWxzZSB7CiAgICAgIHBhci5YcmVzID0gNjQwOwogICAgICBwYXIuWXJlcyA9IDQ4MDsKICAgIH0KCiAgICBwYXIuRGVwdGggPSAoRGVwdGggPCA4KSA/IDggOiBEZXB0aDsKCiAgICB2Z2FfbW9kZV9pbml0aWFsaXplZCA9IFRSVUU7CgogICAgTVpfUnVuSW5UaHJlYWQoVkdBX0RvU2V0TW9kZSwgKFVMT05HX1BUUikmcGFyKTsKICAgIHJldHVybiBwYXIucmV0Owp9CgppbnQgVkdBX0dldE1vZGUodW5zaWduZWQqSGVpZ2h0LHVuc2lnbmVkKldpZHRoLHVuc2lnbmVkKkRlcHRoKQp7CiAgICBpZiAoIWxwZGRyYXcpIHJldHVybiAxOwogICAgaWYgKCFscGRkc3VyZikgcmV0dXJuIDE7CiAgICBpZiAoSGVpZ2h0KSAqSGVpZ2h0PXNkZXNjLmR3SGVpZ2h0OwogICAgaWYgKFdpZHRoKSAqV2lkdGg9c2Rlc2MuZHdXaWR0aDsKICAgIGlmIChEZXB0aCkgKkRlcHRoPXNkZXNjLmRkcGZQaXhlbEZvcm1hdC51MS5kd1JHQkJpdENvdW50OwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBWR0FfRG9FeGl0KFVMT05HX1BUUiBhcmcpCnsKICAgIFZHQV9EZWluc3RhbGxUaW1lcigpOwogICAgSURpcmVjdERyYXdTdXJmYWNlX1NldFBhbGV0dGUobHBkZHN1cmYsTlVMTCk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VfUmVsZWFzZShscGRkc3VyZik7CiAgICBscGRkc3VyZj1OVUxMOwogICAgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2UobHBkZHBhbCk7CiAgICBscGRkcGFsPU5VTEw7CiAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgbHBkZHJhdz1OVUxMOwp9Cgp2b2lkIFZHQV9FeGl0KHZvaWQpCnsKICAgIGlmIChscGRkcmF3KSBNWl9SdW5JblRocmVhZChWR0FfRG9FeGl0LCAwKTsKfQoKdm9pZCBWR0FfU2V0UGFsZXR0ZShQQUxFVFRFRU5UUlkqcGFsLGludCBzdGFydCxpbnQgbGVuKQp7CiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCxzdGFydCxsZW4scGFsKTsKfQoKLyogc2V0IGEgc2luZ2xlIGNvbG9yIGluIDE2IGNvbG9yIG1vZGUuICovCnZvaWQgVkdBX1NldENvbG9yMTYoaW50IHJlZyxpbnQgY29sb3IpCnsKCVBBTEVUVEVFTlRSWSAqcGFsOwoKICAgIGlmICghbHBkZHJhdykgcmV0dXJuOwoJcGFsPSAmdmdhX2RlZjY0X3BhbGV0dGVbY29sb3JdOwogICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCxyZWcsMSxwYWwpOwoJdmdhXzE2X3BhbGV0dGVbcmVnXT0oY2hhciljb2xvcjsKfQoKdm9pZCBWR0FfU2V0UXVhZFBhbGV0dGUoUkdCUVVBRCpjb2xvcixpbnQgc3RhcnQsaW50IGxlbikKewogICAgUEFMRVRURUVOVFJZIHBhbFsyNTZdOwogICAgaW50IGM7CgogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBmb3IgKGM9MDsgYzxsZW47IGMrKykgewogICAgICAgIHBhbFtjXS5wZVJlZCAgPWNvbG9yW2NdLnJnYlJlZDsKICAgICAgICBwYWxbY10ucGVHcmVlbj1jb2xvcltjXS5yZ2JHcmVlbjsKICAgICAgICBwYWxbY10ucGVCbHVlID1jb2xvcltjXS5yZ2JCbHVlOwogICAgICAgIHBhbFtjXS5wZUZsYWdzPTA7CiAgICB9CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCkxQU1RSIFZHQV9Mb2NrKHVuc2lnbmVkKlBpdGNoLHVuc2lnbmVkKkhlaWdodCx1bnNpZ25lZCpXaWR0aCx1bnNpZ25lZCpEZXB0aCkKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm4gTlVMTDsKICAgIGlmICghbHBkZHN1cmYpIHJldHVybiBOVUxMOwogICAgaWYgKElEaXJlY3REcmF3U3VyZmFjZV9Mb2NrKGxwZGRzdXJmLE5VTEwsJnNkZXNjLDAsMCkpIHsKICAgICAgICBFUlIoImNvdWxkIG5vdCBsb2NrIHN1cmZhY2UhXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGlmIChQaXRjaCkgKlBpdGNoPXNkZXNjLnUxLmxQaXRjaDsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gc2Rlc2MubHBTdXJmYWNlOwp9Cgp2b2lkIFZHQV9VbmxvY2sodm9pZCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlX1VubG9jayhscGRkc3VyZixzZGVzYy5scFN1cmZhY2UpOwp9CgovKioqIFRFWFQgTU9ERSAqKiovCgppbnQgVkdBX1NldEFscGhhTW9kZSh1bnNpZ25lZCBYcmVzLHVuc2lnbmVkIFlyZXMpCnsKICAgIENPT1JEIHNpejsKCiAgICBpZiAobHBkZHJhdykgVkdBX0V4aXQoKTsKCiAgICAvKiBGSVhNRTogV2hlcmUgdG8gaW5pdGlhbGl6ZSB0ZXh0IGF0dHJpYnV0ZXM/ICovCiAgICBWR0FfU2V0VGV4dEF0dHJpYnV0ZSgweGYpOwoKICAgIC8qIHRoZSB4dGVybSBpcyBzbG93LCBzbyByZWZyZXNoIG9ubHkgZXZlcnkgMjAwbXMgKDVmcHMpICovCiAgICBWR0FfSW5zdGFsbFRpbWVyKDIwMCk7CgogICAgc2l6LlggPSBYcmVzOwogICAgc2l6LlkgPSBZcmVzOwogICAgU2V0Q29uc29sZVNjcmVlbkJ1ZmZlclNpemUoVkdBX0FscGhhQ29uc29sZSgpLHNpeik7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfR2V0QWxwaGFNb2RlKHVuc2lnbmVkKlhyZXMsdW5zaWduZWQqWXJlcykKewogICAgQ09OU09MRV9TQ1JFRU5fQlVGRkVSX0lORk8gaW5mbzsKICAgIEdldENvbnNvbGVTY3JlZW5CdWZmZXJJbmZvKFZHQV9BbHBoYUNvbnNvbGUoKSwmaW5mbyk7CiAgICBpZiAoWHJlcykgKlhyZXM9aW5mby5kd1NpemUuWDsKICAgIGlmIChZcmVzKSAqWXJlcz1pbmZvLmR3U2l6ZS5ZOwp9Cgp2b2lkIFZHQV9TZXRDdXJzb3JQb3ModW5zaWduZWQgWCx1bnNpZ25lZCBZKQp7CiAgICBDT09SRCBwb3M7CgogICAgaWYgKCFwb2xsX3RpbWVyKSBWR0FfU2V0QWxwaGFNb2RlKDgwLCAyNSk7CiAgICBwb3MuWCA9IFg7CiAgICBwb3MuWSA9IFk7CiAgICBTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oVkdBX0FscGhhQ29uc29sZSgpLHBvcyk7Cn0KCnZvaWQgVkdBX0dldEN1cnNvclBvcyh1bnNpZ25lZCpYLHVuc2lnbmVkKlkpCnsKICAgIENPTlNPTEVfU0NSRUVOX0JVRkZFUl9JTkZPIGluZm87CiAgICBHZXRDb25zb2xlU2NyZWVuQnVmZmVySW5mbyhWR0FfQWxwaGFDb25zb2xlKCksJmluZm8pOwogICAgaWYgKFgpICpYPWluZm8uZHdDdXJzb3JQb3NpdGlvbi5YOwogICAgaWYgKFkpICpZPWluZm8uZHdDdXJzb3JQb3NpdGlvbi5ZOwp9Cgp2b2lkIFZHQV9Xcml0ZUNoYXJzKHVuc2lnbmVkIFgsdW5zaWduZWQgWSx1bnNpZ25lZCBjaCxpbnQgYXR0cixpbnQgY291bnQpCnsKICAgIENIQVJfSU5GTyBpbmZvOwogICAgQ09PUkQgc2l6LCBvZmY7CiAgICBTTUFMTF9SRUNUIGRlc3Q7CiAgICB1bnNpZ25lZCBYUiwgWVI7CiAgICBjaGFyICpkYXQ7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKCiAgICBpbmZvLkNoYXIuQXNjaWlDaGFyID0gY2g7CiAgICBpbmZvLkF0dHJpYnV0ZXMgPSAoV09SRClhdHRyOwogICAgc2l6LlggPSAxOwogICAgc2l6LlkgPSAxOwogICAgb2ZmLlggPSAwOwogICAgb2ZmLlkgPSAwOwogICAgZGVzdC5Ub3A9WTsgCiAgICBkZXN0LkJvdHRvbT1ZOwoKICAgIFZHQV9HZXRBbHBoYU1vZGUoJlhSLCAmWVIpOwogICAgZGF0ID0gVkdBX0FscGhhQnVmZmVyKCkgKyAoKFhSKlkgKyBYKSAqIDIpOwogICAgd2hpbGUgKGNvdW50LS0pIHsKICAgICAgICBkZXN0LkxlZnQgPSBYICsgY291bnQ7CiAgICAgICBkZXN0LlJpZ2h0ID0gWCArIGNvdW50OwoKICAgICAgICAqZGF0KysgPSBjaDsKICAgICAgICBpZiAoYXR0cj49MCkgCiAgICAgICAgICpkYXQgPSBhdHRyOwogICAgICAgZWxzZQogICAgICAgICBpbmZvLkF0dHJpYnV0ZXMgPSAqZGF0OwogICAgICAgIGRhdCsrOwoKICAgICAgIFdyaXRlQ29uc29sZU91dHB1dEEoVkdBX0FscGhhQ29uc29sZSgpLCAmaW5mbywgc2l6LCBvZmYsICZkZXN0KTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9CgpzdGF0aWMgdm9pZCBWR0FfUHV0Q2hhckF0KEJZVEUgYXNjaWksIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHkpCnsKICAgIHVuc2lnbmVkIHdpZHRoLCBoZWlnaHQ7CiAgICBjaGFyICpkYXQ7CgogICAgVkdBX0dldEFscGhhTW9kZSgmd2lkdGgsICZoZWlnaHQpOwogICAgZGF0ID0gVkdBX0FscGhhQnVmZmVyKCkgKyAoKHdpZHRoKnkgKyB4KSAqIDIpOwogICAgZGF0WzBdID0gYXNjaWk7CiAgICBkYXRbMV0gPSB2Z2FfdGV4dF9hdHRyOwp9Cgp2b2lkIFZHQV9QdXRDaGFyKEJZVEUgYXNjaWkpCnsKICAgIHVuc2lnbmVkIHdpZHRoLCBoZWlnaHQsIHgsIHksIG54LCBueTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwoKICAgIFZHQV9HZXRBbHBoYU1vZGUoJndpZHRoLCAmaGVpZ2h0KTsKICAgIFZHQV9HZXRDdXJzb3JQb3MoJngsICZ5KTsKICAKICAgIHN3aXRjaChhc2NpaSkgewogICAgY2FzZSAnXGInOgogICAgICAgIFZHQV9QdXRDaGFyQXQoJyAnLCB4LCB5KTsKICAgICAgIHgtLTsKICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ1x0JzoKICAgICAgIHggKz0gKCh4ICsgOCkgJiB+NykgLSB4OwogICAgICAgYnJlYWs7CgogICAgY2FzZSAnXG4nOgogICAgICAgIHkrKzsKICAgICAgIHggPSAwOwogICAgICAgYnJlYWs7CiAgCiAgICBjYXNlICdcYSc6CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnXHInOgogICAgICAgIHggPSAwOwogICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBWR0FfUHV0Q2hhckF0KGFzY2lpLCB4LCB5KTsKICAgICAgIHgrKzsKICAgIH0KCiAgICAvKgogICAgICogRklYTUU6IGFkZCBsaW5lIHdyYXBwaW5nIGFuZCBzY3JvbGxpbmcKICAgICAqLwoKICAgIFdyaXRlRmlsZShWR0FfQWxwaGFDb25zb2xlKCksICZhc2NpaSwgMSwgTlVMTCwgTlVMTCk7CgogICAgLyoKICAgICAqIFRoZSBmb2xsb3dpbmcgaXMganVzdCBhIHNhbml0eSBjaGVjay4KICAgICAqLwogICAgVkdBX0dldEN1cnNvclBvcygmbngsICZueSk7CiAgICBpZihueCAhPSB4IHx8IG55ICE9IHkpCiAgICAgIFdBUk4oIlZHQSBlbXVsYXRvciBhbmQgdGV4dCBjb25zb2xlIGhhdmUgYmVjb21lIHVuc3luY2hyb25pemVkLlxuIik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsKfQoKdm9pZCBWR0FfU2V0VGV4dEF0dHJpYnV0ZShCWVRFIGF0dHIpCnsKICAgIHZnYV90ZXh0X2F0dHIgPSBhdHRyOwogICAgU2V0Q29uc29sZVRleHRBdHRyaWJ1dGUoVkdBX0FscGhhQ29uc29sZSgpLCBhdHRyKTsKfQoKdm9pZCBWR0FfQ2xlYXJUZXh0KHVuc2lnbmVkIHJvdzEsIHVuc2lnbmVkIGNvbDEsIAogICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCB1bnNpZ25lZCBjb2wyLAogICAgICAgICAgICAgICAgICBCWVRFIGF0dHIpCnsKICAgIHVuc2lnbmVkIHdpZHRoLCBoZWlnaHQsIHgsIHk7CiAgICBDT09SRCBvZmY7CiAgICBjaGFyICpkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKTsKICAgIEhBTkRMRSBjb24gPSBWR0FfQWxwaGFDb25zb2xlKCk7CiAgICBWR0FfR2V0QWxwaGFNb2RlKCZ3aWR0aCwgJmhlaWdodCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnZnYV9sb2NrKTsgCgogICAgZm9yKHk9cm93MTsgeTw9cm93MjsgeSsrKSB7CiAgICAgICAgb2ZmLlggPSBjb2wxOwogICAgICAgb2ZmLlkgPSB5OwogICAgICAgRmlsbENvbnNvbGVPdXRwdXRDaGFyYWN0ZXJBKGNvbiwgJyAnLCBjb2wyLWNvbDErMSwgb2ZmLCBOVUxMKTsKICAgICAgIEZpbGxDb25zb2xlT3V0cHV0QXR0cmlidXRlKGNvbiwgYXR0ciwgY29sMi1jb2wxKzEsIG9mZiwgTlVMTCk7CgogICAgICAgZm9yKHg9Y29sMTsgeDw9Y29sMjsgeCsrKSB7CiAgICAgICAgICAgY2hhciAqcHRyID0gZGF0ICsgKCh3aWR0aCp5ICsgeCkgKiAyKTsKICAgICAgICAgICBwdHJbMF0gPSAnICc7CiAgICAgICAgICAgcHRyWzFdID0gYXR0cjsKICAgICAgIH0KICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9Cgp2b2lkIFZHQV9TY3JvbGxVcFRleHQodW5zaWduZWQgcm93MSwgdW5zaWduZWQgY29sMSwgCiAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHJvdzIsIHVuc2lnbmVkIGNvbDIsCiAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxpbmVzLCBCWVRFIGF0dHIpCnsKICAgIEZJWE1FKCJub3QgaW1wbGVtZW50ZWRcbiIpOwp9Cgp2b2lkIFZHQV9TY3JvbGxEb3duVGV4dCh1bnNpZ25lZCByb3cxLCB1bnNpZ25lZCBjb2wxLCAKICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCByb3cyLCB1bnNpZ25lZCBjb2wyLAogICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxpbmVzLCBCWVRFIGF0dHIpCnsKICAgIEZJWE1FKCJub3QgaW1wbGVtZW50ZWRcbiIpOwp9Cgp2b2lkIFZHQV9HZXRDaGFyYWN0ZXJBdEN1cnNvcihCWVRFICphc2NpaSwgQllURSAqYXR0cikKewogICAgdW5zaWduZWQgd2lkdGgsIGhlaWdodCwgeCwgeTsKICAgIGNoYXIgKmRhdDsKCiAgICBWR0FfR2V0QWxwaGFNb2RlKCZ3aWR0aCwgJmhlaWdodCk7CiAgICBWR0FfR2V0Q3Vyc29yUG9zKCZ4LCAmeSk7CiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKSArICgod2lkdGgqeSArIHgpICogMik7CgogICAgKmFzY2lpID0gZGF0WzBdOwogICAgKmF0dHIgPSBkYXRbMV07Cn0KCgovKioqIENPTlRST0wgKioqLwoKc3RhdGljIHZvaWQgVkdBX1BvbGxfR3JhcGhpY3Modm9pZCkKewogIHVuc2lnbmVkIGludCBQaXRjaCwgSGVpZ2h0LCBXaWR0aCwgWCwgWTsKICBjaGFyICpzdXJmOwogIGNoYXIgKmRhdCA9IERPU01FTV9NYXBEb3NUb0xpbmVhcigweGEwMDAwKTsKCiAgc3VyZiA9IFZHQV9Mb2NrKCZQaXRjaCwmSGVpZ2h0LCZXaWR0aCxOVUxMKTsKICBpZiAoIXN1cmYpIHJldHVybjsKCiAgaWYodmdhX3dpZHRoID09IDMyMCAmJiB2Z2FfZGVwdGggPD0gNCkKICAgIGZvciAoWT0wOyBZPHZnYV9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCoyLGRhdCs9dmdhX3dpZHRoLzgpIHsKICAgICAgZm9yKFg9MDsgWDx2Z2Ffd2lkdGg7IFgrPTgpIHsKICAgICAgIGludCBvZmZzZXQgPSBYLzg7CiAgICAgICBpbnQgWjsKICAgICAgIGZvcihaPTA7IFo8ODsgWisrKSB7CiAgICAgICAgIGludCBiMCA9ICAoZGF0W29mZnNldF0gPj4gWikgJiAweDE7CiAgICAgICAgIGludCBpbmRleCA9IDctWjsKICAgICAgICAgc3VyZlsoWCtpbmRleCkqMl0gPSBiMDsKICAgICAgICAgc3VyZlsoWCtpbmRleCkqMisxXSA9IGIwOwogICAgICAgICBzdXJmWyhYK2luZGV4KSoyK1BpdGNoXSA9IGIwOwogICAgICAgICBzdXJmWyhYK2luZGV4KSoyK1BpdGNoKzFdID0gYjA7CiAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgaWYodmdhX3dpZHRoID09IDMyMCAmJiB2Z2FfZGVwdGggPT0gOCkKICAgIGZvciAoWT0wOyBZPHZnYV9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCoyLGRhdCs9dmdhX3dpZHRoKSB7CiAgICAgIGZvcihYPTA7IFg8dmdhX3dpZHRoOyBYKyspIHsKICAgICAgIGludCBiMCA9IGRhdFtYXTsKICAgICAgIHN1cmZbWCoyXSA9IGIwOwogICAgICAgc3VyZltYKjIrMV0gPSBiMDsKICAgICAgIHN1cmZbWCoyK1BpdGNoXSA9IGIwOwogICAgICAgc3VyZltYKjIrUGl0Y2grMV0gPSBiMDsKICAgICAgfQogICAgfQoKICBpZih2Z2FfZGVwdGggPD0gNCkKICAgIGZvciAoWT0wOyBZPHZnYV9oZWlnaHQ7IFkrKyxzdXJmKz1QaXRjaCxkYXQrPXZnYV93aWR0aC84KSB7CiAgICAgIGZvcihYPTA7IFg8dmdhX3dpZHRoOyBYKz04KSB7CiAgICAgICBpbnQgb2Zmc2V0ID0gWC84OwogICAgICAgaW50IFo7CiAgICAgICBmb3IoWj0wOyBaPDg7IForKykgewogICAgICAgICBpbnQgYjAgPSAgKGRhdFtvZmZzZXRdID4+IFopICYgMHgxOwogICAgICAgICBpbnQgaW5kZXggPSA3LVo7CiAgICAgICAgIHN1cmZbWCtpbmRleF0gPSBiMDsKICAgICAgIH0KICAgICAgfQogICAgfQoKICBWR0FfVW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIFZHQV9Qb2xsX1RleHQodm9pZCkKewogICAgY2hhciAqZGF0OwogICAgdW5zaWduZWQgaW50IEhlaWdodCxXaWR0aCxZLFg7CiAgICBDSEFSX0lORk8gY2hbODBdOwogICAgQ09PUkQgc2l6LCBvZmY7CiAgICBTTUFMTF9SRUNUIGRlc3Q7CiAgICBIQU5ETEUgY29uID0gVkdBX0FscGhhQ29uc29sZSgpOwoKICAgIFZHQV9HZXRBbHBoYU1vZGUoJldpZHRoLCZIZWlnaHQpOwogICAgZGF0ID0gVkdBX0FscGhhQnVmZmVyKCk7CiAgICBzaXouWCA9IDgwOyBzaXouWSA9IDE7CiAgICBvZmYuWCA9IDA7IG9mZi5ZID0gMDsKICAgIC8qIGNvcHkgZnJvbSB2aXJ0dWFsIFZHQSBmcmFtZSBidWZmZXIgdG8gY29uc29sZSAqLwogICAgZm9yIChZPTA7IFk8SGVpZ2h0OyBZKyspIHsKICAgICAgICBkZXN0LlRvcD1ZOyBkZXN0LkJvdHRvbT1ZOwogICAgICAgZm9yIChYPTA7IFg8V2lkdGg7IFgrKykgewogICAgICAgICAgIGNoW1hdLkNoYXIuQXNjaWlDaGFyID0gKmRhdCsrOwogICAgICAgICAgIC8qIFdyaXRlQ29uc29sZU91dHB1dEEgZG9lc24ndCBsaWtlICJkZWFkIiBjaGFycyAqLwogICAgICAgICAgIGlmIChjaFtYXS5DaGFyLkFzY2lpQ2hhciA9PSAnXDAnKQogICAgICAgICAgICAgICBjaFtYXS5DaGFyLkFzY2lpQ2hhciA9ICcgJzsKICAgICAgICAgICBjaFtYXS5BdHRyaWJ1dGVzID0gKmRhdCsrOwogICAgICAgfQogICAgICAgZGVzdC5MZWZ0PTA7IGRlc3QuUmlnaHQ9V2lkdGgrMTsKICAgICAgIFdyaXRlQ29uc29sZU91dHB1dEEoY29uLCBjaCwgc2l6LCBvZmYsICZkZXN0KTsKICAgIH0KfQoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgVkdBX1BvbGwoIExQVk9JRCBhcmcsIERXT1JEIGxvdywgRFdPUkQgaGlnaCApCnsKICAgIGlmKCFUcnlFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spKQogICAgICAgIHJldHVybjsKCiAgICAvKiBGSVhNRTogb3B0aW1pemUgYnkgZG9pbmcgdGhpcyBvbmx5IGlmIHRoZSBkYXRhIGhhcyBhY3R1YWxseSBjaGFuZ2VkCiAgICAgKiAgICAgICAgKGluIGEgd2F5IHNpbWlsYXIgdG8gRElCU2VjdGlvbiwgcGVyaGFwcykgKi8KICAgIGlmIChscGRkcmF3KSB7CiAgICAgICAgVkdBX1BvbGxfR3JhcGhpY3MoKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVkdBX1BvbGxfVGV4dCgpOwogICAgfQoKICAgIHZnYV9yZWZyZXNoPTE7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2xvY2spOwp9CgpzdGF0aWMgQllURSBwYWxyZWcscGFsY250OwpzdGF0aWMgUEFMRVRURUVOVFJZIHBhbGRhdDsKCnZvaWQgVkdBX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwgKQp7CiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2M4OgogICAgICAgICAgICBwYWxyZWc9dmFsOyBwYWxjbnQ9MDsgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjOToKICAgICAgICAgICAgKChCWVRFKikmcGFsZGF0KVtwYWxjbnQrK109dmFsIDw8IDI7CiAgICAgICAgICAgIGlmIChwYWxjbnQ9PTMpIHsKICAgICAgICAgICAgICAgIFZHQV9TZXRQYWxldHRlKCZwYWxkYXQscGFscmVnKyssMSk7CiAgICAgICAgICAgICAgICBwYWxjbnQ9MDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKQllURSBWR0FfaW9wb3J0X2luKCBXT1JEIHBvcnQgKQp7CiAgICBCWVRFIHJldDsKCiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2RhOgogICAgICAgICAgICAvKiBzaW5jZSB3ZSBkb24ndCAoeWV0Pykgc2VydmUgRE9TIFZNIHJlcXVlc3RzIHdoaWxlIFZHQV9Qb2xsIGlzIHJ1bm5pbmcsCiAgICAgICAgICAgICAgIHdlIG5lZWQgdG8gZmFrZSB0aGUgb2NjdXJyZW5jZSBvZiB0aGUgdmVydGljYWwgcmVmcmVzaCAqLwogICAgICAgICAgICByZXQ9dmdhX3JlZnJlc2g/MHgwMDoweDA4OwogICAgICAgICAgICBpZiAodmdhX21vZGVfaW5pdGlhbGl6ZWQpCiAgICAgICAgICAgICAgICB2Z2FfcmVmcmVzaD0wOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAvKiBBbHNvIGZha2UgdGhlIG9jY3VyZW5jZSBvZiB0aGUgdmVydGljYWwgcmVmcmVzaCB3aGVuIG5vIGdyYXBoaWMKICAgICAgICAgICAgICAgICAgIG1vZGUgaGFzIGJlZW4gc2V0ICovCiAgICAgICAgICAgICAgICB2Z2FfcmVmcmVzaD0hdmdhX3JlZnJlc2g7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldD0weGZmOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKdm9pZCBWR0FfQ2xlYW4odm9pZCkKewogICAgVkdBX0V4aXQoKTsKICAgIFZHQV9EZWluc3RhbGxUaW1lcigpOwp9Cg==