LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2RlZmluZSBDT01fTk9fV0lORE9XU19ICiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgImRtby5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT1Jvb3RLZXlbXSA9IAp7CiAgICAnRCcsJ2knLCdyJywnZScsJ2MnLCd0JywnUycsJ2gnLCdvJywndycsJ1xcJywKICAgICdNJywnZScsJ2QnLCdpJywnYScsJ08nLCdiJywnaicsJ2UnLCdjJywndCcsJ3MnLDAKfTsgCgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9JbnB1dFR5cGVbXSA9CnsKICAgICdJJywnbicsJ3AnLCd1JywndCcsJ1QnLCd5JywncCcsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pETU9PdXRwdXRUeXBlW10gPQp7CiAgICAnTycsJ3UnLCd0JywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0tleWVkW10gPQp7CiAgICAnSycsJ2UnLCd5JywnZScsJ2QnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0NhdGVnb3JpZXNbXSA9CnsKICAgICdDJywnYScsJ3QnLCdlJywnZycsJ28nLCdyJywnaScsJ2UnLCdzJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pHVUlERm10W10gPQp7CiAgICAnJScsJzAnLCc4JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLAogICAgJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0M0ZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekNhdDJGbXRbXSA9CnsKICAgICclJywncycsJ1xcJywnJScsJ3MnLDAKfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIElFbnVtRE1PVnRibCAgICAgICAgICAgICAgICpscFZ0Ymw7CiAgICBEV09SRAkJCXJlZjsKICAgIERXT1JECQkJaW5kZXg7CiAgICBjb25zdCBHVUlEKiAgICAgICAgICAgICAgICAgZ3VpZENhdGVnb3J5OwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIGR3RmxhZ3M7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY0luVHlwZXM7CiAgICBETU9fUEFSVElBTF9NRURJQVRZUEUgICAgICAgKnBJblR5cGVzOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIGNPdXRUeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcE91dFR5cGVzOwogICAgSEtFWSAgICAgICAgICAgICAgICAgICAgICAgIGhrZXk7Cn0gSUVudW1ETU9JbXBsOwoKY29uc3QgR1VJRCBJSURfSUVudW1ETU8gPSB7IDB4MmMzY2Q5OGEsIDB4MmJmYSwgMHg0YTUzLAogICAgeyAweDljLCAweDI3LCAweDUyLCAweDQ5LCAweGJhLCAweDY0LCAweGJhLCAweDBmfX07CgpzdGF0aWMgc3RydWN0IElFbnVtRE1PVnRibCBlZG1vdnQ7CgpzdGF0aWMgTFBXU1RSIEdVSURUb1N0cmluZyhMUFdTVFIgbHB3c3RyLCBSRUZHVUlEIGxwY2d1aWQpCnsKICAgIHdzcHJpbnRmVyhscHdzdHIsIHN6R1VJREZtdCwgbHBjZ3VpZC0+RGF0YTEsIGxwY2d1aWQtPkRhdGEyLAogICAgICAgIGxwY2d1aWQtPkRhdGEzLCBscGNndWlkLT5EYXRhNFswXSwgbHBjZ3VpZC0+RGF0YTRbMV0sCiAgICAgICAgbHBjZ3VpZC0+RGF0YTRbMl0sIGxwY2d1aWQtPkRhdGE0WzNdLCBscGNndWlkLT5EYXRhNFs0XSwKICAgICAgICBscGNndWlkLT5EYXRhNFs1XSwgbHBjZ3VpZC0+RGF0YTRbNl0sIGxwY2d1aWQtPkRhdGE0WzddKTsKCiAgICByZXR1cm4gbHB3c3RyOwp9CgpzdGF0aWMgQk9PTCBJc01lZGlhVHlwZUVxdWFsKERNT19QQVJUSUFMX01FRElBVFlQRSogbXQxLCBETU9fUEFSVElBTF9NRURJQVRZUEUqIG10MikKewoKICAgIHJldHVybiAoSXNFcXVhbENMU0lEKCZtdDEtPnR5cGUsICZtdDItPnR5cGUpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQyLT50eXBlLCAmR1VJRF9OVUxMKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10MS0+dHlwZSwgJkdVSURfTlVMTCkpICYmCiAgICAgICAgICAgIChJc0VxdWFsQ0xTSUQoJm10MS0+c3VidHlwZSwgJm10Mi0+c3VidHlwZSkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDItPnN1YnR5cGUsICZHVUlEX05VTEwpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQxLT5zdWJ0eXBlLCAmR1VJRF9OVUxMKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PUmVnaXN0ZXIKICoKICogUmVnaXN0ZXIgYSBEaXJlY3RYIE1lZGlhIE9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIERNT1JlZ2lzdGVyKAogICBMUENXU1RSIHN6TmFtZSwKICAgUkVGQ0xTSUQgY2xzaWRETU8sCiAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICBEV09SRCBkd0ZsYWdzLAogICBEV09SRCBjSW5UeXBlcywKICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgRFdPUkQgY091dFR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcwopCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBIS0VZIGhja2V5ID0gMDsKICAgIEhLRVkgaGNsc2tleSA9IDA7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIC8qIENyZWF0ZSBjbHNpZERNTyBrZXkgdW5kZXIgTWVkaWFPYmplY3RzICovIAogICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4VyhocmtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoa2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIC8qIFNldCBkZWZhdWx0IE5hbWUgdmFsdWUgKi8KICAgIGhyZXMgPSBSZWdTZXRWYWx1ZUV4Vyhoa2V5LCBOVUxMLCAwLCBSRUdfU1osIChMUEJZVEUpIHN6TmFtZSwgCiAgICAgICAgKHN0cmxlblcoc3pOYW1lKSArIDEpKSAqIHNpemVvZihXQ0hBUik7CiAgICAvKiBTZXQgSW5wdXRUeXBlcyAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIHN6RE1PSW5wdXRUeXBlLCAwLCBSRUdfQklOQVJZLCAKICAgICAgICAoTFBCWVRFKSBwSW5UeXBlcywgY0luVHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSk7CiAgICAvKiBTZXQgT3V0cHV0VHlwZXMgKi8KICAgIGhyZXMgPSBSZWdTZXRWYWx1ZUV4Vyhoa2V5LCBzekRNT091dHB1dFR5cGUsIDAsIFJFR19CSU5BUlksIAogICAgICAgIChMUEJZVEUpIHBPdXRUeXBlcywgY091dFR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSkpOwoKICAgIGlmIChkd0ZsYWdzICYgRE1PX1JFR0lTVEVSRl9JU19LRVlFRCkKICAgIHsKICAgICAgICAvKiBDcmVhdGUgS2V5ZWQga2V5ICovIAogICAgICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgc3pETU9LZXllZCwgMCwgTlVMTCwKICAgICAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhja2V5LCBOVUxMKTsKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICBnb3RvIGxlbmQ7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgfQoKICAgIC8qIFJlZ2lzdGVyIHRoZSBjYXRlZ29yeSAqLwogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaGNrZXksIEdVSURUb1N0cmluZyhzemd1aWQsIGd1aWRDYXRlZ29yeSksIDAsIEtFWV9XUklURSwgJmhrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhrZXksIEdVSURUb1N0cmluZyhzemd1aWQsIGNsc2lkRE1PKSwgMCwgTlVMTCwKICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNsc2tleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgIGlmIChoY2tleSkKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICBpZiAoaGNsc2tleSkKICAgICAgICBSZWdDbG9zZUtleShoY2xza2V5KTsKICAgIGlmIChocmtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CgogICAgVFJBQ0UoIiBocmVzdWx0PTB4JTA4bHhcbiIsIGhyZXMpOwogICAgcmV0dXJuIGhyZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERNT1VucmVnaXN0ZXIKICoKICogVW5yZWdpc3RlciBhIERpcmVjdFggTWVkaWEgT2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PVW5yZWdpc3RlcihSRUZDTFNJRCBjbHNpZERNTywgUkVGR1VJRCBndWlkQ2F0ZWdvcnkpCnsKICAgIEhSRVNVTFQgaHJlczsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGNrZXkgPSAwOwoKICAgIEdVSURUb1N0cmluZyhzemd1aWQsIGNsc2lkRE1PKTsKCiAgICBUUkFDRSgiJXMgJXBcbiIsIGRlYnVnc3RyX3coc3pndWlkKSwgZ3VpZENhdGVnb3J5KTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAwLCBLRVlfV1JJVEUsICZocmtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBocmVzID0gUmVnRGVsZXRlS2V5VyhocmtleSwgc3pndWlkKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKGhya2V5LCBzekRNT0NhdGVnb3JpZXMsIDAsIEtFWV9XUklURSwgJmhja2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhja2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgpsZW5kOgogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChocmtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERNT0dldE5hbWUKICoKICogR2V0IERNUCBOYW1lIGZyb20gdGhlIHJlZ2lzdHJ5CiAqLwpIUkVTVUxUIFdJTkFQSSBETU9HZXROYW1lKFJFRkNMU0lEIGNsc2lkRE1PLCBXQ0hBUiogc3pOYW1lKQp7CiAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgSFJFU1VMVCBocmVzOwogICAgSEtFWSBocmtleSA9IDA7CiAgICBIS0VZIGhrZXkgPSAwOwogICAgRFdPUkQgY291bnQ7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkRE1PKSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgMCwgS0VZX1JFQUQsICZocmtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhocmtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLAogICAgICAgIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBjb3VudCA9IDgwICogc2l6ZW9mKFdDSEFSKTsgLyogODAgYnkgQVBJIGRlZmluaXRpb24gKi8KICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIAogICAgICAgIChMUEJZVEUpIHN6TmFtZSwgJmNvdW50KTsgCgogICAgVFJBQ0UoIiBzek5hbWU9JXNcbiIsIGRlYnVnc3RyX3coc3pOYW1lKSk7CmxlbmQ6CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgSUVudW1ETU9fRGVzdHJ1Y3RvcgoqLwpzdGF0aWMgQk9PTCBJRW51bURNT19EZXN0cnVjdG9yKElFbnVtRE1PKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CgogICAgaWYgKFRoaXMtPmhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoVGhpcy0+aGtleSk7CgogICAgaWYgKFRoaXMtPnBJblR5cGVzKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBJblR5cGVzKTsKCiAgICBpZiAoVGhpcy0+cE91dFR5cGVzKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBPdXRUeXBlcyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElFbnVtRE1PX0NvbnN0cnVjdG9yCiAqLwpJRW51bURNTyAqIElFbnVtRE1PX0NvbnN0cnVjdG9yKAogICAgUkVGR1VJRCBndWlkQ2F0ZWdvcnksCiAgICBEV09SRCBkd0ZsYWdzLAogICAgRFdPUkQgY0luVHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBJblR5cGVzLAogICAgRFdPUkQgY091dFR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwT3V0VHlwZXMpCnsKICAgIFVJTlQgc2l6ZTsKICAgIElFbnVtRE1PSW1wbCogbHBlZG1vOwogICAgQk9PTCByZXQgPSBGQUxTRTsKCiAgICBscGVkbW8gPSAoSUVudW1ETU9JbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgCiAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElFbnVtRE1PSW1wbCkpOwoKICAgIGlmIChscGVkbW8pCiAgICB7CiAgICAgICAgbHBlZG1vLT5yZWYgPSAxOwogICAgICAgIGxwZWRtby0+bHBWdGJsID0gJmVkbW92dDsKICAgICAgICBscGVkbW8tPmluZGV4ID0gLTE7CglscGVkbW8tPmd1aWRDYXRlZ29yeSA9IGd1aWRDYXRlZ29yeTsKCWxwZWRtby0+ZHdGbGFncyA9IGR3RmxhZ3M7CgoJc2l6ZSA9IGNJblR5cGVzICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CiAgICAgICAgbHBlZG1vLT5wSW5UeXBlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgICAgICBpZiAoIWxwZWRtby0+cEluVHlwZXMpCiAgICAgICAgICAgIGdvdG8gbGVycjsKCW1lbWNweShscGVkbW8tPnBJblR5cGVzLCBwSW5UeXBlcywgc2l6ZSk7CiAgICAgICAgbHBlZG1vLT5jSW5UeXBlcyA9IGNJblR5cGVzOwoKCXNpemUgPSBjT3V0VHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgICAgICBscGVkbW8tPnBPdXRUeXBlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgICAgICBpZiAoIWxwZWRtby0+cE91dFR5cGVzKQogICAgICAgICAgICBnb3RvIGxlcnI7CgltZW1jcHkobHBlZG1vLT5wT3V0VHlwZXMsIHBPdXRUeXBlcywgc2l6ZSk7CiAgICAgICAgbHBlZG1vLT5jT3V0VHlwZXMgPSBjT3V0VHlwZXM7CgogICAgICAgIC8qIElmIG5vdCBmaWx0ZXJpbmcgYnkgY2F0ZWdvcnkgZW51bSBmcm9tIG1lZGlhIG9iamVjdHMgcm9vdCAqLwogICAgICAgIGlmIChJc0VxdWFsR1VJRChndWlkQ2F0ZWdvcnksICZHVUlEX05VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEVSUk9SX1NVQ0NFU1MgPT0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAKICAgICAgICAgICAgICAgIDAsIEtFWV9SRUFELCAmbHBlZG1vLT5oa2V5KSkKICAgICAgICAgICAgICAgIHJldCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICAgICAgICAgIFdDSEFSIHN6S2V5W01BWF9QQVRIXTsKCiAgICAgICAgICAgIHdzcHJpbnRmVyhzektleSwgc3pDYXQzRm10LCBzekRNT1Jvb3RLZXksIHN6RE1PQ2F0ZWdvcmllcywgCiAgICAgICAgICAgICAgICBHVUlEVG9TdHJpbmcoc3pndWlkLCBndWlkQ2F0ZWdvcnkpKTsKICAgICAgICAgICAgaWYgKEVSUk9SX1NVQ0NFU1MgPT0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIAogICAgICAgICAgICAgICAgMCwgS0VZX1JFQUQsICZscGVkbW8tPmhrZXkpKQogICAgICAgICAgICAgICAgcmV0ID0gVFJVRTsKICAgICAgICB9CgpsZXJyOgogICAgICAgIGlmKCFyZXQpCiAgICAgICAgewogICAgICAgICAgICBJRW51bURNT19EZXN0cnVjdG9yKChJRW51bURNTyopbHBlZG1vKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwZWRtbyk7CiAgICAgICAgICAgIGxwZWRtbyA9IE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsIGxwZWRtbyk7CgogICAgcmV0dXJuIChJRW51bURNTyopbHBlZG1vOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJRW51bURNT19mbkFkZFJlZihJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CiAgICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRW51bURNT19RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJRW51bURNTyogaWZhY2UsCiAgICBSRUZJSUQgcmlpZCwKICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgKnBwdk9iaiA9IE5VTEw7CgogICAgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkKICAgICAgICAqcHB2T2JqID0gVGhpczsKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lFbnVtRE1PKSkKICAgICAgICAqcHB2T2JqID0gKElFbnVtRE1PKilUaGlzOwoKICAgIGlmKCpwcHZPYmopCiAgICB7CiAgICAgICAgSUVudW1ETU9fZm5BZGRSZWYoKElFbnVtRE1PKikqcHB2T2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElFbnVtRE1PX2ZuUmVsZWFzZShJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgaWYgKCEtLShUaGlzLT5yZWYpKQogICAgewogICAgICAgIElFbnVtRE1PX0Rlc3RydWN0b3IoKElFbnVtRE1PKilUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcmV0dXJuIFRoaXMtPnJlZjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5OZXh0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5OZXh0KAogICAgSUVudW1ETU8gKiBpZmFjZSwgCiAgICBEV09SRCBjSXRlbXNUb0ZldGNoLAogICAgQ0xTSUQgKiBwQ0xTSUQsCiAgICBXQ0hBUiAqKiBOYW1lcywKICAgIERXT1JEICogcGNJdGVtc0ZldGNoZWQpCnsKICAgIEZJTEVUSU1FIGZ0OwogICAgSEtFWSBoa2V5OwogICAgV0NIQVIgc3pOZXh0S2V5W01BWF9QQVRIXTsKICAgIFdDSEFSIHN6S2V5W01BWF9QQVRIXTsKICAgIFdDSEFSIHN6VmFsdWVbTUFYX1BBVEhdOwogICAgRFdPUkQgbGVuOwogICAgVUlOVCBjb3VudCA9IDA7CiAgICBIUkVTVUxUIGhyZXMgPSBTX09LOwoKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiJWxkXG4iLCBjSXRlbXNUb0ZldGNoKTsKCiAgICBpZiAoIXBDTFNJRCB8fCAhTmFtZXMgfHwgIXBjSXRlbXNGZXRjaGVkKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgd2hpbGUgKGNvdW50IDwgY0l0ZW1zVG9GZXRjaCkKICAgIHsKICAgICAgICBUaGlzLT5pbmRleCsrOwoKICAgICAgICBocmVzID0gUmVnRW51bUtleUV4VyhUaGlzLT5oa2V5LCBUaGlzLT5pbmRleCwgc3pOZXh0S2V5LCAmbGVuLCBOVUxMLCBOVUxMLCBOVUxMLCAmZnQpOwogICAgICAgIGlmIChocmVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBUUkFDRSgiZm91bmQgJXNcbiIsIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CgoJaWYgKFRoaXMtPmR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgICAgIHsKICAgICAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDNGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5LCBzekRNT0tleWVkKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAwLCBLRVlfUkVBRCwgJmhrZXkpOwogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgIH0KCiAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDJGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5KTsKICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CgogICAgICAgIGlmIChUaGlzLT5wSW5UeXBlcykKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgaSwgajsKICAgICAgICAgICAgRFdPUkQgY0luVHlwZXM7CiAgICAgICAgICAgIERNT19QQVJUSUFMX01FRElBVFlQRSogcEluVHlwZXM7CgoJICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pETU9JbnB1dFR5cGUsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOwoJICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCgkgICAgY0luVHlwZXMgPSBsZW4gLyBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKCSAgICBwSW5UeXBlcyA9IChETU9fUEFSVElBTF9NRURJQVRZUEUqKSBzelZhbHVlOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmNJblR5cGVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBjSW5UeXBlczsgaisrKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoSXNNZWRpYVR5cGVFcXVhbCgmcEluVHlwZXNbal0sICZUaGlzLT5wSW5UeXBlc1tpXSkpCgkJICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCgkJaWYgKGogPj0gY0luVHlwZXMpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpIDwgVGhpcy0+Y0luVHlwZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5wT3V0VHlwZXMpCiAgICAgICAgewogICAgICAgICAgICBVSU5UIGksIGo7CiAgICAgICAgICAgIERXT1JEIGNPdXRUeXBlczsKICAgICAgICAgICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBwT3V0VHlwZXM7CgoJICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSBzelZhbHVlLCAmbGVuKTsKCSAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgoJICAgIGNPdXRUeXBlcyA9IGxlbiAvIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwoJICAgIHBPdXRUeXBlcyA9IChETU9fUEFSVElBTF9NRURJQVRZUEUqKSBzelZhbHVlOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmNPdXRUeXBlczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY091dFR5cGVzOyBqKyspIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChJc01lZGlhVHlwZUVxdWFsKCZwT3V0VHlwZXNbal0sICZUaGlzLT5wT3V0VHlwZXNbaV0pKQoJCSAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCWlmIChqID49IGNPdXRUeXBlcykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPCBUaGlzLT5jT3V0VHlwZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoJLyogTWVkaWEgb2JqZWN0IHdhc24ndCBmaWx0ZXJlZCBzbyBhZGQgaXQgdG8gcmV0dXJuIGxpc3QgKi8KICAgICAgICBOYW1lc1tjb3VudF0gPSBOVUxMOwoJbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHN6VmFsdWUsICZsZW4pOyAKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBocmVzKQoJewogICAgICAgICAgICBOYW1lc1tjb3VudF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuVyhzelZhbHVlKSArIDEpOwoJICAgIGlmIChOYW1lc1tjb3VudF0pCiAgICAgICAgICAgICAgICBzdHJjbXBXKE5hbWVzW2NvdW50XSwgc3pWYWx1ZSk7Cgl9CiAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6TmV4dEtleSwgJnBDTFNJRFtjb3VudF0pOwoKICAgICAgICBUUkFDRSgiZm91bmQgbWF0Y2ggJXMgJXNcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZSksIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cgljb3VudCsrOwogICAgfQoKICAgICpwY0l0ZW1zRmV0Y2hlZCA9IGNvdW50OwogICAgaWYgKCpwY0l0ZW1zRmV0Y2hlZCA8IGNJdGVtc1RvRmV0Y2gpCiAgICAgICAgaHJlcyA9IFNfRkFMU0U7CgogICAgcmV0dXJuIGhyZXM7Cn0KIAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblNraXAKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblNraXAoSUVudW1ETU8gKiBpZmFjZSwgRFdPUkQgY0l0ZW1zVG9Ta2lwKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVGhpcy0+aW5kZXggKz0gY0l0ZW1zVG9Ta2lwOwoKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblJlc2V0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5SZXNldChJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVGhpcy0+aW5kZXggPSAtMTsKCiAgICByZXR1cm4gU19PSzsKfQogCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuQ2xvbmUKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mbkNsb25lKElFbnVtRE1PICogaWZhY2UsIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgRklYTUUoIiglcCktPigpIHRvICglcCktPigpIEVfTk9USU1QTFxuIiwgVGhpcywgcHBFbnVtKTsKCiAgcmV0dXJuIEVfTk9USU1QTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PRW51bQogKgogKiBFbnVtZXJhdGUgRGlyZWN0WCBNZWRpYSBPYmplY3RzIGluIHRoZSByZWdpc3RyeS4KICovCkhSRVNVTFQgV0lOQVBJIERNT0VudW0oCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcywKICAgIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBIUkVTVUxUIGhyZXMgPSBFX0ZBSUw7CgogICAgVFJBQ0UoImd1aWRDYXRlZ29yeT0lcCBkd0ZsYWdzPTB4JTA4bHggY0luVHlwZXM9JWxkIGNPdXRUeXBlcz0lbGRcbiIsCiAgICAgICAgZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywgY091dFR5cGVzKTsKCiAgICAqcHBFbnVtID0gSUVudW1ETU9fQ29uc3RydWN0b3IoZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywKICAgICAgICBwSW5UeXBlcywgY091dFR5cGVzLCBwT3V0VHlwZXMpOwogICAgaWYgKCpwcEVudW0pCiAgICAgICAgaHJlcyA9IFNfT0s7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdGF0aWMgSUVudW1ETU9WdGJsIGVkbW92dCA9CnsKCUlFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UsCglJRW51bURNT19mbkFkZFJlZiwKCUlFbnVtRE1PX2ZuUmVsZWFzZSwKCUlFbnVtRE1PX2ZuTmV4dCwKCUlFbnVtRE1PX2ZuU2tpcCwKCUlFbnVtRE1PX2ZuUmVzZXQsCglJRW51bURNT19mbkNsb25lLAp9OwoKCkhSRVNVTFQgV0lOQVBJIERNT0dldFR5cGVzKFJFRkNMU0lEIGEsIHVuc2lnbmVkIGxvbmcgYiwgdW5zaWduZWQgbG9uZyogYywKCQkJICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBkLCB1bnNpZ25lZCBsb25nIGUsCgkJCSAgIHVuc2lnbmVkIGxvbmcqIGYsIERNT19QQVJUSUFMX01FRElBVFlQRSogZykKewogIEZJWE1FKCIoJXAsJWx1LCVwLCVwLCVsdSwlcCwlcCksc3R1YiFcbiIsYSxiLGMsZCxlLGYsZyk7CgogIHJldHVybiBFX05PVElNUEw7Cn0K