LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0gCnsKICAgIFJHQigweDAwLCAweDAwLCAweDAwKSwgUkdCKDB4MDAsIDB4MDAsIDB4ODApLCBSR0IoMHgwMCwgMHg4MCwgMHgwMCksIFJHQigweDAwLCAweDgwLCAweDgwKSwKICAgIFJHQigweDgwLCAweDAwLCAweDAwKSwgUkdCKDB4ODAsIDB4MDAsIDB4ODApLCBSR0IoMHg4MCwgMHg4MCwgMHgwMCksIFJHQigweDgwLCAweDgwLCAweDgwKSwKICAgIFJHQigweEMwLCAweEMwLCAweEMwKSwgUkdCKDB4MDAsIDB4MDAsIDB4RkYpLCBSR0IoMHgwMCwgMHhGRiwgMHgwMCksIFJHQigweDAwLCAweEZGLCAweEZGKSwKICAgIFJHQigweEZGLCAweDAwLCAweDAwKSwgUkdCKDB4RkYsIDB4MDAsIDB4RkYpLCBSR0IoMHhGRiwgMHhGRiwgMHgwMCksIFJHQigweEZGLCAweEZGLCAweEZGKSwKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTWVtREMKICoKICogRmlsbHMgdGhlIE1lbSBEQyB3aXRoIGN1cnJlbnQgY2VsbHMgdmFsdWVzCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfRmlsbE1lbURDKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgdXBkX3RwLCBpbnQgdXBkX2JtKQp7CiAgICB1bnNpZ25lZAkJaSwgaiwgazsKICAgIENIQVJfSU5GTyoJCWNlbGw7CiAgICBIRk9OVAkJaE9sZEZvbnQ7CiAgICBXT1JECQlhdHRyOwogICAgV0NIQVIqCQlsaW5lOwoKICAgIC8qIG5vIGZvbnQgaGFzIGJlZW4gc2V0IHVwIHlldCwgZG9uJ3Qgd29ycnkgYWJvdXQgZmlsbGluZyB0aGUgYml0bWFwLCAKICAgICAqIHdlJ2xsIGRvIGl0IG9uY2UgYSBmb250IGlzIGNob3NlbgogICAgICovCiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhGb250KSByZXR1cm47CgogICAgaWYgKCEobGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggKiBzaXplb2YoV0NIQVIpKSkpCiAgICB7V0lORV9FUlIoIk9PTVxuIik7IHJldHVybjt9CgogICAgaE9sZEZvbnQgPSBTZWxlY3RPYmplY3QoUFJJVkFURShkYXRhKS0+aE1lbURDLCBQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBmb3IgKGogPSB1cGRfdHA7IGogPD0gdXBkX2JtOyBqKyspCiAgICB7CgljZWxsID0gJmRhdGEtPmNlbGxzW2ogKiBkYXRhLT5jdXJjZmcuc2Jfd2lkdGhdOwoJZm9yIChpID0gMDsgaSA8IGRhdGEtPmN1cmNmZy5zYl93aWR0aDsgaSsrKQoJewoJICAgIGF0dHIgPSBjZWxsW2ldLkF0dHJpYnV0ZXM7CgkgICAgU2V0QmtDb2xvcihQUklWQVRFKGRhdGEpLT5oTWVtREMsIFdDVVNFUl9Db2xvck1hcFsoYXR0cj4+NCkmMHgwRl0pOwoJICAgIFNldFRleHRDb2xvcihQUklWQVRFKGRhdGEpLT5oTWVtREMsIFdDVVNFUl9Db2xvck1hcFthdHRyJjB4MEZdKTsKCSAgICBmb3IgKGsgPSBpOyBrIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoICYmIGNlbGxba10uQXR0cmlidXRlcyA9PSBhdHRyOyBrKyspCgkgICAgewoJCWxpbmVbayAtIGldID0gY2VsbFtrXS5DaGFyLlVuaWNvZGVDaGFyOwoJICAgIH0KCSAgICBUZXh0T3V0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgaSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBqICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCAKCQkgICAgbGluZSwgayAtIGkpOwoJICAgIGkgPSBrIC0gMTsKCX0KICAgIH0KICAgIFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGhPbGRGb250KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxpbmUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfTmV3Qml0bWFwCiAqCiAqIEVpdGhlciB0aGUgZm9udCBnZW9tZXRyeSBvciB0aGUgc2IgZ2VvbWV0cnkgaGFzIGNoYW5nZWQuIHdlIG5lZWQgdG8gcmVjcmVhdGUgdGhlCiAqIGJpdG1hcCBnZW9tZXRyeQogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX05ld0JpdG1hcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQk9PTCBmaWxsKQp7CiAgICBIREMgICAgICAgICBoREM7CiAgICBIQklUTUFQCWhuZXcsIGhvbGQ7CgogICAgaWYgKCFkYXRhLT5jdXJjZmcuc2Jfd2lkdGggfHwgIWRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgfHwgCiAgICAgICAgIVBSSVZBVEUoZGF0YSktPmhGb250IHx8ICEoaERDID0gR2V0REMoUFJJVkFURShkYXRhKS0+aFduZCkpKQogICAgICAgIHJldHVybjsKICAgIGhuZXcgPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKGhEQywgCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgCgkJCQkgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwogICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CiAgICBob2xkID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgaG5ldyk7CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCiAgICB7CglpZiAoaG9sZCA9PSBQUklWQVRFKGRhdGEpLT5oQml0bWFwKQoJICAgIERlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oQml0bWFwKTsKCWVsc2UKCSAgICBXSU5FX0ZJWE1FKCJsZWFrXG4iKTsKICAgIH0KICAgIFBSSVZBVEUoZGF0YSktPmhCaXRtYXAgPSBobmV3OwogICAgaWYgKGZpbGwpCglXQ1VTRVJfRmlsbE1lbURDKGRhdGEsIDAsIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcgogKgogKgogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NVU0VSX05ld0JpdG1hcChkYXRhLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Qb3NDdXJzb3IKICoKICogU2V0IGEgbmV3IHBvc2l0aW9uIGZvciB0aGUgY3Vyc29yCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUG9zQ3Vyc29yKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aFduZCAhPSBHZXRGb2N1cygpIHx8ICFkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpIHJldHVybjsKCiAgICBTZXRDYXJldFBvcygoZGF0YS0+Y3Vyc29yLlggLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCAKCQkoZGF0YS0+Y3Vyc29yLlkgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CiAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7IAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2hhcGVDdXJzb3IKICoKICogU2V0cyBhIG5ldyBzaGFwZSBmb3IgdGhlIGN1cnNvcgogKi8Kdm9pZAlXQ1VTRVJfU2hhcGVDdXJzb3Ioc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCBzaXplLCBpbnQgdmlzLCBCT09MIGZvcmNlKQp7CiAgICBpZiAoZm9yY2UgfHwgc2l6ZSAhPSBkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUpCiAgICB7CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlICYmIFBSSVZBVEUoZGF0YSktPmhXbmQgPT0gR2V0Rm9jdXMoKSkgRGVzdHJveUNhcmV0KCk7CglpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkgRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwoJUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCA9IChIQklUTUFQKTA7CglpZiAoc2l6ZSAhPSAxMDApCgl7CgkgICAgaW50CQl3MTZiOyAvKiBudW1iZXIgb2YgYnlldHMgcGVyIHJvdywgYWxpZ25lZCBvbiB3b3JkIHNpemUgKi8KCSAgICBCWVRFKglwdHI7CgkgICAgaW50CQlpLCBqLCBuYmw7CgoJICAgIHcxNmIgPSAoKGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoICsgMTUpICYgfjE1KSAvIDg7CgkgICAgcHRyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHcxNmIgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOwoJICAgIGlmICghcHRyKSB7V0lORV9FUlIoIk9PTVxuIik7IHJldHVybjt9CgkgICAgbmJsID0gbWF4KChkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQgKiBzaXplKSAvIDEwMCwgMSk7CgkgICAgZm9yIChqID0gZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0IC0gbmJsOyBqIDwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OyBqKyspCgkgICAgewoJCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsgaSsrKQoJCXsKCQkgICAgcHRyW3cxNmIgKiBqICsgKGkgLyA4KV0gfD0gMHg4MCA+PiAoaSAmIDcpOwoJCX0KCSAgICB9CgkgICAgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCA9IENyZWF0ZUJpdG1hcChkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCAxLCAxLCBwdHIpOwoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHB0cik7Cgl9CglkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUgPSBzaXplOwoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlID0gLTE7CiAgICB9CgogICAgdmlzID0gKHZpcykgPyBUUlVFIDogRkFMU0U7CiAgICBpZiAoZm9yY2UgfHwgdmlzICE9IGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKICAgIHsKCWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSA9IHZpczsKCWlmIChQUklWQVRFKGRhdGEpLT5oV25kID09IEdldEZvY3VzKCkpCgl7CgkgICAgaWYgKHZpcykKCSAgICB7CgkJQ3JlYXRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCwgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCQlXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCURlc3Ryb3lDYXJldCgpOwoJICAgIH0KCX0KICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSU5FQ09OX0NvbXB1dGVQb3NpdGlvbnMKICoKICogUmVjb21wdXRlcyBhbGwgdGhlIGNvbXBvbmVudHMgKG1haW5seSBzY3JvbGwgYmFycykgcG9zaXRpb25zCiAqLwp2b2lkCVdDVVNFUl9Db21wdXRlUG9zaXRpb25zKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBSRUNUCQlyOwogICAgaW50CQkJZHgsIGR5OwoKICAgIC8qIGNvbXB1dGUgd2luZG93IHNpemUgZnJvbSBkZXNpcmVkIGNsaWVudCBzaXplICovCiAgICByLmxlZnQgPSByLnRvcCA9IDA7CiAgICByLnJpZ2h0ID0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci5ib3R0b20gPSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCiAgICBpZiAoSXNSZWN0RW1wdHkoJnIpKQogICAgewoJU2hvd1dpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kLCBTV19ISURFKTsKCXJldHVybjsKICAgIH0KCiAgICBBZGp1c3RXaW5kb3dSZWN0KCZyLCBHZXRXaW5kb3dMb25nKFBSSVZBVEUoZGF0YSktPmhXbmQsIEdXTF9TVFlMRSksIEZBTFNFKTsKCiAgICBkeCA9IGR5ID0gMDsKICAgIGlmIChkYXRhLT5jdXJjZmcuc2Jfd2lkdGggPiBkYXRhLT5jdXJjZmcud2luX3dpZHRoKQogICAgewoJZHkgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCAwLCAKICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoLCBGQUxTRSk7CglTZXRTY3JvbGxQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgMCwgRkFMU0UpOyAvKiBGSVhNRSAqLwoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCBUUlVFKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgRkFMU0UpOwogICAgfQoKICAgIGlmIChkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0ID4gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQpCiAgICB7CglkeCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKTsKCVNldFNjcm9sbFJhbmdlKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIDAsIAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCwgRkFMU0UpOwoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIDAsIEZBTFNFKTsgLyogRklYTUUgKi8KCVNob3dTY3JvbGxCYXIoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgVFJVRSk7CiAgICB9CQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCBGQUxTRSk7CiAgICB9CgogICAgU2V0V2luZG93UG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIDAsIDAsIDAsIHIucmlnaHQgLSByLmxlZnQgKyBkeCwgci5ib3R0b20gLSByLnRvcCArIGR5LAoJCSBTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUnxTV1BfU0hPV1dJTkRPVyk7CiAgICBXQ1VTRVJfU2hhcGVDdXJzb3IoZGF0YSwgZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUsIFRSVUUpOwogICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldFRpdGxlCiAqCiAqIFNldHMgdGhlIHRpdGxlIHRvIHRoZSB3aW5lIGNvbnNvbGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRUaXRsZShjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NIQVIJYnVmZmVyWzI1Nl07CQoKICAgIGlmIChXSU5FQ09OX0dldENvbnNvbGVUaXRsZShkYXRhLT5oQ29uSW4sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpKQoJU2V0V2luZG93VGV4dChQUklWQVRFKGRhdGEpLT5oV25kLCBidWZmZXIpOwp9Cgp2b2lkIFdDVVNFUl9EdW1wTG9nRm9udChjb25zdCBjaGFyKiBwZngsIGNvbnN0IExPR0ZPTlQqIGxmLCBEV09SRCBmdCkKewogICAgV0lORV9UUkFDRV8od2NfZm9udCkoIiVzICVzJXMlcyVzXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi5sZkhlaWdodD0lbGQgbGYubGZXaWR0aD0lbGQgbGYubGZFc2NhcGVtZW50PSVsZCBsZi5sZk9yaWVudGF0aW9uPSVsZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYubGZXZWlnaHQ9JWxkIGxmLmxmSXRhbGljPSV1IGxmLmxmVW5kZXJsaW5lPSV1IGxmLmxmU3RyaWtlT3V0PSV1XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi5sZkNoYXJTZXQ9JXUgbGYubGZPdXRQcmVjaXNpb249JXUgbGYubGZDbGlwUHJlY2lzaW9uPSV1IGxmLmxmUXVhbGl0eT0ldVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0bGYtPmxmUGl0Y2hBbmRGYW1pbHk9JXUgbGYubGZGYWNlTmFtZT0lc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHBmeCwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFJBU1RFUl9GT05UVFlQRSkgPyAicmFzdGVyIiA6ICIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFRSVUVUWVBFX0ZPTlRUWVBFKSA/ICJ0cnVldHlwZSIgOiAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBERVZJQ0VfRk9OVFRZUEUpID8gInxkZXZpY2UiIDogIiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmSGVpZ2h0LCBsZi0+bGZXaWR0aCwgbGYtPmxmRXNjYXBlbWVudCwgbGYtPmxmT3JpZW50YXRpb24sIAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmV2VpZ2h0LCBsZi0+bGZJdGFsaWMsIGxmLT5sZlVuZGVybGluZSwgbGYtPmxmU3RyaWtlT3V0LCBsZi0+bGZDaGFyU2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmT3V0UHJlY2lzaW9uLCBsZi0+bGZDbGlwUHJlY2lzaW9uLCBsZi0+bGZRdWFsaXR5LCBsZi0+bGZQaXRjaEFuZEZhbWlseSwgCiAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lX2RiZ3N0cl93KGxmLT5sZkZhY2VOYW1lKSk7Cn0KCnZvaWQgV0NVU0VSX0R1bXBUZXh0TWV0cmljKGNvbnN0IFRFWFRNRVRSSUMqIHRtLCBEV09SRCBmdCkKewogICAgV0lORV9UUkFDRV8od2NfZm9udCkoIiVzJXMlcyVzXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUhlaWdodD0lbGQgdG1Bc2NlbnQ9JWxkIHRtRGVzY2VudD0lbGQgdG1JbnRlcm5hbExlYWRpbmc9JWxkIHRtRXh0ZXJuYWxMZWFkaW5nPSVsZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1BdmVDaGFyV2lkdGg9JWxkIHRtTWF4Q2hhcldpZHRoPSVsZCB0bVdlaWdodD0lbGQgdG1PdmVyaGFuZz0lbGRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtRGlnaXRpemVkQXNwZWN0WD0lbGQgdG1EaWdpdGl6ZWRBc3BlY3RZPSVsZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1GaXJzdENoYXI9JWQgdG1MYXN0Q2hhcj0lZCB0bURlZmF1bHRDaGFyPSVkIHRtQnJlYWtDaGFyPSVkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUl0YWxpYz0ldSB0bVVuZGVybGluZWQ9JXUgdG1TdHJ1Y2tPdXQ9JXUgdG1QaXRjaEFuZEZhbWlseT0ldSB0bUNoYXJTZXQ9JXVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBSQVNURVJfRk9OVFRZUEUpID8gInJhc3RlciIgOiAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgKChmdCAmIChSQVNURVJfRk9OVFRZUEV8VFJVRVRZUEVfRk9OVFRZUEUpKSA9PSAwKSA/ICJ2ZWN0b3IiIDogIiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgREVWSUNFX0ZPTlRUWVBFKSA/ICJ8ZGV2aWNlIiA6ICIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCwgdG0tPnRtQXNjZW50LCB0bS0+dG1EZXNjZW50LCB0bS0+dG1JbnRlcm5hbExlYWRpbmcsIHRtLT50bUV4dGVybmFsTGVhZGluZywgdG0tPnRtQXZlQ2hhcldpZHRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bU1heENoYXJXaWR0aCwgdG0tPnRtV2VpZ2h0LCB0bS0+dG1PdmVyaGFuZywgdG0tPnRtRGlnaXRpemVkQXNwZWN0WCwgdG0tPnRtRGlnaXRpemVkQXNwZWN0WSwgCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1GaXJzdENoYXIsIHRtLT50bUxhc3RDaGFyLCB0bS0+dG1EZWZhdWx0Q2hhciwgdG0tPnRtQnJlYWtDaGFyLCB0bS0+dG1JdGFsaWMsIHRtLT50bVVuZGVybGluZWQsIHRtLT50bVN0cnVja091dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1QaXRjaEFuZEZhbWlseSwgdG0tPnRtQ2hhclNldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUZvbnRFcXVhbAogKgogKgogKi8KQk9PTCBXQ1VTRVJfQXJlRm9udHNFcXVhbChjb25zdCBzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIHJldHVybiBsZi0+bGZIZWlnaHQgPT0gY29uZmlnLT5jZWxsX2hlaWdodCAmJgogICAgICAgIGxmLT5sZldlaWdodCA9PSBjb25maWctPmZvbnRfd2VpZ2h0ICYmCiAgICAgICAgIWxmLT5sZkl0YWxpYyAmJiAhbGYtPmxmVW5kZXJsaW5lICYmICFsZi0+bGZTdHJpa2VPdXQgJiYKICAgICAgICAhbHN0cmNtcChsZi0+bGZGYWNlTmFtZSwgY29uZmlnLT5mYWNlX25hbWUpOwp9CgpzdHJ1Y3QgZm9udF9jaG9vc2VyIAp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YTsKICAgIGludAkJCWRvbmU7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljCiAqCiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZm9udCBkZXNjcmliZWQgaW4gdG0gaXMgdXNhYmxlIGFzIGEgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpCT09MCVdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLCBEV09SRCBmb250VHlwZSkKewogICAgQk9PTCAgICAgICAgcmV0ID0gVFJVRTsKCiAgICBpZiAoZm9udFR5cGUgJiBSQVNURVJfRk9OVFRZUEUpCiAgICAgICAgcmV0ID0gKHRtLT50bU1heENoYXJXaWR0aCAqIGRhdGEtPmN1cmNmZy53aW5fd2lkdGggPCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSAmJgogICAgICAgICAgICAgICB0bS0+dG1IZWlnaHQgKiBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA8IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pKTsKICAgIHJldHVybiByZXQgJiYgIXRtLT50bUl0YWxpYyAmJiAhdG0tPnRtVW5kZXJsaW5lZCAmJiAhdG0tPnRtU3RydWNrT3V0ICYmCiAgICAgICAgKHRtLT50bUNoYXJTZXQgPT0gREVGQVVMVF9DSEFSU0VUIHx8IHRtLT50bUNoYXJTZXQgPT0gQU5TSV9DSEFSU0VUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1ZhbGlkYXRlRm9udAogKgogKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZvbnQgZmFtaWx5IGRlc2NyaWJlZCBpbiBsZiBpcyB1c2FibGUgYXMgYSBmb250IGZvciB0aGUgcmVuZGVyZXIKICovCkJPT0wJV0NVU0VSX1ZhbGlkYXRlRm9udChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIHJldHVybiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAzKSA9PSBGSVhFRF9QSVRDSCAmJiAKICAgICAgICAvKiAobGYtPmxmUGl0Y2hBbmRGYW1pbHkgJiAweEYwKSA9PSBGRl9NT0RFUk4gJiYgKi8KICAgICAgICAobGYtPmxmQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgbGYtPmxmQ2hhclNldCA9PSBBTlNJX0NIQVJTRVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtXzIKICoJCWdldF9maXJzdF9mb250X2VudW0KICoKICogSGVscGVyIGZ1bmN0aW9ucyB0byBnZXQgYSBkZWNlbnQgZm9udCBmb3IgdGhlIHJlbmRlcmVyCiAqLwpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW1fMihjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sIAoJCQkJCSAgRFdPUkQgRm9udFR5cGUsIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBmb250X2Nob29zZXIqCWZjID0gKHN0cnVjdCBmb250X2Nob29zZXIqKWxQYXJhbTsKCiAgICBXQ1VTRVJfRHVtcFRleHRNZXRyaWModG0sIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGZjLT5kYXRhLCB0bSwgRm9udFR5cGUpKQogICAgewogICAgICAgIExPR0ZPTlQgbWxmID0gKmxmOwoKICAgICAgICAvKiBVc2UgdGhlIGRlZmF1bHQgc2l6ZXMgZm9yIHRoZSBmb250ICh0aGlzIGlzIG5lZWRlZCwgZXNwZWNpYWxseSBmb3IKICAgICAgICAgKiBUcnVlVHlwZSBmb250cywgc28gdGhhdCB3ZSBnZXQgYSBkZWNlbnQgc2l6ZSwgbm90IHRoZSBtYXggc2l6ZSkgCiAgICAgICAgICovCiAgICAgICAgbWxmLmxmV2lkdGggID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgIG1sZi5sZkhlaWdodCA9IGZjLT5kYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGZjLT5kYXRhLCAmbWxmKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9EdW1wTG9nRm9udCgiSW5pdENob29zaW5nOiAiLCAmbWxmLCBGb250VHlwZSk7CiAgICAgICAgICAgIGZjLT5kb25lID0gMTsKICAgICAgICAgICAgLyogc2luY2Ugd2UndmUgbW9kaWZpZWQgdGhlIGN1cnJlbnQgY29uZmlnIHdpdGggbmV3IGZvbnQgaW5mb3JtYXRpb24sIAogICAgICAgICAgICAgKiBzZXQgdGhpcyBpbmZvcm1hdGlvbiBhcyB0aGUgbmV3IGRlZmF1bHQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmYy0+ZGF0YS0+ZGVmY2ZnLmNlbGxfd2lkdGggPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIGZjLT5kYXRhLT5kZWZjZmcuY2VsbF9oZWlnaHQgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgICAgICAgICBsc3RyY3B5VyhmYy0+ZGF0YS0+ZGVmY2ZnLmZhY2VfbmFtZSwgZmMtPmRhdGEtPmN1cmNmZy5mYWNlX25hbWUpOwogICAgICAgICAgICAvKiBGb3JjZSBhbHNvIGl0cyB3cml0aW5nIGJhY2sgdG8gdGhlIHJlZ2lzdHJ5IHNvIHRoYXQgd2UgY2FuIGdldCBpdAogICAgICAgICAgICAgKiB0aGUgbmV4dCB0aW1lLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgV0lORUNPTl9SZWdTYXZlKCZmYy0+ZGF0YS0+ZGVmY2ZnKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgQ0FMTEJBQ0sgZ2V0X2ZpcnN0X2ZvbnRfZW51bShjb25zdCBMT0dGT05UKiBsZiwgY29uc3QgVEVYVE1FVFJJQyogdG0sIAoJCQkJCURXT1JEIEZvbnRUeXBlLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyKglmYyA9IChzdHJ1Y3QgZm9udF9jaG9vc2VyKilsUGFyYW07CgogICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0RmFtaWx5OiAiLCBsZiwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnQoZmMtPmRhdGEsIGxmKSkKICAgIHsKCUVudW1Gb250RmFtaWxpZXMoUFJJVkFURShmYy0+ZGF0YSktPmhNZW1EQywgbGYtPmxmRmFjZU5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yLCBsUGFyYW0pOwoJcmV0dXJuICFmYy0+ZG9uZTsgLyogd2UganVzdCBuZWVkIHRoZSBmaXJzdCBtYXRjaGluZyBvbmUuLi4gKi8KICAgIH0KICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDb3B5Rm9udAogKgogKiBnZXQgdGhlIHJlbGV2YW50IGluZm9ybWF0aW9uIGZyb20gdGhlIGZvbnQgZGVzY3JpYmVkIGluIGxmIGFuZCBzdG9yZSB0aGVtCiAqIGluIGNvbmZpZwogKi8KSEZPTlQgV0NVU0VSX0NvcHlGb250KHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBIV05EIGhXbmQsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICBURVhUTUVUUklDICB0bTsKICAgIEhEQyAgICAgICAgIGhEQzsKICAgIEhGT05UICAgICAgIGhGb250LCBoT2xkRm9udDsKICAgIGludCAgICAgICAgIHcsIGksIGJ1ZlsyNTZdOwoKICAgIGlmICghKGhEQyA9IEdldERDKGhXbmQpKSkgcmV0dXJuIChIRk9OVCkwOwogICAgaWYgKCEoaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3QobGYpKSkgZ290byBlcnIxOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KGhEQywgaEZvbnQpOwogICAgR2V0VGV4dE1ldHJpY3MoaERDLCAmdG0pOwoKICAgIC8qIEZJWE1FOgogICAgICogdGhlIGN1cnJlbnQgZnJlZXR5cGUgZW5naW5lIChhdCBsZWFzdCAyLjAueCB3aXRoIHggPD0gOCkgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbgogICAgICogaW4gV2luZSBkb24ndCByZXR1cm4gYWRlcXVhdGUgdmFsdWVzIGZvciBmaXhlZCBmb250cwogICAgICogSW4gV2luZG93cywgdGhvc2UgZm9udHMgYXJlIGV4cGVjdGVzIHRvIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IKICAgICAqICAtIHRoZSBhdmVyYWdlIHdpZHRoCiAgICAgKiAgLSB0aGUgbGFyZ2VzdCB3aWR0aAogICAgICogIC0gdGhlIHdpZHRoIG9mIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBmb250CiAgICAgKiBUaGlzIGlzbid0IHRydWUgaW4gV2luZS4gQXMgYSB0ZW1wb3Jhcnkgd29ya2FvdW5kLCB3ZSBnZXQgYXMgdGhlIHdpZHRoIG9mIHRoZSAKICAgICAqIGNlbGwsIHRoZSB3aWR0aCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBmb250LCBhZnRlciBjaGVja2luZyB0aGF0IGFsbAogICAgICogY2hhcmFjdGVycyBpbiB0aGUgZm9udCBoYXZlIHRoZSBzYW1lIHdpZHRoIChJIGhlYXIgcGFyYW5v72EgY29taW5nKQogICAgICogd2hlbiB0aGlzIGdldHMgZml4ZWQsIHRoZSBzaG91bGQgYmUgdXNpbmcgdG0udG1BdmVDaGFyV2lkdGggb3IgdG0udG1NYXhDaGFyV2lkdGgKICAgICAqIGFzIHRoZSBjZWxsIHdpZHRoLgogICAgICovCiAgICBHZXRDaGFyV2lkdGgzMihoREMsIHRtLnRtRmlyc3RDaGFyLCB0bS50bUZpcnN0Q2hhciwgJncpOwogICAgZm9yIChpID0gdG0udG1GaXJzdENoYXIgKyAxOyBpIDw9IHRtLnRtTGFzdENoYXI7IGkgKz0gc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSkKICAgIHsKICAgICAgICBpbnQgaiwgbDsKICAgICAgICAgICAgCiAgICAgICAgbCA9IG1pbih0bS50bUxhc3RDaGFyIC0gaSwgc2l6ZW9mKGJ1ZikgLyBzaXplb2YoYnVmWzBdKSAtIDEpOwogICAgICAgIEdldENoYXJXaWR0aDMyKGhEQywgaSwgaSArIGwsIGJ1Zik7CiAgICAgICAgZm9yIChqID0gMDsgaiA8PSBsOyBqKyspIAogICAgICAgIHsKICAgICAgICAgICAgaWYgKGJ1ZltqXSAhPSB3KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX1dBUk4oIk5vbiB1bmlmb3JtIGNlbGwgd2lkdGg6IFslZF09JWQgWyVkXT0lZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIG1heSBiZSBjYXVzZWQgYnkgb2xkIGZyZWV0eXBlIGxpYnJhcmllcywgPj0gMi4wLjggaXMgcmVjb21tZW5kZWRcbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBqLCBidWZbal0sIHRtLnRtRmlyc3RDaGFyLCB3KTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIFJlbGVhc2VEQyhoV25kLCBoREMpOwoKICAgIGNvbmZpZy0+Y2VsbF93aWR0aCAgPSB3OwogICAgY29uZmlnLT5jZWxsX2hlaWdodCA9IHRtLnRtSGVpZ2h0OwogICAgY29uZmlnLT5mb250X3dlaWdodCA9IHRtLnRtV2VpZ2h0OwogICAgbHN0cmNweShjb25maWctPmZhY2VfbmFtZSwgbGYtPmxmRmFjZU5hbWUpOwoKICAgIHJldHVybiBoRm9udDsKIGVycjoKICAgIGlmIChoREMgJiYgaE9sZEZvbnQpIFNlbGVjdE9iamVjdChoREMsIGhPbGRGb250KTsKICAgIGlmIChoRm9udCkgRGVsZXRlT2JqZWN0KGhGb250KTsKIGVycjE6CiAgICBpZiAoaERDKSBSZWxlYXNlREMoaFduZCwgaERDKTsKCiAgICByZXR1cm4gKEhGT05UKTA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTG9nRm9udAogKgogKgogKi8Kdm9pZCAgICBXQ1VTRVJfRmlsbExvZ0ZvbnQoTE9HRk9OVCogbGYsIGNvbnN0IFdDSEFSKiBuYW1lLCBVSU5UIGhlaWdodCwgVUlOVCB3ZWlnaHQpCnsKICAgIGxmLT5sZkhlaWdodCAgICAgICAgPSBoZWlnaHQ7CiAgICBsZi0+bGZXaWR0aCAgICAgICAgID0gMDsKICAgIGxmLT5sZkVzY2FwZW1lbnQgICAgPSAwOwogICAgbGYtPmxmT3JpZW50YXRpb24gICA9IDA7CiAgICBsZi0+bGZXZWlnaHQgICAgICAgID0gd2VpZ2h0OwogICAgbGYtPmxmSXRhbGljICAgICAgICA9IEZBTFNFOwogICAgbGYtPmxmVW5kZXJsaW5lICAgICA9IEZBTFNFOwogICAgbGYtPmxmU3RyaWtlT3V0ICAgICA9IEZBTFNFOwogICAgbGYtPmxmQ2hhclNldCAgICAgICA9IERFRkFVTFRfQ0hBUlNFVDsKICAgIGxmLT5sZk91dFByZWNpc2lvbiAgPSBPVVRfREVGQVVMVF9QUkVDSVM7CiAgICBsZi0+bGZDbGlwUHJlY2lzaW9uID0gQ0xJUF9ERUZBVUxUX1BSRUNJUzsgCiAgICBsZi0+bGZRdWFsaXR5ICAgICAgID0gREVGQVVMVF9RVUFMSVRZOwogICAgbGYtPmxmUGl0Y2hBbmRGYW1pbHkgPSBGSVhFRF9QSVRDSCB8IEZGX0RPTlRDQVJFOwogICAgbHN0cmNweShsZi0+bGZGYWNlTmFtZSwgbmFtZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250CiAqCiAqIHNldHMgbG9nZm9udCBhcyB0aGUgbmV3IGZvbnQgZm9yIHRoZSBjb25zb2xlCiAqLwpCT09MCVdDVVNFUl9TZXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsb2dmb250KQp7CiAgICBIRk9OVCAgICAgICBoRm9udDsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQgIT0gMCAmJiBXQ1VTRVJfQXJlRm9udHNFcXVhbCgmZGF0YS0+Y3VyY2ZnLCBsb2dmb250KSkgCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaEZvbnQgPSBXQ1VTRVJfQ29weUZvbnQoJmRhdGEtPmN1cmNmZywgUFJJVkFURShkYXRhKS0+aFduZCwgbG9nZm9udCk7CiAgICBpZiAoIWhGb250KSB7V0lORV9FUlIoIndyb25nIGZvbnRcbiIpOyByZXR1cm4gRkFMU0U7fQoKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkgRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIFBSSVZBVEUoZGF0YSktPmhGb250ID0gaEZvbnQ7CgogICAgV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMoZGF0YSk7CiAgICBXQ1VTRVJfTmV3Qml0bWFwKGRhdGEsIFRSVUUpOwogICAgSW52YWxpZGF0ZVJlY3QoUFJJVkFURShkYXRhKS0+aFduZCwgTlVMTCwgRkFMU0UpOwogICAgVXBkYXRlV2luZG93KFBSSVZBVEUoZGF0YSktPmhXbmQpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSW5pdEZvbnQKICoKICogY3JlYXRlIGEgaEZvbnQgZnJvbSB0aGUgc2V0dGluZ3Mgc2F2ZWQgaW4gcmVnaXN0cnkuLi4KICogKGNhbGxlZCBvbiBpbml0LCBhc3N1bWluZyBubyBmb250IGhhcyBiZWVuIGNyZWF0ZWQgYmVmb3JlKQogKi8Kc3RhdGljIEJPT0wJV0NVU0VSX0luaXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyIGZjOwoKICAgIFdJTkVfVFJBQ0VfKHdjX2ZvbnQpKCI9PiAlc1xuIiwgd2luZV9kYmdzdHJfd24oZGF0YS0+Y3VyY2ZnLmZhY2VfbmFtZSwgLTEpKTsKICAgIGlmIChkYXRhLT5jdXJjZmcuZmFjZV9uYW1lWzBdICE9ICdcMCcgJiYKICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQgIT0gMCAmJgogICAgICAgIGRhdGEtPmN1cmNmZy5mb250X3dlaWdodCAhPSAwKQogICAgewogICAgICAgIExPR0ZPTlQgICAgICAgICAgICAgbGY7CgogICAgICAgIFdDVVNFUl9GaWxsTG9nRm9udCgmbGYsIGRhdGEtPmN1cmNmZy5mYWNlX25hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsIGRhdGEtPmN1cmNmZy5mb250X3dlaWdodCk7CiAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhGb250ICE9IDApIFdJTkVfRklYTUUoIk9oIHN0cmFuZ2VcbiIpOwoKICAgICAgICBpZiAoV0NVU0VSX1NldEZvbnQoZGF0YSwgJmxmKSkgCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRSZXVzZXM6ICIsICZsZiwgMCk7CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB0cnkgdG8gZmluZCBhbiBhY2NlcHRhYmxlIGZvbnQgKi8KICAgIFdJTkVfV0FSTigiQ291bGRuJ3QgbWF0Y2ggdGhlIGZvbnQgZnJvbSByZWdpc3RyeS4uLiB0cnlpbmcgdG8gZmluZCBvbmVcbiIpOwogICAgZmMuZGF0YSA9IGRhdGE7CiAgICBmYy5kb25lID0gMDsKICAgIEVudW1Gb250RmFtaWxpZXMoUFJJVkFURShkYXRhKS0+aE1lbURDLCBOVUxMLCBnZXRfZmlyc3RfZm9udF9lbnVtLCAoTFBBUkFNKSZmYyk7CiAgICBpZiAoIWZjLmRvbmUpIFdJTkVfV0FSTigiQ291bGRuJ3QgZmluZCBhIGRlY2VudCBmb250LCBhYm9ydGluZ1xuIik7CiAgICByZXR1cm4gZmMuZG9uZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldENlbGwKICoKICogR2V0IGEgY2VsbCBmcm9tIHRoZSBhIHJlbGF0aXZlIGNvb3JkaW5hdGUgaW4gd2luZG93ICh0YWtlcyBpbnRvCiAqIGFjY291bnQgdGhlIHNjcm9sbGluZykKICovCnN0YXRpYyBDT09SRAlXQ1VTRVJfR2V0Q2VsbChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgTFBBUkFNIGxQYXJhbSkKewogICAgQ09PUkQJYzsKCiAgICBjLlggPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YICsgKHNob3J0KUxPV09SRChsUGFyYW0pIC8gZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICBjLlkgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICsgKHNob3J0KUhJV09SRChsUGFyYW0pIC8gZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoKICAgIHJldHVybiBjOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdAogKgogKiBHZXQgdGhlIHNlbGVjdGlvbiByZWN0YW5nbGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBMUFJFQ1QgcikKewogICAgci0+bGVmdCAgID0gKG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICAgICkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPnRvcCAgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSAgICApICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwogICAgci0+cmlnaHQgID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpICsgMSkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPmJvdHRvbSA9IChtYXgoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSArIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0U2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0U2VsZWN0aW9uKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBIREMgaFJlZkRDKQp7CiAgICBIREMJCWhEQzsKICAgIFJFQ1QJcjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBoUmVmREMgPyBoUmVmREMgOiBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJaWYgKGhEQyAhPSBoUmVmREMpCgkgICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfTW92ZVNlbGVjdGlvbihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYzEsIENPT1JEIGMyLCBCT09MIGZpbmFsKQp7CiAgICBSRUNUCXI7CiAgICBIREMJCWhEQzsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwogICAgfQogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gYzE7CiAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBjMjsKICAgIGlmIChoREMpCiAgICB7CglXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9CiAgICBpZiAoZmluYWwpCiAgICB7CglSZWxlYXNlQ2FwdHVyZSgpOwoJUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQKICoKICogQ29waWVzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbnRvIHRoZSBjbGlwYm9hcmQKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhBTkRMRQloTWVtOwogICAgTFBXU1RSCXA7CiAgICB1bnNpZ25lZAl3LCBoOwoKICAgIHcgPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgKyAyOwogICAgaCA9IGFicyhQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSAtIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSArIDE7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBFbXB0eUNsaXBib2FyZCgpOwoKICAgIGhNZW0gPSBHbG9iYWxBbGxvYyhHTUVNX01PVkVBQkxFLCAodyAqIGggLSAxKSAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKGhNZW0gJiYgKHAgPSBHbG9iYWxMb2NrKGhNZW0pKSkKICAgIHsKCUNPT1JECWM7CglpbnQJeTsKCgljLlggPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YICsgbWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCk7CgljLlkgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICsgbWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSk7CgkKCWZvciAoeSA9IDA7IHkgPCBoOyB5KyssIGMuWSsrKQoJewoJICAgIFJlYWRDb25zb2xlT3V0cHV0Q2hhcmFjdGVyKGRhdGEtPmhDb25PdXQsICZwW3kgKiB3XSwgdyAtIDEsIGMsIE5VTEwpOwoJICAgIGlmICh5IDwgaCAtIDEpIHBbeSAqIHcgKyB3IC0gMV0gPSAnXG4nOwoJfQoJR2xvYmFsVW5sb2NrKGhNZW0pOwoJU2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCwgaE1lbSk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFzdGVGcm9tQ2xpcGJvYXJkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBIQU5ETEUJaDsKICAgIFdDSEFSKglwdHI7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBoID0gR2V0Q2xpcGJvYXJkRGF0YShDRl9VTklDT0RFVEVYVCk7CiAgICBpZiAoaCAmJiAocHRyID0gR2xvYmFsTG9jayhoKSkpCiAgICB7CglpbnQJCWksIGxlbiA9IEdsb2JhbFNpemUoaCkgLyBzaXplb2YoV0NIQVIpOwoJSU5QVVRfUkVDT1JECWlyWzJdOwoJRFdPUkQJCW47CglTSE9SVAkJc2g7CgoJaXJbMF0uRXZlbnRUeXBlID0gS0VZX0VWRU5UOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQud1JlcGVhdENvdW50ID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gMDsKCWlyWzBdLkV2ZW50LktleUV2ZW50LmJLZXlEb3duID0gVFJVRTsKCgkvKiBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBpbnB1dCByZWNvcmRzICovCglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCgl7CgkgICAgLyogRklYTUU6IHRoZSBtb2RpZnlpbmcga2V5cyBhcmUgbm90IGdlbmVyYXRlZCAoc2hpZnQsIGN0cmwuLi4pICovCgkgICAgc2ggPSBWa0tleVNjYW4ocHRyW2ldKTsKCSAgICBpclswXS5FdmVudC5LZXlFdmVudC53VmlydHVhbEtleUNvZGUgPSBMT0JZVEUoc2gpOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGUgPSBNYXBWaXJ0dWFsS2V5KExPQllURShzaCksIDApOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gcHRyW2ldOwoJICAgIAoJICAgIGlyWzFdID0gaXJbMF07CgkgICAgaXJbMV0uRXZlbnQuS2V5RXZlbnQuYktleURvd24gPSBGQUxTRTsKCSAgICAKCSAgICBXcml0ZUNvbnNvbGVJbnB1dChkYXRhLT5oQ29uSW4sIGlyLCAyLCAmbik7Cgl9CglHbG9iYWxVbmxvY2soaCk7CiAgICB9CiAgICBDbG9zZUNsaXBib2FyZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlSZWZyZXNoCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfUmVmcmVzaChjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHRwLCBpbnQgYm0pCnsKICAgIFdDVVNFUl9GaWxsTWVtREMoZGF0YSwgdHAsIGJtKTsKICAgIGlmIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIDw9IGJtICYmIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyBkYXRhLT5jdXJjZmcud2luX2hlaWdodCA+PSB0cCkKICAgIHsKCVJFQ1QJcjsKCglyLmxlZnQgICA9IDA7CglyLnJpZ2h0ICA9IGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKCXIudG9wICAgID0gKHRwIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CglyLmJvdHRvbSA9IChibSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCUludmFsaWRhdGVSZWN0KFBSSVZBVEUoZGF0YSktPmhXbmQsICZyLCBGQUxTRSk7CglVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYWludAogKgogKgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1BhaW50KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBQQUlOVFNUUlVDVAkJcHM7CgogICAgQmVnaW5QYWludChQUklWQVRFKGRhdGEpLT5oV25kLCAmcHMpOwogICAgQml0Qmx0KHBzLmhkYywgMCwgMCwgCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCAKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCSAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQywgCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCAKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LAoJICAgU1JDQ09QWSk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKCVdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgcHMuaGRjKTsKICAgIEVuZFBhaW50KFBSSVZBVEUoZGF0YSktPmhXbmQsICZwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TY3JvbGwKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9TY3JvbGwoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCBwb3MsIEJPT0wgaG9yeikKewogICAgaWYgKGhvcnopCiAgICB7CglTZXRTY3JvbGxQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKCWRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICB9CiAgICBlbHNlCiAgICB7CglTZXRTY3JvbGxQb3MoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCWRhdGEtPmN1cmNmZy53aW5fcG9zLlkgPSBwb3M7CiAgICB9CiAgICBJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCBOVUxMLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9GaWxsTWVudQogKgogKgogKi8Kc3RhdGljIEJPT0wgV0NVU0VSX0ZpbGxNZW51KEhNRU5VIGhNZW51LCBCT09MIHNlcCkKewogICAgSE1FTlUJCWhTdWJNZW51OwogICAgSElOU1RBTkNFCQloSW5zdGFuY2UgPSBHZXRNb2R1bGVIYW5kbGUoTlVMTCk7CiAgICBXQ0hBUgkJYnVmZlsyNTZdOwoKICAgIGlmICghaE1lbnUpIHJldHVybiBGQUxTRTsKCiAgICAvKiBGSVhNRTogZXJyb3IgaGFuZGxpbmcgJiBtZW1vcnkgY2xlYW51cCAqLwogICAgaFN1Yk1lbnUgPSBDcmVhdGVNZW51KCk7CiAgICBpZiAoIWhTdWJNZW51KSByZXR1cm4gRkFMU0U7CgogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19NQVJLLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX01BUkssIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19DT1BZLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX0NPUFksIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19QQVNURSwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19QQVNURSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NFTEVDVEFMTCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TRUxFQ1RBTEwsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TQ1JPTEwsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0NST0xMLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0VBUkNILCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NFQVJDSCwgYnVmZik7CgogICAgaWYgKHNlcCkgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU0VQQVJBVE9SLCAwLCBOVUxMKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfRURJVCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkd8TUZfUE9QVVAsIChVSU5UX1BUUiloU3ViTWVudSwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0RFRkFVTFQsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfREVGQVVMVCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1BST1BFUlRZLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BST1BFUlRZLCBidWZmKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NyZWF0ZQogKgogKiBDcmVhdGVzIHRoZSB3aW5kb3cgZm9yIHRoZSByZW5kZXJpbmcKICovCnN0YXRpYyBMUkVTVUxUIFdDVVNFUl9DcmVhdGUoSFdORCBoV25kLCBMUENSRUFURVNUUlVDVCBscGNzKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YTsKICAgIEhNRU5VCQloU3lzTWVudTsKCiAgICBkYXRhID0gbHBjcy0+bHBDcmVhdGVQYXJhbXM7CiAgICBTZXRXaW5kb3dMb25nKGhXbmQsIDBMLCAoRFdPUkQpZGF0YSk7CiAgICBQUklWQVRFKGRhdGEpLT5oV25kID0gaFduZDsKCiAgICBkYXRhLT5jdXJjZmcuY3Vyc29yX3NpemUgPSAxMDE7IC8qIGludmFsaWQgdmFsdWUsIHdpbGwgdHJpZ2dlciBhIGNvbXBsZXRlIGNsZWFudXAgKi8KCiAgICBoU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaFduZCwgRkFMU0UpOwogICAgaWYgKCFoU3lzTWVudSkgcmV0dXJuIDA7CiAgICBQUklWQVRFKGRhdGEpLT5oUG9wTWVudSA9IENyZWF0ZVBvcHVwTWVudSgpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oUG9wTWVudSkgcmV0dXJuIDA7CgogICAgV0NVU0VSX0ZpbGxNZW51KGhTeXNNZW51LCBUUlVFKTsKICAgIFdDVVNFUl9GaWxsTWVudShQUklWQVRFKGRhdGEpLT5oUG9wTWVudSwgRkFMU0UpOwoKICAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQyA9IENyZWF0ZUNvbXBhdGlibGVEQygwKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aE1lbURDKSB7V0lORV9FUlIoIm5vIG1lbSBkY1xuIik7cmV0dXJuIDA7fQoKICAgIGRhdGEtPmN1cmNmZy5xdWlja19lZGl0ID0gRkFMU0U7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldE1lbnVEZXRhaWxzCiAqCiAqIEdyYXlzIC8gdW5ncmF5cyB0aGUgbWVudSBpdGVtcyBhY2NvcmRpbmcgdG8gdGhlaXIgc3RhdGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRNZW51RGV0YWlscyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgSE1FTlUgaE1lbnUpCnsKICAgIGlmICghaE1lbnUpIHtXSU5FX0VSUigiSXNzdWUgaW4gZ2V0dGluZyBtZW51IGJpdHNcbiIpO3JldHVybjt9CgogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19DT1BZLCAKICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORHwoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA/IE1GX0VOQUJMRUQgOiBNRl9HUkFZRUQpKTsKICAgIEVuYWJsZU1lbnVJdGVtKGhNZW51LCBJRFNfUEFTVEUsIAoJCSAgIE1GX0JZQ09NTUFORHwoSXNDbGlwYm9hcmRGb3JtYXRBdmFpbGFibGUoQ0ZfVU5JQ09ERVRFWFQpIAoJCQkJID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCkpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TQ1JPTEwsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwogICAgRW5hYmxlTWVudUl0ZW0oaE1lbnUsIElEU19TRUFSQ0gsIE1GX0JZQ09NTUFORHxNRl9HUkFZRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDVVNFUl9HZXRDdHJsS2V5U3RhdGUKICoKICogR2V0IHRoZSBjb25zb2xlIGJpdCBtYXNrIGVxdWl2YWxlbnQgdG8gdGhlIFZLXyBzdGF0dXMgaW4ga2V5U3RhdGUKICovCnN0YXRpYyBEV09SRCAgICBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKEJZVEUqIGtleVN0YXRlKQp7CiAgICBEV09SRCAgICAgICAgICAgICAgIHJldCA9IDA7CgogICAgR2V0S2V5Ym9hcmRTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAoa2V5U3RhdGVbVktfU0hJRlRdICAgICYgMHg4MCkJcmV0IHw9IFNISUZUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfQ09OVFJPTF0gICYgMHg4MCkJcmV0IHw9IExFRlRfQ1RSTF9QUkVTU0VEOyAvKiBGSVhNRTogZ290dGEgY2hvb3NlIG9uZSAqLwogICAgaWYgKGtleVN0YXRlW1ZLX0xDT05UUk9MXSAmIDB4ODApCXJldCB8PSBMRUZUX0NUUkxfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19SQ09OVFJPTF0gJiAweDgwKQlyZXQgfD0gUklHSFRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0xNRU5VXSAgICAmIDB4ODApCXJldCB8PSBMRUZUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JNRU5VXSAgICAmIDB4ODApCXJldCB8PSBSSUdIVF9BTFRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19DQVBJVEFMXSAgJiAweDAxKQlyZXQgfD0gQ0FQU0xPQ0tfT047CSAgICAKICAgIGlmIChrZXlTdGF0ZVtWS19OVU1MT0NLXSAgJiAweDAxKQlyZXQgfD0gTlVNTE9DS19PTjsKICAgIGlmIChrZXlTdGF0ZVtWS19TQ1JPTExdICAgJiAweDAxKQlyZXQgfD0gU0NST0xMTE9DS19PTjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleQogKgogKiBIYW5kbGVzIGtleXMgd2hpbGUgc2VsZWN0aW5nIGFuIGFyZWEKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQllURQlrZXlTdGF0ZVsyNTZdOwogICAgRFdPUkQgICAgICAgc3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKSAmIH4oQ0FQU0xPQ0tfT058TlVNTE9DS19PTnxTQ1JPTExMT0NLX09OKTsKICAgIENPT1JEICAgICAgIGMxLCBjMjsKCiAgICBpZiAoZG93bikgcmV0dXJuOwoKICAgIHN3aXRjaCAoc3RhdGUpCiAgICB7CiAgICBjYXNlIDA6CiAgICAgICAgc3dpdGNoICh3UGFyYW0pCiAgICAgICAgewogICAgICAgIGNhc2UgVktfUkVUVVJOOgogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIFdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfUklHSFQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWCsrOyBjMi5YKys7CiAgICAgICAgICAgIGlmIChjMS5YIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoICYmIGMyLlggPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMS5YLS07IGMyLlgtLTsKICAgICAgICAgICAgaWYgKGMxLlggPj0gMCAmJiBjMi5YID49IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWS0tOyBjMi5ZLS07CiAgICAgICAgICAgIGlmIChjMS5ZID49IDAgJiYgYzIuWSA+PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWSsrOyBjMi5ZKys7CiAgICAgICAgICAgIGlmIChjMS5YIDwgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAmJiBjMi5YIDwgZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBTSElGVF9QUkVTU0VEOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JJR0hUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlgrKzsKICAgICAgICAgICAgaWYgKGMyLlggPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfTEVGVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YLS07CiAgICAgICAgICAgIGlmIChjMi5YID49IGMxLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVktfVVA6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWS0tOwogICAgICAgICAgICBpZiAoYzIuWSA+PSBjMS5ZKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0RPV046CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWSsrOwogICAgICAgICAgICBpZiAoYzIuWCA8IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQKICoKICogZ2VuZXJhdGVzIGlucHV0X3JlY29yZCBmcm9tIHdpbmRvd3MgV01fS0VZVVAvV01fS0VZRE9XTiBtZXNzYWdlcwogKi8Kc3RhdGljIHZvaWQgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZG93biwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgc3lzKQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBEV09SRAkJbjsKICAgIFdDSEFSCQlidWZbMl07CiAgICBzdGF0aWMJV0NIQVIJbGFzdDsgLyoga2VlcCBsYXN0IGNoYXIgc2VlbiBhcyBmZWVkIGZvciBrZXkgdXAgbWVzc2FnZSAqLwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKCiAgICBpci5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CiAgICBpci5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IGRvd247CiAgICBpci5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSBMT1dPUkQobFBhcmFtKTsKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IHdQYXJhbTsKICAgIAogICAgaXIuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZSA9IEhJV09SRChsUGFyYW0pICYgMHhGRjsKICAgIAogICAgaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSAwOwogICAgaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChsUGFyYW0gJiAoMUwgPDwgMjQpKQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gRU5IQU5DRURfS0VZOwogICAgaWYgKHN5cykJCQkJaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgfD0gTEVGVF9BTFRfUFJFU1NFRDsgLyogRklYTUU6IGdvdHRhIGNob29zZSBvbmUgKi8KCiAgICBpZiAoIShpci5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkpCiAgICB7CglpZiAoZG93bikKCXsKCSAgICBzd2l0Y2ggKFRvVW5pY29kZSh3UGFyYW0sIEhJV09SRChsUGFyYW0pLCBrZXlTdGF0ZSwgYnVmLCAyLCAwKSkKCSAgICB7CgkgICAgY2FzZSAyOgoJCS8qIEZJWE1FLi4uIHNob3VsZCBnZW5lcmF0ZSB0d28gZXZlbnRzLi4uICovCgkJLyogZmFsbCB0aHJ1ICovCgkgICAgY2FzZSAxOgkKCQlsYXN0ID0gYnVmWzBdOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJbGFzdCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQoJaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBsYXN0OyAvKiBGSVhNRSBIQUNLWS4uLiBhbmQgYnVnZ3kgJ2NveiBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIERXT1JEIGV2ZW50KQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBCWVRFCQlrZXlTdGF0ZVsyNTZdOwogICAgRFdPUkQgICAgICAgICAgICAgICBtb2RlLCBuOwoKICAgIC8qIE1PVVNFX0VWRU5UcyBzaG91bGRuJ3QgYmUgc2VudCB1bmxlc3MgRU5BQkxFX01PVVNFX0lOUFVUIGlzIGFjdGl2ZSAqLwogICAgaWYgKCFHZXRDb25zb2xlTW9kZShkYXRhLT5oQ29uSW4sICZtb2RlKSB8fCAhKG1vZGUgJiBFTkFCTEVfTU9VU0VfSU5QVVQpKQogICAgICAgIHJldHVybjsKCiAgICBpci5FdmVudFR5cGUgPSBNT1VTRV9FVkVOVDsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdNb3VzZVBvc2l0aW9uID0gYzsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdCdXR0b25TdGF0ZSA9IDA7CiAgICBpZiAod1BhcmFtICYgTUtfTEJVVFRPTikgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlIHw9IEZST01fTEVGVF8xU1RfQlVUVE9OX1BSRVNTRUQ7CiAgICBpZiAod1BhcmFtICYgTUtfTUJVVFRPTikgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlIHw9IEZST01fTEVGVF8yTkRfQlVUVE9OX1BSRVNTRUQ7CiAgICBpZiAod1BhcmFtICYgTUtfUkJVVFRPTikgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlIHw9IFJJR0hUTU9TVF9CVVRUT05fUFJFU1NFRDsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSBXQ1VTRVJfR2V0Q3RybEtleVN0YXRlKGtleVN0YXRlKTsKICAgIGlyLkV2ZW50Lk1vdXNlRXZlbnQuZHdFdmVudEZsYWdzID0gZXZlbnQ7CgogICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCAmaXIsIDEsICZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1Byb2MKICoKICoKICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIFdDVVNFUl9Qcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgaW5uZXJfZGF0YSoJZGF0YSA9IChzdHJ1Y3QgaW5uZXJfZGF0YSopR2V0V2luZG93TG9uZyhoV25kLCAwKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICByZXR1cm4gV0NVU0VSX0NyZWF0ZShoV25kLCAoTFBDUkVBVEVTVFJVQ1QpbFBhcmFtKTsKICAgIGNhc2UgV01fREVTVFJPWToKCVBSSVZBVEUoZGF0YSktPmhXbmQgPSAwOwoJUG9zdFF1aXRNZXNzYWdlKDApOwoJYnJlYWs7CiAgICBjYXNlIFdNX1BBSU5UOgoJV0NVU0VSX1BhaW50KGRhdGEpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICBXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5KGRhdGEsIHVNc2cgPT0gV01fS0VZRE9XTiwgd1BhcmFtLCBsUGFyYW0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgRkFMU0UpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NZU0tFWURPV046CiAgICBjYXNlIFdNX1NZU0tFWVVQOgoJV0NVU0VSX0dlbmVyYXRlS2V5SW5wdXRSZWNvcmQoZGF0YSwgdU1zZyA9PSBXTV9TWVNLRVlET1dOLCB3UGFyYW0sIGxQYXJhbSwgVFJVRSk7CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTkRPV046CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBGQUxTRTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pOwogICAgICAgICAgICAgICAgU2V0Q2FwdHVyZShQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9TZXRTZWxlY3Rpb24oZGF0YSwgMCk7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIAogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKGRhdGEtPmN1cmNmZy5xdWlja19lZGl0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBQUklWQVRFKGRhdGEpLT5oV25kICYmIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gJiYKICAgICAgICAgICAgICAgICh3UGFyYW0gJiBNS19MQlVUVE9OKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX01PVkVEKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fTEJVVFRPTlVQOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gUFJJVkFURShkYXRhKS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uICYmIAogICAgICAgICAgICAgICAgKHdQYXJhbSYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgVFJVRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9SQlVUVE9ORE9XTjoKICAgICAgICBpZiAoKHdQYXJhbSAmIChNS19DT05UUk9MfE1LX1NISUZUKSkgPT0gZGF0YS0+Y3VyY2ZnLm1lbnVfbWFzaykKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgICAgICAgIHI7CgogICAgICAgICAgICBHZXRXaW5kb3dSZWN0KGhXbmQsICZyKTsKICAgICAgICAgICAgV0NVU0VSX1NldE1lbnVEZXRhaWxzKGRhdGEsIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51KTsKICAgICAgICAgICAgVHJhY2tQb3B1cE1lbnUoUFJJVkFURShkYXRhKS0+aFBvcE1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1RPUEFMSUdOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgci5sZWZ0ICsgTE9XT1JEKGxQYXJhbSksIHIudG9wICsgSElXT1JEKGxQYXJhbSksIDAsIGhXbmQsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVNb3VzZUlucHV0UmVjb3JkKGRhdGEsIFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSksIHdQYXJhbSwgMCk7CiAgICAgICAgfQoJYnJlYWs7ICAgIAogICAgY2FzZSBXTV9SQlVUVE9OVVA6CiAgICAgICAgLyogbm8gbmVlZCB0byB0cmFjayBmb3IgcmJ1dHRvbiB1cCB3aGVuIG9wZW5pbmcgdGhlIHBvcHVwLi4uIHRoZSBldmVudCB3aWxsIGJlCiAgICAgICAgICogc3dhbGxvd2VkIGJ5IFRyYWNrUG9wdXBNZW51ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwoJYnJlYWs7ICAgIAogICAgY2FzZSBXTV9NT1VTRVdIRUVMOgogICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc2Nyb2xsIHRvbyA/ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7ICAgIAogICAgY2FzZSBXTV9TRVRGT0NVUzoKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgl7CgkgICAgQ3JlYXRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCwgUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQpOyAKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOyAKICAgIGNhc2UgV01fS0lMTEZPQ1VTOiAKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCgkgICAgRGVzdHJveUNhcmV0KCk7IAoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6IAogICAgICAgIHsKICAgICAgICAgICAgaW50CXBvcyA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlg7CgogICAgICAgICAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKSAKICAgICAgICAgICAgeyAKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsgCiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsgCiAgICAgICAgICAgIGNhc2UgU0JfTElORVVQOiAJcG9zLS07CQkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfTElORURPV046IAlwb3MrKzsJIAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfVEhVTUJUUkFDSzogcG9zID0gSElXT1JEKHdQYXJhbSk7CWJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiAJCQkJCWJyZWFrOwogICAgICAgICAgICB9IAogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpIAogICAgICAgICAgICAgICAgcG9zID0gZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIC0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aDsKICAgICAgICAgICAgaWYgKHBvcyAhPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTY3JvbGxXaW5kb3coaFduZCwgKGRhdGEtPmN1cmNmZy53aW5fcG9zLlggLSBwb3MpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCA9IHBvczsKICAgICAgICAgICAgICAgIFNldFNjcm9sbFBvcyhoV25kLCBTQl9IT1JaLCBwb3MsIFRSVUUpOyAKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsgCiAgICAgICAgICAgICAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwogICAgICAgICAgICAgICAgV0lORUNPTl9Ob3RpZnlXaW5kb3dDaGFuZ2UoZGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fVlNDUk9MTDogCiAgICAgICAgewoJICAgIGludAlwb3MgPSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZOwoKCSAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKSAKCSAgICB7IAogICAgICAgICAgICBjYXNlIFNCX1BBR0VVUDogCXBvcyAtPSA4OyAJCWJyZWFrOyAKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOyAKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9IAoJICAgIGlmIChwb3MgPCAwKSBwb3MgPSAwOwoJICAgIGlmIChwb3MgPiBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQpIAogICAgICAgICAgICAgICAgcG9zID0gZGF0YS0+Y3VyY2ZnLnNiX2hlaWdodCAtIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0OwoJICAgIGlmIChwb3MgIT0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSkKCSAgICB7CgkJU2Nyb2xsV2luZG93KGhXbmQsIDAsIChkYXRhLT5jdXJjZmcud2luX3Bvcy5ZIC0gcG9zKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsgCgkJVXBkYXRlV2luZG93KGhXbmQpOyAKCQlXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJCVdJTkVDT05fTm90aWZ5V2luZG93Q2hhbmdlKGRhdGEpOwoJICAgIH0KCiAgICAgICAgfSAKICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUWToKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBUUlVFKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6IAoJICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCX0KCWJyZWFrOwogICAgY2FzZSBXTV9DT01NQU5EOgoJc3dpdGNoICh3UGFyYW0pCgl7CgljYXNlIElEU19ERUZBVUxUOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIEZBTFNFKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1BST1BFUlRZOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAleFxuIiwgd1BhcmFtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6IAoJICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCX0KCWJyZWFrOwogICAgY2FzZSBXTV9JTklUTUVOVVBPUFVQOgoJaWYgKCFISVdPUkQobFBhcmFtKSkJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJV0NVU0VSX1NldE1lbnVEZXRhaWxzKGRhdGEsIEdldFN5c3RlbU1lbnUoUFJJVkFURShkYXRhKS0+aFduZCwgRkFMU0UpKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXJldHVybiBEZWZXaW5kb3dQcm9jKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRGVsZXRlQmFja2VuZAogKgogKgogKi8Kdm9pZCBXQ1VTRVJfRGVsZXRlQmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgaWYgKCFQUklWQVRFKGRhdGEpKSByZXR1cm47CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aE1lbURDKQkJRGVsZXRlREMoUFJJVkFURShkYXRhKS0+aE1lbURDKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oV25kKQkJRGVzdHJveVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oRm9udCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXApOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhCaXRtYXApCQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBQUklWQVRFKGRhdGEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX01haW5Mb29wCiAqCiAqCiAqLwpzdGF0aWMgaW50IFdDVVNFUl9NYWluTG9vcChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgTVNHCQltc2c7CgogICAgZm9yICg7OykgCiAgICB7Cglzd2l0Y2ggKE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMSwgJmRhdGEtPmhTeW5jaHJvLCBGQUxTRSwgSU5GSU5JVEUsIFFTX0FMTElOUFVUKSkKCXsKCWNhc2UgV0FJVF9PQkpFQ1RfMDoKCSAgICBpZiAoIVdJTkVDT05fR3JhYkNoYW5nZXMoZGF0YSkgJiYgZGF0YS0+Y3VyY2ZnLmV4aXRfb25fZGllKQogICAgICAgICAgICAgICAgUG9zdFF1aXRNZXNzYWdlKDApOwoJICAgIGJyZWFrOwoJY2FzZSBXQUlUX09CSkVDVF8wKzE6CgkgICAgc3dpdGNoIChHZXRNZXNzYWdlKCZtc2csIDAsIDAsIDApKQoJICAgIHsKCSAgICBjYXNlIC0xOiAvKiB0aGUgZXZlbnQgaGFuZGxlIGJlY2FtZSBpbnZhbGlkLCBzbyBleGl0ICovCgkJcmV0dXJuIC0xOwoJICAgIGNhc2UgMDogLyogV01fUVVJVCBoYXMgYmVlbiBwb3N0ZWQgKi8KCQlyZXR1cm4gMDsKCSAgICBkZWZhdWx0OgoJCURpc3BhdGNoTWVzc2FnZSgmbXNnKTsKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIFdJTkVfRVJSKCJnb3QgcGJcbiIpOwoJICAgIC8qIGVyciAqLwoJICAgIGJyZWFrOwoJfQogICAgfQkKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0luaXRCYWNrZW5kCiAqCiAqIEluaXRpYWxpc2F0aW9uIHBhcnQgSUk6IGNyZWF0aW9uIG9mIHdpbmRvdy4KICoKICovCkJPT0wgV0NVU0VSX0luaXRCYWNrZW5kKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBzdGF0aWMgV0NIQVIgd0NsYXNzTmFtZVtdID0geydXJywnaScsJ24nLCdlJywnQycsJ28nLCduJywncycsJ28nLCdsJywnZScsJ0MnLCdsJywnYScsJ3MnLCdzJywwfTsKCiAgICBXTkRDTEFTUwkJd25kY2xhc3M7CgogICAgZGF0YS0+cHJpdmF0ZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2Yoc3RydWN0IGlubmVyX2RhdGFfdXNlcikpOwogICAgaWYgKCFkYXRhLT5wcml2YXRlKSByZXR1cm4gRkFMU0U7CgogICAgZGF0YS0+Zm5NYWluTG9vcCA9IFdDVVNFUl9NYWluTG9vcDsKICAgIGRhdGEtPmZuUG9zQ3Vyc29yID0gV0NVU0VSX1Bvc0N1cnNvcjsKICAgIGRhdGEtPmZuU2hhcGVDdXJzb3IgPSBXQ1VTRVJfU2hhcGVDdXJzb3I7CiAgICBkYXRhLT5mbkNvbXB1dGVQb3NpdGlvbnMgPSBXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9uczsKICAgIGRhdGEtPmZuUmVmcmVzaCA9IFdDVVNFUl9SZWZyZXNoOwogICAgZGF0YS0+Zm5SZXNpemVTY3JlZW5CdWZmZXIgPSBXQ1VTRVJfUmVzaXplU2NyZWVuQnVmZmVyOwogICAgZGF0YS0+Zm5TZXRUaXRsZSA9IFdDVVNFUl9TZXRUaXRsZTsKICAgIGRhdGEtPmZuU2Nyb2xsID0gV0NVU0VSX1Njcm9sbDsKICAgIGRhdGEtPmZuRGVsZXRlQmFja2VuZCA9IFdDVVNFUl9EZWxldGVCYWNrZW5kOwoKICAgIHduZGNsYXNzLnN0eWxlICAgICAgICAgPSAwOwogICAgd25kY2xhc3MubHBmblduZFByb2MgICA9IFdDVVNFUl9Qcm9jOwogICAgd25kY2xhc3MuY2JDbHNFeHRyYSAgICA9IDA7CiAgICB3bmRjbGFzcy5jYlduZEV4dHJhICAgID0gc2l6ZW9mKERXT1JEKTsKICAgIHduZGNsYXNzLmhJbnN0YW5jZSAgICAgPSBHZXRNb2R1bGVIYW5kbGUoTlVMTCk7CiAgICB3bmRjbGFzcy5oSWNvbiAgICAgICAgID0gTG9hZEljb24oMCwgSURJX1dJTkxPR08pOwogICAgd25kY2xhc3MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3IoMCwgSURDX0FSUk9XKTsKICAgIHduZGNsYXNzLmhickJhY2tncm91bmQgPSBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCk7CiAgICB3bmRjbGFzcy5scHN6TWVudU5hbWUgID0gTlVMTDsKICAgIHduZGNsYXNzLmxwc3pDbGFzc05hbWUgPSB3Q2xhc3NOYW1lOwogIAogICAgUmVnaXN0ZXJDbGFzcygmd25kY2xhc3MpOwoKICAgIENyZWF0ZVdpbmRvdyh3bmRjbGFzcy5scHN6Q2xhc3NOYW1lLCBOVUxMLAoJCSBXU19PVkVSTEFQUEVEfFdTX0NBUFRJT058V1NfU1lTTUVOVXxXU19USElDS0ZSQU1FfFdTX01JTklNSVpFQk9YfFdTX0hTQ1JPTEx8V1NfVlNDUk9MTCwgCgkJIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIDAsIDAsIDAsIDAsIHduZGNsYXNzLmhJbnN0YW5jZSwgZGF0YSk7ICAgCiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhXbmQpIHJldHVybiBGQUxTRTsKCiAgICAvKiBmb3JjZSB1cGRhdGUgb2YgY3VycmVudCBkYXRhICovCiAgICBpZiAoIVdJTkVDT05fR3JhYkNoYW5nZXMoZGF0YSkpIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIVdDVVNFUl9Jbml0Rm9udChkYXRhKSkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwp9Cgo=