Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBVcHNhbXBsaW5nIC8gZG93bnNhbXBsaW5nIGNsYXNzZXMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gRGV0bGV2IFZlbmR0IChkZXRsZXYudmVuZHRAYnJpbGxpdC5kZSkKLy8gLSBDYXJzdGVuIEtsZWluIChja2xlaW4wNUB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIlJlc2l6ZS5oIgoKLyoqClJldHVybnMgdGhlIGNvbG9yIHR5cGUgb2YgYSBiaXRtYXAuIEluIGNvbnRyYXN0IHRvIEZyZWVJbWFnZV9HZXRDb2xvclR5cGUsCnRoaXMgZnVuY3Rpb24gb3B0aW9uYWxseSBzdXBwb3J0cyBhIGJvb2xlYW4gT1VUIHBhcmFtZXRlciwgdGhhdCByZWNlaXZlcyBUUlVFLAppZiB0aGUgc3BlY2lmaWVkIGJpdG1hcCBpcyBncmV5c2NhbGUsIHRoYXQgaXMsIGl0IGNvbnNpc3RzIG9mIGdyZXkgY29sb3JzIG9ubHkuCkFsdGhvdWdoIGl0IHJldHVybnMgdGhlIHNhbWUgdmFsdWUgYXMgcmV0dXJuZWQgYnkgRnJlZUltYWdlX0dldENvbG9yVHlwZSBmb3IgYWxsCmltYWdlIHR5cGVzLCB0aGlzIGV4dGVuZGVkIGZ1bmN0aW9uIHByaW1hcmlseSBpcyBpbnRlbmRlZCBmb3IgcGFsbGV0aXplZCBpbWFnZXMsCnNpbmNlIHRoZSBib29sZWFuIHBvaW50ZWQgdG8gYnkgJ2JJc0dyZXlzY2FsZScgcmVtYWlucyB1bmNoYW5nZWQgZm9yIFJHQihBL0YpCmltYWdlcy4gSG93ZXZlciwgdGhlIG91dGdvaW5nIGJvb2xlYW4gaXMgcHJvcGVybHkgbWFpbnRhaW5lZCBmb3IgcGFsbGV0aXplZCBpbWFnZXMsCmFzIHdlbGwgYXMgZm9yIGFueSBub24tUkdCIGltYWdlIHR5cGUsIGxpa2UgRklUX1VJTlR4eCBhbmQgRklUX0RPVUJMRSwgZm9yIGV4YW1wbGUuCkBwYXJhbSBkaWIgQSBwb2ludGVyIHRvIGEgRnJlZUltYWdlIGJpdG1hcCB0byBjYWxjdWxhdGUgdGhlIGV4dGVuZGVkIGNvbG9yIHR5cGUgZm9yCkBwYXJhbSBiSXNHcmV5c2NhbGUgQSBwb2ludGVyIHRvIGEgYm9vbGVhbiwgdGhhdCByZWNlaXZlcyBUUlVFLCBpZiB0aGUgc3BlY2lmaWVkIGJpdG1hcAppcyBncmV5c2NhbGUsIHRoYXQgaXMsIGl0IGNvbnNpc3RzIG9mIGdyZXkgY29sb3JzIG9ubHkuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBOVUxMLgpAcmV0dXJuIHRoZSBjb2xvciB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYml0bWFwCiovCnN0YXRpYyBGUkVFX0lNQUdFX0NPTE9SX1RZUEUKR2V0RXh0ZW5kZWRDb2xvclR5cGUoRklCSVRNQVAgKmRpYiwgQk9PTCAqYklzR3JleXNjYWxlKSB7Cgljb25zdCB1bnNpZ25lZCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7Cgljb25zdCB1bnNpZ25lZCBzaXplID0gQ2FsY3VsYXRlVXNlZFBhbGV0dGVFbnRyaWVzKGJwcCk7Cgljb25zdCBSR0JRVUFEICogY29uc3QgcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCUZSRUVfSU1BR0VfQ09MT1JfVFlQRSBjb2xvcl90eXBlID0gRklDX01JTklTQkxBQ0s7CglCT09MIGJJc0dyZXkgPSBUUlVFOwoKCXN3aXRjaCAoYnBwKSB7CgkJY2FzZSAxOgoJCXsKCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKChwYWxbaV0ucmdiUmVkICE9IHBhbFtpXS5yZ2JHcmVlbikgfHwgKHBhbFtpXS5yZ2JSZWQgIT0gcGFsW2ldLnJnYkJsdWUpKSB7CgkJCQkJY29sb3JfdHlwZSA9IEZJQ19QQUxFVFRFOwoJCQkJCWJJc0dyZXkgPSBGQUxTRTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpZiAoYklzR3JleSkgewoJCQkJaWYgKHBhbFswXS5yZ2JCbHVlID09IDI1NSAmJiBwYWxbMV0ucmdiQmx1ZSA9PSAwKSB7CgkJCQkJY29sb3JfdHlwZSA9IEZJQ19NSU5JU1dISVRFOwoJCQkJfSBlbHNlIGlmIChwYWxbMF0ucmdiQmx1ZSAhPSAwIHx8IHBhbFsxXS5yZ2JCbHVlICE9IDI1NSkgewoJCQkJCWNvbG9yX3R5cGUgPSBGSUNfUEFMRVRURTsKCQkJCX0KCQkJfQoJCQlicmVhazsKCQl9CgoJCWNhc2UgNDoKCQljYXNlIDg6CgkJewoJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoKHBhbFtpXS5yZ2JSZWQgIT0gcGFsW2ldLnJnYkdyZWVuKSB8fCAocGFsW2ldLnJnYlJlZCAhPSBwYWxbaV0ucmdiQmx1ZSkpIHsKCQkJCQljb2xvcl90eXBlID0gRklDX1BBTEVUVEU7CgkJCQkJYklzR3JleSA9IEZBTFNFOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJaWYgKGNvbG9yX3R5cGUgIT0gRklDX1BBTEVUVEUgJiYgcGFsW2ldLnJnYkJsdWUgIT0gaSkgewoJCQkJCWlmICgoc2l6ZSAtIGkgLSAxKSAhPSBwYWxbaV0ucmdiQmx1ZSkgewoJCQkJCQljb2xvcl90eXBlID0gRklDX1BBTEVUVEU7CgkJCQkJCWlmICghYklzR3JleXNjYWxlKSB7CgkJCQkJCQkvLyBleGl0IGxvb3AgaWYgd2UncmUgbm90IHNldHRpbmcKCQkJCQkJCS8vIGJJc0dyZXlzY2FsZSBwYXJhbWV0ZXIKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfSBlbHNlIHsKCQkJCQkJY29sb3JfdHlwZSA9IEZJQ19NSU5JU1dISVRFOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlicmVhazsKCQl9CgoJCWRlZmF1bHQ6CgkJewoJCQljb2xvcl90eXBlID0gRnJlZUltYWdlX0dldENvbG9yVHlwZShkaWIpOwoJCQliSXNHcmV5ID0gKGNvbG9yX3R5cGUgPT0gRklDX01JTklTQkxBQ0spID8gVFJVRSA6IEZBTFNFOwoJCQlicmVhazsKCQl9CgoJfQoJaWYgKGJJc0dyZXlzY2FsZSkgewoJCSpiSXNHcmV5c2NhbGUgPSBiSXNHcmV5OwoJfQoKCXJldHVybiBjb2xvcl90eXBlOwp9CgovKioKUmV0dXJucyBhIHBvaW50ZXIgdG8gYW4gUkdCQSBwYWxldHRlLCBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCBiaXRtYXAuClRoZSBSR0JBIHBhbGV0dGUgaXMgYSBjb3B5IG9mIHRoZSBzcGVjaWZpZWQgYml0bWFwJ3MgcGFsZXR0ZSwgdGhhdCwgYWRkaXRpb25hbGx5CmNvbnRhaW5zIHRoZSBiaXRtYXAncyB0cmFuc3BhcmVuY3kgaW5mb3JtYXRpb24gaW4gdGhlIHJnYlJlc2VydmVkIG1lbWJlcgpvZiB0aGUgcGFsZXR0ZSdzIFJHQlFVQUQgZWxlbWVudHMuCkBwYXJhbSBkaWIgQSBwb2ludGVyIHRvIGEgRnJlZUltYWdlIGJpdG1hcCB0byBjcmVhdGUgdGhlIFJHQkEgcGFsZXR0ZSBmcm9tLgpAcGFyYW0gYnVmZmVyIEEgcG9pbnRlciB0byB0aGUgYnVmZmVyIHRvIHN0b3JlIHRoZSBSR0JBIHBhbGV0dGUuCkByZXR1cm4gQSBwb2ludGVyIHRvIHRoZSBuZXdseSBjcmVhdGVkIFJHQkEgcGFsZXR0ZSBvciBOVUxMLCBpZiB0aGUgc3BlY2lmaWVkCmJpdG1hcCBpcyBubyBwYWxsZXRpemVkIHN0YW5kYXJkIGJpdG1hcC4gSWYgbm9uLU5VTEwsIHRoZSByZXR1cm5lZCB2YWx1ZSBpcwphY3R1YWxseSB0aGUgcG9pbnRlciBwYXNzZWQgaW4gcGFyYW1ldGVyICdidWZmZXInLgoqLwpzdGF0aWMgaW5saW5lIFJHQlFVQUQgKgpHZXRSR0JBUGFsZXR0ZShGSUJJVE1BUCAqZGliLCBSR0JRVUFEICogY29uc3QgYnVmZmVyKSB7CgkvLyBjbG9uZSB0aGUgcGFsZXR0ZQoJY29uc3QgdW5zaWduZWQgbmNvbG9ycyA9IEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKGRpYik7CglpZiAobmNvbG9ycyA9PSAwKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgltZW1jcHkoYnVmZmVyLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpLCBuY29sb3JzICogc2l6ZW9mKFJHQlFVQUQpKTsKCS8vIG1lcmdlIHRoZSB0cmFuc3BhcmVuY3kgdGFibGUKCWNvbnN0IHVuc2lnbmVkIG50cmFuc3AgPSBNSU4obmNvbG9ycywgRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeUNvdW50KGRpYikpOwoJY29uc3QgQllURSAqIGNvbnN0IHR0ID0gRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeVRhYmxlKGRpYik7Cglmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgbnRyYW5zcDsgaSsrKSB7CgkJYnVmZmVyW2ldLnJnYlJlc2VydmVkID0gdHRbaV07Cgl9Cglmb3IgKHVuc2lnbmVkIGkgPSBudHJhbnNwOyBpIDwgbmNvbG9yczsgaSsrKSB7CgkJYnVmZmVyW2ldLnJnYlJlc2VydmVkID0gMjU1OwoJfQoJcmV0dXJuIGJ1ZmZlcjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkNXZWlnaHRzVGFibGU6OkNXZWlnaHRzVGFibGUoQ0dlbmVyaWNGaWx0ZXIgKnBGaWx0ZXIsIHVuc2lnbmVkIHVEc3RTaXplLCB1bnNpZ25lZCB1U3JjU2l6ZSkgewoJZG91YmxlIGRXaWR0aDsKCWRvdWJsZSBkRlNjYWxlOwoJY29uc3QgZG91YmxlIGRGaWx0ZXJXaWR0aCA9IHBGaWx0ZXItPkdldFdpZHRoKCk7CgoJLy8gc2NhbGUgZmFjdG9yCgljb25zdCBkb3VibGUgZFNjYWxlID0gZG91YmxlKHVEc3RTaXplKSAvIGRvdWJsZSh1U3JjU2l6ZSk7CgoJaWYoZFNjYWxlIDwgMS4wKSB7CgkJLy8gbWluaWZpY2F0aW9uCgkJZFdpZHRoID0gZEZpbHRlcldpZHRoIC8gZFNjYWxlOyAKCQlkRlNjYWxlID0gZFNjYWxlOyAKCX0gZWxzZSB7CgkJLy8gbWFnbmlmaWNhdGlvbgoJCWRXaWR0aCA9IGRGaWx0ZXJXaWR0aDsgCgkJZEZTY2FsZSA9IDEuMDsgCgl9CgoJLy8gYWxsb2NhdGUgYSBuZXcgbGluZSBjb250cmlidXRpb25zIHN0cnVjdHVyZQoJLy8KCS8vIHdpbmRvdyBzaXplIGlzIHRoZSBudW1iZXIgb2Ygc2FtcGxlZCBwaXhlbHMKCW1fV2luZG93U2l6ZSA9IDIgKiAoaW50KWNlaWwoZFdpZHRoKSArIDE7IAoJLy8gbGVuZ3RoIG9mIGRzdCBsaW5lIChuby4gb2Ygcm93cyAvIGNvbHMpIAoJbV9MaW5lTGVuZ3RoID0gdURzdFNpemU7IAoKCSAvLyBhbGxvY2F0ZSBsaXN0IG9mIGNvbnRyaWJ1dGlvbnMgCgltX1dlaWdodFRhYmxlID0gKENvbnRyaWJ1dGlvbiopbWFsbG9jKG1fTGluZUxlbmd0aCAqIHNpemVvZihDb250cmlidXRpb24pKTsKCWZvcih1bnNpZ25lZCB1ID0gMDsgdSA8IG1fTGluZUxlbmd0aDsgdSsrKSB7CgkJLy8gYWxsb2NhdGUgY29udHJpYnV0aW9ucyBmb3IgZXZlcnkgcGl4ZWwKCQltX1dlaWdodFRhYmxlW3VdLldlaWdodHMgPSAoZG91YmxlKiltYWxsb2MobV9XaW5kb3dTaXplICogc2l6ZW9mKGRvdWJsZSkpOwoJfQoKCS8vIG9mZnNldCBmb3IgZGlzY3JldGUgdG8gY29udGludW91cyBjb29yZGluYXRlIGNvbnZlcnNpb24KCWNvbnN0IGRvdWJsZSBkT2Zmc2V0ID0gKDAuNSAvIGRTY2FsZSk7CgoJZm9yKHVuc2lnbmVkIHUgPSAwOyB1IDwgbV9MaW5lTGVuZ3RoOyB1KyspIHsKCQkvLyBzY2FuIHRocm91Z2ggbGluZSBvZiBjb250cmlidXRpb25zCgoJCS8vIGludmVyc2UgbWFwcGluZyAoZGlzY3JldGUgZHN0ICd1JyB0byBjb250aW5vdXMgc3JjICdkQ2VudGVyJykKCQljb25zdCBkb3VibGUgZENlbnRlciA9IChkb3VibGUpdSAvIGRTY2FsZSArIGRPZmZzZXQ7CgoJCS8vIGZpbmQgdGhlIHNpZ25pZmljYW50IGVkZ2UgcG9pbnRzIHRoYXQgYWZmZWN0IHRoZSBwaXhlbAoJCWNvbnN0IGludCBpTGVmdCA9IE1BWCgwLCAoaW50KShkQ2VudGVyIC0gZFdpZHRoICsgMC41KSk7CgkJY29uc3QgaW50IGlSaWdodCA9IE1JTigoaW50KShkQ2VudGVyICsgZFdpZHRoICsgMC41KSwgaW50KHVTcmNTaXplKSk7CgoJCW1fV2VpZ2h0VGFibGVbdV0uTGVmdCA9IGlMZWZ0OyAKCQltX1dlaWdodFRhYmxlW3VdLlJpZ2h0ID0gaVJpZ2h0OwoKCQlkb3VibGUgZFRvdGFsV2VpZ2h0ID0gMDsgIC8vIHN1bSBvZiB3ZWlnaHRzIChpbml0aWFsaXplZCB0byB6ZXJvKQoJCWZvcihpbnQgaVNyYyA9IGlMZWZ0OyBpU3JjIDwgaVJpZ2h0OyBpU3JjKyspIHsKCQkJLy8gY2FsY3VsYXRlIHdlaWdodHMKCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IGRGU2NhbGUgKiBwRmlsdGVyLT5GaWx0ZXIoZEZTY2FsZSAqICgoZG91YmxlKWlTcmMgKyAwLjUgLSBkQ2VudGVyKSk7CgkJCS8vIGFzc2VydCgoaVNyYy1pTGVmdCkgPCBtX1dpbmRvd1NpemUpOwoJCQltX1dlaWdodFRhYmxlW3VdLldlaWdodHNbaVNyYy1pTGVmdF0gPSB3ZWlnaHQ7CgkJCWRUb3RhbFdlaWdodCArPSB3ZWlnaHQ7CgkJfQoJCWlmKChkVG90YWxXZWlnaHQgPiAwKSAmJiAoZFRvdGFsV2VpZ2h0ICE9IDEpKSB7CgkJCS8vIG5vcm1hbGl6ZSB3ZWlnaHQgb2YgbmVpZ2hib3VyaW5nIHBvaW50cwoJCQlmb3IoaW50IGlTcmMgPSBpTGVmdDsgaVNyYyA8IGlSaWdodDsgaVNyYysrKSB7CgkJCQkvLyBub3JtYWxpemUgcG9pbnQKCQkJCW1fV2VpZ2h0VGFibGVbdV0uV2VpZ2h0c1tpU3JjLWlMZWZ0XSAvPSBkVG90YWxXZWlnaHQ7IAoJCQl9CgkJfQoKCQkvLyBzaW1wbGlmeSB0aGUgZmlsdGVyLCBkaXNjYXJkaW5nIG51bGwgd2VpZ2h0cyBhdCB0aGUgcmlnaHQKCQl7CQkJCgkJCWludCBpVHJhaWxpbmcgPSBpUmlnaHQgLSBpTGVmdCAtIDE7CgkJCXdoaWxlKG1fV2VpZ2h0VGFibGVbdV0uV2VpZ2h0c1tpVHJhaWxpbmddID09IDApIHsKCQkJCW1fV2VpZ2h0VGFibGVbdV0uUmlnaHQtLTsKCQkJCWlUcmFpbGluZy0tOwoJCQkJaWYobV9XZWlnaHRUYWJsZVt1XS5SaWdodCA9PSBtX1dlaWdodFRhYmxlW3VdLkxlZnQpIHsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQkKCQl9CgoJfSAvLyBuZXh0IGRzdCBwaXhlbAp9CgpDV2VpZ2h0c1RhYmxlOjp+Q1dlaWdodHNUYWJsZSgpIHsKCWZvcih1bnNpZ25lZCB1ID0gMDsgdSA8IG1fTGluZUxlbmd0aDsgdSsrKSB7CgkJLy8gZnJlZSBjb250cmlidXRpb25zIGZvciBldmVyeSBwaXhlbAoJCWZyZWUobV9XZWlnaHRUYWJsZVt1XS5XZWlnaHRzKTsKCX0KCS8vIGZyZWUgbGlzdCBvZiBwaXhlbHMgY29udHJpYnV0aW9ucwoJZnJlZShtX1dlaWdodFRhYmxlKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQKiBDUmVzaXplRW5naW5lOjpzY2FsZShGSUJJVE1BUCAqc3JjLCB1bnNpZ25lZCBkc3Rfd2lkdGgsIHVuc2lnbmVkIGRzdF9oZWlnaHQsIHVuc2lnbmVkIHNyY19sZWZ0LCB1bnNpZ25lZCBzcmNfdG9wLCB1bnNpZ25lZCBzcmNfd2lkdGgsIHVuc2lnbmVkIHNyY19oZWlnaHQsIHVuc2lnbmVkIGZsYWdzKSB7CgoJY29uc3QgRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBzcmNfYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoKCS8vIGRldGVybWluZSB0aGUgaW1hZ2UncyBjb2xvciB0eXBlCglCT09MIGJJc0dyZXlzY2FsZSA9IEZBTFNFOwoJRlJFRV9JTUFHRV9DT0xPUl9UWVBFIGNvbG9yX3R5cGU7CglpZiAoc3JjX2JwcCA8PSA4KSB7CgkJY29sb3JfdHlwZSA9IEdldEV4dGVuZGVkQ29sb3JUeXBlKHNyYywgJmJJc0dyZXlzY2FsZSk7Cgl9IGVsc2UgewoJCWNvbG9yX3R5cGUgPSBGSUNfUkdCOwoJfQoKCS8vIGRldGVybWluZSB0aGUgcmVxdWlyZWQgYml0IGRlcHRoIG9mIHRoZSBkZXN0aW5hdGlvbiBpbWFnZQoJdW5zaWduZWQgZHN0X2JwcDsKCXVuc2lnbmVkIGRzdF9icHBfczEgPSAwOwoJaWYgKGNvbG9yX3R5cGUgPT0gRklDX1BBTEVUVEUgJiYgIWJJc0dyZXlzY2FsZSkgewoJCS8vIG5vbiBncmV5c2NhbGUgRklDX1BBTEVUVEUgaW1hZ2VzIHJlcXVpcmUgYSBoaWdoLWNvbG9yIGRlc3RpbmF0aW9uCgkJLy8gaW1hZ2UgKDI0LSBvciAzMi1iaXRzIGRlcGVuZGluZyBvbiB0aGUgaW1hZ2UncyB0cmFuc3BhcmVudCBzdGF0ZSkKCQlkc3RfYnBwID0gRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQoc3JjKSA/IDMyIDogMjQ7Cgl9IGVsc2UgaWYgKHNyY19icHAgPD0gOCkgewoJCS8vIGdyZXlzY2FsZSBpbWFnZXMgcmVxdWlyZSBhbiA4LWJpdCBkZXN0aW5hdGlvbiBpbWFnZQoJCS8vIChvciBhIDMyLWJpdCBpbWFnZSBpZiB0aGUgaW1hZ2UgaXMgdHJhbnNwYXJlbnQpOwoJCS8vIGhvd2V2ZXIsIGlmIGZsYWcgRklfUkVTQ0FMRV9UUlVFX0NPTE9SIGlzIHNldCwgd2Ugd2lsbCByZXR1cm4KCQkvLyBhIHRydWUgY29sb3IgKDI0IGJwcCkgaW1hZ2UKCQlpZiAoRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQoc3JjKSkgewoJCQlkc3RfYnBwID0gMzI7CgkJCS8vIGFkZGl0aW9uYWxseSwgZm9yIHRyYW5zcGFyZW50IGltYWdlcyB3ZSBhbHdheXMgbmVlZCBhCgkJCS8vIHBhbGV0dGUgaW5jbHVkaW5nIHRyYW5zcGFyZW5jeSBpbmZvcm1hdGlvbiAoYW4gUkdCQSBwYWxldHRlKQoJCQkvLyBzbywgc2V0IGNvbG9yX3R5cGUgYWNjb3JkaW5nbHkKCQkJY29sb3JfdHlwZSA9IEZJQ19QQUxFVFRFOwoJCX0gZWxzZSB7CgkJCWRzdF9icHAgPSAoKGZsYWdzICYgRklfUkVTQ0FMRV9UUlVFX0NPTE9SKSA9PSBGSV9SRVNDQUxFX1RSVUVfQ09MT1IpID8gMjQgOiA4OwoJCQkvLyBpbiBhbnkgY2FzZSwgd2UgdXNlIGEgZmFzdCA4LWJpdCB0ZW1wb3JhcnkgaW1hZ2UgZm9yIHRoZQoJCQkvLyBmaXJzdCBmaWx0ZXIgb3BlcmF0aW9uIChzdGFnZSAxLCBlaXRoZXIgaG9yaXpvbnRhbCBvcgoJCQkvLyB2ZXJ0aWNhbCkgYW5kIGltcGxpY2l0bHkgY29udmVydCB0byAyNCBicHAgKGlmIHJlcXVlc3RlZAoJCQkvLyBieSBmbGFnIEZJX1JFU0NBTEVfVFJVRV9DT0xPUikgZHVyaW5nIHRoZSBzZWNvbmQgZmlsdGVyCgkJCS8vIG9wZXJhdGlvbgoJCQlkc3RfYnBwX3MxID0gODsKCQl9Cgl9IGVsc2UgaWYgKHNyY19icHAgPT0gMTYgJiYgaW1hZ2VfdHlwZSA9PSBGSVRfQklUTUFQKSB7CgkJLy8gMTYtYml0IDU1NSBhbmQgNTY1IFJHQiBpbWFnZXMgcmVxdWlyZSBhIGhpZ2gtY29sb3IgZGVzdGluYXRpb24KCQkvLyBpbWFnZSAoZml4ZWQgdG8gMjQgYml0cywgc2luY2UgMTYtYml0IFJHQnMgZG9uJ3Qgc3VwcG9ydAoJCS8vIHRyYW5zcGFyZW5jeSBpbiBGcmVlSW1hZ2UpCgkJZHN0X2JwcCA9IDI0OwoJfSBlbHNlIHsKCQkvLyBiaXQgZGVwdGggcmVtYWlucyB1bmNoYW5nZWQgZm9yIGFsbCBvdGhlciBpbWFnZXMKCQlkc3RfYnBwID0gc3JjX2JwcDsKCX0KCgkvLyBtYWtlICdzdGFnZSAxJyBicHAgYSBjb3B5IG9mIHRoZSBkZXN0aW5hdGlvbiBicHAgaWYgaXQKCS8vIHdhcyBub3QgZXhwbGljaXRseSBzZXQKCWlmIChkc3RfYnBwX3MxID09IDApIHsKCQlkc3RfYnBwX3MxID0gZHN0X2JwcDsKCX0KCgkvLyBlYXJseSBleGl0IGlmIGRlc3RpbmF0aW9uIHNpemUgaXMgZXF1YWwgdG8gc291cmNlIHNpemUKCWlmICgoc3JjX3dpZHRoID09IGRzdF93aWR0aCkgJiYgKHNyY19oZWlnaHQgPT0gZHN0X2hlaWdodCkpIHsKCQlGSUJJVE1BUCAqb3V0ID0gc3JjOwoJCUZJQklUTUFQICp0bXAgPSBzcmM7CgkJaWYgKChzcmNfd2lkdGggIT0gRnJlZUltYWdlX0dldFdpZHRoKHNyYykpIHx8IChzcmNfaGVpZ2h0ICE9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKSkpIHsKCQkJb3V0ID0gRnJlZUltYWdlX0NvcHkodG1wLCBzcmNfbGVmdCwgc3JjX3RvcCwgc3JjX2xlZnQgKyBzcmNfd2lkdGgsIHNyY190b3AgKyBzcmNfaGVpZ2h0KTsKCQkJdG1wID0gb3V0OwoJCX0KCQlpZiAoc3JjX2JwcCAhPSBkc3RfYnBwKSB7CgkJCXN3aXRjaCAoZHN0X2JwcCkgewoJCQkJY2FzZSA4OgoJCQkJCW91dCA9IEZyZWVJbWFnZV9Db252ZXJ0VG9HcmV5c2NhbGUodG1wKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgMjQ6CgkJCQkJb3V0ID0gRnJlZUltYWdlX0NvbnZlcnRUbzI0Qml0cyh0bXApOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAzMjoKCQkJCQlvdXQgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKHRtcCk7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCWJyZWFrOwoJCQl9CgkJCWlmICh0bXAgIT0gc3JjKSB7CgkJCQlGcmVlSW1hZ2VfVW5sb2FkKHRtcCk7CgkJCQl0bXAgPSBOVUxMOwoJCQl9CgkJfQoKCQlyZXR1cm4gKG91dCAhPSBzcmMpID8gb3V0IDogRnJlZUltYWdlX0Nsb25lKHNyYyk7Cgl9CgoJUkdCUVVBRCBwYWxfYnVmZmVyWzI1Nl07CglSR0JRVUFEICpzcmNfcGFsID0gTlVMTDsKCgkvLyBwcm92aWRlIHRoZSBzb3VyY2UgaW1hZ2UncyBwYWxldHRlIHRvIHRoZSByZXNjYWxlciBmb3IKCS8vIEZJQ19QQUxFVFRFIHR5cGUgaW1hZ2VzICh0aGlzIGluY2x1ZGVzIHBhbGxldGl6ZWQgZ3JleXNjYWxlCgkvLyBpbWFnZXMgd2l0aCBhbiB1bm9yZGVyZWQgcGFsZXR0ZSBhcyB3ZWxsIGFzIHRyYW5zcGFyZW50IGltYWdlcykKCWlmIChjb2xvcl90eXBlID09IEZJQ19QQUxFVFRFKSB7CgkJaWYgKGRzdF9icHAgPT0gMzIpIHsKCQkJLy8gYSAzMi1iaXQgZGVzdGluYXRpb24gaW1hZ2Ugc2lnbmFscyB0cmFuc3BhcmVuY3ksIHNvCgkJCS8vIGNyZWF0ZSBhbiBSR0JBIHBhbGV0dGUgZnJvbSB0aGUgc291cmNlIHBhbGV0dGUKCQkJc3JjX3BhbCA9IEdldFJHQkFQYWxldHRlKHNyYywgcGFsX2J1ZmZlcik7CgkJfSBlbHNlIHsKCQkJc3JjX3BhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKHNyYyk7CgkJfQoJfQoKCS8vIGFsbG9jYXRlIHRoZSBkc3QgaW1hZ2UKCUZJQklUTUFQICpkc3QgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKGltYWdlX3R5cGUsIGRzdF93aWR0aCwgZHN0X2hlaWdodCwgZHN0X2JwcCwgMCwgMCwgMCk7CglpZiAoIWRzdCkgewoJCXJldHVybiBOVUxMOwoJfQoJCglpZiAoZHN0X2JwcCA9PSA4KSB7CgkJUkdCUVVBRCAqIGNvbnN0IGRzdF9wYWwgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkc3QpOwoJCWlmIChjb2xvcl90eXBlID09IEZJQ19NSU5JU1dISVRFKSB7CgkJCS8vIGJ1aWxkIGFuIGludmVydGVkIGdyZXlzY2FsZSBwYWxldHRlCgkJCUNSRUFURV9HUkVZU0NBTEVfUEFMRVRURV9SRVZFUlNFKGRzdF9wYWwsIDI1Nik7CgkJfSAKCQkvKgoJCWVsc2UgewoJCQkvLyBidWlsZCBhIGRlZmF1bHQgZ3JleXNjYWxlIHBhbGV0dGUKCQkJLy8gQ3VycmVudGx5LCBGcmVlSW1hZ2VfQWxsb2NhdGVUIGFscmVhZHkgY3JlYXRlcyBhIGRlZmF1bHQKCQkJLy8gZ3JleXNjYWxlIHBhbGV0dGUgZm9yIDggYnBwIGltYWdlcywgc28gd2UgY2FuIHNraXAgdGhpcyBoZXJlLgoJCQlDUkVBVEVfR1JFWVNDQUxFX1BBTEVUVEUoZHN0X3BhbCwgMjU2KTsKCQl9CgkJKi8KCX0KCgkvLyBjYWxjdWxhdGUgeCBhbmQgeSBvZmZzZXRzOyBzaW5jZSBGcmVlSW1hZ2UgdXNlcyBib3R0b20tdXAgYml0bWFwcywgdGhlCgkvLyB2YWx1ZSBvZiBzcmNfb2Zmc2V0X3kgaXMgbWVhc3VyZWQgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSBpbWFnZQoJdW5zaWduZWQgc3JjX29mZnNldF94ID0gc3JjX2xlZnQ7Cgl1bnNpZ25lZCBzcmNfb2Zmc2V0X3kgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYykgLSBzcmNfaGVpZ2h0IC0gc3JjX3RvcDsKCgkvKgoJRGVjaWRlIHdoaWNoIGZpbHRlcmluZyBvcmRlciAoeHkgb3IgeXgpIGlzIGZhc3RlciBmb3IgdGhpcyBtYXBwaW5nLiAKCS0tLSBUaGUgdGhlb3J5IC0tLQoJVHJ5IHRvIG1pbmltaXplIGNhbGN1bGF0aW9ucyBieSBjb3VudGluZyB0aGUgbnVtYmVyIG9mIGNvbnZvbHV0aW9uIG11bHRpcGxpZXMKCWlmKGRzdF93aWR0aCpzcmNfaGVpZ2h0IDw9IHNyY193aWR0aCpkc3RfaGVpZ2h0KSB7CgkJLy8geHkgZmlsdGVyaW5nCgl9IGVsc2UgewoJCS8vIHl4IGZpbHRlcmluZwoJfQoJLS0tIFRoZSBwcmFjdGljZSAtLS0KCVRyeSB0byBtaW5pbWl6ZSBjYWxjdWxhdGlvbnMgYnkgY291bnRpbmcgdGhlIG51bWJlciBvZiB2ZXJ0aWNhbCBjb252b2x1dGlvbnMgKHRoZSBtb3N0IHRpbWUgY29uc3VtaW5nIHRhc2spCglpZihkc3Rfd2lkdGgqZHN0X2hlaWdodCA8PSBzcmNfd2lkdGgqZHN0X2hlaWdodCkgewoJCS8vIHh5IGZpbHRlcmluZwoJfSBlbHNlIHsKCQkvLyB5eCBmaWx0ZXJpbmcKCX0KCSovCgoJaWYgKGRzdF93aWR0aCA8PSBzcmNfd2lkdGgpIHsKCQkvLyB4eSBmaWx0ZXJpbmcKCQkvLyAtLS0tLS0tLS0tLS0tCgoJCUZJQklUTUFQICp0bXAgPSBOVUxMOwoKCQlpZiAoc3JjX3dpZHRoICE9IGRzdF93aWR0aCkgewoJCQkvLyBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHdpZHRocyBhcmUgZGlmZmVyZW50IHNvLCB3ZSBtdXN0CgkJCS8vIGZpbHRlciBob3Jpem9udGFsbHkKCQkJaWYgKHNyY19oZWlnaHQgIT0gZHN0X2hlaWdodCkgewoJCQkJLy8gc291cmNlIGFuZCBkZXN0aW5hdGlvbiBoZWlnaHRzIGFyZSBhbHNvIGRpZmZlcmVudCBzbywgd2UgbmVlZAoJCQkJLy8gYSB0ZW1wb3JhcnkgaW1hZ2UKCQkJCXRtcCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoaW1hZ2VfdHlwZSwgZHN0X3dpZHRoLCBzcmNfaGVpZ2h0LCBkc3RfYnBwX3MxLCAwLCAwLCAwKTsKCQkJCWlmICghdG1wKSB7CgkJCQkJRnJlZUltYWdlX1VubG9hZChkc3QpOwoJCQkJCXJldHVybiBOVUxMOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJLy8gc291cmNlIGFuZCBkZXN0aW5hdGlvbiBoZWlnaHRzIGFyZSBlcXVhbCBzbywgd2UgY2FuIGRpcmVjdGx5CgkJCQkvLyBzY2FsZSBpbnRvIGRlc3RpbmF0aW9uIGltYWdlIChzZWNvbmQgZmlsdGVyIG1ldGhvZCB3aWxsIG5vdAoJCQkJLy8gYmUgaW52b2tlZCkKCQkJCXRtcCA9IGRzdDsKCQkJfQoKCQkJLy8gc2NhbGUgc291cmNlIGltYWdlIGhvcml6b250YWxseSBpbnRvIHRlbXBvcmFyeSAob3IgZGVzdGluYXRpb24pIGltYWdlCgkJCWhvcml6b250YWxGaWx0ZXIoc3JjLCBzcmNfaGVpZ2h0LCBzcmNfd2lkdGgsIHNyY19vZmZzZXRfeCwgc3JjX29mZnNldF95LCBzcmNfcGFsLCB0bXAsIGRzdF93aWR0aCk7CgoJCQkvLyBzZXQgeCBhbmQgeSBvZmZzZXRzIHRvIHplcm8gZm9yIHRoZSBzZWNvbmQgZmlsdGVyIG1ldGhvZAoJCQkvLyBpbnZvY2F0aW9uICh0aGUgdGVtcG9yYXJ5IGltYWdlIG9ubHkgY29udGFpbnMgdGhlIHBvcnRpb24gb2YKCQkJLy8gdGhlIGltYWdlIHRvIGJlIHJlc2NhbGVkIHdpdGggbm8gb2Zmc2V0cykKCQkJc3JjX29mZnNldF94ID0gMDsKCQkJc3JjX29mZnNldF95ID0gMDsKCgkJCS8vIGFsc28gZW5zdXJlLCB0aGF0IHRoZSBzZWNvbmQgZmlsdGVyIG1ldGhvZCBnZXRzIG5vIHNvdXJjZQoJCQkvLyBwYWxldHRlICh0aGUgdGVtcG9yYXJ5IGltYWdlIGlzIHBhbGxldGl6ZWQgb25seSwgaWYgaXQgaXMKCQkJLy8gZ3JleXNjYWxlOyBpbiB0aGF0IGNhc2UsIGl0IGlzIGFuIDgtYml0IGltYWdlIHdpdGggYSBsaW5lYXIKCQkJLy8gcGFsZXR0ZSBzbywgdGhlIHNvdXJjZSBwYWxldHRlIGlzIG5vdCBuZWVkZWQgb3Igd2lsbCBldmVuIGJlCgkJCS8vIG1pc21hdGNoaW5nLCBpZiB0aGUgc291cmNlIHBhbGV0dGUgaXMgdW5vcmRlcmVkKQoJCQlzcmNfcGFsID0gTlVMTDsKCQl9IGVsc2UgewoJCQkvLyBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHdpZHRocyBhcmUgZXF1YWwgc28sIGp1c3QgY29weSB0aGUKCQkJLy8gaW1hZ2UgcG9pbnRlcgoJCQl0bXAgPSBzcmM7CgkJfQoKCQlpZiAoc3JjX2hlaWdodCAhPSBkc3RfaGVpZ2h0KSB7CgkJCS8vIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gaGVpZ2h0cyBhcmUgZGlmZmVyZW50IHNvLCBzY2FsZQoJCQkvLyB0ZW1wb3JhcnkgKG9yIHNvdXJjZSkgaW1hZ2UgdmVydGljYWxseSBpbnRvIGRlc3RpbmF0aW9uIGltYWdlCgkJCXZlcnRpY2FsRmlsdGVyKHRtcCwgZHN0X3dpZHRoLCBzcmNfaGVpZ2h0LCBzcmNfb2Zmc2V0X3gsIHNyY19vZmZzZXRfeSwgc3JjX3BhbCwgZHN0LCBkc3RfaGVpZ2h0KTsKCQl9CgoJCS8vIGZyZWUgdGVtcG9yYXJ5IGltYWdlLCBpZiBub3QgcG9pbnRpbmcgdG8gZWl0aGVyIHNyYyBvciBkc3QKCQlpZiAodG1wICE9IHNyYyAmJiB0bXAgIT0gZHN0KSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQodG1wKTsKCQl9CgoJfSBlbHNlIHsKCQkvLyB5eCBmaWx0ZXJpbmcKCQkvLyAtLS0tLS0tLS0tLS0tCgoJCS8vIFJlbWFyazoKCQkvLyBUaGUgeXggZmlsdGVyaW5nIGJyYW5jaCBjb3VsZCBiZSBtb3JlIG9wdGltaXplZCBieSB0YWtpbmcgaW50bywKCQkvLyBhY2NvdW50IHRoYXQgKHNyY193aWR0aCAhPSBkc3Rfd2lkdGgpIGlzIGFsd2F5cyB0cnVlLCB3aGljaAoJCS8vIGZvbGxvd3MgZnJvbSB0aGUgYWJvdmUgY29uZGl0aW9uLCB3aGljaCBzZWxlY3RzIGZpbHRlcmluZyBvcmRlci4KCQkvLyBTaW5jZSAoZHN0X3dpZHRoIDw9IHNyY193aWR0aCkgPT0gVFJVRSBzZWxlY3RzIHh5IGZpbHRlcmluZywKCQkvLyBib3RoIHdpZHRocyBtdXN0IGJlIGRpZmZlcmVudCB3aGVuIHBlcmZvcm1pbmcgeXggZmlsdGVyaW5nLgoJCS8vIEhvd2V2ZXIsIHRvIG1ha2UgdGhlIGNvZGUgbW9yZSByb2J1c3QsIG5vdCBkZXBlbmRpbmcgb24gdGhhdAoJCS8vIGNvbmRpdGlvbiBhbmQgbW9yZSBzeW1tZXRyaWMgdG8gdGhlIHh5IGZpbHRlcmluZyBjYXNlLCB0aGVzZQoJCS8vIChzcmNfd2lkdGggIT0gZHN0X3dpZHRoKSBjb25kaXRpb25zIGFyZSBzdGlsbCBpbiBwbGFjZS4KCgkJRklCSVRNQVAgKnRtcCA9IE5VTEw7CgoJCWlmIChzcmNfaGVpZ2h0ICE9IGRzdF9oZWlnaHQpIHsKCQkJLy8gc291cmNlIGFuZCBkZXN0aW5hdGlvbiBoZWlnaHRzIGFyZSBkaWZmZXJlbnQgc28sIHdlIG11c3QKCQkJLy8gZmlsdGVyIHZlcnRpY2FsbHkKCQkJaWYgKHNyY193aWR0aCAhPSBkc3Rfd2lkdGgpIHsKCQkJCS8vIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gd2lkdGhzIGFyZSBhbHNvIGRpZmZlcmVudCBzbywgd2UgbmVlZAoJCQkJLy8gYSB0ZW1wb3JhcnkgaW1hZ2UKCQkJCXRtcCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoaW1hZ2VfdHlwZSwgc3JjX3dpZHRoLCBkc3RfaGVpZ2h0LCBkc3RfYnBwX3MxLCAwLCAwLCAwKTsKCQkJCWlmICghdG1wKSB7CgkJCQkJRnJlZUltYWdlX1VubG9hZChkc3QpOwoJCQkJCXJldHVybiBOVUxMOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJLy8gc291cmNlIGFuZCBkZXN0aW5hdGlvbiB3aWR0aHMgYXJlIGVxdWFsIHNvLCB3ZSBjYW4gZGlyZWN0bHkKCQkJCS8vIHNjYWxlIGludG8gZGVzdGluYXRpb24gaW1hZ2UgKHNlY29uZCBmaWx0ZXIgbWV0aG9kIHdpbGwgbm90CgkJCQkvLyBiZSBpbnZva2VkKQoJCQkJdG1wID0gZHN0OwoJCQl9CgoJCQkvLyBzY2FsZSBzb3VyY2UgaW1hZ2UgdmVydGljYWxseSBpbnRvIHRlbXBvcmFyeSAob3IgZGVzdGluYXRpb24pIGltYWdlCgkJCXZlcnRpY2FsRmlsdGVyKHNyYywgc3JjX3dpZHRoLCBzcmNfaGVpZ2h0LCBzcmNfb2Zmc2V0X3gsIHNyY19vZmZzZXRfeSwgc3JjX3BhbCwgdG1wLCBkc3RfaGVpZ2h0KTsKCgkJCS8vIHNldCB4IGFuZCB5IG9mZnNldHMgdG8gemVybyBmb3IgdGhlIHNlY29uZCBmaWx0ZXIgbWV0aG9kCgkJCS8vIGludm9jYXRpb24gKHRoZSB0ZW1wb3JhcnkgaW1hZ2Ugb25seSBjb250YWlucyB0aGUgcG9ydGlvbiBvZgoJCQkvLyB0aGUgaW1hZ2UgdG8gYmUgcmVzY2FsZWQgd2l0aCBubyBvZmZzZXRzKQoJCQlzcmNfb2Zmc2V0X3ggPSAwOwoJCQlzcmNfb2Zmc2V0X3kgPSAwOwoKCQkJLy8gYWxzbyBlbnN1cmUsIHRoYXQgdGhlIHNlY29uZCBmaWx0ZXIgbWV0aG9kIGdldHMgbm8gc291cmNlCgkJCS8vIHBhbGV0dGUgKHRoZSB0ZW1wb3JhcnkgaW1hZ2UgaXMgcGFsbGV0aXplZCBvbmx5LCBpZiBpdCBpcwoJCQkvLyBncmV5c2NhbGU7IGluIHRoYXQgY2FzZSwgaXQgaXMgYW4gOC1iaXQgaW1hZ2Ugd2l0aCBhIGxpbmVhcgoJCQkvLyBwYWxldHRlIHNvLCB0aGUgc291cmNlIHBhbGV0dGUgaXMgbm90IG5lZWRlZCBvciB3aWxsIGV2ZW4gYmUKCQkJLy8gbWlzbWF0Y2hpbmcsIGlmIHRoZSBzb3VyY2UgcGFsZXR0ZSBpcyB1bm9yZGVyZWQpCgkJCXNyY19wYWwgPSBOVUxMOwoKCQl9IGVsc2UgewoJCQkvLyBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGhlaWdodHMgYXJlIGVxdWFsIHNvLCBqdXN0IGNvcHkgdGhlCgkJCS8vIGltYWdlIHBvaW50ZXIKCQkJdG1wID0gc3JjOwoJCX0KCgkJaWYgKHNyY193aWR0aCAhPSBkc3Rfd2lkdGgpIHsKCQkJLy8gc291cmNlIGFuZCBkZXN0aW5hdGlvbiBoZWlnaHRzIGFyZSBkaWZmZXJlbnQgc28sIHNjYWxlCgkJCS8vIHRlbXBvcmFyeSAob3Igc291cmNlKSBpbWFnZSBob3Jpem9udGFsbHkgaW50byBkZXN0aW5hdGlvbiBpbWFnZQoJCQlob3Jpem9udGFsRmlsdGVyKHRtcCwgZHN0X2hlaWdodCwgc3JjX3dpZHRoLCBzcmNfb2Zmc2V0X3gsIHNyY19vZmZzZXRfeSwgc3JjX3BhbCwgZHN0LCBkc3Rfd2lkdGgpOwoJCX0KCgkJLy8gZnJlZSB0ZW1wb3JhcnkgaW1hZ2UsIGlmIG5vdCBwb2ludGluZyB0byBlaXRoZXIgc3JjIG9yIGRzdAoJCWlmICh0bXAgIT0gc3JjICYmIHRtcCAhPSBkc3QpIHsKCQkJRnJlZUltYWdlX1VubG9hZCh0bXApOwoJCX0KCX0KCglyZXR1cm4gZHN0Owp9IAoKdm9pZCBDUmVzaXplRW5naW5lOjpob3Jpem9udGFsRmlsdGVyKEZJQklUTUFQICpjb25zdCBzcmMsIHVuc2lnbmVkIGhlaWdodCwgdW5zaWduZWQgc3JjX3dpZHRoLCB1bnNpZ25lZCBzcmNfb2Zmc2V0X3gsIHVuc2lnbmVkIHNyY19vZmZzZXRfeSwgY29uc3QgUkdCUVVBRCAqY29uc3Qgc3JjX3BhbCwgRklCSVRNQVAgKmNvbnN0IGRzdCwgdW5zaWduZWQgZHN0X3dpZHRoKSB7CgoJLy8gYWxsb2NhdGUgYW5kIGNhbGN1bGF0ZSB0aGUgY29udHJpYnV0aW9ucwoJQ1dlaWdodHNUYWJsZSB3ZWlnaHRzVGFibGUobV9wRmlsdGVyLCBkc3Rfd2lkdGgsIHNyY193aWR0aCk7CgoJLy8gc3RlcCB0aHJvdWdoIHJvd3MKCXN3aXRjaChGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYykpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJewoJCQlzd2l0Y2goRnJlZUltYWdlX0dldEJQUChzcmMpKSB7CgkJCQljYXNlIDE6CgkJCQl7CgkJCQkJc3dpdGNoKEZyZWVJbWFnZV9HZXRCUFAoZHN0KSkgewoJCQkJCQljYXNlIDg6CgkJCQkJCXsKCQkJCQkJCS8vIHRyYW5zcGFyZW50bHkgY29udmVydCB0aGUgMS1iaXQgbm9uLXRyYW5zcGFyZW50IGdyZXlzY2FsZSBpbWFnZSB0byA4IGJwcAoJCQkJCQkJc3JjX29mZnNldF94ID4+PSAzOwoJCQkJCQkJaWYgKHNyY19wYWwpIHsKCQkJCQkJCQkvLyB3ZSBoYXZlIGdvdCBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQkJCUJZVEUgKiBjb25zdCBkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpUmlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KTsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gaUxlZnQ7IGkgPCBpUmlnaHQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gKHNyY19iaXRzW2kgPj4gM10gJiAoMHg4MCA+PiAoaSAmIDB4MDcpKSkgIT0gMDsKCQkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpIC0gaUxlZnQpICogKGRvdWJsZSkqKEJZVEUgKikmc3JjX3BhbFtwaXhlbF0pOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWRzdF9iaXRzW3hdID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkvLyB3ZSBkbyBub3QgaGF2ZSBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQkJCUJZVEUgKiBjb25zdCBkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpUmlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KTsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gaUxlZnQ7IGkgPCBpUmlnaHQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gKHNyY19iaXRzW2kgPj4gM10gJiAoMHg4MCA+PiAoaSAmIDB4MDcpKSkgIT0gMDsKCQkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpIC0gaUxlZnQpICogKGRvdWJsZSlwaXhlbCk7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCQl2YWx1ZSAqPSAweEZGOwoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWRzdF9iaXRzW3hdID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAyNDoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSBub24tdHJhbnNwYXJlbnQgMS1iaXQgaW1hZ2UgdG8gMjQgYnBwCgkJCQkJCQlzcmNfb2Zmc2V0X3ggPj49IDM7CgkJCQkJCQlpZiAoc3JjX3BhbCkgewoJCQkJCQkJCS8vIHdlIGhhdmUgZ290IGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeDsKCQkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCgkJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHgpOyAgICAvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpUmlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KTsgIC8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMDsKCgkJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSBpTGVmdDsgaSA8IGlSaWdodDsgaSsrKSB7CgkJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeCwgaSAtIGlMZWZ0KTsKCQkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBwaXhlbCA9IChzcmNfYml0c1tpID4+IDNdICYgKDB4ODAgPj4gKGkgJiAweDA3KSkpICE9IDA7CgkJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFtwaXhlbF07CgkJCQkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJCQl9CgoJCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9SRURdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShyICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYiArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHMgKz0gMzsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJLy8gd2UgZG8gbm90IGhhdmUgYSBwYWxldHRlCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCQkJCS8vIHNjYWxlIGVhY2ggcm93CgkJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkgKyBzcmNfb2Zmc2V0X3kpICsgc3JjX29mZnNldF94OwoJCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7ICAgIC8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlSaWdodCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpOyAgLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gaUxlZnQ7IGkgPCBpUmlnaHQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gKHNyY19iaXRzW2kgPj4gM10gJiAoMHg4MCA+PiAoaSAmIDB4MDcpKSkgIT0gMDsKCQkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpIC0gaUxlZnQpICogKGRvdWJsZSlwaXhlbCk7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCQl2YWx1ZSAqPSAweEZGOwoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWNvbnN0IEJZVEUgYnZhbCA9IChCWVRFKUNMQU1QPGludD4oKGludCkodmFsdWUgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IGJ2YWw7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IGJ2YWw7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gYnZhbDsKCQkJCQkJCQkJCWRzdF9iaXRzICs9IDM7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDMyOgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIHRyYW5zcGFyZW50IDEtYml0IGltYWdlIHRvIDMyIGJwcDsgCgkJCQkJCQkvLyB3ZSBhbHdheXMgaGF2ZSBnb3QgYSBwYWxldHRlIGhlcmUKCQkJCQkJCXNyY19vZmZzZXRfeCA+Pj0gMzsKCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkgKyBzcmNfb2Zmc2V0X3kpICsgc3JjX29mZnNldF94OwoJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh4KTsgICAgLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpUmlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KTsgIC8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwLCBhID0gMDsKCgkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IGlMZWZ0OyBpIDwgaVJpZ2h0OyBpKyspIHsKCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpIC0gaUxlZnQpOwoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWwgPSAoc3JjX2JpdHNbaSA+PiAzXSAmICgweDgwID4+IChpICYgMHgwNykpKSAhPSAwOwoJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFtwaXhlbF07CgkJCQkJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfUkVEXSk7CgkJCQkJCQkJCQlnICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfR1JFRU5dKTsKCQkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQUxQSEFdKTsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYiArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0FMUEhBXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0cyArPSA0OwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCgkJCQljYXNlIDQ6CgkJCQl7CgkJCQkJc3dpdGNoKEZyZWVJbWFnZV9HZXRCUFAoZHN0KSkgewoJCQkJCQljYXNlIDg6CgkJCQkJCXsKCQkJCQkJCS8vIHRyYW5zcGFyZW50bHkgY29udmVydCB0aGUgbm9uLXRyYW5zcGFyZW50IDQtYml0IGdyZXlzY2FsZSBpbWFnZSB0byA4IGJwcDsgCgkJCQkJCQkvLyB3ZSBhbHdheXMgaGF2ZSBnb3QgYSBwYWxldHRlIGZvciA0LWJpdCBpbWFnZXMKCQkJCQkJCXNyY19vZmZzZXRfeCA+Pj0gMTsKCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkgKyBzcmNfb2Zmc2V0X3kpICsgc3JjX29mZnNldF94OwoJCQkJCQkJCUJZVEUgKiBjb25zdCBkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7ICAgIC8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaVJpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCk7ICAvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQlkb3VibGUgdmFsdWUgPSAwOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gaUxlZnQ7IGkgPCBpUmlnaHQ7IGkrKykgewoJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gaSAmIDB4MDEgPyBzcmNfYml0c1tpID4+IDFdICYgMHgwRiA6IHNyY19iaXRzW2kgPj4gMV0gPj4gNDsKCQkJCQkJCQkJCXZhbHVlICs9ICh3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkgLSBpTGVmdCkgKiAoZG91YmxlKSooQllURSAqKSZzcmNfcGFsW3BpeGVsXSk7CgkJCQkJCQkJCX0KCgkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJZHN0X2JpdHNbeF0gPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAyNDoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSBub24tdHJhbnNwYXJlbnQgNC1iaXQgaW1hZ2UgdG8gMjQgYnBwOyAKCQkJCQkJCS8vIHdlIGFsd2F5cyBoYXZlIGdvdCBhIHBhbGV0dGUgZm9yIDQtYml0IGltYWdlcwoJCQkJCQkJc3JjX29mZnNldF94ID4+PSAxOwoKCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJCS8vIHNjYWxlIGVhY2ggcm93CgkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCByb3cKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHgpOyAgICAvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlSaWdodCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpOyAgLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDA7CgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSBpTGVmdDsgaSA8IGlSaWdodDsgaSsrKSB7CgkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeCwgaSAtIGlMZWZ0KTsKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gaSAmIDB4MDEgPyBzcmNfYml0c1tpID4+IDFdICYgMHgwRiA6IHNyY19iaXRzW2kgPj4gMV0gPj4gNDsKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBlbnRyeSA9IChCWVRFICopJnNyY19wYWxbcGl4ZWxdOwoJCQkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0dSRUVOXSk7CgkJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQkxVRV0pOwoJCQkJCQkJCQl9CgoJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzICs9IDM7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAzMjoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSB0cmFuc3BhcmVudCA0LWJpdCBpbWFnZSB0byAzMiBicHA7IAoJCQkJCQkJLy8gd2UgYWx3YXlzIGhhdmUgZ290IGEgcGFsZXR0ZSBmb3IgNC1iaXQgaW1hZ2VzCgkJCQkJCQlzcmNfb2Zmc2V0X3ggPj49IDE7CgoJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeDsKCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7ICAgIC8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaVJpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCk7ICAvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSBpTGVmdDsgaSA8IGlSaWdodDsgaSsrKSB7CgkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeCwgaSAtIGlMZWZ0KTsKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gaSAmIDB4MDEgPyBzcmNfYml0c1tpID4+IDFdICYgMHgwRiA6IHNyY19iaXRzW2kgPj4gMV0gPj4gNDsKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBlbnRyeSA9IChCWVRFICopJnNyY19wYWxbcGl4ZWxdOwoJCQkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0dSRUVOXSk7CgkJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQkxVRV0pOwoJCQkJCQkJCQkJYSArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0FMUEhBXSk7CgkJCQkJCQkJCX0KCgkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9SRURdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShyICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShnICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9BTFBIQV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGEgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHMgKz0gNDsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgoJCQkJY2FzZSA4OgoJCQkJewoJCQkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRzdCkpIHsKCQkJCQkJY2FzZSA4OgoJCQkJCQl7CgkJCQkJCQkvLyBzY2FsZSB0aGUgOC1iaXQgbm9uLXRyYW5zcGFyZW50IGdyZXlzY2FsZSBpbWFnZQoJCQkJCQkJLy8gaW50byBhbiA4IGJwcCBkZXN0aW5hdGlvbiBpbWFnZQoJCQkJCQkJaWYgKHNyY19wYWwpIHsKCQkJCQkJCQkvLyB3ZSBoYXZlIGdvdCBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQkJCUJZVEUgKiBjb25zdCBkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3QgcGl4ZWwgPSBzcmNfYml0cyArIGlMZWZ0OwoJCQkJCQkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJCQkJCQkvLyBmb3IoaSA9IGlMZWZ0IHRvIGlSaWdodCkKCQkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCXZhbHVlICs9ICh3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkpICogKGRvdWJsZSkqKEJZVEUgKikmc3JjX3BhbFtwaXhlbFtpXV0pOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWRzdF9iaXRzW3hdID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkvLyB3ZSBkbyBub3QgaGF2ZSBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQkJCUJZVEUgKiBjb25zdCBkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3QgcGl4ZWwgPSBzcmNfYml0cyArIGlMZWZ0OwoJCQkJCQkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJCQkJCQkvLyBmb3IoaSA9IGlMZWZ0IHRvIGlSaWdodCkKCQkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCXZhbHVlICs9ICh3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkpICogKGRvdWJsZSlwaXhlbFtpXSk7CgkJCQkJCQkJCQl9CgoJCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkJZHN0X2JpdHNbeF0gPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDI0OgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIG5vbi10cmFuc3BhcmVudCA4LWJpdCBpbWFnZSB0byAyNCBicHAKCQkJCQkJCWlmIChzcmNfcGFsKSB7CgkJCQkJCQkJLy8gd2UgaGF2ZSBnb3QgYSBwYWxldHRlCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCQkJCS8vIHNjYWxlIGVhY2ggcm93CgkJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkgKyBzcmNfb2Zmc2V0X3kpICsgc3JjX29mZnNldF94OwoJCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3QgcGl4ZWwgPSBzcmNfYml0cyArIGlMZWZ0OwoJCQkJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDA7CgoJCQkJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpKTsKCQkJCQkJCQkJCQljb25zdCBCWVRFICpjb25zdCBlbnRyeSA9IChCWVRFICopJnNyY19wYWxbcGl4ZWxbaV1dOwoJCQkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9SRURdKTsKCQkJCQkJCQkJCQlnICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfR1JFRU5dKTsKCQkJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQkxVRV0pOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzICs9IDM7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCS8vIHdlIGRvIG5vdCBoYXZlIGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeDsKCQkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCgkJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHgpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHBpeGVsID0gc3JjX2JpdHMgKyBpTGVmdDsKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpKTsKCQkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFtpXSk7CgkJCQkJCQkJCQl9CgoJCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkJY29uc3QgQllURSBidmFsID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9SRURdCT0gYnZhbDsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gYnZhbDsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSBidmFsOwoJCQkJCQkJCQkJZHN0X2JpdHMgKz0gMzsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlicmVhazsKCgkJCQkJCWNhc2UgMzI6CgkJCQkJCXsKCQkJCQkJCS8vIHRyYW5zcGFyZW50bHkgY29udmVydCB0aGUgdHJhbnNwYXJlbnQgOC1iaXQgaW1hZ2UgdG8gMzIgYnBwOyAKCQkJCQkJCS8vIHdlIGFsd2F5cyBoYXZlIGdvdCBhIHBhbGV0dGUgaGVyZQoJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeDsKCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IHBpeGVsID0gc3JjX2JpdHMgKyBpTGVmdDsKCQkJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDAsIGEgPSAwOwoKCQkJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCWNvbnN0IGRvdWJsZSB3ZWlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkpOwoJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFtwaXhlbFtpXV07CgkJCQkJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfUkVEXSk7CgkJCQkJCQkJCQlnICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfR1JFRU5dKTsKCQkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQUxQSEFdKTsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYiArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0FMUEhBXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0cyArPSA0OwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCgkJCQljYXNlIDE2OgoJCQkJewoJCQkJCS8vIHRyYW5zcGFyZW50bHkgY29udmVydCB0aGUgMTYtYml0IG5vbi10cmFuc3BhcmVudCBpbWFnZSB0byAyNCBicHAKCQkJCQlpZiAoSVNfRk9STUFUX1JHQjU2NShzcmMpKSB7CgkJCQkJCS8vIGltYWdlIGhhcyA1NjUgZm9ybWF0CgkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCWNvbnN0IFdPUkQgKiBjb25zdCBzcmNfYml0cyA9IChXT1JEICopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3ggLyBzaXplb2YoV09SRCk7CgkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCByb3cKCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCWNvbnN0IFdPUkQgKnBpeGVsID0gc3JjX2JpdHMgKyBpTGVmdDsKCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMDsKCgkJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeCwgaSk7CgkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqcGl4ZWwgJiBGSTE2XzU2NV9SRURfTUFTSykgPj4gRkkxNl81NjVfUkVEX1NISUZUKSk7CgkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqcGl4ZWwgJiBGSTE2XzU2NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU2NV9HUkVFTl9TSElGVCkpOwoJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKSgoKnBpeGVsICYgRkkxNl81NjVfQkxVRV9NQVNLKSA+PiBGSTE2XzU2NV9CTFVFX1NISUZUKSk7CgkJCQkJCQkJCXBpeGVsKys7CgkJCQkJCQkJfQoKCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9SRURdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSgoKHIgKiAweEZGKSAvIDB4MUYpICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKCgoZyAqIDB4RkYpIC8gMHgzRikgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSgoKGIgKiAweEZGKSAvIDB4MUYpICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJZHN0X2JpdHMgKz0gMzsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCS8vIGltYWdlIGhhcyA1NTUgZm9ybWF0CgkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCQkJCWNvbnN0IFdPUkQgKiBjb25zdCBzcmNfYml0cyA9IChXT1JEICopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3g7CgkJCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCByb3cKCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeCk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh4KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCWNvbnN0IFdPUkQgKnBpeGVsID0gc3JjX2JpdHMgKyBpTGVmdDsKCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMDsKCgkJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeCwgaSk7CgkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqcGl4ZWwgJiBGSTE2XzU1NV9SRURfTUFTSykgPj4gRkkxNl81NTVfUkVEX1NISUZUKSk7CgkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqcGl4ZWwgJiBGSTE2XzU1NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU1NV9HUkVFTl9TSElGVCkpOwoJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKSgoKnBpeGVsICYgRkkxNl81NTVfQkxVRV9NQVNLKSA+PiBGSTE2XzU1NV9CTFVFX1NISUZUKSk7CgkJCQkJCQkJCXBpeGVsKys7CgkJCQkJCQkJfQoKCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9SRURdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSgoKHIgKiAweEZGKSAvIDB4MUYpICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKCgoZyAqIDB4RkYpIC8gMHgxRikgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSgoKGIgKiAweEZGKSAvIDB4MUYpICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJZHN0X2JpdHMgKz0gMzsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWNhc2UgMjQ6CgkJCQl7CgkJCQkJLy8gc2NhbGUgdGhlIDI0LWJpdCBub24tdHJhbnNwYXJlbnQgaW1hZ2UgaW50byBhIDI0IGJwcCBkZXN0aW5hdGlvbiBpbWFnZQoJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeCAqIDM7CgkJCQkJCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgoJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCByb3cKCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh4KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCWNvbnN0IEJZVEUgKiBwaXhlbCA9IHNyY19iaXRzICsgaUxlZnQgKiAzOwoJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDA7CgoJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpKTsKCQkJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsW0ZJX1JHQkFfUkVEXSk7CgkJCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFtGSV9SR0JBX0dSRUVOXSk7CgkJCQkJCQkJYiArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFtGSV9SR0JBX0JMVUVdKTsKCQkJCQkJCQlwaXhlbCArPSAzOwoJCQkJCQkJfQoKCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzICs9IDM7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCgkJCQljYXNlIDMyOgoJCQkJewoJCQkJCS8vIHNjYWxlIHRoZSAzMi1iaXQgdHJhbnNwYXJlbnQgaW1hZ2UgaW50byBhIDMyIGJwcCBkZXN0aW5hdGlvbiBpbWFnZQoJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJCQljb25zdCBCWVRFICogY29uc3Qgc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeCAqIDQ7CgkJCQkJCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgoJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCByb3cKCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh4KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCWNvbnN0IEJZVEUgKnBpeGVsID0gc3JjX2JpdHMgKyBpTGVmdCAqIDQ7CgkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCQkJLy8gZm9yKGkgPSBpTGVmdCB0byBpUmlnaHQpCgkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpKTsKCQkJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsW0ZJX1JHQkFfUkVEXSk7CgkJCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFtGSV9SR0JBX0dSRUVOXSk7CgkJCQkJCQkJYiArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFtGSV9SR0JBX0JMVUVdKTsKCQkJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsW0ZJX1JHQkFfQUxQSEFdKTsKCQkJCQkJCQlwaXhlbCArPSA0OwoJCQkJCQkJfQoKCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQUxQSEFdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShhICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQlkc3RfYml0cyArPSA0OwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1VJTlQxNjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHdvcmRzIHBlciBwaXhlbCAoMSBmb3IgMTYtYml0LCAzIGZvciA0OC1iaXQgb3IgNCBmb3IgNjQtYml0KQoJCQljb25zdCB1bnNpZ25lZCB3b3Jkc3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyBzcmNfd2lkdGgpIC8gc2l6ZW9mKFdPUkQpOwoKCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJY29uc3QgV09SRCAqc3JjX2JpdHMgPSAoV09SRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3ggLyBzaXplb2YoV09SRCk7CgkJCQlXT1JEICpkc3RfYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCgkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHgpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQljb25zdCBXT1JEICpwaXhlbCA9IHNyY19iaXRzICsgaUxlZnQgKiB3b3Jkc3BwOwoJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCS8vIGZvcihpID0gaUxlZnQgdG8gaVJpZ2h0KQoJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCWNvbnN0IGRvdWJsZSB3ZWlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkpOwkJCQkJCQoJCQkJCQl2YWx1ZSArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFswXSk7CgkJCQkJCXBpeGVsKys7CgkJCQkJfQoKCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJZHN0X2JpdHNbMF0gPSAoV09SRClDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRkZGKTsKCQkJCQlkc3RfYml0cyArPSB3b3Jkc3BwOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0IxNjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHdvcmRzIHBlciBwaXhlbCAoMSBmb3IgMTYtYml0LCAzIGZvciA0OC1iaXQgb3IgNCBmb3IgNjQtYml0KQoJCQljb25zdCB1bnNpZ25lZCB3b3Jkc3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyBzcmNfd2lkdGgpIC8gc2l6ZW9mKFdPUkQpOwoKCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJY29uc3QgV09SRCAqc3JjX2JpdHMgPSAoV09SRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSArIHNyY19vZmZzZXRfeSkgKyBzcmNfb2Zmc2V0X3ggLyBzaXplb2YoV09SRCk7CgkJCQlXT1JEICpkc3RfYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCB5KTsKCgkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCQkvLyBsb29wIHRocm91Z2ggcm93CgkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHgpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeCkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQljb25zdCBXT1JEICpwaXhlbCA9IHNyY19iaXRzICsgaUxlZnQgKiB3b3Jkc3BwOwoJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwOwoKCQkJCQkvLyBmb3IoaSA9IGlMZWZ0IHRvIGlSaWdodCkKCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpKTsJCQkJCQkKCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFswXSk7CgkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpcGl4ZWxbMV0pOwoJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsWzJdKTsKCQkJCQkJcGl4ZWwgKz0gd29yZHNwcDsKCQkJCQl9CgoJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQlkc3RfYml0c1swXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkZGRik7CgkJCQkJZHN0X2JpdHNbMV0gPSAoV09SRClDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGRkYpOwoJCQkJCWRzdF9iaXRzWzJdID0gKFdPUkQpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRkZGKTsKCQkJCQlkc3RfYml0cyArPSB3b3Jkc3BwOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JBMTY6CgkJewoJCQkvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiB3b3JkcyBwZXIgcGl4ZWwgKDEgZm9yIDE2LWJpdCwgMyBmb3IgNDgtYml0IG9yIDQgZm9yIDY0LWJpdCkKCQkJY29uc3QgdW5zaWduZWQgd29yZHNwcCA9IChGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gc3JjX3dpZHRoKSAvIHNpemVvZihXT1JEKTsKCgkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJLy8gc2NhbGUgZWFjaCByb3cKCQkJCWNvbnN0IFdPUkQgKnNyY19iaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkgKyBzcmNfb2Zmc2V0X3kpICsgc3JjX29mZnNldF94IC8gc2l6ZW9mKFdPUkQpOwoJCQkJV09SRCAqZHN0X2JpdHMgPSAoV09SRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgoJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh4KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJY29uc3QgV09SRCAqcGl4ZWwgPSBzcmNfYml0cyArIGlMZWZ0ICogd29yZHNwcDsKCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCS8vIGZvcihpID0gaUxlZnQgdG8gaVJpZ2h0KQoJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCWNvbnN0IGRvdWJsZSB3ZWlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHgsIGkpOwkJCQkJCQoJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsWzBdKTsKCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSlwaXhlbFsxXSk7CgkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpcGl4ZWxbMl0pOwoJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKXBpeGVsWzNdKTsKCQkJCQkJcGl4ZWwgKz0gd29yZHNwcDsKCQkJCQl9CgoJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQlkc3RfYml0c1swXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkZGRik7CgkJCQkJZHN0X2JpdHNbMV0gPSAoV09SRClDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGRkYpOwoJCQkJCWRzdF9iaXRzWzJdID0gKFdPUkQpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRkZGKTsKCQkJCQlkc3RfYml0c1szXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkoYSArIDAuNSksIDAsIDB4RkZGRik7CgkJCQkJZHN0X2JpdHMgKz0gd29yZHNwcDsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfRkxPQVQ6CgkJY2FzZSBGSVRfUkdCRjoKCQljYXNlIEZJVF9SR0JBRjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGZsb2F0cyBwZXIgcGl4ZWwgKDEgZm9yIDMyLWJpdCwgMyBmb3IgOTYtYml0IG9yIDQgZm9yIDEyOC1iaXQpCgkJCWNvbnN0IHVuc2lnbmVkIGZsb2F0c3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyBzcmNfd2lkdGgpIC8gc2l6ZW9mKGZsb2F0KTsKCgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkvLyBzY2FsZSBlYWNoIHJvdwoJCQkJY29uc3QgZmxvYXQgKnNyY19iaXRzID0gKGZsb2F0KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5ICsgc3JjX29mZnNldF95KSArIHNyY19vZmZzZXRfeCAvIHNpemVvZihmbG9hdCk7CgkJCQlmbG9hdCAqZHN0X2JpdHMgPSAoZmxvYXQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJLy8gbG9vcCB0aHJvdWdoIHJvdwoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh4KTsgICAgLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCWNvbnN0IHVuc2lnbmVkIGlSaWdodCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHgpOyAgLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQlkb3VibGUgdmFsdWVbNF0gPSB7MCwgMCwgMCwgMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDQgPSAxMjggYnBwIG1heAoKCQkJCQlmb3IodW5zaWduZWQgaSA9IGlMZWZ0OyBpIDwgaVJpZ2h0OyBpKyspIHsKCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh4LCBpLWlMZWZ0KTsKCgkJCQkJCXVuc2lnbmVkIGluZGV4ID0gaSAqIGZsb2F0c3BwOwkvLyBwaXhlbCBpbmRleAoJCQkJCQlmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgZmxvYXRzcHA7IGorKykgewoJCQkJCQkJdmFsdWVbal0gKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbaW5kZXgrK10pOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQkvLyBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQlmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgZmxvYXRzcHA7IGorKykgewoJCQkJCQlkc3RfYml0c1tqXSA9IChmbG9hdCl2YWx1ZVtqXTsKCQkJCQl9CgoJCQkJCWRzdF9iaXRzICs9IGZsb2F0c3BwOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoJfQp9CgovLy8gUGVyZm9ybXMgdmVydGljYWwgaW1hZ2UgZmlsdGVyaW5nCnZvaWQgQ1Jlc2l6ZUVuZ2luZTo6dmVydGljYWxGaWx0ZXIoRklCSVRNQVAgKmNvbnN0IHNyYywgdW5zaWduZWQgd2lkdGgsIHVuc2lnbmVkIHNyY19oZWlnaHQsIHVuc2lnbmVkIHNyY19vZmZzZXRfeCwgdW5zaWduZWQgc3JjX29mZnNldF95LCBjb25zdCBSR0JRVUFEICpjb25zdCBzcmNfcGFsLCBGSUJJVE1BUCAqY29uc3QgZHN0LCB1bnNpZ25lZCBkc3RfaGVpZ2h0KSB7CgoJLy8gYWxsb2NhdGUgYW5kIGNhbGN1bGF0ZSB0aGUgY29udHJpYnV0aW9ucwoJQ1dlaWdodHNUYWJsZSB3ZWlnaHRzVGFibGUobV9wRmlsdGVyLCBkc3RfaGVpZ2h0LCBzcmNfaGVpZ2h0KTsKCgkvLyBzdGVwIHRocm91Z2ggY29sdW1ucwoJc3dpdGNoKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCWNvbnN0IHVuc2lnbmVkIGRzdF9waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3QpOwoJCQlCWVRFICogY29uc3QgZHN0X2Jhc2UgPSBGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJc3dpdGNoKEZyZWVJbWFnZV9HZXRCUFAoc3JjKSkgewoJCQkJY2FzZSAxOgoJCQkJewoJCQkJCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBzcmNfYmFzZSA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYykgKyBzcmNfb2Zmc2V0X3kgKiBzcmNfcGl0Y2ggKyAoc3JjX29mZnNldF94ID4+IDMpOwoKCQkJCQlzd2l0Y2goRnJlZUltYWdlX0dldEJQUChkc3QpKSB7CgkJCQkJCWNhc2UgODoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSAxLWJpdCBub24tdHJhbnNwYXJlbnQgZ3JleXNjYWxlIGltYWdlIHRvIDggYnBwCgkJCQkJCQlpZiAoc3JjX3BhbCkgewoJCQkJCQkJCS8vIHdlIGhhdmUgZ290IGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyB4OwoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpbmRleCA9IHggPj4gMzsKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgbWFzayA9IDB4ODAgPj4gKHggJiAweDA3KTsKCgkJCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCQkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBwaXhlbCA9ICgqc3JjX2JpdHMgJiBtYXNrKSAhPSAwOwoJCQkJCQkJCQkJCXZhbHVlICs9ICh3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHksIGkpICogKGRvdWJsZSkqKEJZVEUgKikmc3JjX3BhbFtwaXhlbF0pOwoJCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJCXZhbHVlICo9IDB4RkY7CgoJCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkJKmRzdF9iaXRzID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkvLyB3ZSBkbyBub3QgaGF2ZSBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCQkvLyB3b3JrIG9uIGNvbHVtbiB4IGluIGRzdAoJCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGRzdF9iYXNlICsgeDsKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ID4+IDM7CgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIG1hc2sgPSAweDgwID4+ICh4ICYgMHgwNyk7CgoJCQkJCQkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyBpbmRleDsKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQkJdmFsdWUgKz0gKHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSkgKiAoZG91YmxlKSgoKnNyY19iaXRzICYgbWFzaykgIT0gMCkpOwoJCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJCXZhbHVlICo9IDB4RkY7CgoJCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkJKmRzdF9iaXRzID0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAyNDoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSBub24tdHJhbnNwYXJlbnQgMS1iaXQgaW1hZ2UgdG8gMjQgYnBwCgkJCQkJCQlpZiAoc3JjX3BhbCkgewoJCQkJCQkJCS8vIHdlIGhhdmUgZ290IGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyB4ICogMzsKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ID4+IDM7CgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIG1hc2sgPSAweDgwID4+ICh4ICYgMHgwNyk7CgoJCQkJCQkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyBpbmRleDsKCQkJCQkJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwOwoKCQkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCWNvbnN0IGRvdWJsZSB3ZWlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHksIGkpOwoJCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gKCpzcmNfYml0cyAmIG1hc2spICE9IDA7CgkJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFtwaXhlbF07CgkJCQkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJLy8gd2UgZG8gbm90IGhhdmUgYSBwYWxldHRlCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQkJLy8gd29yayBvbiBjb2x1bW4geCBpbiBkc3QKCQkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIHggKiAzOwoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpbmRleCA9IHggPj4gMzsKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgbWFzayA9IDB4ODAgPj4gKHggJiAweDA3KTsKCgkJCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCQkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKSAqIChkb3VibGUpKCgqc3JjX2JpdHMgJiBtYXNrKSAhPSAwKSk7CgkJCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQkJdmFsdWUgKj0gMHhGRjsKCgkJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCQljb25zdCBCWVRFIGJ2YWwgPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSBidmFsOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSBidmFsOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IGJ2YWw7CgkJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDMyOgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIHRyYW5zcGFyZW50IDEtYml0IGltYWdlIHRvIDMyIGJwcDsgCgkJCQkJCQkvLyB3ZSBhbHdheXMgaGF2ZSBnb3QgYSBwYWxldHRlIGhlcmUKCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJLy8gd29yayBvbiBjb2x1bW4geCBpbiBkc3QKCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGRzdF9iYXNlICsgeCAqIDQ7CgkJCQkJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ID4+IDM7CgkJCQkJCQkJY29uc3QgdW5zaWduZWQgbWFzayA9IDB4ODAgPj4gKHggJiAweDA3KTsKCgkJCQkJCQkJLy8gc2NhbGUgZWFjaCBjb2x1bW4KCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHkpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKTsKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0gKCpzcmNfYml0cyAmIG1hc2spICE9IDA7CgkJCQkJCQkJCQljb25zdCBCWVRFICogY29uc3QgZW50cnkgPSAoQllURSAqKSZzcmNfcGFsW3BpeGVsXTsKCQkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9SRURdKTsKCQkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCQkJYiArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0JMVUVdKTsKCQkJCQkJCQkJCWEgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9BTFBIQV0pOwoJCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCQl9CgoJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQUxQSEFdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShhICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgoJCQkJY2FzZSA0OgoJCQkJewoJCQkJCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJCQkJCWNvbnN0IEJZVEUgKmNvbnN0IHNyY19iYXNlID0gRnJlZUltYWdlX0dldEJpdHMoc3JjKSArIHNyY19vZmZzZXRfeSAqIHNyY19waXRjaCArIChzcmNfb2Zmc2V0X3ggPj4gMSk7CgoJCQkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRzdCkpIHsKCQkJCQkJY2FzZSA4OgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIG5vbi10cmFuc3BhcmVudCA0LWJpdCBncmV5c2NhbGUgaW1hZ2UgdG8gOCBicHA7IAoJCQkJCQkJLy8gd2UgYWx3YXlzIGhhdmUgZ290IGEgcGFsZXR0ZSBmb3IgNC1iaXQgaW1hZ2VzCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIHg7CgkJCQkJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ID4+IDE7CgoJCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyBpbmRleDsKCQkJCQkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsID0geCAmIDB4MDEgPyAqc3JjX2JpdHMgJiAweDBGIDogKnNyY19iaXRzID4+IDQ7CgkJCQkJCQkJCQl2YWx1ZSArPSAod2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKSAqIChkb3VibGUpKihCWVRFICopJnNyY19wYWxbcGl4ZWxdKTsKCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQkqZHN0X2JpdHMgPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDI0OgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIG5vbi10cmFuc3BhcmVudCA0LWJpdCBpbWFnZSB0byAyNCBicHA7IAoJCQkJCQkJLy8gd2UgYWx3YXlzIGhhdmUgZ290IGEgcGFsZXR0ZSBmb3IgNC1iaXQgaW1hZ2VzCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIHggKiAzOwoJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGluZGV4ID0geCA+PiAxOwoKCQkJCQkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgaW5kZXg7CgkJCQkJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwOwoKCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCQkvLyBzY2FuIGJldHdlZW4gYm91bmRhcmllcwoJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBwaXhlbCA9IHggJiAweDAxID8gKnNyY19iaXRzICYgMHgwRiA6ICpzcmNfYml0cyA+PiA0OwoJCQkJCQkJCQkJY29uc3QgQllURSAqY29uc3QgZW50cnkgPSAoQllURSAqKSZzcmNfcGFsW3BpeGVsXTsKCQkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9SRURdKTsKCQkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCQkJYiArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0JMVUVdKTsKCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYiArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSAzMjoKCQkJCQkJewoJCQkJCQkJLy8gdHJhbnNwYXJlbnRseSBjb252ZXJ0IHRoZSB0cmFuc3BhcmVudCA0LWJpdCBpbWFnZSB0byAzMiBicHA7IAoJCQkJCQkJLy8gd2UgYWx3YXlzIGhhdmUgZ290IGEgcGFsZXR0ZSBmb3IgNC1iaXQgaW1hZ2VzCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIHggKiA0OwoJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGluZGV4ID0geCA+PiAxOwoKCQkJCQkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgaW5kZXg7CgkJCQkJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwLCBhID0gMDsKCgkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJCWNvbnN0IGRvdWJsZSB3ZWlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHksIGkpOwoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWwgPSB4ICYgMHgwMSA/ICpzcmNfYml0cyAmIDB4MEYgOiAqc3JjX2JpdHMgPj4gNDsKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKmNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFtwaXhlbF07CgkJCQkJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfUkVEXSk7CgkJCQkJCQkJCQlnICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfR1JFRU5dKTsKCQkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQUxQSEFdKTsKCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYiArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0FMUEhBXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoYSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWNhc2UgODoKCQkJCXsKCQkJCQljb25zdCB1bnNpZ25lZCBzcmNfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCQkJCQljb25zdCBCWVRFICpjb25zdCBzcmNfYmFzZSA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYykgKyBzcmNfb2Zmc2V0X3kgKiBzcmNfcGl0Y2ggKyBzcmNfb2Zmc2V0X3g7CgoJCQkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRzdCkpIHsKCQkJCQkJY2FzZSA4OgoJCQkJCQl7CgkJCQkJCQkvLyBzY2FsZSB0aGUgOC1iaXQgbm9uLXRyYW5zcGFyZW50IGdyZXlzY2FsZSBpbWFnZSBpbnRvIGFuIDggYnBwIGRlc3RpbmF0aW9uIGltYWdlCgkJCQkJCQlpZiAoc3JjX3BhbCkgewoJCQkJCQkJCS8vIHdlIGhhdmUgZ290IGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyB4OwoKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCBjb2x1bW4KCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHkpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgeDsKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQkJdmFsdWUgKz0gKHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSkgKiAoZG91YmxlKSooQllURSAqKSZzcmNfcGFsWypzcmNfYml0c10pOwoJCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJCX0KCgkJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCQkqZHN0X2JpdHMgPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCS8vIHdlIGRvIG5vdCBoYXZlIGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyB4OwoKCQkJCQkJCQkJLy8gc2NhbGUgZWFjaCBjb2x1bW4KCQkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHkpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgeDsKCQkJCQkJCQkJCWRvdWJsZSB2YWx1ZSA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQkJdmFsdWUgKz0gKHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSkgKiAoZG91YmxlKSpzcmNfYml0cyk7CgkJCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQkJCSpkc3RfYml0cyA9IChCWVRFKUNMQU1QPGludD4oKGludCkodmFsdWUgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlicmVhazsKCgkJCQkJCWNhc2UgMjQ6CgkJCQkJCXsKCQkJCQkJCS8vIHRyYW5zcGFyZW50bHkgY29udmVydCB0aGUgbm9uLXRyYW5zcGFyZW50IDgtYml0IGltYWdlIHRvIDI0IGJwcAoJCQkJCQkJaWYgKHNyY19wYWwpIHsKCQkJCQkJCQkvLyB3ZSBoYXZlIGdvdCBhIHBhbGV0dGUKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCQkvLyB3b3JrIG9uIGNvbHVtbiB4IGluIGRzdAoJCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGRzdF9iYXNlICsgeCAqIDM7CgoJCQkJCQkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyB4OwoJCQkJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDA7CgoJCQkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCQkJCQkJY29uc3QgQllURSAqIGNvbnN0IGVudHJ5ID0gKEJZVEUgKikmc3JjX3BhbFsqc3JjX2JpdHNdOwoJCQkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9SRURdKTsKCQkJCQkJCQkJCQlnICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfR1JFRU5dKTsKCQkJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKWVudHJ5W0ZJX1JHQkFfQkxVRV0pOwoJCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJCX0KCgkJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShnICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCS8vIHdlIGRvIG5vdCBoYXZlIGEgcGFsZXR0ZQoJCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyB4ICogMzsKCgkJCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIHg7CgkJCQkJCQkJCQlkb3VibGUgdmFsdWUgPSAwOwoKCQkJCQkJCQkJCWZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBpTGltaXQ7IGkrKykgewoJCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQkJCXZhbHVlICs9ICh3ZWlnaHRzVGFibGUuZ2V0V2VpZ2h0KHksIGkpICogKGRvdWJsZSkqc3JjX2JpdHMpOwoJCQkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQkJCX0KCgkJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCQljb25zdCBCWVRFIGJ2YWwgPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKHZhbHVlICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSBidmFsOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0JPSBidmFsOwoJCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IGJ2YWw7CgkJCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDMyOgoJCQkJCQl7CgkJCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIHRyYW5zcGFyZW50IDgtYml0IGltYWdlIHRvIDMyIGJwcDsgCgkJCQkJCQkvLyB3ZSBhbHdheXMgaGF2ZSBnb3QgYSBwYWxldHRlIGhlcmUKCQkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJLy8gd29yayBvbiBjb2x1bW4geCBpbiBkc3QKCQkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGRzdF9iYXNlICsgeCAqIDQ7CgoJCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyB4OwoJCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKTsKCQkJCQkJCQkJCWNvbnN0IEJZVEUgKiBjb25zdCBlbnRyeSA9IChCWVRFICopJnNyY19wYWxbKnNyY19iaXRzXTsKCQkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9SRURdKTsKCQkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCQkJYiArPSAod2VpZ2h0ICogKGRvdWJsZSllbnRyeVtGSV9SR0JBX0JMVUVdKTsKCQkJCQkJCQkJCWEgKz0gKHdlaWdodCAqIChkb3VibGUpZW50cnlbRklfUkdCQV9BTFBIQV0pOwoJCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCQl9CgoJCQkJCQkJCQkvLyBjbGFtcCBhbmQgcGxhY2UgcmVzdWx0IGluIGRlc3RpbmF0aW9uIHBpeGVsCgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQUxQSEFdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KShhICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgoJCQkJY2FzZSAxNjoKCQkJCXsKCQkJCQkvLyB0cmFuc3BhcmVudGx5IGNvbnZlcnQgdGhlIDE2LWJpdCBub24tdHJhbnNwYXJlbnQgaW1hZ2UgdG8gMjQgYnBwCgkJCQkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKHNyYykgLyBzaXplb2YoV09SRCk7CgkJCQkJY29uc3QgV09SRCAqY29uc3Qgc3JjX2Jhc2UgPSAoV09SRCAqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYykgKyBzcmNfb2Zmc2V0X3kgKiBzcmNfcGl0Y2ggKyBzcmNfb2Zmc2V0X3g7CgoJCQkJCWlmIChJU19GT1JNQVRfUkdCNTY1KHNyYykpIHsKCQkJCQkJLy8gaW1hZ2UgaGFzIDU2NSBmb3JtYXQKCQkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGRzdF9iYXNlICsgeCAqIDM7CgoJCQkJCQkJLy8gc2NhbGUgZWFjaCBjb2x1bW4KCQkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQkvLyBsb29wIHRocm91Z2ggY29sdW1uCgkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHkpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCQljb25zdCBXT1JEICpzcmNfYml0cyA9IHNyY19iYXNlICsgaUxlZnQgKiBzcmNfcGl0Y2ggKyB4OwoJCQkJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwOwoKCQkJCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKTsKCQkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSkoKCpzcmNfYml0cyAmIEZJMTZfNTY1X1JFRF9NQVNLKSA+PiBGSTE2XzU2NV9SRURfU0hJRlQpKTsKCQkJCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSkoKCpzcmNfYml0cyAmIEZJMTZfNTY1X0dSRUVOX01BU0spID4+IEZJMTZfNTY1X0dSRUVOX1NISUZUKSk7CgkJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqc3JjX2JpdHMgJiBGSTE2XzU2NV9CTFVFX01BU0spID4+IEZJMTZfNTY1X0JMVUVfU0hJRlQpKTsKCQkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJCX0KCgkJCQkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoKChyICogMHhGRikgLyAweDFGKSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSgoKGcgKiAweEZGKSAvIDB4M0YpICsgMC41KSwgMCwgMHhGRik7CgkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoKChiICogMHhGRikgLyAweDFGKSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCS8vIGltYWdlIGhhcyA1NTUgZm9ybWF0CgkJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkvLyB3b3JrIG9uIGNvbHVtbiB4IGluIGRzdAoJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIHggKiAzOwoKCQkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJCQkJY29uc3QgV09SRCAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgeDsKCQkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMDsKCgkJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCQkJCXIgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqc3JjX2JpdHMgJiBGSTE2XzU1NV9SRURfTUFTSykgPj4gRkkxNl81NTVfUkVEX1NISUZUKSk7CgkJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpKCgqc3JjX2JpdHMgJiBGSTE2XzU1NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU1NV9HUkVFTl9TSElGVCkpOwoJCQkJCQkJCQliICs9ICh3ZWlnaHQgKiAoZG91YmxlKSgoKnNyY19iaXRzICYgRkkxNl81NTVfQkxVRV9NQVNLKSA+PiBGSTE2XzU1NV9CTFVFX1NISUZUKSk7CgkJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCQl9CgoJCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKCgociAqIDB4RkYpIC8gMHgxRikgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX0dSRUVOXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkoKChnICogMHhGRikgLyAweDFGKSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlDTEFNUDxpbnQ+KChpbnQpKCgoYiAqIDB4RkYpIC8gMHgxRikgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCgkJCQljYXNlIDI0OgoJCQkJewoJCQkJCS8vIHNjYWxlIHRoZSAyNC1iaXQgdHJhbnNwYXJlbnQgaW1hZ2UgaW50byBhIDI0IGJwcCBkZXN0aW5hdGlvbiBpbWFnZQoJCQkJCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJCQkJCWNvbnN0IEJZVEUgKmNvbnN0IHNyY19iYXNlID0gRnJlZUltYWdlX0dldEJpdHMoc3JjKSArIHNyY19vZmZzZXRfeSAqIHNyY19waXRjaCArIHNyY19vZmZzZXRfeCAqIDM7CgoJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQkJCWNvbnN0IHVuc2lnbmVkIGluZGV4ID0geCAqIDM7CgkJCQkJCUJZVEUgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyBpbmRleDsKCgkJCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxpbWl0ID0gd2VpZ2h0c1RhYmxlLmdldFJpZ2h0Qm91bmRhcnkoeSkgLSBpTGVmdDsJLy8gcmV0cmlldmUgcmlnaHQgYm91bmRhcnkKCQkJCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDA7CgoJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSlzcmNfYml0c1tGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJfQoKCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkgKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSAoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkgKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWNhc2UgMzI6CgkJCQl7CgkJCQkJLy8gc2NhbGUgdGhlIDMyLWJpdCB0cmFuc3BhcmVudCBpbWFnZSBpbnRvIGEgMzIgYnBwIGRlc3RpbmF0aW9uIGltYWdlCgkJCQkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKHNyYyk7CgkJCQkJY29uc3QgQllURSAqY29uc3Qgc3JjX2Jhc2UgPSBGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpICsgc3JjX29mZnNldF95ICogc3JjX3BpdGNoICsgc3JjX29mZnNldF94ICogNDsKCgkJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJLy8gd29yayBvbiBjb2x1bW4geCBpbiBkc3QKCQkJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ICogNDsKCQkJCQkJQllURSAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIGluZGV4OwoKCQkJCQkJLy8gc2NhbGUgZWFjaCBjb2x1bW4KCQkJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCQkJY29uc3QgdW5zaWduZWQgaUxlZnQgPSB3ZWlnaHRzVGFibGUuZ2V0TGVmdEJvdW5kYXJ5KHkpOwkJCQkvLyByZXRyaWV2ZSBsZWZ0IGJvdW5kYXJ5CgkJCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgaW5kZXg7CgkJCQkJCQlkb3VibGUgciA9IDAsIGcgPSAwLCBiID0gMCwgYSA9IDA7CgoJCQkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJCQkvLyBhY2N1bXVsYXRlIHdlaWdodGVkIGVmZmVjdCBvZiBlYWNoIG5laWdoYm9yaW5nIHBpeGVsCgkJCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCQkJciArPSAod2VpZ2h0ICogKGRvdWJsZSlzcmNfYml0c1tGSV9SR0JBX1JFRF0pOwoJCQkJCQkJCWcgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbRklfUkdCQV9HUkVFTl0pOwoJCQkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbRklfUkdCQV9CTFVFXSk7CgkJCQkJCQkJYSArPSAod2VpZ2h0ICogKGRvdWJsZSlzcmNfYml0c1tGSV9SR0JBX0FMUEhBXSk7CgkJCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCQkJfQoKCQkJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkgKHIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfR1JFRU5dCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSAoZyArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChCWVRFKUNMQU1QPGludD4oKGludCkgKGIgKyAwLjUpLCAwLCAweEZGKTsKCQkJCQkJCWRzdF9iaXRzW0ZJX1JHQkFfQUxQSEFdCT0gKEJZVEUpQ0xBTVA8aW50PigoaW50KSAoYSArIDAuNSksIDAsIDB4RkYpOwoJCQkJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1VJTlQxNjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHdvcmRzIHBlciBwaXhlbCAoMSBmb3IgMTYtYml0LCAzIGZvciA0OC1iaXQgb3IgNCBmb3IgNjQtYml0KQoJCQljb25zdCB1bnNpZ25lZCB3b3Jkc3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyB3aWR0aCkgLyBzaXplb2YoV09SRCk7CgoJCQljb25zdCB1bnNpZ25lZCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KSAvIHNpemVvZihXT1JEKTsKCQkJV09SRCAqY29uc3QgZHN0X2Jhc2UgPSAoV09SRCAqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQljb25zdCB1bnNpZ25lZCBzcmNfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKSAvIHNpemVvZihXT1JEKTsKCQkJY29uc3QgV09SRCAqY29uc3Qgc3JjX2Jhc2UgPSAoV09SRCAqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYykJKyBzcmNfb2Zmc2V0X3kgKiBzcmNfcGl0Y2ggKyBzcmNfb2Zmc2V0X3ggKiB3b3Jkc3BwOwoKCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQljb25zdCB1bnNpZ25lZCBpbmRleCA9IHggKiB3b3Jkc3BwOwkvLyBwaXhlbCBpbmRleAoJCQkJV09SRCAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIGluZGV4OwoKCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJY29uc3QgV09SRCAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgaW5kZXg7CgkJCQkJZG91YmxlIHZhbHVlID0gMDsKCgkJCQkJZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IGlMaW1pdDsgaSsrKSB7CgkJCQkJCS8vIHNjYW4gYmV0d2VlbiBib3VuZGFyaWVzCgkJCQkJCS8vIGFjY3VtdWxhdGUgd2VpZ2h0ZWQgZWZmZWN0IG9mIGVhY2ggbmVpZ2hib3JpbmcgcGl4ZWwKCQkJCQkJY29uc3QgZG91YmxlIHdlaWdodCA9IHdlaWdodHNUYWJsZS5nZXRXZWlnaHQoeSwgaSk7CgkJCQkJCXZhbHVlICs9ICh3ZWlnaHQgKiAoZG91YmxlKXNyY19iaXRzWzBdKTsKCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCX0KCgkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCWRzdF9iaXRzWzBdID0gKFdPUkQpQ0xBTVA8aW50PigoaW50KSh2YWx1ZSArIDAuNSksIDAsIDB4RkZGRik7CgoJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCMTY6CgkJewoJCQkvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiB3b3JkcyBwZXIgcGl4ZWwgKDEgZm9yIDE2LWJpdCwgMyBmb3IgNDgtYml0IG9yIDQgZm9yIDY0LWJpdCkKCQkJY29uc3QgdW5zaWduZWQgd29yZHNwcCA9IChGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gd2lkdGgpIC8gc2l6ZW9mKFdPUkQpOwoKCQkJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRzdCkgLyBzaXplb2YoV09SRCk7CgkJCVdPUkQgKmNvbnN0IGRzdF9iYXNlID0gKFdPUkQgKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKHNyYykgLyBzaXplb2YoV09SRCk7CgkJCWNvbnN0IFdPUkQgKmNvbnN0IHNyY19iYXNlID0gKFdPUkQgKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpICsgc3JjX29mZnNldF95ICogc3JjX3BpdGNoICsgc3JjX29mZnNldF94ICogd29yZHNwcDsKCgkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkvLyB3b3JrIG9uIGNvbHVtbiB4IGluIGRzdAoJCQkJY29uc3QgdW5zaWduZWQgaW5kZXggPSB4ICogd29yZHNwcDsJLy8gcGl4ZWwgaW5kZXgKCQkJCVdPUkQgKmRzdF9iaXRzID0gZHN0X2Jhc2UgKyBpbmRleDsKCgkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7CQkJCS8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQljb25zdCB1bnNpZ25lZCBpTGltaXQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KSAtIGlMZWZ0OwkvLyByZXRyaWV2ZSByaWdodCBib3VuZGFyeQoJCQkJCWNvbnN0IFdPUkQgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCWRvdWJsZSByID0gMCwgZyA9IDAsIGIgPSAwOwoKCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKTsJCQkJCQoJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKXNyY19iaXRzWzBdKTsKCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSlzcmNfYml0c1sxXSk7CgkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbMl0pOwoKCQkJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJCX0KCgkJCQkJLy8gY2xhbXAgYW5kIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCWRzdF9iaXRzWzBdID0gKFdPUkQpQ0xBTVA8aW50PigoaW50KShyICsgMC41KSwgMCwgMHhGRkZGKTsKCQkJCQlkc3RfYml0c1sxXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkoZyArIDAuNSksIDAsIDB4RkZGRik7CgkJCQkJZHN0X2JpdHNbMl0gPSAoV09SRClDTEFNUDxpbnQ+KChpbnQpKGIgKyAwLjUpLCAwLCAweEZGRkYpOwoKCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1JHQkExNjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHdvcmRzIHBlciBwaXhlbCAoMSBmb3IgMTYtYml0LCAzIGZvciA0OC1iaXQgb3IgNCBmb3IgNjQtYml0KQoJCQljb25zdCB1bnNpZ25lZCB3b3Jkc3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyB3aWR0aCkgLyBzaXplb2YoV09SRCk7CgoJCQljb25zdCB1bnNpZ25lZCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KSAvIHNpemVvZihXT1JEKTsKCQkJV09SRCAqY29uc3QgZHN0X2Jhc2UgPSAoV09SRCAqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQljb25zdCB1bnNpZ25lZCBzcmNfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKSAvIHNpemVvZihXT1JEKTsKCQkJY29uc3QgV09SRCAqY29uc3Qgc3JjX2Jhc2UgPSAoV09SRCAqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYykgKyBzcmNfb2Zmc2V0X3kgKiBzcmNfcGl0Y2ggKyBzcmNfb2Zmc2V0X3ggKiB3b3Jkc3BwOwoKCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCS8vIHdvcmsgb24gY29sdW1uIHggaW4gZHN0CgkJCQljb25zdCB1bnNpZ25lZCBpbmRleCA9IHggKiB3b3Jkc3BwOwkvLyBwaXhlbCBpbmRleAoJCQkJV09SRCAqZHN0X2JpdHMgPSBkc3RfYmFzZSArIGluZGV4OwoKCQkJCS8vIHNjYWxlIGVhY2ggY29sdW1uCgkJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCQkJLy8gbG9vcCB0aHJvdWdoIGNvbHVtbgoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMZWZ0ID0gd2VpZ2h0c1RhYmxlLmdldExlZnRCb3VuZGFyeSh5KTsJCQkJLy8gcmV0cmlldmUgbGVmdCBib3VuZGFyeQoJCQkJCWNvbnN0IHVuc2lnbmVkIGlMaW1pdCA9IHdlaWdodHNUYWJsZS5nZXRSaWdodEJvdW5kYXJ5KHkpIC0gaUxlZnQ7CS8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJY29uc3QgV09SRCAqc3JjX2JpdHMgPSBzcmNfYmFzZSArIGlMZWZ0ICogc3JjX3BpdGNoICsgaW5kZXg7CgkJCQkJZG91YmxlIHIgPSAwLCBnID0gMCwgYiA9IDAsIGEgPSAwOwoKCQkJCQlmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgaUxpbWl0OyBpKyspIHsKCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpKTsJCQkJCQoJCQkJCQlyICs9ICh3ZWlnaHQgKiAoZG91YmxlKXNyY19iaXRzWzBdKTsKCQkJCQkJZyArPSAod2VpZ2h0ICogKGRvdWJsZSlzcmNfYml0c1sxXSk7CgkJCQkJCWIgKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbMl0pOwoJCQkJCQlhICs9ICh3ZWlnaHQgKiAoZG91YmxlKXNyY19iaXRzWzNdKTsKCgkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQl9CgoJCQkJCS8vIGNsYW1wIGFuZCBwbGFjZSByZXN1bHQgaW4gZGVzdGluYXRpb24gcGl4ZWwKCQkJCQlkc3RfYml0c1swXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkociArIDAuNSksIDAsIDB4RkZGRik7CgkJCQkJZHN0X2JpdHNbMV0gPSAoV09SRClDTEFNUDxpbnQ+KChpbnQpKGcgKyAwLjUpLCAwLCAweEZGRkYpOwoJCQkJCWRzdF9iaXRzWzJdID0gKFdPUkQpQ0xBTVA8aW50PigoaW50KShiICsgMC41KSwgMCwgMHhGRkZGKTsKCQkJCQlkc3RfYml0c1szXSA9IChXT1JEKUNMQU1QPGludD4oKGludCkoYSArIDAuNSksIDAsIDB4RkZGRik7CgoJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfRkxPQVQ6CgkJY2FzZSBGSVRfUkdCRjoKCQljYXNlIEZJVF9SR0JBRjoKCQl7CgkJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGZsb2F0cyBwZXIgcGl4ZWwgKDEgZm9yIDMyLWJpdCwgMyBmb3IgOTYtYml0IG9yIDQgZm9yIDEyOC1iaXQpCgkJCWNvbnN0IHVuc2lnbmVkIGZsb2F0c3BwID0gKEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyB3aWR0aCkgLyBzaXplb2YoZmxvYXQpOwoKCQkJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRzdCkgLyBzaXplb2YoZmxvYXQpOwoJCQlmbG9hdCAqY29uc3QgZHN0X2Jhc2UgPSAoZmxvYXQgKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKHNyYykgLyBzaXplb2YoZmxvYXQpOwoJCQljb25zdCBmbG9hdCAqY29uc3Qgc3JjX2Jhc2UgPSAoZmxvYXQgKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpICsgc3JjX29mZnNldF95ICogc3JjX3BpdGNoICsgc3JjX29mZnNldF94ICogZmxvYXRzcHA7CgoJCQlmb3IgKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJLy8gd29yayBvbiBjb2x1bW4geCBpbiBkc3QKCQkJCWNvbnN0IHVuc2lnbmVkIGluZGV4ID0geCAqIGZsb2F0c3BwOwkvLyBwaXhlbCBpbmRleAoJCQkJZmxvYXQgKmRzdF9iaXRzID0gKGZsb2F0ICopZHN0X2Jhc2UgKyBpbmRleDsKCgkJCQkvLyBzY2FsZSBlYWNoIGNvbHVtbgoJCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQkJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4KCQkJCQljb25zdCB1bnNpZ25lZCBpTGVmdCA9IHdlaWdodHNUYWJsZS5nZXRMZWZ0Qm91bmRhcnkoeSk7ICAgIC8vIHJldHJpZXZlIGxlZnQgYm91bmRhcnkKCQkJCQljb25zdCB1bnNpZ25lZCBpUmlnaHQgPSB3ZWlnaHRzVGFibGUuZ2V0UmlnaHRCb3VuZGFyeSh5KTsgIC8vIHJldHJpZXZlIHJpZ2h0IGJvdW5kYXJ5CgkJCQkJY29uc3QgZmxvYXQgKnNyY19iaXRzID0gc3JjX2Jhc2UgKyBpTGVmdCAqIHNyY19waXRjaCArIGluZGV4OwoJCQkJCWRvdWJsZSB2YWx1ZVs0XSA9IHswLCAwLCAwLCAwfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNCA9IDEyOCBicHAgbWF4CgoJCQkJCWZvciAodW5zaWduZWQgaSA9IGlMZWZ0OyBpIDwgaVJpZ2h0OyBpKyspIHsKCQkJCQkJLy8gc2NhbiBiZXR3ZWVuIGJvdW5kYXJpZXMKCQkJCQkJLy8gYWNjdW11bGF0ZSB3ZWlnaHRlZCBlZmZlY3Qgb2YgZWFjaCBuZWlnaGJvcmluZyBwaXhlbAoJCQkJCQljb25zdCBkb3VibGUgd2VpZ2h0ID0gd2VpZ2h0c1RhYmxlLmdldFdlaWdodCh5LCBpIC0gaUxlZnQpOwoJCQkJCQlmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgZmxvYXRzcHA7IGorKykgewoJCQkJCQkJdmFsdWVbal0gKz0gKHdlaWdodCAqIChkb3VibGUpc3JjX2JpdHNbal0pOwoJCQkJCQl9CgkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQl9CgoJCQkJCS8vIHBsYWNlIHJlc3VsdCBpbiBkZXN0aW5hdGlvbiBwaXhlbAoJCQkJCWZvciAodW5zaWduZWQgaiA9IDA7IGogPCBmbG9hdHNwcDsgaisrKSB7CgkJCQkJCWRzdF9iaXRzW2pdID0gKGZsb2F0KXZhbHVlW2pdOwoJCQkJCX0KCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7Cgl9Cn0K