Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDE5OTYtMjAwMyBHbHlwaCAmIENvZywgTExDCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA1IEpvbmF0aGFuIEJsYW5kZm9yZCA8anJiQHJlZGhhdC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwNiBUaG9ya2lsZCBTdHJheSA8dGhvcmtpbGRAaWZpLnVpby5ubz4KLy8gQ29weXJpZ2h0IChDKSAyMDA3IEplZmYgTXVpemVsYWFyIDxqZWZmQGluZmlkaWdtLm5ldD4KLy8gQ29weXJpZ2h0IChDKSAyMDA3IEFkcmlhbiBKb2huc29uIDxham9obnNvbkByZWRuZW9uLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDA5LCAyMDEwIFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgQ2FybG9zIEdhcmNpYSBDYW1wb3MgPGNhcmxvc2djQGdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDA5IEFsYmVydCBBc3RhbHMgQ2lkIDxhYWNpZEBrZGUub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgQ2hyaXN0aWFuIEZldWVyc+RuZ2VyIDxjZmV1ZXJzYWVuZ2VyQGdvb2dsZW1haWwuY29tPgovLwovLyBUbyBzZWUgYSBkZXNjcmlwdGlvbiBvZiB0aGUgY2hhbmdlcyBwbGVhc2Ugc2VlIHRoZSBDaGFuZ2Vsb2cgZmlsZSB0aGF0Ci8vIGNhbWUgd2l0aCB5b3VyIHRhcmJhbGwgb3IgdHlwZSBtYWtlIENoYW5nZUxvZyBpZiB5b3UgYXJlIGJ1aWxkaW5nIGZyb20gZ2l0Ci8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZuZGVmIE9VVFBVVERFVl9ICiNkZWZpbmUgT1VUUFVUREVWX0gKCiNpZmRlZiBVU0VfR0NDX1BSQUdNQVMKI3ByYWdtYSBpbnRlcmZhY2UKI2VuZGlmCgojaW5jbHVkZSAicG9wcGxlci1jb25maWcuaCIKI2luY2x1ZGUgImdvby9ndHlwZXMuaCIKI2luY2x1ZGUgIkNoYXJUeXBlcy5oIgojaW5jbHVkZSAiT2JqZWN0LmgiCgpjbGFzcyBEaWN0OwpjbGFzcyBHb29IYXNoOwpjbGFzcyBHb29TdHJpbmc7CmNsYXNzIEdmeFN0YXRlOwpzdHJ1Y3QgR2Z4Q29sb3I7CmNsYXNzIEdmeENvbG9yU3BhY2U7CmNsYXNzIEdmeEltYWdlQ29sb3JNYXA7CmNsYXNzIEdmeEZ1bmN0aW9uU2hhZGluZzsKY2xhc3MgR2Z4QXhpYWxTaGFkaW5nOwpjbGFzcyBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nOwpjbGFzcyBHZnhQYXRjaE1lc2hTaGFkaW5nOwpjbGFzcyBHZnhSYWRpYWxTaGFkaW5nOwpjbGFzcyBTdHJlYW07CmNsYXNzIExpbmtzOwpjbGFzcyBMaW5rOwpjbGFzcyBDYXRhbG9nOwpjbGFzcyBQYWdlOwpjbGFzcyBGdW5jdGlvbjsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIE91dHB1dERldgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgT3V0cHV0RGV2IHsKcHVibGljOgoKICAvLyBDb25zdHJ1Y3Rvci4KICBPdXRwdXREZXYoKSB7IHByb2ZpbGVIYXNoID0gTlVMTDsgfQoKICAvLyBEZXN0cnVjdG9yLgogIHZpcnR1YWwgfk91dHB1dERldigpIHt9CgogIC8vLS0tLS0gZ2V0IGluZm8gYWJvdXQgb3V0cHV0IGRldmljZQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB1cHNpZGUtZG93biBjb29yZGluYXRlcz8KICAvLyAoVXBzaWRlLWRvd24gbWVhbnMgKDAsMCkgaXMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgcGFnZS4pCiAgdmlydHVhbCBHQm9vbCB1cHNpZGVEb3duKCkgPSAwOwoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBkcmF3Q2hhcigpIG9yIGRyYXdTdHJpbmcoKT8KICB2aXJ0dWFsIEdCb29sIHVzZURyYXdDaGFyKCkgPSAwOwoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB0aWxpbmdQYXR0ZXJuRmlsbCgpPyAgSWYgdGhpcyByZXR1cm5zIGZhbHNlLAogIC8vIHRpbGluZyBwYXR0ZXJuIGZpbGxzIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nCiAgLy8gb3BlcmF0aW9ucy4KICB2aXJ0dWFsIEdCb29sIHVzZVRpbGluZ1BhdHRlcm5GaWxsKCkgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2Ugc3VwcG9ydCBzcGVjaWZpYyBzaGFkaW5nIHR5cGVzPwogIC8vIHNlZSBnb3VyYXVkVHJpYW5nbGVTaGFkZWRGaWxsKCkgYW5kIHBhdGNoTWVzaFNoYWRlZEZpbGwoKQogIHZpcnR1YWwgR0Jvb2wgdXNlU2hhZGVkRmlsbHMoaW50IHR5cGUpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBGaWxsQ29sb3JTdG9wKCk/CiAgdmlydHVhbCBHQm9vbCB1c2VGaWxsQ29sb3JTdG9wKCkgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGRyYXdGb3JtKCk/ICBJZiB0aGlzIHJldHVybnMgZmFsc2UsCiAgLy8gZm9ybS10eXBlIFhPYmplY3RzIHdpbGwgYmUgaW50ZXJwcmV0ZWQgKGkuZS4sIHVucm9sbGVkKS4KICB2aXJ0dWFsIEdCb29sIHVzZURyYXdGb3JtKCkgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGJlZ2luVHlwZTNDaGFyL2VuZFR5cGUzQ2hhcj8gIE90aGVyd2lzZSwKICAvLyB0ZXh0IGluIFR5cGUgMyBmb250cyB3aWxsIGJlIGRyYXduIHdpdGggZHJhd0NoYXIvZHJhd1N0cmluZy4KICB2aXJ0dWFsIEdCb29sIGludGVycHJldFR5cGUzQ2hhcnMoKSA9IDA7CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgbmVlZCBub24tdGV4dCBjb250ZW50PwogIHZpcnR1YWwgR0Jvb2wgbmVlZE5vblRleHQoKSB7IHJldHVybiBnVHJ1ZTsgfQoKICAvLyBJZiBjdXJyZW50IGNvbG9yc3BhY2UgaXN0IHBhdHRlcm4sCiAgLy8gZG9lcyB0aGlzIGRldmljZSBzdXBwb3J0IHRleHQgaW4gcGF0dGVybiBjb2xvcnNwYWNlPwogIC8vIERlZmF1bHQgaXMgZmFsc2UKICB2aXJ0dWFsIEdCb29sIHN1cHBvcnRUZXh0Q1NQYXR0ZXJuKEdmeFN0YXRlICogLypzdGF0ZSovKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgLy8gSWYgY3VycmVudCBjb2xvcnNwYWNlIGlzdCBwYXR0ZXJuLAogIC8vIG5lZWQgdGhpcyBkZXZpY2Ugc3BlY2lhbCBoYW5kbGluZyBmb3IgbWFza3MgaW4gcGF0dGVybiBjb2xvcnNwYWNlPwogIC8vIERlZmF1bHQgaXMgZmFsc2UKICB2aXJ0dWFsIEdCb29sIGZpbGxNYXNrQ1NQYXR0ZXJuKEdmeFN0YXRlICogLypzdGF0ZSovKSB7IHJldHVybiBnRmFsc2U7IH0KICB2aXJ0dWFsIHZvaWQgZW5kTWFza0NsaXAoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CgogIC8vLS0tLS0gaW5pdGlhbGl6YXRpb24gYW5kIGNvbnRyb2wKCiAgLy8gU2V0IGRlZmF1bHQgdHJhbnNmb3JtIG1hdHJpeC4KICB2aXJ0dWFsIHZvaWQgc2V0RGVmYXVsdENUTShkb3VibGUgKmN0bSk7CgogIC8vIENoZWNrIHRvIHNlZSBpZiBhIHBhZ2Ugc2xpY2Ugc2hvdWxkIGJlIGRpc3BsYXllZC4gIElmIHRoaXMKICAvLyByZXR1cm5zIGZhbHNlLCB0aGUgcGFnZSBkaXNwbGF5IGlzIGFib3J0ZWQuICBUeXBpY2FsbHksIGFuCiAgLy8gT3V0cHV0RGV2IHdpbGwgdXNlIHNvbWUgYWx0ZXJuYXRlIG1lYW5zIHRvIGRpc3BsYXkgdGhlIHBhZ2UKICAvLyBiZWZvcmUgcmV0dXJuaW5nIGZhbHNlLgogIHZpcnR1YWwgR0Jvb2wgY2hlY2tQYWdlU2xpY2UoUGFnZSAqcGFnZSwgZG91YmxlIGhEUEksIGRvdWJsZSB2RFBJLAoJCQkgICAgICAgaW50IHJvdGF0ZSwgR0Jvb2wgdXNlTWVkaWFCb3gsIEdCb29sIGNyb3AsCgkJCSAgICAgICBpbnQgc2xpY2VYLCBpbnQgc2xpY2VZLCBpbnQgc2xpY2VXLCBpbnQgc2xpY2VILAoJCQkgICAgICAgR0Jvb2wgcHJpbnRpbmcsIENhdGFsb2cgKiBjYXRhbG9nLAoJCQkgICAgICAgR0Jvb2wgKCogYWJvcnRDaGVja0Niaykodm9pZCAqZGF0YSkgPSBOVUxMLAoJCQkgICAgICAgdm9pZCAqIGFib3J0Q2hlY2tDYmtEYXRhID0gTlVMTCkKICAgIHsgcmV0dXJuIGdUcnVlOyB9CgogIC8vIFN0YXJ0IGEgcGFnZS4KICB2aXJ0dWFsIHZvaWQgc3RhcnRQYWdlKGludCBwYWdlTnVtLCBHZnhTdGF0ZSAqc3RhdGUpIHt9CgogIC8vIEVuZCBhIHBhZ2UuCiAgdmlydHVhbCB2b2lkIGVuZFBhZ2UoKSB7fQoKICAvLyBEdW1wIHBhZ2UgY29udGVudHMgdG8gZGlzcGxheS4KICB2aXJ0dWFsIHZvaWQgZHVtcCgpIHt9CgogIC8vLS0tLS0gY29vcmRpbmF0ZSBjb252ZXJzaW9uCgogIC8vIENvbnZlcnQgYmV0d2VlbiBkZXZpY2UgYW5kIHVzZXIgY29vcmRpbmF0ZXMuCiAgdmlydHVhbCB2b2lkIGN2dERldlRvVXNlcihkb3VibGUgZHgsIGRvdWJsZSBkeSwgZG91YmxlICp1eCwgZG91YmxlICp1eSk7CiAgdmlydHVhbCB2b2lkIGN2dFVzZXJUb0Rldihkb3VibGUgdXgsIGRvdWJsZSB1eSwgaW50ICpkeCwgaW50ICpkeSk7CgogIGRvdWJsZSAqZ2V0RGVmQ1RNKCkgeyByZXR1cm4gZGVmQ1RNOyB9CiAgZG91YmxlICpnZXREZWZJQ1RNKCkgeyByZXR1cm4gZGVmSUNUTTsgfQoKICAvLy0tLS0tIHNhdmUvcmVzdG9yZSBncmFwaGljcyBzdGF0ZQogIHZpcnR1YWwgdm9pZCBzYXZlU3RhdGUoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHJlc3RvcmVTdGF0ZShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KCiAgLy8tLS0tLSB1cGRhdGUgZ3JhcGhpY3Mgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlQWxsKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUNUTShHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qbTExKi8sIGRvdWJsZSAvKm0xMiovLAoJCQkgZG91YmxlIC8qbTIxKi8sIGRvdWJsZSAvKm0yMiovLCBkb3VibGUgLyptMzEqLywgZG91YmxlIC8qbTMyKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVEYXNoKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVGbGF0bmVzcyhHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZUpvaW4oR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVDYXAoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZU1pdGVyTGltaXQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVXaWR0aChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlQWRqdXN0KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVBbHBoYUlzU2hhcGUoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVRleHRLbm9ja291dChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbENvbG9yU3BhY2UoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUNvbG9yU3BhY2UoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxDb2xvcihHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlQ29sb3IoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUJsZW5kTW9kZShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbE9wYWNpdHkoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZU9wYWNpdHkoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxPdmVycHJpbnQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZU92ZXJwcmludChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVHJhbnNmZXIoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxDb2xvclN0b3AoR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIGRvdWJsZSAvKm9mZnNldCovKSB7fQoKICAvLy0tLS0tIHVwZGF0ZSB0ZXh0IHN0YXRlCiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZvbnQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVRleHRNYXQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUNoYXJTcGFjZShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlUmVuZGVyKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVSaXNlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVXb3JkU3BhY2UoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUhvcml6U2NhbGluZyhHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVGV4dFBvcyhHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVGV4dFNoaWZ0KEdmeFN0YXRlICogLypzdGF0ZSovLCBkb3VibGUgLypzaGlmdCovKSB7fQoKICAvLy0tLS0tIHBhdGggcGFpbnRpbmcKICB2aXJ0dWFsIHZvaWQgc3Ryb2tlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBmaWxsKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBlb0ZpbGwoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCBHQm9vbCB0aWxpbmdQYXR0ZXJuRmlsbChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgT2JqZWN0ICogLypzdHIqLywKCQkJCSAgaW50IC8qcGFpbnRUeXBlKi8sIERpY3QgKiAvKnJlc0RpY3QqLywKCQkJCSAgZG91YmxlICogLyptYXQqLywgZG91YmxlICogLypiYm94Ki8sCgkJCQkgIGludCAvKngwKi8sIGludCAvKnkwKi8sIGludCAvKngxKi8sIGludCAvKnkxKi8sCgkJCQkgIGRvdWJsZSAvKnhTdGVwKi8sIGRvdWJsZSAvKnlTdGVwKi8pCiAgICB7IHJldHVybiBnRmFsc2U7IH0KICB2aXJ0dWFsIEdCb29sIGZ1bmN0aW9uU2hhZGVkRmlsbChHZnhTdGF0ZSAqIC8qc3RhdGUqLywKCQkJCSAgIEdmeEZ1bmN0aW9uU2hhZGluZyAqIC8qc2hhZGluZyovKQogICAgeyByZXR1cm4gZ0ZhbHNlOyB9CiAgdmlydHVhbCBHQm9vbCBheGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIEdmeEF4aWFsU2hhZGluZyAqIC8qc2hhZGluZyovLCBkb3VibGUgLyp0TWluKi8sIGRvdWJsZSAvKnRNYXgqLykKICAgIHsgcmV0dXJuIGdGYWxzZTsgfQogIHZpcnR1YWwgR0Jvb2wgYXhpYWxTaGFkZWRTdXBwb3J0RXh0ZW5kKEdmeFN0YXRlICogLypzdGF0ZSovLCBHZnhBeGlhbFNoYWRpbmcgKiAvKnNoYWRpbmcqLykKICAgIHsgcmV0dXJuIGdGYWxzZTsgfQogIHZpcnR1YWwgR0Jvb2wgcmFkaWFsU2hhZGVkRmlsbChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgR2Z4UmFkaWFsU2hhZGluZyAqIC8qc2hhZGluZyovLCBkb3VibGUgLypzTWluKi8sIGRvdWJsZSAvKnNNYXgqLykKICAgIHsgcmV0dXJuIGdGYWxzZTsgfQogIHZpcnR1YWwgR0Jvb2wgcmFkaWFsU2hhZGVkU3VwcG9ydEV4dGVuZChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgR2Z4UmFkaWFsU2hhZGluZyAqIC8qc2hhZGluZyovKQogICAgeyByZXR1cm4gZ0ZhbHNlOyB9CiAgdmlydHVhbCBHQm9vbCBnb3VyYXVkVHJpYW5nbGVTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZyAqc2hhZGluZykKICAgIHsgcmV0dXJuIGdGYWxzZTsgfQogIHZpcnR1YWwgR0Jvb2wgcGF0Y2hNZXNoU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeFBhdGNoTWVzaFNoYWRpbmcgKnNoYWRpbmcpCiAgICB7IHJldHVybiBnRmFsc2U7IH0KCiAgLy8tLS0tLSBwYXRoIGNsaXBwaW5nCiAgdmlydHVhbCB2b2lkIGNsaXAoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIGVvQ2xpcChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgY2xpcFRvU3Ryb2tlUGF0aChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KCiAgLy8tLS0tLSB0ZXh0IGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgYmVnaW5TdHJpbmdPcChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgZW5kU3RyaW5nT3AoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIGJlZ2luU3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovLCBHb29TdHJpbmcgKiAvKnMqLykge30KICB2aXJ0dWFsIHZvaWQgZW5kU3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBkcmF3Q2hhcihHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qeCovLCBkb3VibGUgLyp5Ki8sCgkJCWRvdWJsZSAvKmR4Ki8sIGRvdWJsZSAvKmR5Ki8sCgkJCWRvdWJsZSAvKm9yaWdpblgqLywgZG91YmxlIC8qb3JpZ2luWSovLAoJCQlDaGFyQ29kZSAvKmNvZGUqLywgaW50IC8qbkJ5dGVzKi8sIFVuaWNvZGUgKiAvKnUqLywgaW50IC8qdUxlbiovKSB7fQogIHZpcnR1YWwgdm9pZCBkcmF3U3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovLCBHb29TdHJpbmcgKiAvKnMqLykge30KICB2aXJ0dWFsIEdCb29sIGJlZ2luVHlwZTNDaGFyKEdmeFN0YXRlICogLypzdGF0ZSovLCBkb3VibGUgLyp4Ki8sIGRvdWJsZSAvKnkqLywKCQkJICAgICAgIGRvdWJsZSAvKmR4Ki8sIGRvdWJsZSAvKmR5Ki8sCgkJCSAgICAgICBDaGFyQ29kZSAvKmNvZGUqLywgVW5pY29kZSAqIC8qdSovLCBpbnQgLyp1TGVuKi8pOwogIHZpcnR1YWwgdm9pZCBlbmRUeXBlM0NoYXIoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIGJlZ2luVGV4dE9iamVjdChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIEdCb29sIGRldmljZUhhc1RleHRDbGlwKEdmeFN0YXRlICogLypzdGF0ZSovKSB7IHJldHVybiBnRmFsc2U7IH0KICB2aXJ0dWFsIHZvaWQgZW5kVGV4dE9iamVjdChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KCiAgLy8tLS0tLSBpbWFnZSBkcmF3aW5nCiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZU1hc2soR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHQm9vbCBpbnZlcnQsIEdCb29sIGludGVycG9sYXRlLAoJCQkgICAgIEdCb29sIGlubGluZUltZyk7CiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJIGludCB3aWR0aCwgaW50IGhlaWdodCwgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsCgkJCSBHQm9vbCBpbnRlcnBvbGF0ZSwgaW50ICptYXNrQ29sb3JzLCBHQm9vbCBpbmxpbmVJbWcpOwogIHZpcnR1YWwgdm9pZCBkcmF3TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCSAgICAgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwgR0Jvb2wgaW50ZXJwb2xhdGUsCgkJCSAgICAgICBTdHJlYW0gKm1hc2tTdHIsIGludCBtYXNrV2lkdGgsIGludCBtYXNrSGVpZ2h0LAoJCQkgICAgICAgR0Jvb2wgbWFza0ludmVydCwgR0Jvb2wgbWFza0ludGVycG9sYXRlKTsKICB2aXJ0dWFsIHZvaWQgZHJhd1NvZnRNYXNrZWRJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJCSAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJCSAgIEdmeEltYWdlQ29sb3JNYXAgKmNvbG9yTWFwLAoJCQkJICAgR0Jvb2wgaW50ZXJwb2xhdGUsCgkJCQkgICBTdHJlYW0gKm1hc2tTdHIsCgkJCQkgICBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJCSAgIEdmeEltYWdlQ29sb3JNYXAgKm1hc2tDb2xvck1hcCwKCQkJCSAgIEdCb29sIG1hc2tJbnRlcnBvbGF0ZSk7CgogIC8vLS0tLS0gZ3JvdXBpbmcgb3BlcmF0b3JzCgogIHZpcnR1YWwgdm9pZCBlbmRNYXJrZWRDb250ZW50KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGJlZ2luTWFya2VkQ29udGVudChjaGFyICpuYW1lLCBEaWN0ICpwcm9wZXJ0aWVzKTsKICB2aXJ0dWFsIHZvaWQgbWFya1BvaW50KGNoYXIgKm5hbWUpOwogIHZpcnR1YWwgdm9pZCBtYXJrUG9pbnQoY2hhciAqbmFtZSwgRGljdCAqcHJvcGVydGllcyk7CiAgCiAgCgojaWYgT1BJX1NVUFBPUlQKICAvLy0tLS0tIE9QSSBmdW5jdGlvbnMKICB2aXJ0dWFsIHZvaWQgb3BpQmVnaW4oR2Z4U3RhdGUgKnN0YXRlLCBEaWN0ICpvcGlEaWN0KTsKICB2aXJ0dWFsIHZvaWQgb3BpRW5kKEdmeFN0YXRlICpzdGF0ZSwgRGljdCAqb3BpRGljdCk7CiNlbmRpZgoKICAvLy0tLS0tIFR5cGUgMyBmb250IG9wZXJhdG9ycwogIHZpcnR1YWwgdm9pZCB0eXBlM0QwKEdmeFN0YXRlICogLypzdGF0ZSovLCBkb3VibGUgLyp3eCovLCBkb3VibGUgLyp3eSovKSB7fQogIHZpcnR1YWwgdm9pZCB0eXBlM0QxKEdmeFN0YXRlICogLypzdGF0ZSovLCBkb3VibGUgLyp3eCovLCBkb3VibGUgLyp3eSovLAoJCSAgICAgICBkb3VibGUgLypsbHgqLywgZG91YmxlIC8qbGx5Ki8sIGRvdWJsZSAvKnVyeCovLCBkb3VibGUgLyp1cnkqLykge30KCiAgLy8tLS0tLSBmb3JtIFhPYmplY3RzCiAgdmlydHVhbCB2b2lkIGRyYXdGb3JtKFJlZiAvKmlkKi8pIHt9CgogIC8vLS0tLS0gUG9zdFNjcmlwdCBYT2JqZWN0cwogIHZpcnR1YWwgdm9pZCBwc1hPYmplY3QoU3RyZWFtICogLypwc1N0cmVhbSovLCBTdHJlYW0gKiAvKmxldmVsMVN0cmVhbSovKSB7fQoKICAvLy0tLS0tIFByb2ZpbGluZwogIHZpcnR1YWwgdm9pZCBzdGFydFByb2ZpbGUoKTsKICB2aXJ0dWFsIEdvb0hhc2ggKmdldFByb2ZpbGVIYXNoKCkge3JldHVybiBwcm9maWxlSGFzaDsgfQogIHZpcnR1YWwgR29vSGFzaCAqZW5kUHJvZmlsZSgpOwoKICAvLy0tLS0tIHRyYW5zcGFyZW5jeSBncm91cHMgYW5kIHNvZnQgbWFza3MKICB2aXJ0dWFsIHZvaWQgYmVnaW5UcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlICogLypiYm94Ki8sCgkJCQkgICAgICBHZnhDb2xvclNwYWNlICogLypibGVuZGluZ0NvbG9yU3BhY2UqLywKCQkJCSAgICAgIEdCb29sIC8qaXNvbGF0ZWQqLywgR0Jvb2wgLyprbm9ja291dCovLAoJCQkJICAgICAgR0Jvb2wgLypmb3JTb2Z0TWFzayovKSB7fQogIHZpcnR1YWwgdm9pZCBlbmRUcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgcGFpbnRUcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlICogLypiYm94Ki8pIHt9CiAgdmlydHVhbCB2b2lkIHNldFNvZnRNYXNrKEdmeFN0YXRlICogLypzdGF0ZSovLCBkb3VibGUgKiAvKmJib3gqLywgR0Jvb2wgLyphbHBoYSovLAoJCQkgICBGdW5jdGlvbiAqIC8qdHJhbnNmZXJGdW5jKi8sIEdmeENvbG9yICogLypiYWNrZHJvcENvbG9yKi8pIHt9CiAgdmlydHVhbCB2b2lkIGNsZWFyU29mdE1hc2soR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CgogIC8vLS0tLS0gbGlua3MKICB2aXJ0dWFsIHZvaWQgcHJvY2Vzc0xpbmsoTGluayAqIC8qbGluayovLCBDYXRhbG9nICogLypjYXRhbG9nKi8pIHt9CgojaWYgMSAvL350bXA6IHR1cm4gb2ZmIGFudGktYWxpYXNpbmcgdGVtcG9yYXJpbHkKICB2aXJ0dWFsIEdCb29sIGdldFZlY3RvckFudGlhbGlhcygpIHsgcmV0dXJuIGdGYWxzZTsgfQogIHZpcnR1YWwgdm9pZCBzZXRWZWN0b3JBbnRpYWxpYXMoR0Jvb2wgLyp2YWEqLykge30KI2VuZGlmCgpwcml2YXRlOgoKICBkb3VibGUgZGVmQ1RNWzZdOwkJLy8gZGVmYXVsdCBjb29yZGluYXRlIHRyYW5zZm9ybSBtYXRyaXgKICBkb3VibGUgZGVmSUNUTVs2XTsJCS8vIGludmVyc2Ugb2YgZGVmYXVsdCBDVE0KICBHb29IYXNoICpwcm9maWxlSGFzaDsKfTsKCiNlbmRpZgo=