LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0KewogICAgUkdCKDB4MDAsIDB4MDAsIDB4MDApLCBSR0IoMHgwMCwgMHgwMCwgMHg4MCksIFJHQigweDAwLCAweDgwLCAweDAwKSwgUkdCKDB4MDAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4ODAsIDB4MDAsIDB4MDApLCBSR0IoMHg4MCwgMHgwMCwgMHg4MCksIFJHQigweDgwLCAweDgwLCAweDAwKSwgUkdCKDB4ODAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4QzAsIDB4QzAsIDB4QzApLCBSR0IoMHgwMCwgMHgwMCwgMHhGRiksIFJHQigweDAwLCAweEZGLCAweDAwKSwgUkdCKDB4MDAsIDB4RkYsIDB4RkYpLAogICAgUkdCKDB4RkYsIDB4MDAsIDB4MDApLCBSR0IoMHhGRiwgMHgwMCwgMHhGRiksIFJHQigweEZGLCAweEZGLCAweDAwKSwgUkdCKDB4RkYsIDB4RkYsIDB4RkYpLAp9OwoKc3RhdGljIEJPT0wgV0NVU0VSX1NldEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGZvbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW1EQwogKgogKiBGaWxscyB0aGUgTWVtIERDIHdpdGggY3VycmVudCBjZWxscyB2YWx1ZXMKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9GaWxsTWVtREMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB1cGRfdHAsIGludCB1cGRfYm0pCnsKICAgIHVuc2lnbmVkCQlpLCBqLCBrOwogICAgQ0hBUl9JTkZPKgkJY2VsbDsKICAgIEhGT05UCQloT2xkRm9udDsKICAgIFdPUkQJCWF0dHI7CiAgICBXQ0hBUioJCWxpbmU7CiAgICBSRUNUICAgICAgICAgICAgICAgIHI7CiAgICBIQlJVU0ggICAgICAgICAgICAgIGhicjsKCiAgICAvKiBubyBmb250IGhhcyBiZWVuIHNldCB1cCB5ZXQsIGRvbid0IHdvcnJ5IGFib3V0IGZpbGxpbmcgdGhlIGJpdG1hcCwKICAgICAqIHdlJ2xsIGRvIGl0IG9uY2UgYSBmb250IGlzIGNob3NlbgogICAgICovCiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhGb250KSByZXR1cm47CgogICAgLyogRklYTUU6IGNvdWxkIHNldCB1cCBhIG1lY2hhbmlzbSB0byByZXVzZSB0aGUgbGluZSBiZXR3ZWVuIGRpZmZlcmVudAogICAgICogY2FsbHMgdG8gdGhpcyBmdW5jdGlvbgogICAgICovCiAgICBpZiAoIShsaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAqIHNpemVvZihXQ0hBUikpKSkKICAgICAgICBXSU5FQ09OX0ZhdGFsKCJPT01cbiIpOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgZm9yIChqID0gdXBkX3RwOyBqIDw9IHVwZF9ibTsgaisrKQogICAgewoJY2VsbCA9ICZkYXRhLT5jZWxsc1tqICogZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoXTsKCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGg7IGkrKykKCXsKCSAgICBhdHRyID0gY2VsbFtpXS5BdHRyaWJ1dGVzOwoJICAgIFNldEJrQ29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbKGF0dHI+PjQpJjB4MEZdKTsKCSAgICBTZXRUZXh0Q29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbYXR0ciYweDBGXSk7CgkgICAgZm9yIChrID0gaTsgayA8IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAmJiBjZWxsW2tdLkF0dHJpYnV0ZXMgPT0gYXR0cjsgaysrKQoJICAgIHsKCQlsaW5lW2sgLSBpXSA9IGNlbGxba10uQ2hhci5Vbmljb2RlQ2hhcjsKCSAgICB9CgkgICAgVGV4dE91dChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgaiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCQkgICAgbGluZSwgayAtIGkpOwogICAgICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmcgJiYgCiAgICAgICAgICAgICAgICAoaGJyID0gQ3JlYXRlU29saWRCcnVzaChXQ1VTRVJfQ29sb3JNYXBbKGF0dHI+PjQpJjB4MEZdKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHIubGVmdCAgID0gaSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgICAgICAgICAgci50b3AgICAgPSAoaiArIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0IC0gUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmc7CiAgICAgICAgICAgICAgICByLnJpZ2h0ICA9IGsgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgICAgIHIuYm90dG9tID0gKGogKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgICAgIEZpbGxSZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgJnIsIGhicik7CiAgICAgICAgICAgICAgICBEZWxldGVPYmplY3QoaGJyKTsKICAgICAgICAgICAgfQoJICAgIGkgPSBrIC0gMTsKCX0KICAgIH0KICAgIFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGhPbGRGb250KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxpbmUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfTmV3Qml0bWFwCiAqCiAqIEVpdGhlciB0aGUgZm9udCBnZW9tZXRyeSBvciB0aGUgc2IgZ2VvbWV0cnkgaGFzIGNoYW5nZWQuIHdlIG5lZWQKICogdG8gcmVjcmVhdGUgdGhlIGJpdG1hcCBnZW9tZXRyeS4KICovCnN0YXRpYyB2b2lkIFdDVVNFUl9OZXdCaXRtYXAoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhEQyAgICAgICAgIGhEQzsKICAgIEhCSVRNQVAJaG5ldywgaG9sZDsKCiAgICBpZiAoIWRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fCAhZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCB8fAogICAgICAgICFQUklWQVRFKGRhdGEpLT5oRm9udCB8fCAhKGhEQyA9IEdldERDKFBSSVZBVEUoZGF0YSktPmhXbmQpKSkKICAgICAgICByZXR1cm47CiAgICBobmV3ID0gQ3JlYXRlQ29tcGF0aWJsZUJpdG1hcChoREMsCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKCQkJCSAgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CiAgICBSZWxlYXNlREMoUFJJVkFURShkYXRhKS0+aFduZCwgaERDKTsKICAgIGhvbGQgPSBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBobmV3KTsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEJpdG1hcCkKICAgIHsKCWlmIChob2xkID09IFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCgkgICAgRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhCaXRtYXApOwoJZWxzZQoJICAgIFdJTkVfRklYTUUoImxlYWtcbiIpOwogICAgfQogICAgUFJJVkFURShkYXRhKS0+aEJpdG1hcCA9IGhuZXc7CiAgICBXQ1VTRVJfRmlsbE1lbURDKGRhdGEsIDAsIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcgogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NVU0VSX05ld0JpdG1hcChkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Bvc0N1cnNvcgogKgogKiBTZXQgYSBuZXcgcG9zaXRpb24gZm9yIHRoZSBjdXJzb3IKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Qb3NDdXJzb3IoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kICE9IEdldEZvY3VzKCkgfHwgIWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkgcmV0dXJuOwoKICAgIFNldENhcmV0UG9zKChkYXRhLT5jdXJzb3IuWCAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCgkJKGRhdGEtPmN1cnNvci5ZIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgU2hvd0NhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2hhcGVDdXJzb3IKICoKICogU2V0cyBhIG5ldyBzaGFwZSBmb3IgdGhlIGN1cnNvcgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NoYXBlQ3Vyc29yKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgc2l6ZSwgaW50IHZpcywgQk9PTCBmb3JjZSkKewogICAgaWYgKGZvcmNlIHx8IHNpemUgIT0gZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplKQogICAgewoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSAmJiBQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkpIERlc3Ryb3lDYXJldCgpOwoJaWYgKFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKTsKCVBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAgPSBOVUxMOwoJaWYgKHNpemUgIT0gMTAwKQoJewoJICAgIGludAkJdzE2YjsgLyogbnVtYmVyIG9mIGJ5dGVzIHBlciByb3csIGFsaWduZWQgb24gd29yZCBzaXplICovCgkgICAgQllURSoJcHRyOwoJICAgIGludAkJaSwgaiwgbmJsOwoKCSAgICB3MTZiID0gKChkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCArIDE1KSAmIH4xNSkgLyA4OwoJICAgIHB0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCB3MTZiICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBpZiAoIXB0cikgV0lORUNPTl9GYXRhbCgiT09NIik7CgkgICAgbmJsID0gbWF4KChkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQgKiBzaXplKSAvIDEwMCwgMSk7CgkgICAgZm9yIChqID0gZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0IC0gbmJsOyBqIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OyBqKyspCgkgICAgewoJCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsgaSsrKQoJCXsKCQkgICAgcHRyW3cxNmIgKiBqICsgKGkgLyA4KV0gfD0gMHg4MCA+PiAoaSAmIDcpOwoJCX0KCSAgICB9CgkgICAgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCA9IENyZWF0ZUJpdG1hcChkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsIDEsIDEsIHB0cik7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHRyKTsKCX0KCWRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSA9IHNpemU7CglkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgPSAtMTsKICAgIH0KCiAgICB2aXMgPSAodmlzKSA/IFRSVUUgOiBGQUxTRTsKICAgIGlmIChmb3JjZSB8fCB2aXMgIT0gZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQogICAgewoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gdmlzOwoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSkKCXsKCSAgICBpZiAodmlzKQoJICAgIHsKCQlDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlEZXN0cm95Q2FyZXQoKTsKCSAgICB9Cgl9CiAgICB9CiAgICBXSU5FQ09OX0R1bXBDb25maWcoImNyc3IiLCAmZGF0YS0+Y3VyY2ZnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMKICoKICogUmVjb21wdXRlcyBhbGwgdGhlIGNvbXBvbmVudHMgKG1haW5seSBzY3JvbGwgYmFycykgcG9zaXRpb25zCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgUkVDVAkJcjsKICAgIGludAkJCWR4LCBkeTsKCiAgICAvKiBjb21wdXRlIHdpbmRvdyBzaXplIGZyb20gZGVzaXJlZCBjbGllbnQgc2l6ZSAqLwogICAgci5sZWZ0ID0gci50b3AgPSAwOwogICAgci5yaWdodCA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHIuYm90dG9tID0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgaWYgKElzUmVjdEVtcHR5KCZyKSkgcmV0dXJuOwoKICAgIEFkanVzdFdpbmRvd1JlY3QoJnIsIEdldFdpbmRvd0xvbmcoUFJJVkFURShkYXRhKS0+aFduZCwgR1dMX1NUWUxFKSwgRkFMU0UpOwoKICAgIGR4ID0gZHkgPSAwOwogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl93aWR0aCA+IGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICB7CglkeSA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCVNldFNjcm9sbFJhbmdlKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIEZBTFNFKTsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCA+IGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0KQogICAgewoJZHggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgVFJVRSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIEZBTFNFKTsKICAgIH0KCiAgICBTZXRXaW5kb3dQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgMCwgMCwgMCwgci5yaWdodCAtIHIubGVmdCArIGR4LCByLmJvdHRvbSAtIHIudG9wICsgZHksCgkJIFNXUF9OT01PVkV8U1dQX05PWk9SREVSKTsKICAgIFdDVVNFUl9TaGFwZUN1cnNvcihkYXRhLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUsIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSwgVFJVRSk7CiAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0VGl0bGUKICoKICogU2V0cyB0aGUgdGl0bGUgdG8gdGhlIHdpbmUgY29uc29sZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldFRpdGxlKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBXQ0hBUglidWZmZXJbMjU2XTsKCiAgICBpZiAoV0lORUNPTl9HZXRDb25zb2xlVGl0bGUoZGF0YS0+aENvbkluLCBidWZmZXIsIHNpemVvZihidWZmZXIpKSkKCVNldFdpbmRvd1RleHQoUFJJVkFURShkYXRhKS0+aFduZCwgYnVmZmVyKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcExvZ0ZvbnQoY29uc3QgY2hhciogcGZ4LCBjb25zdCBMT0dGT05UKiBsZiwgRFdPUkQgZnQpCnsKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCIlcyAlcyVzJXMlc1xuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZIZWlnaHQ9JWxkIGxmLmxmV2lkdGg9JWxkIGxmLmxmRXNjYXBlbWVudD0lbGQgbGYubGZPcmllbnRhdGlvbj0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmV2VpZ2h0PSVsZCBsZi5sZkl0YWxpYz0ldSBsZi5sZlVuZGVybGluZT0ldSBsZi5sZlN0cmlrZU91dD0ldVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZDaGFyU2V0PSV1IGxmLmxmT3V0UHJlY2lzaW9uPSV1IGxmLmxmQ2xpcFByZWNpc2lvbj0ldSBsZi5sZlF1YWxpdHk9JXVcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLT5sZlBpdGNoQW5kRmFtaWx5PSV1IGxmLmxmRmFjZU5hbWU9JXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwZngsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBSQVNURVJfRk9OVFRZUEUpID8gInJhc3RlciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFRSVUVUWVBFX0ZPTlRUWVBFKSA/ICJ0cnVldHlwZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICgoZnQgJiAoUkFTVEVSX0ZPTlRUWVBFfFRSVUVUWVBFX0ZPTlRUWVBFKSkgPT0gMCkgPyAidmVjdG9yIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgREVWSUNFX0ZPTlRUWVBFKSA/ICJ8ZGV2aWNlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmSGVpZ2h0LCBsZi0+bGZXaWR0aCwgbGYtPmxmRXNjYXBlbWVudCwgbGYtPmxmT3JpZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBsZi0+bGZXZWlnaHQsIGxmLT5sZkl0YWxpYywgbGYtPmxmVW5kZXJsaW5lLCBsZi0+bGZTdHJpa2VPdXQsIGxmLT5sZkNoYXJTZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZi0+bGZPdXRQcmVjaXNpb24sIGxmLT5sZkNsaXBQcmVjaXNpb24sIGxmLT5sZlF1YWxpdHksIGxmLT5sZlBpdGNoQW5kRmFtaWx5LAogICAgICAgICAgICAgICAgICAgICAgICAgd2luZV9kYmdzdHJfdyhsZi0+bGZGYWNlTmFtZSkpOwp9Cgp2b2lkIFdDVVNFUl9EdW1wVGV4dE1ldHJpYyhjb25zdCBURVhUTUVUUklDKiB0bSwgRFdPUkQgZnQpCnsKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCIlcyVzJXMlc1xuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1IZWlnaHQ9JWxkIHRtQXNjZW50PSVsZCB0bURlc2NlbnQ9JWxkIHRtSW50ZXJuYWxMZWFkaW5nPSVsZCB0bUV4dGVybmFsTGVhZGluZz0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtQXZlQ2hhcldpZHRoPSVsZCB0bU1heENoYXJXaWR0aD0lbGQgdG1XZWlnaHQ9JWxkIHRtT3Zlcmhhbmc9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bURpZ2l0aXplZEFzcGVjdFg9JWxkIHRtRGlnaXRpemVkQXNwZWN0WT0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtRmlyc3RDaGFyPSVkIHRtTGFzdENoYXI9JWQgdG1EZWZhdWx0Q2hhcj0lZCB0bUJyZWFrQ2hhcj0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1JdGFsaWM9JXUgdG1VbmRlcmxpbmVkPSV1IHRtU3RydWNrT3V0PSV1IHRtUGl0Y2hBbmRGYW1pbHk9JXUgdG1DaGFyU2V0PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCwgdG0tPnRtQXNjZW50LCB0bS0+dG1EZXNjZW50LCB0bS0+dG1JbnRlcm5hbExlYWRpbmcsIHRtLT50bUV4dGVybmFsTGVhZGluZywgdG0tPnRtQXZlQ2hhcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtTWF4Q2hhcldpZHRoLCB0bS0+dG1XZWlnaHQsIHRtLT50bU92ZXJoYW5nLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RYLCB0bS0+dG1EaWdpdGl6ZWRBc3BlY3RZLAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtRmlyc3RDaGFyLCB0bS0+dG1MYXN0Q2hhciwgdG0tPnRtRGVmYXVsdENoYXIsIHRtLT50bUJyZWFrQ2hhciwgdG0tPnRtSXRhbGljLCB0bS0+dG1VbmRlcmxpbmVkLCB0bS0+dG1TdHJ1Y2tPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1QaXRjaEFuZEZhbWlseSwgdG0tPnRtQ2hhclNldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9BcmVGb250c0VxdWFsCiAqCiAqCiAqLwpCT09MIFdDVVNFUl9BcmVGb250c0VxdWFsKGNvbnN0IHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgcmV0dXJuIGxmLT5sZkhlaWdodCA9PSBjb25maWctPmNlbGxfaGVpZ2h0ICYmCiAgICAgICAgbGYtPmxmV2VpZ2h0ID09IGNvbmZpZy0+Zm9udF93ZWlnaHQgJiYKICAgICAgICAhbGYtPmxmSXRhbGljICYmICFsZi0+bGZVbmRlcmxpbmUgJiYgIWxmLT5sZlN0cmlrZU91dCAmJgogICAgICAgICFsc3RyY21wKGxmLT5sZkZhY2VOYW1lLCBjb25maWctPmZhY2VfbmFtZSk7Cn0KCnN0cnVjdCBmb250X2Nob29zZXIKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBpbnQJCQlkb25lOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYwogKgogKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvbnQgZGVzY3JpYmVkIGluIHRtIGlzIHVzYWJsZSBhcyBhIGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8KQk9PTAlXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBURVhUTUVUUklDKiB0bSwgRFdPUkQgZm9udFR5cGUpCnsKICAgIEJPT0wgICAgICAgIHJldCA9IFRSVUU7CgogICAgaWYgKGZvbnRUeXBlICYgUkFTVEVSX0ZPTlRUWVBFKQogICAgICAgIHJldCA9ICh0bS0+dG1NYXhDaGFyV2lkdGggKiBkYXRhLT5jdXJjZmcud2luX3dpZHRoIDwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTikgJiYKICAgICAgICAgICAgICAgdG0tPnRtSGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgPCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSk7CiAgICByZXR1cm4gcmV0ICYmICF0bS0+dG1JdGFsaWMgJiYgIXRtLT50bVVuZGVybGluZWQgJiYgIXRtLT50bVN0cnVja091dCAmJgogICAgICAgICh0bS0+dG1DaGFyU2V0ID09IERFRkFVTFRfQ0hBUlNFVCB8fCB0bS0+dG1DaGFyU2V0ID09IEFOU0lfQ0hBUlNFVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9WYWxpZGF0ZUZvbnQKICoKICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb250IGZhbWlseSBkZXNjcmliZWQgaW4gbGYgaXMgdXNhYmxlIGFzIGEgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpCT09MCVdDVVNFUl9WYWxpZGF0ZUZvbnQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICByZXR1cm4gKGxmLT5sZlBpdGNoQW5kRmFtaWx5ICYgMykgPT0gRklYRURfUElUQ0ggJiYKICAgICAgICAvKiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAweEYwKSA9PSBGRl9NT0RFUk4gJiYgKi8KICAgICAgICAobGYtPmxmQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgbGYtPmxmQ2hhclNldCA9PSBBTlNJX0NIQVJTRVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtXzIKICoJCWdldF9maXJzdF9mb250X2VudW0KICoKICogSGVscGVyIGZ1bmN0aW9ucyB0byBnZXQgYSBkZWNlbnQgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW1fMihjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sCgkJCQkJICBEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wVGV4dE1ldHJpYyh0bSwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMoZmMtPmRhdGEsIHRtLCBGb250VHlwZSkpCiAgICB7CiAgICAgICAgTE9HRk9OVCBtbGYgPSAqbGY7CgogICAgICAgIC8qIFVzZSB0aGUgZGVmYXVsdCBzaXplcyBmb3IgdGhlIGZvbnQgKHRoaXMgaXMgbmVlZGVkLCBlc3BlY2lhbGx5IGZvcgogICAgICAgICAqIFRydWVUeXBlIGZvbnRzLCBzbyB0aGF0IHdlIGdldCBhIGRlY2VudCBzaXplLCBub3QgdGhlIG1heCBzaXplKQogICAgICAgICAqLwogICAgICAgIG1sZi5sZldpZHRoICA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICBtbGYubGZIZWlnaHQgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgIGlmIChXQ1VTRVJfU2V0Rm9udChmYy0+ZGF0YSwgJm1sZikpCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgICAgICBjb25maWdfZGF0YSAgICAgZGVmY2ZnOwoKICAgICAgICAgICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0Q2hvb3Npbmc6ICIsICZtbGYsIEZvbnRUeXBlKTsKICAgICAgICAgICAgZmMtPmRvbmUgPSAxOwogICAgICAgICAgICAvKiBzaW5jZSB3ZSd2ZSBtb2RpZmllZCB0aGUgY3VycmVudCBjb25maWcgd2l0aCBuZXcgZm9udCBpbmZvcm1hdGlvbiwKICAgICAgICAgICAgICogc2V0IHRoaXMgaW5mb3JtYXRpb24gYXMgdGhlIG5ldyBkZWZhdWx0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdMb2FkKE5VTEwsICZkZWZjZmcpOwogICAgICAgICAgICBkZWZjZmcuY2VsbF93aWR0aCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgICAgICAgICAgZGVmY2ZnLmNlbGxfaGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgbHN0cmNweVcoZGVmY2ZnLmZhY2VfbmFtZSwgZmMtPmRhdGEtPmN1cmNmZy5mYWNlX25hbWUpOwogICAgICAgICAgICAvKiBGb3JjZSBhbHNvIGl0cyB3cml0aW5nIGJhY2sgdG8gdGhlIHJlZ2lzdHJ5IHNvIHRoYXQgd2UgY2FuIGdldCBpdAogICAgICAgICAgICAgKiB0aGUgbmV4dCB0aW1lLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdTYXZlKCZkZWZjZmcpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIGludCBDQUxMQkFDSyBnZXRfZmlyc3RfZm9udF9lbnVtKGNvbnN0IExPR0ZPTlQqIGxmLCBjb25zdCBURVhUTUVUUklDKiB0bSwKCQkJCQlEV09SRCBGb250VHlwZSwgTFBBUkFNIGxQYXJhbSkKewogICAgc3RydWN0IGZvbnRfY2hvb3NlcioJZmMgPSAoc3RydWN0IGZvbnRfY2hvb3NlciopbFBhcmFtOwoKICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdEZhbWlseTogIiwgbGYsIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250KGZjLT5kYXRhLCBsZikpCiAgICB7CglFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZmMtPmRhdGEpLT5oTWVtREMsIGxmLT5sZkZhY2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yLCBsUGFyYW0pOwoJcmV0dXJuICFmYy0+ZG9uZTsgLyogd2UganVzdCBuZWVkIHRoZSBmaXJzdCBtYXRjaGluZyBvbmUuLi4gKi8KICAgIH0KICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weUZvbnQKICoKICogZ2V0IHRoZSByZWxldmFudCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBmb250IGRlc2NyaWJlZCBpbiBsZiBhbmQgc3RvcmUgdGhlbQogKiBpbiBjb25maWcKICovCkhGT05UIFdDVVNFUl9Db3B5Rm9udChzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgSFdORCBoV25kLCBjb25zdCBMT0dGT05UKiBsZiwgTE9ORyogZWwpCnsKICAgIFRFWFRNRVRSSUMgIHRtOwogICAgSERDICAgICAgICAgaERDOwogICAgSEZPTlQgICAgICAgaEZvbnQsIGhPbGRGb250OwogICAgaW50ICAgICAgICAgdywgaSwgYnVmWzI1Nl07CgogICAgaWYgKCEoaERDID0gR2V0REMoaFduZCkpKSByZXR1cm4gTlVMTDsKICAgIGlmICghKGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KGxmKSkpIGdvdG8gZXJyMTsKCiAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdChoREMsIGhGb250KTsKICAgIEdldFRleHRNZXRyaWNzKGhEQywgJnRtKTsKCiAgICAvKiBGSVhNRToKICAgICAqIHRoZSBjdXJyZW50IGZyZWV0eXBlIGVuZ2luZSAoYXQgbGVhc3QgMi4wLnggd2l0aCB4IDw9IDgpIGFuZCBpdHMgaW1wbGVtZW50YXRpb24KICAgICAqIGluIFdpbmUgZG9uJ3QgcmV0dXJuIGFkZXF1YXRlIHZhbHVlcyBmb3IgZml4ZWQgZm9udHMKICAgICAqIEluIFdpbmRvd3MsIHRob3NlIGZvbnRzIGFyZSBleHBlY3RlZCB0byByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yCiAgICAgKiAgLSB0aGUgYXZlcmFnZSB3aWR0aAogICAgICogIC0gdGhlIGxhcmdlc3Qgd2lkdGgKICAgICAqICAtIHRoZSB3aWR0aCBvZiBhbGwgY2hhcmFjdGVycyBpbiB0aGUgZm9udAogICAgICogVGhpcyBpc24ndCB0cnVlIGluIFdpbmUuIEFzIGEgdGVtcG9yYXJ5IHdvcmthcm91bmQsIHdlIGdldCBhcyB0aGUgd2lkdGggb2YgdGhlCiAgICAgKiBjZWxsLCB0aGUgd2lkdGggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgZm9udCwgYWZ0ZXIgY2hlY2tpbmcgdGhhdCBhbGwKICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGZvbnQgaGF2ZSB0aGUgc2FtZSB3aWR0aCAoSSBoZWFyIHBhcmFub+9hIGNvbWluZykKICAgICAqIHdoZW4gdGhpcyBnZXRzIGZpeGVkLCB0aGUgY29kZSBzaG91bGQgYmUgdXNpbmcgdG0udG1BdmVDaGFyV2lkdGgKICAgICAqIG9yIHRtLnRtTWF4Q2hhcldpZHRoIGFzIHRoZSBjZWxsIHdpZHRoLgogICAgICovCiAgICBHZXRDaGFyV2lkdGgzMihoREMsIHRtLnRtRmlyc3RDaGFyLCB0bS50bUZpcnN0Q2hhciwgJncpOwogICAgZm9yIChpID0gdG0udG1GaXJzdENoYXIgKyAxOyBpIDw9IHRtLnRtTGFzdENoYXI7IGkgKz0gc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSkKICAgIHsKICAgICAgICBpbnQgaiwgazsKCiAgICAgICAgayA9IG1pbih0bS50bUxhc3RDaGFyIC0gaSwgc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSAtIDEpOwogICAgICAgIEdldENoYXJXaWR0aDMyKGhEQywgaSwgaSArIGssIGJ1Zik7CiAgICAgICAgZm9yIChqID0gMDsgaiA8PSBrOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoYnVmW2pdICE9IHcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfV0FSTigiTm9uIHVuaWZvcm0gY2VsbCB3aWR0aDogWyVkXT0lZCBbJWRdPSVkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoaXMgbWF5IGJlIGNhdXNlZCBieSBvbGQgZnJlZXR5cGUgbGlicmFyaWVzLCA+PSAyLjAuOCBpcyByZWNvbW1lbmRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgaiwgYnVmW2pdLCB0bS50bUZpcnN0Q2hhciwgdyk7CiAgICAgICAgICAgICAgICBnb3RvIGVycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIGNvbmZpZy0+Y2VsbF93aWR0aCAgPSB3OwogICAgY29uZmlnLT5jZWxsX2hlaWdodCA9IHRtLnRtSGVpZ2h0ICsgdG0udG1FeHRlcm5hbExlYWRpbmc7CiAgICBjb25maWctPmZvbnRfd2VpZ2h0ID0gdG0udG1XZWlnaHQ7CiAgICBsc3RyY3B5KGNvbmZpZy0+ZmFjZV9uYW1lLCBsZi0+bGZGYWNlTmFtZSk7CiAgICBpZiAoZWwpICplbCA9IHRtLnRtRXh0ZXJuYWxMZWFkaW5nOwoKICAgIHJldHVybiBoRm9udDsKIGVycjoKICAgIGlmIChoREMgJiYgaE9sZEZvbnQpIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIGlmIChoRm9udCkgRGVsZXRlT2JqZWN0KGhGb250KTsKIGVycjE6CiAgICBpZiAoaERDKSBSZWxlYXNlREMoaFduZCwgaERDKTsKCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxMb2dGb250CiAqCiAqCiAqLwp2b2lkICAgIFdDVVNFUl9GaWxsTG9nRm9udChMT0dGT05UKiBsZiwgY29uc3QgV0NIQVIqIG5hbWUsIFVJTlQgaGVpZ2h0LCBVSU5UIHdlaWdodCkKewogICAgbGYtPmxmSGVpZ2h0ICAgICAgICA9IGhlaWdodDsKICAgIGxmLT5sZldpZHRoICAgICAgICAgPSAwOwogICAgbGYtPmxmRXNjYXBlbWVudCAgICA9IDA7CiAgICBsZi0+bGZPcmllbnRhdGlvbiAgID0gMDsKICAgIGxmLT5sZldlaWdodCAgICAgICAgPSB3ZWlnaHQ7CiAgICBsZi0+bGZJdGFsaWMgICAgICAgID0gRkFMU0U7CiAgICBsZi0+bGZVbmRlcmxpbmUgICAgID0gRkFMU0U7CiAgICBsZi0+bGZTdHJpa2VPdXQgICAgID0gRkFMU0U7CiAgICBsZi0+bGZDaGFyU2V0ICAgICAgID0gREVGQVVMVF9DSEFSU0VUOwogICAgbGYtPmxmT3V0UHJlY2lzaW9uICA9IE9VVF9ERUZBVUxUX1BSRUNJUzsKICAgIGxmLT5sZkNsaXBQcmVjaXNpb24gPSBDTElQX0RFRkFVTFRfUFJFQ0lTOwogICAgbGYtPmxmUXVhbGl0eSAgICAgICA9IERFRkFVTFRfUVVBTElUWTsKICAgIGxmLT5sZlBpdGNoQW5kRmFtaWx5ID0gRklYRURfUElUQ0ggfCBGRl9ET05UQ0FSRTsKICAgIGxzdHJjcHkobGYtPmxmRmFjZU5hbWUsIG5hbWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0Rm9udAogKgogKiBzZXRzIGxvZ2ZvbnQgYXMgdGhlIG5ldyBmb250IGZvciB0aGUgY29uc29sZQogKi8KQk9PTAlXQ1VTRVJfU2V0Rm9udChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgTE9HRk9OVCogbG9nZm9udCkKewogICAgSEZPTlQgICAgICAgaEZvbnQ7CiAgICBMT05HICAgICAgICBlbDsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQgIT0gMCAmJiBXQ1VTRVJfQXJlRm9udHNFcXVhbCgmZGF0YS0+Y3VyY2ZnLCBsb2dmb250KSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBoRm9udCA9IFdDVVNFUl9Db3B5Rm9udCgmZGF0YS0+Y3VyY2ZnLCBQUklWQVRFKGRhdGEpLT5oV25kLCBsb2dmb250LCAmZWwpOwogICAgaWYgKCFoRm9udCkge1dJTkVfRVJSKCJ3cm9uZyBmb250XG4iKTsgcmV0dXJuIEZBTFNFO30KCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQpIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBQUklWQVRFKGRhdGEpLT5oRm9udCA9IGhGb250OwogICAgUFJJVkFURShkYXRhKS0+ZXh0X2xlYWRpbmcgPSBlbDsKCiAgICBXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhkYXRhKTsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSk7CiAgICBJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCBOVUxMLCBGQUxTRSk7CiAgICBVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250UG10CiAqCiAqIFNldHMgYSBuZXcgZm9udCBmb3IgdGhlIGNvbnNvbGUuCiAqIEluIGZhY3QgYSB3cmFwcGVyIGZvciBXQ1VTRVJfU2V0Rm9udAogKi8Kc3RhdGljIHZvaWQgICAgIFdDVVNFUl9TZXRGb250UG10KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBXQ0hBUiogZm9udCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGhlaWdodCwgdW5zaWduZWQgd2VpZ2h0KQp7CiAgICBMT0dGT05UICAgICAgICAgICAgIGxmOwogICAgc3RydWN0IGZvbnRfY2hvb3NlciBmYzsKCiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiPT4gJXMgaD0ldSB3PSV1XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgd2luZV9kYmdzdHJfd24oZm9udCwgLTEpLCBoZWlnaHQsIHdlaWdodCk7CgogICAgaWYgKGZvbnRbMF0gIT0gJ1wwJyAmJiBoZWlnaHQgIT0gMCAmJiB3ZWlnaHQgIT0gMCkKICAgIHsKICAgICAgICBXQ1VTRVJfRmlsbExvZ0ZvbnQoJmxmLCBmb250LCBoZWlnaHQsIHdlaWdodCk7CiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGRhdGEsICZsZikpCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRSZXVzZXM6ICIsICZsZiwgMCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgLyogdHJ5IHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBmb250ICovCiAgICBXSU5FX1dBUk4oIkNvdWxkbid0IG1hdGNoIHRoZSBmb250IGZyb20gcmVnaXN0cnkuLi4gdHJ5aW5nIHRvIGZpbmQgb25lXG4iKTsKICAgIGZjLmRhdGEgPSBkYXRhOwogICAgZmMuZG9uZSA9IDA7CiAgICBFbnVtRm9udEZhbWlsaWVzKFBSSVZBVEUoZGF0YSktPmhNZW1EQywgTlVMTCwgZ2V0X2ZpcnN0X2ZvbnRfZW51bSwgKExQQVJBTSkmZmMpOwogICAgaWYgKCFmYy5kb25lKSBXSU5FQ09OX0ZhdGFsKCJDb3VsZG4ndCBmaW5kIGEgZGVjZW50IGZvbnQsIGFib3J0aW5nXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldENlbGwKICoKICogR2V0IGEgY2VsbCBmcm9tIGEgcmVsYXRpdmUgY29vcmRpbmF0ZSBpbiB3aW5kb3cgKHRha2VzIGludG8KICogYWNjb3VudCB0aGUgc2Nyb2xsaW5nKQogKi8Kc3RhdGljIENPT1JECVdDVVNFUl9HZXRDZWxsKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBDT09SRAljOwoKICAgIGMuWCA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlggKyAoc2hvcnQpTE9XT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIGMuWSA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAoc2hvcnQpSElXT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgcmV0dXJuIGM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0CiAqCiAqIEdldCB0aGUgc2VsZWN0aW9uIHJlY3RhbmdsZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIExQUkVDVCByKQp7CiAgICByLT5sZWZ0ICAgPSAobWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgICAgIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPnRvcCAgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSAgICAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgIHItPnJpZ2h0ICA9IChtYXgoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSArIDEgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci0+Ym90dG9tID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICsgMSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0U2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0U2VsZWN0aW9uKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBIREMgaFJlZkRDKQp7CiAgICBIREMJCWhEQzsKICAgIFJFQ1QJcjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBoUmVmREMgPyBoUmVmREMgOiBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJaWYgKGhEQyAhPSBoUmVmREMpCgkgICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfTW92ZVNlbGVjdGlvbihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYzEsIENPT1JEIGMyKQp7CiAgICBSRUNUCXI7CiAgICBIREMJCWhEQzsKCiAgICBpZiAoYzEuWCA8IDAgfHwgYzEuWCA+PSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwKICAgICAgICBjMi5YIDwgMCB8fCBjMi5YID49IGRhdGEtPmN1cmNmZy5zYl93aWR0aCB8fAogICAgICAgIGMxLlkgPCAwIHx8IGMxLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCB8fAogICAgICAgIGMyLlkgPCAwIHx8IGMyLlkgPj0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCkKICAgICAgICByZXR1cm47CgogICAgV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwogICAgaERDID0gR2V0REMoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICBpZiAoaERDKQogICAgewoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgSGlkZUNhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSA9IGMxOwogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyID0gYzI7CiAgICBpZiAoaERDKQogICAgewoJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoZGF0YSwgJnIpOwoJSW52ZXJ0UmVjdChoREMsICZyKTsKCVJlbGVhc2VEQyhQUklWQVRFKGRhdGEpLT5oV25kLCBoREMpOwoJaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSAmJiBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgU2hvd0NhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkCiAqCiAqIENvcGllcyB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW50byB0aGUgY2xpcGJvYXJkCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaE1lbTsKICAgIExQV1NUUglwOwogICAgdW5zaWduZWQJdywgaDsKCiAgICB3ID0gYWJzKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YIC0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICsgMjsKICAgIGggPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlkgLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSkgKyAxOwoKICAgIGlmICghT3BlbkNsaXBib2FyZChQUklWQVRFKGRhdGEpLT5oV25kKSkgcmV0dXJuOwogICAgRW1wdHlDbGlwYm9hcmQoKTsKCiAgICBoTWVtID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRSwgKHcgKiBoKSAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKGhNZW0gJiYgKHAgPSBHbG9iYWxMb2NrKGhNZW0pKSkKICAgIHsKCUNPT1JECWM7CglpbnQJeTsKCgljLlggPSBtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKTsKCWMuWSA9IG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpOwoKCWZvciAoeSA9IDA7IHkgPCBoOyB5KyssIGMuWSsrKQoJewoJICAgIFJlYWRDb25zb2xlT3V0cHV0Q2hhcmFjdGVyKGRhdGEtPmhDb25PdXQsICZwW3kgKiB3XSwgdyAtIDEsIGMsIE5VTEwpOwoJICAgIHBbeSAqIHcgKyB3IC0gMV0gPSAoeSA8IGggLSAxKSA/ICdcbicgOiAnXDAnOwoJfQoJR2xvYmFsVW5sb2NrKGhNZW0pOwoJU2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCwgaE1lbSk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaDsKICAgIFdDSEFSKglwdHI7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBoID0gR2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCk7CiAgICBpZiAoaCAmJiAocHRyID0gR2xvYmFsTG9jayhoKSkpCiAgICB7CglpbnQJCWksIGxlbiA9IEdsb2JhbFNpemUoaCkgLyBzaXplb2YoV0NIQVIpOwoJSU5QVVRfUkVDT1JECWlyWzJdOwoJRFdPUkQJCW47CglTSE9SVAkJc2g7CgoJaXJbMF0uRXZlbnRUeXBlID0gS0VZX0VWRU5UOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQud1JlcGVhdENvdW50ID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gVFJVRTsKCgkvKiBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBpbnB1dCByZWNvcmRzICovCglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCgl7CgkgICAgLyogRklYTUU6IHRoZSBtb2RpZnlpbmcga2V5cyBhcmUgbm90IGdlbmVyYXRlZCAoc2hpZnQsIGN0cmwuLi4pICovCgkgICAgc2ggPSBWa0tleVNjYW4ocHRyW2ldKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC53VmlydHVhbEtleUNvZGUgPSBMT0JZVEUoc2gpOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBNYXBWaXJ0dWFsS2V5KExPQllURShzaCksIDApOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gcHRyW2ldOwoKCSAgICBpclsxXSA9IGlyWzBdOwoJICAgIGlyWzFdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gRkFMU0U7CgoJICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgaXIsIDIsICZuKTsKCX0KCUdsb2JhbFVubG9jayhoKTsKICAgIH0KICAgIENsb3NlQ2xpcGJvYXJkKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZWZyZXNoCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfUmVmcmVzaChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHRwLCBpbnQgYm0pCnsKICAgIFdDVVNFUl9GaWxsTWVtREMoZGF0YSwgdHAsIGJtKTsKICAgIGlmIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIDw9IGJtICYmIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA+PSB0cCkKICAgIHsKCVJFQ1QJcjsKCglyLmxlZnQgICA9IDA7CglyLnJpZ2h0ICA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKCXIudG9wICAgID0gKHRwIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CglyLmJvdHRvbSA9IChibSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCUludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsICZyLCBGQUxTRSk7CglVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYWludAogKgogKgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1BhaW50KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBQQUlOVFNUUlVDVAkJcHM7CgogICAgQmVnaW5QYWludChQUklWQVRFKGRhdGEpLT5oV25kLCAmcHMpOwogICAgQml0Qmx0KHBzLmhkYywgMCwgMCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3dpZHRoICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBQUklWQVRFKGRhdGEpLT5oTWVtREMsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCgkgICBTUkNDT1BZKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQoJV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCBwcy5oZGMpOwogICAgRW5kUGFpbnQoUFJJVkFURShkYXRhKS0+aFduZCwgJnBzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Njcm9sbAogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Njcm9sbChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHBvcywgQk9PTCBob3J6KQp7CiAgICBpZiAoaG9yeikKICAgIHsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgIH0KICAgIGVsc2UKICAgIHsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCBwb3MsIFRSVUUpOwoJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKICAgIH0KICAgIEludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsIE5VTEwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW51CiAqCiAqCiAqLwpzdGF0aWMgQk9PTCBXQ1VTRVJfRmlsbE1lbnUoSE1FTlUgaE1lbnUsIEJPT0wgc2VwKQp7CiAgICBITUVOVQkJaFN1Yk1lbnU7CiAgICBISU5TVEFOQ0UJCWhJbnN0YW5jZSA9IEdldE1vZHVsZUhhbmRsZShOVUxMKTsKICAgIFdDSEFSCQlidWZmWzI1Nl07CgogICAgaWYgKCFoTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIC8qIEZJWE1FOiBlcnJvciBoYW5kbGluZyAmIG1lbW9yeSBjbGVhbnVwICovCiAgICBoU3ViTWVudSA9IENyZWF0ZU1lbnUoKTsKICAgIGlmICghaFN1Yk1lbnUpIHJldHVybiBGQUxTRTsKCiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX01BUkssIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfTUFSSywgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0NPUFksIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfQ09QWSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1BBU1RFLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BBU1RFLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0VMRUNUQUxMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NFTEVDVEFMTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NDUk9MTCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TQ1JPTEwsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUFSQ0gsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VBUkNILCBidWZmKTsKCiAgICBpZiAoc2VwKSBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TRVBBUkFUT1IsIDAsIE5VTEwpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19FRElULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklOR3xNRl9QT1BVUCwgKFVJTlRfUFRSKWhTdWJNZW51LCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfREVGQVVMVCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19ERUZBVUxULCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUFJPUEVSVElFUywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19QUk9QRVJUSUVTLCBidWZmKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldE1lbnVEZXRhaWxzCiAqCiAqIEdyYXlzIC8gdW5ncmF5cyB0aGUgbWVudSBpdGVtcyBhY2NvcmRpbmcgdG8gdGhlaXIgc3RhdGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRNZW51RGV0YWlscyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgSE1FTlUgaE1lbnUpCnsKICAgIGlmICghaE1lbnUpIHtXSU5FX0VSUigiSXNzdWUgaW4gZ2V0dGluZyBtZW51IGJpdHNcbiIpO3JldHVybjt9CgogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19DT1BZLAogICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EfChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19QQVNURSwKCQkgICBNRl9CWUNPTU1BTkR8KElzQ2xpcGJvYXJkRm9ybWF0QXZhaWxhYmxlKENGX1VOSUNPREVURVhUKQoJCQkJID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TQ1JPTEwsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TRUFSQ0gsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQ3JlYXRlCiAqCiAqIENyZWF0ZXMgdGhlIHdpbmRvdyBmb3IgdGhlIHJlbmRlcmluZwogKi8Kc3RhdGljIExSRVNVTFQgV0NVU0VSX0NyZWF0ZShIV05EIGhXbmQsIExQQ1JFQVRFU1RSVUNUIGxwY3MpCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhOwogICAgSE1FTlUJCWhTeXNNZW51OwoKICAgIGRhdGEgPSBscGNzLT5scENyZWF0ZVBhcmFtczsKICAgIFNldFdpbmRvd0xvbmcoaFduZCwgMEwsIChEV09SRClkYXRhKTsKICAgIFBSSVZBVEUoZGF0YSktPmhXbmQgPSBoV25kOwoKICAgIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShoV25kLCBGQUxTRSk7CiAgICBpZiAoIWhTeXNNZW51KSByZXR1cm4gMDsKICAgIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhQb3BNZW51KSByZXR1cm4gMDsKCiAgICBXQ1VTRVJfRmlsbE1lbnUoaFN5c01lbnUsIFRSVUUpOwogICAgV0NVU0VSX0ZpbGxNZW51KFBSSVZBVEUoZGF0YSktPmhQb3BNZW51LCBGQUxTRSk7CgogICAgUFJJVkFURShkYXRhKS0+aE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oTWVtREMpIHtXSU5FX0VSUigibm8gbWVtIGRjXG4iKTtyZXR1cm4gMDt9CgogICAgZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQgPSBGQUxTRTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfR2V0Q3RybEtleVN0YXRlCiAqCiAqIEdldCB0aGUgY29uc29sZSBiaXQgbWFzayBlcXVpdmFsZW50IHRvIHRoZSBWS18gc3RhdHVzIGluIGtleVN0YXRlCiAqLwpzdGF0aWMgRFdPUkQgICAgV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShCWVRFKiBrZXlTdGF0ZSkKewogICAgRFdPUkQgICAgICAgICAgICAgICByZXQgPSAwOwoKICAgIEdldEtleWJvYXJkU3RhdGUoa2V5U3RhdGUpOwogICAgaWYgKGtleVN0YXRlW1ZLX1NISUZUXSAgICAmIDB4ODApCXJldCB8PSBTSElGVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xDT05UUk9MXSAmIDB4ODApCXJldCB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19SQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gUklHSFRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xNRU5VXSAgICAmIDB4ODApCXJldCB8PSBMRUZUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JNRU5VXSAgICAmIDB4ODApCXJldCB8PSBSSUdIVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19DQVBJVEFMXSAgJiAweDAxKQlyZXQgfD0gQ0FQU0xPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfTlVNTE9DS10gICYgMHgwMSkJcmV0IHw9IE5VTUxPQ0tfT047CiAgICBpZiAoa2V5U3RhdGVbVktfU0NST0xMXSAgICYgMHgwMSkJcmV0IHw9IFNDUk9MTExPQ0tfT047CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleQogKgogKiBIYW5kbGVzIGtleXMgd2hpbGUgc2VsZWN0aW5nIGFuIGFyZWEKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBCWVRFCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICBzdGF0ZSA9IFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoa2V5U3RhdGUpICYgfihDQVBTTE9DS19PTnxOVU1MT0NLX09OfFNDUk9MTExPQ0tfT04pOwogICAgQ09PUkQgICAgICAgYzEsIGMyOwoKICAgIGlmIChkb3duKSByZXR1cm47CgogICAgc3dpdGNoIChzdGF0ZSkKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SRVRVUk46CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YKys7IGMyLlgrKzsKICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19MRUZUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlgtLTsgYzIuWC0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1VQOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlktLTsgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgU0hJRlRfUFJFU1NFRDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YKys7CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YLS07CiAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWSsrOwogICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkCiAqCiAqIGdlbmVyYXRlcyBpbnB1dF9yZWNvcmQgZnJvbSB3aW5kb3dzIFdNX0tFWVVQL1dNX0tFWURPV04gbWVzc2FnZXMKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgc3lzKQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBEV09SRAkJbjsKICAgIFdDSEFSCQlidWZbMl07CiAgICBzdGF0aWMJV0NIQVIJbGFzdDsgLyoga2VlcCBsYXN0IGNoYXIgc2VlbiBhcyBmZWVkIGZvciBrZXkgdXAgbWVzc2FnZSAqLwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKCiAgICBpci5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CiAgICBpci5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IGRvd247CiAgICBpci5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSBMT1dPUkQobFBhcmFtKTsKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IHdQYXJhbTsKCiAgICBpci5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlID0gSElXT1JEKGxQYXJhbSkgJiAweEZGOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gMDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAobFBhcmFtICYgKDFMIDw8IDI0KSkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IEVOSEFOQ0VEX0tFWTsKICAgIGlmIChzeXMpCQkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IExFRlRfQUxUX1BSRVNTRUQ7IC8qIEZJWE1FOiBnb3R0YSBjaG9vc2Ugb25lICovCgogICAgaWYgKCEoaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpKQogICAgewoJaWYgKGRvd24pCgl7CgkgICAgc3dpdGNoIChUb1VuaWNvZGUod1BhcmFtLCBISVdPUkQobFBhcmFtKSwga2V5U3RhdGUsIGJ1ZiwgMiwgMCkpCgkgICAgewoJICAgIGNhc2UgMjoKCQkvKiBGSVhNRS4uLiBzaG91bGQgZ2VuZXJhdGUgdHdvIGV2ZW50cy4uLiAqLwoJCS8qIGZhbGwgdGhydSAqLwoJICAgIGNhc2UgMToKCQlsYXN0ID0gYnVmWzBdOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJbGFzdCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQoJaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBsYXN0OyAvKiBGSVhNRSBIQUNLWS4uLiBhbmQgYnVnZ3kgJ2NveiBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgRFdPUkQgZXZlbnQpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIEJZVEUJCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICAgICAgICAgIG1vZGUsIG47CgogICAgLyogTU9VU0VfRVZFTlRzIHNob3VsZG4ndCBiZSBzZW50IHVubGVzcyBFTkFCTEVfTU9VU0VfSU5QVVQgaXMgYWN0aXZlICovCiAgICBpZiAoIUdldENvbnNvbGVNb2RlKGRhdGEtPmhDb25JbiwgJm1vZGUpIHx8ICEobW9kZSAmIEVOQUJMRV9NT1VTRV9JTlBVVCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlyLkV2ZW50VHlwZSA9IE1PVVNFX0VWRU5UOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd01vdXNlUG9zaXRpb24gPSBjOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlID0gMDsKICAgIGlmICh3UGFyYW0gJiBNS19MQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19NQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19SQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gUklHSFRNT1NUX0JVVFRPTl9QUkVTU0VEOwogICAgaWYgKHdQYXJhbSAmIE1LX0NPTlRST0wpIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19TSElGVCkgICBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChldmVudCA9PSBNT1VTRV9XSEVFTEVEKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gd1BhcmFtICYgMHhGRkZGMDAwMDsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdFdmVudEZsYWdzID0gZXZlbnQ7CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Byb2MKICoKICoKICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIFdDVVNFUl9Qcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YSA9IChzdHJ1Y3QgaW5uZXJfZGF0YSopR2V0V2luZG93TG9uZyhoV25kLCAwKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICByZXR1cm4gV0NVU0VSX0NyZWF0ZShoV25kLCAoTFBDUkVBVEVTVFJVQ1QpbFBhcmFtKTsKICAgIGNhc2UgV01fREVTVFJPWToKCVBSSVZBVEUoZGF0YSktPmhXbmQgPSAwOwoJUG9zdFF1aXRNZXNzYWdlKDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX1BBSU5UOgoJV0NVU0VSX1BhaW50KGRhdGEpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgRkFMU0UpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NZU0tFWURPV046CiAgICBjYXNlIFdNX1NZU0tFWVVQOgoJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9TWVNLRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgVFJVRSk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRPV046CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pOwogICAgICAgICAgICAgICAgU2V0Q2FwdHVyZShQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX01PVVNFTU9WRToKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IFBSSVZBVEUoZGF0YSktPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSAmIE1LX0xCVVRUT04pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCBNT1VTRV9NT1ZFRCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05VUDoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IFBSSVZBVEUoZGF0YSktPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSk7CiAgICAgICAgICAgICAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fUkJVVFRPTkRPV046CiAgICAgICAgaWYgKCh3UGFyYW0gJiAoTUtfQ09OVFJPTHxNS19TSElGVCkpID09IGRhdGEtPmN1cmNmZy5tZW51X21hc2spCiAgICAgICAgewogICAgICAgICAgICBSRUNUICAgICAgICByOwoKICAgICAgICAgICAgR2V0V2luZG93UmVjdChoV25kLCAmcik7CiAgICAgICAgICAgIFdDVVNFUl9TZXRNZW51RGV0YWlscyhkYXRhLCBQUklWQVRFKGRhdGEpLT5oUG9wTWVudSk7CiAgICAgICAgICAgIFRyYWNrUG9wdXBNZW51KFBSSVZBVEUoZGF0YSktPmhQb3BNZW51LCBUUE1fTEVGVEFMSUdOfFRQTV9UT1BBTElHTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgci5sZWZ0ICsgTE9XT1JEKGxQYXJhbSksIHIudG9wICsgSElXT1JEKGxQYXJhbSksIDAsIGhXbmQsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX1JCVVRUT05VUDoKICAgICAgICAvKiBubyBuZWVkIHRvIHRyYWNrIGZvciByYnV0dG9uIHVwIHdoZW4gb3BlbmluZyB0aGUgcG9wdXAuLi4gdGhlIGV2ZW50IHdpbGwgYmUKICAgICAgICAgKiBzd2FsbG93ZWQgYnkgVHJhY2tQb3B1cE1lbnUgKi8KICAgIGNhc2UgV01fTUJVVFRPTkRPV046CiAgICBjYXNlIFdNX01CVVRUT05VUDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fTUJVVFRPTkRCTENMSzoKICAgIGNhc2UgV01fUkJVVFRPTkRCTENMSzoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgRE9VQkxFX0NMSUNLKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV01fTU9VU0VXSEVFTDoKICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsICBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NFVEZPQ1VTOgoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCXsKCSAgICBDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBXTV9LSUxMRk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIERlc3Ryb3lDYXJldCgpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6CiAgICAgICAgewogICAgICAgICAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWDsKCiAgICAgICAgICAgIHN3aXRjaCAoTE9XT1JEKHdQYXJhbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICAgICAgICAgICAgICBwb3MgPSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoOwogICAgICAgICAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNjcm9sbFdpbmRvdyhoV25kLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICAgICAgICAgICAgICBTZXRTY3JvbGxQb3MoaFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CiAgICAgICAgICAgICAgICBXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9WU0NST0xMOgogICAgICAgIHsKCSAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWTsKCgkgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKCSAgICB7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRVVQOiAJcG9zIC09IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBvcyA8IDApIHBvcyA9IDA7CgkgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodDsKCSAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpCgkgICAgewoJCVNjcm9sbFdpbmRvdyhoV25kLCAwLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCQlVcGRhdGVXaW5kb3coaFduZCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCQlXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKCSAgICB9CgogICAgICAgIH0KICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAleFxuIiwgd1BhcmFtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJfQoJYnJlYWs7CiAgICBjYXNlIFdNX0lOSVRNRU5VUE9QVVA6CglpZiAoIUhJV09SRChsUGFyYW0pKQlyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CglXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgR2V0U3lzdGVtTWVudShQUklWQVRFKGRhdGEpLT5oV25kLCBGQUxTRSkpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9EZWxldGVCYWNrZW5kCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfRGVsZXRlQmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgaWYgKCFQUklWQVRFKGRhdGEpKSByZXR1cm47CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aE1lbURDKQkJRGVsZXRlREMoUFJJVkFURShkYXRhKS0+aE1lbURDKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kKQkJRGVzdHJveVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBQUklWQVRFKGRhdGEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01haW5Mb29wCiAqCiAqCiAqLwpzdGF0aWMgaW50IFdDVVNFUl9NYWluTG9vcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgTVNHCQltc2c7CgogICAgU2hvd1dpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kLCBkYXRhLT5uQ21kU2hvdyk7CiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZkYXRhLT5oU3luY2hybywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCkpCgl7CgljYXNlIFdBSVRfT0JKRUNUXzA6CgkgICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpICYmIGRhdGEtPmN1cmNmZy5leGl0X29uX2RpZSkKICAgICAgICAgICAgICAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKCSAgICBicmVhazsKCWNhc2UgV0FJVF9PQkpFQ1RfMCsxOgoJICAgIC8qIG5lZWQgdG8gdXNlIFBlZWtNZXNzYWdlIGxvb3AgaW5zdGVhZCBvZiBzaW1wbGUgR2V0TWVzc2FnZToKCSAgICAgKiBtdWx0aXBsZSBtZXNzYWdlcyBtaWdodCBoYXZlIGFycml2ZWQgaW4gYmV0d2VlbiwKCSAgICAgKiBzbyBHZXRNZXNzYWdlIHdvdWxkIGxlYWQgdG8gZGVsYXllZCBwcm9jZXNzaW5nICovCgkgICAgd2hpbGUgKFBlZWtNZXNzYWdlKCZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSkpCgkgICAgewogICAgICAgICAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1FVSVQpIHJldHVybiAwOwogICAgICAgICAgICAgICAgV0lORV9UUkFDRSgiZGlzcGF0Y2hpbmcgbXNnICUwNHhcbiIsIG1zZy5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEJhY2tlbmQKICoKICogSW5pdGlhbGlzYXRpb24gcGFydCBJSTogY3JlYXRpb24gb2Ygd2luZG93LgogKgogKi8KZW51bSBpbml0X3JldHVybiBXQ1VTRVJfSW5pdEJhY2tlbmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3Q2xhc3NOYW1lW10gPSB7J1cnLCdpJywnbicsJ2UnLCdDJywnbycsJ24nLCdzJywnbycsJ2wnLCdlJywnQycsJ2wnLCdhJywncycsJ3MnLDB9OwoKICAgIFdORENMQVNTCQl3bmRjbGFzczsKCiAgICBkYXRhLT5wcml2YXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3QgaW5uZXJfZGF0YV91c2VyKSk7CiAgICBpZiAoIWRhdGEtPnByaXZhdGUpIHJldHVybiBpbml0X2ZhaWxlZDsKCiAgICBkYXRhLT5mbk1haW5Mb29wID0gV0NVU0VSX01haW5Mb29wOwogICAgZGF0YS0+Zm5Qb3NDdXJzb3IgPSBXQ1VTRVJfUG9zQ3Vyc29yOwogICAgZGF0YS0+Zm5TaGFwZUN1cnNvciA9IFdDVVNFUl9TaGFwZUN1cnNvcjsKICAgIGRhdGEtPmZuQ29tcHV0ZVBvc2l0aW9ucyA9IFdDVVNFUl9Db21wdXRlUG9zaXRpb25zOwogICAgZGF0YS0+Zm5SZWZyZXNoID0gV0NVU0VSX1JlZnJlc2g7CiAgICBkYXRhLT5mblJlc2l6ZVNjcmVlbkJ1ZmZlciA9IFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXI7CiAgICBkYXRhLT5mblNldFRpdGxlID0gV0NVU0VSX1NldFRpdGxlOwogICAgZGF0YS0+Zm5TZXRGb250ID0gV0NVU0VSX1NldEZvbnRQbXQ7CiAgICBkYXRhLT5mblNjcm9sbCA9IFdDVVNFUl9TY3JvbGw7CiAgICBkYXRhLT5mbkRlbGV0ZUJhY2tlbmQgPSBXQ1VTRVJfRGVsZXRlQmFja2VuZDsKCiAgICB3bmRjbGFzcy5zdHlsZSAgICAgICAgID0gQ1NfREJMQ0xLUzsKICAgIHduZGNsYXNzLmxwZm5XbmRQcm9jICAgPSBXQ1VTRVJfUHJvYzsKICAgIHduZGNsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kY2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihEV09SRCk7CiAgICB3bmRjbGFzcy5oSW5zdGFuY2UgICAgID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgd25kY2xhc3MuaEljb24gICAgICAgICA9IExvYWRJY29uKDAsIElESV9XSU5MT0dPKTsKICAgIHduZGNsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7CiAgICB3bmRjbGFzcy5oYnJCYWNrZ3JvdW5kID0gR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgd25kY2xhc3MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgICB3bmRjbGFzcy5scHN6Q2xhc3NOYW1lID0gd0NsYXNzTmFtZTsKCiAgICBSZWdpc3RlckNsYXNzKCZ3bmRjbGFzcyk7CgogICAgQ3JlYXRlV2luZG93KHduZGNsYXNzLmxwc3pDbGFzc05hbWUsIE5VTEwsCgkJIFdTX09WRVJMQVBQRUR8V1NfQ0FQVElPTnxXU19TWVNNRU5VfFdTX1RISUNLRlJBTUV8V1NfTUlOSU1JWkVCT1h8V1NfSFNDUk9MTHxXU19WU0NST0xMLAoJCSBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCAwLCAwLCAwLCAwLCB3bmRjbGFzcy5oSW5zdGFuY2UsIGRhdGEpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oV25kKSByZXR1cm4gaW5pdF9mYWlsZWQ7CgogICAgcmV0dXJuIGluaXRfc3VjY2VzczsKfQo=