LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAibWVkaWFvYmouaCIKI2luY2x1ZGUgImRtb3J0LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNb0NyZWF0ZU1lZGlhVHlwZQkoTVNETU8uQCkKICovCkhSRVNVTFQgV0lOQVBJIE1vQ3JlYXRlTWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiogcHBtZWRpYSwgRFdPUkQgY2JGb3JtYXQpCnsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsdSlcbiIsIHBwbWVkaWEsIGNiRm9ybWF0KTsKCiAgaWYgKHBwbWVkaWEgPT0gTlVMTCkKICAgIHJldHVybiBFX1BPSU5URVI7CgogICpwcG1lZGlhID0gQ29UYXNrTWVtQWxsb2Moc2l6ZW9mKERNT19NRURJQV9UWVBFKSk7CiAgaWYgKCpwcG1lZGlhID09IE5VTEwpCiAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgaHIgPSBNb0luaXRNZWRpYVR5cGUoKnBwbWVkaWEsIGNiRm9ybWF0KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgQ29UYXNrTWVtRnJlZSgqcHBtZWRpYSk7CiAgICAqcHBtZWRpYSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTW9Jbml0TWVkaWFUeXBlCQkoTVNETU8uQCkKICovCkhSRVNVTFQgV0lOQVBJIE1vSW5pdE1lZGlhVHlwZShETU9fTUVESUFfVFlQRSogcG1lZGlhLCBEV09SRCBjYkZvcm1hdCkKewogIFRSQUNFKCIoJXAsJWx1KVxuIiwgcG1lZGlhLGNiRm9ybWF0KTsKCiAgaWYgKHBtZWRpYSA9PSBOVUxMKQogICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgbWVtc2V0KHBtZWRpYSwgMCwgc2l6ZW9mKERNT19NRURJQV9UWVBFKSk7CgogIGlmIChjYkZvcm1hdCA+IDApIHsKICAgIHBtZWRpYS0+cGJGb3JtYXQgPSBDb1Rhc2tNZW1BbGxvYyhjYkZvcm1hdCk7CiAgICBpZiAocG1lZGlhLT5wYkZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBwbWVkaWEtPmNiRm9ybWF0ID0gY2JGb3JtYXQ7CiAgfQoKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNb0RlbGV0ZU1lZGlhVHlwZQkoTVNETU8uQCkKICovCkhSRVNVTFQgV0lOQVBJIE1vRGVsZXRlTWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiBwbWVkaWEpCnsKICBUUkFDRSgiKCVwKVxuIiwgcG1lZGlhKTsKCiAgaWYgKHBtZWRpYSA9PSBOVUxMKQogICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgTW9GcmVlTWVkaWFUeXBlKHBtZWRpYSk7CiAgQ29UYXNrTWVtRnJlZShwbWVkaWEpOwoKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNb0ZyZWVNZWRpYVR5cGUJCShNU0RNTy5AKQogKi8KSFJFU1VMVCBXSU5BUEkgTW9GcmVlTWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiBwbWVkaWEpCnsKICBUUkFDRSgiKCVwKVxuIiwgcG1lZGlhKTsKCiAgaWYgKHBtZWRpYSA9PSBOVUxMKQogICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgaWYgKHBtZWRpYS0+cFVuayAhPSBOVUxMKSB7CiAgICBJVW5rbm93bl9SZWxlYXNlKHBtZWRpYS0+cFVuayk7CiAgICBwbWVkaWEtPnBVbmsgPSBOVUxMOwogIH0KCiAgaWYgKHBtZWRpYS0+cGJGb3JtYXQgIT0gTlVMTCkgewogICAgQ29UYXNrTWVtRnJlZShwbWVkaWEtPnBiRm9ybWF0KTsKICAgIHBtZWRpYS0+cGJGb3JtYXQgPSBOVUxMOwogIH0KCiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTW9EdXBsaWNhdGVNZWRpYVR5cGUJKE1TRE1PLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0R1cGxpY2F0ZU1lZGlhVHlwZShETU9fTUVESUFfVFlQRSoqIHBwZHN0LAoJCQkJICAgIGNvbnN0IERNT19NRURJQV9UWVBFKiBwc3JjKQp7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBwZHN0LCBwc3JjKTsKCiAgaWYgKHBwZHN0ID09IE5VTEwgfHwgcHNyYyA9PSBOVUxMKQogICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgKnBwZHN0ID0gQ29UYXNrTWVtQWxsb2Moc2l6ZW9mKERNT19NRURJQV9UWVBFKSk7CiAgaWYgKCpwcGRzdCA9PSBOVUxMKQogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogIGhyID0gTW9Db3B5TWVkaWFUeXBlKCpwcGRzdCwgcHNyYyk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIE1vRnJlZU1lZGlhVHlwZSgqcHBkc3QpOwogICAgKnBwZHN0ID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNb0NvcHlNZWRpYVR5cGUJCShNU0RNTy5AKQogKi8KSFJFU1VMVCBXSU5BUEkgTW9Db3B5TWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiBwZHN0LAoJCQkgICAgICAgY29uc3QgRE1PX01FRElBX1RZUEUqIHBzcmMpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgcGRzdCwgcHNyYyk7CgogIGlmIChwZHN0ID09IE5VTEwgfHwgcHNyYyA9PSBOVUxMKQogICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgbWVtY3B5KCZwZHN0LT5tYWpvcnR5cGUsICAmcHNyYy0+bWFqb3J0eXBlLCAgc2l6ZW9mKHBzcmMtPm1ham9ydHlwZSkpOwogIG1lbWNweSgmcGRzdC0+c3VidHlwZSwgICAgJnBzcmMtPnN1YnR5cGUsICAgIHNpemVvZihwc3JjLT5zdWJ0eXBlKSk7CiAgbWVtY3B5KCZwZHN0LT5mb3JtYXR0eXBlLCAmcHNyYy0+Zm9ybWF0dHlwZSwgc2l6ZW9mKHBzcmMtPmZvcm1hdHR5cGUpKTsKCiAgcGRzdC0+YkZpeGVkU2l6ZVNhbXBsZXMgICAgPSBwc3JjLT5iRml4ZWRTaXplU2FtcGxlczsKICBwZHN0LT5iVGVtcG9yYWxDb21wcmVzc2lvbiA9IHBzcmMtPmJUZW1wb3JhbENvbXByZXNzaW9uOwogIHBkc3QtPmxTYW1wbGVTaXplICAgICAgICAgID0gcHNyYy0+bFNhbXBsZVNpemU7CiAgcGRzdC0+Y2JGb3JtYXQgICAgICAgICAgICAgPSBwc3JjLT5jYkZvcm1hdDsKCiAgaWYgKHBzcmMtPnBiRm9ybWF0ICE9IE5VTEwgJiYgcHNyYy0+Y2JGb3JtYXQgPiAwKSB7CiAgICBwZHN0LT5wYkZvcm1hdCA9IENvVGFza01lbUFsbG9jKHBzcmMtPmNiRm9ybWF0KTsKICAgIGlmIChwZHN0LT5wYkZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBtZW1jcHkocGRzdC0+cGJGb3JtYXQsIHBzcmMtPnBiRm9ybWF0LCBwc3JjLT5jYkZvcm1hdCk7CiAgfSBlbHNlCiAgICBwZHN0LT5wYkZvcm1hdCA9IE5VTEw7CgogIGlmIChwc3JjLT5wVW5rICE9IE5VTEwpIHsKICAgIHBkc3QtPnBVbmsgPSBwc3JjLT5wVW5rOwogICAgSVVua25vd25fQWRkUmVmKHBkc3QtPnBVbmspOwogIH0gZWxzZQogICAgcGRzdC0+cFVuayA9IE5VTEw7CgogIHJldHVybiBTX09LOwp9Cg==