LyoKVGhlIE1JVCBMaWNlbnNlCgpDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBHb29nbGUsIEluYy4gaHR0cDovL2FuZ3VsYXJqcy5vcmcKClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgpUSEUgU09GVFdBUkUuCiovCi8qKgogKiBAbGljZW5zZSBBbmd1bGFySlMgdjEuMy44CiAqIChjKSAyMDEwLTIwMTQgR29vZ2xlLCBJbmMuIGh0dHA6Ly9hbmd1bGFyanMub3JnCiAqIExpY2Vuc2U6IE1JVAogKi8KKGZ1bmN0aW9uKHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkgeyd1c2Ugc3RyaWN0JzsKCi8qKgogKiBAZGVzY3JpcHRpb24KICoKICogVGhpcyBvYmplY3QgcHJvdmlkZXMgYSB1dGlsaXR5IGZvciBwcm9kdWNpbmcgcmljaCBFcnJvciBtZXNzYWdlcyB3aXRoaW4KICogQW5ndWxhci4gSXQgY2FuIGJlIGNhbGxlZCBhcyBmb2xsb3dzOgogKgogKiB2YXIgZXhhbXBsZU1pbkVyciA9IG1pbkVycignZXhhbXBsZScpOwogKiB0aHJvdyBleGFtcGxlTWluRXJyKCdvbmUnLCAnVGhpcyB7MH0gaXMgezF9JywgZm9vLCBiYXIpOwogKgogKiBUaGUgYWJvdmUgY3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBtaW5FcnIgaW4gdGhlIGV4YW1wbGUgbmFtZXNwYWNlLiBUaGUKICogcmVzdWx0aW5nIGVycm9yIHdpbGwgaGF2ZSBhIG5hbWVzcGFjZWQgZXJyb3IgY29kZSBvZiBleGFtcGxlLm9uZS4gIFRoZQogKiByZXN1bHRpbmcgZXJyb3Igd2lsbCByZXBsYWNlIHswfSB3aXRoIHRoZSB2YWx1ZSBvZiBmb28sIGFuZCB7MX0gd2l0aCB0aGUKICogdmFsdWUgb2YgYmFyLiBUaGUgb2JqZWN0IGlzIG5vdCByZXN0cmljdGVkIGluIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIGl0IGNhbgogKiB0YWtlLgogKgogKiBJZiBmZXdlciBhcmd1bWVudHMgYXJlIHNwZWNpZmllZCB0aGFuIG5lY2Vzc2FyeSBmb3IgaW50ZXJwb2xhdGlvbiwgdGhlIGV4dHJhCiAqIGludGVycG9sYXRpb24gbWFya2VycyB3aWxsIGJlIHByZXNlcnZlZCBpbiB0aGUgZmluYWwgc3RyaW5nLgogKgogKiBTaW5jZSBkYXRhIHdpbGwgYmUgcGFyc2VkIHN0YXRpY2FsbHkgZHVyaW5nIGEgYnVpbGQgc3RlcCwgc29tZSByZXN0cmljdGlvbnMKICogYXJlIGFwcGxpZWQgd2l0aCByZXNwZWN0IHRvIGhvdyBtaW5FcnIgaW5zdGFuY2VzIGFyZSBjcmVhdGVkIGFuZCBjYWxsZWQuCiAqIEluc3RhbmNlcyBzaG91bGQgaGF2ZSBuYW1lcyBvZiB0aGUgZm9ybSBuYW1lc3BhY2VNaW5FcnIgZm9yIGEgbWluRXJyIGNyZWF0ZWQKICogdXNpbmcgbWluRXJyKCduYW1lc3BhY2UnKSAuIEVycm9yIGNvZGVzLCBuYW1lc3BhY2VzIGFuZCB0ZW1wbGF0ZSBzdHJpbmdzCiAqIHNob3VsZCBhbGwgYmUgc3RhdGljIHN0cmluZ3MsIG5vdCB2YXJpYWJsZXMgb3IgZ2VuZXJhbCBleHByZXNzaW9ucy4KICoKICogQHBhcmFtIHtzdHJpbmd9IG1vZHVsZSBUaGUgbmFtZXNwYWNlIHRvIHVzZSBmb3IgdGhlIG5ldyBtaW5FcnIgaW5zdGFuY2UuCiAqIEBwYXJhbSB7ZnVuY3Rpb259IEVycm9yQ29uc3RydWN0b3IgQ3VzdG9tIGVycm9yIGNvbnN0cnVjdG9yIHRvIGJlIGluc3RhbnRpYXRlZCB3aGVuIHJldHVybmluZwogKiAgIGVycm9yIGZyb20gcmV0dXJuZWQgZnVuY3Rpb24sIGZvciBjYXNlcyB3aGVuIGEgcGFydGljdWxhciB0eXBlIG9mIGVycm9yIGlzIHVzZWZ1bC4KICogQHJldHVybnMge2Z1bmN0aW9uKGNvZGU6c3RyaW5nLCB0ZW1wbGF0ZTpzdHJpbmcsIC4uLnRlbXBsYXRlQXJncyk6IEVycm9yfSBtaW5FcnIgaW5zdGFuY2UKICovCgpmdW5jdGlvbiBtaW5FcnIobW9kdWxlLCBFcnJvckNvbnN0cnVjdG9yKSB7CiAgRXJyb3JDb25zdHJ1Y3RvciA9IEVycm9yQ29uc3RydWN0b3IgfHwgRXJyb3I7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgdmFyIGNvZGUgPSBhcmd1bWVudHNbMF0sCiAgICAgIHByZWZpeCA9ICdbJyArIChtb2R1bGUgPyBtb2R1bGUgKyAnOicgOiAnJykgKyBjb2RlICsgJ10gJywKICAgICAgdGVtcGxhdGUgPSBhcmd1bWVudHNbMV0sCiAgICAgIHRlbXBsYXRlQXJncyA9IGFyZ3VtZW50cywKCiAgICAgIG1lc3NhZ2UsIGk7CgogICAgbWVzc2FnZSA9IHByZWZpeCArIHRlbXBsYXRlLnJlcGxhY2UoL1x7XGQrXH0vZywgZnVuY3Rpb24obWF0Y2gpIHsKICAgICAgdmFyIGluZGV4ID0gK21hdGNoLnNsaWNlKDEsIC0xKSwgYXJnOwoKICAgICAgaWYgKGluZGV4ICsgMiA8IHRlbXBsYXRlQXJncy5sZW5ndGgpIHsKICAgICAgICByZXR1cm4gdG9EZWJ1Z1N0cmluZyh0ZW1wbGF0ZUFyZ3NbaW5kZXggKyAyXSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hdGNoOwogICAgfSk7CgogICAgbWVzc2FnZSA9IG1lc3NhZ2UgKyAnXG5odHRwOi8vZXJyb3JzLmFuZ3VsYXJqcy5vcmcvMS4zLjgvJyArCiAgICAgIChtb2R1bGUgPyBtb2R1bGUgKyAnLycgOiAnJykgKyBjb2RlOwogICAgZm9yIChpID0gMjsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewogICAgICBtZXNzYWdlID0gbWVzc2FnZSArIChpID09IDIgPyAnPycgOiAnJicpICsgJ3AnICsgKGkgLSAyKSArICc9JyArCiAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KHRvRGVidWdTdHJpbmcoYXJndW1lbnRzW2ldKSk7CiAgICB9CiAgICByZXR1cm4gbmV3IEVycm9yQ29uc3RydWN0b3IobWVzc2FnZSk7CiAgfTsKfQoKLyogV2UgbmVlZCB0byB0ZWxsIGpzaGludCB3aGF0IHZhcmlhYmxlcyBhcmUgYmVpbmcgZXhwb3J0ZWQgKi8KLyogZ2xvYmFsIGFuZ3VsYXI6IHRydWUsCiAgbXNpZTogdHJ1ZSwKICBqcUxpdGU6IHRydWUsCiAgalF1ZXJ5OiB0cnVlLAogIHNsaWNlOiB0cnVlLAogIHNwbGljZTogdHJ1ZSwKICBwdXNoOiB0cnVlLAogIHRvU3RyaW5nOiB0cnVlLAogIG5nTWluRXJyOiB0cnVlLAogIGFuZ3VsYXJNb2R1bGU6IHRydWUsCiAgdWlkOiB0cnVlLAogIFJFR0VYX1NUUklOR19SRUdFWFA6IHRydWUsCiAgVkFMSURJVFlfU1RBVEVfUFJPUEVSVFk6IHRydWUsCgogIGxvd2VyY2FzZTogdHJ1ZSwKICB1cHBlcmNhc2U6IHRydWUsCiAgbWFudWFsTG93ZXJjYXNlOiB0cnVlLAogIG1hbnVhbFVwcGVyY2FzZTogdHJ1ZSwKICBub2RlTmFtZV86IHRydWUsCiAgaXNBcnJheUxpa2U6IHRydWUsCiAgZm9yRWFjaDogdHJ1ZSwKICBzb3J0ZWRLZXlzOiB0cnVlLAogIGZvckVhY2hTb3J0ZWQ6IHRydWUsCiAgcmV2ZXJzZVBhcmFtczogdHJ1ZSwKICBuZXh0VWlkOiB0cnVlLAogIHNldEhhc2hLZXk6IHRydWUsCiAgZXh0ZW5kOiB0cnVlLAogIGludDogdHJ1ZSwKICBpbmhlcml0OiB0cnVlLAogIG5vb3A6IHRydWUsCiAgaWRlbnRpdHk6IHRydWUsCiAgdmFsdWVGbjogdHJ1ZSwKICBpc1VuZGVmaW5lZDogdHJ1ZSwKICBpc0RlZmluZWQ6IHRydWUsCiAgaXNPYmplY3Q6IHRydWUsCiAgaXNTdHJpbmc6IHRydWUsCiAgaXNOdW1iZXI6IHRydWUsCiAgaXNEYXRlOiB0cnVlLAogIGlzQXJyYXk6IHRydWUsCiAgaXNGdW5jdGlvbjogdHJ1ZSwKICBpc1JlZ0V4cDogdHJ1ZSwKICBpc1dpbmRvdzogdHJ1ZSwKICBpc1Njb3BlOiB0cnVlLAogIGlzRmlsZTogdHJ1ZSwKICBpc0Zvcm1EYXRhOiB0cnVlLAogIGlzQmxvYjogdHJ1ZSwKICBpc0Jvb2xlYW46IHRydWUsCiAgaXNQcm9taXNlTGlrZTogdHJ1ZSwKICB0cmltOiB0cnVlLAogIGVzY2FwZUZvclJlZ2V4cDogdHJ1ZSwKICBpc0VsZW1lbnQ6IHRydWUsCiAgbWFrZU1hcDogdHJ1ZSwKICBpbmNsdWRlczogdHJ1ZSwKICBhcnJheVJlbW92ZTogdHJ1ZSwKICBjb3B5OiB0cnVlLAogIHNoYWxsb3dDb3B5OiB0cnVlLAogIGVxdWFsczogdHJ1ZSwKICBjc3A6IHRydWUsCiAgY29uY2F0OiB0cnVlLAogIHNsaWNlQXJnczogdHJ1ZSwKICBiaW5kOiB0cnVlLAogIHRvSnNvblJlcGxhY2VyOiB0cnVlLAogIHRvSnNvbjogdHJ1ZSwKICBmcm9tSnNvbjogdHJ1ZSwKICBzdGFydGluZ1RhZzogdHJ1ZSwKICB0cnlEZWNvZGVVUklDb21wb25lbnQ6IHRydWUsCiAgcGFyc2VLZXlWYWx1ZTogdHJ1ZSwKICB0b0tleVZhbHVlOiB0cnVlLAogIGVuY29kZVVyaVNlZ21lbnQ6IHRydWUsCiAgZW5jb2RlVXJpUXVlcnk6IHRydWUsCiAgYW5ndWxhckluaXQ6IHRydWUsCiAgYm9vdHN0cmFwOiB0cnVlLAogIGdldFRlc3RhYmlsaXR5OiB0cnVlLAogIHNuYWtlX2Nhc2U6IHRydWUsCiAgYmluZEpRdWVyeTogdHJ1ZSwKICBhc3NlcnRBcmc6IHRydWUsCiAgYXNzZXJ0QXJnRm46IHRydWUsCiAgYXNzZXJ0Tm90SGFzT3duUHJvcGVydHk6IHRydWUsCiAgZ2V0dGVyOiB0cnVlLAogIGdldEJsb2NrTm9kZXM6IHRydWUsCiAgaGFzT3duUHJvcGVydHk6IHRydWUsCiAgY3JlYXRlTWFwOiB0cnVlLAoKICBOT0RFX1RZUEVfRUxFTUVOVDogdHJ1ZSwKICBOT0RFX1RZUEVfVEVYVDogdHJ1ZSwKICBOT0RFX1RZUEVfQ09NTUVOVDogdHJ1ZSwKICBOT0RFX1RZUEVfRE9DVU1FTlQ6IHRydWUsCiAgTk9ERV9UWVBFX0RPQ1VNRU5UX0ZSQUdNRU5UOiB0cnVlLAoqLwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovKioKICogQG5nZG9jIG1vZHVsZQogKiBAbmFtZSBuZwogKiBAbW9kdWxlIG5nCiAqIEBkZXNjcmlwdGlvbgogKgogKiAjIG5nIChjb3JlIG1vZHVsZSkKICogVGhlIG5nIG1vZHVsZSBpcyBsb2FkZWQgYnkgZGVmYXVsdCB3aGVuIGFuIEFuZ3VsYXJKUyBhcHBsaWNhdGlvbiBpcyBzdGFydGVkLiBUaGUgbW9kdWxlIGl0c2VsZgogKiBjb250YWlucyB0aGUgZXNzZW50aWFsIGNvbXBvbmVudHMgZm9yIGFuIEFuZ3VsYXJKUyBhcHBsaWNhdGlvbiB0byBmdW5jdGlvbi4gVGhlIHRhYmxlIGJlbG93CiAqIGxpc3RzIGEgaGlnaCBsZXZlbCBicmVha2Rvd24gb2YgZWFjaCBvZiB0aGUgc2VydmljZXMvZmFjdG9yaWVzLCBmaWx0ZXJzLCBkaXJlY3RpdmVzIGFuZCB0ZXN0aW5nCiAqIGNvbXBvbmVudHMgYXZhaWxhYmxlIHdpdGhpbiB0aGlzIGNvcmUgbW9kdWxlLgogKgogKiA8ZGl2IGRvYy1tb2R1bGUtY29tcG9uZW50cz0ibmciPjwvZGl2PgogKi8KCnZhciBSRUdFWF9TVFJJTkdfUkVHRVhQID0gL15cLyguKylcLyhbYS16XSopJC87CgovLyBUaGUgbmFtZSBvZiBhIGZvcm0gY29udHJvbCdzIFZhbGlkaXR5U3RhdGUgcHJvcGVydHkuCi8vIFRoaXMgaXMgdXNlZCBzbyB0aGF0IGl0J3MgcG9zc2libGUgZm9yIGludGVybmFsIHRlc3RzIHRvIGNyZWF0ZSBtb2NrIFZhbGlkaXR5U3RhdGVzLgp2YXIgVkFMSURJVFlfU1RBVEVfUFJPUEVSVFkgPSAndmFsaWRpdHknOwoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLmxvd2VyY2FzZQogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byBsb3dlcmNhc2UuCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCiAqIEByZXR1cm5zIHtzdHJpbmd9IExvd2VyY2FzZWQgc3RyaW5nLgogKi8KdmFyIGxvd2VyY2FzZSA9IGZ1bmN0aW9uKHN0cmluZykge3JldHVybiBpc1N0cmluZyhzdHJpbmcpID8gc3RyaW5nLnRvTG93ZXJDYXNlKCkgOiBzdHJpbmc7fTsKdmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBAbmdkb2MgZnVuY3Rpb24KICogQG5hbWUgYW5ndWxhci51cHBlcmNhc2UKICogQG1vZHVsZSBuZwogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24gQ29udmVydHMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdXBwZXJjYXNlLgogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFN0cmluZyB0byBiZSBjb252ZXJ0ZWQgdG8gdXBwZXJjYXNlLgogKiBAcmV0dXJucyB7c3RyaW5nfSBVcHBlcmNhc2VkIHN0cmluZy4KICovCnZhciB1cHBlcmNhc2UgPSBmdW5jdGlvbihzdHJpbmcpIHtyZXR1cm4gaXNTdHJpbmcoc3RyaW5nKSA/IHN0cmluZy50b1VwcGVyQ2FzZSgpIDogc3RyaW5nO307CgoKdmFyIG1hbnVhbExvd2VyY2FzZSA9IGZ1bmN0aW9uKHMpIHsKICAvKiBqc2hpbnQgYml0d2lzZTogZmFsc2UgKi8KICByZXR1cm4gaXNTdHJpbmcocykKICAgICAgPyBzLnJlcGxhY2UoL1tBLVpdL2csIGZ1bmN0aW9uKGNoKSB7cmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY2guY2hhckNvZGVBdCgwKSB8IDMyKTt9KQogICAgICA6IHM7Cn07CnZhciBtYW51YWxVcHBlcmNhc2UgPSBmdW5jdGlvbihzKSB7CiAgLyoganNoaW50IGJpdHdpc2U6IGZhbHNlICovCiAgcmV0dXJuIGlzU3RyaW5nKHMpCiAgICAgID8gcy5yZXBsYWNlKC9bYS16XS9nLCBmdW5jdGlvbihjaCkge3JldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoLmNoYXJDb2RlQXQoMCkgJiB+MzIpO30pCiAgICAgIDogczsKfTsKCgovLyBTdHJpbmcjdG9Mb3dlckNhc2UgYW5kIFN0cmluZyN0b1VwcGVyQ2FzZSBkb24ndCBwcm9kdWNlIGNvcnJlY3QgcmVzdWx0cyBpbiBicm93c2VycyB3aXRoIFR1cmtpc2gKLy8gbG9jYWxlLCBmb3IgdGhpcyByZWFzb24gd2UgbmVlZCB0byBkZXRlY3QgdGhpcyBjYXNlIGFuZCByZWRlZmluZSBsb3dlcmNhc2UvdXBwZXJjYXNlIG1ldGhvZHMKLy8gd2l0aCBjb3JyZWN0IGJ1dCBzbG93ZXIgYWx0ZXJuYXRpdmVzLgppZiAoJ2knICE9PSAnSScudG9Mb3dlckNhc2UoKSkgewogIGxvd2VyY2FzZSA9IG1hbnVhbExvd2VyY2FzZTsKICB1cHBlcmNhc2UgPSBtYW51YWxVcHBlcmNhc2U7Cn0KCgp2YXIKICAgIG1zaWUsICAgICAgICAgICAgIC8vIGhvbGRzIG1ham9yIHZlcnNpb24gbnVtYmVyIGZvciBJRSwgb3IgTmFOIGlmIFVBIGlzIG5vdCBJRS4KICAgIGpxTGl0ZSwgICAgICAgICAgIC8vIGRlbGF5IGJpbmRpbmcgc2luY2UgalF1ZXJ5IGNvdWxkIGJlIGxvYWRlZCBhZnRlciB1cy4KICAgIGpRdWVyeSwgICAgICAgICAgIC8vIGRlbGF5IGJpbmRpbmcKICAgIHNsaWNlICAgICAgICAgICAgID0gW10uc2xpY2UsCiAgICBzcGxpY2UgICAgICAgICAgICA9IFtdLnNwbGljZSwKICAgIHB1c2ggICAgICAgICAgICAgID0gW10ucHVzaCwKICAgIHRvU3RyaW5nICAgICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZywKICAgIG5nTWluRXJyICAgICAgICAgID0gbWluRXJyKCduZycpLAoKICAgIC8qKiBAbmFtZSBhbmd1bGFyICovCiAgICBhbmd1bGFyICAgICAgICAgICA9IHdpbmRvdy5hbmd1bGFyIHx8ICh3aW5kb3cuYW5ndWxhciA9IHt9KSwKICAgIGFuZ3VsYXJNb2R1bGUsCiAgICB1aWQgICAgICAgICAgICAgICA9IDA7CgovKioKICogZG9jdW1lbnRNb2RlIGlzIGFuIElFLW9ubHkgcHJvcGVydHkKICogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2NjMTk2OTg4KHY9dnMuODUpLmFzcHgKICovCm1zaWUgPSBkb2N1bWVudC5kb2N1bWVudE1vZGU7CgoKLyoqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gb2JqCiAqIEByZXR1cm4ge2Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiBgb2JqYCBpcyBhbiBhcnJheSBvciBhcnJheS1saWtlIG9iamVjdCAoTm9kZUxpc3QsIEFyZ3VtZW50cywKICogICAgICAgICAgICAgICAgICAgU3RyaW5nIC4uLikKICovCmZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikgewogIGlmIChvYmogPT0gbnVsbCB8fCBpc1dpbmRvdyhvYmopKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDsKCiAgaWYgKG9iai5ub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0VMRU1FTlQgJiYgbGVuZ3RoKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHJldHVybiBpc1N0cmluZyhvYmopIHx8IGlzQXJyYXkob2JqKSB8fCBsZW5ndGggPT09IDAgfHwKICAgICAgICAgdHlwZW9mIGxlbmd0aCA9PT0gJ251bWJlcicgJiYgbGVuZ3RoID4gMCAmJiAobGVuZ3RoIC0gMSkgaW4gb2JqOwp9CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuZm9yRWFjaAogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBJbnZva2VzIHRoZSBgaXRlcmF0b3JgIGZ1bmN0aW9uIG9uY2UgZm9yIGVhY2ggaXRlbSBpbiBgb2JqYCBjb2xsZWN0aW9uLCB3aGljaCBjYW4gYmUgZWl0aGVyIGFuCiAqIG9iamVjdCBvciBhbiBhcnJheS4gVGhlIGBpdGVyYXRvcmAgZnVuY3Rpb24gaXMgaW52b2tlZCB3aXRoIGBpdGVyYXRvcih2YWx1ZSwga2V5LCBvYmopYCwgd2hlcmUgYHZhbHVlYAogKiBpcyB0aGUgdmFsdWUgb2YgYW4gb2JqZWN0IHByb3BlcnR5IG9yIGFuIGFycmF5IGVsZW1lbnQsIGBrZXlgIGlzIHRoZSBvYmplY3QgcHJvcGVydHkga2V5IG9yCiAqIGFycmF5IGVsZW1lbnQgaW5kZXggYW5kIG9iaiBpcyB0aGUgYG9iamAgaXRzZWxmLiBTcGVjaWZ5aW5nIGEgYGNvbnRleHRgIGZvciB0aGUgZnVuY3Rpb24gaXMgb3B0aW9uYWwuCiAqCiAqIEl0IGlzIHdvcnRoIG5vdGluZyB0aGF0IGAuZm9yRWFjaGAgZG9lcyBub3QgaXRlcmF0ZSBvdmVyIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlY2F1c2UgaXQgZmlsdGVycwogKiB1c2luZyB0aGUgYGhhc093blByb3BlcnR5YCBtZXRob2QuCiAqCiAqIFVubGlrZSBFUzI2MidzCiAqIFtBcnJheS5wcm90b3R5cGUuZm9yRWFjaF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzUuMS8jc2VjLTE1LjQuNC4xOCksCiAqIFByb3ZpZGluZyAndW5kZWZpbmVkJyBvciAnbnVsbCcgdmFsdWVzIGZvciBgb2JqYCB3aWxsIG5vdCB0aHJvdyBhIFR5cGVFcnJvciwgYnV0IHJhdGhlciBqdXN0CiAqIHJldHVybiB0aGUgdmFsdWUgcHJvdmlkZWQuCiAqCiAgIGBgYGpzCiAgICAgdmFyIHZhbHVlcyA9IHtuYW1lOiAnbWlza28nLCBnZW5kZXI6ICdtYWxlJ307CiAgICAgdmFyIGxvZyA9IFtdOwogICAgIGFuZ3VsYXIuZm9yRWFjaCh2YWx1ZXMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICAgICAgIHRoaXMucHVzaChrZXkgKyAnOiAnICsgdmFsdWUpOwogICAgIH0sIGxvZyk7CiAgICAgZXhwZWN0KGxvZykudG9FcXVhbChbJ25hbWU6IG1pc2tvJywgJ2dlbmRlcjogbWFsZSddKTsKICAgYGBgCiAqCiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogT2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0b3IgSXRlcmF0b3IgZnVuY3Rpb24uCiAqIEBwYXJhbSB7T2JqZWN0PX0gY29udGV4dCBPYmplY3QgdG8gYmVjb21lIGNvbnRleHQgKGB0aGlzYCkgZm9yIHRoZSBpdGVyYXRvciBmdW5jdGlvbi4KICogQHJldHVybnMge09iamVjdHxBcnJheX0gUmVmZXJlbmNlIHRvIGBvYmpgLgogKi8KCmZ1bmN0aW9uIGZvckVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkgewogIHZhciBrZXksIGxlbmd0aDsKICBpZiAob2JqKSB7CiAgICBpZiAoaXNGdW5jdGlvbihvYmopKSB7CiAgICAgIGZvciAoa2V5IGluIG9iaikgewogICAgICAgIC8vIE5lZWQgdG8gY2hlY2sgaWYgaGFzT3duUHJvcGVydHkgZXhpc3RzLAogICAgICAgIC8vIGFzIG9uIElFOCB0aGUgcmVzdWx0IG9mIHF1ZXJ5U2VsZWN0b3JBbGwgaXMgYW4gb2JqZWN0IHdpdGhvdXQgYSBoYXNPd25Qcm9wZXJ0eSBmdW5jdGlvbgogICAgICAgIGlmIChrZXkgIT0gJ3Byb3RvdHlwZScgJiYga2V5ICE9ICdsZW5ndGgnICYmIGtleSAhPSAnbmFtZScgJiYgKCFvYmouaGFzT3duUHJvcGVydHkgfHwgb2JqLmhhc093blByb3BlcnR5KGtleSkpKSB7CiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqKSB8fCBpc0FycmF5TGlrZShvYmopKSB7CiAgICAgIHZhciBpc1ByaW1pdGl2ZSA9IHR5cGVvZiBvYmogIT09ICdvYmplY3QnOwogICAgICBmb3IgKGtleSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGtleSA8IGxlbmd0aDsga2V5KyspIHsKICAgICAgICBpZiAoaXNQcmltaXRpdmUgfHwga2V5IGluIG9iaikgewogICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpba2V5XSwga2V5LCBvYmopOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmIChvYmouZm9yRWFjaCAmJiBvYmouZm9yRWFjaCAhPT0gZm9yRWFjaCkgewogICAgICAgIG9iai5mb3JFYWNoKGl0ZXJhdG9yLCBjb250ZXh0LCBvYmopOwogICAgfSBlbHNlIHsKICAgICAgZm9yIChrZXkgaW4gb2JqKSB7CiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CiAgICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaik7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBvYmo7Cn0KCmZ1bmN0aW9uIHNvcnRlZEtleXMob2JqKSB7CiAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikuc29ydCgpOwp9CgpmdW5jdGlvbiBmb3JFYWNoU29ydGVkKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHsKICB2YXIga2V5cyA9IHNvcnRlZEtleXMob2JqKTsKICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2tleXNbaV1dLCBrZXlzW2ldKTsKICB9CiAgcmV0dXJuIGtleXM7Cn0KCgovKioKICogd2hlbiB1c2luZyBmb3JFYWNoIHRoZSBwYXJhbXMgYXJlIHZhbHVlLCBrZXksIGJ1dCBpdCBpcyBvZnRlbiB1c2VmdWwgdG8gaGF2ZSBrZXksIHZhbHVlLgogKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZywgKil9IGl0ZXJhdG9yRm4KICogQHJldHVybnMge2Z1bmN0aW9uKCosIHN0cmluZyl9CiAqLwpmdW5jdGlvbiByZXZlcnNlUGFyYW1zKGl0ZXJhdG9yRm4pIHsKICByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGtleSkgeyBpdGVyYXRvckZuKGtleSwgdmFsdWUpOyB9Owp9CgovKioKICogQSBjb25zaXN0ZW50IHdheSBvZiBjcmVhdGluZyB1bmlxdWUgSURzIGluIGFuZ3VsYXIuCiAqCiAqIFVzaW5nIHNpbXBsZSBudW1iZXJzIGFsbG93cyB1cyB0byBnZW5lcmF0ZSAyOC42IG1pbGxpb24gdW5pcXVlIGlkcyBwZXIgc2Vjb25kIGZvciAxMCB5ZWFycyBiZWZvcmUKICogd2UgaGl0IG51bWJlciBwcmVjaXNpb24gaXNzdWVzIGluIEphdmFTY3JpcHQuCiAqCiAqIE1hdGgucG93KDIsNTMpIC8gNjAgLyA2MCAvIDI0IC8gMzY1IC8gMTAgPSAyOC42TQogKgogKiBAcmV0dXJucyB7bnVtYmVyfSBhbiB1bmlxdWUgYWxwaGEtbnVtZXJpYyBzdHJpbmcKICovCmZ1bmN0aW9uIG5leHRVaWQoKSB7CiAgcmV0dXJuICsrdWlkOwp9CgoKLyoqCiAqIFNldCBvciBjbGVhciB0aGUgaGFzaGtleSBmb3IgYW4gb2JqZWN0LgogKiBAcGFyYW0gb2JqIG9iamVjdAogKiBAcGFyYW0gaCB0aGUgaGFzaGtleSAoIXRydXRoeSB0byBkZWxldGUgdGhlIGhhc2hrZXkpCiAqLwpmdW5jdGlvbiBzZXRIYXNoS2V5KG9iaiwgaCkgewogIGlmIChoKSB7CiAgICBvYmouJCRoYXNoS2V5ID0gaDsKICB9CiAgZWxzZSB7CiAgICBkZWxldGUgb2JqLiQkaGFzaEtleTsKICB9Cn0KCi8qKgogKiBAbmdkb2MgZnVuY3Rpb24KICogQG5hbWUgYW5ndWxhci5leHRlbmQKICogQG1vZHVsZSBuZwogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogRXh0ZW5kcyB0aGUgZGVzdGluYXRpb24gb2JqZWN0IGBkc3RgIGJ5IGNvcHlpbmcgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBmcm9tIHRoZSBgc3JjYCBvYmplY3QocykKICogdG8gYGRzdGAuIFlvdSBjYW4gc3BlY2lmeSBtdWx0aXBsZSBgc3JjYCBvYmplY3RzLiBJZiB5b3Ugd2FudCB0byBwcmVzZXJ2ZSBvcmlnaW5hbCBvYmplY3RzLCB5b3UgY2FuIGRvIHNvCiAqIGJ5IHBhc3NpbmcgYW4gZW1wdHkgb2JqZWN0IGFzIHRoZSB0YXJnZXQ6IGB2YXIgb2JqZWN0ID0gYW5ndWxhci5leHRlbmQoe30sIG9iamVjdDEsIG9iamVjdDIpYC4KICogTm90ZTogS2VlcCBpbiBtaW5kIHRoYXQgYGFuZ3VsYXIuZXh0ZW5kYCBkb2VzIG5vdCBzdXBwb3J0IHJlY3Vyc2l2ZSBtZXJnZSAoZGVlcCBjb3B5KS4KICoKICogQHBhcmFtIHtPYmplY3R9IGRzdCBEZXN0aW5hdGlvbiBvYmplY3QuCiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzcmMgU291cmNlIG9iamVjdChzKS4KICogQHJldHVybnMge09iamVjdH0gUmVmZXJlbmNlIHRvIGBkc3RgLgogKi8KZnVuY3Rpb24gZXh0ZW5kKGRzdCkgewogIHZhciBoID0gZHN0LiQkaGFzaEtleTsKCiAgZm9yICh2YXIgaSA9IDEsIGlpID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgIHZhciBvYmogPSBhcmd1bWVudHNbaV07CiAgICBpZiAob2JqKSB7CiAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTsKICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0ga2V5cy5sZW5ndGg7IGogPCBqajsgaisrKSB7CiAgICAgICAgdmFyIGtleSA9IGtleXNbal07CiAgICAgICAgZHN0W2tleV0gPSBvYmpba2V5XTsKICAgICAgfQogICAgfQogIH0KCiAgc2V0SGFzaEtleShkc3QsIGgpOwogIHJldHVybiBkc3Q7Cn0KCmZ1bmN0aW9uIGludChzdHIpIHsKICByZXR1cm4gcGFyc2VJbnQoc3RyLCAxMCk7Cn0KCgpmdW5jdGlvbiBpbmhlcml0KHBhcmVudCwgZXh0cmEpIHsKICByZXR1cm4gZXh0ZW5kKE9iamVjdC5jcmVhdGUocGFyZW50KSwgZXh0cmEpOwp9CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIubm9vcAogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgbm8gb3BlcmF0aW9ucy4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZnVsIHdoZW4gd3JpdGluZyBjb2RlIGluIHRoZQogKiBmdW5jdGlvbmFsIHN0eWxlLgogICBgYGBqcwogICAgIGZ1bmN0aW9uIGZvbyhjYWxsYmFjaykgewogICAgICAgdmFyIHJlc3VsdCA9IGNhbGN1bGF0ZVJlc3VsdCgpOwogICAgICAgKGNhbGxiYWNrIHx8IGFuZ3VsYXIubm9vcCkocmVzdWx0KTsKICAgICB9CiAgIGBgYAogKi8KZnVuY3Rpb24gbm9vcCgpIHt9Cm5vb3AuJGluamVjdCA9IFtdOwoKCi8qKgogKiBAbmdkb2MgZnVuY3Rpb24KICogQG5hbWUgYW5ndWxhci5pZGVudGl0eQogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBpdHMgZmlyc3QgYXJndW1lbnQuIFRoaXMgZnVuY3Rpb24gaXMgdXNlZnVsIHdoZW4gd3JpdGluZyBjb2RlIGluIHRoZQogKiBmdW5jdGlvbmFsIHN0eWxlLgogKgogICBgYGBqcwogICAgIGZ1bmN0aW9uIHRyYW5zZm9ybWVyKHRyYW5zZm9ybWF0aW9uRm4sIHZhbHVlKSB7CiAgICAgICByZXR1cm4gKHRyYW5zZm9ybWF0aW9uRm4gfHwgYW5ndWxhci5pZGVudGl0eSkodmFsdWUpOwogICAgIH07CiAgIGBgYAogICogQHBhcmFtIHsqfSB2YWx1ZSB0byBiZSByZXR1cm5lZC4KICAqIEByZXR1cm5zIHsqfSB0aGUgdmFsdWUgcGFzc2VkIGluLgogKi8KZnVuY3Rpb24gaWRlbnRpdHkoJCkge3JldHVybiAkO30KaWRlbnRpdHkuJGluamVjdCA9IFtdOwoKCmZ1bmN0aW9uIHZhbHVlRm4odmFsdWUpIHtyZXR1cm4gZnVuY3Rpb24oKSB7cmV0dXJuIHZhbHVlO307fQoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLmlzVW5kZWZpbmVkCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERldGVybWluZXMgaWYgYSByZWZlcmVuY2UgaXMgdW5kZWZpbmVkLgogKgogKiBAcGFyYW0geyp9IHZhbHVlIFJlZmVyZW5jZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYHZhbHVlYCBpcyB1bmRlZmluZWQuCiAqLwpmdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge3JldHVybiB0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnO30KCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuaXNEZWZpbmVkCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERldGVybWluZXMgaWYgYSByZWZlcmVuY2UgaXMgZGVmaW5lZC4KICoKICogQHBhcmFtIHsqfSB2YWx1ZSBSZWZlcmVuY2UgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgZGVmaW5lZC4KICovCmZ1bmN0aW9uIGlzRGVmaW5lZCh2YWx1ZSkge3JldHVybiB0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnO30KCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuaXNPYmplY3QKICogQG1vZHVsZSBuZwogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogRGV0ZXJtaW5lcyBpZiBhIHJlZmVyZW5jZSBpcyBhbiBgT2JqZWN0YC4gVW5saWtlIGB0eXBlb2ZgIGluIEphdmFTY3JpcHQsIGBudWxsYHMgYXJlIG5vdAogKiBjb25zaWRlcmVkIHRvIGJlIG9iamVjdHMuIE5vdGUgdGhhdCBKYXZhU2NyaXB0IGFycmF5cyBhcmUgb2JqZWN0cy4KICoKICogQHBhcmFtIHsqfSB2YWx1ZSBSZWZlcmVuY2UgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgYW4gYE9iamVjdGAgYnV0IG5vdCBgbnVsbGAuCiAqLwpmdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkgewogIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2lzb2JqZWN0NAogIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnOwp9CgoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLmlzU3RyaW5nCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERldGVybWluZXMgaWYgYSByZWZlcmVuY2UgaXMgYSBgU3RyaW5nYC4KICoKICogQHBhcmFtIHsqfSB2YWx1ZSBSZWZlcmVuY2UgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgYSBgU3RyaW5nYC4KICovCmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7fQoKCi8qKgogKiBAbmdkb2MgZnVuY3Rpb24KICogQG5hbWUgYW5ndWxhci5pc051bWJlcgogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBEZXRlcm1pbmVzIGlmIGEgcmVmZXJlbmNlIGlzIGEgYE51bWJlcmAuCiAqCiAqIEBwYXJhbSB7Kn0gdmFsdWUgUmVmZXJlbmNlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBgdmFsdWVgIGlzIGEgYE51bWJlcmAuCiAqLwpmdW5jdGlvbiBpc051bWJlcih2YWx1ZSkge3JldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO30KCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuaXNEYXRlCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERldGVybWluZXMgaWYgYSB2YWx1ZSBpcyBhIGRhdGUuCiAqCiAqIEBwYXJhbSB7Kn0gdmFsdWUgUmVmZXJlbmNlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBgdmFsdWVgIGlzIGEgYERhdGVgLgogKi8KZnVuY3Rpb24gaXNEYXRlKHZhbHVlKSB7CiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBEYXRlXSc7Cn0KCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuaXNBcnJheQogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBEZXRlcm1pbmVzIGlmIGEgcmVmZXJlbmNlIGlzIGFuIGBBcnJheWAuCiAqCiAqIEBwYXJhbSB7Kn0gdmFsdWUgUmVmZXJlbmNlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBgdmFsdWVgIGlzIGFuIGBBcnJheWAuCiAqLwp2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuaXNGdW5jdGlvbgogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBEZXRlcm1pbmVzIGlmIGEgcmVmZXJlbmNlIGlzIGEgYEZ1bmN0aW9uYC4KICoKICogQHBhcmFtIHsqfSB2YWx1ZSBSZWZlcmVuY2UgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgYSBgRnVuY3Rpb25gLgogKi8KZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge3JldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7fQoKCi8qKgogKiBEZXRlcm1pbmVzIGlmIGEgdmFsdWUgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0LgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFJlZmVyZW5jZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYHZhbHVlYCBpcyBhIGBSZWdFeHBgLgogKi8KZnVuY3Rpb24gaXNSZWdFeHAodmFsdWUpIHsKICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nOwp9CgoKLyoqCiAqIENoZWNrcyBpZiBgb2JqYCBpcyBhIHdpbmRvdyBvYmplY3QuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdCB0byBjaGVjawogKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBgb2JqYCBpcyBhIHdpbmRvdyBvYmouCiAqLwpmdW5jdGlvbiBpc1dpbmRvdyhvYmopIHsKICByZXR1cm4gb2JqICYmIG9iai53aW5kb3cgPT09IG9iajsKfQoKCmZ1bmN0aW9uIGlzU2NvcGUob2JqKSB7CiAgcmV0dXJuIG9iaiAmJiBvYmouJGV2YWxBc3luYyAmJiBvYmouJHdhdGNoOwp9CgoKZnVuY3Rpb24gaXNGaWxlKG9iaikgewogIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEZpbGVdJzsKfQoKCmZ1bmN0aW9uIGlzRm9ybURhdGEob2JqKSB7CiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgRm9ybURhdGFdJzsKfQoKCmZ1bmN0aW9uIGlzQmxvYihvYmopIHsKICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBCbG9iXSc7Cn0KCgpmdW5jdGlvbiBpc0Jvb2xlYW4odmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbic7Cn0KCgpmdW5jdGlvbiBpc1Byb21pc2VMaWtlKG9iaikgewogIHJldHVybiBvYmogJiYgaXNGdW5jdGlvbihvYmoudGhlbik7Cn0KCgp2YXIgdHJpbSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgcmV0dXJuIGlzU3RyaW5nKHZhbHVlKSA/IHZhbHVlLnRyaW0oKSA6IHZhbHVlOwp9OwoKLy8gQ29waWVkIGZyb206Ci8vIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvbG9jYWxfY2xvc3VyZV9nb29nX3N0cmluZ19zdHJpbmcuanMuc291cmNlLmh0bWwjbGluZTEwMjEKLy8gUHJlcmVxOiBzIGlzIGEgc3RyaW5nLgp2YXIgZXNjYXBlRm9yUmVnZXhwID0gZnVuY3Rpb24ocykgewogIHJldHVybiBzLnJlcGxhY2UoLyhbLSgpXFtcXXt9Kz8qLiRcXnwsOiM8IVxcXSkvZywgJ1xcJDEnKS4KICAgICAgICAgICByZXBsYWNlKC9ceDA4L2csICdcXHgwOCcpOwp9OwoKCi8qKgogKiBAbmdkb2MgZnVuY3Rpb24KICogQG5hbWUgYW5ndWxhci5pc0VsZW1lbnQKICogQG1vZHVsZSBuZwogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogRGV0ZXJtaW5lcyBpZiBhIHJlZmVyZW5jZSBpcyBhIERPTSBlbGVtZW50IChvciB3cmFwcGVkIGpRdWVyeSBlbGVtZW50KS4KICoKICogQHBhcmFtIHsqfSB2YWx1ZSBSZWZlcmVuY2UgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgYSBET00gZWxlbWVudCAob3Igd3JhcHBlZCBqUXVlcnkgZWxlbWVudCkuCiAqLwpmdW5jdGlvbiBpc0VsZW1lbnQobm9kZSkgewogIHJldHVybiAhIShub2RlICYmCiAgICAobm9kZS5ub2RlTmFtZSAgLy8gd2UgYXJlIGEgZGlyZWN0IGVsZW1lbnQKICAgIHx8IChub2RlLnByb3AgJiYgbm9kZS5hdHRyICYmIG5vZGUuZmluZCkpKTsgIC8vIHdlIGhhdmUgYW4gb24gYW5kIGZpbmQgbWV0aG9kIHBhcnQgb2YgalF1ZXJ5IEFQSQp9CgovKioKICogQHBhcmFtIHN0ciAna2V5MSxrZXkyLC4uLicKICogQHJldHVybnMge29iamVjdH0gaW4gdGhlIGZvcm0gb2Yge2tleTE6dHJ1ZSwga2V5Mjp0cnVlLCAuLi59CiAqLwpmdW5jdGlvbiBtYWtlTWFwKHN0cikgewogIHZhciBvYmogPSB7fSwgaXRlbXMgPSBzdHIuc3BsaXQoIiwiKSwgaTsKICBmb3IgKGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspCiAgICBvYmpbIGl0ZW1zW2ldIF0gPSB0cnVlOwogIHJldHVybiBvYmo7Cn0KCgpmdW5jdGlvbiBub2RlTmFtZV8oZWxlbWVudCkgewogIHJldHVybiBsb3dlcmNhc2UoZWxlbWVudC5ub2RlTmFtZSB8fCAoZWxlbWVudFswXSAmJiBlbGVtZW50WzBdLm5vZGVOYW1lKSk7Cn0KCmZ1bmN0aW9uIGluY2x1ZGVzKGFycmF5LCBvYmopIHsKICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChhcnJheSwgb2JqKSAhPSAtMTsKfQoKZnVuY3Rpb24gYXJyYXlSZW1vdmUoYXJyYXksIHZhbHVlKSB7CiAgdmFyIGluZGV4ID0gYXJyYXkuaW5kZXhPZih2YWx1ZSk7CiAgaWYgKGluZGV4ID49IDApCiAgICBhcnJheS5zcGxpY2UoaW5kZXgsIDEpOwogIHJldHVybiB2YWx1ZTsKfQoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLmNvcHkKICogQG1vZHVsZSBuZwogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiBgc291cmNlYCwgd2hpY2ggc2hvdWxkIGJlIGFuIG9iamVjdCBvciBhbiBhcnJheS4KICoKICogKiBJZiBubyBkZXN0aW5hdGlvbiBpcyBzdXBwbGllZCwgYSBjb3B5IG9mIHRoZSBvYmplY3Qgb3IgYXJyYXkgaXMgY3JlYXRlZC4KICogKiBJZiBhIGRlc3RpbmF0aW9uIGlzIHByb3ZpZGVkLCBhbGwgb2YgaXRzIGVsZW1lbnRzIChmb3IgYXJyYXlzKSBvciBwcm9wZXJ0aWVzIChmb3Igb2JqZWN0cykKICogICBhcmUgZGVsZXRlZCBhbmQgdGhlbiBhbGwgZWxlbWVudHMvcHJvcGVydGllcyBmcm9tIHRoZSBzb3VyY2UgYXJlIGNvcGllZCB0byBpdC4KICogKiBJZiBgc291cmNlYCBpcyBub3QgYW4gb2JqZWN0IG9yIGFycmF5IChpbmMuIGBudWxsYCBhbmQgYHVuZGVmaW5lZGApLCBgc291cmNlYCBpcyByZXR1cm5lZC4KICogKiBJZiBgc291cmNlYCBpcyBpZGVudGljYWwgdG8gJ2Rlc3RpbmF0aW9uJyBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqCiAqIEBwYXJhbSB7Kn0gc291cmNlIFRoZSBzb3VyY2UgdGhhdCB3aWxsIGJlIHVzZWQgdG8gbWFrZSBhIGNvcHkuCiAqICAgICAgICAgICAgICAgICAgIENhbiBiZSBhbnkgdHlwZSwgaW5jbHVkaW5nIHByaW1pdGl2ZXMsIGBudWxsYCwgYW5kIGB1bmRlZmluZWRgLgogKiBAcGFyYW0geyhPYmplY3R8QXJyYXkpPX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gaW50byB3aGljaCB0aGUgc291cmNlIGlzIGNvcGllZC4gSWYKICogICAgIHByb3ZpZGVkLCBtdXN0IGJlIG9mIHRoZSBzYW1lIHR5cGUgYXMgYHNvdXJjZWAuCiAqIEByZXR1cm5zIHsqfSBUaGUgY29weSBvciB1cGRhdGVkIGBkZXN0aW5hdGlvbmAsIGlmIGBkZXN0aW5hdGlvbmAgd2FzIHNwZWNpZmllZC4KICoKICogQGV4YW1wbGUKIDxleGFtcGxlIG1vZHVsZT0iY29weUV4YW1wbGUiPgogPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KIDxmb3JtIG5vdmFsaWRhdGUgY2xhc3M9InNpbXBsZS1mb3JtIj4KIE5hbWU6IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1tb2RlbD0idXNlci5uYW1lIiAvPjxiciAvPgogRS1tYWlsOiA8aW5wdXQgdHlwZT0iZW1haWwiIG5nLW1vZGVsPSJ1c2VyLmVtYWlsIiAvPjxiciAvPgogR2VuZGVyOiA8aW5wdXQgdHlwZT0icmFkaW8iIG5nLW1vZGVsPSJ1c2VyLmdlbmRlciIgdmFsdWU9Im1hbGUiIC8+bWFsZQogPGlucHV0IHR5cGU9InJhZGlvIiBuZy1tb2RlbD0idXNlci5nZW5kZXIiIHZhbHVlPSJmZW1hbGUiIC8+ZmVtYWxlPGJyIC8+CiA8YnV0dG9uIG5nLWNsaWNrPSJyZXNldCgpIj5SRVNFVDwvYnV0dG9uPgogPGJ1dHRvbiBuZy1jbGljaz0idXBkYXRlKHVzZXIpIj5TQVZFPC9idXR0b24+CiA8L2Zvcm0+CiA8cHJlPmZvcm0gPSB7e3VzZXIgfCBqc29ufX08L3ByZT4KIDxwcmU+bWFzdGVyID0ge3ttYXN0ZXIgfCBqc29ufX08L3ByZT4KIDwvZGl2PgoKIDxzY3JpcHQ+CiAgYW5ndWxhci5tb2R1bGUoJ2NvcHlFeGFtcGxlJywgW10pCiAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAkc2NvcGUubWFzdGVyPSB7fTsKCiAgICAgICRzY29wZS51cGRhdGUgPSBmdW5jdGlvbih1c2VyKSB7CiAgICAgICAgLy8gRXhhbXBsZSB3aXRoIDEgYXJndW1lbnQKICAgICAgICAkc2NvcGUubWFzdGVyPSBhbmd1bGFyLmNvcHkodXNlcik7CiAgICAgIH07CgogICAgICAkc2NvcGUucmVzZXQgPSBmdW5jdGlvbigpIHsKICAgICAgICAvLyBFeGFtcGxlIHdpdGggMiBhcmd1bWVudHMKICAgICAgICBhbmd1bGFyLmNvcHkoJHNjb3BlLm1hc3RlciwgJHNjb3BlLnVzZXIpOwogICAgICB9OwoKICAgICAgJHNjb3BlLnJlc2V0KCk7CiAgICB9XSk7CiA8L3NjcmlwdD4KIDwvZmlsZT4KIDwvZXhhbXBsZT4KICovCmZ1bmN0aW9uIGNvcHkoc291cmNlLCBkZXN0aW5hdGlvbiwgc3RhY2tTb3VyY2UsIHN0YWNrRGVzdCkgewogIGlmIChpc1dpbmRvdyhzb3VyY2UpIHx8IGlzU2NvcGUoc291cmNlKSkgewogICAgdGhyb3cgbmdNaW5FcnIoJ2Nwd3MnLAogICAgICAiQ2FuJ3QgY29weSEgTWFraW5nIGNvcGllcyBvZiBXaW5kb3cgb3IgU2NvcGUgaW5zdGFuY2VzIGlzIG5vdCBzdXBwb3J0ZWQuIik7CiAgfQoKICBpZiAoIWRlc3RpbmF0aW9uKSB7CiAgICBkZXN0aW5hdGlvbiA9IHNvdXJjZTsKICAgIGlmIChzb3VyY2UpIHsKICAgICAgaWYgKGlzQXJyYXkoc291cmNlKSkgewogICAgICAgIGRlc3RpbmF0aW9uID0gY29weShzb3VyY2UsIFtdLCBzdGFja1NvdXJjZSwgc3RhY2tEZXN0KTsKICAgICAgfSBlbHNlIGlmIChpc0RhdGUoc291cmNlKSkgewogICAgICAgIGRlc3RpbmF0aW9uID0gbmV3IERhdGUoc291cmNlLmdldFRpbWUoKSk7CiAgICAgIH0gZWxzZSBpZiAoaXNSZWdFeHAoc291cmNlKSkgewogICAgICAgIGRlc3RpbmF0aW9uID0gbmV3IFJlZ0V4cChzb3VyY2Uuc291cmNlLCBzb3VyY2UudG9TdHJpbmcoKS5tYXRjaCgvW15cL10qJC8pWzBdKTsKICAgICAgICBkZXN0aW5hdGlvbi5sYXN0SW5kZXggPSBzb3VyY2UubGFzdEluZGV4OwogICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHNvdXJjZSkpIHsKICAgICAgICB2YXIgZW1wdHlPYmplY3QgPSBPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZihzb3VyY2UpKTsKICAgICAgICBkZXN0aW5hdGlvbiA9IGNvcHkoc291cmNlLCBlbXB0eU9iamVjdCwgc3RhY2tTb3VyY2UsIHN0YWNrRGVzdCk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgaWYgKHNvdXJjZSA9PT0gZGVzdGluYXRpb24pIHRocm93IG5nTWluRXJyKCdjcGknLAogICAgICAiQ2FuJ3QgY29weSEgU291cmNlIGFuZCBkZXN0aW5hdGlvbiBhcmUgaWRlbnRpY2FsLiIpOwoKICAgIHN0YWNrU291cmNlID0gc3RhY2tTb3VyY2UgfHwgW107CiAgICBzdGFja0Rlc3QgPSBzdGFja0Rlc3QgfHwgW107CgogICAgaWYgKGlzT2JqZWN0KHNvdXJjZSkpIHsKICAgICAgdmFyIGluZGV4ID0gc3RhY2tTb3VyY2UuaW5kZXhPZihzb3VyY2UpOwogICAgICBpZiAoaW5kZXggIT09IC0xKSByZXR1cm4gc3RhY2tEZXN0W2luZGV4XTsKCiAgICAgIHN0YWNrU291cmNlLnB1c2goc291cmNlKTsKICAgICAgc3RhY2tEZXN0LnB1c2goZGVzdGluYXRpb24pOwogICAgfQoKICAgIHZhciByZXN1bHQ7CiAgICBpZiAoaXNBcnJheShzb3VyY2UpKSB7CiAgICAgIGRlc3RpbmF0aW9uLmxlbmd0aCA9IDA7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgcmVzdWx0ID0gY29weShzb3VyY2VbaV0sIG51bGwsIHN0YWNrU291cmNlLCBzdGFja0Rlc3QpOwogICAgICAgIGlmIChpc09iamVjdChzb3VyY2VbaV0pKSB7CiAgICAgICAgICBzdGFja1NvdXJjZS5wdXNoKHNvdXJjZVtpXSk7CiAgICAgICAgICBzdGFja0Rlc3QucHVzaChyZXN1bHQpOwogICAgICAgIH0KICAgICAgICBkZXN0aW5hdGlvbi5wdXNoKHJlc3VsdCk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhciBoID0gZGVzdGluYXRpb24uJCRoYXNoS2V5OwogICAgICBpZiAoaXNBcnJheShkZXN0aW5hdGlvbikpIHsKICAgICAgICBkZXN0aW5hdGlvbi5sZW5ndGggPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIGZvckVhY2goZGVzdGluYXRpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICAgICAgICAgIGRlbGV0ZSBkZXN0aW5hdGlvbltrZXldOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsKICAgICAgICBpZiAoc291cmNlLmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgIHJlc3VsdCA9IGNvcHkoc291cmNlW2tleV0sIG51bGwsIHN0YWNrU291cmNlLCBzdGFja0Rlc3QpOwogICAgICAgICAgaWYgKGlzT2JqZWN0KHNvdXJjZVtrZXldKSkgewogICAgICAgICAgICBzdGFja1NvdXJjZS5wdXNoKHNvdXJjZVtrZXldKTsKICAgICAgICAgICAgc3RhY2tEZXN0LnB1c2gocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIGRlc3RpbmF0aW9uW2tleV0gPSByZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIHNldEhhc2hLZXkoZGVzdGluYXRpb24saCk7CiAgICB9CgogIH0KICByZXR1cm4gZGVzdGluYXRpb247Cn0KCi8qKgogKiBDcmVhdGVzIGEgc2hhbGxvdyBjb3B5IG9mIGFuIG9iamVjdCwgYW4gYXJyYXkgb3IgYSBwcmltaXRpdmUuCiAqCiAqIEFzc3VtZXMgdGhhdCB0aGVyZSBhcmUgbm8gcHJvdG8gcHJvcGVydGllcyBmb3Igb2JqZWN0cy4KICovCmZ1bmN0aW9uIHNoYWxsb3dDb3B5KHNyYywgZHN0KSB7CiAgaWYgKGlzQXJyYXkoc3JjKSkgewogICAgZHN0ID0gZHN0IHx8IFtdOwoKICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHNyYy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgIGRzdFtpXSA9IHNyY1tpXTsKICAgIH0KICB9IGVsc2UgaWYgKGlzT2JqZWN0KHNyYykpIHsKICAgIGRzdCA9IGRzdCB8fCB7fTsKCiAgICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7CiAgICAgIGlmICghKGtleS5jaGFyQXQoMCkgPT09ICckJyAmJiBrZXkuY2hhckF0KDEpID09PSAnJCcpKSB7CiAgICAgICAgZHN0W2tleV0gPSBzcmNba2V5XTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRzdCB8fCBzcmM7Cn0KCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuZXF1YWxzCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERldGVybWluZXMgaWYgdHdvIG9iamVjdHMgb3IgdHdvIHZhbHVlcyBhcmUgZXF1aXZhbGVudC4gU3VwcG9ydHMgdmFsdWUgdHlwZXMsIHJlZ3VsYXIKICogZXhwcmVzc2lvbnMsIGFycmF5cyBhbmQgb2JqZWN0cy4KICoKICogVHdvIG9iamVjdHMgb3IgdmFsdWVzIGFyZSBjb25zaWRlcmVkIGVxdWl2YWxlbnQgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgaXMgdHJ1ZToKICoKICogKiBCb3RoIG9iamVjdHMgb3IgdmFsdWVzIHBhc3MgYD09PWAgY29tcGFyaXNvbi4KICogKiBCb3RoIG9iamVjdHMgb3IgdmFsdWVzIGFyZSBvZiB0aGUgc2FtZSB0eXBlIGFuZCBhbGwgb2YgdGhlaXIgcHJvcGVydGllcyBhcmUgZXF1YWwgYnkKICogICBjb21wYXJpbmcgdGhlbSB3aXRoIGBhbmd1bGFyLmVxdWFsc2AuCiAqICogQm90aCB2YWx1ZXMgYXJlIE5hTi4gKEluIEphdmFTY3JpcHQsIE5hTiA9PSBOYU4gPT4gZmFsc2UuIEJ1dCB3ZSBjb25zaWRlciB0d28gTmFOIGFzIGVxdWFsKQogKiAqIEJvdGggdmFsdWVzIHJlcHJlc2VudCB0aGUgc2FtZSByZWd1bGFyIGV4cHJlc3Npb24gKEluIEphdmFTY3JpcHQsCiAqICAgL2FiYy8gPT0gL2FiYy8gPT4gZmFsc2UuIEJ1dCB3ZSBjb25zaWRlciB0d28gcmVndWxhciBleHByZXNzaW9ucyBhcyBlcXVhbCB3aGVuIHRoZWlyIHRleHR1YWwKICogICByZXByZXNlbnRhdGlvbiBtYXRjaGVzKS4KICoKICogRHVyaW5nIGEgcHJvcGVydHkgY29tcGFyaXNvbiwgcHJvcGVydGllcyBvZiBgZnVuY3Rpb25gIHR5cGUgYW5kIHByb3BlcnRpZXMgd2l0aCBuYW1lcwogKiB0aGF0IGJlZ2luIHdpdGggYCRgIGFyZSBpZ25vcmVkLgogKgogKiBTY29wZSBhbmQgRE9NV2luZG93IG9iamVjdHMgYXJlIGJlaW5nIGNvbXBhcmVkIG9ubHkgYnkgaWRlbnRpZnkgKGA9PT1gKS4KICoKICogQHBhcmFtIHsqfSBvMSBPYmplY3Qgb3IgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvMiBPYmplY3Qgb3IgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYXJndW1lbnRzIGFyZSBlcXVhbC4KICovCmZ1bmN0aW9uIGVxdWFscyhvMSwgbzIpIHsKICBpZiAobzEgPT09IG8yKSByZXR1cm4gdHJ1ZTsKICBpZiAobzEgPT09IG51bGwgfHwgbzIgPT09IG51bGwpIHJldHVybiBmYWxzZTsKICBpZiAobzEgIT09IG8xICYmIG8yICE9PSBvMikgcmV0dXJuIHRydWU7IC8vIE5hTiA9PT0gTmFOCiAgdmFyIHQxID0gdHlwZW9mIG8xLCB0MiA9IHR5cGVvZiBvMiwgbGVuZ3RoLCBrZXksIGtleVNldDsKICBpZiAodDEgPT0gdDIpIHsKICAgIGlmICh0MSA9PSAnb2JqZWN0JykgewogICAgICBpZiAoaXNBcnJheShvMSkpIHsKICAgICAgICBpZiAoIWlzQXJyYXkobzIpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKChsZW5ndGggPSBvMS5sZW5ndGgpID09IG8yLmxlbmd0aCkgewogICAgICAgICAgZm9yIChrZXkgPSAwOyBrZXkgPCBsZW5ndGg7IGtleSsrKSB7CiAgICAgICAgICAgIGlmICghZXF1YWxzKG8xW2tleV0sIG8yW2tleV0pKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKG8xKSkgewogICAgICAgIGlmICghaXNEYXRlKG8yKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiBlcXVhbHMobzEuZ2V0VGltZSgpLCBvMi5nZXRUaW1lKCkpOwogICAgICB9IGVsc2UgaWYgKGlzUmVnRXhwKG8xKSAmJiBpc1JlZ0V4cChvMikpIHsKICAgICAgICByZXR1cm4gbzEudG9TdHJpbmcoKSA9PSBvMi50b1N0cmluZygpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChpc1Njb3BlKG8xKSB8fCBpc1Njb3BlKG8yKSB8fCBpc1dpbmRvdyhvMSkgfHwgaXNXaW5kb3cobzIpIHx8IGlzQXJyYXkobzIpKSByZXR1cm4gZmFsc2U7CiAgICAgICAga2V5U2V0ID0ge307CiAgICAgICAgZm9yIChrZXkgaW4gbzEpIHsKICAgICAgICAgIGlmIChrZXkuY2hhckF0KDApID09PSAnJCcgfHwgaXNGdW5jdGlvbihvMVtrZXldKSkgY29udGludWU7CiAgICAgICAgICBpZiAoIWVxdWFscyhvMVtrZXldLCBvMltrZXldKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAga2V5U2V0W2tleV0gPSB0cnVlOwogICAgICAgIH0KICAgICAgICBmb3IgKGtleSBpbiBvMikgewogICAgICAgICAgaWYgKCFrZXlTZXQuaGFzT3duUHJvcGVydHkoa2V5KSAmJgogICAgICAgICAgICAgIGtleS5jaGFyQXQoMCkgIT09ICckJyAmJgogICAgICAgICAgICAgIG8yW2tleV0gIT09IHVuZGVmaW5lZCAmJgogICAgICAgICAgICAgICFpc0Z1bmN0aW9uKG8yW2tleV0pKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKdmFyIGNzcCA9IGZ1bmN0aW9uKCkgewogIGlmIChpc0RlZmluZWQoY3NwLmlzQWN0aXZlXykpIHJldHVybiBjc3AuaXNBY3RpdmVfOwoKICB2YXIgYWN0aXZlID0gISEoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25nLWNzcF0nKSB8fAogICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1uZy1jc3BdJykpOwoKICBpZiAoIWFjdGl2ZSkgewogICAgdHJ5IHsKICAgICAgLyoganNoaW50IC1XMDMxLCAtVzA1NCAqLwogICAgICBuZXcgRnVuY3Rpb24oJycpOwogICAgICAvKiBqc2hpbnQgK1cwMzEsICtXMDU0ICovCiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGFjdGl2ZSA9IHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gKGNzcC5pc0FjdGl2ZV8gPSBhY3RpdmUpOwp9OwoKCgpmdW5jdGlvbiBjb25jYXQoYXJyYXkxLCBhcnJheTIsIGluZGV4KSB7CiAgcmV0dXJuIGFycmF5MS5jb25jYXQoc2xpY2UuY2FsbChhcnJheTIsIGluZGV4KSk7Cn0KCmZ1bmN0aW9uIHNsaWNlQXJncyhhcmdzLCBzdGFydEluZGV4KSB7CiAgcmV0dXJuIHNsaWNlLmNhbGwoYXJncywgc3RhcnRJbmRleCB8fCAwKTsKfQoKCi8qIGpzaGludCAtVzEwMSAqLwovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuYmluZAogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBSZXR1cm5zIGEgZnVuY3Rpb24gd2hpY2ggY2FsbHMgZnVuY3Rpb24gYGZuYCBib3VuZCB0byBgc2VsZmAgKGBzZWxmYCBiZWNvbWVzIHRoZSBgdGhpc2AgZm9yCiAqIGBmbmApLiBZb3UgY2FuIHN1cHBseSBvcHRpb25hbCBgYXJnc2AgdGhhdCBhcmUgcHJlYm91bmQgdG8gdGhlIGZ1bmN0aW9uLiBUaGlzIGZlYXR1cmUgaXMgYWxzbwogKiBrbm93biBhcyBbcGFydGlhbCBhcHBsaWNhdGlvbl0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QYXJ0aWFsX2FwcGxpY2F0aW9uKSwgYXMKICogZGlzdGluZ3Vpc2hlZCBmcm9tIFtmdW5jdGlvbiBjdXJyeWluZ10oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DdXJyeWluZyNDb250cmFzdF93aXRoX3BhcnRpYWxfZnVuY3Rpb25fYXBwbGljYXRpb24pLgogKgogKiBAcGFyYW0ge09iamVjdH0gc2VsZiBDb250ZXh0IHdoaWNoIGBmbmAgc2hvdWxkIGJlIGV2YWx1YXRlZCBpbi4KICogQHBhcmFtIHtmdW5jdGlvbigpfSBmbiBGdW5jdGlvbiB0byBiZSBib3VuZC4KICogQHBhcmFtIHsuLi4qfSBhcmdzIE9wdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwcmVib3VuZCB0byB0aGUgYGZuYCBmdW5jdGlvbiBjYWxsLgogKiBAcmV0dXJucyB7ZnVuY3Rpb24oKX0gRnVuY3Rpb24gdGhhdCB3cmFwcyB0aGUgYGZuYCB3aXRoIGFsbCB0aGUgc3BlY2lmaWVkIGJpbmRpbmdzLgogKi8KLyoganNoaW50ICtXMTAxICovCmZ1bmN0aW9uIGJpbmQoc2VsZiwgZm4pIHsKICB2YXIgY3VycnlBcmdzID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBzbGljZUFyZ3MoYXJndW1lbnRzLCAyKSA6IFtdOwogIGlmIChpc0Z1bmN0aW9uKGZuKSAmJiAhKGZuIGluc3RhbmNlb2YgUmVnRXhwKSkgewogICAgcmV0dXJuIGN1cnJ5QXJncy5sZW5ndGgKICAgICAgPyBmdW5jdGlvbigpIHsKICAgICAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoCiAgICAgICAgICAgID8gZm4uYXBwbHkoc2VsZiwgY29uY2F0KGN1cnJ5QXJncywgYXJndW1lbnRzLCAwKSkKICAgICAgICAgICAgOiBmbi5hcHBseShzZWxmLCBjdXJyeUFyZ3MpOwogICAgICAgIH0KICAgICAgOiBmdW5jdGlvbigpIHsKICAgICAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoCiAgICAgICAgICAgID8gZm4uYXBwbHkoc2VsZiwgYXJndW1lbnRzKQogICAgICAgICAgICA6IGZuLmNhbGwoc2VsZik7CiAgICAgICAgfTsKICB9IGVsc2UgewogICAgLy8gaW4gSUUsIG5hdGl2ZSBtZXRob2RzIGFyZSBub3QgZnVuY3Rpb25zIHNvIHRoZXkgY2Fubm90IGJlIGJvdW5kIChub3RlOiB0aGV5IGRvbid0IG5lZWQgdG8gYmUpCiAgICByZXR1cm4gZm47CiAgfQp9CgoKZnVuY3Rpb24gdG9Kc29uUmVwbGFjZXIoa2V5LCB2YWx1ZSkgewogIHZhciB2YWwgPSB2YWx1ZTsKCiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmIGtleS5jaGFyQXQoMCkgPT09ICckJyAmJiBrZXkuY2hhckF0KDEpID09PSAnJCcpIHsKICAgIHZhbCA9IHVuZGVmaW5lZDsKICB9IGVsc2UgaWYgKGlzV2luZG93KHZhbHVlKSkgewogICAgdmFsID0gJyRXSU5ET1cnOwogIH0gZWxzZSBpZiAodmFsdWUgJiYgIGRvY3VtZW50ID09PSB2YWx1ZSkgewogICAgdmFsID0gJyRET0NVTUVOVCc7CiAgfSBlbHNlIGlmIChpc1Njb3BlKHZhbHVlKSkgewogICAgdmFsID0gJyRTQ09QRSc7CiAgfQoKICByZXR1cm4gdmFsOwp9CgoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLnRvSnNvbgogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBTZXJpYWxpemVzIGlucHV0IGludG8gYSBKU09OLWZvcm1hdHRlZCBzdHJpbmcuIFByb3BlcnRpZXMgd2l0aCBsZWFkaW5nICQkIGNoYXJhY3RlcnMgd2lsbCBiZQogKiBzdHJpcHBlZCBzaW5jZSBhbmd1bGFyIHVzZXMgdGhpcyBub3RhdGlvbiBpbnRlcm5hbGx5LgogKgogKiBAcGFyYW0ge09iamVjdHxBcnJheXxEYXRlfHN0cmluZ3xudW1iZXJ9IG9iaiBJbnB1dCB0byBiZSBzZXJpYWxpemVkIGludG8gSlNPTi4KICogQHBhcmFtIHtib29sZWFufG51bWJlcj19IHByZXR0eSBJZiBzZXQgdG8gdHJ1ZSwgdGhlIEpTT04gb3V0cHV0IHdpbGwgY29udGFpbiBuZXdsaW5lcyBhbmQgd2hpdGVzcGFjZS4KICogICAgSWYgc2V0IHRvIGFuIGludGVnZXIsIHRoZSBKU09OIG91dHB1dCB3aWxsIGNvbnRhaW4gdGhhdCBtYW55IHNwYWNlcyBwZXIgaW5kZW50YXRpb24gKHRoZSBkZWZhdWx0IGlzIDIpLgogKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gSlNPTi1pZmllZCBzdHJpbmcgcmVwcmVzZW50aW5nIGBvYmpgLgogKi8KZnVuY3Rpb24gdG9Kc29uKG9iaiwgcHJldHR5KSB7CiAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSByZXR1cm4gdW5kZWZpbmVkOwogIGlmICghaXNOdW1iZXIocHJldHR5KSkgewogICAgcHJldHR5ID0gcHJldHR5ID8gMiA6IG51bGw7CiAgfQogIHJldHVybiBKU09OLnN0cmluZ2lmeShvYmosIHRvSnNvblJlcGxhY2VyLCBwcmV0dHkpOwp9CgoKLyoqCiAqIEBuZ2RvYyBmdW5jdGlvbgogKiBAbmFtZSBhbmd1bGFyLmZyb21Kc29uCiAqIEBtb2R1bGUgbmcKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIERlc2VyaWFsaXplcyBhIEpTT04gc3RyaW5nLgogKgogKiBAcGFyYW0ge3N0cmluZ30ganNvbiBKU09OIHN0cmluZyB0byBkZXNlcmlhbGl6ZS4KICogQHJldHVybnMge09iamVjdHxBcnJheXxzdHJpbmd8bnVtYmVyfSBEZXNlcmlhbGl6ZWQgSlNPTiBzdHJpbmcuCiAqLwpmdW5jdGlvbiBmcm9tSnNvbihqc29uKSB7CiAgcmV0dXJuIGlzU3RyaW5nKGpzb24pCiAgICAgID8gSlNPTi5wYXJzZShqc29uKQogICAgICA6IGpzb247Cn0KCgovKioKICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50LgogKi8KZnVuY3Rpb24gc3RhcnRpbmdUYWcoZWxlbWVudCkgewogIGVsZW1lbnQgPSBqcUxpdGUoZWxlbWVudCkuY2xvbmUoKTsKICB0cnkgewogICAgLy8gdHVybnMgb3V0IElFIGRvZXMgbm90IGxldCB5b3Ugc2V0IC5odG1sKCkgb24gZWxlbWVudHMgd2hpY2gKICAgIC8vIGFyZSBub3QgYWxsb3dlZCB0byBoYXZlIGNoaWxkcmVuLiBTbyB3ZSBqdXN0IGlnbm9yZSBpdC4KICAgIGVsZW1lbnQuZW1wdHkoKTsKICB9IGNhdGNoIChlKSB7fQogIHZhciBlbGVtSHRtbCA9IGpxTGl0ZSgnPGRpdj4nKS5hcHBlbmQoZWxlbWVudCkuaHRtbCgpOwogIHRyeSB7CiAgICByZXR1cm4gZWxlbWVudFswXS5ub2RlVHlwZSA9PT0gTk9ERV9UWVBFX1RFWFQgPyBsb3dlcmNhc2UoZWxlbUh0bWwpIDoKICAgICAgICBlbGVtSHRtbC4KICAgICAgICAgIG1hdGNoKC9eKDxbXj5dKz4pLylbMV0uCiAgICAgICAgICByZXBsYWNlKC9ePChbXHdcLV0rKS8sIGZ1bmN0aW9uKG1hdGNoLCBub2RlTmFtZSkgeyByZXR1cm4gJzwnICsgbG93ZXJjYXNlKG5vZGVOYW1lKTsgfSk7CiAgfSBjYXRjaCAoZSkgewogICAgcmV0dXJuIGxvd2VyY2FzZShlbGVtSHRtbCk7CiAgfQoKfQoKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8qKgogKiBUcmllcyB0byBkZWNvZGUgdGhlIFVSSSBjb21wb25lbnQgd2l0aG91dCB0aHJvd2luZyBhbiBleGNlcHRpb24uCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSBzdHIgdmFsdWUgcG90ZW50aWFsIFVSSSBjb21wb25lbnQgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgY2FuIGJlIGRlY29kZWQKICogd2l0aCB0aGUgZGVjb2RlVVJJQ29tcG9uZW50IGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gdHJ5RGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSB7CiAgdHJ5IHsKICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQodmFsdWUpOwogIH0gY2F0Y2ggKGUpIHsKICAgIC8vIElnbm9yZSBhbnkgaW52YWxpZCB1cmkgY29tcG9uZW50CiAgfQp9CgoKLyoqCiAqIFBhcnNlcyBhbiBlc2NhcGVkIHVybCBxdWVyeSBzdHJpbmcgaW50byBrZXktdmFsdWUgcGFpcnMuCiAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZyxib29sZWFufEFycmF5Pn0KICovCmZ1bmN0aW9uIHBhcnNlS2V5VmFsdWUoLyoqc3RyaW5nKi9rZXlWYWx1ZSkgewogIHZhciBvYmogPSB7fSwga2V5X3ZhbHVlLCBrZXk7CiAgZm9yRWFjaCgoa2V5VmFsdWUgfHwgIiIpLnNwbGl0KCcmJyksIGZ1bmN0aW9uKGtleVZhbHVlKSB7CiAgICBpZiAoa2V5VmFsdWUpIHsKICAgICAga2V5X3ZhbHVlID0ga2V5VmFsdWUucmVwbGFjZSgvXCsvZywnJTIwJykuc3BsaXQoJz0nKTsKICAgICAga2V5ID0gdHJ5RGVjb2RlVVJJQ29tcG9uZW50KGtleV92YWx1ZVswXSk7CiAgICAgIGlmIChpc0RlZmluZWQoa2V5KSkgewogICAgICAgIHZhciB2YWwgPSBpc0RlZmluZWQoa2V5X3ZhbHVlWzFdKSA/IHRyeURlY29kZVVSSUNvbXBvbmVudChrZXlfdmFsdWVbMV0pIDogdHJ1ZTsKICAgICAgICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7CiAgICAgICAgICBvYmpba2V5XSA9IHZhbDsKICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqW2tleV0pKSB7CiAgICAgICAgICBvYmpba2V5XS5wdXNoKHZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9ialtrZXldID0gW29ialtrZXldLHZhbF07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSk7CiAgcmV0dXJuIG9iajsKfQoKZnVuY3Rpb24gdG9LZXlWYWx1ZShvYmopIHsKICB2YXIgcGFydHMgPSBbXTsKICBmb3JFYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGtleSkgewogICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7CiAgICAgIGZvckVhY2godmFsdWUsIGZ1bmN0aW9uKGFycmF5VmFsdWUpIHsKICAgICAgICBwYXJ0cy5wdXNoKGVuY29kZVVyaVF1ZXJ5KGtleSwgdHJ1ZSkgKwogICAgICAgICAgICAgICAgICAgKGFycmF5VmFsdWUgPT09IHRydWUgPyAnJyA6ICc9JyArIGVuY29kZVVyaVF1ZXJ5KGFycmF5VmFsdWUsIHRydWUpKSk7CiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgIHBhcnRzLnB1c2goZW5jb2RlVXJpUXVlcnkoa2V5LCB0cnVlKSArCiAgICAgICAgICAgICAgICh2YWx1ZSA9PT0gdHJ1ZSA/ICcnIDogJz0nICsgZW5jb2RlVXJpUXVlcnkodmFsdWUsIHRydWUpKSk7CiAgICB9CiAgfSk7CiAgcmV0dXJuIHBhcnRzLmxlbmd0aCA/IHBhcnRzLmpvaW4oJyYnKSA6ICcnOwp9CgoKLyoqCiAqIFdlIG5lZWQgb3VyIGN1c3RvbSBtZXRob2QgYmVjYXVzZSBlbmNvZGVVUklDb21wb25lbnQgaXMgdG9vIGFnZ3Jlc3NpdmUgYW5kIGRvZXNuJ3QgZm9sbG93CiAqIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM5ODYudHh0IHdpdGggcmVnYXJkcyB0byB0aGUgY2hhcmFjdGVyIHNldCAocGNoYXIpIGFsbG93ZWQgaW4gcGF0aAogKiBzZWdtZW50czoKICogICAgc2VnbWVudCAgICAgICA9ICpwY2hhcgogKiAgICBwY2hhciAgICAgICAgID0gdW5yZXNlcnZlZCAvIHBjdC1lbmNvZGVkIC8gc3ViLWRlbGltcyAvICI6IiAvICJAIgogKiAgICBwY3QtZW5jb2RlZCAgID0gIiUiIEhFWERJRyBIRVhESUcKICogICAgdW5yZXNlcnZlZCAgICA9IEFMUEhBIC8gRElHSVQgLyAiLSIgLyAiLiIgLyAiXyIgLyAifiIKICogICAgc3ViLWRlbGltcyAgICA9ICIhIiAvICIkIiAvICImIiAvICInIiAvICIoIiAvICIpIgogKiAgICAgICAgICAgICAgICAgICAgIC8gIioiIC8gIisiIC8gIiwiIC8gIjsiIC8gIj0iCiAqLwpmdW5jdGlvbiBlbmNvZGVVcmlTZWdtZW50KHZhbCkgewogIHJldHVybiBlbmNvZGVVcmlRdWVyeSh2YWwsIHRydWUpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTI2L2dpLCAnJicpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTNEL2dpLCAnPScpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTJCL2dpLCAnKycpOwp9CgoKLyoqCiAqIFRoaXMgbWV0aG9kIGlzIGludGVuZGVkIGZvciBlbmNvZGluZyAqa2V5KiBvciAqdmFsdWUqIHBhcnRzIG9mIHF1ZXJ5IGNvbXBvbmVudC4gV2UgbmVlZCBhIGN1c3RvbQogKiBtZXRob2QgYmVjYXVzZSBlbmNvZGVVUklDb21wb25lbnQgaXMgdG9vIGFnZ3Jlc3NpdmUgYW5kIGVuY29kZXMgc3R1ZmYgdGhhdCBkb2Vzbid0IGhhdmUgdG8gYmUKICogZW5jb2RlZCBwZXIgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzk4NjoKICogICAgcXVlcnkgICAgICAgPSAqKCBwY2hhciAvICIvIiAvICI/IiApCiAqICAgIHBjaGFyICAgICAgICAgPSB1bnJlc2VydmVkIC8gcGN0LWVuY29kZWQgLyBzdWItZGVsaW1zIC8gIjoiIC8gIkAiCiAqICAgIHVucmVzZXJ2ZWQgICAgPSBBTFBIQSAvIERJR0lUIC8gIi0iIC8gIi4iIC8gIl8iIC8gIn4iCiAqICAgIHBjdC1lbmNvZGVkICAgPSAiJSIgSEVYRElHIEhFWERJRwogKiAgICBzdWItZGVsaW1zICAgID0gIiEiIC8gIiQiIC8gIiYiIC8gIiciIC8gIigiIC8gIikiCiAqICAgICAgICAgICAgICAgICAgICAgLyAiKiIgLyAiKyIgLyAiLCIgLyAiOyIgLyAiPSIKICovCmZ1bmN0aW9uIGVuY29kZVVyaVF1ZXJ5KHZhbCwgcGN0RW5jb2RlU3BhY2VzKSB7CiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh2YWwpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTQwL2dpLCAnQCcpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLgogICAgICAgICAgICAgcmVwbGFjZSgvJTI0L2csICckJykuCiAgICAgICAgICAgICByZXBsYWNlKC8lMkMvZ2ksICcsJykuCiAgICAgICAgICAgICByZXBsYWNlKC8lM0IvZ2ksICc7JykuCiAgICAgICAgICAgICByZXBsYWNlKC8lMjAvZywgKHBjdEVuY29kZVNwYWNlcyA/ICclMjAnIDogJysnKSk7Cn0KCnZhciBuZ0F0dHJQcmVmaXhlcyA9IFsnbmctJywgJ2RhdGEtbmctJywgJ25nOicsICd4LW5nLSddOwoKZnVuY3Rpb24gZ2V0TmdBdHRyaWJ1dGUoZWxlbWVudCwgbmdBdHRyKSB7CiAgdmFyIGF0dHIsIGksIGlpID0gbmdBdHRyUHJlZml4ZXMubGVuZ3RoOwogIGVsZW1lbnQgPSBqcUxpdGUoZWxlbWVudCk7CiAgZm9yIChpID0gMDsgaSA8IGlpOyArK2kpIHsKICAgIGF0dHIgPSBuZ0F0dHJQcmVmaXhlc1tpXSArIG5nQXR0cjsKICAgIGlmIChpc1N0cmluZyhhdHRyID0gZWxlbWVudC5hdHRyKGF0dHIpKSkgewogICAgICByZXR1cm4gYXR0cjsKICAgIH0KICB9CiAgcmV0dXJuIG51bGw7Cn0KCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQXBwCiAqIEBtb2R1bGUgbmcKICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7YW5ndWxhci5Nb2R1bGV9IG5nQXBwIGFuIG9wdGlvbmFsIGFwcGxpY2F0aW9uCiAqICAge0BsaW5rIGFuZ3VsYXIubW9kdWxlIG1vZHVsZX0gbmFtZSB0byBsb2FkLgogKiBAcGFyYW0ge2Jvb2xlYW49fSBuZ1N0cmljdERpIGlmIHRoaXMgYXR0cmlidXRlIGlzIHByZXNlbnQgb24gdGhlIGFwcCBlbGVtZW50LCB0aGUgaW5qZWN0b3Igd2lsbCBiZQogKiAgIGNyZWF0ZWQgaW4gInN0cmljdC1kaSIgbW9kZS4gVGhpcyBtZWFucyB0aGF0IHRoZSBhcHBsaWNhdGlvbiB3aWxsIGZhaWwgdG8gaW52b2tlIGZ1bmN0aW9ucyB3aGljaAogKiAgIGRvIG5vdCB1c2UgZXhwbGljaXQgZnVuY3Rpb24gYW5ub3RhdGlvbiAoYW5kIGFyZSB0aHVzIHVuc3VpdGFibGUgZm9yIG1pbmlmaWNhdGlvbiksIGFzIGRlc2NyaWJlZAogKiAgIGluIHtAbGluayBndWlkZS9kaSB0aGUgRGVwZW5kZW5jeSBJbmplY3Rpb24gZ3VpZGV9LCBhbmQgdXNlZnVsIGRlYnVnZ2luZyBpbmZvIHdpbGwgYXNzaXN0IGluCiAqICAgdHJhY2tpbmcgZG93biB0aGUgcm9vdCBvZiB0aGVzZSBidWdzLgogKgogKiBAZGVzY3JpcHRpb24KICoKICogVXNlIHRoaXMgZGlyZWN0aXZlIHRvICoqYXV0by1ib290c3RyYXAqKiBhbiBBbmd1bGFySlMgYXBwbGljYXRpb24uIFRoZSBgbmdBcHBgIGRpcmVjdGl2ZQogKiBkZXNpZ25hdGVzIHRoZSAqKnJvb3QgZWxlbWVudCoqIG9mIHRoZSBhcHBsaWNhdGlvbiBhbmQgaXMgdHlwaWNhbGx5IHBsYWNlZCBuZWFyIHRoZSByb290IGVsZW1lbnQKICogb2YgdGhlIHBhZ2UgLSBlLmcuIG9uIHRoZSBgPGJvZHk+YCBvciBgPGh0bWw+YCB0YWdzLgogKgogKiBPbmx5IG9uZSBBbmd1bGFySlMgYXBwbGljYXRpb24gY2FuIGJlIGF1dG8tYm9vdHN0cmFwcGVkIHBlciBIVE1MIGRvY3VtZW50LiBUaGUgZmlyc3QgYG5nQXBwYAogKiBmb3VuZCBpbiB0aGUgZG9jdW1lbnQgd2lsbCBiZSB1c2VkIHRvIGRlZmluZSB0aGUgcm9vdCBlbGVtZW50IHRvIGF1dG8tYm9vdHN0cmFwIGFzIGFuCiAqIGFwcGxpY2F0aW9uLiBUbyBydW4gbXVsdGlwbGUgYXBwbGljYXRpb25zIGluIGFuIEhUTUwgZG9jdW1lbnQgeW91IG11c3QgbWFudWFsbHkgYm9vdHN0cmFwIHRoZW0gdXNpbmcKICoge0BsaW5rIGFuZ3VsYXIuYm9vdHN0cmFwfSBpbnN0ZWFkLiBBbmd1bGFySlMgYXBwbGljYXRpb25zIGNhbm5vdCBiZSBuZXN0ZWQgd2l0aGluIGVhY2ggb3RoZXIuCiAqCiAqIFlvdSBjYW4gc3BlY2lmeSBhbiAqKkFuZ3VsYXJKUyBtb2R1bGUqKiB0byBiZSB1c2VkIGFzIHRoZSByb290IG1vZHVsZSBmb3IgdGhlIGFwcGxpY2F0aW9uLiAgVGhpcwogKiBtb2R1bGUgd2lsbCBiZSBsb2FkZWQgaW50byB0aGUge0BsaW5rIGF1dG8uJGluamVjdG9yfSB3aGVuIHRoZSBhcHBsaWNhdGlvbiBpcyBib290c3RyYXBwZWQuIEl0CiAqIHNob3VsZCBjb250YWluIHRoZSBhcHBsaWNhdGlvbiBjb2RlIG5lZWRlZCBvciBoYXZlIGRlcGVuZGVuY2llcyBvbiBvdGhlciBtb2R1bGVzIHRoYXQgd2lsbAogKiBjb250YWluIHRoZSBjb2RlLiBTZWUge0BsaW5rIGFuZ3VsYXIubW9kdWxlfSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICoKICogSW4gdGhlIGV4YW1wbGUgYmVsb3cgaWYgdGhlIGBuZ0FwcGAgZGlyZWN0aXZlIHdlcmUgbm90IHBsYWNlZCBvbiB0aGUgYGh0bWxgIGVsZW1lbnQgdGhlbiB0aGUKICogZG9jdW1lbnQgd291bGQgbm90IGJlIGNvbXBpbGVkLCB0aGUgYEFwcENvbnRyb2xsZXJgIHdvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgYW5kIHRoZSBge3sgYStiIH19YAogKiB3b3VsZCBub3QgYmUgcmVzb2x2ZWQgdG8gYDNgLgogKgogKiBgbmdBcHBgIGlzIHRoZSBlYXNpZXN0LCBhbmQgbW9zdCBjb21tb24gd2F5IHRvIGJvb3RzdHJhcCBhbiBhcHBsaWNhdGlvbi4KICoKIDxleGFtcGxlIG1vZHVsZT0ibmdBcHBEZW1vIj4KICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgIDxkaXYgbmctY29udHJvbGxlcj0ibmdBcHBEZW1vQ29udHJvbGxlciI+CiAgICAgSSBjYW4gYWRkOiB7e2F9fSArIHt7Yn19ID0gIHt7IGErYiB9fQogICA8L2Rpdj4KICAgPC9maWxlPgogICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICBhbmd1bGFyLm1vZHVsZSgnbmdBcHBEZW1vJywgW10pLmNvbnRyb2xsZXIoJ25nQXBwRGVtb0NvbnRyb2xsZXInLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAkc2NvcGUuYSA9IDE7CiAgICAgJHNjb3BlLmIgPSAyOwogICB9KTsKICAgPC9maWxlPgogPC9leGFtcGxlPgogKgogKiBVc2luZyBgbmdTdHJpY3REaWAsIHlvdSB3b3VsZCBzZWUgc29tZXRoaW5nIGxpa2UgdGhpczoKICoKIDxleGFtcGxlIG5nLWFwcC1pbmNsdWRlZD0idHJ1ZSI+CiAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICA8ZGl2IG5nLWFwcD0ibmdBcHBTdHJpY3REZW1vIiBuZy1zdHJpY3QtZGk+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9Ikdvb2RDb250cm9sbGVyMSI+CiAgICAgICAgICAgSSBjYW4gYWRkOiB7e2F9fSArIHt7Yn19ID0gIHt7IGErYiB9fQoKICAgICAgICAgICA8cD5UaGlzIHJlbmRlcnMgYmVjYXVzZSB0aGUgY29udHJvbGxlciBkb2VzIG5vdCBmYWlsIHRvCiAgICAgICAgICAgICAgaW5zdGFudGlhdGUsIGJ5IHVzaW5nIGV4cGxpY2l0IGFubm90YXRpb24gc3R5bGUgKHNlZQogICAgICAgICAgICAgIHNjcmlwdC5qcyBmb3IgZGV0YWlscykKICAgICAgICAgICA8L3A+CiAgICAgICA8L2Rpdj4KCiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9Ikdvb2RDb250cm9sbGVyMiI+CiAgICAgICAgICAgTmFtZTogPGlucHV0IG5nLW1vZGVsPSJuYW1lIj48YnIgLz4KICAgICAgICAgICBIZWxsbywge3tuYW1lfX0hCgogICAgICAgICAgIDxwPlRoaXMgcmVuZGVycyBiZWNhdXNlIHRoZSBjb250cm9sbGVyIGRvZXMgbm90IGZhaWwgdG8KICAgICAgICAgICAgICBpbnN0YW50aWF0ZSwgYnkgdXNpbmcgZXhwbGljaXQgYW5ub3RhdGlvbiBzdHlsZQogICAgICAgICAgICAgIChzZWUgc2NyaXB0LmpzIGZvciBkZXRhaWxzKQogICAgICAgICAgIDwvcD4KICAgICAgIDwvZGl2PgoKICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iQmFkQ29udHJvbGxlciI+CiAgICAgICAgICAgSSBjYW4gYWRkOiB7e2F9fSArIHt7Yn19ID0gIHt7IGErYiB9fQoKICAgICAgICAgICA8cD5UaGUgY29udHJvbGxlciBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLCBkdWUgdG8gcmVseWluZwogICAgICAgICAgICAgIG9uIGF1dG9tYXRpYyBmdW5jdGlvbiBhbm5vdGF0aW9ucyAod2hpY2ggYXJlIGRpc2FibGVkIGluCiAgICAgICAgICAgICAgc3RyaWN0IG1vZGUpLiBBcyBzdWNoLCB0aGUgY29udGVudCBvZiB0aGlzIHNlY3Rpb24gaXMgbm90CiAgICAgICAgICAgICAgaW50ZXJwb2xhdGVkLCBhbmQgdGhlcmUgc2hvdWxkIGJlIGFuIGVycm9yIGluIHlvdXIgd2ViIGNvbnNvbGUuCiAgICAgICAgICAgPC9wPgogICAgICAgPC9kaXY+CiAgIDwvZGl2PgogICA8L2ZpbGU+CiAgIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+CiAgIGFuZ3VsYXIubW9kdWxlKCduZ0FwcFN0cmljdERlbW8nLCBbXSkKICAgICAvLyBCYWRDb250cm9sbGVyIHdpbGwgZmFpbCB0byBpbnN0YW50aWF0ZSwgZHVlIHRvIHJlbHlpbmcgb24gYXV0b21hdGljIGZ1bmN0aW9uIGFubm90YXRpb24sCiAgICAgLy8gcmF0aGVyIHRoYW4gYW4gZXhwbGljaXQgYW5ub3RhdGlvbgogICAgIC5jb250cm9sbGVyKCdCYWRDb250cm9sbGVyJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAkc2NvcGUuYSA9IDE7CiAgICAgICAkc2NvcGUuYiA9IDI7CiAgICAgfSkKICAgICAvLyBVbmxpa2UgQmFkQ29udHJvbGxlciwgR29vZENvbnRyb2xsZXIxIGFuZCBHb29kQ29udHJvbGxlcjIgd2lsbCBub3QgZmFpbCB0byBiZSBpbnN0YW50aWF0ZWQsCiAgICAgLy8gZHVlIHRvIHVzaW5nIGV4cGxpY2l0IGFubm90YXRpb25zIHVzaW5nIHRoZSBhcnJheSBzdHlsZSBhbmQgJGluamVjdCBwcm9wZXJ0eSwgcmVzcGVjdGl2ZWx5LgogICAgIC5jb250cm9sbGVyKCdHb29kQ29udHJvbGxlcjEnLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgJHNjb3BlLmEgPSAxOwogICAgICAgJHNjb3BlLmIgPSAyOwogICAgIH1dKQogICAgIC5jb250cm9sbGVyKCdHb29kQ29udHJvbGxlcjInLCBHb29kQ29udHJvbGxlcjIpOwogICAgIGZ1bmN0aW9uIEdvb2RDb250cm9sbGVyMigkc2NvcGUpIHsKICAgICAgICRzY29wZS5uYW1lID0gIldvcmxkIjsKICAgICB9CiAgICAgR29vZENvbnRyb2xsZXIyLiRpbmplY3QgPSBbJyRzY29wZSddOwogICA8L2ZpbGU+CiAgIDxmaWxlIG5hbWU9InN0eWxlLmNzcyI+CiAgIGRpdltuZy1jb250cm9sbGVyXSB7CiAgICAgICBtYXJnaW4tYm90dG9tOiAxZW07CiAgICAgICAtd2Via2l0LWJvcmRlci1yYWRpdXM6IDRweDsKICAgICAgIGJvcmRlci1yYWRpdXM6IDRweDsKICAgICAgIGJvcmRlcjogMXB4IHNvbGlkOwogICAgICAgcGFkZGluZzogLjVlbTsKICAgfQogICBkaXZbbmctY29udHJvbGxlcl49R29vZF0gewogICAgICAgYm9yZGVyLWNvbG9yOiAjZDZlOWM2OwogICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2RmZjBkODsKICAgICAgIGNvbG9yOiAjM2M3NjNkOwogICB9CiAgIGRpdltuZy1jb250cm9sbGVyXj1CYWRdIHsKICAgICAgIGJvcmRlci1jb2xvcjogI2ViY2NkMTsKICAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmMmRlZGU7CiAgICAgICBjb2xvcjogI2E5NDQ0MjsKICAgICAgIG1hcmdpbi1ib3R0b206IDA7CiAgIH0KICAgPC9maWxlPgogPC9leGFtcGxlPgogKi8KZnVuY3Rpb24gYW5ndWxhckluaXQoZWxlbWVudCwgYm9vdHN0cmFwKSB7CiAgdmFyIGFwcEVsZW1lbnQsCiAgICAgIG1vZHVsZSwKICAgICAgY29uZmlnID0ge307CgogIC8vIFRoZSBlbGVtZW50IGBlbGVtZW50YCBoYXMgcHJpb3JpdHkgb3ZlciBhbnkgb3RoZXIgZWxlbWVudAogIGZvckVhY2gobmdBdHRyUHJlZml4ZXMsIGZ1bmN0aW9uKHByZWZpeCkgewogICAgdmFyIG5hbWUgPSBwcmVmaXggKyAnYXBwJzsKCiAgICBpZiAoIWFwcEVsZW1lbnQgJiYgZWxlbWVudC5oYXNBdHRyaWJ1dGUgJiYgZWxlbWVudC5oYXNBdHRyaWJ1dGUobmFtZSkpIHsKICAgICAgYXBwRWxlbWVudCA9IGVsZW1lbnQ7CiAgICAgIG1vZHVsZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKG5hbWUpOwogICAgfQogIH0pOwogIGZvckVhY2gobmdBdHRyUHJlZml4ZXMsIGZ1bmN0aW9uKHByZWZpeCkgewogICAgdmFyIG5hbWUgPSBwcmVmaXggKyAnYXBwJzsKICAgIHZhciBjYW5kaWRhdGU7CgogICAgaWYgKCFhcHBFbGVtZW50ICYmIChjYW5kaWRhdGUgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ1snICsgbmFtZS5yZXBsYWNlKCc6JywgJ1xcOicpICsgJ10nKSkpIHsKICAgICAgYXBwRWxlbWVudCA9IGNhbmRpZGF0ZTsKICAgICAgbW9kdWxlID0gY2FuZGlkYXRlLmdldEF0dHJpYnV0ZShuYW1lKTsKICAgIH0KICB9KTsKICBpZiAoYXBwRWxlbWVudCkgewogICAgY29uZmlnLnN0cmljdERpID0gZ2V0TmdBdHRyaWJ1dGUoYXBwRWxlbWVudCwgInN0cmljdC1kaSIpICE9PSBudWxsOwogICAgYm9vdHN0cmFwKGFwcEVsZW1lbnQsIG1vZHVsZSA/IFttb2R1bGVdIDogW10sIGNvbmZpZyk7CiAgfQp9CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuYm9vdHN0cmFwCiAqIEBtb2R1bGUgbmcKICogQGRlc2NyaXB0aW9uCiAqIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIG1hbnVhbGx5IHN0YXJ0IHVwIGFuZ3VsYXIgYXBwbGljYXRpb24uCiAqCiAqIFNlZToge0BsaW5rIGd1aWRlL2Jvb3RzdHJhcCBCb290c3RyYXB9CiAqCiAqIE5vdGUgdGhhdCBQcm90cmFjdG9yIGJhc2VkIGVuZC10by1lbmQgdGVzdHMgY2Fubm90IHVzZSB0aGlzIGZ1bmN0aW9uIHRvIGJvb3RzdHJhcCBtYW51YWxseS4KICogVGhleSBtdXN0IHVzZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQXBwIG5nQXBwfS4KICoKICogQW5ndWxhciB3aWxsIGRldGVjdCBpZiBpdCBoYXMgYmVlbiBsb2FkZWQgaW50byB0aGUgYnJvd3NlciBtb3JlIHRoYW4gb25jZSBhbmQgb25seSBhbGxvdyB0aGUKICogZmlyc3QgbG9hZGVkIHNjcmlwdCB0byBiZSBib290c3RyYXBwZWQgYW5kIHdpbGwgcmVwb3J0IGEgd2FybmluZyB0byB0aGUgYnJvd3NlciBjb25zb2xlIGZvcgogKiBlYWNoIG9mIHRoZSBzdWJzZXF1ZW50IHNjcmlwdHMuIFRoaXMgcHJldmVudHMgc3RyYW5nZSByZXN1bHRzIGluIGFwcGxpY2F0aW9ucywgd2hlcmUgb3RoZXJ3aXNlCiAqIG11bHRpcGxlIGluc3RhbmNlcyBvZiBBbmd1bGFyIHRyeSB0byB3b3JrIG9uIHRoZSBET00uCiAqCiAqIGBgYGh0bWwKICogPCFkb2N0eXBlIGh0bWw+CiAqIDxodG1sPgogKiA8Ym9keT4KICogPGRpdiBuZy1jb250cm9sbGVyPSJXZWxjb21lQ29udHJvbGxlciI+CiAqICAge3tncmVldGluZ319CiAqIDwvZGl2PgogKgogKiA8c2NyaXB0IHNyYz0iYW5ndWxhci5qcyI+PC9zY3JpcHQ+CiAqIDxzY3JpcHQ+CiAqICAgdmFyIGFwcCA9IGFuZ3VsYXIubW9kdWxlKCdkZW1vJywgW10pCiAqICAgLmNvbnRyb2xsZXIoJ1dlbGNvbWVDb250cm9sbGVyJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAqICAgICAgICRzY29wZS5ncmVldGluZyA9ICdXZWxjb21lISc7CiAqICAgfSk7CiAqICAgYW5ndWxhci5ib290c3RyYXAoZG9jdW1lbnQsIFsnZGVtbyddKTsKICogPC9zY3JpcHQ+CiAqIDwvYm9keT4KICogPC9odG1sPgogKiBgYGAKICoKICogQHBhcmFtIHtET01FbGVtZW50fSBlbGVtZW50IERPTSBlbGVtZW50IHdoaWNoIGlzIHRoZSByb290IG9mIGFuZ3VsYXIgYXBwbGljYXRpb24uCiAqIEBwYXJhbSB7QXJyYXk8U3RyaW5nfEZ1bmN0aW9ufEFycmF5Pj19IG1vZHVsZXMgYW4gYXJyYXkgb2YgbW9kdWxlcyB0byBsb2FkIGludG8gdGhlIGFwcGxpY2F0aW9uLgogKiAgICAgRWFjaCBpdGVtIGluIHRoZSBhcnJheSBzaG91bGQgYmUgdGhlIG5hbWUgb2YgYSBwcmVkZWZpbmVkIG1vZHVsZSBvciBhIChESSBhbm5vdGF0ZWQpCiAqICAgICBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZCBieSB0aGUgaW5qZWN0b3IgYXMgYSBydW4gYmxvY2suCiAqICAgICBTZWU6IHtAbGluayBhbmd1bGFyLm1vZHVsZSBtb2R1bGVzfQogKiBAcGFyYW0ge09iamVjdD19IGNvbmZpZyBhbiBvYmplY3QgZm9yIGRlZmluaW5nIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGFwcGxpY2F0aW9uLiBUaGUKICogICAgIGZvbGxvd2luZyBrZXlzIGFyZSBzdXBwb3J0ZWQ6CiAqCiAqICogYHN0cmljdERpYCAtIGRpc2FibGUgYXV0b21hdGljIGZ1bmN0aW9uIGFubm90YXRpb24gZm9yIHRoZSBhcHBsaWNhdGlvbi4gVGhpcyBpcyBtZWFudCB0bwogKiAgIGFzc2lzdCBpbiBmaW5kaW5nIGJ1Z3Mgd2hpY2ggYnJlYWsgbWluaWZpZWQgY29kZS4gRGVmYXVsdHMgdG8gYGZhbHNlYC4KICoKICogQHJldHVybnMge2F1dG8uJGluamVjdG9yfSBSZXR1cm5zIHRoZSBuZXdseSBjcmVhdGVkIGluamVjdG9yIGZvciB0aGlzIGFwcC4KICovCmZ1bmN0aW9uIGJvb3RzdHJhcChlbGVtZW50LCBtb2R1bGVzLCBjb25maWcpIHsKICBpZiAoIWlzT2JqZWN0KGNvbmZpZykpIGNvbmZpZyA9IHt9OwogIHZhciBkZWZhdWx0Q29uZmlnID0gewogICAgc3RyaWN0RGk6IGZhbHNlCiAgfTsKICBjb25maWcgPSBleHRlbmQoZGVmYXVsdENvbmZpZywgY29uZmlnKTsKICB2YXIgZG9Cb290c3RyYXAgPSBmdW5jdGlvbigpIHsKICAgIGVsZW1lbnQgPSBqcUxpdGUoZWxlbWVudCk7CgogICAgaWYgKGVsZW1lbnQuaW5qZWN0b3IoKSkgewogICAgICB2YXIgdGFnID0gKGVsZW1lbnRbMF0gPT09IGRvY3VtZW50KSA/ICdkb2N1bWVudCcgOiBzdGFydGluZ1RhZyhlbGVtZW50KTsKICAgICAgLy9FbmNvZGUgYW5nbGUgYnJhY2tldHMgdG8gcHJldmVudCBpbnB1dCBmcm9tIGJlaW5nIHNhbml0aXplZCB0byBlbXB0eSBzdHJpbmcgIzg2ODMKICAgICAgdGhyb3cgbmdNaW5FcnIoCiAgICAgICAgICAnYnRzdHJwZCcsCiAgICAgICAgICAiQXBwIEFscmVhZHkgQm9vdHN0cmFwcGVkIHdpdGggdGhpcyBFbGVtZW50ICd7MH0nIiwKICAgICAgICAgIHRhZy5yZXBsYWNlKC88LywnJmx0OycpLnJlcGxhY2UoLz4vLCcmZ3Q7JykpOwogICAgfQoKICAgIG1vZHVsZXMgPSBtb2R1bGVzIHx8IFtdOwogICAgbW9kdWxlcy51bnNoaWZ0KFsnJHByb3ZpZGUnLCBmdW5jdGlvbigkcHJvdmlkZSkgewogICAgICAkcHJvdmlkZS52YWx1ZSgnJHJvb3RFbGVtZW50JywgZWxlbWVudCk7CiAgICB9XSk7CgogICAgaWYgKGNvbmZpZy5kZWJ1Z0luZm9FbmFibGVkKSB7CiAgICAgIC8vIFB1c2hpbmcgc28gdGhhdCB0aGlzIG92ZXJyaWRlcyBgZGVidWdJbmZvRW5hYmxlZGAgc2V0dGluZyBkZWZpbmVkIGluIHVzZXIncyBgbW9kdWxlc2AuCiAgICAgIG1vZHVsZXMucHVzaChbJyRjb21waWxlUHJvdmlkZXInLCBmdW5jdGlvbigkY29tcGlsZVByb3ZpZGVyKSB7CiAgICAgICAgJGNvbXBpbGVQcm92aWRlci5kZWJ1Z0luZm9FbmFibGVkKHRydWUpOwogICAgICB9XSk7CiAgICB9CgogICAgbW9kdWxlcy51bnNoaWZ0KCduZycpOwogICAgdmFyIGluamVjdG9yID0gY3JlYXRlSW5qZWN0b3IobW9kdWxlcywgY29uZmlnLnN0cmljdERpKTsKICAgIGluamVjdG9yLmludm9rZShbJyRyb290U2NvcGUnLCAnJHJvb3RFbGVtZW50JywgJyRjb21waWxlJywgJyRpbmplY3RvcicsCiAgICAgICBmdW5jdGlvbiBib290c3RyYXBBcHBseShzY29wZSwgZWxlbWVudCwgY29tcGlsZSwgaW5qZWN0b3IpIHsKICAgICAgICBzY29wZS4kYXBwbHkoZnVuY3Rpb24oKSB7CiAgICAgICAgICBlbGVtZW50LmRhdGEoJyRpbmplY3RvcicsIGluamVjdG9yKTsKICAgICAgICAgIGNvbXBpbGUoZWxlbWVudCkoc2NvcGUpOwogICAgICAgIH0pOwogICAgICB9XQogICAgKTsKICAgIHJldHVybiBpbmplY3RvcjsKICB9OwoKICB2YXIgTkdfRU5BQkxFX0RFQlVHX0lORk8gPSAvXk5HX0VOQUJMRV9ERUJVR19JTkZPIS87CiAgdmFyIE5HX0RFRkVSX0JPT1RTVFJBUCA9IC9eTkdfREVGRVJfQk9PVFNUUkFQIS87CgogIGlmICh3aW5kb3cgJiYgTkdfRU5BQkxFX0RFQlVHX0lORk8udGVzdCh3aW5kb3cubmFtZSkpIHsKICAgIGNvbmZpZy5kZWJ1Z0luZm9FbmFibGVkID0gdHJ1ZTsKICAgIHdpbmRvdy5uYW1lID0gd2luZG93Lm5hbWUucmVwbGFjZShOR19FTkFCTEVfREVCVUdfSU5GTywgJycpOwogIH0KCiAgaWYgKHdpbmRvdyAmJiAhTkdfREVGRVJfQk9PVFNUUkFQLnRlc3Qod2luZG93Lm5hbWUpKSB7CiAgICByZXR1cm4gZG9Cb290c3RyYXAoKTsKICB9CgogIHdpbmRvdy5uYW1lID0gd2luZG93Lm5hbWUucmVwbGFjZShOR19ERUZFUl9CT09UU1RSQVAsICcnKTsKICBhbmd1bGFyLnJlc3VtZUJvb3RzdHJhcCA9IGZ1bmN0aW9uKGV4dHJhTW9kdWxlcykgewogICAgZm9yRWFjaChleHRyYU1vZHVsZXMsIGZ1bmN0aW9uKG1vZHVsZSkgewogICAgICBtb2R1bGVzLnB1c2gobW9kdWxlKTsKICAgIH0pOwogICAgZG9Cb290c3RyYXAoKTsKICB9Owp9CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIucmVsb2FkV2l0aERlYnVnSW5mbwogKiBAbW9kdWxlIG5nCiAqIEBkZXNjcmlwdGlvbgogKiBVc2UgdGhpcyBmdW5jdGlvbiB0byByZWxvYWQgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24gd2l0aCBkZWJ1ZyBpbmZvcm1hdGlvbiB0dXJuZWQgb24uCiAqIFRoaXMgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgY2FsbCB0byBgJGNvbXBpbGVQcm92aWRlci5kZWJ1Z0luZm9FbmFibGVkKGZhbHNlKWAuCiAqCiAqIFNlZSB7QGxpbmsgbmcuJGNvbXBpbGVQcm92aWRlciNkZWJ1Z0luZm9FbmFibGVkfSBmb3IgbW9yZS4KICovCmZ1bmN0aW9uIHJlbG9hZFdpdGhEZWJ1Z0luZm8oKSB7CiAgd2luZG93Lm5hbWUgPSAnTkdfRU5BQkxFX0RFQlVHX0lORk8hJyArIHdpbmRvdy5uYW1lOwogIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTsKfQoKLyoqCiAqIEBuYW1lIGFuZ3VsYXIuZ2V0VGVzdGFiaWxpdHkKICogQG1vZHVsZSBuZwogKiBAZGVzY3JpcHRpb24KICogR2V0IHRoZSB0ZXN0YWJpbGl0eSBzZXJ2aWNlIGZvciB0aGUgaW5zdGFuY2Ugb2YgQW5ndWxhciBvbiB0aGUgZ2l2ZW4KICogZWxlbWVudC4KICogQHBhcmFtIHtET01FbGVtZW50fSBlbGVtZW50IERPTSBlbGVtZW50IHdoaWNoIGlzIHRoZSByb290IG9mIGFuZ3VsYXIgYXBwbGljYXRpb24uCiAqLwpmdW5jdGlvbiBnZXRUZXN0YWJpbGl0eShyb290RWxlbWVudCkgewogIHZhciBpbmplY3RvciA9IGFuZ3VsYXIuZWxlbWVudChyb290RWxlbWVudCkuaW5qZWN0b3IoKTsKICBpZiAoIWluamVjdG9yKSB7CiAgICB0aHJvdyBuZ01pbkVycigndGVzdCcsCiAgICAgICdubyBpbmplY3RvciBmb3VuZCBmb3IgZWxlbWVudCBhcmd1bWVudCB0byBnZXRUZXN0YWJpbGl0eScpOwogIH0KICByZXR1cm4gaW5qZWN0b3IuZ2V0KCckJHRlc3RhYmlsaXR5Jyk7Cn0KCnZhciBTTkFLRV9DQVNFX1JFR0VYUCA9IC9bQS1aXS9nOwpmdW5jdGlvbiBzbmFrZV9jYXNlKG5hbWUsIHNlcGFyYXRvcikgewogIHNlcGFyYXRvciA9IHNlcGFyYXRvciB8fCAnXyc7CiAgcmV0dXJuIG5hbWUucmVwbGFjZShTTkFLRV9DQVNFX1JFR0VYUCwgZnVuY3Rpb24obGV0dGVyLCBwb3MpIHsKICAgIHJldHVybiAocG9zID8gc2VwYXJhdG9yIDogJycpICsgbGV0dGVyLnRvTG93ZXJDYXNlKCk7CiAgfSk7Cn0KCnZhciBiaW5kSlF1ZXJ5RmlyZWQgPSBmYWxzZTsKdmFyIHNraXBEZXN0cm95T25OZXh0SlF1ZXJ5Q2xlYW5EYXRhOwpmdW5jdGlvbiBiaW5kSlF1ZXJ5KCkgewogIHZhciBvcmlnaW5hbENsZWFuRGF0YTsKCiAgaWYgKGJpbmRKUXVlcnlGaXJlZCkgewogICAgcmV0dXJuOwogIH0KCiAgLy8gYmluZCB0byBqUXVlcnkgaWYgcHJlc2VudDsKICBqUXVlcnkgPSB3aW5kb3cualF1ZXJ5OwogIC8vIFVzZSBqUXVlcnkgaWYgaXQgZXhpc3RzIHdpdGggcHJvcGVyIGZ1bmN0aW9uYWxpdHksIG90aGVyd2lzZSBkZWZhdWx0IHRvIHVzLgogIC8vIEFuZ3VsYXIgMS4yKyByZXF1aXJlcyBqUXVlcnkgMS43KyBmb3Igb24oKS9vZmYoKSBzdXBwb3J0LgogIC8vIEFuZ3VsYXIgMS4zKyB0ZWNobmljYWxseSByZXF1aXJlcyBhdCBsZWFzdCBqUXVlcnkgMi4xKyBidXQgaXQgbWF5IHdvcmsgd2l0aCBvbGRlcgogIC8vIHZlcnNpb25zLiBJdCB3aWxsIG5vdCB3b3JrIGZvciBzdXJlIHdpdGggalF1ZXJ5IDwxLjcsIHRob3VnaC4KICBpZiAoalF1ZXJ5ICYmIGpRdWVyeS5mbi5vbikgewogICAganFMaXRlID0galF1ZXJ5OwogICAgZXh0ZW5kKGpRdWVyeS5mbiwgewogICAgICBzY29wZTogSlFMaXRlUHJvdG90eXBlLnNjb3BlLAogICAgICBpc29sYXRlU2NvcGU6IEpRTGl0ZVByb3RvdHlwZS5pc29sYXRlU2NvcGUsCiAgICAgIGNvbnRyb2xsZXI6IEpRTGl0ZVByb3RvdHlwZS5jb250cm9sbGVyLAogICAgICBpbmplY3RvcjogSlFMaXRlUHJvdG90eXBlLmluamVjdG9yLAogICAgICBpbmhlcml0ZWREYXRhOiBKUUxpdGVQcm90b3R5cGUuaW5oZXJpdGVkRGF0YQogICAgfSk7CgogICAgLy8gQWxsIG5vZGVzIHJlbW92ZWQgZnJvbSB0aGUgRE9NIHZpYSB2YXJpb3VzIGpRdWVyeSBBUElzIGxpa2UgLnJlbW92ZSgpCiAgICAvLyBhcmUgcGFzc2VkIHRocm91Z2ggalF1ZXJ5LmNsZWFuRGF0YS4gTW9ua2V5LXBhdGNoIHRoaXMgbWV0aG9kIHRvIGZpcmUKICAgIC8vIHRoZSAkZGVzdHJveSBldmVudCBvbiBhbGwgcmVtb3ZlZCBub2Rlcy4KICAgIG9yaWdpbmFsQ2xlYW5EYXRhID0galF1ZXJ5LmNsZWFuRGF0YTsKICAgIGpRdWVyeS5jbGVhbkRhdGEgPSBmdW5jdGlvbihlbGVtcykgewogICAgICB2YXIgZXZlbnRzOwogICAgICBpZiAoIXNraXBEZXN0cm95T25OZXh0SlF1ZXJ5Q2xlYW5EYXRhKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGVsZW07IChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKykgewogICAgICAgICAgZXZlbnRzID0galF1ZXJ5Ll9kYXRhKGVsZW0sICJldmVudHMiKTsKICAgICAgICAgIGlmIChldmVudHMgJiYgZXZlbnRzLiRkZXN0cm95KSB7CiAgICAgICAgICAgIGpRdWVyeShlbGVtKS50cmlnZ2VySGFuZGxlcignJGRlc3Ryb3knKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2tpcERlc3Ryb3lPbk5leHRKUXVlcnlDbGVhbkRhdGEgPSBmYWxzZTsKICAgICAgfQogICAgICBvcmlnaW5hbENsZWFuRGF0YShlbGVtcyk7CiAgICB9OwogIH0gZWxzZSB7CiAgICBqcUxpdGUgPSBKUUxpdGU7CiAgfQoKICBhbmd1bGFyLmVsZW1lbnQgPSBqcUxpdGU7CgogIC8vIFByZXZlbnQgZG91YmxlLXByb3h5aW5nLgogIGJpbmRKUXVlcnlGaXJlZCA9IHRydWU7Cn0KCi8qKgogKiB0aHJvdyBlcnJvciBpZiB0aGUgYXJndW1lbnQgaXMgZmFsc3kuCiAqLwpmdW5jdGlvbiBhc3NlcnRBcmcoYXJnLCBuYW1lLCByZWFzb24pIHsKICBpZiAoIWFyZykgewogICAgdGhyb3cgbmdNaW5FcnIoJ2FyZXEnLCAiQXJndW1lbnQgJ3swfScgaXMgezF9IiwgKG5hbWUgfHwgJz8nKSwgKHJlYXNvbiB8fCAicmVxdWlyZWQiKSk7CiAgfQogIHJldHVybiBhcmc7Cn0KCmZ1bmN0aW9uIGFzc2VydEFyZ0ZuKGFyZywgbmFtZSwgYWNjZXB0QXJyYXlBbm5vdGF0aW9uKSB7CiAgaWYgKGFjY2VwdEFycmF5QW5ub3RhdGlvbiAmJiBpc0FycmF5KGFyZykpIHsKICAgICAgYXJnID0gYXJnW2FyZy5sZW5ndGggLSAxXTsKICB9CgogIGFzc2VydEFyZyhpc0Z1bmN0aW9uKGFyZyksIG5hbWUsICdub3QgYSBmdW5jdGlvbiwgZ290ICcgKwogICAgICAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnID8gYXJnLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ09iamVjdCcgOiB0eXBlb2YgYXJnKSk7CiAgcmV0dXJuIGFyZzsKfQoKLyoqCiAqIHRocm93IGVycm9yIGlmIHRoZSBuYW1lIGdpdmVuIGlzIGhhc093blByb3BlcnR5CiAqIEBwYXJhbSAge1N0cmluZ30gbmFtZSAgICB0aGUgbmFtZSB0byB0ZXN0CiAqIEBwYXJhbSAge1N0cmluZ30gY29udGV4dCB0aGUgY29udGV4dCBpbiB3aGljaCB0aGUgbmFtZSBpcyB1c2VkLCBzdWNoIGFzIG1vZHVsZSBvciBkaXJlY3RpdmUKICovCmZ1bmN0aW9uIGFzc2VydE5vdEhhc093blByb3BlcnR5KG5hbWUsIGNvbnRleHQpIHsKICBpZiAobmFtZSA9PT0gJ2hhc093blByb3BlcnR5JykgewogICAgdGhyb3cgbmdNaW5FcnIoJ2JhZG5hbWUnLCAiaGFzT3duUHJvcGVydHkgaXMgbm90IGEgdmFsaWQgezB9IG5hbWUiLCBjb250ZXh0KTsKICB9Cn0KCi8qKgogKiBSZXR1cm4gdGhlIHZhbHVlIGFjY2Vzc2libGUgZnJvbSB0aGUgb2JqZWN0IGJ5IHBhdGguIEFueSB1bmRlZmluZWQgdHJhdmVyc2FscyBhcmUgaWdub3JlZAogKiBAcGFyYW0ge09iamVjdH0gb2JqIHN0YXJ0aW5nIG9iamVjdAogKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBwYXRoIHRvIHRyYXZlcnNlCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2JpbmRGblRvU2NvcGU9dHJ1ZV0KICogQHJldHVybnMge09iamVjdH0gdmFsdWUgYXMgYWNjZXNzaWJsZSBieSBwYXRoCiAqLwovL1RPRE8obWlza28pOiB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJlbW92ZWQKZnVuY3Rpb24gZ2V0dGVyKG9iaiwgcGF0aCwgYmluZEZuVG9TY29wZSkgewogIGlmICghcGF0aCkgcmV0dXJuIG9iajsKICB2YXIga2V5cyA9IHBhdGguc3BsaXQoJy4nKTsKICB2YXIga2V5OwogIHZhciBsYXN0SW5zdGFuY2UgPSBvYmo7CiAgdmFyIGxlbiA9IGtleXMubGVuZ3RoOwoKICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICBrZXkgPSBrZXlzW2ldOwogICAgaWYgKG9iaikgewogICAgICBvYmogPSAobGFzdEluc3RhbmNlID0gb2JqKVtrZXldOwogICAgfQogIH0KICBpZiAoIWJpbmRGblRvU2NvcGUgJiYgaXNGdW5jdGlvbihvYmopKSB7CiAgICByZXR1cm4gYmluZChsYXN0SW5zdGFuY2UsIG9iaik7CiAgfQogIHJldHVybiBvYmo7Cn0KCi8qKgogKiBSZXR1cm4gdGhlIERPTSBzaWJsaW5ncyBiZXR3ZWVuIHRoZSBmaXJzdCBhbmQgbGFzdCBub2RlIGluIHRoZSBnaXZlbiBhcnJheS4KICogQHBhcmFtIHtBcnJheX0gYXJyYXkgbGlrZSBvYmplY3QKICogQHJldHVybnMge2pxTGl0ZX0ganFMaXRlIGNvbGxlY3Rpb24gY29udGFpbmluZyB0aGUgbm9kZXMKICovCmZ1bmN0aW9uIGdldEJsb2NrTm9kZXMobm9kZXMpIHsKICAvLyBUT0RPKHBlcmYpOiBqdXN0IGNoZWNrIGlmIGFsbCBpdGVtcyBpbiBgbm9kZXNgIGFyZSBzaWJsaW5ncyBhbmQgaWYgdGhleSBhcmUgcmV0dXJuIHRoZSBvcmlnaW5hbAogIC8vICAgICAgICAgICAgIGNvbGxlY3Rpb24sIG90aGVyd2lzZSB1cGRhdGUgdGhlIG9yaWdpbmFsIGNvbGxlY3Rpb24uCiAgdmFyIG5vZGUgPSBub2Rlc1swXTsKICB2YXIgZW5kTm9kZSA9IG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdOwogIHZhciBibG9ja05vZGVzID0gW25vZGVdOwoKICBkbyB7CiAgICBub2RlID0gbm9kZS5uZXh0U2libGluZzsKICAgIGlmICghbm9kZSkgYnJlYWs7CiAgICBibG9ja05vZGVzLnB1c2gobm9kZSk7CiAgfSB3aGlsZSAobm9kZSAhPT0gZW5kTm9kZSk7CgogIHJldHVybiBqcUxpdGUoYmxvY2tOb2Rlcyk7Cn0KCgovKioKICogQ3JlYXRlcyBhIG5ldyBvYmplY3Qgd2l0aG91dCBhIHByb3RvdHlwZS4gVGhpcyBvYmplY3QgaXMgdXNlZnVsIGZvciBsb29rdXAgd2l0aG91dCBoYXZpbmcgdG8KICogZ3VhcmQgYWdhaW5zdCBwcm90b3R5cGljYWxseSBpbmhlcml0ZWQgcHJvcGVydGllcyB2aWEgaGFzT3duUHJvcGVydHkuCiAqCiAqIFJlbGF0ZWQgbWljcm8tYmVuY2htYXJrczoKICogLSBodHRwOi8vanNwZXJmLmNvbS9vYmplY3QtY3JlYXRlMgogKiAtIGh0dHA6Ly9qc3BlcmYuY29tL3Byb3RvLW1hcC1sb29rdXAvMgogKiAtIGh0dHA6Ly9qc3BlcmYuY29tL2Zvci1pbi12cy1vYmplY3Qta2V5czIKICoKICogQHJldHVybnMge09iamVjdH0KICovCmZ1bmN0aW9uIGNyZWF0ZU1hcCgpIHsKICByZXR1cm4gT2JqZWN0LmNyZWF0ZShudWxsKTsKfQoKdmFyIE5PREVfVFlQRV9FTEVNRU5UID0gMTsKdmFyIE5PREVfVFlQRV9URVhUID0gMzsKdmFyIE5PREVfVFlQRV9DT01NRU5UID0gODsKdmFyIE5PREVfVFlQRV9ET0NVTUVOVCA9IDk7CnZhciBOT0RFX1RZUEVfRE9DVU1FTlRfRlJBR01FTlQgPSAxMTsKCi8qKgogKiBAbmdkb2MgdHlwZQogKiBAbmFtZSBhbmd1bGFyLk1vZHVsZQogKiBAbW9kdWxlIG5nCiAqIEBkZXNjcmlwdGlvbgogKgogKiBJbnRlcmZhY2UgZm9yIGNvbmZpZ3VyaW5nIGFuZ3VsYXIge0BsaW5rIGFuZ3VsYXIubW9kdWxlIG1vZHVsZXN9LgogKi8KCmZ1bmN0aW9uIHNldHVwTW9kdWxlTG9hZGVyKHdpbmRvdykgewoKICB2YXIgJGluamVjdG9yTWluRXJyID0gbWluRXJyKCckaW5qZWN0b3InKTsKICB2YXIgbmdNaW5FcnIgPSBtaW5FcnIoJ25nJyk7CgogIGZ1bmN0aW9uIGVuc3VyZShvYmosIG5hbWUsIGZhY3RvcnkpIHsKICAgIHJldHVybiBvYmpbbmFtZV0gfHwgKG9ialtuYW1lXSA9IGZhY3RvcnkoKSk7CiAgfQoKICB2YXIgYW5ndWxhciA9IGVuc3VyZSh3aW5kb3csICdhbmd1bGFyJywgT2JqZWN0KTsKCiAgLy8gV2UgbmVlZCB0byBleHBvc2UgYGFuZ3VsYXIuJCRtaW5FcnJgIHRvIG1vZHVsZXMgc3VjaCBhcyBgbmdSZXNvdXJjZWAgdGhhdCByZWZlcmVuY2UgaXQgZHVyaW5nIGJvb3RzdHJhcAogIGFuZ3VsYXIuJCRtaW5FcnIgPSBhbmd1bGFyLiQkbWluRXJyIHx8IG1pbkVycjsKCiAgcmV0dXJuIGVuc3VyZShhbmd1bGFyLCAnbW9kdWxlJywgZnVuY3Rpb24oKSB7CiAgICAvKiogQHR5cGUge09iamVjdC48c3RyaW5nLCBhbmd1bGFyLk1vZHVsZT59ICovCiAgICB2YXIgbW9kdWxlcyA9IHt9OwoKICAgIC8qKgogICAgICogQG5nZG9jIGZ1bmN0aW9uCiAgICAgKiBAbmFtZSBhbmd1bGFyLm1vZHVsZQogICAgICogQG1vZHVsZSBuZwogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKgogICAgICogVGhlIGBhbmd1bGFyLm1vZHVsZWAgaXMgYSBnbG9iYWwgcGxhY2UgZm9yIGNyZWF0aW5nLCByZWdpc3RlcmluZyBhbmQgcmV0cmlldmluZyBBbmd1bGFyCiAgICAgKiBtb2R1bGVzLgogICAgICogQWxsIG1vZHVsZXMgKGFuZ3VsYXIgY29yZSBvciAzcmQgcGFydHkpIHRoYXQgc2hvdWxkIGJlIGF2YWlsYWJsZSB0byBhbiBhcHBsaWNhdGlvbiBtdXN0IGJlCiAgICAgKiByZWdpc3RlcmVkIHVzaW5nIHRoaXMgbWVjaGFuaXNtLgogICAgICoKICAgICAqIFdoZW4gcGFzc2VkIHR3byBvciBtb3JlIGFyZ3VtZW50cywgYSBuZXcgbW9kdWxlIGlzIGNyZWF0ZWQuICBJZiBwYXNzZWQgb25seSBvbmUgYXJndW1lbnQsIGFuCiAgICAgKiBleGlzdGluZyBtb2R1bGUgKHRoZSBuYW1lIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gYG1vZHVsZWApIGlzIHJldHJpZXZlZC4KICAgICAqCiAgICAgKgogICAgICogIyBNb2R1bGUKICAgICAqCiAgICAgKiBBIG1vZHVsZSBpcyBhIGNvbGxlY3Rpb24gb2Ygc2VydmljZXMsIGRpcmVjdGl2ZXMsIGNvbnRyb2xsZXJzLCBmaWx0ZXJzLCBhbmQgY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbi4KICAgICAqIGBhbmd1bGFyLm1vZHVsZWAgaXMgdXNlZCB0byBjb25maWd1cmUgdGhlIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiAvLyBDcmVhdGUgYSBuZXcgbW9kdWxlCiAgICAgKiB2YXIgbXlNb2R1bGUgPSBhbmd1bGFyLm1vZHVsZSgnbXlNb2R1bGUnLCBbXSk7CiAgICAgKgogICAgICogLy8gcmVnaXN0ZXIgYSBuZXcgc2VydmljZQogICAgICogbXlNb2R1bGUudmFsdWUoJ2FwcE5hbWUnLCAnTXlDb29sQXBwJyk7CiAgICAgKgogICAgICogLy8gY29uZmlndXJlIGV4aXN0aW5nIHNlcnZpY2VzIGluc2lkZSBpbml0aWFsaXphdGlvbiBibG9ja3MuCiAgICAgKiBteU1vZHVsZS5jb25maWcoWyckbG9jYXRpb25Qcm92aWRlcicsIGZ1bmN0aW9uKCRsb2NhdGlvblByb3ZpZGVyKSB7CiAgICAgKiAgIC8vIENvbmZpZ3VyZSBleGlzdGluZyBwcm92aWRlcnMKICAgICAqICAgJGxvY2F0aW9uUHJvdmlkZXIuaGFzaFByZWZpeCgnIScpOwogICAgICogfV0pOwogICAgICogYGBgCiAgICAgKgogICAgICogVGhlbiB5b3UgY2FuIGNyZWF0ZSBhbiBpbmplY3RvciBhbmQgbG9hZCB5b3VyIG1vZHVsZXMgbGlrZSB0aGlzOgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiB2YXIgaW5qZWN0b3IgPSBhbmd1bGFyLmluamVjdG9yKFsnbmcnLCAnbXlNb2R1bGUnXSkKICAgICAqIGBgYAogICAgICoKICAgICAqIEhvd2V2ZXIgaXQncyBtb3JlIGxpa2VseSB0aGF0IHlvdSdsbCBqdXN0IHVzZQogICAgICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ0FwcCBuZ0FwcH0gb3IKICAgICAqIHtAbGluayBhbmd1bGFyLmJvb3RzdHJhcH0gdG8gc2ltcGxpZnkgdGhpcyBwcm9jZXNzIGZvciB5b3UuCiAgICAgKgogICAgICogQHBhcmFtIHshc3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGUgdG8gY3JlYXRlIG9yIHJldHJpZXZlLgogICAgICogQHBhcmFtIHshQXJyYXkuPHN0cmluZz49fSByZXF1aXJlcyBJZiBzcGVjaWZpZWQgdGhlbiBuZXcgbW9kdWxlIGlzIGJlaW5nIGNyZWF0ZWQuIElmCiAgICAgKiAgICAgICAgdW5zcGVjaWZpZWQgdGhlbiB0aGUgbW9kdWxlIGlzIGJlaW5nIHJldHJpZXZlZCBmb3IgZnVydGhlciBjb25maWd1cmF0aW9uLgogICAgICogQHBhcmFtIHtGdW5jdGlvbj19IGNvbmZpZ0ZuIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBtb2R1bGUuIFNhbWUgYXMKICAgICAqICAgICAgICB7QGxpbmsgYW5ndWxhci5Nb2R1bGUjY29uZmlnIE1vZHVsZSNjb25maWcoKX0uCiAgICAgKiBAcmV0dXJucyB7bW9kdWxlfSBuZXcgbW9kdWxlIHdpdGggdGhlIHtAbGluayBhbmd1bGFyLk1vZHVsZX0gYXBpLgogICAgICovCiAgICByZXR1cm4gZnVuY3Rpb24gbW9kdWxlKG5hbWUsIHJlcXVpcmVzLCBjb25maWdGbikgewogICAgICB2YXIgYXNzZXJ0Tm90SGFzT3duUHJvcGVydHkgPSBmdW5jdGlvbihuYW1lLCBjb250ZXh0KSB7CiAgICAgICAgaWYgKG5hbWUgPT09ICdoYXNPd25Qcm9wZXJ0eScpIHsKICAgICAgICAgIHRocm93IG5nTWluRXJyKCdiYWRuYW1lJywgJ2hhc093blByb3BlcnR5IGlzIG5vdCBhIHZhbGlkIHswfSBuYW1lJywgY29udGV4dCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgYXNzZXJ0Tm90SGFzT3duUHJvcGVydHkobmFtZSwgJ21vZHVsZScpOwogICAgICBpZiAocmVxdWlyZXMgJiYgbW9kdWxlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkgewogICAgICAgIG1vZHVsZXNbbmFtZV0gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBlbnN1cmUobW9kdWxlcywgbmFtZSwgZnVuY3Rpb24oKSB7CiAgICAgICAgaWYgKCFyZXF1aXJlcykgewogICAgICAgICAgdGhyb3cgJGluamVjdG9yTWluRXJyKCdub21vZCcsICJNb2R1bGUgJ3swfScgaXMgbm90IGF2YWlsYWJsZSEgWW91IGVpdGhlciBtaXNzcGVsbGVkICIgKwogICAgICAgICAgICAgInRoZSBtb2R1bGUgbmFtZSBvciBmb3Jnb3QgdG8gbG9hZCBpdC4gSWYgcmVnaXN0ZXJpbmcgYSBtb2R1bGUgZW5zdXJlIHRoYXQgeW91ICIgKwogICAgICAgICAgICAgInNwZWNpZnkgdGhlIGRlcGVuZGVuY2llcyBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LiIsIG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEB0eXBlIHshQXJyYXkuPEFycmF5LjwqPj59ICovCiAgICAgICAgdmFyIGludm9rZVF1ZXVlID0gW107CgogICAgICAgIC8qKiBAdHlwZSB7IUFycmF5LjxGdW5jdGlvbj59ICovCiAgICAgICAgdmFyIGNvbmZpZ0Jsb2NrcyA9IFtdOwoKICAgICAgICAvKiogQHR5cGUgeyFBcnJheS48RnVuY3Rpb24+fSAqLwogICAgICAgIHZhciBydW5CbG9ja3MgPSBbXTsKCiAgICAgICAgdmFyIGNvbmZpZyA9IGludm9rZUxhdGVyKCckaW5qZWN0b3InLCAnaW52b2tlJywgJ3B1c2gnLCBjb25maWdCbG9ja3MpOwoKICAgICAgICAvKiogQHR5cGUge2FuZ3VsYXIuTW9kdWxlfSAqLwogICAgICAgIHZhciBtb2R1bGVJbnN0YW5jZSA9IHsKICAgICAgICAgIC8vIFByaXZhdGUgc3RhdGUKICAgICAgICAgIF9pbnZva2VRdWV1ZTogaW52b2tlUXVldWUsCiAgICAgICAgICBfY29uZmlnQmxvY2tzOiBjb25maWdCbG9ja3MsCiAgICAgICAgICBfcnVuQmxvY2tzOiBydW5CbG9ja3MsCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgcHJvcGVydHkKICAgICAgICAgICAqIEBuYW1lIGFuZ3VsYXIuTW9kdWxlI3JlcXVpcmVzCiAgICAgICAgICAgKiBAbW9kdWxlIG5nCiAgICAgICAgICAgKgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBIb2xkcyB0aGUgbGlzdCBvZiBtb2R1bGVzIHdoaWNoIHRoZSBpbmplY3RvciB3aWxsIGxvYWQgYmVmb3JlIHRoZSBjdXJyZW50IG1vZHVsZSBpcwogICAgICAgICAgICogbG9hZGVkLgogICAgICAgICAgICovCiAgICAgICAgICByZXF1aXJlczogcmVxdWlyZXMsCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgcHJvcGVydHkKICAgICAgICAgICAqIEBuYW1lIGFuZ3VsYXIuTW9kdWxlI25hbWUKICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgICAqIE5hbWUgb2YgdGhlIG1vZHVsZS4KICAgICAgICAgICAqLwogICAgICAgICAgbmFtZTogbmFtZSwKCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICAgKiBAbmFtZSBhbmd1bGFyLk1vZHVsZSNwcm92aWRlcgogICAgICAgICAgICogQG1vZHVsZSBuZwogICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgc2VydmljZSBuYW1lCiAgICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcm92aWRlclR5cGUgQ29uc3RydWN0aW9uIGZ1bmN0aW9uIGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2Ugb2YgdGhlCiAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZS4KICAgICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAgICogU2VlIHtAbGluayBhdXRvLiRwcm92aWRlI3Byb3ZpZGVyICRwcm92aWRlLnByb3ZpZGVyKCl9LgogICAgICAgICAgICovCiAgICAgICAgICBwcm92aWRlcjogaW52b2tlTGF0ZXIoJyRwcm92aWRlJywgJ3Byb3ZpZGVyJyksCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICAgKiBAbmFtZSBhbmd1bGFyLk1vZHVsZSNmYWN0b3J5CiAgICAgICAgICAgKiBAbW9kdWxlIG5nCiAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBzZXJ2aWNlIG5hbWUKICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByb3ZpZGVyRnVuY3Rpb24gRnVuY3Rpb24gZm9yIGNyZWF0aW5nIG5ldyBpbnN0YW5jZSBvZiB0aGUgc2VydmljZS4KICAgICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAgICogU2VlIHtAbGluayBhdXRvLiRwcm92aWRlI2ZhY3RvcnkgJHByb3ZpZGUuZmFjdG9yeSgpfS4KICAgICAgICAgICAqLwogICAgICAgICAgZmFjdG9yeTogaW52b2tlTGF0ZXIoJyRwcm92aWRlJywgJ2ZhY3RvcnknKSwKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICAgICAqIEBuYW1lIGFuZ3VsYXIuTW9kdWxlI3NlcnZpY2UKICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHNlcnZpY2UgbmFtZQogICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29uc3RydWN0b3IgQSBjb25zdHJ1Y3RvciBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW5zdGFudGlhdGVkLgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBTZWUge0BsaW5rIGF1dG8uJHByb3ZpZGUjc2VydmljZSAkcHJvdmlkZS5zZXJ2aWNlKCl9LgogICAgICAgICAgICovCiAgICAgICAgICBzZXJ2aWNlOiBpbnZva2VMYXRlcignJHByb3ZpZGUnLCAnc2VydmljZScpLAoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAgICogQG5hbWUgYW5ndWxhci5Nb2R1bGUjdmFsdWUKICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHNlcnZpY2UgbmFtZQogICAgICAgICAgICogQHBhcmFtIHsqfSBvYmplY3QgU2VydmljZSBpbnN0YW5jZSBvYmplY3QuCiAgICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgICAqIFNlZSB7QGxpbmsgYXV0by4kcHJvdmlkZSN2YWx1ZSAkcHJvdmlkZS52YWx1ZSgpfS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFsdWU6IGludm9rZUxhdGVyKCckcHJvdmlkZScsICd2YWx1ZScpLAoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAgICogQG5hbWUgYW5ndWxhci5Nb2R1bGUjY29uc3RhbnQKICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIGNvbnN0YW50IG5hbWUKICAgICAgICAgICAqIEBwYXJhbSB7Kn0gb2JqZWN0IENvbnN0YW50IHZhbHVlLgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBCZWNhdXNlIHRoZSBjb25zdGFudCBhcmUgZml4ZWQsIHRoZXkgZ2V0IGFwcGxpZWQgYmVmb3JlIG90aGVyIHByb3ZpZGUgbWV0aG9kcy4KICAgICAgICAgICAqIFNlZSB7QGxpbmsgYXV0by4kcHJvdmlkZSNjb25zdGFudCAkcHJvdmlkZS5jb25zdGFudCgpfS4KICAgICAgICAgICAqLwogICAgICAgICAgY29uc3RhbnQ6IGludm9rZUxhdGVyKCckcHJvdmlkZScsICdjb25zdGFudCcsICd1bnNoaWZ0JyksCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICAgKiBAbmFtZSBhbmd1bGFyLk1vZHVsZSNhbmltYXRpb24KICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIGFuaW1hdGlvbiBuYW1lCiAgICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhbmltYXRpb25GYWN0b3J5IEZhY3RvcnkgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIG5ldyBpbnN0YW5jZSBvZiBhbgogICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uCiAgICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgICAqCiAgICAgICAgICAgKiAqKk5PVEUqKjogYW5pbWF0aW9ucyB0YWtlIGVmZmVjdCBvbmx5IGlmIHRoZSAqKm5nQW5pbWF0ZSoqIG1vZHVsZSBpcyBsb2FkZWQuCiAgICAgICAgICAgKgogICAgICAgICAgICoKICAgICAgICAgICAqIERlZmluZXMgYW4gYW5pbWF0aW9uIGhvb2sgdGhhdCBjYW4gYmUgbGF0ZXIgdXNlZCB3aXRoCiAgICAgICAgICAgKiB7QGxpbmsgbmdBbmltYXRlLiRhbmltYXRlICRhbmltYXRlfSBzZXJ2aWNlIGFuZCBkaXJlY3RpdmVzIHRoYXQgdXNlIHRoaXMgc2VydmljZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBgYGBqcwogICAgICAgICAgICogbW9kdWxlLmFuaW1hdGlvbignLmFuaW1hdGlvbi1uYW1lJywgZnVuY3Rpb24oJGluamVjdDEsICRpbmplY3QyKSB7CiAgICAgICAgICAgKiAgIHJldHVybiB7CiAgICAgICAgICAgKiAgICAgZXZlbnROYW1lIDogZnVuY3Rpb24oZWxlbWVudCwgZG9uZSkgewogICAgICAgICAgICogICAgICAgLy9jb2RlIHRvIHJ1biB0aGUgYW5pbWF0aW9uCiAgICAgICAgICAgKiAgICAgICAvL29uY2UgY29tcGxldGUsIHRoZW4gcnVuIGRvbmUoKQogICAgICAgICAgICogICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNhbmNlbGxhdGlvbkZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICAgICAqICAgICAgICAgLy9jb2RlIHRvIGNhbmNlbCB0aGUgYW5pbWF0aW9uCiAgICAgICAgICAgKiAgICAgICB9CiAgICAgICAgICAgKiAgICAgfQogICAgICAgICAgICogICB9CiAgICAgICAgICAgKiB9KQogICAgICAgICAgICogYGBgCiAgICAgICAgICAgKgogICAgICAgICAgICogU2VlIHtAbGluayBuZy4kYW5pbWF0ZVByb3ZpZGVyI3JlZ2lzdGVyICRhbmltYXRlUHJvdmlkZXIucmVnaXN0ZXIoKX0gYW5kCiAgICAgICAgICAgKiB7QGxpbmsgbmdBbmltYXRlIG5nQW5pbWF0ZSBtb2R1bGV9IGZvciBtb3JlIGluZm9ybWF0aW9uLgogICAgICAgICAgICovCiAgICAgICAgICBhbmltYXRpb246IGludm9rZUxhdGVyKCckYW5pbWF0ZVByb3ZpZGVyJywgJ3JlZ2lzdGVyJyksCgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICAgKiBAbmFtZSBhbmd1bGFyLk1vZHVsZSNmaWx0ZXIKICAgICAgICAgICAqIEBtb2R1bGUgbmcKICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEZpbHRlciBuYW1lLgogICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZmlsdGVyRmFjdG9yeSBGYWN0b3J5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2Ugb2YgZmlsdGVyLgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBTZWUge0BsaW5rIG5nLiRmaWx0ZXJQcm92aWRlciNyZWdpc3RlciAkZmlsdGVyUHJvdmlkZXIucmVnaXN0ZXIoKX0uCiAgICAgICAgICAgKi8KICAgICAgICAgIGZpbHRlcjogaW52b2tlTGF0ZXIoJyRmaWx0ZXJQcm92aWRlcicsICdyZWdpc3RlcicpLAoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAgICogQG5hbWUgYW5ndWxhci5Nb2R1bGUjY29udHJvbGxlcgogICAgICAgICAgICogQG1vZHVsZSBuZwogICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBuYW1lIENvbnRyb2xsZXIgbmFtZSwgb3IgYW4gb2JqZWN0IG1hcCBvZiBjb250cm9sbGVycyB3aGVyZSB0aGUKICAgICAgICAgICAqICAgIGtleXMgYXJlIHRoZSBuYW1lcyBhbmQgdGhlIHZhbHVlcyBhcmUgdGhlIGNvbnN0cnVjdG9ycy4KICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbnN0cnVjdG9yIENvbnRyb2xsZXIgY29uc3RydWN0b3IgZnVuY3Rpb24uCiAgICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgICAqIFNlZSB7QGxpbmsgbmcuJGNvbnRyb2xsZXJQcm92aWRlciNyZWdpc3RlciAkY29udHJvbGxlclByb3ZpZGVyLnJlZ2lzdGVyKCl9LgogICAgICAgICAgICovCiAgICAgICAgICBjb250cm9sbGVyOiBpbnZva2VMYXRlcignJGNvbnRyb2xsZXJQcm92aWRlcicsICdyZWdpc3RlcicpLAoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAgICogQG5hbWUgYW5ndWxhci5Nb2R1bGUjZGlyZWN0aXZlCiAgICAgICAgICAgKiBAbW9kdWxlIG5nCiAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IG5hbWUgRGlyZWN0aXZlIG5hbWUsIG9yIGFuIG9iamVjdCBtYXAgb2YgZGlyZWN0aXZlcyB3aGVyZSB0aGUKICAgICAgICAgICAqICAgIGtleXMgYXJlIHRoZSBuYW1lcyBhbmQgdGhlIHZhbHVlcyBhcmUgdGhlIGZhY3Rvcmllcy4KICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGRpcmVjdGl2ZUZhY3RvcnkgRmFjdG9yeSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgbmV3IGluc3RhbmNlIG9mCiAgICAgICAgICAgKiBkaXJlY3RpdmVzLgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBTZWUge0BsaW5rIG5nLiRjb21waWxlUHJvdmlkZXIjZGlyZWN0aXZlICRjb21waWxlUHJvdmlkZXIuZGlyZWN0aXZlKCl9LgogICAgICAgICAgICovCiAgICAgICAgICBkaXJlY3RpdmU6IGludm9rZUxhdGVyKCckY29tcGlsZVByb3ZpZGVyJywgJ2RpcmVjdGl2ZScpLAoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAgICogQG5hbWUgYW5ndWxhci5Nb2R1bGUjY29uZmlnCiAgICAgICAgICAgKiBAbW9kdWxlIG5nCiAgICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb25maWdGbiBFeGVjdXRlIHRoaXMgZnVuY3Rpb24gb24gbW9kdWxlIGxvYWQuIFVzZWZ1bCBmb3Igc2VydmljZQogICAgICAgICAgICogICAgY29uZmlndXJhdGlvbi4KICAgICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAgICogVXNlIHRoaXMgbWV0aG9kIHRvIHJlZ2lzdGVyIHdvcmsgd2hpY2ggbmVlZHMgdG8gYmUgcGVyZm9ybWVkIG9uIG1vZHVsZSBsb2FkaW5nLgogICAgICAgICAgICogRm9yIG1vcmUgYWJvdXQgaG93IHRvIGNvbmZpZ3VyZSBzZXJ2aWNlcywgc2VlCiAgICAgICAgICAgKiB7QGxpbmsgcHJvdmlkZXJzI3Byb3ZpZGVyLXJlY2lwZSBQcm92aWRlciBSZWNpcGV9LgogICAgICAgICAgICovCiAgICAgICAgICBjb25maWc6IGNvbmZpZywKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICAgICAqIEBuYW1lIGFuZ3VsYXIuTW9kdWxlI3J1bgogICAgICAgICAgICogQG1vZHVsZSBuZwogICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaW5pdGlhbGl6YXRpb25GbiBFeGVjdXRlIHRoaXMgZnVuY3Rpb24gYWZ0ZXIgaW5qZWN0b3IgY3JlYXRpb24uCiAgICAgICAgICAgKiAgICBVc2VmdWwgZm9yIGFwcGxpY2F0aW9uIGluaXRpYWxpemF0aW9uLgogICAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICAgKiBVc2UgdGhpcyBtZXRob2QgdG8gcmVnaXN0ZXIgd29yayB3aGljaCBzaG91bGQgYmUgcGVyZm9ybWVkIHdoZW4gdGhlIGluamVjdG9yIGlzIGRvbmUKICAgICAgICAgICAqIGxvYWRpbmcgYWxsIG1vZHVsZXMuCiAgICAgICAgICAgKi8KICAgICAgICAgIHJ1bjogZnVuY3Rpb24oYmxvY2spIHsKICAgICAgICAgICAgcnVuQmxvY2tzLnB1c2goYmxvY2spOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBpZiAoY29uZmlnRm4pIHsKICAgICAgICAgIGNvbmZpZyhjb25maWdGbik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbW9kdWxlSW5zdGFuY2U7CgogICAgICAgIC8qKgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwcm92aWRlcgogICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZz19IGluc2VydE1ldGhvZAogICAgICAgICAqIEByZXR1cm5zIHthbmd1bGFyLk1vZHVsZX0KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBpbnZva2VMYXRlcihwcm92aWRlciwgbWV0aG9kLCBpbnNlcnRNZXRob2QsIHF1ZXVlKSB7CiAgICAgICAgICBpZiAoIXF1ZXVlKSBxdWV1ZSA9IGludm9rZVF1ZXVlOwogICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBxdWV1ZVtpbnNlcnRNZXRob2QgfHwgJ3B1c2gnXShbcHJvdmlkZXIsIG1ldGhvZCwgYXJndW1lbnRzXSk7CiAgICAgICAgICAgIHJldHVybiBtb2R1bGVJbnN0YW5jZTsKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9KTsKICAgIH07CiAgfSk7Cgp9CgovKiBnbG9iYWw6IHRvRGVidWdTdHJpbmc6IHRydWUgKi8KCmZ1bmN0aW9uIHNlcmlhbGl6ZU9iamVjdChvYmopIHsKICB2YXIgc2VlbiA9IFtdOwoKICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqLCBmdW5jdGlvbihrZXksIHZhbCkgewogICAgdmFsID0gdG9Kc29uUmVwbGFjZXIoa2V5LCB2YWwpOwogICAgaWYgKGlzT2JqZWN0KHZhbCkpIHsKCiAgICAgIGlmIChzZWVuLmluZGV4T2YodmFsKSA+PSAwKSByZXR1cm4gJzw8YWxyZWFkeSBzZWVuPj4nOwoKICAgICAgc2Vlbi5wdXNoKHZhbCk7CiAgICB9CiAgICByZXR1cm4gdmFsOwogIH0pOwp9CgpmdW5jdGlvbiB0b0RlYnVnU3RyaW5nKG9iaikgewogIGlmICh0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7CiAgICByZXR1cm4gb2JqLnRvU3RyaW5nKCkucmVwbGFjZSgvIFx7W1xzXFNdKiQvLCAnJyk7CiAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuICd1bmRlZmluZWQnOwogIH0gZWxzZSBpZiAodHlwZW9mIG9iaiAhPT0gJ3N0cmluZycpIHsKICAgIHJldHVybiBzZXJpYWxpemVPYmplY3Qob2JqKTsKICB9CiAgcmV0dXJuIG9iajsKfQoKLyogZ2xvYmFsIGFuZ3VsYXJNb2R1bGU6IHRydWUsCiAgdmVyc2lvbjogdHJ1ZSwKCiAgJExvY2FsZVByb3ZpZGVyLAogICRDb21waWxlUHJvdmlkZXIsCgogIGh0bWxBbmNob3JEaXJlY3RpdmUsCiAgaW5wdXREaXJlY3RpdmUsCiAgaW5wdXREaXJlY3RpdmUsCiAgZm9ybURpcmVjdGl2ZSwKICBzY3JpcHREaXJlY3RpdmUsCiAgc2VsZWN0RGlyZWN0aXZlLAogIHN0eWxlRGlyZWN0aXZlLAogIG9wdGlvbkRpcmVjdGl2ZSwKICBuZ0JpbmREaXJlY3RpdmUsCiAgbmdCaW5kSHRtbERpcmVjdGl2ZSwKICBuZ0JpbmRUZW1wbGF0ZURpcmVjdGl2ZSwKICBuZ0NsYXNzRGlyZWN0aXZlLAogIG5nQ2xhc3NFdmVuRGlyZWN0aXZlLAogIG5nQ2xhc3NPZGREaXJlY3RpdmUsCiAgbmdDc3BEaXJlY3RpdmUsCiAgbmdDbG9ha0RpcmVjdGl2ZSwKICBuZ0NvbnRyb2xsZXJEaXJlY3RpdmUsCiAgbmdGb3JtRGlyZWN0aXZlLAogIG5nSGlkZURpcmVjdGl2ZSwKICBuZ0lmRGlyZWN0aXZlLAogIG5nSW5jbHVkZURpcmVjdGl2ZSwKICBuZ0luY2x1ZGVGaWxsQ29udGVudERpcmVjdGl2ZSwKICBuZ0luaXREaXJlY3RpdmUsCiAgbmdOb25CaW5kYWJsZURpcmVjdGl2ZSwKICBuZ1BsdXJhbGl6ZURpcmVjdGl2ZSwKICBuZ1JlcGVhdERpcmVjdGl2ZSwKICBuZ1Nob3dEaXJlY3RpdmUsCiAgbmdTdHlsZURpcmVjdGl2ZSwKICBuZ1N3aXRjaERpcmVjdGl2ZSwKICBuZ1N3aXRjaFdoZW5EaXJlY3RpdmUsCiAgbmdTd2l0Y2hEZWZhdWx0RGlyZWN0aXZlLAogIG5nT3B0aW9uc0RpcmVjdGl2ZSwKICBuZ1RyYW5zY2x1ZGVEaXJlY3RpdmUsCiAgbmdNb2RlbERpcmVjdGl2ZSwKICBuZ0xpc3REaXJlY3RpdmUsCiAgbmdDaGFuZ2VEaXJlY3RpdmUsCiAgcGF0dGVybkRpcmVjdGl2ZSwKICBwYXR0ZXJuRGlyZWN0aXZlLAogIHJlcXVpcmVkRGlyZWN0aXZlLAogIHJlcXVpcmVkRGlyZWN0aXZlLAogIG1pbmxlbmd0aERpcmVjdGl2ZSwKICBtaW5sZW5ndGhEaXJlY3RpdmUsCiAgbWF4bGVuZ3RoRGlyZWN0aXZlLAogIG1heGxlbmd0aERpcmVjdGl2ZSwKICBuZ1ZhbHVlRGlyZWN0aXZlLAogIG5nTW9kZWxPcHRpb25zRGlyZWN0aXZlLAogIG5nQXR0cmlidXRlQWxpYXNEaXJlY3RpdmVzLAogIG5nRXZlbnREaXJlY3RpdmVzLAoKICAkQW5jaG9yU2Nyb2xsUHJvdmlkZXIsCiAgJEFuaW1hdGVQcm92aWRlciwKICAkQnJvd3NlclByb3ZpZGVyLAogICRDYWNoZUZhY3RvcnlQcm92aWRlciwKICAkQ29udHJvbGxlclByb3ZpZGVyLAogICREb2N1bWVudFByb3ZpZGVyLAogICRFeGNlcHRpb25IYW5kbGVyUHJvdmlkZXIsCiAgJEZpbHRlclByb3ZpZGVyLAogICRJbnRlcnBvbGF0ZVByb3ZpZGVyLAogICRJbnRlcnZhbFByb3ZpZGVyLAogICRIdHRwUHJvdmlkZXIsCiAgJEh0dHBCYWNrZW5kUHJvdmlkZXIsCiAgJExvY2F0aW9uUHJvdmlkZXIsCiAgJExvZ1Byb3ZpZGVyLAogICRQYXJzZVByb3ZpZGVyLAogICRSb290U2NvcGVQcm92aWRlciwKICAkUVByb3ZpZGVyLAogICQkUVByb3ZpZGVyLAogICQkU2FuaXRpemVVcmlQcm92aWRlciwKICAkU2NlUHJvdmlkZXIsCiAgJFNjZURlbGVnYXRlUHJvdmlkZXIsCiAgJFNuaWZmZXJQcm92aWRlciwKICAkVGVtcGxhdGVDYWNoZVByb3ZpZGVyLAogICRUZW1wbGF0ZVJlcXVlc3RQcm92aWRlciwKICAkJFRlc3RhYmlsaXR5UHJvdmlkZXIsCiAgJFRpbWVvdXRQcm92aWRlciwKICAkJFJBRlByb3ZpZGVyLAogICQkQXN5bmNDYWxsYmFja1Byb3ZpZGVyLAogICRXaW5kb3dQcm92aWRlciwKICAkJGpxTGl0ZVByb3ZpZGVyCiovCgoKLyoqCiAqIEBuZ2RvYyBvYmplY3QKICogQG5hbWUgYW5ndWxhci52ZXJzaW9uCiAqIEBtb2R1bGUgbmcKICogQGRlc2NyaXB0aW9uCiAqIEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IEFuZ3VsYXJKUyB2ZXJzaW9uLiBUaGlzIG9iamVjdCBoYXMgdGhlCiAqIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogKgogKiAtIGBmdWxsYCDigD8gYHtzdHJpbmd9YCDigD8gRnVsbCB2ZXJzaW9uIHN0cmluZywgc3VjaCBhcyAiMC45LjE4Ii4KICogLSBgbWFqb3JgIOKAPyBge251bWJlcn1gIOKAPyBNYWpvciB2ZXJzaW9uIG51bWJlciwgc3VjaCBhcyAiMCIuCiAqIC0gYG1pbm9yYCDigD8gYHtudW1iZXJ9YCDigD8gTWlub3IgdmVyc2lvbiBudW1iZXIsIHN1Y2ggYXMgIjkiLgogKiAtIGBkb3RgIOKAPyBge251bWJlcn1gIOKAPyBEb3QgdmVyc2lvbiBudW1iZXIsIHN1Y2ggYXMgIjE4Ii4KICogLSBgY29kZU5hbWVgIOKAPyBge3N0cmluZ31gIOKAPyBDb2RlIG5hbWUgb2YgdGhlIHJlbGVhc2UsIHN1Y2ggYXMgImppZ2dsaW5nLWFybWZhdCIuCiAqLwp2YXIgdmVyc2lvbiA9IHsKICBmdWxsOiAnMS4zLjgnLCAgICAvLyBhbGwgb2YgdGhlc2UgcGxhY2Vob2xkZXIgc3RyaW5ncyB3aWxsIGJlIHJlcGxhY2VkIGJ5IGdydW50J3MKICBtYWpvcjogMSwgICAgLy8gcGFja2FnZSB0YXNrCiAgbWlub3I6IDMsCiAgZG90OiA4LAogIGNvZGVOYW1lOiAncHJvcGhldGljLW5hcndoYWwnCn07CgoKZnVuY3Rpb24gcHVibGlzaEV4dGVybmFsQVBJKGFuZ3VsYXIpIHsKICBleHRlbmQoYW5ndWxhciwgewogICAgJ2Jvb3RzdHJhcCc6IGJvb3RzdHJhcCwKICAgICdjb3B5JzogY29weSwKICAgICdleHRlbmQnOiBleHRlbmQsCiAgICAnZXF1YWxzJzogZXF1YWxzLAogICAgJ2VsZW1lbnQnOiBqcUxpdGUsCiAgICAnZm9yRWFjaCc6IGZvckVhY2gsCiAgICAnaW5qZWN0b3InOiBjcmVhdGVJbmplY3RvciwKICAgICdub29wJzogbm9vcCwKICAgICdiaW5kJzogYmluZCwKICAgICd0b0pzb24nOiB0b0pzb24sCiAgICAnZnJvbUpzb24nOiBmcm9tSnNvbiwKICAgICdpZGVudGl0eSc6IGlkZW50aXR5LAogICAgJ2lzVW5kZWZpbmVkJzogaXNVbmRlZmluZWQsCiAgICAnaXNEZWZpbmVkJzogaXNEZWZpbmVkLAogICAgJ2lzU3RyaW5nJzogaXNTdHJpbmcsCiAgICAnaXNGdW5jdGlvbic6IGlzRnVuY3Rpb24sCiAgICAnaXNPYmplY3QnOiBpc09iamVjdCwKICAgICdpc051bWJlcic6IGlzTnVtYmVyLAogICAgJ2lzRWxlbWVudCc6IGlzRWxlbWVudCwKICAgICdpc0FycmF5JzogaXNBcnJheSwKICAgICd2ZXJzaW9uJzogdmVyc2lvbiwKICAgICdpc0RhdGUnOiBpc0RhdGUsCiAgICAnbG93ZXJjYXNlJzogbG93ZXJjYXNlLAogICAgJ3VwcGVyY2FzZSc6IHVwcGVyY2FzZSwKICAgICdjYWxsYmFja3MnOiB7Y291bnRlcjogMH0sCiAgICAnZ2V0VGVzdGFiaWxpdHknOiBnZXRUZXN0YWJpbGl0eSwKICAgICckJG1pbkVycic6IG1pbkVyciwKICAgICckJGNzcCc6IGNzcCwKICAgICdyZWxvYWRXaXRoRGVidWdJbmZvJzogcmVsb2FkV2l0aERlYnVnSW5mbwogIH0pOwoKICBhbmd1bGFyTW9kdWxlID0gc2V0dXBNb2R1bGVMb2FkZXIod2luZG93KTsKICB0cnkgewogICAgYW5ndWxhck1vZHVsZSgnbmdMb2NhbGUnKTsKICB9IGNhdGNoIChlKSB7CiAgICBhbmd1bGFyTW9kdWxlKCduZ0xvY2FsZScsIFtdKS5wcm92aWRlcignJGxvY2FsZScsICRMb2NhbGVQcm92aWRlcik7CiAgfQoKICBhbmd1bGFyTW9kdWxlKCduZycsIFsnbmdMb2NhbGUnXSwgWyckcHJvdmlkZScsCiAgICBmdW5jdGlvbiBuZ01vZHVsZSgkcHJvdmlkZSkgewogICAgICAvLyAkJHNhbml0aXplVXJpUHJvdmlkZXIgbmVlZHMgdG8gYmUgYmVmb3JlICRjb21waWxlUHJvdmlkZXIgYXMgaXQgaXMgdXNlZCBieSBpdC4KICAgICAgJHByb3ZpZGUucHJvdmlkZXIoewogICAgICAgICQkc2FuaXRpemVVcmk6ICQkU2FuaXRpemVVcmlQcm92aWRlcgogICAgICB9KTsKICAgICAgJHByb3ZpZGUucHJvdmlkZXIoJyRjb21waWxlJywgJENvbXBpbGVQcm92aWRlcikuCiAgICAgICAgZGlyZWN0aXZlKHsKICAgICAgICAgICAgYTogaHRtbEFuY2hvckRpcmVjdGl2ZSwKICAgICAgICAgICAgaW5wdXQ6IGlucHV0RGlyZWN0aXZlLAogICAgICAgICAgICB0ZXh0YXJlYTogaW5wdXREaXJlY3RpdmUsCiAgICAgICAgICAgIGZvcm06IGZvcm1EaXJlY3RpdmUsCiAgICAgICAgICAgIHNjcmlwdDogc2NyaXB0RGlyZWN0aXZlLAogICAgICAgICAgICBzZWxlY3Q6IHNlbGVjdERpcmVjdGl2ZSwKICAgICAgICAgICAgc3R5bGU6IHN0eWxlRGlyZWN0aXZlLAogICAgICAgICAgICBvcHRpb246IG9wdGlvbkRpcmVjdGl2ZSwKICAgICAgICAgICAgbmdCaW5kOiBuZ0JpbmREaXJlY3RpdmUsCiAgICAgICAgICAgIG5nQmluZEh0bWw6IG5nQmluZEh0bWxEaXJlY3RpdmUsCiAgICAgICAgICAgIG5nQmluZFRlbXBsYXRlOiBuZ0JpbmRUZW1wbGF0ZURpcmVjdGl2ZSwKICAgICAgICAgICAgbmdDbGFzczogbmdDbGFzc0RpcmVjdGl2ZSwKICAgICAgICAgICAgbmdDbGFzc0V2ZW46IG5nQ2xhc3NFdmVuRGlyZWN0aXZlLAogICAgICAgICAgICBuZ0NsYXNzT2RkOiBuZ0NsYXNzT2RkRGlyZWN0aXZlLAogICAgICAgICAgICBuZ0Nsb2FrOiBuZ0Nsb2FrRGlyZWN0aXZlLAogICAgICAgICAgICBuZ0NvbnRyb2xsZXI6IG5nQ29udHJvbGxlckRpcmVjdGl2ZSwKICAgICAgICAgICAgbmdGb3JtOiBuZ0Zvcm1EaXJlY3RpdmUsCiAgICAgICAgICAgIG5nSGlkZTogbmdIaWRlRGlyZWN0aXZlLAogICAgICAgICAgICBuZ0lmOiBuZ0lmRGlyZWN0aXZlLAogICAgICAgICAgICBuZ0luY2x1ZGU6IG5nSW5jbHVkZURpcmVjdGl2ZSwKICAgICAgICAgICAgbmdJbml0OiBuZ0luaXREaXJlY3RpdmUsCiAgICAgICAgICAgIG5nTm9uQmluZGFibGU6IG5nTm9uQmluZGFibGVEaXJlY3RpdmUsCiAgICAgICAgICAgIG5nUGx1cmFsaXplOiBuZ1BsdXJhbGl6ZURpcmVjdGl2ZSwKICAgICAgICAgICAgbmdSZXBlYXQ6IG5nUmVwZWF0RGlyZWN0aXZlLAogICAgICAgICAgICBuZ1Nob3c6IG5nU2hvd0RpcmVjdGl2ZSwKICAgICAgICAgICAgbmdTdHlsZTogbmdTdHlsZURpcmVjdGl2ZSwKICAgICAgICAgICAgbmdTd2l0Y2g6IG5nU3dpdGNoRGlyZWN0aXZlLAogICAgICAgICAgICBuZ1N3aXRjaFdoZW46IG5nU3dpdGNoV2hlbkRpcmVjdGl2ZSwKICAgICAgICAgICAgbmdTd2l0Y2hEZWZhdWx0OiBuZ1N3aXRjaERlZmF1bHREaXJlY3RpdmUsCiAgICAgICAgICAgIG5nT3B0aW9uczogbmdPcHRpb25zRGlyZWN0aXZlLAogICAgICAgICAgICBuZ1RyYW5zY2x1ZGU6IG5nVHJhbnNjbHVkZURpcmVjdGl2ZSwKICAgICAgICAgICAgbmdNb2RlbDogbmdNb2RlbERpcmVjdGl2ZSwKICAgICAgICAgICAgbmdMaXN0OiBuZ0xpc3REaXJlY3RpdmUsCiAgICAgICAgICAgIG5nQ2hhbmdlOiBuZ0NoYW5nZURpcmVjdGl2ZSwKICAgICAgICAgICAgcGF0dGVybjogcGF0dGVybkRpcmVjdGl2ZSwKICAgICAgICAgICAgbmdQYXR0ZXJuOiBwYXR0ZXJuRGlyZWN0aXZlLAogICAgICAgICAgICByZXF1aXJlZDogcmVxdWlyZWREaXJlY3RpdmUsCiAgICAgICAgICAgIG5nUmVxdWlyZWQ6IHJlcXVpcmVkRGlyZWN0aXZlLAogICAgICAgICAgICBtaW5sZW5ndGg6IG1pbmxlbmd0aERpcmVjdGl2ZSwKICAgICAgICAgICAgbmdNaW5sZW5ndGg6IG1pbmxlbmd0aERpcmVjdGl2ZSwKICAgICAgICAgICAgbWF4bGVuZ3RoOiBtYXhsZW5ndGhEaXJlY3RpdmUsCiAgICAgICAgICAgIG5nTWF4bGVuZ3RoOiBtYXhsZW5ndGhEaXJlY3RpdmUsCiAgICAgICAgICAgIG5nVmFsdWU6IG5nVmFsdWVEaXJlY3RpdmUsCiAgICAgICAgICAgIG5nTW9kZWxPcHRpb25zOiBuZ01vZGVsT3B0aW9uc0RpcmVjdGl2ZQogICAgICAgIH0pLgogICAgICAgIGRpcmVjdGl2ZSh7CiAgICAgICAgICBuZ0luY2x1ZGU6IG5nSW5jbHVkZUZpbGxDb250ZW50RGlyZWN0aXZlCiAgICAgICAgfSkuCiAgICAgICAgZGlyZWN0aXZlKG5nQXR0cmlidXRlQWxpYXNEaXJlY3RpdmVzKS4KICAgICAgICBkaXJlY3RpdmUobmdFdmVudERpcmVjdGl2ZXMpOwogICAgICAkcHJvdmlkZS5wcm92aWRlcih7CiAgICAgICAgJGFuY2hvclNjcm9sbDogJEFuY2hvclNjcm9sbFByb3ZpZGVyLAogICAgICAgICRhbmltYXRlOiAkQW5pbWF0ZVByb3ZpZGVyLAogICAgICAgICRicm93c2VyOiAkQnJvd3NlclByb3ZpZGVyLAogICAgICAgICRjYWNoZUZhY3Rvcnk6ICRDYWNoZUZhY3RvcnlQcm92aWRlciwKICAgICAgICAkY29udHJvbGxlcjogJENvbnRyb2xsZXJQcm92aWRlciwKICAgICAgICAkZG9jdW1lbnQ6ICREb2N1bWVudFByb3ZpZGVyLAogICAgICAgICRleGNlcHRpb25IYW5kbGVyOiAkRXhjZXB0aW9uSGFuZGxlclByb3ZpZGVyLAogICAgICAgICRmaWx0ZXI6ICRGaWx0ZXJQcm92aWRlciwKICAgICAgICAkaW50ZXJwb2xhdGU6ICRJbnRlcnBvbGF0ZVByb3ZpZGVyLAogICAgICAgICRpbnRlcnZhbDogJEludGVydmFsUHJvdmlkZXIsCiAgICAgICAgJGh0dHA6ICRIdHRwUHJvdmlkZXIsCiAgICAgICAgJGh0dHBCYWNrZW5kOiAkSHR0cEJhY2tlbmRQcm92aWRlciwKICAgICAgICAkbG9jYXRpb246ICRMb2NhdGlvblByb3ZpZGVyLAogICAgICAgICRsb2c6ICRMb2dQcm92aWRlciwKICAgICAgICAkcGFyc2U6ICRQYXJzZVByb3ZpZGVyLAogICAgICAgICRyb290U2NvcGU6ICRSb290U2NvcGVQcm92aWRlciwKICAgICAgICAkcTogJFFQcm92aWRlciwKICAgICAgICAkJHE6ICQkUVByb3ZpZGVyLAogICAgICAgICRzY2U6ICRTY2VQcm92aWRlciwKICAgICAgICAkc2NlRGVsZWdhdGU6ICRTY2VEZWxlZ2F0ZVByb3ZpZGVyLAogICAgICAgICRzbmlmZmVyOiAkU25pZmZlclByb3ZpZGVyLAogICAgICAgICR0ZW1wbGF0ZUNhY2hlOiAkVGVtcGxhdGVDYWNoZVByb3ZpZGVyLAogICAgICAgICR0ZW1wbGF0ZVJlcXVlc3Q6ICRUZW1wbGF0ZVJlcXVlc3RQcm92aWRlciwKICAgICAgICAkJHRlc3RhYmlsaXR5OiAkJFRlc3RhYmlsaXR5UHJvdmlkZXIsCiAgICAgICAgJHRpbWVvdXQ6ICRUaW1lb3V0UHJvdmlkZXIsCiAgICAgICAgJHdpbmRvdzogJFdpbmRvd1Byb3ZpZGVyLAogICAgICAgICQkckFGOiAkJFJBRlByb3ZpZGVyLAogICAgICAgICQkYXN5bmNDYWxsYmFjazogJCRBc3luY0NhbGxiYWNrUHJvdmlkZXIsCiAgICAgICAgJCRqcUxpdGU6ICQkanFMaXRlUHJvdmlkZXIKICAgICAgfSk7CiAgICB9CiAgXSk7Cn0KCi8qIGdsb2JhbCBKUUxpdGVQcm90b3R5cGU6IHRydWUsCiAgYWRkRXZlbnRMaXN0ZW5lckZuOiB0cnVlLAogIHJlbW92ZUV2ZW50TGlzdGVuZXJGbjogdHJ1ZSwKICBCT09MRUFOX0FUVFI6IHRydWUsCiAgQUxJQVNFRF9BVFRSOiB0cnVlLAoqLwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovL0pRTGl0ZQovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBuYW1lIGFuZ3VsYXIuZWxlbWVudAogKiBAbW9kdWxlIG5nCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBXcmFwcyBhIHJhdyBET00gZWxlbWVudCBvciBIVE1MIHN0cmluZyBhcyBhIFtqUXVlcnldKGh0dHA6Ly9qcXVlcnkuY29tKSBlbGVtZW50LgogKgogKiBJZiBqUXVlcnkgaXMgYXZhaWxhYmxlLCBgYW5ndWxhci5lbGVtZW50YCBpcyBhbiBhbGlhcyBmb3IgdGhlCiAqIFtqUXVlcnldKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9qUXVlcnkvKSBmdW5jdGlvbi4gSWYgalF1ZXJ5IGlzIG5vdCBhdmFpbGFibGUsIGBhbmd1bGFyLmVsZW1lbnRgCiAqIGRlbGVnYXRlcyB0byBBbmd1bGFyJ3MgYnVpbHQtaW4gc3Vic2V0IG9mIGpRdWVyeSwgY2FsbGVkICJqUXVlcnkgbGl0ZSIgb3IgImpxTGl0ZS4iCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MiPmpxTGl0ZSBpcyBhIHRpbnksIEFQSS1jb21wYXRpYmxlIHN1YnNldCBvZiBqUXVlcnkgdGhhdCBhbGxvd3MKICogQW5ndWxhciB0byBtYW5pcHVsYXRlIHRoZSBET00gaW4gYSBjcm9zcy1icm93c2VyIGNvbXBhdGlibGUgd2F5LiAqKmpxTGl0ZSoqIGltcGxlbWVudHMgb25seSB0aGUgbW9zdAogKiBjb21tb25seSBuZWVkZWQgZnVuY3Rpb25hbGl0eSB3aXRoIHRoZSBnb2FsIG9mIGhhdmluZyBhIHZlcnkgc21hbGwgZm9vdHByaW50LjwvZGl2PgogKgogKiBUbyB1c2UgalF1ZXJ5LCBzaW1wbHkgbG9hZCBpdCBiZWZvcmUgYERPTUNvbnRlbnRMb2FkZWRgIGV2ZW50IGZpcmVkLgogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCI+KipOb3RlOioqIGFsbCBlbGVtZW50IHJlZmVyZW5jZXMgaW4gQW5ndWxhciBhcmUgYWx3YXlzIHdyYXBwZWQgd2l0aCBqUXVlcnkgb3IKICoganFMaXRlOyB0aGV5IGFyZSBuZXZlciByYXcgRE9NIHJlZmVyZW5jZXMuPC9kaXY+CiAqCiAqICMjIEFuZ3VsYXIncyBqcUxpdGUKICoganFMaXRlIHByb3ZpZGVzIG9ubHkgdGhlIGZvbGxvd2luZyBqUXVlcnkgbWV0aG9kczoKICoKICogLSBbYGFkZENsYXNzKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vYWRkQ2xhc3MvKQogKiAtIFtgYWZ0ZXIoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9hZnRlci8pCiAqIC0gW2BhcHBlbmQoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9hcHBlbmQvKQogKiAtIFtgYXR0cigpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL2F0dHIvKSAtIERvZXMgbm90IHN1cHBvcnQgZnVuY3Rpb25zIGFzIHBhcmFtZXRlcnMKICogLSBbYGJpbmQoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9iaW5kLykgLSBEb2VzIG5vdCBzdXBwb3J0IG5hbWVzcGFjZXMsIHNlbGVjdG9ycyBvciBldmVudERhdGEKICogLSBbYGNoaWxkcmVuKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vY2hpbGRyZW4vKSAtIERvZXMgbm90IHN1cHBvcnQgc2VsZWN0b3JzCiAqIC0gW2BjbG9uZSgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL2Nsb25lLykKICogLSBbYGNvbnRlbnRzKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vY29udGVudHMvKQogKiAtIFtgY3NzKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vY3NzLykgLSBPbmx5IHJldHJpZXZlcyBpbmxpbmUtc3R5bGVzLCBkb2VzIG5vdCBjYWxsIGBnZXRDb21wdXRlZFN0eWxlKClgCiAqIC0gW2BkYXRhKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vZGF0YS8pCiAqIC0gW2BkZXRhY2goKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9kZXRhY2gvKQogKiAtIFtgZW1wdHkoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9lbXB0eS8pCiAqIC0gW2BlcSgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL2VxLykKICogLSBbYGZpbmQoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9maW5kLykgLSBMaW1pdGVkIHRvIGxvb2t1cHMgYnkgdGFnIG5hbWUKICogLSBbYGhhc0NsYXNzKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vaGFzQ2xhc3MvKQogKiAtIFtgaHRtbCgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL2h0bWwvKQogKiAtIFtgbmV4dCgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL25leHQvKSAtIERvZXMgbm90IHN1cHBvcnQgc2VsZWN0b3JzCiAqIC0gW2BvbigpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL29uLykgLSBEb2VzIG5vdCBzdXBwb3J0IG5hbWVzcGFjZXMsIHNlbGVjdG9ycyBvciBldmVudERhdGEKICogLSBbYG9mZigpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL29mZi8pIC0gRG9lcyBub3Qgc3VwcG9ydCBuYW1lc3BhY2VzIG9yIHNlbGVjdG9ycwogKiAtIFtgb25lKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vb25lLykgLSBEb2VzIG5vdCBzdXBwb3J0IG5hbWVzcGFjZXMgb3Igc2VsZWN0b3JzCiAqIC0gW2BwYXJlbnQoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9wYXJlbnQvKSAtIERvZXMgbm90IHN1cHBvcnQgc2VsZWN0b3JzCiAqIC0gW2BwcmVwZW5kKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vcHJlcGVuZC8pCiAqIC0gW2Bwcm9wKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vcHJvcC8pCiAqIC0gW2ByZWFkeSgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL3JlYWR5LykKICogLSBbYHJlbW92ZSgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL3JlbW92ZS8pCiAqIC0gW2ByZW1vdmVBdHRyKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vcmVtb3ZlQXR0ci8pCiAqIC0gW2ByZW1vdmVDbGFzcygpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL3JlbW92ZUNsYXNzLykKICogLSBbYHJlbW92ZURhdGEoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9yZW1vdmVEYXRhLykKICogLSBbYHJlcGxhY2VXaXRoKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vcmVwbGFjZVdpdGgvKQogKiAtIFtgdGV4dCgpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL3RleHQvKQogKiAtIFtgdG9nZ2xlQ2xhc3MoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS90b2dnbGVDbGFzcy8pCiAqIC0gW2B0cmlnZ2VySGFuZGxlcigpYF0oaHR0cDovL2FwaS5qcXVlcnkuY29tL3RyaWdnZXJIYW5kbGVyLykgLSBQYXNzZXMgYSBkdW1teSBldmVudCBvYmplY3QgdG8gaGFuZGxlcnMuCiAqIC0gW2B1bmJpbmQoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS91bmJpbmQvKSAtIERvZXMgbm90IHN1cHBvcnQgbmFtZXNwYWNlcwogKiAtIFtgdmFsKClgXShodHRwOi8vYXBpLmpxdWVyeS5jb20vdmFsLykKICogLSBbYHdyYXAoKWBdKGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS93cmFwLykKICoKICogIyMgalF1ZXJ5L2pxTGl0ZSBFeHRyYXMKICogQW5ndWxhciBhbHNvIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcgYWRkaXRpb25hbCBtZXRob2RzIGFuZCBldmVudHMgdG8gYm90aCBqUXVlcnkgYW5kIGpxTGl0ZToKICoKICogIyMjIEV2ZW50cwogKiAtIGAkZGVzdHJveWAgLSBBbmd1bGFySlMgaW50ZXJjZXB0cyBhbGwganFMaXRlL2pRdWVyeSdzIERPTSBkZXN0cnVjdGlvbiBhcGlzIGFuZCBmaXJlcyB0aGlzIGV2ZW50CiAqICAgIG9uIGFsbCBET00gbm9kZXMgYmVpbmcgcmVtb3ZlZC4gIFRoaXMgY2FuIGJlIHVzZWQgdG8gY2xlYW4gdXAgYW55IDNyZCBwYXJ0eSBiaW5kaW5ncyB0byB0aGUgRE9NCiAqICAgIGVsZW1lbnQgYmVmb3JlIGl0IGlzIHJlbW92ZWQuCiAqCiAqICMjIyBNZXRob2RzCiAqIC0gYGNvbnRyb2xsZXIobmFtZSlgIC0gcmV0cmlldmVzIHRoZSBjb250cm9sbGVyIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgb3IgaXRzIHBhcmVudC4gQnkgZGVmYXVsdAogKiAgIHJldHJpZXZlcyBjb250cm9sbGVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgYG5nQ29udHJvbGxlcmAgZGlyZWN0aXZlLiBJZiBgbmFtZWAgaXMgcHJvdmlkZWQgYXMKICogICBjYW1lbENhc2UgZGlyZWN0aXZlIG5hbWUsIHRoZW4gdGhlIGNvbnRyb2xsZXIgZm9yIHRoaXMgZGlyZWN0aXZlIHdpbGwgYmUgcmV0cmlldmVkIChlLmcuCiAqICAgYCduZ01vZGVsJ2ApLgogKiAtIGBpbmplY3RvcigpYCAtIHJldHJpZXZlcyB0aGUgaW5qZWN0b3Igb2YgdGhlIGN1cnJlbnQgZWxlbWVudCBvciBpdHMgcGFyZW50LgogKiAtIGBzY29wZSgpYCAtIHJldHJpZXZlcyB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUgc2NvcGV9IG9mIHRoZSBjdXJyZW50CiAqICAgZWxlbWVudCBvciBpdHMgcGFyZW50LiBSZXF1aXJlcyB7QGxpbmsgZ3VpZGUvcHJvZHVjdGlvbiNkaXNhYmxpbmctZGVidWctZGF0YSBEZWJ1ZyBEYXRhfSB0bwogKiAgIGJlIGVuYWJsZWQuCiAqIC0gYGlzb2xhdGVTY29wZSgpYCAtIHJldHJpZXZlcyBhbiBpc29sYXRlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIHNjb3BlfSBpZiBvbmUgaXMgYXR0YWNoZWQgZGlyZWN0bHkgdG8gdGhlCiAqICAgY3VycmVudCBlbGVtZW50LiBUaGlzIGdldHRlciBzaG91bGQgYmUgdXNlZCBvbmx5IG9uIGVsZW1lbnRzIHRoYXQgY29udGFpbiBhIGRpcmVjdGl2ZSB3aGljaCBzdGFydHMgYSBuZXcgaXNvbGF0ZQogKiAgIHNjb3BlLiBDYWxsaW5nIGBzY29wZSgpYCBvbiB0aGlzIGVsZW1lbnQgYWx3YXlzIHJldHVybnMgdGhlIG9yaWdpbmFsIG5vbi1pc29sYXRlIHNjb3BlLgogKiAgIFJlcXVpcmVzIHtAbGluayBndWlkZS9wcm9kdWN0aW9uI2Rpc2FibGluZy1kZWJ1Zy1kYXRhIERlYnVnIERhdGF9IHRvIGJlIGVuYWJsZWQuCiAqIC0gYGluaGVyaXRlZERhdGEoKWAgLSBzYW1lIGFzIGBkYXRhKClgLCBidXQgd2Fsa3MgdXAgdGhlIERPTSB1bnRpbCBhIHZhbHVlIGlzIGZvdW5kIG9yIHRoZSB0b3AKICogICBwYXJlbnQgZWxlbWVudCBpcyByZWFjaGVkLgogKgogKiBAcGFyYW0ge3N0cmluZ3xET01FbGVtZW50fSBlbGVtZW50IEhUTUwgc3RyaW5nIG9yIERPTUVsZW1lbnQgdG8gYmUgd3JhcHBlZCBpbnRvIGpRdWVyeS4KICogQHJldHVybnMge09iamVjdH0galF1ZXJ5IG9iamVjdC4KICovCgpKUUxpdGUuZXhwYW5kbyA9ICduZzMzOSc7Cgp2YXIganFDYWNoZSA9IEpRTGl0ZS5jYWNoZSA9IHt9LAogICAganFJZCA9IDEsCiAgICBhZGRFdmVudExpc3RlbmVyRm4gPSBmdW5jdGlvbihlbGVtZW50LCB0eXBlLCBmbikgewogICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIGZhbHNlKTsKICAgIH0sCiAgICByZW1vdmVFdmVudExpc3RlbmVyRm4gPSBmdW5jdGlvbihlbGVtZW50LCB0eXBlLCBmbikgewogICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIGZhbHNlKTsKICAgIH07CgovKgogKiAhISEgVGhpcyBpcyBhbiB1bmRvY3VtZW50ZWQgInByaXZhdGUiIGZ1bmN0aW9uICEhIQogKi8KSlFMaXRlLl9kYXRhID0gZnVuY3Rpb24obm9kZSkgewogIC8valF1ZXJ5IGFsd2F5cyByZXR1cm5zIGFuIG9iamVjdCBvbiBjYWNoZSBtaXNzCiAgcmV0dXJuIHRoaXMuY2FjaGVbbm9kZVt0aGlzLmV4cGFuZG9dXSB8fCB7fTsKfTsKCmZ1bmN0aW9uIGpxTmV4dElkKCkgeyByZXR1cm4gKytqcUlkOyB9CgoKdmFyIFNQRUNJQUxfQ0hBUlNfUkVHRVhQID0gLyhbXDpcLVxfXSsoLikpL2c7CnZhciBNT1pfSEFDS19SRUdFWFAgPSAvXm1veihbQS1aXSkvOwp2YXIgTU9VU0VfRVZFTlRfTUFQPSB7IG1vdXNlbGVhdmU6ICJtb3VzZW91dCIsIG1vdXNlZW50ZXI6ICJtb3VzZW92ZXIifTsKdmFyIGpxTGl0ZU1pbkVyciA9IG1pbkVycignanFMaXRlJyk7CgovKioKICogQ29udmVydHMgc25ha2VfY2FzZSB0byBjYW1lbENhc2UuCiAqIEFsc28gdGhlcmUgaXMgc3BlY2lhbCBjYXNlIGZvciBNb3ogcHJlZml4IHN0YXJ0aW5nIHdpdGggdXBwZXIgY2FzZSBsZXR0ZXIuCiAqIEBwYXJhbSBuYW1lIE5hbWUgdG8gbm9ybWFsaXplCiAqLwpmdW5jdGlvbiBjYW1lbENhc2UobmFtZSkgewogIHJldHVybiBuYW1lLgogICAgcmVwbGFjZShTUEVDSUFMX0NIQVJTX1JFR0VYUCwgZnVuY3Rpb24oXywgc2VwYXJhdG9yLCBsZXR0ZXIsIG9mZnNldCkgewogICAgICByZXR1cm4gb2Zmc2V0ID8gbGV0dGVyLnRvVXBwZXJDYXNlKCkgOiBsZXR0ZXI7CiAgICB9KS4KICAgIHJlcGxhY2UoTU9aX0hBQ0tfUkVHRVhQLCAnTW96JDEnKTsKfQoKdmFyIFNJTkdMRV9UQUdfUkVHRVhQID0gL148KFx3KylccypcLz8+KD86PFwvXDE+fCkkLzsKdmFyIEhUTUxfUkVHRVhQID0gLzx8JiM/XHcrOy87CnZhciBUQUdfTkFNRV9SRUdFWFAgPSAvPChbXHc6XSspLzsKdmFyIFhIVE1MX1RBR19SRUdFWFAgPSAvPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbXHc6XSspW14+XSopXC8+L2dpOwoKdmFyIHdyYXBNYXAgPSB7CiAgJ29wdGlvbic6IFsxLCAnPHNlbGVjdCBtdWx0aXBsZT0ibXVsdGlwbGUiPicsICc8L3NlbGVjdD4nXSwKCiAgJ3RoZWFkJzogWzEsICc8dGFibGU+JywgJzwvdGFibGU+J10sCiAgJ2NvbCc6IFsyLCAnPHRhYmxlPjxjb2xncm91cD4nLCAnPC9jb2xncm91cD48L3RhYmxlPiddLAogICd0cic6IFsyLCAnPHRhYmxlPjx0Ym9keT4nLCAnPC90Ym9keT48L3RhYmxlPiddLAogICd0ZCc6IFszLCAnPHRhYmxlPjx0Ym9keT48dHI+JywgJzwvdHI+PC90Ym9keT48L3RhYmxlPiddLAogICdfZGVmYXVsdCc6IFswLCAiIiwgIiJdCn07Cgp3cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247CndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7CndyYXBNYXAudGggPSB3cmFwTWFwLnRkOwoKCmZ1bmN0aW9uIGpxTGl0ZUlzVGV4dE5vZGUoaHRtbCkgewogIHJldHVybiAhSFRNTF9SRUdFWFAudGVzdChodG1sKTsKfQoKZnVuY3Rpb24ganFMaXRlQWNjZXB0c0RhdGEobm9kZSkgewogIC8vIFRoZSB3aW5kb3cgb2JqZWN0IGNhbiBhY2NlcHQgZGF0YSBidXQgaGFzIG5vIG5vZGVUeXBlCiAgLy8gT3RoZXJ3aXNlIHdlIGFyZSBvbmx5IGludGVyZXN0ZWQgaW4gZWxlbWVudHMgKDEpIGFuZCBkb2N1bWVudHMgKDkpCiAgdmFyIG5vZGVUeXBlID0gbm9kZS5ub2RlVHlwZTsKICByZXR1cm4gbm9kZVR5cGUgPT09IE5PREVfVFlQRV9FTEVNRU5UIHx8ICFub2RlVHlwZSB8fCBub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0RPQ1VNRU5UOwp9CgpmdW5jdGlvbiBqcUxpdGVCdWlsZEZyYWdtZW50KGh0bWwsIGNvbnRleHQpIHsKICB2YXIgdG1wLCB0YWcsIHdyYXAsCiAgICAgIGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksCiAgICAgIG5vZGVzID0gW10sIGk7CgogIGlmIChqcUxpdGVJc1RleHROb2RlKGh0bWwpKSB7CiAgICAvLyBDb252ZXJ0IG5vbi1odG1sIGludG8gYSB0ZXh0IG5vZGUKICAgIG5vZGVzLnB1c2goY29udGV4dC5jcmVhdGVUZXh0Tm9kZShodG1sKSk7CiAgfSBlbHNlIHsKICAgIC8vIENvbnZlcnQgaHRtbCBpbnRvIERPTSBub2RlcwogICAgdG1wID0gdG1wIHx8IGZyYWdtZW50LmFwcGVuZENoaWxkKGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2IikpOwogICAgdGFnID0gKFRBR19OQU1FX1JFR0VYUC5leGVjKGh0bWwpIHx8IFsiIiwgIiJdKVsxXS50b0xvd2VyQ2FzZSgpOwogICAgd3JhcCA9IHdyYXBNYXBbdGFnXSB8fCB3cmFwTWFwLl9kZWZhdWx0OwogICAgdG1wLmlubmVySFRNTCA9IHdyYXBbMV0gKyBodG1sLnJlcGxhY2UoWEhUTUxfVEFHX1JFR0VYUCwgIjwkMT48LyQyPiIpICsgd3JhcFsyXTsKCiAgICAvLyBEZXNjZW5kIHRocm91Z2ggd3JhcHBlcnMgdG8gdGhlIHJpZ2h0IGNvbnRlbnQKICAgIGkgPSB3cmFwWzBdOwogICAgd2hpbGUgKGktLSkgewogICAgICB0bXAgPSB0bXAubGFzdENoaWxkOwogICAgfQoKICAgIG5vZGVzID0gY29uY2F0KG5vZGVzLCB0bXAuY2hpbGROb2Rlcyk7CgogICAgdG1wID0gZnJhZ21lbnQuZmlyc3RDaGlsZDsKICAgIHRtcC50ZXh0Q29udGVudCA9ICIiOwogIH0KCiAgLy8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudAogIGZyYWdtZW50LnRleHRDb250ZW50ID0gIiI7CiAgZnJhZ21lbnQuaW5uZXJIVE1MID0gIiI7IC8vIENsZWFyIGlubmVyIEhUTUwKICBmb3JFYWNoKG5vZGVzLCBmdW5jdGlvbihub2RlKSB7CiAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChub2RlKTsKICB9KTsKCiAgcmV0dXJuIGZyYWdtZW50Owp9CgpmdW5jdGlvbiBqcUxpdGVQYXJzZUhUTUwoaHRtbCwgY29udGV4dCkgewogIGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwogIHZhciBwYXJzZWQ7CgogIGlmICgocGFyc2VkID0gU0lOR0xFX1RBR19SRUdFWFAuZXhlYyhodG1sKSkpIHsKICAgIHJldHVybiBbY29udGV4dC5jcmVhdGVFbGVtZW50KHBhcnNlZFsxXSldOwogIH0KCiAgaWYgKChwYXJzZWQgPSBqcUxpdGVCdWlsZEZyYWdtZW50KGh0bWwsIGNvbnRleHQpKSkgewogICAgcmV0dXJuIHBhcnNlZC5jaGlsZE5vZGVzOwogIH0KCiAgcmV0dXJuIFtdOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KZnVuY3Rpb24gSlFMaXRlKGVsZW1lbnQpIHsKICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEpRTGl0ZSkgewogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfQoKICB2YXIgYXJnSXNTdHJpbmc7CgogIGlmIChpc1N0cmluZyhlbGVtZW50KSkgewogICAgZWxlbWVudCA9IHRyaW0oZWxlbWVudCk7CiAgICBhcmdJc1N0cmluZyA9IHRydWU7CiAgfQogIGlmICghKHRoaXMgaW5zdGFuY2VvZiBKUUxpdGUpKSB7CiAgICBpZiAoYXJnSXNTdHJpbmcgJiYgZWxlbWVudC5jaGFyQXQoMCkgIT0gJzwnKSB7CiAgICAgIHRocm93IGpxTGl0ZU1pbkVycignbm9zZWwnLCAnTG9va2luZyB1cCBlbGVtZW50cyB2aWEgc2VsZWN0b3JzIGlzIG5vdCBzdXBwb3J0ZWQgYnkganFMaXRlISBTZWU6IGh0dHA6Ly9kb2NzLmFuZ3VsYXJqcy5vcmcvYXBpL2FuZ3VsYXIuZWxlbWVudCcpOwogICAgfQogICAgcmV0dXJuIG5ldyBKUUxpdGUoZWxlbWVudCk7CiAgfQoKICBpZiAoYXJnSXNTdHJpbmcpIHsKICAgIGpxTGl0ZUFkZE5vZGVzKHRoaXMsIGpxTGl0ZVBhcnNlSFRNTChlbGVtZW50KSk7CiAgfSBlbHNlIHsKICAgIGpxTGl0ZUFkZE5vZGVzKHRoaXMsIGVsZW1lbnQpOwogIH0KfQoKZnVuY3Rpb24ganFMaXRlQ2xvbmUoZWxlbWVudCkgewogIHJldHVybiBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTsKfQoKZnVuY3Rpb24ganFMaXRlRGVhbG9jKGVsZW1lbnQsIG9ubHlEZXNjZW5kYW50cykgewogIGlmICghb25seURlc2NlbmRhbnRzKSBqcUxpdGVSZW1vdmVEYXRhKGVsZW1lbnQpOwoKICBpZiAoZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKSB7CiAgICB2YXIgZGVzY2VuZGFudHMgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKTsKICAgIGZvciAodmFyIGkgPSAwLCBsID0gZGVzY2VuZGFudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgIGpxTGl0ZVJlbW92ZURhdGEoZGVzY2VuZGFudHNbaV0pOwogICAgfQogIH0KfQoKZnVuY3Rpb24ganFMaXRlT2ZmKGVsZW1lbnQsIHR5cGUsIGZuLCB1bnN1cHBvcnRlZCkgewogIGlmIChpc0RlZmluZWQodW5zdXBwb3J0ZWQpKSB0aHJvdyBqcUxpdGVNaW5FcnIoJ29mZmFyZ3MnLCAnanFMaXRlI29mZigpIGRvZXMgbm90IHN1cHBvcnQgdGhlIGBzZWxlY3RvcmAgYXJndW1lbnQnKTsKCiAgdmFyIGV4cGFuZG9TdG9yZSA9IGpxTGl0ZUV4cGFuZG9TdG9yZShlbGVtZW50KTsKICB2YXIgZXZlbnRzID0gZXhwYW5kb1N0b3JlICYmIGV4cGFuZG9TdG9yZS5ldmVudHM7CiAgdmFyIGhhbmRsZSA9IGV4cGFuZG9TdG9yZSAmJiBleHBhbmRvU3RvcmUuaGFuZGxlOwoKICBpZiAoIWhhbmRsZSkgcmV0dXJuOyAvL25vIGxpc3RlbmVycyByZWdpc3RlcmVkCgogIGlmICghdHlwZSkgewogICAgZm9yICh0eXBlIGluIGV2ZW50cykgewogICAgICBpZiAodHlwZSAhPT0gJyRkZXN0cm95JykgewogICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXJGbihlbGVtZW50LCB0eXBlLCBoYW5kbGUpOwogICAgICB9CiAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvckVhY2godHlwZS5zcGxpdCgnICcpLCBmdW5jdGlvbih0eXBlKSB7CiAgICAgIGlmIChpc0RlZmluZWQoZm4pKSB7CiAgICAgICAgdmFyIGxpc3RlbmVyRm5zID0gZXZlbnRzW3R5cGVdOwogICAgICAgIGFycmF5UmVtb3ZlKGxpc3RlbmVyRm5zIHx8IFtdLCBmbik7CiAgICAgICAgaWYgKGxpc3RlbmVyRm5zICYmIGxpc3RlbmVyRm5zLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXJGbihlbGVtZW50LCB0eXBlLCBoYW5kbGUpOwogICAgICBkZWxldGUgZXZlbnRzW3R5cGVdOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBqcUxpdGVSZW1vdmVEYXRhKGVsZW1lbnQsIG5hbWUpIHsKICB2YXIgZXhwYW5kb0lkID0gZWxlbWVudC5uZzMzOTsKICB2YXIgZXhwYW5kb1N0b3JlID0gZXhwYW5kb0lkICYmIGpxQ2FjaGVbZXhwYW5kb0lkXTsKCiAgaWYgKGV4cGFuZG9TdG9yZSkgewogICAgaWYgKG5hbWUpIHsKICAgICAgZGVsZXRlIGV4cGFuZG9TdG9yZS5kYXRhW25hbWVdOwogICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGV4cGFuZG9TdG9yZS5oYW5kbGUpIHsKICAgICAgaWYgKGV4cGFuZG9TdG9yZS5ldmVudHMuJGRlc3Ryb3kpIHsKICAgICAgICBleHBhbmRvU3RvcmUuaGFuZGxlKHt9LCAnJGRlc3Ryb3knKTsKICAgICAgfQogICAgICBqcUxpdGVPZmYoZWxlbWVudCk7CiAgICB9CiAgICBkZWxldGUganFDYWNoZVtleHBhbmRvSWRdOwogICAgZWxlbWVudC5uZzMzOSA9IHVuZGVmaW5lZDsgLy8gZG9uJ3QgZGVsZXRlIERPTSBleHBhbmRvcy4gSUUgYW5kIENocm9tZSBkb24ndCBsaWtlIGl0CiAgfQp9CgoKZnVuY3Rpb24ganFMaXRlRXhwYW5kb1N0b3JlKGVsZW1lbnQsIGNyZWF0ZUlmTmVjZXNzYXJ5KSB7CiAgdmFyIGV4cGFuZG9JZCA9IGVsZW1lbnQubmczMzksCiAgICAgIGV4cGFuZG9TdG9yZSA9IGV4cGFuZG9JZCAmJiBqcUNhY2hlW2V4cGFuZG9JZF07CgogIGlmIChjcmVhdGVJZk5lY2Vzc2FyeSAmJiAhZXhwYW5kb1N0b3JlKSB7CiAgICBlbGVtZW50Lm5nMzM5ID0gZXhwYW5kb0lkID0ganFOZXh0SWQoKTsKICAgIGV4cGFuZG9TdG9yZSA9IGpxQ2FjaGVbZXhwYW5kb0lkXSA9IHtldmVudHM6IHt9LCBkYXRhOiB7fSwgaGFuZGxlOiB1bmRlZmluZWR9OwogIH0KCiAgcmV0dXJuIGV4cGFuZG9TdG9yZTsKfQoKCmZ1bmN0aW9uIGpxTGl0ZURhdGEoZWxlbWVudCwga2V5LCB2YWx1ZSkgewogIGlmIChqcUxpdGVBY2NlcHRzRGF0YShlbGVtZW50KSkgewoKICAgIHZhciBpc1NpbXBsZVNldHRlciA9IGlzRGVmaW5lZCh2YWx1ZSk7CiAgICB2YXIgaXNTaW1wbGVHZXR0ZXIgPSAhaXNTaW1wbGVTZXR0ZXIgJiYga2V5ICYmICFpc09iamVjdChrZXkpOwogICAgdmFyIG1hc3NHZXR0ZXIgPSAha2V5OwogICAgdmFyIGV4cGFuZG9TdG9yZSA9IGpxTGl0ZUV4cGFuZG9TdG9yZShlbGVtZW50LCAhaXNTaW1wbGVHZXR0ZXIpOwogICAgdmFyIGRhdGEgPSBleHBhbmRvU3RvcmUgJiYgZXhwYW5kb1N0b3JlLmRhdGE7CgogICAgaWYgKGlzU2ltcGxlU2V0dGVyKSB7IC8vIGRhdGEoJ2tleScsIHZhbHVlKQogICAgICBkYXRhW2tleV0gPSB2YWx1ZTsKICAgIH0gZWxzZSB7CiAgICAgIGlmIChtYXNzR2V0dGVyKSB7ICAvLyBkYXRhKCkKICAgICAgICByZXR1cm4gZGF0YTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoaXNTaW1wbGVHZXR0ZXIpIHsgLy8gZGF0YSgna2V5JykKICAgICAgICAgIC8vIGRvbid0IGZvcmNlIGNyZWF0aW9uIG9mIGV4cGFuZG9TdG9yZSBpZiBpdCBkb2Vzbid0IGV4aXN0IHlldAogICAgICAgICAgcmV0dXJuIGRhdGEgJiYgZGF0YVtrZXldOwogICAgICAgIH0gZWxzZSB7IC8vIG1hc3Mtc2V0dGVyOiBkYXRhKHtrZXkxOiB2YWwxLCBrZXkyOiB2YWwyfSkKICAgICAgICAgIGV4dGVuZChkYXRhLCBrZXkpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQoKZnVuY3Rpb24ganFMaXRlSGFzQ2xhc3MoZWxlbWVudCwgc2VsZWN0b3IpIHsKICBpZiAoIWVsZW1lbnQuZ2V0QXR0cmlidXRlKSByZXR1cm4gZmFsc2U7CiAgcmV0dXJuICgoIiAiICsgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnKSArICIgIikucmVwbGFjZSgvW1xuXHRdL2csICIgIikuCiAgICAgIGluZGV4T2YoIiAiICsgc2VsZWN0b3IgKyAiICIpID4gLTEpOwp9CgpmdW5jdGlvbiBqcUxpdGVSZW1vdmVDbGFzcyhlbGVtZW50LCBjc3NDbGFzc2VzKSB7CiAgaWYgKGNzc0NsYXNzZXMgJiYgZWxlbWVudC5zZXRBdHRyaWJ1dGUpIHsKICAgIGZvckVhY2goY3NzQ2xhc3Nlcy5zcGxpdCgnICcpLCBmdW5jdGlvbihjc3NDbGFzcykgewogICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCB0cmltKAogICAgICAgICAgKCIgIiArIChlbGVtZW50LmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykgKyAiICIpCiAgICAgICAgICAucmVwbGFjZSgvW1xuXHRdL2csICIgIikKICAgICAgICAgIC5yZXBsYWNlKCIgIiArIHRyaW0oY3NzQ2xhc3MpICsgIiAiLCAiICIpKQogICAgICApOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBqcUxpdGVBZGRDbGFzcyhlbGVtZW50LCBjc3NDbGFzc2VzKSB7CiAgaWYgKGNzc0NsYXNzZXMgJiYgZWxlbWVudC5zZXRBdHRyaWJ1dGUpIHsKICAgIHZhciBleGlzdGluZ0NsYXNzZXMgPSAoJyAnICsgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnKSArICcgJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9bXG5cdF0vZywgIiAiKTsKCiAgICBmb3JFYWNoKGNzc0NsYXNzZXMuc3BsaXQoJyAnKSwgZnVuY3Rpb24oY3NzQ2xhc3MpIHsKICAgICAgY3NzQ2xhc3MgPSB0cmltKGNzc0NsYXNzKTsKICAgICAgaWYgKGV4aXN0aW5nQ2xhc3Nlcy5pbmRleE9mKCcgJyArIGNzc0NsYXNzICsgJyAnKSA9PT0gLTEpIHsKICAgICAgICBleGlzdGluZ0NsYXNzZXMgKz0gY3NzQ2xhc3MgKyAnICc7CiAgICAgIH0KICAgIH0pOwoKICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdjbGFzcycsIHRyaW0oZXhpc3RpbmdDbGFzc2VzKSk7CiAgfQp9CgoKZnVuY3Rpb24ganFMaXRlQWRkTm9kZXMocm9vdCwgZWxlbWVudHMpIHsKICAvLyBUSElTIENPREUgSVMgVkVSWSBIT1QuIERvbid0IG1ha2UgY2hhbmdlcyB3aXRob3V0IGJlbmNobWFya2luZy4KCiAgaWYgKGVsZW1lbnRzKSB7CgogICAgLy8gaWYgYSBOb2RlICh0aGUgbW9zdCBjb21tb24gY2FzZSkKICAgIGlmIChlbGVtZW50cy5ub2RlVHlwZSkgewogICAgICByb290W3Jvb3QubGVuZ3RoKytdID0gZWxlbWVudHM7CiAgICB9IGVsc2UgewogICAgICB2YXIgbGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoOwoKICAgICAgLy8gaWYgYW4gQXJyYXkgb3IgTm9kZUxpc3QgYW5kIG5vdCBhIFdpbmRvdwogICAgICBpZiAodHlwZW9mIGxlbmd0aCA9PT0gJ251bWJlcicgJiYgZWxlbWVudHMud2luZG93ICE9PSBlbGVtZW50cykgewogICAgICAgIGlmIChsZW5ndGgpIHsKICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgcm9vdFtyb290Lmxlbmd0aCsrXSA9IGVsZW1lbnRzW2ldOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByb290W3Jvb3QubGVuZ3RoKytdID0gZWxlbWVudHM7CiAgICAgIH0KICAgIH0KICB9Cn0KCgpmdW5jdGlvbiBqcUxpdGVDb250cm9sbGVyKGVsZW1lbnQsIG5hbWUpIHsKICByZXR1cm4ganFMaXRlSW5oZXJpdGVkRGF0YShlbGVtZW50LCAnJCcgKyAobmFtZSB8fCAnbmdDb250cm9sbGVyJykgKyAnQ29udHJvbGxlcicpOwp9CgpmdW5jdGlvbiBqcUxpdGVJbmhlcml0ZWREYXRhKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7CiAgLy8gaWYgZWxlbWVudCBpcyB0aGUgZG9jdW1lbnQgb2JqZWN0IHdvcmsgd2l0aCB0aGUgaHRtbCBlbGVtZW50IGluc3RlYWQKICAvLyB0aGlzIG1ha2VzICQoZG9jdW1lbnQpLnNjb3BlKCkgcG9zc2libGUKICBpZiAoZWxlbWVudC5ub2RlVHlwZSA9PSBOT0RFX1RZUEVfRE9DVU1FTlQpIHsKICAgIGVsZW1lbnQgPSBlbGVtZW50LmRvY3VtZW50RWxlbWVudDsKICB9CiAgdmFyIG5hbWVzID0gaXNBcnJheShuYW1lKSA/IG5hbWUgOiBbbmFtZV07CgogIHdoaWxlIChlbGVtZW50KSB7CiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBuYW1lcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgIGlmICgodmFsdWUgPSBqcUxpdGUuZGF0YShlbGVtZW50LCBuYW1lc1tpXSkpICE9PSB1bmRlZmluZWQpIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvLyBJZiBkZWFsaW5nIHdpdGggYSBkb2N1bWVudCBmcmFnbWVudCBub2RlIHdpdGggYSBob3N0IGVsZW1lbnQsIGFuZCBubyBwYXJlbnQsIHVzZSB0aGUgaG9zdAogICAgLy8gZWxlbWVudCBhcyB0aGUgcGFyZW50LiBUaGlzIGVuYWJsZXMgZGlyZWN0aXZlcyB3aXRoaW4gYSBTaGFkb3cgRE9NIG9yIHBvbHlmaWxsZWQgU2hhZG93IERPTQogICAgLy8gdG8gbG9va3VwIHBhcmVudCBjb250cm9sbGVycy4KICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGUgfHwgKGVsZW1lbnQubm9kZVR5cGUgPT09IE5PREVfVFlQRV9ET0NVTUVOVF9GUkFHTUVOVCAmJiBlbGVtZW50Lmhvc3QpOwogIH0KfQoKZnVuY3Rpb24ganFMaXRlRW1wdHkoZWxlbWVudCkgewogIGpxTGl0ZURlYWxvYyhlbGVtZW50LCB0cnVlKTsKICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7CiAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQuZmlyc3RDaGlsZCk7CiAgfQp9CgpmdW5jdGlvbiBqcUxpdGVSZW1vdmUoZWxlbWVudCwga2VlcERhdGEpIHsKICBpZiAoIWtlZXBEYXRhKSBqcUxpdGVEZWFsb2MoZWxlbWVudCk7CiAgdmFyIHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTsKICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudCk7Cn0KCgpmdW5jdGlvbiBqcUxpdGVEb2N1bWVudExvYWRlZChhY3Rpb24sIHdpbikgewogIHdpbiA9IHdpbiB8fCB3aW5kb3c7CiAgaWYgKHdpbi5kb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7CiAgICAvLyBGb3JjZSB0aGUgYWN0aW9uIHRvIGJlIHJ1biBhc3luYyBmb3IgY29uc2lzdGVudCBiZWhhdmlvdXIKICAgIC8vIGZyb20gdGhlIGFjdGlvbidzIHBvaW50IG9mIHZpZXcKICAgIC8vIGkuZS4gaXQgd2lsbCBkZWZpbml0ZWx5IG5vdCBiZSBpbiBhICRhcHBseQogICAgd2luLnNldFRpbWVvdXQoYWN0aW9uKTsKICB9IGVsc2UgewogICAgLy8gTm8gbmVlZCB0byB1bmJpbmQgdGhpcyBoYW5kbGVyIGFzIGxvYWQgaXMgb25seSBldmVyIGNhbGxlZCBvbmNlCiAgICBqcUxpdGUod2luKS5vbignbG9hZCcsIGFjdGlvbik7CiAgfQp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLy8gRnVuY3Rpb25zIHdoaWNoIGFyZSBkZWNsYXJlZCBkaXJlY3RseS4KLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCnZhciBKUUxpdGVQcm90b3R5cGUgPSBKUUxpdGUucHJvdG90eXBlID0gewogIHJlYWR5OiBmdW5jdGlvbihmbikgewogICAgdmFyIGZpcmVkID0gZmFsc2U7CgogICAgZnVuY3Rpb24gdHJpZ2dlcigpIHsKICAgICAgaWYgKGZpcmVkKSByZXR1cm47CiAgICAgIGZpcmVkID0gdHJ1ZTsKICAgICAgZm4oKTsKICAgIH0KCiAgICAvLyBjaGVjayBpZiBkb2N1bWVudCBpcyBhbHJlYWR5IGxvYWRlZAogICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScpIHsKICAgICAgc2V0VGltZW91dCh0cmlnZ2VyKTsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMub24oJ0RPTUNvbnRlbnRMb2FkZWQnLCB0cmlnZ2VyKTsgLy8gd29ya3MgZm9yIG1vZGVybiBicm93c2VycyBhbmQgSUU5CiAgICAgIC8vIHdlIGNhbiBub3QgdXNlIGpxTGl0ZSBzaW5jZSB3ZSBhcmUgbm90IGRvbmUgbG9hZGluZyBhbmQgalF1ZXJ5IGNvdWxkIGJlIGxvYWRlZCBsYXRlci4KICAgICAgLy8ganNoaW50IC1XMDY0CiAgICAgIEpRTGl0ZSh3aW5kb3cpLm9uKCdsb2FkJywgdHJpZ2dlcik7IC8vIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQgZm9yIG90aGVycwogICAgICAvLyBqc2hpbnQgK1cwNjQKICAgIH0KICB9LAogIHRvU3RyaW5nOiBmdW5jdGlvbigpIHsKICAgIHZhciB2YWx1ZSA9IFtdOwogICAgZm9yRWFjaCh0aGlzLCBmdW5jdGlvbihlKSB7IHZhbHVlLnB1c2goJycgKyBlKTt9KTsKICAgIHJldHVybiAnWycgKyB2YWx1ZS5qb2luKCcsICcpICsgJ10nOwogIH0sCgogIGVxOiBmdW5jdGlvbihpbmRleCkgewogICAgICByZXR1cm4gKGluZGV4ID49IDApID8ganFMaXRlKHRoaXNbaW5kZXhdKSA6IGpxTGl0ZSh0aGlzW3RoaXMubGVuZ3RoICsgaW5kZXhdKTsKICB9LAoKICBsZW5ndGg6IDAsCiAgcHVzaDogcHVzaCwKICBzb3J0OiBbXS5zb3J0LAogIHNwbGljZTogW10uc3BsaWNlCn07CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLy8gRnVuY3Rpb25zIGl0ZXJhdGluZyBnZXR0ZXIvc2V0dGVycy4KLy8gdGhlc2UgZnVuY3Rpb25zIHJldHVybiBzZWxmIG9uIHNldHRlciBhbmQKLy8gdmFsdWUgb24gZ2V0LgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KdmFyIEJPT0xFQU5fQVRUUiA9IHt9Owpmb3JFYWNoKCdtdWx0aXBsZSxzZWxlY3RlZCxjaGVja2VkLGRpc2FibGVkLHJlYWRPbmx5LHJlcXVpcmVkLG9wZW4nLnNwbGl0KCcsJyksIGZ1bmN0aW9uKHZhbHVlKSB7CiAgQk9PTEVBTl9BVFRSW2xvd2VyY2FzZSh2YWx1ZSldID0gdmFsdWU7Cn0pOwp2YXIgQk9PTEVBTl9FTEVNRU5UUyA9IHt9Owpmb3JFYWNoKCdpbnB1dCxzZWxlY3Qsb3B0aW9uLHRleHRhcmVhLGJ1dHRvbixmb3JtLGRldGFpbHMnLnNwbGl0KCcsJyksIGZ1bmN0aW9uKHZhbHVlKSB7CiAgQk9PTEVBTl9FTEVNRU5UU1t2YWx1ZV0gPSB0cnVlOwp9KTsKdmFyIEFMSUFTRURfQVRUUiA9IHsKICAnbmdNaW5sZW5ndGgnOiAnbWlubGVuZ3RoJywKICAnbmdNYXhsZW5ndGgnOiAnbWF4bGVuZ3RoJywKICAnbmdNaW4nOiAnbWluJywKICAnbmdNYXgnOiAnbWF4JywKICAnbmdQYXR0ZXJuJzogJ3BhdHRlcm4nCn07CgpmdW5jdGlvbiBnZXRCb29sZWFuQXR0ck5hbWUoZWxlbWVudCwgbmFtZSkgewogIC8vIGNoZWNrIGRvbSBsYXN0IHNpbmNlIHdlIHdpbGwgbW9zdCBsaWtlbHkgZmFpbCBvbiBuYW1lCiAgdmFyIGJvb2xlYW5BdHRyID0gQk9PTEVBTl9BVFRSW25hbWUudG9Mb3dlckNhc2UoKV07CgogIC8vIGJvb2xlYW5BdHRyIGlzIGhlcmUgdHdpY2UgdG8gbWluaW1pemUgRE9NIGFjY2VzcwogIHJldHVybiBib29sZWFuQXR0ciAmJiBCT09MRUFOX0VMRU1FTlRTW25vZGVOYW1lXyhlbGVtZW50KV0gJiYgYm9vbGVhbkF0dHI7Cn0KCmZ1bmN0aW9uIGdldEFsaWFzZWRBdHRyTmFtZShlbGVtZW50LCBuYW1lKSB7CiAgdmFyIG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZTsKICByZXR1cm4gKG5vZGVOYW1lID09PSAnSU5QVVQnIHx8IG5vZGVOYW1lID09PSAnVEVYVEFSRUEnKSAmJiBBTElBU0VEX0FUVFJbbmFtZV07Cn0KCmZvckVhY2goewogIGRhdGE6IGpxTGl0ZURhdGEsCiAgcmVtb3ZlRGF0YToganFMaXRlUmVtb3ZlRGF0YQp9LCBmdW5jdGlvbihmbiwgbmFtZSkgewogIEpRTGl0ZVtuYW1lXSA9IGZuOwp9KTsKCmZvckVhY2goewogIGRhdGE6IGpxTGl0ZURhdGEsCiAgaW5oZXJpdGVkRGF0YToganFMaXRlSW5oZXJpdGVkRGF0YSwKCiAgc2NvcGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIC8vIENhbid0IHVzZSBqcUxpdGVEYXRhIGhlcmUgZGlyZWN0bHkgc28gd2Ugc3RheSBjb21wYXRpYmxlIHdpdGggalF1ZXJ5IQogICAgcmV0dXJuIGpxTGl0ZS5kYXRhKGVsZW1lbnQsICckc2NvcGUnKSB8fCBqcUxpdGVJbmhlcml0ZWREYXRhKGVsZW1lbnQucGFyZW50Tm9kZSB8fCBlbGVtZW50LCBbJyRpc29sYXRlU2NvcGUnLCAnJHNjb3BlJ10pOwogIH0sCgogIGlzb2xhdGVTY29wZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgLy8gQ2FuJ3QgdXNlIGpxTGl0ZURhdGEgaGVyZSBkaXJlY3RseSBzbyB3ZSBzdGF5IGNvbXBhdGlibGUgd2l0aCBqUXVlcnkhCiAgICByZXR1cm4ganFMaXRlLmRhdGEoZWxlbWVudCwgJyRpc29sYXRlU2NvcGUnKSB8fCBqcUxpdGUuZGF0YShlbGVtZW50LCAnJGlzb2xhdGVTY29wZU5vVGVtcGxhdGUnKTsKICB9LAoKICBjb250cm9sbGVyOiBqcUxpdGVDb250cm9sbGVyLAoKICBpbmplY3RvcjogZnVuY3Rpb24oZWxlbWVudCkgewogICAgcmV0dXJuIGpxTGl0ZUluaGVyaXRlZERhdGEoZWxlbWVudCwgJyRpbmplY3RvcicpOwogIH0sCgogIHJlbW92ZUF0dHI6IGZ1bmN0aW9uKGVsZW1lbnQsIG5hbWUpIHsKICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpOwogIH0sCgogIGhhc0NsYXNzOiBqcUxpdGVIYXNDbGFzcywKCiAgY3NzOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCB2YWx1ZSkgewogICAgbmFtZSA9IGNhbWVsQ2FzZShuYW1lKTsKCiAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSkgewogICAgICBlbGVtZW50LnN0eWxlW25hbWVdID0gdmFsdWU7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gZWxlbWVudC5zdHlsZVtuYW1lXTsKICAgIH0KICB9LAoKICBhdHRyOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCB2YWx1ZSkgewogICAgdmFyIGxvd2VyY2FzZWROYW1lID0gbG93ZXJjYXNlKG5hbWUpOwogICAgaWYgKEJPT0xFQU5fQVRUUltsb3dlcmNhc2VkTmFtZV0pIHsKICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgICBpZiAoISF2YWx1ZSkgewogICAgICAgICAgZWxlbWVudFtuYW1lXSA9IHRydWU7CiAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCBsb3dlcmNhc2VkTmFtZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVsZW1lbnRbbmFtZV0gPSBmYWxzZTsKICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGxvd2VyY2FzZWROYW1lKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChlbGVtZW50W25hbWVdIHx8CiAgICAgICAgICAgICAgICAgKGVsZW1lbnQuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0obmFtZSkgfHwgbm9vcCkuc3BlY2lmaWVkKQogICAgICAgICAgICAgICA/IGxvd2VyY2FzZWROYW1lCiAgICAgICAgICAgICAgIDogdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpOwogICAgfSBlbHNlIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZSkgewogICAgICAvLyB0aGUgZXh0cmEgYXJndW1lbnQgIjIiIGlzIHRvIGdldCB0aGUgcmlnaHQgdGhpbmcgZm9yIGEuaHJlZiBpbiBJRSwgc2VlIGpRdWVyeSBjb2RlCiAgICAgIC8vIHNvbWUgZWxlbWVudHMgKGUuZy4gRG9jdW1lbnQpIGRvbid0IGhhdmUgZ2V0IGF0dHJpYnV0ZSwgc28gcmV0dXJuIHVuZGVmaW5lZAogICAgICB2YXIgcmV0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUobmFtZSwgMik7CiAgICAgIC8vIG5vcm1hbGl6ZSBub24tZXhpc3RpbmcgYXR0cmlidXRlcyB0byB1bmRlZmluZWQgKGFzIGpRdWVyeSkKICAgICAgcmV0dXJuIHJldCA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDsKICAgIH0KICB9LAoKICBwcm9wOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCB2YWx1ZSkgewogICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgZWxlbWVudFtuYW1lXSA9IHZhbHVlOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGVsZW1lbnRbbmFtZV07CiAgICB9CiAgfSwKCiAgdGV4dDogKGZ1bmN0aW9uKCkgewogICAgZ2V0VGV4dC4kZHYgPSAnJzsKICAgIHJldHVybiBnZXRUZXh0OwoKICAgIGZ1bmN0aW9uIGdldFRleHQoZWxlbWVudCwgdmFsdWUpIHsKICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSkgewogICAgICAgIHZhciBub2RlVHlwZSA9IGVsZW1lbnQubm9kZVR5cGU7CiAgICAgICAgcmV0dXJuIChub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0VMRU1FTlQgfHwgbm9kZVR5cGUgPT09IE5PREVfVFlQRV9URVhUKSA/IGVsZW1lbnQudGV4dENvbnRlbnQgOiAnJzsKICAgICAgfQogICAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdmFsdWU7CiAgICB9CiAgfSkoKSwKCiAgdmFsOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSkgewogICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSkgewogICAgICBpZiAoZWxlbWVudC5tdWx0aXBsZSAmJiBub2RlTmFtZV8oZWxlbWVudCkgPT09ICdzZWxlY3QnKSB7CiAgICAgICAgdmFyIHJlc3VsdCA9IFtdOwogICAgICAgIGZvckVhY2goZWxlbWVudC5vcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHsKICAgICAgICAgIGlmIChvcHRpb24uc2VsZWN0ZWQpIHsKICAgICAgICAgICAgcmVzdWx0LnB1c2gob3B0aW9uLnZhbHVlIHx8IG9wdGlvbi50ZXh0KTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcmVzdWx0Lmxlbmd0aCA9PT0gMCA/IG51bGwgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgcmV0dXJuIGVsZW1lbnQudmFsdWU7CiAgICB9CiAgICBlbGVtZW50LnZhbHVlID0gdmFsdWU7CiAgfSwKCiAgaHRtbDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUpIHsKICAgIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuIGVsZW1lbnQuaW5uZXJIVE1MOwogICAgfQogICAganFMaXRlRGVhbG9jKGVsZW1lbnQsIHRydWUpOwogICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICB9LAoKICBlbXB0eToganFMaXRlRW1wdHkKfSwgZnVuY3Rpb24oZm4sIG5hbWUpIHsKICAvKioKICAgKiBQcm9wZXJ0aWVzOiB3cml0ZXMgcmV0dXJuIHNlbGVjdGlvbiwgcmVhZHMgcmV0dXJuIGZpcnN0IHZhbHVlCiAgICovCiAgSlFMaXRlLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKGFyZzEsIGFyZzIpIHsKICAgIHZhciBpLCBrZXk7CiAgICB2YXIgbm9kZUNvdW50ID0gdGhpcy5sZW5ndGg7CgogICAgLy8ganFMaXRlSGFzQ2xhc3MgaGFzIG9ubHkgdHdvIGFyZ3VtZW50cywgYnV0IGlzIGEgZ2V0dGVyLW9ubHkgZm4sIHNvIHdlIG5lZWQgdG8gc3BlY2lhbC1jYXNlIGl0CiAgICAvLyBpbiBhIHdheSB0aGF0IHN1cnZpdmVzIG1pbmlmaWNhdGlvbi4KICAgIC8vIGpxTGl0ZUVtcHR5IHRha2VzIG5vIGFyZ3VtZW50cyBidXQgaXMgYSBzZXR0ZXIuCiAgICBpZiAoZm4gIT09IGpxTGl0ZUVtcHR5ICYmCiAgICAgICAgKCgoZm4ubGVuZ3RoID09IDIgJiYgKGZuICE9PSBqcUxpdGVIYXNDbGFzcyAmJiBmbiAhPT0ganFMaXRlQ29udHJvbGxlcikpID8gYXJnMSA6IGFyZzIpID09PSB1bmRlZmluZWQpKSB7CiAgICAgIGlmIChpc09iamVjdChhcmcxKSkgewoKICAgICAgICAvLyB3ZSBhcmUgYSB3cml0ZSwgYnV0IHRoZSBvYmplY3QgcHJvcGVydGllcyBhcmUgdGhlIGtleS92YWx1ZXMKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbm9kZUNvdW50OyBpKyspIHsKICAgICAgICAgIGlmIChmbiA9PT0ganFMaXRlRGF0YSkgewogICAgICAgICAgICAvLyBkYXRhKCkgdGFrZXMgdGhlIHdob2xlIG9iamVjdCBpbiBqUXVlcnkKICAgICAgICAgICAgZm4odGhpc1tpXSwgYXJnMSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKGtleSBpbiBhcmcxKSB7CiAgICAgICAgICAgICAgZm4odGhpc1tpXSwga2V5LCBhcmcxW2tleV0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIHJldHVybiBzZWxmIGZvciBjaGFpbmluZwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIHdlIGFyZSBhIHJlYWQsIHNvIHJlYWQgdGhlIGZpcnN0IGNoaWxkLgogICAgICAgIC8vIFRPRE86IGRvIHdlIHN0aWxsIG5lZWQgdGhpcz8KICAgICAgICB2YXIgdmFsdWUgPSBmbi4kZHY7CiAgICAgICAgLy8gT25seSBpZiB3ZSBoYXZlICRkdiBkbyB3ZSBpdGVyYXRlIG92ZXIgYWxsLCBvdGhlcndpc2UgaXQgaXMganVzdCB0aGUgZmlyc3QgZWxlbWVudC4KICAgICAgICB2YXIgamogPSAodmFsdWUgPT09IHVuZGVmaW5lZCkgPyBNYXRoLm1pbihub2RlQ291bnQsIDEpIDogbm9kZUNvdW50OwogICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgamo7IGorKykgewogICAgICAgICAgdmFyIG5vZGVWYWx1ZSA9IGZuKHRoaXNbal0sIGFyZzEsIGFyZzIpOwogICAgICAgICAgdmFsdWUgPSB2YWx1ZSA/IHZhbHVlICsgbm9kZVZhbHVlIDogbm9kZVZhbHVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8vIHdlIGFyZSBhIHdyaXRlLCBzbyBhcHBseSB0byBhbGwgY2hpbGRyZW4KICAgICAgZm9yIChpID0gMDsgaSA8IG5vZGVDb3VudDsgaSsrKSB7CiAgICAgICAgZm4odGhpc1tpXSwgYXJnMSwgYXJnMik7CiAgICAgIH0KICAgICAgLy8gcmV0dXJuIHNlbGYgZm9yIGNoYWluaW5nCiAgICAgIHJldHVybiB0aGlzOwogICAgfQogIH07Cn0pOwoKZnVuY3Rpb24gY3JlYXRlRXZlbnRIYW5kbGVyKGVsZW1lbnQsIGV2ZW50cykgewogIHZhciBldmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudCwgdHlwZSkgewogICAgLy8galF1ZXJ5IHNwZWNpZmljIGFwaQogICAgZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkID0gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBldmVudC5kZWZhdWx0UHJldmVudGVkOwogICAgfTsKCiAgICB2YXIgZXZlbnRGbnMgPSBldmVudHNbdHlwZSB8fCBldmVudC50eXBlXTsKICAgIHZhciBldmVudEZuc0xlbmd0aCA9IGV2ZW50Rm5zID8gZXZlbnRGbnMubGVuZ3RoIDogMDsKCiAgICBpZiAoIWV2ZW50Rm5zTGVuZ3RoKSByZXR1cm47CgogICAgaWYgKGlzVW5kZWZpbmVkKGV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCkpIHsKICAgICAgdmFyIG9yaWdpbmFsU3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOwogICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPSBmdW5jdGlvbigpIHsKICAgICAgICBldmVudC5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlOwoKICAgICAgICBpZiAoZXZlbnQuc3RvcFByb3BhZ2F0aW9uKSB7CiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICB9CgogICAgICAgIGlmIChvcmlnaW5hbFN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbikgewogICAgICAgICAgb3JpZ2luYWxTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24uY2FsbChldmVudCk7CiAgICAgICAgfQogICAgICB9OwogICAgfQoKICAgIGV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkID0gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBldmVudC5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPT09IHRydWU7CiAgICB9OwoKICAgIC8vIENvcHkgZXZlbnQgaGFuZGxlcnMgaW4gY2FzZSBldmVudCBoYW5kbGVycyBhcnJheSBpcyBtb2RpZmllZCBkdXJpbmcgZXhlY3V0aW9uLgogICAgaWYgKChldmVudEZuc0xlbmd0aCA+IDEpKSB7CiAgICAgIGV2ZW50Rm5zID0gc2hhbGxvd0NvcHkoZXZlbnRGbnMpOwogICAgfQoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZlbnRGbnNMZW5ndGg7IGkrKykgewogICAgICBpZiAoIWV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkpIHsKICAgICAgICBldmVudEZuc1tpXS5jYWxsKGVsZW1lbnQsIGV2ZW50KTsKICAgICAgfQogICAgfQogIH07CgogIC8vIFRPRE86IHRoaXMgaXMgYSBoYWNrIGZvciBhbmd1bGFyTW9ja3MvY2xlYXJEYXRhQ2FjaGUgdGhhdCBtYWtlcyBpdCBwb3NzaWJsZSB0byBkZXJlZ2lzdGVyIGFsbAogIC8vICAgICAgIGV2ZW50cyBvbiBgZWxlbWVudGAKICBldmVudEhhbmRsZXIuZWxlbSA9IGVsZW1lbnQ7CiAgcmV0dXJuIGV2ZW50SGFuZGxlcjsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIEZ1bmN0aW9ucyBpdGVyYXRpbmcgdHJhdmVyc2FsLgovLyBUaGVzZSBmdW5jdGlvbnMgY2hhaW4gcmVzdWx0cyBpbnRvIGEgc2luZ2xlCi8vIHNlbGVjdG9yLgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KZm9yRWFjaCh7CiAgcmVtb3ZlRGF0YToganFMaXRlUmVtb3ZlRGF0YSwKCiAgb246IGZ1bmN0aW9uIGpxTGl0ZU9uKGVsZW1lbnQsIHR5cGUsIGZuLCB1bnN1cHBvcnRlZCkgewogICAgaWYgKGlzRGVmaW5lZCh1bnN1cHBvcnRlZCkpIHRocm93IGpxTGl0ZU1pbkVycignb25hcmdzJywgJ2pxTGl0ZSNvbigpIGRvZXMgbm90IHN1cHBvcnQgdGhlIGBzZWxlY3RvcmAgb3IgYGV2ZW50RGF0YWAgcGFyYW1ldGVycycpOwoKICAgIC8vIERvIG5vdCBhZGQgZXZlbnQgaGFuZGxlcnMgdG8gbm9uLWVsZW1lbnRzIGJlY2F1c2UgdGhleSB3aWxsIG5vdCBiZSBjbGVhbmVkIHVwLgogICAgaWYgKCFqcUxpdGVBY2NlcHRzRGF0YShlbGVtZW50KSkgewogICAgICByZXR1cm47CiAgICB9CgogICAgdmFyIGV4cGFuZG9TdG9yZSA9IGpxTGl0ZUV4cGFuZG9TdG9yZShlbGVtZW50LCB0cnVlKTsKICAgIHZhciBldmVudHMgPSBleHBhbmRvU3RvcmUuZXZlbnRzOwogICAgdmFyIGhhbmRsZSA9IGV4cGFuZG9TdG9yZS5oYW5kbGU7CgogICAgaWYgKCFoYW5kbGUpIHsKICAgICAgaGFuZGxlID0gZXhwYW5kb1N0b3JlLmhhbmRsZSA9IGNyZWF0ZUV2ZW50SGFuZGxlcihlbGVtZW50LCBldmVudHMpOwogICAgfQoKICAgIC8vIGh0dHA6Ly9qc3BlcmYuY29tL3N0cmluZy1pbmRleG9mLXZzLXNwbGl0CiAgICB2YXIgdHlwZXMgPSB0eXBlLmluZGV4T2YoJyAnKSA+PSAwID8gdHlwZS5zcGxpdCgnICcpIDogW3R5cGVdOwogICAgdmFyIGkgPSB0eXBlcy5sZW5ndGg7CgogICAgd2hpbGUgKGktLSkgewogICAgICB0eXBlID0gdHlwZXNbaV07CiAgICAgIHZhciBldmVudEZucyA9IGV2ZW50c1t0eXBlXTsKCiAgICAgIGlmICghZXZlbnRGbnMpIHsKICAgICAgICBldmVudHNbdHlwZV0gPSBbXTsKCiAgICAgICAgaWYgKHR5cGUgPT09ICdtb3VzZWVudGVyJyB8fCB0eXBlID09PSAnbW91c2VsZWF2ZScpIHsKICAgICAgICAgIC8vIFJlZmVyIHRvIGpRdWVyeSdzIGltcGxlbWVudGF0aW9uIG9mIG1vdXNlZW50ZXIgJiBtb3VzZWxlYXZlCiAgICAgICAgICAvLyBSZWFkIGFib3V0IG1vdXNlZW50ZXIgYW5kIG1vdXNlbGVhdmU6CiAgICAgICAgICAvLyBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2pzL2V2ZW50c19tb3VzZS5odG1sI2xpbms4CgogICAgICAgICAganFMaXRlT24oZWxlbWVudCwgTU9VU0VfRVZFTlRfTUFQW3R5cGVdLCBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhpcywgcmVsYXRlZCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7CiAgICAgICAgICAgIC8vIEZvciBtb3VzZW50ZXIvbGVhdmUgY2FsbCB0aGUgaGFuZGxlciBpZiByZWxhdGVkIGlzIG91dHNpZGUgdGhlIHRhcmdldC4KICAgICAgICAgICAgLy8gTkI6IE5vIHJlbGF0ZWRUYXJnZXQgaWYgdGhlIG1vdXNlIGxlZnQvZW50ZXJlZCB0aGUgYnJvd3NlciB3aW5kb3cKICAgICAgICAgICAgaWYgKCFyZWxhdGVkIHx8IChyZWxhdGVkICE9PSB0YXJnZXQgJiYgIXRhcmdldC5jb250YWlucyhyZWxhdGVkKSkpIHsKICAgICAgICAgICAgICBoYW5kbGUoZXZlbnQsIHR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0eXBlICE9PSAnJGRlc3Ryb3knKSB7CiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXJGbihlbGVtZW50LCB0eXBlLCBoYW5kbGUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBldmVudEZucyA9IGV2ZW50c1t0eXBlXTsKICAgICAgfQogICAgICBldmVudEZucy5wdXNoKGZuKTsKICAgIH0KICB9LAoKICBvZmY6IGpxTGl0ZU9mZiwKCiAgb25lOiBmdW5jdGlvbihlbGVtZW50LCB0eXBlLCBmbikgewogICAgZWxlbWVudCA9IGpxTGl0ZShlbGVtZW50KTsKCiAgICAvL2FkZCB0aGUgbGlzdGVuZXIgdHdpY2Ugc28gdGhhdCB3aGVuIGl0IGlzIGNhbGxlZAogICAgLy95b3UgY2FuIHJlbW92ZSB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gYW5kIHN0aWxsIGJlCiAgICAvL2FibGUgdG8gY2FsbCBlbGVtZW50Lm9mZihldiwgZm4pIG5vcm1hbGx5CiAgICBlbGVtZW50Lm9uKHR5cGUsIGZ1bmN0aW9uIG9uRm4oKSB7CiAgICAgIGVsZW1lbnQub2ZmKHR5cGUsIGZuKTsKICAgICAgZWxlbWVudC5vZmYodHlwZSwgb25Gbik7CiAgICB9KTsKICAgIGVsZW1lbnQub24odHlwZSwgZm4pOwogIH0sCgogIHJlcGxhY2VXaXRoOiBmdW5jdGlvbihlbGVtZW50LCByZXBsYWNlTm9kZSkgewogICAgdmFyIGluZGV4LCBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7CiAgICBqcUxpdGVEZWFsb2MoZWxlbWVudCk7CiAgICBmb3JFYWNoKG5ldyBKUUxpdGUocmVwbGFjZU5vZGUpLCBmdW5jdGlvbihub2RlKSB7CiAgICAgIGlmIChpbmRleCkgewogICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUobm9kZSwgaW5kZXgubmV4dFNpYmxpbmcpOwogICAgICB9IGVsc2UgewogICAgICAgIHBhcmVudC5yZXBsYWNlQ2hpbGQobm9kZSwgZWxlbWVudCk7CiAgICAgIH0KICAgICAgaW5kZXggPSBub2RlOwogICAgfSk7CiAgfSwKCiAgY2hpbGRyZW46IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHZhciBjaGlsZHJlbiA9IFtdOwogICAgZm9yRWFjaChlbGVtZW50LmNoaWxkTm9kZXMsIGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT09IE5PREVfVFlQRV9FTEVNRU5UKQogICAgICAgIGNoaWxkcmVuLnB1c2goZWxlbWVudCk7CiAgICB9KTsKICAgIHJldHVybiBjaGlsZHJlbjsKICB9LAoKICBjb250ZW50czogZnVuY3Rpb24oZWxlbWVudCkgewogICAgcmV0dXJuIGVsZW1lbnQuY29udGVudERvY3VtZW50IHx8IGVsZW1lbnQuY2hpbGROb2RlcyB8fCBbXTsKICB9LAoKICBhcHBlbmQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHsKICAgIHZhciBub2RlVHlwZSA9IGVsZW1lbnQubm9kZVR5cGU7CiAgICBpZiAobm9kZVR5cGUgIT09IE5PREVfVFlQRV9FTEVNRU5UICYmIG5vZGVUeXBlICE9PSBOT0RFX1RZUEVfRE9DVU1FTlRfRlJBR01FTlQpIHJldHVybjsKCiAgICBub2RlID0gbmV3IEpRTGl0ZShub2RlKTsKCiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBub2RlLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgdmFyIGNoaWxkID0gbm9kZVtpXTsKICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZCk7CiAgICB9CiAgfSwKCiAgcHJlcGVuZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkgewogICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT09IE5PREVfVFlQRV9FTEVNRU5UKSB7CiAgICAgIHZhciBpbmRleCA9IGVsZW1lbnQuZmlyc3RDaGlsZDsKICAgICAgZm9yRWFjaChuZXcgSlFMaXRlKG5vZGUpLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgIGVsZW1lbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBpbmRleCk7CiAgICAgIH0pOwogICAgfQogIH0sCgogIHdyYXA6IGZ1bmN0aW9uKGVsZW1lbnQsIHdyYXBOb2RlKSB7CiAgICB3cmFwTm9kZSA9IGpxTGl0ZSh3cmFwTm9kZSkuZXEoMCkuY2xvbmUoKVswXTsKICAgIHZhciBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7CiAgICBpZiAocGFyZW50KSB7CiAgICAgIHBhcmVudC5yZXBsYWNlQ2hpbGQod3JhcE5vZGUsIGVsZW1lbnQpOwogICAgfQogICAgd3JhcE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgfSwKCiAgcmVtb3ZlOiBqcUxpdGVSZW1vdmUsCgogIGRldGFjaDogZnVuY3Rpb24oZWxlbWVudCkgewogICAganFMaXRlUmVtb3ZlKGVsZW1lbnQsIHRydWUpOwogIH0sCgogIGFmdGVyOiBmdW5jdGlvbihlbGVtZW50LCBuZXdFbGVtZW50KSB7CiAgICB2YXIgaW5kZXggPSBlbGVtZW50LCBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7CiAgICBuZXdFbGVtZW50ID0gbmV3IEpRTGl0ZShuZXdFbGVtZW50KTsKCiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBuZXdFbGVtZW50Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgdmFyIG5vZGUgPSBuZXdFbGVtZW50W2ldOwogICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5vZGUsIGluZGV4Lm5leHRTaWJsaW5nKTsKICAgICAgaW5kZXggPSBub2RlOwogICAgfQogIH0sCgogIGFkZENsYXNzOiBqcUxpdGVBZGRDbGFzcywKICByZW1vdmVDbGFzczoganFMaXRlUmVtb3ZlQ2xhc3MsCgogIHRvZ2dsZUNsYXNzOiBmdW5jdGlvbihlbGVtZW50LCBzZWxlY3RvciwgY29uZGl0aW9uKSB7CiAgICBpZiAoc2VsZWN0b3IpIHsKICAgICAgZm9yRWFjaChzZWxlY3Rvci5zcGxpdCgnICcpLCBmdW5jdGlvbihjbGFzc05hbWUpIHsKICAgICAgICB2YXIgY2xhc3NDb25kaXRpb24gPSBjb25kaXRpb247CiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGNsYXNzQ29uZGl0aW9uKSkgewogICAgICAgICAgY2xhc3NDb25kaXRpb24gPSAhanFMaXRlSGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKTsKICAgICAgICB9CiAgICAgICAgKGNsYXNzQ29uZGl0aW9uID8ganFMaXRlQWRkQ2xhc3MgOiBqcUxpdGVSZW1vdmVDbGFzcykoZWxlbWVudCwgY2xhc3NOYW1lKTsKICAgICAgfSk7CiAgICB9CiAgfSwKCiAgcGFyZW50OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlOwogICAgcmV0dXJuIHBhcmVudCAmJiBwYXJlbnQubm9kZVR5cGUgIT09IE5PREVfVFlQRV9ET0NVTUVOVF9GUkFHTUVOVCA/IHBhcmVudCA6IG51bGw7CiAgfSwKCiAgbmV4dDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgcmV0dXJuIGVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nOwogIH0sCgogIGZpbmQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHNlbGVjdG9yKSB7CiAgICBpZiAoZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSkgewogICAgICByZXR1cm4gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShzZWxlY3Rvcik7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gW107CiAgICB9CiAgfSwKCiAgY2xvbmU6IGpxTGl0ZUNsb25lLAoKICB0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oZWxlbWVudCwgZXZlbnQsIGV4dHJhUGFyYW1ldGVycykgewoKICAgIHZhciBkdW1teUV2ZW50LCBldmVudEZuc0NvcHksIGhhbmRsZXJBcmdzOwogICAgdmFyIGV2ZW50TmFtZSA9IGV2ZW50LnR5cGUgfHwgZXZlbnQ7CiAgICB2YXIgZXhwYW5kb1N0b3JlID0ganFMaXRlRXhwYW5kb1N0b3JlKGVsZW1lbnQpOwogICAgdmFyIGV2ZW50cyA9IGV4cGFuZG9TdG9yZSAmJiBleHBhbmRvU3RvcmUuZXZlbnRzOwogICAgdmFyIGV2ZW50Rm5zID0gZXZlbnRzICYmIGV2ZW50c1tldmVudE5hbWVdOwoKICAgIGlmIChldmVudEZucykgewogICAgICAvLyBDcmVhdGUgYSBkdW1teSBldmVudCB0byBwYXNzIHRvIHRoZSBoYW5kbGVycwogICAgICBkdW1teUV2ZW50ID0gewogICAgICAgIHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHsgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTsgfSwKICAgICAgICBpc0RlZmF1bHRQcmV2ZW50ZWQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5kZWZhdWx0UHJldmVudGVkID09PSB0cnVlOyB9LAogICAgICAgIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7IHRoaXMuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTsgfSwKICAgICAgICBpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9PT0gdHJ1ZTsgfSwKICAgICAgICBzdG9wUHJvcGFnYXRpb246IG5vb3AsCiAgICAgICAgdHlwZTogZXZlbnROYW1lLAogICAgICAgIHRhcmdldDogZWxlbWVudAogICAgICB9OwoKICAgICAgLy8gSWYgYSBjdXN0b20gZXZlbnQgd2FzIHByb3ZpZGVkIHRoZW4gZXh0ZW5kIG91ciBkdW1teSBldmVudCB3aXRoIGl0CiAgICAgIGlmIChldmVudC50eXBlKSB7CiAgICAgICAgZHVtbXlFdmVudCA9IGV4dGVuZChkdW1teUV2ZW50LCBldmVudCk7CiAgICAgIH0KCiAgICAgIC8vIENvcHkgZXZlbnQgaGFuZGxlcnMgaW4gY2FzZSBldmVudCBoYW5kbGVycyBhcnJheSBpcyBtb2RpZmllZCBkdXJpbmcgZXhlY3V0aW9uLgogICAgICBldmVudEZuc0NvcHkgPSBzaGFsbG93Q29weShldmVudEZucyk7CiAgICAgIGhhbmRsZXJBcmdzID0gZXh0cmFQYXJhbWV0ZXJzID8gW2R1bW15RXZlbnRdLmNvbmNhdChleHRyYVBhcmFtZXRlcnMpIDogW2R1bW15RXZlbnRdOwoKICAgICAgZm9yRWFjaChldmVudEZuc0NvcHksIGZ1bmN0aW9uKGZuKSB7CiAgICAgICAgaWYgKCFkdW1teUV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkpIHsKICAgICAgICAgIGZuLmFwcGx5KGVsZW1lbnQsIGhhbmRsZXJBcmdzKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogIH0KfSwgZnVuY3Rpb24oZm4sIG5hbWUpIHsKICAvKioKICAgKiBjaGFpbmluZyBmdW5jdGlvbnMKICAgKi8KICBKUUxpdGUucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oYXJnMSwgYXJnMiwgYXJnMykgewogICAgdmFyIHZhbHVlOwoKICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKSB7CiAgICAgICAgdmFsdWUgPSBmbih0aGlzW2ldLCBhcmcxLCBhcmcyLCBhcmczKTsKICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSkgewogICAgICAgICAgLy8gYW55IGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSB2YWx1ZSBuZWVkcyB0byBiZSB3cmFwcGVkCiAgICAgICAgICB2YWx1ZSA9IGpxTGl0ZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGpxTGl0ZUFkZE5vZGVzKHZhbHVlLCBmbih0aGlzW2ldLCBhcmcxLCBhcmcyLCBhcmczKSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpc0RlZmluZWQodmFsdWUpID8gdmFsdWUgOiB0aGlzOwogIH07CgogIC8vIGJpbmQgbGVnYWN5IGJpbmQvdW5iaW5kIHRvIG9uL29mZgogIEpRTGl0ZS5wcm90b3R5cGUuYmluZCA9IEpRTGl0ZS5wcm90b3R5cGUub247CiAgSlFMaXRlLnByb3RvdHlwZS51bmJpbmQgPSBKUUxpdGUucHJvdG90eXBlLm9mZjsKfSk7CgoKLy8gUHJvdmlkZXIgZm9yIHByaXZhdGUgJCRqcUxpdGUgc2VydmljZQpmdW5jdGlvbiAkJGpxTGl0ZVByb3ZpZGVyKCkgewogIHRoaXMuJGdldCA9IGZ1bmN0aW9uICQkanFMaXRlKCkgewogICAgcmV0dXJuIGV4dGVuZChKUUxpdGUsIHsKICAgICAgaGFzQ2xhc3M6IGZ1bmN0aW9uKG5vZGUsIGNsYXNzZXMpIHsKICAgICAgICBpZiAobm9kZS5hdHRyKSBub2RlID0gbm9kZVswXTsKICAgICAgICByZXR1cm4ganFMaXRlSGFzQ2xhc3Mobm9kZSwgY2xhc3Nlcyk7CiAgICAgIH0sCiAgICAgIGFkZENsYXNzOiBmdW5jdGlvbihub2RlLCBjbGFzc2VzKSB7CiAgICAgICAgaWYgKG5vZGUuYXR0cikgbm9kZSA9IG5vZGVbMF07CiAgICAgICAgcmV0dXJuIGpxTGl0ZUFkZENsYXNzKG5vZGUsIGNsYXNzZXMpOwogICAgICB9LAogICAgICByZW1vdmVDbGFzczogZnVuY3Rpb24obm9kZSwgY2xhc3NlcykgewogICAgICAgIGlmIChub2RlLmF0dHIpIG5vZGUgPSBub2RlWzBdOwogICAgICAgIHJldHVybiBqcUxpdGVSZW1vdmVDbGFzcyhub2RlLCBjbGFzc2VzKTsKICAgICAgfQogICAgfSk7CiAgfTsKfQoKLyoqCiAqIENvbXB1dGVzIGEgaGFzaCBvZiBhbiAnb2JqJy4KICogSGFzaCBvZiBhOgogKiAgc3RyaW5nIGlzIHN0cmluZwogKiAgbnVtYmVyIGlzIG51bWJlciBhcyBzdHJpbmcKICogIG9iamVjdCBpcyBlaXRoZXIgcmVzdWx0IG9mIGNhbGxpbmcgJCRoYXNoS2V5IGZ1bmN0aW9uIG9uIHRoZSBvYmplY3Qgb3IgdW5pcXVlbHkgZ2VuZXJhdGVkIGlkLAogKiAgICAgICAgIHRoYXQgaXMgYWxzbyBhc3NpZ25lZCB0byB0aGUgJCRoYXNoS2V5IHByb3BlcnR5IG9mIHRoZSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmoKICogQHJldHVybnMge3N0cmluZ30gaGFzaCBzdHJpbmcgc3VjaCB0aGF0IHRoZSBzYW1lIGlucHV0IHdpbGwgaGF2ZSB0aGUgc2FtZSBoYXNoIHN0cmluZy4KICogICAgICAgICBUaGUgcmVzdWx0aW5nIHN0cmluZyBrZXkgaXMgaW4gJ3R5cGU6aGFzaEtleScgZm9ybWF0LgogKi8KZnVuY3Rpb24gaGFzaEtleShvYmosIG5leHRVaWRGbikgewogIHZhciBrZXkgPSBvYmogJiYgb2JqLiQkaGFzaEtleTsKCiAgaWYgKGtleSkgewogICAgaWYgKHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpIHsKICAgICAga2V5ID0gb2JqLiQkaGFzaEtleSgpOwogICAgfQogICAgcmV0dXJuIGtleTsKICB9CgogIHZhciBvYmpUeXBlID0gdHlwZW9mIG9iajsKICBpZiAob2JqVHlwZSA9PSAnZnVuY3Rpb24nIHx8IChvYmpUeXBlID09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkpIHsKICAgIGtleSA9IG9iai4kJGhhc2hLZXkgPSBvYmpUeXBlICsgJzonICsgKG5leHRVaWRGbiB8fCBuZXh0VWlkKSgpOwogIH0gZWxzZSB7CiAgICBrZXkgPSBvYmpUeXBlICsgJzonICsgb2JqOwogIH0KCiAgcmV0dXJuIGtleTsKfQoKLyoqCiAqIEhhc2hNYXAgd2hpY2ggY2FuIHVzZSBvYmplY3RzIGFzIGtleXMKICovCmZ1bmN0aW9uIEhhc2hNYXAoYXJyYXksIGlzb2xhdGVkVWlkKSB7CiAgaWYgKGlzb2xhdGVkVWlkKSB7CiAgICB2YXIgdWlkID0gMDsKICAgIHRoaXMubmV4dFVpZCA9IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gKyt1aWQ7CiAgICB9OwogIH0KICBmb3JFYWNoKGFycmF5LCB0aGlzLnB1dCwgdGhpcyk7Cn0KSGFzaE1hcC5wcm90b3R5cGUgPSB7CiAgLyoqCiAgICogU3RvcmUga2V5IHZhbHVlIHBhaXIKICAgKiBAcGFyYW0ga2V5IGtleSB0byBzdG9yZSBjYW4gYmUgYW55IHR5cGUKICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gc3RvcmUgY2FuIGJlIGFueSB0eXBlCiAgICovCiAgcHV0OiBmdW5jdGlvbihrZXksIHZhbHVlKSB7CiAgICB0aGlzW2hhc2hLZXkoa2V5LCB0aGlzLm5leHRVaWQpXSA9IHZhbHVlOwogIH0sCgogIC8qKgogICAqIEBwYXJhbSBrZXkKICAgKiBAcmV0dXJucyB7T2JqZWN0fSB0aGUgdmFsdWUgZm9yIHRoZSBrZXkKICAgKi8KICBnZXQ6IGZ1bmN0aW9uKGtleSkgewogICAgcmV0dXJuIHRoaXNbaGFzaEtleShrZXksIHRoaXMubmV4dFVpZCldOwogIH0sCgogIC8qKgogICAqIFJlbW92ZSB0aGUga2V5L3ZhbHVlIHBhaXIKICAgKiBAcGFyYW0ga2V5CiAgICovCiAgcmVtb3ZlOiBmdW5jdGlvbihrZXkpIHsKICAgIHZhciB2YWx1ZSA9IHRoaXNba2V5ID0gaGFzaEtleShrZXksIHRoaXMubmV4dFVpZCldOwogICAgZGVsZXRlIHRoaXNba2V5XTsKICAgIHJldHVybiB2YWx1ZTsKICB9Cn07CgovKioKICogQG5nZG9jIGZ1bmN0aW9uCiAqIEBtb2R1bGUgbmcKICogQG5hbWUgYW5ndWxhci5pbmplY3RvcgogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogQ3JlYXRlcyBhbiBpbmplY3RvciBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBmb3IgcmV0cmlldmluZyBzZXJ2aWNlcyBhcyB3ZWxsIGFzIGZvcgogKiBkZXBlbmRlbmN5IGluamVjdGlvbiAoc2VlIHtAbGluayBndWlkZS9kaSBkZXBlbmRlbmN5IGluamVjdGlvbn0pLgogKgogKiBAcGFyYW0ge0FycmF5LjxzdHJpbmd8RnVuY3Rpb24+fSBtb2R1bGVzIEEgbGlzdCBvZiBtb2R1bGUgZnVuY3Rpb25zIG9yIHRoZWlyIGFsaWFzZXMuIFNlZQogKiAgICAge0BsaW5rIGFuZ3VsYXIubW9kdWxlfS4gVGhlIGBuZ2AgbW9kdWxlIG11c3QgYmUgZXhwbGljaXRseSBhZGRlZC4KICogQHBhcmFtIHtib29sZWFuPX0gW3N0cmljdERpPWZhbHNlXSBXaGV0aGVyIHRoZSBpbmplY3RvciBzaG91bGQgYmUgaW4gc3RyaWN0IG1vZGUsIHdoaWNoCiAqICAgICBkaXNhbGxvd3MgYXJndW1lbnQgbmFtZSBhbm5vdGF0aW9uIGluZmVyZW5jZS4KICogQHJldHVybnMge2luamVjdG9yfSBJbmplY3RvciBvYmplY3QuIFNlZSB7QGxpbmsgYXV0by4kaW5qZWN0b3IgJGluamVjdG9yfS4KICoKICogQGV4YW1wbGUKICogVHlwaWNhbCB1c2FnZQogKiBgYGBqcwogKiAgIC8vIGNyZWF0ZSBhbiBpbmplY3RvcgogKiAgIHZhciAkaW5qZWN0b3IgPSBhbmd1bGFyLmluamVjdG9yKFsnbmcnXSk7CiAqCiAqICAgLy8gdXNlIHRoZSBpbmplY3RvciB0byBraWNrIG9mZiB5b3VyIGFwcGxpY2F0aW9uCiAqICAgLy8gdXNlIHRoZSB0eXBlIGluZmVyZW5jZSB0byBhdXRvIGluamVjdCBhcmd1bWVudHMsIG9yIHVzZSBpbXBsaWNpdCBpbmplY3Rpb24KICogICAkaW5qZWN0b3IuaW52b2tlKGZ1bmN0aW9uKCRyb290U2NvcGUsICRjb21waWxlLCAkZG9jdW1lbnQpIHsKICogICAgICRjb21waWxlKCRkb2N1bWVudCkoJHJvb3RTY29wZSk7CiAqICAgICAkcm9vdFNjb3BlLiRkaWdlc3QoKTsKICogICB9KTsKICogYGBgCiAqCiAqIFNvbWV0aW1lcyB5b3Ugd2FudCB0byBnZXQgYWNjZXNzIHRvIHRoZSBpbmplY3RvciBvZiBhIGN1cnJlbnRseSBydW5uaW5nIEFuZ3VsYXIgYXBwCiAqIGZyb20gb3V0c2lkZSBBbmd1bGFyLiBQZXJoYXBzLCB5b3Ugd2FudCB0byBpbmplY3QgYW5kIGNvbXBpbGUgc29tZSBtYXJrdXAgYWZ0ZXIgdGhlCiAqIGFwcGxpY2F0aW9uIGhhcyBiZWVuIGJvb3RzdHJhcHBlZC4gWW91IGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBleHRyYSBgaW5qZWN0b3IoKWAgYWRkZWQKICogdG8gSlF1ZXJ5L2pxTGl0ZSBlbGVtZW50cy4gU2VlIHtAbGluayBhbmd1bGFyLmVsZW1lbnR9LgogKgogKiAqVGhpcyBpcyBmYWlybHkgcmFyZSBidXQgY291bGQgYmUgdGhlIGNhc2UgaWYgYSB0aGlyZCBwYXJ0eSBsaWJyYXJ5IGlzIGluamVjdGluZyB0aGUKICogbWFya3VwLioKICoKICogSW4gdGhlIGZvbGxvd2luZyBleGFtcGxlIGEgbmV3IGJsb2NrIG9mIEhUTUwgY29udGFpbmluZyBhIGBuZy1jb250cm9sbGVyYAogKiBkaXJlY3RpdmUgaXMgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQgYm9keSBieSBKUXVlcnkuIFdlIHRoZW4gY29tcGlsZSBhbmQgbGluawogKiBpdCBpbnRvIHRoZSBjdXJyZW50IEFuZ3VsYXJKUyBzY29wZS4KICoKICogYGBganMKICogdmFyICRkaXYgPSAkKCc8ZGl2IG5nLWNvbnRyb2xsZXI9Ik15Q3RybCI+e3tjb250ZW50LmxhYmVsfX08L2Rpdj4nKTsKICogJChkb2N1bWVudC5ib2R5KS5hcHBlbmQoJGRpdik7CiAqCiAqIGFuZ3VsYXIuZWxlbWVudChkb2N1bWVudCkuaW5qZWN0b3IoKS5pbnZva2UoZnVuY3Rpb24oJGNvbXBpbGUpIHsKICogICB2YXIgc2NvcGUgPSBhbmd1bGFyLmVsZW1lbnQoJGRpdikuc2NvcGUoKTsKICogICAkY29tcGlsZSgkZGl2KShzY29wZSk7CiAqIH0pOwogKiBgYGAKICovCgoKLyoqCiAqIEBuZ2RvYyBtb2R1bGUKICogQG5hbWUgYXV0bwogKiBAZGVzY3JpcHRpb24KICoKICogSW1wbGljaXQgbW9kdWxlIHdoaWNoIGdldHMgYXV0b21hdGljYWxseSBhZGRlZCB0byBlYWNoIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LgogKi8KCnZhciBGTl9BUkdTID0gL15mdW5jdGlvblxzKlteXChdKlwoXHMqKFteXCldKilcKS9tOwp2YXIgRk5fQVJHX1NQTElUID0gLywvOwp2YXIgRk5fQVJHID0gL15ccyooXz8pKFxTKz8pXDFccyokLzsKdmFyIFNUUklQX0NPTU1FTlRTID0gLygoXC9cLy4qJCl8KFwvXCpbXHNcU10qP1wqXC8pKS9tZzsKdmFyICRpbmplY3Rvck1pbkVyciA9IG1pbkVycignJGluamVjdG9yJyk7CgpmdW5jdGlvbiBhbm9uRm4oZm4pIHsKICAvLyBGb3IgYW5vbnltb3VzIGZ1bmN0aW9ucywgc2hvd2luZyBhdCB0aGUgdmVyeSBsZWFzdCB0aGUgZnVuY3Rpb24gc2lnbmF0dXJlIGNhbiBoZWxwIGluCiAgLy8gZGVidWdnaW5nLgogIHZhciBmblRleHQgPSBmbi50b1N0cmluZygpLnJlcGxhY2UoU1RSSVBfQ09NTUVOVFMsICcnKSwKICAgICAgYXJncyA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTsKICBpZiAoYXJncykgewogICAgcmV0dXJuICdmdW5jdGlvbignICsgKGFyZ3NbMV0gfHwgJycpLnJlcGxhY2UoL1tcc1xyXG5dKy8sICcgJykgKyAnKSc7CiAgfQogIHJldHVybiAnZm4nOwp9CgpmdW5jdGlvbiBhbm5vdGF0ZShmbiwgc3RyaWN0RGksIG5hbWUpIHsKICB2YXIgJGluamVjdCwKICAgICAgZm5UZXh0LAogICAgICBhcmdEZWNsLAogICAgICBsYXN0OwoKICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7CiAgICBpZiAoISgkaW5qZWN0ID0gZm4uJGluamVjdCkpIHsKICAgICAgJGluamVjdCA9IFtdOwogICAgICBpZiAoZm4ubGVuZ3RoKSB7CiAgICAgICAgaWYgKHN0cmljdERpKSB7CiAgICAgICAgICBpZiAoIWlzU3RyaW5nKG5hbWUpIHx8ICFuYW1lKSB7CiAgICAgICAgICAgIG5hbWUgPSBmbi5uYW1lIHx8IGFub25Gbihmbik7CiAgICAgICAgICB9CiAgICAgICAgICB0aHJvdyAkaW5qZWN0b3JNaW5FcnIoJ3N0cmljdGRpJywKICAgICAgICAgICAgJ3swfSBpcyBub3QgdXNpbmcgZXhwbGljaXQgYW5ub3RhdGlvbiBhbmQgY2Fubm90IGJlIGludm9rZWQgaW4gc3RyaWN0IG1vZGUnLCBuYW1lKTsKICAgICAgICB9CiAgICAgICAgZm5UZXh0ID0gZm4udG9TdHJpbmcoKS5yZXBsYWNlKFNUUklQX0NPTU1FTlRTLCAnJyk7CiAgICAgICAgYXJnRGVjbCA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTsKICAgICAgICBmb3JFYWNoKGFyZ0RlY2xbMV0uc3BsaXQoRk5fQVJHX1NQTElUKSwgZnVuY3Rpb24oYXJnKSB7CiAgICAgICAgICBhcmcucmVwbGFjZShGTl9BUkcsIGZ1bmN0aW9uKGFsbCwgdW5kZXJzY29yZSwgbmFtZSkgewogICAgICAgICAgICAkaW5qZWN0LnB1c2gobmFtZSk7CiAgICAgICAgICB9KTsKICAgICAgICB9KTsKICAgICAgfQogICAgICBmbi4kaW5qZWN0ID0gJGluamVjdDsKICAgIH0KICB9IGVsc2UgaWYgKGlzQXJyYXkoZm4pKSB7CiAgICBsYXN0ID0gZm4ubGVuZ3RoIC0gMTsKICAgIGFzc2VydEFyZ0ZuKGZuW2xhc3RdLCAnZm4nKTsKICAgICRpbmplY3QgPSBmbi5zbGljZSgwLCBsYXN0KTsKICB9IGVsc2UgewogICAgYXNzZXJ0QXJnRm4oZm4sICdmbicsIHRydWUpOwogIH0KICByZXR1cm4gJGluamVjdDsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJGluamVjdG9yCiAqCiAqIEBkZXNjcmlwdGlvbgogKgogKiBgJGluamVjdG9yYCBpcyB1c2VkIHRvIHJldHJpZXZlIG9iamVjdCBpbnN0YW5jZXMgYXMgZGVmaW5lZCBieQogKiB7QGxpbmsgYXV0by4kcHJvdmlkZSBwcm92aWRlcn0sIGluc3RhbnRpYXRlIHR5cGVzLCBpbnZva2UgbWV0aG9kcywKICogYW5kIGxvYWQgbW9kdWxlcy4KICoKICogVGhlIGZvbGxvd2luZyBhbHdheXMgaG9sZHMgdHJ1ZToKICoKICogYGBganMKICogICB2YXIgJGluamVjdG9yID0gYW5ndWxhci5pbmplY3RvcigpOwogKiAgIGV4cGVjdCgkaW5qZWN0b3IuZ2V0KCckaW5qZWN0b3InKSkudG9CZSgkaW5qZWN0b3IpOwogKiAgIGV4cGVjdCgkaW5qZWN0b3IuaW52b2tlKGZ1bmN0aW9uKCRpbmplY3RvcikgewogKiAgICAgcmV0dXJuICRpbmplY3RvcjsKICogICB9KSkudG9CZSgkaW5qZWN0b3IpOwogKiBgYGAKICoKICogIyBJbmplY3Rpb24gRnVuY3Rpb24gQW5ub3RhdGlvbgogKgogKiBKYXZhU2NyaXB0IGRvZXMgbm90IGhhdmUgYW5ub3RhdGlvbnMsIGFuZCBhbm5vdGF0aW9ucyBhcmUgbmVlZGVkIGZvciBkZXBlbmRlbmN5IGluamVjdGlvbi4gVGhlCiAqIGZvbGxvd2luZyBhcmUgYWxsIHZhbGlkIHdheXMgb2YgYW5ub3RhdGluZyBmdW5jdGlvbiB3aXRoIGluamVjdGlvbiBhcmd1bWVudHMgYW5kIGFyZSBlcXVpdmFsZW50LgogKgogKiBgYGBqcwogKiAgIC8vIGluZmVycmVkIChvbmx5IHdvcmtzIGlmIGNvZGUgbm90IG1pbmlmaWVkL29iZnVzY2F0ZWQpCiAqICAgJGluamVjdG9yLmludm9rZShmdW5jdGlvbihzZXJ2aWNlQSl7fSk7CiAqCiAqICAgLy8gYW5ub3RhdGVkCiAqICAgZnVuY3Rpb24gZXhwbGljaXQoc2VydmljZUEpIHt9OwogKiAgIGV4cGxpY2l0LiRpbmplY3QgPSBbJ3NlcnZpY2VBJ107CiAqICAgJGluamVjdG9yLmludm9rZShleHBsaWNpdCk7CiAqCiAqICAgLy8gaW5saW5lCiAqICAgJGluamVjdG9yLmludm9rZShbJ3NlcnZpY2VBJywgZnVuY3Rpb24oc2VydmljZUEpe31dKTsKICogYGBgCiAqCiAqICMjIEluZmVyZW5jZQogKgogKiBJbiBKYXZhU2NyaXB0IGNhbGxpbmcgYHRvU3RyaW5nKClgIG9uIGEgZnVuY3Rpb24gcmV0dXJucyB0aGUgZnVuY3Rpb24gZGVmaW5pdGlvbi4gVGhlIGRlZmluaXRpb24KICogY2FuIHRoZW4gYmUgcGFyc2VkIGFuZCB0aGUgZnVuY3Rpb24gYXJndW1lbnRzIGNhbiBiZSBleHRyYWN0ZWQuIFRoaXMgbWV0aG9kIG9mIGRpc2NvdmVyaW5nCiAqIGFubm90YXRpb25zIGlzIGRpc2FsbG93ZWQgd2hlbiB0aGUgaW5qZWN0b3IgaXMgaW4gc3RyaWN0IG1vZGUuCiAqICpOT1RFOiogVGhpcyBkb2VzIG5vdCB3b3JrIHdpdGggbWluaWZpY2F0aW9uLCBhbmQgb2JmdXNjYXRpb24gdG9vbHMgc2luY2UgdGhlc2UgdG9vbHMgY2hhbmdlIHRoZQogKiBhcmd1bWVudCBuYW1lcy4KICoKICogIyMgYCRpbmplY3RgIEFubm90YXRpb24KICogQnkgYWRkaW5nIGFuIGAkaW5qZWN0YCBwcm9wZXJ0eSBvbnRvIGEgZnVuY3Rpb24gdGhlIGluamVjdGlvbiBwYXJhbWV0ZXJzIGNhbiBiZSBzcGVjaWZpZWQuCiAqCiAqICMjIElubGluZQogKiBBcyBhbiBhcnJheSBvZiBpbmplY3Rpb24gbmFtZXMsIHdoZXJlIHRoZSBsYXN0IGl0ZW0gaW4gdGhlIGFycmF5IGlzIHRoZSBmdW5jdGlvbiB0byBjYWxsLgogKi8KCi8qKgogKiBAbmdkb2MgbWV0aG9kCiAqIEBuYW1lICRpbmplY3RvciNnZXQKICoKICogQGRlc2NyaXB0aW9uCiAqIFJldHVybiBhbiBpbnN0YW5jZSBvZiB0aGUgc2VydmljZS4KICoKICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlIHRvIHJldHJpZXZlLgogKiBAcGFyYW0ge3N0cmluZ30gY2FsbGVyIEFuIG9wdGlvbmFsIHN0cmluZyB0byBwcm92aWRlIHRoZSBvcmlnaW4gb2YgdGhlIGZ1bmN0aW9uIGNhbGwgZm9yIGVycm9yIG1lc3NhZ2VzLgogKiBAcmV0dXJuIHsqfSBUaGUgaW5zdGFuY2UuCiAqLwoKLyoqCiAqIEBuZ2RvYyBtZXRob2QKICogQG5hbWUgJGluamVjdG9yI2ludm9rZQogKgogKiBAZGVzY3JpcHRpb24KICogSW52b2tlIHRoZSBtZXRob2QgYW5kIHN1cHBseSB0aGUgbWV0aG9kIGFyZ3VtZW50cyBmcm9tIHRoZSBgJGluamVjdG9yYC4KICoKICogQHBhcmFtIHshRnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBpbnZva2UuIEZ1bmN0aW9uIHBhcmFtZXRlcnMgYXJlIGluamVjdGVkIGFjY29yZGluZyB0byB0aGUKICogICB7QGxpbmsgZ3VpZGUvZGkgJGluamVjdCBBbm5vdGF0aW9ufSBydWxlcy4KICogQHBhcmFtIHtPYmplY3Q9fSBzZWxmIFRoZSBgdGhpc2AgZm9yIHRoZSBpbnZva2VkIG1ldGhvZC4KICogQHBhcmFtIHtPYmplY3Q9fSBsb2NhbHMgT3B0aW9uYWwgb2JqZWN0LiBJZiBwcmVzZXQgdGhlbiBhbnkgYXJndW1lbnQgbmFtZXMgYXJlIHJlYWQgZnJvbSB0aGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCBmaXJzdCwgYmVmb3JlIHRoZSBgJGluamVjdG9yYCBpcyBjb25zdWx0ZWQuCiAqIEByZXR1cm5zIHsqfSB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGludm9rZWQgYGZuYCBmdW5jdGlvbi4KICovCgovKioKICogQG5nZG9jIG1ldGhvZAogKiBAbmFtZSAkaW5qZWN0b3IjaGFzCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBbGxvd3MgdGhlIHVzZXIgdG8gcXVlcnkgaWYgdGhlIHBhcnRpY3VsYXIgc2VydmljZSBleGlzdHMuCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIHNlcnZpY2UgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgaW5qZWN0b3IgaGFzIGdpdmVuIHNlcnZpY2UuCiAqLwoKLyoqCiAqIEBuZ2RvYyBtZXRob2QKICogQG5hbWUgJGluamVjdG9yI2luc3RhbnRpYXRlCiAqIEBkZXNjcmlwdGlvbgogKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgSlMgdHlwZS4gVGhlIG1ldGhvZCB0YWtlcyBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLCBpbnZva2VzIHRoZSBuZXcKICogb3BlcmF0b3IsIGFuZCBzdXBwbGllcyBhbGwgb2YgdGhlIGFyZ3VtZW50cyB0byB0aGUgY29uc3RydWN0b3IgZnVuY3Rpb24gYXMgc3BlY2lmaWVkIGJ5IHRoZQogKiBjb25zdHJ1Y3RvciBhbm5vdGF0aW9uLgogKgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBUeXBlIEFubm90YXRlZCBjb25zdHJ1Y3RvciBmdW5jdGlvbi4KICogQHBhcmFtIHtPYmplY3Q9fSBsb2NhbHMgT3B0aW9uYWwgb2JqZWN0LiBJZiBwcmVzZXQgdGhlbiBhbnkgYXJndW1lbnQgbmFtZXMgYXJlIHJlYWQgZnJvbSB0aGlzCiAqIG9iamVjdCBmaXJzdCwgYmVmb3JlIHRoZSBgJGluamVjdG9yYCBpcyBjb25zdWx0ZWQuCiAqIEByZXR1cm5zIHtPYmplY3R9IG5ldyBpbnN0YW5jZSBvZiBgVHlwZWAuCiAqLwoKLyoqCiAqIEBuZ2RvYyBtZXRob2QKICogQG5hbWUgJGluamVjdG9yI2Fubm90YXRlCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBSZXR1cm5zIGFuIGFycmF5IG9mIHNlcnZpY2UgbmFtZXMgd2hpY2ggdGhlIGZ1bmN0aW9uIGlzIHJlcXVlc3RpbmcgZm9yIGluamVjdGlvbi4gVGhpcyBBUEkgaXMKICogdXNlZCBieSB0aGUgaW5qZWN0b3IgdG8gZGV0ZXJtaW5lIHdoaWNoIHNlcnZpY2VzIG5lZWQgdG8gYmUgaW5qZWN0ZWQgaW50byB0aGUgZnVuY3Rpb24gd2hlbiB0aGUKICogZnVuY3Rpb24gaXMgaW52b2tlZC4gVGhlcmUgYXJlIHRocmVlIHdheXMgaW4gd2hpY2ggdGhlIGZ1bmN0aW9uIGNhbiBiZSBhbm5vdGF0ZWQgd2l0aCB0aGUgbmVlZGVkCiAqIGRlcGVuZGVuY2llcy4KICoKICogIyBBcmd1bWVudCBuYW1lcwogKgogKiBUaGUgc2ltcGxlc3QgZm9ybSBpcyB0byBleHRyYWN0IHRoZSBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgYXJndW1lbnRzIG9mIHRoZSBmdW5jdGlvbi4gVGhpcyBpcyBkb25lCiAqIGJ5IGNvbnZlcnRpbmcgdGhlIGZ1bmN0aW9uIGludG8gYSBzdHJpbmcgdXNpbmcgYHRvU3RyaW5nKClgIG1ldGhvZCBhbmQgZXh0cmFjdGluZyB0aGUgYXJndW1lbnQKICogbmFtZXMuCiAqIGBgYGpzCiAqICAgLy8gR2l2ZW4KICogICBmdW5jdGlvbiBNeUNvbnRyb2xsZXIoJHNjb3BlLCAkcm91dGUpIHsKICogICAgIC8vIC4uLgogKiAgIH0KICoKICogICAvLyBUaGVuCiAqICAgZXhwZWN0KGluamVjdG9yLmFubm90YXRlKE15Q29udHJvbGxlcikpLnRvRXF1YWwoWyckc2NvcGUnLCAnJHJvdXRlJ10pOwogKiBgYGAKICoKICogWW91IGNhbiBkaXNhbGxvdyB0aGlzIG1ldGhvZCBieSB1c2luZyBzdHJpY3QgaW5qZWN0aW9uIG1vZGUuCiAqCiAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHdvcmsgd2l0aCBjb2RlIG1pbmlmaWNhdGlvbiAvIG9iZnVzY2F0aW9uLiBGb3IgdGhpcyByZWFzb24gdGhlIGZvbGxvd2luZwogKiBhbm5vdGF0aW9uIHN0cmF0ZWdpZXMgYXJlIHN1cHBvcnRlZC4KICoKICogIyBUaGUgYCRpbmplY3RgIHByb3BlcnR5CiAqCiAqIElmIGEgZnVuY3Rpb24gaGFzIGFuIGAkaW5qZWN0YCBwcm9wZXJ0eSBhbmQgaXRzIHZhbHVlIGlzIGFuIGFycmF5IG9mIHN0cmluZ3MsIHRoZW4gdGhlIHN0cmluZ3MKICogcmVwcmVzZW50IG5hbWVzIG9mIHNlcnZpY2VzIHRvIGJlIGluamVjdGVkIGludG8gdGhlIGZ1bmN0aW9uLgogKiBgYGBqcwogKiAgIC8vIEdpdmVuCiAqICAgdmFyIE15Q29udHJvbGxlciA9IGZ1bmN0aW9uKG9iZnVzY2F0ZWRTY29wZSwgb2JmdXNjYXRlZFJvdXRlKSB7CiAqICAgICAvLyAuLi4KICogICB9CiAqICAgLy8gRGVmaW5lIGZ1bmN0aW9uIGRlcGVuZGVuY2llcwogKiAgIE15Q29udHJvbGxlclsnJGluamVjdCddID0gWyckc2NvcGUnLCAnJHJvdXRlJ107CiAqCiAqICAgLy8gVGhlbgogKiAgIGV4cGVjdChpbmplY3Rvci5hbm5vdGF0ZShNeUNvbnRyb2xsZXIpKS50b0VxdWFsKFsnJHNjb3BlJywgJyRyb3V0ZSddKTsKICogYGBgCiAqCiAqICMgVGhlIGFycmF5IG5vdGF0aW9uCiAqCiAqIEl0IGlzIG9mdGVuIGRlc2lyYWJsZSB0byBpbmxpbmUgSW5qZWN0ZWQgZnVuY3Rpb25zIGFuZCB0aGF0J3Mgd2hlbiBzZXR0aW5nIHRoZSBgJGluamVjdGAgcHJvcGVydHkKICogaXMgdmVyeSBpbmNvbnZlbmllbnQuIEluIHRoZXNlIHNpdHVhdGlvbnMgdXNpbmcgdGhlIGFycmF5IG5vdGF0aW9uIHRvIHNwZWNpZnkgdGhlIGRlcGVuZGVuY2llcyBpbgogKiBhIHdheSB0aGF0IHN1cnZpdmVzIG1pbmlmaWNhdGlvbiBpcyBhIGJldHRlciBjaG9pY2U6CiAqCiAqIGBgYGpzCiAqICAgLy8gV2Ugd2lzaCB0byB3cml0ZSB0aGlzIChub3QgbWluaWZpY2F0aW9uIC8gb2JmdXNjYXRpb24gc2FmZSkKICogICBpbmplY3Rvci5pbnZva2UoZnVuY3Rpb24oJGNvbXBpbGUsICRyb290U2NvcGUpIHsKICogICAgIC8vIC4uLgogKiAgIH0pOwogKgogKiAgIC8vIFdlIGFyZSBmb3JjZWQgdG8gd3JpdGUgYnJlYWsgaW5saW5pbmcKICogICB2YXIgdG1wRm4gPSBmdW5jdGlvbihvYmZ1c2NhdGVkQ29tcGlsZSwgb2JmdXNjYXRlZFJvb3RTY29wZSkgewogKiAgICAgLy8gLi4uCiAqICAgfTsKICogICB0bXBGbi4kaW5qZWN0ID0gWyckY29tcGlsZScsICckcm9vdFNjb3BlJ107CiAqICAgaW5qZWN0b3IuaW52b2tlKHRtcEZuKTsKICoKICogICAvLyBUbyBiZXR0ZXIgc3VwcG9ydCBpbmxpbmUgZnVuY3Rpb24gdGhlIGlubGluZSBhbm5vdGF0aW9uIGlzIHN1cHBvcnRlZAogKiAgIGluamVjdG9yLmludm9rZShbJyRjb21waWxlJywgJyRyb290U2NvcGUnLCBmdW5jdGlvbihvYmZDb21waWxlLCBvYmZSb290U2NvcGUpIHsKICogICAgIC8vIC4uLgogKiAgIH1dKTsKICoKICogICAvLyBUaGVyZWZvcmUKICogICBleHBlY3QoaW5qZWN0b3IuYW5ub3RhdGUoCiAqICAgICAgWyckY29tcGlsZScsICckcm9vdFNjb3BlJywgZnVuY3Rpb24ob2JmdXNfJGNvbXBpbGUsIG9iZnVzXyRyb290U2NvcGUpIHt9XSkKICogICAgKS50b0VxdWFsKFsnJGNvbXBpbGUnLCAnJHJvb3RTY29wZSddKTsKICogYGBgCiAqCiAqIEBwYXJhbSB7RnVuY3Rpb258QXJyYXkuPHN0cmluZ3xGdW5jdGlvbj59IGZuIEZ1bmN0aW9uIGZvciB3aGljaCBkZXBlbmRlbnQgc2VydmljZSBuYW1lcyBuZWVkIHRvCiAqIGJlIHJldHJpZXZlZCBhcyBkZXNjcmliZWQgYWJvdmUuCiAqCiAqIEBwYXJhbSB7Ym9vbGVhbj19IFtzdHJpY3REaT1mYWxzZV0gRGlzYWxsb3cgYXJndW1lbnQgbmFtZSBhbm5vdGF0aW9uIGluZmVyZW5jZS4KICoKICogQHJldHVybnMge0FycmF5LjxzdHJpbmc+fSBUaGUgbmFtZXMgb2YgdGhlIHNlcnZpY2VzIHdoaWNoIHRoZSBmdW5jdGlvbiByZXF1aXJlcy4KICovCgoKCgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJHByb3ZpZGUKICoKICogQGRlc2NyaXB0aW9uCiAqCiAqIFRoZSB7QGxpbmsgYXV0by4kcHJvdmlkZSAkcHJvdmlkZX0gc2VydmljZSBoYXMgYSBudW1iZXIgb2YgbWV0aG9kcyBmb3IgcmVnaXN0ZXJpbmcgY29tcG9uZW50cwogKiB3aXRoIHRoZSB7QGxpbmsgYXV0by4kaW5qZWN0b3IgJGluamVjdG9yfS4gTWFueSBvZiB0aGVzZSBmdW5jdGlvbnMgYXJlIGFsc28gZXhwb3NlZCBvbgogKiB7QGxpbmsgYW5ndWxhci5Nb2R1bGV9LgogKgogKiBBbiBBbmd1bGFyICoqc2VydmljZSoqIGlzIGEgc2luZ2xldG9uIG9iamVjdCBjcmVhdGVkIGJ5IGEgKipzZXJ2aWNlIGZhY3RvcnkqKi4gIFRoZXNlICoqc2VydmljZQogKiBmYWN0b3JpZXMqKiBhcmUgZnVuY3Rpb25zIHdoaWNoLCBpbiB0dXJuLCBhcmUgY3JlYXRlZCBieSBhICoqc2VydmljZSBwcm92aWRlcioqLgogKiBUaGUgKipzZXJ2aWNlIHByb3ZpZGVycyoqIGFyZSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMuIFdoZW4gaW5zdGFudGlhdGVkIHRoZXkgbXVzdCBjb250YWluIGEKICogcHJvcGVydHkgY2FsbGVkIGAkZ2V0YCwgd2hpY2ggaG9sZHMgdGhlICoqc2VydmljZSBmYWN0b3J5KiogZnVuY3Rpb24uCiAqCiAqIFdoZW4geW91IHJlcXVlc3QgYSBzZXJ2aWNlLCB0aGUge0BsaW5rIGF1dG8uJGluamVjdG9yICRpbmplY3Rvcn0gaXMgcmVzcG9uc2libGUgZm9yIGZpbmRpbmcgdGhlCiAqIGNvcnJlY3QgKipzZXJ2aWNlIHByb3ZpZGVyKiosIGluc3RhbnRpYXRpbmcgaXQgYW5kIHRoZW4gY2FsbGluZyBpdHMgYCRnZXRgICoqc2VydmljZSBmYWN0b3J5KioKICogZnVuY3Rpb24gdG8gZ2V0IHRoZSBpbnN0YW5jZSBvZiB0aGUgKipzZXJ2aWNlKiouCiAqCiAqIE9mdGVuIHNlcnZpY2VzIGhhdmUgbm8gY29uZmlndXJhdGlvbiBvcHRpb25zIGFuZCB0aGVyZSBpcyBubyBuZWVkIHRvIGFkZCBtZXRob2RzIHRvIHRoZSBzZXJ2aWNlCiAqIHByb3ZpZGVyLiAgVGhlIHByb3ZpZGVyIHdpbGwgYmUgbm8gbW9yZSB0aGFuIGEgY29uc3RydWN0b3IgZnVuY3Rpb24gd2l0aCBhIGAkZ2V0YCBwcm9wZXJ0eS4gRm9yCiAqIHRoZXNlIGNhc2VzIHRoZSB7QGxpbmsgYXV0by4kcHJvdmlkZSAkcHJvdmlkZX0gc2VydmljZSBoYXMgYWRkaXRpb25hbCBoZWxwZXIgbWV0aG9kcyB0byByZWdpc3RlcgogKiBzZXJ2aWNlcyB3aXRob3V0IHNwZWNpZnlpbmcgYSBwcm92aWRlci4KICoKICogKiB7QGxpbmsgYXV0by4kcHJvdmlkZSNwcm92aWRlciBwcm92aWRlcihwcm92aWRlcil9IC0gcmVnaXN0ZXJzIGEgKipzZXJ2aWNlIHByb3ZpZGVyKiogd2l0aCB0aGUKICogICAgIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9CiAqICoge0BsaW5rIGF1dG8uJHByb3ZpZGUjY29uc3RhbnQgY29uc3RhbnQob2JqKX0gLSByZWdpc3RlcnMgYSB2YWx1ZS9vYmplY3QgdGhhdCBjYW4gYmUgYWNjZXNzZWQgYnkKICogICAgIHByb3ZpZGVycyBhbmQgc2VydmljZXMuCiAqICoge0BsaW5rIGF1dG8uJHByb3ZpZGUjdmFsdWUgdmFsdWUob2JqKX0gLSByZWdpc3RlcnMgYSB2YWx1ZS9vYmplY3QgdGhhdCBjYW4gb25seSBiZSBhY2Nlc3NlZCBieQogKiAgICAgc2VydmljZXMsIG5vdCBwcm92aWRlcnMuCiAqICoge0BsaW5rIGF1dG8uJHByb3ZpZGUjZmFjdG9yeSBmYWN0b3J5KGZuKX0gLSByZWdpc3RlcnMgYSBzZXJ2aWNlICoqZmFjdG9yeSBmdW5jdGlvbioqLCBgZm5gLAogKiAgICAgdGhhdCB3aWxsIGJlIHdyYXBwZWQgaW4gYSAqKnNlcnZpY2UgcHJvdmlkZXIqKiBvYmplY3QsIHdob3NlIGAkZ2V0YCBwcm9wZXJ0eSB3aWxsIGNvbnRhaW4gdGhlCiAqICAgICBnaXZlbiBmYWN0b3J5IGZ1bmN0aW9uLgogKiAqIHtAbGluayBhdXRvLiRwcm92aWRlI3NlcnZpY2Ugc2VydmljZShjbGFzcyl9IC0gcmVnaXN0ZXJzIGEgKipjb25zdHJ1Y3RvciBmdW5jdGlvbioqLCBgY2xhc3NgCiAqICAgICB0aGF0IHdpbGwgYmUgd3JhcHBlZCBpbiBhICoqc2VydmljZSBwcm92aWRlcioqIG9iamVjdCwgd2hvc2UgYCRnZXRgIHByb3BlcnR5IHdpbGwgaW5zdGFudGlhdGUKICogICAgICBhIG5ldyBvYmplY3QgdXNpbmcgdGhlIGdpdmVuIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLgogKgogKiBTZWUgdGhlIGluZGl2aWR1YWwgbWV0aG9kcyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhbmQgZXhhbXBsZXMuCiAqLwoKLyoqCiAqIEBuZ2RvYyBtZXRob2QKICogQG5hbWUgJHByb3ZpZGUjcHJvdmlkZXIKICogQGRlc2NyaXB0aW9uCiAqCiAqIFJlZ2lzdGVyIGEgKipwcm92aWRlciBmdW5jdGlvbioqIHdpdGggdGhlIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LiBQcm92aWRlciBmdW5jdGlvbnMKICogYXJlIGNvbnN0cnVjdG9yIGZ1bmN0aW9ucywgd2hvc2UgaW5zdGFuY2VzIGFyZSByZXNwb25zaWJsZSBmb3IgInByb3ZpZGluZyIgYSBmYWN0b3J5IGZvciBhCiAqIHNlcnZpY2UuCiAqCiAqIFNlcnZpY2UgcHJvdmlkZXIgbmFtZXMgc3RhcnQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0aGV5IHByb3ZpZGUgZm9sbG93ZWQgYnkgYFByb3ZpZGVyYC4KICogRm9yIGV4YW1wbGUsIHRoZSB7QGxpbmsgbmcuJGxvZyAkbG9nfSBzZXJ2aWNlIGhhcyBhIHByb3ZpZGVyIGNhbGxlZAogKiB7QGxpbmsgbmcuJGxvZ1Byb3ZpZGVyICRsb2dQcm92aWRlcn0uCiAqCiAqIFNlcnZpY2UgcHJvdmlkZXIgb2JqZWN0cyBjYW4gaGF2ZSBhZGRpdGlvbmFsIG1ldGhvZHMgd2hpY2ggYWxsb3cgY29uZmlndXJhdGlvbiBvZiB0aGUgcHJvdmlkZXIKICogYW5kIGl0cyBzZXJ2aWNlLiBJbXBvcnRhbnRseSwgeW91IGNhbiBjb25maWd1cmUgd2hhdCBraW5kIG9mIHNlcnZpY2UgaXMgY3JlYXRlZCBieSB0aGUgYCRnZXRgCiAqIG1ldGhvZCwgb3IgaG93IHRoYXQgc2VydmljZSB3aWxsIGFjdC4gRm9yIGV4YW1wbGUsIHRoZSB7QGxpbmsgbmcuJGxvZ1Byb3ZpZGVyICRsb2dQcm92aWRlcn0gaGFzIGEKICogbWV0aG9kIHtAbGluayBuZy4kbG9nUHJvdmlkZXIjZGVidWdFbmFibGVkIGRlYnVnRW5hYmxlZH0KICogd2hpY2ggbGV0cyB5b3Ugc3BlY2lmeSB3aGV0aGVyIHRoZSB7QGxpbmsgbmcuJGxvZyAkbG9nfSBzZXJ2aWNlIHdpbGwgbG9nIGRlYnVnIG1lc3NhZ2VzIHRvIHRoZQogKiBjb25zb2xlIG9yIG5vdC4KICoKICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlLiBOT1RFOiB0aGUgcHJvdmlkZXIgd2lsbCBiZSBhdmFpbGFibGUgdW5kZXIgYG5hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAnUHJvdmlkZXInYCBrZXkuCiAqIEBwYXJhbSB7KE9iamVjdHxmdW5jdGlvbigpKX0gcHJvdmlkZXIgSWYgdGhlIHByb3ZpZGVyIGlzOgogKgogKiAgIC0gYE9iamVjdGA6IHRoZW4gaXQgc2hvdWxkIGhhdmUgYSBgJGdldGAgbWV0aG9kLiBUaGUgYCRnZXRgIG1ldGhvZCB3aWxsIGJlIGludm9rZWQgdXNpbmcKICogICAgIHtAbGluayBhdXRvLiRpbmplY3RvciNpbnZva2UgJGluamVjdG9yLmludm9rZSgpfSB3aGVuIGFuIGluc3RhbmNlIG5lZWRzIHRvIGJlIGNyZWF0ZWQuCiAqICAgLSBgQ29uc3RydWN0b3JgOiBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgcHJvdmlkZXIgd2lsbCBiZSBjcmVhdGVkIHVzaW5nCiAqICAgICB7QGxpbmsgYXV0by4kaW5qZWN0b3IjaW5zdGFudGlhdGUgJGluamVjdG9yLmluc3RhbnRpYXRlKCl9LCB0aGVuIHRyZWF0ZWQgYXMgYG9iamVjdGAuCiAqCiAqIEByZXR1cm5zIHtPYmplY3R9IHJlZ2lzdGVyZWQgcHJvdmlkZXIgaW5zdGFuY2UKCiAqIEBleGFtcGxlCiAqCiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gY3JlYXRlIGEgc2ltcGxlIGV2ZW50IHRyYWNraW5nIHNlcnZpY2UgYW5kIHJlZ2lzdGVyIGl0IHVzaW5nCiAqIHtAbGluayBhdXRvLiRwcm92aWRlI3Byb3ZpZGVyICRwcm92aWRlLnByb3ZpZGVyKCl9LgogKgogKiBgYGBqcwogKiAgLy8gRGVmaW5lIHRoZSBldmVudFRyYWNrZXIgcHJvdmlkZXIKICogIGZ1bmN0aW9uIEV2ZW50VHJhY2tlclByb3ZpZGVyKCkgewogKiAgICB2YXIgdHJhY2tpbmdVcmwgPSAnL3RyYWNrJzsKICoKICogICAgLy8gQSBwcm92aWRlciBtZXRob2QgZm9yIGNvbmZpZ3VyaW5nIHdoZXJlIHRoZSB0cmFja2VkIGV2ZW50cyBzaG91bGQgYmVlbiBzYXZlZAogKiAgICB0aGlzLnNldFRyYWNraW5nVXJsID0gZnVuY3Rpb24odXJsKSB7CiAqICAgICAgdHJhY2tpbmdVcmwgPSB1cmw7CiAqICAgIH07CiAqCiAqICAgIC8vIFRoZSBzZXJ2aWNlIGZhY3RvcnkgZnVuY3Rpb24KICogICAgdGhpcy4kZ2V0ID0gWyckaHR0cCcsIGZ1bmN0aW9uKCRodHRwKSB7CiAqICAgICAgdmFyIHRyYWNrZWRFdmVudHMgPSB7fTsKICogICAgICByZXR1cm4gewogKiAgICAgICAgLy8gQ2FsbCB0aGlzIHRvIHRyYWNrIGFuIGV2ZW50CiAqICAgICAgICBldmVudDogZnVuY3Rpb24oZXZlbnQpIHsKICogICAgICAgICAgdmFyIGNvdW50ID0gdHJhY2tlZEV2ZW50c1tldmVudF0gfHwgMDsKICogICAgICAgICAgY291bnQgKz0gMTsKICogICAgICAgICAgdHJhY2tlZEV2ZW50c1tldmVudF0gPSBjb3VudDsKICogICAgICAgICAgcmV0dXJuIGNvdW50OwogKiAgICAgICAgfSwKICogICAgICAgIC8vIENhbGwgdGhpcyB0byBzYXZlIHRoZSB0cmFja2VkIGV2ZW50cyB0byB0aGUgdHJhY2tpbmdVcmwKICogICAgICAgIHNhdmU6IGZ1bmN0aW9uKCkgewogKiAgICAgICAgICAkaHR0cC5wb3N0KHRyYWNraW5nVXJsLCB0cmFja2VkRXZlbnRzKTsKICogICAgICAgIH0KICogICAgICB9OwogKiAgICB9XTsKICogIH0KICoKICogIGRlc2NyaWJlKCdldmVudFRyYWNrZXInLCBmdW5jdGlvbigpIHsKICogICAgdmFyIHBvc3RTcHk7CiAqCiAqICAgIGJlZm9yZUVhY2gobW9kdWxlKGZ1bmN0aW9uKCRwcm92aWRlKSB7CiAqICAgICAgLy8gUmVnaXN0ZXIgdGhlIGV2ZW50VHJhY2tlciBwcm92aWRlcgogKiAgICAgICRwcm92aWRlLnByb3ZpZGVyKCdldmVudFRyYWNrZXInLCBFdmVudFRyYWNrZXJQcm92aWRlcik7CiAqICAgIH0pKTsKICoKICogICAgYmVmb3JlRWFjaChtb2R1bGUoZnVuY3Rpb24oZXZlbnRUcmFja2VyUHJvdmlkZXIpIHsKICogICAgICAvLyBDb25maWd1cmUgZXZlbnRUcmFja2VyIHByb3ZpZGVyCiAqICAgICAgZXZlbnRUcmFja2VyUHJvdmlkZXIuc2V0VHJhY2tpbmdVcmwoJy9jdXN0b20tdHJhY2snKTsKICogICAgfSkpOwogKgogKiAgICBpdCgndHJhY2tzIGV2ZW50cycsIGluamVjdChmdW5jdGlvbihldmVudFRyYWNrZXIpIHsKICogICAgICBleHBlY3QoZXZlbnRUcmFja2VyLmV2ZW50KCdsb2dpbicpKS50b0VxdWFsKDEpOwogKiAgICAgIGV4cGVjdChldmVudFRyYWNrZXIuZXZlbnQoJ2xvZ2luJykpLnRvRXF1YWwoMik7CiAqICAgIH0pKTsKICoKICogICAgaXQoJ3NhdmVzIHRvIHRoZSB0cmFja2luZyB1cmwnLCBpbmplY3QoZnVuY3Rpb24oZXZlbnRUcmFja2VyLCAkaHR0cCkgewogKiAgICAgIHBvc3RTcHkgPSBzcHlPbigkaHR0cCwgJ3Bvc3QnKTsKICogICAgICBldmVudFRyYWNrZXIuZXZlbnQoJ2xvZ2luJyk7CiAqICAgICAgZXZlbnRUcmFja2VyLnNhdmUoKTsKICogICAgICBleHBlY3QocG9zdFNweSkudG9IYXZlQmVlbkNhbGxlZCgpOwogKiAgICAgIGV4cGVjdChwb3N0U3B5Lm1vc3RSZWNlbnRDYWxsLmFyZ3NbMF0pLm5vdC50b0VxdWFsKCcvdHJhY2snKTsKICogICAgICBleHBlY3QocG9zdFNweS5tb3N0UmVjZW50Q2FsbC5hcmdzWzBdKS50b0VxdWFsKCcvY3VzdG9tLXRyYWNrJyk7CiAqICAgICAgZXhwZWN0KHBvc3RTcHkubW9zdFJlY2VudENhbGwuYXJnc1sxXSkudG9FcXVhbCh7ICdsb2dpbic6IDEgfSk7CiAqICAgIH0pKTsKICogIH0pOwogKiBgYGAKICovCgovKioKICogQG5nZG9jIG1ldGhvZAogKiBAbmFtZSAkcHJvdmlkZSNmYWN0b3J5CiAqIEBkZXNjcmlwdGlvbgogKgogKiBSZWdpc3RlciBhICoqc2VydmljZSBmYWN0b3J5KiosIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHRvIHJldHVybiB0aGUgc2VydmljZSBpbnN0YW5jZS4KICogVGhpcyBpcyBzaG9ydCBmb3IgcmVnaXN0ZXJpbmcgYSBzZXJ2aWNlIHdoZXJlIGl0cyBwcm92aWRlciBjb25zaXN0cyBvZiBvbmx5IGEgYCRnZXRgIHByb3BlcnR5LAogKiB3aGljaCBpcyB0aGUgZ2l2ZW4gc2VydmljZSBmYWN0b3J5IGZ1bmN0aW9uLgogKiBZb3Ugc2hvdWxkIHVzZSB7QGxpbmsgYXV0by4kcHJvdmlkZSNmYWN0b3J5ICRwcm92aWRlLmZhY3RvcnkoZ2V0Rm4pfSBpZiB5b3UgZG8gbm90IG5lZWQgdG8KICogY29uZmlndXJlIHlvdXIgc2VydmljZSBpbiBhIHByb3ZpZGVyLgogKgogKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgaW5zdGFuY2UuCiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gJGdldEZuIFRoZSAkZ2V0Rm4gZm9yIHRoZSBpbnN0YW5jZSBjcmVhdGlvbi4gSW50ZXJuYWxseSB0aGlzIGlzIGEgc2hvcnQgaGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgYCRwcm92aWRlLnByb3ZpZGVyKG5hbWUsIHskZ2V0OiAkZ2V0Rm59KWAuCiAqIEByZXR1cm5zIHtPYmplY3R9IHJlZ2lzdGVyZWQgcHJvdmlkZXIgaW5zdGFuY2UKICoKICogQGV4YW1wbGUKICogSGVyZSBpcyBhbiBleGFtcGxlIG9mIHJlZ2lzdGVyaW5nIGEgc2VydmljZQogKiBgYGBqcwogKiAgICRwcm92aWRlLmZhY3RvcnkoJ3BpbmcnLCBbJyRodHRwJywgZnVuY3Rpb24oJGh0dHApIHsKICogICAgIHJldHVybiBmdW5jdGlvbiBwaW5nKCkgewogKiAgICAgICByZXR1cm4gJGh0dHAuc2VuZCgnL3BpbmcnKTsKICogICAgIH07CiAqICAgfV0pOwogKiBgYGAKICogWW91IHdvdWxkIHRoZW4gaW5qZWN0IGFuZCB1c2UgdGhpcyBzZXJ2aWNlIGxpa2UgdGhpczoKICogYGBganMKICogICBzb21lTW9kdWxlLmNvbnRyb2xsZXIoJ0N0cmwnLCBbJ3BpbmcnLCBmdW5jdGlvbihwaW5nKSB7CiAqICAgICBwaW5nKCk7CiAqICAgfV0pOwogKiBgYGAKICovCgoKLyoqCiAqIEBuZ2RvYyBtZXRob2QKICogQG5hbWUgJHByb3ZpZGUjc2VydmljZQogKiBAZGVzY3JpcHRpb24KICoKICogUmVnaXN0ZXIgYSAqKnNlcnZpY2UgY29uc3RydWN0b3IqKiwgd2hpY2ggd2lsbCBiZSBpbnZva2VkIHdpdGggYG5ld2AgdG8gY3JlYXRlIHRoZSBzZXJ2aWNlCiAqIGluc3RhbmNlLgogKiBUaGlzIGlzIHNob3J0IGZvciByZWdpc3RlcmluZyBhIHNlcnZpY2Ugd2hlcmUgaXRzIHByb3ZpZGVyJ3MgYCRnZXRgIHByb3BlcnR5IGlzIHRoZSBzZXJ2aWNlCiAqIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGluc3RhbnRpYXRlIHRoZSBzZXJ2aWNlIGluc3RhbmNlLgogKgogKiBZb3Ugc2hvdWxkIHVzZSB7QGxpbmsgYXV0by4kcHJvdmlkZSNzZXJ2aWNlICRwcm92aWRlLnNlcnZpY2UoY2xhc3MpfSBpZiB5b3UgZGVmaW5lIHlvdXIgc2VydmljZQogKiBhcyBhIHR5cGUvY2xhc3MuCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBpbnN0YW5jZS4KICogQHBhcmFtIHtGdW5jdGlvbn0gY29uc3RydWN0b3IgQSBjbGFzcyAoY29uc3RydWN0b3IgZnVuY3Rpb24pIHRoYXQgd2lsbCBiZSBpbnN0YW50aWF0ZWQuCiAqIEByZXR1cm5zIHtPYmplY3R9IHJlZ2lzdGVyZWQgcHJvdmlkZXIgaW5zdGFuY2UKICoKICogQGV4YW1wbGUKICogSGVyZSBpcyBhbiBleGFtcGxlIG9mIHJlZ2lzdGVyaW5nIGEgc2VydmljZSB1c2luZwogKiB7QGxpbmsgYXV0by4kcHJvdmlkZSNzZXJ2aWNlICRwcm92aWRlLnNlcnZpY2UoY2xhc3MpfS4KICogYGBganMKICogICB2YXIgUGluZyA9IGZ1bmN0aW9uKCRodHRwKSB7CiAqICAgICB0aGlzLiRodHRwID0gJGh0dHA7CiAqICAgfTsKICoKICogICBQaW5nLiRpbmplY3QgPSBbJyRodHRwJ107CiAqCiAqICAgUGluZy5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uKCkgewogKiAgICAgcmV0dXJuIHRoaXMuJGh0dHAuZ2V0KCcvcGluZycpOwogKiAgIH07CiAqICAgJHByb3ZpZGUuc2VydmljZSgncGluZycsIFBpbmcpOwogKiBgYGAKICogWW91IHdvdWxkIHRoZW4gaW5qZWN0IGFuZCB1c2UgdGhpcyBzZXJ2aWNlIGxpa2UgdGhpczoKICogYGBganMKICogICBzb21lTW9kdWxlLmNvbnRyb2xsZXIoJ0N0cmwnLCBbJ3BpbmcnLCBmdW5jdGlvbihwaW5nKSB7CiAqICAgICBwaW5nLnNlbmQoKTsKICogICB9XSk7CiAqIGBgYAogKi8KCgovKioKICogQG5nZG9jIG1ldGhvZAogKiBAbmFtZSAkcHJvdmlkZSN2YWx1ZQogKiBAZGVzY3JpcHRpb24KICoKICogUmVnaXN0ZXIgYSAqKnZhbHVlIHNlcnZpY2UqKiB3aXRoIHRoZSB7QGxpbmsgYXV0by4kaW5qZWN0b3IgJGluamVjdG9yfSwgc3VjaCBhcyBhIHN0cmluZywgYQogKiBudW1iZXIsIGFuIGFycmF5LCBhbiBvYmplY3Qgb3IgYSBmdW5jdGlvbi4gIFRoaXMgaXMgc2hvcnQgZm9yIHJlZ2lzdGVyaW5nIGEgc2VydmljZSB3aGVyZSBpdHMKICogcHJvdmlkZXIncyBgJGdldGAgcHJvcGVydHkgaXMgYSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgdGFrZXMgbm8gYXJndW1lbnRzIGFuZCByZXR1cm5zIHRoZSAqKnZhbHVlCiAqIHNlcnZpY2UqKi4KICoKICogVmFsdWUgc2VydmljZXMgYXJlIHNpbWlsYXIgdG8gY29uc3RhbnQgc2VydmljZXMsIGV4Y2VwdCB0aGF0IHRoZXkgY2Fubm90IGJlIGluamVjdGVkIGludG8gYQogKiBtb2R1bGUgY29uZmlndXJhdGlvbiBmdW5jdGlvbiAoc2VlIHtAbGluayBhbmd1bGFyLk1vZHVsZSNjb25maWd9KSBidXQgdGhleSBjYW4gYmUgb3ZlcnJpZGRlbiBieQogKiBhbiBBbmd1bGFyCiAqIHtAbGluayBhdXRvLiRwcm92aWRlI2RlY29yYXRvciBkZWNvcmF0b3J9LgogKgogKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgaW5zdGFuY2UuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLgogKiBAcmV0dXJucyB7T2JqZWN0fSByZWdpc3RlcmVkIHByb3ZpZGVyIGluc3RhbmNlCiAqCiAqIEBleGFtcGxlCiAqIEhlcmUgYXJlIHNvbWUgZXhhbXBsZXMgb2YgY3JlYXRpbmcgdmFsdWUgc2VydmljZXMuCiAqIGBgYGpzCiAqICAgJHByb3ZpZGUudmFsdWUoJ0FETUlOX1VTRVInLCAnYWRtaW4nKTsKICoKICogICAkcHJvdmlkZS52YWx1ZSgnUm9sZUxvb2t1cCcsIHsgYWRtaW46IDAsIHdyaXRlcjogMSwgcmVhZGVyOiAyIH0pOwogKgogKiAgICRwcm92aWRlLnZhbHVlKCdoYWxmT2YnLCBmdW5jdGlvbih2YWx1ZSkgewogKiAgICAgcmV0dXJuIHZhbHVlIC8gMjsKICogICB9KTsKICogYGBgCiAqLwoKCi8qKgogKiBAbmdkb2MgbWV0aG9kCiAqIEBuYW1lICRwcm92aWRlI2NvbnN0YW50CiAqIEBkZXNjcmlwdGlvbgogKgogKiBSZWdpc3RlciBhICoqY29uc3RhbnQgc2VydmljZSoqLCBzdWNoIGFzIGEgc3RyaW5nLCBhIG51bWJlciwgYW4gYXJyYXksIGFuIG9iamVjdCBvciBhIGZ1bmN0aW9uLAogKiB3aXRoIHRoZSB7QGxpbmsgYXV0by4kaW5qZWN0b3IgJGluamVjdG9yfS4gVW5saWtlIHtAbGluayBhdXRvLiRwcm92aWRlI3ZhbHVlIHZhbHVlfSBpdCBjYW4gYmUKICogaW5qZWN0ZWQgaW50byBhIG1vZHVsZSBjb25maWd1cmF0aW9uIGZ1bmN0aW9uIChzZWUge0BsaW5rIGFuZ3VsYXIuTW9kdWxlI2NvbmZpZ30pIGFuZCBpdCBjYW5ub3QKICogYmUgb3ZlcnJpZGRlbiBieSBhbiBBbmd1bGFyIHtAbGluayBhdXRvLiRwcm92aWRlI2RlY29yYXRvciBkZWNvcmF0b3J9LgogKgogKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY29uc3RhbnQuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIGNvbnN0YW50IHZhbHVlLgogKiBAcmV0dXJucyB7T2JqZWN0fSByZWdpc3RlcmVkIGluc3RhbmNlCiAqCiAqIEBleGFtcGxlCiAqIEhlcmUgYSBzb21lIGV4YW1wbGVzIG9mIGNyZWF0aW5nIGNvbnN0YW50czoKICogYGBganMKICogICAkcHJvdmlkZS5jb25zdGFudCgnU0hBUkRfSEVJR0hUJywgMzA2KTsKICoKICogICAkcHJvdmlkZS5jb25zdGFudCgnTVlfQ09MT1VSUycsIFsncmVkJywgJ2JsdWUnLCAnZ3JleSddKTsKICoKICogICAkcHJvdmlkZS5jb25zdGFudCgnZG91YmxlJywgZnVuY3Rpb24odmFsdWUpIHsKICogICAgIHJldHVybiB2YWx1ZSAqIDI7CiAqICAgfSk7CiAqIGBgYAogKi8KCgovKioKICogQG5nZG9jIG1ldGhvZAogKiBAbmFtZSAkcHJvdmlkZSNkZWNvcmF0b3IKICogQGRlc2NyaXB0aW9uCiAqCiAqIFJlZ2lzdGVyIGEgKipzZXJ2aWNlIGRlY29yYXRvcioqIHdpdGggdGhlIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LiBBIHNlcnZpY2UgZGVjb3JhdG9yCiAqIGludGVyY2VwdHMgdGhlIGNyZWF0aW9uIG9mIGEgc2VydmljZSwgYWxsb3dpbmcgaXQgdG8gb3ZlcnJpZGUgb3IgbW9kaWZ5IHRoZSBiZWhhdmlvdXIgb2YgdGhlCiAqIHNlcnZpY2UuIFRoZSBvYmplY3QgcmV0dXJuZWQgYnkgdGhlIGRlY29yYXRvciBtYXkgYmUgdGhlIG9yaWdpbmFsIHNlcnZpY2UsIG9yIGEgbmV3IHNlcnZpY2UKICogb2JqZWN0IHdoaWNoIHJlcGxhY2VzIG9yIHdyYXBzIGFuZCBkZWxlZ2F0ZXMgdG8gdGhlIG9yaWdpbmFsIHNlcnZpY2UuCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIHRvIGRlY29yYXRlLgogKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGRlY29yYXRvciBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgaW52b2tlZCB3aGVuIHRoZSBzZXJ2aWNlIG5lZWRzIHRvIGJlCiAqICAgIGluc3RhbnRpYXRlZCBhbmQgc2hvdWxkIHJldHVybiB0aGUgZGVjb3JhdGVkIHNlcnZpY2UgaW5zdGFuY2UuIFRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgdXNpbmcKICogICAgdGhlIHtAbGluayBhdXRvLiRpbmplY3RvciNpbnZva2UgaW5qZWN0b3IuaW52b2tlfSBtZXRob2QgYW5kIGlzIHRoZXJlZm9yZSBmdWxseSBpbmplY3RhYmxlLgogKiAgICBMb2NhbCBpbmplY3Rpb24gYXJndW1lbnRzOgogKgogKiAgICAqIGAkZGVsZWdhdGVgIC0gVGhlIG9yaWdpbmFsIHNlcnZpY2UgaW5zdGFuY2UsIHdoaWNoIGNhbiBiZSBtb25rZXkgcGF0Y2hlZCwgY29uZmlndXJlZCwKICogICAgICBkZWNvcmF0ZWQgb3IgZGVsZWdhdGVkIHRvLgogKgogKiBAZXhhbXBsZQogKiBIZXJlIHdlIGRlY29yYXRlIHRoZSB7QGxpbmsgbmcuJGxvZyAkbG9nfSBzZXJ2aWNlIHRvIGNvbnZlcnQgd2FybmluZ3MgdG8gZXJyb3JzIGJ5IGludGVyY2VwdGluZwogKiBjYWxscyB0byB7QGxpbmsgbmcuJGxvZyNlcnJvciAkbG9nLndhcm4oKX0uCiAqIGBgYGpzCiAqICAgJHByb3ZpZGUuZGVjb3JhdG9yKCckbG9nJywgWyckZGVsZWdhdGUnLCBmdW5jdGlvbigkZGVsZWdhdGUpIHsKICogICAgICRkZWxlZ2F0ZS53YXJuID0gJGRlbGVnYXRlLmVycm9yOwogKiAgICAgcmV0dXJuICRkZWxlZ2F0ZTsKICogICB9XSk7CiAqIGBgYAogKi8KCgpmdW5jdGlvbiBjcmVhdGVJbmplY3Rvcihtb2R1bGVzVG9Mb2FkLCBzdHJpY3REaSkgewogIHN0cmljdERpID0gKHN0cmljdERpID09PSB0cnVlKTsKICB2YXIgSU5TVEFOVElBVElORyA9IHt9LAogICAgICBwcm92aWRlclN1ZmZpeCA9ICdQcm92aWRlcicsCiAgICAgIHBhdGggPSBbXSwKICAgICAgbG9hZGVkTW9kdWxlcyA9IG5ldyBIYXNoTWFwKFtdLCB0cnVlKSwKICAgICAgcHJvdmlkZXJDYWNoZSA9IHsKICAgICAgICAkcHJvdmlkZTogewogICAgICAgICAgICBwcm92aWRlcjogc3VwcG9ydE9iamVjdChwcm92aWRlciksCiAgICAgICAgICAgIGZhY3Rvcnk6IHN1cHBvcnRPYmplY3QoZmFjdG9yeSksCiAgICAgICAgICAgIHNlcnZpY2U6IHN1cHBvcnRPYmplY3Qoc2VydmljZSksCiAgICAgICAgICAgIHZhbHVlOiBzdXBwb3J0T2JqZWN0KHZhbHVlKSwKICAgICAgICAgICAgY29uc3RhbnQ6IHN1cHBvcnRPYmplY3QoY29uc3RhbnQpLAogICAgICAgICAgICBkZWNvcmF0b3I6IGRlY29yYXRvcgogICAgICAgICAgfQogICAgICB9LAogICAgICBwcm92aWRlckluamVjdG9yID0gKHByb3ZpZGVyQ2FjaGUuJGluamVjdG9yID0KICAgICAgICAgIGNyZWF0ZUludGVybmFsSW5qZWN0b3IocHJvdmlkZXJDYWNoZSwgZnVuY3Rpb24oc2VydmljZU5hbWUsIGNhbGxlcikgewogICAgICAgICAgICBpZiAoYW5ndWxhci5pc1N0cmluZyhjYWxsZXIpKSB7CiAgICAgICAgICAgICAgcGF0aC5wdXNoKGNhbGxlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgJGluamVjdG9yTWluRXJyKCd1bnByJywgIlVua25vd24gcHJvdmlkZXI6IHswfSIsIHBhdGguam9pbignIDwtICcpKTsKICAgICAgICAgIH0pKSwKICAgICAgaW5zdGFuY2VDYWNoZSA9IHt9LAogICAgICBpbnN0YW5jZUluamVjdG9yID0gKGluc3RhbmNlQ2FjaGUuJGluamVjdG9yID0KICAgICAgICAgIGNyZWF0ZUludGVybmFsSW5qZWN0b3IoaW5zdGFuY2VDYWNoZSwgZnVuY3Rpb24oc2VydmljZU5hbWUsIGNhbGxlcikgewogICAgICAgICAgICB2YXIgcHJvdmlkZXIgPSBwcm92aWRlckluamVjdG9yLmdldChzZXJ2aWNlTmFtZSArIHByb3ZpZGVyU3VmZml4LCBjYWxsZXIpOwogICAgICAgICAgICByZXR1cm4gaW5zdGFuY2VJbmplY3Rvci5pbnZva2UocHJvdmlkZXIuJGdldCwgcHJvdmlkZXIsIHVuZGVmaW5lZCwgc2VydmljZU5hbWUpOwogICAgICAgICAgfSkpOwoKCiAgZm9yRWFjaChsb2FkTW9kdWxlcyhtb2R1bGVzVG9Mb2FkKSwgZnVuY3Rpb24oZm4pIHsgaW5zdGFuY2VJbmplY3Rvci5pbnZva2UoZm4gfHwgbm9vcCk7IH0pOwoKICByZXR1cm4gaW5zdGFuY2VJbmplY3RvcjsKCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgLy8gJHByb3ZpZGVyCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgogIGZ1bmN0aW9uIHN1cHBvcnRPYmplY3QoZGVsZWdhdGUpIHsKICAgIHJldHVybiBmdW5jdGlvbihrZXksIHZhbHVlKSB7CiAgICAgIGlmIChpc09iamVjdChrZXkpKSB7CiAgICAgICAgZm9yRWFjaChrZXksIHJldmVyc2VQYXJhbXMoZGVsZWdhdGUpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZGVsZWdhdGUoa2V5LCB2YWx1ZSk7CiAgICAgIH0KICAgIH07CiAgfQoKICBmdW5jdGlvbiBwcm92aWRlcihuYW1lLCBwcm92aWRlcl8pIHsKICAgIGFzc2VydE5vdEhhc093blByb3BlcnR5KG5hbWUsICdzZXJ2aWNlJyk7CiAgICBpZiAoaXNGdW5jdGlvbihwcm92aWRlcl8pIHx8IGlzQXJyYXkocHJvdmlkZXJfKSkgewogICAgICBwcm92aWRlcl8gPSBwcm92aWRlckluamVjdG9yLmluc3RhbnRpYXRlKHByb3ZpZGVyXyk7CiAgICB9CiAgICBpZiAoIXByb3ZpZGVyXy4kZ2V0KSB7CiAgICAgIHRocm93ICRpbmplY3Rvck1pbkVycigncGdldCcsICJQcm92aWRlciAnezB9JyBtdXN0IGRlZmluZSAkZ2V0IGZhY3RvcnkgbWV0aG9kLiIsIG5hbWUpOwogICAgfQogICAgcmV0dXJuIHByb3ZpZGVyQ2FjaGVbbmFtZSArIHByb3ZpZGVyU3VmZml4XSA9IHByb3ZpZGVyXzsKICB9CgogIGZ1bmN0aW9uIGVuZm9yY2VSZXR1cm5WYWx1ZShuYW1lLCBmYWN0b3J5KSB7CiAgICByZXR1cm4gZnVuY3Rpb24gZW5mb3JjZWRSZXR1cm5WYWx1ZSgpIHsKICAgICAgdmFyIHJlc3VsdCA9IGluc3RhbmNlSW5qZWN0b3IuaW52b2tlKGZhY3RvcnksIHRoaXMpOwogICAgICBpZiAoaXNVbmRlZmluZWQocmVzdWx0KSkgewogICAgICAgIHRocm93ICRpbmplY3Rvck1pbkVycigndW5kZWYnLCAiUHJvdmlkZXIgJ3swfScgbXVzdCByZXR1cm4gYSB2YWx1ZSBmcm9tICRnZXQgZmFjdG9yeSBtZXRob2QuIiwgbmFtZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH07CiAgfQoKICBmdW5jdGlvbiBmYWN0b3J5KG5hbWUsIGZhY3RvcnlGbiwgZW5mb3JjZSkgewogICAgcmV0dXJuIHByb3ZpZGVyKG5hbWUsIHsKICAgICAgJGdldDogZW5mb3JjZSAhPT0gZmFsc2UgPyBlbmZvcmNlUmV0dXJuVmFsdWUobmFtZSwgZmFjdG9yeUZuKSA6IGZhY3RvcnlGbgogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBzZXJ2aWNlKG5hbWUsIGNvbnN0cnVjdG9yKSB7CiAgICByZXR1cm4gZmFjdG9yeShuYW1lLCBbJyRpbmplY3RvcicsIGZ1bmN0aW9uKCRpbmplY3RvcikgewogICAgICByZXR1cm4gJGluamVjdG9yLmluc3RhbnRpYXRlKGNvbnN0cnVjdG9yKTsKICAgIH1dKTsKICB9CgogIGZ1bmN0aW9uIHZhbHVlKG5hbWUsIHZhbCkgeyByZXR1cm4gZmFjdG9yeShuYW1lLCB2YWx1ZUZuKHZhbCksIGZhbHNlKTsgfQoKICBmdW5jdGlvbiBjb25zdGFudChuYW1lLCB2YWx1ZSkgewogICAgYXNzZXJ0Tm90SGFzT3duUHJvcGVydHkobmFtZSwgJ2NvbnN0YW50Jyk7CiAgICBwcm92aWRlckNhY2hlW25hbWVdID0gdmFsdWU7CiAgICBpbnN0YW5jZUNhY2hlW25hbWVdID0gdmFsdWU7CiAgfQoKICBmdW5jdGlvbiBkZWNvcmF0b3Ioc2VydmljZU5hbWUsIGRlY29yRm4pIHsKICAgIHZhciBvcmlnUHJvdmlkZXIgPSBwcm92aWRlckluamVjdG9yLmdldChzZXJ2aWNlTmFtZSArIHByb3ZpZGVyU3VmZml4KSwKICAgICAgICBvcmlnJGdldCA9IG9yaWdQcm92aWRlci4kZ2V0OwoKICAgIG9yaWdQcm92aWRlci4kZ2V0ID0gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBvcmlnSW5zdGFuY2UgPSBpbnN0YW5jZUluamVjdG9yLmludm9rZShvcmlnJGdldCwgb3JpZ1Byb3ZpZGVyKTsKICAgICAgcmV0dXJuIGluc3RhbmNlSW5qZWN0b3IuaW52b2tlKGRlY29yRm4sIG51bGwsIHskZGVsZWdhdGU6IG9yaWdJbnN0YW5jZX0pOwogICAgfTsKICB9CgogIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogIC8vIE1vZHVsZSBMb2FkaW5nCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgZnVuY3Rpb24gbG9hZE1vZHVsZXMobW9kdWxlc1RvTG9hZCkgewogICAgdmFyIHJ1bkJsb2NrcyA9IFtdLCBtb2R1bGVGbjsKICAgIGZvckVhY2gobW9kdWxlc1RvTG9hZCwgZnVuY3Rpb24obW9kdWxlKSB7CiAgICAgIGlmIChsb2FkZWRNb2R1bGVzLmdldChtb2R1bGUpKSByZXR1cm47CiAgICAgIGxvYWRlZE1vZHVsZXMucHV0KG1vZHVsZSwgdHJ1ZSk7CgogICAgICBmdW5jdGlvbiBydW5JbnZva2VRdWV1ZShxdWV1ZSkgewogICAgICAgIHZhciBpLCBpaTsKICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IHF1ZXVlLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgIHZhciBpbnZva2VBcmdzID0gcXVldWVbaV0sCiAgICAgICAgICAgICAgcHJvdmlkZXIgPSBwcm92aWRlckluamVjdG9yLmdldChpbnZva2VBcmdzWzBdKTsKCiAgICAgICAgICBwcm92aWRlcltpbnZva2VBcmdzWzFdXS5hcHBseShwcm92aWRlciwgaW52b2tlQXJnc1syXSk7CiAgICAgICAgfQogICAgICB9CgogICAgICB0cnkgewogICAgICAgIGlmIChpc1N0cmluZyhtb2R1bGUpKSB7CiAgICAgICAgICBtb2R1bGVGbiA9IGFuZ3VsYXJNb2R1bGUobW9kdWxlKTsKICAgICAgICAgIHJ1bkJsb2NrcyA9IHJ1bkJsb2Nrcy5jb25jYXQobG9hZE1vZHVsZXMobW9kdWxlRm4ucmVxdWlyZXMpKS5jb25jYXQobW9kdWxlRm4uX3J1bkJsb2Nrcyk7CiAgICAgICAgICBydW5JbnZva2VRdWV1ZShtb2R1bGVGbi5faW52b2tlUXVldWUpOwogICAgICAgICAgcnVuSW52b2tlUXVldWUobW9kdWxlRm4uX2NvbmZpZ0Jsb2Nrcyk7CiAgICAgICAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKG1vZHVsZSkpIHsKICAgICAgICAgICAgcnVuQmxvY2tzLnB1c2gocHJvdmlkZXJJbmplY3Rvci5pbnZva2UobW9kdWxlKSk7CiAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KG1vZHVsZSkpIHsKICAgICAgICAgICAgcnVuQmxvY2tzLnB1c2gocHJvdmlkZXJJbmplY3Rvci5pbnZva2UobW9kdWxlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFzc2VydEFyZ0ZuKG1vZHVsZSwgJ21vZHVsZScpOwogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIGlmIChpc0FycmF5KG1vZHVsZSkpIHsKICAgICAgICAgIG1vZHVsZSA9IG1vZHVsZVttb2R1bGUubGVuZ3RoIC0gMV07CiAgICAgICAgfQogICAgICAgIGlmIChlLm1lc3NhZ2UgJiYgZS5zdGFjayAmJiBlLnN0YWNrLmluZGV4T2YoZS5tZXNzYWdlKSA9PSAtMSkgewogICAgICAgICAgLy8gU2FmYXJpICYgRkYncyBzdGFjayB0cmFjZXMgZG9uJ3QgY29udGFpbiBlcnJvci5tZXNzYWdlIGNvbnRlbnQKICAgICAgICAgIC8vIHVubGlrZSB0aG9zZSBvZiBDaHJvbWUgYW5kIElFCiAgICAgICAgICAvLyBTbyBpZiBzdGFjayBkb2Vzbid0IGNvbnRhaW4gbWVzc2FnZSwgd2UgY3JlYXRlIGEgbmV3IHN0cmluZyB0aGF0IGNvbnRhaW5zIGJvdGguCiAgICAgICAgICAvLyBTaW5jZSBlcnJvci5zdGFjayBpcyByZWFkLW9ubHkgaW4gU2FmYXJpLCBJJ20gb3ZlcnJpZGluZyBlIGFuZCBub3QgZS5zdGFjayBoZXJlLgogICAgICAgICAgLyoganNoaW50IC1XMDIyICovCiAgICAgICAgICBlID0gZS5tZXNzYWdlICsgJ1xuJyArIGUuc3RhY2s7CiAgICAgICAgfQogICAgICAgIHRocm93ICRpbmplY3Rvck1pbkVycignbW9kdWxlcnInLCAiRmFpbGVkIHRvIGluc3RhbnRpYXRlIG1vZHVsZSB7MH0gZHVlIHRvOlxuezF9IiwKICAgICAgICAgICAgICAgICAgbW9kdWxlLCBlLnN0YWNrIHx8IGUubWVzc2FnZSB8fCBlKTsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gcnVuQmxvY2tzOwogIH0KCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgLy8gaW50ZXJuYWwgSW5qZWN0b3IKICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiAgZnVuY3Rpb24gY3JlYXRlSW50ZXJuYWxJbmplY3RvcihjYWNoZSwgZmFjdG9yeSkgewoKICAgIGZ1bmN0aW9uIGdldFNlcnZpY2Uoc2VydmljZU5hbWUsIGNhbGxlcikgewogICAgICBpZiAoY2FjaGUuaGFzT3duUHJvcGVydHkoc2VydmljZU5hbWUpKSB7CiAgICAgICAgaWYgKGNhY2hlW3NlcnZpY2VOYW1lXSA9PT0gSU5TVEFOVElBVElORykgewogICAgICAgICAgdGhyb3cgJGluamVjdG9yTWluRXJyKCdjZGVwJywgJ0NpcmN1bGFyIGRlcGVuZGVuY3kgZm91bmQ6IHswfScsCiAgICAgICAgICAgICAgICAgICAgc2VydmljZU5hbWUgKyAnIDwtICcgKyBwYXRoLmpvaW4oJyA8LSAnKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjYWNoZVtzZXJ2aWNlTmFtZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHBhdGgudW5zaGlmdChzZXJ2aWNlTmFtZSk7CiAgICAgICAgICBjYWNoZVtzZXJ2aWNlTmFtZV0gPSBJTlNUQU5USUFUSU5HOwogICAgICAgICAgcmV0dXJuIGNhY2hlW3NlcnZpY2VOYW1lXSA9IGZhY3Rvcnkoc2VydmljZU5hbWUsIGNhbGxlcik7CiAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICBpZiAoY2FjaGVbc2VydmljZU5hbWVdID09PSBJTlNUQU5USUFUSU5HKSB7CiAgICAgICAgICAgIGRlbGV0ZSBjYWNoZVtzZXJ2aWNlTmFtZV07CiAgICAgICAgICB9CiAgICAgICAgICB0aHJvdyBlcnI7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIHBhdGguc2hpZnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpbnZva2UoZm4sIHNlbGYsIGxvY2Fscywgc2VydmljZU5hbWUpIHsKICAgICAgaWYgKHR5cGVvZiBsb2NhbHMgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgc2VydmljZU5hbWUgPSBsb2NhbHM7CiAgICAgICAgbG9jYWxzID0gbnVsbDsKICAgICAgfQoKICAgICAgdmFyIGFyZ3MgPSBbXSwKICAgICAgICAgICRpbmplY3QgPSBhbm5vdGF0ZShmbiwgc3RyaWN0RGksIHNlcnZpY2VOYW1lKSwKICAgICAgICAgIGxlbmd0aCwgaSwKICAgICAgICAgIGtleTsKCiAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9ICRpbmplY3QubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICBrZXkgPSAkaW5qZWN0W2ldOwogICAgICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJykgewogICAgICAgICAgdGhyb3cgJGluamVjdG9yTWluRXJyKCdpdGtuJywKICAgICAgICAgICAgICAgICAgJ0luY29ycmVjdCBpbmplY3Rpb24gdG9rZW4hIEV4cGVjdGVkIHNlcnZpY2UgbmFtZSBhcyBzdHJpbmcsIGdvdCB7MH0nLCBrZXkpOwogICAgICAgIH0KICAgICAgICBhcmdzLnB1c2goCiAgICAgICAgICBsb2NhbHMgJiYgbG9jYWxzLmhhc093blByb3BlcnR5KGtleSkKICAgICAgICAgID8gbG9jYWxzW2tleV0KICAgICAgICAgIDogZ2V0U2VydmljZShrZXksIHNlcnZpY2VOYW1lKQogICAgICAgICk7CiAgICAgIH0KICAgICAgaWYgKGlzQXJyYXkoZm4pKSB7CiAgICAgICAgZm4gPSBmbltsZW5ndGhdOwogICAgICB9CgogICAgICAvLyBodHRwOi8vanNwZXJmLmNvbS9hbmd1bGFyanMtaW52b2tlLWFwcGx5LXZzLXN3aXRjaAogICAgICAvLyAjNTM4OAogICAgICByZXR1cm4gZm4uYXBwbHkoc2VsZiwgYXJncyk7CiAgICB9CgogICAgZnVuY3Rpb24gaW5zdGFudGlhdGUoVHlwZSwgbG9jYWxzLCBzZXJ2aWNlTmFtZSkgewogICAgICAvLyBDaGVjayBpZiBUeXBlIGlzIGFubm90YXRlZCBhbmQgdXNlIGp1c3QgdGhlIGdpdmVuIGZ1bmN0aW9uIGF0IG4tMSBhcyBwYXJhbWV0ZXIKICAgICAgLy8gZS5nLiBzb21lTW9kdWxlLmZhY3RvcnkoJ2dyZWV0ZXInLCBbJyR3aW5kb3cnLCBmdW5jdGlvbihyZW5hbWVkJHdpbmRvdykge31dKTsKICAgICAgLy8gT2JqZWN0IGNyZWF0aW9uOiBodHRwOi8vanNwZXJmLmNvbS9jcmVhdGUtY29uc3RydWN0b3IvMgogICAgICB2YXIgaW5zdGFuY2UgPSBPYmplY3QuY3JlYXRlKChpc0FycmF5KFR5cGUpID8gVHlwZVtUeXBlLmxlbmd0aCAtIDFdIDogVHlwZSkucHJvdG90eXBlKTsKICAgICAgdmFyIHJldHVybmVkVmFsdWUgPSBpbnZva2UoVHlwZSwgaW5zdGFuY2UsIGxvY2Fscywgc2VydmljZU5hbWUpOwoKICAgICAgcmV0dXJuIGlzT2JqZWN0KHJldHVybmVkVmFsdWUpIHx8IGlzRnVuY3Rpb24ocmV0dXJuZWRWYWx1ZSkgPyByZXR1cm5lZFZhbHVlIDogaW5zdGFuY2U7CiAgICB9CgogICAgcmV0dXJuIHsKICAgICAgaW52b2tlOiBpbnZva2UsCiAgICAgIGluc3RhbnRpYXRlOiBpbnN0YW50aWF0ZSwKICAgICAgZ2V0OiBnZXRTZXJ2aWNlLAogICAgICBhbm5vdGF0ZTogYW5ub3RhdGUsCiAgICAgIGhhczogZnVuY3Rpb24obmFtZSkgewogICAgICAgIHJldHVybiBwcm92aWRlckNhY2hlLmhhc093blByb3BlcnR5KG5hbWUgKyBwcm92aWRlclN1ZmZpeCkgfHwgY2FjaGUuaGFzT3duUHJvcGVydHkobmFtZSk7CiAgICAgIH0KICAgIH07CiAgfQp9CgpjcmVhdGVJbmplY3Rvci4kJGFubm90YXRlID0gYW5ub3RhdGU7CgovKioKICogQG5nZG9jIHByb3ZpZGVyCiAqIEBuYW1lICRhbmNob3JTY3JvbGxQcm92aWRlcgogKgogKiBAZGVzY3JpcHRpb24KICogVXNlIGAkYW5jaG9yU2Nyb2xsUHJvdmlkZXJgIHRvIGRpc2FibGUgYXV0b21hdGljIHNjcm9sbGluZyB3aGVuZXZlcgogKiB7QGxpbmsgbmcuJGxvY2F0aW9uI2hhc2ggJGxvY2F0aW9uLmhhc2goKX0gY2hhbmdlcy4KICovCmZ1bmN0aW9uICRBbmNob3JTY3JvbGxQcm92aWRlcigpIHsKCiAgdmFyIGF1dG9TY3JvbGxpbmdFbmFibGVkID0gdHJ1ZTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRhbmNob3JTY3JvbGxQcm92aWRlciNkaXNhYmxlQXV0b1Njcm9sbGluZwogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQnkgZGVmYXVsdCwge0BsaW5rIG5nLiRhbmNob3JTY3JvbGwgJGFuY2hvclNjcm9sbCgpfSB3aWxsIGF1dG9tYXRpY2FsbHkgZGV0ZWN0IGNoYW5nZXMgdG8KICAgKiB7QGxpbmsgbmcuJGxvY2F0aW9uI2hhc2ggJGxvY2F0aW9uLmhhc2goKX0gYW5kIHNjcm9sbCB0byB0aGUgZWxlbWVudCBtYXRjaGluZyB0aGUgbmV3IGhhc2guPGJyIC8+CiAgICogVXNlIHRoaXMgbWV0aG9kIHRvIGRpc2FibGUgYXV0b21hdGljIHNjcm9sbGluZy4KICAgKgogICAqIElmIGF1dG9tYXRpYyBzY3JvbGxpbmcgaXMgZGlzYWJsZWQsIG9uZSBtdXN0IGV4cGxpY2l0bHkgY2FsbAogICAqIHtAbGluayBuZy4kYW5jaG9yU2Nyb2xsICRhbmNob3JTY3JvbGwoKX0gaW4gb3JkZXIgdG8gc2Nyb2xsIHRvIHRoZSBlbGVtZW50IHJlbGF0ZWQgdG8gdGhlCiAgICogY3VycmVudCBoYXNoLgogICAqLwogIHRoaXMuZGlzYWJsZUF1dG9TY3JvbGxpbmcgPSBmdW5jdGlvbigpIHsKICAgIGF1dG9TY3JvbGxpbmdFbmFibGVkID0gZmFsc2U7CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIHNlcnZpY2UKICAgKiBAbmFtZSAkYW5jaG9yU2Nyb2xsCiAgICogQGtpbmQgZnVuY3Rpb24KICAgKiBAcmVxdWlyZXMgJHdpbmRvdwogICAqIEByZXF1aXJlcyAkbG9jYXRpb24KICAgKiBAcmVxdWlyZXMgJHJvb3RTY29wZQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogV2hlbiBjYWxsZWQsIGl0IGNoZWNrcyB0aGUgY3VycmVudCB2YWx1ZSBvZiB7QGxpbmsgbmcuJGxvY2F0aW9uI2hhc2ggJGxvY2F0aW9uLmhhc2goKX0gYW5kCiAgICogc2Nyb2xscyB0byB0aGUgcmVsYXRlZCBlbGVtZW50LCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIHNwZWNpZmllZCBpbiB0aGUKICAgKiBbSHRtbDUgc3BlY10oaHR0cDovL2Rldi53My5vcmcvaHRtbDUvc3BlYy9PdmVydmlldy5odG1sI3RoZS1pbmRpY2F0ZWQtcGFydC1vZi10aGUtZG9jdW1lbnQpLgogICAqCiAgICogSXQgYWxzbyB3YXRjaGVzIHRoZSB7QGxpbmsgbmcuJGxvY2F0aW9uI2hhc2ggJGxvY2F0aW9uLmhhc2goKX0gYW5kIGF1dG9tYXRpY2FsbHkgc2Nyb2xscyB0bwogICAqIG1hdGNoIGFueSBhbmNob3Igd2hlbmV2ZXIgaXQgY2hhbmdlcy4gVGhpcyBjYW4gYmUgZGlzYWJsZWQgYnkgY2FsbGluZwogICAqIHtAbGluayBuZy4kYW5jaG9yU2Nyb2xsUHJvdmlkZXIjZGlzYWJsZUF1dG9TY3JvbGxpbmcgJGFuY2hvclNjcm9sbFByb3ZpZGVyLmRpc2FibGVBdXRvU2Nyb2xsaW5nKCl9LgogICAqCiAgICogQWRkaXRpb25hbGx5LCB5b3UgY2FuIHVzZSBpdHMge0BsaW5rIG5nLiRhbmNob3JTY3JvbGwjeU9mZnNldCB5T2Zmc2V0fSBwcm9wZXJ0eSB0byBzcGVjaWZ5IGEKICAgKiB2ZXJ0aWNhbCBzY3JvbGwtb2Zmc2V0IChlaXRoZXIgZml4ZWQgb3IgZHluYW1pYykuCiAgICoKICAgKiBAcHJvcGVydHkgeyhudW1iZXJ8ZnVuY3Rpb258anFMaXRlKX0geU9mZnNldAogICAqIElmIHNldCwgc3BlY2lmaWVzIGEgdmVydGljYWwgc2Nyb2xsLW9mZnNldC4gVGhpcyBpcyBvZnRlbiB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgZml4ZWQKICAgKiBwb3NpdGlvbmVkIGVsZW1lbnRzIGF0IHRoZSB0b3Agb2YgdGhlIHBhZ2UsIHN1Y2ggYXMgbmF2YmFycywgaGVhZGVycyBldGMuCiAgICoKICAgKiBgeU9mZnNldGAgY2FuIGJlIHNwZWNpZmllZCBpbiB2YXJpb3VzIHdheXM6CiAgICogLSAqKm51bWJlcioqOiBBIGZpeGVkIG51bWJlciBvZiBwaXhlbHMgdG8gYmUgdXNlZCBhcyBvZmZzZXQuPGJyIC8+PGJyIC8+CiAgICogLSAqKmZ1bmN0aW9uKio6IEEgZ2V0dGVyIGZ1bmN0aW9uIGNhbGxlZCBldmVyeXRpbWUgYCRhbmNob3JTY3JvbGwoKWAgaXMgZXhlY3V0ZWQuIE11c3QgcmV0dXJuCiAgICogICBhIG51bWJlciByZXByZXNlbnRpbmcgdGhlIG9mZnNldCAoaW4gcGl4ZWxzKS48YnIgLz48YnIgLz4KICAgKiAtICoqanFMaXRlKio6IEEganFMaXRlL2pRdWVyeSBlbGVtZW50IHRvIGJlIHVzZWQgZm9yIHNwZWNpZnlpbmcgdGhlIG9mZnNldC4gVGhlIGRpc3RhbmNlIGZyb20KICAgKiAgIHRoZSB0b3Agb2YgdGhlIHBhZ2UgdG8gdGhlIGVsZW1lbnQncyBib3R0b20gd2lsbCBiZSB1c2VkIGFzIG9mZnNldC48YnIgLz4KICAgKiAgICoqTm90ZSoqOiBUaGUgZWxlbWVudCB3aWxsIGJlIHRha2VuIGludG8gYWNjb3VudCBvbmx5IGFzIGxvbmcgYXMgaXRzIGBwb3NpdGlvbmAgaXMgc2V0IHRvCiAgICogICBgZml4ZWRgLiBUaGlzIG9wdGlvbiBpcyB1c2VmdWwsIHdoZW4gZGVhbGluZyB3aXRoIHJlc3BvbnNpdmUgbmF2YmFycy9oZWFkZXJzIHRoYXQgYWRqdXN0CiAgICogICB0aGVpciBoZWlnaHQgYW5kL29yIHBvc2l0aW9uaW5nIGFjY29yZGluZyB0byB0aGUgdmlld3BvcnQncyBzaXplLgogICAqCiAgICogPGJyIC8+CiAgICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CiAgICogSW4gb3JkZXIgZm9yIGB5T2Zmc2V0YCB0byB3b3JrIHByb3Blcmx5LCBzY3JvbGxpbmcgc2hvdWxkIHRha2UgcGxhY2Ugb24gdGhlIGRvY3VtZW50J3Mgcm9vdCBhbmQKICAgKiBub3Qgc29tZSBjaGlsZCBlbGVtZW50LgogICAqIDwvZGl2PgogICAqCiAgICogQGV4YW1wbGUKICAgICA8ZXhhbXBsZSBtb2R1bGU9ImFuY2hvclNjcm9sbEV4YW1wbGUiPgogICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgIDxkaXYgaWQ9InNjcm9sbEFyZWEiIG5nLWNvbnRyb2xsZXI9IlNjcm9sbENvbnRyb2xsZXIiPgogICAgICAgICAgIDxhIG5nLWNsaWNrPSJnb3RvQm90dG9tKCkiPkdvIHRvIGJvdHRvbTwvYT4KICAgICAgICAgICA8YSBpZD0iYm90dG9tIj48L2E+IFlvdSdyZSBhdCB0aGUgYm90dG9tIQogICAgICAgICA8L2Rpdj4KICAgICAgIDwvZmlsZT4KICAgICAgIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+CiAgICAgICAgIGFuZ3VsYXIubW9kdWxlKCdhbmNob3JTY3JvbGxFeGFtcGxlJywgW10pCiAgICAgICAgICAgLmNvbnRyb2xsZXIoJ1Njcm9sbENvbnRyb2xsZXInLCBbJyRzY29wZScsICckbG9jYXRpb24nLCAnJGFuY2hvclNjcm9sbCcsCiAgICAgICAgICAgICBmdW5jdGlvbiAoJHNjb3BlLCAkbG9jYXRpb24sICRhbmNob3JTY3JvbGwpIHsKICAgICAgICAgICAgICAgJHNjb3BlLmdvdG9Cb3R0b20gPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIGxvY2F0aW9uLmhhc2ggdG8gdGhlIGlkIG9mCiAgICAgICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnQgeW91IHdpc2ggdG8gc2Nyb2xsIHRvLgogICAgICAgICAgICAgICAgICRsb2NhdGlvbi5oYXNoKCdib3R0b20nKTsKCiAgICAgICAgICAgICAgICAgLy8gY2FsbCAkYW5jaG9yU2Nyb2xsKCkKICAgICAgICAgICAgICAgICAkYW5jaG9yU2Nyb2xsKCk7CiAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICB9XSk7CiAgICAgICA8L2ZpbGU+CiAgICAgICA8ZmlsZSBuYW1lPSJzdHlsZS5jc3MiPgogICAgICAgICAjc2Nyb2xsQXJlYSB7CiAgICAgICAgICAgaGVpZ2h0OiAyODBweDsKICAgICAgICAgICBvdmVyZmxvdzogYXV0bzsKICAgICAgICAgfQoKICAgICAgICAgI2JvdHRvbSB7CiAgICAgICAgICAgZGlzcGxheTogYmxvY2s7CiAgICAgICAgICAgbWFyZ2luLXRvcDogMjAwMHB4OwogICAgICAgICB9CiAgICAgICA8L2ZpbGU+CiAgICAgPC9leGFtcGxlPgogICAqCiAgICogPGhyIC8+CiAgICogVGhlIGV4YW1wbGUgYmVsb3cgaWxsdXN0cmF0ZXMgdGhlIHVzZSBvZiBhIHZlcnRpY2FsIHNjcm9sbC1vZmZzZXQgKHNwZWNpZmllZCBhcyBhIGZpeGVkIHZhbHVlKS4KICAgKiBTZWUge0BsaW5rIG5nLiRhbmNob3JTY3JvbGwjeU9mZnNldCAkYW5jaG9yU2Nyb2xsLnlPZmZzZXR9IGZvciBtb3JlIGRldGFpbHMuCiAgICoKICAgKiBAZXhhbXBsZQogICAgIDxleGFtcGxlIG1vZHVsZT0iYW5jaG9yU2Nyb2xsT2Zmc2V0RXhhbXBsZSI+CiAgICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICAgPGRpdiBjbGFzcz0iZml4ZWQtaGVhZGVyIiBuZy1jb250cm9sbGVyPSJoZWFkZXJDdHJsIj4KICAgICAgICAgICA8YSBocmVmPSIiIG5nLWNsaWNrPSJnb3RvQW5jaG9yKHgpIiBuZy1yZXBlYXQ9InggaW4gWzEsMiwzLDQsNV0iPgogICAgICAgICAgICAgR28gdG8gYW5jaG9yIHt7eH19CiAgICAgICAgICAgPC9hPgogICAgICAgICA8L2Rpdj4KICAgICAgICAgPGRpdiBpZD0iYW5jaG9ye3t4fX0iIGNsYXNzPSJhbmNob3IiIG5nLXJlcGVhdD0ieCBpbiBbMSwyLDMsNCw1XSI+CiAgICAgICAgICAgQW5jaG9yIHt7eH19IG9mIDUKICAgICAgICAgPC9kaXY+CiAgICAgICA8L2ZpbGU+CiAgICAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICAgICBhbmd1bGFyLm1vZHVsZSgnYW5jaG9yU2Nyb2xsT2Zmc2V0RXhhbXBsZScsIFtdKQogICAgICAgICAgIC5ydW4oWyckYW5jaG9yU2Nyb2xsJywgZnVuY3Rpb24oJGFuY2hvclNjcm9sbCkgewogICAgICAgICAgICAgJGFuY2hvclNjcm9sbC55T2Zmc2V0ID0gNTA7ICAgLy8gYWx3YXlzIHNjcm9sbCBieSA1MCBleHRyYSBwaXhlbHMKICAgICAgICAgICB9XSkKICAgICAgICAgICAuY29udHJvbGxlcignaGVhZGVyQ3RybCcsIFsnJGFuY2hvclNjcm9sbCcsICckbG9jYXRpb24nLCAnJHNjb3BlJywKICAgICAgICAgICAgIGZ1bmN0aW9uICgkYW5jaG9yU2Nyb2xsLCAkbG9jYXRpb24sICRzY29wZSkgewogICAgICAgICAgICAgICAkc2NvcGUuZ290b0FuY2hvciA9IGZ1bmN0aW9uKHgpIHsKICAgICAgICAgICAgICAgICB2YXIgbmV3SGFzaCA9ICdhbmNob3InICsgeDsKICAgICAgICAgICAgICAgICBpZiAoJGxvY2F0aW9uLmhhc2goKSAhPT0gbmV3SGFzaCkgewogICAgICAgICAgICAgICAgICAgLy8gc2V0IHRoZSAkbG9jYXRpb24uaGFzaCB0byBgbmV3SGFzaGAgYW5kCiAgICAgICAgICAgICAgICAgICAvLyAkYW5jaG9yU2Nyb2xsIHdpbGwgYXV0b21hdGljYWxseSBzY3JvbGwgdG8gaXQKICAgICAgICAgICAgICAgICAgICRsb2NhdGlvbi5oYXNoKCdhbmNob3InICsgeCk7CiAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgJGFuY2hvclNjcm9sbCgpIGV4cGxpY2l0bHksCiAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSAkbG9jYXRpb24uaGFzaCBoYXNuJ3QgY2hhbmdlZAogICAgICAgICAgICAgICAgICAgJGFuY2hvclNjcm9sbCgpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgIH0KICAgICAgICAgICBdKTsKICAgICAgIDwvZmlsZT4KICAgICAgIDxmaWxlIG5hbWU9InN0eWxlLmNzcyI+CiAgICAgICAgIGJvZHkgewogICAgICAgICAgIHBhZGRpbmctdG9wOiA1MHB4OwogICAgICAgICB9CgogICAgICAgICAuYW5jaG9yIHsKICAgICAgICAgICBib3JkZXI6IDJweCBkYXNoZWQgRGFya09yY2hpZDsKICAgICAgICAgICBwYWRkaW5nOiAxMHB4IDEwcHggMjAwcHggMTBweDsKICAgICAgICAgfQoKICAgICAgICAgLmZpeGVkLWhlYWRlciB7CiAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjIpOwogICAgICAgICAgIGhlaWdodDogNTBweDsKICAgICAgICAgICBwb3NpdGlvbjogZml4ZWQ7CiAgICAgICAgICAgdG9wOiAwOyBsZWZ0OiAwOyByaWdodDogMDsKICAgICAgICAgfQoKICAgICAgICAgLmZpeGVkLWhlYWRlciA+IGEgewogICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgICAgICAgICBtYXJnaW46IDVweCAxNXB4OwogICAgICAgICB9CiAgICAgICA8L2ZpbGU+CiAgICAgPC9leGFtcGxlPgogICAqLwogIHRoaXMuJGdldCA9IFsnJHdpbmRvdycsICckbG9jYXRpb24nLCAnJHJvb3RTY29wZScsIGZ1bmN0aW9uKCR3aW5kb3csICRsb2NhdGlvbiwgJHJvb3RTY29wZSkgewogICAgdmFyIGRvY3VtZW50ID0gJHdpbmRvdy5kb2N1bWVudDsKCiAgICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IGZpcnN0IGFuY2hvciBmcm9tIGEgTm9kZUxpc3QKICAgIC8vICh1c2luZyBgQXJyYXkjc29tZSgpYCBpbnN0ZWFkIG9mIGBhbmd1bGFyI2ZvckVhY2goKWAgc2luY2UgaXQncyBtb3JlIHBlcmZvcm1hbnQKICAgIC8vICBhbmQgd29ya2luZyBpbiBhbGwgc3VwcG9ydGVkIGJyb3dzZXJzLikKICAgIGZ1bmN0aW9uIGdldEZpcnN0QW5jaG9yKGxpc3QpIHsKICAgICAgdmFyIHJlc3VsdCA9IG51bGw7CiAgICAgIEFycmF5LnByb3RvdHlwZS5zb21lLmNhbGwobGlzdCwgZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIGlmIChub2RlTmFtZV8oZWxlbWVudCkgPT09ICdhJykgewogICAgICAgICAgcmVzdWx0ID0gZWxlbWVudDsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0WU9mZnNldCgpIHsKCiAgICAgIHZhciBvZmZzZXQgPSBzY3JvbGwueU9mZnNldDsKCiAgICAgIGlmIChpc0Z1bmN0aW9uKG9mZnNldCkpIHsKICAgICAgICBvZmZzZXQgPSBvZmZzZXQoKTsKICAgICAgfSBlbHNlIGlmIChpc0VsZW1lbnQob2Zmc2V0KSkgewogICAgICAgIHZhciBlbGVtID0gb2Zmc2V0WzBdOwogICAgICAgIHZhciBzdHlsZSA9ICR3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKTsKICAgICAgICBpZiAoc3R5bGUucG9zaXRpb24gIT09ICdmaXhlZCcpIHsKICAgICAgICAgIG9mZnNldCA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmICghaXNOdW1iZXIob2Zmc2V0KSkgewogICAgICAgIG9mZnNldCA9IDA7CiAgICAgIH0KCiAgICAgIHJldHVybiBvZmZzZXQ7CiAgICB9CgogICAgZnVuY3Rpb24gc2Nyb2xsVG8oZWxlbSkgewogICAgICBpZiAoZWxlbSkgewogICAgICAgIGVsZW0uc2Nyb2xsSW50b1ZpZXcoKTsKCiAgICAgICAgdmFyIG9mZnNldCA9IGdldFlPZmZzZXQoKTsKCiAgICAgICAgaWYgKG9mZnNldCkgewogICAgICAgICAgLy8gYG9mZnNldGAgaXMgdGhlIG51bWJlciBvZiBwaXhlbHMgd2Ugc2hvdWxkIHNjcm9sbCBVUCBpbiBvcmRlciB0byBhbGlnbiBgZWxlbWAgcHJvcGVybHkuCiAgICAgICAgICAvLyBUaGlzIGlzIHRydWUgT05MWSBpZiB0aGUgY2FsbCB0byBgZWxlbS5zY3JvbGxJbnRvVmlldygpYCBpbml0aWFsbHkgYWxpZ25zIGBlbGVtYCBhdCB0aGUKICAgICAgICAgIC8vIHRvcCBvZiB0aGUgdmlld3BvcnQuCiAgICAgICAgICAvLwogICAgICAgICAgLy8gSUYgdGhlIG51bWJlciBvZiBwaXhlbHMgZnJvbSB0aGUgdG9wIG9mIGBlbGVtYCB0byB0aGUgZW5kIG9mIHRoZSBwYWdlJ3MgY29udGVudCBpcyBsZXNzCiAgICAgICAgICAvLyB0aGFuIHRoZSBoZWlnaHQgb2YgdGhlIHZpZXdwb3J0LCB0aGVuIGBlbGVtLnNjcm9sbEludG9WaWV3KClgIHdpbGwgYWxpZ24gdGhlIGBlbGVtYCBzb21lCiAgICAgICAgICAvLyB3YXkgZG93biB0aGUgcGFnZS4KICAgICAgICAgIC8vCiAgICAgICAgICAvLyBUaGlzIGlzIG9mdGVuIHRoZSBjYXNlIGZvciBlbGVtZW50cyBuZWFyIHRoZSBib3R0b20gb2YgdGhlIHBhZ2UuCiAgICAgICAgICAvLwogICAgICAgICAgLy8gSW4gc3VjaCBjYXNlcyB3ZSBkbyBub3QgbmVlZCB0byBzY3JvbGwgdGhlIHdob2xlIGBvZmZzZXRgIHVwLCBqdXN0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KICAgICAgICAgIC8vIHRoZSB0b3Agb2YgdGhlIGVsZW1lbnQgYW5kIHRoZSBvZmZzZXQsIHdoaWNoIGlzIGVub3VnaCB0byBhbGlnbiB0aGUgdG9wIG9mIGBlbGVtYCBhdCB0aGUKICAgICAgICAgIC8vIGRlc2lyZWQgcG9zaXRpb24uCiAgICAgICAgICB2YXIgZWxlbVRvcCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wOwogICAgICAgICAgJHdpbmRvdy5zY3JvbGxCeSgwLCBlbGVtVG9wIC0gb2Zmc2V0KTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgJHdpbmRvdy5zY3JvbGxUbygwLCAwKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHNjcm9sbCgpIHsKICAgICAgdmFyIGhhc2ggPSAkbG9jYXRpb24uaGFzaCgpLCBlbG07CgogICAgICAvLyBlbXB0eSBoYXNoLCBzY3JvbGwgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZQogICAgICBpZiAoIWhhc2gpIHNjcm9sbFRvKG51bGwpOwoKICAgICAgLy8gZWxlbWVudCB3aXRoIGdpdmVuIGlkCiAgICAgIGVsc2UgaWYgKChlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoKSkpIHNjcm9sbFRvKGVsbSk7CgogICAgICAvLyBmaXJzdCBhbmNob3Igd2l0aCBnaXZlbiBuYW1lIDotRAogICAgICBlbHNlIGlmICgoZWxtID0gZ2V0Rmlyc3RBbmNob3IoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUoaGFzaCkpKSkgc2Nyb2xsVG8oZWxtKTsKCiAgICAgIC8vIG5vIGVsZW1lbnQgYW5kIGhhc2ggPT0gJ3RvcCcsIHNjcm9sbCB0byB0aGUgdG9wIG9mIHRoZSBwYWdlCiAgICAgIGVsc2UgaWYgKGhhc2ggPT09ICd0b3AnKSBzY3JvbGxUbyhudWxsKTsKICAgIH0KCiAgICAvLyBkb2VzIG5vdCBzY3JvbGwgd2hlbiB1c2VyIGNsaWNrcyBvbiBhbmNob3IgbGluayB0aGF0IGlzIGN1cnJlbnRseSBvbgogICAgLy8gKG5vIHVybCBjaGFuZ2UsIG5vICRsb2NhdGlvbi5oYXNoKCkgY2hhbmdlKSwgYnJvd3NlciBuYXRpdmUgZG9lcyBzY3JvbGwKICAgIGlmIChhdXRvU2Nyb2xsaW5nRW5hYmxlZCkgewogICAgICAkcm9vdFNjb3BlLiR3YXRjaChmdW5jdGlvbiBhdXRvU2Nyb2xsV2F0Y2goKSB7cmV0dXJuICRsb2NhdGlvbi5oYXNoKCk7fSwKICAgICAgICBmdW5jdGlvbiBhdXRvU2Nyb2xsV2F0Y2hBY3Rpb24obmV3VmFsLCBvbGRWYWwpIHsKICAgICAgICAgIC8vIHNraXAgdGhlIGluaXRpYWwgc2Nyb2xsIGlmICRsb2NhdGlvbi5oYXNoIGlzIGVtcHR5CiAgICAgICAgICBpZiAobmV3VmFsID09PSBvbGRWYWwgJiYgbmV3VmFsID09PSAnJykgcmV0dXJuOwoKICAgICAgICAgIGpxTGl0ZURvY3VtZW50TG9hZGVkKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAkcm9vdFNjb3BlLiRldmFsQXN5bmMoc2Nyb2xsKTsKICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgfQoKICAgIHJldHVybiBzY3JvbGw7CiAgfV07Cn0KCnZhciAkYW5pbWF0ZU1pbkVyciA9IG1pbkVycignJGFuaW1hdGUnKTsKCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJGFuaW1hdGVQcm92aWRlcgogKgogKiBAZGVzY3JpcHRpb24KICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiAkYW5pbWF0ZSB0aGF0IGRvZXNuJ3QgcGVyZm9ybSBhbnkgYW5pbWF0aW9ucywgaW5zdGVhZCBqdXN0CiAqIHN5bmNocm9ub3VzbHkgcGVyZm9ybXMgRE9NCiAqIHVwZGF0ZXMgYW5kIGNhbGxzIGRvbmUoKSBjYWxsYmFja3MuCiAqCiAqIEluIG9yZGVyIHRvIGVuYWJsZSBhbmltYXRpb25zIHRoZSBuZ0FuaW1hdGUgbW9kdWxlIGhhcyB0byBiZSBsb2FkZWQuCiAqCiAqIFRvIHNlZSB0aGUgZnVuY3Rpb25hbCBpbXBsZW1lbnRhdGlvbiBjaGVjayBvdXQgc3JjL25nQW5pbWF0ZS9hbmltYXRlLmpzCiAqLwp2YXIgJEFuaW1hdGVQcm92aWRlciA9IFsnJHByb3ZpZGUnLCBmdW5jdGlvbigkcHJvdmlkZSkgewoKCiAgdGhpcy4kJHNlbGVjdG9ycyA9IHt9OwoKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRhbmltYXRlUHJvdmlkZXIjcmVnaXN0ZXIKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJlZ2lzdGVycyBhIG5ldyBpbmplY3RhYmxlIGFuaW1hdGlvbiBmYWN0b3J5IGZ1bmN0aW9uLiBUaGUgZmFjdG9yeSBmdW5jdGlvbiBwcm9kdWNlcyB0aGUKICAgKiBhbmltYXRpb24gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGNhbGxiYWNrIGZ1bmN0aW9ucyBmb3IgZWFjaCBldmVudCB0aGF0IGlzIGV4cGVjdGVkIHRvIGJlCiAgICogYW5pbWF0ZWQuCiAgICoKICAgKiAgICogYGV2ZW50Rm5gOiBgZnVuY3Rpb24oRWxlbWVudCwgZG9uZUZ1bmN0aW9uKWAgVGhlIGVsZW1lbnQgdG8gYW5pbWF0ZSwgdGhlIGBkb25lRnVuY3Rpb25gCiAgICogICBtdXN0IGJlIGNhbGxlZCBvbmNlIHRoZSBlbGVtZW50IGFuaW1hdGlvbiBpcyBjb21wbGV0ZS4gSWYgYSBmdW5jdGlvbiBpcyByZXR1cm5lZCB0aGVuIHRoZQogICAqICAgYW5pbWF0aW9uIHNlcnZpY2Ugd2lsbCB1c2UgdGhpcyBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGFuaW1hdGlvbiB3aGVuZXZlciBhIGNhbmNlbCBldmVudCBpcwogICAqICAgdHJpZ2dlcmVkLgogICAqCiAgICoKICAgKiBgYGBqcwogICAqICAgcmV0dXJuIHsKICAgICAqICAgICBldmVudEZuIDogZnVuY3Rpb24oZWxlbWVudCwgZG9uZSkgewogICAgICogICAgICAgLy9jb2RlIHRvIHJ1biB0aGUgYW5pbWF0aW9uCiAgICAgKiAgICAgICAvL29uY2UgY29tcGxldGUsIHRoZW4gcnVuIGRvbmUoKQogICAgICogICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNhbmNlbGxhdGlvbkZ1bmN0aW9uKCkgewogICAgICogICAgICAgICAvL2NvZGUgdG8gY2FuY2VsIHRoZSBhbmltYXRpb24KICAgICAqICAgICAgIH0KICAgICAqICAgICB9CiAgICAgKiAgIH0KICAgKiBgYGAKICAgKgogICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhbmltYXRpb24uCiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZmFjdG9yeSBUaGUgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgdG8gcmV0dXJuIHRoZSBhbmltYXRpb24KICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC4KICAgKi8KICB0aGlzLnJlZ2lzdGVyID0gZnVuY3Rpb24obmFtZSwgZmFjdG9yeSkgewogICAgdmFyIGtleSA9IG5hbWUgKyAnLWFuaW1hdGlvbic7CiAgICBpZiAobmFtZSAmJiBuYW1lLmNoYXJBdCgwKSAhPSAnLicpIHRocm93ICRhbmltYXRlTWluRXJyKCdub3Rjc2VsJywKICAgICAgICAiRXhwZWN0aW5nIGNsYXNzIHNlbGVjdG9yIHN0YXJ0aW5nIHdpdGggJy4nIGdvdCAnezB9Jy4iLCBuYW1lKTsKICAgIHRoaXMuJCRzZWxlY3RvcnNbbmFtZS5zdWJzdHIoMSldID0ga2V5OwogICAgJHByb3ZpZGUuZmFjdG9yeShrZXksIGZhY3RvcnkpOwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkYW5pbWF0ZVByb3ZpZGVyI2NsYXNzTmFtZUZpbHRlcgogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyBhbmQvb3IgcmV0dXJucyB0aGUgQ1NTIGNsYXNzIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IGlzIGNoZWNrZWQgd2hlbiBwZXJmb3JtaW5nCiAgICogYW4gYW5pbWF0aW9uLiBVcG9uIGJvb3RzdHJhcCB0aGUgY2xhc3NOYW1lRmlsdGVyIHZhbHVlIGlzIG5vdCBzZXQgYXQgYWxsIGFuZCB3aWxsCiAgICogdGhlcmVmb3JlIGVuYWJsZSAkYW5pbWF0ZSB0byBhdHRlbXB0IHRvIHBlcmZvcm0gYW4gYW5pbWF0aW9uIG9uIGFueSBlbGVtZW50LgogICAqIFdoZW4gc2V0dGluZyB0aGUgY2xhc3NOYW1lRmlsdGVyIHZhbHVlLCBhbmltYXRpb25zIHdpbGwgb25seSBiZSBwZXJmb3JtZWQgb24gZWxlbWVudHMKICAgKiB0aGF0IHN1Y2Nlc3NmdWxseSBtYXRjaCB0aGUgZmlsdGVyIGV4cHJlc3Npb24uIFRoaXMgaW4gdHVybiBjYW4gYm9vc3QgcGVyZm9ybWFuY2UKICAgKiBmb3IgbG93LXBvd2VyZWQgZGV2aWNlcyBhcyB3ZWxsIGFzIGFwcGxpY2F0aW9ucyBjb250YWluaW5nIGEgbG90IG9mIHN0cnVjdHVyYWwgb3BlcmF0aW9ucy4KICAgKiBAcGFyYW0ge1JlZ0V4cD19IGV4cHJlc3Npb24gVGhlIGNsYXNzTmFtZSBleHByZXNzaW9uIHdoaWNoIHdpbGwgYmUgY2hlY2tlZCBhZ2FpbnN0IGFsbCBhbmltYXRpb25zCiAgICogQHJldHVybiB7UmVnRXhwfSBUaGUgY3VycmVudCBDU1MgY2xhc3NOYW1lIGV4cHJlc3Npb24gdmFsdWUuIElmIG51bGwgdGhlbiB0aGVyZSBpcyBubyBleHByZXNzaW9uIHZhbHVlCiAgICovCiAgdGhpcy5jbGFzc05hbWVGaWx0ZXIgPSBmdW5jdGlvbihleHByZXNzaW9uKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgewogICAgICB0aGlzLiQkY2xhc3NOYW1lRmlsdGVyID0gKGV4cHJlc3Npb24gaW5zdGFuY2VvZiBSZWdFeHApID8gZXhwcmVzc2lvbiA6IG51bGw7CiAgICB9CiAgICByZXR1cm4gdGhpcy4kJGNsYXNzTmFtZUZpbHRlcjsKICB9OwoKICB0aGlzLiRnZXQgPSBbJyQkcScsICckJGFzeW5jQ2FsbGJhY2snLCAnJHJvb3RTY29wZScsIGZ1bmN0aW9uKCQkcSwgJCRhc3luY0NhbGxiYWNrLCAkcm9vdFNjb3BlKSB7CgogICAgdmFyIGN1cnJlbnREZWZlcjsKCiAgICBmdW5jdGlvbiBydW5BbmltYXRpb25Qb3N0RGlnZXN0KGZuKSB7CiAgICAgIHZhciBjYW5jZWxGbiwgZGVmZXIgPSAkJHEuZGVmZXIoKTsKICAgICAgZGVmZXIucHJvbWlzZS4kJGNhbmNlbEZuID0gZnVuY3Rpb24gbmdBbmltYXRlTWF5YmVDYW5jZWwoKSB7CiAgICAgICAgY2FuY2VsRm4gJiYgY2FuY2VsRm4oKTsKICAgICAgfTsKCiAgICAgICRyb290U2NvcGUuJCRwb3N0RGlnZXN0KGZ1bmN0aW9uIG5nQW5pbWF0ZVBvc3REaWdlc3QoKSB7CiAgICAgICAgY2FuY2VsRm4gPSBmbihmdW5jdGlvbiBuZ0FuaW1hdGVOb3RpZnlDb21wbGV0ZSgpIHsKICAgICAgICAgIGRlZmVyLnJlc29sdmUoKTsKICAgICAgICB9KTsKICAgICAgfSk7CgogICAgICByZXR1cm4gZGVmZXIucHJvbWlzZTsKICAgIH0KCiAgICBmdW5jdGlvbiByZXNvbHZlRWxlbWVudENsYXNzZXMoZWxlbWVudCwgY2xhc3NlcykgewogICAgICB2YXIgdG9BZGQgPSBbXSwgdG9SZW1vdmUgPSBbXTsKCiAgICAgIHZhciBoYXNDbGFzc2VzID0gY3JlYXRlTWFwKCk7CiAgICAgIGZvckVhY2goKGVsZW1lbnQuYXR0cignY2xhc3MnKSB8fCAnJykuc3BsaXQoL1xzKy8pLCBmdW5jdGlvbihjbGFzc05hbWUpIHsKICAgICAgICBoYXNDbGFzc2VzW2NsYXNzTmFtZV0gPSB0cnVlOwogICAgICB9KTsKCiAgICAgIGZvckVhY2goY2xhc3NlcywgZnVuY3Rpb24oc3RhdHVzLCBjbGFzc05hbWUpIHsKICAgICAgICB2YXIgaGFzQ2xhc3MgPSBoYXNDbGFzc2VzW2NsYXNzTmFtZV07CgogICAgICAgIC8vIElmIHRoZSBtb3N0IHJlY2VudCBjbGFzcyBtYW5pcHVsYXRpb24gKHZpYSAkYW5pbWF0ZSkgd2FzIHRvIHJlbW92ZSB0aGUgY2xhc3MsIGFuZCB0aGUKICAgICAgICAvLyBlbGVtZW50IGN1cnJlbnRseSBoYXMgdGhlIGNsYXNzLCB0aGUgY2xhc3MgaXMgc2NoZWR1bGVkIGZvciByZW1vdmFsLiBPdGhlcndpc2UsIGlmCiAgICAgICAgLy8gdGhlIG1vc3QgcmVjZW50IGNsYXNzIG1hbmlwdWxhdGlvbiAodmlhICRhbmltYXRlKSB3YXMgdG8gYWRkIHRoZSBjbGFzcywgYW5kIHRoZQogICAgICAgIC8vIGVsZW1lbnQgZG9lcyBub3QgY3VycmVudGx5IGhhdmUgdGhlIGNsYXNzLCB0aGUgY2xhc3MgaXMgc2NoZWR1bGVkIHRvIGJlIGFkZGVkLgogICAgICAgIGlmIChzdGF0dXMgPT09IGZhbHNlICYmIGhhc0NsYXNzKSB7CiAgICAgICAgICB0b1JlbW92ZS5wdXNoKGNsYXNzTmFtZSk7CiAgICAgICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IHRydWUgJiYgIWhhc0NsYXNzKSB7CiAgICAgICAgICB0b0FkZC5wdXNoKGNsYXNzTmFtZSk7CiAgICAgICAgfQogICAgICB9KTsKCiAgICAgIHJldHVybiAodG9BZGQubGVuZ3RoICsgdG9SZW1vdmUubGVuZ3RoKSA+IDAgJiYKICAgICAgICBbdG9BZGQubGVuZ3RoID8gdG9BZGQgOiBudWxsLCB0b1JlbW92ZS5sZW5ndGggPyB0b1JlbW92ZSA6IG51bGxdOwogICAgfQoKICAgIGZ1bmN0aW9uIGNhY2hlZENsYXNzTWFuaXB1bGF0aW9uKGNhY2hlLCBjbGFzc2VzLCBvcCkgewogICAgICBmb3IgKHZhciBpPTAsIGlpID0gY2xhc3Nlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7CiAgICAgICAgdmFyIGNsYXNzTmFtZSA9IGNsYXNzZXNbaV07CiAgICAgICAgY2FjaGVbY2xhc3NOYW1lXSA9IG9wOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXN5bmNQcm9taXNlKCkgewogICAgICAvLyBvbmx5IHNlcnZlIG9uZSBpbnN0YW5jZSBvZiBhIHByb21pc2UgaW4gb3JkZXIgdG8gc2F2ZSBDUFUgY3ljbGVzCiAgICAgIGlmICghY3VycmVudERlZmVyKSB7CiAgICAgICAgY3VycmVudERlZmVyID0gJCRxLmRlZmVyKCk7CiAgICAgICAgJCRhc3luY0NhbGxiYWNrKGZ1bmN0aW9uKCkgewogICAgICAgICAgY3VycmVudERlZmVyLnJlc29sdmUoKTsKICAgICAgICAgIGN1cnJlbnREZWZlciA9IG51bGw7CiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGN1cnJlbnREZWZlci5wcm9taXNlOwogICAgfQoKICAgIGZ1bmN0aW9uIGFwcGx5U3R5bGVzKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgICAgaWYgKGFuZ3VsYXIuaXNPYmplY3Qob3B0aW9ucykpIHsKICAgICAgICB2YXIgc3R5bGVzID0gZXh0ZW5kKG9wdGlvbnMuZnJvbSB8fCB7fSwgb3B0aW9ucy50byB8fCB7fSk7CiAgICAgICAgZWxlbWVudC5jc3Moc3R5bGVzKTsKICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICoKICAgICAqIEBuZ2RvYyBzZXJ2aWNlCiAgICAgKiBAbmFtZSAkYW5pbWF0ZQogICAgICogQGRlc2NyaXB0aW9uIFRoZSAkYW5pbWF0ZSBzZXJ2aWNlIHByb3ZpZGVzIHJ1ZGltZW50YXJ5IERPTSBtYW5pcHVsYXRpb24gZnVuY3Rpb25zIHRvCiAgICAgKiBpbnNlcnQsIHJlbW92ZSBhbmQgbW92ZSBlbGVtZW50cyB3aXRoaW4gdGhlIERPTSwgYXMgd2VsbCBhcyBhZGRpbmcgYW5kIHJlbW92aW5nIGNsYXNzZXMuCiAgICAgKiBUaGlzIHNlcnZpY2UgaXMgdGhlIGNvcmUgc2VydmljZSB1c2VkIGJ5IHRoZSBuZ0FuaW1hdGUgJGFuaW1hdG9yIHNlcnZpY2Ugd2hpY2ggcHJvdmlkZXMKICAgICAqIGhpZ2gtbGV2ZWwgYW5pbWF0aW9uIGhvb2tzIGZvciBDU1MgYW5kIEphdmFTY3JpcHQuCiAgICAgKgogICAgICogJGFuaW1hdGUgaXMgYXZhaWxhYmxlIGluIHRoZSBBbmd1bGFySlMgY29yZSwgaG93ZXZlciwgdGhlIG5nQW5pbWF0ZSBtb2R1bGUgbXVzdCBiZSBpbmNsdWRlZAogICAgICogdG8gZW5hYmxlIGZ1bGwgb3V0IGFuaW1hdGlvbiBzdXBwb3J0LiBPdGhlcndpc2UsICRhbmltYXRlIHdpbGwgb25seSBwZXJmb3JtIHNpbXBsZSBET00KICAgICAqIG1hbmlwdWxhdGlvbiBvcGVyYXRpb25zLgogICAgICoKICAgICAqIFRvIGxlYXJuIG1vcmUgYWJvdXQgZW5hYmxpbmcgYW5pbWF0aW9uIHN1cHBvcnQsIGNsaWNrIGhlcmUgdG8gdmlzaXQgdGhlIHtAbGluayBuZ0FuaW1hdGUKICAgICAqIG5nQW5pbWF0ZSBtb2R1bGUgcGFnZX0gYXMgd2VsbCBhcyB0aGUge0BsaW5rIG5nQW5pbWF0ZS4kYW5pbWF0ZSBuZ0FuaW1hdGUgJGFuaW1hdGUgc2VydmljZQogICAgICogcGFnZX0uCiAgICAgKi8KICAgIHJldHVybiB7CiAgICAgIGFuaW1hdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIGZyb20sIHRvKSB7CiAgICAgICAgYXBwbHlTdHlsZXMoZWxlbWVudCwgeyBmcm9tOiBmcm9tLCB0bzogdG8gfSk7CiAgICAgICAgcmV0dXJuIGFzeW5jUHJvbWlzZSgpOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGFuaW1hdGUjZW50ZXIKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICogQGRlc2NyaXB0aW9uIEluc2VydHMgdGhlIGVsZW1lbnQgaW50byB0aGUgRE9NIGVpdGhlciBhZnRlciB0aGUgYGFmdGVyYCBlbGVtZW50IG9yCiAgICAgICAqIGFzIHRoZSBmaXJzdCBjaGlsZCB3aXRoaW4gdGhlIGBwYXJlbnRgIGVsZW1lbnQuIFdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBhIHByb21pc2UKICAgICAgICogaXMgcmV0dXJuZWQgdGhhdCB3aWxsIGJlIHJlc29sdmVkIGF0IGEgbGF0ZXIgdGltZS4KICAgICAgICogQHBhcmFtIHtET01FbGVtZW50fSBlbGVtZW50IHRoZSBlbGVtZW50IHdoaWNoIHdpbGwgYmUgaW5zZXJ0ZWQgaW50byB0aGUgRE9NCiAgICAgICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gcGFyZW50IHRoZSBwYXJlbnQgZWxlbWVudCB3aGljaCB3aWxsIGFwcGVuZCB0aGUgZWxlbWVudCBhcwogICAgICAgKiAgIGEgY2hpbGQgKGlmIHRoZSBhZnRlciBlbGVtZW50IGlzIG5vdCBwcmVzZW50KQogICAgICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGFmdGVyIHRoZSBzaWJsaW5nIGVsZW1lbnQgd2hpY2ggd2lsbCBhcHBlbmQgdGhlIGVsZW1lbnQKICAgICAgICogICBhZnRlciBpdHNlbGYKICAgICAgICogQHBhcmFtIHtvYmplY3Q9fSBvcHRpb25zIGFuIG9wdGlvbmFsIGNvbGxlY3Rpb24gb2Ygc3R5bGVzIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50LgogICAgICAgKiBAcmV0dXJuIHtQcm9taXNlfSB0aGUgYW5pbWF0aW9uIGNhbGxiYWNrIHByb21pc2UKICAgICAgICovCiAgICAgIGVudGVyOiBmdW5jdGlvbihlbGVtZW50LCBwYXJlbnQsIGFmdGVyLCBvcHRpb25zKSB7CiAgICAgICAgYXBwbHlTdHlsZXMoZWxlbWVudCwgb3B0aW9ucyk7CiAgICAgICAgYWZ0ZXIgPyBhZnRlci5hZnRlcihlbGVtZW50KQogICAgICAgICAgICAgIDogcGFyZW50LnByZXBlbmQoZWxlbWVudCk7CiAgICAgICAgcmV0dXJuIGFzeW5jUHJvbWlzZSgpOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGFuaW1hdGUjbGVhdmUKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgdGhlIGVsZW1lbnQgZnJvbSB0aGUgRE9NLiBXaGVuIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgYSBwcm9taXNlCiAgICAgICAqIGlzIHJldHVybmVkIHRoYXQgd2lsbCBiZSByZXNvbHZlZCBhdCBhIGxhdGVyIHRpbWUuCiAgICAgICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gZWxlbWVudCB0aGUgZWxlbWVudCB3aGljaCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgRE9NCiAgICAgICAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0aW9ucyBhbiBvcHRpb25hbCBjb2xsZWN0aW9uIG9mIG9wdGlvbnMgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQuCiAgICAgICAqIEByZXR1cm4ge1Byb21pc2V9IHRoZSBhbmltYXRpb24gY2FsbGJhY2sgcHJvbWlzZQogICAgICAgKi8KICAgICAgbGVhdmU6IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgICAgICBlbGVtZW50LnJlbW92ZSgpOwogICAgICAgIHJldHVybiBhc3luY1Byb21pc2UoKTsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRhbmltYXRlI21vdmUKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICogQGRlc2NyaXB0aW9uIE1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgcHJvdmlkZWQgZWxlbWVudCB3aXRoaW4gdGhlIERPTSB0byBiZSBwbGFjZWQKICAgICAgICogZWl0aGVyIGFmdGVyIHRoZSBgYWZ0ZXJgIGVsZW1lbnQgb3IgaW5zaWRlIG9mIHRoZSBgcGFyZW50YCBlbGVtZW50LiBXaGVuIHRoZSBmdW5jdGlvbgogICAgICAgKiBpcyBjYWxsZWQgYSBwcm9taXNlIGlzIHJldHVybmVkIHRoYXQgd2lsbCBiZSByZXNvbHZlZCBhdCBhIGxhdGVyIHRpbWUuCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gZWxlbWVudCB0aGUgZWxlbWVudCB3aGljaCB3aWxsIGJlIG1vdmVkIGFyb3VuZCB3aXRoaW4gdGhlCiAgICAgICAqICAgRE9NCiAgICAgICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gcGFyZW50IHRoZSBwYXJlbnQgZWxlbWVudCB3aGVyZSB0aGUgZWxlbWVudCB3aWxsIGJlCiAgICAgICAqICAgaW5zZXJ0ZWQgaW50byAoaWYgdGhlIGFmdGVyIGVsZW1lbnQgaXMgbm90IHByZXNlbnQpCiAgICAgICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gYWZ0ZXIgdGhlIHNpYmxpbmcgZWxlbWVudCB3aGVyZSB0aGUgZWxlbWVudCB3aWxsIGJlCiAgICAgICAqICAgcG9zaXRpb25lZCBuZXh0IHRvCiAgICAgICAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0aW9ucyBhbiBvcHRpb25hbCBjb2xsZWN0aW9uIG9mIG9wdGlvbnMgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQuCiAgICAgICAqIEByZXR1cm4ge1Byb21pc2V9IHRoZSBhbmltYXRpb24gY2FsbGJhY2sgcHJvbWlzZQogICAgICAgKi8KICAgICAgbW92ZTogZnVuY3Rpb24oZWxlbWVudCwgcGFyZW50LCBhZnRlciwgb3B0aW9ucykgewogICAgICAgIC8vIERvIG5vdCByZW1vdmUgZWxlbWVudCBiZWZvcmUgaW5zZXJ0LiBSZW1vdmluZyB3aWxsIGNhdXNlIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZQogICAgICAgIC8vIGVsZW1lbnQgdG8gYmUgZHJvcHBlZC4gSW5zZXJ0IHdpbGwgaW1wbGljaXRseSBkbyB0aGUgcmVtb3ZlLgogICAgICAgIHJldHVybiB0aGlzLmVudGVyKGVsZW1lbnQsIHBhcmVudCwgYWZ0ZXIsIG9wdGlvbnMpOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGFuaW1hdGUjYWRkQ2xhc3MKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICogQGRlc2NyaXB0aW9uIEFkZHMgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZSBDU1MgY2xhc3MgdmFsdWUgdG8gdGhlIHByb3ZpZGVkIGVsZW1lbnQuCiAgICAgICAqIFdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBhIHByb21pc2UgaXMgcmV0dXJuZWQgdGhhdCB3aWxsIGJlIHJlc29sdmVkIGF0IGEgbGF0ZXIgdGltZS4KICAgICAgICogQHBhcmFtIHtET01FbGVtZW50fSBlbGVtZW50IHRoZSBlbGVtZW50IHdoaWNoIHdpbGwgaGF2ZSB0aGUgY2xhc3NOYW1lIHZhbHVlCiAgICAgICAqICAgYWRkZWQgdG8gaXQKICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZSB0aGUgQ1NTIGNsYXNzIHdoaWNoIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGVsZW1lbnQKICAgICAgICogQHBhcmFtIHtvYmplY3Q9fSBvcHRpb25zIGFuIG9wdGlvbmFsIGNvbGxlY3Rpb24gb2Ygb3B0aW9ucyB0aGF0IHdpbGwgYmUgYXBwbGllZCB0byB0aGUgZWxlbWVudC4KICAgICAgICogQHJldHVybiB7UHJvbWlzZX0gdGhlIGFuaW1hdGlvbiBjYWxsYmFjayBwcm9taXNlCiAgICAgICAqLwogICAgICBhZGRDbGFzczogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lLCBvcHRpb25zKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuc2V0Q2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lLCBbXSwgb3B0aW9ucyk7CiAgICAgIH0sCgogICAgICAkJGFkZENsYXNzSW1tZWRpYXRlbHk6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSwgb3B0aW9ucykgewogICAgICAgIGVsZW1lbnQgPSBqcUxpdGUoZWxlbWVudCk7CiAgICAgICAgY2xhc3NOYW1lID0gIWlzU3RyaW5nKGNsYXNzTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgPyAoaXNBcnJheShjbGFzc05hbWUpID8gY2xhc3NOYW1lLmpvaW4oJyAnKSA6ICcnKQogICAgICAgICAgICAgICAgICAgICAgICA6IGNsYXNzTmFtZTsKICAgICAgICBmb3JFYWNoKGVsZW1lbnQsIGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICAgIGpxTGl0ZUFkZENsYXNzKGVsZW1lbnQsIGNsYXNzTmFtZSk7CiAgICAgICAgfSk7CiAgICAgICAgYXBwbHlTdHlsZXMoZWxlbWVudCwgb3B0aW9ucyk7CiAgICAgICAgcmV0dXJuIGFzeW5jUHJvbWlzZSgpOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGFuaW1hdGUjcmVtb3ZlQ2xhc3MKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZSBDU1MgY2xhc3MgdmFsdWUgZnJvbSB0aGUgcHJvdmlkZWQgZWxlbWVudC4KICAgICAgICogV2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIGEgcHJvbWlzZSBpcyByZXR1cm5lZCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgYXQgYSBsYXRlciB0aW1lLgogICAgICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGVsZW1lbnQgdGhlIGVsZW1lbnQgd2hpY2ggd2lsbCBoYXZlIHRoZSBjbGFzc05hbWUgdmFsdWUKICAgICAgICogICByZW1vdmVkIGZyb20gaXQKICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZSB0aGUgQ1NTIGNsYXNzIHdoaWNoIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50CiAgICAgICAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0aW9ucyBhbiBvcHRpb25hbCBjb2xsZWN0aW9uIG9mIG9wdGlvbnMgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQuCiAgICAgICAqIEByZXR1cm4ge1Byb21pc2V9IHRoZSBhbmltYXRpb24gY2FsbGJhY2sgcHJvbWlzZQogICAgICAgKi8KICAgICAgcmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSwgb3B0aW9ucykgewogICAgICAgIHJldHVybiB0aGlzLnNldENsYXNzKGVsZW1lbnQsIFtdLCBjbGFzc05hbWUsIG9wdGlvbnMpOwogICAgICB9LAoKICAgICAgJCRyZW1vdmVDbGFzc0ltbWVkaWF0ZWx5OiBmdW5jdGlvbihlbGVtZW50LCBjbGFzc05hbWUsIG9wdGlvbnMpIHsKICAgICAgICBlbGVtZW50ID0ganFMaXRlKGVsZW1lbnQpOwogICAgICAgIGNsYXNzTmFtZSA9ICFpc1N0cmluZyhjbGFzc05hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgID8gKGlzQXJyYXkoY2xhc3NOYW1lKSA/IGNsYXNzTmFtZS5qb2luKCcgJykgOiAnJykKICAgICAgICAgICAgICAgICAgICAgICAgOiBjbGFzc05hbWU7CiAgICAgICAgZm9yRWFjaChlbGVtZW50LCBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgICBqcUxpdGVSZW1vdmVDbGFzcyhlbGVtZW50LCBjbGFzc05hbWUpOwogICAgICAgIH0pOwogICAgICAgIGFwcGx5U3R5bGVzKGVsZW1lbnQsIG9wdGlvbnMpOwogICAgICAgIHJldHVybiBhc3luY1Byb21pc2UoKTsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRhbmltYXRlI3NldENsYXNzCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqIEBkZXNjcmlwdGlvbiBBZGRzIGFuZC9vciByZW1vdmVzIHRoZSBnaXZlbiBDU1MgY2xhc3NlcyB0byBhbmQgZnJvbSB0aGUgZWxlbWVudC4KICAgICAgICogV2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIGEgcHJvbWlzZSBpcyByZXR1cm5lZCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgYXQgYSBsYXRlciB0aW1lLgogICAgICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGVsZW1lbnQgdGhlIGVsZW1lbnQgd2hpY2ggd2lsbCBoYXZlIGl0cyBDU1MgY2xhc3NlcyBjaGFuZ2VkCiAgICAgICAqICAgcmVtb3ZlZCBmcm9tIGl0CiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGQgdGhlIENTUyBjbGFzc2VzIHdoaWNoIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGVsZW1lbnQKICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHJlbW92ZSB0aGUgQ1NTIGNsYXNzIHdoaWNoIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50CiAgICAgICAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0aW9ucyBhbiBvcHRpb25hbCBjb2xsZWN0aW9uIG9mIG9wdGlvbnMgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQuCiAgICAgICAqIEByZXR1cm4ge1Byb21pc2V9IHRoZSBhbmltYXRpb24gY2FsbGJhY2sgcHJvbWlzZQogICAgICAgKi8KICAgICAgc2V0Q2xhc3M6IGZ1bmN0aW9uKGVsZW1lbnQsIGFkZCwgcmVtb3ZlLCBvcHRpb25zKSB7CiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHZhciBTVE9SQUdFX0tFWSA9ICckJGFuaW1hdGVDbGFzc2VzJzsKICAgICAgICB2YXIgY3JlYXRlZENhY2hlID0gZmFsc2U7CiAgICAgICAgZWxlbWVudCA9IGpxTGl0ZShlbGVtZW50KTsKCiAgICAgICAgdmFyIGNhY2hlID0gZWxlbWVudC5kYXRhKFNUT1JBR0VfS0VZKTsKICAgICAgICBpZiAoIWNhY2hlKSB7CiAgICAgICAgICBjYWNoZSA9IHsKICAgICAgICAgICAgY2xhc3Nlczoge30sCiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMKICAgICAgICAgIH07CiAgICAgICAgICBjcmVhdGVkQ2FjaGUgPSB0cnVlOwogICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucyAmJiBjYWNoZS5vcHRpb25zKSB7CiAgICAgICAgICBjYWNoZS5vcHRpb25zID0gYW5ndWxhci5leHRlbmQoY2FjaGUub3B0aW9ucyB8fCB7fSwgb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICB2YXIgY2xhc3NlcyA9IGNhY2hlLmNsYXNzZXM7CgogICAgICAgIGFkZCA9IGlzQXJyYXkoYWRkKSA/IGFkZCA6IGFkZC5zcGxpdCgnICcpOwogICAgICAgIHJlbW92ZSA9IGlzQXJyYXkocmVtb3ZlKSA/IHJlbW92ZSA6IHJlbW92ZS5zcGxpdCgnICcpOwogICAgICAgIGNhY2hlZENsYXNzTWFuaXB1bGF0aW9uKGNsYXNzZXMsIGFkZCwgdHJ1ZSk7CiAgICAgICAgY2FjaGVkQ2xhc3NNYW5pcHVsYXRpb24oY2xhc3NlcywgcmVtb3ZlLCBmYWxzZSk7CgogICAgICAgIGlmIChjcmVhdGVkQ2FjaGUpIHsKICAgICAgICAgIGNhY2hlLnByb21pc2UgPSBydW5BbmltYXRpb25Qb3N0RGlnZXN0KGZ1bmN0aW9uKGRvbmUpIHsKICAgICAgICAgICAgdmFyIGNhY2hlID0gZWxlbWVudC5kYXRhKFNUT1JBR0VfS0VZKTsKICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVEYXRhKFNUT1JBR0VfS0VZKTsKCiAgICAgICAgICAgIC8vIGluIHRoZSBldmVudCB0aGF0IHRoZSBlbGVtZW50IGlzIHJlbW92ZWQgYmVmb3JlIHBvc3REaWdlc3QKICAgICAgICAgICAgLy8gaXMgcnVuIHRoZW4gdGhlIGNhY2hlIHdpbGwgYmUgdW5kZWZpbmVkIGFuZCB0aGVyZSB3aWxsIGJlCiAgICAgICAgICAgIC8vIG5vIG5lZWQgYW55bW9yZSB0byBhZGQgb3IgcmVtb3ZlIGFuZCBvZiB0aGUgZWxlbWVudCBjbGFzc2VzCiAgICAgICAgICAgIGlmIChjYWNoZSkgewogICAgICAgICAgICAgIHZhciBjbGFzc2VzID0gcmVzb2x2ZUVsZW1lbnRDbGFzc2VzKGVsZW1lbnQsIGNhY2hlLmNsYXNzZXMpOwogICAgICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBzZWxmLiQkc2V0Q2xhc3NJbW1lZGlhdGVseShlbGVtZW50LCBjbGFzc2VzWzBdLCBjbGFzc2VzWzFdLCBjYWNoZS5vcHRpb25zKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRvbmUoKTsKICAgICAgICAgIH0pOwogICAgICAgICAgZWxlbWVudC5kYXRhKFNUT1JBR0VfS0VZLCBjYWNoZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2FjaGUucHJvbWlzZTsKICAgICAgfSwKCiAgICAgICQkc2V0Q2xhc3NJbW1lZGlhdGVseTogZnVuY3Rpb24oZWxlbWVudCwgYWRkLCByZW1vdmUsIG9wdGlvbnMpIHsKICAgICAgICBhZGQgJiYgdGhpcy4kJGFkZENsYXNzSW1tZWRpYXRlbHkoZWxlbWVudCwgYWRkKTsKICAgICAgICByZW1vdmUgJiYgdGhpcy4kJHJlbW92ZUNsYXNzSW1tZWRpYXRlbHkoZWxlbWVudCwgcmVtb3ZlKTsKICAgICAgICBhcHBseVN0eWxlcyhlbGVtZW50LCBvcHRpb25zKTsKICAgICAgICByZXR1cm4gYXN5bmNQcm9taXNlKCk7CiAgICAgIH0sCgogICAgICBlbmFibGVkOiBub29wLAogICAgICBjYW5jZWw6IG5vb3AKICAgIH07CiAgfV07Cn1dOwoKZnVuY3Rpb24gJCRBc3luY0NhbGxiYWNrUHJvdmlkZXIoKSB7CiAgdGhpcy4kZ2V0ID0gWyckJHJBRicsICckdGltZW91dCcsIGZ1bmN0aW9uKCQkckFGLCAkdGltZW91dCkgewogICAgcmV0dXJuICQkckFGLnN1cHBvcnRlZAogICAgICA/IGZ1bmN0aW9uKGZuKSB7IHJldHVybiAkJHJBRihmbik7IH0KICAgICAgOiBmdW5jdGlvbihmbikgewogICAgICAgIHJldHVybiAkdGltZW91dChmbiwgMCwgZmFsc2UpOwogICAgICB9OwogIH1dOwp9CgovKiBnbG9iYWwgc3RyaXBIYXNoOiB0cnVlICovCgovKioKICogISBUaGlzIGlzIGEgcHJpdmF0ZSB1bmRvY3VtZW50ZWQgc2VydmljZSAhCiAqCiAqIEBuYW1lICRicm93c2VyCiAqIEByZXF1aXJlcyAkbG9nCiAqIEBkZXNjcmlwdGlvbgogKiBUaGlzIG9iamVjdCBoYXMgdHdvIGdvYWxzOgogKgogKiAtIGhpZGUgYWxsIHRoZSBnbG9iYWwgc3RhdGUgaW4gdGhlIGJyb3dzZXIgY2F1c2VkIGJ5IHRoZSB3aW5kb3cgb2JqZWN0CiAqIC0gYWJzdHJhY3QgYXdheSBhbGwgdGhlIGJyb3dzZXIgc3BlY2lmaWMgZmVhdHVyZXMgYW5kIGluY29uc2lzdGVuY2llcwogKgogKiBGb3IgdGVzdHMgd2UgcHJvdmlkZSB7QGxpbmsgbmdNb2NrLiRicm93c2VyIG1vY2sgaW1wbGVtZW50YXRpb259IG9mIHRoZSBgJGJyb3dzZXJgCiAqIHNlcnZpY2UsIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBjb252ZW5pZW50IHRlc3Rpbmcgb2YgdGhlIGFwcGxpY2F0aW9uIHdpdGhvdXQgdGhlIGludGVyYWN0aW9uIHdpdGgKICogdGhlIHJlYWwgYnJvd3NlciBhcGlzLgogKi8KLyoqCiAqIEBwYXJhbSB7b2JqZWN0fSB3aW5kb3cgVGhlIGdsb2JhbCB3aW5kb3cgb2JqZWN0LgogKiBAcGFyYW0ge29iamVjdH0gZG9jdW1lbnQgalF1ZXJ5IHdyYXBwZWQgZG9jdW1lbnQuCiAqIEBwYXJhbSB7b2JqZWN0fSAkbG9nIHdpbmRvdy5jb25zb2xlIG9yIGFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGludGVyZmFjZS4KICogQHBhcmFtIHtvYmplY3R9ICRzbmlmZmVyICRzbmlmZmVyIHNlcnZpY2UKICovCmZ1bmN0aW9uIEJyb3dzZXIod2luZG93LCBkb2N1bWVudCwgJGxvZywgJHNuaWZmZXIpIHsKICB2YXIgc2VsZiA9IHRoaXMsCiAgICAgIHJhd0RvY3VtZW50ID0gZG9jdW1lbnRbMF0sCiAgICAgIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uLAogICAgICBoaXN0b3J5ID0gd2luZG93Lmhpc3RvcnksCiAgICAgIHNldFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCwKICAgICAgY2xlYXJUaW1lb3V0ID0gd2luZG93LmNsZWFyVGltZW91dCwKICAgICAgcGVuZGluZ0RlZmVySWRzID0ge307CgogIHNlbGYuaXNNb2NrID0gZmFsc2U7CgogIHZhciBvdXRzdGFuZGluZ1JlcXVlc3RDb3VudCA9IDA7CiAgdmFyIG91dHN0YW5kaW5nUmVxdWVzdENhbGxiYWNrcyA9IFtdOwoKICAvLyBUT0RPKHZvanRhKTogcmVtb3ZlIHRoaXMgdGVtcG9yYXJ5IGFwaQogIHNlbGYuJCRjb21wbGV0ZU91dHN0YW5kaW5nUmVxdWVzdCA9IGNvbXBsZXRlT3V0c3RhbmRpbmdSZXF1ZXN0OwogIHNlbGYuJCRpbmNPdXRzdGFuZGluZ1JlcXVlc3RDb3VudCA9IGZ1bmN0aW9uKCkgeyBvdXRzdGFuZGluZ1JlcXVlc3RDb3VudCsrOyB9OwoKICAvKioKICAgKiBFeGVjdXRlcyB0aGUgYGZuYCBmdW5jdGlvbihzdXBwb3J0cyBjdXJyeWluZykgYW5kIGRlY3JlbWVudHMgdGhlIGBvdXRzdGFuZGluZ1JlcXVlc3RDYWxsYmFja3NgCiAgICogY291bnRlci4gSWYgdGhlIGNvdW50ZXIgcmVhY2hlcyAwLCBhbGwgdGhlIGBvdXRzdGFuZGluZ1JlcXVlc3RDYWxsYmFja3NgIGFyZSBleGVjdXRlZC4KICAgKi8KICBmdW5jdGlvbiBjb21wbGV0ZU91dHN0YW5kaW5nUmVxdWVzdChmbikgewogICAgdHJ5IHsKICAgICAgZm4uYXBwbHkobnVsbCwgc2xpY2VBcmdzKGFyZ3VtZW50cywgMSkpOwogICAgfSBmaW5hbGx5IHsKICAgICAgb3V0c3RhbmRpbmdSZXF1ZXN0Q291bnQtLTsKICAgICAgaWYgKG91dHN0YW5kaW5nUmVxdWVzdENvdW50ID09PSAwKSB7CiAgICAgICAgd2hpbGUgKG91dHN0YW5kaW5nUmVxdWVzdENhbGxiYWNrcy5sZW5ndGgpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIG91dHN0YW5kaW5nUmVxdWVzdENhbGxiYWNrcy5wb3AoKSgpOwogICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAkbG9nLmVycm9yKGUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gZ2V0SGFzaCh1cmwpIHsKICAgIHZhciBpbmRleCA9IHVybC5pbmRleE9mKCcjJyk7CiAgICByZXR1cm4gaW5kZXggPT09IC0xID8gJycgOiB1cmwuc3Vic3RyKGluZGV4ICsgMSk7CiAgfQoKICAvKioKICAgKiBAcHJpdmF0ZQogICAqIE5vdGU6IHRoaXMgbWV0aG9kIGlzIHVzZWQgb25seSBieSBzY2VuYXJpbyBydW5uZXIKICAgKiBUT0RPKHZvanRhKTogcHJlZml4IHRoaXMgbWV0aG9kIHdpdGggJCQgPwogICAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gY2FsbGJhY2sgRnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIG5vIG91dHN0YW5kaW5nIHJlcXVlc3QKICAgKi8KICBzZWxmLm5vdGlmeVdoZW5Ob091dHN0YW5kaW5nUmVxdWVzdHMgPSBmdW5jdGlvbihjYWxsYmFjaykgewogICAgLy8gZm9yY2UgYnJvd3NlciB0byBleGVjdXRlIGFsbCBwb2xsRm5zIC0gdGhpcyBpcyBuZWVkZWQgc28gdGhhdCBjb29raWVzIGFuZCBvdGhlciBwb2xsZXJzIGZpcmUKICAgIC8vIGF0IHNvbWUgZGV0ZXJtaW5pc3RpYyB0aW1lIGluIHJlc3BlY3QgdG8gdGhlIHRlc3QgcnVubmVyJ3MgYWN0aW9ucy4gTGVhdmluZyB0aGluZ3MgdXAgdG8gdGhlCiAgICAvLyByZWd1bGFyIHBvbGxlciB3b3VsZCByZXN1bHQgaW4gZmxha3kgdGVzdHMuCiAgICBmb3JFYWNoKHBvbGxGbnMsIGZ1bmN0aW9uKHBvbGxGbikgeyBwb2xsRm4oKTsgfSk7CgogICAgaWYgKG91dHN0YW5kaW5nUmVxdWVzdENvdW50ID09PSAwKSB7CiAgICAgIGNhbGxiYWNrKCk7CiAgICB9IGVsc2UgewogICAgICBvdXRzdGFuZGluZ1JlcXVlc3RDYWxsYmFja3MucHVzaChjYWxsYmFjayk7CiAgICB9CiAgfTsKCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAvLyBQb2xsIFdhdGNoZXIgQVBJCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICB2YXIgcG9sbEZucyA9IFtdLAogICAgICBwb2xsVGltZW91dDsKCiAgLyoqCiAgICogQG5hbWUgJGJyb3dzZXIjYWRkUG9sbEZuCiAgICoKICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGZuIFBvbGwgZnVuY3Rpb24gdG8gYWRkCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBBZGRzIGEgZnVuY3Rpb24gdG8gdGhlIGxpc3Qgb2YgZnVuY3Rpb25zIHRoYXQgcG9sbGVyIHBlcmlvZGljYWxseSBleGVjdXRlcywKICAgKiBhbmQgc3RhcnRzIHBvbGxpbmcgaWYgbm90IHN0YXJ0ZWQgeWV0LgogICAqCiAgICogQHJldHVybnMge2Z1bmN0aW9uKCl9IHRoZSBhZGRlZCBmdW5jdGlvbgogICAqLwogIHNlbGYuYWRkUG9sbEZuID0gZnVuY3Rpb24oZm4pIHsKICAgIGlmIChpc1VuZGVmaW5lZChwb2xsVGltZW91dCkpIHN0YXJ0UG9sbGVyKDEwMCwgc2V0VGltZW91dCk7CiAgICBwb2xsRm5zLnB1c2goZm4pOwogICAgcmV0dXJuIGZuOwogIH07CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyfSBpbnRlcnZhbCBIb3cgb2Z0ZW4gc2hvdWxkIGJyb3dzZXIgY2FsbCBwb2xsIGZ1bmN0aW9ucyAobXMpCiAgICogQHBhcmFtIHtmdW5jdGlvbigpfSBzZXRUaW1lb3V0IFJlZmVyZW5jZSB0byBhIHJlYWwgb3IgZmFrZSBgc2V0VGltZW91dGAgZnVuY3Rpb24uCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBDb25maWd1cmVzIHRoZSBwb2xsZXIgdG8gcnVuIGluIHRoZSBzcGVjaWZpZWQgaW50ZXJ2YWxzLCB1c2luZyB0aGUgc3BlY2lmaWVkCiAgICogc2V0VGltZW91dCBmbiBhbmQga2lja3MgaXQgb2ZmLgogICAqLwogIGZ1bmN0aW9uIHN0YXJ0UG9sbGVyKGludGVydmFsLCBzZXRUaW1lb3V0KSB7CiAgICAoZnVuY3Rpb24gY2hlY2soKSB7CiAgICAgIGZvckVhY2gocG9sbEZucywgZnVuY3Rpb24ocG9sbEZuKSB7IHBvbGxGbigpOyB9KTsKICAgICAgcG9sbFRpbWVvdXQgPSBzZXRUaW1lb3V0KGNoZWNrLCBpbnRlcnZhbCk7CiAgICB9KSgpOwogIH0KCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAvLyBVUkwgQVBJCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiAgdmFyIGNhY2hlZFN0YXRlLCBsYXN0SGlzdG9yeVN0YXRlLAogICAgICBsYXN0QnJvd3NlclVybCA9IGxvY2F0aW9uLmhyZWYsCiAgICAgIGJhc2VFbGVtZW50ID0gZG9jdW1lbnQuZmluZCgnYmFzZScpLAogICAgICByZWxvYWRMb2NhdGlvbiA9IG51bGw7CgogIGNhY2hlU3RhdGUoKTsKICBsYXN0SGlzdG9yeVN0YXRlID0gY2FjaGVkU3RhdGU7CgogIC8qKgogICAqIEBuYW1lICRicm93c2VyI3VybAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogR0VUVEVSOgogICAqIFdpdGhvdXQgYW55IGFyZ3VtZW50LCB0aGlzIG1ldGhvZCBqdXN0IHJldHVybnMgY3VycmVudCB2YWx1ZSBvZiBsb2NhdGlvbi5ocmVmLgogICAqCiAgICogU0VUVEVSOgogICAqIFdpdGggYXQgbGVhc3Qgb25lIGFyZ3VtZW50LCB0aGlzIG1ldGhvZCBzZXRzIHVybCB0byBuZXcgdmFsdWUuCiAgICogSWYgaHRtbDUgaGlzdG9yeSBhcGkgc3VwcG9ydGVkLCBwdXNoU3RhdGUvcmVwbGFjZVN0YXRlIGlzIHVzZWQsIG90aGVyd2lzZQogICAqIGxvY2F0aW9uLmhyZWYvbG9jYXRpb24ucmVwbGFjZSBpcyB1c2VkLgogICAqIFJldHVybnMgaXRzIG93biBpbnN0YW5jZSB0byBhbGxvdyBjaGFpbmluZwogICAqCiAgICogTk9URTogdGhpcyBhcGkgaXMgaW50ZW5kZWQgZm9yIHVzZSBvbmx5IGJ5IHRoZSAkbG9jYXRpb24gc2VydmljZS4gUGxlYXNlIHVzZSB0aGUKICAgKiB7QGxpbmsgbmcuJGxvY2F0aW9uICRsb2NhdGlvbiBzZXJ2aWNlfSB0byBjaGFuZ2UgdXJsLgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBOZXcgdXJsICh3aGVuIHVzZWQgYXMgc2V0dGVyKQogICAqIEBwYXJhbSB7Ym9vbGVhbj19IHJlcGxhY2UgU2hvdWxkIG5ldyB1cmwgcmVwbGFjZSBjdXJyZW50IGhpc3RvcnkgcmVjb3JkPwogICAqIEBwYXJhbSB7b2JqZWN0PX0gc3RhdGUgb2JqZWN0IHRvIHVzZSB3aXRoIHB1c2hTdGF0ZS9yZXBsYWNlU3RhdGUKICAgKi8KICBzZWxmLnVybCA9IGZ1bmN0aW9uKHVybCwgcmVwbGFjZSwgc3RhdGUpIHsKICAgIC8vIEluIG1vZGVybiBicm93c2VycyBgaGlzdG9yeS5zdGF0ZWAgaXMgYG51bGxgIGJ5IGRlZmF1bHQ7IHRyZWF0aW5nIGl0IHNlcGFyYXRlbHkKICAgIC8vIGZyb20gYHVuZGVmaW5lZGAgd291bGQgY2F1c2UgYCRicm93c2VyLnVybCgnL2ZvbycpYCB0byBjaGFuZ2UgYGhpc3Rvcnkuc3RhdGVgCiAgICAvLyB0byB1bmRlZmluZWQgdmlhIGBwdXNoU3RhdGVgLiBJbnN0ZWFkLCBsZXQncyBjaGFuZ2UgYHVuZGVmaW5lZGAgdG8gYG51bGxgIGhlcmUuCiAgICBpZiAoaXNVbmRlZmluZWQoc3RhdGUpKSB7CiAgICAgIHN0YXRlID0gbnVsbDsKICAgIH0KCiAgICAvLyBBbmRyb2lkIEJyb3dzZXIgQkZDYWNoZSBjYXVzZXMgbG9jYXRpb24sIGhpc3RvcnkgcmVmZXJlbmNlIHRvIGJlY29tZSBzdGFsZS4KICAgIGlmIChsb2NhdGlvbiAhPT0gd2luZG93LmxvY2F0aW9uKSBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbjsKICAgIGlmIChoaXN0b3J5ICE9PSB3aW5kb3cuaGlzdG9yeSkgaGlzdG9yeSA9IHdpbmRvdy5oaXN0b3J5OwoKICAgIC8vIHNldHRlcgogICAgaWYgKHVybCkgewogICAgICB2YXIgc2FtZVN0YXRlID0gbGFzdEhpc3RvcnlTdGF0ZSA9PT0gc3RhdGU7CgogICAgICAvLyBEb24ndCBjaGFuZ2UgYW55dGhpbmcgaWYgcHJldmlvdXMgYW5kIGN1cnJlbnQgVVJMcyBhbmQgc3RhdGVzIG1hdGNoLiBUaGlzIGFsc28gcHJldmVudHMKICAgICAgLy8gSUU8MTAgZnJvbSBnZXR0aW5nIGludG8gcmVkaXJlY3QgbG9vcCB3aGVuIGluIExvY2F0aW9uSGFzaGJhbmdJbkh0bWw1VXJsIG1vZGUuCiAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2NvbW1pdC9mZmIyNzAxCiAgICAgIGlmIChsYXN0QnJvd3NlclVybCA9PT0gdXJsICYmICghJHNuaWZmZXIuaGlzdG9yeSB8fCBzYW1lU3RhdGUpKSB7CiAgICAgICAgcmV0dXJuIHNlbGY7CiAgICAgIH0KICAgICAgdmFyIHNhbWVCYXNlID0gbGFzdEJyb3dzZXJVcmwgJiYgc3RyaXBIYXNoKGxhc3RCcm93c2VyVXJsKSA9PT0gc3RyaXBIYXNoKHVybCk7CiAgICAgIGxhc3RCcm93c2VyVXJsID0gdXJsOwogICAgICBsYXN0SGlzdG9yeVN0YXRlID0gc3RhdGU7CiAgICAgIC8vIERvbid0IHVzZSBoaXN0b3J5IEFQSSBpZiBvbmx5IHRoZSBoYXNoIGNoYW5nZWQKICAgICAgLy8gZHVlIHRvIGEgYnVnIGluIElFMTAvSUUxMSB3aGljaCBsZWFkcwogICAgICAvLyB0byBub3QgZmlyaW5nIGEgYGhhc2hjaGFuZ2VgIG5vciBgcG9wc3RhdGVgIGV2ZW50CiAgICAgIC8vIGluIHNvbWUgY2FzZXMgKHNlZSAjOTE0MykuCiAgICAgIGlmICgkc25pZmZlci5oaXN0b3J5ICYmICghc2FtZUJhc2UgfHwgIXNhbWVTdGF0ZSkpIHsKICAgICAgICBoaXN0b3J5W3JlcGxhY2UgPyAncmVwbGFjZVN0YXRlJyA6ICdwdXNoU3RhdGUnXShzdGF0ZSwgJycsIHVybCk7CiAgICAgICAgY2FjaGVTdGF0ZSgpOwogICAgICAgIC8vIERvIHRoZSBhc3NpZ25tZW50IGFnYWluIHNvIHRoYXQgdGhvc2UgdHdvIHZhcmlhYmxlcyBhcmUgcmVmZXJlbnRpYWxseSBpZGVudGljYWwuCiAgICAgICAgbGFzdEhpc3RvcnlTdGF0ZSA9IGNhY2hlZFN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIGlmICghc2FtZUJhc2UpIHsKICAgICAgICAgIHJlbG9hZExvY2F0aW9uID0gdXJsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwbGFjZSkgewogICAgICAgICAgbG9jYXRpb24ucmVwbGFjZSh1cmwpOwogICAgICAgIH0gZWxzZSBpZiAoIXNhbWVCYXNlKSB7CiAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gdXJsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsb2NhdGlvbi5oYXNoID0gZ2V0SGFzaCh1cmwpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gc2VsZjsKICAgIC8vIGdldHRlcgogICAgfSBlbHNlIHsKICAgICAgLy8gLSByZWxvYWRMb2NhdGlvbiBpcyBuZWVkZWQgYXMgYnJvd3NlcnMgZG9uJ3QgYWxsb3cgdG8gcmVhZCBvdXQKICAgICAgLy8gICB0aGUgbmV3IGxvY2F0aW9uLmhyZWYgaWYgYSByZWxvYWQgaGFwcGVuZWQuCiAgICAgIC8vIC0gdGhlIHJlcGxhY2VtZW50IGlzIGEgd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDA3MTcyCiAgICAgIHJldHVybiByZWxvYWRMb2NhdGlvbiB8fCBsb2NhdGlvbi5ocmVmLnJlcGxhY2UoLyUyNy9nLCInIik7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQG5hbWUgJGJyb3dzZXIjc3RhdGUKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRoaXMgbWV0aG9kIGlzIGEgZ2V0dGVyLgogICAqCiAgICogUmV0dXJuIGhpc3Rvcnkuc3RhdGUgb3IgbnVsbCBpZiBoaXN0b3J5LnN0YXRlIGlzIHVuZGVmaW5lZC4KICAgKgogICAqIEByZXR1cm5zIHtvYmplY3R9IHN0YXRlCiAgICovCiAgc2VsZi5zdGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIGNhY2hlZFN0YXRlOwogIH07CgogIHZhciB1cmxDaGFuZ2VMaXN0ZW5lcnMgPSBbXSwKICAgICAgdXJsQ2hhbmdlSW5pdCA9IGZhbHNlOwoKICBmdW5jdGlvbiBjYWNoZVN0YXRlQW5kRmlyZVVybENoYW5nZSgpIHsKICAgIGNhY2hlU3RhdGUoKTsKICAgIGZpcmVVcmxDaGFuZ2UoKTsKICB9CgogIC8vIFRoaXMgdmFyaWFibGUgc2hvdWxkIGJlIHVzZWQgKm9ubHkqIGluc2lkZSB0aGUgY2FjaGVTdGF0ZSBmdW5jdGlvbi4KICB2YXIgbGFzdENhY2hlZFN0YXRlID0gbnVsbDsKICBmdW5jdGlvbiBjYWNoZVN0YXRlKCkgewogICAgLy8gVGhpcyBzaG91bGQgYmUgdGhlIG9ubHkgcGxhY2UgaW4gJGJyb3dzZXIgd2hlcmUgYGhpc3Rvcnkuc3RhdGVgIGlzIHJlYWQuCiAgICBjYWNoZWRTdGF0ZSA9IHdpbmRvdy5oaXN0b3J5LnN0YXRlOwogICAgY2FjaGVkU3RhdGUgPSBpc1VuZGVmaW5lZChjYWNoZWRTdGF0ZSkgPyBudWxsIDogY2FjaGVkU3RhdGU7CgogICAgLy8gUHJldmVudCBjYWxsYmFja3MgZm8gZmlyZSB0d2ljZSBpZiBib3RoIGhhc2hjaGFuZ2UgJiBwb3BzdGF0ZSB3ZXJlIGZpcmVkLgogICAgaWYgKGVxdWFscyhjYWNoZWRTdGF0ZSwgbGFzdENhY2hlZFN0YXRlKSkgewogICAgICBjYWNoZWRTdGF0ZSA9IGxhc3RDYWNoZWRTdGF0ZTsKICAgIH0KICAgIGxhc3RDYWNoZWRTdGF0ZSA9IGNhY2hlZFN0YXRlOwogIH0KCiAgZnVuY3Rpb24gZmlyZVVybENoYW5nZSgpIHsKICAgIGlmIChsYXN0QnJvd3NlclVybCA9PT0gc2VsZi51cmwoKSAmJiBsYXN0SGlzdG9yeVN0YXRlID09PSBjYWNoZWRTdGF0ZSkgewogICAgICByZXR1cm47CiAgICB9CgogICAgbGFzdEJyb3dzZXJVcmwgPSBzZWxmLnVybCgpOwogICAgbGFzdEhpc3RvcnlTdGF0ZSA9IGNhY2hlZFN0YXRlOwogICAgZm9yRWFjaCh1cmxDaGFuZ2VMaXN0ZW5lcnMsIGZ1bmN0aW9uKGxpc3RlbmVyKSB7CiAgICAgIGxpc3RlbmVyKHNlbGYudXJsKCksIGNhY2hlZFN0YXRlKTsKICAgIH0pOwogIH0KCiAgLyoqCiAgICogQG5hbWUgJGJyb3dzZXIjb25VcmxDaGFuZ2UKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJlZ2lzdGVyIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQsIHdoZW4gdXJsIGNoYW5nZXMuCiAgICoKICAgKiBJdCdzIG9ubHkgY2FsbGVkIHdoZW4gdGhlIHVybCBpcyBjaGFuZ2VkIGZyb20gb3V0c2lkZSBvZiBhbmd1bGFyOgogICAqIC0gdXNlciB0eXBlcyBkaWZmZXJlbnQgdXJsIGludG8gYWRkcmVzcyBiYXIKICAgKiAtIHVzZXIgY2xpY2tzIG9uIGhpc3RvcnkgKGZvcndhcmQvYmFjaykgYnV0dG9uCiAgICogLSB1c2VyIGNsaWNrcyBvbiBhIGxpbmsKICAgKgogICAqIEl0J3Mgbm90IGNhbGxlZCB3aGVuIHVybCBpcyBjaGFuZ2VkIGJ5ICRicm93c2VyLnVybCgpIG1ldGhvZAogICAqCiAgICogVGhlIGxpc3RlbmVyIGdldHMgY2FsbGVkIHdpdGggbmV3IHVybCBhcyBwYXJhbWV0ZXIuCiAgICoKICAgKiBOT1RFOiB0aGlzIGFwaSBpcyBpbnRlbmRlZCBmb3IgdXNlIG9ubHkgYnkgdGhlICRsb2NhdGlvbiBzZXJ2aWNlLiBQbGVhc2UgdXNlIHRoZQogICAqIHtAbGluayBuZy4kbG9jYXRpb24gJGxvY2F0aW9uIHNlcnZpY2V9IHRvIG1vbml0b3IgdXJsIGNoYW5nZXMgaW4gYW5ndWxhciBhcHBzLgogICAqCiAgICogQHBhcmFtIHtmdW5jdGlvbihzdHJpbmcpfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB1cmwgY2hhbmdlcy4KICAgKiBAcmV0dXJuIHtmdW5jdGlvbihzdHJpbmcpfSBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIGxpc3RlbmVyIGZuIC0gaGFuZHkgaWYgdGhlIGZuIGlzIGFub255bW91cy4KICAgKi8KICBzZWxmLm9uVXJsQ2hhbmdlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIC8vIFRPRE8odm9qdGEpOiByZWZhY3RvciB0byB1c2Ugbm9kZSdzIHN5bnRheCBmb3IgZXZlbnRzCiAgICBpZiAoIXVybENoYW5nZUluaXQpIHsKICAgICAgLy8gV2UgbGlzdGVuIG9uIGJvdGggKGhhc2hjaGFuZ2UvcG9wc3RhdGUpIHdoZW4gYXZhaWxhYmxlLCBhcyBzb21lIGJyb3dzZXJzIChlLmcuIE9wZXJhKQogICAgICAvLyBkb24ndCBmaXJlIHBvcHN0YXRlIHdoZW4gdXNlciBjaGFuZ2UgdGhlIGFkZHJlc3MgYmFyIGFuZCBkb24ndCBmaXJlIGhhc2hjaGFuZ2Ugd2hlbiB1cmwKICAgICAgLy8gY2hhbmdlZCBieSBwdXNoL3JlcGxhY2VTdGF0ZQoKICAgICAgLy8gaHRtbDUgaGlzdG9yeSBhcGkgLSBwb3BzdGF0ZSBldmVudAogICAgICBpZiAoJHNuaWZmZXIuaGlzdG9yeSkganFMaXRlKHdpbmRvdykub24oJ3BvcHN0YXRlJywgY2FjaGVTdGF0ZUFuZEZpcmVVcmxDaGFuZ2UpOwogICAgICAvLyBoYXNoY2hhbmdlIGV2ZW50CiAgICAgIGpxTGl0ZSh3aW5kb3cpLm9uKCdoYXNoY2hhbmdlJywgY2FjaGVTdGF0ZUFuZEZpcmVVcmxDaGFuZ2UpOwoKICAgICAgdXJsQ2hhbmdlSW5pdCA9IHRydWU7CiAgICB9CgogICAgdXJsQ2hhbmdlTGlzdGVuZXJzLnB1c2goY2FsbGJhY2spOwogICAgcmV0dXJuIGNhbGxiYWNrOwogIH07CgogIC8qKgogICAqIENoZWNrcyB3aGV0aGVyIHRoZSB1cmwgaGFzIGNoYW5nZWQgb3V0c2lkZSBvZiBBbmd1bGFyLgogICAqIE5lZWRzIHRvIGJlIGV4cG9ydGVkIHRvIGJlIGFibGUgdG8gY2hlY2sgZm9yIGNoYW5nZXMgdGhhdCBoYXZlIGJlZW4gZG9uZSBpbiBzeW5jLAogICAqIGFzIGhhc2hjaGFuZ2UvcG9wc3RhdGUgZXZlbnRzIGZpcmUgaW4gYXN5bmMuCiAgICovCiAgc2VsZi4kJGNoZWNrVXJsQ2hhbmdlID0gZmlyZVVybENoYW5nZTsKCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAvLyBNaXNjIEFQSQogIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgogIC8qKgogICAqIEBuYW1lICRicm93c2VyI2Jhc2VIcmVmCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBSZXR1cm5zIGN1cnJlbnQgPGJhc2UgaHJlZj4KICAgKiAoYWx3YXlzIHJlbGF0aXZlIC0gd2l0aG91dCBkb21haW4pCiAgICoKICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudCBiYXNlIGhyZWYKICAgKi8KICBzZWxmLmJhc2VIcmVmID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgaHJlZiA9IGJhc2VFbGVtZW50LmF0dHIoJ2hyZWYnKTsKICAgIHJldHVybiBocmVmID8gaHJlZi5yZXBsYWNlKC9eKGh0dHBzP1w6KT9cL1wvW15cL10qLywgJycpIDogJyc7CiAgfTsKCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAvLyBDb29raWVzIEFQSQogIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgdmFyIGxhc3RDb29raWVzID0ge307CiAgdmFyIGxhc3RDb29raWVTdHJpbmcgPSAnJzsKICB2YXIgY29va2llUGF0aCA9IHNlbGYuYmFzZUhyZWYoKTsKCiAgZnVuY3Rpb24gc2FmZURlY29kZVVSSUNvbXBvbmVudChzdHIpIHsKICAgIHRyeSB7CiAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgcmV0dXJuIHN0cjsKICAgIH0KICB9CgogIC8qKgogICAqIEBuYW1lICRicm93c2VyI2Nvb2tpZXMKICAgKgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBDb29raWUgbmFtZQogICAqIEBwYXJhbSB7c3RyaW5nPX0gdmFsdWUgQ29va2llIHZhbHVlCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBUaGUgY29va2llcyBtZXRob2QgcHJvdmlkZXMgYSAncHJpdmF0ZScgbG93IGxldmVsIGFjY2VzcyB0byBicm93c2VyIGNvb2tpZXMuCiAgICogSXQgaXMgbm90IG1lYW50IHRvIGJlIHVzZWQgZGlyZWN0bHksIHVzZSB0aGUgJGNvb2tpZSBzZXJ2aWNlIGluc3RlYWQuCiAgICoKICAgKiBUaGUgcmV0dXJuIHZhbHVlcyB2YXJ5IGRlcGVuZGluZyBvbiB0aGUgYXJndW1lbnRzIHRoYXQgdGhlIG1ldGhvZCB3YXMgY2FsbGVkIHdpdGggYXMgZm9sbG93czoKICAgKgogICAqIC0gY29va2llcygpIC0+IGhhc2ggb2YgYWxsIGNvb2tpZXMsIHRoaXMgaXMgTk9UIGEgY29weSBvZiB0aGUgaW50ZXJuYWwgc3RhdGUsIHNvIGRvIG5vdCBtb2RpZnkKICAgKiAgIGl0CiAgICogLSBjb29raWVzKG5hbWUsIHZhbHVlKSAtPiBzZXQgbmFtZSB0byB2YWx1ZSwgaWYgdmFsdWUgaXMgdW5kZWZpbmVkIGRlbGV0ZSB0aGUgY29va2llCiAgICogLSBjb29raWVzKG5hbWUpIC0+IHRoZSBzYW1lIGFzIChuYW1lLCB1bmRlZmluZWQpID09IERFTEVURVMgKG5vIG9uZSBjYWxscyBpdCByaWdodCBub3cgdGhhdAogICAqICAgd2F5KQogICAqCiAgICogQHJldHVybnMge09iamVjdH0gSGFzaCBvZiBhbGwgY29va2llcyAoaWYgY2FsbGVkIHdpdGhvdXQgYW55IHBhcmFtZXRlcikKICAgKi8KICBzZWxmLmNvb2tpZXMgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkgewogICAgdmFyIGNvb2tpZUxlbmd0aCwgY29va2llQXJyYXksIGNvb2tpZSwgaSwgaW5kZXg7CgogICAgaWYgKG5hbWUpIHsKICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHsKICAgICAgICByYXdEb2N1bWVudC5jb29raWUgPSBlbmNvZGVVUklDb21wb25lbnQobmFtZSkgKyAiPTtwYXRoPSIgKyBjb29raWVQYXRoICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiO2V4cGlyZXM9VGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMCBHTVQiOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHsKICAgICAgICAgIGNvb2tpZUxlbmd0aCA9IChyYXdEb2N1bWVudC5jb29raWUgPSBlbmNvZGVVUklDb21wb25lbnQobmFtZSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnO3BhdGg9JyArIGNvb2tpZVBhdGgpLmxlbmd0aCArIDE7CgogICAgICAgICAgLy8gcGVyIGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIxMDkudHh0IGJyb3dzZXIgbXVzdCBhbGxvdyBhdCBtaW5pbXVtOgogICAgICAgICAgLy8gLSAzMDAgY29va2llcwogICAgICAgICAgLy8gLSAyMCBjb29raWVzIHBlciB1bmlxdWUgZG9tYWluCiAgICAgICAgICAvLyAtIDQwOTYgYnl0ZXMgcGVyIGNvb2tpZQogICAgICAgICAgaWYgKGNvb2tpZUxlbmd0aCA+IDQwOTYpIHsKICAgICAgICAgICAgJGxvZy53YXJuKCJDb29raWUgJyIgKyBuYW1lICsKICAgICAgICAgICAgICAiJyBwb3NzaWJseSBub3Qgc2V0IG9yIG92ZXJmbG93ZWQgYmVjYXVzZSBpdCB3YXMgdG9vIGxhcmdlICgiICsKICAgICAgICAgICAgICBjb29raWVMZW5ndGggKyAiID4gNDA5NiBieXRlcykhIik7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgewogICAgICBpZiAocmF3RG9jdW1lbnQuY29va2llICE9PSBsYXN0Q29va2llU3RyaW5nKSB7CiAgICAgICAgbGFzdENvb2tpZVN0cmluZyA9IHJhd0RvY3VtZW50LmNvb2tpZTsKICAgICAgICBjb29raWVBcnJheSA9IGxhc3RDb29raWVTdHJpbmcuc3BsaXQoIjsgIik7CiAgICAgICAgbGFzdENvb2tpZXMgPSB7fTsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZUFycmF5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICBjb29raWUgPSBjb29raWVBcnJheVtpXTsKICAgICAgICAgIGluZGV4ID0gY29va2llLmluZGV4T2YoJz0nKTsKICAgICAgICAgIGlmIChpbmRleCA+IDApIHsgLy9pZ25vcmUgbmFtZWxlc3MgY29va2llcwogICAgICAgICAgICBuYW1lID0gc2FmZURlY29kZVVSSUNvbXBvbmVudChjb29raWUuc3Vic3RyaW5nKDAsIGluZGV4KSk7CiAgICAgICAgICAgIC8vIHRoZSBmaXJzdCB2YWx1ZSB0aGF0IGlzIHNlZW4gZm9yIGEgY29va2llIGlzIHRoZSBtb3N0CiAgICAgICAgICAgIC8vIHNwZWNpZmljIG9uZS4gIHZhbHVlcyBmb3IgdGhlIHNhbWUgY29va2llIG5hbWUgdGhhdAogICAgICAgICAgICAvLyBmb2xsb3cgYXJlIGZvciBsZXNzIHNwZWNpZmljIHBhdGhzLgogICAgICAgICAgICBpZiAobGFzdENvb2tpZXNbbmFtZV0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgIGxhc3RDb29raWVzW25hbWVdID0gc2FmZURlY29kZVVSSUNvbXBvbmVudChjb29raWUuc3Vic3RyaW5nKGluZGV4ICsgMSkpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBsYXN0Q29va2llczsKICAgIH0KICB9OwoKCiAgLyoqCiAgICogQG5hbWUgJGJyb3dzZXIjZGVmZXIKICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGZuIEEgZnVuY3Rpb24sIHdobydzIGV4ZWN1dGlvbiBzaG91bGQgYmUgZGVmZXJyZWQuCiAgICogQHBhcmFtIHtudW1iZXI9fSBbZGVsYXk9MF0gb2YgbWlsbGlzZWNvbmRzIHRvIGRlZmVyIHRoZSBmdW5jdGlvbiBleGVjdXRpb24uCiAgICogQHJldHVybnMgeyp9IERlZmVySWQgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIHRhc2sgdmlhIGAkYnJvd3Nlci5kZWZlci5jYW5jZWwoKWAuCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBFeGVjdXRlcyBhIGZuIGFzeW5jaHJvbm91c2x5IHZpYSBgc2V0VGltZW91dChmbiwgZGVsYXkpYC4KICAgKgogICAqIFVubGlrZSB3aGVuIGNhbGxpbmcgYHNldFRpbWVvdXRgIGRpcmVjdGx5LCBpbiB0ZXN0IHRoaXMgZnVuY3Rpb24gaXMgbW9ja2VkIGFuZCBpbnN0ZWFkIG9mIHVzaW5nCiAgICogYHNldFRpbWVvdXRgIGluIHRlc3RzLCB0aGUgZm5zIGFyZSBxdWV1ZWQgaW4gYW4gYXJyYXksIHdoaWNoIGNhbiBiZSBwcm9ncmFtbWF0aWNhbGx5IGZsdXNoZWQKICAgKiB2aWEgYCRicm93c2VyLmRlZmVyLmZsdXNoKClgLgogICAqCiAgICovCiAgc2VsZi5kZWZlciA9IGZ1bmN0aW9uKGZuLCBkZWxheSkgewogICAgdmFyIHRpbWVvdXRJZDsKICAgIG91dHN0YW5kaW5nUmVxdWVzdENvdW50Kys7CiAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICBkZWxldGUgcGVuZGluZ0RlZmVySWRzW3RpbWVvdXRJZF07CiAgICAgIGNvbXBsZXRlT3V0c3RhbmRpbmdSZXF1ZXN0KGZuKTsKICAgIH0sIGRlbGF5IHx8IDApOwogICAgcGVuZGluZ0RlZmVySWRzW3RpbWVvdXRJZF0gPSB0cnVlOwogICAgcmV0dXJuIHRpbWVvdXRJZDsKICB9OwoKCiAgLyoqCiAgICogQG5hbWUgJGJyb3dzZXIjZGVmZXIuY2FuY2VsCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBDYW5jZWxzIGEgZGVmZXJyZWQgdGFzayBpZGVudGlmaWVkIHdpdGggYGRlZmVySWRgLgogICAqCiAgICogQHBhcmFtIHsqfSBkZWZlcklkIFRva2VuIHJldHVybmVkIGJ5IHRoZSBgJGJyb3dzZXIuZGVmZXJgIGZ1bmN0aW9uLgogICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdGFzayBoYXNuJ3QgZXhlY3V0ZWQgeWV0IGFuZCB3YXMgc3VjY2Vzc2Z1bGx5CiAgICogICAgICAgICAgICAgICAgICAgIGNhbmNlbGVkLgogICAqLwogIHNlbGYuZGVmZXIuY2FuY2VsID0gZnVuY3Rpb24oZGVmZXJJZCkgewogICAgaWYgKHBlbmRpbmdEZWZlcklkc1tkZWZlcklkXSkgewogICAgICBkZWxldGUgcGVuZGluZ0RlZmVySWRzW2RlZmVySWRdOwogICAgICBjbGVhclRpbWVvdXQoZGVmZXJJZCk7CiAgICAgIGNvbXBsZXRlT3V0c3RhbmRpbmdSZXF1ZXN0KG5vb3ApOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKfQoKZnVuY3Rpb24gJEJyb3dzZXJQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyR3aW5kb3cnLCAnJGxvZycsICckc25pZmZlcicsICckZG9jdW1lbnQnLAogICAgICBmdW5jdGlvbigkd2luZG93LCAkbG9nLCAkc25pZmZlciwgJGRvY3VtZW50KSB7CiAgICAgICAgcmV0dXJuIG5ldyBCcm93c2VyKCR3aW5kb3csICRkb2N1bWVudCwgJGxvZywgJHNuaWZmZXIpOwogICAgICB9XTsKfQoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICRjYWNoZUZhY3RvcnkKICoKICogQGRlc2NyaXB0aW9uCiAqIEZhY3RvcnkgdGhhdCBjb25zdHJ1Y3RzIHtAbGluayAkY2FjaGVGYWN0b3J5LkNhY2hlIENhY2hlfSBvYmplY3RzIGFuZCBnaXZlcyBhY2Nlc3MgdG8KICogdGhlbS4KICoKICogYGBganMKICoKICogIHZhciBjYWNoZSA9ICRjYWNoZUZhY3RvcnkoJ2NhY2hlSWQnKTsKICogIGV4cGVjdCgkY2FjaGVGYWN0b3J5LmdldCgnY2FjaGVJZCcpKS50b0JlKGNhY2hlKTsKICogIGV4cGVjdCgkY2FjaGVGYWN0b3J5LmdldCgnbm9TdWNoQ2FjaGVJZCcpKS5ub3QudG9CZURlZmluZWQoKTsKICoKICogIGNhY2hlLnB1dCgia2V5IiwgInZhbHVlIik7CiAqICBjYWNoZS5wdXQoImFub3RoZXIga2V5IiwgImFub3RoZXIgdmFsdWUiKTsKICoKICogIC8vIFdlJ3ZlIHNwZWNpZmllZCBubyBvcHRpb25zIG9uIGNyZWF0aW9uCiAqICBleHBlY3QoY2FjaGUuaW5mbygpKS50b0VxdWFsKHtpZDogJ2NhY2hlSWQnLCBzaXplOiAyfSk7CiAqCiAqIGBgYAogKgogKgogKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVJZCBOYW1lIG9yIGlkIG9mIHRoZSBuZXdseSBjcmVhdGVkIGNhY2hlLgogKiBAcGFyYW0ge29iamVjdD19IG9wdGlvbnMgT3B0aW9ucyBvYmplY3QgdGhhdCBzcGVjaWZpZXMgdGhlIGNhY2hlIGJlaGF2aW9yLiBQcm9wZXJ0aWVzOgogKgogKiAgIC0gYHtudW1iZXI9fWAgYGNhcGFjaXR5YCDigD8gdHVybnMgdGhlIGNhY2hlIGludG8gTFJVIGNhY2hlLgogKgogKiBAcmV0dXJucyB7b2JqZWN0fSBOZXdseSBjcmVhdGVkIGNhY2hlIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgc2V0IG9mIG1ldGhvZHM6CiAqCiAqIC0gYHtvYmplY3R9YCBgaW5mbygpYCDigD8gUmV0dXJucyBpZCwgc2l6ZSwgYW5kIG9wdGlvbnMgb2YgY2FjaGUuCiAqIC0gYHt7Kn19YCBgcHV0KHtzdHJpbmd9IGtleSwgeyp9IHZhbHVlKWAg4oA/IFB1dHMgYSBuZXcga2V5LXZhbHVlIHBhaXIgaW50byB0aGUgY2FjaGUgYW5kIHJldHVybnMKICogICBpdC4KICogLSBge3sqfX1gIGBnZXQoe3N0cmluZ30ga2V5KWAg4oA/IFJldHVybnMgY2FjaGVkIHZhbHVlIGZvciBga2V5YCBvciB1bmRlZmluZWQgZm9yIGNhY2hlIG1pc3MuCiAqIC0gYHt2b2lkfWAgYHJlbW92ZSh7c3RyaW5nfSBrZXkpYCDigD8gUmVtb3ZlcyBhIGtleS12YWx1ZSBwYWlyIGZyb20gdGhlIGNhY2hlLgogKiAtIGB7dm9pZH1gIGByZW1vdmVBbGwoKWAg4oA/IFJlbW92ZXMgYWxsIGNhY2hlZCB2YWx1ZXMuCiAqIC0gYHt2b2lkfWAgYGRlc3Ryb3koKWAg4oA/IFJlbW92ZXMgcmVmZXJlbmNlcyB0byB0aGlzIGNhY2hlIGZyb20gJGNhY2hlRmFjdG9yeS4KICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGUgbW9kdWxlPSJjYWNoZUV4YW1wbGVBcHAiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJDYWNoZUNvbnRyb2xsZXIiPgogICAgICAgICA8aW5wdXQgbmctbW9kZWw9Im5ld0NhY2hlS2V5IiBwbGFjZWhvbGRlcj0iS2V5Ij4KICAgICAgICAgPGlucHV0IG5nLW1vZGVsPSJuZXdDYWNoZVZhbHVlIiBwbGFjZWhvbGRlcj0iVmFsdWUiPgogICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSJwdXQobmV3Q2FjaGVLZXksIG5ld0NhY2hlVmFsdWUpIj5DYWNoZTwvYnV0dG9uPgoKICAgICAgICAgPHAgbmctaWY9ImtleXMubGVuZ3RoIj5DYWNoZWQgVmFsdWVzPC9wPgogICAgICAgICA8ZGl2IG5nLXJlcGVhdD0ia2V5IGluIGtleXMiPgogICAgICAgICAgIDxzcGFuIG5nLWJpbmQ9ImtleSI+PC9zcGFuPgogICAgICAgICAgIDxzcGFuPjogPC9zcGFuPgogICAgICAgICAgIDxiIG5nLWJpbmQ9ImNhY2hlLmdldChrZXkpIj48L2I+CiAgICAgICAgIDwvZGl2PgoKICAgICAgICAgPHA+Q2FjaGUgSW5mbzwvcD4KICAgICAgICAgPGRpdiBuZy1yZXBlYXQ9IihrZXksIHZhbHVlKSBpbiBjYWNoZS5pbmZvKCkiPgogICAgICAgICAgIDxzcGFuIG5nLWJpbmQ9ImtleSI+PC9zcGFuPgogICAgICAgICAgIDxzcGFuPjogPC9zcGFuPgogICAgICAgICAgIDxiIG5nLWJpbmQ9InZhbHVlIj48L2I+CiAgICAgICAgIDwvZGl2PgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+CiAgICAgICBhbmd1bGFyLm1vZHVsZSgnY2FjaGVFeGFtcGxlQXBwJywgW10pLgogICAgICAgICBjb250cm9sbGVyKCdDYWNoZUNvbnRyb2xsZXInLCBbJyRzY29wZScsICckY2FjaGVGYWN0b3J5JywgZnVuY3Rpb24oJHNjb3BlLCAkY2FjaGVGYWN0b3J5KSB7CiAgICAgICAgICAgJHNjb3BlLmtleXMgPSBbXTsKICAgICAgICAgICAkc2NvcGUuY2FjaGUgPSAkY2FjaGVGYWN0b3J5KCdjYWNoZUlkJyk7CiAgICAgICAgICAgJHNjb3BlLnB1dCA9IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHsKICAgICAgICAgICAgIGlmICgkc2NvcGUuY2FjaGUuZ2V0KGtleSkgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAkc2NvcGUua2V5cy5wdXNoKGtleSk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICAkc2NvcGUuY2FjaGUucHV0KGtleSwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IG51bGwgOiB2YWx1ZSk7CiAgICAgICAgICAgfTsKICAgICAgICAgfV0pOwogICAgIDwvZmlsZT4KICAgICA8ZmlsZSBuYW1lPSJzdHlsZS5jc3MiPgogICAgICAgcCB7CiAgICAgICAgIG1hcmdpbjogMTBweCAwIDNweDsKICAgICAgIH0KICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCmZ1bmN0aW9uICRDYWNoZUZhY3RvcnlQcm92aWRlcigpIHsKCiAgdGhpcy4kZ2V0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgY2FjaGVzID0ge307CgogICAgZnVuY3Rpb24gY2FjaGVGYWN0b3J5KGNhY2hlSWQsIG9wdGlvbnMpIHsKICAgICAgaWYgKGNhY2hlSWQgaW4gY2FjaGVzKSB7CiAgICAgICAgdGhyb3cgbWluRXJyKCckY2FjaGVGYWN0b3J5JykoJ2lpZCcsICJDYWNoZUlkICd7MH0nIGlzIGFscmVhZHkgdGFrZW4hIiwgY2FjaGVJZCk7CiAgICAgIH0KCiAgICAgIHZhciBzaXplID0gMCwKICAgICAgICAgIHN0YXRzID0gZXh0ZW5kKHt9LCBvcHRpb25zLCB7aWQ6IGNhY2hlSWR9KSwKICAgICAgICAgIGRhdGEgPSB7fSwKICAgICAgICAgIGNhcGFjaXR5ID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5jYXBhY2l0eSkgfHwgTnVtYmVyLk1BWF9WQUxVRSwKICAgICAgICAgIGxydUhhc2ggPSB7fSwKICAgICAgICAgIGZyZXNoRW5kID0gbnVsbCwKICAgICAgICAgIHN0YWxlRW5kID0gbnVsbDsKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgdHlwZQogICAgICAgKiBAbmFtZSAkY2FjaGVGYWN0b3J5LkNhY2hlCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBBIGNhY2hlIG9iamVjdCB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBkYXRhLCBwcmltYXJpbHkgdXNlZCBieQogICAgICAgKiB7QGxpbmsgJGh0dHAgJGh0dHB9IGFuZCB0aGUge0BsaW5rIG5nLmRpcmVjdGl2ZTpzY3JpcHQgc2NyaXB0fSBkaXJlY3RpdmUgdG8gY2FjaGUKICAgICAgICogdGVtcGxhdGVzIGFuZCBvdGhlciBkYXRhLgogICAgICAgKgogICAgICAgKiBgYGBqcwogICAgICAgKiAgYW5ndWxhci5tb2R1bGUoJ3N1cGVyQ2FjaGUnKQogICAgICAgKiAgICAuZmFjdG9yeSgnc3VwZXJDYWNoZScsIFsnJGNhY2hlRmFjdG9yeScsIGZ1bmN0aW9uKCRjYWNoZUZhY3RvcnkpIHsKICAgICAgICogICAgICByZXR1cm4gJGNhY2hlRmFjdG9yeSgnc3VwZXItY2FjaGUnKTsKICAgICAgICogICAgfV0pOwogICAgICAgKiBgYGAKICAgICAgICoKICAgICAgICogRXhhbXBsZSB0ZXN0OgogICAgICAgKgogICAgICAgKiBgYGBqcwogICAgICAgKiAgaXQoJ3Nob3VsZCBiZWhhdmUgbGlrZSBhIGNhY2hlJywgaW5qZWN0KGZ1bmN0aW9uKHN1cGVyQ2FjaGUpIHsKICAgICAgICogICAgc3VwZXJDYWNoZS5wdXQoJ2tleScsICd2YWx1ZScpOwogICAgICAgKiAgICBzdXBlckNhY2hlLnB1dCgnYW5vdGhlciBrZXknLCAnYW5vdGhlciB2YWx1ZScpOwogICAgICAgKgogICAgICAgKiAgICBleHBlY3Qoc3VwZXJDYWNoZS5pbmZvKCkpLnRvRXF1YWwoewogICAgICAgKiAgICAgIGlkOiAnc3VwZXItY2FjaGUnLAogICAgICAgKiAgICAgIHNpemU6IDIKICAgICAgICogICAgfSk7CiAgICAgICAqCiAgICAgICAqICAgIHN1cGVyQ2FjaGUucmVtb3ZlKCdhbm90aGVyIGtleScpOwogICAgICAgKiAgICBleHBlY3Qoc3VwZXJDYWNoZS5nZXQoJ2Fub3RoZXIga2V5JykpLnRvQmVVbmRlZmluZWQoKTsKICAgICAgICoKICAgICAgICogICAgc3VwZXJDYWNoZS5yZW1vdmVBbGwoKTsKICAgICAgICogICAgZXhwZWN0KHN1cGVyQ2FjaGUuaW5mbygpKS50b0VxdWFsKHsKICAgICAgICogICAgICBpZDogJ3N1cGVyLWNhY2hlJywKICAgICAgICogICAgICBzaXplOiAwCiAgICAgICAqICAgIH0pOwogICAgICAgKiAgfSkpOwogICAgICAgKiBgYGAKICAgICAgICovCiAgICAgIHJldHVybiBjYWNoZXNbY2FjaGVJZF0gPSB7CgogICAgICAgIC8qKgogICAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICAgKiBAbmFtZSAkY2FjaGVGYWN0b3J5LkNhY2hlI3B1dAogICAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAgICoKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBJbnNlcnRzIGEgbmFtZWQgZW50cnkgaW50byB0aGUge0BsaW5rICRjYWNoZUZhY3RvcnkuQ2FjaGUgQ2FjaGV9IG9iamVjdCB0byBiZQogICAgICAgICAqIHJldHJpZXZlZCBsYXRlciwgYW5kIGluY3JlbWVudGluZyB0aGUgc2l6ZSBvZiB0aGUgY2FjaGUgaWYgdGhlIGtleSB3YXMgbm90IGFscmVhZHkKICAgICAgICAgKiBwcmVzZW50IGluIHRoZSBjYWNoZS4gSWYgYmVoYXZpbmcgbGlrZSBhbiBMUlUgY2FjaGUsIGl0IHdpbGwgYWxzbyByZW1vdmUgc3RhbGUKICAgICAgICAgKiBlbnRyaWVzIGZyb20gdGhlIHNldC4KICAgICAgICAgKgogICAgICAgICAqIEl0IHdpbGwgbm90IGluc2VydCB1bmRlZmluZWQgdmFsdWVzIGludG8gdGhlIGNhY2hlLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSB0aGUga2V5IHVuZGVyIHdoaWNoIHRoZSBjYWNoZWQgZGF0YSBpcyBzdG9yZWQuCiAgICAgICAgICogQHBhcmFtIHsqfSB2YWx1ZSB0aGUgdmFsdWUgdG8gc3RvcmUgYWxvbmdzaWRlIHRoZSBrZXkuIElmIGl0IGlzIHVuZGVmaW5lZCwgdGhlIGtleQogICAgICAgICAqICAgIHdpbGwgbm90IGJlIHN0b3JlZC4KICAgICAgICAgKiBAcmV0dXJucyB7Kn0gdGhlIHZhbHVlIHN0b3JlZC4KICAgICAgICAgKi8KICAgICAgICBwdXQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHsKICAgICAgICAgIGlmIChjYXBhY2l0eSA8IE51bWJlci5NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdmFyIGxydUVudHJ5ID0gbHJ1SGFzaFtrZXldIHx8IChscnVIYXNoW2tleV0gPSB7a2V5OiBrZXl9KTsKCiAgICAgICAgICAgIHJlZnJlc2gobHJ1RW50cnkpOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpIHJldHVybjsKICAgICAgICAgIGlmICghKGtleSBpbiBkYXRhKSkgc2l6ZSsrOwogICAgICAgICAgZGF0YVtrZXldID0gdmFsdWU7CgogICAgICAgICAgaWYgKHNpemUgPiBjYXBhY2l0eSkgewogICAgICAgICAgICB0aGlzLnJlbW92ZShzdGFsZUVuZC5rZXkpOwogICAgICAgICAgfQoKICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICogQG5hbWUgJGNhY2hlRmFjdG9yeS5DYWNoZSNnZXQKICAgICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICogUmV0cmlldmVzIG5hbWVkIGRhdGEgc3RvcmVkIGluIHRoZSB7QGxpbmsgJGNhY2hlRmFjdG9yeS5DYWNoZSBDYWNoZX0gb2JqZWN0LgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSB0aGUga2V5IG9mIHRoZSBkYXRhIHRvIGJlIHJldHJpZXZlZAogICAgICAgICAqIEByZXR1cm5zIHsqfSB0aGUgdmFsdWUgc3RvcmVkLgogICAgICAgICAqLwogICAgICAgIGdldDogZnVuY3Rpb24oa2V5KSB7CiAgICAgICAgICBpZiAoY2FwYWNpdHkgPCBOdW1iZXIuTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHZhciBscnVFbnRyeSA9IGxydUhhc2hba2V5XTsKCiAgICAgICAgICAgIGlmICghbHJ1RW50cnkpIHJldHVybjsKCiAgICAgICAgICAgIHJlZnJlc2gobHJ1RW50cnkpOwogICAgICAgICAgfQoKICAgICAgICAgIHJldHVybiBkYXRhW2tleV07CiAgICAgICAgfSwKCgogICAgICAgIC8qKgogICAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICAgKiBAbmFtZSAkY2FjaGVGYWN0b3J5LkNhY2hlI3JlbW92ZQogICAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAgICoKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBSZW1vdmVzIGFuIGVudHJ5IGZyb20gdGhlIHtAbGluayAkY2FjaGVGYWN0b3J5LkNhY2hlIENhY2hlfSBvYmplY3QuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IHRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGJlIHJlbW92ZWQKICAgICAgICAgKi8KICAgICAgICByZW1vdmU6IGZ1bmN0aW9uKGtleSkgewogICAgICAgICAgaWYgKGNhcGFjaXR5IDwgTnVtYmVyLk1BWF9WQUxVRSkgewogICAgICAgICAgICB2YXIgbHJ1RW50cnkgPSBscnVIYXNoW2tleV07CgogICAgICAgICAgICBpZiAoIWxydUVudHJ5KSByZXR1cm47CgogICAgICAgICAgICBpZiAobHJ1RW50cnkgPT0gZnJlc2hFbmQpIGZyZXNoRW5kID0gbHJ1RW50cnkucDsKICAgICAgICAgICAgaWYgKGxydUVudHJ5ID09IHN0YWxlRW5kKSBzdGFsZUVuZCA9IGxydUVudHJ5Lm47CiAgICAgICAgICAgIGxpbmsobHJ1RW50cnkubixscnVFbnRyeS5wKTsKCiAgICAgICAgICAgIGRlbGV0ZSBscnVIYXNoW2tleV07CiAgICAgICAgICB9CgogICAgICAgICAgZGVsZXRlIGRhdGFba2V5XTsKICAgICAgICAgIHNpemUtLTsKICAgICAgICB9LAoKCiAgICAgICAgLyoqCiAgICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgICAqIEBuYW1lICRjYWNoZUZhY3RvcnkuQ2FjaGUjcmVtb3ZlQWxsCiAgICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICAgKgogICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAqIENsZWFycyB0aGUgY2FjaGUgb2JqZWN0IG9mIGFueSBlbnRyaWVzLgogICAgICAgICAqLwogICAgICAgIHJlbW92ZUFsbDogZnVuY3Rpb24oKSB7CiAgICAgICAgICBkYXRhID0ge307CiAgICAgICAgICBzaXplID0gMDsKICAgICAgICAgIGxydUhhc2ggPSB7fTsKICAgICAgICAgIGZyZXNoRW5kID0gc3RhbGVFbmQgPSBudWxsOwogICAgICAgIH0sCgoKICAgICAgICAvKioKICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICogQG5hbWUgJGNhY2hlRmFjdG9yeS5DYWNoZSNkZXN0cm95CiAgICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICAgKgogICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAqIERlc3Ryb3lzIHRoZSB7QGxpbmsgJGNhY2hlRmFjdG9yeS5DYWNoZSBDYWNoZX0gb2JqZWN0IGVudGlyZWx5LAogICAgICAgICAqIHJlbW92aW5nIGl0IGZyb20gdGhlIHtAbGluayAkY2FjaGVGYWN0b3J5ICRjYWNoZUZhY3Rvcnl9IHNldC4KICAgICAgICAgKi8KICAgICAgICBkZXN0cm95OiBmdW5jdGlvbigpIHsKICAgICAgICAgIGRhdGEgPSBudWxsOwogICAgICAgICAgc3RhdHMgPSBudWxsOwogICAgICAgICAgbHJ1SGFzaCA9IG51bGw7CiAgICAgICAgICBkZWxldGUgY2FjaGVzW2NhY2hlSWRdOwogICAgICAgIH0sCgoKICAgICAgICAvKioKICAgICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAgICogQG5hbWUgJGNhY2hlRmFjdG9yeS5DYWNoZSNpbmZvCiAgICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICAgKgogICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAqIFJldHJpZXZlIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBhIHBhcnRpY3VsYXIge0BsaW5rICRjYWNoZUZhY3RvcnkuQ2FjaGUgQ2FjaGV9LgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybnMge29iamVjdH0gYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogICAgICAgICAqICAgPHVsPgogICAgICAgICAqICAgICA8bGk+KippZCoqOiB0aGUgaWQgb2YgdGhlIGNhY2hlIGluc3RhbmNlPC9saT4KICAgICAgICAgKiAgICAgPGxpPioqc2l6ZSoqOiB0aGUgbnVtYmVyIG9mIGVudHJpZXMga2VwdCBpbiB0aGUgY2FjaGUgaW5zdGFuY2U8L2xpPgogICAgICAgICAqICAgICA8bGk+KiouLi4qKjogYW55IGFkZGl0aW9uYWwgcHJvcGVydGllcyBmcm9tIHRoZSBvcHRpb25zIG9iamVjdCB3aGVuIGNyZWF0aW5nIHRoZQogICAgICAgICAqICAgICAgIGNhY2hlLjwvbGk+CiAgICAgICAgICogICA8L3VsPgogICAgICAgICAqLwogICAgICAgIGluZm86IGZ1bmN0aW9uKCkgewogICAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgc3RhdHMsIHtzaXplOiBzaXplfSk7CiAgICAgICAgfQogICAgICB9OwoKCiAgICAgIC8qKgogICAgICAgKiBtYWtlcyB0aGUgYGVudHJ5YCB0aGUgZnJlc2hFbmQgb2YgdGhlIExSVSBsaW5rZWQgbGlzdAogICAgICAgKi8KICAgICAgZnVuY3Rpb24gcmVmcmVzaChlbnRyeSkgewogICAgICAgIGlmIChlbnRyeSAhPSBmcmVzaEVuZCkgewogICAgICAgICAgaWYgKCFzdGFsZUVuZCkgewogICAgICAgICAgICBzdGFsZUVuZCA9IGVudHJ5OwogICAgICAgICAgfSBlbHNlIGlmIChzdGFsZUVuZCA9PSBlbnRyeSkgewogICAgICAgICAgICBzdGFsZUVuZCA9IGVudHJ5Lm47CiAgICAgICAgICB9CgogICAgICAgICAgbGluayhlbnRyeS5uLCBlbnRyeS5wKTsKICAgICAgICAgIGxpbmsoZW50cnksIGZyZXNoRW5kKTsKICAgICAgICAgIGZyZXNoRW5kID0gZW50cnk7CiAgICAgICAgICBmcmVzaEVuZC5uID0gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCgogICAgICAvKioKICAgICAgICogYmlkaXJlY3Rpb25hbGx5IGxpbmtzIHR3byBlbnRyaWVzIG9mIHRoZSBMUlUgbGlua2VkIGxpc3QKICAgICAgICovCiAgICAgIGZ1bmN0aW9uIGxpbmsobmV4dEVudHJ5LCBwcmV2RW50cnkpIHsKICAgICAgICBpZiAobmV4dEVudHJ5ICE9IHByZXZFbnRyeSkgewogICAgICAgICAgaWYgKG5leHRFbnRyeSkgbmV4dEVudHJ5LnAgPSBwcmV2RW50cnk7IC8vcCBzdGFuZHMgZm9yIHByZXZpb3VzLCAncHJldicgZGlkbid0IG1pbmlmeQogICAgICAgICAgaWYgKHByZXZFbnRyeSkgcHJldkVudHJ5Lm4gPSBuZXh0RW50cnk7IC8vbiBzdGFuZHMgZm9yIG5leHQsICduZXh0JyBkaWRuJ3QgbWluaWZ5CiAgICAgICAgfQogICAgICB9CiAgICB9CgoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGNhY2hlRmFjdG9yeSNpbmZvCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYWxsIHRoZSBjYWNoZXMgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZAogICAqCiAgICogQHJldHVybnMge09iamVjdH0gLSBrZXktdmFsdWUgbWFwIG9mIGBjYWNoZUlkYCB0byB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgYGNhY2hlI2luZm9gCiAgICovCiAgICBjYWNoZUZhY3RvcnkuaW5mbyA9IGZ1bmN0aW9uKCkgewogICAgICB2YXIgaW5mbyA9IHt9OwogICAgICBmb3JFYWNoKGNhY2hlcywgZnVuY3Rpb24oY2FjaGUsIGNhY2hlSWQpIHsKICAgICAgICBpbmZvW2NhY2hlSWRdID0gY2FjaGUuaW5mbygpOwogICAgICB9KTsKICAgICAgcmV0dXJuIGluZm87CiAgICB9OwoKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRjYWNoZUZhY3RvcnkjZ2V0CiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBHZXQgYWNjZXNzIHRvIGEgY2FjaGUgb2JqZWN0IGJ5IHRoZSBgY2FjaGVJZGAgdXNlZCB3aGVuIGl0IHdhcyBjcmVhdGVkLgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlSWQgTmFtZSBvciBpZCBvZiBhIGNhY2hlIHRvIGFjY2Vzcy4KICAgKiBAcmV0dXJucyB7b2JqZWN0fSBDYWNoZSBvYmplY3QgaWRlbnRpZmllZCBieSB0aGUgY2FjaGVJZCBvciB1bmRlZmluZWQgaWYgbm8gc3VjaCBjYWNoZS4KICAgKi8KICAgIGNhY2hlRmFjdG9yeS5nZXQgPSBmdW5jdGlvbihjYWNoZUlkKSB7CiAgICAgIHJldHVybiBjYWNoZXNbY2FjaGVJZF07CiAgICB9OwoKCiAgICByZXR1cm4gY2FjaGVGYWN0b3J5OwogIH07Cn0KCi8qKgogKiBAbmdkb2Mgc2VydmljZQogKiBAbmFtZSAkdGVtcGxhdGVDYWNoZQogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGZpcnN0IHRpbWUgYSB0ZW1wbGF0ZSBpcyB1c2VkLCBpdCBpcyBsb2FkZWQgaW4gdGhlIHRlbXBsYXRlIGNhY2hlIGZvciBxdWljayByZXRyaWV2YWwuIFlvdQogKiBjYW4gbG9hZCB0ZW1wbGF0ZXMgZGlyZWN0bHkgaW50byB0aGUgY2FjaGUgaW4gYSBgc2NyaXB0YCB0YWcsIG9yIGJ5IGNvbnN1bWluZyB0aGUKICogYCR0ZW1wbGF0ZUNhY2hlYCBzZXJ2aWNlIGRpcmVjdGx5LgogKgogKiBBZGRpbmcgdmlhIHRoZSBgc2NyaXB0YCB0YWc6CiAqCiAqIGBgYGh0bWwKICogICA8c2NyaXB0IHR5cGU9InRleHQvbmctdGVtcGxhdGUiIGlkPSJ0ZW1wbGF0ZUlkLmh0bWwiPgogKiAgICAgPHA+VGhpcyBpcyB0aGUgY29udGVudCBvZiB0aGUgdGVtcGxhdGU8L3A+CiAqICAgPC9zY3JpcHQ+CiAqIGBgYAogKgogKiAqKk5vdGU6KiogdGhlIGBzY3JpcHRgIHRhZyBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZSBkb2VzIG5vdCBuZWVkIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBgaGVhZGAgb2YKICogdGhlIGRvY3VtZW50LCBidXQgaXQgbXVzdCBiZSBhIGRlc2NlbmRlbnQgb2YgdGhlIHtAbGluayBuZy4kcm9vdEVsZW1lbnQgJHJvb3RFbGVtZW50fSAoSUUsCiAqIGVsZW1lbnQgd2l0aCBuZy1hcHAgYXR0cmlidXRlKSwgb3RoZXJ3aXNlIHRoZSB0ZW1wbGF0ZSB3aWxsIGJlIGlnbm9yZWQuCiAqCiAqIEFkZGluZyB2aWEgdGhlICR0ZW1wbGF0ZUNhY2hlIHNlcnZpY2U6CiAqCiAqIGBgYGpzCiAqIHZhciBteUFwcCA9IGFuZ3VsYXIubW9kdWxlKCdteUFwcCcsIFtdKTsKICogbXlBcHAucnVuKGZ1bmN0aW9uKCR0ZW1wbGF0ZUNhY2hlKSB7CiAqICAgJHRlbXBsYXRlQ2FjaGUucHV0KCd0ZW1wbGF0ZUlkLmh0bWwnLCAnVGhpcyBpcyB0aGUgY29udGVudCBvZiB0aGUgdGVtcGxhdGUnKTsKICogfSk7CiAqIGBgYAogKgogKiBUbyByZXRyaWV2ZSB0aGUgdGVtcGxhdGUgbGF0ZXIsIHNpbXBseSB1c2UgaXQgaW4geW91ciBIVE1MOgogKiBgYGBodG1sCiAqIDxkaXYgbmctaW5jbHVkZT0iICd0ZW1wbGF0ZUlkLmh0bWwnICI+PC9kaXY+CiAqIGBgYAogKgogKiBvciBnZXQgaXQgdmlhIEphdmFzY3JpcHQ6CiAqIGBgYGpzCiAqICR0ZW1wbGF0ZUNhY2hlLmdldCgndGVtcGxhdGVJZC5odG1sJykKICogYGBgCiAqCiAqIFNlZSB7QGxpbmsgbmcuJGNhY2hlRmFjdG9yeSAkY2FjaGVGYWN0b3J5fS4KICoKICovCmZ1bmN0aW9uICRUZW1wbGF0ZUNhY2hlUHJvdmlkZXIoKSB7CiAgdGhpcy4kZ2V0ID0gWyckY2FjaGVGYWN0b3J5JywgZnVuY3Rpb24oJGNhY2hlRmFjdG9yeSkgewogICAgcmV0dXJuICRjYWNoZUZhY3RvcnkoJ3RlbXBsYXRlcycpOwogIH1dOwp9CgovKiAhIFZBUklBQkxFL0ZVTkNUSU9OIE5BTUlORyBDT05WRU5USU9OUyBUSEFUIEFQUExZIFRPIFRISVMgRklMRSEKICoKICogRE9NLXJlbGF0ZWQgdmFyaWFibGVzOgogKgogKiAtICJub2RlIiAtIERPTSBOb2RlCiAqIC0gImVsZW1lbnQiIC0gRE9NIEVsZW1lbnQgb3IgTm9kZQogKiAtICIkbm9kZSIgb3IgIiRlbGVtZW50IiAtIGpxTGl0ZS13cmFwcGVkIG5vZGUgb3IgZWxlbWVudAogKgogKgogKiBDb21waWxlciByZWxhdGVkIHN0dWZmOgogKgogKiAtICJsaW5rRm4iIC0gbGlua2luZyBmbiBvZiBhIHNpbmdsZSBkaXJlY3RpdmUKICogLSAibm9kZUxpbmtGbiIgLSBmdW5jdGlvbiB0aGF0IGFnZ3JlZ2F0ZXMgYWxsIGxpbmtpbmcgZm5zIGZvciBhIHBhcnRpY3VsYXIgbm9kZQogKiAtICJjaGlsZExpbmtGbiIgLSAgZnVuY3Rpb24gdGhhdCBhZ2dyZWdhdGVzIGFsbCBsaW5raW5nIGZucyBmb3IgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyIG5vZGUKICogLSAiY29tcG9zaXRlTGlua0ZuIiAtIGZ1bmN0aW9uIHRoYXQgYWdncmVnYXRlcyBhbGwgbGlua2luZyBmbnMgZm9yIGEgY29tcGlsYXRpb24gcm9vdCAobm9kZUxpc3QpCiAqLwoKCi8qKgogKiBAbmdkb2Mgc2VydmljZQogKiBAbmFtZSAkY29tcGlsZQogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogQ29tcGlsZXMgYW4gSFRNTCBzdHJpbmcgb3IgRE9NIGludG8gYSB0ZW1wbGF0ZSBhbmQgcHJvZHVjZXMgYSB0ZW1wbGF0ZSBmdW5jdGlvbiwgd2hpY2gKICogY2FuIHRoZW4gYmUgdXNlZCB0byBsaW5rIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIGBzY29wZWB9IGFuZCB0aGUgdGVtcGxhdGUgdG9nZXRoZXIuCiAqCiAqIFRoZSBjb21waWxhdGlvbiBpcyBhIHByb2Nlc3Mgb2Ygd2Fsa2luZyB0aGUgRE9NIHRyZWUgYW5kIG1hdGNoaW5nIERPTSBlbGVtZW50cyB0bwogKiB7QGxpbmsgbmcuJGNvbXBpbGVQcm92aWRlciNkaXJlY3RpdmUgZGlyZWN0aXZlc30uCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXdhcm5pbmciPgogKiAqKk5vdGU6KiogVGhpcyBkb2N1bWVudCBpcyBhbiBpbi1kZXB0aCByZWZlcmVuY2Ugb2YgYWxsIGRpcmVjdGl2ZSBvcHRpb25zLgogKiBGb3IgYSBnZW50bGUgaW50cm9kdWN0aW9uIHRvIGRpcmVjdGl2ZXMgd2l0aCBleGFtcGxlcyBvZiBjb21tb24gdXNlIGNhc2VzLAogKiBzZWUgdGhlIHtAbGluayBndWlkZS9kaXJlY3RpdmUgZGlyZWN0aXZlIGd1aWRlfS4KICogPC9kaXY+CiAqCiAqICMjIENvbXByZWhlbnNpdmUgRGlyZWN0aXZlIEFQSQogKgogKiBUaGVyZSBhcmUgbWFueSBkaWZmZXJlbnQgb3B0aW9ucyBmb3IgYSBkaXJlY3RpdmUuCiAqCiAqIFRoZSBkaWZmZXJlbmNlIHJlc2lkZXMgaW4gdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZmFjdG9yeSBmdW5jdGlvbi4KICogWW91IGNhbiBlaXRoZXIgcmV0dXJuIGEgIkRpcmVjdGl2ZSBEZWZpbml0aW9uIE9iamVjdCIgKHNlZSBiZWxvdykgdGhhdCBkZWZpbmVzIHRoZSBkaXJlY3RpdmUgcHJvcGVydGllcywKICogb3IganVzdCB0aGUgYHBvc3RMaW5rYCBmdW5jdGlvbiAoYWxsIG90aGVyIHByb3BlcnRpZXMgd2lsbCBoYXZlIHRoZSBkZWZhdWx0IHZhbHVlcykuCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MiPgogKiAqKkJlc3QgUHJhY3RpY2U6KiogSXQncyByZWNvbW1lbmRlZCB0byB1c2UgdGhlICJkaXJlY3RpdmUgZGVmaW5pdGlvbiBvYmplY3QiIGZvcm0uCiAqIDwvZGl2PgogKgogKiBIZXJlJ3MgYW4gZXhhbXBsZSBkaXJlY3RpdmUgZGVjbGFyZWQgd2l0aCBhIERpcmVjdGl2ZSBEZWZpbml0aW9uIE9iamVjdDoKICoKICogYGBganMKICogICB2YXIgbXlNb2R1bGUgPSBhbmd1bGFyLm1vZHVsZSguLi4pOwogKgogKiAgIG15TW9kdWxlLmRpcmVjdGl2ZSgnZGlyZWN0aXZlTmFtZScsIGZ1bmN0aW9uIGZhY3RvcnkoaW5qZWN0YWJsZXMpIHsKICogICAgIHZhciBkaXJlY3RpdmVEZWZpbml0aW9uT2JqZWN0ID0gewogKiAgICAgICBwcmlvcml0eTogMCwKICogICAgICAgdGVtcGxhdGU6ICc8ZGl2PjwvZGl2PicsIC8vIG9yIC8vIGZ1bmN0aW9uKHRFbGVtZW50LCB0QXR0cnMpIHsgLi4uIH0sCiAqICAgICAgIC8vIG9yCiAqICAgICAgIC8vIHRlbXBsYXRlVXJsOiAnZGlyZWN0aXZlLmh0bWwnLCAvLyBvciAvLyBmdW5jdGlvbih0RWxlbWVudCwgdEF0dHJzKSB7IC4uLiB9LAogKiAgICAgICB0cmFuc2NsdWRlOiBmYWxzZSwKICogICAgICAgcmVzdHJpY3Q6ICdBJywKICogICAgICAgdGVtcGxhdGVOYW1lc3BhY2U6ICdodG1sJywKICogICAgICAgc2NvcGU6IGZhbHNlLAogKiAgICAgICBjb250cm9sbGVyOiBmdW5jdGlvbigkc2NvcGUsICRlbGVtZW50LCAkYXR0cnMsICR0cmFuc2NsdWRlLCBvdGhlckluamVjdGFibGVzKSB7IC4uLiB9LAogKiAgICAgICBjb250cm9sbGVyQXM6ICdzdHJpbmdBbGlhcycsCiAqICAgICAgIHJlcXVpcmU6ICdzaWJsaW5nRGlyZWN0aXZlTmFtZScsIC8vIG9yIC8vIFsnXnBhcmVudERpcmVjdGl2ZU5hbWUnLCAnP29wdGlvbmFsRGlyZWN0aXZlTmFtZScsICc/Xm9wdGlvbmFsUGFyZW50J10sCiAqICAgICAgIGNvbXBpbGU6IGZ1bmN0aW9uIGNvbXBpbGUodEVsZW1lbnQsIHRBdHRycywgdHJhbnNjbHVkZSkgewogKiAgICAgICAgIHJldHVybiB7CiAqICAgICAgICAgICBwcmU6IGZ1bmN0aW9uIHByZUxpbmsoc2NvcGUsIGlFbGVtZW50LCBpQXR0cnMsIGNvbnRyb2xsZXIpIHsgLi4uIH0sCiAqICAgICAgICAgICBwb3N0OiBmdW5jdGlvbiBwb3N0TGluayhzY29wZSwgaUVsZW1lbnQsIGlBdHRycywgY29udHJvbGxlcikgeyAuLi4gfQogKiAgICAgICAgIH0KICogICAgICAgICAvLyBvcgogKiAgICAgICAgIC8vIHJldHVybiBmdW5jdGlvbiBwb3N0TGluayggLi4uICkgeyAuLi4gfQogKiAgICAgICB9LAogKiAgICAgICAvLyBvcgogKiAgICAgICAvLyBsaW5rOiB7CiAqICAgICAgIC8vICBwcmU6IGZ1bmN0aW9uIHByZUxpbmsoc2NvcGUsIGlFbGVtZW50LCBpQXR0cnMsIGNvbnRyb2xsZXIpIHsgLi4uIH0sCiAqICAgICAgIC8vICBwb3N0OiBmdW5jdGlvbiBwb3N0TGluayhzY29wZSwgaUVsZW1lbnQsIGlBdHRycywgY29udHJvbGxlcikgeyAuLi4gfQogKiAgICAgICAvLyB9CiAqICAgICAgIC8vIG9yCiAqICAgICAgIC8vIGxpbms6IGZ1bmN0aW9uIHBvc3RMaW5rKCAuLi4gKSB7IC4uLiB9CiAqICAgICB9OwogKiAgICAgcmV0dXJuIGRpcmVjdGl2ZURlZmluaXRpb25PYmplY3Q7CiAqICAgfSk7CiAqIGBgYAogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICogKipOb3RlOioqIEFueSB1bnNwZWNpZmllZCBvcHRpb25zIHdpbGwgdXNlIHRoZSBkZWZhdWx0IHZhbHVlLiBZb3UgY2FuIHNlZSB0aGUgZGVmYXVsdCB2YWx1ZXMgYmVsb3cuCiAqIDwvZGl2PgogKgogKiBUaGVyZWZvcmUgdGhlIGFib3ZlIGNhbiBiZSBzaW1wbGlmaWVkIGFzOgogKgogKiBgYGBqcwogKiAgIHZhciBteU1vZHVsZSA9IGFuZ3VsYXIubW9kdWxlKC4uLik7CiAqCiAqICAgbXlNb2R1bGUuZGlyZWN0aXZlKCdkaXJlY3RpdmVOYW1lJywgZnVuY3Rpb24gZmFjdG9yeShpbmplY3RhYmxlcykgewogKiAgICAgdmFyIGRpcmVjdGl2ZURlZmluaXRpb25PYmplY3QgPSB7CiAqICAgICAgIGxpbms6IGZ1bmN0aW9uIHBvc3RMaW5rKHNjb3BlLCBpRWxlbWVudCwgaUF0dHJzKSB7IC4uLiB9CiAqICAgICB9OwogKiAgICAgcmV0dXJuIGRpcmVjdGl2ZURlZmluaXRpb25PYmplY3Q7CiAqICAgICAvLyBvcgogKiAgICAgLy8gcmV0dXJuIGZ1bmN0aW9uIHBvc3RMaW5rKHNjb3BlLCBpRWxlbWVudCwgaUF0dHJzKSB7IC4uLiB9CiAqICAgfSk7CiAqIGBgYAogKgogKgogKgogKiAjIyMgRGlyZWN0aXZlIERlZmluaXRpb24gT2JqZWN0CiAqCiAqIFRoZSBkaXJlY3RpdmUgZGVmaW5pdGlvbiBvYmplY3QgcHJvdmlkZXMgaW5zdHJ1Y3Rpb25zIHRvIHRoZSB7QGxpbmsgbmcuJGNvbXBpbGUKICogY29tcGlsZXJ9LiBUaGUgYXR0cmlidXRlcyBhcmU6CiAqCiAqICMjIyMgYG11bHRpRWxlbWVudGAKICogV2hlbiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byB0cnVlLCB0aGUgSFRNTCBjb21waWxlciB3aWxsIGNvbGxlY3QgRE9NIG5vZGVzIGJldHdlZW4KICogbm9kZXMgd2l0aCB0aGUgYXR0cmlidXRlcyBgZGlyZWN0aXZlLW5hbWUtc3RhcnRgIGFuZCBgZGlyZWN0aXZlLW5hbWUtZW5kYCwgYW5kIGdyb3VwIHRoZW0KICogdG9nZXRoZXIgYXMgdGhlIGRpcmVjdGl2ZSBlbGVtZW50cy4gSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGlzIGZlYXR1cmUgYmUgdXNlZCBvbiBkaXJlY3RpdmVzCiAqIHdoaWNoIGFyZSBub3Qgc3RyaWN0bHkgYmVoYXZpb3VyYWwgKHN1Y2ggYXMge0BsaW5rIG5nQ2xpY2t9KSwgYW5kIHdoaWNoCiAqIGRvIG5vdCBtYW5pcHVsYXRlIG9yIHJlcGxhY2UgY2hpbGQgbm9kZXMgKHN1Y2ggYXMge0BsaW5rIG5nSW5jbHVkZX0pLgogKgogKiAjIyMjIGBwcmlvcml0eWAKICogV2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgZGlyZWN0aXZlcyBkZWZpbmVkIG9uIGEgc2luZ2xlIERPTSBlbGVtZW50LCBzb21ldGltZXMgaXQKICogaXMgbmVjZXNzYXJ5IHRvIHNwZWNpZnkgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSBkaXJlY3RpdmVzIGFyZSBhcHBsaWVkLiBUaGUgYHByaW9yaXR5YCBpcyB1c2VkCiAqIHRvIHNvcnQgdGhlIGRpcmVjdGl2ZXMgYmVmb3JlIHRoZWlyIGBjb21waWxlYCBmdW5jdGlvbnMgZ2V0IGNhbGxlZC4gUHJpb3JpdHkgaXMgZGVmaW5lZCBhcyBhCiAqIG51bWJlci4gRGlyZWN0aXZlcyB3aXRoIGdyZWF0ZXIgbnVtZXJpY2FsIGBwcmlvcml0eWAgYXJlIGNvbXBpbGVkIGZpcnN0LiBQcmUtbGluayBmdW5jdGlvbnMKICogYXJlIGFsc28gcnVuIGluIHByaW9yaXR5IG9yZGVyLCBidXQgcG9zdC1saW5rIGZ1bmN0aW9ucyBhcmUgcnVuIGluIHJldmVyc2Ugb3JkZXIuIFRoZSBvcmRlcgogKiBvZiBkaXJlY3RpdmVzIHdpdGggdGhlIHNhbWUgcHJpb3JpdHkgaXMgdW5kZWZpbmVkLiBUaGUgZGVmYXVsdCBwcmlvcml0eSBpcyBgMGAuCiAqCiAqICMjIyMgYHRlcm1pbmFsYAogKiBJZiBzZXQgdG8gdHJ1ZSB0aGVuIHRoZSBjdXJyZW50IGBwcmlvcml0eWAgd2lsbCBiZSB0aGUgbGFzdCBzZXQgb2YgZGlyZWN0aXZlcwogKiB3aGljaCB3aWxsIGV4ZWN1dGUgKGFueSBkaXJlY3RpdmVzIGF0IHRoZSBjdXJyZW50IHByaW9yaXR5IHdpbGwgc3RpbGwgZXhlY3V0ZQogKiBhcyB0aGUgb3JkZXIgb2YgZXhlY3V0aW9uIG9uIHNhbWUgYHByaW9yaXR5YCBpcyB1bmRlZmluZWQpLiBOb3RlIHRoYXQgZXhwcmVzc2lvbnMKICogYW5kIG90aGVyIGRpcmVjdGl2ZXMgdXNlZCBpbiB0aGUgZGlyZWN0aXZlJ3MgdGVtcGxhdGUgd2lsbCBhbHNvIGJlIGV4Y2x1ZGVkIGZyb20gZXhlY3V0aW9uLgogKgogKiAjIyMjIGBzY29wZWAKICogKipJZiBzZXQgdG8gYHRydWVgLCoqIHRoZW4gYSBuZXcgc2NvcGUgd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIGRpcmVjdGl2ZS4gSWYgbXVsdGlwbGUgZGlyZWN0aXZlcyBvbiB0aGUKICogc2FtZSBlbGVtZW50IHJlcXVlc3QgYSBuZXcgc2NvcGUsIG9ubHkgb25lIG5ldyBzY29wZSBpcyBjcmVhdGVkLiBUaGUgbmV3IHNjb3BlIHJ1bGUgZG9lcyBub3QKICogYXBwbHkgZm9yIHRoZSByb290IG9mIHRoZSB0ZW1wbGF0ZSBzaW5jZSB0aGUgcm9vdCBvZiB0aGUgdGVtcGxhdGUgYWx3YXlzIGdldHMgYSBuZXcgc2NvcGUuCiAqCiAqICoqSWYgc2V0IHRvIGB7fWAgKG9iamVjdCBoYXNoKSwqKiB0aGVuIGEgbmV3ICJpc29sYXRlIiBzY29wZSBpcyBjcmVhdGVkLiBUaGUgJ2lzb2xhdGUnIHNjb3BlIGRpZmZlcnMgZnJvbQogKiBub3JtYWwgc2NvcGUgaW4gdGhhdCBpdCBkb2VzIG5vdCBwcm90b3R5cGljYWxseSBpbmhlcml0IGZyb20gdGhlIHBhcmVudCBzY29wZS4gVGhpcyBpcyB1c2VmdWwKICogd2hlbiBjcmVhdGluZyByZXVzYWJsZSBjb21wb25lbnRzLCB3aGljaCBzaG91bGQgbm90IGFjY2lkZW50YWxseSByZWFkIG9yIG1vZGlmeSBkYXRhIGluIHRoZQogKiBwYXJlbnQgc2NvcGUuCiAqCiAqIFRoZSAnaXNvbGF0ZScgc2NvcGUgdGFrZXMgYW4gb2JqZWN0IGhhc2ggd2hpY2ggZGVmaW5lcyBhIHNldCBvZiBsb2NhbCBzY29wZSBwcm9wZXJ0aWVzCiAqIGRlcml2ZWQgZnJvbSB0aGUgcGFyZW50IHNjb3BlLiBUaGVzZSBsb2NhbCBwcm9wZXJ0aWVzIGFyZSB1c2VmdWwgZm9yIGFsaWFzaW5nIHZhbHVlcyBmb3IKICogdGVtcGxhdGVzLiBMb2NhbHMgZGVmaW5pdGlvbiBpcyBhIGhhc2ggb2YgbG9jYWwgc2NvcGUgcHJvcGVydHkgdG8gaXRzIHNvdXJjZToKICoKICogKiBgQGAgb3IgYEBhdHRyYCAtIGJpbmQgYSBsb2NhbCBzY29wZSBwcm9wZXJ0eSB0byB0aGUgdmFsdWUgb2YgRE9NIGF0dHJpYnV0ZS4gVGhlIHJlc3VsdCBpcwogKiAgIGFsd2F5cyBhIHN0cmluZyBzaW5jZSBET00gYXR0cmlidXRlcyBhcmUgc3RyaW5ncy4gSWYgbm8gYGF0dHJgIG5hbWUgaXMgc3BlY2lmaWVkICB0aGVuIHRoZQogKiAgIGF0dHJpYnV0ZSBuYW1lIGlzIGFzc3VtZWQgdG8gYmUgdGhlIHNhbWUgYXMgdGhlIGxvY2FsIG5hbWUuCiAqICAgR2l2ZW4gYDx3aWRnZXQgbXktYXR0cj0iaGVsbG8ge3tuYW1lfX0iPmAgYW5kIHdpZGdldCBkZWZpbml0aW9uCiAqICAgb2YgYHNjb3BlOiB7IGxvY2FsTmFtZTonQG15QXR0cicgfWAsIHRoZW4gd2lkZ2V0IHNjb3BlIHByb3BlcnR5IGBsb2NhbE5hbWVgIHdpbGwgcmVmbGVjdAogKiAgIHRoZSBpbnRlcnBvbGF0ZWQgdmFsdWUgb2YgYGhlbGxvIHt7bmFtZX19YC4gQXMgdGhlIGBuYW1lYCBhdHRyaWJ1dGUgY2hhbmdlcyBzbyB3aWxsIHRoZQogKiAgIGBsb2NhbE5hbWVgIHByb3BlcnR5IG9uIHRoZSB3aWRnZXQgc2NvcGUuIFRoZSBgbmFtZWAgaXMgcmVhZCBmcm9tIHRoZSBwYXJlbnQgc2NvcGUgKG5vdAogKiAgIGNvbXBvbmVudCBzY29wZSkuCiAqCiAqICogYD1gIG9yIGA9YXR0cmAgLSBzZXQgdXAgYmktZGlyZWN0aW9uYWwgYmluZGluZyBiZXR3ZWVuIGEgbG9jYWwgc2NvcGUgcHJvcGVydHkgYW5kIHRoZQogKiAgIHBhcmVudCBzY29wZSBwcm9wZXJ0eSBvZiBuYW1lIGRlZmluZWQgdmlhIHRoZSB2YWx1ZSBvZiB0aGUgYGF0dHJgIGF0dHJpYnV0ZS4gSWYgbm8gYGF0dHJgCiAqICAgbmFtZSBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgYXR0cmlidXRlIG5hbWUgaXMgYXNzdW1lZCB0byBiZSB0aGUgc2FtZSBhcyB0aGUgbG9jYWwgbmFtZS4KICogICBHaXZlbiBgPHdpZGdldCBteS1hdHRyPSJwYXJlbnRNb2RlbCI+YCBhbmQgd2lkZ2V0IGRlZmluaXRpb24gb2YKICogICBgc2NvcGU6IHsgbG9jYWxNb2RlbDonPW15QXR0cicgfWAsIHRoZW4gd2lkZ2V0IHNjb3BlIHByb3BlcnR5IGBsb2NhbE1vZGVsYCB3aWxsIHJlZmxlY3QgdGhlCiAqICAgdmFsdWUgb2YgYHBhcmVudE1vZGVsYCBvbiB0aGUgcGFyZW50IHNjb3BlLiBBbnkgY2hhbmdlcyB0byBgcGFyZW50TW9kZWxgIHdpbGwgYmUgcmVmbGVjdGVkCiAqICAgaW4gYGxvY2FsTW9kZWxgIGFuZCBhbnkgY2hhbmdlcyBpbiBgbG9jYWxNb2RlbGAgd2lsbCByZWZsZWN0IGluIGBwYXJlbnRNb2RlbGAuIElmIHRoZSBwYXJlbnQKICogICBzY29wZSBwcm9wZXJ0eSBkb2Vzbid0IGV4aXN0LCBpdCB3aWxsIHRocm93IGEgTk9OX0FTU0lHTkFCTEVfTU9ERUxfRVhQUkVTU0lPTiBleGNlcHRpb24uIFlvdQogKiAgIGNhbiBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzaW5nIGA9P2Agb3IgYD0/YXR0cmAgaW4gb3JkZXIgdG8gZmxhZyB0aGUgcHJvcGVydHkgYXMgb3B0aW9uYWwuIElmCiAqICAgeW91IHdhbnQgdG8gc2hhbGxvdyB3YXRjaCBmb3IgY2hhbmdlcyAoaS5lLiAkd2F0Y2hDb2xsZWN0aW9uIGluc3RlYWQgb2YgJHdhdGNoKSB5b3UgY2FuIHVzZQogKiAgIGA9KmAgb3IgYD0qYXR0cmAgKGA9Kj9gIG9yIGA9Kj9hdHRyYCBpZiB0aGUgcHJvcGVydHkgaXMgb3B0aW9uYWwpLgogKgogKiAqIGAmYCBvciBgJmF0dHJgIC0gcHJvdmlkZXMgYSB3YXkgdG8gZXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBjb250ZXh0IG9mIHRoZSBwYXJlbnQgc2NvcGUuCiAqICAgSWYgbm8gYGF0dHJgIG5hbWUgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGF0dHJpYnV0ZSBuYW1lIGlzIGFzc3VtZWQgdG8gYmUgdGhlIHNhbWUgYXMgdGhlCiAqICAgbG9jYWwgbmFtZS4gR2l2ZW4gYDx3aWRnZXQgbXktYXR0cj0iY291bnQgPSBjb3VudCArIHZhbHVlIj5gIGFuZCB3aWRnZXQgZGVmaW5pdGlvbiBvZgogKiAgIGBzY29wZTogeyBsb2NhbEZuOicmbXlBdHRyJyB9YCwgdGhlbiBpc29sYXRlIHNjb3BlIHByb3BlcnR5IGBsb2NhbEZuYCB3aWxsIHBvaW50IHRvCiAqICAgYSBmdW5jdGlvbiB3cmFwcGVyIGZvciB0aGUgYGNvdW50ID0gY291bnQgKyB2YWx1ZWAgZXhwcmVzc2lvbi4gT2Z0ZW4gaXQncyBkZXNpcmFibGUgdG8KICogICBwYXNzIGRhdGEgZnJvbSB0aGUgaXNvbGF0ZWQgc2NvcGUgdmlhIGFuIGV4cHJlc3Npb24gdG8gdGhlIHBhcmVudCBzY29wZSwgdGhpcyBjYW4gYmUKICogICBkb25lIGJ5IHBhc3NpbmcgYSBtYXAgb2YgbG9jYWwgdmFyaWFibGUgbmFtZXMgYW5kIHZhbHVlcyBpbnRvIHRoZSBleHByZXNzaW9uIHdyYXBwZXIgZm4uCiAqICAgRm9yIGV4YW1wbGUsIGlmIHRoZSBleHByZXNzaW9uIGlzIGBpbmNyZW1lbnQoYW1vdW50KWAgdGhlbiB3ZSBjYW4gc3BlY2lmeSB0aGUgYW1vdW50IHZhbHVlCiAqICAgYnkgY2FsbGluZyB0aGUgYGxvY2FsRm5gIGFzIGBsb2NhbEZuKHthbW91bnQ6IDIyfSlgLgogKgogKgogKiAjIyMjIGBiaW5kVG9Db250cm9sbGVyYAogKiBXaGVuIGFuIGlzb2xhdGUgc2NvcGUgaXMgdXNlZCBmb3IgYSBjb21wb25lbnQgKHNlZSBhYm92ZSksIGFuZCBgY29udHJvbGxlckFzYCBpcyB1c2VkLCBgYmluZFRvQ29udHJvbGxlcjogdHJ1ZWAgd2lsbAogKiBhbGxvdyBhIGNvbXBvbmVudCB0byBoYXZlIGl0cyBwcm9wZXJ0aWVzIGJvdW5kIHRvIHRoZSBjb250cm9sbGVyLCByYXRoZXIgdGhhbiB0byBzY29wZS4gV2hlbiB0aGUgY29udHJvbGxlcgogKiBpcyBpbnN0YW50aWF0ZWQsIHRoZSBpbml0aWFsIHZhbHVlcyBvZiB0aGUgaXNvbGF0ZSBzY29wZSBiaW5kaW5ncyBhcmUgYWxyZWFkeSBhdmFpbGFibGUuCiAqCiAqICMjIyMgYGNvbnRyb2xsZXJgCiAqIENvbnRyb2xsZXIgY29uc3RydWN0b3IgZnVuY3Rpb24uIFRoZSBjb250cm9sbGVyIGlzIGluc3RhbnRpYXRlZCBiZWZvcmUgdGhlCiAqIHByZS1saW5raW5nIHBoYXNlIGFuZCBpdCBpcyBzaGFyZWQgd2l0aCBvdGhlciBkaXJlY3RpdmVzIChzZWUKICogYHJlcXVpcmVgIGF0dHJpYnV0ZSkuIFRoaXMgYWxsb3dzIHRoZSBkaXJlY3RpdmVzIHRvIGNvbW11bmljYXRlIHdpdGggZWFjaCBvdGhlciBhbmQgYXVnbWVudAogKiBlYWNoIG90aGVyJ3MgYmVoYXZpb3IuIFRoZSBjb250cm9sbGVyIGlzIGluamVjdGFibGUgKGFuZCBzdXBwb3J0cyBicmFja2V0IG5vdGF0aW9uKSB3aXRoIHRoZSBmb2xsb3dpbmcgbG9jYWxzOgogKgogKiAqIGAkc2NvcGVgIC0gQ3VycmVudCBzY29wZSBhc3NvY2lhdGVkIHdpdGggdGhlIGVsZW1lbnQKICogKiBgJGVsZW1lbnRgIC0gQ3VycmVudCBlbGVtZW50CiAqICogYCRhdHRyc2AgLSBDdXJyZW50IGF0dHJpYnV0ZXMgb2JqZWN0IGZvciB0aGUgZWxlbWVudAogKiAqIGAkdHJhbnNjbHVkZWAgLSBBIHRyYW5zY2x1ZGUgbGlua2luZyBmdW5jdGlvbiBwcmUtYm91bmQgdG8gdGhlIGNvcnJlY3QgdHJhbnNjbHVzaW9uIHNjb3BlOgogKiAgIGBmdW5jdGlvbihbc2NvcGVdLCBjbG9uZUxpbmtpbmdGbiwgZnV0dXJlUGFyZW50RWxlbWVudClgLgogKiAgICAqIGBzY29wZWA6IG9wdGlvbmFsIGFyZ3VtZW50IHRvIG92ZXJyaWRlIHRoZSBzY29wZS4KICogICAgKiBgY2xvbmVMaW5raW5nRm5gOiBvcHRpb25hbCBhcmd1bWVudCB0byBjcmVhdGUgY2xvbmVzIG9mIHRoZSBvcmlnaW5hbCB0cmFuc2NsdWRlZCBjb250ZW50LgogKiAgICAqIGBmdXR1cmVQYXJlbnRFbGVtZW50YDoKICogICAgICAgICogZGVmaW5lcyB0aGUgcGFyZW50IHRvIHdoaWNoIHRoZSBgY2xvbmVMaW5raW5nRm5gIHdpbGwgYWRkIHRoZSBjbG9uZWQgZWxlbWVudHMuCiAqICAgICAgICAqIGRlZmF1bHQ6IGAkZWxlbWVudC5wYXJlbnQoKWAgcmVzcC4gYCRlbGVtZW50YCBmb3IgYHRyYW5zY2x1ZGU6J2VsZW1lbnQnYCByZXNwLiBgdHJhbnNjbHVkZTp0cnVlYC4KICogICAgICAgICogb25seSBuZWVkZWQgZm9yIHRyYW5zY2x1ZGVzIHRoYXQgYXJlIGFsbG93ZWQgdG8gY29udGFpbiBub24gaHRtbCBlbGVtZW50cyAoZS5nLiBTVkcgZWxlbWVudHMpCiAqICAgICAgICAgIGFuZCB3aGVuIHRoZSBgY2xvbmVMaW5raW5GbmAgaXMgcGFzc2VkLAogKiAgICAgICAgICBhcyB0aG9zZSBlbGVtZW50cyBuZWVkIHRvIGNyZWF0ZWQgYW5kIGNsb25lZCBpbiBhIHNwZWNpYWwgd2F5IHdoZW4gdGhleSBhcmUgZGVmaW5lZCBvdXRzaWRlIHRoZWlyCiAqICAgICAgICAgIHVzdWFsIGNvbnRhaW5lcnMgKGUuZy4gbGlrZSBgPHN2Zz5gKS4KICogICAgICAgICogU2VlIGFsc28gdGhlIGBkaXJlY3RpdmUudGVtcGxhdGVOYW1lc3BhY2VgIHByb3BlcnR5LgogKgogKgogKiAjIyMjIGByZXF1aXJlYAogKiBSZXF1aXJlIGFub3RoZXIgZGlyZWN0aXZlIGFuZCBpbmplY3QgaXRzIGNvbnRyb2xsZXIgYXMgdGhlIGZvdXJ0aCBhcmd1bWVudCB0byB0aGUgbGlua2luZyBmdW5jdGlvbi4gVGhlCiAqIGByZXF1aXJlYCB0YWtlcyBhIHN0cmluZyBuYW1lIChvciBhcnJheSBvZiBzdHJpbmdzKSBvZiB0aGUgZGlyZWN0aXZlKHMpIHRvIHBhc3MgaW4uIElmIGFuIGFycmF5IGlzIHVzZWQsIHRoZQogKiBpbmplY3RlZCBhcmd1bWVudCB3aWxsIGJlIGFuIGFycmF5IGluIGNvcnJlc3BvbmRpbmcgb3JkZXIuIElmIG5vIHN1Y2ggZGlyZWN0aXZlIGNhbiBiZQogKiBmb3VuZCwgb3IgaWYgdGhlIGRpcmVjdGl2ZSBkb2VzIG5vdCBoYXZlIGEgY29udHJvbGxlciwgdGhlbiBhbiBlcnJvciBpcyByYWlzZWQuIFRoZSBuYW1lIGNhbiBiZSBwcmVmaXhlZCB3aXRoOgogKgogKiAqIChubyBwcmVmaXgpIC0gTG9jYXRlIHRoZSByZXF1aXJlZCBjb250cm9sbGVyIG9uIHRoZSBjdXJyZW50IGVsZW1lbnQuIFRocm93IGFuIGVycm9yIGlmIG5vdCBmb3VuZC4KICogKiBgP2AgLSBBdHRlbXB0IHRvIGxvY2F0ZSB0aGUgcmVxdWlyZWQgY29udHJvbGxlciBvciBwYXNzIGBudWxsYCB0byB0aGUgYGxpbmtgIGZuIGlmIG5vdCBmb3VuZC4KICogKiBgXmAgLSBMb2NhdGUgdGhlIHJlcXVpcmVkIGNvbnRyb2xsZXIgYnkgc2VhcmNoaW5nIHRoZSBlbGVtZW50IGFuZCBpdHMgcGFyZW50cy4gVGhyb3cgYW4gZXJyb3IgaWYgbm90IGZvdW5kLgogKiAqIGBeXmAgLSBMb2NhdGUgdGhlIHJlcXVpcmVkIGNvbnRyb2xsZXIgYnkgc2VhcmNoaW5nIHRoZSBlbGVtZW50J3MgcGFyZW50cy4gVGhyb3cgYW4gZXJyb3IgaWYgbm90IGZvdW5kLgogKiAqIGA/XmAgLSBBdHRlbXB0IHRvIGxvY2F0ZSB0aGUgcmVxdWlyZWQgY29udHJvbGxlciBieSBzZWFyY2hpbmcgdGhlIGVsZW1lbnQgYW5kIGl0cyBwYXJlbnRzIG9yIHBhc3MKICogICBgbnVsbGAgdG8gdGhlIGBsaW5rYCBmbiBpZiBub3QgZm91bmQuCiAqICogYD9eXmAgLSBBdHRlbXB0IHRvIGxvY2F0ZSB0aGUgcmVxdWlyZWQgY29udHJvbGxlciBieSBzZWFyY2hpbmcgdGhlIGVsZW1lbnQncyBwYXJlbnRzLCBvciBwYXNzCiAqICAgYG51bGxgIHRvIHRoZSBgbGlua2AgZm4gaWYgbm90IGZvdW5kLgogKgogKgogKiAjIyMjIGBjb250cm9sbGVyQXNgCiAqIENvbnRyb2xsZXIgYWxpYXMgYXQgdGhlIGRpcmVjdGl2ZSBzY29wZS4gQW4gYWxpYXMgZm9yIHRoZSBjb250cm9sbGVyIHNvIGl0CiAqIGNhbiBiZSByZWZlcmVuY2VkIGF0IHRoZSBkaXJlY3RpdmUgdGVtcGxhdGUuIFRoZSBkaXJlY3RpdmUgbmVlZHMgdG8gZGVmaW5lIGEgc2NvcGUgZm9yIHRoaXMKICogY29uZmlndXJhdGlvbiB0byBiZSB1c2VkLiBVc2VmdWwgaW4gdGhlIGNhc2Ugd2hlbiBkaXJlY3RpdmUgaXMgdXNlZCBhcyBjb21wb25lbnQuCiAqCiAqCiAqICMjIyMgYHJlc3RyaWN0YAogKiBTdHJpbmcgb2Ygc3Vic2V0IG9mIGBFQUNNYCB3aGljaCByZXN0cmljdHMgdGhlIGRpcmVjdGl2ZSB0byBhIHNwZWNpZmljIGRpcmVjdGl2ZQogKiBkZWNsYXJhdGlvbiBzdHlsZS4gSWYgb21pdHRlZCwgdGhlIGRlZmF1bHRzIChlbGVtZW50cyBhbmQgYXR0cmlidXRlcykgYXJlIHVzZWQuCiAqCiAqICogYEVgIC0gRWxlbWVudCBuYW1lIChkZWZhdWx0KTogYDxteS1kaXJlY3RpdmU+PC9teS1kaXJlY3RpdmU+YAogKiAqIGBBYCAtIEF0dHJpYnV0ZSAoZGVmYXVsdCk6IGA8ZGl2IG15LWRpcmVjdGl2ZT0iZXhwIj48L2Rpdj5gCiAqICogYENgIC0gQ2xhc3M6IGA8ZGl2IGNsYXNzPSJteS1kaXJlY3RpdmU6IGV4cDsiPjwvZGl2PmAKICogKiBgTWAgLSBDb21tZW50OiBgPCEtLSBkaXJlY3RpdmU6IG15LWRpcmVjdGl2ZSBleHAgLS0+YAogKgogKgogKiAjIyMjIGB0ZW1wbGF0ZU5hbWVzcGFjZWAKICogU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgZG9jdW1lbnQgdHlwZSB1c2VkIGJ5IHRoZSBtYXJrdXAgaW4gdGhlIHRlbXBsYXRlLgogKiBBbmd1bGFySlMgbmVlZHMgdGhpcyBpbmZvcm1hdGlvbiBhcyB0aG9zZSBlbGVtZW50cyBuZWVkIHRvIGJlIGNyZWF0ZWQgYW5kIGNsb25lZAogKiBpbiBhIHNwZWNpYWwgd2F5IHdoZW4gdGhleSBhcmUgZGVmaW5lZCBvdXRzaWRlIHRoZWlyIHVzdWFsIGNvbnRhaW5lcnMgbGlrZSBgPHN2Zz5gIGFuZCBgPG1hdGg+YC4KICoKICogKiBgaHRtbGAgLSBBbGwgcm9vdCBub2RlcyBpbiB0aGUgdGVtcGxhdGUgYXJlIEhUTUwuIFJvb3Qgbm9kZXMgbWF5IGFsc28gYmUKICogICB0b3AtbGV2ZWwgZWxlbWVudHMgc3VjaCBhcyBgPHN2Zz5gIG9yIGA8bWF0aD5gLgogKiAqIGBzdmdgIC0gVGhlIHJvb3Qgbm9kZXMgaW4gdGhlIHRlbXBsYXRlIGFyZSBTVkcgZWxlbWVudHMgKGV4Y2x1ZGluZyBgPG1hdGg+YCkuCiAqICogYG1hdGhgIC0gVGhlIHJvb3Qgbm9kZXMgaW4gdGhlIHRlbXBsYXRlIGFyZSBNYXRoTUwgZWxlbWVudHMgKGV4Y2x1ZGluZyBgPHN2Zz5gKS4KICoKICogSWYgbm8gYHRlbXBsYXRlTmFtZXNwYWNlYCBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlIG5hbWVzcGFjZSBpcyBjb25zaWRlcmVkIHRvIGJlIGBodG1sYC4KICoKICogIyMjIyBgdGVtcGxhdGVgCiAqIEhUTUwgbWFya3VwIHRoYXQgbWF5OgogKiAqIFJlcGxhY2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBkaXJlY3RpdmUncyBlbGVtZW50IChkZWZhdWx0KS4KICogKiBSZXBsYWNlIHRoZSBkaXJlY3RpdmUncyBlbGVtZW50IGl0c2VsZiAoaWYgYHJlcGxhY2VgIGlzIHRydWUgLSBERVBSRUNBVEVEKS4KICogKiBXcmFwIHRoZSBjb250ZW50cyBvZiB0aGUgZGlyZWN0aXZlJ3MgZWxlbWVudCAoaWYgYHRyYW5zY2x1ZGVgIGlzIHRydWUpLgogKgogKiBWYWx1ZSBtYXkgYmU6CiAqCiAqICogQSBzdHJpbmcuIEZvciBleGFtcGxlIGA8ZGl2IHJlZC1vbi1ob3Zlcj57e2RlbGV0ZV9zdHJ9fTwvZGl2PmAuCiAqICogQSBmdW5jdGlvbiB3aGljaCB0YWtlcyB0d28gYXJndW1lbnRzIGB0RWxlbWVudGAgYW5kIGB0QXR0cnNgIChkZXNjcmliZWQgaW4gdGhlIGBjb21waWxlYAogKiAgIGZ1bmN0aW9uIGFwaSBiZWxvdykgYW5kIHJldHVybnMgYSBzdHJpbmcgdmFsdWUuCiAqCiAqCiAqICMjIyMgYHRlbXBsYXRlVXJsYAogKiBUaGlzIGlzIHNpbWlsYXIgdG8gYHRlbXBsYXRlYCBidXQgdGhlIHRlbXBsYXRlIGlzIGxvYWRlZCBmcm9tIHRoZSBzcGVjaWZpZWQgVVJMLCBhc3luY2hyb25vdXNseS4KICoKICogQmVjYXVzZSB0ZW1wbGF0ZSBsb2FkaW5nIGlzIGFzeW5jaHJvbm91cyB0aGUgY29tcGlsZXIgd2lsbCBzdXNwZW5kIGNvbXBpbGF0aW9uIG9mIGRpcmVjdGl2ZXMgb24gdGhhdCBlbGVtZW50CiAqIGZvciBsYXRlciB3aGVuIHRoZSB0ZW1wbGF0ZSBoYXMgYmVlbiByZXNvbHZlZC4gIEluIHRoZSBtZWFudGltZSBpdCB3aWxsIGNvbnRpbnVlIHRvIGNvbXBpbGUgYW5kIGxpbmsKICogc2libGluZyBhbmQgcGFyZW50IGVsZW1lbnRzIGFzIHRob3VnaCB0aGlzIGVsZW1lbnQgaGFkIG5vdCBjb250YWluZWQgYW55IGRpcmVjdGl2ZXMuCiAqCiAqIFRoZSBjb21waWxlciBkb2VzIG5vdCBzdXNwZW5kIHRoZSBlbnRpcmUgY29tcGlsYXRpb24gdG8gd2FpdCBmb3IgdGVtcGxhdGVzIHRvIGJlIGxvYWRlZCBiZWNhdXNlIHRoaXMKICogd291bGQgcmVzdWx0IGluIHRoZSB3aG9sZSBhcHAgInN0YWxsaW5nIiB1bnRpbCBhbGwgdGVtcGxhdGVzIGFyZSBsb2FkZWQgYXN5bmNocm9ub3VzbHkgLSBldmVuIGluIHRoZQogKiBjYXNlIHdoZW4gb25seSBvbmUgZGVlcGx5IG5lc3RlZCBkaXJlY3RpdmUgaGFzIGB0ZW1wbGF0ZVVybGAuCiAqCiAqIFRlbXBsYXRlIGxvYWRpbmcgaXMgYXN5bmNocm9ub3VzIGV2ZW4gaWYgdGhlIHRlbXBsYXRlIGhhcyBiZWVuIHByZWxvYWRlZCBpbnRvIHRoZSB7QGxpbmsgJHRlbXBsYXRlQ2FjaGV9CiAqCiAqIFlvdSBjYW4gc3BlY2lmeSBgdGVtcGxhdGVVcmxgIGFzIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgVVJMIG9yIGFzIGEgZnVuY3Rpb24gd2hpY2ggdGFrZXMgdHdvCiAqIGFyZ3VtZW50cyBgdEVsZW1lbnRgIGFuZCBgdEF0dHJzYCAoZGVzY3JpYmVkIGluIHRoZSBgY29tcGlsZWAgZnVuY3Rpb24gYXBpIGJlbG93KSBhbmQgcmV0dXJucwogKiBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIHVybC4gIEluIGVpdGhlciBjYXNlLCB0aGUgdGVtcGxhdGUgVVJMIGlzIHBhc3NlZCB0aHJvdWdoIHtAbGluawogKiAkc2NlI2dldFRydXN0ZWRSZXNvdXJjZVVybCAkc2NlLmdldFRydXN0ZWRSZXNvdXJjZVVybH0uCiAqCiAqCiAqICMjIyMgYHJlcGxhY2VgIChbKkRFUFJFQ0FURUQqIV0sIHdpbGwgYmUgcmVtb3ZlZCBpbiBuZXh0IG1ham9yIHJlbGVhc2UgLSBpLmUuIHYyLjApCiAqIHNwZWNpZnkgd2hhdCB0aGUgdGVtcGxhdGUgc2hvdWxkIHJlcGxhY2UuIERlZmF1bHRzIHRvIGBmYWxzZWAuCiAqCiAqICogYHRydWVgIC0gdGhlIHRlbXBsYXRlIHdpbGwgcmVwbGFjZSB0aGUgZGlyZWN0aXZlJ3MgZWxlbWVudC4KICogKiBgZmFsc2VgIC0gdGhlIHRlbXBsYXRlIHdpbGwgcmVwbGFjZSB0aGUgY29udGVudHMgb2YgdGhlIGRpcmVjdGl2ZSdzIGVsZW1lbnQuCiAqCiAqIFRoZSByZXBsYWNlbWVudCBwcm9jZXNzIG1pZ3JhdGVzIGFsbCBvZiB0aGUgYXR0cmlidXRlcyAvIGNsYXNzZXMgZnJvbSB0aGUgb2xkIGVsZW1lbnQgdG8gdGhlIG5ldwogKiBvbmUuIFNlZSB0aGUge0BsaW5rIGd1aWRlL2RpcmVjdGl2ZSN0ZW1wbGF0ZS1leHBhbmRpbmctZGlyZWN0aXZlCiAqIERpcmVjdGl2ZXMgR3VpZGV9IGZvciBhbiBleGFtcGxlLgogKgogKiBUaGVyZSBhcmUgdmVyeSBmZXcgc2NlbmFyaW9zIHdoZXJlIGVsZW1lbnQgcmVwbGFjZW1lbnQgaXMgcmVxdWlyZWQgZm9yIHRoZSBhcHBsaWNhdGlvbiBmdW5jdGlvbiwKICogdGhlIG1haW4gb25lIGJlaW5nIHJldXNhYmxlIGN1c3RvbSBjb21wb25lbnRzIHRoYXQgYXJlIHVzZWQgd2l0aGluIFNWRyBjb250ZXh0cwogKiAoYmVjYXVzZSBTVkcgZG9lc24ndCB3b3JrIHdpdGggY3VzdG9tIGVsZW1lbnRzIGluIHRoZSBET00gdHJlZSkuCiAqCiAqICMjIyMgYHRyYW5zY2x1ZGVgCiAqIEV4dHJhY3QgdGhlIGNvbnRlbnRzIG9mIHRoZSBlbGVtZW50IHdoZXJlIHRoZSBkaXJlY3RpdmUgYXBwZWFycyBhbmQgbWFrZSBpdCBhdmFpbGFibGUgdG8gdGhlIGRpcmVjdGl2ZS4KICogVGhlIGNvbnRlbnRzIGFyZSBjb21waWxlZCBhbmQgcHJvdmlkZWQgdG8gdGhlIGRpcmVjdGl2ZSBhcyBhICoqdHJhbnNjbHVzaW9uIGZ1bmN0aW9uKiouIFNlZSB0aGUKICoge0BsaW5rICRjb21waWxlI3RyYW5zY2x1c2lvbiBUcmFuc2NsdXNpb259IHNlY3Rpb24gYmVsb3cuCiAqCiAqIFRoZXJlIGFyZSB0d28ga2luZHMgb2YgdHJhbnNjbHVzaW9uIGRlcGVuZGluZyB1cG9uIHdoZXRoZXIgeW91IHdhbnQgdG8gdHJhbnNjbHVkZSBqdXN0IHRoZSBjb250ZW50cyBvZiB0aGUKICogZGlyZWN0aXZlJ3MgZWxlbWVudCBvciB0aGUgZW50aXJlIGVsZW1lbnQ6CiAqCiAqICogYHRydWVgIC0gdHJhbnNjbHVkZSB0aGUgY29udGVudCAoaS5lLiB0aGUgY2hpbGQgbm9kZXMpIG9mIHRoZSBkaXJlY3RpdmUncyBlbGVtZW50LgogKiAqIGAnZWxlbWVudCdgIC0gdHJhbnNjbHVkZSB0aGUgd2hvbGUgb2YgdGhlIGRpcmVjdGl2ZSdzIGVsZW1lbnQgaW5jbHVkaW5nIGFueSBkaXJlY3RpdmVzIG9uIHRoaXMKICogICBlbGVtZW50IHRoYXQgZGVmaW5lZCBhdCBhIGxvd2VyIHByaW9yaXR5IHRoYW4gdGhpcyBkaXJlY3RpdmUuIFdoZW4gdXNlZCwgdGhlIGB0ZW1wbGF0ZWAKICogICBwcm9wZXJ0eSBpcyBpZ25vcmVkLgogKgogKgogKiAjIyMjIGBjb21waWxlYAogKgogKiBgYGBqcwogKiAgIGZ1bmN0aW9uIGNvbXBpbGUodEVsZW1lbnQsIHRBdHRycywgdHJhbnNjbHVkZSkgeyAuLi4gfQogKiBgYGAKICoKICogVGhlIGNvbXBpbGUgZnVuY3Rpb24gZGVhbHMgd2l0aCB0cmFuc2Zvcm1pbmcgdGhlIHRlbXBsYXRlIERPTS4gU2luY2UgbW9zdCBkaXJlY3RpdmVzIGRvIG5vdCBkbwogKiB0ZW1wbGF0ZSB0cmFuc2Zvcm1hdGlvbiwgaXQgaXMgbm90IHVzZWQgb2Z0ZW4uIFRoZSBjb21waWxlIGZ1bmN0aW9uIHRha2VzIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOgogKgogKiAgICogYHRFbGVtZW50YCAtIHRlbXBsYXRlIGVsZW1lbnQgLSBUaGUgZWxlbWVudCB3aGVyZSB0aGUgZGlyZWN0aXZlIGhhcyBiZWVuIGRlY2xhcmVkLiBJdCBpcwogKiAgICAgc2FmZSB0byBkbyB0ZW1wbGF0ZSB0cmFuc2Zvcm1hdGlvbiBvbiB0aGUgZWxlbWVudCBhbmQgY2hpbGQgZWxlbWVudHMgb25seS4KICoKICogICAqIGB0QXR0cnNgIC0gdGVtcGxhdGUgYXR0cmlidXRlcyAtIE5vcm1hbGl6ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzIGRlY2xhcmVkIG9uIHRoaXMgZWxlbWVudCBzaGFyZWQKICogICAgIGJldHdlZW4gYWxsIGRpcmVjdGl2ZSBjb21waWxlIGZ1bmN0aW9ucy4KICoKICogICAqIGB0cmFuc2NsdWRlYCAtICBbKkRFUFJFQ0FURUQqIV0gQSB0cmFuc2NsdWRlIGxpbmtpbmcgZnVuY3Rpb246IGBmdW5jdGlvbihzY29wZSwgY2xvbmVMaW5raW5nRm4pYAogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICogKipOb3RlOioqIFRoZSB0ZW1wbGF0ZSBpbnN0YW5jZSBhbmQgdGhlIGxpbmsgaW5zdGFuY2UgbWF5IGJlIGRpZmZlcmVudCBvYmplY3RzIGlmIHRoZSB0ZW1wbGF0ZSBoYXMKICogYmVlbiBjbG9uZWQuIEZvciB0aGlzIHJlYXNvbiBpdCBpcyAqKm5vdCoqIHNhZmUgdG8gZG8gYW55dGhpbmcgb3RoZXIgdGhhbiBET00gdHJhbnNmb3JtYXRpb25zIHRoYXQKICogYXBwbHkgdG8gYWxsIGNsb25lZCBET00gbm9kZXMgd2l0aGluIHRoZSBjb21waWxlIGZ1bmN0aW9uLiBTcGVjaWZpY2FsbHksIERPTSBsaXN0ZW5lciByZWdpc3RyYXRpb24KICogc2hvdWxkIGJlIGRvbmUgaW4gYSBsaW5raW5nIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGluIGEgY29tcGlsZSBmdW5jdGlvbi4KICogPC9kaXY+CgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICogKipOb3RlOioqIFRoZSBjb21waWxlIGZ1bmN0aW9uIGNhbm5vdCBoYW5kbGUgZGlyZWN0aXZlcyB0aGF0IHJlY3Vyc2l2ZWx5IHVzZSB0aGVtc2VsdmVzIGluIHRoZWlyCiAqIG93biB0ZW1wbGF0ZXMgb3IgY29tcGlsZSBmdW5jdGlvbnMuIENvbXBpbGluZyB0aGVzZSBkaXJlY3RpdmVzIHJlc3VsdHMgaW4gYW4gaW5maW5pdGUgbG9vcCBhbmQgYQogKiBzdGFjayBvdmVyZmxvdyBlcnJvcnMuCiAqCiAqIFRoaXMgY2FuIGJlIGF2b2lkZWQgYnkgbWFudWFsbHkgdXNpbmcgJGNvbXBpbGUgaW4gdGhlIHBvc3RMaW5rIGZ1bmN0aW9uIHRvIGltcGVyYXRpdmVseSBjb21waWxlCiAqIGEgZGlyZWN0aXZlJ3MgdGVtcGxhdGUgaW5zdGVhZCBvZiByZWx5aW5nIG9uIGF1dG9tYXRpYyB0ZW1wbGF0ZSBjb21waWxhdGlvbiB2aWEgYHRlbXBsYXRlYCBvcgogKiBgdGVtcGxhdGVVcmxgIGRlY2xhcmF0aW9uIG9yIG1hbnVhbCBjb21waWxhdGlvbiBpbnNpZGUgdGhlIGNvbXBpbGUgZnVuY3Rpb24uCiAqIDwvZGl2PgogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1lcnJvciI+CiAqICoqTm90ZToqKiBUaGUgYHRyYW5zY2x1ZGVgIGZ1bmN0aW9uIHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjb21waWxlIGZ1bmN0aW9uIGlzIGRlcHJlY2F0ZWQsIGFzIGl0CiAqICAgZS5nLiBkb2VzIG5vdCBrbm93IGFib3V0IHRoZSByaWdodCBvdXRlciBzY29wZS4gUGxlYXNlIHVzZSB0aGUgdHJhbnNjbHVkZSBmdW5jdGlvbiB0aGF0IGlzIHBhc3NlZAogKiAgIHRvIHRoZSBsaW5rIGZ1bmN0aW9uIGluc3RlYWQuCiAqIDwvZGl2PgoKICogQSBjb21waWxlIGZ1bmN0aW9uIGNhbiBoYXZlIGEgcmV0dXJuIHZhbHVlIHdoaWNoIGNhbiBiZSBlaXRoZXIgYSBmdW5jdGlvbiBvciBhbiBvYmplY3QuCiAqCiAqICogcmV0dXJuaW5nIGEgKHBvc3QtbGluaykgZnVuY3Rpb24gLSBpcyBlcXVpdmFsZW50IHRvIHJlZ2lzdGVyaW5nIHRoZSBsaW5raW5nIGZ1bmN0aW9uIHZpYSB0aGUKICogICBgbGlua2AgcHJvcGVydHkgb2YgdGhlIGNvbmZpZyBvYmplY3Qgd2hlbiB0aGUgY29tcGlsZSBmdW5jdGlvbiBpcyBlbXB0eS4KICoKICogKiByZXR1cm5pbmcgYW4gb2JqZWN0IHdpdGggZnVuY3Rpb24ocykgcmVnaXN0ZXJlZCB2aWEgYHByZWAgYW5kIGBwb3N0YCBwcm9wZXJ0aWVzIC0gYWxsb3dzIHlvdSB0bwogKiAgIGNvbnRyb2wgd2hlbiBhIGxpbmtpbmcgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBkdXJpbmcgdGhlIGxpbmtpbmcgcGhhc2UuIFNlZSBpbmZvIGFib3V0CiAqICAgcHJlLWxpbmtpbmcgYW5kIHBvc3QtbGlua2luZyBmdW5jdGlvbnMgYmVsb3cuCiAqCiAqCiAqICMjIyMgYGxpbmtgCiAqIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBvbmx5IGlmIHRoZSBgY29tcGlsZWAgcHJvcGVydHkgaXMgbm90IGRlZmluZWQuCiAqCiAqIGBgYGpzCiAqICAgZnVuY3Rpb24gbGluayhzY29wZSwgaUVsZW1lbnQsIGlBdHRycywgY29udHJvbGxlciwgdHJhbnNjbHVkZUZuKSB7IC4uLiB9CiAqIGBgYAogKgogKiBUaGUgbGluayBmdW5jdGlvbiBpcyByZXNwb25zaWJsZSBmb3IgcmVnaXN0ZXJpbmcgRE9NIGxpc3RlbmVycyBhcyB3ZWxsIGFzIHVwZGF0aW5nIHRoZSBET00uIEl0IGlzCiAqIGV4ZWN1dGVkIGFmdGVyIHRoZSB0ZW1wbGF0ZSBoYXMgYmVlbiBjbG9uZWQuIFRoaXMgaXMgd2hlcmUgbW9zdCBvZiB0aGUgZGlyZWN0aXZlIGxvZ2ljIHdpbGwgYmUKICogcHV0LgogKgogKiAgICogYHNjb3BlYCAtIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIFNjb3BlfSAtIFRoZSBzY29wZSB0byBiZSB1c2VkIGJ5IHRoZQogKiAgICAgZGlyZWN0aXZlIGZvciByZWdpc3RlcmluZyB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkd2F0Y2ggd2F0Y2hlc30uCiAqCiAqICAgKiBgaUVsZW1lbnRgIC0gaW5zdGFuY2UgZWxlbWVudCAtIFRoZSBlbGVtZW50IHdoZXJlIHRoZSBkaXJlY3RpdmUgaXMgdG8gYmUgdXNlZC4gSXQgaXMgc2FmZSB0bwogKiAgICAgbWFuaXB1bGF0ZSB0aGUgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQgb25seSBpbiBgcG9zdExpbmtgIGZ1bmN0aW9uIHNpbmNlIHRoZSBjaGlsZHJlbiBoYXZlCiAqICAgICBhbHJlYWR5IGJlZW4gbGlua2VkLgogKgogKiAgICogYGlBdHRyc2AgLSBpbnN0YW5jZSBhdHRyaWJ1dGVzIC0gTm9ybWFsaXplZCBsaXN0IG9mIGF0dHJpYnV0ZXMgZGVjbGFyZWQgb24gdGhpcyBlbGVtZW50IHNoYXJlZAogKiAgICAgYmV0d2VlbiBhbGwgZGlyZWN0aXZlIGxpbmtpbmcgZnVuY3Rpb25zLgogKgogKiAgICogYGNvbnRyb2xsZXJgIC0gYSBjb250cm9sbGVyIGluc3RhbmNlIC0gQSBjb250cm9sbGVyIGluc3RhbmNlIGlmIGF0IGxlYXN0IG9uZSBkaXJlY3RpdmUgb24gdGhlCiAqICAgICBlbGVtZW50IGRlZmluZXMgYSBjb250cm9sbGVyLiBUaGUgY29udHJvbGxlciBpcyBzaGFyZWQgYW1vbmcgYWxsIHRoZSBkaXJlY3RpdmVzLCB3aGljaCBhbGxvd3MKICogICAgIHRoZSBkaXJlY3RpdmVzIHRvIHVzZSB0aGUgY29udHJvbGxlcnMgYXMgYSBjb21tdW5pY2F0aW9uIGNoYW5uZWwuCiAqCiAqICAgKiBgdHJhbnNjbHVkZUZuYCAtIEEgdHJhbnNjbHVkZSBsaW5raW5nIGZ1bmN0aW9uIHByZS1ib3VuZCB0byB0aGUgY29ycmVjdCB0cmFuc2NsdXNpb24gc2NvcGUuCiAqICAgICBUaGlzIGlzIHRoZSBzYW1lIGFzIHRoZSBgJHRyYW5zY2x1ZGVgCiAqICAgICBwYXJhbWV0ZXIgb2YgZGlyZWN0aXZlIGNvbnRyb2xsZXJzLCBzZWUgdGhlcmUgZm9yIGRldGFpbHMuCiAqICAgICBgZnVuY3Rpb24oW3Njb3BlXSwgY2xvbmVMaW5raW5nRm4sIGZ1dHVyZVBhcmVudEVsZW1lbnQpYC4KICoKICogIyMjIyBQcmUtbGlua2luZyBmdW5jdGlvbgogKgogKiBFeGVjdXRlZCBiZWZvcmUgdGhlIGNoaWxkIGVsZW1lbnRzIGFyZSBsaW5rZWQuIE5vdCBzYWZlIHRvIGRvIERPTSB0cmFuc2Zvcm1hdGlvbiBzaW5jZSB0aGUKICogY29tcGlsZXIgbGlua2luZyBmdW5jdGlvbiB3aWxsIGZhaWwgdG8gbG9jYXRlIHRoZSBjb3JyZWN0IGVsZW1lbnRzIGZvciBsaW5raW5nLgogKgogKiAjIyMjIFBvc3QtbGlua2luZyBmdW5jdGlvbgogKgogKiBFeGVjdXRlZCBhZnRlciB0aGUgY2hpbGQgZWxlbWVudHMgYXJlIGxpbmtlZC4KICoKICogTm90ZSB0aGF0IGNoaWxkIGVsZW1lbnRzIHRoYXQgY29udGFpbiBgdGVtcGxhdGVVcmxgIGRpcmVjdGl2ZXMgd2lsbCBub3QgaGF2ZSBiZWVuIGNvbXBpbGVkCiAqIGFuZCBsaW5rZWQgc2luY2UgdGhleSBhcmUgd2FpdGluZyBmb3IgdGhlaXIgdGVtcGxhdGUgdG8gbG9hZCBhc3luY2hyb25vdXNseSBhbmQgdGhlaXIgb3duCiAqIGNvbXBpbGF0aW9uIGFuZCBsaW5raW5nIGhhcyBiZWVuIHN1c3BlbmRlZCB1bnRpbCB0aGF0IG9jY3Vycy4KICoKICogSXQgaXMgc2FmZSB0byBkbyBET00gdHJhbnNmb3JtYXRpb24gaW4gdGhlIHBvc3QtbGlua2luZyBmdW5jdGlvbiBvbiBlbGVtZW50cyB0aGF0IGFyZSBub3Qgd2FpdGluZwogKiBmb3IgdGhlaXIgYXN5bmMgdGVtcGxhdGVzIHRvIGJlIHJlc29sdmVkLgogKgogKgogKiAjIyMgVHJhbnNjbHVzaW9uCiAqCiAqIFRyYW5zY2x1c2lvbiBpcyB0aGUgcHJvY2VzcyBvZiBleHRyYWN0aW5nIGEgY29sbGVjdGlvbiBvZiBET00gZWxlbWVudCBmcm9tIG9uZSBwYXJ0IG9mIHRoZSBET00gYW5kCiAqIGNvcHlpbmcgdGhlbSB0byBhbm90aGVyIHBhcnQgb2YgdGhlIERPTSwgd2hpbGUgbWFpbnRhaW5pbmcgdGhlaXIgY29ubmVjdGlvbiB0byB0aGUgb3JpZ2luYWwgQW5ndWxhckpTCiAqIHNjb3BlIGZyb20gd2hlcmUgdGhleSB3ZXJlIHRha2VuLgogKgogKiBUcmFuc2NsdXNpb24gaXMgdXNlZCAob2Z0ZW4gd2l0aCB7QGxpbmsgbmdUcmFuc2NsdWRlfSkgdG8gaW5zZXJ0IHRoZQogKiBvcmlnaW5hbCBjb250ZW50cyBvZiBhIGRpcmVjdGl2ZSdzIGVsZW1lbnQgaW50byBhIHNwZWNpZmllZCBwbGFjZSBpbiB0aGUgdGVtcGxhdGUgb2YgdGhlIGRpcmVjdGl2ZS4KICogVGhlIGJlbmVmaXQgb2YgdHJhbnNjbHVzaW9uLCBvdmVyIHNpbXBseSBtb3ZpbmcgdGhlIERPTSBlbGVtZW50cyBtYW51YWxseSwgaXMgdGhhdCB0aGUgdHJhbnNjbHVkZWQKICogY29udGVudCBoYXMgYWNjZXNzIHRvIHRoZSBwcm9wZXJ0aWVzIG9uIHRoZSBzY29wZSBmcm9tIHdoaWNoIGl0IHdhcyB0YWtlbiwgZXZlbiBpZiB0aGUgZGlyZWN0aXZlCiAqIGhhcyBpc29sYXRlZCBzY29wZS4KICogU2VlIHRoZSB7QGxpbmsgZ3VpZGUvZGlyZWN0aXZlI2NyZWF0aW5nLWEtZGlyZWN0aXZlLXRoYXQtd3JhcHMtb3RoZXItZWxlbWVudHMgRGlyZWN0aXZlcyBHdWlkZX0uCiAqCiAqIFRoaXMgbWFrZXMgaXQgcG9zc2libGUgZm9yIHRoZSB3aWRnZXQgdG8gaGF2ZSBwcml2YXRlIHN0YXRlIGZvciBpdHMgdGVtcGxhdGUsIHdoaWxlIHRoZSB0cmFuc2NsdWRlZAogKiBjb250ZW50IGhhcyBhY2Nlc3MgdG8gaXRzIG9yaWdpbmF0aW5nIHNjb3BlLgogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICogKipOb3RlOioqIFdoZW4gdGVzdGluZyBhbiBlbGVtZW50IHRyYW5zY2x1ZGUgZGlyZWN0aXZlIHlvdSBtdXN0IG5vdCBwbGFjZSB0aGUgZGlyZWN0aXZlIGF0IHRoZSByb290IG9mIHRoZQogKiBET00gZnJhZ21lbnQgdGhhdCBpcyBiZWluZyBjb21waWxlZC4gU2VlIHtAbGluayBndWlkZS91bml0LXRlc3RpbmcjdGVzdGluZy10cmFuc2NsdXNpb24tZGlyZWN0aXZlcwogKiBUZXN0aW5nIFRyYW5zY2x1c2lvbiBEaXJlY3RpdmVzfS4KICogPC9kaXY+CiAqCiAqICMjIyMgVHJhbnNjbHVzaW9uIEZ1bmN0aW9ucwogKgogKiBXaGVuIGEgZGlyZWN0aXZlIHJlcXVlc3RzIHRyYW5zY2x1c2lvbiwgdGhlIGNvbXBpbGVyIGV4dHJhY3RzIGl0cyBjb250ZW50cyBhbmQgcHJvdmlkZXMgYSAqKnRyYW5zY2x1c2lvbgogKiBmdW5jdGlvbioqIHRvIHRoZSBkaXJlY3RpdmUncyBgbGlua2AgZnVuY3Rpb24gYW5kIGBjb250cm9sbGVyYC4gVGhpcyB0cmFuc2NsdXNpb24gZnVuY3Rpb24gaXMgYSBzcGVjaWFsCiAqICoqbGlua2luZyBmdW5jdGlvbioqIHRoYXQgd2lsbCByZXR1cm4gdGhlIGNvbXBpbGVkIGNvbnRlbnRzIGxpbmtlZCB0byBhIG5ldyB0cmFuc2NsdXNpb24gc2NvcGUuCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgogKiBJZiB5b3UgYXJlIGp1c3QgdXNpbmcge0BsaW5rIG5nVHJhbnNjbHVkZX0gdGhlbiB5b3UgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCB0aGlzIGZ1bmN0aW9uLCBzaW5jZQogKiBuZ1RyYW5zY2x1ZGUgd2lsbCBkZWFsIHdpdGggaXQgZm9yIHVzLgogKiA8L2Rpdj4KICoKICogSWYgeW91IHdhbnQgdG8gbWFudWFsbHkgY29udHJvbCB0aGUgaW5zZXJ0aW9uIGFuZCByZW1vdmFsIG9mIHRoZSB0cmFuc2NsdWRlZCBjb250ZW50IGluIHlvdXIgZGlyZWN0aXZlCiAqIHRoZW4geW91IG11c3QgdXNlIHRoaXMgdHJhbnNjbHVkZSBmdW5jdGlvbi4gV2hlbiB5b3UgY2FsbCBhIHRyYW5zY2x1ZGUgZnVuY3Rpb24gaXQgcmV0dXJucyBhIGEganFMaXRlL0pRdWVyeQogKiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgY29tcGlsZWQgRE9NLCB3aGljaCBpcyBsaW5rZWQgdG8gdGhlIGNvcnJlY3QgdHJhbnNjbHVzaW9uIHNjb3BlLgogKgogKiBXaGVuIHlvdSBjYWxsIGEgdHJhbnNjbHVzaW9uIGZ1bmN0aW9uIHlvdSBjYW4gcGFzcyBpbiBhICoqY2xvbmUgYXR0YWNoIGZ1bmN0aW9uKiouIFRoaXMgZnVuY3Rpb24gYWNjZXB0cwogKiB0d28gcGFyYW1ldGVycywgYGZ1bmN0aW9uKGNsb25lLCBzY29wZSkgeyAuLi4gfWAsIHdoZXJlIHRoZSBgY2xvbmVgIGlzIGEgZnJlc2ggY29tcGlsZWQgY29weSBvZiB5b3VyIHRyYW5zY2x1ZGVkCiAqIGNvbnRlbnQgYW5kIHRoZSBgc2NvcGVgIGlzIHRoZSBuZXdseSBjcmVhdGVkIHRyYW5zY2x1c2lvbiBzY29wZSwgdG8gd2hpY2ggdGhlIGNsb25lIGlzIGJvdW5kLgogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KICogKipCZXN0IFByYWN0aWNlKio6IEFsd2F5cyBwcm92aWRlIGEgYGNsb25lRm5gIChjbG9uZSBhdHRhY2ggZnVuY3Rpb24pIHdoZW4geW91IGNhbGwgYSB0cmFuc2x1ZGUgZnVuY3Rpb24KICogc2luY2UgeW91IHRoZW4gZ2V0IGEgZnJlc2ggY2xvbmUgb2YgdGhlIG9yaWdpbmFsIERPTSBhbmQgYWxzbyBoYXZlIGFjY2VzcyB0byB0aGUgbmV3IHRyYW5zY2x1c2lvbiBzY29wZS4KICogPC9kaXY+CiAqCiAqIEl0IGlzIG5vcm1hbCBwcmFjdGljZSB0byBhdHRhY2ggeW91ciB0cmFuc2NsdWRlZCBjb250ZW50IChgY2xvbmVgKSB0byB0aGUgRE9NIGluc2lkZSB5b3VyICoqY2xvbmUKICogYXR0YWNoIGZ1bmN0aW9uKio6CiAqCiAqIGBgYGpzCiAqIHZhciB0cmFuc2NsdWRlZENvbnRlbnQsIHRyYW5zY2x1c2lvblNjb3BlOwogKgogKiAkdHJhbnNjbHVkZShmdW5jdGlvbihjbG9uZSwgc2NvcGUpIHsKICogICBlbGVtZW50LmFwcGVuZChjbG9uZSk7CiAqICAgdHJhbnNjbHVkZWRDb250ZW50ID0gY2xvbmU7CiAqICAgdHJhbnNjbHVzaW9uU2NvcGUgPSBzY29wZTsKICogfSk7CiAqIGBgYAogKgogKiBMYXRlciwgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIHRoZSB0cmFuc2NsdWRlZCBjb250ZW50IGZyb20geW91ciBET00gdGhlbiB5b3Ugc2hvdWxkIGFsc28gZGVzdHJveSB0aGUKICogYXNzb2NpYXRlZCB0cmFuc2NsdXNpb24gc2NvcGU6CiAqCiAqIGBgYGpzCiAqIHRyYW5zY2x1ZGVkQ29udGVudC5yZW1vdmUoKTsKICogdHJhbnNjbHVzaW9uU2NvcGUuJGRlc3Ryb3koKTsKICogYGBgCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgogKiAqKkJlc3QgUHJhY3RpY2UqKjogaWYgeW91IGludGVuZCB0byBhZGQgYW5kIHJlbW92ZSB0cmFuc2NsdWRlZCBjb250ZW50IG1hbnVhbGx5IGluIHlvdXIgZGlyZWN0aXZlCiAqIChieSBjYWxsaW5nIHRoZSB0cmFuc2NsdWRlIGZ1bmN0aW9uIHRvIGdldCB0aGUgRE9NIGFuZCBhbmQgY2FsbGluZyBgZWxlbWVudC5yZW1vdmUoKWAgdG8gcmVtb3ZlIGl0KSwKICogdGhlbiB5b3UgYXJlIGFsc28gcmVzcG9uc2libGUgZm9yIGNhbGxpbmcgYCRkZXN0cm95YCBvbiB0aGUgdHJhbnNjbHVzaW9uIHNjb3BlLgogKiA8L2Rpdj4KICoKICogVGhlIGJ1aWx0LWluIERPTSBtYW5pcHVsYXRpb24gZGlyZWN0aXZlcywgc3VjaCBhcyB7QGxpbmsgbmdJZn0sIHtAbGluayBuZ1N3aXRjaH0gYW5kIHtAbGluayBuZ1JlcGVhdH0KICogYXV0b21hdGljYWxseSBkZXN0cm95IHRoZWlyIHRyYW5zbHVkZWQgY2xvbmVzIGFzIG5lY2Vzc2FyeSBzbyB5b3UgZG8gbm90IG5lZWQgdG8gd29ycnkgYWJvdXQgdGhpcyBpZgogKiB5b3UgYXJlIHNpbXBseSB1c2luZyB7QGxpbmsgbmdUcmFuc2NsdWRlfSB0byBpbmplY3QgdGhlIHRyYW5zY2x1c2lvbiBpbnRvIHlvdXIgZGlyZWN0aXZlLgogKgogKgogKiAjIyMjIFRyYW5zY2x1c2lvbiBTY29wZXMKICoKICogV2hlbiB5b3UgY2FsbCBhIHRyYW5zY2x1ZGUgZnVuY3Rpb24gaXQgcmV0dXJucyBhIERPTSBmcmFnbWVudCB0aGF0IGlzIHByZS1ib3VuZCB0byBhICoqdHJhbnNjbHVzaW9uCiAqIHNjb3BlKiouIFRoaXMgc2NvcGUgaXMgc3BlY2lhbCwgaW4gdGhhdCBpdCBpcyBhIGNoaWxkIG9mIHRoZSBkaXJlY3RpdmUncyBzY29wZSAoYW5kIHNvIGdldHMgZGVzdHJveWVkCiAqIHdoZW4gdGhlIGRpcmVjdGl2ZSdzIHNjb3BlIGdldHMgZGVzdHJveWVkKSBidXQgaXQgaW5oZXJpdHMgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHNjb3BlIGZyb20gd2hpY2ggaXQKICogd2FzIHRha2VuLgogKgogKiBGb3IgZXhhbXBsZSBjb25zaWRlciBhIGRpcmVjdGl2ZSB0aGF0IHVzZXMgdHJhbnNjbHVzaW9uIGFuZCBpc29sYXRlZCBzY29wZS4gVGhlIERPTSBoaWVyYXJjaHkgbWlnaHQgbG9vawogKiBsaWtlIHRoaXM6CiAqCiAqIGBgYGh0bWwKICogPGRpdiBuZy1hcHA+CiAqICAgPGRpdiBpc29sYXRlPgogKiAgICAgPGRpdiB0cmFuc2NsdXNpb24+CiAqICAgICA8L2Rpdj4KICogICA8L2Rpdj4KICogPC9kaXY+CiAqIGBgYAogKgogKiBUaGUgYCRwYXJlbnRgIHNjb3BlIGhpZXJhcmNoeSB3aWxsIGxvb2sgbGlrZSB0aGlzOgogKgogKiBgYGAKICogLSAkcm9vdFNjb3BlCiAqICAgLSBpc29sYXRlCiAqICAgICAtIHRyYW5zY2x1c2lvbgogKiBgYGAKICoKICogYnV0IHRoZSBzY29wZXMgd2lsbCBpbmhlcml0IHByb3RvdHlwaWNhbGx5IGZyb20gZGlmZmVyZW50IHNjb3BlcyB0byB0aGVpciBgJHBhcmVudGAuCiAqCiAqIGBgYAogKiAtICRyb290U2NvcGUKICogICAtIHRyYW5zY2x1c2lvbgogKiAtIGlzb2xhdGUKICogYGBgCiAqCiAqCiAqICMjIyBBdHRyaWJ1dGVzCiAqCiAqIFRoZSB7QGxpbmsgbmcuJGNvbXBpbGUuZGlyZWN0aXZlLkF0dHJpYnV0ZXMgQXR0cmlidXRlc30gb2JqZWN0IC0gcGFzc2VkIGFzIGEgcGFyYW1ldGVyIGluIHRoZQogKiBgbGluaygpYCBvciBgY29tcGlsZSgpYCBmdW5jdGlvbnMuIEl0IGhhcyBhIHZhcmlldHkgb2YgdXNlcy4KICoKICogYWNjZXNzaW5nICpOb3JtYWxpemVkIGF0dHJpYnV0ZSBuYW1lczoqCiAqIERpcmVjdGl2ZXMgbGlrZSAnbmdCaW5kJyBjYW4gYmUgZXhwcmVzc2VkIGluIG1hbnkgd2F5czogJ25nOmJpbmQnLCBgZGF0YS1uZy1iaW5kYCwgb3IgJ3gtbmctYmluZCcuCiAqIHRoZSBhdHRyaWJ1dGVzIG9iamVjdCBhbGxvd3MgZm9yIG5vcm1hbGl6ZWQgYWNjZXNzIHRvCiAqICAgdGhlIGF0dHJpYnV0ZXMuCiAqCiAqICogKkRpcmVjdGl2ZSBpbnRlci1jb21tdW5pY2F0aW9uOiogQWxsIGRpcmVjdGl2ZXMgc2hhcmUgdGhlIHNhbWUgaW5zdGFuY2Ugb2YgdGhlIGF0dHJpYnV0ZXMKICogICBvYmplY3Qgd2hpY2ggYWxsb3dzIHRoZSBkaXJlY3RpdmVzIHRvIHVzZSB0aGUgYXR0cmlidXRlcyBvYmplY3QgYXMgaW50ZXIgZGlyZWN0aXZlCiAqICAgY29tbXVuaWNhdGlvbi4KICoKICogKiAqU3VwcG9ydHMgaW50ZXJwb2xhdGlvbjoqIEludGVycG9sYXRpb24gYXR0cmlidXRlcyBhcmUgYXNzaWduZWQgdG8gdGhlIGF0dHJpYnV0ZSBvYmplY3QKICogICBhbGxvd2luZyBvdGhlciBkaXJlY3RpdmVzIHRvIHJlYWQgdGhlIGludGVycG9sYXRlZCB2YWx1ZS4KICoKICogKiAqT2JzZXJ2aW5nIGludGVycG9sYXRlZCBhdHRyaWJ1dGVzOiogVXNlIGAkb2JzZXJ2ZWAgdG8gb2JzZXJ2ZSB0aGUgdmFsdWUgY2hhbmdlcyBvZiBhdHRyaWJ1dGVzCiAqICAgdGhhdCBjb250YWluIGludGVycG9sYXRpb24gKGUuZy4gYHNyYz0ie3tiYXJ9fSJgKS4gTm90IG9ubHkgaXMgdGhpcyB2ZXJ5IGVmZmljaWVudCBidXQgaXQncyBhbHNvCiAqICAgdGhlIG9ubHkgd2F5IHRvIGVhc2lseSBnZXQgdGhlIGFjdHVhbCB2YWx1ZSBiZWNhdXNlIGR1cmluZyB0aGUgbGlua2luZyBwaGFzZSB0aGUgaW50ZXJwb2xhdGlvbgogKiAgIGhhc24ndCBiZWVuIGV2YWx1YXRlZCB5ZXQgYW5kIHNvIHRoZSB2YWx1ZSBpcyBhdCB0aGlzIHRpbWUgc2V0IHRvIGB1bmRlZmluZWRgLgogKgogKiBgYGBqcwogKiBmdW5jdGlvbiBsaW5raW5nRm4oc2NvcGUsIGVsbSwgYXR0cnMsIGN0cmwpIHsKICogICAvLyBnZXQgdGhlIGF0dHJpYnV0ZSB2YWx1ZQogKiAgIGNvbnNvbGUubG9nKGF0dHJzLm5nTW9kZWwpOwogKgogKiAgIC8vIGNoYW5nZSB0aGUgYXR0cmlidXRlCiAqICAgYXR0cnMuJHNldCgnbmdNb2RlbCcsICduZXcgdmFsdWUnKTsKICoKICogICAvLyBvYnNlcnZlIGNoYW5nZXMgdG8gaW50ZXJwb2xhdGVkIGF0dHJpYnV0ZQogKiAgIGF0dHJzLiRvYnNlcnZlKCduZ01vZGVsJywgZnVuY3Rpb24odmFsdWUpIHsKICogICAgIGNvbnNvbGUubG9nKCduZ01vZGVsIGhhcyBjaGFuZ2VkIHZhbHVlIHRvICcgKyB2YWx1ZSk7CiAqICAgfSk7CiAqIH0KICogYGBgCiAqCiAqICMjIEV4YW1wbGUKICoKICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CiAqICoqTm90ZSoqOiBUeXBpY2FsbHkgZGlyZWN0aXZlcyBhcmUgcmVnaXN0ZXJlZCB3aXRoIGBtb2R1bGUuZGlyZWN0aXZlYC4gVGhlIGV4YW1wbGUgYmVsb3cgaXMKICogdG8gaWxsdXN0cmF0ZSBob3cgYCRjb21waWxlYCB3b3Jrcy4KICogPC9kaXY+CiAqCiA8ZXhhbXBsZSBtb2R1bGU9ImNvbXBpbGVFeGFtcGxlIj4KICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICA8c2NyaXB0PgogICAgICBhbmd1bGFyLm1vZHVsZSgnY29tcGlsZUV4YW1wbGUnLCBbXSwgZnVuY3Rpb24oJGNvbXBpbGVQcm92aWRlcikgewogICAgICAgIC8vIGNvbmZpZ3VyZSBuZXcgJ2NvbXBpbGUnIGRpcmVjdGl2ZSBieSBwYXNzaW5nIGEgZGlyZWN0aXZlCiAgICAgICAgLy8gZmFjdG9yeSBmdW5jdGlvbi4gVGhlIGZhY3RvcnkgZnVuY3Rpb24gaW5qZWN0cyB0aGUgJyRjb21waWxlJwogICAgICAgICRjb21waWxlUHJvdmlkZXIuZGlyZWN0aXZlKCdjb21waWxlJywgZnVuY3Rpb24oJGNvbXBpbGUpIHsKICAgICAgICAgIC8vIGRpcmVjdGl2ZSBmYWN0b3J5IGNyZWF0ZXMgYSBsaW5rIGZ1bmN0aW9uCiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHJzKSB7CiAgICAgICAgICAgIHNjb3BlLiR3YXRjaCgKICAgICAgICAgICAgICBmdW5jdGlvbihzY29wZSkgewogICAgICAgICAgICAgICAgIC8vIHdhdGNoIHRoZSAnY29tcGlsZScgZXhwcmVzc2lvbiBmb3IgY2hhbmdlcwogICAgICAgICAgICAgICAgcmV0dXJuIHNjb3BlLiRldmFsKGF0dHJzLmNvbXBpbGUpOwogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhlICdjb21waWxlJyBleHByZXNzaW9uIGNoYW5nZXMKICAgICAgICAgICAgICAgIC8vIGFzc2lnbiBpdCBpbnRvIHRoZSBjdXJyZW50IERPTQogICAgICAgICAgICAgICAgZWxlbWVudC5odG1sKHZhbHVlKTsKCiAgICAgICAgICAgICAgICAvLyBjb21waWxlIHRoZSBuZXcgRE9NIGFuZCBsaW5rIGl0IHRvIHRoZSBjdXJyZW50CiAgICAgICAgICAgICAgICAvLyBzY29wZS4KICAgICAgICAgICAgICAgIC8vIE5PVEU6IHdlIG9ubHkgY29tcGlsZSAuY2hpbGROb2RlcyBzbyB0aGF0CiAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCBnZXQgaW50byBpbmZpbml0ZSBsb29wIGNvbXBpbGluZyBvdXJzZWx2ZXMKICAgICAgICAgICAgICAgICRjb21waWxlKGVsZW1lbnQuY29udGVudHMoKSkoc2NvcGUpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgKTsKICAgICAgICAgIH07CiAgICAgICAgfSk7CiAgICAgIH0pCiAgICAgIC5jb250cm9sbGVyKCdHcmVldGVyQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgJHNjb3BlLm5hbWUgPSAnQW5ndWxhcic7CiAgICAgICAgJHNjb3BlLmh0bWwgPSAnSGVsbG8ge3tuYW1lfX0nOwogICAgICB9XSk7CiAgICA8L3NjcmlwdD4KICAgIDxkaXYgbmctY29udHJvbGxlcj0iR3JlZXRlckNvbnRyb2xsZXIiPgogICAgICA8aW5wdXQgbmctbW9kZWw9Im5hbWUiPiA8YnI+CiAgICAgIDx0ZXh0YXJlYSBuZy1tb2RlbD0iaHRtbCI+PC90ZXh0YXJlYT4gPGJyPgogICAgICA8ZGl2IGNvbXBpbGU9Imh0bWwiPjwvZGl2PgogICAgPC9kaXY+CiAgIDwvZmlsZT4KICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgaXQoJ3Nob3VsZCBhdXRvIGNvbXBpbGUnLCBmdW5jdGlvbigpIHsKICAgICAgIHZhciB0ZXh0YXJlYSA9ICQoJ3RleHRhcmVhJyk7CiAgICAgICB2YXIgb3V0cHV0ID0gJCgnZGl2W2NvbXBpbGVdJyk7CiAgICAgICAvLyBUaGUgaW5pdGlhbCBzdGF0ZSByZWFkcyAnSGVsbG8gQW5ndWxhcicuCiAgICAgICBleHBlY3Qob3V0cHV0LmdldFRleHQoKSkudG9CZSgnSGVsbG8gQW5ndWxhcicpOwogICAgICAgdGV4dGFyZWEuY2xlYXIoKTsKICAgICAgIHRleHRhcmVhLnNlbmRLZXlzKCd7e25hbWV9fSEnKTsKICAgICAgIGV4cGVjdChvdXRwdXQuZ2V0VGV4dCgpKS50b0JlKCdBbmd1bGFyIScpOwogICAgIH0pOwogICA8L2ZpbGU+CiA8L2V4YW1wbGU+CgogKgogKgogKiBAcGFyYW0ge3N0cmluZ3xET01FbGVtZW50fSBlbGVtZW50IEVsZW1lbnQgb3IgSFRNTCBzdHJpbmcgdG8gY29tcGlsZSBpbnRvIGEgdGVtcGxhdGUgZnVuY3Rpb24uCiAqIEBwYXJhbSB7ZnVuY3Rpb24oYW5ndWxhci5TY29wZSwgY2xvbmVBdHRhY2hGbj0pfSB0cmFuc2NsdWRlIGZ1bmN0aW9uIGF2YWlsYWJsZSB0byBkaXJlY3RpdmVzIC0gREVQUkVDQVRFRC4KICoKICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtZXJyb3IiPgogKiAqKk5vdGU6KiogUGFzc2luZyBhIGB0cmFuc2NsdWRlYCBmdW5jdGlvbiB0byB0aGUgJGNvbXBpbGUgZnVuY3Rpb24gaXMgZGVwcmVjYXRlZCwgYXMgaXQKICogICBlLmcuIHdpbGwgbm90IHVzZSB0aGUgcmlnaHQgb3V0ZXIgc2NvcGUuIFBsZWFzZSBwYXNzIHRoZSB0cmFuc2NsdWRlIGZ1bmN0aW9uIGFzIGEKICogICBgcGFyZW50Qm91bmRUcmFuc2NsdWRlRm5gIHRvIHRoZSBsaW5rIGZ1bmN0aW9uIGluc3RlYWQuCiAqIDwvZGl2PgogKgogKiBAcGFyYW0ge251bWJlcn0gbWF4UHJpb3JpdHkgb25seSBhcHBseSBkaXJlY3RpdmVzIGxvd2VyIHRoYW4gZ2l2ZW4gcHJpb3JpdHkgKE9ubHkgZWZmZWN0cyB0aGUKICogICAgICAgICAgICAgICAgIHJvb3QgZWxlbWVudChzKSwgbm90IHRoZWlyIGNoaWxkcmVuKQogKiBAcmV0dXJucyB7ZnVuY3Rpb24oc2NvcGUsIGNsb25lQXR0YWNoRm49LCBvcHRpb25zPSl9IGEgbGluayBmdW5jdGlvbiB3aGljaCBpcyB1c2VkIHRvIGJpbmQgdGVtcGxhdGUKICogKGEgRE9NIGVsZW1lbnQvdHJlZSkgdG8gYSBzY29wZS4gV2hlcmU6CiAqCiAqICAqIGBzY29wZWAgLSBBIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIFNjb3BlfSB0byBiaW5kIHRvLgogKiAgKiBgY2xvbmVBdHRhY2hGbmAgLSBJZiBgY2xvbmVBdHRhY2hGbmAgaXMgcHJvdmlkZWQsIHRoZW4gdGhlIGxpbmsgZnVuY3Rpb24gd2lsbCBjbG9uZSB0aGUKICogIGB0ZW1wbGF0ZWAgYW5kIGNhbGwgdGhlIGBjbG9uZUF0dGFjaEZuYCBmdW5jdGlvbiBhbGxvd2luZyB0aGUgY2FsbGVyIHRvIGF0dGFjaCB0aGUKICogIGNsb25lZCBlbGVtZW50cyB0byB0aGUgRE9NIGRvY3VtZW50IGF0IHRoZSBhcHByb3ByaWF0ZSBwbGFjZS4gVGhlIGBjbG9uZUF0dGFjaEZuYCBpcwogKiAgY2FsbGVkIGFzOiA8YnI+IGBjbG9uZUF0dGFjaEZuKGNsb25lZEVsZW1lbnQsIHNjb3BlKWAgd2hlcmU6CiAqCiAqICAgICAgKiBgY2xvbmVkRWxlbWVudGAgLSBpcyBhIGNsb25lIG9mIHRoZSBvcmlnaW5hbCBgZWxlbWVudGAgcGFzc2VkIGludG8gdGhlIGNvbXBpbGVyLgogKiAgICAgICogYHNjb3BlYCAtIGlzIHRoZSBjdXJyZW50IHNjb3BlIHdpdGggd2hpY2ggdGhlIGxpbmtpbmcgZnVuY3Rpb24gaXMgd29ya2luZyB3aXRoLgogKgogKiAgKiBgb3B0aW9uc2AgLSBBbiBvcHRpb25hbCBvYmplY3QgaGFzaCB3aXRoIGxpbmtpbmcgb3B0aW9ucy4gSWYgYG9wdGlvbnNgIGlzIHByb3ZpZGVkLCB0aGVuIHRoZSBmb2xsb3dpbmcKICogIGtleXMgbWF5IGJlIHVzZWQgdG8gY29udHJvbCBsaW5raW5nIGJlaGF2aW9yOgogKgogKiAgICAgICogYHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuYCAtIHRoZSB0cmFuc2NsdWRlIGZ1bmN0aW9uIG1hZGUgYXZhaWxhYmxlIHRvCiAqICAgICAgICBkaXJlY3RpdmVzOyBpZiBnaXZlbiwgaXQgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCB0byB0aGUgbGluayBmdW5jdGlvbnMgb2YKICogICAgICAgIGRpcmVjdGl2ZXMgZm91bmQgaW4gYGVsZW1lbnRgIGR1cmluZyBjb21waWxhdGlvbi4KICogICAgICAqIGB0cmFuc2NsdWRlQ29udHJvbGxlcnNgIC0gYW4gb2JqZWN0IGhhc2ggd2l0aCBrZXlzIHRoYXQgbWFwIGNvbnRyb2xsZXIgbmFtZXMKICogICAgICAgIHRvIGNvbnRyb2xsZXIgaW5zdGFuY2VzOyBpZiBnaXZlbiwgaXQgd2lsbCBtYWtlIHRoZSBjb250cm9sbGVycwogKiAgICAgICAgYXZhaWxhYmxlIHRvIGRpcmVjdGl2ZXMuCiAqICAgICAgKiBgZnV0dXJlUGFyZW50RWxlbWVudGAgLSBkZWZpbmVzIHRoZSBwYXJlbnQgdG8gd2hpY2ggdGhlIGBjbG9uZUF0dGFjaEZuYCB3aWxsIGFkZAogKiAgICAgICAgdGhlIGNsb25lZCBlbGVtZW50czsgb25seSBuZWVkZWQgZm9yIHRyYW5zY2x1ZGVzIHRoYXQgYXJlIGFsbG93ZWQgdG8gY29udGFpbiBub24gaHRtbAogKiAgICAgICAgZWxlbWVudHMgKGUuZy4gU1ZHIGVsZW1lbnRzKS4gU2VlIGFsc28gdGhlIGRpcmVjdGl2ZS5jb250cm9sbGVyIHByb3BlcnR5LgogKgogKiBDYWxsaW5nIHRoZSBsaW5raW5nIGZ1bmN0aW9uIHJldHVybnMgdGhlIGVsZW1lbnQgb2YgdGhlIHRlbXBsYXRlLiBJdCBpcyBlaXRoZXIgdGhlIG9yaWdpbmFsCiAqIGVsZW1lbnQgcGFzc2VkIGluLCBvciB0aGUgY2xvbmUgb2YgdGhlIGVsZW1lbnQgaWYgdGhlIGBjbG9uZUF0dGFjaEZuYCBpcyBwcm92aWRlZC4KICoKICogQWZ0ZXIgbGlua2luZyB0aGUgdmlldyBpcyBub3QgdXBkYXRlZCB1bnRpbCBhZnRlciBhIGNhbGwgdG8gJGRpZ2VzdCB3aGljaCB0eXBpY2FsbHkgaXMgZG9uZSBieQogKiBBbmd1bGFyIGF1dG9tYXRpY2FsbHkuCiAqCiAqIElmIHlvdSBuZWVkIGFjY2VzcyB0byB0aGUgYm91bmQgdmlldywgdGhlcmUgYXJlIHR3byB3YXlzIHRvIGRvIGl0OgogKgogKiAtIElmIHlvdSBhcmUgbm90IGFza2luZyB0aGUgbGlua2luZyBmdW5jdGlvbiB0byBjbG9uZSB0aGUgdGVtcGxhdGUsIGNyZWF0ZSB0aGUgRE9NIGVsZW1lbnQocykKICogICBiZWZvcmUgeW91IHNlbmQgdGhlbSB0byB0aGUgY29tcGlsZXIgYW5kIGtlZXAgdGhpcyByZWZlcmVuY2UgYXJvdW5kLgogKiAgIGBgYGpzCiAqICAgICB2YXIgZWxlbWVudCA9ICRjb21waWxlKCc8cD57e3RvdGFsfX08L3A+Jykoc2NvcGUpOwogKiAgIGBgYAogKgogKiAtIGlmIG9uIHRoZSBvdGhlciBoYW5kLCB5b3UgbmVlZCB0aGUgZWxlbWVudCB0byBiZSBjbG9uZWQsIHRoZSB2aWV3IHJlZmVyZW5jZSBmcm9tIHRoZSBvcmlnaW5hbAogKiAgIGV4YW1wbGUgd291bGQgbm90IHBvaW50IHRvIHRoZSBjbG9uZSwgYnV0IHJhdGhlciB0byB0aGUgb3JpZ2luYWwgdGVtcGxhdGUgdGhhdCB3YXMgY2xvbmVkLiBJbgogKiAgIHRoaXMgY2FzZSwgeW91IGNhbiBhY2Nlc3MgdGhlIGNsb25lIHZpYSB0aGUgY2xvbmVBdHRhY2hGbjoKICogICBgYGBqcwogKiAgICAgdmFyIHRlbXBsYXRlRWxlbWVudCA9IGFuZ3VsYXIuZWxlbWVudCgnPHA+e3t0b3RhbH19PC9wPicpLAogKiAgICAgICAgIHNjb3BlID0gLi4uLjsKICoKICogICAgIHZhciBjbG9uZWRFbGVtZW50ID0gJGNvbXBpbGUodGVtcGxhdGVFbGVtZW50KShzY29wZSwgZnVuY3Rpb24oY2xvbmVkRWxlbWVudCwgc2NvcGUpIHsKICogICAgICAgLy9hdHRhY2ggdGhlIGNsb25lIHRvIERPTSBkb2N1bWVudCBhdCB0aGUgcmlnaHQgcGxhY2UKICogICAgIH0pOwogKgogKiAgICAgLy9ub3cgd2UgaGF2ZSByZWZlcmVuY2UgdG8gdGhlIGNsb25lZCBET00gdmlhIGBjbG9uZWRFbGVtZW50YAogKiAgIGBgYAogKgogKgogKiBGb3IgaW5mb3JtYXRpb24gb24gaG93IHRoZSBjb21waWxlciB3b3Jrcywgc2VlIHRoZQogKiB7QGxpbmsgZ3VpZGUvY29tcGlsZXIgQW5ndWxhciBIVE1MIENvbXBpbGVyfSBzZWN0aW9uIG9mIHRoZSBEZXZlbG9wZXIgR3VpZGUuCiAqLwoKdmFyICRjb21waWxlTWluRXJyID0gbWluRXJyKCckY29tcGlsZScpOwoKLyoqCiAqIEBuZ2RvYyBwcm92aWRlcgogKiBAbmFtZSAkY29tcGlsZVByb3ZpZGVyCiAqCiAqIEBkZXNjcmlwdGlvbgogKi8KJENvbXBpbGVQcm92aWRlci4kaW5qZWN0ID0gWyckcHJvdmlkZScsICckJHNhbml0aXplVXJpUHJvdmlkZXInXTsKZnVuY3Rpb24gJENvbXBpbGVQcm92aWRlcigkcHJvdmlkZSwgJCRzYW5pdGl6ZVVyaVByb3ZpZGVyKSB7CiAgdmFyIGhhc0RpcmVjdGl2ZXMgPSB7fSwKICAgICAgU3VmZml4ID0gJ0RpcmVjdGl2ZScsCiAgICAgIENPTU1FTlRfRElSRUNUSVZFX1JFR0VYUCA9IC9eXHMqZGlyZWN0aXZlXDpccyooW1x3XC1dKylccysoLiopJC8sCiAgICAgIENMQVNTX0RJUkVDVElWRV9SRUdFWFAgPSAvKChbXHdcLV0rKSg/Olw6KFteO10rKSk/Oz8pLywKICAgICAgQUxMX09SX05PVEhJTkdfQVRUUlMgPSBtYWtlTWFwKCduZ1NyYyxuZ1NyY3NldCxzcmMsc3Jjc2V0JyksCiAgICAgIFJFUVVJUkVfUFJFRklYX1JFR0VYUCA9IC9eKD86KFxeXF4/KT8oXD8pPyhcXlxePyk/KT8vOwoKICAvLyBSZWY6IGh0dHA6Ly9kZXZlbG9wZXJzLndoYXR3Zy5vcmcvd2ViYXBwYXBpcy5odG1sI2V2ZW50LWhhbmRsZXItaWRsLWF0dHJpYnV0ZXMKICAvLyBUaGUgYXNzdW1wdGlvbiBpcyB0aGF0IGZ1dHVyZSBET00gZXZlbnQgYXR0cmlidXRlIG5hbWVzIHdpbGwgYmVnaW4gd2l0aAogIC8vICdvbicgYW5kIGJlIGNvbXBvc2VkIG9mIG9ubHkgRW5nbGlzaCBsZXR0ZXJzLgogIHZhciBFVkVOVF9IQU5ETEVSX0FUVFJfUkVHRVhQID0gL14ob25bYS16XSt8Zm9ybWFjdGlvbikkLzsKCiAgZnVuY3Rpb24gcGFyc2VJc29sYXRlQmluZGluZ3Moc2NvcGUsIGRpcmVjdGl2ZU5hbWUpIHsKICAgIHZhciBMT0NBTF9SRUdFWFAgPSAvXlxzKihbQCZdfD0oXCo/KSkoXD8/KVxzKihcdyopXHMqJC87CgogICAgdmFyIGJpbmRpbmdzID0ge307CgogICAgZm9yRWFjaChzY29wZSwgZnVuY3Rpb24oZGVmaW5pdGlvbiwgc2NvcGVOYW1lKSB7CiAgICAgIHZhciBtYXRjaCA9IGRlZmluaXRpb24ubWF0Y2goTE9DQUxfUkVHRVhQKTsKCiAgICAgIGlmICghbWF0Y2gpIHsKICAgICAgICB0aHJvdyAkY29tcGlsZU1pbkVycignaXNjcCcsCiAgICAgICAgICAgICJJbnZhbGlkIGlzb2xhdGUgc2NvcGUgZGVmaW5pdGlvbiBmb3IgZGlyZWN0aXZlICd7MH0nLiIgKwogICAgICAgICAgICAiIERlZmluaXRpb246IHsuLi4gezF9OiAnezJ9JyAuLi59IiwKICAgICAgICAgICAgZGlyZWN0aXZlTmFtZSwgc2NvcGVOYW1lLCBkZWZpbml0aW9uKTsKICAgICAgfQoKICAgICAgYmluZGluZ3Nbc2NvcGVOYW1lXSA9IHsKICAgICAgICBtb2RlOiBtYXRjaFsxXVswXSwKICAgICAgICBjb2xsZWN0aW9uOiBtYXRjaFsyXSA9PT0gJyonLAogICAgICAgIG9wdGlvbmFsOiBtYXRjaFszXSA9PT0gJz8nLAogICAgICAgIGF0dHJOYW1lOiBtYXRjaFs0XSB8fCBzY29wZU5hbWUKICAgICAgfTsKICAgIH0pOwoKICAgIHJldHVybiBiaW5kaW5nczsKICB9CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkY29tcGlsZVByb3ZpZGVyI2RpcmVjdGl2ZQogICAqIEBraW5kIGZ1bmN0aW9uCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBSZWdpc3RlciBhIG5ldyBkaXJlY3RpdmUgd2l0aCB0aGUgY29tcGlsZXIuCiAgICoKICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IG5hbWUgTmFtZSBvZiB0aGUgZGlyZWN0aXZlIGluIGNhbWVsLWNhc2UgKGkuZS4gPGNvZGU+bmdCaW5kPC9jb2RlPiB3aGljaAogICAqICAgIHdpbGwgbWF0Y2ggYXMgPGNvZGU+bmctYmluZDwvY29kZT4pLCBvciBhbiBvYmplY3QgbWFwIG9mIGRpcmVjdGl2ZXMgd2hlcmUgdGhlIGtleXMgYXJlIHRoZQogICAqICAgIG5hbWVzIGFuZCB0aGUgdmFsdWVzIGFyZSB0aGUgZmFjdG9yaWVzLgogICAqIEBwYXJhbSB7RnVuY3Rpb258QXJyYXl9IGRpcmVjdGl2ZUZhY3RvcnkgQW4gaW5qZWN0YWJsZSBkaXJlY3RpdmUgZmFjdG9yeSBmdW5jdGlvbi4gU2VlCiAgICogICAge0BsaW5rIGd1aWRlL2RpcmVjdGl2ZX0gZm9yIG1vcmUgaW5mby4KICAgKiBAcmV0dXJucyB7bmcuJGNvbXBpbGVQcm92aWRlcn0gU2VsZiBmb3IgY2hhaW5pbmcuCiAgICovCiAgIHRoaXMuZGlyZWN0aXZlID0gZnVuY3Rpb24gcmVnaXN0ZXJEaXJlY3RpdmUobmFtZSwgZGlyZWN0aXZlRmFjdG9yeSkgewogICAgYXNzZXJ0Tm90SGFzT3duUHJvcGVydHkobmFtZSwgJ2RpcmVjdGl2ZScpOwogICAgaWYgKGlzU3RyaW5nKG5hbWUpKSB7CiAgICAgIGFzc2VydEFyZyhkaXJlY3RpdmVGYWN0b3J5LCAnZGlyZWN0aXZlRmFjdG9yeScpOwogICAgICBpZiAoIWhhc0RpcmVjdGl2ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHsKICAgICAgICBoYXNEaXJlY3RpdmVzW25hbWVdID0gW107CiAgICAgICAgJHByb3ZpZGUuZmFjdG9yeShuYW1lICsgU3VmZml4LCBbJyRpbmplY3RvcicsICckZXhjZXB0aW9uSGFuZGxlcicsCiAgICAgICAgICBmdW5jdGlvbigkaW5qZWN0b3IsICRleGNlcHRpb25IYW5kbGVyKSB7CiAgICAgICAgICAgIHZhciBkaXJlY3RpdmVzID0gW107CiAgICAgICAgICAgIGZvckVhY2goaGFzRGlyZWN0aXZlc1tuYW1lXSwgZnVuY3Rpb24oZGlyZWN0aXZlRmFjdG9yeSwgaW5kZXgpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGRpcmVjdGl2ZSA9ICRpbmplY3Rvci5pbnZva2UoZGlyZWN0aXZlRmFjdG9yeSk7CiAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihkaXJlY3RpdmUpKSB7CiAgICAgICAgICAgICAgICAgIGRpcmVjdGl2ZSA9IHsgY29tcGlsZTogdmFsdWVGbihkaXJlY3RpdmUpIH07CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFkaXJlY3RpdmUuY29tcGlsZSAmJiBkaXJlY3RpdmUubGluaykgewogICAgICAgICAgICAgICAgICBkaXJlY3RpdmUuY29tcGlsZSA9IHZhbHVlRm4oZGlyZWN0aXZlLmxpbmspOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlyZWN0aXZlLnByaW9yaXR5ID0gZGlyZWN0aXZlLnByaW9yaXR5IHx8IDA7CiAgICAgICAgICAgICAgICBkaXJlY3RpdmUuaW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgIGRpcmVjdGl2ZS5uYW1lID0gZGlyZWN0aXZlLm5hbWUgfHwgbmFtZTsKICAgICAgICAgICAgICAgIGRpcmVjdGl2ZS5yZXF1aXJlID0gZGlyZWN0aXZlLnJlcXVpcmUgfHwgKGRpcmVjdGl2ZS5jb250cm9sbGVyICYmIGRpcmVjdGl2ZS5uYW1lKTsKICAgICAgICAgICAgICAgIGRpcmVjdGl2ZS5yZXN0cmljdCA9IGRpcmVjdGl2ZS5yZXN0cmljdCB8fCAnRUEnOwogICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGRpcmVjdGl2ZS5zY29wZSkpIHsKICAgICAgICAgICAgICAgICAgZGlyZWN0aXZlLiQkaXNvbGF0ZUJpbmRpbmdzID0gcGFyc2VJc29sYXRlQmluZGluZ3MoZGlyZWN0aXZlLnNjb3BlLCBkaXJlY3RpdmUubmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkaXJlY3RpdmVzLnB1c2goZGlyZWN0aXZlKTsKICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAkZXhjZXB0aW9uSGFuZGxlcihlKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gZGlyZWN0aXZlczsKICAgICAgICAgIH1dKTsKICAgICAgfQogICAgICBoYXNEaXJlY3RpdmVzW25hbWVdLnB1c2goZGlyZWN0aXZlRmFjdG9yeSk7CiAgICB9IGVsc2UgewogICAgICBmb3JFYWNoKG5hbWUsIHJldmVyc2VQYXJhbXMocmVnaXN0ZXJEaXJlY3RpdmUpKTsKICAgIH0KICAgIHJldHVybiB0aGlzOwogIH07CgoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGNvbXBpbGVQcm92aWRlciNhSHJlZlNhbml0aXphdGlvbldoaXRlbGlzdAogICAqIEBraW5kIGZ1bmN0aW9uCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBSZXRyaWV2ZXMgb3Igb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IGlzIHVzZWQgZm9yIHdoaXRlbGlzdGluZyBvZiBzYWZlCiAgICogdXJscyBkdXJpbmcgYVtocmVmXSBzYW5pdGl6YXRpb24uCiAgICoKICAgKiBUaGUgc2FuaXRpemF0aW9uIGlzIGEgc2VjdXJpdHkgbWVhc3VyZSBhaW1lZCBhdCBwcmV2ZW50aW5nIFhTUyBhdHRhY2tzIHZpYSBodG1sIGxpbmtzLgogICAqCiAgICogQW55IHVybCBhYm91dCB0byBiZSBhc3NpZ25lZCB0byBhW2hyZWZdIHZpYSBkYXRhLWJpbmRpbmcgaXMgZmlyc3Qgbm9ybWFsaXplZCBhbmQgdHVybmVkIGludG8KICAgKiBhbiBhYnNvbHV0ZSB1cmwuIEFmdGVyd2FyZHMsIHRoZSB1cmwgaXMgbWF0Y2hlZCBhZ2FpbnN0IHRoZSBgYUhyZWZTYW5pdGl6YXRpb25XaGl0ZWxpc3RgCiAgICogcmVndWxhciBleHByZXNzaW9uLiBJZiBhIG1hdGNoIGlzIGZvdW5kLCB0aGUgb3JpZ2luYWwgdXJsIGlzIHdyaXR0ZW4gaW50byB0aGUgZG9tLiBPdGhlcndpc2UsCiAgICogdGhlIGFic29sdXRlIHVybCBpcyBwcmVmaXhlZCB3aXRoIGAndW5zYWZlOidgIHN0cmluZyBhbmQgb25seSB0aGVuIGlzIGl0IHdyaXR0ZW4gaW50byB0aGUgRE9NLgogICAqCiAgICogQHBhcmFtIHtSZWdFeHA9fSByZWdleHAgTmV3IHJlZ2V4cCB0byB3aGl0ZWxpc3QgdXJscyB3aXRoLgogICAqIEByZXR1cm5zIHtSZWdFeHB8bmcuJGNvbXBpbGVQcm92aWRlcn0gQ3VycmVudCBSZWdFeHAgaWYgY2FsbGVkIHdpdGhvdXQgdmFsdWUgb3Igc2VsZiBmb3IKICAgKiAgICBjaGFpbmluZyBvdGhlcndpc2UuCiAgICovCiAgdGhpcy5hSHJlZlNhbml0aXphdGlvbldoaXRlbGlzdCA9IGZ1bmN0aW9uKHJlZ2V4cCkgewogICAgaWYgKGlzRGVmaW5lZChyZWdleHApKSB7CiAgICAgICQkc2FuaXRpemVVcmlQcm92aWRlci5hSHJlZlNhbml0aXphdGlvbldoaXRlbGlzdChyZWdleHApOwogICAgICByZXR1cm4gdGhpczsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiAkJHNhbml0aXplVXJpUHJvdmlkZXIuYUhyZWZTYW5pdGl6YXRpb25XaGl0ZWxpc3QoKTsKICAgIH0KICB9OwoKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRjb21waWxlUHJvdmlkZXIjaW1nU3JjU2FuaXRpemF0aW9uV2hpdGVsaXN0CiAgICogQGtpbmQgZnVuY3Rpb24KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJldHJpZXZlcyBvciBvdmVycmlkZXMgdGhlIGRlZmF1bHQgcmVndWxhciBleHByZXNzaW9uIHRoYXQgaXMgdXNlZCBmb3Igd2hpdGVsaXN0aW5nIG9mIHNhZmUKICAgKiB1cmxzIGR1cmluZyBpbWdbc3JjXSBzYW5pdGl6YXRpb24uCiAgICoKICAgKiBUaGUgc2FuaXRpemF0aW9uIGlzIGEgc2VjdXJpdHkgbWVhc3VyZSBhaW1lZCBhdCBwcmV2ZW50IFhTUyBhdHRhY2tzIHZpYSBodG1sIGxpbmtzLgogICAqCiAgICogQW55IHVybCBhYm91dCB0byBiZSBhc3NpZ25lZCB0byBpbWdbc3JjXSB2aWEgZGF0YS1iaW5kaW5nIGlzIGZpcnN0IG5vcm1hbGl6ZWQgYW5kIHR1cm5lZCBpbnRvCiAgICogYW4gYWJzb2x1dGUgdXJsLiBBZnRlcndhcmRzLCB0aGUgdXJsIGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgYGltZ1NyY1Nhbml0aXphdGlvbldoaXRlbGlzdGAKICAgKiByZWd1bGFyIGV4cHJlc3Npb24uIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoZSBvcmlnaW5hbCB1cmwgaXMgd3JpdHRlbiBpbnRvIHRoZSBkb20uIE90aGVyd2lzZSwKICAgKiB0aGUgYWJzb2x1dGUgdXJsIGlzIHByZWZpeGVkIHdpdGggYCd1bnNhZmU6J2Agc3RyaW5nIGFuZCBvbmx5IHRoZW4gaXMgaXQgd3JpdHRlbiBpbnRvIHRoZSBET00uCiAgICoKICAgKiBAcGFyYW0ge1JlZ0V4cD19IHJlZ2V4cCBOZXcgcmVnZXhwIHRvIHdoaXRlbGlzdCB1cmxzIHdpdGguCiAgICogQHJldHVybnMge1JlZ0V4cHxuZy4kY29tcGlsZVByb3ZpZGVyfSBDdXJyZW50IFJlZ0V4cCBpZiBjYWxsZWQgd2l0aG91dCB2YWx1ZSBvciBzZWxmIGZvcgogICAqICAgIGNoYWluaW5nIG90aGVyd2lzZS4KICAgKi8KICB0aGlzLmltZ1NyY1Nhbml0aXphdGlvbldoaXRlbGlzdCA9IGZ1bmN0aW9uKHJlZ2V4cCkgewogICAgaWYgKGlzRGVmaW5lZChyZWdleHApKSB7CiAgICAgICQkc2FuaXRpemVVcmlQcm92aWRlci5pbWdTcmNTYW5pdGl6YXRpb25XaGl0ZWxpc3QocmVnZXhwKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gJCRzYW5pdGl6ZVVyaVByb3ZpZGVyLmltZ1NyY1Nhbml0aXphdGlvbldoaXRlbGlzdCgpOwogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAgJGNvbXBpbGVQcm92aWRlciNkZWJ1Z0luZm9FbmFibGVkCiAgICoKICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBlbmFibGVkIHVwZGF0ZSB0aGUgZGVidWdJbmZvRW5hYmxlZCBzdGF0ZSBpZiBwcm92aWRlZCwgb3RoZXJ3aXNlIGp1c3QgcmV0dXJuIHRoZQogICAqIGN1cnJlbnQgZGVidWdJbmZvRW5hYmxlZCBzdGF0ZQogICAqIEByZXR1cm5zIHsqfSBjdXJyZW50IHZhbHVlIGlmIHVzZWQgYXMgZ2V0dGVyIG9yIGl0c2VsZiAoY2hhaW5pbmcpIGlmIHVzZWQgYXMgc2V0dGVyCiAgICoKICAgKiBAa2luZCBmdW5jdGlvbgogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ2FsbCB0aGlzIG1ldGhvZCB0byBlbmFibGUvZGlzYWJsZSB2YXJpb3VzIGRlYnVnIHJ1bnRpbWUgaW5mb3JtYXRpb24gaW4gdGhlIGNvbXBpbGVyIHN1Y2ggYXMgYWRkaW5nCiAgICogYmluZGluZyBpbmZvcm1hdGlvbiBhbmQgYSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgc2NvcGUgb24gdG8gRE9NIGVsZW1lbnRzLgogICAqIElmIGVuYWJsZWQsIHRoZSBjb21waWxlciB3aWxsIGFkZCB0aGUgZm9sbG93aW5nIHRvIERPTSBlbGVtZW50cyB0aGF0IGhhdmUgYmVlbiBib3VuZCB0byB0aGUgc2NvcGUKICAgKiAqIGBuZy1iaW5kaW5nYCBDU1MgY2xhc3MKICAgKiAqIGAkYmluZGluZ2AgZGF0YSBwcm9wZXJ0eSBjb250YWluaW5nIGFuIGFycmF5IG9mIHRoZSBiaW5kaW5nIGV4cHJlc3Npb25zCiAgICoKICAgKiBZb3UgbWF5IHdhbnQgdG8gZGlzYWJsZSB0aGlzIGluIHByb2R1Y3Rpb24gZm9yIGEgc2lnbmlmaWNhbnQgcGVyZm9ybWFuY2UgYm9vc3QuIFNlZQogICAqIHtAbGluayBndWlkZS9wcm9kdWN0aW9uI2Rpc2FibGluZy1kZWJ1Zy1kYXRhIERpc2FibGluZyBEZWJ1ZyBEYXRhfSBmb3IgbW9yZS4KICAgKgogICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRydWUuCiAgICovCiAgdmFyIGRlYnVnSW5mb0VuYWJsZWQgPSB0cnVlOwogIHRoaXMuZGVidWdJbmZvRW5hYmxlZCA9IGZ1bmN0aW9uKGVuYWJsZWQpIHsKICAgIGlmIChpc0RlZmluZWQoZW5hYmxlZCkpIHsKICAgICAgZGVidWdJbmZvRW5hYmxlZCA9IGVuYWJsZWQ7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcmV0dXJuIGRlYnVnSW5mb0VuYWJsZWQ7CiAgfTsKCiAgdGhpcy4kZ2V0ID0gWwogICAgICAgICAgICAnJGluamVjdG9yJywgJyRpbnRlcnBvbGF0ZScsICckZXhjZXB0aW9uSGFuZGxlcicsICckdGVtcGxhdGVSZXF1ZXN0JywgJyRwYXJzZScsCiAgICAgICAgICAgICckY29udHJvbGxlcicsICckcm9vdFNjb3BlJywgJyRkb2N1bWVudCcsICckc2NlJywgJyRhbmltYXRlJywgJyQkc2FuaXRpemVVcmknLAogICAgZnVuY3Rpb24oJGluamVjdG9yLCAgICRpbnRlcnBvbGF0ZSwgICAkZXhjZXB0aW9uSGFuZGxlciwgICAkdGVtcGxhdGVSZXF1ZXN0LCAgICRwYXJzZSwKICAgICAgICAgICAgICRjb250cm9sbGVyLCAgICRyb290U2NvcGUsICAgJGRvY3VtZW50LCAgICRzY2UsICAgJGFuaW1hdGUsICAgJCRzYW5pdGl6ZVVyaSkgewoKICAgIHZhciBBdHRyaWJ1dGVzID0gZnVuY3Rpb24oZWxlbWVudCwgYXR0cmlidXRlc1RvQ29weSkgewogICAgICBpZiAoYXR0cmlidXRlc1RvQ29weSkgewogICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYXR0cmlidXRlc1RvQ29weSk7CiAgICAgICAgdmFyIGksIGwsIGtleTsKCiAgICAgICAgZm9yIChpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgICAgICBrZXkgPSBrZXlzW2ldOwogICAgICAgICAgdGhpc1trZXldID0gYXR0cmlidXRlc1RvQ29weVtrZXldOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICB0aGlzLiRhdHRyID0ge307CiAgICAgIH0KCiAgICAgIHRoaXMuJCRlbGVtZW50ID0gZWxlbWVudDsKICAgIH07CgogICAgQXR0cmlidXRlcy5wcm90b3R5cGUgPSB7CiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRjb21waWxlLmRpcmVjdGl2ZS5BdHRyaWJ1dGVzIyRub3JtYWxpemUKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIENvbnZlcnRzIGFuIGF0dHJpYnV0ZSBuYW1lIChlLmcuIGRhc2gvY29sb24vdW5kZXJzY29yZS1kZWxpbWl0ZWQgc3RyaW5nLCBvcHRpb25hbGx5IHByZWZpeGVkIHdpdGggYHgtYCBvcgogICAgICAgKiBgZGF0YS1gKSB0byBpdHMgbm9ybWFsaXplZCwgY2FtZWxDYXNlIGZvcm0uCiAgICAgICAqCiAgICAgICAqIEFsc28gdGhlcmUgaXMgc3BlY2lhbCBjYXNlIGZvciBNb3ogcHJlZml4IHN0YXJ0aW5nIHdpdGggdXBwZXIgY2FzZSBsZXR0ZXIuCiAgICAgICAqCiAgICAgICAqIEZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIGNoZWNrIG91dCB0aGUgZ3VpZGUgb24ge0BsaW5rIGd1aWRlL2RpcmVjdGl2ZSNtYXRjaGluZy1kaXJlY3RpdmVzIE1hdGNoaW5nIERpcmVjdGl2ZXN9CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5hbWUgdG8gbm9ybWFsaXplCiAgICAgICAqLwogICAgICAkbm9ybWFsaXplOiBkaXJlY3RpdmVOb3JtYWxpemUsCgoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGNvbXBpbGUuZGlyZWN0aXZlLkF0dHJpYnV0ZXMjJGFkZENsYXNzCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBBZGRzIHRoZSBDU1MgY2xhc3MgdmFsdWUgc3BlY2lmaWVkIGJ5IHRoZSBjbGFzc1ZhbCBwYXJhbWV0ZXIgdG8gdGhlIGVsZW1lbnQuIElmIGFuaW1hdGlvbnMKICAgICAgICogYXJlIGVuYWJsZWQgdGhlbiBhbiBhbmltYXRpb24gd2lsbCBiZSB0cmlnZ2VyZWQgZm9yIHRoZSBjbGFzcyBhZGRpdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzVmFsIFRoZSBjbGFzc05hbWUgdmFsdWUgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBlbGVtZW50CiAgICAgICAqLwogICAgICAkYWRkQ2xhc3M6IGZ1bmN0aW9uKGNsYXNzVmFsKSB7CiAgICAgICAgaWYgKGNsYXNzVmFsICYmIGNsYXNzVmFsLmxlbmd0aCA+IDApIHsKICAgICAgICAgICRhbmltYXRlLmFkZENsYXNzKHRoaXMuJCRlbGVtZW50LCBjbGFzc1ZhbCk7CiAgICAgICAgfQogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGNvbXBpbGUuZGlyZWN0aXZlLkF0dHJpYnV0ZXMjJHJlbW92ZUNsYXNzCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBSZW1vdmVzIHRoZSBDU1MgY2xhc3MgdmFsdWUgc3BlY2lmaWVkIGJ5IHRoZSBjbGFzc1ZhbCBwYXJhbWV0ZXIgZnJvbSB0aGUgZWxlbWVudC4gSWYKICAgICAgICogYW5pbWF0aW9ucyBhcmUgZW5hYmxlZCB0aGVuIGFuIGFuaW1hdGlvbiB3aWxsIGJlIHRyaWdnZXJlZCBmb3IgdGhlIGNsYXNzIHJlbW92YWwuCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc1ZhbCBUaGUgY2xhc3NOYW1lIHZhbHVlIHRoYXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQKICAgICAgICovCiAgICAgICRyZW1vdmVDbGFzczogZnVuY3Rpb24oY2xhc3NWYWwpIHsKICAgICAgICBpZiAoY2xhc3NWYWwgJiYgY2xhc3NWYWwubGVuZ3RoID4gMCkgewogICAgICAgICAgJGFuaW1hdGUucmVtb3ZlQ2xhc3ModGhpcy4kJGVsZW1lbnQsIGNsYXNzVmFsKTsKICAgICAgICB9CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgKiBAbmFtZSAkY29tcGlsZS5kaXJlY3RpdmUuQXR0cmlidXRlcyMkdXBkYXRlQ2xhc3MKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIEFkZHMgYW5kIHJlbW92ZXMgdGhlIGFwcHJvcHJpYXRlIENTUyBjbGFzcyB2YWx1ZXMgdG8gdGhlIGVsZW1lbnQgYmFzZWQgb24gdGhlIGRpZmZlcmVuY2UKICAgICAgICogYmV0d2VlbiB0aGUgbmV3IGFuZCBvbGQgQ1NTIGNsYXNzIHZhbHVlcyAoc3BlY2lmaWVkIGFzIG5ld0NsYXNzZXMgYW5kIG9sZENsYXNzZXMpLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3Q2xhc3NlcyBUaGUgY3VycmVudCBDU1MgY2xhc3NOYW1lIHZhbHVlCiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvbGRDbGFzc2VzIFRoZSBmb3JtZXIgQ1NTIGNsYXNzTmFtZSB2YWx1ZQogICAgICAgKi8KICAgICAgJHVwZGF0ZUNsYXNzOiBmdW5jdGlvbihuZXdDbGFzc2VzLCBvbGRDbGFzc2VzKSB7CiAgICAgICAgdmFyIHRvQWRkID0gdG9rZW5EaWZmZXJlbmNlKG5ld0NsYXNzZXMsIG9sZENsYXNzZXMpOwogICAgICAgIGlmICh0b0FkZCAmJiB0b0FkZC5sZW5ndGgpIHsKICAgICAgICAgICRhbmltYXRlLmFkZENsYXNzKHRoaXMuJCRlbGVtZW50LCB0b0FkZCk7CiAgICAgICAgfQoKICAgICAgICB2YXIgdG9SZW1vdmUgPSB0b2tlbkRpZmZlcmVuY2Uob2xkQ2xhc3NlcywgbmV3Q2xhc3Nlcyk7CiAgICAgICAgaWYgKHRvUmVtb3ZlICYmIHRvUmVtb3ZlLmxlbmd0aCkgewogICAgICAgICAgJGFuaW1hdGUucmVtb3ZlQ2xhc3ModGhpcy4kJGVsZW1lbnQsIHRvUmVtb3ZlKTsKICAgICAgICB9CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogU2V0IGEgbm9ybWFsaXplZCBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQgaW4gYSB3YXkgc3VjaCB0aGF0IGFsbCBkaXJlY3RpdmVzCiAgICAgICAqIGNhbiBzaGFyZSB0aGUgYXR0cmlidXRlLiBUaGlzIGZ1bmN0aW9uIHByb3Blcmx5IGhhbmRsZXMgYm9vbGVhbiBhdHRyaWJ1dGVzLgogICAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IE5vcm1hbGl6ZWQga2V5LiAoaWUgbmdBdHRyaWJ1dGUpCiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfGJvb2xlYW59IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuIElmIGBudWxsYCBhdHRyaWJ1dGUgd2lsbCBiZSBkZWxldGVkLgogICAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB3cml0ZUF0dHIgSWYgZmFsc2UsIGRvZXMgbm90IHdyaXRlIHRoZSB2YWx1ZSB0byBET00gZWxlbWVudCBhdHRyaWJ1dGUuCiAgICAgICAqICAgICBEZWZhdWx0cyB0byB0cnVlLgogICAgICAgKiBAcGFyYW0ge3N0cmluZz19IGF0dHJOYW1lIE9wdGlvbmFsIG5vbmUgbm9ybWFsaXplZCBuYW1lLiBEZWZhdWx0cyB0byBrZXkuCiAgICAgICAqLwogICAgICAkc2V0OiBmdW5jdGlvbihrZXksIHZhbHVlLCB3cml0ZUF0dHIsIGF0dHJOYW1lKSB7CiAgICAgICAgLy8gVE9ETzogZGVjaWRlIHdoZXRoZXIgb3Igbm90IHRvIHRocm93IGFuIGVycm9yIGlmICJjbGFzcyIKICAgICAgICAvL2lzIHNldCB0aHJvdWdoIHRoaXMgZnVuY3Rpb24gc2luY2UgaXQgbWF5IGNhdXNlICR1cGRhdGVDbGFzcyB0bwogICAgICAgIC8vYmVjb21lIHVuc3RhYmxlLgoKICAgICAgICB2YXIgbm9kZSA9IHRoaXMuJCRlbGVtZW50WzBdLAogICAgICAgICAgICBib29sZWFuS2V5ID0gZ2V0Qm9vbGVhbkF0dHJOYW1lKG5vZGUsIGtleSksCiAgICAgICAgICAgIGFsaWFzZWRLZXkgPSBnZXRBbGlhc2VkQXR0ck5hbWUobm9kZSwga2V5KSwKICAgICAgICAgICAgb2JzZXJ2ZXIgPSBrZXksCiAgICAgICAgICAgIG5vZGVOYW1lOwoKICAgICAgICBpZiAoYm9vbGVhbktleSkgewogICAgICAgICAgdGhpcy4kJGVsZW1lbnQucHJvcChrZXksIHZhbHVlKTsKICAgICAgICAgIGF0dHJOYW1lID0gYm9vbGVhbktleTsKICAgICAgICB9IGVsc2UgaWYgKGFsaWFzZWRLZXkpIHsKICAgICAgICAgIHRoaXNbYWxpYXNlZEtleV0gPSB2YWx1ZTsKICAgICAgICAgIG9ic2VydmVyID0gYWxpYXNlZEtleTsKICAgICAgICB9CgogICAgICAgIHRoaXNba2V5XSA9IHZhbHVlOwoKICAgICAgICAvLyB0cmFuc2xhdGUgbm9ybWFsaXplZCBrZXkgdG8gYWN0dWFsIGtleQogICAgICAgIGlmIChhdHRyTmFtZSkgewogICAgICAgICAgdGhpcy4kYXR0cltrZXldID0gYXR0ck5hbWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGF0dHJOYW1lID0gdGhpcy4kYXR0cltrZXldOwogICAgICAgICAgaWYgKCFhdHRyTmFtZSkgewogICAgICAgICAgICB0aGlzLiRhdHRyW2tleV0gPSBhdHRyTmFtZSA9IHNuYWtlX2Nhc2Uoa2V5LCAnLScpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgbm9kZU5hbWUgPSBub2RlTmFtZV8odGhpcy4kJGVsZW1lbnQpOwoKICAgICAgICBpZiAoKG5vZGVOYW1lID09PSAnYScgJiYga2V5ID09PSAnaHJlZicpIHx8CiAgICAgICAgICAgIChub2RlTmFtZSA9PT0gJ2ltZycgJiYga2V5ID09PSAnc3JjJykpIHsKICAgICAgICAgIC8vIHNhbml0aXplIGFbaHJlZl0gYW5kIGltZ1tzcmNdIHZhbHVlcwogICAgICAgICAgdGhpc1trZXldID0gdmFsdWUgPSAkJHNhbml0aXplVXJpKHZhbHVlLCBrZXkgPT09ICdzcmMnKTsKICAgICAgICB9IGVsc2UgaWYgKG5vZGVOYW1lID09PSAnaW1nJyAmJiBrZXkgPT09ICdzcmNzZXQnKSB7CiAgICAgICAgICAvLyBzYW5pdGl6ZSBpbWdbc3Jjc2V0XSB2YWx1ZXMKICAgICAgICAgIHZhciByZXN1bHQgPSAiIjsKCiAgICAgICAgICAvLyBmaXJzdCBjaGVjayBpZiB0aGVyZSBhcmUgc3BhY2VzIGJlY2F1c2UgaXQncyBub3QgdGhlIHNhbWUgcGF0dGVybgogICAgICAgICAgdmFyIHRyaW1tZWRTcmNzZXQgPSB0cmltKHZhbHVlKTsKICAgICAgICAgIC8vICAgICAgICAgICAgICAgICggICA5OTl4ICAgLHwgICA5OTl3ICAgLHwgICAsfCwgICApCiAgICAgICAgICB2YXIgc3JjUGF0dGVybiA9IC8oXHMrXGQreFxzKix8XHMrXGQrd1xzKix8XHMrLHwsXHMrKS87CiAgICAgICAgICB2YXIgcGF0dGVybiA9IC9ccy8udGVzdCh0cmltbWVkU3Jjc2V0KSA/IHNyY1BhdHRlcm4gOiAvKCwpLzsKCiAgICAgICAgICAvLyBzcGxpdCBzcmNzZXQgaW50byB0dXBsZSBvZiB1cmkgYW5kIGRlc2NyaXB0b3IgZXhjZXB0IGZvciB0aGUgbGFzdCBpdGVtCiAgICAgICAgICB2YXIgcmF3VXJpcyA9IHRyaW1tZWRTcmNzZXQuc3BsaXQocGF0dGVybik7CgogICAgICAgICAgLy8gZm9yIGVhY2ggdHVwbGVzCiAgICAgICAgICB2YXIgbmJyVXJpc1dpdGgycGFydHMgPSBNYXRoLmZsb29yKHJhd1VyaXMubGVuZ3RoIC8gMik7CiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5iclVyaXNXaXRoMnBhcnRzOyBpKyspIHsKICAgICAgICAgICAgdmFyIGlubmVySWR4ID0gaSAqIDI7CiAgICAgICAgICAgIC8vIHNhbml0aXplIHRoZSB1cmkKICAgICAgICAgICAgcmVzdWx0ICs9ICQkc2FuaXRpemVVcmkodHJpbShyYXdVcmlzW2lubmVySWR4XSksIHRydWUpOwogICAgICAgICAgICAvLyBhZGQgdGhlIGRlc2NyaXB0b3IKICAgICAgICAgICAgcmVzdWx0ICs9ICgiICIgKyB0cmltKHJhd1VyaXNbaW5uZXJJZHggKyAxXSkpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIHNwbGl0IHRoZSBsYXN0IGl0ZW0gaW50byB1cmkgYW5kIGRlc2NyaXB0b3IKICAgICAgICAgIHZhciBsYXN0VHVwbGUgPSB0cmltKHJhd1VyaXNbaSAqIDJdKS5zcGxpdCgvXHMvKTsKCiAgICAgICAgICAvLyBzYW5pdGl6ZSB0aGUgbGFzdCB1cmkKICAgICAgICAgIHJlc3VsdCArPSAkJHNhbml0aXplVXJpKHRyaW0obGFzdFR1cGxlWzBdKSwgdHJ1ZSk7CgogICAgICAgICAgLy8gYW5kIGFkZCB0aGUgbGFzdCBkZXNjcmlwdG9yIGlmIGFueQogICAgICAgICAgaWYgKGxhc3RUdXBsZS5sZW5ndGggPT09IDIpIHsKICAgICAgICAgICAgcmVzdWx0ICs9ICgiICIgKyB0cmltKGxhc3RUdXBsZVsxXSkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpc1trZXldID0gdmFsdWUgPSByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAod3JpdGVBdHRyICE9PSBmYWxzZSkgewogICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdGhpcy4kJGVsZW1lbnQucmVtb3ZlQXR0cihhdHRyTmFtZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLiQkZWxlbWVudC5hdHRyKGF0dHJOYW1lLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBmaXJlIG9ic2VydmVycwogICAgICAgIHZhciAkJG9ic2VydmVycyA9IHRoaXMuJCRvYnNlcnZlcnM7CiAgICAgICAgJCRvYnNlcnZlcnMgJiYgZm9yRWFjaCgkJG9ic2VydmVyc1tvYnNlcnZlcl0sIGZ1bmN0aW9uKGZuKSB7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBmbih2YWx1ZSk7CiAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9LAoKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRjb21waWxlLmRpcmVjdGl2ZS5BdHRyaWJ1dGVzIyRvYnNlcnZlCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBPYnNlcnZlcyBhbiBpbnRlcnBvbGF0ZWQgYXR0cmlidXRlLgogICAgICAgKgogICAgICAgKiBUaGUgb2JzZXJ2ZXIgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIG9uY2UgZHVyaW5nIHRoZSBuZXh0IGAkZGlnZXN0YCBmb2xsb3dpbmcKICAgICAgICogY29tcGlsYXRpb24uIFRoZSBvYnNlcnZlciBpcyB0aGVuIGludm9rZWQgd2hlbmV2ZXIgdGhlIGludGVycG9sYXRlZCB2YWx1ZQogICAgICAgKiBjaGFuZ2VzLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IE5vcm1hbGl6ZWQga2V5LiAoaWUgbmdBdHRyaWJ1dGUpIC4KICAgICAgICogQHBhcmFtIHtmdW5jdGlvbihpbnRlcnBvbGF0ZWRWYWx1ZSl9IGZuIEZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIKICAgICAgICAgICAgICAgIHRoZSBpbnRlcnBvbGF0ZWQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBjaGFuZ2VzLgogICAgICAgKiAgICAgICAgU2VlIHRoZSB7QGxpbmsgZ3VpZGUvZGlyZWN0aXZlI3RleHQtYW5kLWF0dHJpYnV0ZS1iaW5kaW5ncyBEaXJlY3RpdmVzfSBndWlkZSBmb3IgbW9yZSBpbmZvLgogICAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oKX0gUmV0dXJucyBhIGRlcmVnaXN0cmF0aW9uIGZ1bmN0aW9uIGZvciB0aGlzIG9ic2VydmVyLgogICAgICAgKi8KICAgICAgJG9ic2VydmU6IGZ1bmN0aW9uKGtleSwgZm4pIHsKICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLAogICAgICAgICAgICAkJG9ic2VydmVycyA9IChhdHRycy4kJG9ic2VydmVycyB8fCAoYXR0cnMuJCRvYnNlcnZlcnMgPSBjcmVhdGVNYXAoKSkpLAogICAgICAgICAgICBsaXN0ZW5lcnMgPSAoJCRvYnNlcnZlcnNba2V5XSB8fCAoJCRvYnNlcnZlcnNba2V5XSA9IFtdKSk7CgogICAgICAgIGxpc3RlbmVycy5wdXNoKGZuKTsKICAgICAgICAkcm9vdFNjb3BlLiRldmFsQXN5bmMoZnVuY3Rpb24oKSB7CiAgICAgICAgICBpZiAoIWxpc3RlbmVycy4kJGludGVyICYmIGF0dHJzLmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgLy8gbm8gb25lIHJlZ2lzdGVyZWQgYXR0cmlidXRlIGludGVycG9sYXRpb24gZnVuY3Rpb24sIHNvIGxldHMgY2FsbCBpdCBtYW51YWxseQogICAgICAgICAgICBmbihhdHRyc1trZXldKTsKICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgYXJyYXlSZW1vdmUobGlzdGVuZXJzLCBmbik7CiAgICAgICAgfTsKICAgICAgfQogICAgfTsKCgogICAgZnVuY3Rpb24gc2FmZUFkZENsYXNzKCRlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgICAgdHJ5IHsKICAgICAgICAkZWxlbWVudC5hZGRDbGFzcyhjbGFzc05hbWUpOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgLy8gaWdub3JlLCBzaW5jZSBpdCBtZWFucyB0aGF0IHdlIGFyZSB0cnlpbmcgdG8gc2V0IGNsYXNzIG9uCiAgICAgICAgLy8gU1ZHIGVsZW1lbnQsIHdoZXJlIGNsYXNzIG5hbWUgaXMgcmVhZC1vbmx5LgogICAgICB9CiAgICB9CgoKICAgIHZhciBzdGFydFN5bWJvbCA9ICRpbnRlcnBvbGF0ZS5zdGFydFN5bWJvbCgpLAogICAgICAgIGVuZFN5bWJvbCA9ICRpbnRlcnBvbGF0ZS5lbmRTeW1ib2woKSwKICAgICAgICBkZW5vcm1hbGl6ZVRlbXBsYXRlID0gKHN0YXJ0U3ltYm9sID09ICd7eycgfHwgZW5kU3ltYm9sICA9PSAnfX0nKQogICAgICAgICAgICA/IGlkZW50aXR5CiAgICAgICAgICAgIDogZnVuY3Rpb24gZGVub3JtYWxpemVUZW1wbGF0ZSh0ZW1wbGF0ZSkgewogICAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKC9ce1x7L2csIHN0YXJ0U3ltYm9sKS5yZXBsYWNlKC99fS9nLCBlbmRTeW1ib2wpOwogICAgICAgIH0sCiAgICAgICAgTkdfQVRUUl9CSU5ESU5HID0gL15uZ0F0dHJbQS1aXS87CgogICAgY29tcGlsZS4kJGFkZEJpbmRpbmdJbmZvID0gZGVidWdJbmZvRW5hYmxlZCA/IGZ1bmN0aW9uICQkYWRkQmluZGluZ0luZm8oJGVsZW1lbnQsIGJpbmRpbmcpIHsKICAgICAgdmFyIGJpbmRpbmdzID0gJGVsZW1lbnQuZGF0YSgnJGJpbmRpbmcnKSB8fCBbXTsKCiAgICAgIGlmIChpc0FycmF5KGJpbmRpbmcpKSB7CiAgICAgICAgYmluZGluZ3MgPSBiaW5kaW5ncy5jb25jYXQoYmluZGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYmluZGluZ3MucHVzaChiaW5kaW5nKTsKICAgICAgfQoKICAgICAgJGVsZW1lbnQuZGF0YSgnJGJpbmRpbmcnLCBiaW5kaW5ncyk7CiAgICB9IDogbm9vcDsKCiAgICBjb21waWxlLiQkYWRkQmluZGluZ0NsYXNzID0gZGVidWdJbmZvRW5hYmxlZCA/IGZ1bmN0aW9uICQkYWRkQmluZGluZ0NsYXNzKCRlbGVtZW50KSB7CiAgICAgIHNhZmVBZGRDbGFzcygkZWxlbWVudCwgJ25nLWJpbmRpbmcnKTsKICAgIH0gOiBub29wOwoKICAgIGNvbXBpbGUuJCRhZGRTY29wZUluZm8gPSBkZWJ1Z0luZm9FbmFibGVkID8gZnVuY3Rpb24gJCRhZGRTY29wZUluZm8oJGVsZW1lbnQsIHNjb3BlLCBpc29sYXRlZCwgbm9UZW1wbGF0ZSkgewogICAgICB2YXIgZGF0YU5hbWUgPSBpc29sYXRlZCA/IChub1RlbXBsYXRlID8gJyRpc29sYXRlU2NvcGVOb1RlbXBsYXRlJyA6ICckaXNvbGF0ZVNjb3BlJykgOiAnJHNjb3BlJzsKICAgICAgJGVsZW1lbnQuZGF0YShkYXRhTmFtZSwgc2NvcGUpOwogICAgfSA6IG5vb3A7CgogICAgY29tcGlsZS4kJGFkZFNjb3BlQ2xhc3MgPSBkZWJ1Z0luZm9FbmFibGVkID8gZnVuY3Rpb24gJCRhZGRTY29wZUNsYXNzKCRlbGVtZW50LCBpc29sYXRlZCkgewogICAgICBzYWZlQWRkQ2xhc3MoJGVsZW1lbnQsIGlzb2xhdGVkID8gJ25nLWlzb2xhdGUtc2NvcGUnIDogJ25nLXNjb3BlJyk7CiAgICB9IDogbm9vcDsKCiAgICByZXR1cm4gY29tcGlsZTsKCiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgZnVuY3Rpb24gY29tcGlsZSgkY29tcGlsZU5vZGVzLCB0cmFuc2NsdWRlRm4sIG1heFByaW9yaXR5LCBpZ25vcmVEaXJlY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzQ29tcGlsZUNvbnRleHQpIHsKICAgICAgaWYgKCEoJGNvbXBpbGVOb2RlcyBpbnN0YW5jZW9mIGpxTGl0ZSkpIHsKICAgICAgICAvLyBqcXVlcnkgYWx3YXlzIHJld3JhcHMsIHdoZXJlYXMgd2UgbmVlZCB0byBwcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgc2VsZWN0b3Igc28gdGhhdCB3ZSBjYW4KICAgICAgICAvLyBtb2RpZnkgaXQuCiAgICAgICAgJGNvbXBpbGVOb2RlcyA9IGpxTGl0ZSgkY29tcGlsZU5vZGVzKTsKICAgICAgfQogICAgICAvLyBXZSBjYW4gbm90IGNvbXBpbGUgdG9wIGxldmVsIHRleHQgZWxlbWVudHMgc2luY2UgdGV4dCBub2RlcyBjYW4gYmUgbWVyZ2VkIGFuZCB3ZSB3aWxsCiAgICAgIC8vIG5vdCBiZSBhYmxlIHRvIGF0dGFjaCBzY29wZSBkYXRhIHRvIHRoZW0sIHNvIHdlIHdpbGwgd3JhcCB0aGVtIGluIDxzcGFuPgogICAgICBmb3JFYWNoKCRjb21waWxlTm9kZXMsIGZ1bmN0aW9uKG5vZGUsIGluZGV4KSB7CiAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gTk9ERV9UWVBFX1RFWFQgJiYgbm9kZS5ub2RlVmFsdWUubWF0Y2goL1xTKy8pIC8qIG5vbi1lbXB0eSAqLyApIHsKICAgICAgICAgICRjb21waWxlTm9kZXNbaW5kZXhdID0ganFMaXRlKG5vZGUpLndyYXAoJzxzcGFuPjwvc3Bhbj4nKS5wYXJlbnQoKVswXTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICB2YXIgY29tcG9zaXRlTGlua0ZuID0KICAgICAgICAgICAgICBjb21waWxlTm9kZXMoJGNvbXBpbGVOb2RlcywgdHJhbnNjbHVkZUZuLCAkY29tcGlsZU5vZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhQcmlvcml0eSwgaWdub3JlRGlyZWN0aXZlLCBwcmV2aW91c0NvbXBpbGVDb250ZXh0KTsKICAgICAgY29tcGlsZS4kJGFkZFNjb3BlQ2xhc3MoJGNvbXBpbGVOb2Rlcyk7CiAgICAgIHZhciBuYW1lc3BhY2UgPSBudWxsOwogICAgICByZXR1cm4gZnVuY3Rpb24gcHVibGljTGlua0ZuKHNjb3BlLCBjbG9uZUNvbm5lY3RGbiwgb3B0aW9ucykgewogICAgICAgIGFzc2VydEFyZyhzY29wZSwgJ3Njb3BlJyk7CgogICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgIHZhciBwYXJlbnRCb3VuZFRyYW5zY2x1ZGVGbiA9IG9wdGlvbnMucGFyZW50Qm91bmRUcmFuc2NsdWRlRm4sCiAgICAgICAgICB0cmFuc2NsdWRlQ29udHJvbGxlcnMgPSBvcHRpb25zLnRyYW5zY2x1ZGVDb250cm9sbGVycywKICAgICAgICAgIGZ1dHVyZVBhcmVudEVsZW1lbnQgPSBvcHRpb25zLmZ1dHVyZVBhcmVudEVsZW1lbnQ7CgogICAgICAgIC8vIFdoZW4gYHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuYCBpcyBwYXNzZWQsIGl0IGlzIGEKICAgICAgICAvLyBgY29udHJvbGxlcnNCb3VuZFRyYW5zY2x1ZGVgIGZ1bmN0aW9uIChpdCB3YXMgcHJldmlvdXNseSBwYXNzZWQKICAgICAgICAvLyBhcyBgdHJhbnNjbHVkZWAgdG8gZGlyZWN0aXZlLmxpbmspIHNvIHdlIG11c3QgdW53cmFwIGl0IHRvIGdldAogICAgICAgIC8vIGl0cyBgYm91bmRUcmFuc2NsdWRlRm5gCiAgICAgICAgaWYgKHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuICYmIHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuLiQkYm91bmRUcmFuc2NsdWRlKSB7CiAgICAgICAgICBwYXJlbnRCb3VuZFRyYW5zY2x1ZGVGbiA9IHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuLiQkYm91bmRUcmFuc2NsdWRlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFuYW1lc3BhY2UpIHsKICAgICAgICAgIG5hbWVzcGFjZSA9IGRldGVjdE5hbWVzcGFjZUZvckNoaWxkRWxlbWVudHMoZnV0dXJlUGFyZW50RWxlbWVudCk7CiAgICAgICAgfQogICAgICAgIHZhciAkbGlua05vZGU7CiAgICAgICAgaWYgKG5hbWVzcGFjZSAhPT0gJ2h0bWwnKSB7CiAgICAgICAgICAvLyBXaGVuIHVzaW5nIGEgZGlyZWN0aXZlIHdpdGggcmVwbGFjZTp0cnVlIGFuZCB0ZW1wbGF0ZVVybCB0aGUgJGNvbXBpbGVOb2RlcwogICAgICAgICAgLy8gKG9yIGEgY2hpbGQgZWxlbWVudCBpbnNpZGUgb2YgdGhlbSkKICAgICAgICAgIC8vIG1pZ2h0IGNoYW5nZSwgc28gd2UgbmVlZCB0byByZWNyZWF0ZSB0aGUgbmFtZXNwYWNlIGFkYXB0ZWQgY29tcGlsZU5vZGVzCiAgICAgICAgICAvLyBmb3IgY2FsbCB0byB0aGUgbGluayBmdW5jdGlvbi4KICAgICAgICAgIC8vIE5vdGU6IFRoaXMgd2lsbCBhbHJlYWR5IGNsb25lIHRoZSBub2Rlcy4uLgogICAgICAgICAgJGxpbmtOb2RlID0ganFMaXRlKAogICAgICAgICAgICB3cmFwVGVtcGxhdGUobmFtZXNwYWNlLCBqcUxpdGUoJzxkaXY+JykuYXBwZW5kKCRjb21waWxlTm9kZXMpLmh0bWwoKSkKICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIGlmIChjbG9uZUNvbm5lY3RGbikgewogICAgICAgICAgLy8gaW1wb3J0YW50ISE6IHdlIG11c3QgY2FsbCBvdXIganFMaXRlLmNsb25lKCkgc2luY2UgdGhlIGpRdWVyeSBvbmUgaXMgdHJ5aW5nIHRvIGJlIHNtYXJ0CiAgICAgICAgICAvLyBhbmQgc29tZXRpbWVzIGNoYW5nZXMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgRE9NLgogICAgICAgICAgJGxpbmtOb2RlID0gSlFMaXRlUHJvdG90eXBlLmNsb25lLmNhbGwoJGNvbXBpbGVOb2Rlcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICRsaW5rTm9kZSA9ICRjb21waWxlTm9kZXM7CiAgICAgICAgfQoKICAgICAgICBpZiAodHJhbnNjbHVkZUNvbnRyb2xsZXJzKSB7CiAgICAgICAgICBmb3IgKHZhciBjb250cm9sbGVyTmFtZSBpbiB0cmFuc2NsdWRlQ29udHJvbGxlcnMpIHsKICAgICAgICAgICAgJGxpbmtOb2RlLmRhdGEoJyQnICsgY29udHJvbGxlck5hbWUgKyAnQ29udHJvbGxlcicsIHRyYW5zY2x1ZGVDb250cm9sbGVyc1tjb250cm9sbGVyTmFtZV0uaW5zdGFuY2UpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgY29tcGlsZS4kJGFkZFNjb3BlSW5mbygkbGlua05vZGUsIHNjb3BlKTsKCiAgICAgICAgaWYgKGNsb25lQ29ubmVjdEZuKSBjbG9uZUNvbm5lY3RGbigkbGlua05vZGUsIHNjb3BlKTsKICAgICAgICBpZiAoY29tcG9zaXRlTGlua0ZuKSBjb21wb3NpdGVMaW5rRm4oc2NvcGUsICRsaW5rTm9kZSwgJGxpbmtOb2RlLCBwYXJlbnRCb3VuZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgcmV0dXJuICRsaW5rTm9kZTsKICAgICAgfTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXRlY3ROYW1lc3BhY2VGb3JDaGlsZEVsZW1lbnRzKHBhcmVudEVsZW1lbnQpIHsKICAgICAgLy8gVE9ETzogTWFrZSB0aGlzIGRldGVjdCBNYXRoTUwgYXMgd2VsbC4uLgogICAgICB2YXIgbm9kZSA9IHBhcmVudEVsZW1lbnQgJiYgcGFyZW50RWxlbWVudFswXTsKICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgcmV0dXJuICdodG1sJzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbm9kZU5hbWVfKG5vZGUpICE9PSAnZm9yZWlnbm9iamVjdCcgJiYgbm9kZS50b1N0cmluZygpLm1hdGNoKC9TVkcvKSA/ICdzdmcnIDogJ2h0bWwnOwogICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21waWxlIGZ1bmN0aW9uIG1hdGNoZXMgZWFjaCBub2RlIGluIG5vZGVMaXN0IGFnYWluc3QgdGhlIGRpcmVjdGl2ZXMuIE9uY2UgYWxsIGRpcmVjdGl2ZXMKICAgICAqIGZvciBhIHBhcnRpY3VsYXIgbm9kZSBhcmUgY29sbGVjdGVkIHRoZWlyIGNvbXBpbGUgZnVuY3Rpb25zIGFyZSBleGVjdXRlZC4gVGhlIGNvbXBpbGUKICAgICAqIGZ1bmN0aW9ucyByZXR1cm4gdmFsdWVzIC0gdGhlIGxpbmtpbmcgZnVuY3Rpb25zIC0gYXJlIGNvbWJpbmVkIGludG8gYSBjb21wb3NpdGUgbGlua2luZwogICAgICogZnVuY3Rpb24sIHdoaWNoIGlzIHRoZSBhIGxpbmtpbmcgZnVuY3Rpb24gZm9yIHRoZSBub2RlLgogICAgICoKICAgICAqIEBwYXJhbSB7Tm9kZUxpc3R9IG5vZGVMaXN0IGFuIGFycmF5IG9mIG5vZGVzIG9yIE5vZGVMaXN0IHRvIGNvbXBpbGUKICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oYW5ndWxhci5TY29wZSwgY2xvbmVBdHRhY2hGbj0pfSB0cmFuc2NsdWRlRm4gQSBsaW5raW5nIGZ1bmN0aW9uLCB3aGVyZSB0aGUKICAgICAqICAgICAgICBzY29wZSBhcmd1bWVudCBpcyBhdXRvLWdlbmVyYXRlZCB0byB0aGUgbmV3IGNoaWxkIG9mIHRoZSB0cmFuc2NsdWRlZCBwYXJlbnQgc2NvcGUuCiAgICAgKiBAcGFyYW0ge0RPTUVsZW1lbnQ9fSAkcm9vdEVsZW1lbnQgSWYgdGhlIG5vZGVMaXN0IGlzIHRoZSByb290IG9mIHRoZSBjb21waWxhdGlvbiB0cmVlIHRoZW4KICAgICAqICAgICAgICB0aGUgcm9vdEVsZW1lbnQgbXVzdCBiZSBzZXQgdGhlIGpxTGl0ZSBjb2xsZWN0aW9uIG9mIHRoZSBjb21waWxlIHJvb3QuIFRoaXMgaXMKICAgICAqICAgICAgICBuZWVkZWQgc28gdGhhdCB0aGUganFMaXRlIGNvbGxlY3Rpb24gaXRlbXMgY2FuIGJlIHJlcGxhY2VkIHdpdGggd2lkZ2V0cy4KICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gbWF4UHJpb3JpdHkgTWF4IGRpcmVjdGl2ZSBwcmlvcml0eS4KICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gQSBjb21wb3NpdGUgbGlua2luZyBmdW5jdGlvbiBvZiBhbGwgb2YgdGhlIG1hdGNoZWQgZGlyZWN0aXZlcyBvciBudWxsLgogICAgICovCiAgICBmdW5jdGlvbiBjb21waWxlTm9kZXMobm9kZUxpc3QsIHRyYW5zY2x1ZGVGbiwgJHJvb3RFbGVtZW50LCBtYXhQcmlvcml0eSwgaWdub3JlRGlyZWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNDb21waWxlQ29udGV4dCkgewogICAgICB2YXIgbGlua0ZucyA9IFtdLAogICAgICAgICAgYXR0cnMsIGRpcmVjdGl2ZXMsIG5vZGVMaW5rRm4sIGNoaWxkTm9kZXMsIGNoaWxkTGlua0ZuLCBsaW5rRm5Gb3VuZCwgbm9kZUxpbmtGbkZvdW5kOwoKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlTGlzdC5sZW5ndGg7IGkrKykgewogICAgICAgIGF0dHJzID0gbmV3IEF0dHJpYnV0ZXMoKTsKCiAgICAgICAgLy8gd2UgbXVzdCBhbHdheXMgcmVmZXIgdG8gbm9kZUxpc3RbaV0gc2luY2UgdGhlIG5vZGVzIGNhbiBiZSByZXBsYWNlZCB1bmRlcm5lYXRoIHVzLgogICAgICAgIGRpcmVjdGl2ZXMgPSBjb2xsZWN0RGlyZWN0aXZlcyhub2RlTGlzdFtpXSwgW10sIGF0dHJzLCBpID09PSAwID8gbWF4UHJpb3JpdHkgOiB1bmRlZmluZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVEaXJlY3RpdmUpOwoKICAgICAgICBub2RlTGlua0ZuID0gKGRpcmVjdGl2ZXMubGVuZ3RoKQogICAgICAgICAgICA/IGFwcGx5RGlyZWN0aXZlc1RvTm9kZShkaXJlY3RpdmVzLCBub2RlTGlzdFtpXSwgYXR0cnMsIHRyYW5zY2x1ZGVGbiwgJHJvb3RFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIFtdLCBbXSwgcHJldmlvdXNDb21waWxlQ29udGV4dCkKICAgICAgICAgICAgOiBudWxsOwoKICAgICAgICBpZiAobm9kZUxpbmtGbiAmJiBub2RlTGlua0ZuLnNjb3BlKSB7CiAgICAgICAgICBjb21waWxlLiQkYWRkU2NvcGVDbGFzcyhhdHRycy4kJGVsZW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgY2hpbGRMaW5rRm4gPSAobm9kZUxpbmtGbiAmJiBub2RlTGlua0ZuLnRlcm1pbmFsIHx8CiAgICAgICAgICAgICAgICAgICAgICAhKGNoaWxkTm9kZXMgPSBub2RlTGlzdFtpXS5jaGlsZE5vZGVzKSB8fAogICAgICAgICAgICAgICAgICAgICAgIWNoaWxkTm9kZXMubGVuZ3RoKQogICAgICAgICAgICA/IG51bGwKICAgICAgICAgICAgOiBjb21waWxlTm9kZXMoY2hpbGROb2RlcywKICAgICAgICAgICAgICAgICBub2RlTGlua0ZuID8gKAogICAgICAgICAgICAgICAgICAobm9kZUxpbmtGbi50cmFuc2NsdWRlT25UaGlzRWxlbWVudCB8fCAhbm9kZUxpbmtGbi50ZW1wbGF0ZU9uVGhpc0VsZW1lbnQpCiAgICAgICAgICAgICAgICAgICAgICYmIG5vZGVMaW5rRm4udHJhbnNjbHVkZSkgOiB0cmFuc2NsdWRlRm4pOwoKICAgICAgICBpZiAobm9kZUxpbmtGbiB8fCBjaGlsZExpbmtGbikgewogICAgICAgICAgbGlua0Zucy5wdXNoKGksIG5vZGVMaW5rRm4sIGNoaWxkTGlua0ZuKTsKICAgICAgICAgIGxpbmtGbkZvdW5kID0gdHJ1ZTsKICAgICAgICAgIG5vZGVMaW5rRm5Gb3VuZCA9IG5vZGVMaW5rRm5Gb3VuZCB8fCBub2RlTGlua0ZuOwogICAgICAgIH0KCiAgICAgICAgLy91c2UgdGhlIHByZXZpb3VzIGNvbnRleHQgb25seSBmb3IgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHZpcnR1YWwgZ3JvdXAKICAgICAgICBwcmV2aW91c0NvbXBpbGVDb250ZXh0ID0gbnVsbDsKICAgICAgfQoKICAgICAgLy8gcmV0dXJuIGEgbGlua2luZyBmdW5jdGlvbiBpZiB3ZSBoYXZlIGZvdW5kIGFueXRoaW5nLCBudWxsIG90aGVyd2lzZQogICAgICByZXR1cm4gbGlua0ZuRm91bmQgPyBjb21wb3NpdGVMaW5rRm4gOiBudWxsOwoKICAgICAgZnVuY3Rpb24gY29tcG9zaXRlTGlua0ZuKHNjb3BlLCBub2RlTGlzdCwgJHJvb3RFbGVtZW50LCBwYXJlbnRCb3VuZFRyYW5zY2x1ZGVGbikgewogICAgICAgIHZhciBub2RlTGlua0ZuLCBjaGlsZExpbmtGbiwgbm9kZSwgY2hpbGRTY29wZSwgaSwgaWksIGlkeCwgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbjsKICAgICAgICB2YXIgc3RhYmxlTm9kZUxpc3Q7CgoKICAgICAgICBpZiAobm9kZUxpbmtGbkZvdW5kKSB7CiAgICAgICAgICAvLyBjb3B5IG5vZGVMaXN0IHNvIHRoYXQgaWYgYSBub2RlTGlua0ZuIHJlbW92ZXMgb3IgYWRkcyBhbiBlbGVtZW50IGF0IHRoaXMgRE9NIGxldmVsIG91cgogICAgICAgICAgLy8gb2Zmc2V0cyBkb24ndCBnZXQgc2NyZXdlZCB1cAogICAgICAgICAgdmFyIG5vZGVMaXN0TGVuZ3RoID0gbm9kZUxpc3QubGVuZ3RoOwogICAgICAgICAgc3RhYmxlTm9kZUxpc3QgPSBuZXcgQXJyYXkobm9kZUxpc3RMZW5ndGgpOwoKICAgICAgICAgIC8vIGNyZWF0ZSBhIHNwYXJzZSBhcnJheSBieSBvbmx5IGNvcHlpbmcgdGhlIGVsZW1lbnRzIHdoaWNoIGhhdmUgYSBsaW5rRm4KICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaW5rRm5zLmxlbmd0aDsgaSs9MykgewogICAgICAgICAgICBpZHggPSBsaW5rRm5zW2ldOwogICAgICAgICAgICBzdGFibGVOb2RlTGlzdFtpZHhdID0gbm9kZUxpc3RbaWR4XTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RhYmxlTm9kZUxpc3QgPSBub2RlTGlzdDsKICAgICAgICB9CgogICAgICAgIGZvciAoaSA9IDAsIGlpID0gbGlua0Zucy5sZW5ndGg7IGkgPCBpaTspIHsKICAgICAgICAgIG5vZGUgPSBzdGFibGVOb2RlTGlzdFtsaW5rRm5zW2krK11dOwogICAgICAgICAgbm9kZUxpbmtGbiA9IGxpbmtGbnNbaSsrXTsKICAgICAgICAgIGNoaWxkTGlua0ZuID0gbGlua0Zuc1tpKytdOwoKICAgICAgICAgIGlmIChub2RlTGlua0ZuKSB7CiAgICAgICAgICAgIGlmIChub2RlTGlua0ZuLnNjb3BlKSB7CiAgICAgICAgICAgICAgY2hpbGRTY29wZSA9IHNjb3BlLiRuZXcoKTsKICAgICAgICAgICAgICBjb21waWxlLiQkYWRkU2NvcGVJbmZvKGpxTGl0ZShub2RlKSwgY2hpbGRTY29wZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgY2hpbGRTY29wZSA9IHNjb3BlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobm9kZUxpbmtGbi50cmFuc2NsdWRlT25UaGlzRWxlbWVudCkgewogICAgICAgICAgICAgIGNoaWxkQm91bmRUcmFuc2NsdWRlRm4gPSBjcmVhdGVCb3VuZFRyYW5zY2x1ZGVGbigKICAgICAgICAgICAgICAgICAgc2NvcGUsIG5vZGVMaW5rRm4udHJhbnNjbHVkZSwgcGFyZW50Qm91bmRUcmFuc2NsdWRlRm4sCiAgICAgICAgICAgICAgICAgIG5vZGVMaW5rRm4uZWxlbWVudFRyYW5zY2x1ZGVPblRoaXNFbGVtZW50KTsKCiAgICAgICAgICAgIH0gZWxzZSBpZiAoIW5vZGVMaW5rRm4udGVtcGxhdGVPblRoaXNFbGVtZW50ICYmIHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuKSB7CiAgICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbiA9IHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuOwoKICAgICAgICAgICAgfSBlbHNlIGlmICghcGFyZW50Qm91bmRUcmFuc2NsdWRlRm4gJiYgdHJhbnNjbHVkZUZuKSB7CiAgICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbiA9IGNyZWF0ZUJvdW5kVHJhbnNjbHVkZUZuKHNjb3BlLCB0cmFuc2NsdWRlRm4pOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBjaGlsZEJvdW5kVHJhbnNjbHVkZUZuID0gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbm9kZUxpbmtGbihjaGlsZExpbmtGbiwgY2hpbGRTY29wZSwgbm9kZSwgJHJvb3RFbGVtZW50LCBjaGlsZEJvdW5kVHJhbnNjbHVkZUZuKTsKCiAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkTGlua0ZuKSB7CiAgICAgICAgICAgIGNoaWxkTGlua0ZuKHNjb3BlLCBub2RlLmNoaWxkTm9kZXMsIHVuZGVmaW5lZCwgcGFyZW50Qm91bmRUcmFuc2NsdWRlRm4pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZUJvdW5kVHJhbnNjbHVkZUZuKHNjb3BlLCB0cmFuc2NsdWRlRm4sIHByZXZpb3VzQm91bmRUcmFuc2NsdWRlRm4sIGVsZW1lbnRUcmFuc2NsdXNpb24pIHsKCiAgICAgIHZhciBib3VuZFRyYW5zY2x1ZGVGbiA9IGZ1bmN0aW9uKHRyYW5zY2x1ZGVkU2NvcGUsIGNsb25lRm4sIGNvbnRyb2xsZXJzLCBmdXR1cmVQYXJlbnRFbGVtZW50LCBjb250YWluaW5nU2NvcGUpIHsKCiAgICAgICAgaWYgKCF0cmFuc2NsdWRlZFNjb3BlKSB7CiAgICAgICAgICB0cmFuc2NsdWRlZFNjb3BlID0gc2NvcGUuJG5ldyhmYWxzZSwgY29udGFpbmluZ1Njb3BlKTsKICAgICAgICAgIHRyYW5zY2x1ZGVkU2NvcGUuJCR0cmFuc2NsdWRlZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJhbnNjbHVkZUZuKHRyYW5zY2x1ZGVkU2NvcGUsIGNsb25lRm4sIHsKICAgICAgICAgIHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuOiBwcmV2aW91c0JvdW5kVHJhbnNjbHVkZUZuLAogICAgICAgICAgdHJhbnNjbHVkZUNvbnRyb2xsZXJzOiBjb250cm9sbGVycywKICAgICAgICAgIGZ1dHVyZVBhcmVudEVsZW1lbnQ6IGZ1dHVyZVBhcmVudEVsZW1lbnQKICAgICAgICB9KTsKICAgICAgfTsKCiAgICAgIHJldHVybiBib3VuZFRyYW5zY2x1ZGVGbjsKICAgIH0KCiAgICAvKioKICAgICAqIExvb2tzIGZvciBkaXJlY3RpdmVzIG9uIHRoZSBnaXZlbiBub2RlIGFuZCBhZGRzIHRoZW0gdG8gdGhlIGRpcmVjdGl2ZSBjb2xsZWN0aW9uIHdoaWNoIGlzCiAgICAgKiBzb3J0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBzZWFyY2guCiAgICAgKiBAcGFyYW0gZGlyZWN0aXZlcyBBbiBhcnJheSB0byB3aGljaCB0aGUgZGlyZWN0aXZlcyBhcmUgYWRkZWQgdG8uIFRoaXMgYXJyYXkgaXMgc29ydGVkIGJlZm9yZQogICAgICogICAgICAgIHRoZSBmdW5jdGlvbiByZXR1cm5zLgogICAgICogQHBhcmFtIGF0dHJzIFRoZSBzaGFyZWQgYXR0cnMgb2JqZWN0IHdoaWNoIGlzIHVzZWQgdG8gcG9wdWxhdGUgdGhlIG5vcm1hbGl6ZWQgYXR0cmlidXRlcy4KICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gbWF4UHJpb3JpdHkgTWF4IGRpcmVjdGl2ZSBwcmlvcml0eS4KICAgICAqLwogICAgZnVuY3Rpb24gY29sbGVjdERpcmVjdGl2ZXMobm9kZSwgZGlyZWN0aXZlcywgYXR0cnMsIG1heFByaW9yaXR5LCBpZ25vcmVEaXJlY3RpdmUpIHsKICAgICAgdmFyIG5vZGVUeXBlID0gbm9kZS5ub2RlVHlwZSwKICAgICAgICAgIGF0dHJzTWFwID0gYXR0cnMuJGF0dHIsCiAgICAgICAgICBtYXRjaCwKICAgICAgICAgIGNsYXNzTmFtZTsKCiAgICAgIHN3aXRjaCAobm9kZVR5cGUpIHsKICAgICAgICBjYXNlIE5PREVfVFlQRV9FTEVNRU5UOiAvKiBFbGVtZW50ICovCiAgICAgICAgICAvLyB1c2UgdGhlIG5vZGUgbmFtZTogPGRpcmVjdGl2ZT4KICAgICAgICAgIGFkZERpcmVjdGl2ZShkaXJlY3RpdmVzLAogICAgICAgICAgICAgIGRpcmVjdGl2ZU5vcm1hbGl6ZShub2RlTmFtZV8obm9kZSkpLCAnRScsIG1heFByaW9yaXR5LCBpZ25vcmVEaXJlY3RpdmUpOwoKICAgICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgYXR0cmlidXRlcwogICAgICAgICAgZm9yICh2YXIgYXR0ciwgbmFtZSwgbk5hbWUsIG5nQXR0ck5hbWUsIHZhbHVlLCBpc05nQXR0ciwgbkF0dHJzID0gbm9kZS5hdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgaiA9IDAsIGpqID0gbkF0dHJzICYmIG5BdHRycy5sZW5ndGg7IGogPCBqajsgaisrKSB7CiAgICAgICAgICAgIHZhciBhdHRyU3RhcnROYW1lID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBhdHRyRW5kTmFtZSA9IGZhbHNlOwoKICAgICAgICAgICAgYXR0ciA9IG5BdHRyc1tqXTsKICAgICAgICAgICAgbmFtZSA9IGF0dHIubmFtZTsKICAgICAgICAgICAgdmFsdWUgPSB0cmltKGF0dHIudmFsdWUpOwoKICAgICAgICAgICAgLy8gc3VwcG9ydCBuZ0F0dHIgYXR0cmlidXRlIGJpbmRpbmcKICAgICAgICAgICAgbmdBdHRyTmFtZSA9IGRpcmVjdGl2ZU5vcm1hbGl6ZShuYW1lKTsKICAgICAgICAgICAgaWYgKGlzTmdBdHRyID0gTkdfQVRUUl9CSU5ESU5HLnRlc3QobmdBdHRyTmFtZSkpIHsKICAgICAgICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKFBSRUZJWF9SRUdFWFAsICcnKQogICAgICAgICAgICAgICAgLnN1YnN0cig4KS5yZXBsYWNlKC9fKC4pL2csIGZ1bmN0aW9uKG1hdGNoLCBsZXR0ZXIpIHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkaXJlY3RpdmVOTmFtZSA9IG5nQXR0ck5hbWUucmVwbGFjZSgvKFN0YXJ0fEVuZCkkLywgJycpOwogICAgICAgICAgICBpZiAoZGlyZWN0aXZlSXNNdWx0aUVsZW1lbnQoZGlyZWN0aXZlTk5hbWUpKSB7CiAgICAgICAgICAgICAgaWYgKG5nQXR0ck5hbWUgPT09IGRpcmVjdGl2ZU5OYW1lICsgJ1N0YXJ0JykgewogICAgICAgICAgICAgICAgYXR0clN0YXJ0TmFtZSA9IG5hbWU7CiAgICAgICAgICAgICAgICBhdHRyRW5kTmFtZSA9IG5hbWUuc3Vic3RyKDAsIG5hbWUubGVuZ3RoIC0gNSkgKyAnZW5kJzsKICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigwLCBuYW1lLmxlbmd0aCAtIDYpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbk5hbWUgPSBkaXJlY3RpdmVOb3JtYWxpemUobmFtZS50b0xvd2VyQ2FzZSgpKTsKICAgICAgICAgICAgYXR0cnNNYXBbbk5hbWVdID0gbmFtZTsKICAgICAgICAgICAgaWYgKGlzTmdBdHRyIHx8ICFhdHRycy5oYXNPd25Qcm9wZXJ0eShuTmFtZSkpIHsKICAgICAgICAgICAgICAgIGF0dHJzW25OYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgaWYgKGdldEJvb2xlYW5BdHRyTmFtZShub2RlLCBuTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgYXR0cnNbbk5hbWVdID0gdHJ1ZTsgLy8gcHJlc2VuY2UgbWVhbnMgdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFkZEF0dHJJbnRlcnBvbGF0ZURpcmVjdGl2ZShub2RlLCBkaXJlY3RpdmVzLCB2YWx1ZSwgbk5hbWUsIGlzTmdBdHRyKTsKICAgICAgICAgICAgYWRkRGlyZWN0aXZlKGRpcmVjdGl2ZXMsIG5OYW1lLCAnQScsIG1heFByaW9yaXR5LCBpZ25vcmVEaXJlY3RpdmUsIGF0dHJTdGFydE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckVuZE5hbWUpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIHVzZSBjbGFzcyBhcyBkaXJlY3RpdmUKICAgICAgICAgIGNsYXNzTmFtZSA9IG5vZGUuY2xhc3NOYW1lOwogICAgICAgICAgaWYgKGlzU3RyaW5nKGNsYXNzTmFtZSkgJiYgY2xhc3NOYW1lICE9PSAnJykgewogICAgICAgICAgICB3aGlsZSAobWF0Y2ggPSBDTEFTU19ESVJFQ1RJVkVfUkVHRVhQLmV4ZWMoY2xhc3NOYW1lKSkgewogICAgICAgICAgICAgIG5OYW1lID0gZGlyZWN0aXZlTm9ybWFsaXplKG1hdGNoWzJdKTsKICAgICAgICAgICAgICBpZiAoYWRkRGlyZWN0aXZlKGRpcmVjdGl2ZXMsIG5OYW1lLCAnQycsIG1heFByaW9yaXR5LCBpZ25vcmVEaXJlY3RpdmUpKSB7CiAgICAgICAgICAgICAgICBhdHRyc1tuTmFtZV0gPSB0cmltKG1hdGNoWzNdKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY2xhc3NOYW1lID0gY2xhc3NOYW1lLnN1YnN0cihtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTk9ERV9UWVBFX1RFWFQ6IC8qIFRleHQgTm9kZSAqLwogICAgICAgICAgYWRkVGV4dEludGVycG9sYXRlRGlyZWN0aXZlKGRpcmVjdGl2ZXMsIG5vZGUubm9kZVZhbHVlKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTk9ERV9UWVBFX0NPTU1FTlQ6IC8qIENvbW1lbnQgKi8KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIG1hdGNoID0gQ09NTUVOVF9ESVJFQ1RJVkVfUkVHRVhQLmV4ZWMobm9kZS5ub2RlVmFsdWUpOwogICAgICAgICAgICBpZiAobWF0Y2gpIHsKICAgICAgICAgICAgICBuTmFtZSA9IGRpcmVjdGl2ZU5vcm1hbGl6ZShtYXRjaFsxXSk7CiAgICAgICAgICAgICAgaWYgKGFkZERpcmVjdGl2ZShkaXJlY3RpdmVzLCBuTmFtZSwgJ00nLCBtYXhQcmlvcml0eSwgaWdub3JlRGlyZWN0aXZlKSkgewogICAgICAgICAgICAgICAgYXR0cnNbbk5hbWVdID0gdHJpbShtYXRjaFsyXSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIC8vIHR1cm5zIG91dCB0aGF0IHVuZGVyIHNvbWUgY2lyY3Vtc3RhbmNlcyBJRTkgdGhyb3dzIGVycm9ycyB3aGVuIG9uZSBhdHRlbXB0cyB0byByZWFkCiAgICAgICAgICAgIC8vIGNvbW1lbnQncyBub2RlIHZhbHVlLgogICAgICAgICAgICAvLyBKdXN0IGlnbm9yZSBpdCBhbmQgY29udGludWUuIChDYW4ndCBzZWVtIHRvIHJlcHJvZHVjZSBpbiB0ZXN0IGNhc2UuKQogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGRpcmVjdGl2ZXMuc29ydChieVByaW9yaXR5KTsKICAgICAgcmV0dXJuIGRpcmVjdGl2ZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIG5vZGUgd2l0aCBhbiBkaXJlY3RpdmUtc3RhcnQgaXQgY29sbGVjdHMgYWxsIG9mIHRoZSBzaWJsaW5ncyB1bnRpbCBpdCBmaW5kcwogICAgICogZGlyZWN0aXZlLWVuZC4KICAgICAqIEBwYXJhbSBub2RlCiAgICAgKiBAcGFyYW0gYXR0clN0YXJ0CiAgICAgKiBAcGFyYW0gYXR0ckVuZAogICAgICogQHJldHVybnMgeyp9CiAgICAgKi8KICAgIGZ1bmN0aW9uIGdyb3VwU2Nhbihub2RlLCBhdHRyU3RhcnQsIGF0dHJFbmQpIHsKICAgICAgdmFyIG5vZGVzID0gW107CiAgICAgIHZhciBkZXB0aCA9IDA7CiAgICAgIGlmIChhdHRyU3RhcnQgJiYgbm9kZS5oYXNBdHRyaWJ1dGUgJiYgbm9kZS5oYXNBdHRyaWJ1dGUoYXR0clN0YXJ0KSkgewogICAgICAgIGRvIHsKICAgICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICB0aHJvdyAkY29tcGlsZU1pbkVycigndXRlcmRpcicsCiAgICAgICAgICAgICAgICAgICAgICAiVW50ZXJtaW5hdGVkIGF0dHJpYnV0ZSwgZm91bmQgJ3swfScgYnV0IG5vIG1hdGNoaW5nICd7MX0nIGZvdW5kLiIsCiAgICAgICAgICAgICAgICAgICAgICBhdHRyU3RhcnQsIGF0dHJFbmQpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gTk9ERV9UWVBFX0VMRU1FTlQpIHsKICAgICAgICAgICAgaWYgKG5vZGUuaGFzQXR0cmlidXRlKGF0dHJTdGFydCkpIGRlcHRoKys7CiAgICAgICAgICAgIGlmIChub2RlLmhhc0F0dHJpYnV0ZShhdHRyRW5kKSkgZGVwdGgtLTsKICAgICAgICAgIH0KICAgICAgICAgIG5vZGVzLnB1c2gobm9kZSk7CiAgICAgICAgICBub2RlID0gbm9kZS5uZXh0U2libGluZzsKICAgICAgICB9IHdoaWxlIChkZXB0aCA+IDApOwogICAgICB9IGVsc2UgewogICAgICAgIG5vZGVzLnB1c2gobm9kZSk7CiAgICAgIH0KCiAgICAgIHJldHVybiBqcUxpdGUobm9kZXMpOwogICAgfQoKICAgIC8qKgogICAgICogV3JhcHBlciBmb3IgbGlua2luZyBmdW5jdGlvbiB3aGljaCBjb252ZXJ0cyBub3JtYWwgbGlua2luZyBmdW5jdGlvbiBpbnRvIGEgZ3JvdXBlZAogICAgICogbGlua2luZyBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSBsaW5rRm4KICAgICAqIEBwYXJhbSBhdHRyU3RhcnQKICAgICAqIEBwYXJhbSBhdHRyRW5kCiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259CiAgICAgKi8KICAgIGZ1bmN0aW9uIGdyb3VwRWxlbWVudHNMaW5rRm5XcmFwcGVyKGxpbmtGbiwgYXR0clN0YXJ0LCBhdHRyRW5kKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0cnMsIGNvbnRyb2xsZXJzLCB0cmFuc2NsdWRlRm4pIHsKICAgICAgICBlbGVtZW50ID0gZ3JvdXBTY2FuKGVsZW1lbnRbMF0sIGF0dHJTdGFydCwgYXR0ckVuZCk7CiAgICAgICAgcmV0dXJuIGxpbmtGbihzY29wZSwgZWxlbWVudCwgYXR0cnMsIGNvbnRyb2xsZXJzLCB0cmFuc2NsdWRlRm4pOwogICAgICB9OwogICAgfQoKICAgIC8qKgogICAgICogT25jZSB0aGUgZGlyZWN0aXZlcyBoYXZlIGJlZW4gY29sbGVjdGVkLCB0aGVpciBjb21waWxlIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWQuIFRoaXMgbWV0aG9kCiAgICAgKiBpcyByZXNwb25zaWJsZSBmb3IgaW5saW5pbmcgZGlyZWN0aXZlIHRlbXBsYXRlcyBhcyB3ZWxsIGFzIHRlcm1pbmF0aW5nIHRoZSBhcHBsaWNhdGlvbgogICAgICogb2YgdGhlIGRpcmVjdGl2ZXMgaWYgdGhlIHRlcm1pbmFsIGRpcmVjdGl2ZSBoYXMgYmVlbiByZWFjaGVkLgogICAgICoKICAgICAqIEBwYXJhbSB7QXJyYXl9IGRpcmVjdGl2ZXMgQXJyYXkgb2YgY29sbGVjdGVkIGRpcmVjdGl2ZXMgdG8gZXhlY3V0ZSB0aGVpciBjb21waWxlIGZ1bmN0aW9uLgogICAgICogICAgICAgIHRoaXMgbmVlZHMgdG8gYmUgcHJlLXNvcnRlZCBieSBwcmlvcml0eSBvcmRlci4KICAgICAqIEBwYXJhbSB7Tm9kZX0gY29tcGlsZU5vZGUgVGhlIHJhdyBET00gbm9kZSB0byBhcHBseSB0aGUgY29tcGlsZSBmdW5jdGlvbnMgdG8KICAgICAqIEBwYXJhbSB7T2JqZWN0fSB0ZW1wbGF0ZUF0dHJzIFRoZSBzaGFyZWQgYXR0cmlidXRlIGZ1bmN0aW9uCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGFuZ3VsYXIuU2NvcGUsIGNsb25lQXR0YWNoRm49KX0gdHJhbnNjbHVkZUZuIEEgbGlua2luZyBmdW5jdGlvbiwgd2hlcmUgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGUgYXJndW1lbnQgaXMgYXV0by1nZW5lcmF0ZWQgdG8gdGhlIG5ldwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkIG9mIHRoZSB0cmFuc2NsdWRlZCBwYXJlbnQgc2NvcGUuCiAgICAgKiBAcGFyYW0ge0pRTGl0ZX0ganFDb2xsZWN0aW9uIElmIHdlIGFyZSB3b3JraW5nIG9uIHRoZSByb290IG9mIHRoZSBjb21waWxlIHRyZWUgdGhlbiB0aGlzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50IGhhcyB0aGUgcm9vdCBqcUxpdGUgYXJyYXkgc28gdGhhdCB3ZSBjYW4gcmVwbGFjZSBub2RlcwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbiBpdC4KICAgICAqIEBwYXJhbSB7T2JqZWN0PX0gb3JpZ2luYWxSZXBsYWNlRGlyZWN0aXZlIEFuIG9wdGlvbmFsIGRpcmVjdGl2ZSB0aGF0IHdpbGwgYmUgaWdub3JlZCB3aGVuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxpbmcgdGhlIHRyYW5zY2x1c2lvbi4KICAgICAqIEBwYXJhbSB7QXJyYXkuPEZ1bmN0aW9uPn0gcHJlTGlua0ZucwogICAgICogQHBhcmFtIHtBcnJheS48RnVuY3Rpb24+fSBwb3N0TGlua0ZucwogICAgICogQHBhcmFtIHtPYmplY3R9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQgQ29udGV4dCB1c2VkIGZvciBwcmV2aW91cyBjb21waWxhdGlvbiBvZiB0aGUgY3VycmVudAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZQogICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBsaW5rRm4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwbHlEaXJlY3RpdmVzVG9Ob2RlKGRpcmVjdGl2ZXMsIGNvbXBpbGVOb2RlLCB0ZW1wbGF0ZUF0dHJzLCB0cmFuc2NsdWRlRm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganFDb2xsZWN0aW9uLCBvcmlnaW5hbFJlcGxhY2VEaXJlY3RpdmUsIHByZUxpbmtGbnMsIHBvc3RMaW5rRm5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzQ29tcGlsZUNvbnRleHQpIHsKICAgICAgcHJldmlvdXNDb21waWxlQ29udGV4dCA9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQgfHwge307CgogICAgICB2YXIgdGVybWluYWxQcmlvcml0eSA9IC1OdW1iZXIuTUFYX1ZBTFVFLAogICAgICAgICAgbmV3U2NvcGVEaXJlY3RpdmUsCiAgICAgICAgICBjb250cm9sbGVyRGlyZWN0aXZlcyA9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQuY29udHJvbGxlckRpcmVjdGl2ZXMsCiAgICAgICAgICBjb250cm9sbGVycywKICAgICAgICAgIG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSA9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQubmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlLAogICAgICAgICAgdGVtcGxhdGVEaXJlY3RpdmUgPSBwcmV2aW91c0NvbXBpbGVDb250ZXh0LnRlbXBsYXRlRGlyZWN0aXZlLAogICAgICAgICAgbm9uVGxiVHJhbnNjbHVkZURpcmVjdGl2ZSA9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQubm9uVGxiVHJhbnNjbHVkZURpcmVjdGl2ZSwKICAgICAgICAgIGhhc1RyYW5zY2x1ZGVEaXJlY3RpdmUgPSBmYWxzZSwKICAgICAgICAgIGhhc1RlbXBsYXRlID0gZmFsc2UsCiAgICAgICAgICBoYXNFbGVtZW50VHJhbnNjbHVkZURpcmVjdGl2ZSA9IHByZXZpb3VzQ29tcGlsZUNvbnRleHQuaGFzRWxlbWVudFRyYW5zY2x1ZGVEaXJlY3RpdmUsCiAgICAgICAgICAkY29tcGlsZU5vZGUgPSB0ZW1wbGF0ZUF0dHJzLiQkZWxlbWVudCA9IGpxTGl0ZShjb21waWxlTm9kZSksCiAgICAgICAgICBkaXJlY3RpdmUsCiAgICAgICAgICBkaXJlY3RpdmVOYW1lLAogICAgICAgICAgJHRlbXBsYXRlLAogICAgICAgICAgcmVwbGFjZURpcmVjdGl2ZSA9IG9yaWdpbmFsUmVwbGFjZURpcmVjdGl2ZSwKICAgICAgICAgIGNoaWxkVHJhbnNjbHVkZUZuID0gdHJhbnNjbHVkZUZuLAogICAgICAgICAgbGlua0ZuLAogICAgICAgICAgZGlyZWN0aXZlVmFsdWU7CgogICAgICAvLyBleGVjdXRlcyBhbGwgZGlyZWN0aXZlcyBvbiB0aGUgY3VycmVudCBlbGVtZW50CiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGRpcmVjdGl2ZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgIGRpcmVjdGl2ZSA9IGRpcmVjdGl2ZXNbaV07CiAgICAgICAgdmFyIGF0dHJTdGFydCA9IGRpcmVjdGl2ZS4kJHN0YXJ0OwogICAgICAgIHZhciBhdHRyRW5kID0gZGlyZWN0aXZlLiQkZW5kOwoKICAgICAgICAvLyBjb2xsZWN0IG11bHRpYmxvY2sgc2VjdGlvbnMKICAgICAgICBpZiAoYXR0clN0YXJ0KSB7CiAgICAgICAgICAkY29tcGlsZU5vZGUgPSBncm91cFNjYW4oY29tcGlsZU5vZGUsIGF0dHJTdGFydCwgYXR0ckVuZCk7CiAgICAgICAgfQogICAgICAgICR0ZW1wbGF0ZSA9IHVuZGVmaW5lZDsKCiAgICAgICAgaWYgKHRlcm1pbmFsUHJpb3JpdHkgPiBkaXJlY3RpdmUucHJpb3JpdHkpIHsKICAgICAgICAgIGJyZWFrOyAvLyBwcmV2ZW50IGZ1cnRoZXIgcHJvY2Vzc2luZyBvZiBkaXJlY3RpdmVzCiAgICAgICAgfQoKICAgICAgICBpZiAoZGlyZWN0aXZlVmFsdWUgPSBkaXJlY3RpdmUuc2NvcGUpIHsKCiAgICAgICAgICAvLyBza2lwIHRoZSBjaGVjayBmb3IgZGlyZWN0aXZlcyB3aXRoIGFzeW5jIHRlbXBsYXRlcywgd2UnbGwgY2hlY2sgdGhlIGRlcml2ZWQgc3luYwogICAgICAgICAgLy8gZGlyZWN0aXZlIHdoZW4gdGhlIHRlbXBsYXRlIGFycml2ZXMKICAgICAgICAgIGlmICghZGlyZWN0aXZlLnRlbXBsYXRlVXJsKSB7CiAgICAgICAgICAgIGlmIChpc09iamVjdChkaXJlY3RpdmVWYWx1ZSkpIHsKICAgICAgICAgICAgICAvLyBUaGlzIGRpcmVjdGl2ZSBpcyB0cnlpbmcgdG8gYWRkIGFuIGlzb2xhdGVkIHNjb3BlLgogICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlcmUgaXMgbm8gc2NvcGUgb2YgYW55IGtpbmQgYWxyZWFkeQogICAgICAgICAgICAgIGFzc2VydE5vRHVwbGljYXRlKCduZXcvaXNvbGF0ZWQgc2NvcGUnLCBuZXdJc29sYXRlU2NvcGVEaXJlY3RpdmUgfHwgbmV3U2NvcGVEaXJlY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aXZlLCAkY29tcGlsZU5vZGUpOwogICAgICAgICAgICAgIG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSA9IGRpcmVjdGl2ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAvLyBUaGlzIGRpcmVjdGl2ZSBpcyB0cnlpbmcgdG8gYWRkIGEgY2hpbGQgc2NvcGUuCiAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGVyZSBpcyBubyBpc29sYXRlZCBzY29wZSBhbHJlYWR5CiAgICAgICAgICAgICAgYXNzZXJ0Tm9EdXBsaWNhdGUoJ25ldy9pc29sYXRlZCBzY29wZScsIG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSwgZGlyZWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb21waWxlTm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBuZXdTY29wZURpcmVjdGl2ZSA9IG5ld1Njb3BlRGlyZWN0aXZlIHx8IGRpcmVjdGl2ZTsKICAgICAgICB9CgogICAgICAgIGRpcmVjdGl2ZU5hbWUgPSBkaXJlY3RpdmUubmFtZTsKCiAgICAgICAgaWYgKCFkaXJlY3RpdmUudGVtcGxhdGVVcmwgJiYgZGlyZWN0aXZlLmNvbnRyb2xsZXIpIHsKICAgICAgICAgIGRpcmVjdGl2ZVZhbHVlID0gZGlyZWN0aXZlLmNvbnRyb2xsZXI7CiAgICAgICAgICBjb250cm9sbGVyRGlyZWN0aXZlcyA9IGNvbnRyb2xsZXJEaXJlY3RpdmVzIHx8IHt9OwogICAgICAgICAgYXNzZXJ0Tm9EdXBsaWNhdGUoIiciICsgZGlyZWN0aXZlTmFtZSArICInIGNvbnRyb2xsZXIiLAogICAgICAgICAgICAgIGNvbnRyb2xsZXJEaXJlY3RpdmVzW2RpcmVjdGl2ZU5hbWVdLCBkaXJlY3RpdmUsICRjb21waWxlTm9kZSk7CiAgICAgICAgICBjb250cm9sbGVyRGlyZWN0aXZlc1tkaXJlY3RpdmVOYW1lXSA9IGRpcmVjdGl2ZTsKICAgICAgICB9CgogICAgICAgIGlmIChkaXJlY3RpdmVWYWx1ZSA9IGRpcmVjdGl2ZS50cmFuc2NsdWRlKSB7CiAgICAgICAgICBoYXNUcmFuc2NsdWRlRGlyZWN0aXZlID0gdHJ1ZTsKCiAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgbmdJZiBhbmQgbmdSZXBlYXQgc28gdGhhdCB3ZSBkb24ndCBjb21wbGFpbiBhYm91dCBkdXBsaWNhdGUgdHJhbnNjbHVzaW9uLgogICAgICAgICAgLy8gVGhpcyBvcHRpb24gc2hvdWxkIG9ubHkgYmUgdXNlZCBieSBkaXJlY3RpdmVzIHRoYXQga25vdyBob3cgdG8gc2FmZWx5IGhhbmRsZSBlbGVtZW50IHRyYW5zY2x1c2lvbiwKICAgICAgICAgIC8vIHdoZXJlIHRoZSB0cmFuc2NsdWRlZCBub2RlcyBhcmUgYWRkZWQgb3IgcmVwbGFjZWQgYWZ0ZXIgbGlua2luZy4KICAgICAgICAgIGlmICghZGlyZWN0aXZlLiQkdGxiKSB7CiAgICAgICAgICAgIGFzc2VydE5vRHVwbGljYXRlKCd0cmFuc2NsdXNpb24nLCBub25UbGJUcmFuc2NsdWRlRGlyZWN0aXZlLCBkaXJlY3RpdmUsICRjb21waWxlTm9kZSk7CiAgICAgICAgICAgIG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmUgPSBkaXJlY3RpdmU7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKGRpcmVjdGl2ZVZhbHVlID09ICdlbGVtZW50JykgewogICAgICAgICAgICBoYXNFbGVtZW50VHJhbnNjbHVkZURpcmVjdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIHRlcm1pbmFsUHJpb3JpdHkgPSBkaXJlY3RpdmUucHJpb3JpdHk7CiAgICAgICAgICAgICR0ZW1wbGF0ZSA9ICRjb21waWxlTm9kZTsKICAgICAgICAgICAgJGNvbXBpbGVOb2RlID0gdGVtcGxhdGVBdHRycy4kJGVsZW1lbnQgPQogICAgICAgICAgICAgICAganFMaXRlKGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoJyAnICsgZGlyZWN0aXZlTmFtZSArICc6ICcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVBdHRyc1tkaXJlY3RpdmVOYW1lXSArICcgJykpOwogICAgICAgICAgICBjb21waWxlTm9kZSA9ICRjb21waWxlTm9kZVswXTsKICAgICAgICAgICAgcmVwbGFjZVdpdGgoanFDb2xsZWN0aW9uLCBzbGljZUFyZ3MoJHRlbXBsYXRlKSwgY29tcGlsZU5vZGUpOwoKICAgICAgICAgICAgY2hpbGRUcmFuc2NsdWRlRm4gPSBjb21waWxlKCR0ZW1wbGF0ZSwgdHJhbnNjbHVkZUZuLCB0ZXJtaW5hbFByaW9yaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZURpcmVjdGl2ZSAmJiByZXBsYWNlRGlyZWN0aXZlLm5hbWUsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgcGFzcyBpbjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLSBjb250cm9sbGVyRGlyZWN0aXZlcyAtIG90aGVyd2lzZSB3ZSdsbCBjcmVhdGUgZHVwbGljYXRlcyBjb250cm9sbGVycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtIG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSBvciB0ZW1wbGF0ZURpcmVjdGl2ZSAtIGNvbWJpbmluZyB0ZW1wbGF0ZXMgd2l0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgIGVsZW1lbnQgdHJhbnNjbHVzaW9uIGRvZXNuJ3QgbWFrZSBzZW5zZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgbmVlZCBvbmx5IG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmUgc28gdGhhdCB3ZSBwcmV2ZW50IHB1dHRpbmcgdHJhbnNjbHVzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9uIHRoZSBzYW1lIGVsZW1lbnQgbW9yZSB0aGFuIG9uY2UuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmU6IG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRlbXBsYXRlID0ganFMaXRlKGpxTGl0ZUNsb25lKGNvbXBpbGVOb2RlKSkuY29udGVudHMoKTsKICAgICAgICAgICAgJGNvbXBpbGVOb2RlLmVtcHR5KCk7IC8vIGNsZWFyIGNvbnRlbnRzCiAgICAgICAgICAgIGNoaWxkVHJhbnNjbHVkZUZuID0gY29tcGlsZSgkdGVtcGxhdGUsIHRyYW5zY2x1ZGVGbik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZGlyZWN0aXZlLnRlbXBsYXRlKSB7CiAgICAgICAgICBoYXNUZW1wbGF0ZSA9IHRydWU7CiAgICAgICAgICBhc3NlcnROb0R1cGxpY2F0ZSgndGVtcGxhdGUnLCB0ZW1wbGF0ZURpcmVjdGl2ZSwgZGlyZWN0aXZlLCAkY29tcGlsZU5vZGUpOwogICAgICAgICAgdGVtcGxhdGVEaXJlY3RpdmUgPSBkaXJlY3RpdmU7CgogICAgICAgICAgZGlyZWN0aXZlVmFsdWUgPSAoaXNGdW5jdGlvbihkaXJlY3RpdmUudGVtcGxhdGUpKQogICAgICAgICAgICAgID8gZGlyZWN0aXZlLnRlbXBsYXRlKCRjb21waWxlTm9kZSwgdGVtcGxhdGVBdHRycykKICAgICAgICAgICAgICA6IGRpcmVjdGl2ZS50ZW1wbGF0ZTsKCiAgICAgICAgICBkaXJlY3RpdmVWYWx1ZSA9IGRlbm9ybWFsaXplVGVtcGxhdGUoZGlyZWN0aXZlVmFsdWUpOwoKICAgICAgICAgIGlmIChkaXJlY3RpdmUucmVwbGFjZSkgewogICAgICAgICAgICByZXBsYWNlRGlyZWN0aXZlID0gZGlyZWN0aXZlOwogICAgICAgICAgICBpZiAoanFMaXRlSXNUZXh0Tm9kZShkaXJlY3RpdmVWYWx1ZSkpIHsKICAgICAgICAgICAgICAkdGVtcGxhdGUgPSBbXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAkdGVtcGxhdGUgPSByZW1vdmVDb21tZW50cyh3cmFwVGVtcGxhdGUoZGlyZWN0aXZlLnRlbXBsYXRlTmFtZXNwYWNlLCB0cmltKGRpcmVjdGl2ZVZhbHVlKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbXBpbGVOb2RlID0gJHRlbXBsYXRlWzBdOwoKICAgICAgICAgICAgaWYgKCR0ZW1wbGF0ZS5sZW5ndGggIT0gMSB8fCBjb21waWxlTm9kZS5ub2RlVHlwZSAhPT0gTk9ERV9UWVBFX0VMRU1FTlQpIHsKICAgICAgICAgICAgICB0aHJvdyAkY29tcGlsZU1pbkVycigndHBscnQnLAogICAgICAgICAgICAgICAgICAiVGVtcGxhdGUgZm9yIGRpcmVjdGl2ZSAnezB9JyBtdXN0IGhhdmUgZXhhY3RseSBvbmUgcm9vdCBlbGVtZW50LiB7MX0iLAogICAgICAgICAgICAgICAgICBkaXJlY3RpdmVOYW1lLCAnJyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlcGxhY2VXaXRoKGpxQ29sbGVjdGlvbiwgJGNvbXBpbGVOb2RlLCBjb21waWxlTm9kZSk7CgogICAgICAgICAgICB2YXIgbmV3VGVtcGxhdGVBdHRycyA9IHskYXR0cjoge319OwoKICAgICAgICAgICAgLy8gY29tYmluZSBkaXJlY3RpdmVzIGZyb20gdGhlIG9yaWdpbmFsIG5vZGUgYW5kIGZyb20gdGhlIHRlbXBsYXRlOgogICAgICAgICAgICAvLyAtIHRha2UgdGhlIGFycmF5IG9mIGRpcmVjdGl2ZXMgZm9yIHRoaXMgZWxlbWVudAogICAgICAgICAgICAvLyAtIHNwbGl0IGl0IGludG8gdHdvIHBhcnRzLCB0aG9zZSB0aGF0IGFscmVhZHkgYXBwbGllZCAocHJvY2Vzc2VkKSBhbmQgdGhvc2UgdGhhdCB3ZXJlbid0ICh1bnByb2Nlc3NlZCkKICAgICAgICAgICAgLy8gLSBjb2xsZWN0IGRpcmVjdGl2ZXMgZnJvbSB0aGUgdGVtcGxhdGUgYW5kIHNvcnQgdGhlbSBieSBwcmlvcml0eQogICAgICAgICAgICAvLyAtIGNvbWJpbmUgZGlyZWN0aXZlcyBhczogcHJvY2Vzc2VkICsgdGVtcGxhdGUgKyB1bnByb2Nlc3NlZAogICAgICAgICAgICB2YXIgdGVtcGxhdGVEaXJlY3RpdmVzID0gY29sbGVjdERpcmVjdGl2ZXMoY29tcGlsZU5vZGUsIFtdLCBuZXdUZW1wbGF0ZUF0dHJzKTsKICAgICAgICAgICAgdmFyIHVucHJvY2Vzc2VkRGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXMuc3BsaWNlKGkgKyAxLCBkaXJlY3RpdmVzLmxlbmd0aCAtIChpICsgMSkpOwoKICAgICAgICAgICAgaWYgKG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSkgewogICAgICAgICAgICAgIG1hcmtEaXJlY3RpdmVzQXNJc29sYXRlKHRlbXBsYXRlRGlyZWN0aXZlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXMuY29uY2F0KHRlbXBsYXRlRGlyZWN0aXZlcykuY29uY2F0KHVucHJvY2Vzc2VkRGlyZWN0aXZlcyk7CiAgICAgICAgICAgIG1lcmdlVGVtcGxhdGVBdHRyaWJ1dGVzKHRlbXBsYXRlQXR0cnMsIG5ld1RlbXBsYXRlQXR0cnMpOwoKICAgICAgICAgICAgaWkgPSBkaXJlY3RpdmVzLmxlbmd0aDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRjb21waWxlTm9kZS5odG1sKGRpcmVjdGl2ZVZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChkaXJlY3RpdmUudGVtcGxhdGVVcmwpIHsKICAgICAgICAgIGhhc1RlbXBsYXRlID0gdHJ1ZTsKICAgICAgICAgIGFzc2VydE5vRHVwbGljYXRlKCd0ZW1wbGF0ZScsIHRlbXBsYXRlRGlyZWN0aXZlLCBkaXJlY3RpdmUsICRjb21waWxlTm9kZSk7CiAgICAgICAgICB0ZW1wbGF0ZURpcmVjdGl2ZSA9IGRpcmVjdGl2ZTsKCiAgICAgICAgICBpZiAoZGlyZWN0aXZlLnJlcGxhY2UpIHsKICAgICAgICAgICAgcmVwbGFjZURpcmVjdGl2ZSA9IGRpcmVjdGl2ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBub2RlTGlua0ZuID0gY29tcGlsZVRlbXBsYXRlVXJsKGRpcmVjdGl2ZXMuc3BsaWNlKGksIGRpcmVjdGl2ZXMubGVuZ3RoIC0gaSksICRjb21waWxlTm9kZSwKICAgICAgICAgICAgICB0ZW1wbGF0ZUF0dHJzLCBqcUNvbGxlY3Rpb24sIGhhc1RyYW5zY2x1ZGVEaXJlY3RpdmUgJiYgY2hpbGRUcmFuc2NsdWRlRm4sIHByZUxpbmtGbnMsIHBvc3RMaW5rRm5zLCB7CiAgICAgICAgICAgICAgICBjb250cm9sbGVyRGlyZWN0aXZlczogY29udHJvbGxlckRpcmVjdGl2ZXMsCiAgICAgICAgICAgICAgICBuZXdJc29sYXRlU2NvcGVEaXJlY3RpdmU6IG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSwKICAgICAgICAgICAgICAgIHRlbXBsYXRlRGlyZWN0aXZlOiB0ZW1wbGF0ZURpcmVjdGl2ZSwKICAgICAgICAgICAgICAgIG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmU6IG5vblRsYlRyYW5zY2x1ZGVEaXJlY3RpdmUKICAgICAgICAgICAgICB9KTsKICAgICAgICAgIGlpID0gZGlyZWN0aXZlcy5sZW5ndGg7CiAgICAgICAgfSBlbHNlIGlmIChkaXJlY3RpdmUuY29tcGlsZSkgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbGlua0ZuID0gZGlyZWN0aXZlLmNvbXBpbGUoJGNvbXBpbGVOb2RlLCB0ZW1wbGF0ZUF0dHJzLCBjaGlsZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGxpbmtGbikpIHsKICAgICAgICAgICAgICBhZGRMaW5rRm5zKG51bGwsIGxpbmtGbiwgYXR0clN0YXJ0LCBhdHRyRW5kKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChsaW5rRm4pIHsKICAgICAgICAgICAgICBhZGRMaW5rRm5zKGxpbmtGbi5wcmUsIGxpbmtGbi5wb3N0LCBhdHRyU3RhcnQsIGF0dHJFbmQpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUsIHN0YXJ0aW5nVGFnKCRjb21waWxlTm9kZSkpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGRpcmVjdGl2ZS50ZXJtaW5hbCkgewogICAgICAgICAgbm9kZUxpbmtGbi50ZXJtaW5hbCA9IHRydWU7CiAgICAgICAgICB0ZXJtaW5hbFByaW9yaXR5ID0gTWF0aC5tYXgodGVybWluYWxQcmlvcml0eSwgZGlyZWN0aXZlLnByaW9yaXR5KTsKICAgICAgICB9CgogICAgICB9CgogICAgICBub2RlTGlua0ZuLnNjb3BlID0gbmV3U2NvcGVEaXJlY3RpdmUgJiYgbmV3U2NvcGVEaXJlY3RpdmUuc2NvcGUgPT09IHRydWU7CiAgICAgIG5vZGVMaW5rRm4udHJhbnNjbHVkZU9uVGhpc0VsZW1lbnQgPSBoYXNUcmFuc2NsdWRlRGlyZWN0aXZlOwogICAgICBub2RlTGlua0ZuLmVsZW1lbnRUcmFuc2NsdWRlT25UaGlzRWxlbWVudCA9IGhhc0VsZW1lbnRUcmFuc2NsdWRlRGlyZWN0aXZlOwogICAgICBub2RlTGlua0ZuLnRlbXBsYXRlT25UaGlzRWxlbWVudCA9IGhhc1RlbXBsYXRlOwogICAgICBub2RlTGlua0ZuLnRyYW5zY2x1ZGUgPSBjaGlsZFRyYW5zY2x1ZGVGbjsKCiAgICAgIHByZXZpb3VzQ29tcGlsZUNvbnRleHQuaGFzRWxlbWVudFRyYW5zY2x1ZGVEaXJlY3RpdmUgPSBoYXNFbGVtZW50VHJhbnNjbHVkZURpcmVjdGl2ZTsKCiAgICAgIC8vIG1pZ2h0IGJlIG5vcm1hbCBvciBkZWxheWVkIG5vZGVMaW5rRm4gZGVwZW5kaW5nIG9uIGlmIHRlbXBsYXRlVXJsIGlzIHByZXNlbnQKICAgICAgcmV0dXJuIG5vZGVMaW5rRm47CgogICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLwoKICAgICAgZnVuY3Rpb24gYWRkTGlua0ZucyhwcmUsIHBvc3QsIGF0dHJTdGFydCwgYXR0ckVuZCkgewogICAgICAgIGlmIChwcmUpIHsKICAgICAgICAgIGlmIChhdHRyU3RhcnQpIHByZSA9IGdyb3VwRWxlbWVudHNMaW5rRm5XcmFwcGVyKHByZSwgYXR0clN0YXJ0LCBhdHRyRW5kKTsKICAgICAgICAgIHByZS5yZXF1aXJlID0gZGlyZWN0aXZlLnJlcXVpcmU7CiAgICAgICAgICBwcmUuZGlyZWN0aXZlTmFtZSA9IGRpcmVjdGl2ZU5hbWU7CiAgICAgICAgICBpZiAobmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlID09PSBkaXJlY3RpdmUgfHwgZGlyZWN0aXZlLiQkaXNvbGF0ZVNjb3BlKSB7CiAgICAgICAgICAgIHByZSA9IGNsb25lQW5kQW5ub3RhdGVGbihwcmUsIHtpc29sYXRlU2NvcGU6IHRydWV9KTsKICAgICAgICAgIH0KICAgICAgICAgIHByZUxpbmtGbnMucHVzaChwcmUpOwogICAgICAgIH0KICAgICAgICBpZiAocG9zdCkgewogICAgICAgICAgaWYgKGF0dHJTdGFydCkgcG9zdCA9IGdyb3VwRWxlbWVudHNMaW5rRm5XcmFwcGVyKHBvc3QsIGF0dHJTdGFydCwgYXR0ckVuZCk7CiAgICAgICAgICBwb3N0LnJlcXVpcmUgPSBkaXJlY3RpdmUucmVxdWlyZTsKICAgICAgICAgIHBvc3QuZGlyZWN0aXZlTmFtZSA9IGRpcmVjdGl2ZU5hbWU7CiAgICAgICAgICBpZiAobmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlID09PSBkaXJlY3RpdmUgfHwgZGlyZWN0aXZlLiQkaXNvbGF0ZVNjb3BlKSB7CiAgICAgICAgICAgIHBvc3QgPSBjbG9uZUFuZEFubm90YXRlRm4ocG9zdCwge2lzb2xhdGVTY29wZTogdHJ1ZX0pOwogICAgICAgICAgfQogICAgICAgICAgcG9zdExpbmtGbnMucHVzaChwb3N0KTsKICAgICAgICB9CiAgICAgIH0KCgogICAgICBmdW5jdGlvbiBnZXRDb250cm9sbGVycyhkaXJlY3RpdmVOYW1lLCByZXF1aXJlLCAkZWxlbWVudCwgZWxlbWVudENvbnRyb2xsZXJzKSB7CiAgICAgICAgdmFyIHZhbHVlLCByZXRyaWV2YWxNZXRob2QgPSAnZGF0YScsIG9wdGlvbmFsID0gZmFsc2U7CiAgICAgICAgdmFyICRzZWFyY2hFbGVtZW50ID0gJGVsZW1lbnQ7CiAgICAgICAgdmFyIG1hdGNoOwogICAgICAgIGlmIChpc1N0cmluZyhyZXF1aXJlKSkgewogICAgICAgICAgbWF0Y2ggPSByZXF1aXJlLm1hdGNoKFJFUVVJUkVfUFJFRklYX1JFR0VYUCk7CiAgICAgICAgICByZXF1aXJlID0gcmVxdWlyZS5zdWJzdHJpbmcobWF0Y2hbMF0ubGVuZ3RoKTsKCiAgICAgICAgICBpZiAobWF0Y2hbM10pIHsKICAgICAgICAgICAgaWYgKG1hdGNoWzFdKSBtYXRjaFszXSA9IG51bGw7CiAgICAgICAgICAgIGVsc2UgbWF0Y2hbMV0gPSBtYXRjaFszXTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gJ14nKSB7CiAgICAgICAgICAgIHJldHJpZXZhbE1ldGhvZCA9ICdpbmhlcml0ZWREYXRhJzsKICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbMV0gPT09ICdeXicpIHsKICAgICAgICAgICAgcmV0cmlldmFsTWV0aG9kID0gJ2luaGVyaXRlZERhdGEnOwogICAgICAgICAgICAkc2VhcmNoRWxlbWVudCA9ICRlbGVtZW50LnBhcmVudCgpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG1hdGNoWzJdID09PSAnPycpIHsKICAgICAgICAgICAgb3B0aW9uYWwgPSB0cnVlOwogICAgICAgICAgfQoKICAgICAgICAgIHZhbHVlID0gbnVsbDsKCiAgICAgICAgICBpZiAoZWxlbWVudENvbnRyb2xsZXJzICYmIHJldHJpZXZhbE1ldGhvZCA9PT0gJ2RhdGEnKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9IGVsZW1lbnRDb250cm9sbGVyc1tyZXF1aXJlXSkgewogICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuaW5zdGFuY2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHZhbHVlID0gdmFsdWUgfHwgJHNlYXJjaEVsZW1lbnRbcmV0cmlldmFsTWV0aG9kXSgnJCcgKyByZXF1aXJlICsgJ0NvbnRyb2xsZXInKTsKCiAgICAgICAgICBpZiAoIXZhbHVlICYmICFvcHRpb25hbCkgewogICAgICAgICAgICB0aHJvdyAkY29tcGlsZU1pbkVycignY3RyZXEnLAogICAgICAgICAgICAgICAgIkNvbnRyb2xsZXIgJ3swfScsIHJlcXVpcmVkIGJ5IGRpcmVjdGl2ZSAnezF9JywgY2FuJ3QgYmUgZm91bmQhIiwKICAgICAgICAgICAgICAgIHJlcXVpcmUsIGRpcmVjdGl2ZU5hbWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHZhbHVlIHx8IG51bGw7CiAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KHJlcXVpcmUpKSB7CiAgICAgICAgICB2YWx1ZSA9IFtdOwogICAgICAgICAgZm9yRWFjaChyZXF1aXJlLCBmdW5jdGlvbihyZXF1aXJlKSB7CiAgICAgICAgICAgIHZhbHVlLnB1c2goZ2V0Q29udHJvbGxlcnMoZGlyZWN0aXZlTmFtZSwgcmVxdWlyZSwgJGVsZW1lbnQsIGVsZW1lbnRDb250cm9sbGVycykpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKCiAgICAgIGZ1bmN0aW9uIG5vZGVMaW5rRm4oY2hpbGRMaW5rRm4sIHNjb3BlLCBsaW5rTm9kZSwgJHJvb3RFbGVtZW50LCBib3VuZFRyYW5zY2x1ZGVGbikgewogICAgICAgIHZhciBpLCBpaSwgbGlua0ZuLCBjb250cm9sbGVyLCBpc29sYXRlU2NvcGUsIGVsZW1lbnRDb250cm9sbGVycywgdHJhbnNjbHVkZUZuLCAkZWxlbWVudCwKICAgICAgICAgICAgYXR0cnM7CgogICAgICAgIGlmIChjb21waWxlTm9kZSA9PT0gbGlua05vZGUpIHsKICAgICAgICAgIGF0dHJzID0gdGVtcGxhdGVBdHRyczsKICAgICAgICAgICRlbGVtZW50ID0gdGVtcGxhdGVBdHRycy4kJGVsZW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICRlbGVtZW50ID0ganFMaXRlKGxpbmtOb2RlKTsKICAgICAgICAgIGF0dHJzID0gbmV3IEF0dHJpYnV0ZXMoJGVsZW1lbnQsIHRlbXBsYXRlQXR0cnMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSkgewogICAgICAgICAgaXNvbGF0ZVNjb3BlID0gc2NvcGUuJG5ldyh0cnVlKTsKICAgICAgICB9CgogICAgICAgIGlmIChib3VuZFRyYW5zY2x1ZGVGbikgewogICAgICAgICAgLy8gdHJhY2sgYGJvdW5kVHJhbnNjbHVkZUZuYCBzbyBpdCBjYW4gYmUgdW53cmFwcGVkIGlmIGB0cmFuc2NsdWRlRm5gCiAgICAgICAgICAvLyBpcyBsYXRlciBwYXNzZWQgYXMgYHBhcmVudEJvdW5kVHJhbnNjbHVkZUZuYCB0byBgcHVibGljTGlua0ZuYAogICAgICAgICAgdHJhbnNjbHVkZUZuID0gY29udHJvbGxlcnNCb3VuZFRyYW5zY2x1ZGU7CiAgICAgICAgICB0cmFuc2NsdWRlRm4uJCRib3VuZFRyYW5zY2x1ZGUgPSBib3VuZFRyYW5zY2x1ZGVGbjsKICAgICAgICB9CgogICAgICAgIGlmIChjb250cm9sbGVyRGlyZWN0aXZlcykgewogICAgICAgICAgLy8gVE9ETzogbWVyZ2UgYGNvbnRyb2xsZXJzYCBhbmQgYGVsZW1lbnRDb250cm9sbGVyc2AgaW50byBzaW5nbGUgb2JqZWN0LgogICAgICAgICAgY29udHJvbGxlcnMgPSB7fTsKICAgICAgICAgIGVsZW1lbnRDb250cm9sbGVycyA9IHt9OwogICAgICAgICAgZm9yRWFjaChjb250cm9sbGVyRGlyZWN0aXZlcywgZnVuY3Rpb24oZGlyZWN0aXZlKSB7CiAgICAgICAgICAgIHZhciBsb2NhbHMgPSB7CiAgICAgICAgICAgICAgJHNjb3BlOiBkaXJlY3RpdmUgPT09IG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSB8fCBkaXJlY3RpdmUuJCRpc29sYXRlU2NvcGUgPyBpc29sYXRlU2NvcGUgOiBzY29wZSwKICAgICAgICAgICAgICAkZWxlbWVudDogJGVsZW1lbnQsCiAgICAgICAgICAgICAgJGF0dHJzOiBhdHRycywKICAgICAgICAgICAgICAkdHJhbnNjbHVkZTogdHJhbnNjbHVkZUZuCiAgICAgICAgICAgIH0sIGNvbnRyb2xsZXJJbnN0YW5jZTsKCiAgICAgICAgICAgIGNvbnRyb2xsZXIgPSBkaXJlY3RpdmUuY29udHJvbGxlcjsKICAgICAgICAgICAgaWYgKGNvbnRyb2xsZXIgPT0gJ0AnKSB7CiAgICAgICAgICAgICAgY29udHJvbGxlciA9IGF0dHJzW2RpcmVjdGl2ZS5uYW1lXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udHJvbGxlckluc3RhbmNlID0gJGNvbnRyb2xsZXIoY29udHJvbGxlciwgbG9jYWxzLCB0cnVlLCBkaXJlY3RpdmUuY29udHJvbGxlckFzKTsKCiAgICAgICAgICAgIC8vIEZvciBkaXJlY3RpdmVzIHdpdGggZWxlbWVudCB0cmFuc2NsdXNpb24gdGhlIGVsZW1lbnQgaXMgYSBjb21tZW50LAogICAgICAgICAgICAvLyBidXQgalF1ZXJ5IC5kYXRhIGRvZXNuJ3Qgc3VwcG9ydCBhdHRhY2hpbmcgZGF0YSB0byBjb21tZW50IG5vZGVzIGFzIGl0J3MgaGFyZCB0bwogICAgICAgICAgICAvLyBjbGVhbiB1cCAoaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvODMzNSkuCiAgICAgICAgICAgIC8vIEluc3RlYWQsIHdlIHNhdmUgdGhlIGNvbnRyb2xsZXJzIGZvciB0aGUgZWxlbWVudCBpbiBhIGxvY2FsIGhhc2ggYW5kIGF0dGFjaCB0byAuZGF0YQogICAgICAgICAgICAvLyBsYXRlciwgb25jZSB3ZSBoYXZlIHRoZSBhY3R1YWwgZWxlbWVudC4KICAgICAgICAgICAgZWxlbWVudENvbnRyb2xsZXJzW2RpcmVjdGl2ZS5uYW1lXSA9IGNvbnRyb2xsZXJJbnN0YW5jZTsKICAgICAgICAgICAgaWYgKCFoYXNFbGVtZW50VHJhbnNjbHVkZURpcmVjdGl2ZSkgewogICAgICAgICAgICAgICRlbGVtZW50LmRhdGEoJyQnICsgZGlyZWN0aXZlLm5hbWUgKyAnQ29udHJvbGxlcicsIGNvbnRyb2xsZXJJbnN0YW5jZS5pbnN0YW5jZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRyb2xsZXJzW2RpcmVjdGl2ZS5uYW1lXSA9IGNvbnRyb2xsZXJJbnN0YW5jZTsKICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZSkgewogICAgICAgICAgY29tcGlsZS4kJGFkZFNjb3BlSW5mbygkZWxlbWVudCwgaXNvbGF0ZVNjb3BlLCB0cnVlLCAhKHRlbXBsYXRlRGlyZWN0aXZlICYmICh0ZW1wbGF0ZURpcmVjdGl2ZSA9PT0gbmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlIHx8CiAgICAgICAgICAgICAgdGVtcGxhdGVEaXJlY3RpdmUgPT09IG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZS4kJG9yaWdpbmFsRGlyZWN0aXZlKSkpOwogICAgICAgICAgY29tcGlsZS4kJGFkZFNjb3BlQ2xhc3MoJGVsZW1lbnQsIHRydWUpOwoKICAgICAgICAgIHZhciBpc29sYXRlU2NvcGVDb250cm9sbGVyID0gY29udHJvbGxlcnMgJiYgY29udHJvbGxlcnNbbmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlLm5hbWVdOwogICAgICAgICAgdmFyIGlzb2xhdGVCaW5kaW5nQ29udGV4dCA9IGlzb2xhdGVTY29wZTsKICAgICAgICAgIGlmIChpc29sYXRlU2NvcGVDb250cm9sbGVyICYmIGlzb2xhdGVTY29wZUNvbnRyb2xsZXIuaWRlbnRpZmllciAmJgogICAgICAgICAgICAgIG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZS5iaW5kVG9Db250cm9sbGVyID09PSB0cnVlKSB7CiAgICAgICAgICAgIGlzb2xhdGVCaW5kaW5nQ29udGV4dCA9IGlzb2xhdGVTY29wZUNvbnRyb2xsZXIuaW5zdGFuY2U7CiAgICAgICAgICB9CgogICAgICAgICAgZm9yRWFjaChpc29sYXRlU2NvcGUuJCRpc29sYXRlQmluZGluZ3MgPSBuZXdJc29sYXRlU2NvcGVEaXJlY3RpdmUuJCRpc29sYXRlQmluZGluZ3MsIGZ1bmN0aW9uKGRlZmluaXRpb24sIHNjb3BlTmFtZSkgewogICAgICAgICAgICB2YXIgYXR0ck5hbWUgPSBkZWZpbml0aW9uLmF0dHJOYW1lLAogICAgICAgICAgICAgICAgb3B0aW9uYWwgPSBkZWZpbml0aW9uLm9wdGlvbmFsLAogICAgICAgICAgICAgICAgbW9kZSA9IGRlZmluaXRpb24ubW9kZSwgLy8gQCwgPSwgb3IgJgogICAgICAgICAgICAgICAgbGFzdFZhbHVlLAogICAgICAgICAgICAgICAgcGFyZW50R2V0LCBwYXJlbnRTZXQsIGNvbXBhcmU7CgogICAgICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKCiAgICAgICAgICAgICAgY2FzZSAnQCc6CiAgICAgICAgICAgICAgICBhdHRycy4kb2JzZXJ2ZShhdHRyTmFtZSwgZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgaXNvbGF0ZUJpbmRpbmdDb250ZXh0W3Njb3BlTmFtZV0gPSB2YWx1ZTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYXR0cnMuJCRvYnNlcnZlcnNbYXR0ck5hbWVdLiQkc2NvcGUgPSBzY29wZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyc1thdHRyTmFtZV0pIHsKICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGF0dHJpYnV0ZSBoYXMgYmVlbiBwcm92aWRlZCB0aGVuIHdlIHRyaWdnZXIgYW4gaW50ZXJwb2xhdGlvbiB0byBlbnN1cmUKICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGlzIHRoZXJlIGZvciB1c2UgaW4gdGhlIGxpbmsgZm4KICAgICAgICAgICAgICAgICAgaXNvbGF0ZUJpbmRpbmdDb250ZXh0W3Njb3BlTmFtZV0gPSAkaW50ZXJwb2xhdGUoYXR0cnNbYXR0ck5hbWVdKShzY29wZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgY2FzZSAnPSc6CiAgICAgICAgICAgICAgICBpZiAob3B0aW9uYWwgJiYgIWF0dHJzW2F0dHJOYW1lXSkgewogICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwYXJlbnRHZXQgPSAkcGFyc2UoYXR0cnNbYXR0ck5hbWVdKTsKICAgICAgICAgICAgICAgIGlmIChwYXJlbnRHZXQubGl0ZXJhbCkgewogICAgICAgICAgICAgICAgICBjb21wYXJlID0gZXF1YWxzOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgY29tcGFyZSA9IGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEgPT09IGIgfHwgKGEgIT09IGEgJiYgYiAhPT0gYik7IH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwYXJlbnRTZXQgPSBwYXJlbnRHZXQuYXNzaWduIHx8IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAvLyByZXNldCB0aGUgY2hhbmdlLCBvciB3ZSB3aWxsIHRocm93IHRoaXMgZXhjZXB0aW9uIG9uIGV2ZXJ5ICRkaWdlc3QKICAgICAgICAgICAgICAgICAgbGFzdFZhbHVlID0gaXNvbGF0ZUJpbmRpbmdDb250ZXh0W3Njb3BlTmFtZV0gPSBwYXJlbnRHZXQoc2NvcGUpOwogICAgICAgICAgICAgICAgICB0aHJvdyAkY29tcGlsZU1pbkVycignbm9uYXNzaWduJywKICAgICAgICAgICAgICAgICAgICAgICJFeHByZXNzaW9uICd7MH0nIHVzZWQgd2l0aCBkaXJlY3RpdmUgJ3sxfScgaXMgbm9uLWFzc2lnbmFibGUhIiwKICAgICAgICAgICAgICAgICAgICAgIGF0dHJzW2F0dHJOYW1lXSwgbmV3SXNvbGF0ZVNjb3BlRGlyZWN0aXZlLm5hbWUpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGxhc3RWYWx1ZSA9IGlzb2xhdGVCaW5kaW5nQ29udGV4dFtzY29wZU5hbWVdID0gcGFyZW50R2V0KHNjb3BlKTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRWYWx1ZVdhdGNoID0gZnVuY3Rpb24gcGFyZW50VmFsdWVXYXRjaChwYXJlbnRWYWx1ZSkgewogICAgICAgICAgICAgICAgICBpZiAoIWNvbXBhcmUocGFyZW50VmFsdWUsIGlzb2xhdGVCaW5kaW5nQ29udGV4dFtzY29wZU5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSBvdXQgb2Ygc3luYyBhbmQgbmVlZCB0byBjb3B5CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21wYXJlKHBhcmVudFZhbHVlLCBsYXN0VmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJlbnQgY2hhbmdlZCBhbmQgaXQgaGFzIHByZWNlZGVuY2UKICAgICAgICAgICAgICAgICAgICAgIGlzb2xhdGVCaW5kaW5nQ29udGV4dFtzY29wZU5hbWVdID0gcGFyZW50VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJlbnQgY2FuIGJlIGFzc2lnbmVkIHRoZW4gZG8gc28KICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFNldChzY29wZSwgcGFyZW50VmFsdWUgPSBpc29sYXRlQmluZGluZ0NvbnRleHRbc2NvcGVOYW1lXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0VmFsdWUgPSBwYXJlbnRWYWx1ZTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBwYXJlbnRWYWx1ZVdhdGNoLiRzdGF0ZWZ1bCA9IHRydWU7CiAgICAgICAgICAgICAgICB2YXIgdW53YXRjaDsKICAgICAgICAgICAgICAgIGlmIChkZWZpbml0aW9uLmNvbGxlY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgdW53YXRjaCA9IHNjb3BlLiR3YXRjaENvbGxlY3Rpb24oYXR0cnNbYXR0ck5hbWVdLCBwYXJlbnRWYWx1ZVdhdGNoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHVud2F0Y2ggPSBzY29wZS4kd2F0Y2goJHBhcnNlKGF0dHJzW2F0dHJOYW1lXSwgcGFyZW50VmFsdWVXYXRjaCksIG51bGwsIHBhcmVudEdldC5saXRlcmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlzb2xhdGVTY29wZS4kb24oJyRkZXN0cm95JywgdW53YXRjaCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgY2FzZSAnJic6CiAgICAgICAgICAgICAgICBwYXJlbnRHZXQgPSAkcGFyc2UoYXR0cnNbYXR0ck5hbWVdKTsKICAgICAgICAgICAgICAgIGlzb2xhdGVCaW5kaW5nQ29udGV4dFtzY29wZU5hbWVdID0gZnVuY3Rpb24obG9jYWxzKSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnRHZXQoc2NvcGUsIGxvY2Fscyk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBpZiAoY29udHJvbGxlcnMpIHsKICAgICAgICAgIGZvckVhY2goY29udHJvbGxlcnMsIGZ1bmN0aW9uKGNvbnRyb2xsZXIpIHsKICAgICAgICAgICAgY29udHJvbGxlcigpOwogICAgICAgICAgfSk7CiAgICAgICAgICBjb250cm9sbGVycyA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICAvLyBQUkVMSU5LSU5HCiAgICAgICAgZm9yIChpID0gMCwgaWkgPSBwcmVMaW5rRm5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgIGxpbmtGbiA9IHByZUxpbmtGbnNbaV07CiAgICAgICAgICBpbnZva2VMaW5rRm4obGlua0ZuLAogICAgICAgICAgICAgIGxpbmtGbi5pc29sYXRlU2NvcGUgPyBpc29sYXRlU2NvcGUgOiBzY29wZSwKICAgICAgICAgICAgICAkZWxlbWVudCwKICAgICAgICAgICAgICBhdHRycywKICAgICAgICAgICAgICBsaW5rRm4ucmVxdWlyZSAmJiBnZXRDb250cm9sbGVycyhsaW5rRm4uZGlyZWN0aXZlTmFtZSwgbGlua0ZuLnJlcXVpcmUsICRlbGVtZW50LCBlbGVtZW50Q29udHJvbGxlcnMpLAogICAgICAgICAgICAgIHRyYW5zY2x1ZGVGbgogICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIC8vIFJFQ1VSU0lPTgogICAgICAgIC8vIFdlIG9ubHkgcGFzcyB0aGUgaXNvbGF0ZSBzY29wZSwgaWYgdGhlIGlzb2xhdGUgZGlyZWN0aXZlIGhhcyBhIHRlbXBsYXRlLAogICAgICAgIC8vIG90aGVyd2lzZSB0aGUgY2hpbGQgZWxlbWVudHMgZG8gbm90IGJlbG9uZyB0byB0aGUgaXNvbGF0ZSBkaXJlY3RpdmUuCiAgICAgICAgdmFyIHNjb3BlVG9DaGlsZCA9IHNjb3BlOwogICAgICAgIGlmIChuZXdJc29sYXRlU2NvcGVEaXJlY3RpdmUgJiYgKG5ld0lzb2xhdGVTY29wZURpcmVjdGl2ZS50ZW1wbGF0ZSB8fCBuZXdJc29sYXRlU2NvcGVEaXJlY3RpdmUudGVtcGxhdGVVcmwgPT09IG51bGwpKSB7CiAgICAgICAgICBzY29wZVRvQ2hpbGQgPSBpc29sYXRlU2NvcGU7CiAgICAgICAgfQogICAgICAgIGNoaWxkTGlua0ZuICYmIGNoaWxkTGlua0ZuKHNjb3BlVG9DaGlsZCwgbGlua05vZGUuY2hpbGROb2RlcywgdW5kZWZpbmVkLCBib3VuZFRyYW5zY2x1ZGVGbik7CgogICAgICAgIC8vIFBPU1RMSU5LSU5HCiAgICAgICAgZm9yIChpID0gcG9zdExpbmtGbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgIGxpbmtGbiA9IHBvc3RMaW5rRm5zW2ldOwogICAgICAgICAgaW52b2tlTGlua0ZuKGxpbmtGbiwKICAgICAgICAgICAgICBsaW5rRm4uaXNvbGF0ZVNjb3BlID8gaXNvbGF0ZVNjb3BlIDogc2NvcGUsCiAgICAgICAgICAgICAgJGVsZW1lbnQsCiAgICAgICAgICAgICAgYXR0cnMsCiAgICAgICAgICAgICAgbGlua0ZuLnJlcXVpcmUgJiYgZ2V0Q29udHJvbGxlcnMobGlua0ZuLmRpcmVjdGl2ZU5hbWUsIGxpbmtGbi5yZXF1aXJlLCAkZWxlbWVudCwgZWxlbWVudENvbnRyb2xsZXJzKSwKICAgICAgICAgICAgICB0cmFuc2NsdWRlRm4KICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGlzIGlzIHRoZSBmdW5jdGlvbiB0aGF0IGlzIGluamVjdGVkIGFzIGAkdHJhbnNjbHVkZWAuCiAgICAgICAgLy8gTm90ZTogYWxsIGFyZ3VtZW50cyBhcmUgb3B0aW9uYWwhCiAgICAgICAgZnVuY3Rpb24gY29udHJvbGxlcnNCb3VuZFRyYW5zY2x1ZGUoc2NvcGUsIGNsb25lQXR0YWNoRm4sIGZ1dHVyZVBhcmVudEVsZW1lbnQpIHsKICAgICAgICAgIHZhciB0cmFuc2NsdWRlQ29udHJvbGxlcnM7CgogICAgICAgICAgLy8gTm8gc2NvcGUgcGFzc2VkIGluOgogICAgICAgICAgaWYgKCFpc1Njb3BlKHNjb3BlKSkgewogICAgICAgICAgICBmdXR1cmVQYXJlbnRFbGVtZW50ID0gY2xvbmVBdHRhY2hGbjsKICAgICAgICAgICAgY2xvbmVBdHRhY2hGbiA9IHNjb3BlOwogICAgICAgICAgICBzY29wZSA9IHVuZGVmaW5lZDsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoaGFzRWxlbWVudFRyYW5zY2x1ZGVEaXJlY3RpdmUpIHsKICAgICAgICAgICAgdHJhbnNjbHVkZUNvbnRyb2xsZXJzID0gZWxlbWVudENvbnRyb2xsZXJzOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCFmdXR1cmVQYXJlbnRFbGVtZW50KSB7CiAgICAgICAgICAgIGZ1dHVyZVBhcmVudEVsZW1lbnQgPSBoYXNFbGVtZW50VHJhbnNjbHVkZURpcmVjdGl2ZSA/ICRlbGVtZW50LnBhcmVudCgpIDogJGVsZW1lbnQ7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYm91bmRUcmFuc2NsdWRlRm4oc2NvcGUsIGNsb25lQXR0YWNoRm4sIHRyYW5zY2x1ZGVDb250cm9sbGVycywgZnV0dXJlUGFyZW50RWxlbWVudCwgc2NvcGVUb0NoaWxkKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBtYXJrRGlyZWN0aXZlc0FzSXNvbGF0ZShkaXJlY3RpdmVzKSB7CiAgICAgIC8vIG1hcmsgYWxsIGRpcmVjdGl2ZXMgYXMgbmVlZGluZyBpc29sYXRlIHNjb3BlLgogICAgICBmb3IgKHZhciBqID0gMCwgamogPSBkaXJlY3RpdmVzLmxlbmd0aDsgaiA8IGpqOyBqKyspIHsKICAgICAgICBkaXJlY3RpdmVzW2pdID0gaW5oZXJpdChkaXJlY3RpdmVzW2pdLCB7JCRpc29sYXRlU2NvcGU6IHRydWV9KTsKICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogbG9va3MgdXAgdGhlIGRpcmVjdGl2ZSBhbmQgZGVjb3JhdGVzIGl0IHdpdGggZXhjZXB0aW9uIGhhbmRsaW5nIGFuZCBwcm9wZXIgcGFyYW1ldGVycy4gV2UKICAgICAqIGNhbGwgdGhpcyB0aGUgYm91bmREaXJlY3RpdmUuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgZGlyZWN0aXZlIHRvIGxvb2sgdXAuCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYXRpb24gVGhlIGRpcmVjdGl2ZSBtdXN0IGJlIGZvdW5kIGluIHNwZWNpZmljIGZvcm1hdC4KICAgICAqICAgU3RyaW5nIGNvbnRhaW5pbmcgYW55IG9mIHRoZXNlcyBjaGFyYWN0ZXJzOgogICAgICoKICAgICAqICAgKiBgRWA6IGVsZW1lbnQgbmFtZQogICAgICogICAqIGBBJzogYXR0cmlidXRlCiAgICAgKiAgICogYENgOiBjbGFzcwogICAgICogICAqIGBNYDogY29tbWVudAogICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgZGlyZWN0aXZlIHdhcyBhZGRlZC4KICAgICAqLwogICAgZnVuY3Rpb24gYWRkRGlyZWN0aXZlKHREaXJlY3RpdmVzLCBuYW1lLCBsb2NhdGlvbiwgbWF4UHJpb3JpdHksIGlnbm9yZURpcmVjdGl2ZSwgc3RhcnRBdHRyTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRBdHRyTmFtZSkgewogICAgICBpZiAobmFtZSA9PT0gaWdub3JlRGlyZWN0aXZlKSByZXR1cm4gbnVsbDsKICAgICAgdmFyIG1hdGNoID0gbnVsbDsKICAgICAgaWYgKGhhc0RpcmVjdGl2ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHsKICAgICAgICBmb3IgKHZhciBkaXJlY3RpdmUsIGRpcmVjdGl2ZXMgPSAkaW5qZWN0b3IuZ2V0KG5hbWUgKyBTdWZmaXgpLAogICAgICAgICAgICBpID0gMCwgaWkgPSBkaXJlY3RpdmVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGRpcmVjdGl2ZSA9IGRpcmVjdGl2ZXNbaV07CiAgICAgICAgICAgIGlmICgobWF4UHJpb3JpdHkgPT09IHVuZGVmaW5lZCB8fCBtYXhQcmlvcml0eSA+IGRpcmVjdGl2ZS5wcmlvcml0eSkgJiYKICAgICAgICAgICAgICAgICBkaXJlY3RpdmUucmVzdHJpY3QuaW5kZXhPZihsb2NhdGlvbikgIT0gLTEpIHsKICAgICAgICAgICAgICBpZiAoc3RhcnRBdHRyTmFtZSkgewogICAgICAgICAgICAgICAgZGlyZWN0aXZlID0gaW5oZXJpdChkaXJlY3RpdmUsIHskJHN0YXJ0OiBzdGFydEF0dHJOYW1lLCAkJGVuZDogZW5kQXR0ck5hbWV9KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgdERpcmVjdGl2ZXMucHVzaChkaXJlY3RpdmUpOwogICAgICAgICAgICAgIG1hdGNoID0gZGlyZWN0aXZlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGNhdGNoIChlKSB7ICRleGNlcHRpb25IYW5kbGVyKGUpOyB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXRjaDsKICAgIH0KCgogICAgLyoqCiAgICAgKiBsb29rcyB1cCB0aGUgZGlyZWN0aXZlIGFuZCByZXR1cm5zIHRydWUgaWYgaXQgaXMgYSBtdWx0aS1lbGVtZW50IGRpcmVjdGl2ZSwKICAgICAqIGFuZCB0aGVyZWZvcmUgcmVxdWlyZXMgRE9NIG5vZGVzIGJldHdlZW4gLXN0YXJ0IGFuZCAtZW5kIG1hcmtlcnMgdG8gYmUgZ3JvdXBlZAogICAgICogdG9nZXRoZXIuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgZGlyZWN0aXZlIHRvIGxvb2sgdXAuCiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIGRpcmVjdGl2ZSB3YXMgcmVnaXN0ZXJlZCBhcyBtdWx0aS1lbGVtZW50LgogICAgICovCiAgICBmdW5jdGlvbiBkaXJlY3RpdmVJc011bHRpRWxlbWVudChuYW1lKSB7CiAgICAgIGlmIChoYXNEaXJlY3RpdmVzLmhhc093blByb3BlcnR5KG5hbWUpKSB7CiAgICAgICAgZm9yICh2YXIgZGlyZWN0aXZlLCBkaXJlY3RpdmVzID0gJGluamVjdG9yLmdldChuYW1lICsgU3VmZml4KSwKICAgICAgICAgICAgaSA9IDAsIGlpID0gZGlyZWN0aXZlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgICBkaXJlY3RpdmUgPSBkaXJlY3RpdmVzW2ldOwogICAgICAgICAgaWYgKGRpcmVjdGl2ZS5tdWx0aUVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFdoZW4gdGhlIGVsZW1lbnQgaXMgcmVwbGFjZWQgd2l0aCBIVE1MIHRlbXBsYXRlIHRoZW4gdGhlIG5ldyBhdHRyaWJ1dGVzCiAgICAgKiBvbiB0aGUgdGVtcGxhdGUgbmVlZCB0byBiZSBtZXJnZWQgd2l0aCB0aGUgZXhpc3RpbmcgYXR0cmlidXRlcyBpbiB0aGUgRE9NLgogICAgICogVGhlIGRlc2lyZWQgZWZmZWN0IGlzIHRvIGhhdmUgYm90aCBvZiB0aGUgYXR0cmlidXRlcyBwcmVzZW50LgogICAgICoKICAgICAqIEBwYXJhbSB7b2JqZWN0fSBkc3QgZGVzdGluYXRpb24gYXR0cmlidXRlcyAob3JpZ2luYWwgRE9NKQogICAgICogQHBhcmFtIHtvYmplY3R9IHNyYyBzb3VyY2UgYXR0cmlidXRlcyAoZnJvbSB0aGUgZGlyZWN0aXZlIHRlbXBsYXRlKQogICAgICovCiAgICBmdW5jdGlvbiBtZXJnZVRlbXBsYXRlQXR0cmlidXRlcyhkc3QsIHNyYykgewogICAgICB2YXIgc3JjQXR0ciA9IHNyYy4kYXR0ciwKICAgICAgICAgIGRzdEF0dHIgPSBkc3QuJGF0dHIsCiAgICAgICAgICAkZWxlbWVudCA9IGRzdC4kJGVsZW1lbnQ7CgogICAgICAvLyByZWFwcGx5IHRoZSBvbGQgYXR0cmlidXRlcyB0byB0aGUgbmV3IGVsZW1lbnQKICAgICAgZm9yRWFjaChkc3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICAgICAgICBpZiAoa2V5LmNoYXJBdCgwKSAhPSAnJCcpIHsKICAgICAgICAgIGlmIChzcmNba2V5XSAmJiBzcmNba2V5XSAhPT0gdmFsdWUpIHsKICAgICAgICAgICAgdmFsdWUgKz0gKGtleSA9PT0gJ3N0eWxlJyA/ICc7JyA6ICcgJykgKyBzcmNba2V5XTsKICAgICAgICAgIH0KICAgICAgICAgIGRzdC4kc2V0KGtleSwgdmFsdWUsIHRydWUsIHNyY0F0dHJba2V5XSk7CiAgICAgICAgfQogICAgICB9KTsKCiAgICAgIC8vIGNvcHkgdGhlIG5ldyBhdHRyaWJ1dGVzIG9uIHRoZSBvbGQgYXR0cnMgb2JqZWN0CiAgICAgIGZvckVhY2goc3JjLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSAnY2xhc3MnKSB7CiAgICAgICAgICBzYWZlQWRkQ2xhc3MoJGVsZW1lbnQsIHZhbHVlKTsKICAgICAgICAgIGRzdFsnY2xhc3MnXSA9IChkc3RbJ2NsYXNzJ10gPyBkc3RbJ2NsYXNzJ10gKyAnICcgOiAnJykgKyB2YWx1ZTsKICAgICAgICB9IGVsc2UgaWYgKGtleSA9PSAnc3R5bGUnKSB7CiAgICAgICAgICAkZWxlbWVudC5hdHRyKCdzdHlsZScsICRlbGVtZW50LmF0dHIoJ3N0eWxlJykgKyAnOycgKyB2YWx1ZSk7CiAgICAgICAgICBkc3RbJ3N0eWxlJ10gPSAoZHN0WydzdHlsZSddID8gZHN0WydzdHlsZSddICsgJzsnIDogJycpICsgdmFsdWU7CiAgICAgICAgICAvLyBgZHN0YCB3aWxsIG5ldmVyIGNvbnRhaW4gaGFzT3duUHJvcGVydHkgYXMgRE9NIHBhcnNlciB3b24ndCBsZXQgaXQuCiAgICAgICAgICAvLyBZb3Ugd2lsbCBnZXQgYW4gIkludmFsaWRDaGFyYWN0ZXJFcnJvcjogRE9NIEV4Y2VwdGlvbiA1IiBlcnJvciBpZiB5b3UKICAgICAgICAgIC8vIGhhdmUgYW4gYXR0cmlidXRlIGxpa2UgImhhcy1vd24tcHJvcGVydHkiIG9yICJkYXRhLWhhcy1vd24tcHJvcGVydHkiLCBldGMuCiAgICAgICAgfSBlbHNlIGlmIChrZXkuY2hhckF0KDApICE9ICckJyAmJiAhZHN0Lmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgIGRzdFtrZXldID0gdmFsdWU7CiAgICAgICAgICBkc3RBdHRyW2tleV0gPSBzcmNBdHRyW2tleV07CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KCgogICAgZnVuY3Rpb24gY29tcGlsZVRlbXBsYXRlVXJsKGRpcmVjdGl2ZXMsICRjb21waWxlTm9kZSwgdEF0dHJzLAogICAgICAgICRyb290RWxlbWVudCwgY2hpbGRUcmFuc2NsdWRlRm4sIHByZUxpbmtGbnMsIHBvc3RMaW5rRm5zLCBwcmV2aW91c0NvbXBpbGVDb250ZXh0KSB7CiAgICAgIHZhciBsaW5rUXVldWUgPSBbXSwKICAgICAgICAgIGFmdGVyVGVtcGxhdGVOb2RlTGlua0ZuLAogICAgICAgICAgYWZ0ZXJUZW1wbGF0ZUNoaWxkTGlua0ZuLAogICAgICAgICAgYmVmb3JlVGVtcGxhdGVDb21waWxlTm9kZSA9ICRjb21waWxlTm9kZVswXSwKICAgICAgICAgIG9yaWdBc3luY0RpcmVjdGl2ZSA9IGRpcmVjdGl2ZXMuc2hpZnQoKSwKICAgICAgICAgIC8vIFRoZSBmYWN0IHRoYXQgd2UgaGF2ZSB0byBjb3B5IGFuZCBwYXRjaCB0aGUgZGlyZWN0aXZlIHNlZW1zIHdyb25nIQogICAgICAgICAgZGVyaXZlZFN5bmNEaXJlY3RpdmUgPSBleHRlbmQoe30sIG9yaWdBc3luY0RpcmVjdGl2ZSwgewogICAgICAgICAgICB0ZW1wbGF0ZVVybDogbnVsbCwgdHJhbnNjbHVkZTogbnVsbCwgcmVwbGFjZTogbnVsbCwgJCRvcmlnaW5hbERpcmVjdGl2ZTogb3JpZ0FzeW5jRGlyZWN0aXZlCiAgICAgICAgICB9KSwKICAgICAgICAgIHRlbXBsYXRlVXJsID0gKGlzRnVuY3Rpb24ob3JpZ0FzeW5jRGlyZWN0aXZlLnRlbXBsYXRlVXJsKSkKICAgICAgICAgICAgICA/IG9yaWdBc3luY0RpcmVjdGl2ZS50ZW1wbGF0ZVVybCgkY29tcGlsZU5vZGUsIHRBdHRycykKICAgICAgICAgICAgICA6IG9yaWdBc3luY0RpcmVjdGl2ZS50ZW1wbGF0ZVVybCwKICAgICAgICAgIHRlbXBsYXRlTmFtZXNwYWNlID0gb3JpZ0FzeW5jRGlyZWN0aXZlLnRlbXBsYXRlTmFtZXNwYWNlOwoKICAgICAgJGNvbXBpbGVOb2RlLmVtcHR5KCk7CgogICAgICAkdGVtcGxhdGVSZXF1ZXN0KCRzY2UuZ2V0VHJ1c3RlZFJlc291cmNlVXJsKHRlbXBsYXRlVXJsKSkKICAgICAgICAudGhlbihmdW5jdGlvbihjb250ZW50KSB7CiAgICAgICAgICB2YXIgY29tcGlsZU5vZGUsIHRlbXBUZW1wbGF0ZUF0dHJzLCAkdGVtcGxhdGUsIGNoaWxkQm91bmRUcmFuc2NsdWRlRm47CgogICAgICAgICAgY29udGVudCA9IGRlbm9ybWFsaXplVGVtcGxhdGUoY29udGVudCk7CgogICAgICAgICAgaWYgKG9yaWdBc3luY0RpcmVjdGl2ZS5yZXBsYWNlKSB7CiAgICAgICAgICAgIGlmIChqcUxpdGVJc1RleHROb2RlKGNvbnRlbnQpKSB7CiAgICAgICAgICAgICAgJHRlbXBsYXRlID0gW107CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgJHRlbXBsYXRlID0gcmVtb3ZlQ29tbWVudHMod3JhcFRlbXBsYXRlKHRlbXBsYXRlTmFtZXNwYWNlLCB0cmltKGNvbnRlbnQpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29tcGlsZU5vZGUgPSAkdGVtcGxhdGVbMF07CgogICAgICAgICAgICBpZiAoJHRlbXBsYXRlLmxlbmd0aCAhPSAxIHx8IGNvbXBpbGVOb2RlLm5vZGVUeXBlICE9PSBOT0RFX1RZUEVfRUxFTUVOVCkgewogICAgICAgICAgICAgIHRocm93ICRjb21waWxlTWluRXJyKCd0cGxydCcsCiAgICAgICAgICAgICAgICAgICJUZW1wbGF0ZSBmb3IgZGlyZWN0aXZlICd7MH0nIG11c3QgaGF2ZSBleGFjdGx5IG9uZSByb290IGVsZW1lbnQuIHsxfSIsCiAgICAgICAgICAgICAgICAgIG9yaWdBc3luY0RpcmVjdGl2ZS5uYW1lLCB0ZW1wbGF0ZVVybCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRlbXBUZW1wbGF0ZUF0dHJzID0geyRhdHRyOiB7fX07CiAgICAgICAgICAgIHJlcGxhY2VXaXRoKCRyb290RWxlbWVudCwgJGNvbXBpbGVOb2RlLCBjb21waWxlTm9kZSk7CiAgICAgICAgICAgIHZhciB0ZW1wbGF0ZURpcmVjdGl2ZXMgPSBjb2xsZWN0RGlyZWN0aXZlcyhjb21waWxlTm9kZSwgW10sIHRlbXBUZW1wbGF0ZUF0dHJzKTsKCiAgICAgICAgICAgIGlmIChpc09iamVjdChvcmlnQXN5bmNEaXJlY3RpdmUuc2NvcGUpKSB7CiAgICAgICAgICAgICAgbWFya0RpcmVjdGl2ZXNBc0lzb2xhdGUodGVtcGxhdGVEaXJlY3RpdmVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkaXJlY3RpdmVzID0gdGVtcGxhdGVEaXJlY3RpdmVzLmNvbmNhdChkaXJlY3RpdmVzKTsKICAgICAgICAgICAgbWVyZ2VUZW1wbGF0ZUF0dHJpYnV0ZXModEF0dHJzLCB0ZW1wVGVtcGxhdGVBdHRycyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb21waWxlTm9kZSA9IGJlZm9yZVRlbXBsYXRlQ29tcGlsZU5vZGU7CiAgICAgICAgICAgICRjb21waWxlTm9kZS5odG1sKGNvbnRlbnQpOwogICAgICAgICAgfQoKICAgICAgICAgIGRpcmVjdGl2ZXMudW5zaGlmdChkZXJpdmVkU3luY0RpcmVjdGl2ZSk7CgogICAgICAgICAgYWZ0ZXJUZW1wbGF0ZU5vZGVMaW5rRm4gPSBhcHBseURpcmVjdGl2ZXNUb05vZGUoZGlyZWN0aXZlcywgY29tcGlsZU5vZGUsIHRBdHRycywKICAgICAgICAgICAgICBjaGlsZFRyYW5zY2x1ZGVGbiwgJGNvbXBpbGVOb2RlLCBvcmlnQXN5bmNEaXJlY3RpdmUsIHByZUxpbmtGbnMsIHBvc3RMaW5rRm5zLAogICAgICAgICAgICAgIHByZXZpb3VzQ29tcGlsZUNvbnRleHQpOwogICAgICAgICAgZm9yRWFjaCgkcm9vdEVsZW1lbnQsIGZ1bmN0aW9uKG5vZGUsIGkpIHsKICAgICAgICAgICAgaWYgKG5vZGUgPT0gY29tcGlsZU5vZGUpIHsKICAgICAgICAgICAgICAkcm9vdEVsZW1lbnRbaV0gPSAkY29tcGlsZU5vZGVbMF07CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgICAgYWZ0ZXJUZW1wbGF0ZUNoaWxkTGlua0ZuID0gY29tcGlsZU5vZGVzKCRjb21waWxlTm9kZVswXS5jaGlsZE5vZGVzLCBjaGlsZFRyYW5zY2x1ZGVGbik7CgogICAgICAgICAgd2hpbGUgKGxpbmtRdWV1ZS5sZW5ndGgpIHsKICAgICAgICAgICAgdmFyIHNjb3BlID0gbGlua1F1ZXVlLnNoaWZ0KCksCiAgICAgICAgICAgICAgICBiZWZvcmVUZW1wbGF0ZUxpbmtOb2RlID0gbGlua1F1ZXVlLnNoaWZ0KCksCiAgICAgICAgICAgICAgICBsaW5rUm9vdEVsZW1lbnQgPSBsaW5rUXVldWUuc2hpZnQoKSwKICAgICAgICAgICAgICAgIGJvdW5kVHJhbnNjbHVkZUZuID0gbGlua1F1ZXVlLnNoaWZ0KCksCiAgICAgICAgICAgICAgICBsaW5rTm9kZSA9ICRjb21waWxlTm9kZVswXTsKCiAgICAgICAgICAgIGlmIChzY29wZS4kJGRlc3Ryb3llZCkgY29udGludWU7CgogICAgICAgICAgICBpZiAoYmVmb3JlVGVtcGxhdGVMaW5rTm9kZSAhPT0gYmVmb3JlVGVtcGxhdGVDb21waWxlTm9kZSkgewogICAgICAgICAgICAgIHZhciBvbGRDbGFzc2VzID0gYmVmb3JlVGVtcGxhdGVMaW5rTm9kZS5jbGFzc05hbWU7CgogICAgICAgICAgICAgIGlmICghKHByZXZpb3VzQ29tcGlsZUNvbnRleHQuaGFzRWxlbWVudFRyYW5zY2x1ZGVEaXJlY3RpdmUgJiYKICAgICAgICAgICAgICAgICAgb3JpZ0FzeW5jRGlyZWN0aXZlLnJlcGxhY2UpKSB7CiAgICAgICAgICAgICAgICAvLyBpdCB3YXMgY2xvbmVkIHRoZXJlZm9yZSB3ZSBoYXZlIHRvIGNsb25lIGFzIHdlbGwuCiAgICAgICAgICAgICAgICBsaW5rTm9kZSA9IGpxTGl0ZUNsb25lKGNvbXBpbGVOb2RlKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmVwbGFjZVdpdGgobGlua1Jvb3RFbGVtZW50LCBqcUxpdGUoYmVmb3JlVGVtcGxhdGVMaW5rTm9kZSksIGxpbmtOb2RlKTsKCiAgICAgICAgICAgICAgLy8gQ29weSBpbiBDU1MgY2xhc3NlcyBmcm9tIG9yaWdpbmFsIG5vZGUKICAgICAgICAgICAgICBzYWZlQWRkQ2xhc3MoanFMaXRlKGxpbmtOb2RlKSwgb2xkQ2xhc3Nlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFmdGVyVGVtcGxhdGVOb2RlTGlua0ZuLnRyYW5zY2x1ZGVPblRoaXNFbGVtZW50KSB7CiAgICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbiA9IGNyZWF0ZUJvdW5kVHJhbnNjbHVkZUZuKHNjb3BlLCBhZnRlclRlbXBsYXRlTm9kZUxpbmtGbi50cmFuc2NsdWRlLCBib3VuZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbiA9IGJvdW5kVHJhbnNjbHVkZUZuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFmdGVyVGVtcGxhdGVOb2RlTGlua0ZuKGFmdGVyVGVtcGxhdGVDaGlsZExpbmtGbiwgc2NvcGUsIGxpbmtOb2RlLCAkcm9vdEVsZW1lbnQsCiAgICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgICB9CiAgICAgICAgICBsaW5rUXVldWUgPSBudWxsOwogICAgICAgIH0pOwoKICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGF5ZWROb2RlTGlua0ZuKGlnbm9yZUNoaWxkTGlua0ZuLCBzY29wZSwgbm9kZSwgcm9vdEVsZW1lbnQsIGJvdW5kVHJhbnNjbHVkZUZuKSB7CiAgICAgICAgdmFyIGNoaWxkQm91bmRUcmFuc2NsdWRlRm4gPSBib3VuZFRyYW5zY2x1ZGVGbjsKICAgICAgICBpZiAoc2NvcGUuJCRkZXN0cm95ZWQpIHJldHVybjsKICAgICAgICBpZiAobGlua1F1ZXVlKSB7CiAgICAgICAgICBsaW5rUXVldWUucHVzaChzY29wZSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICByb290RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkQm91bmRUcmFuc2NsdWRlRm4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoYWZ0ZXJUZW1wbGF0ZU5vZGVMaW5rRm4udHJhbnNjbHVkZU9uVGhpc0VsZW1lbnQpIHsKICAgICAgICAgICAgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbiA9IGNyZWF0ZUJvdW5kVHJhbnNjbHVkZUZuKHNjb3BlLCBhZnRlclRlbXBsYXRlTm9kZUxpbmtGbi50cmFuc2NsdWRlLCBib3VuZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgICB9CiAgICAgICAgICBhZnRlclRlbXBsYXRlTm9kZUxpbmtGbihhZnRlclRlbXBsYXRlQ2hpbGRMaW5rRm4sIHNjb3BlLCBub2RlLCByb290RWxlbWVudCwgY2hpbGRCb3VuZFRyYW5zY2x1ZGVGbik7CiAgICAgICAgfQogICAgICB9OwogICAgfQoKCiAgICAvKioKICAgICAqIFNvcnRpbmcgZnVuY3Rpb24gZm9yIGJvdW5kIGRpcmVjdGl2ZXMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGJ5UHJpb3JpdHkoYSwgYikgewogICAgICB2YXIgZGlmZiA9IGIucHJpb3JpdHkgLSBhLnByaW9yaXR5OwogICAgICBpZiAoZGlmZiAhPT0gMCkgcmV0dXJuIGRpZmY7CiAgICAgIGlmIChhLm5hbWUgIT09IGIubmFtZSkgcmV0dXJuIChhLm5hbWUgPCBiLm5hbWUpID8gLTEgOiAxOwogICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7CiAgICB9CgoKICAgIGZ1bmN0aW9uIGFzc2VydE5vRHVwbGljYXRlKHdoYXQsIHByZXZpb3VzRGlyZWN0aXZlLCBkaXJlY3RpdmUsIGVsZW1lbnQpIHsKICAgICAgaWYgKHByZXZpb3VzRGlyZWN0aXZlKSB7CiAgICAgICAgdGhyb3cgJGNvbXBpbGVNaW5FcnIoJ211bHRpZGlyJywgJ011bHRpcGxlIGRpcmVjdGl2ZXMgW3swfSwgezF9XSBhc2tpbmcgZm9yIHsyfSBvbjogezN9JywKICAgICAgICAgICAgcHJldmlvdXNEaXJlY3RpdmUubmFtZSwgZGlyZWN0aXZlLm5hbWUsIHdoYXQsIHN0YXJ0aW5nVGFnKGVsZW1lbnQpKTsKICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBhZGRUZXh0SW50ZXJwb2xhdGVEaXJlY3RpdmUoZGlyZWN0aXZlcywgdGV4dCkgewogICAgICB2YXIgaW50ZXJwb2xhdGVGbiA9ICRpbnRlcnBvbGF0ZSh0ZXh0LCB0cnVlKTsKICAgICAgaWYgKGludGVycG9sYXRlRm4pIHsKICAgICAgICBkaXJlY3RpdmVzLnB1c2goewogICAgICAgICAgcHJpb3JpdHk6IDAsCiAgICAgICAgICBjb21waWxlOiBmdW5jdGlvbiB0ZXh0SW50ZXJwb2xhdGVDb21waWxlRm4odGVtcGxhdGVOb2RlKSB7CiAgICAgICAgICAgIHZhciB0ZW1wbGF0ZU5vZGVQYXJlbnQgPSB0ZW1wbGF0ZU5vZGUucGFyZW50KCksCiAgICAgICAgICAgICAgICBoYXNDb21waWxlUGFyZW50ID0gISF0ZW1wbGF0ZU5vZGVQYXJlbnQubGVuZ3RoOwoKICAgICAgICAgICAgLy8gV2hlbiB0cmFuc2NsdWRpbmcgYSB0ZW1wbGF0ZSB0aGF0IGhhcyBiaW5kaW5ncyBpbiB0aGUgcm9vdAogICAgICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIGEgcGFyZW50IGFuZCB0aHVzIG5lZWQgdG8gYWRkIHRoZSBjbGFzcyBkdXJpbmcgbGlua2luZyBmbi4KICAgICAgICAgICAgaWYgKGhhc0NvbXBpbGVQYXJlbnQpIGNvbXBpbGUuJCRhZGRCaW5kaW5nQ2xhc3ModGVtcGxhdGVOb2RlUGFyZW50KTsKCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiB0ZXh0SW50ZXJwb2xhdGVMaW5rRm4oc2NvcGUsIG5vZGUpIHsKICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbm9kZS5wYXJlbnQoKTsKICAgICAgICAgICAgICBpZiAoIWhhc0NvbXBpbGVQYXJlbnQpIGNvbXBpbGUuJCRhZGRCaW5kaW5nQ2xhc3MocGFyZW50KTsKICAgICAgICAgICAgICBjb21waWxlLiQkYWRkQmluZGluZ0luZm8ocGFyZW50LCBpbnRlcnBvbGF0ZUZuLmV4cHJlc3Npb25zKTsKICAgICAgICAgICAgICBzY29wZS4kd2F0Y2goaW50ZXJwb2xhdGVGbiwgZnVuY3Rpb24gaW50ZXJwb2xhdGVGbldhdGNoQWN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICBub2RlWzBdLm5vZGVWYWx1ZSA9IHZhbHVlOwogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICB9CgoKICAgIGZ1bmN0aW9uIHdyYXBUZW1wbGF0ZSh0eXBlLCB0ZW1wbGF0ZSkgewogICAgICB0eXBlID0gbG93ZXJjYXNlKHR5cGUgfHwgJ2h0bWwnKTsKICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgIGNhc2UgJ3N2Zyc6CiAgICAgIGNhc2UgJ21hdGgnOgogICAgICAgIHZhciB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgICAgd3JhcHBlci5pbm5lckhUTUwgPSAnPCcgKyB0eXBlICsgJz4nICsgdGVtcGxhdGUgKyAnPC8nICsgdHlwZSArICc+JzsKICAgICAgICByZXR1cm4gd3JhcHBlci5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXM7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHRlbXBsYXRlOwogICAgICB9CiAgICB9CgoKICAgIGZ1bmN0aW9uIGdldFRydXN0ZWRDb250ZXh0KG5vZGUsIGF0dHJOb3JtYWxpemVkTmFtZSkgewogICAgICBpZiAoYXR0ck5vcm1hbGl6ZWROYW1lID09ICJzcmNkb2MiKSB7CiAgICAgICAgcmV0dXJuICRzY2UuSFRNTDsKICAgICAgfQogICAgICB2YXIgdGFnID0gbm9kZU5hbWVfKG5vZGUpOwogICAgICAvLyBtYWN0aW9uW3hsaW5rOmhyZWZdIGNhbiBzb3VyY2UgU1ZHLiAgSXQncyBub3QgbGltaXRlZCB0byA8bWFjdGlvbj4uCiAgICAgIGlmIChhdHRyTm9ybWFsaXplZE5hbWUgPT0gInhsaW5rSHJlZiIgfHwKICAgICAgICAgICh0YWcgPT0gImZvcm0iICYmIGF0dHJOb3JtYWxpemVkTmFtZSA9PSAiYWN0aW9uIikgfHwKICAgICAgICAgICh0YWcgIT0gImltZyIgJiYgKGF0dHJOb3JtYWxpemVkTmFtZSA9PSAic3JjIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ck5vcm1hbGl6ZWROYW1lID09ICJuZ1NyYyIpKSkgewogICAgICAgIHJldHVybiAkc2NlLlJFU09VUkNFX1VSTDsKICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBhZGRBdHRySW50ZXJwb2xhdGVEaXJlY3RpdmUobm9kZSwgZGlyZWN0aXZlcywgdmFsdWUsIG5hbWUsIGFsbE9yTm90aGluZykgewogICAgICB2YXIgdHJ1c3RlZENvbnRleHQgPSBnZXRUcnVzdGVkQ29udGV4dChub2RlLCBuYW1lKTsKICAgICAgYWxsT3JOb3RoaW5nID0gQUxMX09SX05PVEhJTkdfQVRUUlNbbmFtZV0gfHwgYWxsT3JOb3RoaW5nOwoKICAgICAgdmFyIGludGVycG9sYXRlRm4gPSAkaW50ZXJwb2xhdGUodmFsdWUsIHRydWUsIHRydXN0ZWRDb250ZXh0LCBhbGxPck5vdGhpbmcpOwoKICAgICAgLy8gbm8gaW50ZXJwb2xhdGlvbiBmb3VuZCAtPiBpZ25vcmUKICAgICAgaWYgKCFpbnRlcnBvbGF0ZUZuKSByZXR1cm47CgoKICAgICAgaWYgKG5hbWUgPT09ICJtdWx0aXBsZSIgJiYgbm9kZU5hbWVfKG5vZGUpID09PSAic2VsZWN0IikgewogICAgICAgIHRocm93ICRjb21waWxlTWluRXJyKCJzZWxtdWx0aSIsCiAgICAgICAgICAgICJCaW5kaW5nIHRvIHRoZSAnbXVsdGlwbGUnIGF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkLiBFbGVtZW50OiB7MH0iLAogICAgICAgICAgICBzdGFydGluZ1RhZyhub2RlKSk7CiAgICAgIH0KCiAgICAgIGRpcmVjdGl2ZXMucHVzaCh7CiAgICAgICAgcHJpb3JpdHk6IDEwMCwKICAgICAgICBjb21waWxlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICBwcmU6IGZ1bmN0aW9uIGF0dHJJbnRlcnBvbGF0ZVByZUxpbmtGbihzY29wZSwgZWxlbWVudCwgYXR0cikgewogICAgICAgICAgICAgICAgdmFyICQkb2JzZXJ2ZXJzID0gKGF0dHIuJCRvYnNlcnZlcnMgfHwgKGF0dHIuJCRvYnNlcnZlcnMgPSB7fSkpOwoKICAgICAgICAgICAgICAgIGlmIChFVkVOVF9IQU5ETEVSX0FUVFJfUkVHRVhQLnRlc3QobmFtZSkpIHsKICAgICAgICAgICAgICAgICAgdGhyb3cgJGNvbXBpbGVNaW5FcnIoJ25vZG9tZXZlbnRzJywKICAgICAgICAgICAgICAgICAgICAgICJJbnRlcnBvbGF0aW9ucyBmb3IgSFRNTCBET00gZXZlbnQgYXR0cmlidXRlcyBhcmUgZGlzYWxsb3dlZC4gIFBsZWFzZSB1c2UgdGhlICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICJuZy0gdmVyc2lvbnMgKHN1Y2ggYXMgbmctY2xpY2sgaW5zdGVhZCBvZiBvbmNsaWNrKSBpbnN0ZWFkLiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBhdHRyaWJ1dGUgaGFzIGNoYW5nZWQgc2luY2UgbGFzdCAkaW50ZXJwb2xhdGUoKWVkCiAgICAgICAgICAgICAgICB2YXIgbmV3VmFsdWUgPSBhdHRyW25hbWVdOwogICAgICAgICAgICAgICAgaWYgKG5ld1ZhbHVlICE9PSB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGludGVycG9sYXRlIGFnYWluIHNpbmNlIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaGFzIGJlZW4gdXBkYXRlZAogICAgICAgICAgICAgICAgICAvLyAoZS5nLiBieSBhbm90aGVyIGRpcmVjdGl2ZSdzIGNvbXBpbGUgZnVuY3Rpb24pCiAgICAgICAgICAgICAgICAgIC8vIGVuc3VyZSB1bnNldC9lbXB0eSB2YWx1ZXMgbWFrZSBpbnRlcnBvbGF0ZUZuIGZhbHN5CiAgICAgICAgICAgICAgICAgIGludGVycG9sYXRlRm4gPSBuZXdWYWx1ZSAmJiAkaW50ZXJwb2xhdGUobmV3VmFsdWUsIHRydWUsIHRydXN0ZWRDb250ZXh0LCBhbGxPck5vdGhpbmcpOwogICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ld1ZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGlmIGF0dHJpYnV0ZSB3YXMgdXBkYXRlZCBzbyB0aGF0IHRoZXJlIGlzIG5vIGludGVycG9sYXRpb24gZ29pbmcgb24gd2UgZG9uJ3Qgd2FudCB0bwogICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgYW55IG9ic2VydmVycwogICAgICAgICAgICAgICAgaWYgKCFpbnRlcnBvbGF0ZUZuKSByZXR1cm47CgogICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSBhdHRyIG9iamVjdCBzbyB0aGF0IGl0J3MgcmVhZHkgaW4gY2FzZSB3ZSBuZWVkIHRoZSB2YWx1ZSBmb3IgaXNvbGF0ZQogICAgICAgICAgICAgICAgLy8gc2NvcGUgaW5pdGlhbGl6YXRpb24sIG90aGVyd2lzZSB0aGUgdmFsdWUgd291bGQgbm90IGJlIGF2YWlsYWJsZSBmcm9tIGlzb2xhdGUKICAgICAgICAgICAgICAgIC8vIGRpcmVjdGl2ZSdzIGxpbmtpbmcgZm4gZHVyaW5nIGxpbmtpbmcgcGhhc2UKICAgICAgICAgICAgICAgIGF0dHJbbmFtZV0gPSBpbnRlcnBvbGF0ZUZuKHNjb3BlKTsKCiAgICAgICAgICAgICAgICAoJCRvYnNlcnZlcnNbbmFtZV0gfHwgKCQkb2JzZXJ2ZXJzW25hbWVdID0gW10pKS4kJGludGVyID0gdHJ1ZTsKICAgICAgICAgICAgICAgIChhdHRyLiQkb2JzZXJ2ZXJzICYmIGF0dHIuJCRvYnNlcnZlcnNbbmFtZV0uJCRzY29wZSB8fCBzY29wZSkuCiAgICAgICAgICAgICAgICAgICR3YXRjaChpbnRlcnBvbGF0ZUZuLCBmdW5jdGlvbiBpbnRlcnBvbGF0ZUZuV2F0Y2hBY3Rpb24obmV3VmFsdWUsIG9sZFZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgLy9zcGVjaWFsIGNhc2UgZm9yIGNsYXNzIGF0dHJpYnV0ZSBhZGRpdGlvbiArIHJlbW92YWwKICAgICAgICAgICAgICAgICAgICAvL3NvIHRoYXQgY2xhc3MgY2hhbmdlcyBjYW4gdGFwIGludG8gdGhlIGFuaW1hdGlvbgogICAgICAgICAgICAgICAgICAgIC8vaG9va3MgcHJvdmlkZWQgYnkgdGhlICRhbmltYXRlIHNlcnZpY2UuIEJlIHN1cmUgdG8KICAgICAgICAgICAgICAgICAgICAvL3NraXAgYW5pbWF0aW9ucyB3aGVuIHRoZSBmaXJzdCBkaWdlc3Qgb2NjdXJzICh3aGVuCiAgICAgICAgICAgICAgICAgICAgLy9ib3RoIHRoZSBuZXcgYW5kIHRoZSBvbGQgdmFsdWVzIGFyZSB0aGUgc2FtZSkgc2luY2UKICAgICAgICAgICAgICAgICAgICAvL3RoZSBDU1MgY2xhc3NlcyBhcmUgdGhlIG5vbi1pbnRlcnBvbGF0ZWQgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdjbGFzcycgJiYgbmV3VmFsdWUgIT0gb2xkVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgIGF0dHIuJHVwZGF0ZUNsYXNzKG5ld1ZhbHVlLCBvbGRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIGF0dHIuJHNldChuYW1lLCBuZXdWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgIH0pOwogICAgfQoKCiAgICAvKioKICAgICAqIFRoaXMgaXMgYSBzcGVjaWFsIGpxTGl0ZS5yZXBsYWNlV2l0aCwgd2hpY2ggY2FuIHJlcGxhY2UgaXRlbXMgd2hpY2gKICAgICAqIGhhdmUgbm8gcGFyZW50cywgcHJvdmlkZWQgdGhhdCB0aGUgY29udGFpbmluZyBqcUxpdGUgY29sbGVjdGlvbiBpcyBwcm92aWRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0ge0pxTGl0ZT19ICRyb290RWxlbWVudCBUaGUgcm9vdCBvZiB0aGUgY29tcGlsZSB0cmVlLiBVc2VkIHNvIHRoYXQgd2UgY2FuIHJlcGxhY2Ugbm9kZXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSByb290IG9mIHRoZSB0cmVlLgogICAgICogQHBhcmFtIHtKcUxpdGV9IGVsZW1lbnRzVG9SZW1vdmUgVGhlIGpxTGl0ZSBlbGVtZW50IHdoaWNoIHdlIGFyZSBnb2luZyB0byByZXBsYWNlLiBXZSBrZWVwCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgc2hlbGwsIGJ1dCByZXBsYWNlIGl0cyBET00gbm9kZSByZWZlcmVuY2UuCiAgICAgKiBAcGFyYW0ge05vZGV9IG5ld05vZGUgVGhlIG5ldyBET00gbm9kZS4KICAgICAqLwogICAgZnVuY3Rpb24gcmVwbGFjZVdpdGgoJHJvb3RFbGVtZW50LCBlbGVtZW50c1RvUmVtb3ZlLCBuZXdOb2RlKSB7CiAgICAgIHZhciBmaXJzdEVsZW1lbnRUb1JlbW92ZSA9IGVsZW1lbnRzVG9SZW1vdmVbMF0sCiAgICAgICAgICByZW1vdmVDb3VudCA9IGVsZW1lbnRzVG9SZW1vdmUubGVuZ3RoLAogICAgICAgICAgcGFyZW50ID0gZmlyc3RFbGVtZW50VG9SZW1vdmUucGFyZW50Tm9kZSwKICAgICAgICAgIGksIGlpOwoKICAgICAgaWYgKCRyb290RWxlbWVudCkgewogICAgICAgIGZvciAoaSA9IDAsIGlpID0gJHJvb3RFbGVtZW50Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICAgIGlmICgkcm9vdEVsZW1lbnRbaV0gPT0gZmlyc3RFbGVtZW50VG9SZW1vdmUpIHsKICAgICAgICAgICAgJHJvb3RFbGVtZW50W2krK10gPSBuZXdOb2RlOwogICAgICAgICAgICBmb3IgKHZhciBqID0gaSwgajIgPSBqICsgcmVtb3ZlQ291bnQgLSAxLAogICAgICAgICAgICAgICAgICAgICBqaiA9ICRyb290RWxlbWVudC5sZW5ndGg7CiAgICAgICAgICAgICAgICAgaiA8IGpqOyBqKyssIGoyKyspIHsKICAgICAgICAgICAgICBpZiAoajIgPCBqaikgewogICAgICAgICAgICAgICAgJHJvb3RFbGVtZW50W2pdID0gJHJvb3RFbGVtZW50W2oyXTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVsZXRlICRyb290RWxlbWVudFtqXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJvb3RFbGVtZW50Lmxlbmd0aCAtPSByZW1vdmVDb3VudCAtIDE7CgogICAgICAgICAgICAvLyBJZiB0aGUgcmVwbGFjZWQgZWxlbWVudCBpcyBhbHNvIHRoZSBqUXVlcnkgLmNvbnRleHQgdGhlbiByZXBsYWNlIGl0CiAgICAgICAgICAgIC8vIC5jb250ZXh0IGlzIGEgZGVwcmVjYXRlZCBqUXVlcnkgYXBpLCBzbyB3ZSBzaG91bGQgc2V0IGl0IG9ubHkgd2hlbiBqUXVlcnkgc2V0IGl0CiAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGkuanF1ZXJ5LmNvbS9jb250ZXh0LwogICAgICAgICAgICBpZiAoJHJvb3RFbGVtZW50LmNvbnRleHQgPT09IGZpcnN0RWxlbWVudFRvUmVtb3ZlKSB7CiAgICAgICAgICAgICAgJHJvb3RFbGVtZW50LmNvbnRleHQgPSBuZXdOb2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKHBhcmVudCkgewogICAgICAgIHBhcmVudC5yZXBsYWNlQ2hpbGQobmV3Tm9kZSwgZmlyc3RFbGVtZW50VG9SZW1vdmUpOwogICAgICB9CgogICAgICAvLyBUT0RPKHBlcmYpOiB3aGF0J3MgdGhpcyBkb2N1bWVudCBmcmFnbWVudCBmb3I/IGlzIGl0IG5lZWRlZD8gY2FuIHdlIGF0IGxlYXN0IHJldXNlIGl0PwogICAgICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGZpcnN0RWxlbWVudFRvUmVtb3ZlKTsKCiAgICAgIC8vIENvcHkgb3ZlciB1c2VyIGRhdGEgKHRoYXQgaW5jbHVkZXMgQW5ndWxhcidzICRzY29wZSBldGMuKS4gRG9uJ3QgY29weSBwcml2YXRlCiAgICAgIC8vIGRhdGEgaGVyZSBiZWNhdXNlIHRoZXJlJ3Mgbm8gcHVibGljIGludGVyZmFjZSBpbiBqUXVlcnkgdG8gZG8gdGhhdCBhbmQgY29weWluZyBvdmVyCiAgICAgIC8vIGV2ZW50IGxpc3RlbmVycyAod2hpY2ggaXMgdGhlIG1haW4gdXNlIG9mIHByaXZhdGUgZGF0YSkgd291bGRuJ3Qgd29yayBhbnl3YXkuCiAgICAgIGpxTGl0ZShuZXdOb2RlKS5kYXRhKGpxTGl0ZShmaXJzdEVsZW1lbnRUb1JlbW92ZSkuZGF0YSgpKTsKCiAgICAgIC8vIFJlbW92ZSBkYXRhIG9mIHRoZSByZXBsYWNlZCBlbGVtZW50LiBXZSBjYW5ub3QganVzdCBjYWxsIC5yZW1vdmUoKQogICAgICAvLyBvbiB0aGUgZWxlbWVudCBpdCBzaW5jZSB0aGF0IHdvdWxkIGRlYWxsb2NhdGUgc2NvcGUgdGhhdCBpcyBuZWVkZWQKICAgICAgLy8gZm9yIHRoZSBuZXcgbm9kZS4gSW5zdGVhZCwgcmVtb3ZlIHRoZSBkYXRhICJtYW51YWxseSIuCiAgICAgIGlmICghalF1ZXJ5KSB7CiAgICAgICAgZGVsZXRlIGpxTGl0ZS5jYWNoZVtmaXJzdEVsZW1lbnRUb1JlbW92ZVtqcUxpdGUuZXhwYW5kb11dOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGpRdWVyeSAyLnggZG9lc24ndCBleHBvc2UgdGhlIGRhdGEgc3RvcmFnZS4gVXNlIGpRdWVyeS5jbGVhbkRhdGEgdG8gY2xlYW4gdXAgYWZ0ZXIKICAgICAgICAvLyB0aGUgcmVwbGFjZWQgZWxlbWVudC4gVGhlIGNsZWFuRGF0YSB2ZXJzaW9uIG1vbmtleS1wYXRjaGVkIGJ5IEFuZ3VsYXIgd291bGQgY2F1c2UKICAgICAgICAvLyB0aGUgc2NvcGUgdG8gYmUgdHJhc2hlZCBhbmQgd2UgZG8gbmVlZCB0aGUgdmVyeSBzYW1lIHNjb3BlIHRvIHdvcmsgd2l0aCB0aGUgbmV3CiAgICAgICAgLy8gZWxlbWVudC4gSG93ZXZlciwgd2UgY2Fubm90IGp1c3QgY2FjaGUgdGhlIG5vbi1wYXRjaGVkIHZlcnNpb24gYW5kIHVzZSBpdCBoZXJlIGFzCiAgICAgICAgLy8gdGhhdCB3b3VsZCBicmVhayBpZiBhbm90aGVyIGxpYnJhcnkgcGF0Y2hlcyB0aGUgbWV0aG9kIGFmdGVyIEFuZ3VsYXIgZG9lcyAob25lCiAgICAgICAgLy8gZXhhbXBsZSBpcyBqUXVlcnkgVUkpLiBJbnN0ZWFkLCBzZXQgYSBmbGFnIGluZGljYXRpbmcgc2NvcGUgZGVzdHJveWluZyBzaG91bGQgYmUKICAgICAgICAvLyBza2lwcGVkIHRoaXMgb25lIHRpbWUuCiAgICAgICAgc2tpcERlc3Ryb3lPbk5leHRKUXVlcnlDbGVhbkRhdGEgPSB0cnVlOwogICAgICAgIGpRdWVyeS5jbGVhbkRhdGEoW2ZpcnN0RWxlbWVudFRvUmVtb3ZlXSk7CiAgICAgIH0KCiAgICAgIGZvciAodmFyIGsgPSAxLCBrayA9IGVsZW1lbnRzVG9SZW1vdmUubGVuZ3RoOyBrIDwga2s7IGsrKykgewogICAgICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNUb1JlbW92ZVtrXTsKICAgICAgICBqcUxpdGUoZWxlbWVudCkucmVtb3ZlKCk7IC8vIG11c3QgZG8gdGhpcyB3YXkgdG8gY2xlYW4gdXAgZXhwYW5kbwogICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgICAgIGRlbGV0ZSBlbGVtZW50c1RvUmVtb3ZlW2tdOwogICAgICB9CgogICAgICBlbGVtZW50c1RvUmVtb3ZlWzBdID0gbmV3Tm9kZTsKICAgICAgZWxlbWVudHNUb1JlbW92ZS5sZW5ndGggPSAxOwogICAgfQoKCiAgICBmdW5jdGlvbiBjbG9uZUFuZEFubm90YXRlRm4oZm4sIGFubm90YXRpb24pIHsKICAgICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbigpIHsgcmV0dXJuIGZuLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7IH0sIGZuLCBhbm5vdGF0aW9uKTsKICAgIH0KCgogICAgZnVuY3Rpb24gaW52b2tlTGlua0ZuKGxpbmtGbiwgc2NvcGUsICRlbGVtZW50LCBhdHRycywgY29udHJvbGxlcnMsIHRyYW5zY2x1ZGVGbikgewogICAgICB0cnkgewogICAgICAgIGxpbmtGbihzY29wZSwgJGVsZW1lbnQsIGF0dHJzLCBjb250cm9sbGVycywgdHJhbnNjbHVkZUZuKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUsIHN0YXJ0aW5nVGFnKCRlbGVtZW50KSk7CiAgICAgIH0KICAgIH0KICB9XTsKfQoKdmFyIFBSRUZJWF9SRUdFWFAgPSAvXigoPzp4fGRhdGEpW1w6XC1fXSkvaTsKLyoqCiAqIENvbnZlcnRzIGFsbCBhY2NlcHRlZCBkaXJlY3RpdmVzIGZvcm1hdCBpbnRvIHByb3BlciBkaXJlY3RpdmUgbmFtZS4KICogQHBhcmFtIG5hbWUgTmFtZSB0byBub3JtYWxpemUKICovCmZ1bmN0aW9uIGRpcmVjdGl2ZU5vcm1hbGl6ZShuYW1lKSB7CiAgcmV0dXJuIGNhbWVsQ2FzZShuYW1lLnJlcGxhY2UoUFJFRklYX1JFR0VYUCwgJycpKTsKfQoKLyoqCiAqIEBuZ2RvYyB0eXBlCiAqIEBuYW1lICRjb21waWxlLmRpcmVjdGl2ZS5BdHRyaWJ1dGVzCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBIHNoYXJlZCBvYmplY3QgYmV0d2VlbiBkaXJlY3RpdmUgY29tcGlsZSAvIGxpbmtpbmcgZnVuY3Rpb25zIHdoaWNoIGNvbnRhaW5zIG5vcm1hbGl6ZWQgRE9NCiAqIGVsZW1lbnQgYXR0cmlidXRlcy4gVGhlIHZhbHVlcyByZWZsZWN0IGN1cnJlbnQgYmluZGluZyBzdGF0ZSBge3sgfX1gLiBUaGUgbm9ybWFsaXphdGlvbiBpcwogKiBuZWVkZWQgc2luY2UgYWxsIG9mIHRoZXNlIGFyZSB0cmVhdGVkIGFzIGVxdWl2YWxlbnQgaW4gQW5ndWxhcjoKICoKICogYGBgCiAqICAgIDxzcGFuIG5nOmJpbmQ9ImEiIG5nLWJpbmQ9ImEiIGRhdGEtbmctYmluZD0iYSIgeC1uZy1iaW5kPSJhIj4KICogYGBgCiAqLwoKLyoqCiAqIEBuZ2RvYyBwcm9wZXJ0eQogKiBAbmFtZSAkY29tcGlsZS5kaXJlY3RpdmUuQXR0cmlidXRlcyMkYXR0cgogKgogKiBAZGVzY3JpcHRpb24KICogQSBtYXAgb2YgRE9NIGVsZW1lbnQgYXR0cmlidXRlIG5hbWVzIHRvIHRoZSBub3JtYWxpemVkIG5hbWUuIFRoaXMgaXMKICogbmVlZGVkIHRvIGRvIHJldmVyc2UgbG9va3VwIGZyb20gbm9ybWFsaXplZCBuYW1lIGJhY2sgdG8gYWN0dWFsIG5hbWUuCiAqLwoKCi8qKgogKiBAbmdkb2MgbWV0aG9kCiAqIEBuYW1lICRjb21waWxlLmRpcmVjdGl2ZS5BdHRyaWJ1dGVzIyRzZXQKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIFNldCBET00gZWxlbWVudCBhdHRyaWJ1dGUgdmFsdWUuCiAqCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5vcm1hbGl6ZWQgZWxlbWVudCBhdHRyaWJ1dGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gbW9kaWZ5LiBUaGUgbmFtZSBpcwogKiAgICAgICAgICByZXZlcnNlLXRyYW5zbGF0ZWQgdXNpbmcgdGhlIHtAbGluayBuZy4kY29tcGlsZS5kaXJlY3RpdmUuQXR0cmlidXRlcyMkYXR0ciAkYXR0cn0KICogICAgICAgICAgcHJvcGVydHkgdG8gdGhlIG9yaWdpbmFsIG5hbWUuCiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byBzZXQgdGhlIGF0dHJpYnV0ZSB0by4gVGhlIHZhbHVlIGNhbiBiZSBhbiBpbnRlcnBvbGF0ZWQgc3RyaW5nLgogKi8KCgoKLyoqCiAqIENsb3N1cmUgY29tcGlsZXIgdHlwZSBpbmZvcm1hdGlvbgogKi8KCmZ1bmN0aW9uIG5vZGVzZXRMaW5raW5nRm4oCiAgLyogYW5ndWxhci5TY29wZSAqLyBzY29wZSwKICAvKiBOb2RlTGlzdCAqLyBub2RlTGlzdCwKICAvKiBFbGVtZW50ICovIHJvb3RFbGVtZW50LAogIC8qIGZ1bmN0aW9uKEZ1bmN0aW9uKSAqLyBib3VuZFRyYW5zY2x1ZGVGbgopIHt9CgpmdW5jdGlvbiBkaXJlY3RpdmVMaW5raW5nRm4oCiAgLyogbm9kZXNldExpbmtpbmdGbiAqLyBub2Rlc2V0TGlua2luZ0ZuLAogIC8qIGFuZ3VsYXIuU2NvcGUgKi8gc2NvcGUsCiAgLyogTm9kZSAqLyBub2RlLAogIC8qIEVsZW1lbnQgKi8gcm9vdEVsZW1lbnQsCiAgLyogZnVuY3Rpb24oRnVuY3Rpb24pICovIGJvdW5kVHJhbnNjbHVkZUZuCikge30KCmZ1bmN0aW9uIHRva2VuRGlmZmVyZW5jZShzdHIxLCBzdHIyKSB7CiAgdmFyIHZhbHVlcyA9ICcnLAogICAgICB0b2tlbnMxID0gc3RyMS5zcGxpdCgvXHMrLyksCiAgICAgIHRva2VuczIgPSBzdHIyLnNwbGl0KC9ccysvKTsKCiAgb3V0ZXI6CiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b2tlbnMxLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgdG9rZW4gPSB0b2tlbnMxW2ldOwogICAgZm9yICh2YXIgaiA9IDA7IGogPCB0b2tlbnMyLmxlbmd0aDsgaisrKSB7CiAgICAgIGlmICh0b2tlbiA9PSB0b2tlbnMyW2pdKSBjb250aW51ZSBvdXRlcjsKICAgIH0KICAgIHZhbHVlcyArPSAodmFsdWVzLmxlbmd0aCA+IDAgPyAnICcgOiAnJykgKyB0b2tlbjsKICB9CiAgcmV0dXJuIHZhbHVlczsKfQoKZnVuY3Rpb24gcmVtb3ZlQ29tbWVudHMoanFOb2RlcykgewogIGpxTm9kZXMgPSBqcUxpdGUoanFOb2Rlcyk7CiAgdmFyIGkgPSBqcU5vZGVzLmxlbmd0aDsKCiAgaWYgKGkgPD0gMSkgewogICAgcmV0dXJuIGpxTm9kZXM7CiAgfQoKICB3aGlsZSAoaS0tKSB7CiAgICB2YXIgbm9kZSA9IGpxTm9kZXNbaV07CiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTk9ERV9UWVBFX0NPTU1FTlQpIHsKICAgICAgc3BsaWNlLmNhbGwoanFOb2RlcywgaSwgMSk7CiAgICB9CiAgfQogIHJldHVybiBqcU5vZGVzOwp9CgovKioKICogQG5nZG9jIHByb3ZpZGVyCiAqIEBuYW1lICRjb250cm9sbGVyUHJvdmlkZXIKICogQGRlc2NyaXB0aW9uCiAqIFRoZSB7QGxpbmsgbmcuJGNvbnRyb2xsZXIgJGNvbnRyb2xsZXIgc2VydmljZX0gaXMgdXNlZCBieSBBbmd1bGFyIHRvIGNyZWF0ZSBuZXcKICogY29udHJvbGxlcnMuCiAqCiAqIFRoaXMgcHJvdmlkZXIgYWxsb3dzIGNvbnRyb2xsZXIgcmVnaXN0cmF0aW9uIHZpYSB0aGUKICoge0BsaW5rIG5nLiRjb250cm9sbGVyUHJvdmlkZXIjcmVnaXN0ZXIgcmVnaXN0ZXJ9IG1ldGhvZC4KICovCmZ1bmN0aW9uICRDb250cm9sbGVyUHJvdmlkZXIoKSB7CiAgdmFyIGNvbnRyb2xsZXJzID0ge30sCiAgICAgIGdsb2JhbHMgPSBmYWxzZSwKICAgICAgQ05UUkxfUkVHID0gL14oXFMrKShccythc1xzKyhcdyspKT8kLzsKCgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkY29udHJvbGxlclByb3ZpZGVyI3JlZ2lzdGVyCiAgICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBuYW1lIENvbnRyb2xsZXIgbmFtZSwgb3IgYW4gb2JqZWN0IG1hcCBvZiBjb250cm9sbGVycyB3aGVyZSB0aGUga2V5cyBhcmUKICAgKiAgICB0aGUgbmFtZXMgYW5kIHRoZSB2YWx1ZXMgYXJlIHRoZSBjb25zdHJ1Y3RvcnMuCiAgICogQHBhcmFtIHtGdW5jdGlvbnxBcnJheX0gY29uc3RydWN0b3IgQ29udHJvbGxlciBjb25zdHJ1Y3RvciBmbiAob3B0aW9uYWxseSBkZWNvcmF0ZWQgd2l0aCBESQogICAqICAgIGFubm90YXRpb25zIGluIHRoZSBhcnJheSBub3RhdGlvbikuCiAgICovCiAgdGhpcy5yZWdpc3RlciA9IGZ1bmN0aW9uKG5hbWUsIGNvbnN0cnVjdG9yKSB7CiAgICBhc3NlcnROb3RIYXNPd25Qcm9wZXJ0eShuYW1lLCAnY29udHJvbGxlcicpOwogICAgaWYgKGlzT2JqZWN0KG5hbWUpKSB7CiAgICAgIGV4dGVuZChjb250cm9sbGVycywgbmFtZSk7CiAgICB9IGVsc2UgewogICAgICBjb250cm9sbGVyc1tuYW1lXSA9IGNvbnN0cnVjdG9yOwogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkY29udHJvbGxlclByb3ZpZGVyI2FsbG93R2xvYmFscwogICAqIEBkZXNjcmlwdGlvbiBJZiBjYWxsZWQsIGFsbG93cyBgJGNvbnRyb2xsZXJgIHRvIGZpbmQgY29udHJvbGxlciBjb25zdHJ1Y3RvcnMgb24gYHdpbmRvd2AKICAgKi8KICB0aGlzLmFsbG93R2xvYmFscyA9IGZ1bmN0aW9uKCkgewogICAgZ2xvYmFscyA9IHRydWU7CiAgfTsKCgogIHRoaXMuJGdldCA9IFsnJGluamVjdG9yJywgJyR3aW5kb3cnLCBmdW5jdGlvbigkaW5qZWN0b3IsICR3aW5kb3cpIHsKCiAgICAvKioKICAgICAqIEBuZ2RvYyBzZXJ2aWNlCiAgICAgKiBAbmFtZSAkY29udHJvbGxlcgogICAgICogQHJlcXVpcmVzICRpbmplY3RvcgogICAgICoKICAgICAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBjb25zdHJ1Y3RvciBJZiBjYWxsZWQgd2l0aCBhIGZ1bmN0aW9uIHRoZW4gaXQncyBjb25zaWRlcmVkIHRvIGJlIHRoZQogICAgICogICAgY29udHJvbGxlciBjb25zdHJ1Y3RvciBmdW5jdGlvbi4gT3RoZXJ3aXNlIGl0J3MgY29uc2lkZXJlZCB0byBiZSBhIHN0cmluZyB3aGljaCBpcyB1c2VkCiAgICAgKiAgICB0byByZXRyaWV2ZSB0aGUgY29udHJvbGxlciBjb25zdHJ1Y3RvciB1c2luZyB0aGUgZm9sbG93aW5nIHN0ZXBzOgogICAgICoKICAgICAqICAgICogY2hlY2sgaWYgYSBjb250cm9sbGVyIHdpdGggZ2l2ZW4gbmFtZSBpcyByZWdpc3RlcmVkIHZpYSBgJGNvbnRyb2xsZXJQcm92aWRlcmAKICAgICAqICAgICogY2hlY2sgaWYgZXZhbHVhdGluZyB0aGUgc3RyaW5nIG9uIHRoZSBjdXJyZW50IHNjb3BlIHJldHVybnMgYSBjb25zdHJ1Y3RvcgogICAgICogICAgKiBpZiAkY29udHJvbGxlclByb3ZpZGVyI2FsbG93R2xvYmFscywgY2hlY2sgYHdpbmRvd1tjb25zdHJ1Y3Rvcl1gIG9uIHRoZSBnbG9iYWwKICAgICAqICAgICAgYHdpbmRvd2Agb2JqZWN0IChub3QgcmVjb21tZW5kZWQpCiAgICAgKgogICAgICogICAgVGhlIHN0cmluZyBjYW4gdXNlIHRoZSBgY29udHJvbGxlciBhcyBwcm9wZXJ0eWAgc3ludGF4LCB3aGVyZSB0aGUgY29udHJvbGxlciBpbnN0YW5jZSBpcyBwdWJsaXNoZWQKICAgICAqICAgIGFzIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkgb24gdGhlIGBzY29wZWA7IHRoZSBgc2NvcGVgIG11c3QgYmUgaW5qZWN0ZWQgaW50byBgbG9jYWxzYCBwYXJhbSBmb3IgdGhpcwogICAgICogICAgdG8gd29yayBjb3JyZWN0bHkuCiAgICAgKgogICAgICogQHBhcmFtIHtPYmplY3R9IGxvY2FscyBJbmplY3Rpb24gbG9jYWxzIGZvciBDb250cm9sbGVyLgogICAgICogQHJldHVybiB7T2JqZWN0fSBJbnN0YW5jZSBvZiBnaXZlbiBjb250cm9sbGVyLgogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogYCRjb250cm9sbGVyYCBzZXJ2aWNlIGlzIHJlc3BvbnNpYmxlIGZvciBpbnN0YW50aWF0aW5nIGNvbnRyb2xsZXJzLgogICAgICoKICAgICAqIEl0J3MganVzdCBhIHNpbXBsZSBjYWxsIHRvIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LCBidXQgZXh0cmFjdGVkIGludG8KICAgICAqIGEgc2VydmljZSwgc28gdGhhdCBvbmUgY2FuIG92ZXJyaWRlIHRoaXMgc2VydmljZSB3aXRoIFtCQyB2ZXJzaW9uXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xNjQ5Nzg4KS4KICAgICAqLwogICAgcmV0dXJuIGZ1bmN0aW9uKGV4cHJlc3Npb24sIGxvY2FscywgbGF0ZXIsIGlkZW50KSB7CiAgICAgIC8vIFBSSVZBVEUgQVBJOgogICAgICAvLyAgIHBhcmFtIGBsYXRlcmAgLS0tIGluZGljYXRlcyB0aGF0IHRoZSBjb250cm9sbGVyJ3MgY29uc3RydWN0b3IgaXMgaW52b2tlZCBhdCBhIGxhdGVyIHRpbWUuCiAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgSWYgdHJ1ZSwgJGNvbnRyb2xsZXIgd2lsbCBhbGxvY2F0ZSB0aGUgb2JqZWN0IHdpdGggdGhlIGNvcnJlY3QKICAgICAgLy8gICAgICAgICAgICAgICAgICAgICBwcm90b3R5cGUgY2hhaW4sIGJ1dCB3aWxsIG5vdCBpbnZva2UgdGhlIGNvbnRyb2xsZXIgdW50aWwgYSByZXR1cm5lZAogICAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrIGlzIGludm9rZWQuCiAgICAgIC8vICAgcGFyYW0gYGlkZW50YCAtLS0gQW4gb3B0aW9uYWwgbGFiZWwgd2hpY2ggb3ZlcnJpZGVzIHRoZSBsYWJlbCBwYXJzZWQgZnJvbSB0aGUgY29udHJvbGxlcgogICAgICAvLyAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24sIGlmIGFueS4KICAgICAgdmFyIGluc3RhbmNlLCBtYXRjaCwgY29uc3RydWN0b3IsIGlkZW50aWZpZXI7CiAgICAgIGxhdGVyID0gbGF0ZXIgPT09IHRydWU7CiAgICAgIGlmIChpZGVudCAmJiBpc1N0cmluZyhpZGVudCkpIHsKICAgICAgICBpZGVudGlmaWVyID0gaWRlbnQ7CiAgICAgIH0KCiAgICAgIGlmIChpc1N0cmluZyhleHByZXNzaW9uKSkgewogICAgICAgIG1hdGNoID0gZXhwcmVzc2lvbi5tYXRjaChDTlRSTF9SRUcpLAogICAgICAgIGNvbnN0cnVjdG9yID0gbWF0Y2hbMV0sCiAgICAgICAgaWRlbnRpZmllciA9IGlkZW50aWZpZXIgfHwgbWF0Y2hbM107CiAgICAgICAgZXhwcmVzc2lvbiA9IGNvbnRyb2xsZXJzLmhhc093blByb3BlcnR5KGNvbnN0cnVjdG9yKQogICAgICAgICAgICA/IGNvbnRyb2xsZXJzW2NvbnN0cnVjdG9yXQogICAgICAgICAgICA6IGdldHRlcihsb2NhbHMuJHNjb3BlLCBjb25zdHJ1Y3RvciwgdHJ1ZSkgfHwKICAgICAgICAgICAgICAgIChnbG9iYWxzID8gZ2V0dGVyKCR3aW5kb3csIGNvbnN0cnVjdG9yLCB0cnVlKSA6IHVuZGVmaW5lZCk7CgogICAgICAgIGFzc2VydEFyZ0ZuKGV4cHJlc3Npb24sIGNvbnN0cnVjdG9yLCB0cnVlKTsKICAgICAgfQoKICAgICAgaWYgKGxhdGVyKSB7CiAgICAgICAgLy8gSW5zdGFudGlhdGUgY29udHJvbGxlciBsYXRlcjoKICAgICAgICAvLyBUaGlzIG1hY2hpbmVyeSBpcyB1c2VkIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgb2JqZWN0IGJlZm9yZSBjYWxsaW5nIHRoZQogICAgICAgIC8vIGNvbnRyb2xsZXIncyBjb25zdHJ1Y3RvciBpdHNlbGYuCiAgICAgICAgLy8KICAgICAgICAvLyBUaGlzIGFsbG93cyBwcm9wZXJ0aWVzIHRvIGJlIGFkZGVkIHRvIHRoZSBjb250cm9sbGVyIGJlZm9yZSB0aGUgY29uc3RydWN0b3IgaXMKICAgICAgICAvLyBpbnZva2VkLiBQcmltYXJpbHksIHRoaXMgaXMgdXNlZCBmb3IgaXNvbGF0ZSBzY29wZSBiaW5kaW5ncyBpbiAkY29tcGlsZS4KICAgICAgICAvLwogICAgICAgIC8vIFRoaXMgZmVhdHVyZSBpcyBub3QgaW50ZW5kZWQgZm9yIHVzZSBieSBhcHBsaWNhdGlvbnMsIGFuZCBpcyB0aHVzIG5vdCBkb2N1bWVudGVkCiAgICAgICAgLy8gcHVibGljbHkuCiAgICAgICAgLy8gT2JqZWN0IGNyZWF0aW9uOiBodHRwOi8vanNwZXJmLmNvbS9jcmVhdGUtY29uc3RydWN0b3IvMgogICAgICAgIHZhciBjb250cm9sbGVyUHJvdG90eXBlID0gKGlzQXJyYXkoZXhwcmVzc2lvbikgPwogICAgICAgICAgZXhwcmVzc2lvbltleHByZXNzaW9uLmxlbmd0aCAtIDFdIDogZXhwcmVzc2lvbikucHJvdG90eXBlOwogICAgICAgIGluc3RhbmNlID0gT2JqZWN0LmNyZWF0ZShjb250cm9sbGVyUHJvdG90eXBlKTsKCiAgICAgICAgaWYgKGlkZW50aWZpZXIpIHsKICAgICAgICAgIGFkZElkZW50aWZpZXIobG9jYWxzLCBpZGVudGlmaWVyLCBpbnN0YW5jZSwgY29uc3RydWN0b3IgfHwgZXhwcmVzc2lvbi5uYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAkaW5qZWN0b3IuaW52b2tlKGV4cHJlc3Npb24sIGluc3RhbmNlLCBsb2NhbHMsIGNvbnN0cnVjdG9yKTsKICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgICAgICB9LCB7CiAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2UsCiAgICAgICAgICBpZGVudGlmaWVyOiBpZGVudGlmaWVyCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGluc3RhbmNlID0gJGluamVjdG9yLmluc3RhbnRpYXRlKGV4cHJlc3Npb24sIGxvY2FscywgY29uc3RydWN0b3IpOwoKICAgICAgaWYgKGlkZW50aWZpZXIpIHsKICAgICAgICBhZGRJZGVudGlmaWVyKGxvY2FscywgaWRlbnRpZmllciwgaW5zdGFuY2UsIGNvbnN0cnVjdG9yIHx8IGV4cHJlc3Npb24ubmFtZSk7CiAgICAgIH0KCiAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH07CgogICAgZnVuY3Rpb24gYWRkSWRlbnRpZmllcihsb2NhbHMsIGlkZW50aWZpZXIsIGluc3RhbmNlLCBuYW1lKSB7CiAgICAgIGlmICghKGxvY2FscyAmJiBpc09iamVjdChsb2NhbHMuJHNjb3BlKSkpIHsKICAgICAgICB0aHJvdyBtaW5FcnIoJyRjb250cm9sbGVyJykoJ25vc2NwJywKICAgICAgICAgICJDYW5ub3QgZXhwb3J0IGNvbnRyb2xsZXIgJ3swfScgYXMgJ3sxfSchIE5vICRzY29wZSBvYmplY3QgcHJvdmlkZWQgdmlhIGBsb2NhbHNgLiIsCiAgICAgICAgICBuYW1lLCBpZGVudGlmaWVyKTsKICAgICAgfQoKICAgICAgbG9jYWxzLiRzY29wZVtpZGVudGlmaWVyXSA9IGluc3RhbmNlOwogICAgfQogIH1dOwp9CgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJGRvY3VtZW50CiAqIEByZXF1aXJlcyAkd2luZG93CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBIHtAbGluayBhbmd1bGFyLmVsZW1lbnQgalF1ZXJ5IG9yIGpxTGl0ZX0gd3JhcHBlciBmb3IgdGhlIGJyb3dzZXIncyBgd2luZG93LmRvY3VtZW50YCBvYmplY3QuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG1vZHVsZT0iZG9jdW1lbnRFeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICA8cD4kZG9jdW1lbnQgdGl0bGU6IDxiIG5nLWJpbmQ9InRpdGxlIj48L2I+PC9wPgogICAgICAgICA8cD53aW5kb3cuZG9jdW1lbnQgdGl0bGU6IDxiIG5nLWJpbmQ9IndpbmRvd1RpdGxlIj48L2I+PC9wPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+CiAgICAgICBhbmd1bGFyLm1vZHVsZSgnZG9jdW1lbnRFeGFtcGxlJywgW10pCiAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgJyRkb2N1bWVudCcsIGZ1bmN0aW9uKCRzY29wZSwgJGRvY3VtZW50KSB7CiAgICAgICAgICAgJHNjb3BlLnRpdGxlID0gJGRvY3VtZW50WzBdLnRpdGxlOwogICAgICAgICAgICRzY29wZS53aW5kb3dUaXRsZSA9IGFuZ3VsYXIuZWxlbWVudCh3aW5kb3cuZG9jdW1lbnQpWzBdLnRpdGxlOwogICAgICAgICB9XSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwpmdW5jdGlvbiAkRG9jdW1lbnRQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyR3aW5kb3cnLCBmdW5jdGlvbih3aW5kb3cpIHsKICAgIHJldHVybiBqcUxpdGUod2luZG93LmRvY3VtZW50KTsKICB9XTsKfQoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICRleGNlcHRpb25IYW5kbGVyCiAqIEByZXF1aXJlcyBuZy4kbG9nCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBbnkgdW5jYXVnaHQgZXhjZXB0aW9uIGluIGFuZ3VsYXIgZXhwcmVzc2lvbnMgaXMgZGVsZWdhdGVkIHRvIHRoaXMgc2VydmljZS4KICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gc2ltcGx5IGRlbGVnYXRlcyB0byBgJGxvZy5lcnJvcmAgd2hpY2ggbG9ncyBpdCBpbnRvCiAqIHRoZSBicm93c2VyIGNvbnNvbGUuCiAqCiAqIEluIHVuaXQgdGVzdHMsIGlmIGBhbmd1bGFyLW1vY2tzLmpzYCBpcyBsb2FkZWQsIHRoaXMgc2VydmljZSBpcyBvdmVycmlkZGVuIGJ5CiAqIHtAbGluayBuZ01vY2suJGV4Y2VwdGlvbkhhbmRsZXIgbW9jayAkZXhjZXB0aW9uSGFuZGxlcn0gd2hpY2ggYWlkcyBpbiB0ZXN0aW5nLgogKgogKiAjIyBFeGFtcGxlOgogKgogKiBgYGBqcwogKiAgIGFuZ3VsYXIubW9kdWxlKCdleGNlcHRpb25PdmVycmlkZScsIFtdKS5mYWN0b3J5KCckZXhjZXB0aW9uSGFuZGxlcicsIGZ1bmN0aW9uKCkgewogKiAgICAgcmV0dXJuIGZ1bmN0aW9uKGV4Y2VwdGlvbiwgY2F1c2UpIHsKICogICAgICAgZXhjZXB0aW9uLm1lc3NhZ2UgKz0gJyAoY2F1c2VkIGJ5ICInICsgY2F1c2UgKyAnIiknOwogKiAgICAgICB0aHJvdyBleGNlcHRpb247CiAqICAgICB9OwogKiAgIH0pOwogKiBgYGAKICoKICogVGhpcyBleGFtcGxlIHdpbGwgb3ZlcnJpZGUgdGhlIG5vcm1hbCBhY3Rpb24gb2YgYCRleGNlcHRpb25IYW5kbGVyYCwgdG8gbWFrZSBhbmd1bGFyCiAqIGV4Y2VwdGlvbnMgZmFpbCBoYXJkIHdoZW4gdGhleSBoYXBwZW4sIGluc3RlYWQgb2YganVzdCBsb2dnaW5nIHRvIHRoZSBjb25zb2xlLgogKgogKiA8aHIgLz4KICogTm90ZSwgdGhhdCBjb2RlIGV4ZWN1dGVkIGluIGV2ZW50LWxpc3RlbmVycyAoZXZlbiB0aG9zZSByZWdpc3RlcmVkIHVzaW5nIGpxTGl0ZSdzIGBvbmAvYGJpbmRgCiAqIG1ldGhvZHMpIGRvZXMgbm90IGRlbGVnYXRlIGV4Y2VwdGlvbnMgdG8gdGhlIHtAbGluayBuZy4kZXhjZXB0aW9uSGFuZGxlciAkZXhjZXB0aW9uSGFuZGxlcn0KICogKHVubGVzcyBleGVjdXRlZCBkdXJpbmcgYSBkaWdlc3QpLgogKgogKiBJZiB5b3Ugd2lzaCwgeW91IGNhbiBtYW51YWxseSBkZWxlZ2F0ZSBleGNlcHRpb25zLCBlLmcuCiAqIGB0cnkgeyAuLi4gfSBjYXRjaChlKSB7ICRleGNlcHRpb25IYW5kbGVyKGUpOyB9YAogKgogKiBAcGFyYW0ge0Vycm9yfSBleGNlcHRpb24gRXhjZXB0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXJyb3IuCiAqIEBwYXJhbSB7c3RyaW5nPX0gY2F1c2Ugb3B0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRleHQgaW4gd2hpY2gKICogICAgICAgdGhlIGVycm9yIHdhcyB0aHJvd24uCiAqCiAqLwpmdW5jdGlvbiAkRXhjZXB0aW9uSGFuZGxlclByb3ZpZGVyKCkgewogIHRoaXMuJGdldCA9IFsnJGxvZycsIGZ1bmN0aW9uKCRsb2cpIHsKICAgIHJldHVybiBmdW5jdGlvbihleGNlcHRpb24sIGNhdXNlKSB7CiAgICAgICRsb2cuZXJyb3IuYXBwbHkoJGxvZywgYXJndW1lbnRzKTsKICAgIH07CiAgfV07Cn0KCnZhciBBUFBMSUNBVElPTl9KU09OID0gJ2FwcGxpY2F0aW9uL2pzb24nOwp2YXIgQ09OVEVOVF9UWVBFX0FQUExJQ0FUSU9OX0pTT04gPSB7J0NvbnRlbnQtVHlwZSc6IEFQUExJQ0FUSU9OX0pTT04gKyAnO2NoYXJzZXQ9dXRmLTgnfTsKdmFyIEpTT05fU1RBUlQgPSAvXlxbfF5ceyg/IVx7KS87CnZhciBKU09OX0VORFMgPSB7CiAgJ1snOiAvXSQvLAogICd7JzogL30kLwp9Owp2YXIgSlNPTl9QUk9URUNUSU9OX1BSRUZJWCA9IC9eXClcXVx9Jyw/XG4vOwoKZnVuY3Rpb24gZGVmYXVsdEh0dHBSZXNwb25zZVRyYW5zZm9ybShkYXRhLCBoZWFkZXJzKSB7CiAgaWYgKGlzU3RyaW5nKGRhdGEpKSB7CiAgICAvLyBTdHJpcCBqc29uIHZ1bG5lcmFiaWxpdHkgcHJvdGVjdGlvbiBwcmVmaXggYW5kIHRyaW0gd2hpdGVzcGFjZQogICAgdmFyIHRlbXBEYXRhID0gZGF0YS5yZXBsYWNlKEpTT05fUFJPVEVDVElPTl9QUkVGSVgsICcnKS50cmltKCk7CgogICAgaWYgKHRlbXBEYXRhKSB7CiAgICAgIHZhciBjb250ZW50VHlwZSA9IGhlYWRlcnMoJ0NvbnRlbnQtVHlwZScpOwogICAgICBpZiAoKGNvbnRlbnRUeXBlICYmIChjb250ZW50VHlwZS5pbmRleE9mKEFQUExJQ0FUSU9OX0pTT04pID09PSAwKSkgfHwgaXNKc29uTGlrZSh0ZW1wRGF0YSkpIHsKICAgICAgICBkYXRhID0gZnJvbUpzb24odGVtcERhdGEpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gZGF0YTsKfQoKZnVuY3Rpb24gaXNKc29uTGlrZShzdHIpIHsKICAgIHZhciBqc29uU3RhcnQgPSBzdHIubWF0Y2goSlNPTl9TVEFSVCk7CiAgICByZXR1cm4ganNvblN0YXJ0ICYmIEpTT05fRU5EU1tqc29uU3RhcnRbMF1dLnRlc3Qoc3RyKTsKfQoKLyoqCiAqIFBhcnNlIGhlYWRlcnMgaW50byBrZXkgdmFsdWUgb2JqZWN0CiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBoZWFkZXJzIFJhdyBoZWFkZXJzIGFzIGEgc3RyaW5nCiAqIEByZXR1cm5zIHtPYmplY3R9IFBhcnNlZCBoZWFkZXJzIGFzIGtleSB2YWx1ZSBvYmplY3QKICovCmZ1bmN0aW9uIHBhcnNlSGVhZGVycyhoZWFkZXJzKSB7CiAgdmFyIHBhcnNlZCA9IGNyZWF0ZU1hcCgpLCBrZXksIHZhbCwgaTsKCiAgaWYgKCFoZWFkZXJzKSByZXR1cm4gcGFyc2VkOwoKICBmb3JFYWNoKGhlYWRlcnMuc3BsaXQoJ1xuJyksIGZ1bmN0aW9uKGxpbmUpIHsKICAgIGkgPSBsaW5lLmluZGV4T2YoJzonKTsKICAgIGtleSA9IGxvd2VyY2FzZSh0cmltKGxpbmUuc3Vic3RyKDAsIGkpKSk7CiAgICB2YWwgPSB0cmltKGxpbmUuc3Vic3RyKGkgKyAxKSk7CgogICAgaWYgKGtleSkgewogICAgICBwYXJzZWRba2V5XSA9IHBhcnNlZFtrZXldID8gcGFyc2VkW2tleV0gKyAnLCAnICsgdmFsIDogdmFsOwogICAgfQogIH0pOwoKICByZXR1cm4gcGFyc2VkOwp9CgoKLyoqCiAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHByb3ZpZGVzIGFjY2VzcyB0byBwYXJzZWQgaGVhZGVycy4KICoKICogSGVhZGVycyBhcmUgbGF6eSBwYXJzZWQgd2hlbiBmaXJzdCByZXF1ZXN0ZWQuCiAqIEBzZWUgcGFyc2VIZWFkZXJzCiAqCiAqIEBwYXJhbSB7KHN0cmluZ3xPYmplY3QpfSBoZWFkZXJzIEhlYWRlcnMgdG8gcHJvdmlkZSBhY2Nlc3MgdG8uCiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmc9KX0gUmV0dXJucyBhIGdldHRlciBmdW5jdGlvbiB3aGljaCBpZiBjYWxsZWQgd2l0aDoKICoKICogICAtIGlmIGNhbGxlZCB3aXRoIHNpbmdsZSBhbiBhcmd1bWVudCByZXR1cm5zIGEgc2luZ2xlIGhlYWRlciB2YWx1ZSBvciBudWxsCiAqICAgLSBpZiBjYWxsZWQgd2l0aCBubyBhcmd1bWVudHMgcmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyBhbGwgaGVhZGVycy4KICovCmZ1bmN0aW9uIGhlYWRlcnNHZXR0ZXIoaGVhZGVycykgewogIHZhciBoZWFkZXJzT2JqID0gaXNPYmplY3QoaGVhZGVycykgPyBoZWFkZXJzIDogdW5kZWZpbmVkOwoKICByZXR1cm4gZnVuY3Rpb24obmFtZSkgewogICAgaWYgKCFoZWFkZXJzT2JqKSBoZWFkZXJzT2JqID0gIHBhcnNlSGVhZGVycyhoZWFkZXJzKTsKCiAgICBpZiAobmFtZSkgewogICAgICB2YXIgdmFsdWUgPSBoZWFkZXJzT2JqW2xvd2VyY2FzZShuYW1lKV07CiAgICAgIGlmICh2YWx1ZSA9PT0gdm9pZCAwKSB7CiAgICAgICAgdmFsdWUgPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gaGVhZGVyc09iajsKICB9Owp9CgoKLyoqCiAqIENoYWluIGFsbCBnaXZlbiBmdW5jdGlvbnMKICoKICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciBib3RoIHJlcXVlc3QgYW5kIHJlc3BvbnNlIHRyYW5zZm9ybWluZwogKgogKiBAcGFyYW0geyp9IGRhdGEgRGF0YSB0byB0cmFuc2Zvcm0uCiAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nPSl9IGhlYWRlcnMgSFRUUCBoZWFkZXJzIGdldHRlciBmbi4KICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1cyBIVFRQIHN0YXR1cyBjb2RlIG9mIHRoZSByZXNwb25zZS4KICogQHBhcmFtIHsoRnVuY3Rpb258QXJyYXkuPEZ1bmN0aW9uPil9IGZucyBGdW5jdGlvbiBvciBhbiBhcnJheSBvZiBmdW5jdGlvbnMuCiAqIEByZXR1cm5zIHsqfSBUcmFuc2Zvcm1lZCBkYXRhLgogKi8KZnVuY3Rpb24gdHJhbnNmb3JtRGF0YShkYXRhLCBoZWFkZXJzLCBzdGF0dXMsIGZucykgewogIGlmIChpc0Z1bmN0aW9uKGZucykpCiAgICByZXR1cm4gZm5zKGRhdGEsIGhlYWRlcnMsIHN0YXR1cyk7CgogIGZvckVhY2goZm5zLCBmdW5jdGlvbihmbikgewogICAgZGF0YSA9IGZuKGRhdGEsIGhlYWRlcnMsIHN0YXR1cyk7CiAgfSk7CgogIHJldHVybiBkYXRhOwp9CgoKZnVuY3Rpb24gaXNTdWNjZXNzKHN0YXR1cykgewogIHJldHVybiAyMDAgPD0gc3RhdHVzICYmIHN0YXR1cyA8IDMwMDsKfQoKCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJGh0dHBQcm92aWRlcgogKiBAZGVzY3JpcHRpb24KICogVXNlIGAkaHR0cFByb3ZpZGVyYCB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIHtAbGluayBuZy4kaHR0cCAkaHR0cH0gc2VydmljZS4KICogKi8KZnVuY3Rpb24gJEh0dHBQcm92aWRlcigpIHsKICAvKioKICAgKiBAbmdkb2MgcHJvcGVydHkKICAgKiBAbmFtZSAkaHR0cFByb3ZpZGVyI2RlZmF1bHRzCiAgICogQGRlc2NyaXB0aW9uCiAgICoKICAgKiBPYmplY3QgY29udGFpbmluZyBkZWZhdWx0IHZhbHVlcyBmb3IgYWxsIHtAbGluayBuZy4kaHR0cCAkaHR0cH0gcmVxdWVzdHMuCiAgICoKICAgKiAtICoqYGRlZmF1bHRzLmNhY2hlYCoqIC0ge09iamVjdH0gLSBhbiBvYmplY3QgYnVpbHQgd2l0aCB7QGxpbmsgbmcuJGNhY2hlRmFjdG9yeSBgJGNhY2hlRmFjdG9yeWB9CiAgICogdGhhdCB3aWxsIHByb3ZpZGUgdGhlIGNhY2hlIGZvciBhbGwgcmVxdWVzdHMgd2hvIHNldCB0aGVpciBgY2FjaGVgIHByb3BlcnR5IHRvIGB0cnVlYC4KICAgKiBJZiB5b3Ugc2V0IHRoZSBgZGVmYXVsdC5jYWNoZSA9IGZhbHNlYCB0aGVuIG9ubHkgcmVxdWVzdHMgdGhhdCBzcGVjaWZ5IHRoZWlyIG93biBjdXN0b20KICAgKiBjYWNoZSBvYmplY3Qgd2lsbCBiZSBjYWNoZWQuIFNlZSB7QGxpbmsgJGh0dHAjY2FjaGluZyAkaHR0cCBDYWNoaW5nfSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgKgogICAqIC0gKipgZGVmYXVsdHMueHNyZkNvb2tpZU5hbWVgKiogLSB7c3RyaW5nfSAtIE5hbWUgb2YgY29va2llIGNvbnRhaW5pbmcgdGhlIFhTUkYgdG9rZW4uCiAgICogRGVmYXVsdHMgdmFsdWUgaXMgYCdYU1JGLVRPS0VOJ2AuCiAgICoKICAgKiAtICoqYGRlZmF1bHRzLnhzcmZIZWFkZXJOYW1lYCoqIC0ge3N0cmluZ30gLSBOYW1lIG9mIEhUVFAgaGVhZGVyIHRvIHBvcHVsYXRlIHdpdGggdGhlCiAgICogWFNSRiB0b2tlbi4gRGVmYXVsdHMgdmFsdWUgaXMgYCdYLVhTUkYtVE9LRU4nYC4KICAgKgogICAqIC0gKipgZGVmYXVsdHMuaGVhZGVyc2AqKiAtIHtPYmplY3R9IC0gRGVmYXVsdCBoZWFkZXJzIGZvciBhbGwgJGh0dHAgcmVxdWVzdHMuCiAgICogUmVmZXIgdG8ge0BsaW5rIG5nLiRodHRwI3NldHRpbmctaHR0cC1oZWFkZXJzICRodHRwfSBmb3IgZG9jdW1lbnRhdGlvbiBvbgogICAqIHNldHRpbmcgZGVmYXVsdCBoZWFkZXJzLgogICAqICAgICAtICoqYGRlZmF1bHRzLmhlYWRlcnMuY29tbW9uYCoqCiAgICogICAgIC0gKipgZGVmYXVsdHMuaGVhZGVycy5wb3N0YCoqCiAgICogICAgIC0gKipgZGVmYXVsdHMuaGVhZGVycy5wdXRgKioKICAgKiAgICAgLSAqKmBkZWZhdWx0cy5oZWFkZXJzLnBhdGNoYCoqCiAgICoKICAgKiovCiAgdmFyIGRlZmF1bHRzID0gdGhpcy5kZWZhdWx0cyA9IHsKICAgIC8vIHRyYW5zZm9ybSBpbmNvbWluZyByZXNwb25zZSBkYXRhCiAgICB0cmFuc2Zvcm1SZXNwb25zZTogW2RlZmF1bHRIdHRwUmVzcG9uc2VUcmFuc2Zvcm1dLAoKICAgIC8vIHRyYW5zZm9ybSBvdXRnb2luZyByZXF1ZXN0IGRhdGEKICAgIHRyYW5zZm9ybVJlcXVlc3Q6IFtmdW5jdGlvbihkKSB7CiAgICAgIHJldHVybiBpc09iamVjdChkKSAmJiAhaXNGaWxlKGQpICYmICFpc0Jsb2IoZCkgJiYgIWlzRm9ybURhdGEoZCkgPyB0b0pzb24oZCkgOiBkOwogICAgfV0sCgogICAgLy8gZGVmYXVsdCBoZWFkZXJzCiAgICBoZWFkZXJzOiB7CiAgICAgIGNvbW1vbjogewogICAgICAgICdBY2NlcHQnOiAnYXBwbGljYXRpb24vanNvbiwgdGV4dC9wbGFpbiwgKi8qJwogICAgICB9LAogICAgICBwb3N0OiAgIHNoYWxsb3dDb3B5KENPTlRFTlRfVFlQRV9BUFBMSUNBVElPTl9KU09OKSwKICAgICAgcHV0OiAgICBzaGFsbG93Q29weShDT05URU5UX1RZUEVfQVBQTElDQVRJT05fSlNPTiksCiAgICAgIHBhdGNoOiAgc2hhbGxvd0NvcHkoQ09OVEVOVF9UWVBFX0FQUExJQ0FUSU9OX0pTT04pCiAgICB9LAoKICAgIHhzcmZDb29raWVOYW1lOiAnWFNSRi1UT0tFTicsCiAgICB4c3JmSGVhZGVyTmFtZTogJ1gtWFNSRi1UT0tFTicKICB9OwoKICB2YXIgdXNlQXBwbHlBc3luYyA9IGZhbHNlOwogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkaHR0cFByb3ZpZGVyI3VzZUFwcGx5QXN5bmMKICAgKiBAZGVzY3JpcHRpb24KICAgKgogICAqIENvbmZpZ3VyZSAkaHR0cCBzZXJ2aWNlIHRvIGNvbWJpbmUgcHJvY2Vzc2luZyBvZiBtdWx0aXBsZSBodHRwIHJlc3BvbnNlcyByZWNlaXZlZCBhdCBhcm91bmQKICAgKiB0aGUgc2FtZSB0aW1lIHZpYSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkYXBwbHlBc3luYyAkcm9vdFNjb3BlLiRhcHBseUFzeW5jfS4gVGhpcyBjYW4gcmVzdWx0IGluCiAgICogc2lnbmlmaWNhbnQgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQgZm9yIGJpZ2dlciBhcHBsaWNhdGlvbnMgdGhhdCBtYWtlIG1hbnkgSFRUUCByZXF1ZXN0cwogICAqIGNvbmN1cnJlbnRseSAoY29tbW9uIGR1cmluZyBhcHBsaWNhdGlvbiBib290c3RyYXApLgogICAqCiAgICogRGVmYXVsdHMgdG8gZmFsc2UuIElmIG5vIHZhbHVlIGlzIHNwZWNpZmVkLCByZXR1cm5zIHRoZSBjdXJyZW50IGNvbmZpZ3VyZWQgdmFsdWUuCiAgICoKICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB2YWx1ZSBJZiB0cnVlLCB3aGVuIHJlcXVlc3RzIGFyZSBsb2FkZWQsIHRoZXkgd2lsbCBzY2hlZHVsZSBhIGRlZmVycmVkCiAgICogICAgImFwcGx5IiBvbiB0aGUgbmV4dCB0aWNrLCBnaXZpbmcgdGltZSBmb3Igc3Vic2VxdWVudCByZXF1ZXN0cyBpbiBhIHJvdWdobHkgfjEwbXMgd2luZG93CiAgICogICAgdG8gbG9hZCBhbmQgc2hhcmUgdGhlIHNhbWUgZGlnZXN0IGN5Y2xlLgogICAqCiAgICogQHJldHVybnMge2Jvb2xlYW58T2JqZWN0fSBJZiBhIHZhbHVlIGlzIHNwZWNpZmllZCwgcmV0dXJucyB0aGUgJGh0dHBQcm92aWRlciBmb3IgY2hhaW5pbmcuCiAgICogICAgb3RoZXJ3aXNlLCByZXR1cm5zIHRoZSBjdXJyZW50IGNvbmZpZ3VyZWQgdmFsdWUuCiAgICoqLwogIHRoaXMudXNlQXBwbHlBc3luYyA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSkgewogICAgICB1c2VBcHBseUFzeW5jID0gISF2YWx1ZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICByZXR1cm4gdXNlQXBwbHlBc3luYzsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgcHJvcGVydHkKICAgKiBAbmFtZSAkaHR0cFByb3ZpZGVyI2ludGVyY2VwdG9ycwogICAqIEBkZXNjcmlwdGlvbgogICAqCiAgICogQXJyYXkgY29udGFpbmluZyBzZXJ2aWNlIGZhY3RvcmllcyBmb3IgYWxsIHN5bmNocm9ub3VzIG9yIGFzeW5jaHJvbm91cyB7QGxpbmsgbmcuJGh0dHAgJGh0dHB9CiAgICogcHJlLXByb2Nlc3Npbmcgb2YgcmVxdWVzdCBvciBwb3N0cHJvY2Vzc2luZyBvZiByZXNwb25zZXMuCiAgICoKICAgKiBUaGVzZSBzZXJ2aWNlIGZhY3RvcmllcyBhcmUgb3JkZXJlZCBieSByZXF1ZXN0LCBpLmUuIHRoZXkgYXJlIGFwcGxpZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlCiAgICogYXJyYXksIG9uIHJlcXVlc3QsIGJ1dCByZXZlcnNlIG9yZGVyLCBvbiByZXNwb25zZS4KICAgKgogICAqIHtAbGluayBuZy4kaHR0cCNpbnRlcmNlcHRvcnMgSW50ZXJjZXB0b3JzIGRldGFpbGVkIGluZm99CiAgICoqLwogIHZhciBpbnRlcmNlcHRvckZhY3RvcmllcyA9IHRoaXMuaW50ZXJjZXB0b3JzID0gW107CgogIHRoaXMuJGdldCA9IFsnJGh0dHBCYWNrZW5kJywgJyRicm93c2VyJywgJyRjYWNoZUZhY3RvcnknLCAnJHJvb3RTY29wZScsICckcScsICckaW5qZWN0b3InLAogICAgICBmdW5jdGlvbigkaHR0cEJhY2tlbmQsICRicm93c2VyLCAkY2FjaGVGYWN0b3J5LCAkcm9vdFNjb3BlLCAkcSwgJGluamVjdG9yKSB7CgogICAgdmFyIGRlZmF1bHRDYWNoZSA9ICRjYWNoZUZhY3RvcnkoJyRodHRwJyk7CgogICAgLyoqCiAgICAgKiBJbnRlcmNlcHRvcnMgc3RvcmVkIGluIHJldmVyc2Ugb3JkZXIuIElubmVyIGludGVyY2VwdG9ycyBiZWZvcmUgb3V0ZXIgaW50ZXJjZXB0b3JzLgogICAgICogVGhlIHJldmVyc2FsIGlzIG5lZWRlZCBzbyB0aGF0IHdlIGNhbiBidWlsZCB1cCB0aGUgaW50ZXJjZXB0aW9uIGNoYWluIGFyb3VuZCB0aGUKICAgICAqIHNlcnZlciByZXF1ZXN0LgogICAgICovCiAgICB2YXIgcmV2ZXJzZWRJbnRlcmNlcHRvcnMgPSBbXTsKCiAgICBmb3JFYWNoKGludGVyY2VwdG9yRmFjdG9yaWVzLCBmdW5jdGlvbihpbnRlcmNlcHRvckZhY3RvcnkpIHsKICAgICAgcmV2ZXJzZWRJbnRlcmNlcHRvcnMudW5zaGlmdChpc1N0cmluZyhpbnRlcmNlcHRvckZhY3RvcnkpCiAgICAgICAgICA/ICRpbmplY3Rvci5nZXQoaW50ZXJjZXB0b3JGYWN0b3J5KSA6ICRpbmplY3Rvci5pbnZva2UoaW50ZXJjZXB0b3JGYWN0b3J5KSk7CiAgICB9KTsKCiAgICAvKioKICAgICAqIEBuZ2RvYyBzZXJ2aWNlCiAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICogQG5hbWUgJGh0dHAKICAgICAqIEByZXF1aXJlcyBuZy4kaHR0cEJhY2tlbmQKICAgICAqIEByZXF1aXJlcyAkY2FjaGVGYWN0b3J5CiAgICAgKiBAcmVxdWlyZXMgJHJvb3RTY29wZQogICAgICogQHJlcXVpcmVzICRxCiAgICAgKiBAcmVxdWlyZXMgJGluamVjdG9yCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBUaGUgYCRodHRwYCBzZXJ2aWNlIGlzIGEgY29yZSBBbmd1bGFyIHNlcnZpY2UgdGhhdCBmYWNpbGl0YXRlcyBjb21tdW5pY2F0aW9uIHdpdGggdGhlIHJlbW90ZQogICAgICogSFRUUCBzZXJ2ZXJzIHZpYSB0aGUgYnJvd3NlcidzIFtYTUxIdHRwUmVxdWVzdF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4veG1saHR0cHJlcXVlc3QpCiAgICAgKiBvYmplY3Qgb3IgdmlhIFtKU09OUF0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9KU09OUCkuCiAgICAgKgogICAgICogRm9yIHVuaXQgdGVzdGluZyBhcHBsaWNhdGlvbnMgdGhhdCB1c2UgYCRodHRwYCBzZXJ2aWNlLCBzZWUKICAgICAqIHtAbGluayBuZ01vY2suJGh0dHBCYWNrZW5kICRodHRwQmFja2VuZCBtb2NrfS4KICAgICAqCiAgICAgKiBGb3IgYSBoaWdoZXIgbGV2ZWwgb2YgYWJzdHJhY3Rpb24sIHBsZWFzZSBjaGVjayBvdXQgdGhlIHtAbGluayBuZ1Jlc291cmNlLiRyZXNvdXJjZQogICAgICogJHJlc291cmNlfSBzZXJ2aWNlLgogICAgICoKICAgICAqIFRoZSAkaHR0cCBBUEkgaXMgYmFzZWQgb24gdGhlIHtAbGluayBuZy4kcSBkZWZlcnJlZC9wcm9taXNlIEFQSXN9IGV4cG9zZWQgYnkKICAgICAqIHRoZSAkcSBzZXJ2aWNlLiBXaGlsZSBmb3Igc2ltcGxlIHVzYWdlIHBhdHRlcm5zIHRoaXMgZG9lc24ndCBtYXR0ZXIgbXVjaCwgZm9yIGFkdmFuY2VkIHVzYWdlCiAgICAgKiBpdCBpcyBpbXBvcnRhbnQgdG8gZmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCB0aGVzZSBBUElzIGFuZCB0aGUgZ3VhcmFudGVlcyB0aGV5IHByb3ZpZGUuCiAgICAgKgogICAgICoKICAgICAqICMjIEdlbmVyYWwgdXNhZ2UKICAgICAqIFRoZSBgJGh0dHBgIHNlcnZpY2UgaXMgYSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHNpbmdsZSBhcmd1bWVudCDigD8gYSBjb25maWd1cmF0aW9uIG9iamVjdCDigD8KICAgICAqIHRoYXQgaXMgdXNlZCB0byBnZW5lcmF0ZSBhbiBIVFRQIHJlcXVlc3QgYW5kIHJldHVybnMgIGEge0BsaW5rIG5nLiRxIHByb21pc2V9CiAgICAgKiB3aXRoIHR3byAkaHR0cCBzcGVjaWZpYyBtZXRob2RzOiBgc3VjY2Vzc2AgYW5kIGBlcnJvcmAuCiAgICAgKgogICAgICogYGBganMKICAgICAqICAgLy8gU2ltcGxlIEdFVCByZXF1ZXN0IGV4YW1wbGUgOgogICAgICogICAkaHR0cC5nZXQoJy9zb21lVXJsJykuCiAgICAgKiAgICAgc3VjY2VzcyhmdW5jdGlvbihkYXRhLCBzdGF0dXMsIGhlYWRlcnMsIGNvbmZpZykgewogICAgICogICAgICAgLy8gdGhpcyBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCBhc3luY2hyb25vdXNseQogICAgICogICAgICAgLy8gd2hlbiB0aGUgcmVzcG9uc2UgaXMgYXZhaWxhYmxlCiAgICAgKiAgICAgfSkuCiAgICAgKiAgICAgZXJyb3IoZnVuY3Rpb24oZGF0YSwgc3RhdHVzLCBoZWFkZXJzLCBjb25maWcpIHsKICAgICAqICAgICAgIC8vIGNhbGxlZCBhc3luY2hyb25vdXNseSBpZiBhbiBlcnJvciBvY2N1cnMKICAgICAqICAgICAgIC8vIG9yIHNlcnZlciByZXR1cm5zIHJlc3BvbnNlIHdpdGggYW4gZXJyb3Igc3RhdHVzLgogICAgICogICAgIH0pOwogICAgICogYGBgCiAgICAgKgogICAgICogYGBganMKICAgICAqICAgLy8gU2ltcGxlIFBPU1QgcmVxdWVzdCBleGFtcGxlIChwYXNzaW5nIGRhdGEpIDoKICAgICAqICAgJGh0dHAucG9zdCgnL3NvbWVVcmwnLCB7bXNnOidoZWxsbyB3b3JkISd9KS4KICAgICAqICAgICBzdWNjZXNzKGZ1bmN0aW9uKGRhdGEsIHN0YXR1cywgaGVhZGVycywgY29uZmlnKSB7CiAgICAgKiAgICAgICAvLyB0aGlzIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIGFzeW5jaHJvbm91c2x5CiAgICAgKiAgICAgICAvLyB3aGVuIHRoZSByZXNwb25zZSBpcyBhdmFpbGFibGUKICAgICAqICAgICB9KS4KICAgICAqICAgICBlcnJvcihmdW5jdGlvbihkYXRhLCBzdGF0dXMsIGhlYWRlcnMsIGNvbmZpZykgewogICAgICogICAgICAgLy8gY2FsbGVkIGFzeW5jaHJvbm91c2x5IGlmIGFuIGVycm9yIG9jY3VycwogICAgICogICAgICAgLy8gb3Igc2VydmVyIHJldHVybnMgcmVzcG9uc2Ugd2l0aCBhbiBlcnJvciBzdGF0dXMuCiAgICAgKiAgICAgfSk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKgogICAgICogU2luY2UgdGhlIHJldHVybmVkIHZhbHVlIG9mIGNhbGxpbmcgdGhlICRodHRwIGZ1bmN0aW9uIGlzIGEgYHByb21pc2VgLCB5b3UgY2FuIGFsc28gdXNlCiAgICAgKiB0aGUgYHRoZW5gIG1ldGhvZCB0byByZWdpc3RlciBjYWxsYmFja3MsIGFuZCB0aGVzZSBjYWxsYmFja3Mgd2lsbCByZWNlaXZlIGEgc2luZ2xlIGFyZ3VtZW50IOKAPwogICAgICogYW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcmVzcG9uc2UuIFNlZSB0aGUgQVBJIHNpZ25hdHVyZSBhbmQgdHlwZSBpbmZvIGJlbG93IGZvciBtb3JlCiAgICAgKiBkZXRhaWxzLgogICAgICoKICAgICAqIEEgcmVzcG9uc2Ugc3RhdHVzIGNvZGUgYmV0d2VlbiAyMDAgYW5kIDI5OSBpcyBjb25zaWRlcmVkIGEgc3VjY2VzcyBzdGF0dXMgYW5kCiAgICAgKiB3aWxsIHJlc3VsdCBpbiB0aGUgc3VjY2VzcyBjYWxsYmFjayBiZWluZyBjYWxsZWQuIE5vdGUgdGhhdCBpZiB0aGUgcmVzcG9uc2UgaXMgYSByZWRpcmVjdCwKICAgICAqIFhNTEh0dHBSZXF1ZXN0IHdpbGwgdHJhbnNwYXJlbnRseSBmb2xsb3cgaXQsIG1lYW5pbmcgdGhhdCB0aGUgZXJyb3IgY2FsbGJhY2sgd2lsbCBub3QgYmUKICAgICAqIGNhbGxlZCBmb3Igc3VjaCByZXNwb25zZXMuCiAgICAgKgogICAgICogIyMgV3JpdGluZyBVbml0IFRlc3RzIHRoYXQgdXNlICRodHRwCiAgICAgKiBXaGVuIHVuaXQgdGVzdGluZyAodXNpbmcge0BsaW5rIG5nTW9jayBuZ01vY2t9KSwgaXQgaXMgbmVjZXNzYXJ5IHRvIGNhbGwKICAgICAqIHtAbGluayBuZ01vY2suJGh0dHBCYWNrZW5kI2ZsdXNoICRodHRwQmFja2VuZC5mbHVzaCgpfSB0byBmbHVzaCBlYWNoIHBlbmRpbmcKICAgICAqIHJlcXVlc3QgdXNpbmcgdHJhaW5lZCByZXNwb25zZXMuCiAgICAgKgogICAgICogYGBgCiAgICAgKiAkaHR0cEJhY2tlbmQuZXhwZWN0R0VUKC4uLik7CiAgICAgKiAkaHR0cC5nZXQoLi4uKTsKICAgICAqICRodHRwQmFja2VuZC5mbHVzaCgpOwogICAgICogYGBgCiAgICAgKgogICAgICogIyMgU2hvcnRjdXQgbWV0aG9kcwogICAgICoKICAgICAqIFNob3J0Y3V0IG1ldGhvZHMgYXJlIGFsc28gYXZhaWxhYmxlLiBBbGwgc2hvcnRjdXQgbWV0aG9kcyByZXF1aXJlIHBhc3NpbmcgaW4gdGhlIFVSTCwgYW5kCiAgICAgKiByZXF1ZXN0IGRhdGEgbXVzdCBiZSBwYXNzZWQgaW4gZm9yIFBPU1QvUFVUIHJlcXVlc3RzLgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiAgICRodHRwLmdldCgnL3NvbWVVcmwnKS5zdWNjZXNzKHN1Y2Nlc3NDYWxsYmFjayk7CiAgICAgKiAgICRodHRwLnBvc3QoJy9zb21lVXJsJywgZGF0YSkuc3VjY2VzcyhzdWNjZXNzQ2FsbGJhY2spOwogICAgICogYGBgCiAgICAgKgogICAgICogQ29tcGxldGUgbGlzdCBvZiBzaG9ydGN1dCBtZXRob2RzOgogICAgICoKICAgICAqIC0ge0BsaW5rIG5nLiRodHRwI2dldCAkaHR0cC5nZXR9CiAgICAgKiAtIHtAbGluayBuZy4kaHR0cCNoZWFkICRodHRwLmhlYWR9CiAgICAgKiAtIHtAbGluayBuZy4kaHR0cCNwb3N0ICRodHRwLnBvc3R9CiAgICAgKiAtIHtAbGluayBuZy4kaHR0cCNwdXQgJGh0dHAucHV0fQogICAgICogLSB7QGxpbmsgbmcuJGh0dHAjZGVsZXRlICRodHRwLmRlbGV0ZX0KICAgICAqIC0ge0BsaW5rIG5nLiRodHRwI2pzb25wICRodHRwLmpzb25wfQogICAgICogLSB7QGxpbmsgbmcuJGh0dHAjcGF0Y2ggJGh0dHAucGF0Y2h9CiAgICAgKgogICAgICoKICAgICAqICMjIFNldHRpbmcgSFRUUCBIZWFkZXJzCiAgICAgKgogICAgICogVGhlICRodHRwIHNlcnZpY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGFkZCBjZXJ0YWluIEhUVFAgaGVhZGVycyB0byBhbGwgcmVxdWVzdHMuIFRoZXNlIGRlZmF1bHRzCiAgICAgKiBjYW4gYmUgZnVsbHkgY29uZmlndXJlZCBieSBhY2Nlc3NpbmcgdGhlIGAkaHR0cFByb3ZpZGVyLmRlZmF1bHRzLmhlYWRlcnNgIGNvbmZpZ3VyYXRpb24KICAgICAqIG9iamVjdCwgd2hpY2ggY3VycmVudGx5IGNvbnRhaW5zIHRoaXMgZGVmYXVsdCBjb25maWd1cmF0aW9uOgogICAgICoKICAgICAqIC0gYCRodHRwUHJvdmlkZXIuZGVmYXVsdHMuaGVhZGVycy5jb21tb25gIChoZWFkZXJzIHRoYXQgYXJlIGNvbW1vbiBmb3IgYWxsIHJlcXVlc3RzKToKICAgICAqICAgLSBgQWNjZXB0OiBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqIC8gKmAKICAgICAqIC0gYCRodHRwUHJvdmlkZXIuZGVmYXVsdHMuaGVhZGVycy5wb3N0YDogKGhlYWRlciBkZWZhdWx0cyBmb3IgUE9TVCByZXF1ZXN0cykKICAgICAqICAgLSBgQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uYAogICAgICogLSBgJGh0dHBQcm92aWRlci5kZWZhdWx0cy5oZWFkZXJzLnB1dGAgKGhlYWRlciBkZWZhdWx0cyBmb3IgUFVUIHJlcXVlc3RzKQogICAgICogICAtIGBDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb25gCiAgICAgKgogICAgICogVG8gYWRkIG9yIG92ZXJ3cml0ZSB0aGVzZSBkZWZhdWx0cywgc2ltcGx5IGFkZCBvciByZW1vdmUgYSBwcm9wZXJ0eSBmcm9tIHRoZXNlIGNvbmZpZ3VyYXRpb24KICAgICAqIG9iamVjdHMuIFRvIGFkZCBoZWFkZXJzIGZvciBhbiBIVFRQIG1ldGhvZCBvdGhlciB0aGFuIFBPU1Qgb3IgUFVULCBzaW1wbHkgYWRkIGEgbmV3IG9iamVjdAogICAgICogd2l0aCB0aGUgbG93ZXJjYXNlZCBIVFRQIG1ldGhvZCBuYW1lIGFzIHRoZSBrZXksIGUuZy4KICAgICAqIGAkaHR0cFByb3ZpZGVyLmRlZmF1bHRzLmhlYWRlcnMuZ2V0ID0geyAnTXktSGVhZGVyJyA6ICd2YWx1ZScgfS4KICAgICAqCiAgICAgKiBUaGUgZGVmYXVsdHMgY2FuIGFsc28gYmUgc2V0IGF0IHJ1bnRpbWUgdmlhIHRoZSBgJGh0dHAuZGVmYXVsdHNgIG9iamVjdCBpbiB0aGUgc2FtZQogICAgICogZmFzaGlvbi4gRm9yIGV4YW1wbGU6CiAgICAgKgogICAgICogYGBgCiAgICAgKiBtb2R1bGUucnVuKGZ1bmN0aW9uKCRodHRwKSB7CiAgICAgKiAgICRodHRwLmRlZmF1bHRzLmhlYWRlcnMuY29tbW9uLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgWW1WbGNEcGliMjl3JwogICAgICogfSk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBJbiBhZGRpdGlvbiwgeW91IGNhbiBzdXBwbHkgYSBgaGVhZGVyc2AgcHJvcGVydHkgaW4gdGhlIGNvbmZpZyBvYmplY3QgcGFzc2VkIHdoZW4KICAgICAqIGNhbGxpbmcgYCRodHRwKGNvbmZpZylgLCB3aGljaCBvdmVycmlkZXMgdGhlIGRlZmF1bHRzIHdpdGhvdXQgY2hhbmdpbmcgdGhlbSBnbG9iYWxseS4KICAgICAqCiAgICAgKiBUbyBleHBsaWNpdGx5IHJlbW92ZSBhIGhlYWRlciBhdXRvbWF0aWNhbGx5IGFkZGVkIHZpYSAkaHR0cFByb3ZpZGVyLmRlZmF1bHRzLmhlYWRlcnMgb24gYSBwZXIgcmVxdWVzdCBiYXNpcywKICAgICAqIFVzZSB0aGUgYGhlYWRlcnNgIHByb3BlcnR5LCBzZXR0aW5nIHRoZSBkZXNpcmVkIGhlYWRlciB0byBgdW5kZWZpbmVkYC4gRm9yIGV4YW1wbGU6CiAgICAgKgogICAgICogYGBganMKICAgICAqIHZhciByZXEgPSB7CiAgICAgKiAgbWV0aG9kOiAnUE9TVCcsCiAgICAgKiAgdXJsOiAnaHR0cDovL2V4YW1wbGUuY29tJywKICAgICAqICBoZWFkZXJzOiB7CiAgICAgKiAgICAnQ29udGVudC1UeXBlJzogdW5kZWZpbmVkCiAgICAgKiAgfSwKICAgICAqICBkYXRhOiB7IHRlc3Q6ICd0ZXN0JyB9LAogICAgICogfQogICAgICoKICAgICAqICRodHRwKHJlcSkuc3VjY2VzcyhmdW5jdGlvbigpey4uLn0pLmVycm9yKGZ1bmN0aW9uKCl7Li4ufSk7CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiAjIyBUcmFuc2Zvcm1pbmcgUmVxdWVzdHMgYW5kIFJlc3BvbnNlcwogICAgICoKICAgICAqIEJvdGggcmVxdWVzdHMgYW5kIHJlc3BvbnNlcyBjYW4gYmUgdHJhbnNmb3JtZWQgdXNpbmcgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb25zOiBgdHJhbnNmb3JtUmVxdWVzdGAKICAgICAqIGFuZCBgdHJhbnNmb3JtUmVzcG9uc2VgLiBUaGVzZSBwcm9wZXJ0aWVzIGNhbiBiZSBhIHNpbmdsZSBmdW5jdGlvbiB0aGF0IHJldHVybnMKICAgICAqIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSAoYHtmdW5jdGlvbihkYXRhLCBoZWFkZXJzR2V0dGVyLCBzdGF0dXMpYCkgb3IgYW4gYXJyYXkgb2Ygc3VjaCB0cmFuc2Zvcm1hdGlvbiBmdW5jdGlvbnMsCiAgICAgKiB3aGljaCBhbGxvd3MgeW91IHRvIGBwdXNoYCBvciBgdW5zaGlmdGAgYSBuZXcgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb24gaW50byB0aGUgdHJhbnNmb3JtYXRpb24gY2hhaW4uCiAgICAgKgogICAgICogIyMjIERlZmF1bHQgVHJhbnNmb3JtYXRpb25zCiAgICAgKgogICAgICogVGhlIGAkaHR0cFByb3ZpZGVyYCBwcm92aWRlciBhbmQgYCRodHRwYCBzZXJ2aWNlIGV4cG9zZSBgZGVmYXVsdHMudHJhbnNmb3JtUmVxdWVzdGAgYW5kCiAgICAgKiBgZGVmYXVsdHMudHJhbnNmb3JtUmVzcG9uc2VgIHByb3BlcnRpZXMuIElmIGEgcmVxdWVzdCBkb2VzIG5vdCBwcm92aWRlIGl0cyBvd24gdHJhbnNmb3JtYXRpb25zCiAgICAgKiB0aGVuIHRoZXNlIHdpbGwgYmUgYXBwbGllZC4KICAgICAqCiAgICAgKiBZb3UgY2FuIGF1Z21lbnQgb3IgcmVwbGFjZSB0aGUgZGVmYXVsdCB0cmFuc2Zvcm1hdGlvbnMgYnkgbW9kaWZ5aW5nIHRoZXNlIHByb3BlcnRpZXMgYnkgYWRkaW5nIHRvIG9yCiAgICAgKiByZXBsYWNpbmcgdGhlIGFycmF5LgogICAgICoKICAgICAqIEFuZ3VsYXIgcHJvdmlkZXMgdGhlIGZvbGxvd2luZyBkZWZhdWx0IHRyYW5zZm9ybWF0aW9uczoKICAgICAqCiAgICAgKiBSZXF1ZXN0IHRyYW5zZm9ybWF0aW9ucyAoYCRodHRwUHJvdmlkZXIuZGVmYXVsdHMudHJhbnNmb3JtUmVxdWVzdGAgYW5kIGAkaHR0cC5kZWZhdWx0cy50cmFuc2Zvcm1SZXF1ZXN0YCk6CiAgICAgKgogICAgICogLSBJZiB0aGUgYGRhdGFgIHByb3BlcnR5IG9mIHRoZSByZXF1ZXN0IGNvbmZpZ3VyYXRpb24gb2JqZWN0IGNvbnRhaW5zIGFuIG9iamVjdCwgc2VyaWFsaXplIGl0CiAgICAgKiAgIGludG8gSlNPTiBmb3JtYXQuCiAgICAgKgogICAgICogUmVzcG9uc2UgdHJhbnNmb3JtYXRpb25zIChgJGh0dHBQcm92aWRlci5kZWZhdWx0cy50cmFuc2Zvcm1SZXNwb25zZWAgYW5kIGAkaHR0cC5kZWZhdWx0cy50cmFuc2Zvcm1SZXNwb25zZWApOgogICAgICoKICAgICAqICAtIElmIFhTUkYgcHJlZml4IGlzIGRldGVjdGVkLCBzdHJpcCBpdCAoc2VlIFNlY3VyaXR5IENvbnNpZGVyYXRpb25zIHNlY3Rpb24gYmVsb3cpLgogICAgICogIC0gSWYgSlNPTiByZXNwb25zZSBpcyBkZXRlY3RlZCwgZGVzZXJpYWxpemUgaXQgdXNpbmcgYSBKU09OIHBhcnNlci4KICAgICAqCiAgICAgKgogICAgICogIyMjIE92ZXJyaWRpbmcgdGhlIERlZmF1bHQgVHJhbnNmb3JtYXRpb25zIFBlciBSZXF1ZXN0CiAgICAgKgogICAgICogSWYgeW91IHdpc2ggb3ZlcnJpZGUgdGhlIHJlcXVlc3QvcmVzcG9uc2UgdHJhbnNmb3JtYXRpb25zIG9ubHkgZm9yIGEgc2luZ2xlIHJlcXVlc3QgdGhlbiBwcm92aWRlCiAgICAgKiBgdHJhbnNmb3JtUmVxdWVzdGAgYW5kL29yIGB0cmFuc2Zvcm1SZXNwb25zZWAgcHJvcGVydGllcyBvbiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgcGFzc2VkCiAgICAgKiBpbnRvIGAkaHR0cGAuCiAgICAgKgogICAgICogTm90ZSB0aGF0IGlmIHlvdSBwcm92aWRlIHRoZXNlIHByb3BlcnRpZXMgb24gdGhlIGNvbmZpZyBvYmplY3QgdGhlIGRlZmF1bHQgdHJhbnNmb3JtYXRpb25zIHdpbGwgYmUKICAgICAqIG92ZXJ3cml0dGVuLiBJZiB5b3Ugd2lzaCB0byBhdWdtZW50IHRoZSBkZWZhdWx0IHRyYW5zZm9ybWF0aW9ucyB0aGVuIHlvdSBtdXN0IGluY2x1ZGUgdGhlbSBpbiB5b3VyCiAgICAgKiBsb2NhbCB0cmFuc2Zvcm1hdGlvbiBhcnJheS4KICAgICAqCiAgICAgKiBUaGUgZm9sbG93aW5nIGNvZGUgZGVtb25zdHJhdGVzIGFkZGluZyBhIG5ldyByZXNwb25zZSB0cmFuc2Zvcm1hdGlvbiB0byBiZSBydW4gYWZ0ZXIgdGhlIGRlZmF1bHQgcmVzcG9uc2UKICAgICAqIHRyYW5zZm9ybWF0aW9ucyBoYXZlIGJlZW4gcnVuLgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiBmdW5jdGlvbiBhcHBlbmRUcmFuc2Zvcm0oZGVmYXVsdHMsIHRyYW5zZm9ybSkgewogICAgICoKICAgICAqICAgLy8gV2UgY2FuJ3QgZ3VhcmFudGVlIHRoYXQgdGhlIGRlZmF1bHQgdHJhbnNmb3JtYXRpb24gaXMgYW4gYXJyYXkKICAgICAqICAgZGVmYXVsdHMgPSBhbmd1bGFyLmlzQXJyYXkoZGVmYXVsdHMpID8gZGVmYXVsdHMgOiBbZGVmYXVsdHNdOwogICAgICoKICAgICAqICAgLy8gQXBwZW5kIHRoZSBuZXcgdHJhbnNmb3JtYXRpb24gdG8gdGhlIGRlZmF1bHRzCiAgICAgKiAgIHJldHVybiBkZWZhdWx0cy5jb25jYXQodHJhbnNmb3JtKTsKICAgICAqIH0KICAgICAqCiAgICAgKiAkaHR0cCh7CiAgICAgKiAgIHVybDogJy4uLicsCiAgICAgKiAgIG1ldGhvZDogJ0dFVCcsCiAgICAgKiAgIHRyYW5zZm9ybVJlc3BvbnNlOiBhcHBlbmRUcmFuc2Zvcm0oJGh0dHAuZGVmYXVsdHMudHJhbnNmb3JtUmVzcG9uc2UsIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgKiAgICAgcmV0dXJuIGRvVHJhbnNmb3JtKHZhbHVlKTsKICAgICAqICAgfSkKICAgICAqIH0pOwogICAgICogYGBgCiAgICAgKgogICAgICoKICAgICAqICMjIENhY2hpbmcKICAgICAqCiAgICAgKiBUbyBlbmFibGUgY2FjaGluZywgc2V0IHRoZSByZXF1ZXN0IGNvbmZpZ3VyYXRpb24gYGNhY2hlYCBwcm9wZXJ0eSB0byBgdHJ1ZWAgKHRvIHVzZSBkZWZhdWx0CiAgICAgKiBjYWNoZSkgb3IgdG8gYSBjdXN0b20gY2FjaGUgb2JqZWN0IChidWlsdCB3aXRoIHtAbGluayBuZy4kY2FjaGVGYWN0b3J5IGAkY2FjaGVGYWN0b3J5YH0pLgogICAgICogV2hlbiB0aGUgY2FjaGUgaXMgZW5hYmxlZCwgYCRodHRwYCBzdG9yZXMgdGhlIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlciBpbiB0aGUgc3BlY2lmaWVkCiAgICAgKiBjYWNoZS4gVGhlIG5leHQgdGltZSB0aGUgc2FtZSByZXF1ZXN0IGlzIG1hZGUsIHRoZSByZXNwb25zZSBpcyBzZXJ2ZWQgZnJvbSB0aGUgY2FjaGUgd2l0aG91dAogICAgICogc2VuZGluZyBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlci4KICAgICAqCiAgICAgKiBOb3RlIHRoYXQgZXZlbiBpZiB0aGUgcmVzcG9uc2UgaXMgc2VydmVkIGZyb20gY2FjaGUsIGRlbGl2ZXJ5IG9mIHRoZSBkYXRhIGlzIGFzeW5jaHJvbm91cyBpbgogICAgICogdGhlIHNhbWUgd2F5IHRoYXQgcmVhbCByZXF1ZXN0cyBhcmUuCiAgICAgKgogICAgICogSWYgdGhlcmUgYXJlIG11bHRpcGxlIEdFVCByZXF1ZXN0cyBmb3IgdGhlIHNhbWUgVVJMIHRoYXQgc2hvdWxkIGJlIGNhY2hlZCB1c2luZyB0aGUgc2FtZQogICAgICogY2FjaGUsIGJ1dCB0aGUgY2FjaGUgaXMgbm90IHBvcHVsYXRlZCB5ZXQsIG9ubHkgb25lIHJlcXVlc3QgdG8gdGhlIHNlcnZlciB3aWxsIGJlIG1hZGUgYW5kCiAgICAgKiB0aGUgcmVtYWluaW5nIHJlcXVlc3RzIHdpbGwgYmUgZnVsZmlsbGVkIHVzaW5nIHRoZSByZXNwb25zZSBmcm9tIHRoZSBmaXJzdCByZXF1ZXN0LgogICAgICoKICAgICAqIFlvdSBjYW4gY2hhbmdlIHRoZSBkZWZhdWx0IGNhY2hlIHRvIGEgbmV3IG9iamVjdCAoYnVpbHQgd2l0aAogICAgICoge0BsaW5rIG5nLiRjYWNoZUZhY3RvcnkgYCRjYWNoZUZhY3RvcnlgfSkgYnkgdXBkYXRpbmcgdGhlCiAgICAgKiB7QGxpbmsgbmcuJGh0dHAjZGVmYXVsdHMgYCRodHRwLmRlZmF1bHRzLmNhY2hlYH0gcHJvcGVydHkuIEFsbCByZXF1ZXN0cyB3aG8gc2V0CiAgICAgKiB0aGVpciBgY2FjaGVgIHByb3BlcnR5IHRvIGB0cnVlYCB3aWxsIG5vdyB1c2UgdGhpcyBjYWNoZSBvYmplY3QuCiAgICAgKgogICAgICogSWYgeW91IHNldCB0aGUgZGVmYXVsdCBjYWNoZSB0byBgZmFsc2VgIHRoZW4gb25seSByZXF1ZXN0cyB0aGF0IHNwZWNpZnkgdGhlaXIgb3duIGN1c3RvbQogICAgICogY2FjaGUgb2JqZWN0IHdpbGwgYmUgY2FjaGVkLgogICAgICoKICAgICAqICMjIEludGVyY2VwdG9ycwogICAgICoKICAgICAqIEJlZm9yZSB5b3Ugc3RhcnQgY3JlYXRpbmcgaW50ZXJjZXB0b3JzLCBiZSBzdXJlIHRvIHVuZGVyc3RhbmQgdGhlCiAgICAgKiB7QGxpbmsgbmcuJHEgJHEgYW5kIGRlZmVycmVkL3Byb21pc2UgQVBJc30uCiAgICAgKgogICAgICogRm9yIHB1cnBvc2VzIG9mIGdsb2JhbCBlcnJvciBoYW5kbGluZywgYXV0aGVudGljYXRpb24sIG9yIGFueSBraW5kIG9mIHN5bmNocm9ub3VzIG9yCiAgICAgKiBhc3luY2hyb25vdXMgcHJlLXByb2Nlc3Npbmcgb2YgcmVxdWVzdCBvciBwb3N0cHJvY2Vzc2luZyBvZiByZXNwb25zZXMsIGl0IGlzIGRlc2lyYWJsZSB0byBiZQogICAgICogYWJsZSB0byBpbnRlcmNlcHQgcmVxdWVzdHMgYmVmb3JlIHRoZXkgYXJlIGhhbmRlZCB0byB0aGUgc2VydmVyIGFuZAogICAgICogcmVzcG9uc2VzIGJlZm9yZSB0aGV5IGFyZSBoYW5kZWQgb3ZlciB0byB0aGUgYXBwbGljYXRpb24gY29kZSB0aGF0CiAgICAgKiBpbml0aWF0ZWQgdGhlc2UgcmVxdWVzdHMuIFRoZSBpbnRlcmNlcHRvcnMgbGV2ZXJhZ2UgdGhlIHtAbGluayBuZy4kcQogICAgICogcHJvbWlzZSBBUElzfSB0byBmdWxmaWxsIHRoaXMgbmVlZCBmb3IgYm90aCBzeW5jaHJvbm91cyBhbmQgYXN5bmNocm9ub3VzIHByZS1wcm9jZXNzaW5nLgogICAgICoKICAgICAqIFRoZSBpbnRlcmNlcHRvcnMgYXJlIHNlcnZpY2UgZmFjdG9yaWVzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgYCRodHRwUHJvdmlkZXJgIGJ5CiAgICAgKiBhZGRpbmcgdGhlbSB0byB0aGUgYCRodHRwUHJvdmlkZXIuaW50ZXJjZXB0b3JzYCBhcnJheS4gVGhlIGZhY3RvcnkgaXMgY2FsbGVkIGFuZAogICAgICogaW5qZWN0ZWQgd2l0aCBkZXBlbmRlbmNpZXMgKGlmIHNwZWNpZmllZCkgYW5kIHJldHVybnMgdGhlIGludGVyY2VwdG9yLgogICAgICoKICAgICAqIFRoZXJlIGFyZSB0d28ga2luZHMgb2YgaW50ZXJjZXB0b3JzIChhbmQgdHdvIGtpbmRzIG9mIHJlamVjdGlvbiBpbnRlcmNlcHRvcnMpOgogICAgICoKICAgICAqICAgKiBgcmVxdWVzdGA6IGludGVyY2VwdG9ycyBnZXQgY2FsbGVkIHdpdGggYSBodHRwIGBjb25maWdgIG9iamVjdC4gVGhlIGZ1bmN0aW9uIGlzIGZyZWUgdG8KICAgICAqICAgICBtb2RpZnkgdGhlIGBjb25maWdgIG9iamVjdCBvciBjcmVhdGUgYSBuZXcgb25lLiBUaGUgZnVuY3Rpb24gbmVlZHMgdG8gcmV0dXJuIHRoZSBgY29uZmlnYAogICAgICogICAgIG9iamVjdCBkaXJlY3RseSwgb3IgYSBwcm9taXNlIGNvbnRhaW5pbmcgdGhlIGBjb25maWdgIG9yIGEgbmV3IGBjb25maWdgIG9iamVjdC4KICAgICAqICAgKiBgcmVxdWVzdEVycm9yYDogaW50ZXJjZXB0b3IgZ2V0cyBjYWxsZWQgd2hlbiBhIHByZXZpb3VzIGludGVyY2VwdG9yIHRocmV3IGFuIGVycm9yIG9yCiAgICAgKiAgICAgcmVzb2x2ZWQgd2l0aCBhIHJlamVjdGlvbi4KICAgICAqICAgKiBgcmVzcG9uc2VgOiBpbnRlcmNlcHRvcnMgZ2V0IGNhbGxlZCB3aXRoIGh0dHAgYHJlc3BvbnNlYCBvYmplY3QuIFRoZSBmdW5jdGlvbiBpcyBmcmVlIHRvCiAgICAgKiAgICAgbW9kaWZ5IHRoZSBgcmVzcG9uc2VgIG9iamVjdCBvciBjcmVhdGUgYSBuZXcgb25lLiBUaGUgZnVuY3Rpb24gbmVlZHMgdG8gcmV0dXJuIHRoZSBgcmVzcG9uc2VgCiAgICAgKiAgICAgb2JqZWN0IGRpcmVjdGx5LCBvciBhcyBhIHByb21pc2UgY29udGFpbmluZyB0aGUgYHJlc3BvbnNlYCBvciBhIG5ldyBgcmVzcG9uc2VgIG9iamVjdC4KICAgICAqICAgKiBgcmVzcG9uc2VFcnJvcmA6IGludGVyY2VwdG9yIGdldHMgY2FsbGVkIHdoZW4gYSBwcmV2aW91cyBpbnRlcmNlcHRvciB0aHJldyBhbiBlcnJvciBvcgogICAgICogICAgIHJlc29sdmVkIHdpdGggYSByZWplY3Rpb24uCiAgICAgKgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiAgIC8vIHJlZ2lzdGVyIHRoZSBpbnRlcmNlcHRvciBhcyBhIHNlcnZpY2UKICAgICAqICAgJHByb3ZpZGUuZmFjdG9yeSgnbXlIdHRwSW50ZXJjZXB0b3InLCBmdW5jdGlvbigkcSwgZGVwZW5kZW5jeTEsIGRlcGVuZGVuY3kyKSB7CiAgICAgKiAgICAgcmV0dXJuIHsKICAgICAqICAgICAgIC8vIG9wdGlvbmFsIG1ldGhvZAogICAgICogICAgICAgJ3JlcXVlc3QnOiBmdW5jdGlvbihjb25maWcpIHsKICAgICAqICAgICAgICAgLy8gZG8gc29tZXRoaW5nIG9uIHN1Y2Nlc3MKICAgICAqICAgICAgICAgcmV0dXJuIGNvbmZpZzsKICAgICAqICAgICAgIH0sCiAgICAgKgogICAgICogICAgICAgLy8gb3B0aW9uYWwgbWV0aG9kCiAgICAgKiAgICAgICdyZXF1ZXN0RXJyb3InOiBmdW5jdGlvbihyZWplY3Rpb24pIHsKICAgICAqICAgICAgICAgLy8gZG8gc29tZXRoaW5nIG9uIGVycm9yCiAgICAgKiAgICAgICAgIGlmIChjYW5SZWNvdmVyKHJlamVjdGlvbikpIHsKICAgICAqICAgICAgICAgICByZXR1cm4gcmVzcG9uc2VPck5ld1Byb21pc2UKICAgICAqICAgICAgICAgfQogICAgICogICAgICAgICByZXR1cm4gJHEucmVqZWN0KHJlamVjdGlvbik7CiAgICAgKiAgICAgICB9LAogICAgICoKICAgICAqCiAgICAgKgogICAgICogICAgICAgLy8gb3B0aW9uYWwgbWV0aG9kCiAgICAgKiAgICAgICAncmVzcG9uc2UnOiBmdW5jdGlvbihyZXNwb25zZSkgewogICAgICogICAgICAgICAvLyBkbyBzb21ldGhpbmcgb24gc3VjY2VzcwogICAgICogICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICAgKiAgICAgICB9LAogICAgICoKICAgICAqICAgICAgIC8vIG9wdGlvbmFsIG1ldGhvZAogICAgICogICAgICAncmVzcG9uc2VFcnJvcic6IGZ1bmN0aW9uKHJlamVjdGlvbikgewogICAgICogICAgICAgICAvLyBkbyBzb21ldGhpbmcgb24gZXJyb3IKICAgICAqICAgICAgICAgaWYgKGNhblJlY292ZXIocmVqZWN0aW9uKSkgewogICAgICogICAgICAgICAgIHJldHVybiByZXNwb25zZU9yTmV3UHJvbWlzZQogICAgICogICAgICAgICB9CiAgICAgKiAgICAgICAgIHJldHVybiAkcS5yZWplY3QocmVqZWN0aW9uKTsKICAgICAqICAgICAgIH0KICAgICAqICAgICB9OwogICAgICogICB9KTsKICAgICAqCiAgICAgKiAgICRodHRwUHJvdmlkZXIuaW50ZXJjZXB0b3JzLnB1c2goJ215SHR0cEludGVyY2VwdG9yJyk7CiAgICAgKgogICAgICoKICAgICAqICAgLy8gYWx0ZXJuYXRpdmVseSwgcmVnaXN0ZXIgdGhlIGludGVyY2VwdG9yIHZpYSBhbiBhbm9ueW1vdXMgZmFjdG9yeQogICAgICogICAkaHR0cFByb3ZpZGVyLmludGVyY2VwdG9ycy5wdXNoKGZ1bmN0aW9uKCRxLCBkZXBlbmRlbmN5MSwgZGVwZW5kZW5jeTIpIHsKICAgICAqICAgICByZXR1cm4gewogICAgICogICAgICAncmVxdWVzdCc6IGZ1bmN0aW9uKGNvbmZpZykgewogICAgICogICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZQogICAgICogICAgICAgfSwKICAgICAqCiAgICAgKiAgICAgICAncmVzcG9uc2UnOiBmdW5jdGlvbihyZXNwb25zZSkgewogICAgICogICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZQogICAgICogICAgICAgfQogICAgICogICAgIH07CiAgICAgKiAgIH0pOwogICAgICogYGBgCiAgICAgKgogICAgICogIyMgU2VjdXJpdHkgQ29uc2lkZXJhdGlvbnMKICAgICAqCiAgICAgKiBXaGVuIGRlc2lnbmluZyB3ZWIgYXBwbGljYXRpb25zLCBjb25zaWRlciBzZWN1cml0eSB0aHJlYXRzIGZyb206CiAgICAgKgogICAgICogLSBbSlNPTiB2dWxuZXJhYmlsaXR5XShodHRwOi8vaGFhY2tlZC5jb20vYXJjaGl2ZS8yMDA4LzExLzIwL2FuYXRvbXktb2YtYS1zdWJ0bGUtanNvbi12dWxuZXJhYmlsaXR5LmFzcHgpCiAgICAgKiAtIFtYU1JGXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Nyb3NzLXNpdGVfcmVxdWVzdF9mb3JnZXJ5KQogICAgICoKICAgICAqIEJvdGggc2VydmVyIGFuZCB0aGUgY2xpZW50IG11c3QgY29vcGVyYXRlIGluIG9yZGVyIHRvIGVsaW1pbmF0ZSB0aGVzZSB0aHJlYXRzLiBBbmd1bGFyIGNvbWVzCiAgICAgKiBwcmUtY29uZmlndXJlZCB3aXRoIHN0cmF0ZWdpZXMgdGhhdCBhZGRyZXNzIHRoZXNlIGlzc3VlcywgYnV0IGZvciB0aGlzIHRvIHdvcmsgYmFja2VuZCBzZXJ2ZXIKICAgICAqIGNvb3BlcmF0aW9uIGlzIHJlcXVpcmVkLgogICAgICoKICAgICAqICMjIyBKU09OIFZ1bG5lcmFiaWxpdHkgUHJvdGVjdGlvbgogICAgICoKICAgICAqIEEgW0pTT04gdnVsbmVyYWJpbGl0eV0oaHR0cDovL2hhYWNrZWQuY29tL2FyY2hpdmUvMjAwOC8xMS8yMC9hbmF0b215LW9mLWEtc3VidGxlLWpzb24tdnVsbmVyYWJpbGl0eS5hc3B4KQogICAgICogYWxsb3dzIHRoaXJkIHBhcnR5IHdlYnNpdGUgdG8gdHVybiB5b3VyIEpTT04gcmVzb3VyY2UgVVJMIGludG8KICAgICAqIFtKU09OUF0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9KU09OUCkgcmVxdWVzdCB1bmRlciBzb21lIGNvbmRpdGlvbnMuIFRvCiAgICAgKiBjb3VudGVyIHRoaXMgeW91ciBzZXJ2ZXIgY2FuIHByZWZpeCBhbGwgSlNPTiByZXF1ZXN0cyB3aXRoIGZvbGxvd2luZyBzdHJpbmcgYCIpXX0nLFxuImAuCiAgICAgKiBBbmd1bGFyIHdpbGwgYXV0b21hdGljYWxseSBzdHJpcCB0aGUgcHJlZml4IGJlZm9yZSBwcm9jZXNzaW5nIGl0IGFzIEpTT04uCiAgICAgKgogICAgICogRm9yIGV4YW1wbGUgaWYgeW91ciBzZXJ2ZXIgbmVlZHMgdG8gcmV0dXJuOgogICAgICogYGBganMKICAgICAqIFsnb25lJywndHdvJ10KICAgICAqIGBgYAogICAgICoKICAgICAqIHdoaWNoIGlzIHZ1bG5lcmFibGUgdG8gYXR0YWNrLCB5b3VyIHNlcnZlciBjYW4gcmV0dXJuOgogICAgICogYGBganMKICAgICAqICldfScsCiAgICAgKiBbJ29uZScsJ3R3byddCiAgICAgKiBgYGAKICAgICAqCiAgICAgKiBBbmd1bGFyIHdpbGwgc3RyaXAgdGhlIHByZWZpeCwgYmVmb3JlIHByb2Nlc3NpbmcgdGhlIEpTT04uCiAgICAgKgogICAgICoKICAgICAqICMjIyBDcm9zcyBTaXRlIFJlcXVlc3QgRm9yZ2VyeSAoWFNSRikgUHJvdGVjdGlvbgogICAgICoKICAgICAqIFtYU1JGXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Nyb3NzLXNpdGVfcmVxdWVzdF9mb3JnZXJ5KSBpcyBhIHRlY2huaXF1ZSBieSB3aGljaAogICAgICogYW4gdW5hdXRob3JpemVkIHNpdGUgY2FuIGdhaW4geW91ciB1c2VyJ3MgcHJpdmF0ZSBkYXRhLiBBbmd1bGFyIHByb3ZpZGVzIGEgbWVjaGFuaXNtCiAgICAgKiB0byBjb3VudGVyIFhTUkYuIFdoZW4gcGVyZm9ybWluZyBYSFIgcmVxdWVzdHMsIHRoZSAkaHR0cCBzZXJ2aWNlIHJlYWRzIGEgdG9rZW4gZnJvbSBhIGNvb2tpZQogICAgICogKGJ5IGRlZmF1bHQsIGBYU1JGLVRPS0VOYCkgYW5kIHNldHMgaXQgYXMgYW4gSFRUUCBoZWFkZXIgKGBYLVhTUkYtVE9LRU5gKS4gU2luY2Ugb25seQogICAgICogSmF2YVNjcmlwdCB0aGF0IHJ1bnMgb24geW91ciBkb21haW4gY291bGQgcmVhZCB0aGUgY29va2llLCB5b3VyIHNlcnZlciBjYW4gYmUgYXNzdXJlZCB0aGF0CiAgICAgKiB0aGUgWEhSIGNhbWUgZnJvbSBKYXZhU2NyaXB0IHJ1bm5pbmcgb24geW91ciBkb21haW4uIFRoZSBoZWFkZXIgd2lsbCBub3QgYmUgc2V0IGZvcgogICAgICogY3Jvc3MtZG9tYWluIHJlcXVlc3RzLgogICAgICoKICAgICAqIFRvIHRha2UgYWR2YW50YWdlIG9mIHRoaXMsIHlvdXIgc2VydmVyIG5lZWRzIHRvIHNldCBhIHRva2VuIGluIGEgSmF2YVNjcmlwdCByZWFkYWJsZSBzZXNzaW9uCiAgICAgKiBjb29raWUgY2FsbGVkIGBYU1JGLVRPS0VOYCBvbiB0aGUgZmlyc3QgSFRUUCBHRVQgcmVxdWVzdC4gT24gc3Vic2VxdWVudCBYSFIgcmVxdWVzdHMgdGhlCiAgICAgKiBzZXJ2ZXIgY2FuIHZlcmlmeSB0aGF0IHRoZSBjb29raWUgbWF0Y2hlcyBgWC1YU1JGLVRPS0VOYCBIVFRQIGhlYWRlciwgYW5kIHRoZXJlZm9yZSBiZSBzdXJlCiAgICAgKiB0aGF0IG9ubHkgSmF2YVNjcmlwdCBydW5uaW5nIG9uIHlvdXIgZG9tYWluIGNvdWxkIGhhdmUgc2VudCB0aGUgcmVxdWVzdC4gVGhlIHRva2VuIG11c3QgYmUKICAgICAqIHVuaXF1ZSBmb3IgZWFjaCB1c2VyIGFuZCBtdXN0IGJlIHZlcmlmaWFibGUgYnkgdGhlIHNlcnZlciAodG8gcHJldmVudCB0aGUgSmF2YVNjcmlwdCBmcm9tCiAgICAgKiBtYWtpbmcgdXAgaXRzIG93biB0b2tlbnMpLiBXZSByZWNvbW1lbmQgdGhhdCB0aGUgdG9rZW4gaXMgYSBkaWdlc3Qgb2YgeW91ciBzaXRlJ3MKICAgICAqIGF1dGhlbnRpY2F0aW9uIGNvb2tpZSB3aXRoIGEgW3NhbHRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NhbHRfKGNyeXB0b2dyYXBoeSYjNDE7KQogICAgICogZm9yIGFkZGVkIHNlY3VyaXR5LgogICAgICoKICAgICAqIFRoZSBuYW1lIG9mIHRoZSBoZWFkZXJzIGNhbiBiZSBzcGVjaWZpZWQgdXNpbmcgdGhlIHhzcmZIZWFkZXJOYW1lIGFuZCB4c3JmQ29va2llTmFtZQogICAgICogcHJvcGVydGllcyBvZiBlaXRoZXIgJGh0dHBQcm92aWRlci5kZWZhdWx0cyBhdCBjb25maWctdGltZSwgJGh0dHAuZGVmYXVsdHMgYXQgcnVuLXRpbWUsCiAgICAgKiBvciB0aGUgcGVyLXJlcXVlc3QgY29uZmlnIG9iamVjdC4KICAgICAqCiAgICAgKgogICAgICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyBPYmplY3QgZGVzY3JpYmluZyB0aGUgcmVxdWVzdCB0byBiZSBtYWRlIGFuZCBob3cgaXQgc2hvdWxkIGJlCiAgICAgKiAgICBwcm9jZXNzZWQuIFRoZSBvYmplY3QgaGFzIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogICAgICoKICAgICAqICAgIC0gKiptZXRob2QqKiDigD8gYHtzdHJpbmd9YCDigD8gSFRUUCBtZXRob2QgKGUuZy4gJ0dFVCcsICdQT1NUJywgZXRjKQogICAgICogICAgLSAqKnVybCoqIOKAPyBge3N0cmluZ31gIOKAPyBBYnNvbHV0ZSBvciByZWxhdGl2ZSBVUkwgb2YgdGhlIHJlc291cmNlIHRoYXQgaXMgYmVpbmcgcmVxdWVzdGVkLgogICAgICogICAgLSAqKnBhcmFtcyoqIOKAPyBge09iamVjdC48c3RyaW5nfE9iamVjdD59YCDigD8gTWFwIG9mIHN0cmluZ3Mgb3Igb2JqZWN0cyB3aGljaCB3aWxsIGJlIHR1cm5lZAogICAgICogICAgICB0byBgP2tleTE9dmFsdWUxJmtleTI9dmFsdWUyYCBhZnRlciB0aGUgdXJsLiBJZiB0aGUgdmFsdWUgaXMgbm90IGEgc3RyaW5nLCBpdCB3aWxsIGJlCiAgICAgKiAgICAgIEpTT05pZmllZC4KICAgICAqICAgIC0gKipkYXRhKiog4oA/IGB7c3RyaW5nfE9iamVjdH1gIOKAPyBEYXRhIHRvIGJlIHNlbnQgYXMgdGhlIHJlcXVlc3QgbWVzc2FnZSBkYXRhLgogICAgICogICAgLSAqKmhlYWRlcnMqKiDigD8gYHtPYmplY3R9YCDigD8gTWFwIG9mIHN0cmluZ3Mgb3IgZnVuY3Rpb25zIHdoaWNoIHJldHVybiBzdHJpbmdzIHJlcHJlc2VudGluZwogICAgICogICAgICBIVFRQIGhlYWRlcnMgdG8gc2VuZCB0byB0aGUgc2VydmVyLiBJZiB0aGUgcmV0dXJuIHZhbHVlIG9mIGEgZnVuY3Rpb24gaXMgbnVsbCwgdGhlCiAgICAgKiAgICAgIGhlYWRlciB3aWxsIG5vdCBiZSBzZW50LgogICAgICogICAgLSAqKnhzcmZIZWFkZXJOYW1lKiog4oA/IGB7c3RyaW5nfWAg4oA/IE5hbWUgb2YgSFRUUCBoZWFkZXIgdG8gcG9wdWxhdGUgd2l0aCB0aGUgWFNSRiB0b2tlbi4KICAgICAqICAgIC0gKip4c3JmQ29va2llTmFtZSoqIOKAPyBge3N0cmluZ31gIOKAPyBOYW1lIG9mIGNvb2tpZSBjb250YWluaW5nIHRoZSBYU1JGIHRva2VuLgogICAgICogICAgLSAqKnRyYW5zZm9ybVJlcXVlc3QqKiDigD8KICAgICAqICAgICAgYHtmdW5jdGlvbihkYXRhLCBoZWFkZXJzR2V0dGVyKXxBcnJheS48ZnVuY3Rpb24oZGF0YSwgaGVhZGVyc0dldHRlcik+fWAg4oA/CiAgICAgKiAgICAgIHRyYW5zZm9ybSBmdW5jdGlvbiBvciBhbiBhcnJheSBvZiBzdWNoIGZ1bmN0aW9ucy4gVGhlIHRyYW5zZm9ybSBmdW5jdGlvbiB0YWtlcyB0aGUgaHR0cAogICAgICogICAgICByZXF1ZXN0IGJvZHkgYW5kIGhlYWRlcnMgYW5kIHJldHVybnMgaXRzIHRyYW5zZm9ybWVkICh0eXBpY2FsbHkgc2VyaWFsaXplZCkgdmVyc2lvbi4KICAgICAqICAgICAgU2VlIHtAbGluayBuZy4kaHR0cCNvdmVycmlkaW5nLXRoZS1kZWZhdWx0LXRyYW5zZm9ybWF0aW9ucy1wZXItcmVxdWVzdAogICAgICogICAgICBPdmVycmlkaW5nIHRoZSBEZWZhdWx0IFRyYW5zZm9ybWF0aW9uc30KICAgICAqICAgIC0gKip0cmFuc2Zvcm1SZXNwb25zZSoqIOKAPwogICAgICogICAgICBge2Z1bmN0aW9uKGRhdGEsIGhlYWRlcnNHZXR0ZXIsIHN0YXR1cyl8QXJyYXkuPGZ1bmN0aW9uKGRhdGEsIGhlYWRlcnNHZXR0ZXIsIHN0YXR1cyk+fWAg4oA/CiAgICAgKiAgICAgIHRyYW5zZm9ybSBmdW5jdGlvbiBvciBhbiBhcnJheSBvZiBzdWNoIGZ1bmN0aW9ucy4gVGhlIHRyYW5zZm9ybSBmdW5jdGlvbiB0YWtlcyB0aGUgaHR0cAogICAgICogICAgICByZXNwb25zZSBib2R5LCBoZWFkZXJzIGFuZCBzdGF0dXMgYW5kIHJldHVybnMgaXRzIHRyYW5zZm9ybWVkICh0eXBpY2FsbHkgZGVzZXJpYWxpemVkKSB2ZXJzaW9uLgogICAgICogICAgICBTZWUge0BsaW5rIG5nLiRodHRwI292ZXJyaWRpbmctdGhlLWRlZmF1bHQtdHJhbnNmb3JtYXRpb25zLXBlci1yZXF1ZXN0CiAgICAgKiAgICAgIE92ZXJyaWRpbmcgdGhlIERlZmF1bHQgVHJhbnNmb3JtYXRpb25zfQogICAgICogICAgLSAqKmNhY2hlKiog4oA/IGB7Ym9vbGVhbnxDYWNoZX1gIOKAPyBJZiB0cnVlLCBhIGRlZmF1bHQgJGh0dHAgY2FjaGUgd2lsbCBiZSB1c2VkIHRvIGNhY2hlIHRoZQogICAgICogICAgICBHRVQgcmVxdWVzdCwgb3RoZXJ3aXNlIGlmIGEgY2FjaGUgaW5zdGFuY2UgYnVpbHQgd2l0aAogICAgICogICAgICB7QGxpbmsgbmcuJGNhY2hlRmFjdG9yeSAkY2FjaGVGYWN0b3J5fSwgdGhpcyBjYWNoZSB3aWxsIGJlIHVzZWQgZm9yCiAgICAgKiAgICAgIGNhY2hpbmcuCiAgICAgKiAgICAtICoqdGltZW91dCoqIOKAPyBge251bWJlcnxQcm9taXNlfWAg4oA/IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLCBvciB7QGxpbmsgbmcuJHEgcHJvbWlzZX0KICAgICAqICAgICAgdGhhdCBzaG91bGQgYWJvcnQgdGhlIHJlcXVlc3Qgd2hlbiByZXNvbHZlZC4KICAgICAqICAgIC0gKip3aXRoQ3JlZGVudGlhbHMqKiAtIGB7Ym9vbGVhbn1gIC0gd2hldGhlciB0byBzZXQgdGhlIGB3aXRoQ3JlZGVudGlhbHNgIGZsYWcgb24gdGhlCiAgICAgKiAgICAgIFhIUiBvYmplY3QuIFNlZSBbcmVxdWVzdHMgd2l0aCBjcmVkZW50aWFsc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZG9jcy9XZWIvSFRUUC9BY2Nlc3NfY29udHJvbF9DT1JTI1JlcXVlc3RzX3dpdGhfY3JlZGVudGlhbHMpCiAgICAgKiAgICAgIGZvciBtb3JlIGluZm9ybWF0aW9uLgogICAgICogICAgLSAqKnJlc3BvbnNlVHlwZSoqIC0gYHtzdHJpbmd9YCAtIHNlZQogICAgICogICAgICBbcmVxdWVzdFR5cGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvRE9NL1hNTEh0dHBSZXF1ZXN0I3Jlc3BvbnNlVHlwZSkuCiAgICAgKgogICAgICogQHJldHVybnMge0h0dHBQcm9taXNlfSBSZXR1cm5zIGEge0BsaW5rIG5nLiRxIHByb21pc2V9IG9iamVjdCB3aXRoIHRoZQogICAgICogICBzdGFuZGFyZCBgdGhlbmAgbWV0aG9kIGFuZCB0d28gaHR0cCBzcGVjaWZpYyBtZXRob2RzOiBgc3VjY2Vzc2AgYW5kIGBlcnJvcmAuIFRoZSBgdGhlbmAKICAgICAqICAgbWV0aG9kIHRha2VzIHR3byBhcmd1bWVudHMgYSBzdWNjZXNzIGFuZCBhbiBlcnJvciBjYWxsYmFjayB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aXRoIGEKICAgICAqICAgcmVzcG9uc2Ugb2JqZWN0LiBUaGUgYHN1Y2Nlc3NgIGFuZCBgZXJyb3JgIG1ldGhvZHMgdGFrZSBhIHNpbmdsZSBhcmd1bWVudCAtIGEgZnVuY3Rpb24gdGhhdAogICAgICogICB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHN1Y2NlZWRzIG9yIGZhaWxzIHJlc3BlY3RpdmVseS4gVGhlIGFyZ3VtZW50cyBwYXNzZWQgaW50bwogICAgICogICB0aGVzZSBmdW5jdGlvbnMgYXJlIGRlc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVzcG9uc2Ugb2JqZWN0IHBhc3NlZCBpbnRvIHRoZQogICAgICogICBgdGhlbmAgbWV0aG9kLiBUaGUgcmVzcG9uc2Ugb2JqZWN0IGhhcyB0aGVzZSBwcm9wZXJ0aWVzOgogICAgICoKICAgICAqICAgLSAqKmRhdGEqKiDigD8gYHtzdHJpbmd8T2JqZWN0fWAg4oA/IFRoZSByZXNwb25zZSBib2R5IHRyYW5zZm9ybWVkIHdpdGggdGhlIHRyYW5zZm9ybQogICAgICogICAgIGZ1bmN0aW9ucy4KICAgICAqICAgLSAqKnN0YXR1cyoqIOKAPyBge251bWJlcn1gIOKAPyBIVFRQIHN0YXR1cyBjb2RlIG9mIHRoZSByZXNwb25zZS4KICAgICAqICAgLSAqKmhlYWRlcnMqKiDigD8gYHtmdW5jdGlvbihbaGVhZGVyTmFtZV0pfWAg4oA/IEhlYWRlciBnZXR0ZXIgZnVuY3Rpb24uCiAgICAgKiAgIC0gKipjb25maWcqKiDigD8gYHtPYmplY3R9YCDigD8gVGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRoYXQgd2FzIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHJlcXVlc3QuCiAgICAgKiAgIC0gKipzdGF0dXNUZXh0Kiog4oA/IGB7c3RyaW5nfWAg4oA/IEhUVFAgc3RhdHVzIHRleHQgb2YgdGhlIHJlc3BvbnNlLgogICAgICoKICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPE9iamVjdD59IHBlbmRpbmdSZXF1ZXN0cyBBcnJheSBvZiBjb25maWcgb2JqZWN0cyBmb3IgY3VycmVudGx5IHBlbmRpbmcKICAgICAqICAgcmVxdWVzdHMuIFRoaXMgaXMgcHJpbWFyaWx5IG1lYW50IHRvIGJlIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy4KICAgICAqCiAgICAgKgogICAgICogQGV4YW1wbGUKPGV4YW1wbGUgbW9kdWxlPSJodHRwRXhhbXBsZSI+CjxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogIDxkaXYgbmctY29udHJvbGxlcj0iRmV0Y2hDb250cm9sbGVyIj4KICAgIDxzZWxlY3QgbmctbW9kZWw9Im1ldGhvZCI+CiAgICAgIDxvcHRpb24+R0VUPC9vcHRpb24+CiAgICAgIDxvcHRpb24+SlNPTlA8L29wdGlvbj4KICAgIDwvc2VsZWN0PgogICAgPGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJ1cmwiIHNpemU9IjgwIi8+CiAgICA8YnV0dG9uIGlkPSJmZXRjaGJ0biIgbmctY2xpY2s9ImZldGNoKCkiPmZldGNoPC9idXR0b24+PGJyPgogICAgPGJ1dHRvbiBpZD0ic2FtcGxlZ2V0YnRuIiBuZy1jbGljaz0idXBkYXRlTW9kZWwoJ0dFVCcsICdodHRwLWhlbGxvLmh0bWwnKSI+U2FtcGxlIEdFVDwvYnV0dG9uPgogICAgPGJ1dHRvbiBpZD0ic2FtcGxlanNvbnBidG4iCiAgICAgIG5nLWNsaWNrPSJ1cGRhdGVNb2RlbCgnSlNPTlAnLAogICAgICAgICAgICAgICAgICAgICdodHRwczovL2FuZ3VsYXJqcy5vcmcvZ3JlZXQucGhwP2NhbGxiYWNrPUpTT05fQ0FMTEJBQ0smbmFtZT1TdXBlciUyMEhlcm8nKSI+CiAgICAgIFNhbXBsZSBKU09OUAogICAgPC9idXR0b24+CiAgICA8YnV0dG9uIGlkPSJpbnZhbGlkanNvbnBidG4iCiAgICAgIG5nLWNsaWNrPSJ1cGRhdGVNb2RlbCgnSlNPTlAnLCAnaHR0cHM6Ly9hbmd1bGFyanMub3JnL2RvZXNudGV4aXN0JmNhbGxiYWNrPUpTT05fQ0FMTEJBQ0snKSI+CiAgICAgICAgSW52YWxpZCBKU09OUAogICAgICA8L2J1dHRvbj4KICAgIDxwcmU+aHR0cCBzdGF0dXMgY29kZToge3tzdGF0dXN9fTwvcHJlPgogICAgPHByZT5odHRwIHJlc3BvbnNlIGRhdGE6IHt7ZGF0YX19PC9wcmU+CiAgPC9kaXY+CjwvZmlsZT4KPGZpbGUgbmFtZT0ic2NyaXB0LmpzIj4KICBhbmd1bGFyLm1vZHVsZSgnaHR0cEV4YW1wbGUnLCBbXSkKICAgIC5jb250cm9sbGVyKCdGZXRjaENvbnRyb2xsZXInLCBbJyRzY29wZScsICckaHR0cCcsICckdGVtcGxhdGVDYWNoZScsCiAgICAgIGZ1bmN0aW9uKCRzY29wZSwgJGh0dHAsICR0ZW1wbGF0ZUNhY2hlKSB7CiAgICAgICAgJHNjb3BlLm1ldGhvZCA9ICdHRVQnOwogICAgICAgICRzY29wZS51cmwgPSAnaHR0cC1oZWxsby5odG1sJzsKCiAgICAgICAgJHNjb3BlLmZldGNoID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAkc2NvcGUuY29kZSA9IG51bGw7CiAgICAgICAgICAkc2NvcGUucmVzcG9uc2UgPSBudWxsOwoKICAgICAgICAgICRodHRwKHttZXRob2Q6ICRzY29wZS5tZXRob2QsIHVybDogJHNjb3BlLnVybCwgY2FjaGU6ICR0ZW1wbGF0ZUNhY2hlfSkuCiAgICAgICAgICAgIHN1Y2Nlc3MoZnVuY3Rpb24oZGF0YSwgc3RhdHVzKSB7CiAgICAgICAgICAgICAgJHNjb3BlLnN0YXR1cyA9IHN0YXR1czsKICAgICAgICAgICAgICAkc2NvcGUuZGF0YSA9IGRhdGE7CiAgICAgICAgICAgIH0pLgogICAgICAgICAgICBlcnJvcihmdW5jdGlvbihkYXRhLCBzdGF0dXMpIHsKICAgICAgICAgICAgICAkc2NvcGUuZGF0YSA9IGRhdGEgfHwgIlJlcXVlc3QgZmFpbGVkIjsKICAgICAgICAgICAgICAkc2NvcGUuc3RhdHVzID0gc3RhdHVzOwogICAgICAgICAgfSk7CiAgICAgICAgfTsKCiAgICAgICAgJHNjb3BlLnVwZGF0ZU1vZGVsID0gZnVuY3Rpb24obWV0aG9kLCB1cmwpIHsKICAgICAgICAgICRzY29wZS5tZXRob2QgPSBtZXRob2Q7CiAgICAgICAgICAkc2NvcGUudXJsID0gdXJsOwogICAgICAgIH07CiAgICAgIH1dKTsKPC9maWxlPgo8ZmlsZSBuYW1lPSJodHRwLWhlbGxvLmh0bWwiPgogIEhlbGxvLCAkaHR0cCEKPC9maWxlPgo8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICB2YXIgc3RhdHVzID0gZWxlbWVudChieS5iaW5kaW5nKCdzdGF0dXMnKSk7CiAgdmFyIGRhdGEgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ2RhdGEnKSk7CiAgdmFyIGZldGNoQnRuID0gZWxlbWVudChieS5pZCgnZmV0Y2hidG4nKSk7CiAgdmFyIHNhbXBsZUdldEJ0biA9IGVsZW1lbnQoYnkuaWQoJ3NhbXBsZWdldGJ0bicpKTsKICB2YXIgc2FtcGxlSnNvbnBCdG4gPSBlbGVtZW50KGJ5LmlkKCdzYW1wbGVqc29ucGJ0bicpKTsKICB2YXIgaW52YWxpZEpzb25wQnRuID0gZWxlbWVudChieS5pZCgnaW52YWxpZGpzb25wYnRuJykpOwoKICBpdCgnc2hvdWxkIG1ha2UgYW4geGhyIEdFVCByZXF1ZXN0JywgZnVuY3Rpb24oKSB7CiAgICBzYW1wbGVHZXRCdG4uY2xpY2soKTsKICAgIGZldGNoQnRuLmNsaWNrKCk7CiAgICBleHBlY3Qoc3RhdHVzLmdldFRleHQoKSkudG9NYXRjaCgnMjAwJyk7CiAgICBleHBlY3QoZGF0YS5nZXRUZXh0KCkpLnRvTWF0Y2goL0hlbGxvLCBcJGh0dHAhLyk7CiAgfSk7CgovLyBDb21tZW50ZWQgb3V0IGR1ZSB0byBmbGFrZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2lzc3Vlcy85MTg1Ci8vIGl0KCdzaG91bGQgbWFrZSBhIEpTT05QIHJlcXVlc3QgdG8gYW5ndWxhcmpzLm9yZycsIGZ1bmN0aW9uKCkgewovLyAgIHNhbXBsZUpzb25wQnRuLmNsaWNrKCk7Ci8vICAgZmV0Y2hCdG4uY2xpY2soKTsKLy8gICBleHBlY3Qoc3RhdHVzLmdldFRleHQoKSkudG9NYXRjaCgnMjAwJyk7Ci8vICAgZXhwZWN0KGRhdGEuZ2V0VGV4dCgpKS50b01hdGNoKC9TdXBlciBIZXJvIS8pOwovLyB9KTsKCiAgaXQoJ3Nob3VsZCBtYWtlIEpTT05QIHJlcXVlc3QgdG8gaW52YWxpZCBVUkwgYW5kIGludm9rZSB0aGUgZXJyb3IgaGFuZGxlcicsCiAgICAgIGZ1bmN0aW9uKCkgewogICAgaW52YWxpZEpzb25wQnRuLmNsaWNrKCk7CiAgICBmZXRjaEJ0bi5jbGljaygpOwogICAgZXhwZWN0KHN0YXR1cy5nZXRUZXh0KCkpLnRvTWF0Y2goJzAnKTsKICAgIGV4cGVjdChkYXRhLmdldFRleHQoKSkudG9NYXRjaCgnUmVxdWVzdCBmYWlsZWQnKTsKICB9KTsKPC9maWxlPgo8L2V4YW1wbGU+CiAgICAgKi8KICAgIGZ1bmN0aW9uICRodHRwKHJlcXVlc3RDb25maWcpIHsKCiAgICAgIGlmICghYW5ndWxhci5pc09iamVjdChyZXF1ZXN0Q29uZmlnKSkgewogICAgICAgIHRocm93IG1pbkVycignJGh0dHAnKSgnYmFkcmVxJywgJ0h0dHAgcmVxdWVzdCBjb25maWd1cmF0aW9uIG11c3QgYmUgYW4gb2JqZWN0LiAgUmVjZWl2ZWQ6IHswfScsIHJlcXVlc3RDb25maWcpOwogICAgICB9CgogICAgICB2YXIgY29uZmlnID0gZXh0ZW5kKHsKICAgICAgICBtZXRob2Q6ICdnZXQnLAogICAgICAgIHRyYW5zZm9ybVJlcXVlc3Q6IGRlZmF1bHRzLnRyYW5zZm9ybVJlcXVlc3QsCiAgICAgICAgdHJhbnNmb3JtUmVzcG9uc2U6IGRlZmF1bHRzLnRyYW5zZm9ybVJlc3BvbnNlCiAgICAgIH0sIHJlcXVlc3RDb25maWcpOwoKICAgICAgY29uZmlnLmhlYWRlcnMgPSBtZXJnZUhlYWRlcnMocmVxdWVzdENvbmZpZyk7CiAgICAgIGNvbmZpZy5tZXRob2QgPSB1cHBlcmNhc2UoY29uZmlnLm1ldGhvZCk7CgogICAgICB2YXIgc2VydmVyUmVxdWVzdCA9IGZ1bmN0aW9uKGNvbmZpZykgewogICAgICAgIHZhciBoZWFkZXJzID0gY29uZmlnLmhlYWRlcnM7CiAgICAgICAgdmFyIHJlcURhdGEgPSB0cmFuc2Zvcm1EYXRhKGNvbmZpZy5kYXRhLCBoZWFkZXJzR2V0dGVyKGhlYWRlcnMpLCB1bmRlZmluZWQsIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0KTsKCiAgICAgICAgLy8gc3RyaXAgY29udGVudC10eXBlIGlmIGRhdGEgaXMgdW5kZWZpbmVkCiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHJlcURhdGEpKSB7CiAgICAgICAgICBmb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uKHZhbHVlLCBoZWFkZXIpIHsKICAgICAgICAgICAgaWYgKGxvd2VyY2FzZShoZWFkZXIpID09PSAnY29udGVudC10eXBlJykgewogICAgICAgICAgICAgICAgZGVsZXRlIGhlYWRlcnNbaGVhZGVyXTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNVbmRlZmluZWQoY29uZmlnLndpdGhDcmVkZW50aWFscykgJiYgIWlzVW5kZWZpbmVkKGRlZmF1bHRzLndpdGhDcmVkZW50aWFscykpIHsKICAgICAgICAgIGNvbmZpZy53aXRoQ3JlZGVudGlhbHMgPSBkZWZhdWx0cy53aXRoQ3JlZGVudGlhbHM7CiAgICAgICAgfQoKICAgICAgICAvLyBzZW5kIHJlcXVlc3QKICAgICAgICByZXR1cm4gc2VuZFJlcShjb25maWcsIHJlcURhdGEpLnRoZW4odHJhbnNmb3JtUmVzcG9uc2UsIHRyYW5zZm9ybVJlc3BvbnNlKTsKICAgICAgfTsKCiAgICAgIHZhciBjaGFpbiA9IFtzZXJ2ZXJSZXF1ZXN0LCB1bmRlZmluZWRdOwogICAgICB2YXIgcHJvbWlzZSA9ICRxLndoZW4oY29uZmlnKTsKCiAgICAgIC8vIGFwcGx5IGludGVyY2VwdG9ycwogICAgICBmb3JFYWNoKHJldmVyc2VkSW50ZXJjZXB0b3JzLCBmdW5jdGlvbihpbnRlcmNlcHRvcikgewogICAgICAgIGlmIChpbnRlcmNlcHRvci5yZXF1ZXN0IHx8IGludGVyY2VwdG9yLnJlcXVlc3RFcnJvcikgewogICAgICAgICAgY2hhaW4udW5zaGlmdChpbnRlcmNlcHRvci5yZXF1ZXN0LCBpbnRlcmNlcHRvci5yZXF1ZXN0RXJyb3IpOwogICAgICAgIH0KICAgICAgICBpZiAoaW50ZXJjZXB0b3IucmVzcG9uc2UgfHwgaW50ZXJjZXB0b3IucmVzcG9uc2VFcnJvcikgewogICAgICAgICAgY2hhaW4ucHVzaChpbnRlcmNlcHRvci5yZXNwb25zZSwgaW50ZXJjZXB0b3IucmVzcG9uc2VFcnJvcik7CiAgICAgICAgfQogICAgICB9KTsKCiAgICAgIHdoaWxlIChjaGFpbi5sZW5ndGgpIHsKICAgICAgICB2YXIgdGhlbkZuID0gY2hhaW4uc2hpZnQoKTsKICAgICAgICB2YXIgcmVqZWN0Rm4gPSBjaGFpbi5zaGlmdCgpOwoKICAgICAgICBwcm9taXNlID0gcHJvbWlzZS50aGVuKHRoZW5GbiwgcmVqZWN0Rm4pOwogICAgICB9CgogICAgICBwcm9taXNlLnN1Y2Nlc3MgPSBmdW5jdGlvbihmbikgewogICAgICAgIHByb21pc2UudGhlbihmdW5jdGlvbihyZXNwb25zZSkgewogICAgICAgICAgZm4ocmVzcG9uc2UuZGF0YSwgcmVzcG9uc2Uuc3RhdHVzLCByZXNwb25zZS5oZWFkZXJzLCBjb25maWcpOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBwcm9taXNlOwogICAgICB9OwoKICAgICAgcHJvbWlzZS5lcnJvciA9IGZ1bmN0aW9uKGZuKSB7CiAgICAgICAgcHJvbWlzZS50aGVuKG51bGwsIGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICAgICAgICBmbihyZXNwb25zZS5kYXRhLCByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLmhlYWRlcnMsIGNvbmZpZyk7CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHByb21pc2U7CiAgICAgIH07CgogICAgICByZXR1cm4gcHJvbWlzZTsKCiAgICAgIGZ1bmN0aW9uIHRyYW5zZm9ybVJlc3BvbnNlKHJlc3BvbnNlKSB7CiAgICAgICAgLy8gbWFrZSBhIGNvcHkgc2luY2UgdGhlIHJlc3BvbnNlIG11c3QgYmUgY2FjaGVhYmxlCiAgICAgICAgdmFyIHJlc3AgPSBleHRlbmQoe30sIHJlc3BvbnNlKTsKICAgICAgICBpZiAoIXJlc3BvbnNlLmRhdGEpIHsKICAgICAgICAgIHJlc3AuZGF0YSA9IHJlc3BvbnNlLmRhdGE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3AuZGF0YSA9IHRyYW5zZm9ybURhdGEocmVzcG9uc2UuZGF0YSwgcmVzcG9uc2UuaGVhZGVycywgcmVzcG9uc2Uuc3RhdHVzLCBjb25maWcudHJhbnNmb3JtUmVzcG9uc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGlzU3VjY2VzcyhyZXNwb25zZS5zdGF0dXMpKQogICAgICAgICAgPyByZXNwCiAgICAgICAgICA6ICRxLnJlamVjdChyZXNwKTsKICAgICAgfQoKICAgICAgZnVuY3Rpb24gZXhlY3V0ZUhlYWRlckZucyhoZWFkZXJzKSB7CiAgICAgICAgdmFyIGhlYWRlckNvbnRlbnQsIHByb2Nlc3NlZEhlYWRlcnMgPSB7fTsKCiAgICAgICAgZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbihoZWFkZXJGbiwgaGVhZGVyKSB7CiAgICAgICAgICBpZiAoaXNGdW5jdGlvbihoZWFkZXJGbikpIHsKICAgICAgICAgICAgaGVhZGVyQ29udGVudCA9IGhlYWRlckZuKCk7CiAgICAgICAgICAgIGlmIChoZWFkZXJDb250ZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICBwcm9jZXNzZWRIZWFkZXJzW2hlYWRlcl0gPSBoZWFkZXJDb250ZW50OwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcm9jZXNzZWRIZWFkZXJzW2hlYWRlcl0gPSBoZWFkZXJGbjsKICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIHByb2Nlc3NlZEhlYWRlcnM7CiAgICAgIH0KCiAgICAgIGZ1bmN0aW9uIG1lcmdlSGVhZGVycyhjb25maWcpIHsKICAgICAgICB2YXIgZGVmSGVhZGVycyA9IGRlZmF1bHRzLmhlYWRlcnMsCiAgICAgICAgICAgIHJlcUhlYWRlcnMgPSBleHRlbmQoe30sIGNvbmZpZy5oZWFkZXJzKSwKICAgICAgICAgICAgZGVmSGVhZGVyTmFtZSwgbG93ZXJjYXNlRGVmSGVhZGVyTmFtZSwgcmVxSGVhZGVyTmFtZTsKCiAgICAgICAgZGVmSGVhZGVycyA9IGV4dGVuZCh7fSwgZGVmSGVhZGVycy5jb21tb24sIGRlZkhlYWRlcnNbbG93ZXJjYXNlKGNvbmZpZy5tZXRob2QpXSk7CgogICAgICAgIC8vIHVzaW5nIGZvci1pbiBpbnN0ZWFkIG9mIGZvckVhY2ggdG8gYXZvaWQgdW5lY2Vzc2FyeSBpdGVyYXRpb24gYWZ0ZXIgaGVhZGVyIGhhcyBiZWVuIGZvdW5kCiAgICAgICAgZGVmYXVsdEhlYWRlcnNJdGVyYXRpb246CiAgICAgICAgZm9yIChkZWZIZWFkZXJOYW1lIGluIGRlZkhlYWRlcnMpIHsKICAgICAgICAgIGxvd2VyY2FzZURlZkhlYWRlck5hbWUgPSBsb3dlcmNhc2UoZGVmSGVhZGVyTmFtZSk7CgogICAgICAgICAgZm9yIChyZXFIZWFkZXJOYW1lIGluIHJlcUhlYWRlcnMpIHsKICAgICAgICAgICAgaWYgKGxvd2VyY2FzZShyZXFIZWFkZXJOYW1lKSA9PT0gbG93ZXJjYXNlRGVmSGVhZGVyTmFtZSkgewogICAgICAgICAgICAgIGNvbnRpbnVlIGRlZmF1bHRIZWFkZXJzSXRlcmF0aW9uOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgcmVxSGVhZGVyc1tkZWZIZWFkZXJOYW1lXSA9IGRlZkhlYWRlcnNbZGVmSGVhZGVyTmFtZV07CiAgICAgICAgfQoKICAgICAgICAvLyBleGVjdXRlIGlmIGhlYWRlciB2YWx1ZSBpcyBhIGZ1bmN0aW9uIGZvciBtZXJnZWQgaGVhZGVycwogICAgICAgIHJldHVybiBleGVjdXRlSGVhZGVyRm5zKHJlcUhlYWRlcnMpOwogICAgICB9CiAgICB9CgogICAgJGh0dHAucGVuZGluZ1JlcXVlc3RzID0gW107CgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkaHR0cCNnZXQKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFNob3J0Y3V0IG1ldGhvZCB0byBwZXJmb3JtIGBHRVRgIHJlcXVlc3QuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBSZWxhdGl2ZSBvciBhYnNvbHV0ZSBVUkwgc3BlY2lmeWluZyB0aGUgZGVzdGluYXRpb24gb2YgdGhlIHJlcXVlc3QKICAgICAqIEBwYXJhbSB7T2JqZWN0PX0gY29uZmlnIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb2JqZWN0CiAgICAgKiBAcmV0dXJucyB7SHR0cFByb21pc2V9IEZ1dHVyZSBvYmplY3QKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJGh0dHAjZGVsZXRlCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGN1dCBtZXRob2QgdG8gcGVyZm9ybSBgREVMRVRFYCByZXF1ZXN0LgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgUmVsYXRpdmUgb3IgYWJzb2x1dGUgVVJMIHNwZWNpZnlpbmcgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSByZXF1ZXN0CiAgICAgKiBAcGFyYW0ge09iamVjdD19IGNvbmZpZyBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9iamVjdAogICAgICogQHJldHVybnMge0h0dHBQcm9taXNlfSBGdXR1cmUgb2JqZWN0CiAgICAgKi8KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRodHRwI2hlYWQKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFNob3J0Y3V0IG1ldGhvZCB0byBwZXJmb3JtIGBIRUFEYCByZXF1ZXN0LgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgUmVsYXRpdmUgb3IgYWJzb2x1dGUgVVJMIHNwZWNpZnlpbmcgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSByZXF1ZXN0CiAgICAgKiBAcGFyYW0ge09iamVjdD19IGNvbmZpZyBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9iamVjdAogICAgICogQHJldHVybnMge0h0dHBQcm9taXNlfSBGdXR1cmUgb2JqZWN0CiAgICAgKi8KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRodHRwI2pzb25wCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGN1dCBtZXRob2QgdG8gcGVyZm9ybSBgSlNPTlBgIHJlcXVlc3QuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBSZWxhdGl2ZSBvciBhYnNvbHV0ZSBVUkwgc3BlY2lmeWluZyB0aGUgZGVzdGluYXRpb24gb2YgdGhlIHJlcXVlc3QuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBjYWxsYmFjayBzaG91bGQgYmUgdGhlIHN0cmluZyBgSlNPTl9DQUxMQkFDS2AuCiAgICAgKiBAcGFyYW0ge09iamVjdD19IGNvbmZpZyBPcHRpb25hbCBjb25maWd1cmF0aW9uIG9iamVjdAogICAgICogQHJldHVybnMge0h0dHBQcm9taXNlfSBGdXR1cmUgb2JqZWN0CiAgICAgKi8KICAgIGNyZWF0ZVNob3J0TWV0aG9kcygnZ2V0JywgJ2RlbGV0ZScsICdoZWFkJywgJ2pzb25wJyk7CgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkaHR0cCNwb3N0CiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGN1dCBtZXRob2QgdG8gcGVyZm9ybSBgUE9TVGAgcmVxdWVzdC4KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFJlbGF0aXZlIG9yIGFic29sdXRlIFVSTCBzcGVjaWZ5aW5nIHRoZSBkZXN0aW5hdGlvbiBvZiB0aGUgcmVxdWVzdAogICAgICogQHBhcmFtIHsqfSBkYXRhIFJlcXVlc3QgY29udGVudAogICAgICogQHBhcmFtIHtPYmplY3Q9fSBjb25maWcgT3B0aW9uYWwgY29uZmlndXJhdGlvbiBvYmplY3QKICAgICAqIEByZXR1cm5zIHtIdHRwUHJvbWlzZX0gRnV0dXJlIG9iamVjdAogICAgICovCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkaHR0cCNwdXQKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFNob3J0Y3V0IG1ldGhvZCB0byBwZXJmb3JtIGBQVVRgIHJlcXVlc3QuCiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBSZWxhdGl2ZSBvciBhYnNvbHV0ZSBVUkwgc3BlY2lmeWluZyB0aGUgZGVzdGluYXRpb24gb2YgdGhlIHJlcXVlc3QKICAgICAqIEBwYXJhbSB7Kn0gZGF0YSBSZXF1ZXN0IGNvbnRlbnQKICAgICAqIEBwYXJhbSB7T2JqZWN0PX0gY29uZmlnIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb2JqZWN0CiAgICAgKiBAcmV0dXJucyB7SHR0cFByb21pc2V9IEZ1dHVyZSBvYmplY3QKICAgICAqLwoKICAgICAvKioKICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICogQG5hbWUgJGh0dHAjcGF0Y2gKICAgICAgKgogICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAqIFNob3J0Y3V0IG1ldGhvZCB0byBwZXJmb3JtIGBQQVRDSGAgcmVxdWVzdC4KICAgICAgKgogICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgUmVsYXRpdmUgb3IgYWJzb2x1dGUgVVJMIHNwZWNpZnlpbmcgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSByZXF1ZXN0CiAgICAgICogQHBhcmFtIHsqfSBkYXRhIFJlcXVlc3QgY29udGVudAogICAgICAqIEBwYXJhbSB7T2JqZWN0PX0gY29uZmlnIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb2JqZWN0CiAgICAgICogQHJldHVybnMge0h0dHBQcm9taXNlfSBGdXR1cmUgb2JqZWN0CiAgICAgICovCiAgICBjcmVhdGVTaG9ydE1ldGhvZHNXaXRoRGF0YSgncG9zdCcsICdwdXQnLCAncGF0Y2gnKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQG5nZG9jIHByb3BlcnR5CiAgICAgICAgICogQG5hbWUgJGh0dHAjZGVmYXVsdHMKICAgICAgICAgKgogICAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgICAqIFJ1bnRpbWUgZXF1aXZhbGVudCBvZiB0aGUgYCRodHRwUHJvdmlkZXIuZGVmYXVsdHNgIHByb3BlcnR5LiBBbGxvd3MgY29uZmlndXJhdGlvbiBvZgogICAgICAgICAqIGRlZmF1bHQgaGVhZGVycywgd2l0aENyZWRlbnRpYWxzIGFzIHdlbGwgYXMgcmVxdWVzdCBhbmQgcmVzcG9uc2UgdHJhbnNmb3JtYXRpb25zLgogICAgICAgICAqCiAgICAgICAgICogU2VlICJTZXR0aW5nIEhUVFAgSGVhZGVycyIgYW5kICJUcmFuc2Zvcm1pbmcgUmVxdWVzdHMgYW5kIFJlc3BvbnNlcyIgc2VjdGlvbnMgYWJvdmUuCiAgICAgICAgICovCiAgICAkaHR0cC5kZWZhdWx0cyA9IGRlZmF1bHRzOwoKCiAgICByZXR1cm4gJGh0dHA7CgoKICAgIGZ1bmN0aW9uIGNyZWF0ZVNob3J0TWV0aG9kcyhuYW1lcykgewogICAgICBmb3JFYWNoKGFyZ3VtZW50cywgZnVuY3Rpb24obmFtZSkgewogICAgICAgICRodHRwW25hbWVdID0gZnVuY3Rpb24odXJsLCBjb25maWcpIHsKICAgICAgICAgIHJldHVybiAkaHR0cChleHRlbmQoY29uZmlnIHx8IHt9LCB7CiAgICAgICAgICAgIG1ldGhvZDogbmFtZSwKICAgICAgICAgICAgdXJsOiB1cmwKICAgICAgICAgIH0pKTsKICAgICAgICB9OwogICAgICB9KTsKICAgIH0KCgogICAgZnVuY3Rpb24gY3JlYXRlU2hvcnRNZXRob2RzV2l0aERhdGEobmFtZSkgewogICAgICBmb3JFYWNoKGFyZ3VtZW50cywgZnVuY3Rpb24obmFtZSkgewogICAgICAgICRodHRwW25hbWVdID0gZnVuY3Rpb24odXJsLCBkYXRhLCBjb25maWcpIHsKICAgICAgICAgIHJldHVybiAkaHR0cChleHRlbmQoY29uZmlnIHx8IHt9LCB7CiAgICAgICAgICAgIG1ldGhvZDogbmFtZSwKICAgICAgICAgICAgdXJsOiB1cmwsCiAgICAgICAgICAgIGRhdGE6IGRhdGEKICAgICAgICAgIH0pKTsKICAgICAgICB9OwogICAgICB9KTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBNYWtlcyB0aGUgcmVxdWVzdC4KICAgICAqCiAgICAgKiAhISEgQUNDRVNTRVMgQ0xPU1VSRSBWQVJTOgogICAgICogJGh0dHBCYWNrZW5kLCBkZWZhdWx0cywgJGxvZywgJHJvb3RTY29wZSwgZGVmYXVsdENhY2hlLCAkaHR0cC5wZW5kaW5nUmVxdWVzdHMKICAgICAqLwogICAgZnVuY3Rpb24gc2VuZFJlcShjb25maWcsIHJlcURhdGEpIHsKICAgICAgdmFyIGRlZmVycmVkID0gJHEuZGVmZXIoKSwKICAgICAgICAgIHByb21pc2UgPSBkZWZlcnJlZC5wcm9taXNlLAogICAgICAgICAgY2FjaGUsCiAgICAgICAgICBjYWNoZWRSZXNwLAogICAgICAgICAgcmVxSGVhZGVycyA9IGNvbmZpZy5oZWFkZXJzLAogICAgICAgICAgdXJsID0gYnVpbGRVcmwoY29uZmlnLnVybCwgY29uZmlnLnBhcmFtcyk7CgogICAgICAkaHR0cC5wZW5kaW5nUmVxdWVzdHMucHVzaChjb25maWcpOwogICAgICBwcm9taXNlLnRoZW4ocmVtb3ZlUGVuZGluZ1JlcSwgcmVtb3ZlUGVuZGluZ1JlcSk7CgoKICAgICAgaWYgKChjb25maWcuY2FjaGUgfHwgZGVmYXVsdHMuY2FjaGUpICYmIGNvbmZpZy5jYWNoZSAhPT0gZmFsc2UgJiYKICAgICAgICAgIChjb25maWcubWV0aG9kID09PSAnR0VUJyB8fCBjb25maWcubWV0aG9kID09PSAnSlNPTlAnKSkgewogICAgICAgIGNhY2hlID0gaXNPYmplY3QoY29uZmlnLmNhY2hlKSA/IGNvbmZpZy5jYWNoZQogICAgICAgICAgICAgIDogaXNPYmplY3QoZGVmYXVsdHMuY2FjaGUpID8gZGVmYXVsdHMuY2FjaGUKICAgICAgICAgICAgICA6IGRlZmF1bHRDYWNoZTsKICAgICAgfQoKICAgICAgaWYgKGNhY2hlKSB7CiAgICAgICAgY2FjaGVkUmVzcCA9IGNhY2hlLmdldCh1cmwpOwogICAgICAgIGlmIChpc0RlZmluZWQoY2FjaGVkUmVzcCkpIHsKICAgICAgICAgIGlmIChpc1Byb21pc2VMaWtlKGNhY2hlZFJlc3ApKSB7CiAgICAgICAgICAgIC8vIGNhY2hlZCByZXF1ZXN0IGhhcyBhbHJlYWR5IGJlZW4gc2VudCwgYnV0IHRoZXJlIGlzIG5vIHJlc3BvbnNlIHlldAogICAgICAgICAgICBjYWNoZWRSZXNwLnRoZW4ocmVzb2x2ZVByb21pc2VXaXRoUmVzdWx0LCByZXNvbHZlUHJvbWlzZVdpdGhSZXN1bHQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gc2VydmluZyBmcm9tIGNhY2hlCiAgICAgICAgICAgIGlmIChpc0FycmF5KGNhY2hlZFJlc3ApKSB7CiAgICAgICAgICAgICAgcmVzb2x2ZVByb21pc2UoY2FjaGVkUmVzcFsxXSwgY2FjaGVkUmVzcFswXSwgc2hhbGxvd0NvcHkoY2FjaGVkUmVzcFsyXSksIGNhY2hlZFJlc3BbM10pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlc29sdmVQcm9taXNlKGNhY2hlZFJlc3AsIDIwMCwge30sICdPSycpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIHB1dCB0aGUgcHJvbWlzZSBmb3IgdGhlIG5vbi10cmFuc2Zvcm1lZCByZXNwb25zZSBpbnRvIGNhY2hlIGFzIGEgcGxhY2Vob2xkZXIKICAgICAgICAgIGNhY2hlLnB1dCh1cmwsIHByb21pc2UpOwogICAgICAgIH0KICAgICAgfQoKCiAgICAgIC8vIGlmIHdlIHdvbid0IGhhdmUgdGhlIHJlc3BvbnNlIGluIGNhY2hlLCBzZXQgdGhlIHhzcmYgaGVhZGVycyBhbmQKICAgICAgLy8gc2VuZCB0aGUgcmVxdWVzdCB0byB0aGUgYmFja2VuZAogICAgICBpZiAoaXNVbmRlZmluZWQoY2FjaGVkUmVzcCkpIHsKICAgICAgICB2YXIgeHNyZlZhbHVlID0gdXJsSXNTYW1lT3JpZ2luKGNvbmZpZy51cmwpCiAgICAgICAgICAgID8gJGJyb3dzZXIuY29va2llcygpW2NvbmZpZy54c3JmQ29va2llTmFtZSB8fCBkZWZhdWx0cy54c3JmQ29va2llTmFtZV0KICAgICAgICAgICAgOiB1bmRlZmluZWQ7CiAgICAgICAgaWYgKHhzcmZWYWx1ZSkgewogICAgICAgICAgcmVxSGVhZGVyc1soY29uZmlnLnhzcmZIZWFkZXJOYW1lIHx8IGRlZmF1bHRzLnhzcmZIZWFkZXJOYW1lKV0gPSB4c3JmVmFsdWU7CiAgICAgICAgfQoKICAgICAgICAkaHR0cEJhY2tlbmQoY29uZmlnLm1ldGhvZCwgdXJsLCByZXFEYXRhLCBkb25lLCByZXFIZWFkZXJzLCBjb25maWcudGltZW91dCwKICAgICAgICAgICAgY29uZmlnLndpdGhDcmVkZW50aWFscywgY29uZmlnLnJlc3BvbnNlVHlwZSk7CiAgICAgIH0KCiAgICAgIHJldHVybiBwcm9taXNlOwoKCiAgICAgIC8qKgogICAgICAgKiBDYWxsYmFjayByZWdpc3RlcmVkIHRvICRodHRwQmFja2VuZCgpOgogICAgICAgKiAgLSBjYWNoZXMgdGhlIHJlc3BvbnNlIGlmIGRlc2lyZWQKICAgICAgICogIC0gcmVzb2x2ZXMgdGhlIHJhdyAkaHR0cCBwcm9taXNlCiAgICAgICAqICAtIGNhbGxzICRhcHBseQogICAgICAgKi8KICAgICAgZnVuY3Rpb24gZG9uZShzdGF0dXMsIHJlc3BvbnNlLCBoZWFkZXJzU3RyaW5nLCBzdGF0dXNUZXh0KSB7CiAgICAgICAgaWYgKGNhY2hlKSB7CiAgICAgICAgICBpZiAoaXNTdWNjZXNzKHN0YXR1cykpIHsKICAgICAgICAgICAgY2FjaGUucHV0KHVybCwgW3N0YXR1cywgcmVzcG9uc2UsIHBhcnNlSGVhZGVycyhoZWFkZXJzU3RyaW5nKSwgc3RhdHVzVGV4dF0pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIHByb21pc2UgZnJvbSB0aGUgY2FjaGUKICAgICAgICAgICAgY2FjaGUucmVtb3ZlKHVybCk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiByZXNvbHZlSHR0cFByb21pc2UoKSB7CiAgICAgICAgICByZXNvbHZlUHJvbWlzZShyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzU3RyaW5nLCBzdGF0dXNUZXh0KTsKICAgICAgICB9CgogICAgICAgIGlmICh1c2VBcHBseUFzeW5jKSB7CiAgICAgICAgICAkcm9vdFNjb3BlLiRhcHBseUFzeW5jKHJlc29sdmVIdHRwUHJvbWlzZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc29sdmVIdHRwUHJvbWlzZSgpOwogICAgICAgICAgaWYgKCEkcm9vdFNjb3BlLiQkcGhhc2UpICRyb290U2NvcGUuJGFwcGx5KCk7CiAgICAgICAgfQogICAgICB9CgoKICAgICAgLyoqCiAgICAgICAqIFJlc29sdmVzIHRoZSByYXcgJGh0dHAgcHJvbWlzZS4KICAgICAgICovCiAgICAgIGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMsIHN0YXR1c1RleHQpIHsKICAgICAgICAvLyBub3JtYWxpemUgaW50ZXJuYWwgc3RhdHVzZXMgdG8gMAogICAgICAgIHN0YXR1cyA9IE1hdGgubWF4KHN0YXR1cywgMCk7CgogICAgICAgIChpc1N1Y2Nlc3Moc3RhdHVzKSA/IGRlZmVycmVkLnJlc29sdmUgOiBkZWZlcnJlZC5yZWplY3QpKHsKICAgICAgICAgIGRhdGE6IHJlc3BvbnNlLAogICAgICAgICAgc3RhdHVzOiBzdGF0dXMsCiAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzR2V0dGVyKGhlYWRlcnMpLAogICAgICAgICAgY29uZmlnOiBjb25maWcsCiAgICAgICAgICBzdGF0dXNUZXh0OiBzdGF0dXNUZXh0CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlV2l0aFJlc3VsdChyZXN1bHQpIHsKICAgICAgICByZXNvbHZlUHJvbWlzZShyZXN1bHQuZGF0YSwgcmVzdWx0LnN0YXR1cywgc2hhbGxvd0NvcHkocmVzdWx0LmhlYWRlcnMoKSksIHJlc3VsdC5zdGF0dXNUZXh0KTsKICAgICAgfQoKICAgICAgZnVuY3Rpb24gcmVtb3ZlUGVuZGluZ1JlcSgpIHsKICAgICAgICB2YXIgaWR4ID0gJGh0dHAucGVuZGluZ1JlcXVlc3RzLmluZGV4T2YoY29uZmlnKTsKICAgICAgICBpZiAoaWR4ICE9PSAtMSkgJGh0dHAucGVuZGluZ1JlcXVlc3RzLnNwbGljZShpZHgsIDEpOwogICAgICB9CiAgICB9CgoKICAgIGZ1bmN0aW9uIGJ1aWxkVXJsKHVybCwgcGFyYW1zKSB7CiAgICAgIGlmICghcGFyYW1zKSByZXR1cm4gdXJsOwogICAgICB2YXIgcGFydHMgPSBbXTsKICAgICAgZm9yRWFjaFNvcnRlZChwYXJhbXMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgaXNVbmRlZmluZWQodmFsdWUpKSByZXR1cm47CiAgICAgICAgaWYgKCFpc0FycmF5KHZhbHVlKSkgdmFsdWUgPSBbdmFsdWVdOwoKICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbih2KSB7CiAgICAgICAgICBpZiAoaXNPYmplY3QodikpIHsKICAgICAgICAgICAgaWYgKGlzRGF0ZSh2KSkgewogICAgICAgICAgICAgIHYgPSB2LnRvSVNPU3RyaW5nKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgdiA9IHRvSnNvbih2KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcGFydHMucHVzaChlbmNvZGVVcmlRdWVyeShrZXkpICsgJz0nICsKICAgICAgICAgICAgICAgICAgICAgZW5jb2RlVXJpUXVlcnkodikpOwogICAgICAgIH0pOwogICAgICB9KTsKICAgICAgaWYgKHBhcnRzLmxlbmd0aCA+IDApIHsKICAgICAgICB1cmwgKz0gKCh1cmwuaW5kZXhPZignPycpID09IC0xKSA/ICc/JyA6ICcmJykgKyBwYXJ0cy5qb2luKCcmJyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVybDsKICAgIH0KICB9XTsKfQoKZnVuY3Rpb24gY3JlYXRlWGhyKCkgewogICAgcmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTsKfQoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICRodHRwQmFja2VuZAogKiBAcmVxdWlyZXMgJHdpbmRvdwogKiBAcmVxdWlyZXMgJGRvY3VtZW50CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBIVFRQIGJhY2tlbmQgdXNlZCBieSB0aGUge0BsaW5rIG5nLiRodHRwIHNlcnZpY2V9IHRoYXQgZGVsZWdhdGVzIHRvCiAqIFhNTEh0dHBSZXF1ZXN0IG9iamVjdCBvciBKU09OUCBhbmQgZGVhbHMgd2l0aCBicm93c2VyIGluY29tcGF0aWJpbGl0aWVzLgogKgogKiBZb3Ugc2hvdWxkIG5ldmVyIG5lZWQgdG8gdXNlIHRoaXMgc2VydmljZSBkaXJlY3RseSwgaW5zdGVhZCB1c2UgdGhlIGhpZ2hlci1sZXZlbCBhYnN0cmFjdGlvbnM6CiAqIHtAbGluayBuZy4kaHR0cCAkaHR0cH0gb3Ige0BsaW5rIG5nUmVzb3VyY2UuJHJlc291cmNlICRyZXNvdXJjZX0uCiAqCiAqIER1cmluZyB0ZXN0aW5nIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgc3dhcHBlZCB3aXRoIHtAbGluayBuZ01vY2suJGh0dHBCYWNrZW5kIG1vY2sKICogJGh0dHBCYWNrZW5kfSB3aGljaCBjYW4gYmUgdHJhaW5lZCB3aXRoIHJlc3BvbnNlcy4KICovCmZ1bmN0aW9uICRIdHRwQmFja2VuZFByb3ZpZGVyKCkgewogIHRoaXMuJGdldCA9IFsnJGJyb3dzZXInLCAnJHdpbmRvdycsICckZG9jdW1lbnQnLCBmdW5jdGlvbigkYnJvd3NlciwgJHdpbmRvdywgJGRvY3VtZW50KSB7CiAgICByZXR1cm4gY3JlYXRlSHR0cEJhY2tlbmQoJGJyb3dzZXIsIGNyZWF0ZVhociwgJGJyb3dzZXIuZGVmZXIsICR3aW5kb3cuYW5ndWxhci5jYWxsYmFja3MsICRkb2N1bWVudFswXSk7CiAgfV07Cn0KCmZ1bmN0aW9uIGNyZWF0ZUh0dHBCYWNrZW5kKCRicm93c2VyLCBjcmVhdGVYaHIsICRicm93c2VyRGVmZXIsIGNhbGxiYWNrcywgcmF3RG9jdW1lbnQpIHsKICAvLyBUT0RPKHZvanRhKTogZml4IHRoZSBzaWduYXR1cmUKICByZXR1cm4gZnVuY3Rpb24obWV0aG9kLCB1cmwsIHBvc3QsIGNhbGxiYWNrLCBoZWFkZXJzLCB0aW1lb3V0LCB3aXRoQ3JlZGVudGlhbHMsIHJlc3BvbnNlVHlwZSkgewogICAgJGJyb3dzZXIuJCRpbmNPdXRzdGFuZGluZ1JlcXVlc3RDb3VudCgpOwogICAgdXJsID0gdXJsIHx8ICRicm93c2VyLnVybCgpOwoKICAgIGlmIChsb3dlcmNhc2UobWV0aG9kKSA9PSAnanNvbnAnKSB7CiAgICAgIHZhciBjYWxsYmFja0lkID0gJ18nICsgKGNhbGxiYWNrcy5jb3VudGVyKyspLnRvU3RyaW5nKDM2KTsKICAgICAgY2FsbGJhY2tzW2NhbGxiYWNrSWRdID0gZnVuY3Rpb24oZGF0YSkgewogICAgICAgIGNhbGxiYWNrc1tjYWxsYmFja0lkXS5kYXRhID0gZGF0YTsKICAgICAgICBjYWxsYmFja3NbY2FsbGJhY2tJZF0uY2FsbGVkID0gdHJ1ZTsKICAgICAgfTsKCiAgICAgIHZhciBqc29ucERvbmUgPSBqc29ucFJlcSh1cmwucmVwbGFjZSgnSlNPTl9DQUxMQkFDSycsICdhbmd1bGFyLmNhbGxiYWNrcy4nICsgY2FsbGJhY2tJZCksCiAgICAgICAgICBjYWxsYmFja0lkLCBmdW5jdGlvbihzdGF0dXMsIHRleHQpIHsKICAgICAgICBjb21wbGV0ZVJlcXVlc3QoY2FsbGJhY2ssIHN0YXR1cywgY2FsbGJhY2tzW2NhbGxiYWNrSWRdLmRhdGEsICIiLCB0ZXh0KTsKICAgICAgICBjYWxsYmFja3NbY2FsbGJhY2tJZF0gPSBub29wOwogICAgICB9KTsKICAgIH0gZWxzZSB7CgogICAgICB2YXIgeGhyID0gY3JlYXRlWGhyKCk7CgogICAgICB4aHIub3BlbihtZXRob2QsIHVybCwgdHJ1ZSk7CiAgICAgIGZvckVhY2goaGVhZGVycywgZnVuY3Rpb24odmFsdWUsIGtleSkgewogICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7CiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfSk7CgogICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24gcmVxdWVzdExvYWRlZCgpIHsKICAgICAgICB2YXIgc3RhdHVzVGV4dCA9IHhoci5zdGF0dXNUZXh0IHx8ICcnOwoKICAgICAgICAvLyByZXNwb25zZVRleHQgaXMgdGhlIG9sZC1zY2hvb2wgd2F5IG9mIHJldHJpZXZpbmcgcmVzcG9uc2UgKHN1cHBvcnRlZCBieSBJRTggJiA5KQogICAgICAgIC8vIHJlc3BvbnNlL3Jlc3BvbnNlVHlwZSBwcm9wZXJ0aWVzIHdlcmUgaW50cm9kdWNlZCBpbiBYSFIgTGV2ZWwyIHNwZWMgKHN1cHBvcnRlZCBieSBJRTEwKQogICAgICAgIHZhciByZXNwb25zZSA9ICgncmVzcG9uc2UnIGluIHhocikgPyB4aHIucmVzcG9uc2UgOiB4aHIucmVzcG9uc2VUZXh0OwoKICAgICAgICAvLyBub3JtYWxpemUgSUU5IGJ1ZyAoaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTQ1MCkKICAgICAgICB2YXIgc3RhdHVzID0geGhyLnN0YXR1cyA9PT0gMTIyMyA/IDIwNCA6IHhoci5zdGF0dXM7CgogICAgICAgIC8vIGZpeCBzdGF0dXMgY29kZSB3aGVuIGl0IGlzIDAgKDAgc3RhdHVzIGlzIHVuZG9jdW1lbnRlZCkuCiAgICAgICAgLy8gT2NjdXJzIHdoZW4gYWNjZXNzaW5nIGZpbGUgcmVzb3VyY2VzIG9yIG9uIEFuZHJvaWQgNC4xIHN0b2NrIGJyb3dzZXIKICAgICAgICAvLyB3aGlsZSByZXRyaWV2aW5nIGZpbGVzIGZyb20gYXBwbGljYXRpb24gY2FjaGUuCiAgICAgICAgaWYgKHN0YXR1cyA9PT0gMCkgewogICAgICAgICAgc3RhdHVzID0gcmVzcG9uc2UgPyAyMDAgOiB1cmxSZXNvbHZlKHVybCkucHJvdG9jb2wgPT0gJ2ZpbGUnID8gNDA0IDogMDsKICAgICAgICB9CgogICAgICAgIGNvbXBsZXRlUmVxdWVzdChjYWxsYmFjaywKICAgICAgICAgICAgc3RhdHVzLAogICAgICAgICAgICByZXNwb25zZSwKICAgICAgICAgICAgeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLAogICAgICAgICAgICBzdGF0dXNUZXh0KTsKICAgICAgfTsKCiAgICAgIHZhciByZXF1ZXN0RXJyb3IgPSBmdW5jdGlvbigpIHsKICAgICAgICAvLyBUaGUgcmVzcG9uc2UgaXMgYWx3YXlzIGVtcHR5CiAgICAgICAgLy8gU2VlIGh0dHBzOi8veGhyLnNwZWMud2hhdHdnLm9yZy8jcmVxdWVzdC1lcnJvci1zdGVwcyBhbmQgaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtbmV0d29yay1lcnJvcgogICAgICAgIGNvbXBsZXRlUmVxdWVzdChjYWxsYmFjaywgLTEsIG51bGwsIG51bGwsICcnKTsKICAgICAgfTsKCiAgICAgIHhoci5vbmVycm9yID0gcmVxdWVzdEVycm9yOwogICAgICB4aHIub25hYm9ydCA9IHJlcXVlc3RFcnJvcjsKCiAgICAgIGlmICh3aXRoQ3JlZGVudGlhbHMpIHsKICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTsKICAgICAgfQoKICAgICAgaWYgKHJlc3BvbnNlVHlwZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gcmVzcG9uc2VUeXBlOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIC8vIFdlYktpdCBhZGRlZCBzdXBwb3J0IGZvciB0aGUganNvbiByZXNwb25zZVR5cGUgdmFsdWUgb24gMDkvMDMvMjAxMwogICAgICAgICAgLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTczNjQ4LiBWZXJzaW9ucyBvZiBTYWZhcmkgcHJpb3IgdG8gNyBhcmUKICAgICAgICAgIC8vIGtub3duIHRvIHRocm93IHdoZW4gc2V0dGluZyB0aGUgdmFsdWUgImpzb24iIGFzIHRoZSByZXNwb25zZSB0eXBlLiBPdGhlciBvbGRlcgogICAgICAgICAgLy8gYnJvd3NlcnMgaW1wbGVtZW50aW5nIHRoZSByZXNwb25zZVR5cGUKICAgICAgICAgIC8vCiAgICAgICAgICAvLyBUaGUganNvbiByZXNwb25zZSB0eXBlIGNhbiBiZSBpZ25vcmVkIGlmIG5vdCBzdXBwb3J0ZWQsIGJlY2F1c2UgSlNPTiBwYXlsb2FkcyBhcmUKICAgICAgICAgIC8vIHBhcnNlZCBvbiB0aGUgY2xpZW50LXNpZGUgcmVnYXJkbGVzcy4KICAgICAgICAgIGlmIChyZXNwb25zZVR5cGUgIT09ICdqc29uJykgewogICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgeGhyLnNlbmQocG9zdCB8fCBudWxsKTsKICAgIH0KCiAgICBpZiAodGltZW91dCA+IDApIHsKICAgICAgdmFyIHRpbWVvdXRJZCA9ICRicm93c2VyRGVmZXIodGltZW91dFJlcXVlc3QsIHRpbWVvdXQpOwogICAgfSBlbHNlIGlmIChpc1Byb21pc2VMaWtlKHRpbWVvdXQpKSB7CiAgICAgIHRpbWVvdXQudGhlbih0aW1lb3V0UmVxdWVzdCk7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRpbWVvdXRSZXF1ZXN0KCkgewogICAgICBqc29ucERvbmUgJiYganNvbnBEb25lKCk7CiAgICAgIHhociAmJiB4aHIuYWJvcnQoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb21wbGV0ZVJlcXVlc3QoY2FsbGJhY2ssIHN0YXR1cywgcmVzcG9uc2UsIGhlYWRlcnNTdHJpbmcsIHN0YXR1c1RleHQpIHsKICAgICAgLy8gY2FuY2VsIHRpbWVvdXQgYW5kIHN1YnNlcXVlbnQgdGltZW91dCBwcm9taXNlIHJlc29sdXRpb24KICAgICAgaWYgKHRpbWVvdXRJZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgJGJyb3dzZXJEZWZlci5jYW5jZWwodGltZW91dElkKTsKICAgICAgfQogICAgICBqc29ucERvbmUgPSB4aHIgPSBudWxsOwoKICAgICAgY2FsbGJhY2soc3RhdHVzLCByZXNwb25zZSwgaGVhZGVyc1N0cmluZywgc3RhdHVzVGV4dCk7CiAgICAgICRicm93c2VyLiQkY29tcGxldGVPdXRzdGFuZGluZ1JlcXVlc3Qobm9vcCk7CiAgICB9CiAgfTsKCiAgZnVuY3Rpb24ganNvbnBSZXEodXJsLCBjYWxsYmFja0lkLCBkb25lKSB7CiAgICAvLyB3ZSBjYW4ndCB1c2UgalF1ZXJ5L2pxTGl0ZSBoZXJlIGJlY2F1c2UgalF1ZXJ5IGRvZXMgY3Jhenkgc2hpdCB3aXRoIHNjcmlwdCBlbGVtZW50cywgZS5nLjoKICAgIC8vIC0gZmV0Y2hlcyBsb2NhbCBzY3JpcHRzIHZpYSBYSFIgYW5kIGV2YWxzIHRoZW0KICAgIC8vIC0gYWRkcyBhbmQgaW1tZWRpYXRlbHkgcmVtb3ZlcyBzY3JpcHQgZWxlbWVudHMgZnJvbSB0aGUgZG9jdW1lbnQKICAgIHZhciBzY3JpcHQgPSByYXdEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSwgY2FsbGJhY2sgPSBudWxsOwogICAgc2NyaXB0LnR5cGUgPSAidGV4dC9qYXZhc2NyaXB0IjsKICAgIHNjcmlwdC5zcmMgPSB1cmw7CiAgICBzY3JpcHQuYXN5bmMgPSB0cnVlOwoKICAgIGNhbGxiYWNrID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lckZuKHNjcmlwdCwgImxvYWQiLCBjYWxsYmFjayk7CiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXJGbihzY3JpcHQsICJlcnJvciIsIGNhbGxiYWNrKTsKICAgICAgcmF3RG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChzY3JpcHQpOwogICAgICBzY3JpcHQgPSBudWxsOwogICAgICB2YXIgc3RhdHVzID0gLTE7CiAgICAgIHZhciB0ZXh0ID0gInVua25vd24iOwoKICAgICAgaWYgKGV2ZW50KSB7CiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICJsb2FkIiAmJiAhY2FsbGJhY2tzW2NhbGxiYWNrSWRdLmNhbGxlZCkgewogICAgICAgICAgZXZlbnQgPSB7IHR5cGU6ICJlcnJvciIgfTsKICAgICAgICB9CiAgICAgICAgdGV4dCA9IGV2ZW50LnR5cGU7CiAgICAgICAgc3RhdHVzID0gZXZlbnQudHlwZSA9PT0gImVycm9yIiA/IDQwNCA6IDIwMDsKICAgICAgfQoKICAgICAgaWYgKGRvbmUpIHsKICAgICAgICBkb25lKHN0YXR1cywgdGV4dCk7CiAgICAgIH0KICAgIH07CgogICAgYWRkRXZlbnRMaXN0ZW5lckZuKHNjcmlwdCwgImxvYWQiLCBjYWxsYmFjayk7CiAgICBhZGRFdmVudExpc3RlbmVyRm4oc2NyaXB0LCAiZXJyb3IiLCBjYWxsYmFjayk7CiAgICByYXdEb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcmlwdCk7CiAgICByZXR1cm4gY2FsbGJhY2s7CiAgfQp9Cgp2YXIgJGludGVycG9sYXRlTWluRXJyID0gbWluRXJyKCckaW50ZXJwb2xhdGUnKTsKCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJGludGVycG9sYXRlUHJvdmlkZXIKICoKICogQGRlc2NyaXB0aW9uCiAqCiAqIFVzZWQgZm9yIGNvbmZpZ3VyaW5nIHRoZSBpbnRlcnBvbGF0aW9uIG1hcmt1cC4gRGVmYXVsdHMgdG8gYHt7YCBhbmQgYH19YC4KICoKICogQGV4YW1wbGUKPGV4YW1wbGUgbW9kdWxlPSJjdXN0b21JbnRlcnBvbGF0aW9uQXBwIj4KPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CjxzY3JpcHQ+CiAgdmFyIGN1c3RvbUludGVycG9sYXRpb25BcHAgPSBhbmd1bGFyLm1vZHVsZSgnY3VzdG9tSW50ZXJwb2xhdGlvbkFwcCcsIFtdKTsKCiAgY3VzdG9tSW50ZXJwb2xhdGlvbkFwcC5jb25maWcoZnVuY3Rpb24oJGludGVycG9sYXRlUHJvdmlkZXIpIHsKICAgICRpbnRlcnBvbGF0ZVByb3ZpZGVyLnN0YXJ0U3ltYm9sKCcvLycpOwogICAgJGludGVycG9sYXRlUHJvdmlkZXIuZW5kU3ltYm9sKCcvLycpOwogIH0pOwoKCiAgY3VzdG9tSW50ZXJwb2xhdGlvbkFwcC5jb250cm9sbGVyKCdEZW1vQ29udHJvbGxlcicsIGZ1bmN0aW9uKCkgewogICAgICB0aGlzLmxhYmVsID0gIlRoaXMgYmluZGluZyBpcyBicm91Z2h0IHlvdSBieSAvLyBpbnRlcnBvbGF0aW9uIHN5bWJvbHMuIjsKICB9KTsKPC9zY3JpcHQ+CjxkaXYgbmctYXBwPSJBcHAiIG5nLWNvbnRyb2xsZXI9IkRlbW9Db250cm9sbGVyIGFzIGRlbW8iPgogICAgLy9kZW1vLmxhYmVsLy8KPC9kaXY+CjwvZmlsZT4KPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgaXQoJ3Nob3VsZCBpbnRlcnBvbGF0ZSBiaW5kaW5nIHdpdGggY3VzdG9tIHN5bWJvbHMnLCBmdW5jdGlvbigpIHsKICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ2RlbW8ubGFiZWwnKSkuZ2V0VGV4dCgpKS50b0JlKCdUaGlzIGJpbmRpbmcgaXMgYnJvdWdodCB5b3UgYnkgLy8gaW50ZXJwb2xhdGlvbiBzeW1ib2xzLicpOwogIH0pOwo8L2ZpbGU+CjwvZXhhbXBsZT4KICovCmZ1bmN0aW9uICRJbnRlcnBvbGF0ZVByb3ZpZGVyKCkgewogIHZhciBzdGFydFN5bWJvbCA9ICd7eyc7CiAgdmFyIGVuZFN5bWJvbCA9ICd9fSc7CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkaW50ZXJwb2xhdGVQcm92aWRlciNzdGFydFN5bWJvbAogICAqIEBkZXNjcmlwdGlvbgogICAqIFN5bWJvbCB0byBkZW5vdGUgc3RhcnQgb2YgZXhwcmVzc2lvbiBpbiB0aGUgaW50ZXJwb2xhdGVkIHN0cmluZy4gRGVmYXVsdHMgdG8gYHt7YC4KICAgKgogICAqIEBwYXJhbSB7c3RyaW5nPX0gdmFsdWUgbmV3IHZhbHVlIHRvIHNldCB0aGUgc3RhcnRpbmcgc3ltYm9sIHRvLgogICAqIEByZXR1cm5zIHtzdHJpbmd8c2VsZn0gUmV0dXJucyB0aGUgc3ltYm9sIHdoZW4gdXNlZCBhcyBnZXR0ZXIgYW5kIHNlbGYgaWYgdXNlZCBhcyBzZXR0ZXIuCiAgICovCiAgdGhpcy5zdGFydFN5bWJvbCA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBpZiAodmFsdWUpIHsKICAgICAgc3RhcnRTeW1ib2wgPSB2YWx1ZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gc3RhcnRTeW1ib2w7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRpbnRlcnBvbGF0ZVByb3ZpZGVyI2VuZFN5bWJvbAogICAqIEBkZXNjcmlwdGlvbgogICAqIFN5bWJvbCB0byBkZW5vdGUgdGhlIGVuZCBvZiBleHByZXNzaW9uIGluIHRoZSBpbnRlcnBvbGF0ZWQgc3RyaW5nLiBEZWZhdWx0cyB0byBgfX1gLgogICAqCiAgICogQHBhcmFtIHtzdHJpbmc9fSB2YWx1ZSBuZXcgdmFsdWUgdG8gc2V0IHRoZSBlbmRpbmcgc3ltYm9sIHRvLgogICAqIEByZXR1cm5zIHtzdHJpbmd8c2VsZn0gUmV0dXJucyB0aGUgc3ltYm9sIHdoZW4gdXNlZCBhcyBnZXR0ZXIgYW5kIHNlbGYgaWYgdXNlZCBhcyBzZXR0ZXIuCiAgICovCiAgdGhpcy5lbmRTeW1ib2wgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgaWYgKHZhbHVlKSB7CiAgICAgIGVuZFN5bWJvbCA9IHZhbHVlOwogICAgICByZXR1cm4gdGhpczsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBlbmRTeW1ib2w7CiAgICB9CiAgfTsKCgogIHRoaXMuJGdldCA9IFsnJHBhcnNlJywgJyRleGNlcHRpb25IYW5kbGVyJywgJyRzY2UnLCBmdW5jdGlvbigkcGFyc2UsICRleGNlcHRpb25IYW5kbGVyLCAkc2NlKSB7CiAgICB2YXIgc3RhcnRTeW1ib2xMZW5ndGggPSBzdGFydFN5bWJvbC5sZW5ndGgsCiAgICAgICAgZW5kU3ltYm9sTGVuZ3RoID0gZW5kU3ltYm9sLmxlbmd0aCwKICAgICAgICBlc2NhcGVkU3RhcnRSZWdleHAgPSBuZXcgUmVnRXhwKHN0YXJ0U3ltYm9sLnJlcGxhY2UoLy4vZywgZXNjYXBlKSwgJ2cnKSwKICAgICAgICBlc2NhcGVkRW5kUmVnZXhwID0gbmV3IFJlZ0V4cChlbmRTeW1ib2wucmVwbGFjZSgvLi9nLCBlc2NhcGUpLCAnZycpOwoKICAgIGZ1bmN0aW9uIGVzY2FwZShjaCkgewogICAgICByZXR1cm4gJ1xcXFxcXCcgKyBjaDsKICAgIH0KCiAgICAvKioKICAgICAqIEBuZ2RvYyBzZXJ2aWNlCiAgICAgKiBAbmFtZSAkaW50ZXJwb2xhdGUKICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgKgogICAgICogQHJlcXVpcmVzICRwYXJzZQogICAgICogQHJlcXVpcmVzICRzY2UKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqCiAgICAgKiBDb21waWxlcyBhIHN0cmluZyB3aXRoIG1hcmt1cCBpbnRvIGFuIGludGVycG9sYXRpb24gZnVuY3Rpb24uIFRoaXMgc2VydmljZSBpcyB1c2VkIGJ5IHRoZQogICAgICogSFRNTCB7QGxpbmsgbmcuJGNvbXBpbGUgJGNvbXBpbGV9IHNlcnZpY2UgZm9yIGRhdGEgYmluZGluZy4gU2VlCiAgICAgKiB7QGxpbmsgbmcuJGludGVycG9sYXRlUHJvdmlkZXIgJGludGVycG9sYXRlUHJvdmlkZXJ9IGZvciBjb25maWd1cmluZyB0aGUKICAgICAqIGludGVycG9sYXRpb24gbWFya3VwLgogICAgICoKICAgICAqCiAgICAgKiBgYGBqcwogICAgICogICB2YXIgJGludGVycG9sYXRlID0gLi4uOyAvLyBpbmplY3RlZAogICAgICogICB2YXIgZXhwID0gJGludGVycG9sYXRlKCdIZWxsbyB7e25hbWUgfCB1cHBlcmNhc2V9fSEnKTsKICAgICAqICAgZXhwZWN0KGV4cCh7bmFtZTonQW5ndWxhcid9KS50b0VxdWFsKCdIZWxsbyBBTkdVTEFSIScpOwogICAgICogYGBgCiAgICAgKgogICAgICogYCRpbnRlcnBvbGF0ZWAgdGFrZXMgYW4gb3B0aW9uYWwgZm91cnRoIGFyZ3VtZW50LCBgYWxsT3JOb3RoaW5nYC4gSWYgYGFsbE9yTm90aGluZ2AgaXMKICAgICAqIGB0cnVlYCwgdGhlIGludGVycG9sYXRpb24gZnVuY3Rpb24gd2lsbCByZXR1cm4gYHVuZGVmaW5lZGAgdW5sZXNzIGFsbCBlbWJlZGRlZCBleHByZXNzaW9ucwogICAgICogZXZhbHVhdGUgdG8gYSB2YWx1ZSBvdGhlciB0aGFuIGB1bmRlZmluZWRgLgogICAgICoKICAgICAqIGBgYGpzCiAgICAgKiAgIHZhciAkaW50ZXJwb2xhdGUgPSAuLi47IC8vIGluamVjdGVkCiAgICAgKiAgIHZhciBjb250ZXh0ID0ge2dyZWV0aW5nOiAnSGVsbG8nLCBuYW1lOiB1bmRlZmluZWQgfTsKICAgICAqCiAgICAgKiAgIC8vIGRlZmF1bHQgImZvcmdpdmluZyIgbW9kZQogICAgICogICB2YXIgZXhwID0gJGludGVycG9sYXRlKCd7e2dyZWV0aW5nfX0ge3tuYW1lfX0hJyk7CiAgICAgKiAgIGV4cGVjdChleHAoY29udGV4dCkpLnRvRXF1YWwoJ0hlbGxvICEnKTsKICAgICAqCiAgICAgKiAgIC8vICJhbGxPck5vdGhpbmciIG1vZGUKICAgICAqICAgZXhwID0gJGludGVycG9sYXRlKCd7e2dyZWV0aW5nfX0ge3tuYW1lfX0hJywgZmFsc2UsIG51bGwsIHRydWUpOwogICAgICogICBleHBlY3QoZXhwKGNvbnRleHQpKS50b0JlVW5kZWZpbmVkKCk7CiAgICAgKiAgIGNvbnRleHQubmFtZSA9ICdBbmd1bGFyJzsKICAgICAqICAgZXhwZWN0KGV4cChjb250ZXh0KSkudG9FcXVhbCgnSGVsbG8gQW5ndWxhciEnKTsKICAgICAqIGBgYAogICAgICoKICAgICAqIGBhbGxPck5vdGhpbmdgIGlzIHVzZWZ1bCBmb3IgaW50ZXJwb2xhdGluZyBVUkxzLiBgbmdTcmNgIGFuZCBgbmdTcmNzZXRgIHVzZSB0aGlzIGJlaGF2aW9yLgogICAgICoKICAgICAqICMjIyNFc2NhcGVkIEludGVycG9sYXRpb24KICAgICAqICRpbnRlcnBvbGF0ZSBwcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgZXNjYXBpbmcgaW50ZXJwb2xhdGlvbiBtYXJrZXJzLiBTdGFydCBhbmQgZW5kIG1hcmtlcnMKICAgICAqIGNhbiBiZSBlc2NhcGVkIGJ5IHByZWNlZGluZyBlYWNoIG9mIHRoZWlyIGNoYXJhY3RlcnMgd2l0aCBhIFJFVkVSU0UgU09MSURVUyBVKzAwNUMgKGJhY2tzbGFzaCkuCiAgICAgKiBJdCB3aWxsIGJlIHJlbmRlcmVkIGFzIGEgcmVndWxhciBzdGFydC9lbmQgbWFya2VyLCBhbmQgd2lsbCBub3QgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gZXhwcmVzc2lvbgogICAgICogb3IgYmluZGluZy4KICAgICAqCiAgICAgKiBUaGlzIGVuYWJsZXMgd2ViLXNlcnZlcnMgdG8gcHJldmVudCBzY3JpcHQgaW5qZWN0aW9uIGF0dGFja3MgYW5kIGRlZmFjaW5nIGF0dGFja3MsIHRvIHNvbWUKICAgICAqIGRlZ3JlZSwgd2hpbGUgYWxzbyBlbmFibGluZyBjb2RlIGV4YW1wbGVzIHRvIHdvcmsgd2l0aG91dCByZWx5aW5nIG9uIHRoZQogICAgICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ05vbkJpbmRhYmxlIG5nTm9uQmluZGFibGV9IGRpcmVjdGl2ZS4KICAgICAqCiAgICAgKiAqKkZvciBzZWN1cml0eSBwdXJwb3NlcywgaXQgaXMgc3Ryb25nbHkgZW5jb3VyYWdlZCB0aGF0IHdlYiBzZXJ2ZXJzIGVzY2FwZSB1c2VyLXN1cHBsaWVkIGRhdGEsCiAgICAgKiByZXBsYWNpbmcgYW5nbGUgYnJhY2tldHMgKCZsdDssICZndDspIHdpdGggJmFtcDtsdDsgYW5kICZhbXA7Z3Q7IHJlc3BlY3RpdmVseSwgYW5kIHJlcGxhY2luZyBhbGwKICAgICAqIGludGVycG9sYXRpb24gc3RhcnQvZW5kIG1hcmtlcnMgd2l0aCB0aGVpciBlc2NhcGVkIGNvdW50ZXJwYXJ0cy4qKgogICAgICoKICAgICAqIEVzY2FwZWQgaW50ZXJwb2xhdGlvbiBtYXJrZXJzIGFyZSBvbmx5IHJlcGxhY2VkIHdpdGggdGhlIGFjdHVhbCBpbnRlcnBvbGF0aW9uIG1hcmtlcnMgaW4gcmVuZGVyZWQKICAgICAqIG91dHB1dCB3aGVuIHRoZSAkaW50ZXJwb2xhdGUgc2VydmljZSBwcm9jZXNzZXMgdGhlIHRleHQuIFNvLCBmb3IgSFRNTCBlbGVtZW50cyBpbnRlcnBvbGF0ZWQKICAgICAqIGJ5IHtAbGluayBuZy4kY29tcGlsZSAkY29tcGlsZX0sIG9yIG90aGVyd2lzZSBpbnRlcnBvbGF0ZWQgd2l0aCB0aGUgYG11c3RIYXZlRXhwcmVzc2lvbmAgcGFyYW1ldGVyCiAgICAgKiBzZXQgdG8gYHRydWVgLCB0aGUgaW50ZXJwb2xhdGVkIHRleHQgbXVzdCBjb250YWluIGFuIHVuZXNjYXBlZCBpbnRlcnBvbGF0aW9uIGV4cHJlc3Npb24uIEFzIHN1Y2gsCiAgICAgKiB0aGlzIGlzIHR5cGljYWxseSB1c2VmdWwgb25seSB3aGVuIHVzZXItZGF0YSBpcyB1c2VkIGluIHJlbmRlcmluZyBhIHRlbXBsYXRlIGZyb20gdGhlIHNlcnZlciwgb3IKICAgICAqIHdoZW4gb3RoZXJ3aXNlIHVudHJ1c3RlZCBkYXRhIGlzIHVzZWQgYnkgYSBkaXJlY3RpdmUuCiAgICAgKgogICAgICogPGV4YW1wbGU+CiAgICAgKiAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgKiAgICA8ZGl2IG5nLWluaXQ9InVzZXJuYW1lPSdBIHVzZXInIj4KICAgICAqICAgICAgPHAgbmctaW5pdD0iYXBwdGl0bGU9J0VzY2FwaW5nIGRlbW8nIj57e2FwcHRpdGxlfX06IFx7XHsgdXNlcm5hbWUgPSAiZGVmYWNlZCB2YWx1ZSI7IFx9XH0KICAgICAqICAgICAgICA8L3A+CiAgICAgKiAgICAgIDxwPjxzdHJvbmc+e3t1c2VybmFtZX19PC9zdHJvbmc+IGF0dGVtcHRzIHRvIGluamVjdCBjb2RlIHdoaWNoIHdpbGwgZGVmYWNlIHRoZQogICAgICogICAgICAgIGFwcGxpY2F0aW9uLCBidXQgZmFpbHMgdG8gYWNjb21wbGlzaCB0aGVpciB0YXNrLCBiZWNhdXNlIHRoZSBzZXJ2ZXIgaGFzIGNvcnJlY3RseQogICAgICogICAgICAgIGVzY2FwZWQgdGhlIGludGVycG9sYXRpb24gc3RhcnQvZW5kIG1hcmtlcnMgd2l0aCBSRVZFUlNFIFNPTElEVVMgVSswMDVDIChiYWNrc2xhc2gpCiAgICAgKiAgICAgICAgY2hhcmFjdGVycy48L3A+CiAgICAgKiAgICAgIDxwPkluc3RlYWQsIHRoZSByZXN1bHQgb2YgdGhlIGF0dGVtcHRlZCBzY3JpcHQgaW5qZWN0aW9uIGlzIHZpc2libGUsIGFuZCBjYW4gYmUgcmVtb3ZlZAogICAgICogICAgICAgIGZyb20gdGhlIGRhdGFiYXNlIGJ5IGFuIGFkbWluaXN0cmF0b3IuPC9wPgogICAgICogICAgPC9kaXY+CiAgICAgKiAgPC9maWxlPgogICAgICogPC9leGFtcGxlPgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRoZSB0ZXh0IHdpdGggbWFya3VwIHRvIGludGVycG9sYXRlLgogICAgICogQHBhcmFtIHtib29sZWFuPX0gbXVzdEhhdmVFeHByZXNzaW9uIGlmIHNldCB0byB0cnVlIHRoZW4gdGhlIGludGVycG9sYXRpb24gc3RyaW5nIG11c3QgaGF2ZQogICAgICogICAgZW1iZWRkZWQgZXhwcmVzc2lvbiBpbiBvcmRlciB0byByZXR1cm4gYW4gaW50ZXJwb2xhdGlvbiBmdW5jdGlvbi4gU3RyaW5ncyB3aXRoIG5vCiAgICAgKiAgICBlbWJlZGRlZCBleHByZXNzaW9uIHdpbGwgcmV0dXJuIG51bGwgZm9yIHRoZSBpbnRlcnBvbGF0aW9uIGZ1bmN0aW9uLgogICAgICogQHBhcmFtIHtzdHJpbmc9fSB0cnVzdGVkQ29udGV4dCB3aGVuIHByb3ZpZGVkLCB0aGUgcmV0dXJuZWQgZnVuY3Rpb24gcGFzc2VzIHRoZSBpbnRlcnBvbGF0ZWQKICAgICAqICAgIHJlc3VsdCB0aHJvdWdoIHtAbGluayBuZy4kc2NlI2dldFRydXN0ZWQgJHNjZS5nZXRUcnVzdGVkKGludGVycG9sYXRlZFJlc3VsdCwKICAgICAqICAgIHRydXN0ZWRDb250ZXh0KX0gYmVmb3JlIHJldHVybmluZyBpdC4gIFJlZmVyIHRvIHRoZSB7QGxpbmsgbmcuJHNjZSAkc2NlfSBzZXJ2aWNlIHRoYXQKICAgICAqICAgIHByb3ZpZGVzIFN0cmljdCBDb250ZXh0dWFsIEVzY2FwaW5nIGZvciBkZXRhaWxzLgogICAgICogQHBhcmFtIHtib29sZWFuPX0gYWxsT3JOb3RoaW5nIGlmIGB0cnVlYCwgdGhlbiB0aGUgcmV0dXJuZWQgZnVuY3Rpb24gcmV0dXJucyB1bmRlZmluZWQKICAgICAqICAgIHVubGVzcyBhbGwgZW1iZWRkZWQgZXhwcmVzc2lvbnMgZXZhbHVhdGUgdG8gYSB2YWx1ZSBvdGhlciB0aGFuIGB1bmRlZmluZWRgLgogICAgICogQHJldHVybnMge2Z1bmN0aW9uKGNvbnRleHQpfSBhbiBpbnRlcnBvbGF0aW9uIGZ1bmN0aW9uIHdoaWNoIGlzIHVzZWQgdG8gY29tcHV0ZSB0aGUKICAgICAqICAgIGludGVycG9sYXRlZCBzdHJpbmcuIFRoZSBmdW5jdGlvbiBoYXMgdGhlc2UgcGFyYW1ldGVyczoKICAgICAqCiAgICAgKiAtIGBjb250ZXh0YDogZXZhbHVhdGlvbiBjb250ZXh0IGZvciBhbGwgZXhwcmVzc2lvbnMgZW1iZWRkZWQgaW4gdGhlIGludGVycG9sYXRlZCB0ZXh0CiAgICAgKi8KICAgIGZ1bmN0aW9uICRpbnRlcnBvbGF0ZSh0ZXh0LCBtdXN0SGF2ZUV4cHJlc3Npb24sIHRydXN0ZWRDb250ZXh0LCBhbGxPck5vdGhpbmcpIHsKICAgICAgYWxsT3JOb3RoaW5nID0gISFhbGxPck5vdGhpbmc7CiAgICAgIHZhciBzdGFydEluZGV4LAogICAgICAgICAgZW5kSW5kZXgsCiAgICAgICAgICBpbmRleCA9IDAsCiAgICAgICAgICBleHByZXNzaW9ucyA9IFtdLAogICAgICAgICAgcGFyc2VGbnMgPSBbXSwKICAgICAgICAgIHRleHRMZW5ndGggPSB0ZXh0Lmxlbmd0aCwKICAgICAgICAgIGV4cCwKICAgICAgICAgIGNvbmNhdCA9IFtdLAogICAgICAgICAgZXhwcmVzc2lvblBvc2l0aW9ucyA9IFtdOwoKICAgICAgd2hpbGUgKGluZGV4IDwgdGV4dExlbmd0aCkgewogICAgICAgIGlmICgoKHN0YXJ0SW5kZXggPSB0ZXh0LmluZGV4T2Yoc3RhcnRTeW1ib2wsIGluZGV4KSkgIT0gLTEpICYmCiAgICAgICAgICAgICAoKGVuZEluZGV4ID0gdGV4dC5pbmRleE9mKGVuZFN5bWJvbCwgc3RhcnRJbmRleCArIHN0YXJ0U3ltYm9sTGVuZ3RoKSkgIT0gLTEpKSB7CiAgICAgICAgICBpZiAoaW5kZXggIT09IHN0YXJ0SW5kZXgpIHsKICAgICAgICAgICAgY29uY2F0LnB1c2godW5lc2NhcGVUZXh0KHRleHQuc3Vic3RyaW5nKGluZGV4LCBzdGFydEluZGV4KSkpOwogICAgICAgICAgfQogICAgICAgICAgZXhwID0gdGV4dC5zdWJzdHJpbmcoc3RhcnRJbmRleCArIHN0YXJ0U3ltYm9sTGVuZ3RoLCBlbmRJbmRleCk7CiAgICAgICAgICBleHByZXNzaW9ucy5wdXNoKGV4cCk7CiAgICAgICAgICBwYXJzZUZucy5wdXNoKCRwYXJzZShleHAsIHBhcnNlU3RyaW5naWZ5SW50ZXJjZXB0b3IpKTsKICAgICAgICAgIGluZGV4ID0gZW5kSW5kZXggKyBlbmRTeW1ib2xMZW5ndGg7CiAgICAgICAgICBleHByZXNzaW9uUG9zaXRpb25zLnB1c2goY29uY2F0Lmxlbmd0aCk7CiAgICAgICAgICBjb25jYXQucHVzaCgnJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIHdlIGRpZCBub3QgZmluZCBhbiBpbnRlcnBvbGF0aW9uLCBzbyB3ZSBoYXZlIHRvIGFkZCB0aGUgcmVtYWluZGVyIHRvIHRoZSBzZXBhcmF0b3JzIGFycmF5CiAgICAgICAgICBpZiAoaW5kZXggIT09IHRleHRMZW5ndGgpIHsKICAgICAgICAgICAgY29uY2F0LnB1c2godW5lc2NhcGVUZXh0KHRleHQuc3Vic3RyaW5nKGluZGV4KSkpOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBDb25jYXRlbmF0aW5nIGV4cHJlc3Npb25zIG1ha2VzIGl0IGhhcmQgdG8gcmVhc29uIGFib3V0IHdoZXRoZXIgc29tZSBjb21iaW5hdGlvbiBvZgogICAgICAvLyBjb25jYXRlbmF0ZWQgdmFsdWVzIGFyZSB1bnNhZmUgdG8gdXNlIGFuZCBjb3VsZCBlYXNpbHkgbGVhZCB0byBYU1MuICBCeSByZXF1aXJpbmcgdGhhdCBhCiAgICAgIC8vIHNpbmdsZSBleHByZXNzaW9uIGJlIHVzZWQgZm9yIGlmcmFtZVtzcmNdLCBvYmplY3Rbc3JjXSwgZXRjLiwgd2UgZW5zdXJlIHRoYXQgdGhlIHZhbHVlCiAgICAgIC8vIHRoYXQncyB1c2VkIGlzIGFzc2lnbmVkIG9yIGNvbnN0cnVjdGVkIGJ5IHNvbWUgSlMgY29kZSBzb21ld2hlcmUgdGhhdCBpcyBtb3JlIHRlc3RhYmxlIG9yCiAgICAgIC8vIG1ha2UgaXQgb2J2aW91cyB0aGF0IHlvdSBib3VuZCB0aGUgdmFsdWUgdG8gc29tZSB1c2VyIGNvbnRyb2xsZWQgdmFsdWUuICBUaGlzIGhlbHBzIHJlZHVjZQogICAgICAvLyB0aGUgbG9hZCB3aGVuIGF1ZGl0aW5nIGZvciBYU1MgaXNzdWVzLgogICAgICBpZiAodHJ1c3RlZENvbnRleHQgJiYgY29uY2F0Lmxlbmd0aCA+IDEpIHsKICAgICAgICAgIHRocm93ICRpbnRlcnBvbGF0ZU1pbkVycignbm9jb25jYXQnLAogICAgICAgICAgICAgICJFcnJvciB3aGlsZSBpbnRlcnBvbGF0aW5nOiB7MH1cblN0cmljdCBDb250ZXh0dWFsIEVzY2FwaW5nIGRpc2FsbG93cyAiICsKICAgICAgICAgICAgICAiaW50ZXJwb2xhdGlvbnMgdGhhdCBjb25jYXRlbmF0ZSBtdWx0aXBsZSBleHByZXNzaW9ucyB3aGVuIGEgdHJ1c3RlZCB2YWx1ZSBpcyAiICsKICAgICAgICAgICAgICAicmVxdWlyZWQuICBTZWUgaHR0cDovL2RvY3MuYW5ndWxhcmpzLm9yZy9hcGkvbmcuJHNjZSIsIHRleHQpOwogICAgICB9CgogICAgICBpZiAoIW11c3RIYXZlRXhwcmVzc2lvbiB8fCBleHByZXNzaW9ucy5sZW5ndGgpIHsKICAgICAgICB2YXIgY29tcHV0ZSA9IGZ1bmN0aW9uKHZhbHVlcykgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZXhwcmVzc2lvbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgICAgICBpZiAoYWxsT3JOb3RoaW5nICYmIGlzVW5kZWZpbmVkKHZhbHVlc1tpXSkpIHJldHVybjsKICAgICAgICAgICAgY29uY2F0W2V4cHJlc3Npb25Qb3NpdGlvbnNbaV1dID0gdmFsdWVzW2ldOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbmNhdC5qb2luKCcnKTsKICAgICAgICB9OwoKICAgICAgICB2YXIgZ2V0VmFsdWUgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHRydXN0ZWRDb250ZXh0ID8KICAgICAgICAgICAgJHNjZS5nZXRUcnVzdGVkKHRydXN0ZWRDb250ZXh0LCB2YWx1ZSkgOgogICAgICAgICAgICAkc2NlLnZhbHVlT2YodmFsdWUpOwogICAgICAgIH07CgogICAgICAgIHZhciBzdHJpbmdpZnkgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgLy8gbnVsbCB8fCB1bmRlZmluZWQKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHsKICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzoKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnbnVtYmVyJzoKICAgICAgICAgICAgICB2YWx1ZSA9ICcnICsgdmFsdWU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdmFsdWUgPSB0b0pzb24odmFsdWUpOwogICAgICAgICAgfQoKICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9OwoKICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uIGludGVycG9sYXRpb25Gbihjb250ZXh0KSB7CiAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgdmFyIGlpID0gZXhwcmVzc2lvbnMubGVuZ3RoOwogICAgICAgICAgICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGlpKTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgZm9yICg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXNbaV0gPSBwYXJzZUZuc1tpXShjb250ZXh0KTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIHJldHVybiBjb21wdXRlKHZhbHVlcyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICAgIHZhciBuZXdFcnIgPSAkaW50ZXJwb2xhdGVNaW5FcnIoJ2ludGVycicsICJDYW4ndCBpbnRlcnBvbGF0ZTogezB9XG57MX0iLCB0ZXh0LAogICAgICAgICAgICAgICAgICBlcnIudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgJGV4Y2VwdGlvbkhhbmRsZXIobmV3RXJyKTsKICAgICAgICAgICAgfQoKICAgICAgICAgIH0sIHsKICAgICAgICAgIC8vIGFsbCBvZiB0aGVzZSBwcm9wZXJ0aWVzIGFyZSB1bmRvY3VtZW50ZWQgZm9yIG5vdwogICAgICAgICAgZXhwOiB0ZXh0LCAvL2p1c3QgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCByZWd1bGFyIHdhdGNoZXJzIGNyZWF0ZWQgdmlhICR3YXRjaAogICAgICAgICAgZXhwcmVzc2lvbnM6IGV4cHJlc3Npb25zLAogICAgICAgICAgJCR3YXRjaERlbGVnYXRlOiBmdW5jdGlvbihzY29wZSwgbGlzdGVuZXIsIG9iamVjdEVxdWFsaXR5KSB7CiAgICAgICAgICAgIHZhciBsYXN0VmFsdWU7CiAgICAgICAgICAgIHJldHVybiBzY29wZS4kd2F0Y2hHcm91cChwYXJzZUZucywgZnVuY3Rpb24gaW50ZXJwb2xhdGVGbldhdGNoZXIodmFsdWVzLCBvbGRWYWx1ZXMpIHsKICAgICAgICAgICAgICB2YXIgY3VyclZhbHVlID0gY29tcHV0ZSh2YWx1ZXMpOwogICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVyKSkgewogICAgICAgICAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBjdXJyVmFsdWUsIHZhbHVlcyAhPT0gb2xkVmFsdWVzID8gbGFzdFZhbHVlIDogY3VyclZhbHVlLCBzY29wZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGxhc3RWYWx1ZSA9IGN1cnJWYWx1ZTsKICAgICAgICAgICAgfSwgb2JqZWN0RXF1YWxpdHkpOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CgogICAgICBmdW5jdGlvbiB1bmVzY2FwZVRleHQodGV4dCkgewogICAgICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoZXNjYXBlZFN0YXJ0UmVnZXhwLCBzdGFydFN5bWJvbCkuCiAgICAgICAgICByZXBsYWNlKGVzY2FwZWRFbmRSZWdleHAsIGVuZFN5bWJvbCk7CiAgICAgIH0KCiAgICAgIGZ1bmN0aW9uIHBhcnNlU3RyaW5naWZ5SW50ZXJjZXB0b3IodmFsdWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgdmFsdWUgPSBnZXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgICByZXR1cm4gYWxsT3JOb3RoaW5nICYmICFpc0RlZmluZWQodmFsdWUpID8gdmFsdWUgOiBzdHJpbmdpZnkodmFsdWUpOwogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgdmFyIG5ld0VyciA9ICRpbnRlcnBvbGF0ZU1pbkVycignaW50ZXJyJywgIkNhbid0IGludGVycG9sYXRlOiB7MH1cbnsxfSIsIHRleHQsCiAgICAgICAgICAgIGVyci50b1N0cmluZygpKTsKICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKG5ld0Vycik7CiAgICAgICAgfQogICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJGludGVycG9sYXRlI3N0YXJ0U3ltYm9sCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFN5bWJvbCB0byBkZW5vdGUgdGhlIHN0YXJ0IG9mIGV4cHJlc3Npb24gaW4gdGhlIGludGVycG9sYXRlZCBzdHJpbmcuIERlZmF1bHRzIHRvIGB7e2AuCiAgICAgKgogICAgICogVXNlIHtAbGluayBuZy4kaW50ZXJwb2xhdGVQcm92aWRlciNzdGFydFN5bWJvbCBgJGludGVycG9sYXRlUHJvdmlkZXIuc3RhcnRTeW1ib2xgfSB0byBjaGFuZ2UKICAgICAqIHRoZSBzeW1ib2wuCiAgICAgKgogICAgICogQHJldHVybnMge3N0cmluZ30gc3RhcnQgc3ltYm9sLgogICAgICovCiAgICAkaW50ZXJwb2xhdGUuc3RhcnRTeW1ib2wgPSBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHN0YXJ0U3ltYm9sOwogICAgfTsKCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkaW50ZXJwb2xhdGUjZW5kU3ltYm9sCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFN5bWJvbCB0byBkZW5vdGUgdGhlIGVuZCBvZiBleHByZXNzaW9uIGluIHRoZSBpbnRlcnBvbGF0ZWQgc3RyaW5nLiBEZWZhdWx0cyB0byBgfX1gLgogICAgICoKICAgICAqIFVzZSB7QGxpbmsgbmcuJGludGVycG9sYXRlUHJvdmlkZXIjZW5kU3ltYm9sIGAkaW50ZXJwb2xhdGVQcm92aWRlci5lbmRTeW1ib2xgfSB0byBjaGFuZ2UKICAgICAqIHRoZSBzeW1ib2wuCiAgICAgKgogICAgICogQHJldHVybnMge3N0cmluZ30gZW5kIHN5bWJvbC4KICAgICAqLwogICAgJGludGVycG9sYXRlLmVuZFN5bWJvbCA9IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gZW5kU3ltYm9sOwogICAgfTsKCiAgICByZXR1cm4gJGludGVycG9sYXRlOwogIH1dOwp9CgpmdW5jdGlvbiAkSW50ZXJ2YWxQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyRyb290U2NvcGUnLCAnJHdpbmRvdycsICckcScsICckJHEnLAogICAgICAgZnVuY3Rpb24oJHJvb3RTY29wZSwgICAkd2luZG93LCAgICRxLCAgICQkcSkgewogICAgdmFyIGludGVydmFscyA9IHt9OwoKCiAgICAgLyoqCiAgICAgICogQG5nZG9jIHNlcnZpY2UKICAgICAgKiBAbmFtZSAkaW50ZXJ2YWwKICAgICAgKgogICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAqIEFuZ3VsYXIncyB3cmFwcGVyIGZvciBgd2luZG93LnNldEludGVydmFsYC4gVGhlIGBmbmAgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZXZlcnkgYGRlbGF5YAogICAgICAqIG1pbGxpc2Vjb25kcy4KICAgICAgKgogICAgICAqIFRoZSByZXR1cm4gdmFsdWUgb2YgcmVnaXN0ZXJpbmcgYW4gaW50ZXJ2YWwgZnVuY3Rpb24gaXMgYSBwcm9taXNlLiBUaGlzIHByb21pc2Ugd2lsbCBiZQogICAgICAqIG5vdGlmaWVkIHVwb24gZWFjaCB0aWNrIG9mIHRoZSBpbnRlcnZhbCwgYW5kIHdpbGwgYmUgcmVzb2x2ZWQgYWZ0ZXIgYGNvdW50YCBpdGVyYXRpb25zLCBvcgogICAgICAqIHJ1biBpbmRlZmluaXRlbHkgaWYgYGNvdW50YCBpcyBub3QgZGVmaW5lZC4gVGhlIHZhbHVlIG9mIHRoZSBub3RpZmljYXRpb24gd2lsbCBiZSB0aGUKICAgICAgKiBudW1iZXIgb2YgaXRlcmF0aW9ucyB0aGF0IGhhdmUgcnVuLgogICAgICAqIFRvIGNhbmNlbCBhbiBpbnRlcnZhbCwgY2FsbCBgJGludGVydmFsLmNhbmNlbChwcm9taXNlKWAuCiAgICAgICoKICAgICAgKiBJbiB0ZXN0cyB5b3UgY2FuIHVzZSB7QGxpbmsgbmdNb2NrLiRpbnRlcnZhbCNmbHVzaCBgJGludGVydmFsLmZsdXNoKG1pbGxpcylgfSB0bwogICAgICAqIG1vdmUgZm9yd2FyZCBieSBgbWlsbGlzYCBtaWxsaXNlY29uZHMgYW5kIHRyaWdnZXIgYW55IGZ1bmN0aW9ucyBzY2hlZHVsZWQgdG8gcnVuIGluIHRoYXQKICAgICAgKiB0aW1lLgogICAgICAqCiAgICAgICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CiAgICAgICogKipOb3RlKio6IEludGVydmFscyBjcmVhdGVkIGJ5IHRoaXMgc2VydmljZSBtdXN0IGJlIGV4cGxpY2l0bHkgZGVzdHJveWVkIHdoZW4geW91IGFyZSBmaW5pc2hlZAogICAgICAqIHdpdGggdGhlbS4gIEluIHBhcnRpY3VsYXIgdGhleSBhcmUgbm90IGF1dG9tYXRpY2FsbHkgZGVzdHJveWVkIHdoZW4gYSBjb250cm9sbGVyJ3Mgc2NvcGUgb3IgYQogICAgICAqIGRpcmVjdGl2ZSdzIGVsZW1lbnQgYXJlIGRlc3Ryb3llZC4KICAgICAgKiBZb3Ugc2hvdWxkIHRha2UgdGhpcyBpbnRvIGNvbnNpZGVyYXRpb24gYW5kIG1ha2Ugc3VyZSB0byBhbHdheXMgY2FuY2VsIHRoZSBpbnRlcnZhbCBhdCB0aGUKICAgICAgKiBhcHByb3ByaWF0ZSBtb21lbnQuICBTZWUgdGhlIGV4YW1wbGUgYmVsb3cgZm9yIG1vcmUgZGV0YWlscyBvbiBob3cgYW5kIHdoZW4gdG8gZG8gdGhpcy4KICAgICAgKiA8L2Rpdj4KICAgICAgKgogICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gZm4gQSBmdW5jdGlvbiB0aGF0IHNob3VsZCBiZSBjYWxsZWQgcmVwZWF0ZWRseS4KICAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIGVhY2ggZnVuY3Rpb24gY2FsbC4KICAgICAgKiBAcGFyYW0ge251bWJlcj19IFtjb3VudD0wXSBOdW1iZXIgb2YgdGltZXMgdG8gcmVwZWF0LiBJZiBub3Qgc2V0LCBvciAwLCB3aWxsIHJlcGVhdAogICAgICAqICAgaW5kZWZpbml0ZWx5LgogICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IFtpbnZva2VBcHBseT10cnVlXSBJZiBzZXQgdG8gYGZhbHNlYCBza2lwcyBtb2RlbCBkaXJ0eSBjaGVja2luZywgb3RoZXJ3aXNlCiAgICAgICogICB3aWxsIGludm9rZSBgZm5gIHdpdGhpbiB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGFwcGx5ICRhcHBseX0gYmxvY2suCiAgICAgICogQHJldHVybnMge3Byb21pc2V9IEEgcHJvbWlzZSB3aGljaCB3aWxsIGJlIG5vdGlmaWVkIG9uIGVhY2ggaXRlcmF0aW9uLgogICAgICAqCiAgICAgICogQGV4YW1wbGUKICAgICAgKiA8ZXhhbXBsZSBtb2R1bGU9ImludGVydmFsRXhhbXBsZSI+CiAgICAgICogPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICogICA8c2NyaXB0PgogICAgICAqICAgICBhbmd1bGFyLm1vZHVsZSgnaW50ZXJ2YWxFeGFtcGxlJywgW10pCiAgICAgICogICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCAnJGludGVydmFsJywKICAgICAgKiAgICAgICAgIGZ1bmN0aW9uKCRzY29wZSwgJGludGVydmFsKSB7CiAgICAgICogICAgICAgICAgICRzY29wZS5mb3JtYXQgPSAnTS9kL3l5IGg6bW06c3MgYSc7CiAgICAgICogICAgICAgICAgICRzY29wZS5ibG9vZF8xID0gMTAwOwogICAgICAqICAgICAgICAgICAkc2NvcGUuYmxvb2RfMiA9IDEyMDsKICAgICAgKgogICAgICAqICAgICAgICAgICB2YXIgc3RvcDsKICAgICAgKiAgICAgICAgICAgJHNjb3BlLmZpZ2h0ID0gZnVuY3Rpb24oKSB7CiAgICAgICogICAgICAgICAgICAgLy8gRG9uJ3Qgc3RhcnQgYSBuZXcgZmlnaHQgaWYgd2UgYXJlIGFscmVhZHkgZmlnaHRpbmcKICAgICAgKiAgICAgICAgICAgICBpZiAoIGFuZ3VsYXIuaXNEZWZpbmVkKHN0b3ApICkgcmV0dXJuOwogICAgICAqCiAgICAgICogICAgICAgICAgICAgc3RvcCA9ICRpbnRlcnZhbChmdW5jdGlvbigpIHsKICAgICAgKiAgICAgICAgICAgICAgIGlmICgkc2NvcGUuYmxvb2RfMSA+IDAgJiYgJHNjb3BlLmJsb29kXzIgPiAwKSB7CiAgICAgICogICAgICAgICAgICAgICAgICRzY29wZS5ibG9vZF8xID0gJHNjb3BlLmJsb29kXzEgLSAzOwogICAgICAqICAgICAgICAgICAgICAgICAkc2NvcGUuYmxvb2RfMiA9ICRzY29wZS5ibG9vZF8yIC0gNDsKICAgICAgKiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICogICAgICAgICAgICAgICAgICRzY29wZS5zdG9wRmlnaHQoKTsKICAgICAgKiAgICAgICAgICAgICAgIH0KICAgICAgKiAgICAgICAgICAgICB9LCAxMDApOwogICAgICAqICAgICAgICAgICB9OwogICAgICAqCiAgICAgICogICAgICAgICAgICRzY29wZS5zdG9wRmlnaHQgPSBmdW5jdGlvbigpIHsKICAgICAgKiAgICAgICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQoc3RvcCkpIHsKICAgICAgKiAgICAgICAgICAgICAgICRpbnRlcnZhbC5jYW5jZWwoc3RvcCk7CiAgICAgICogICAgICAgICAgICAgICBzdG9wID0gdW5kZWZpbmVkOwogICAgICAqICAgICAgICAgICAgIH0KICAgICAgKiAgICAgICAgICAgfTsKICAgICAgKgogICAgICAqICAgICAgICAgICAkc2NvcGUucmVzZXRGaWdodCA9IGZ1bmN0aW9uKCkgewogICAgICAqICAgICAgICAgICAgICRzY29wZS5ibG9vZF8xID0gMTAwOwogICAgICAqICAgICAgICAgICAgICRzY29wZS5ibG9vZF8yID0gMTIwOwogICAgICAqICAgICAgICAgICB9OwogICAgICAqCiAgICAgICogICAgICAgICAgICRzY29wZS4kb24oJyRkZXN0cm95JywgZnVuY3Rpb24oKSB7CiAgICAgICogICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGludGVydmFsIGlzIGRlc3Ryb3llZCB0b28KICAgICAgKiAgICAgICAgICAgICAkc2NvcGUuc3RvcEZpZ2h0KCk7CiAgICAgICogICAgICAgICAgIH0pOwogICAgICAqICAgICAgICAgfV0pCiAgICAgICogICAgICAgLy8gUmVnaXN0ZXIgdGhlICdteUN1cnJlbnRUaW1lJyBkaXJlY3RpdmUgZmFjdG9yeSBtZXRob2QuCiAgICAgICogICAgICAgLy8gV2UgaW5qZWN0ICRpbnRlcnZhbCBhbmQgZGF0ZUZpbHRlciBzZXJ2aWNlIHNpbmNlIHRoZSBmYWN0b3J5IG1ldGhvZCBpcyBESS4KICAgICAgKiAgICAgICAuZGlyZWN0aXZlKCdteUN1cnJlbnRUaW1lJywgWyckaW50ZXJ2YWwnLCAnZGF0ZUZpbHRlcicsCiAgICAgICogICAgICAgICBmdW5jdGlvbigkaW50ZXJ2YWwsIGRhdGVGaWx0ZXIpIHsKICAgICAgKiAgICAgICAgICAgLy8gcmV0dXJuIHRoZSBkaXJlY3RpdmUgbGluayBmdW5jdGlvbi4gKGNvbXBpbGUgZnVuY3Rpb24gbm90IG5lZWRlZCkKICAgICAgKiAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRycykgewogICAgICAqICAgICAgICAgICAgIHZhciBmb3JtYXQsICAvLyBkYXRlIGZvcm1hdAogICAgICAqICAgICAgICAgICAgICAgICBzdG9wVGltZTsgLy8gc28gdGhhdCB3ZSBjYW4gY2FuY2VsIHRoZSB0aW1lIHVwZGF0ZXMKICAgICAgKgogICAgICAqICAgICAgICAgICAgIC8vIHVzZWQgdG8gdXBkYXRlIHRoZSBVSQogICAgICAqICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRpbWUoKSB7CiAgICAgICogICAgICAgICAgICAgICBlbGVtZW50LnRleHQoZGF0ZUZpbHRlcihuZXcgRGF0ZSgpLCBmb3JtYXQpKTsKICAgICAgKiAgICAgICAgICAgICB9CiAgICAgICoKICAgICAgKiAgICAgICAgICAgICAvLyB3YXRjaCB0aGUgZXhwcmVzc2lvbiwgYW5kIHVwZGF0ZSB0aGUgVUkgb24gY2hhbmdlLgogICAgICAqICAgICAgICAgICAgIHNjb3BlLiR3YXRjaChhdHRycy5teUN1cnJlbnRUaW1lLCBmdW5jdGlvbih2YWx1ZSkgewogICAgICAqICAgICAgICAgICAgICAgZm9ybWF0ID0gdmFsdWU7CiAgICAgICogICAgICAgICAgICAgICB1cGRhdGVUaW1lKCk7CiAgICAgICogICAgICAgICAgICAgfSk7CiAgICAgICoKICAgICAgKiAgICAgICAgICAgICBzdG9wVGltZSA9ICRpbnRlcnZhbCh1cGRhdGVUaW1lLCAxMDAwKTsKICAgICAgKgogICAgICAqICAgICAgICAgICAgIC8vIGxpc3RlbiBvbiBET00gZGVzdHJveSAocmVtb3ZhbCkgZXZlbnQsIGFuZCBjYW5jZWwgdGhlIG5leHQgVUkgdXBkYXRlCiAgICAgICogICAgICAgICAgICAgLy8gdG8gcHJldmVudCB1cGRhdGluZyB0aW1lIGFmdGVyIHRoZSBET00gZWxlbWVudCB3YXMgcmVtb3ZlZC4KICAgICAgKiAgICAgICAgICAgICBlbGVtZW50Lm9uKCckZGVzdHJveScsIGZ1bmN0aW9uKCkgewogICAgICAqICAgICAgICAgICAgICAgJGludGVydmFsLmNhbmNlbChzdG9wVGltZSk7CiAgICAgICogICAgICAgICAgICAgfSk7CiAgICAgICogICAgICAgICAgIH0KICAgICAgKiAgICAgICAgIH1dKTsKICAgICAgKiAgIDwvc2NyaXB0PgogICAgICAqCiAgICAgICogICA8ZGl2PgogICAgICAqICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgKiAgICAgICBEYXRlIGZvcm1hdDogPGlucHV0IG5nLW1vZGVsPSJmb3JtYXQiPiA8aHIvPgogICAgICAqICAgICAgIEN1cnJlbnQgdGltZSBpczogPHNwYW4gbXktY3VycmVudC10aW1lPSJmb3JtYXQiPjwvc3Bhbj4KICAgICAgKiAgICAgICA8aHIvPgogICAgICAqICAgICAgIEJsb29kIDEgOiA8Zm9udCBjb2xvcj0ncmVkJz57e2Jsb29kXzF9fTwvZm9udD4KICAgICAgKiAgICAgICBCbG9vZCAyIDogPGZvbnQgY29sb3I9J3JlZCc+e3tibG9vZF8yfX08L2ZvbnQ+CiAgICAgICogICAgICAgPGJ1dHRvbiB0eXBlPSJidXR0b24iIGRhdGEtbmctY2xpY2s9ImZpZ2h0KCkiPkZpZ2h0PC9idXR0b24+CiAgICAgICogICAgICAgPGJ1dHRvbiB0eXBlPSJidXR0b24iIGRhdGEtbmctY2xpY2s9InN0b3BGaWdodCgpIj5TdG9wRmlnaHQ8L2J1dHRvbj4KICAgICAgKiAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgZGF0YS1uZy1jbGljaz0icmVzZXRGaWdodCgpIj5yZXNldEZpZ2h0PC9idXR0b24+CiAgICAgICogICAgIDwvZGl2PgogICAgICAqICAgPC9kaXY+CiAgICAgICoKICAgICAgKiA8L2ZpbGU+CiAgICAgICogPC9leGFtcGxlPgogICAgICAqLwogICAgZnVuY3Rpb24gaW50ZXJ2YWwoZm4sIGRlbGF5LCBjb3VudCwgaW52b2tlQXBwbHkpIHsKICAgICAgdmFyIHNldEludGVydmFsID0gJHdpbmRvdy5zZXRJbnRlcnZhbCwKICAgICAgICAgIGNsZWFySW50ZXJ2YWwgPSAkd2luZG93LmNsZWFySW50ZXJ2YWwsCiAgICAgICAgICBpdGVyYXRpb24gPSAwLAogICAgICAgICAgc2tpcEFwcGx5ID0gKGlzRGVmaW5lZChpbnZva2VBcHBseSkgJiYgIWludm9rZUFwcGx5KSwKICAgICAgICAgIGRlZmVycmVkID0gKHNraXBBcHBseSA/ICQkcSA6ICRxKS5kZWZlcigpLAogICAgICAgICAgcHJvbWlzZSA9IGRlZmVycmVkLnByb21pc2U7CgogICAgICBjb3VudCA9IGlzRGVmaW5lZChjb3VudCkgPyBjb3VudCA6IDA7CgogICAgICBwcm9taXNlLnRoZW4obnVsbCwgbnVsbCwgZm4pOwoKICAgICAgcHJvbWlzZS4kJGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiB0aWNrKCkgewogICAgICAgIGRlZmVycmVkLm5vdGlmeShpdGVyYXRpb24rKyk7CgogICAgICAgIGlmIChjb3VudCA+IDAgJiYgaXRlcmF0aW9uID49IGNvdW50KSB7CiAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKGl0ZXJhdGlvbik7CiAgICAgICAgICBjbGVhckludGVydmFsKHByb21pc2UuJCRpbnRlcnZhbElkKTsKICAgICAgICAgIGRlbGV0ZSBpbnRlcnZhbHNbcHJvbWlzZS4kJGludGVydmFsSWRdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFza2lwQXBwbHkpICRyb290U2NvcGUuJGFwcGx5KCk7CgogICAgICB9LCBkZWxheSk7CgogICAgICBpbnRlcnZhbHNbcHJvbWlzZS4kJGludGVydmFsSWRdID0gZGVmZXJyZWQ7CgogICAgICByZXR1cm4gcHJvbWlzZTsKICAgIH0KCgogICAgIC8qKgogICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgKiBAbmFtZSAkaW50ZXJ2YWwjY2FuY2VsCiAgICAgICoKICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgKiBDYW5jZWxzIGEgdGFzayBhc3NvY2lhdGVkIHdpdGggdGhlIGBwcm9taXNlYC4KICAgICAgKgogICAgICAqIEBwYXJhbSB7cHJvbWlzZX0gcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgYCRpbnRlcnZhbGAgZnVuY3Rpb24uCiAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB0YXNrIHdhcyBzdWNjZXNzZnVsbHkgY2FuY2VsZWQuCiAgICAgICovCiAgICBpbnRlcnZhbC5jYW5jZWwgPSBmdW5jdGlvbihwcm9taXNlKSB7CiAgICAgIGlmIChwcm9taXNlICYmIHByb21pc2UuJCRpbnRlcnZhbElkIGluIGludGVydmFscykgewogICAgICAgIGludGVydmFsc1twcm9taXNlLiQkaW50ZXJ2YWxJZF0ucmVqZWN0KCdjYW5jZWxlZCcpOwogICAgICAgICR3aW5kb3cuY2xlYXJJbnRlcnZhbChwcm9taXNlLiQkaW50ZXJ2YWxJZCk7CiAgICAgICAgZGVsZXRlIGludGVydmFsc1twcm9taXNlLiQkaW50ZXJ2YWxJZF07CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKCiAgICByZXR1cm4gaW50ZXJ2YWw7CiAgfV07Cn0KCi8qKgogKiBAbmdkb2Mgc2VydmljZQogKiBAbmFtZSAkbG9jYWxlCiAqCiAqIEBkZXNjcmlwdGlvbgogKiAkbG9jYWxlIHNlcnZpY2UgcHJvdmlkZXMgbG9jYWxpemF0aW9uIHJ1bGVzIGZvciB2YXJpb3VzIEFuZ3VsYXIgY29tcG9uZW50cy4gQXMgb2YgcmlnaHQgbm93IHRoZQogKiBvbmx5IHB1YmxpYyBhcGkgaXM6CiAqCiAqICogYGlkYCDigD8gYHtzdHJpbmd9YCDigD8gbG9jYWxlIGlkIGZvcm1hdHRlZCBhcyBgbGFuZ3VhZ2VJZC1jb3VudHJ5SWRgIChlLmcuIGBlbi11c2ApCiAqLwpmdW5jdGlvbiAkTG9jYWxlUHJvdmlkZXIoKSB7CiAgdGhpcy4kZ2V0ID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gewogICAgICBpZDogJ2VuLXVzJywKCiAgICAgIE5VTUJFUl9GT1JNQVRTOiB7CiAgICAgICAgREVDSU1BTF9TRVA6ICcuJywKICAgICAgICBHUk9VUF9TRVA6ICcsJywKICAgICAgICBQQVRURVJOUzogWwogICAgICAgICAgeyAvLyBEZWNpbWFsIFBhdHRlcm4KICAgICAgICAgICAgbWluSW50OiAxLAogICAgICAgICAgICBtaW5GcmFjOiAwLAogICAgICAgICAgICBtYXhGcmFjOiAzLAogICAgICAgICAgICBwb3NQcmU6ICcnLAogICAgICAgICAgICBwb3NTdWY6ICcnLAogICAgICAgICAgICBuZWdQcmU6ICctJywKICAgICAgICAgICAgbmVnU3VmOiAnJywKICAgICAgICAgICAgZ1NpemU6IDMsCiAgICAgICAgICAgIGxnU2l6ZTogMwogICAgICAgICAgfSx7IC8vQ3VycmVuY3kgUGF0dGVybgogICAgICAgICAgICBtaW5JbnQ6IDEsCiAgICAgICAgICAgIG1pbkZyYWM6IDIsCiAgICAgICAgICAgIG1heEZyYWM6IDIsCiAgICAgICAgICAgIHBvc1ByZTogJ1x1MDBBNCcsCiAgICAgICAgICAgIHBvc1N1ZjogJycsCiAgICAgICAgICAgIG5lZ1ByZTogJyhcdTAwQTQnLAogICAgICAgICAgICBuZWdTdWY6ICcpJywKICAgICAgICAgICAgZ1NpemU6IDMsCiAgICAgICAgICAgIGxnU2l6ZTogMwogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgQ1VSUkVOQ1lfU1lNOiAnJCcKICAgICAgfSwKCiAgICAgIERBVEVUSU1FX0ZPUk1BVFM6IHsKICAgICAgICBNT05USDoKICAgICAgICAgICAgJ0phbnVhcnksRmVicnVhcnksTWFyY2gsQXByaWwsTWF5LEp1bmUsSnVseSxBdWd1c3QsU2VwdGVtYmVyLE9jdG9iZXIsTm92ZW1iZXIsRGVjZW1iZXInCiAgICAgICAgICAgIC5zcGxpdCgnLCcpLAogICAgICAgIFNIT1JUTU9OVEg6ICAnSmFuLEZlYixNYXIsQXByLE1heSxKdW4sSnVsLEF1ZyxTZXAsT2N0LE5vdixEZWMnLnNwbGl0KCcsJyksCiAgICAgICAgREFZOiAnU3VuZGF5LE1vbmRheSxUdWVzZGF5LFdlZG5lc2RheSxUaHVyc2RheSxGcmlkYXksU2F0dXJkYXknLnNwbGl0KCcsJyksCiAgICAgICAgU0hPUlREQVk6ICdTdW4sTW9uLFR1ZSxXZWQsVGh1LEZyaSxTYXQnLnNwbGl0KCcsJyksCiAgICAgICAgQU1QTVM6IFsnQU0nLCdQTSddLAogICAgICAgIG1lZGl1bTogJ01NTSBkLCB5IGg6bW06c3MgYScsCiAgICAgICAgJ3Nob3J0JzogJ00vZC95eSBoOm1tIGEnLAogICAgICAgIGZ1bGxEYXRlOiAnRUVFRSwgTU1NTSBkLCB5JywKICAgICAgICBsb25nRGF0ZTogJ01NTU0gZCwgeScsCiAgICAgICAgbWVkaXVtRGF0ZTogJ01NTSBkLCB5JywKICAgICAgICBzaG9ydERhdGU6ICdNL2QveXknLAogICAgICAgIG1lZGl1bVRpbWU6ICdoOm1tOnNzIGEnLAogICAgICAgIHNob3J0VGltZTogJ2g6bW0gYScKICAgICAgfSwKCiAgICAgIHBsdXJhbENhdDogZnVuY3Rpb24obnVtKSB7CiAgICAgICAgaWYgKG51bSA9PT0gMSkgewogICAgICAgICAgcmV0dXJuICdvbmUnOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJ290aGVyJzsKICAgICAgfQogICAgfTsKICB9Owp9Cgp2YXIgUEFUSF9NQVRDSCA9IC9eKFteXD8jXSopKFw/KFteI10qKSk/KCMoLiopKT8kLywKICAgIERFRkFVTFRfUE9SVFMgPSB7J2h0dHAnOiA4MCwgJ2h0dHBzJzogNDQzLCAnZnRwJzogMjF9Owp2YXIgJGxvY2F0aW9uTWluRXJyID0gbWluRXJyKCckbG9jYXRpb24nKTsKCgovKioKICogRW5jb2RlIHBhdGggdXNpbmcgZW5jb2RlVXJpU2VnbWVudCwgaWdub3JpbmcgZm9yd2FyZCBzbGFzaGVzCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFBhdGggdG8gZW5jb2RlCiAqIEByZXR1cm5zIHtzdHJpbmd9CiAqLwpmdW5jdGlvbiBlbmNvZGVQYXRoKHBhdGgpIHsKICB2YXIgc2VnbWVudHMgPSBwYXRoLnNwbGl0KCcvJyksCiAgICAgIGkgPSBzZWdtZW50cy5sZW5ndGg7CgogIHdoaWxlIChpLS0pIHsKICAgIHNlZ21lbnRzW2ldID0gZW5jb2RlVXJpU2VnbWVudChzZWdtZW50c1tpXSk7CiAgfQoKICByZXR1cm4gc2VnbWVudHMuam9pbignLycpOwp9CgpmdW5jdGlvbiBwYXJzZUFic29sdXRlVXJsKGFic29sdXRlVXJsLCBsb2NhdGlvbk9iaikgewogIHZhciBwYXJzZWRVcmwgPSB1cmxSZXNvbHZlKGFic29sdXRlVXJsKTsKCiAgbG9jYXRpb25PYmouJCRwcm90b2NvbCA9IHBhcnNlZFVybC5wcm90b2NvbDsKICBsb2NhdGlvbk9iai4kJGhvc3QgPSBwYXJzZWRVcmwuaG9zdG5hbWU7CiAgbG9jYXRpb25PYmouJCRwb3J0ID0gaW50KHBhcnNlZFVybC5wb3J0KSB8fCBERUZBVUxUX1BPUlRTW3BhcnNlZFVybC5wcm90b2NvbF0gfHwgbnVsbDsKfQoKCmZ1bmN0aW9uIHBhcnNlQXBwVXJsKHJlbGF0aXZlVXJsLCBsb2NhdGlvbk9iaikgewogIHZhciBwcmVmaXhlZCA9IChyZWxhdGl2ZVVybC5jaGFyQXQoMCkgIT09ICcvJyk7CiAgaWYgKHByZWZpeGVkKSB7CiAgICByZWxhdGl2ZVVybCA9ICcvJyArIHJlbGF0aXZlVXJsOwogIH0KICB2YXIgbWF0Y2ggPSB1cmxSZXNvbHZlKHJlbGF0aXZlVXJsKTsKICBsb2NhdGlvbk9iai4kJHBhdGggPSBkZWNvZGVVUklDb21wb25lbnQocHJlZml4ZWQgJiYgbWF0Y2gucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycgPwogICAgICBtYXRjaC5wYXRobmFtZS5zdWJzdHJpbmcoMSkgOiBtYXRjaC5wYXRobmFtZSk7CiAgbG9jYXRpb25PYmouJCRzZWFyY2ggPSBwYXJzZUtleVZhbHVlKG1hdGNoLnNlYXJjaCk7CiAgbG9jYXRpb25PYmouJCRoYXNoID0gZGVjb2RlVVJJQ29tcG9uZW50KG1hdGNoLmhhc2gpOwoKICAvLyBtYWtlIHN1cmUgcGF0aCBzdGFydHMgd2l0aCAnLyc7CiAgaWYgKGxvY2F0aW9uT2JqLiQkcGF0aCAmJiBsb2NhdGlvbk9iai4kJHBhdGguY2hhckF0KDApICE9ICcvJykgewogICAgbG9jYXRpb25PYmouJCRwYXRoID0gJy8nICsgbG9jYXRpb25PYmouJCRwYXRoOwogIH0KfQoKCi8qKgogKgogKiBAcGFyYW0ge3N0cmluZ30gYmVnaW4KICogQHBhcmFtIHtzdHJpbmd9IHdob2xlCiAqIEByZXR1cm5zIHtzdHJpbmd9IHJldHVybnMgdGV4dCBmcm9tIHdob2xlIGFmdGVyIGJlZ2luIG9yIHVuZGVmaW5lZCBpZiBpdCBkb2VzIG5vdCBiZWdpbiB3aXRoCiAqICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkIHN0cmluZy4KICovCmZ1bmN0aW9uIGJlZ2luc1dpdGgoYmVnaW4sIHdob2xlKSB7CiAgaWYgKHdob2xlLmluZGV4T2YoYmVnaW4pID09PSAwKSB7CiAgICByZXR1cm4gd2hvbGUuc3Vic3RyKGJlZ2luLmxlbmd0aCk7CiAgfQp9CgoKZnVuY3Rpb24gc3RyaXBIYXNoKHVybCkgewogIHZhciBpbmRleCA9IHVybC5pbmRleE9mKCcjJyk7CiAgcmV0dXJuIGluZGV4ID09IC0xID8gdXJsIDogdXJsLnN1YnN0cigwLCBpbmRleCk7Cn0KCmZ1bmN0aW9uIHRyaW1FbXB0eUhhc2godXJsKSB7CiAgcmV0dXJuIHVybC5yZXBsYWNlKC8oIy4rKXwjJC8sICckMScpOwp9CgoKZnVuY3Rpb24gc3RyaXBGaWxlKHVybCkgewogIHJldHVybiB1cmwuc3Vic3RyKDAsIHN0cmlwSGFzaCh1cmwpLmxhc3RJbmRleE9mKCcvJykgKyAxKTsKfQoKLyogcmV0dXJuIHRoZSBzZXJ2ZXIgb25seSAoc2NoZW1lOi8vaG9zdDpwb3J0KSAqLwpmdW5jdGlvbiBzZXJ2ZXJCYXNlKHVybCkgewogIHJldHVybiB1cmwuc3Vic3RyaW5nKDAsIHVybC5pbmRleE9mKCcvJywgdXJsLmluZGV4T2YoJy8vJykgKyAyKSk7Cn0KCgovKioKICogTG9jYXRpb25IdG1sNVVybCByZXByZXNlbnRzIGFuIHVybAogKiBUaGlzIG9iamVjdCBpcyBleHBvc2VkIGFzICRsb2NhdGlvbiBzZXJ2aWNlIHdoZW4gSFRNTDUgbW9kZSBpcyBlbmFibGVkIGFuZCBzdXBwb3J0ZWQKICoKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7c3RyaW5nfSBhcHBCYXNlIGFwcGxpY2F0aW9uIGJhc2UgVVJMCiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUHJlZml4IHVybCBwYXRoIHByZWZpeAogKi8KZnVuY3Rpb24gTG9jYXRpb25IdG1sNVVybChhcHBCYXNlLCBiYXNlUHJlZml4KSB7CiAgdGhpcy4kJGh0bWw1ID0gdHJ1ZTsKICBiYXNlUHJlZml4ID0gYmFzZVByZWZpeCB8fCAnJzsKICB2YXIgYXBwQmFzZU5vRmlsZSA9IHN0cmlwRmlsZShhcHBCYXNlKTsKICBwYXJzZUFic29sdXRlVXJsKGFwcEJhc2UsIHRoaXMpOwoKCiAgLyoqCiAgICogUGFyc2UgZ2l2ZW4gaHRtbDUgKHJlZ3VsYXIpIHVybCBzdHJpbmcgaW50byBwcm9wZXJ0aWVzCiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBIVE1MNSB1cmwKICAgKiBAcHJpdmF0ZQogICAqLwogIHRoaXMuJCRwYXJzZSA9IGZ1bmN0aW9uKHVybCkgewogICAgdmFyIHBhdGhVcmwgPSBiZWdpbnNXaXRoKGFwcEJhc2VOb0ZpbGUsIHVybCk7CiAgICBpZiAoIWlzU3RyaW5nKHBhdGhVcmwpKSB7CiAgICAgIHRocm93ICRsb2NhdGlvbk1pbkVycignaXB0aHByZngnLCAnSW52YWxpZCB1cmwgInswfSIsIG1pc3NpbmcgcGF0aCBwcmVmaXggInsxfSIuJywgdXJsLAogICAgICAgICAgYXBwQmFzZU5vRmlsZSk7CiAgICB9CgogICAgcGFyc2VBcHBVcmwocGF0aFVybCwgdGhpcyk7CgogICAgaWYgKCF0aGlzLiQkcGF0aCkgewogICAgICB0aGlzLiQkcGF0aCA9ICcvJzsKICAgIH0KCiAgICB0aGlzLiQkY29tcG9zZSgpOwogIH07CgogIC8qKgogICAqIENvbXBvc2UgdXJsIGFuZCB1cGRhdGUgYGFic1VybGAgcHJvcGVydHkKICAgKiBAcHJpdmF0ZQogICAqLwogIHRoaXMuJCRjb21wb3NlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgc2VhcmNoID0gdG9LZXlWYWx1ZSh0aGlzLiQkc2VhcmNoKSwKICAgICAgICBoYXNoID0gdGhpcy4kJGhhc2ggPyAnIycgKyBlbmNvZGVVcmlTZWdtZW50KHRoaXMuJCRoYXNoKSA6ICcnOwoKICAgIHRoaXMuJCR1cmwgPSBlbmNvZGVQYXRoKHRoaXMuJCRwYXRoKSArIChzZWFyY2ggPyAnPycgKyBzZWFyY2ggOiAnJykgKyBoYXNoOwogICAgdGhpcy4kJGFic1VybCA9IGFwcEJhc2VOb0ZpbGUgKyB0aGlzLiQkdXJsLnN1YnN0cigxKTsgLy8gZmlyc3QgY2hhciBpcyBhbHdheXMgJy8nCiAgfTsKCiAgdGhpcy4kJHBhcnNlTGlua1VybCA9IGZ1bmN0aW9uKHVybCwgcmVsSHJlZikgewogICAgaWYgKHJlbEhyZWYgJiYgcmVsSHJlZlswXSA9PT0gJyMnKSB7CiAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgbGlua3MgdG8gaGFzaCBmcmFnbWVudHM6CiAgICAgIC8vIGtlZXAgdGhlIG9sZCB1cmwgYW5kIG9ubHkgcmVwbGFjZSB0aGUgaGFzaCBmcmFnbWVudAogICAgICB0aGlzLmhhc2gocmVsSHJlZi5zbGljZSgxKSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgdmFyIGFwcFVybCwgcHJldkFwcFVybDsKICAgIHZhciByZXdyaXR0ZW5Vcmw7CgogICAgaWYgKChhcHBVcmwgPSBiZWdpbnNXaXRoKGFwcEJhc2UsIHVybCkpICE9PSB1bmRlZmluZWQpIHsKICAgICAgcHJldkFwcFVybCA9IGFwcFVybDsKICAgICAgaWYgKChhcHBVcmwgPSBiZWdpbnNXaXRoKGJhc2VQcmVmaXgsIGFwcFVybCkpICE9PSB1bmRlZmluZWQpIHsKICAgICAgICByZXdyaXR0ZW5VcmwgPSBhcHBCYXNlTm9GaWxlICsgKGJlZ2luc1dpdGgoJy8nLCBhcHBVcmwpIHx8IGFwcFVybCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV3cml0dGVuVXJsID0gYXBwQmFzZSArIHByZXZBcHBVcmw7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKGFwcFVybCA9IGJlZ2luc1dpdGgoYXBwQmFzZU5vRmlsZSwgdXJsKSkgIT09IHVuZGVmaW5lZCkgewogICAgICByZXdyaXR0ZW5VcmwgPSBhcHBCYXNlTm9GaWxlICsgYXBwVXJsOwogICAgfSBlbHNlIGlmIChhcHBCYXNlTm9GaWxlID09IHVybCArICcvJykgewogICAgICByZXdyaXR0ZW5VcmwgPSBhcHBCYXNlTm9GaWxlOwogICAgfQogICAgaWYgKHJld3JpdHRlblVybCkgewogICAgICB0aGlzLiQkcGFyc2UocmV3cml0dGVuVXJsKTsKICAgIH0KICAgIHJldHVybiAhIXJld3JpdHRlblVybDsKICB9Owp9CgoKLyoqCiAqIExvY2F0aW9uSGFzaGJhbmdVcmwgcmVwcmVzZW50cyB1cmwKICogVGhpcyBvYmplY3QgaXMgZXhwb3NlZCBhcyAkbG9jYXRpb24gc2VydmljZSB3aGVuIGRldmVsb3BlciBkb2Vzbid0IG9wdCBpbnRvIGh0bWw1IG1vZGUuCiAqIEl0IGFsc28gc2VydmVzIGFzIHRoZSBiYXNlIGNsYXNzIGZvciBodG1sNSBtb2RlIGZhbGxiYWNrIG9uIGxlZ2FjeSBicm93c2Vycy4KICoKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7c3RyaW5nfSBhcHBCYXNlIGFwcGxpY2F0aW9uIGJhc2UgVVJMCiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoUHJlZml4IGhhc2hiYW5nIHByZWZpeAogKi8KZnVuY3Rpb24gTG9jYXRpb25IYXNoYmFuZ1VybChhcHBCYXNlLCBoYXNoUHJlZml4KSB7CiAgdmFyIGFwcEJhc2VOb0ZpbGUgPSBzdHJpcEZpbGUoYXBwQmFzZSk7CgogIHBhcnNlQWJzb2x1dGVVcmwoYXBwQmFzZSwgdGhpcyk7CgoKICAvKioKICAgKiBQYXJzZSBnaXZlbiBoYXNoYmFuZyB1cmwgaW50byBwcm9wZXJ0aWVzCiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBIYXNoYmFuZyB1cmwKICAgKiBAcHJpdmF0ZQogICAqLwogIHRoaXMuJCRwYXJzZSA9IGZ1bmN0aW9uKHVybCkgewogICAgdmFyIHdpdGhvdXRCYXNlVXJsID0gYmVnaW5zV2l0aChhcHBCYXNlLCB1cmwpIHx8IGJlZ2luc1dpdGgoYXBwQmFzZU5vRmlsZSwgdXJsKTsKICAgIHZhciB3aXRob3V0SGFzaFVybDsKCiAgICBpZiAod2l0aG91dEJhc2VVcmwuY2hhckF0KDApID09PSAnIycpIHsKCiAgICAgIC8vIFRoZSByZXN0IG9mIHRoZSB1cmwgc3RhcnRzIHdpdGggYSBoYXNoIHNvIHdlIGhhdmUKICAgICAgLy8gZ290IGVpdGhlciBhIGhhc2hiYW5nIHBhdGggb3IgYSBwbGFpbiBoYXNoIGZyYWdtZW50CiAgICAgIHdpdGhvdXRIYXNoVXJsID0gYmVnaW5zV2l0aChoYXNoUHJlZml4LCB3aXRob3V0QmFzZVVybCk7CiAgICAgIGlmIChpc1VuZGVmaW5lZCh3aXRob3V0SGFzaFVybCkpIHsKICAgICAgICAvLyBUaGVyZSB3YXMgbm8gaGFzaGJhbmcgcHJlZml4IHNvIHdlIGp1c3QgaGF2ZSBhIGhhc2ggZnJhZ21lbnQKICAgICAgICB3aXRob3V0SGFzaFVybCA9IHdpdGhvdXRCYXNlVXJsOwogICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgLy8gVGhlcmUgd2FzIG5vIGhhc2hiYW5nIHBhdGggbm9yIGhhc2ggZnJhZ21lbnQ6CiAgICAgIC8vIElmIHdlIGFyZSBpbiBIVE1MNSBtb2RlIHdlIHVzZSB3aGF0IGlzIGxlZnQgYXMgdGhlIHBhdGg7CiAgICAgIC8vIE90aGVyd2lzZSB3ZSBpZ25vcmUgd2hhdCBpcyBsZWZ0CiAgICAgIHdpdGhvdXRIYXNoVXJsID0gdGhpcy4kJGh0bWw1ID8gd2l0aG91dEJhc2VVcmwgOiAnJzsKICAgIH0KCiAgICBwYXJzZUFwcFVybCh3aXRob3V0SGFzaFVybCwgdGhpcyk7CgogICAgdGhpcy4kJHBhdGggPSByZW1vdmVXaW5kb3dzRHJpdmVOYW1lKHRoaXMuJCRwYXRoLCB3aXRob3V0SGFzaFVybCwgYXBwQmFzZSk7CgogICAgdGhpcy4kJGNvbXBvc2UoKTsKCiAgICAvKgogICAgICogSW4gV2luZG93cywgb24gYW4gYW5jaG9yIG5vZGUgb24gZG9jdW1lbnRzIGxvYWRlZCBmcm9tCiAgICAgKiB0aGUgZmlsZXN5c3RlbSwgdGhlIGJyb3dzZXIgd2lsbCByZXR1cm4gYSBwYXRobmFtZQogICAgICogcHJlZml4ZWQgd2l0aCB0aGUgZHJpdmUgbmFtZSAoJy9DOi9wYXRoJykgd2hlbiBhCiAgICAgKiBwYXRobmFtZSB3aXRob3V0IGEgZHJpdmUgaXMgc2V0OgogICAgICogICogYS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCAnL2ZvbycpCiAgICAgKiAgICogYS5wYXRobmFtZSA9PT0gJy9DOi9mb28nIC8vdHJ1ZQogICAgICoKICAgICAqIEluc2lkZSBvZiBBbmd1bGFyLCB3ZSdyZSBhbHdheXMgdXNpbmcgcGF0aG5hbWVzIHRoYXQKICAgICAqIGRvIG5vdCBpbmNsdWRlIGRyaXZlIG5hbWVzIGZvciByb3V0aW5nLgogICAgICovCiAgICBmdW5jdGlvbiByZW1vdmVXaW5kb3dzRHJpdmVOYW1lKHBhdGgsIHVybCwgYmFzZSkgewogICAgICAvKgogICAgICBNYXRjaGVzIHBhdGhzIGZvciBmaWxlIHByb3RvY29sIG9uIHdpbmRvd3MsCiAgICAgIHN1Y2ggYXMgL0M6L2Zvby9iYXIsIGFuZCBjYXB0dXJlcyBvbmx5IC9mb28vYmFyLgogICAgICAqLwogICAgICB2YXIgd2luZG93c0ZpbGVQYXRoRXhwID0gL15cL1tBLVpdOihcLy4qKS87CgogICAgICB2YXIgZmlyc3RQYXRoU2VnbWVudE1hdGNoOwoKICAgICAgLy9HZXQgdGhlIHJlbGF0aXZlIHBhdGggZnJvbSB0aGUgaW5wdXQgVVJMLgogICAgICBpZiAodXJsLmluZGV4T2YoYmFzZSkgPT09IDApIHsKICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShiYXNlLCAnJyk7CiAgICAgIH0KCiAgICAgIC8vIFRoZSBpbnB1dCBVUkwgaW50ZW50aW9uYWxseSBjb250YWlucyBhIGZpcnN0IHBhdGggc2VnbWVudCB0aGF0IGVuZHMgd2l0aCBhIGNvbG9uLgogICAgICBpZiAod2luZG93c0ZpbGVQYXRoRXhwLmV4ZWModXJsKSkgewogICAgICAgIHJldHVybiBwYXRoOwogICAgICB9CgogICAgICBmaXJzdFBhdGhTZWdtZW50TWF0Y2ggPSB3aW5kb3dzRmlsZVBhdGhFeHAuZXhlYyhwYXRoKTsKICAgICAgcmV0dXJuIGZpcnN0UGF0aFNlZ21lbnRNYXRjaCA/IGZpcnN0UGF0aFNlZ21lbnRNYXRjaFsxXSA6IHBhdGg7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ29tcG9zZSBoYXNoYmFuZyB1cmwgYW5kIHVwZGF0ZSBgYWJzVXJsYCBwcm9wZXJ0eQogICAqIEBwcml2YXRlCiAgICovCiAgdGhpcy4kJGNvbXBvc2UgPSBmdW5jdGlvbigpIHsKICAgIHZhciBzZWFyY2ggPSB0b0tleVZhbHVlKHRoaXMuJCRzZWFyY2gpLAogICAgICAgIGhhc2ggPSB0aGlzLiQkaGFzaCA/ICcjJyArIGVuY29kZVVyaVNlZ21lbnQodGhpcy4kJGhhc2gpIDogJyc7CgogICAgdGhpcy4kJHVybCA9IGVuY29kZVBhdGgodGhpcy4kJHBhdGgpICsgKHNlYXJjaCA/ICc/JyArIHNlYXJjaCA6ICcnKSArIGhhc2g7CiAgICB0aGlzLiQkYWJzVXJsID0gYXBwQmFzZSArICh0aGlzLiQkdXJsID8gaGFzaFByZWZpeCArIHRoaXMuJCR1cmwgOiAnJyk7CiAgfTsKCiAgdGhpcy4kJHBhcnNlTGlua1VybCA9IGZ1bmN0aW9uKHVybCwgcmVsSHJlZikgewogICAgaWYgKHN0cmlwSGFzaChhcHBCYXNlKSA9PSBzdHJpcEhhc2godXJsKSkgewogICAgICB0aGlzLiQkcGFyc2UodXJsKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKfQoKCi8qKgogKiBMb2NhdGlvbkhhc2hiYW5nVXJsIHJlcHJlc2VudHMgdXJsCiAqIFRoaXMgb2JqZWN0IGlzIGV4cG9zZWQgYXMgJGxvY2F0aW9uIHNlcnZpY2Ugd2hlbiBodG1sNSBoaXN0b3J5IGFwaSBpcyBlbmFibGVkIGJ1dCB0aGUgYnJvd3NlcgogKiBkb2VzIG5vdCBzdXBwb3J0IGl0LgogKgogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtzdHJpbmd9IGFwcEJhc2UgYXBwbGljYXRpb24gYmFzZSBVUkwKICogQHBhcmFtIHtzdHJpbmd9IGhhc2hQcmVmaXggaGFzaGJhbmcgcHJlZml4CiAqLwpmdW5jdGlvbiBMb2NhdGlvbkhhc2hiYW5nSW5IdG1sNVVybChhcHBCYXNlLCBoYXNoUHJlZml4KSB7CiAgdGhpcy4kJGh0bWw1ID0gdHJ1ZTsKICBMb2NhdGlvbkhhc2hiYW5nVXJsLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CgogIHZhciBhcHBCYXNlTm9GaWxlID0gc3RyaXBGaWxlKGFwcEJhc2UpOwoKICB0aGlzLiQkcGFyc2VMaW5rVXJsID0gZnVuY3Rpb24odXJsLCByZWxIcmVmKSB7CiAgICBpZiAocmVsSHJlZiAmJiByZWxIcmVmWzBdID09PSAnIycpIHsKICAgICAgLy8gc3BlY2lhbCBjYXNlIGZvciBsaW5rcyB0byBoYXNoIGZyYWdtZW50czoKICAgICAgLy8ga2VlcCB0aGUgb2xkIHVybCBhbmQgb25seSByZXBsYWNlIHRoZSBoYXNoIGZyYWdtZW50CiAgICAgIHRoaXMuaGFzaChyZWxIcmVmLnNsaWNlKDEpKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgdmFyIHJld3JpdHRlblVybDsKICAgIHZhciBhcHBVcmw7CgogICAgaWYgKGFwcEJhc2UgPT0gc3RyaXBIYXNoKHVybCkpIHsKICAgICAgcmV3cml0dGVuVXJsID0gdXJsOwogICAgfSBlbHNlIGlmICgoYXBwVXJsID0gYmVnaW5zV2l0aChhcHBCYXNlTm9GaWxlLCB1cmwpKSkgewogICAgICByZXdyaXR0ZW5VcmwgPSBhcHBCYXNlICsgaGFzaFByZWZpeCArIGFwcFVybDsKICAgIH0gZWxzZSBpZiAoYXBwQmFzZU5vRmlsZSA9PT0gdXJsICsgJy8nKSB7CiAgICAgIHJld3JpdHRlblVybCA9IGFwcEJhc2VOb0ZpbGU7CiAgICB9CiAgICBpZiAocmV3cml0dGVuVXJsKSB7CiAgICAgIHRoaXMuJCRwYXJzZShyZXdyaXR0ZW5VcmwpOwogICAgfQogICAgcmV0dXJuICEhcmV3cml0dGVuVXJsOwogIH07CgogIHRoaXMuJCRjb21wb3NlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgc2VhcmNoID0gdG9LZXlWYWx1ZSh0aGlzLiQkc2VhcmNoKSwKICAgICAgICBoYXNoID0gdGhpcy4kJGhhc2ggPyAnIycgKyBlbmNvZGVVcmlTZWdtZW50KHRoaXMuJCRoYXNoKSA6ICcnOwoKICAgIHRoaXMuJCR1cmwgPSBlbmNvZGVQYXRoKHRoaXMuJCRwYXRoKSArIChzZWFyY2ggPyAnPycgKyBzZWFyY2ggOiAnJykgKyBoYXNoOwogICAgLy8gaW5jbHVkZSBoYXNoUHJlZml4IGluICQkYWJzVXJsIHdoZW4gJCR1cmwgaXMgZW1wdHkgc28gSUU4ICYgOSBkbyBub3QgcmVsb2FkIHBhZ2UgYmVjYXVzZSBvZiByZW1vdmFsIG9mICcjJwogICAgdGhpcy4kJGFic1VybCA9IGFwcEJhc2UgKyBoYXNoUHJlZml4ICsgdGhpcy4kJHVybDsKICB9OwoKfQoKCnZhciBsb2NhdGlvblByb3RvdHlwZSA9IHsKCiAgLyoqCiAgICogQXJlIHdlIGluIGh0bWw1IG1vZGU/CiAgICogQHByaXZhdGUKICAgKi8KICAkJGh0bWw1OiBmYWxzZSwKCiAgLyoqCiAgICogSGFzIGFueSBjaGFuZ2UgYmVlbiByZXBsYWNpbmc/CiAgICogQHByaXZhdGUKICAgKi8KICAkJHJlcGxhY2U6IGZhbHNlLAoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGxvY2F0aW9uI2Fic1VybAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGhpcyBtZXRob2QgaXMgZ2V0dGVyIG9ubHkuCiAgICoKICAgKiBSZXR1cm4gZnVsbCB1cmwgcmVwcmVzZW50YXRpb24gd2l0aCBhbGwgc2VnbWVudHMgZW5jb2RlZCBhY2NvcmRpbmcgdG8gcnVsZXMgc3BlY2lmaWVkIGluCiAgICogW1JGQyAzOTg2XShodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzOTg2LnR4dCkuCiAgICoKICAgKgogICAqIGBgYGpzCiAgICogLy8gZ2l2ZW4gdXJsIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvCiAgICogdmFyIGFic1VybCA9ICRsb2NhdGlvbi5hYnNVcmwoKTsKICAgKiAvLyA9PiAiaHR0cDovL2V4YW1wbGUuY29tLyMvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG8iCiAgICogYGBgCiAgICoKICAgKiBAcmV0dXJuIHtzdHJpbmd9IGZ1bGwgdXJsCiAgICovCiAgYWJzVXJsOiBsb2NhdGlvbkdldHRlcignJCRhYnNVcmwnKSwKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2NhdGlvbiN1cmwKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRoaXMgbWV0aG9kIGlzIGdldHRlciAvIHNldHRlci4KICAgKgogICAqIFJldHVybiB1cmwgKGUuZy4gYC9wYXRoP2E9YiNoYXNoYCkgd2hlbiBjYWxsZWQgd2l0aG91dCBhbnkgcGFyYW1ldGVyLgogICAqCiAgICogQ2hhbmdlIHBhdGgsIHNlYXJjaCBhbmQgaGFzaCwgd2hlbiBjYWxsZWQgd2l0aCBwYXJhbWV0ZXIgYW5kIHJldHVybiBgJGxvY2F0aW9uYC4KICAgKgogICAqCiAgICogYGBganMKICAgKiAvLyBnaXZlbiB1cmwgaHR0cDovL2V4YW1wbGUuY29tLyMvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG8KICAgKiB2YXIgdXJsID0gJGxvY2F0aW9uLnVybCgpOwogICAqIC8vID0+ICIvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG8iCiAgICogYGBgCiAgICoKICAgKiBAcGFyYW0ge3N0cmluZz19IHVybCBOZXcgdXJsIHdpdGhvdXQgYmFzZSBwcmVmaXggKGUuZy4gYC9wYXRoP2E9YiNoYXNoYCkKICAgKiBAcmV0dXJuIHtzdHJpbmd9IHVybAogICAqLwogIHVybDogZnVuY3Rpb24odXJsKSB7CiAgICBpZiAoaXNVbmRlZmluZWQodXJsKSkKICAgICAgcmV0dXJuIHRoaXMuJCR1cmw7CgogICAgdmFyIG1hdGNoID0gUEFUSF9NQVRDSC5leGVjKHVybCk7CiAgICBpZiAobWF0Y2hbMV0gfHwgdXJsID09PSAnJykgdGhpcy5wYXRoKGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFsxXSkpOwogICAgaWYgKG1hdGNoWzJdIHx8IG1hdGNoWzFdIHx8IHVybCA9PT0gJycpIHRoaXMuc2VhcmNoKG1hdGNoWzNdIHx8ICcnKTsKICAgIHRoaXMuaGFzaChtYXRjaFs1XSB8fCAnJyk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2NhdGlvbiNwcm90b2NvbAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGhpcyBtZXRob2QgaXMgZ2V0dGVyIG9ubHkuCiAgICoKICAgKiBSZXR1cm4gcHJvdG9jb2wgb2YgY3VycmVudCB1cmwuCiAgICoKICAgKgogICAqIGBgYGpzCiAgICogLy8gZ2l2ZW4gdXJsIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvCiAgICogdmFyIHByb3RvY29sID0gJGxvY2F0aW9uLnByb3RvY29sKCk7CiAgICogLy8gPT4gImh0dHAiCiAgICogYGBgCiAgICoKICAgKiBAcmV0dXJuIHtzdHJpbmd9IHByb3RvY29sIG9mIGN1cnJlbnQgdXJsCiAgICovCiAgcHJvdG9jb2w6IGxvY2F0aW9uR2V0dGVyKCckJHByb3RvY29sJyksCgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkbG9jYXRpb24jaG9zdAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGhpcyBtZXRob2QgaXMgZ2V0dGVyIG9ubHkuCiAgICoKICAgKiBSZXR1cm4gaG9zdCBvZiBjdXJyZW50IHVybC4KICAgKgogICAqCiAgICogYGBganMKICAgKiAvLyBnaXZlbiB1cmwgaHR0cDovL2V4YW1wbGUuY29tLyMvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG8KICAgKiB2YXIgaG9zdCA9ICRsb2NhdGlvbi5ob3N0KCk7CiAgICogLy8gPT4gImV4YW1wbGUuY29tIgogICAqIGBgYAogICAqCiAgICogQHJldHVybiB7c3RyaW5nfSBob3N0IG9mIGN1cnJlbnQgdXJsLgogICAqLwogIGhvc3Q6IGxvY2F0aW9uR2V0dGVyKCckJGhvc3QnKSwKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2NhdGlvbiNwb3J0CiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBUaGlzIG1ldGhvZCBpcyBnZXR0ZXIgb25seS4KICAgKgogICAqIFJldHVybiBwb3J0IG9mIGN1cnJlbnQgdXJsLgogICAqCiAgICoKICAgKiBgYGBqcwogICAqIC8vIGdpdmVuIHVybCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94bwogICAqIHZhciBwb3J0ID0gJGxvY2F0aW9uLnBvcnQoKTsKICAgKiAvLyA9PiA4MAogICAqIGBgYAogICAqCiAgICogQHJldHVybiB7TnVtYmVyfSBwb3J0CiAgICovCiAgcG9ydDogbG9jYXRpb25HZXR0ZXIoJyQkcG9ydCcpLAoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGxvY2F0aW9uI3BhdGgKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRoaXMgbWV0aG9kIGlzIGdldHRlciAvIHNldHRlci4KICAgKgogICAqIFJldHVybiBwYXRoIG9mIGN1cnJlbnQgdXJsIHdoZW4gY2FsbGVkIHdpdGhvdXQgYW55IHBhcmFtZXRlci4KICAgKgogICAqIENoYW5nZSBwYXRoIHdoZW4gY2FsbGVkIHdpdGggcGFyYW1ldGVyIGFuZCByZXR1cm4gYCRsb2NhdGlvbmAuCiAgICoKICAgKiBOb3RlOiBQYXRoIHNob3VsZCBhbHdheXMgYmVnaW4gd2l0aCBmb3J3YXJkIHNsYXNoICgvKSwgdGhpcyBtZXRob2Qgd2lsbCBhZGQgdGhlIGZvcndhcmQgc2xhc2gKICAgKiBpZiBpdCBpcyBtaXNzaW5nLgogICAqCiAgICoKICAgKiBgYGBqcwogICAqIC8vIGdpdmVuIHVybCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94bwogICAqIHZhciBwYXRoID0gJGxvY2F0aW9uLnBhdGgoKTsKICAgKiAvLyA9PiAiL3NvbWUvcGF0aCIKICAgKiBgYGAKICAgKgogICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gcGF0aCBOZXcgcGF0aAogICAqIEByZXR1cm4ge3N0cmluZ30gcGF0aAogICAqLwogIHBhdGg6IGxvY2F0aW9uR2V0dGVyU2V0dGVyKCckJHBhdGgnLCBmdW5jdGlvbihwYXRoKSB7CiAgICBwYXRoID0gcGF0aCAhPT0gbnVsbCA/IHBhdGgudG9TdHJpbmcoKSA6ICcnOwogICAgcmV0dXJuIHBhdGguY2hhckF0KDApID09ICcvJyA/IHBhdGggOiAnLycgKyBwYXRoOwogIH0pLAoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGxvY2F0aW9uI3NlYXJjaAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGhpcyBtZXRob2QgaXMgZ2V0dGVyIC8gc2V0dGVyLgogICAqCiAgICogUmV0dXJuIHNlYXJjaCBwYXJ0IChhcyBvYmplY3QpIG9mIGN1cnJlbnQgdXJsIHdoZW4gY2FsbGVkIHdpdGhvdXQgYW55IHBhcmFtZXRlci4KICAgKgogICAqIENoYW5nZSBzZWFyY2ggcGFydCB3aGVuIGNhbGxlZCB3aXRoIHBhcmFtZXRlciBhbmQgcmV0dXJuIGAkbG9jYXRpb25gLgogICAqCiAgICoKICAgKiBgYGBqcwogICAqIC8vIGdpdmVuIHVybCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94bwogICAqIHZhciBzZWFyY2hPYmplY3QgPSAkbG9jYXRpb24uc2VhcmNoKCk7CiAgICogLy8gPT4ge2ZvbzogJ2JhcicsIGJhejogJ3hveG8nfQogICAqCiAgICogLy8gc2V0IGZvbyB0byAneWlwZWUnCiAgICogJGxvY2F0aW9uLnNlYXJjaCgnZm9vJywgJ3lpcGVlJyk7CiAgICogLy8gJGxvY2F0aW9uLnNlYXJjaCgpID0+IHtmb286ICd5aXBlZScsIGJhejogJ3hveG8nfQogICAqIGBgYAogICAqCiAgICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0LjxzdHJpbmc+fE9iamVjdC48QXJyYXkuPHN0cmluZz4+fSBzZWFyY2ggTmV3IHNlYXJjaCBwYXJhbXMgLSBzdHJpbmcgb3IKICAgKiBoYXNoIG9iamVjdC4KICAgKgogICAqIFdoZW4gY2FsbGVkIHdpdGggYSBzaW5nbGUgYXJndW1lbnQgdGhlIG1ldGhvZCBhY3RzIGFzIGEgc2V0dGVyLCBzZXR0aW5nIHRoZSBgc2VhcmNoYCBjb21wb25lbnQKICAgKiBvZiBgJGxvY2F0aW9uYCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgogICAqCiAgICogSWYgdGhlIGFyZ3VtZW50IGlzIGEgaGFzaCBvYmplY3QgY29udGFpbmluZyBhbiBhcnJheSBvZiB2YWx1ZXMsIHRoZXNlIHZhbHVlcyB3aWxsIGJlIGVuY29kZWQKICAgKiBhcyBkdXBsaWNhdGUgc2VhcmNoIHBhcmFtZXRlcnMgaW4gdGhlIHVybC4KICAgKgogICAqIEBwYXJhbSB7KHN0cmluZ3xOdW1iZXJ8QXJyYXk8c3RyaW5nPnxib29sZWFuKT19IHBhcmFtVmFsdWUgSWYgYHNlYXJjaGAgaXMgYSBzdHJpbmcgb3IgbnVtYmVyLCB0aGVuIGBwYXJhbVZhbHVlYAogICAqIHdpbGwgb3ZlcnJpZGUgb25seSBhIHNpbmdsZSBzZWFyY2ggcHJvcGVydHkuCiAgICoKICAgKiBJZiBgcGFyYW1WYWx1ZWAgaXMgYW4gYXJyYXksIGl0IHdpbGwgb3ZlcnJpZGUgdGhlIHByb3BlcnR5IG9mIHRoZSBgc2VhcmNoYCBjb21wb25lbnQgb2YKICAgKiBgJGxvY2F0aW9uYCBzcGVjaWZpZWQgdmlhIHRoZSBmaXJzdCBhcmd1bWVudC4KICAgKgogICAqIElmIGBwYXJhbVZhbHVlYCBpcyBgbnVsbGAsIHRoZSBwcm9wZXJ0eSBzcGVjaWZpZWQgdmlhIHRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGJlIGRlbGV0ZWQuCiAgICoKICAgKiBJZiBgcGFyYW1WYWx1ZWAgaXMgYHRydWVgLCB0aGUgcHJvcGVydHkgc3BlY2lmaWVkIHZpYSB0aGUgZmlyc3QgYXJndW1lbnQgd2lsbCBiZSBhZGRlZCB3aXRoIG5vCiAgICogdmFsdWUgbm9yIHRyYWlsaW5nIGVxdWFsIHNpZ24uCiAgICoKICAgKiBAcmV0dXJuIHtPYmplY3R9IElmIGNhbGxlZCB3aXRoIG5vIGFyZ3VtZW50cyByZXR1cm5zIHRoZSBwYXJzZWQgYHNlYXJjaGAgb2JqZWN0LiBJZiBjYWxsZWQgd2l0aAogICAqIG9uZSBvciBtb3JlIGFyZ3VtZW50cyByZXR1cm5zIGAkbG9jYXRpb25gIG9iamVjdCBpdHNlbGYuCiAgICovCiAgc2VhcmNoOiBmdW5jdGlvbihzZWFyY2gsIHBhcmFtVmFsdWUpIHsKICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkgewogICAgICBjYXNlIDA6CiAgICAgICAgcmV0dXJuIHRoaXMuJCRzZWFyY2g7CiAgICAgIGNhc2UgMToKICAgICAgICBpZiAoaXNTdHJpbmcoc2VhcmNoKSB8fCBpc051bWJlcihzZWFyY2gpKSB7CiAgICAgICAgICBzZWFyY2ggPSBzZWFyY2gudG9TdHJpbmcoKTsKICAgICAgICAgIHRoaXMuJCRzZWFyY2ggPSBwYXJzZUtleVZhbHVlKHNlYXJjaCk7CiAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChzZWFyY2gpKSB7CiAgICAgICAgICBzZWFyY2ggPSBjb3B5KHNlYXJjaCwge30pOwogICAgICAgICAgLy8gcmVtb3ZlIG9iamVjdCB1bmRlZmluZWQgb3IgbnVsbCBwcm9wZXJ0aWVzCiAgICAgICAgICBmb3JFYWNoKHNlYXJjaCwgZnVuY3Rpb24odmFsdWUsIGtleSkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgZGVsZXRlIHNlYXJjaFtrZXldOwogICAgICAgICAgfSk7CgogICAgICAgICAgdGhpcy4kJHNlYXJjaCA9IHNlYXJjaDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhyb3cgJGxvY2F0aW9uTWluRXJyKCdpc3JjaGFyZycsCiAgICAgICAgICAgICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGUgYCRsb2NhdGlvbiNzZWFyY2goKWAgY2FsbCBtdXN0IGJlIGEgc3RyaW5nIG9yIGFuIG9iamVjdC4nKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHBhcmFtVmFsdWUpIHx8IHBhcmFtVmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgIGRlbGV0ZSB0aGlzLiQkc2VhcmNoW3NlYXJjaF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRoaXMuJCRzZWFyY2hbc2VhcmNoXSA9IHBhcmFtVmFsdWU7CiAgICAgICAgfQogICAgfQoKICAgIHRoaXMuJCRjb21wb3NlKCk7CiAgICByZXR1cm4gdGhpczsKICB9LAoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGxvY2F0aW9uI2hhc2gKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRoaXMgbWV0aG9kIGlzIGdldHRlciAvIHNldHRlci4KICAgKgogICAqIFJldHVybiBoYXNoIGZyYWdtZW50IHdoZW4gY2FsbGVkIHdpdGhvdXQgYW55IHBhcmFtZXRlci4KICAgKgogICAqIENoYW5nZSBoYXNoIGZyYWdtZW50IHdoZW4gY2FsbGVkIHdpdGggcGFyYW1ldGVyIGFuZCByZXR1cm4gYCRsb2NhdGlvbmAuCiAgICoKICAgKgogICAqIGBgYGpzCiAgICogLy8gZ2l2ZW4gdXJsIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvI2hhc2hWYWx1ZQogICAqIHZhciBoYXNoID0gJGxvY2F0aW9uLmhhc2goKTsKICAgKiAvLyA9PiAiaGFzaFZhbHVlIgogICAqIGBgYAogICAqCiAgICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcik9fSBoYXNoIE5ldyBoYXNoIGZyYWdtZW50CiAgICogQHJldHVybiB7c3RyaW5nfSBoYXNoCiAgICovCiAgaGFzaDogbG9jYXRpb25HZXR0ZXJTZXR0ZXIoJyQkaGFzaCcsIGZ1bmN0aW9uKGhhc2gpIHsKICAgIHJldHVybiBoYXNoICE9PSBudWxsID8gaGFzaC50b1N0cmluZygpIDogJyc7CiAgfSksCgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkbG9jYXRpb24jcmVwbGFjZQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogSWYgY2FsbGVkLCBhbGwgY2hhbmdlcyB0byAkbG9jYXRpb24gZHVyaW5nIGN1cnJlbnQgYCRkaWdlc3RgIHdpbGwgYmUgcmVwbGFjaW5nIGN1cnJlbnQgaGlzdG9yeQogICAqIHJlY29yZCwgaW5zdGVhZCBvZiBhZGRpbmcgbmV3IG9uZS4KICAgKi8KICByZXBsYWNlOiBmdW5jdGlvbigpIHsKICAgIHRoaXMuJCRyZXBsYWNlID0gdHJ1ZTsKICAgIHJldHVybiB0aGlzOwogIH0KfTsKCmZvckVhY2goW0xvY2F0aW9uSGFzaGJhbmdJbkh0bWw1VXJsLCBMb2NhdGlvbkhhc2hiYW5nVXJsLCBMb2NhdGlvbkh0bWw1VXJsXSwgZnVuY3Rpb24oTG9jYXRpb24pIHsKICBMb2NhdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKGxvY2F0aW9uUHJvdG90eXBlKTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2NhdGlvbiNzdGF0ZQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGhpcyBtZXRob2QgaXMgZ2V0dGVyIC8gc2V0dGVyLgogICAqCiAgICogUmV0dXJuIHRoZSBoaXN0b3J5IHN0YXRlIG9iamVjdCB3aGVuIGNhbGxlZCB3aXRob3V0IGFueSBwYXJhbWV0ZXIuCiAgICoKICAgKiBDaGFuZ2UgdGhlIGhpc3Rvcnkgc3RhdGUgb2JqZWN0IHdoZW4gY2FsbGVkIHdpdGggb25lIHBhcmFtZXRlciBhbmQgcmV0dXJuIGAkbG9jYXRpb25gLgogICAqIFRoZSBzdGF0ZSBvYmplY3QgaXMgbGF0ZXIgcGFzc2VkIHRvIGBwdXNoU3RhdGVgIG9yIGByZXBsYWNlU3RhdGVgLgogICAqCiAgICogTk9URTogVGhpcyBtZXRob2QgaXMgc3VwcG9ydGVkIG9ubHkgaW4gSFRNTDUgbW9kZSBhbmQgb25seSBpbiBicm93c2VycyBzdXBwb3J0aW5nCiAgICogdGhlIEhUTUw1IEhpc3RvcnkgQVBJIChpLmUuIG1ldGhvZHMgYHB1c2hTdGF0ZWAgYW5kIGByZXBsYWNlU3RhdGVgKS4gSWYgeW91IG5lZWQgdG8gc3VwcG9ydAogICAqIG9sZGVyIGJyb3dzZXJzIChsaWtlIElFOSBvciBBbmRyb2lkIDwgNC4wKSwgZG9uJ3QgdXNlIHRoaXMgbWV0aG9kLgogICAqCiAgICogQHBhcmFtIHtvYmplY3Q9fSBzdGF0ZSBTdGF0ZSBvYmplY3QgZm9yIHB1c2hTdGF0ZSBvciByZXBsYWNlU3RhdGUKICAgKiBAcmV0dXJuIHtvYmplY3R9IHN0YXRlCiAgICovCiAgTG9jYXRpb24ucHJvdG90eXBlLnN0YXRlID0gZnVuY3Rpb24oc3RhdGUpIHsKICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkKICAgICAgcmV0dXJuIHRoaXMuJCRzdGF0ZTsKCiAgICBpZiAoTG9jYXRpb24gIT09IExvY2F0aW9uSHRtbDVVcmwgfHwgIXRoaXMuJCRodG1sNSkgewogICAgICB0aHJvdyAkbG9jYXRpb25NaW5FcnIoJ25vc3RhdGUnLCAnSGlzdG9yeSBBUEkgc3RhdGUgc3VwcG9ydCBpcyBhdmFpbGFibGUgb25seSAnICsKICAgICAgICAnaW4gSFRNTDUgbW9kZSBhbmQgb25seSBpbiBicm93c2VycyBzdXBwb3J0aW5nIEhUTUw1IEhpc3RvcnkgQVBJJyk7CiAgICB9CiAgICAvLyBUaGUgdXNlciBtaWdodCBtb2RpZnkgYHN0YXRlT2JqZWN0YCBhZnRlciBpbnZva2luZyBgJGxvY2F0aW9uLnN0YXRlKHN0YXRlT2JqZWN0KWAKICAgIC8vIGJ1dCB3ZSdyZSBjaGFuZ2luZyB0aGUgJCRzdGF0ZSByZWZlcmVuY2UgdG8gJGJyb3dzZXIuc3RhdGUoKSBkdXJpbmcgdGhlICRkaWdlc3QKICAgIC8vIHNvIHRoZSBtb2RpZmljYXRpb24gd2luZG93IGlzIG5hcnJvdy4KICAgIHRoaXMuJCRzdGF0ZSA9IGlzVW5kZWZpbmVkKHN0YXRlKSA/IG51bGwgOiBzdGF0ZTsKCiAgICByZXR1cm4gdGhpczsKICB9Owp9KTsKCgpmdW5jdGlvbiBsb2NhdGlvbkdldHRlcihwcm9wZXJ0eSkgewogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzW3Byb3BlcnR5XTsKICB9Owp9CgoKZnVuY3Rpb24gbG9jYXRpb25HZXR0ZXJTZXR0ZXIocHJvcGVydHksIHByZXByb2Nlc3MpIHsKICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpCiAgICAgIHJldHVybiB0aGlzW3Byb3BlcnR5XTsKCiAgICB0aGlzW3Byb3BlcnR5XSA9IHByZXByb2Nlc3ModmFsdWUpOwogICAgdGhpcy4kJGNvbXBvc2UoKTsKCiAgICByZXR1cm4gdGhpczsKICB9Owp9CgoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICRsb2NhdGlvbgogKgogKiBAcmVxdWlyZXMgJHJvb3RFbGVtZW50CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgJGxvY2F0aW9uIHNlcnZpY2UgcGFyc2VzIHRoZSBVUkwgaW4gdGhlIGJyb3dzZXIgYWRkcmVzcyBiYXIgKGJhc2VkIG9uIHRoZQogKiBbd2luZG93LmxvY2F0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi93aW5kb3cubG9jYXRpb24pKSBhbmQgbWFrZXMgdGhlIFVSTAogKiBhdmFpbGFibGUgdG8geW91ciBhcHBsaWNhdGlvbi4gQ2hhbmdlcyB0byB0aGUgVVJMIGluIHRoZSBhZGRyZXNzIGJhciBhcmUgcmVmbGVjdGVkIGludG8KICogJGxvY2F0aW9uIHNlcnZpY2UgYW5kIGNoYW5nZXMgdG8gJGxvY2F0aW9uIGFyZSByZWZsZWN0ZWQgaW50byB0aGUgYnJvd3NlciBhZGRyZXNzIGJhci4KICoKICogKipUaGUgJGxvY2F0aW9uIHNlcnZpY2U6KioKICoKICogLSBFeHBvc2VzIHRoZSBjdXJyZW50IFVSTCBpbiB0aGUgYnJvd3NlciBhZGRyZXNzIGJhciwgc28geW91IGNhbgogKiAgIC0gV2F0Y2ggYW5kIG9ic2VydmUgdGhlIFVSTC4KICogICAtIENoYW5nZSB0aGUgVVJMLgogKiAtIFN5bmNocm9uaXplcyB0aGUgVVJMIHdpdGggdGhlIGJyb3dzZXIgd2hlbiB0aGUgdXNlcgogKiAgIC0gQ2hhbmdlcyB0aGUgYWRkcmVzcyBiYXIuCiAqICAgLSBDbGlja3MgdGhlIGJhY2sgb3IgZm9yd2FyZCBidXR0b24gKG9yIGNsaWNrcyBhIEhpc3RvcnkgbGluaykuCiAqICAgLSBDbGlja3Mgb24gYSBsaW5rLgogKiAtIFJlcHJlc2VudHMgdGhlIFVSTCBvYmplY3QgYXMgYSBzZXQgb2YgbWV0aG9kcyAocHJvdG9jb2wsIGhvc3QsIHBvcnQsIHBhdGgsIHNlYXJjaCwgaGFzaCkuCiAqCiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSB7QGxpbmsgZ3VpZGUvJGxvY2F0aW9uIERldmVsb3BlciBHdWlkZTogVXNpbmcgJGxvY2F0aW9ufQogKi8KCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJGxvY2F0aW9uUHJvdmlkZXIKICogQGRlc2NyaXB0aW9uCiAqIFVzZSB0aGUgYCRsb2NhdGlvblByb3ZpZGVyYCB0byBjb25maWd1cmUgaG93IHRoZSBhcHBsaWNhdGlvbiBkZWVwIGxpbmtpbmcgcGF0aHMgYXJlIHN0b3JlZC4KICovCmZ1bmN0aW9uICRMb2NhdGlvblByb3ZpZGVyKCkgewogIHZhciBoYXNoUHJlZml4ID0gJycsCiAgICAgIGh0bWw1TW9kZSA9IHsKICAgICAgICBlbmFibGVkOiBmYWxzZSwKICAgICAgICByZXF1aXJlQmFzZTogdHJ1ZSwKICAgICAgICByZXdyaXRlTGlua3M6IHRydWUKICAgICAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2NhdGlvblByb3ZpZGVyI2hhc2hQcmVmaXgKICAgKiBAZGVzY3JpcHRpb24KICAgKiBAcGFyYW0ge3N0cmluZz19IHByZWZpeCBQcmVmaXggZm9yIGhhc2ggcGFydCAoY29udGFpbmluZyBwYXRoIGFuZCBzZWFyY2gpCiAgICogQHJldHVybnMgeyp9IGN1cnJlbnQgdmFsdWUgaWYgdXNlZCBhcyBnZXR0ZXIgb3IgaXRzZWxmIChjaGFpbmluZykgaWYgdXNlZCBhcyBzZXR0ZXIKICAgKi8KICB0aGlzLmhhc2hQcmVmaXggPSBmdW5jdGlvbihwcmVmaXgpIHsKICAgIGlmIChpc0RlZmluZWQocHJlZml4KSkgewogICAgICBoYXNoUHJlZml4ID0gcHJlZml4OwogICAgICByZXR1cm4gdGhpczsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBoYXNoUHJlZml4OwogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkbG9jYXRpb25Qcm92aWRlciNodG1sNU1vZGUKICAgKiBAZGVzY3JpcHRpb24KICAgKiBAcGFyYW0geyhib29sZWFufE9iamVjdCk9fSBtb2RlIElmIGJvb2xlYW4sIHNldHMgYGh0bWw1TW9kZS5lbmFibGVkYCB0byB2YWx1ZS4KICAgKiAgIElmIG9iamVjdCwgc2V0cyBgZW5hYmxlZGAsIGByZXF1aXJlQmFzZWAgYW5kIGByZXdyaXRlTGlua3NgIHRvIHJlc3BlY3RpdmUgdmFsdWVzLiBTdXBwb3J0ZWQKICAgKiAgIHByb3BlcnRpZXM6CiAgICogICAtICoqZW5hYmxlZCoqIOKAPyBge2Jvb2xlYW59YCDigD8gKGRlZmF1bHQ6IGZhbHNlKSBJZiB0cnVlLCB3aWxsIHJlbHkgb24gYGhpc3RvcnkucHVzaFN0YXRlYCB0bwogICAqICAgICBjaGFuZ2UgdXJscyB3aGVyZSBzdXBwb3J0ZWQuIFdpbGwgZmFsbCBiYWNrIHRvIGhhc2gtcHJlZml4ZWQgcGF0aHMgaW4gYnJvd3NlcnMgdGhhdCBkbyBub3QKICAgKiAgICAgc3VwcG9ydCBgcHVzaFN0YXRlYC4KICAgKiAgIC0gKipyZXF1aXJlQmFzZSoqIC0gYHtib29sZWFufWAgLSAoZGVmYXVsdDogYHRydWVgKSBXaGVuIGh0bWw1TW9kZSBpcyBlbmFibGVkLCBzcGVjaWZpZXMKICAgKiAgICAgd2hldGhlciBvciBub3QgYSA8YmFzZT4gdGFnIGlzIHJlcXVpcmVkIHRvIGJlIHByZXNlbnQuIElmIGBlbmFibGVkYCBhbmQgYHJlcXVpcmVCYXNlYCBhcmUKICAgKiAgICAgdHJ1ZSwgYW5kIGEgYmFzZSB0YWcgaXMgbm90IHByZXNlbnQsIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duIHdoZW4gYCRsb2NhdGlvbmAgaXMgaW5qZWN0ZWQuCiAgICogICAgIFNlZSB0aGUge0BsaW5rIGd1aWRlLyRsb2NhdGlvbiAkbG9jYXRpb24gZ3VpZGUgZm9yIG1vcmUgaW5mb3JtYXRpb259CiAgICogICAtICoqcmV3cml0ZUxpbmtzKiogLSBge2Jvb2xlYW59YCAtIChkZWZhdWx0OiBgdHJ1ZWApIFdoZW4gaHRtbDVNb2RlIGlzIGVuYWJsZWQsCiAgICogICAgIGVuYWJsZXMvZGlzYWJsZXMgdXJsIHJld3JpdGluZyBmb3IgcmVsYXRpdmUgbGlua3MuCiAgICoKICAgKiBAcmV0dXJucyB7T2JqZWN0fSBodG1sNU1vZGUgb2JqZWN0IGlmIHVzZWQgYXMgZ2V0dGVyIG9yIGl0c2VsZiAoY2hhaW5pbmcpIGlmIHVzZWQgYXMgc2V0dGVyCiAgICovCiAgdGhpcy5odG1sNU1vZGUgPSBmdW5jdGlvbihtb2RlKSB7CiAgICBpZiAoaXNCb29sZWFuKG1vZGUpKSB7CiAgICAgIGh0bWw1TW9kZS5lbmFibGVkID0gbW9kZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KG1vZGUpKSB7CgogICAgICBpZiAoaXNCb29sZWFuKG1vZGUuZW5hYmxlZCkpIHsKICAgICAgICBodG1sNU1vZGUuZW5hYmxlZCA9IG1vZGUuZW5hYmxlZDsKICAgICAgfQoKICAgICAgaWYgKGlzQm9vbGVhbihtb2RlLnJlcXVpcmVCYXNlKSkgewogICAgICAgIGh0bWw1TW9kZS5yZXF1aXJlQmFzZSA9IG1vZGUucmVxdWlyZUJhc2U7CiAgICAgIH0KCiAgICAgIGlmIChpc0Jvb2xlYW4obW9kZS5yZXdyaXRlTGlua3MpKSB7CiAgICAgICAgaHRtbDVNb2RlLnJld3JpdGVMaW5rcyA9IG1vZGUucmV3cml0ZUxpbmtzOwogICAgICB9CgogICAgICByZXR1cm4gdGhpczsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBodG1sNU1vZGU7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIGV2ZW50CiAgICogQG5hbWUgJGxvY2F0aW9uIyRsb2NhdGlvbkNoYW5nZVN0YXJ0CiAgICogQGV2ZW50VHlwZSBicm9hZGNhc3Qgb24gcm9vdCBzY29wZQogICAqIEBkZXNjcmlwdGlvbgogICAqIEJyb2FkY2FzdGVkIGJlZm9yZSBhIFVSTCB3aWxsIGNoYW5nZS4KICAgKgogICAqIFRoaXMgY2hhbmdlIGNhbiBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZwogICAqIGBwcmV2ZW50RGVmYXVsdGAgbWV0aG9kIG9mIHRoZSBldmVudC4gU2VlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRvbn0gZm9yIG1vcmUKICAgKiBkZXRhaWxzIGFib3V0IGV2ZW50IG9iamVjdC4gVXBvbiBzdWNjZXNzZnVsIGNoYW5nZQogICAqIHtAbGluayBuZy4kbG9jYXRpb24jJGxvY2F0aW9uQ2hhbmdlU3VjY2VzcyAkbG9jYXRpb25DaGFuZ2VTdWNjZXNzfSBpcyBmaXJlZC4KICAgKgogICAqIFRoZSBgbmV3U3RhdGVgIGFuZCBgb2xkU3RhdGVgIHBhcmFtZXRlcnMgbWF5IGJlIGRlZmluZWQgb25seSBpbiBIVE1MNSBtb2RlIGFuZCB3aGVuCiAgICogdGhlIGJyb3dzZXIgc3VwcG9ydHMgdGhlIEhUTUw1IEhpc3RvcnkgQVBJLgogICAqCiAgICogQHBhcmFtIHtPYmplY3R9IGFuZ3VsYXJFdmVudCBTeW50aGV0aWMgZXZlbnQgb2JqZWN0LgogICAqIEBwYXJhbSB7c3RyaW5nfSBuZXdVcmwgTmV3IFVSTAogICAqIEBwYXJhbSB7c3RyaW5nPX0gb2xkVXJsIFVSTCB0aGF0IHdhcyBiZWZvcmUgaXQgd2FzIGNoYW5nZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZXdTdGF0ZSBOZXcgaGlzdG9yeSBzdGF0ZSBvYmplY3QKICAgKiBAcGFyYW0ge3N0cmluZz19IG9sZFN0YXRlIEhpc3Rvcnkgc3RhdGUgb2JqZWN0IHRoYXQgd2FzIGJlZm9yZSBpdCB3YXMgY2hhbmdlZC4KICAgKi8KCiAgLyoqCiAgICogQG5nZG9jIGV2ZW50CiAgICogQG5hbWUgJGxvY2F0aW9uIyRsb2NhdGlvbkNoYW5nZVN1Y2Nlc3MKICAgKiBAZXZlbnRUeXBlIGJyb2FkY2FzdCBvbiByb290IHNjb3BlCiAgICogQGRlc2NyaXB0aW9uCiAgICogQnJvYWRjYXN0ZWQgYWZ0ZXIgYSBVUkwgd2FzIGNoYW5nZWQuCiAgICoKICAgKiBUaGUgYG5ld1N0YXRlYCBhbmQgYG9sZFN0YXRlYCBwYXJhbWV0ZXJzIG1heSBiZSBkZWZpbmVkIG9ubHkgaW4gSFRNTDUgbW9kZSBhbmQgd2hlbgogICAqIHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBIVE1MNSBIaXN0b3J5IEFQSS4KICAgKgogICAqIEBwYXJhbSB7T2JqZWN0fSBhbmd1bGFyRXZlbnQgU3ludGhldGljIGV2ZW50IG9iamVjdC4KICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VXJsIE5ldyBVUkwKICAgKiBAcGFyYW0ge3N0cmluZz19IG9sZFVybCBVUkwgdGhhdCB3YXMgYmVmb3JlIGl0IHdhcyBjaGFuZ2VkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmV3U3RhdGUgTmV3IGhpc3Rvcnkgc3RhdGUgb2JqZWN0CiAgICogQHBhcmFtIHtzdHJpbmc9fSBvbGRTdGF0ZSBIaXN0b3J5IHN0YXRlIG9iamVjdCB0aGF0IHdhcyBiZWZvcmUgaXQgd2FzIGNoYW5nZWQuCiAgICovCgogIHRoaXMuJGdldCA9IFsnJHJvb3RTY29wZScsICckYnJvd3NlcicsICckc25pZmZlcicsICckcm9vdEVsZW1lbnQnLCAnJHdpbmRvdycsCiAgICAgIGZ1bmN0aW9uKCRyb290U2NvcGUsICRicm93c2VyLCAkc25pZmZlciwgJHJvb3RFbGVtZW50LCAkd2luZG93KSB7CiAgICB2YXIgJGxvY2F0aW9uLAogICAgICAgIExvY2F0aW9uTW9kZSwKICAgICAgICBiYXNlSHJlZiA9ICRicm93c2VyLmJhc2VIcmVmKCksIC8vIGlmIGJhc2VbaHJlZl0gaXMgdW5kZWZpbmVkLCBpdCBkZWZhdWx0cyB0byAnJwogICAgICAgIGluaXRpYWxVcmwgPSAkYnJvd3Nlci51cmwoKSwKICAgICAgICBhcHBCYXNlOwoKICAgIGlmIChodG1sNU1vZGUuZW5hYmxlZCkgewogICAgICBpZiAoIWJhc2VIcmVmICYmIGh0bWw1TW9kZS5yZXF1aXJlQmFzZSkgewogICAgICAgIHRocm93ICRsb2NhdGlvbk1pbkVycignbm9iYXNlJywKICAgICAgICAgICIkbG9jYXRpb24gaW4gSFRNTDUgbW9kZSByZXF1aXJlcyBhIDxiYXNlPiB0YWcgdG8gYmUgcHJlc2VudCEiKTsKICAgICAgfQogICAgICBhcHBCYXNlID0gc2VydmVyQmFzZShpbml0aWFsVXJsKSArIChiYXNlSHJlZiB8fCAnLycpOwogICAgICBMb2NhdGlvbk1vZGUgPSAkc25pZmZlci5oaXN0b3J5ID8gTG9jYXRpb25IdG1sNVVybCA6IExvY2F0aW9uSGFzaGJhbmdJbkh0bWw1VXJsOwogICAgfSBlbHNlIHsKICAgICAgYXBwQmFzZSA9IHN0cmlwSGFzaChpbml0aWFsVXJsKTsKICAgICAgTG9jYXRpb25Nb2RlID0gTG9jYXRpb25IYXNoYmFuZ1VybDsKICAgIH0KICAgICRsb2NhdGlvbiA9IG5ldyBMb2NhdGlvbk1vZGUoYXBwQmFzZSwgJyMnICsgaGFzaFByZWZpeCk7CiAgICAkbG9jYXRpb24uJCRwYXJzZUxpbmtVcmwoaW5pdGlhbFVybCwgaW5pdGlhbFVybCk7CgogICAgJGxvY2F0aW9uLiQkc3RhdGUgPSAkYnJvd3Nlci5zdGF0ZSgpOwoKICAgIHZhciBJR05PUkVfVVJJX1JFR0VYUCA9IC9eXHMqKGphdmFzY3JpcHR8bWFpbHRvKTovaTsKCiAgICBmdW5jdGlvbiBzZXRCcm93c2VyVXJsV2l0aEZhbGxiYWNrKHVybCwgcmVwbGFjZSwgc3RhdGUpIHsKICAgICAgdmFyIG9sZFVybCA9ICRsb2NhdGlvbi51cmwoKTsKICAgICAgdmFyIG9sZFN0YXRlID0gJGxvY2F0aW9uLiQkc3RhdGU7CiAgICAgIHRyeSB7CiAgICAgICAgJGJyb3dzZXIudXJsKHVybCwgcmVwbGFjZSwgc3RhdGUpOwoKICAgICAgICAvLyBNYWtlIHN1cmUgJGxvY2F0aW9uLnN0YXRlKCkgcmV0dXJucyByZWZlcmVudGlhbGx5IGlkZW50aWNhbCAobm90IGp1c3QgZGVlcGx5IGVxdWFsKQogICAgICAgIC8vIHN0YXRlIG9iamVjdDsgdGhpcyBtYWtlcyBwb3NzaWJsZSBxdWljayBjaGVja2luZyBpZiB0aGUgc3RhdGUgY2hhbmdlZCBpbiB0aGUgZGlnZXN0CiAgICAgICAgLy8gbG9vcC4gQ2hlY2tpbmcgZGVlcCBlcXVhbGl0eSB3b3VsZCBiZSB0b28gZXhwZW5zaXZlLgogICAgICAgICRsb2NhdGlvbi4kJHN0YXRlID0gJGJyb3dzZXIuc3RhdGUoKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIC8vIFJlc3RvcmUgb2xkIHZhbHVlcyBpZiBwdXNoU3RhdGUgZmFpbHMKICAgICAgICAkbG9jYXRpb24udXJsKG9sZFVybCk7CiAgICAgICAgJGxvY2F0aW9uLiQkc3RhdGUgPSBvbGRTdGF0ZTsKCiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQoKICAgICRyb290RWxlbWVudC5vbignY2xpY2snLCBmdW5jdGlvbihldmVudCkgewogICAgICAvLyBUT0RPKHZvanRhKTogcmV3cml0ZSBsaW5rIHdoZW4gb3BlbmluZyBpbiBuZXcgdGFiL3dpbmRvdyAoaW4gbGVnYWN5IGJyb3dzZXIpCiAgICAgIC8vIGN1cnJlbnRseSB3ZSBvcGVuIG5pY2UgdXJsIGxpbmsgYW5kIHJlZGlyZWN0IHRoZW4KCiAgICAgIGlmICghaHRtbDVNb2RlLnJld3JpdGVMaW5rcyB8fCBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQud2hpY2ggPT0gMikgcmV0dXJuOwoKICAgICAgdmFyIGVsbSA9IGpxTGl0ZShldmVudC50YXJnZXQpOwoKICAgICAgLy8gdHJhdmVyc2UgdGhlIERPTSB1cCB0byBmaW5kIGZpcnN0IEEgdGFnCiAgICAgIHdoaWxlIChub2RlTmFtZV8oZWxtWzBdKSAhPT0gJ2EnKSB7CiAgICAgICAgLy8gaWdub3JlIHJld3JpdGluZyBpZiBubyBBIHRhZyAocmVhY2hlZCByb290IGVsZW1lbnQsIG9yIG5vIHBhcmVudCAtIHJlbW92ZWQgZnJvbSBkb2N1bWVudCkKICAgICAgICBpZiAoZWxtWzBdID09PSAkcm9vdEVsZW1lbnRbMF0gfHwgIShlbG0gPSBlbG0ucGFyZW50KCkpWzBdKSByZXR1cm47CiAgICAgIH0KCiAgICAgIHZhciBhYnNIcmVmID0gZWxtLnByb3AoJ2hyZWYnKTsKICAgICAgLy8gZ2V0IHRoZSBhY3R1YWwgaHJlZiBhdHRyaWJ1dGUgLSBzZWUKICAgICAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2RkMzQ3MTQ4KHY9dnMuODUpLmFzcHgKICAgICAgdmFyIHJlbEhyZWYgPSBlbG0uYXR0cignaHJlZicpIHx8IGVsbS5hdHRyKCd4bGluazpocmVmJyk7CgogICAgICBpZiAoaXNPYmplY3QoYWJzSHJlZikgJiYgYWJzSHJlZi50b1N0cmluZygpID09PSAnW29iamVjdCBTVkdBbmltYXRlZFN0cmluZ10nKSB7CiAgICAgICAgLy8gU1ZHQW5pbWF0ZWRTdHJpbmcuYW5pbVZhbCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIFNWR0FuaW1hdGVkU3RyaW5nLmJhc2VWYWwsIHVubGVzcyBkdXJpbmcKICAgICAgICAvLyBhbiBhbmltYXRpb24uCiAgICAgICAgYWJzSHJlZiA9IHVybFJlc29sdmUoYWJzSHJlZi5hbmltVmFsKS5ocmVmOwogICAgICB9CgogICAgICAvLyBJZ25vcmUgd2hlbiB1cmwgaXMgc3RhcnRlZCB3aXRoIGphdmFzY3JpcHQ6IG9yIG1haWx0bzoKICAgICAgaWYgKElHTk9SRV9VUklfUkVHRVhQLnRlc3QoYWJzSHJlZikpIHJldHVybjsKCiAgICAgIGlmIChhYnNIcmVmICYmICFlbG0uYXR0cigndGFyZ2V0JykgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKSB7CiAgICAgICAgaWYgKCRsb2NhdGlvbi4kJHBhcnNlTGlua1VybChhYnNIcmVmLCByZWxIcmVmKSkgewogICAgICAgICAgLy8gV2UgZG8gYSBwcmV2ZW50RGVmYXVsdCBmb3IgYWxsIHVybHMgdGhhdCBhcmUgcGFydCBvZiB0aGUgYW5ndWxhciBhcHBsaWNhdGlvbiwKICAgICAgICAgIC8vIGluIGh0bWw1bW9kZSBhbmQgYWxzbyB3aXRob3V0LCBzbyB0aGF0IHdlIGFyZSBhYmxlIHRvIGFib3J0IG5hdmlnYXRpb24gd2l0aG91dAogICAgICAgICAgLy8gZ2V0dGluZyBkb3VibGUgZW50cmllcyBpbiB0aGUgbG9jYXRpb24gaGlzdG9yeS4KICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAvLyB1cGRhdGUgbG9jYXRpb24gbWFudWFsbHkKICAgICAgICAgIGlmICgkbG9jYXRpb24uYWJzVXJsKCkgIT0gJGJyb3dzZXIudXJsKCkpIHsKICAgICAgICAgICAgJHJvb3RTY29wZS4kYXBwbHkoKTsKICAgICAgICAgICAgLy8gaGFjayB0byB3b3JrIGFyb3VuZCBGRjYgYnVnIDY4NDIwOCB3aGVuIHNjZW5hcmlvIHJ1bm5lciBjbGlja3Mgb24gbGlua3MKICAgICAgICAgICAgJHdpbmRvdy5hbmd1bGFyWydmZi02ODQyMDgtcHJldmVudERlZmF1bHQnXSA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKCgogICAgLy8gcmV3cml0ZSBoYXNoYmFuZyB1cmwgPD4gaHRtbDUgdXJsCiAgICBpZiAoJGxvY2F0aW9uLmFic1VybCgpICE9IGluaXRpYWxVcmwpIHsKICAgICAgJGJyb3dzZXIudXJsKCRsb2NhdGlvbi5hYnNVcmwoKSwgdHJ1ZSk7CiAgICB9CgogICAgdmFyIGluaXRpYWxpemluZyA9IHRydWU7CgogICAgLy8gdXBkYXRlICRsb2NhdGlvbiB3aGVuICRicm93c2VyIHVybCBjaGFuZ2VzCiAgICAkYnJvd3Nlci5vblVybENoYW5nZShmdW5jdGlvbihuZXdVcmwsIG5ld1N0YXRlKSB7CiAgICAgICRyb290U2NvcGUuJGV2YWxBc3luYyhmdW5jdGlvbigpIHsKICAgICAgICB2YXIgb2xkVXJsID0gJGxvY2F0aW9uLmFic1VybCgpOwogICAgICAgIHZhciBvbGRTdGF0ZSA9ICRsb2NhdGlvbi4kJHN0YXRlOwogICAgICAgIHZhciBkZWZhdWx0UHJldmVudGVkOwoKICAgICAgICAkbG9jYXRpb24uJCRwYXJzZShuZXdVcmwpOwogICAgICAgICRsb2NhdGlvbi4kJHN0YXRlID0gbmV3U3RhdGU7CgogICAgICAgIGRlZmF1bHRQcmV2ZW50ZWQgPSAkcm9vdFNjb3BlLiRicm9hZGNhc3QoJyRsb2NhdGlvbkNoYW5nZVN0YXJ0JywgbmV3VXJsLCBvbGRVcmwsCiAgICAgICAgICAgIG5ld1N0YXRlLCBvbGRTdGF0ZSkuZGVmYXVsdFByZXZlbnRlZDsKCiAgICAgICAgLy8gaWYgdGhlIGxvY2F0aW9uIHdhcyBjaGFuZ2VkIGJ5IGEgYCRsb2NhdGlvbkNoYW5nZVN0YXJ0YCBoYW5kbGVyIHRoZW4gc3RvcAogICAgICAgIC8vIHByb2Nlc3NpbmcgdGhpcyBsb2NhdGlvbiBjaGFuZ2UKICAgICAgICBpZiAoJGxvY2F0aW9uLmFic1VybCgpICE9PSBuZXdVcmwpIHJldHVybjsKCiAgICAgICAgaWYgKGRlZmF1bHRQcmV2ZW50ZWQpIHsKICAgICAgICAgICRsb2NhdGlvbi4kJHBhcnNlKG9sZFVybCk7CiAgICAgICAgICAkbG9jYXRpb24uJCRzdGF0ZSA9IG9sZFN0YXRlOwogICAgICAgICAgc2V0QnJvd3NlclVybFdpdGhGYWxsYmFjayhvbGRVcmwsIGZhbHNlLCBvbGRTdGF0ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlOwogICAgICAgICAgYWZ0ZXJMb2NhdGlvbkNoYW5nZShvbGRVcmwsIG9sZFN0YXRlKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICBpZiAoISRyb290U2NvcGUuJCRwaGFzZSkgJHJvb3RTY29wZS4kZGlnZXN0KCk7CiAgICB9KTsKCiAgICAvLyB1cGRhdGUgYnJvd3NlcgogICAgJHJvb3RTY29wZS4kd2F0Y2goZnVuY3Rpb24gJGxvY2F0aW9uV2F0Y2goKSB7CiAgICAgIHZhciBvbGRVcmwgPSB0cmltRW1wdHlIYXNoKCRicm93c2VyLnVybCgpKTsKICAgICAgdmFyIG5ld1VybCA9IHRyaW1FbXB0eUhhc2goJGxvY2F0aW9uLmFic1VybCgpKTsKICAgICAgdmFyIG9sZFN0YXRlID0gJGJyb3dzZXIuc3RhdGUoKTsKICAgICAgdmFyIGN1cnJlbnRSZXBsYWNlID0gJGxvY2F0aW9uLiQkcmVwbGFjZTsKICAgICAgdmFyIHVybE9yU3RhdGVDaGFuZ2VkID0gb2xkVXJsICE9PSBuZXdVcmwgfHwKICAgICAgICAoJGxvY2F0aW9uLiQkaHRtbDUgJiYgJHNuaWZmZXIuaGlzdG9yeSAmJiBvbGRTdGF0ZSAhPT0gJGxvY2F0aW9uLiQkc3RhdGUpOwoKICAgICAgaWYgKGluaXRpYWxpemluZyB8fCB1cmxPclN0YXRlQ2hhbmdlZCkgewogICAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlOwoKICAgICAgICAkcm9vdFNjb3BlLiRldmFsQXN5bmMoZnVuY3Rpb24oKSB7CiAgICAgICAgICB2YXIgbmV3VXJsID0gJGxvY2F0aW9uLmFic1VybCgpOwogICAgICAgICAgdmFyIGRlZmF1bHRQcmV2ZW50ZWQgPSAkcm9vdFNjb3BlLiRicm9hZGNhc3QoJyRsb2NhdGlvbkNoYW5nZVN0YXJ0JywgbmV3VXJsLCBvbGRVcmwsCiAgICAgICAgICAgICAgJGxvY2F0aW9uLiQkc3RhdGUsIG9sZFN0YXRlKS5kZWZhdWx0UHJldmVudGVkOwoKICAgICAgICAgIC8vIGlmIHRoZSBsb2NhdGlvbiB3YXMgY2hhbmdlZCBieSBhIGAkbG9jYXRpb25DaGFuZ2VTdGFydGAgaGFuZGxlciB0aGVuIHN0b3AKICAgICAgICAgIC8vIHByb2Nlc3NpbmcgdGhpcyBsb2NhdGlvbiBjaGFuZ2UKICAgICAgICAgIGlmICgkbG9jYXRpb24uYWJzVXJsKCkgIT09IG5ld1VybCkgcmV0dXJuOwoKICAgICAgICAgIGlmIChkZWZhdWx0UHJldmVudGVkKSB7CiAgICAgICAgICAgICRsb2NhdGlvbi4kJHBhcnNlKG9sZFVybCk7CiAgICAgICAgICAgICRsb2NhdGlvbi4kJHN0YXRlID0gb2xkU3RhdGU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAodXJsT3JTdGF0ZUNoYW5nZWQpIHsKICAgICAgICAgICAgICBzZXRCcm93c2VyVXJsV2l0aEZhbGxiYWNrKG5ld1VybCwgY3VycmVudFJlcGxhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRTdGF0ZSA9PT0gJGxvY2F0aW9uLiQkc3RhdGUgPyBudWxsIDogJGxvY2F0aW9uLiQkc3RhdGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFmdGVyTG9jYXRpb25DaGFuZ2Uob2xkVXJsLCBvbGRTdGF0ZSk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgICRsb2NhdGlvbi4kJHJlcGxhY2UgPSBmYWxzZTsKCiAgICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gcmV0dXJuIGFueXRoaW5nIGJlY2F1c2UgJGV2YWxBc3luYyB3aWxsIG1ha2UgdGhlIGRpZ2VzdCBsb29wIGRpcnR5IHdoZW4KICAgICAgLy8gdGhlcmUgaXMgYSBjaGFuZ2UKICAgIH0pOwoKICAgIHJldHVybiAkbG9jYXRpb247CgogICAgZnVuY3Rpb24gYWZ0ZXJMb2NhdGlvbkNoYW5nZShvbGRVcmwsIG9sZFN0YXRlKSB7CiAgICAgICRyb290U2NvcGUuJGJyb2FkY2FzdCgnJGxvY2F0aW9uQ2hhbmdlU3VjY2VzcycsICRsb2NhdGlvbi5hYnNVcmwoKSwgb2xkVXJsLAogICAgICAgICRsb2NhdGlvbi4kJHN0YXRlLCBvbGRTdGF0ZSk7CiAgICB9Cn1dOwp9CgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJGxvZwogKiBAcmVxdWlyZXMgJHdpbmRvdwogKgogKiBAZGVzY3JpcHRpb24KICogU2ltcGxlIHNlcnZpY2UgZm9yIGxvZ2dpbmcuIERlZmF1bHQgaW1wbGVtZW50YXRpb24gc2FmZWx5IHdyaXRlcyB0aGUgbWVzc2FnZQogKiBpbnRvIHRoZSBicm93c2VyJ3MgY29uc29sZSAoaWYgcHJlc2VudCkuCiAqCiAqIFRoZSBtYWluIHB1cnBvc2Ugb2YgdGhpcyBzZXJ2aWNlIGlzIHRvIHNpbXBsaWZ5IGRlYnVnZ2luZyBhbmQgdHJvdWJsZXNob290aW5nLgogKgogKiBUaGUgZGVmYXVsdCBpcyB0byBsb2cgYGRlYnVnYCBtZXNzYWdlcy4gWW91IGNhbiB1c2UKICoge0BsaW5rIG5nLiRsb2dQcm92aWRlciBuZy4kbG9nUHJvdmlkZXIjZGVidWdFbmFibGVkfSB0byBjaGFuZ2UgdGhpcy4KICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGUgbW9kdWxlPSJsb2dFeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICAgYW5ndWxhci5tb2R1bGUoJ2xvZ0V4YW1wbGUnLCBbXSkKICAgICAgICAgLmNvbnRyb2xsZXIoJ0xvZ0NvbnRyb2xsZXInLCBbJyRzY29wZScsICckbG9nJywgZnVuY3Rpb24oJHNjb3BlLCAkbG9nKSB7CiAgICAgICAgICAgJHNjb3BlLiRsb2cgPSAkbG9nOwogICAgICAgICAgICRzY29wZS5tZXNzYWdlID0gJ0hlbGxvIFdvcmxkISc7CiAgICAgICAgIH1dKTsKICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkxvZ0NvbnRyb2xsZXIiPgogICAgICAgICA8cD5SZWxvYWQgdGhpcyBwYWdlIHdpdGggb3BlbiBjb25zb2xlLCBlbnRlciB0ZXh0IGFuZCBoaXQgdGhlIGxvZyBidXR0b24uLi48L3A+CiAgICAgICAgIE1lc3NhZ2U6CiAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1tb2RlbD0ibWVzc2FnZSIvPgogICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSIkbG9nLmxvZyhtZXNzYWdlKSI+bG9nPC9idXR0b24+CiAgICAgICAgIDxidXR0b24gbmctY2xpY2s9IiRsb2cud2FybihtZXNzYWdlKSI+d2FybjwvYnV0dG9uPgogICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSIkbG9nLmluZm8obWVzc2FnZSkiPmluZm88L2J1dHRvbj4KICAgICAgICAgPGJ1dHRvbiBuZy1jbGljaz0iJGxvZy5lcnJvcihtZXNzYWdlKSI+ZXJyb3I8L2J1dHRvbj4KICAgICAgIDwvZGl2PgogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJGxvZ1Byb3ZpZGVyCiAqIEBkZXNjcmlwdGlvbgogKiBVc2UgdGhlIGAkbG9nUHJvdmlkZXJgIHRvIGNvbmZpZ3VyZSBob3cgdGhlIGFwcGxpY2F0aW9uIGxvZ3MgbWVzc2FnZXMKICovCmZ1bmN0aW9uICRMb2dQcm92aWRlcigpIHsKICB2YXIgZGVidWcgPSB0cnVlLAogICAgICBzZWxmID0gdGhpczsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRsb2dQcm92aWRlciNkZWJ1Z0VuYWJsZWQKICAgKiBAZGVzY3JpcHRpb24KICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBmbGFnIGVuYWJsZSBvciBkaXNhYmxlIGRlYnVnIGxldmVsIG1lc3NhZ2VzCiAgICogQHJldHVybnMgeyp9IGN1cnJlbnQgdmFsdWUgaWYgdXNlZCBhcyBnZXR0ZXIgb3IgaXRzZWxmIChjaGFpbmluZykgaWYgdXNlZCBhcyBzZXR0ZXIKICAgKi8KICB0aGlzLmRlYnVnRW5hYmxlZCA9IGZ1bmN0aW9uKGZsYWcpIHsKICAgIGlmIChpc0RlZmluZWQoZmxhZykpIHsKICAgICAgZGVidWcgPSBmbGFnOwogICAgcmV0dXJuIHRoaXM7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gZGVidWc7CiAgICB9CiAgfTsKCiAgdGhpcy4kZ2V0ID0gWyckd2luZG93JywgZnVuY3Rpb24oJHdpbmRvdykgewogICAgcmV0dXJuIHsKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGxvZyNsb2cKICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIFdyaXRlIGEgbG9nIG1lc3NhZ2UKICAgICAgICovCiAgICAgIGxvZzogY29uc29sZUxvZygnbG9nJyksCgogICAgICAvKioKICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgKiBAbmFtZSAkbG9nI2luZm8KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIFdyaXRlIGFuIGluZm9ybWF0aW9uIG1lc3NhZ2UKICAgICAgICovCiAgICAgIGluZm86IGNvbnNvbGVMb2coJ2luZm8nKSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRsb2cjd2FybgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogV3JpdGUgYSB3YXJuaW5nIG1lc3NhZ2UKICAgICAgICovCiAgICAgIHdhcm46IGNvbnNvbGVMb2coJ3dhcm4nKSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRsb2cjZXJyb3IKICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIFdyaXRlIGFuIGVycm9yIG1lc3NhZ2UKICAgICAgICovCiAgICAgIGVycm9yOiBjb25zb2xlTG9nKCdlcnJvcicpLAoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJGxvZyNkZWJ1ZwogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogV3JpdGUgYSBkZWJ1ZyBtZXNzYWdlCiAgICAgICAqLwogICAgICBkZWJ1ZzogKGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBmbiA9IGNvbnNvbGVMb2coJ2RlYnVnJyk7CgogICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgIGlmIChkZWJ1ZykgewogICAgICAgICAgICBmbi5hcHBseShzZWxmLCBhcmd1bWVudHMpOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgIH0oKSkKICAgIH07CgogICAgZnVuY3Rpb24gZm9ybWF0RXJyb3IoYXJnKSB7CiAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBFcnJvcikgewogICAgICAgIGlmIChhcmcuc3RhY2spIHsKICAgICAgICAgIGFyZyA9IChhcmcubWVzc2FnZSAmJiBhcmcuc3RhY2suaW5kZXhPZihhcmcubWVzc2FnZSkgPT09IC0xKQogICAgICAgICAgICAgID8gJ0Vycm9yOiAnICsgYXJnLm1lc3NhZ2UgKyAnXG4nICsgYXJnLnN0YWNrCiAgICAgICAgICAgICAgOiBhcmcuc3RhY2s7CiAgICAgICAgfSBlbHNlIGlmIChhcmcuc291cmNlVVJMKSB7CiAgICAgICAgICBhcmcgPSBhcmcubWVzc2FnZSArICdcbicgKyBhcmcuc291cmNlVVJMICsgJzonICsgYXJnLmxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBhcmc7CiAgICB9CgogICAgZnVuY3Rpb24gY29uc29sZUxvZyh0eXBlKSB7CiAgICAgIHZhciBjb25zb2xlID0gJHdpbmRvdy5jb25zb2xlIHx8IHt9LAogICAgICAgICAgbG9nRm4gPSBjb25zb2xlW3R5cGVdIHx8IGNvbnNvbGUubG9nIHx8IG5vb3AsCiAgICAgICAgICBoYXNBcHBseSA9IGZhbHNlOwoKICAgICAgLy8gTm90ZTogcmVhZGluZyBsb2dGbi5hcHBseSB0aHJvd3MgYW4gZXJyb3IgaW4gSUUxMSBpbiBJRTggZG9jdW1lbnQgbW9kZS4KICAgICAgLy8gVGhlIHJlYXNvbiBiZWhpbmQgdGhpcyBpcyB0aGF0IGNvbnNvbGUubG9nIGhhcyB0eXBlICJvYmplY3QiIGluIElFOC4uLgogICAgICB0cnkgewogICAgICAgIGhhc0FwcGx5ID0gISFsb2dGbi5hcHBseTsKICAgICAgfSBjYXRjaCAoZSkge30KCiAgICAgIGlmIChoYXNBcHBseSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgIHZhciBhcmdzID0gW107CiAgICAgICAgICBmb3JFYWNoKGFyZ3VtZW50cywgZnVuY3Rpb24oYXJnKSB7CiAgICAgICAgICAgIGFyZ3MucHVzaChmb3JtYXRFcnJvcihhcmcpKTsKICAgICAgICAgIH0pOwogICAgICAgICAgcmV0dXJuIGxvZ0ZuLmFwcGx5KGNvbnNvbGUsIGFyZ3MpOwogICAgICAgIH07CiAgICAgIH0KCiAgICAgIC8vIHdlIGFyZSBJRSB3aGljaCBlaXRoZXIgZG9lc24ndCBoYXZlIHdpbmRvdy5jb25zb2xlID0+IHRoaXMgaXMgbm9vcCBhbmQgd2UgZG8gbm90aGluZywKICAgICAgLy8gb3Igd2UgYXJlIElFIHdoZXJlIGNvbnNvbGUubG9nIGRvZXNuJ3QgaGF2ZSBhcHBseSBzbyB3ZSBsb2cgYXQgbGVhc3QgZmlyc3QgMiBhcmdzCiAgICAgIHJldHVybiBmdW5jdGlvbihhcmcxLCBhcmcyKSB7CiAgICAgICAgbG9nRm4oYXJnMSwgYXJnMiA9PSBudWxsID8gJycgOiBhcmcyKTsKICAgICAgfTsKICAgIH0KICB9XTsKfQoKdmFyICRwYXJzZU1pbkVyciA9IG1pbkVycignJHBhcnNlJyk7CgovLyBTYW5kYm94aW5nIEFuZ3VsYXIgRXhwcmVzc2lvbnMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEFuZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIGdlbmVyYWxseSBjb25zaWRlcmVkIHNhZmUgYmVjYXVzZSB0aGVzZSBleHByZXNzaW9ucyBvbmx5IGhhdmUgZGlyZWN0Ci8vIGFjY2VzcyB0byBgJHNjb3BlYCBhbmQgbG9jYWxzLiBIb3dldmVyLCBvbmUgY2FuIG9idGFpbiB0aGUgYWJpbGl0eSB0byBleGVjdXRlIGFyYml0cmFyeSBKUyBjb2RlIGJ5Ci8vIG9idGFpbmluZyBhIHJlZmVyZW5jZSB0byBuYXRpdmUgSlMgZnVuY3Rpb25zIHN1Y2ggYXMgdGhlIEZ1bmN0aW9uIGNvbnN0cnVjdG9yLgovLwovLyBBcyBhbiBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIEFuZ3VsYXIgZXhwcmVzc2lvbjoKLy8KLy8gICB7fS50b1N0cmluZy5jb25zdHJ1Y3RvcignYWxlcnQoImV2aWwgSlMgY29kZSIpJykKLy8KLy8gVGhpcyBzYW5kYm94aW5nIHRlY2huaXF1ZSBpcyBub3QgcGVyZmVjdCBhbmQgZG9lc24ndCBhaW0gdG8gYmUuIFRoZSBnb2FsIGlzIHRvIHByZXZlbnQgZXhwbG9pdHMKLy8gYWdhaW5zdCB0aGUgZXhwcmVzc2lvbiBsYW5ndWFnZSwgYnV0IG5vdCB0byBwcmV2ZW50IGV4cGxvaXRzIHRoYXQgd2VyZSBlbmFibGVkIGJ5IGV4cG9zaW5nCi8vIHNlbnNpdGl2ZSBKYXZhU2NyaXB0IG9yIGJyb3dzZXIgQVBJcyBvbiBTY29wZS4gRXhwb3Npbmcgc3VjaCBvYmplY3RzIG9uIGEgU2NvcGUgaXMgbmV2ZXIgYSBnb29kCi8vIHByYWN0aWNlIGFuZCB0aGVyZWZvcmUgd2UgYXJlIG5vdCBldmVuIHRyeWluZyB0byBwcm90ZWN0IGFnYWluc3QgaW50ZXJhY3Rpb24gd2l0aCBhbiBvYmplY3QKLy8gZXhwbGljaXRseSBleHBvc2VkIGluIHRoaXMgd2F5LgovLwovLyBJbiBnZW5lcmFsLCBpdCBpcyBub3QgcG9zc2libGUgdG8gYWNjZXNzIGEgV2luZG93IG9iamVjdCBmcm9tIGFuIGFuZ3VsYXIgZXhwcmVzc2lvbiB1bmxlc3MgYQovLyB3aW5kb3cgb3Igc29tZSBET00gb2JqZWN0IHRoYXQgaGFzIGEgcmVmZXJlbmNlIHRvIHdpbmRvdyBpcyBwdWJsaXNoZWQgb250byBhIFNjb3BlLgovLyBTaW1pbGFybHkgd2UgcHJldmVudCBpbnZvY2F0aW9ucyBvZiBmdW5jdGlvbiBrbm93biB0byBiZSBkYW5nZXJvdXMsIGFzIHdlbGwgYXMgYXNzaWdubWVudHMgdG8KLy8gbmF0aXZlIG9iamVjdHMuCi8vCi8vIFNlZSBodHRwczovL2RvY3MuYW5ndWxhcmpzLm9yZy9ndWlkZS9zZWN1cml0eQoKCmZ1bmN0aW9uIGVuc3VyZVNhZmVNZW1iZXJOYW1lKG5hbWUsIGZ1bGxFeHByZXNzaW9uKSB7CiAgaWYgKG5hbWUgPT09ICJfX2RlZmluZUdldHRlcl9fIiB8fCBuYW1lID09PSAiX19kZWZpbmVTZXR0ZXJfXyIKICAgICAgfHwgbmFtZSA9PT0gIl9fbG9va3VwR2V0dGVyX18iIHx8IG5hbWUgPT09ICJfX2xvb2t1cFNldHRlcl9fIgogICAgICB8fCBuYW1lID09PSAiX19wcm90b19fIikgewogICAgdGhyb3cgJHBhcnNlTWluRXJyKCdpc2VjZmxkJywKICAgICAgICAnQXR0ZW1wdGluZyB0byBhY2Nlc3MgYSBkaXNhbGxvd2VkIGZpZWxkIGluIEFuZ3VsYXIgZXhwcmVzc2lvbnMhICcKICAgICAgICArICdFeHByZXNzaW9uOiB7MH0nLCBmdWxsRXhwcmVzc2lvbik7CiAgfQogIHJldHVybiBuYW1lOwp9CgpmdW5jdGlvbiBlbnN1cmVTYWZlT2JqZWN0KG9iaiwgZnVsbEV4cHJlc3Npb24pIHsKICAvLyBuaWZ0eSBjaGVjayBpZiBvYmogaXMgRnVuY3Rpb24gdGhhdCBpcyBmYXN0IGFuZCB3b3JrcyBhY3Jvc3MgaWZyYW1lcyBhbmQgb3RoZXIgY29udGV4dHMKICBpZiAob2JqKSB7CiAgICBpZiAob2JqLmNvbnN0cnVjdG9yID09PSBvYmopIHsKICAgICAgdGhyb3cgJHBhcnNlTWluRXJyKCdpc2VjZm4nLAogICAgICAgICAgJ1JlZmVyZW5jaW5nIEZ1bmN0aW9uIGluIEFuZ3VsYXIgZXhwcmVzc2lvbnMgaXMgZGlzYWxsb3dlZCEgRXhwcmVzc2lvbjogezB9JywKICAgICAgICAgIGZ1bGxFeHByZXNzaW9uKTsKICAgIH0gZWxzZSBpZiAoLy8gaXNXaW5kb3cob2JqKQogICAgICAgIG9iai53aW5kb3cgPT09IG9iaikgewogICAgICB0aHJvdyAkcGFyc2VNaW5FcnIoJ2lzZWN3aW5kb3cnLAogICAgICAgICAgJ1JlZmVyZW5jaW5nIHRoZSBXaW5kb3cgaW4gQW5ndWxhciBleHByZXNzaW9ucyBpcyBkaXNhbGxvd2VkISBFeHByZXNzaW9uOiB7MH0nLAogICAgICAgICAgZnVsbEV4cHJlc3Npb24pOwogICAgfSBlbHNlIGlmICgvLyBpc0VsZW1lbnQob2JqKQogICAgICAgIG9iai5jaGlsZHJlbiAmJiAob2JqLm5vZGVOYW1lIHx8IChvYmoucHJvcCAmJiBvYmouYXR0ciAmJiBvYmouZmluZCkpKSB7CiAgICAgIHRocm93ICRwYXJzZU1pbkVycignaXNlY2RvbScsCiAgICAgICAgICAnUmVmZXJlbmNpbmcgRE9NIG5vZGVzIGluIEFuZ3VsYXIgZXhwcmVzc2lvbnMgaXMgZGlzYWxsb3dlZCEgRXhwcmVzc2lvbjogezB9JywKICAgICAgICAgIGZ1bGxFeHByZXNzaW9uKTsKICAgIH0gZWxzZSBpZiAoLy8gYmxvY2sgT2JqZWN0IHNvIHRoYXQgd2UgY2FuJ3QgZ2V0IGhvbGQgb2YgZGFuZ2Vyb3VzIE9iamVjdC4qIG1ldGhvZHMKICAgICAgICBvYmogPT09IE9iamVjdCkgewogICAgICB0aHJvdyAkcGFyc2VNaW5FcnIoJ2lzZWNvYmonLAogICAgICAgICAgJ1JlZmVyZW5jaW5nIE9iamVjdCBpbiBBbmd1bGFyIGV4cHJlc3Npb25zIGlzIGRpc2FsbG93ZWQhIEV4cHJlc3Npb246IHswfScsCiAgICAgICAgICBmdWxsRXhwcmVzc2lvbik7CiAgICB9CiAgfQogIHJldHVybiBvYmo7Cn0KCnZhciBDQUxMID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGw7CnZhciBBUFBMWSA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTsKdmFyIEJJTkQgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZDsKCmZ1bmN0aW9uIGVuc3VyZVNhZmVGdW5jdGlvbihvYmosIGZ1bGxFeHByZXNzaW9uKSB7CiAgaWYgKG9iaikgewogICAgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gb2JqKSB7CiAgICAgIHRocm93ICRwYXJzZU1pbkVycignaXNlY2ZuJywKICAgICAgICAnUmVmZXJlbmNpbmcgRnVuY3Rpb24gaW4gQW5ndWxhciBleHByZXNzaW9ucyBpcyBkaXNhbGxvd2VkISBFeHByZXNzaW9uOiB7MH0nLAogICAgICAgIGZ1bGxFeHByZXNzaW9uKTsKICAgIH0gZWxzZSBpZiAob2JqID09PSBDQUxMIHx8IG9iaiA9PT0gQVBQTFkgfHwgb2JqID09PSBCSU5EKSB7CiAgICAgIHRocm93ICRwYXJzZU1pbkVycignaXNlY2ZmJywKICAgICAgICAnUmVmZXJlbmNpbmcgY2FsbCwgYXBwbHkgb3IgYmluZCBpbiBBbmd1bGFyIGV4cHJlc3Npb25zIGlzIGRpc2FsbG93ZWQhIEV4cHJlc3Npb246IHswfScsCiAgICAgICAgZnVsbEV4cHJlc3Npb24pOwogICAgfQogIH0KfQoKLy9LZXl3b3JkIGNvbnN0YW50cwp2YXIgQ09OU1RBTlRTID0gY3JlYXRlTWFwKCk7CmZvckVhY2goewogICdudWxsJzogZnVuY3Rpb24oKSB7IHJldHVybiBudWxsOyB9LAogICd0cnVlJzogZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LAogICdmYWxzZSc6IGZ1bmN0aW9uKCkgeyByZXR1cm4gZmFsc2U7IH0sCiAgJ3VuZGVmaW5lZCc6IGZ1bmN0aW9uKCkge30KfSwgZnVuY3Rpb24oY29uc3RhbnRHZXR0ZXIsIG5hbWUpIHsKICBjb25zdGFudEdldHRlci5jb25zdGFudCA9IGNvbnN0YW50R2V0dGVyLmxpdGVyYWwgPSBjb25zdGFudEdldHRlci5zaGFyZWRHZXR0ZXIgPSB0cnVlOwogIENPTlNUQU5UU1tuYW1lXSA9IGNvbnN0YW50R2V0dGVyOwp9KTsKCi8vTm90IHF1aXRlIGEgY29uc3RhbnQsIGJ1dCBjYW4gYmUgbGV4L3BhcnNlZCB0aGUgc2FtZQpDT05TVEFOVFNbJ3RoaXMnXSA9IGZ1bmN0aW9uKHNlbGYpIHsgcmV0dXJuIHNlbGY7IH07CkNPTlNUQU5UU1sndGhpcyddLnNoYXJlZEdldHRlciA9IHRydWU7CgoKLy9PcGVyYXRvcnMgLSB3aWxsIGJlIHdyYXBwZWQgYnkgYmluYXJ5Rm4vdW5hcnlGbi9hc3NpZ25tZW50L2ZpbHRlcgp2YXIgT1BFUkFUT1JTID0gZXh0ZW5kKGNyZWF0ZU1hcCgpLCB7CiAgICAnKyc6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7CiAgICAgIGE9YShzZWxmLCBsb2NhbHMpOyBiPWIoc2VsZiwgbG9jYWxzKTsKICAgICAgaWYgKGlzRGVmaW5lZChhKSkgewogICAgICAgIGlmIChpc0RlZmluZWQoYikpIHsKICAgICAgICAgIHJldHVybiBhICsgYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGE7CiAgICAgIH0KICAgICAgcmV0dXJuIGlzRGVmaW5lZChiKSA/IGIgOiB1bmRlZmluZWQ7fSwKICAgICctJzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHsKICAgICAgICAgIGE9YShzZWxmLCBsb2NhbHMpOyBiPWIoc2VsZiwgbG9jYWxzKTsKICAgICAgICAgIHJldHVybiAoaXNEZWZpbmVkKGEpID8gYSA6IDApIC0gKGlzRGVmaW5lZChiKSA/IGIgOiAwKTsKICAgICAgICB9LAogICAgJyonOmZ1bmN0aW9uKHNlbGYsIGxvY2FscywgYSwgYikge3JldHVybiBhKHNlbGYsIGxvY2FscykgKiBiKHNlbGYsIGxvY2Fscyk7fSwKICAgICcvJzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpIC8gYihzZWxmLCBsb2NhbHMpO30sCiAgICAnJSc6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7cmV0dXJuIGEoc2VsZiwgbG9jYWxzKSAlIGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJz09PSc6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7cmV0dXJuIGEoc2VsZiwgbG9jYWxzKSA9PT0gYihzZWxmLCBsb2NhbHMpO30sCiAgICAnIT09JzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpICE9PSBiKHNlbGYsIGxvY2Fscyk7fSwKICAgICc9PSc6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7cmV0dXJuIGEoc2VsZiwgbG9jYWxzKSA9PSBiKHNlbGYsIGxvY2Fscyk7fSwKICAgICchPSc6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7cmV0dXJuIGEoc2VsZiwgbG9jYWxzKSAhPSBiKHNlbGYsIGxvY2Fscyk7fSwKICAgICc8JzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpIDwgYihzZWxmLCBsb2NhbHMpO30sCiAgICAnPic6ZnVuY3Rpb24oc2VsZiwgbG9jYWxzLCBhLCBiKSB7cmV0dXJuIGEoc2VsZiwgbG9jYWxzKSA+IGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJzw9JzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpIDw9IGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJz49JzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpID49IGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJyYmJzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpICYmIGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJ3x8JzpmdW5jdGlvbihzZWxmLCBsb2NhbHMsIGEsIGIpIHtyZXR1cm4gYShzZWxmLCBsb2NhbHMpIHx8IGIoc2VsZiwgbG9jYWxzKTt9LAogICAgJyEnOmZ1bmN0aW9uKHNlbGYsIGxvY2FscywgYSkge3JldHVybiAhYShzZWxmLCBsb2NhbHMpO30sCgogICAgLy9Ub2tlbml6ZWQgYXMgb3BlcmF0b3JzIGJ1dCBwYXJzZWQgYXMgYXNzaWdubWVudC9maWx0ZXJzCiAgICAnPSc6dHJ1ZSwKICAgICd8Jzp0cnVlCn0pOwp2YXIgRVNDQVBFID0geyJuIjoiXG4iLCAiZiI6IlxmIiwgInIiOiJcciIsICJ0IjoiXHQiLCAidiI6Ilx2IiwgIiciOiInIiwgJyInOiciJ307CgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCgovKioKICogQGNvbnN0cnVjdG9yCiAqLwp2YXIgTGV4ZXIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdGhpcy5vcHRpb25zID0gb3B0aW9uczsKfTsKCkxleGVyLnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogTGV4ZXIsCgogIGxleDogZnVuY3Rpb24odGV4dCkgewogICAgdGhpcy50ZXh0ID0gdGV4dDsKICAgIHRoaXMuaW5kZXggPSAwOwogICAgdGhpcy50b2tlbnMgPSBbXTsKCiAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudGV4dC5sZW5ndGgpIHsKICAgICAgdmFyIGNoID0gdGhpcy50ZXh0LmNoYXJBdCh0aGlzLmluZGV4KTsKICAgICAgaWYgKGNoID09PSAnIicgfHwgY2ggPT09ICInIikgewogICAgICAgIHRoaXMucmVhZFN0cmluZyhjaCk7CiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc051bWJlcihjaCkgfHwgY2ggPT09ICcuJyAmJiB0aGlzLmlzTnVtYmVyKHRoaXMucGVlaygpKSkgewogICAgICAgIHRoaXMucmVhZE51bWJlcigpOwogICAgICB9IGVsc2UgaWYgKHRoaXMuaXNJZGVudChjaCkpIHsKICAgICAgICB0aGlzLnJlYWRJZGVudCgpOwogICAgICB9IGVsc2UgaWYgKHRoaXMuaXMoY2gsICcoKXt9W10uLDs6PycpKSB7CiAgICAgICAgdGhpcy50b2tlbnMucHVzaCh7aW5kZXg6IHRoaXMuaW5kZXgsIHRleHQ6IGNofSk7CiAgICAgICAgdGhpcy5pbmRleCsrOwogICAgICB9IGVsc2UgaWYgKHRoaXMuaXNXaGl0ZXNwYWNlKGNoKSkgewogICAgICAgIHRoaXMuaW5kZXgrKzsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgY2gyID0gY2ggKyB0aGlzLnBlZWsoKTsKICAgICAgICB2YXIgY2gzID0gY2gyICsgdGhpcy5wZWVrKDIpOwogICAgICAgIHZhciBvcDEgPSBPUEVSQVRPUlNbY2hdOwogICAgICAgIHZhciBvcDIgPSBPUEVSQVRPUlNbY2gyXTsKICAgICAgICB2YXIgb3AzID0gT1BFUkFUT1JTW2NoM107CiAgICAgICAgaWYgKG9wMSB8fCBvcDIgfHwgb3AzKSB7CiAgICAgICAgICB2YXIgdG9rZW4gPSBvcDMgPyBjaDMgOiAob3AyID8gY2gyIDogY2gpOwogICAgICAgICAgdGhpcy50b2tlbnMucHVzaCh7aW5kZXg6IHRoaXMuaW5kZXgsIHRleHQ6IHRva2VuLCBvcGVyYXRvcjogdHJ1ZX0pOwogICAgICAgICAgdGhpcy5pbmRleCArPSB0b2tlbi5sZW5ndGg7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRoaXMudGhyb3dFcnJvcignVW5leHBlY3RlZCBuZXh0IGNoYXJhY3RlciAnLCB0aGlzLmluZGV4LCB0aGlzLmluZGV4ICsgMSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICByZXR1cm4gdGhpcy50b2tlbnM7CiAgfSwKCiAgaXM6IGZ1bmN0aW9uKGNoLCBjaGFycykgewogICAgcmV0dXJuIGNoYXJzLmluZGV4T2YoY2gpICE9PSAtMTsKICB9LAoKICBwZWVrOiBmdW5jdGlvbihpKSB7CiAgICB2YXIgbnVtID0gaSB8fCAxOwogICAgcmV0dXJuICh0aGlzLmluZGV4ICsgbnVtIDwgdGhpcy50ZXh0Lmxlbmd0aCkgPyB0aGlzLnRleHQuY2hhckF0KHRoaXMuaW5kZXggKyBudW0pIDogZmFsc2U7CiAgfSwKCiAgaXNOdW1iZXI6IGZ1bmN0aW9uKGNoKSB7CiAgICByZXR1cm4gKCcwJyA8PSBjaCAmJiBjaCA8PSAnOScpICYmIHR5cGVvZiBjaCA9PT0gInN0cmluZyI7CiAgfSwKCiAgaXNXaGl0ZXNwYWNlOiBmdW5jdGlvbihjaCkgewogICAgLy8gSUUgdHJlYXRzIG5vbi1icmVha2luZyBzcGFjZSBhcyBcdTAwQTAKICAgIHJldHVybiAoY2ggPT09ICcgJyB8fCBjaCA9PT0gJ1xyJyB8fCBjaCA9PT0gJ1x0JyB8fAogICAgICAgICAgICBjaCA9PT0gJ1xuJyB8fCBjaCA9PT0gJ1x2JyB8fCBjaCA9PT0gJ1x1MDBBMCcpOwogIH0sCgogIGlzSWRlbnQ6IGZ1bmN0aW9uKGNoKSB7CiAgICByZXR1cm4gKCdhJyA8PSBjaCAmJiBjaCA8PSAneicgfHwKICAgICAgICAgICAgJ0EnIDw9IGNoICYmIGNoIDw9ICdaJyB8fAogICAgICAgICAgICAnXycgPT09IGNoIHx8IGNoID09PSAnJCcpOwogIH0sCgogIGlzRXhwT3BlcmF0b3I6IGZ1bmN0aW9uKGNoKSB7CiAgICByZXR1cm4gKGNoID09PSAnLScgfHwgY2ggPT09ICcrJyB8fCB0aGlzLmlzTnVtYmVyKGNoKSk7CiAgfSwKCiAgdGhyb3dFcnJvcjogZnVuY3Rpb24oZXJyb3IsIHN0YXJ0LCBlbmQpIHsKICAgIGVuZCA9IGVuZCB8fCB0aGlzLmluZGV4OwogICAgdmFyIGNvbFN0ciA9IChpc0RlZmluZWQoc3RhcnQpCiAgICAgICAgICAgID8gJ3MgJyArIHN0YXJ0ICsgICctJyArIHRoaXMuaW5kZXggKyAnIFsnICsgdGhpcy50ZXh0LnN1YnN0cmluZyhzdGFydCwgZW5kKSArICddJwogICAgICAgICAgICA6ICcgJyArIGVuZCk7CiAgICB0aHJvdyAkcGFyc2VNaW5FcnIoJ2xleGVycicsICdMZXhlciBFcnJvcjogezB9IGF0IGNvbHVtbnsxfSBpbiBleHByZXNzaW9uIFt7Mn1dLicsCiAgICAgICAgZXJyb3IsIGNvbFN0ciwgdGhpcy50ZXh0KTsKICB9LAoKICByZWFkTnVtYmVyOiBmdW5jdGlvbigpIHsKICAgIHZhciBudW1iZXIgPSAnJzsKICAgIHZhciBzdGFydCA9IHRoaXMuaW5kZXg7CiAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudGV4dC5sZW5ndGgpIHsKICAgICAgdmFyIGNoID0gbG93ZXJjYXNlKHRoaXMudGV4dC5jaGFyQXQodGhpcy5pbmRleCkpOwogICAgICBpZiAoY2ggPT0gJy4nIHx8IHRoaXMuaXNOdW1iZXIoY2gpKSB7CiAgICAgICAgbnVtYmVyICs9IGNoOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBwZWVrQ2ggPSB0aGlzLnBlZWsoKTsKICAgICAgICBpZiAoY2ggPT0gJ2UnICYmIHRoaXMuaXNFeHBPcGVyYXRvcihwZWVrQ2gpKSB7CiAgICAgICAgICBudW1iZXIgKz0gY2g7CiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzRXhwT3BlcmF0b3IoY2gpICYmCiAgICAgICAgICAgIHBlZWtDaCAmJiB0aGlzLmlzTnVtYmVyKHBlZWtDaCkgJiYKICAgICAgICAgICAgbnVtYmVyLmNoYXJBdChudW1iZXIubGVuZ3RoIC0gMSkgPT0gJ2UnKSB7CiAgICAgICAgICBudW1iZXIgKz0gY2g7CiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzRXhwT3BlcmF0b3IoY2gpICYmCiAgICAgICAgICAgICghcGVla0NoIHx8ICF0aGlzLmlzTnVtYmVyKHBlZWtDaCkpICYmCiAgICAgICAgICAgIG51bWJlci5jaGFyQXQobnVtYmVyLmxlbmd0aCAtIDEpID09ICdlJykgewogICAgICAgICAgdGhpcy50aHJvd0Vycm9yKCdJbnZhbGlkIGV4cG9uZW50Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgICB0aGlzLmluZGV4Kys7CiAgICB9CiAgICB0aGlzLnRva2Vucy5wdXNoKHsKICAgICAgaW5kZXg6IHN0YXJ0LAogICAgICB0ZXh0OiBudW1iZXIsCiAgICAgIGNvbnN0YW50OiB0cnVlLAogICAgICB2YWx1ZTogTnVtYmVyKG51bWJlcikKICAgIH0pOwogIH0sCgogIHJlYWRJZGVudDogZnVuY3Rpb24oKSB7CiAgICB2YXIgc3RhcnQgPSB0aGlzLmluZGV4OwogICAgd2hpbGUgKHRoaXMuaW5kZXggPCB0aGlzLnRleHQubGVuZ3RoKSB7CiAgICAgIHZhciBjaCA9IHRoaXMudGV4dC5jaGFyQXQodGhpcy5pbmRleCk7CiAgICAgIGlmICghKHRoaXMuaXNJZGVudChjaCkgfHwgdGhpcy5pc051bWJlcihjaCkpKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgdGhpcy5pbmRleCsrOwogICAgfQogICAgdGhpcy50b2tlbnMucHVzaCh7CiAgICAgIGluZGV4OiBzdGFydCwKICAgICAgdGV4dDogdGhpcy50ZXh0LnNsaWNlKHN0YXJ0LCB0aGlzLmluZGV4KSwKICAgICAgaWRlbnRpZmllcjogdHJ1ZQogICAgfSk7CiAgfSwKCiAgcmVhZFN0cmluZzogZnVuY3Rpb24ocXVvdGUpIHsKICAgIHZhciBzdGFydCA9IHRoaXMuaW5kZXg7CiAgICB0aGlzLmluZGV4Kys7CiAgICB2YXIgc3RyaW5nID0gJyc7CiAgICB2YXIgcmF3U3RyaW5nID0gcXVvdGU7CiAgICB2YXIgZXNjYXBlID0gZmFsc2U7CiAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudGV4dC5sZW5ndGgpIHsKICAgICAgdmFyIGNoID0gdGhpcy50ZXh0LmNoYXJBdCh0aGlzLmluZGV4KTsKICAgICAgcmF3U3RyaW5nICs9IGNoOwogICAgICBpZiAoZXNjYXBlKSB7CiAgICAgICAgaWYgKGNoID09PSAndScpIHsKICAgICAgICAgIHZhciBoZXggPSB0aGlzLnRleHQuc3Vic3RyaW5nKHRoaXMuaW5kZXggKyAxLCB0aGlzLmluZGV4ICsgNSk7CiAgICAgICAgICBpZiAoIWhleC5tYXRjaCgvW1xkYS1mXXs0fS9pKSkKICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKCdJbnZhbGlkIHVuaWNvZGUgZXNjYXBlIFtcXHUnICsgaGV4ICsgJ10nKTsKICAgICAgICAgIHRoaXMuaW5kZXggKz0gNDsKICAgICAgICAgIHN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGhleCwgMTYpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdmFyIHJlcCA9IEVTQ0FQRVtjaF07CiAgICAgICAgICBzdHJpbmcgPSBzdHJpbmcgKyAocmVwIHx8IGNoKTsKICAgICAgICB9CiAgICAgICAgZXNjYXBlID0gZmFsc2U7CiAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICdcXCcpIHsKICAgICAgICBlc2NhcGUgPSB0cnVlOwogICAgICB9IGVsc2UgaWYgKGNoID09PSBxdW90ZSkgewogICAgICAgIHRoaXMuaW5kZXgrKzsKICAgICAgICB0aGlzLnRva2Vucy5wdXNoKHsKICAgICAgICAgIGluZGV4OiBzdGFydCwKICAgICAgICAgIHRleHQ6IHJhd1N0cmluZywKICAgICAgICAgIGNvbnN0YW50OiB0cnVlLAogICAgICAgICAgdmFsdWU6IHN0cmluZwogICAgICAgIH0pOwogICAgICAgIHJldHVybjsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmcgKz0gY2g7CiAgICAgIH0KICAgICAgdGhpcy5pbmRleCsrOwogICAgfQogICAgdGhpcy50aHJvd0Vycm9yKCdVbnRlcm1pbmF0ZWQgcXVvdGUnLCBzdGFydCk7CiAgfQp9OwoKCmZ1bmN0aW9uIGlzQ29uc3RhbnQoZXhwKSB7CiAgcmV0dXJuIGV4cC5jb25zdGFudDsKfQoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKi8KdmFyIFBhcnNlciA9IGZ1bmN0aW9uKGxleGVyLCAkZmlsdGVyLCBvcHRpb25zKSB7CiAgdGhpcy5sZXhlciA9IGxleGVyOwogIHRoaXMuJGZpbHRlciA9ICRmaWx0ZXI7CiAgdGhpcy5vcHRpb25zID0gb3B0aW9uczsKfTsKClBhcnNlci5aRVJPID0gZXh0ZW5kKGZ1bmN0aW9uKCkgewogIHJldHVybiAwOwp9LCB7CiAgc2hhcmVkR2V0dGVyOiB0cnVlLAogIGNvbnN0YW50OiB0cnVlCn0pOwoKUGFyc2VyLnByb3RvdHlwZSA9IHsKICBjb25zdHJ1Y3RvcjogUGFyc2VyLAoKICBwYXJzZTogZnVuY3Rpb24odGV4dCkgewogICAgdGhpcy50ZXh0ID0gdGV4dDsKICAgIHRoaXMudG9rZW5zID0gdGhpcy5sZXhlci5sZXgodGV4dCk7CgogICAgdmFyIHZhbHVlID0gdGhpcy5zdGF0ZW1lbnRzKCk7CgogICAgaWYgKHRoaXMudG9rZW5zLmxlbmd0aCAhPT0gMCkgewogICAgICB0aGlzLnRocm93RXJyb3IoJ2lzIGFuIHVuZXhwZWN0ZWQgdG9rZW4nLCB0aGlzLnRva2Vuc1swXSk7CiAgICB9CgogICAgdmFsdWUubGl0ZXJhbCA9ICEhdmFsdWUubGl0ZXJhbDsKICAgIHZhbHVlLmNvbnN0YW50ID0gISF2YWx1ZS5jb25zdGFudDsKCiAgICByZXR1cm4gdmFsdWU7CiAgfSwKCiAgcHJpbWFyeTogZnVuY3Rpb24oKSB7CiAgICB2YXIgcHJpbWFyeTsKICAgIGlmICh0aGlzLmV4cGVjdCgnKCcpKSB7CiAgICAgIHByaW1hcnkgPSB0aGlzLmZpbHRlckNoYWluKCk7CiAgICAgIHRoaXMuY29uc3VtZSgnKScpOwogICAgfSBlbHNlIGlmICh0aGlzLmV4cGVjdCgnWycpKSB7CiAgICAgIHByaW1hcnkgPSB0aGlzLmFycmF5RGVjbGFyYXRpb24oKTsKICAgIH0gZWxzZSBpZiAodGhpcy5leHBlY3QoJ3snKSkgewogICAgICBwcmltYXJ5ID0gdGhpcy5vYmplY3QoKTsKICAgIH0gZWxzZSBpZiAodGhpcy5wZWVrKCkuaWRlbnRpZmllciAmJiB0aGlzLnBlZWsoKS50ZXh0IGluIENPTlNUQU5UUykgewogICAgICBwcmltYXJ5ID0gQ09OU1RBTlRTW3RoaXMuY29uc3VtZSgpLnRleHRdOwogICAgfSBlbHNlIGlmICh0aGlzLnBlZWsoKS5pZGVudGlmaWVyKSB7CiAgICAgIHByaW1hcnkgPSB0aGlzLmlkZW50aWZpZXIoKTsKICAgIH0gZWxzZSBpZiAodGhpcy5wZWVrKCkuY29uc3RhbnQpIHsKICAgICAgcHJpbWFyeSA9IHRoaXMuY29uc3RhbnQoKTsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMudGhyb3dFcnJvcignbm90IGEgcHJpbWFyeSBleHByZXNzaW9uJywgdGhpcy5wZWVrKCkpOwogICAgfQoKICAgIHZhciBuZXh0LCBjb250ZXh0OwogICAgd2hpbGUgKChuZXh0ID0gdGhpcy5leHBlY3QoJygnLCAnWycsICcuJykpKSB7CiAgICAgIGlmIChuZXh0LnRleHQgPT09ICcoJykgewogICAgICAgIHByaW1hcnkgPSB0aGlzLmZ1bmN0aW9uQ2FsbChwcmltYXJ5LCBjb250ZXh0KTsKICAgICAgICBjb250ZXh0ID0gbnVsbDsKICAgICAgfSBlbHNlIGlmIChuZXh0LnRleHQgPT09ICdbJykgewogICAgICAgIGNvbnRleHQgPSBwcmltYXJ5OwogICAgICAgIHByaW1hcnkgPSB0aGlzLm9iamVjdEluZGV4KHByaW1hcnkpOwogICAgICB9IGVsc2UgaWYgKG5leHQudGV4dCA9PT0gJy4nKSB7CiAgICAgICAgY29udGV4dCA9IHByaW1hcnk7CiAgICAgICAgcHJpbWFyeSA9IHRoaXMuZmllbGRBY2Nlc3MocHJpbWFyeSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy50aHJvd0Vycm9yKCdJTVBPU1NJQkxFJyk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBwcmltYXJ5OwogIH0sCgogIHRocm93RXJyb3I6IGZ1bmN0aW9uKG1zZywgdG9rZW4pIHsKICAgIHRocm93ICRwYXJzZU1pbkVycignc3ludGF4JywKICAgICAgICAnU3ludGF4IEVycm9yOiBUb2tlbiBcJ3swfVwnIHsxfSBhdCBjb2x1bW4gezJ9IG9mIHRoZSBleHByZXNzaW9uIFt7M31dIHN0YXJ0aW5nIGF0IFt7NH1dLicsCiAgICAgICAgICB0b2tlbi50ZXh0LCBtc2csICh0b2tlbi5pbmRleCArIDEpLCB0aGlzLnRleHQsIHRoaXMudGV4dC5zdWJzdHJpbmcodG9rZW4uaW5kZXgpKTsKICB9LAoKICBwZWVrVG9rZW46IGZ1bmN0aW9uKCkgewogICAgaWYgKHRoaXMudG9rZW5zLmxlbmd0aCA9PT0gMCkKICAgICAgdGhyb3cgJHBhcnNlTWluRXJyKCd1ZW9lJywgJ1VuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb246IHswfScsIHRoaXMudGV4dCk7CiAgICByZXR1cm4gdGhpcy50b2tlbnNbMF07CiAgfSwKCiAgcGVlazogZnVuY3Rpb24oZTEsIGUyLCBlMywgZTQpIHsKICAgIHJldHVybiB0aGlzLnBlZWtBaGVhZCgwLCBlMSwgZTIsIGUzLCBlNCk7CiAgfSwKICBwZWVrQWhlYWQ6IGZ1bmN0aW9uKGksIGUxLCBlMiwgZTMsIGU0KSB7CiAgICBpZiAodGhpcy50b2tlbnMubGVuZ3RoID4gaSkgewogICAgICB2YXIgdG9rZW4gPSB0aGlzLnRva2Vuc1tpXTsKICAgICAgdmFyIHQgPSB0b2tlbi50ZXh0OwogICAgICBpZiAodCA9PT0gZTEgfHwgdCA9PT0gZTIgfHwgdCA9PT0gZTMgfHwgdCA9PT0gZTQgfHwKICAgICAgICAgICghZTEgJiYgIWUyICYmICFlMyAmJiAhZTQpKSB7CiAgICAgICAgcmV0dXJuIHRva2VuOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgZXhwZWN0OiBmdW5jdGlvbihlMSwgZTIsIGUzLCBlNCkgewogICAgdmFyIHRva2VuID0gdGhpcy5wZWVrKGUxLCBlMiwgZTMsIGU0KTsKICAgIGlmICh0b2tlbikgewogICAgICB0aGlzLnRva2Vucy5zaGlmdCgpOwogICAgICByZXR1cm4gdG9rZW47CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgY29uc3VtZTogZnVuY3Rpb24oZTEpIHsKICAgIGlmICh0aGlzLnRva2Vucy5sZW5ndGggPT09IDApIHsKICAgICAgdGhyb3cgJHBhcnNlTWluRXJyKCd1ZW9lJywgJ1VuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb246IHswfScsIHRoaXMudGV4dCk7CiAgICB9CgogICAgdmFyIHRva2VuID0gdGhpcy5leHBlY3QoZTEpOwogICAgaWYgKCF0b2tlbikgewogICAgICB0aGlzLnRocm93RXJyb3IoJ2lzIHVuZXhwZWN0ZWQsIGV4cGVjdGluZyBbJyArIGUxICsgJ10nLCB0aGlzLnBlZWsoKSk7CiAgICB9CiAgICByZXR1cm4gdG9rZW47CiAgfSwKCiAgdW5hcnlGbjogZnVuY3Rpb24ob3AsIHJpZ2h0KSB7CiAgICB2YXIgZm4gPSBPUEVSQVRPUlNbb3BdOwogICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbiAkcGFyc2VVbmFyeUZuKHNlbGYsIGxvY2FscykgewogICAgICByZXR1cm4gZm4oc2VsZiwgbG9jYWxzLCByaWdodCk7CiAgICB9LCB7CiAgICAgIGNvbnN0YW50OnJpZ2h0LmNvbnN0YW50LAogICAgICBpbnB1dHM6IFtyaWdodF0KICAgIH0pOwogIH0sCgogIGJpbmFyeUZuOiBmdW5jdGlvbihsZWZ0LCBvcCwgcmlnaHQsIGlzQnJhbmNoaW5nKSB7CiAgICB2YXIgZm4gPSBPUEVSQVRPUlNbb3BdOwogICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbiAkcGFyc2VCaW5hcnlGbihzZWxmLCBsb2NhbHMpIHsKICAgICAgcmV0dXJuIGZuKHNlbGYsIGxvY2FscywgbGVmdCwgcmlnaHQpOwogICAgfSwgewogICAgICBjb25zdGFudDogbGVmdC5jb25zdGFudCAmJiByaWdodC5jb25zdGFudCwKICAgICAgaW5wdXRzOiAhaXNCcmFuY2hpbmcgJiYgW2xlZnQsIHJpZ2h0XQogICAgfSk7CiAgfSwKCiAgaWRlbnRpZmllcjogZnVuY3Rpb24oKSB7CiAgICB2YXIgaWQgPSB0aGlzLmNvbnN1bWUoKS50ZXh0OwoKICAgIC8vQ29udGludWUgcmVhZGluZyBlYWNoIGAuaWRlbnRpZmllcmAgdW5sZXNzIGl0IGlzIGEgbWV0aG9kIGludm9jYXRpb24KICAgIHdoaWxlICh0aGlzLnBlZWsoJy4nKSAmJiB0aGlzLnBlZWtBaGVhZCgxKS5pZGVudGlmaWVyICYmICF0aGlzLnBlZWtBaGVhZCgyLCAnKCcpKSB7CiAgICAgIGlkICs9IHRoaXMuY29uc3VtZSgpLnRleHQgKyB0aGlzLmNvbnN1bWUoKS50ZXh0OwogICAgfQoKICAgIHJldHVybiBnZXR0ZXJGbihpZCwgdGhpcy5vcHRpb25zLCB0aGlzLnRleHQpOwogIH0sCgogIGNvbnN0YW50OiBmdW5jdGlvbigpIHsKICAgIHZhciB2YWx1ZSA9IHRoaXMuY29uc3VtZSgpLnZhbHVlOwoKICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24gJHBhcnNlQ29uc3RhbnQoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0sIHsKICAgICAgY29uc3RhbnQ6IHRydWUsCiAgICAgIGxpdGVyYWw6IHRydWUKICAgIH0pOwogIH0sCgogIHN0YXRlbWVudHM6IGZ1bmN0aW9uKCkgewogICAgdmFyIHN0YXRlbWVudHMgPSBbXTsKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgIGlmICh0aGlzLnRva2Vucy5sZW5ndGggPiAwICYmICF0aGlzLnBlZWsoJ30nLCAnKScsICc7JywgJ10nKSkKICAgICAgICBzdGF0ZW1lbnRzLnB1c2godGhpcy5maWx0ZXJDaGFpbigpKTsKICAgICAgaWYgKCF0aGlzLmV4cGVjdCgnOycpKSB7CiAgICAgICAgLy8gb3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSB3aGVyZSB0aGVyZSBpcyBvbmx5IG9uZSBzdGF0ZW1lbnQuCiAgICAgICAgLy8gVE9ETyhzaXplKTogbWF5YmUgd2Ugc2hvdWxkIG5vdCBzdXBwb3J0IG11bHRpcGxlIHN0YXRlbWVudHM/CiAgICAgICAgcmV0dXJuIChzdGF0ZW1lbnRzLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgPyBzdGF0ZW1lbnRzWzBdCiAgICAgICAgICAgIDogZnVuY3Rpb24gJHBhcnNlU3RhdGVtZW50cyhzZWxmLCBsb2NhbHMpIHsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHN0YXRlbWVudHMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgICAgICAgICAgICB2YWx1ZSA9IHN0YXRlbWVudHNbaV0oc2VsZiwgbG9jYWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICAgICAgICB9OwogICAgICB9CiAgICB9CiAgfSwKCiAgZmlsdGVyQ2hhaW46IGZ1bmN0aW9uKCkgewogICAgdmFyIGxlZnQgPSB0aGlzLmV4cHJlc3Npb24oKTsKICAgIHZhciB0b2tlbjsKICAgIHdoaWxlICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnfCcpKSkgewogICAgICBsZWZ0ID0gdGhpcy5maWx0ZXIobGVmdCk7CiAgICB9CiAgICByZXR1cm4gbGVmdDsKICB9LAoKICBmaWx0ZXI6IGZ1bmN0aW9uKGlucHV0Rm4pIHsKICAgIHZhciBmbiA9IHRoaXMuJGZpbHRlcih0aGlzLmNvbnN1bWUoKS50ZXh0KTsKICAgIHZhciBhcmdzRm47CiAgICB2YXIgYXJnczsKCiAgICBpZiAodGhpcy5wZWVrKCc6JykpIHsKICAgICAgYXJnc0ZuID0gW107CiAgICAgIGFyZ3MgPSBbXTsgLy8gd2UgY2FuIHNhZmVseSByZXVzZSB0aGUgYXJyYXkKICAgICAgd2hpbGUgKHRoaXMuZXhwZWN0KCc6JykpIHsKICAgICAgICBhcmdzRm4ucHVzaCh0aGlzLmV4cHJlc3Npb24oKSk7CiAgICAgIH0KICAgIH0KCiAgICB2YXIgaW5wdXRzID0gW2lucHV0Rm5dLmNvbmNhdChhcmdzRm4gfHwgW10pOwoKICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24gJHBhcnNlRmlsdGVyKHNlbGYsIGxvY2FscykgewogICAgICB2YXIgaW5wdXQgPSBpbnB1dEZuKHNlbGYsIGxvY2Fscyk7CiAgICAgIGlmIChhcmdzKSB7CiAgICAgICAgYXJnc1swXSA9IGlucHV0OwoKICAgICAgICB2YXIgaSA9IGFyZ3NGbi5sZW5ndGg7CiAgICAgICAgd2hpbGUgKGktLSkgewogICAgICAgICAgYXJnc1tpICsgMV0gPSBhcmdzRm5baV0oc2VsZiwgbG9jYWxzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmbi5hcHBseSh1bmRlZmluZWQsIGFyZ3MpOwogICAgICB9CgogICAgICByZXR1cm4gZm4oaW5wdXQpOwogICAgfSwgewogICAgICBjb25zdGFudDogIWZuLiRzdGF0ZWZ1bCAmJiBpbnB1dHMuZXZlcnkoaXNDb25zdGFudCksCiAgICAgIGlucHV0czogIWZuLiRzdGF0ZWZ1bCAmJiBpbnB1dHMKICAgIH0pOwogIH0sCgogIGV4cHJlc3Npb246IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuYXNzaWdubWVudCgpOwogIH0sCgogIGFzc2lnbm1lbnQ6IGZ1bmN0aW9uKCkgewogICAgdmFyIGxlZnQgPSB0aGlzLnRlcm5hcnkoKTsKICAgIHZhciByaWdodDsKICAgIHZhciB0b2tlbjsKICAgIGlmICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnPScpKSkgewogICAgICBpZiAoIWxlZnQuYXNzaWduKSB7CiAgICAgICAgdGhpcy50aHJvd0Vycm9yKCdpbXBsaWVzIGFzc2lnbm1lbnQgYnV0IFsnICsKICAgICAgICAgICAgdGhpcy50ZXh0LnN1YnN0cmluZygwLCB0b2tlbi5pbmRleCkgKyAnXSBjYW4gbm90IGJlIGFzc2lnbmVkIHRvJywgdG9rZW4pOwogICAgICB9CiAgICAgIHJpZ2h0ID0gdGhpcy50ZXJuYXJ5KCk7CiAgICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24gJHBhcnNlQXNzaWdubWVudChzY29wZSwgbG9jYWxzKSB7CiAgICAgICAgcmV0dXJuIGxlZnQuYXNzaWduKHNjb3BlLCByaWdodChzY29wZSwgbG9jYWxzKSwgbG9jYWxzKTsKICAgICAgfSwgewogICAgICAgIGlucHV0czogW2xlZnQsIHJpZ2h0XQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiBsZWZ0OwogIH0sCgogIHRlcm5hcnk6IGZ1bmN0aW9uKCkgewogICAgdmFyIGxlZnQgPSB0aGlzLmxvZ2ljYWxPUigpOwogICAgdmFyIG1pZGRsZTsKICAgIHZhciB0b2tlbjsKICAgIGlmICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnPycpKSkgewogICAgICBtaWRkbGUgPSB0aGlzLmFzc2lnbm1lbnQoKTsKICAgICAgaWYgKHRoaXMuY29uc3VtZSgnOicpKSB7CiAgICAgICAgdmFyIHJpZ2h0ID0gdGhpcy5hc3NpZ25tZW50KCk7CgogICAgICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24gJHBhcnNlVGVybmFyeShzZWxmLCBsb2NhbHMpIHsKICAgICAgICAgIHJldHVybiBsZWZ0KHNlbGYsIGxvY2FscykgPyBtaWRkbGUoc2VsZiwgbG9jYWxzKSA6IHJpZ2h0KHNlbGYsIGxvY2Fscyk7CiAgICAgICAgfSwgewogICAgICAgICAgY29uc3RhbnQ6IGxlZnQuY29uc3RhbnQgJiYgbWlkZGxlLmNvbnN0YW50ICYmIHJpZ2h0LmNvbnN0YW50CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gbGVmdDsKICB9LAoKICBsb2dpY2FsT1I6IGZ1bmN0aW9uKCkgewogICAgdmFyIGxlZnQgPSB0aGlzLmxvZ2ljYWxBTkQoKTsKICAgIHZhciB0b2tlbjsKICAgIHdoaWxlICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnfHwnKSkpIHsKICAgICAgbGVmdCA9IHRoaXMuYmluYXJ5Rm4obGVmdCwgdG9rZW4udGV4dCwgdGhpcy5sb2dpY2FsQU5EKCksIHRydWUpOwogICAgfQogICAgcmV0dXJuIGxlZnQ7CiAgfSwKCiAgbG9naWNhbEFORDogZnVuY3Rpb24oKSB7CiAgICB2YXIgbGVmdCA9IHRoaXMuZXF1YWxpdHkoKTsKICAgIHZhciB0b2tlbjsKICAgIHdoaWxlICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnJiYnKSkpIHsKICAgICAgbGVmdCA9IHRoaXMuYmluYXJ5Rm4obGVmdCwgdG9rZW4udGV4dCwgdGhpcy5lcXVhbGl0eSgpLCB0cnVlKTsKICAgIH0KICAgIHJldHVybiBsZWZ0OwogIH0sCgogIGVxdWFsaXR5OiBmdW5jdGlvbigpIHsKICAgIHZhciBsZWZ0ID0gdGhpcy5yZWxhdGlvbmFsKCk7CiAgICB2YXIgdG9rZW47CiAgICB3aGlsZSAoKHRva2VuID0gdGhpcy5leHBlY3QoJz09JywnIT0nLCc9PT0nLCchPT0nKSkpIHsKICAgICAgbGVmdCA9IHRoaXMuYmluYXJ5Rm4obGVmdCwgdG9rZW4udGV4dCwgdGhpcy5yZWxhdGlvbmFsKCkpOwogICAgfQogICAgcmV0dXJuIGxlZnQ7CiAgfSwKCiAgcmVsYXRpb25hbDogZnVuY3Rpb24oKSB7CiAgICB2YXIgbGVmdCA9IHRoaXMuYWRkaXRpdmUoKTsKICAgIHZhciB0b2tlbjsKICAgIHdoaWxlICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnPCcsICc+JywgJzw9JywgJz49JykpKSB7CiAgICAgIGxlZnQgPSB0aGlzLmJpbmFyeUZuKGxlZnQsIHRva2VuLnRleHQsIHRoaXMuYWRkaXRpdmUoKSk7CiAgICB9CiAgICByZXR1cm4gbGVmdDsKICB9LAoKICBhZGRpdGl2ZTogZnVuY3Rpb24oKSB7CiAgICB2YXIgbGVmdCA9IHRoaXMubXVsdGlwbGljYXRpdmUoKTsKICAgIHZhciB0b2tlbjsKICAgIHdoaWxlICgodG9rZW4gPSB0aGlzLmV4cGVjdCgnKycsJy0nKSkpIHsKICAgICAgbGVmdCA9IHRoaXMuYmluYXJ5Rm4obGVmdCwgdG9rZW4udGV4dCwgdGhpcy5tdWx0aXBsaWNhdGl2ZSgpKTsKICAgIH0KICAgIHJldHVybiBsZWZ0OwogIH0sCgogIG11bHRpcGxpY2F0aXZlOiBmdW5jdGlvbigpIHsKICAgIHZhciBsZWZ0ID0gdGhpcy51bmFyeSgpOwogICAgdmFyIHRva2VuOwogICAgd2hpbGUgKCh0b2tlbiA9IHRoaXMuZXhwZWN0KCcqJywnLycsJyUnKSkpIHsKICAgICAgbGVmdCA9IHRoaXMuYmluYXJ5Rm4obGVmdCwgdG9rZW4udGV4dCwgdGhpcy51bmFyeSgpKTsKICAgIH0KICAgIHJldHVybiBsZWZ0OwogIH0sCgogIHVuYXJ5OiBmdW5jdGlvbigpIHsKICAgIHZhciB0b2tlbjsKICAgIGlmICh0aGlzLmV4cGVjdCgnKycpKSB7CiAgICAgIHJldHVybiB0aGlzLnByaW1hcnkoKTsKICAgIH0gZWxzZSBpZiAoKHRva2VuID0gdGhpcy5leHBlY3QoJy0nKSkpIHsKICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5Rm4oUGFyc2VyLlpFUk8sIHRva2VuLnRleHQsIHRoaXMudW5hcnkoKSk7CiAgICB9IGVsc2UgaWYgKCh0b2tlbiA9IHRoaXMuZXhwZWN0KCchJykpKSB7CiAgICAgIHJldHVybiB0aGlzLnVuYXJ5Rm4odG9rZW4udGV4dCwgdGhpcy51bmFyeSgpKTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB0aGlzLnByaW1hcnkoKTsKICAgIH0KICB9LAoKICBmaWVsZEFjY2VzczogZnVuY3Rpb24ob2JqZWN0KSB7CiAgICB2YXIgZ2V0dGVyID0gdGhpcy5pZGVudGlmaWVyKCk7CgogICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbiAkcGFyc2VGaWVsZEFjY2VzcyhzY29wZSwgbG9jYWxzLCBzZWxmKSB7CiAgICAgIHZhciBvID0gc2VsZiB8fCBvYmplY3Qoc2NvcGUsIGxvY2Fscyk7CiAgICAgIHJldHVybiAobyA9PSBudWxsKSA/IHVuZGVmaW5lZCA6IGdldHRlcihvKTsKICAgIH0sIHsKICAgICAgYXNzaWduOiBmdW5jdGlvbihzY29wZSwgdmFsdWUsIGxvY2FscykgewogICAgICAgIHZhciBvID0gb2JqZWN0KHNjb3BlLCBsb2NhbHMpOwogICAgICAgIGlmICghbykgb2JqZWN0LmFzc2lnbihzY29wZSwgbyA9IHt9KTsKICAgICAgICByZXR1cm4gZ2V0dGVyLmFzc2lnbihvLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0pOwogIH0sCgogIG9iamVjdEluZGV4OiBmdW5jdGlvbihvYmopIHsKICAgIHZhciBleHByZXNzaW9uID0gdGhpcy50ZXh0OwoKICAgIHZhciBpbmRleEZuID0gdGhpcy5leHByZXNzaW9uKCk7CiAgICB0aGlzLmNvbnN1bWUoJ10nKTsKCiAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICRwYXJzZU9iamVjdEluZGV4KHNlbGYsIGxvY2FscykgewogICAgICB2YXIgbyA9IG9iaihzZWxmLCBsb2NhbHMpLAogICAgICAgICAgaSA9IGluZGV4Rm4oc2VsZiwgbG9jYWxzKSwKICAgICAgICAgIHY7CgogICAgICBlbnN1cmVTYWZlTWVtYmVyTmFtZShpLCBleHByZXNzaW9uKTsKICAgICAgaWYgKCFvKSByZXR1cm4gdW5kZWZpbmVkOwogICAgICB2ID0gZW5zdXJlU2FmZU9iamVjdChvW2ldLCBleHByZXNzaW9uKTsKICAgICAgcmV0dXJuIHY7CiAgICB9LCB7CiAgICAgIGFzc2lnbjogZnVuY3Rpb24oc2VsZiwgdmFsdWUsIGxvY2FscykgewogICAgICAgIHZhciBrZXkgPSBlbnN1cmVTYWZlTWVtYmVyTmFtZShpbmRleEZuKHNlbGYsIGxvY2FscyksIGV4cHJlc3Npb24pOwogICAgICAgIC8vIHByZXZlbnQgb3ZlcndyaXRpbmcgb2YgRnVuY3Rpb24uY29uc3RydWN0b3Igd2hpY2ggd291bGQgYnJlYWsgZW5zdXJlU2FmZU9iamVjdCBjaGVjawogICAgICAgIHZhciBvID0gZW5zdXJlU2FmZU9iamVjdChvYmooc2VsZiwgbG9jYWxzKSwgZXhwcmVzc2lvbik7CiAgICAgICAgaWYgKCFvKSBvYmouYXNzaWduKHNlbGYsIG8gPSB7fSk7CiAgICAgICAgcmV0dXJuIG9ba2V5XSA9IHZhbHVlOwogICAgICB9CiAgICB9KTsKICB9LAoKICBmdW5jdGlvbkNhbGw6IGZ1bmN0aW9uKGZuR2V0dGVyLCBjb250ZXh0R2V0dGVyKSB7CiAgICB2YXIgYXJnc0ZuID0gW107CiAgICBpZiAodGhpcy5wZWVrVG9rZW4oKS50ZXh0ICE9PSAnKScpIHsKICAgICAgZG8gewogICAgICAgIGFyZ3NGbi5wdXNoKHRoaXMuZXhwcmVzc2lvbigpKTsKICAgICAgfSB3aGlsZSAodGhpcy5leHBlY3QoJywnKSk7CiAgICB9CiAgICB0aGlzLmNvbnN1bWUoJyknKTsKCiAgICB2YXIgZXhwcmVzc2lvblRleHQgPSB0aGlzLnRleHQ7CiAgICAvLyB3ZSBjYW4gc2FmZWx5IHJldXNlIHRoZSBhcnJheSBhY3Jvc3MgaW52b2NhdGlvbnMKICAgIHZhciBhcmdzID0gYXJnc0ZuLmxlbmd0aCA/IFtdIDogbnVsbDsKCiAgICByZXR1cm4gZnVuY3Rpb24gJHBhcnNlRnVuY3Rpb25DYWxsKHNjb3BlLCBsb2NhbHMpIHsKICAgICAgdmFyIGNvbnRleHQgPSBjb250ZXh0R2V0dGVyID8gY29udGV4dEdldHRlcihzY29wZSwgbG9jYWxzKSA6IGlzRGVmaW5lZChjb250ZXh0R2V0dGVyKSA/IHVuZGVmaW5lZCA6IHNjb3BlOwogICAgICB2YXIgZm4gPSBmbkdldHRlcihzY29wZSwgbG9jYWxzLCBjb250ZXh0KSB8fCBub29wOwoKICAgICAgaWYgKGFyZ3MpIHsKICAgICAgICB2YXIgaSA9IGFyZ3NGbi5sZW5ndGg7CiAgICAgICAgd2hpbGUgKGktLSkgewogICAgICAgICAgYXJnc1tpXSA9IGVuc3VyZVNhZmVPYmplY3QoYXJnc0ZuW2ldKHNjb3BlLCBsb2NhbHMpLCBleHByZXNzaW9uVGV4dCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBlbnN1cmVTYWZlT2JqZWN0KGNvbnRleHQsIGV4cHJlc3Npb25UZXh0KTsKICAgICAgZW5zdXJlU2FmZUZ1bmN0aW9uKGZuLCBleHByZXNzaW9uVGV4dCk7CgogICAgICAvLyBJRSBkb2Vzbid0IGhhdmUgYXBwbHkgZm9yIHNvbWUgbmF0aXZlIGZ1bmN0aW9ucwogICAgICB2YXIgdiA9IGZuLmFwcGx5CiAgICAgICAgICAgID8gZm4uYXBwbHkoY29udGV4dCwgYXJncykKICAgICAgICAgICAgOiBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTsKCiAgICAgIHJldHVybiBlbnN1cmVTYWZlT2JqZWN0KHYsIGV4cHJlc3Npb25UZXh0KTsKICAgICAgfTsKICB9LAoKICAvLyBUaGlzIGlzIHVzZWQgd2l0aCBqc29uIGFycmF5IGRlY2xhcmF0aW9uCiAgYXJyYXlEZWNsYXJhdGlvbjogZnVuY3Rpb24oKSB7CiAgICB2YXIgZWxlbWVudEZucyA9IFtdOwogICAgaWYgKHRoaXMucGVla1Rva2VuKCkudGV4dCAhPT0gJ10nKSB7CiAgICAgIGRvIHsKICAgICAgICBpZiAodGhpcy5wZWVrKCddJykpIHsKICAgICAgICAgIC8vIFN1cHBvcnQgdHJhaWxpbmcgY29tbWFzIHBlciBFUzUuMS4KICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBlbGVtZW50Rm5zLnB1c2godGhpcy5leHByZXNzaW9uKCkpOwogICAgICB9IHdoaWxlICh0aGlzLmV4cGVjdCgnLCcpKTsKICAgIH0KICAgIHRoaXMuY29uc3VtZSgnXScpOwoKICAgIHJldHVybiBleHRlbmQoZnVuY3Rpb24gJHBhcnNlQXJyYXlMaXRlcmFsKHNlbGYsIGxvY2FscykgewogICAgICB2YXIgYXJyYXkgPSBbXTsKICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZWxlbWVudEZucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgYXJyYXkucHVzaChlbGVtZW50Rm5zW2ldKHNlbGYsIGxvY2FscykpOwogICAgICB9CiAgICAgIHJldHVybiBhcnJheTsKICAgIH0sIHsKICAgICAgbGl0ZXJhbDogdHJ1ZSwKICAgICAgY29uc3RhbnQ6IGVsZW1lbnRGbnMuZXZlcnkoaXNDb25zdGFudCksCiAgICAgIGlucHV0czogZWxlbWVudEZucwogICAgfSk7CiAgfSwKCiAgb2JqZWN0OiBmdW5jdGlvbigpIHsKICAgIHZhciBrZXlzID0gW10sIHZhbHVlRm5zID0gW107CiAgICBpZiAodGhpcy5wZWVrVG9rZW4oKS50ZXh0ICE9PSAnfScpIHsKICAgICAgZG8gewogICAgICAgIGlmICh0aGlzLnBlZWsoJ30nKSkgewogICAgICAgICAgLy8gU3VwcG9ydCB0cmFpbGluZyBjb21tYXMgcGVyIEVTNS4xLgogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhciB0b2tlbiA9IHRoaXMuY29uc3VtZSgpOwogICAgICAgIGlmICh0b2tlbi5jb25zdGFudCkgewogICAgICAgICAga2V5cy5wdXNoKHRva2VuLnZhbHVlKTsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmlkZW50aWZpZXIpIHsKICAgICAgICAgIGtleXMucHVzaCh0b2tlbi50ZXh0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhpcy50aHJvd0Vycm9yKCJpbnZhbGlkIGtleSIsIHRva2VuKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5jb25zdW1lKCc6Jyk7CiAgICAgICAgdmFsdWVGbnMucHVzaCh0aGlzLmV4cHJlc3Npb24oKSk7CiAgICAgIH0gd2hpbGUgKHRoaXMuZXhwZWN0KCcsJykpOwogICAgfQogICAgdGhpcy5jb25zdW1lKCd9Jyk7CgogICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbiAkcGFyc2VPYmplY3RMaXRlcmFsKHNlbGYsIGxvY2FscykgewogICAgICB2YXIgb2JqZWN0ID0ge307CiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHZhbHVlRm5zLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICBvYmplY3Rba2V5c1tpXV0gPSB2YWx1ZUZuc1tpXShzZWxmLCBsb2NhbHMpOwogICAgICB9CiAgICAgIHJldHVybiBvYmplY3Q7CiAgICB9LCB7CiAgICAgIGxpdGVyYWw6IHRydWUsCiAgICAgIGNvbnN0YW50OiB2YWx1ZUZucy5ldmVyeShpc0NvbnN0YW50KSwKICAgICAgaW5wdXRzOiB2YWx1ZUZucwogICAgfSk7CiAgfQp9OwoKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIFBhcnNlciBoZWxwZXIgZnVuY3Rpb25zCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpmdW5jdGlvbiBzZXR0ZXIob2JqLCBwYXRoLCBzZXRWYWx1ZSwgZnVsbEV4cCkgewogIGVuc3VyZVNhZmVPYmplY3Qob2JqLCBmdWxsRXhwKTsKCiAgdmFyIGVsZW1lbnQgPSBwYXRoLnNwbGl0KCcuJyksIGtleTsKICBmb3IgKHZhciBpID0gMDsgZWxlbWVudC5sZW5ndGggPiAxOyBpKyspIHsKICAgIGtleSA9IGVuc3VyZVNhZmVNZW1iZXJOYW1lKGVsZW1lbnQuc2hpZnQoKSwgZnVsbEV4cCk7CiAgICB2YXIgcHJvcGVydHlPYmogPSBlbnN1cmVTYWZlT2JqZWN0KG9ialtrZXldLCBmdWxsRXhwKTsKICAgIGlmICghcHJvcGVydHlPYmopIHsKICAgICAgcHJvcGVydHlPYmogPSB7fTsKICAgICAgb2JqW2tleV0gPSBwcm9wZXJ0eU9iajsKICAgIH0KICAgIG9iaiA9IHByb3BlcnR5T2JqOwogIH0KICBrZXkgPSBlbnN1cmVTYWZlTWVtYmVyTmFtZShlbGVtZW50LnNoaWZ0KCksIGZ1bGxFeHApOwogIGVuc3VyZVNhZmVPYmplY3Qob2JqW2tleV0sIGZ1bGxFeHApOwogIG9ialtrZXldID0gc2V0VmFsdWU7CiAgcmV0dXJuIHNldFZhbHVlOwp9Cgp2YXIgZ2V0dGVyRm5DYWNoZURlZmF1bHQgPSBjcmVhdGVNYXAoKTsKdmFyIGdldHRlckZuQ2FjaGVFeHBlbnNpdmUgPSBjcmVhdGVNYXAoKTsKCmZ1bmN0aW9uIGlzUG9zc2libHlEYW5nZXJvdXNNZW1iZXJOYW1lKG5hbWUpIHsKICByZXR1cm4gbmFtZSA9PSAnY29uc3RydWN0b3InOwp9CgovKioKICogSW1wbGVtZW50YXRpb24gb2YgdGhlICJCbGFjayBIb2xlIiB2YXJpYW50IGZyb206CiAqIC0gaHR0cDovL2pzcGVyZi5jb20vYW5ndWxhcmpzLXBhcnNlLWdldHRlci80CiAqIC0gaHR0cDovL2pzcGVyZi5jb20vcGF0aC1ldmFsdWF0aW9uLXNpbXBsaWZpZWQvNwogKi8KZnVuY3Rpb24gY3NwU2FmZUdldHRlckZuKGtleTAsIGtleTEsIGtleTIsIGtleTMsIGtleTQsIGZ1bGxFeHAsIGV4cGVuc2l2ZUNoZWNrcykgewogIGVuc3VyZVNhZmVNZW1iZXJOYW1lKGtleTAsIGZ1bGxFeHApOwogIGVuc3VyZVNhZmVNZW1iZXJOYW1lKGtleTEsIGZ1bGxFeHApOwogIGVuc3VyZVNhZmVNZW1iZXJOYW1lKGtleTIsIGZ1bGxFeHApOwogIGVuc3VyZVNhZmVNZW1iZXJOYW1lKGtleTMsIGZ1bGxFeHApOwogIGVuc3VyZVNhZmVNZW1iZXJOYW1lKGtleTQsIGZ1bGxFeHApOwogIHZhciBlc28gPSBmdW5jdGlvbihvKSB7CiAgICByZXR1cm4gZW5zdXJlU2FmZU9iamVjdChvLCBmdWxsRXhwKTsKICB9OwogIHZhciBlc28wID0gKGV4cGVuc2l2ZUNoZWNrcyB8fCBpc1Bvc3NpYmx5RGFuZ2Vyb3VzTWVtYmVyTmFtZShrZXkwKSkgPyBlc28gOiBpZGVudGl0eTsKICB2YXIgZXNvMSA9IChleHBlbnNpdmVDaGVja3MgfHwgaXNQb3NzaWJseURhbmdlcm91c01lbWJlck5hbWUoa2V5MSkpID8gZXNvIDogaWRlbnRpdHk7CiAgdmFyIGVzbzIgPSAoZXhwZW5zaXZlQ2hlY2tzIHx8IGlzUG9zc2libHlEYW5nZXJvdXNNZW1iZXJOYW1lKGtleTIpKSA/IGVzbyA6IGlkZW50aXR5OwogIHZhciBlc28zID0gKGV4cGVuc2l2ZUNoZWNrcyB8fCBpc1Bvc3NpYmx5RGFuZ2Vyb3VzTWVtYmVyTmFtZShrZXkzKSkgPyBlc28gOiBpZGVudGl0eTsKICB2YXIgZXNvNCA9IChleHBlbnNpdmVDaGVja3MgfHwgaXNQb3NzaWJseURhbmdlcm91c01lbWJlck5hbWUoa2V5NCkpID8gZXNvIDogaWRlbnRpdHk7CgogIHJldHVybiBmdW5jdGlvbiBjc3BTYWZlR2V0dGVyKHNjb3BlLCBsb2NhbHMpIHsKICAgIHZhciBwYXRoVmFsID0gKGxvY2FscyAmJiBsb2NhbHMuaGFzT3duUHJvcGVydHkoa2V5MCkpID8gbG9jYWxzIDogc2NvcGU7CgogICAgaWYgKHBhdGhWYWwgPT0gbnVsbCkgcmV0dXJuIHBhdGhWYWw7CiAgICBwYXRoVmFsID0gZXNvMChwYXRoVmFsW2tleTBdKTsKCiAgICBpZiAoIWtleTEpIHJldHVybiBwYXRoVmFsOwogICAgaWYgKHBhdGhWYWwgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDsKICAgIHBhdGhWYWwgPSBlc28xKHBhdGhWYWxba2V5MV0pOwoKICAgIGlmICgha2V5MikgcmV0dXJuIHBhdGhWYWw7CiAgICBpZiAocGF0aFZhbCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkOwogICAgcGF0aFZhbCA9IGVzbzIocGF0aFZhbFtrZXkyXSk7CgogICAgaWYgKCFrZXkzKSByZXR1cm4gcGF0aFZhbDsKICAgIGlmIChwYXRoVmFsID09IG51bGwpIHJldHVybiB1bmRlZmluZWQ7CiAgICBwYXRoVmFsID0gZXNvMyhwYXRoVmFsW2tleTNdKTsKCiAgICBpZiAoIWtleTQpIHJldHVybiBwYXRoVmFsOwogICAgaWYgKHBhdGhWYWwgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDsKICAgIHBhdGhWYWwgPSBlc280KHBhdGhWYWxba2V5NF0pOwoKICAgIHJldHVybiBwYXRoVmFsOwogIH07Cn0KCmZ1bmN0aW9uIGdldHRlckZuV2l0aEVuc3VyZVNhZmVPYmplY3QoZm4sIGZ1bGxFeHByZXNzaW9uKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKHMsIGwpIHsKICAgIHJldHVybiBmbihzLCBsLCBlbnN1cmVTYWZlT2JqZWN0LCBmdWxsRXhwcmVzc2lvbik7CiAgfTsKfQoKZnVuY3Rpb24gZ2V0dGVyRm4ocGF0aCwgb3B0aW9ucywgZnVsbEV4cCkgewogIHZhciBleHBlbnNpdmVDaGVja3MgPSBvcHRpb25zLmV4cGVuc2l2ZUNoZWNrczsKICB2YXIgZ2V0dGVyRm5DYWNoZSA9IChleHBlbnNpdmVDaGVja3MgPyBnZXR0ZXJGbkNhY2hlRXhwZW5zaXZlIDogZ2V0dGVyRm5DYWNoZURlZmF1bHQpOwogIHZhciBmbiA9IGdldHRlckZuQ2FjaGVbcGF0aF07CiAgaWYgKGZuKSByZXR1cm4gZm47CgoKICB2YXIgcGF0aEtleXMgPSBwYXRoLnNwbGl0KCcuJyksCiAgICAgIHBhdGhLZXlzTGVuZ3RoID0gcGF0aEtleXMubGVuZ3RoOwoKICAvLyBodHRwOi8vanNwZXJmLmNvbS9hbmd1bGFyanMtcGFyc2UtZ2V0dGVyLzYKICBpZiAob3B0aW9ucy5jc3ApIHsKICAgIGlmIChwYXRoS2V5c0xlbmd0aCA8IDYpIHsKICAgICAgZm4gPSBjc3BTYWZlR2V0dGVyRm4ocGF0aEtleXNbMF0sIHBhdGhLZXlzWzFdLCBwYXRoS2V5c1syXSwgcGF0aEtleXNbM10sIHBhdGhLZXlzWzRdLCBmdWxsRXhwLCBleHBlbnNpdmVDaGVja3MpOwogICAgfSBlbHNlIHsKICAgICAgZm4gPSBmdW5jdGlvbiBjc3BTYWZlR2V0dGVyKHNjb3BlLCBsb2NhbHMpIHsKICAgICAgICB2YXIgaSA9IDAsIHZhbDsKICAgICAgICBkbyB7CiAgICAgICAgICB2YWwgPSBjc3BTYWZlR2V0dGVyRm4ocGF0aEtleXNbaSsrXSwgcGF0aEtleXNbaSsrXSwgcGF0aEtleXNbaSsrXSwgcGF0aEtleXNbaSsrXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoS2V5c1tpKytdLCBmdWxsRXhwLCBleHBlbnNpdmVDaGVja3MpKHNjb3BlLCBsb2NhbHMpOwoKICAgICAgICAgIGxvY2FscyA9IHVuZGVmaW5lZDsgLy8gY2xlYXIgYWZ0ZXIgZmlyc3QgaXRlcmF0aW9uCiAgICAgICAgICBzY29wZSA9IHZhbDsKICAgICAgICB9IHdoaWxlIChpIDwgcGF0aEtleXNMZW5ndGgpOwogICAgICAgIHJldHVybiB2YWw7CiAgICAgIH07CiAgICB9CiAgfSBlbHNlIHsKICAgIHZhciBjb2RlID0gJyc7CiAgICBpZiAoZXhwZW5zaXZlQ2hlY2tzKSB7CiAgICAgIGNvZGUgKz0gJ3MgPSBlc28ocywgZmUpO1xubCA9IGVzbyhsLCBmZSk7XG4nOwogICAgfQogICAgdmFyIG5lZWRzRW5zdXJlU2FmZU9iamVjdCA9IGV4cGVuc2l2ZUNoZWNrczsKICAgIGZvckVhY2gocGF0aEtleXMsIGZ1bmN0aW9uKGtleSwgaW5kZXgpIHsKICAgICAgZW5zdXJlU2FmZU1lbWJlck5hbWUoa2V5LCBmdWxsRXhwKTsKICAgICAgdmFyIGxvb2t1cEpzID0gKGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzaW1wbHkgZGVyZWZlcmVuY2UgJ3MnIG9uIGFueSAuZG90IG5vdGF0aW9uCiAgICAgICAgICAgICAgICAgICAgICA/ICdzJwogICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGlmIHdlIGFyZSBmaXJzdCB0aGVuIHdlIGNoZWNrIGxvY2FscyBmaXJzdCwgYW5kIGlmIHNvIHJlYWQgaXQgZmlyc3QKICAgICAgICAgICAgICAgICAgICAgIDogJygobCYmbC5oYXNPd25Qcm9wZXJ0eSgiJyArIGtleSArICciKSk/bDpzKScpICsgJy4nICsga2V5OwogICAgICBpZiAoZXhwZW5zaXZlQ2hlY2tzIHx8IGlzUG9zc2libHlEYW5nZXJvdXNNZW1iZXJOYW1lKGtleSkpIHsKICAgICAgICBsb29rdXBKcyA9ICdlc28oJyArIGxvb2t1cEpzICsgJywgZmUpJzsKICAgICAgICBuZWVkc0Vuc3VyZVNhZmVPYmplY3QgPSB0cnVlOwogICAgICB9CiAgICAgIGNvZGUgKz0gJ2lmKHMgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDtcbicgKwogICAgICAgICAgICAgICdzPScgKyBsb29rdXBKcyArICc7XG4nOwogICAgfSk7CiAgICBjb2RlICs9ICdyZXR1cm4gczsnOwoKICAgIC8qIGpzaGludCAtVzA1NCAqLwogICAgdmFyIGV2YWxlZEZuR2V0dGVyID0gbmV3IEZ1bmN0aW9uKCdzJywgJ2wnLCAnZXNvJywgJ2ZlJywgY29kZSk7IC8vIHM9c2NvcGUsIGw9bG9jYWxzLCBlc289ZW5zdXJlU2FmZU9iamVjdAogICAgLyoganNoaW50ICtXMDU0ICovCiAgICBldmFsZWRGbkdldHRlci50b1N0cmluZyA9IHZhbHVlRm4oY29kZSk7CiAgICBpZiAobmVlZHNFbnN1cmVTYWZlT2JqZWN0KSB7CiAgICAgIGV2YWxlZEZuR2V0dGVyID0gZ2V0dGVyRm5XaXRoRW5zdXJlU2FmZU9iamVjdChldmFsZWRGbkdldHRlciwgZnVsbEV4cCk7CiAgICB9CiAgICBmbiA9IGV2YWxlZEZuR2V0dGVyOwogIH0KCiAgZm4uc2hhcmVkR2V0dGVyID0gdHJ1ZTsKICBmbi5hc3NpZ24gPSBmdW5jdGlvbihzZWxmLCB2YWx1ZSkgewogICAgcmV0dXJuIHNldHRlcihzZWxmLCBwYXRoLCB2YWx1ZSwgcGF0aCk7CiAgfTsKICBnZXR0ZXJGbkNhY2hlW3BhdGhdID0gZm47CiAgcmV0dXJuIGZuOwp9Cgp2YXIgb2JqZWN0VmFsdWVPZiA9IE9iamVjdC5wcm90b3R5cGUudmFsdWVPZjsKCmZ1bmN0aW9uIGdldFZhbHVlT2YodmFsdWUpIHsKICByZXR1cm4gaXNGdW5jdGlvbih2YWx1ZS52YWx1ZU9mKSA/IHZhbHVlLnZhbHVlT2YoKSA6IG9iamVjdFZhbHVlT2YuY2FsbCh2YWx1ZSk7Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJHBhcnNlCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKgogKiBDb252ZXJ0cyBBbmd1bGFyIHtAbGluayBndWlkZS9leHByZXNzaW9uIGV4cHJlc3Npb259IGludG8gYSBmdW5jdGlvbi4KICoKICogYGBganMKICogICB2YXIgZ2V0dGVyID0gJHBhcnNlKCd1c2VyLm5hbWUnKTsKICogICB2YXIgc2V0dGVyID0gZ2V0dGVyLmFzc2lnbjsKICogICB2YXIgY29udGV4dCA9IHt1c2VyOntuYW1lOidhbmd1bGFyJ319OwogKiAgIHZhciBsb2NhbHMgPSB7dXNlcjp7bmFtZTonbG9jYWwnfX07CiAqCiAqICAgZXhwZWN0KGdldHRlcihjb250ZXh0KSkudG9FcXVhbCgnYW5ndWxhcicpOwogKiAgIHNldHRlcihjb250ZXh0LCAnbmV3VmFsdWUnKTsKICogICBleHBlY3QoY29udGV4dC51c2VyLm5hbWUpLnRvRXF1YWwoJ25ld1ZhbHVlJyk7CiAqICAgZXhwZWN0KGdldHRlcihjb250ZXh0LCBsb2NhbHMpKS50b0VxdWFsKCdsb2NhbCcpOwogKiBgYGAKICoKICoKICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gU3RyaW5nIGV4cHJlc3Npb24gdG8gY29tcGlsZS4KICogQHJldHVybnMge2Z1bmN0aW9uKGNvbnRleHQsIGxvY2Fscyl9IGEgZnVuY3Rpb24gd2hpY2ggcmVwcmVzZW50cyB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbjoKICoKICogICAgKiBgY29udGV4dGAg4oA/IGB7b2JqZWN0fWAg4oA/IGFuIG9iamVjdCBhZ2FpbnN0IHdoaWNoIGFueSBleHByZXNzaW9ucyBlbWJlZGRlZCBpbiB0aGUgc3RyaW5ncwogKiAgICAgIGFyZSBldmFsdWF0ZWQgYWdhaW5zdCAodHlwaWNhbGx5IGEgc2NvcGUgb2JqZWN0KS4KICogICAgKiBgbG9jYWxzYCDigD8gYHtvYmplY3Q9fWAg4oA/IGxvY2FsIHZhcmlhYmxlcyBjb250ZXh0IG9iamVjdCwgdXNlZnVsIGZvciBvdmVycmlkaW5nIHZhbHVlcyBpbgogKiAgICAgIGBjb250ZXh0YC4KICoKICogICAgVGhlIHJldHVybmVkIGZ1bmN0aW9uIGFsc28gaGFzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKICogICAgICAqIGBsaXRlcmFsYCDigD8gYHtib29sZWFufWAg4oA/IHdoZXRoZXIgdGhlIGV4cHJlc3Npb24ncyB0b3AtbGV2ZWwgbm9kZSBpcyBhIEphdmFTY3JpcHQKICogICAgICAgIGxpdGVyYWwuCiAqICAgICAgKiBgY29uc3RhbnRgIOKAPyBge2Jvb2xlYW59YCDigD8gd2hldGhlciB0aGUgZXhwcmVzc2lvbiBpcyBtYWRlIGVudGlyZWx5IG9mIEphdmFTY3JpcHQKICogICAgICAgIGNvbnN0YW50IGxpdGVyYWxzLgogKiAgICAgICogYGFzc2lnbmAg4oA/IGB7P2Z1bmN0aW9uKGNvbnRleHQsIHZhbHVlKX1gIOKAPyBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhc3NpZ25hYmxlLCB0aGlzIHdpbGwgYmUKICogICAgICAgIHNldCB0byBhIGZ1bmN0aW9uIHRvIGNoYW5nZSBpdHMgdmFsdWUgb24gdGhlIGdpdmVuIGNvbnRleHQuCiAqCiAqLwoKCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJHBhcnNlUHJvdmlkZXIKICoKICogQGRlc2NyaXB0aW9uCiAqIGAkcGFyc2VQcm92aWRlcmAgY2FuIGJlIHVzZWQgZm9yIGNvbmZpZ3VyaW5nIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSB7QGxpbmsgbmcuJHBhcnNlICRwYXJzZX0KICogIHNlcnZpY2UuCiAqLwpmdW5jdGlvbiAkUGFyc2VQcm92aWRlcigpIHsKICB2YXIgY2FjaGVEZWZhdWx0ID0gY3JlYXRlTWFwKCk7CiAgdmFyIGNhY2hlRXhwZW5zaXZlID0gY3JlYXRlTWFwKCk7CgoKCiAgdGhpcy4kZ2V0ID0gWyckZmlsdGVyJywgJyRzbmlmZmVyJywgZnVuY3Rpb24oJGZpbHRlciwgJHNuaWZmZXIpIHsKICAgIHZhciAkcGFyc2VPcHRpb25zID0gewogICAgICAgICAgY3NwOiAkc25pZmZlci5jc3AsCiAgICAgICAgICBleHBlbnNpdmVDaGVja3M6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAkcGFyc2VPcHRpb25zRXhwZW5zaXZlID0gewogICAgICAgICAgY3NwOiAkc25pZmZlci5jc3AsCiAgICAgICAgICBleHBlbnNpdmVDaGVja3M6IHRydWUKICAgICAgICB9OwoKICAgIGZ1bmN0aW9uIHdyYXBTaGFyZWRFeHByZXNzaW9uKGV4cCkgewogICAgICB2YXIgd3JhcHBlZCA9IGV4cDsKCiAgICAgIGlmIChleHAuc2hhcmVkR2V0dGVyKSB7CiAgICAgICAgd3JhcHBlZCA9IGZ1bmN0aW9uICRwYXJzZVdyYXBwZXIoc2VsZiwgbG9jYWxzKSB7CiAgICAgICAgICByZXR1cm4gZXhwKHNlbGYsIGxvY2Fscyk7CiAgICAgICAgfTsKICAgICAgICB3cmFwcGVkLmxpdGVyYWwgPSBleHAubGl0ZXJhbDsKICAgICAgICB3cmFwcGVkLmNvbnN0YW50ID0gZXhwLmNvbnN0YW50OwogICAgICAgIHdyYXBwZWQuYXNzaWduID0gZXhwLmFzc2lnbjsKICAgICAgfQoKICAgICAgcmV0dXJuIHdyYXBwZWQ7CiAgICB9CgogICAgcmV0dXJuIGZ1bmN0aW9uICRwYXJzZShleHAsIGludGVyY2VwdG9yRm4sIGV4cGVuc2l2ZUNoZWNrcykgewogICAgICB2YXIgcGFyc2VkRXhwcmVzc2lvbiwgb25lVGltZSwgY2FjaGVLZXk7CgogICAgICBzd2l0Y2ggKHR5cGVvZiBleHApIHsKICAgICAgICBjYXNlICdzdHJpbmcnOgogICAgICAgICAgY2FjaGVLZXkgPSBleHAgPSBleHAudHJpbSgpOwoKICAgICAgICAgIHZhciBjYWNoZSA9IChleHBlbnNpdmVDaGVja3MgPyBjYWNoZUV4cGVuc2l2ZSA6IGNhY2hlRGVmYXVsdCk7CiAgICAgICAgICBwYXJzZWRFeHByZXNzaW9uID0gY2FjaGVbY2FjaGVLZXldOwoKICAgICAgICAgIGlmICghcGFyc2VkRXhwcmVzc2lvbikgewogICAgICAgICAgICBpZiAoZXhwLmNoYXJBdCgwKSA9PT0gJzonICYmIGV4cC5jaGFyQXQoMSkgPT09ICc6JykgewogICAgICAgICAgICAgIG9uZVRpbWUgPSB0cnVlOwogICAgICAgICAgICAgIGV4cCA9IGV4cC5zdWJzdHJpbmcoMik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBwYXJzZU9wdGlvbnMgPSBleHBlbnNpdmVDaGVja3MgPyAkcGFyc2VPcHRpb25zRXhwZW5zaXZlIDogJHBhcnNlT3B0aW9uczsKICAgICAgICAgICAgdmFyIGxleGVyID0gbmV3IExleGVyKHBhcnNlT3B0aW9ucyk7CiAgICAgICAgICAgIHZhciBwYXJzZXIgPSBuZXcgUGFyc2VyKGxleGVyLCAkZmlsdGVyLCBwYXJzZU9wdGlvbnMpOwogICAgICAgICAgICBwYXJzZWRFeHByZXNzaW9uID0gcGFyc2VyLnBhcnNlKGV4cCk7CgogICAgICAgICAgICBpZiAocGFyc2VkRXhwcmVzc2lvbi5jb25zdGFudCkgewogICAgICAgICAgICAgIHBhcnNlZEV4cHJlc3Npb24uJCR3YXRjaERlbGVnYXRlID0gY29uc3RhbnRXYXRjaERlbGVnYXRlOwogICAgICAgICAgICB9IGVsc2UgaWYgKG9uZVRpbWUpIHsKICAgICAgICAgICAgICAvL29uZVRpbWUgaXMgbm90IHBhcnQgb2YgdGhlIGV4cCBwYXNzZWQgdG8gdGhlIFBhcnNlciBzbyB3ZSBtYXkgaGF2ZSB0bwogICAgICAgICAgICAgIC8vd3JhcCB0aGUgcGFyc2VkRXhwcmVzc2lvbiBiZWZvcmUgYWRkaW5nIGEgJCR3YXRjaERlbGVnYXRlCiAgICAgICAgICAgICAgcGFyc2VkRXhwcmVzc2lvbiA9IHdyYXBTaGFyZWRFeHByZXNzaW9uKHBhcnNlZEV4cHJlc3Npb24pOwogICAgICAgICAgICAgIHBhcnNlZEV4cHJlc3Npb24uJCR3YXRjaERlbGVnYXRlID0gcGFyc2VkRXhwcmVzc2lvbi5saXRlcmFsID8KICAgICAgICAgICAgICAgIG9uZVRpbWVMaXRlcmFsV2F0Y2hEZWxlZ2F0ZSA6IG9uZVRpbWVXYXRjaERlbGVnYXRlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnNlZEV4cHJlc3Npb24uaW5wdXRzKSB7CiAgICAgICAgICAgICAgcGFyc2VkRXhwcmVzc2lvbi4kJHdhdGNoRGVsZWdhdGUgPSBpbnB1dHNXYXRjaERlbGVnYXRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjYWNoZVtjYWNoZUtleV0gPSBwYXJzZWRFeHByZXNzaW9uOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGFkZEludGVyY2VwdG9yKHBhcnNlZEV4cHJlc3Npb24sIGludGVyY2VwdG9yRm4pOwoKICAgICAgICBjYXNlICdmdW5jdGlvbic6CiAgICAgICAgICByZXR1cm4gYWRkSW50ZXJjZXB0b3IoZXhwLCBpbnRlcmNlcHRvckZuKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiBhZGRJbnRlcmNlcHRvcihub29wLCBpbnRlcmNlcHRvckZuKTsKICAgICAgfQogICAgfTsKCiAgICBmdW5jdGlvbiBjb2xsZWN0RXhwcmVzc2lvbklucHV0cyhpbnB1dHMsIGxpc3QpIHsKICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gaW5wdXRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHsKICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV07CiAgICAgICAgaWYgKCFpbnB1dC5jb25zdGFudCkgewogICAgICAgICAgaWYgKGlucHV0LmlucHV0cykgewogICAgICAgICAgICBjb2xsZWN0RXhwcmVzc2lvbklucHV0cyhpbnB1dC5pbnB1dHMsIGxpc3QpOwogICAgICAgICAgfSBlbHNlIGlmIChsaXN0LmluZGV4T2YoaW5wdXQpID09PSAtMSkgeyAvLyBUT0RPKHBlcmYpIGNhbiB3ZSBkbyBiZXR0ZXI/CiAgICAgICAgICAgIGxpc3QucHVzaChpbnB1dCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICByZXR1cm4gbGlzdDsKICAgIH0KCiAgICBmdW5jdGlvbiBleHByZXNzaW9uSW5wdXREaXJ0eUNoZWNrKG5ld1ZhbHVlLCBvbGRWYWx1ZU9mVmFsdWUpIHsKCiAgICAgIGlmIChuZXdWYWx1ZSA9PSBudWxsIHx8IG9sZFZhbHVlT2ZWYWx1ZSA9PSBudWxsKSB7IC8vIG51bGwvdW5kZWZpbmVkCiAgICAgICAgcmV0dXJuIG5ld1ZhbHVlID09PSBvbGRWYWx1ZU9mVmFsdWU7CiAgICAgIH0KCiAgICAgIGlmICh0eXBlb2YgbmV3VmFsdWUgPT09ICdvYmplY3QnKSB7CgogICAgICAgIC8vIGF0dGVtcHQgdG8gY29udmVydCB0aGUgdmFsdWUgdG8gYSBwcmltaXRpdmUgdHlwZQogICAgICAgIC8vIFRPRE8oZG9jcyk6IGFkZCBhIG5vdGUgdG8gZG9jcyB0aGF0IGJ5IGltcGxlbWVudGluZyB2YWx1ZU9mIGV2ZW4gb2JqZWN0cyBhbmQgYXJyYXlzIGNhbgogICAgICAgIC8vICAgICAgICAgICAgIGJlIGNoZWFwbHkgZGlydHktY2hlY2tlZAogICAgICAgIG5ld1ZhbHVlID0gZ2V0VmFsdWVPZihuZXdWYWx1ZSk7CgogICAgICAgIGlmICh0eXBlb2YgbmV3VmFsdWUgPT09ICdvYmplY3QnKSB7CiAgICAgICAgICAvLyBvYmplY3RzL2FycmF5cyBhcmUgbm90IHN1cHBvcnRlZCAtIGRlZXAtd2F0Y2hpbmcgdGhlbSB3b3VsZCBiZSB0b28gZXhwZW5zaXZlCiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBmYWxsLXRocm91Z2ggdG8gdGhlIHByaW1pdGl2ZSBlcXVhbGl0eSBjaGVjawogICAgICB9CgogICAgICAvL1ByaW1pdGl2ZSBvciBOYU4KICAgICAgcmV0dXJuIG5ld1ZhbHVlID09PSBvbGRWYWx1ZU9mVmFsdWUgfHwgKG5ld1ZhbHVlICE9PSBuZXdWYWx1ZSAmJiBvbGRWYWx1ZU9mVmFsdWUgIT09IG9sZFZhbHVlT2ZWYWx1ZSk7CiAgICB9CgogICAgZnVuY3Rpb24gaW5wdXRzV2F0Y2hEZWxlZ2F0ZShzY29wZSwgbGlzdGVuZXIsIG9iamVjdEVxdWFsaXR5LCBwYXJzZWRFeHByZXNzaW9uKSB7CiAgICAgIHZhciBpbnB1dEV4cHJlc3Npb25zID0gcGFyc2VkRXhwcmVzc2lvbi4kJGlucHV0cyB8fAogICAgICAgICAgICAgICAgICAgIChwYXJzZWRFeHByZXNzaW9uLiQkaW5wdXRzID0gY29sbGVjdEV4cHJlc3Npb25JbnB1dHMocGFyc2VkRXhwcmVzc2lvbi5pbnB1dHMsIFtdKSk7CgogICAgICB2YXIgbGFzdFJlc3VsdDsKCiAgICAgIGlmIChpbnB1dEV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMSkgewogICAgICAgIHZhciBvbGRJbnB1dFZhbHVlID0gZXhwcmVzc2lvbklucHV0RGlydHlDaGVjazsgLy8gaW5pdCB0byBzb21ldGhpbmcgdW5pcXVlIHNvIHRoYXQgZXF1YWxzIGNoZWNrIGZhaWxzCiAgICAgICAgaW5wdXRFeHByZXNzaW9ucyA9IGlucHV0RXhwcmVzc2lvbnNbMF07CiAgICAgICAgcmV0dXJuIHNjb3BlLiR3YXRjaChmdW5jdGlvbiBleHByZXNzaW9uSW5wdXRXYXRjaChzY29wZSkgewogICAgICAgICAgdmFyIG5ld0lucHV0VmFsdWUgPSBpbnB1dEV4cHJlc3Npb25zKHNjb3BlKTsKICAgICAgICAgIGlmICghZXhwcmVzc2lvbklucHV0RGlydHlDaGVjayhuZXdJbnB1dFZhbHVlLCBvbGRJbnB1dFZhbHVlKSkgewogICAgICAgICAgICBsYXN0UmVzdWx0ID0gcGFyc2VkRXhwcmVzc2lvbihzY29wZSk7CiAgICAgICAgICAgIG9sZElucHV0VmFsdWUgPSBuZXdJbnB1dFZhbHVlICYmIGdldFZhbHVlT2YobmV3SW5wdXRWYWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gbGFzdFJlc3VsdDsKICAgICAgICB9LCBsaXN0ZW5lciwgb2JqZWN0RXF1YWxpdHkpOwogICAgICB9CgogICAgICB2YXIgb2xkSW5wdXRWYWx1ZU9mVmFsdWVzID0gW107CiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0RXhwcmVzc2lvbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgIG9sZElucHV0VmFsdWVPZlZhbHVlc1tpXSA9IGV4cHJlc3Npb25JbnB1dERpcnR5Q2hlY2s7IC8vIGluaXQgdG8gc29tZXRoaW5nIHVuaXF1ZSBzbyB0aGF0IGVxdWFscyBjaGVjayBmYWlscwogICAgICB9CgogICAgICByZXR1cm4gc2NvcGUuJHdhdGNoKGZ1bmN0aW9uIGV4cHJlc3Npb25JbnB1dHNXYXRjaChzY29wZSkgewogICAgICAgIHZhciBjaGFuZ2VkID0gZmFsc2U7CgogICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0RXhwcmVzc2lvbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgICAgdmFyIG5ld0lucHV0VmFsdWUgPSBpbnB1dEV4cHJlc3Npb25zW2ldKHNjb3BlKTsKICAgICAgICAgIGlmIChjaGFuZ2VkIHx8IChjaGFuZ2VkID0gIWV4cHJlc3Npb25JbnB1dERpcnR5Q2hlY2sobmV3SW5wdXRWYWx1ZSwgb2xkSW5wdXRWYWx1ZU9mVmFsdWVzW2ldKSkpIHsKICAgICAgICAgICAgb2xkSW5wdXRWYWx1ZU9mVmFsdWVzW2ldID0gbmV3SW5wdXRWYWx1ZSAmJiBnZXRWYWx1ZU9mKG5ld0lucHV0VmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGNoYW5nZWQpIHsKICAgICAgICAgIGxhc3RSZXN1bHQgPSBwYXJzZWRFeHByZXNzaW9uKHNjb3BlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBsYXN0UmVzdWx0OwogICAgICB9LCBsaXN0ZW5lciwgb2JqZWN0RXF1YWxpdHkpOwogICAgfQoKICAgIGZ1bmN0aW9uIG9uZVRpbWVXYXRjaERlbGVnYXRlKHNjb3BlLCBsaXN0ZW5lciwgb2JqZWN0RXF1YWxpdHksIHBhcnNlZEV4cHJlc3Npb24pIHsKICAgICAgdmFyIHVud2F0Y2gsIGxhc3RWYWx1ZTsKICAgICAgcmV0dXJuIHVud2F0Y2ggPSBzY29wZS4kd2F0Y2goZnVuY3Rpb24gb25lVGltZVdhdGNoKHNjb3BlKSB7CiAgICAgICAgcmV0dXJuIHBhcnNlZEV4cHJlc3Npb24oc2NvcGUpOwogICAgICB9LCBmdW5jdGlvbiBvbmVUaW1lTGlzdGVuZXIodmFsdWUsIG9sZCwgc2NvcGUpIHsKICAgICAgICBsYXN0VmFsdWUgPSB2YWx1ZTsKICAgICAgICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcikpIHsKICAgICAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7CiAgICAgICAgICBzY29wZS4kJHBvc3REaWdlc3QoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmIChpc0RlZmluZWQobGFzdFZhbHVlKSkgewogICAgICAgICAgICAgIHVud2F0Y2goKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9LCBvYmplY3RFcXVhbGl0eSk7CiAgICB9CgogICAgZnVuY3Rpb24gb25lVGltZUxpdGVyYWxXYXRjaERlbGVnYXRlKHNjb3BlLCBsaXN0ZW5lciwgb2JqZWN0RXF1YWxpdHksIHBhcnNlZEV4cHJlc3Npb24pIHsKICAgICAgdmFyIHVud2F0Y2gsIGxhc3RWYWx1ZTsKICAgICAgcmV0dXJuIHVud2F0Y2ggPSBzY29wZS4kd2F0Y2goZnVuY3Rpb24gb25lVGltZVdhdGNoKHNjb3BlKSB7CiAgICAgICAgcmV0dXJuIHBhcnNlZEV4cHJlc3Npb24oc2NvcGUpOwogICAgICB9LCBmdW5jdGlvbiBvbmVUaW1lTGlzdGVuZXIodmFsdWUsIG9sZCwgc2NvcGUpIHsKICAgICAgICBsYXN0VmFsdWUgPSB2YWx1ZTsKICAgICAgICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcikpIHsKICAgICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgdmFsdWUsIG9sZCwgc2NvcGUpOwogICAgICAgIH0KICAgICAgICBpZiAoaXNBbGxEZWZpbmVkKHZhbHVlKSkgewogICAgICAgICAgc2NvcGUuJCRwb3N0RGlnZXN0KGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAoaXNBbGxEZWZpbmVkKGxhc3RWYWx1ZSkpIHVud2F0Y2goKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfSwgb2JqZWN0RXF1YWxpdHkpOwoKICAgICAgZnVuY3Rpb24gaXNBbGxEZWZpbmVkKHZhbHVlKSB7CiAgICAgICAgdmFyIGFsbERlZmluZWQgPSB0cnVlOwogICAgICAgIGZvckVhY2godmFsdWUsIGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgaWYgKCFpc0RlZmluZWQodmFsKSkgYWxsRGVmaW5lZCA9IGZhbHNlOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBhbGxEZWZpbmVkOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY29uc3RhbnRXYXRjaERlbGVnYXRlKHNjb3BlLCBsaXN0ZW5lciwgb2JqZWN0RXF1YWxpdHksIHBhcnNlZEV4cHJlc3Npb24pIHsKICAgICAgdmFyIHVud2F0Y2g7CiAgICAgIHJldHVybiB1bndhdGNoID0gc2NvcGUuJHdhdGNoKGZ1bmN0aW9uIGNvbnN0YW50V2F0Y2goc2NvcGUpIHsKICAgICAgICByZXR1cm4gcGFyc2VkRXhwcmVzc2lvbihzY29wZSk7CiAgICAgIH0sIGZ1bmN0aW9uIGNvbnN0YW50TGlzdGVuZXIodmFsdWUsIG9sZCwgc2NvcGUpIHsKICAgICAgICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcikpIHsKICAgICAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgICAgIHVud2F0Y2goKTsKICAgICAgfSwgb2JqZWN0RXF1YWxpdHkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFkZEludGVyY2VwdG9yKHBhcnNlZEV4cHJlc3Npb24sIGludGVyY2VwdG9yRm4pIHsKICAgICAgaWYgKCFpbnRlcmNlcHRvckZuKSByZXR1cm4gcGFyc2VkRXhwcmVzc2lvbjsKICAgICAgdmFyIHdhdGNoRGVsZWdhdGUgPSBwYXJzZWRFeHByZXNzaW9uLiQkd2F0Y2hEZWxlZ2F0ZTsKCiAgICAgIHZhciByZWd1bGFyV2F0Y2ggPQogICAgICAgICAgd2F0Y2hEZWxlZ2F0ZSAhPT0gb25lVGltZUxpdGVyYWxXYXRjaERlbGVnYXRlICYmCiAgICAgICAgICB3YXRjaERlbGVnYXRlICE9PSBvbmVUaW1lV2F0Y2hEZWxlZ2F0ZTsKCiAgICAgIHZhciBmbiA9IHJlZ3VsYXJXYXRjaCA/IGZ1bmN0aW9uIHJlZ3VsYXJJbnRlcmNlcHRlZEV4cHJlc3Npb24oc2NvcGUsIGxvY2FscykgewogICAgICAgIHZhciB2YWx1ZSA9IHBhcnNlZEV4cHJlc3Npb24oc2NvcGUsIGxvY2Fscyk7CiAgICAgICAgcmV0dXJuIGludGVyY2VwdG9yRm4odmFsdWUsIHNjb3BlLCBsb2NhbHMpOwogICAgICB9IDogZnVuY3Rpb24gb25lVGltZUludGVyY2VwdGVkRXhwcmVzc2lvbihzY29wZSwgbG9jYWxzKSB7CiAgICAgICAgdmFyIHZhbHVlID0gcGFyc2VkRXhwcmVzc2lvbihzY29wZSwgbG9jYWxzKTsKICAgICAgICB2YXIgcmVzdWx0ID0gaW50ZXJjZXB0b3JGbih2YWx1ZSwgc2NvcGUsIGxvY2Fscyk7CiAgICAgICAgLy8gd2Ugb25seSByZXR1cm4gdGhlIGludGVyY2VwdG9yJ3MgcmVzdWx0IGlmIHRoZQogICAgICAgIC8vIGluaXRpYWwgdmFsdWUgaXMgZGVmaW5lZCAoZm9yIGJpbmQtb25jZSkKICAgICAgICByZXR1cm4gaXNEZWZpbmVkKHZhbHVlKSA/IHJlc3VsdCA6IHZhbHVlOwogICAgICB9OwoKICAgICAgLy8gUHJvcGFnYXRlICQkd2F0Y2hEZWxlZ2F0ZXMgb3RoZXIgdGhlbiBpbnB1dHNXYXRjaERlbGVnYXRlCiAgICAgIGlmIChwYXJzZWRFeHByZXNzaW9uLiQkd2F0Y2hEZWxlZ2F0ZSAmJgogICAgICAgICAgcGFyc2VkRXhwcmVzc2lvbi4kJHdhdGNoRGVsZWdhdGUgIT09IGlucHV0c1dhdGNoRGVsZWdhdGUpIHsKICAgICAgICBmbi4kJHdhdGNoRGVsZWdhdGUgPSBwYXJzZWRFeHByZXNzaW9uLiQkd2F0Y2hEZWxlZ2F0ZTsKICAgICAgfSBlbHNlIGlmICghaW50ZXJjZXB0b3JGbi4kc3RhdGVmdWwpIHsKICAgICAgICAvLyBJZiB0aGVyZSBpcyBhbiBpbnRlcmNlcHRvciwgYnV0IG5vIHdhdGNoRGVsZWdhdGUgdGhlbiB0cmVhdCB0aGUgaW50ZXJjZXB0b3IgbGlrZQogICAgICAgIC8vIHdlIHRyZWF0IGZpbHRlcnMgLSBpdCBpcyBhc3N1bWVkIHRvIGJlIGEgcHVyZSBmdW5jdGlvbiB1bmxlc3MgZmxhZ2dlZCB3aXRoICRzdGF0ZWZ1bAogICAgICAgIGZuLiQkd2F0Y2hEZWxlZ2F0ZSA9IGlucHV0c1dhdGNoRGVsZWdhdGU7CiAgICAgICAgZm4uaW5wdXRzID0gW3BhcnNlZEV4cHJlc3Npb25dOwogICAgICB9CgogICAgICByZXR1cm4gZm47CiAgICB9CiAgfV07Cn0KCi8qKgogKiBAbmdkb2Mgc2VydmljZQogKiBAbmFtZSAkcQogKiBAcmVxdWlyZXMgJHJvb3RTY29wZQogKgogKiBAZGVzY3JpcHRpb24KICogQSBzZXJ2aWNlIHRoYXQgaGVscHMgeW91IHJ1biBmdW5jdGlvbnMgYXN5bmNocm9ub3VzbHksIGFuZCB1c2UgdGhlaXIgcmV0dXJuIHZhbHVlcyAob3IgZXhjZXB0aW9ucykKICogd2hlbiB0aGV5IGFyZSBkb25lIHByb2Nlc3NpbmcuCiAqCiAqIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgcHJvbWlzZXMvZGVmZXJyZWQgb2JqZWN0cyBpbnNwaXJlZCBieQogKiBbS3JpcyBLb3dhbCdzIFFdKGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcSkuCiAqCiAqICRxIGNhbiBiZSB1c2VkIGluIHR3byBmYXNoaW9ucyAtLS0gb25lIHdoaWNoIGlzIG1vcmUgc2ltaWxhciB0byBLcmlzIEtvd2FsJ3MgUSBvciBqUXVlcnkncyBEZWZlcnJlZAogKiBpbXBsZW1lbnRhdGlvbnMsIGFuZCB0aGUgb3RoZXIgd2hpY2ggcmVzZW1ibGVzIEVTNiBwcm9taXNlcyB0byBzb21lIGRlZ3JlZS4KICoKICogIyAkcSBjb25zdHJ1Y3RvcgogKgogKiBUaGUgc3RyZWFtbGluZWQgRVM2IHN0eWxlIHByb21pc2UgaXMgZXNzZW50aWFsbHkganVzdCB1c2luZyAkcSBhcyBhIGNvbnN0cnVjdG9yIHdoaWNoIHRha2VzIGEgYHJlc29sdmVyYAogKiBmdW5jdGlvbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQuIFRoaXMgaXMgc2ltaWxhciB0byB0aGUgbmF0aXZlIFByb21pc2UgaW1wbGVtZW50YXRpb24gZnJvbSBFUzYgSGFybW9ueSwKICogc2VlIFtNRE5dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1Byb21pc2UpLgogKgogKiBXaGlsZSB0aGUgY29uc3RydWN0b3Itc3R5bGUgdXNlIGlzIHN1cHBvcnRlZCwgbm90IGFsbCBvZiB0aGUgc3VwcG9ydGluZyBtZXRob2RzIGZyb20gRVM2IEhhcm1vbnkgcHJvbWlzZXMgYXJlCiAqIGF2YWlsYWJsZSB5ZXQuCiAqCiAqIEl0IGNhbiBiZSB1c2VkIGxpa2Ugc286CiAqCiAqIGBgYGpzCiAqICAgLy8gZm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgZXhhbXBsZSBsZXQncyBhc3N1bWUgdGhhdCB2YXJpYWJsZXMgYCRxYCBhbmQgYG9rVG9HcmVldGAKICogICAvLyBhcmUgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGxleGljYWwgc2NvcGUgKHRoZXkgY291bGQgaGF2ZSBiZWVuIGluamVjdGVkIG9yIHBhc3NlZCBpbikuCiAqCiAqICAgZnVuY3Rpb24gYXN5bmNHcmVldChuYW1lKSB7CiAqICAgICAvLyBwZXJmb3JtIHNvbWUgYXN5bmNocm9ub3VzIG9wZXJhdGlvbiwgcmVzb2x2ZSBvciByZWplY3QgdGhlIHByb21pc2Ugd2hlbiBhcHByb3ByaWF0ZS4KICogICAgIHJldHVybiAkcShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICogICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsKICogICAgICAgICBpZiAob2tUb0dyZWV0KG5hbWUpKSB7CiAqICAgICAgICAgICByZXNvbHZlKCdIZWxsbywgJyArIG5hbWUgKyAnIScpOwogKiAgICAgICAgIH0gZWxzZSB7CiAqICAgICAgICAgICByZWplY3QoJ0dyZWV0aW5nICcgKyBuYW1lICsgJyBpcyBub3QgYWxsb3dlZC4nKTsKICogICAgICAgICB9CiAqICAgICAgIH0sIDEwMDApOwogKiAgICAgfSk7CiAqICAgfQogKgogKiAgIHZhciBwcm9taXNlID0gYXN5bmNHcmVldCgnUm9iaW4gSG9vZCcpOwogKiAgIHByb21pc2UudGhlbihmdW5jdGlvbihncmVldGluZykgewogKiAgICAgYWxlcnQoJ1N1Y2Nlc3M6ICcgKyBncmVldGluZyk7CiAqICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7CiAqICAgICBhbGVydCgnRmFpbGVkOiAnICsgcmVhc29uKTsKICogICB9KTsKICogYGBgCiAqCiAqIE5vdGU6IHByb2dyZXNzL25vdGlmeSBjYWxsYmFja3MgYXJlIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkIHZpYSB0aGUgRVM2LXN0eWxlIGludGVyZmFjZS4KICoKICogSG93ZXZlciwgdGhlIG1vcmUgdHJhZGl0aW9uYWwgQ29tbW9uSlMtc3R5bGUgdXNhZ2UgaXMgc3RpbGwgYXZhaWxhYmxlLCBhbmQgZG9jdW1lbnRlZCBiZWxvdy4KICoKICogW1RoZSBDb21tb25KUyBQcm9taXNlIHByb3Bvc2FsXShodHRwOi8vd2lraS5jb21tb25qcy5vcmcvd2lraS9Qcm9taXNlcykgZGVzY3JpYmVzIGEgcHJvbWlzZSBhcyBhbgogKiBpbnRlcmZhY2UgZm9yIGludGVyYWN0aW5nIHdpdGggYW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIGFuIGFjdGlvbiB0aGF0IGlzCiAqIHBlcmZvcm1lZCBhc3luY2hyb25vdXNseSwgYW5kIG1heSBvciBtYXkgbm90IGJlIGZpbmlzaGVkIGF0IGFueSBnaXZlbiBwb2ludCBpbiB0aW1lLgogKgogKiBGcm9tIHRoZSBwZXJzcGVjdGl2ZSBvZiBkZWFsaW5nIHdpdGggZXJyb3IgaGFuZGxpbmcsIGRlZmVycmVkIGFuZCBwcm9taXNlIEFQSXMgYXJlIHRvCiAqIGFzeW5jaHJvbm91cyBwcm9ncmFtbWluZyB3aGF0IGB0cnlgLCBgY2F0Y2hgIGFuZCBgdGhyb3dgIGtleXdvcmRzIGFyZSB0byBzeW5jaHJvbm91cyBwcm9ncmFtbWluZy4KICoKICogYGBganMKICogICAvLyBmb3IgdGhlIHB1cnBvc2Ugb2YgdGhpcyBleGFtcGxlIGxldCdzIGFzc3VtZSB0aGF0IHZhcmlhYmxlcyBgJHFgIGFuZCBgb2tUb0dyZWV0YAogKiAgIC8vIGFyZSBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgbGV4aWNhbCBzY29wZSAodGhleSBjb3VsZCBoYXZlIGJlZW4gaW5qZWN0ZWQgb3IgcGFzc2VkIGluKS4KICoKICogICBmdW5jdGlvbiBhc3luY0dyZWV0KG5hbWUpIHsKICogICAgIHZhciBkZWZlcnJlZCA9ICRxLmRlZmVyKCk7CiAqCiAqICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogKiAgICAgICBkZWZlcnJlZC5ub3RpZnkoJ0Fib3V0IHRvIGdyZWV0ICcgKyBuYW1lICsgJy4nKTsKICoKICogICAgICAgaWYgKG9rVG9HcmVldChuYW1lKSkgewogKiAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoJ0hlbGxvLCAnICsgbmFtZSArICchJyk7CiAqICAgICAgIH0gZWxzZSB7CiAqICAgICAgICAgZGVmZXJyZWQucmVqZWN0KCdHcmVldGluZyAnICsgbmFtZSArICcgaXMgbm90IGFsbG93ZWQuJyk7CiAqICAgICAgIH0KICogICAgIH0sIDEwMDApOwogKgogKiAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7CiAqICAgfQogKgogKiAgIHZhciBwcm9taXNlID0gYXN5bmNHcmVldCgnUm9iaW4gSG9vZCcpOwogKiAgIHByb21pc2UudGhlbihmdW5jdGlvbihncmVldGluZykgewogKiAgICAgYWxlcnQoJ1N1Y2Nlc3M6ICcgKyBncmVldGluZyk7CiAqICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7CiAqICAgICBhbGVydCgnRmFpbGVkOiAnICsgcmVhc29uKTsKICogICB9LCBmdW5jdGlvbih1cGRhdGUpIHsKICogICAgIGFsZXJ0KCdHb3Qgbm90aWZpY2F0aW9uOiAnICsgdXBkYXRlKTsKICogICB9KTsKICogYGBgCiAqCiAqIEF0IGZpcnN0IGl0IG1pZ2h0IG5vdCBiZSBvYnZpb3VzIHdoeSB0aGlzIGV4dHJhIGNvbXBsZXhpdHkgaXMgd29ydGggdGhlIHRyb3VibGUuIFRoZSBwYXlvZmYKICogY29tZXMgaW4gdGhlIHdheSBvZiBndWFyYW50ZWVzIHRoYXQgcHJvbWlzZSBhbmQgZGVmZXJyZWQgQVBJcyBtYWtlLCBzZWUKICogaHR0cHM6Ly9naXRodWIuY29tL2tyaXNrb3dhbC91bmNvbW1vbmpzL2Jsb2IvbWFzdGVyL3Byb21pc2VzL3NwZWNpZmljYXRpb24ubWQuCiAqCiAqIEFkZGl0aW9uYWxseSB0aGUgcHJvbWlzZSBhcGkgYWxsb3dzIGZvciBjb21wb3NpdGlvbiB0aGF0IGlzIHZlcnkgaGFyZCB0byBkbyB3aXRoIHRoZQogKiB0cmFkaXRpb25hbCBjYWxsYmFjayAoW0NQU10oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db250aW51YXRpb24tcGFzc2luZ19zdHlsZSkpIGFwcHJvYWNoLgogKiBGb3IgbW9yZSBvbiB0aGlzIHBsZWFzZSBzZWUgdGhlIFtRIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcSkgZXNwZWNpYWxseSB0aGUKICogc2VjdGlvbiBvbiBzZXJpYWwgb3IgcGFyYWxsZWwgam9pbmluZyBvZiBwcm9taXNlcy4KICoKICogIyBUaGUgRGVmZXJyZWQgQVBJCiAqCiAqIEEgbmV3IGluc3RhbmNlIG9mIGRlZmVycmVkIGlzIGNvbnN0cnVjdGVkIGJ5IGNhbGxpbmcgYCRxLmRlZmVyKClgLgogKgogKiBUaGUgcHVycG9zZSBvZiB0aGUgZGVmZXJyZWQgb2JqZWN0IGlzIHRvIGV4cG9zZSB0aGUgYXNzb2NpYXRlZCBQcm9taXNlIGluc3RhbmNlIGFzIHdlbGwgYXMgQVBJcwogKiB0aGF0IGNhbiBiZSB1c2VkIGZvciBzaWduYWxpbmcgdGhlIHN1Y2Nlc3NmdWwgb3IgdW5zdWNjZXNzZnVsIGNvbXBsZXRpb24sIGFzIHdlbGwgYXMgdGhlIHN0YXR1cwogKiBvZiB0aGUgdGFzay4KICoKICogKipNZXRob2RzKioKICoKICogLSBgcmVzb2x2ZSh2YWx1ZSlgIOKAPyByZXNvbHZlcyB0aGUgZGVyaXZlZCBwcm9taXNlIHdpdGggdGhlIGB2YWx1ZWAuIElmIHRoZSB2YWx1ZSBpcyBhIHJlamVjdGlvbgogKiAgIGNvbnN0cnVjdGVkIHZpYSBgJHEucmVqZWN0YCwgdGhlIHByb21pc2Ugd2lsbCBiZSByZWplY3RlZCBpbnN0ZWFkLgogKiAtIGByZWplY3QocmVhc29uKWAg4oA/IHJlamVjdHMgdGhlIGRlcml2ZWQgcHJvbWlzZSB3aXRoIHRoZSBgcmVhc29uYC4gVGhpcyBpcyBlcXVpdmFsZW50IHRvCiAqICAgcmVzb2x2aW5nIGl0IHdpdGggYSByZWplY3Rpb24gY29uc3RydWN0ZWQgdmlhIGAkcS5yZWplY3RgLgogKiAtIGBub3RpZnkodmFsdWUpYCAtIHByb3ZpZGVzIHVwZGF0ZXMgb24gdGhlIHN0YXR1cyBvZiB0aGUgcHJvbWlzZSdzIGV4ZWN1dGlvbi4gVGhpcyBtYXkgYmUgY2FsbGVkCiAqICAgbXVsdGlwbGUgdGltZXMgYmVmb3JlIHRoZSBwcm9taXNlIGlzIGVpdGhlciByZXNvbHZlZCBvciByZWplY3RlZC4KICoKICogKipQcm9wZXJ0aWVzKioKICoKICogLSBwcm9taXNlIOKAPyBge1Byb21pc2V9YCDigD8gcHJvbWlzZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZGVmZXJyZWQuCiAqCiAqCiAqICMgVGhlIFByb21pc2UgQVBJCiAqCiAqIEEgbmV3IHByb21pc2UgaW5zdGFuY2UgaXMgY3JlYXRlZCB3aGVuIGEgZGVmZXJyZWQgaW5zdGFuY2UgaXMgY3JlYXRlZCBhbmQgY2FuIGJlIHJldHJpZXZlZCBieQogKiBjYWxsaW5nIGBkZWZlcnJlZC5wcm9taXNlYC4KICoKICogVGhlIHB1cnBvc2Ugb2YgdGhlIHByb21pc2Ugb2JqZWN0IGlzIHRvIGFsbG93IGZvciBpbnRlcmVzdGVkIHBhcnRpZXMgdG8gZ2V0IGFjY2VzcyB0byB0aGUgcmVzdWx0CiAqIG9mIHRoZSBkZWZlcnJlZCB0YXNrIHdoZW4gaXQgY29tcGxldGVzLgogKgogKiAqKk1ldGhvZHMqKgogKgogKiAtIGB0aGVuKHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaywgbm90aWZ5Q2FsbGJhY2spYCDigD8gcmVnYXJkbGVzcyBvZiB3aGVuIHRoZSBwcm9taXNlIHdhcyBvcgogKiAgIHdpbGwgYmUgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQsIGB0aGVuYCBjYWxscyBvbmUgb2YgdGhlIHN1Y2Nlc3Mgb3IgZXJyb3IgY2FsbGJhY2tzIGFzeW5jaHJvbm91c2x5CiAqICAgYXMgc29vbiBhcyB0aGUgcmVzdWx0IGlzIGF2YWlsYWJsZS4gVGhlIGNhbGxiYWNrcyBhcmUgY2FsbGVkIHdpdGggYSBzaW5nbGUgYXJndW1lbnQ6IHRoZSByZXN1bHQKICogICBvciByZWplY3Rpb24gcmVhc29uLiBBZGRpdGlvbmFsbHksIHRoZSBub3RpZnkgY2FsbGJhY2sgbWF5IGJlIGNhbGxlZCB6ZXJvIG9yIG1vcmUgdGltZXMgdG8KICogICBwcm92aWRlIGEgcHJvZ3Jlc3MgaW5kaWNhdGlvbiwgYmVmb3JlIHRoZSBwcm9taXNlIGlzIHJlc29sdmVkIG9yIHJlamVjdGVkLgogKgogKiAgIFRoaXMgbWV0aG9kICpyZXR1cm5zIGEgbmV3IHByb21pc2UqIHdoaWNoIGlzIHJlc29sdmVkIG9yIHJlamVjdGVkIHZpYSB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZQogKiAgIGBzdWNjZXNzQ2FsbGJhY2tgLCBgZXJyb3JDYWxsYmFja2AuIEl0IGFsc28gbm90aWZpZXMgdmlhIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlCiAqICAgYG5vdGlmeUNhbGxiYWNrYCBtZXRob2QuIFRoZSBwcm9taXNlIGNhbm5vdCBiZSByZXNvbHZlZCBvciByZWplY3RlZCBmcm9tIHRoZSBub3RpZnlDYWxsYmFjawogKiAgIG1ldGhvZC4KICoKICogLSBgY2F0Y2goZXJyb3JDYWxsYmFjaylgIOKAPyBzaG9ydGhhbmQgZm9yIGBwcm9taXNlLnRoZW4obnVsbCwgZXJyb3JDYWxsYmFjaylgCiAqCiAqIC0gYGZpbmFsbHkoY2FsbGJhY2ssIG5vdGlmeUNhbGxiYWNrKWAg4oA/IGFsbG93cyB5b3UgdG8gb2JzZXJ2ZSBlaXRoZXIgdGhlIGZ1bGZpbGxtZW50IG9yIHJlamVjdGlvbiBvZiBhIHByb21pc2UsCiAqICAgYnV0IHRvIGRvIHNvIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBmaW5hbCB2YWx1ZS4gVGhpcyBpcyB1c2VmdWwgdG8gcmVsZWFzZSByZXNvdXJjZXMgb3IgZG8gc29tZQogKiAgIGNsZWFuLXVwIHRoYXQgbmVlZHMgdG8gYmUgZG9uZSB3aGV0aGVyIHRoZSBwcm9taXNlIHdhcyByZWplY3RlZCBvciByZXNvbHZlZC4gU2VlIHRoZSBbZnVsbAogKiAgIHNwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS93aWtpL0FQSS1SZWZlcmVuY2UjcHJvbWlzZWZpbmFsbHljYWxsYmFjaykgZm9yCiAqICAgbW9yZSBpbmZvcm1hdGlvbi4KICoKICogIyBDaGFpbmluZyBwcm9taXNlcwogKgogKiBCZWNhdXNlIGNhbGxpbmcgdGhlIGB0aGVuYCBtZXRob2Qgb2YgYSBwcm9taXNlIHJldHVybnMgYSBuZXcgZGVyaXZlZCBwcm9taXNlLCBpdCBpcyBlYXNpbHkKICogcG9zc2libGUgdG8gY3JlYXRlIGEgY2hhaW4gb2YgcHJvbWlzZXM6CiAqCiAqIGBgYGpzCiAqICAgcHJvbWlzZUIgPSBwcm9taXNlQS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkgewogKiAgICAgcmV0dXJuIHJlc3VsdCArIDE7CiAqICAgfSk7CiAqCiAqICAgLy8gcHJvbWlzZUIgd2lsbCBiZSByZXNvbHZlZCBpbW1lZGlhdGVseSBhZnRlciBwcm9taXNlQSBpcyByZXNvbHZlZCBhbmQgaXRzIHZhbHVlCiAqICAgLy8gd2lsbCBiZSB0aGUgcmVzdWx0IG9mIHByb21pc2VBIGluY3JlbWVudGVkIGJ5IDEKICogYGBgCiAqCiAqIEl0IGlzIHBvc3NpYmxlIHRvIGNyZWF0ZSBjaGFpbnMgb2YgYW55IGxlbmd0aCBhbmQgc2luY2UgYSBwcm9taXNlIGNhbiBiZSByZXNvbHZlZCB3aXRoIGFub3RoZXIKICogcHJvbWlzZSAod2hpY2ggd2lsbCBkZWZlciBpdHMgcmVzb2x1dGlvbiBmdXJ0aGVyKSwgaXQgaXMgcG9zc2libGUgdG8gcGF1c2UvZGVmZXIgcmVzb2x1dGlvbiBvZgogKiB0aGUgcHJvbWlzZXMgYXQgYW55IHBvaW50IGluIHRoZSBjaGFpbi4gVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSB0byBpbXBsZW1lbnQgcG93ZXJmdWwgQVBJcyBsaWtlCiAqICRodHRwJ3MgcmVzcG9uc2UgaW50ZXJjZXB0b3JzLgogKgogKgogKiAjIERpZmZlcmVuY2VzIGJldHdlZW4gS3JpcyBLb3dhbCdzIFEgYW5kICRxCiAqCiAqICBUaGVyZSBhcmUgdHdvIG1haW4gZGlmZmVyZW5jZXM6CiAqCiAqIC0gJHEgaXMgaW50ZWdyYXRlZCB3aXRoIHRoZSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZX0gU2NvcGUgbW9kZWwgb2JzZXJ2YXRpb24KICogICBtZWNoYW5pc20gaW4gYW5ndWxhciwgd2hpY2ggbWVhbnMgZmFzdGVyIHByb3BhZ2F0aW9uIG9mIHJlc29sdXRpb24gb3IgcmVqZWN0aW9uIGludG8geW91cgogKiAgIG1vZGVscyBhbmQgYXZvaWRpbmcgdW5uZWNlc3NhcnkgYnJvd3NlciByZXBhaW50cywgd2hpY2ggd291bGQgcmVzdWx0IGluIGZsaWNrZXJpbmcgVUkuCiAqIC0gUSBoYXMgbWFueSBtb3JlIGZlYXR1cmVzIHRoYW4gJHEsIGJ1dCB0aGF0IGNvbWVzIGF0IGEgY29zdCBvZiBieXRlcy4gJHEgaXMgdGlueSwgYnV0IGNvbnRhaW5zCiAqICAgYWxsIHRoZSBpbXBvcnRhbnQgZnVuY3Rpb25hbGl0eSBuZWVkZWQgZm9yIGNvbW1vbiBhc3luYyB0YXNrcy4KICoKICogICMgVGVzdGluZwogKgogKiAgYGBganMKICogICAgaXQoJ3Nob3VsZCBzaW11bGF0ZSBwcm9taXNlJywgaW5qZWN0KGZ1bmN0aW9uKCRxLCAkcm9vdFNjb3BlKSB7CiAqICAgICAgdmFyIGRlZmVycmVkID0gJHEuZGVmZXIoKTsKICogICAgICB2YXIgcHJvbWlzZSA9IGRlZmVycmVkLnByb21pc2U7CiAqICAgICAgdmFyIHJlc29sdmVkVmFsdWU7CiAqCiAqICAgICAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7IHJlc29sdmVkVmFsdWUgPSB2YWx1ZTsgfSk7CiAqICAgICAgZXhwZWN0KHJlc29sdmVkVmFsdWUpLnRvQmVVbmRlZmluZWQoKTsKICoKICogICAgICAvLyBTaW11bGF0ZSByZXNvbHZpbmcgb2YgcHJvbWlzZQogKiAgICAgIGRlZmVycmVkLnJlc29sdmUoMTIzKTsKICogICAgICAvLyBOb3RlIHRoYXQgdGhlICd0aGVuJyBmdW5jdGlvbiBkb2VzIG5vdCBnZXQgY2FsbGVkIHN5bmNocm9ub3VzbHkuCiAqICAgICAgLy8gVGhpcyBpcyBiZWNhdXNlIHdlIHdhbnQgdGhlIHByb21pc2UgQVBJIHRvIGFsd2F5cyBiZSBhc3luYywgd2hldGhlciBvciBub3QKICogICAgICAvLyBpdCBnb3QgY2FsbGVkIHN5bmNocm9ub3VzbHkgb3IgYXN5bmNocm9ub3VzbHkuCiAqICAgICAgZXhwZWN0KHJlc29sdmVkVmFsdWUpLnRvQmVVbmRlZmluZWQoKTsKICoKICogICAgICAvLyBQcm9wYWdhdGUgcHJvbWlzZSByZXNvbHV0aW9uIHRvICd0aGVuJyBmdW5jdGlvbnMgdXNpbmcgJGFwcGx5KCkuCiAqICAgICAgJHJvb3RTY29wZS4kYXBwbHkoKTsKICogICAgICBleHBlY3QocmVzb2x2ZWRWYWx1ZSkudG9FcXVhbCgxMjMpOwogKiAgICB9KSk7CiAqICBgYGAKICoKICogQHBhcmFtIHtmdW5jdGlvbihmdW5jdGlvbiwgZnVuY3Rpb24pfSByZXNvbHZlciBGdW5jdGlvbiB3aGljaCBpcyByZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIG9yCiAqICAgcmVqZWN0aW5nIHRoZSBuZXdseSBjcmVhdGVkIHByb21pc2UuIFRoZSBmaXJzdCBwYXJhbWV0ZXIgaXMgYSBmdW5jdGlvbiB3aGljaCByZXNvbHZlcyB0aGUKICogICBwcm9taXNlLCB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBhIGZ1bmN0aW9uIHdoaWNoIHJlamVjdHMgdGhlIHByb21pc2UuCiAqCiAqIEByZXR1cm5zIHtQcm9taXNlfSBUaGUgbmV3bHkgY3JlYXRlZCBwcm9taXNlLgogKi8KZnVuY3Rpb24gJFFQcm92aWRlcigpIHsKCiAgdGhpcy4kZ2V0ID0gWyckcm9vdFNjb3BlJywgJyRleGNlcHRpb25IYW5kbGVyJywgZnVuY3Rpb24oJHJvb3RTY29wZSwgJGV4Y2VwdGlvbkhhbmRsZXIpIHsKICAgIHJldHVybiBxRmFjdG9yeShmdW5jdGlvbihjYWxsYmFjaykgewogICAgICAkcm9vdFNjb3BlLiRldmFsQXN5bmMoY2FsbGJhY2spOwogICAgfSwgJGV4Y2VwdGlvbkhhbmRsZXIpOwogIH1dOwp9CgpmdW5jdGlvbiAkJFFQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyRicm93c2VyJywgJyRleGNlcHRpb25IYW5kbGVyJywgZnVuY3Rpb24oJGJyb3dzZXIsICRleGNlcHRpb25IYW5kbGVyKSB7CiAgICByZXR1cm4gcUZhY3RvcnkoZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgJGJyb3dzZXIuZGVmZXIoY2FsbGJhY2spOwogICAgfSwgJGV4Y2VwdGlvbkhhbmRsZXIpOwogIH1dOwp9CgovKioKICogQ29uc3RydWN0cyBhIHByb21pc2UgbWFuYWdlci4KICoKICogQHBhcmFtIHtmdW5jdGlvbihmdW5jdGlvbil9IG5leHRUaWNrIEZ1bmN0aW9uIGZvciBleGVjdXRpbmcgZnVuY3Rpb25zIGluIHRoZSBuZXh0IHR1cm4uCiAqIEBwYXJhbSB7ZnVuY3Rpb24oLi4uKil9IGV4Y2VwdGlvbkhhbmRsZXIgRnVuY3Rpb24gaW50byB3aGljaCB1bmV4cGVjdGVkIGV4Y2VwdGlvbnMgYXJlIHBhc3NlZCBmb3IKICogICAgIGRlYnVnZ2luZyBwdXJwb3Nlcy4KICogQHJldHVybnMge29iamVjdH0gUHJvbWlzZSBtYW5hZ2VyLgogKi8KZnVuY3Rpb24gcUZhY3RvcnkobmV4dFRpY2ssIGV4Y2VwdGlvbkhhbmRsZXIpIHsKICB2YXIgJHFNaW5FcnIgPSBtaW5FcnIoJyRxJywgVHlwZUVycm9yKTsKICBmdW5jdGlvbiBjYWxsT25jZShzZWxmLCByZXNvbHZlRm4sIHJlamVjdEZuKSB7CiAgICB2YXIgY2FsbGVkID0gZmFsc2U7CiAgICBmdW5jdGlvbiB3cmFwKGZuKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgIGlmIChjYWxsZWQpIHJldHVybjsKICAgICAgICBjYWxsZWQgPSB0cnVlOwogICAgICAgIGZuLmNhbGwoc2VsZiwgdmFsdWUpOwogICAgICB9OwogICAgfQoKICAgIHJldHVybiBbd3JhcChyZXNvbHZlRm4pLCB3cmFwKHJlamVjdEZuKV07CiAgfQoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgbmcuJHEjZGVmZXIKICAgKiBAa2luZCBmdW5jdGlvbgogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ3JlYXRlcyBhIGBEZWZlcnJlZGAgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgYSB0YXNrIHdoaWNoIHdpbGwgZmluaXNoIGluIHRoZSBmdXR1cmUuCiAgICoKICAgKiBAcmV0dXJucyB7RGVmZXJyZWR9IFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgZGVmZXJyZWQuCiAgICovCiAgdmFyIGRlZmVyID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gbmV3IERlZmVycmVkKCk7CiAgfTsKCiAgZnVuY3Rpb24gUHJvbWlzZSgpIHsKICAgIHRoaXMuJCRzdGF0ZSA9IHsgc3RhdHVzOiAwIH07CiAgfQoKICBQcm9taXNlLnByb3RvdHlwZSA9IHsKICAgIHRoZW46IGZ1bmN0aW9uKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBwcm9ncmVzc0JhY2spIHsKICAgICAgdmFyIHJlc3VsdCA9IG5ldyBEZWZlcnJlZCgpOwoKICAgICAgdGhpcy4kJHN0YXRlLnBlbmRpbmcgPSB0aGlzLiQkc3RhdGUucGVuZGluZyB8fCBbXTsKICAgICAgdGhpcy4kJHN0YXRlLnBlbmRpbmcucHVzaChbcmVzdWx0LCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcHJvZ3Jlc3NCYWNrXSk7CiAgICAgIGlmICh0aGlzLiQkc3RhdGUuc3RhdHVzID4gMCkgc2NoZWR1bGVQcm9jZXNzUXVldWUodGhpcy4kJHN0YXRlKTsKCiAgICAgIHJldHVybiByZXN1bHQucHJvbWlzZTsKICAgIH0sCgogICAgImNhdGNoIjogZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBjYWxsYmFjayk7CiAgICB9LAoKICAgICJmaW5hbGx5IjogZnVuY3Rpb24oY2FsbGJhY2ssIHByb2dyZXNzQmFjaykgewogICAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGhhbmRsZUNhbGxiYWNrKHZhbHVlLCB0cnVlLCBjYWxsYmFjayk7CiAgICAgIH0sIGZ1bmN0aW9uKGVycm9yKSB7CiAgICAgICAgcmV0dXJuIGhhbmRsZUNhbGxiYWNrKGVycm9yLCBmYWxzZSwgY2FsbGJhY2spOwogICAgICB9LCBwcm9ncmVzc0JhY2spOwogICAgfQogIH07CgogIC8vRmFzdGVyLCBtb3JlIGJhc2ljIHRoYW4gYW5ndWxhci5iaW5kIGh0dHA6Ly9qc3BlcmYuY29tL2FuZ3VsYXItYmluZC12cy1jdXN0b20tdnMtbmF0aXZlCiAgZnVuY3Rpb24gc2ltcGxlQmluZChjb250ZXh0LCBmbikgewogICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIGZuLmNhbGwoY29udGV4dCwgdmFsdWUpOwogICAgfTsKICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NRdWV1ZShzdGF0ZSkgewogICAgdmFyIGZuLCBwcm9taXNlLCBwZW5kaW5nOwoKICAgIHBlbmRpbmcgPSBzdGF0ZS5wZW5kaW5nOwogICAgc3RhdGUucHJvY2Vzc1NjaGVkdWxlZCA9IGZhbHNlOwogICAgc3RhdGUucGVuZGluZyA9IHVuZGVmaW5lZDsKICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBlbmRpbmcubGVuZ3RoOyBpIDwgaWk7ICsraSkgewogICAgICBwcm9taXNlID0gcGVuZGluZ1tpXVswXTsKICAgICAgZm4gPSBwZW5kaW5nW2ldW3N0YXRlLnN0YXR1c107CiAgICAgIHRyeSB7CiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7CiAgICAgICAgICBwcm9taXNlLnJlc29sdmUoZm4oc3RhdGUudmFsdWUpKTsKICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLnN0YXR1cyA9PT0gMSkgewogICAgICAgICAgcHJvbWlzZS5yZXNvbHZlKHN0YXRlLnZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcHJvbWlzZS5yZWplY3Qoc3RhdGUudmFsdWUpOwogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHByb21pc2UucmVqZWN0KGUpOwogICAgICAgIGV4Y2VwdGlvbkhhbmRsZXIoZSk7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIHNjaGVkdWxlUHJvY2Vzc1F1ZXVlKHN0YXRlKSB7CiAgICBpZiAoc3RhdGUucHJvY2Vzc1NjaGVkdWxlZCB8fCAhc3RhdGUucGVuZGluZykgcmV0dXJuOwogICAgc3RhdGUucHJvY2Vzc1NjaGVkdWxlZCA9IHRydWU7CiAgICBuZXh0VGljayhmdW5jdGlvbigpIHsgcHJvY2Vzc1F1ZXVlKHN0YXRlKTsgfSk7CiAgfQoKICBmdW5jdGlvbiBEZWZlcnJlZCgpIHsKICAgIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKCk7CiAgICAvL05lY2Vzc2FyeSB0byBzdXBwb3J0IHVuYm91bmQgZXhlY3V0aW9uIDovCiAgICB0aGlzLnJlc29sdmUgPSBzaW1wbGVCaW5kKHRoaXMsIHRoaXMucmVzb2x2ZSk7CiAgICB0aGlzLnJlamVjdCA9IHNpbXBsZUJpbmQodGhpcywgdGhpcy5yZWplY3QpOwogICAgdGhpcy5ub3RpZnkgPSBzaW1wbGVCaW5kKHRoaXMsIHRoaXMubm90aWZ5KTsKICB9CgogIERlZmVycmVkLnByb3RvdHlwZSA9IHsKICAgIHJlc29sdmU6IGZ1bmN0aW9uKHZhbCkgewogICAgICBpZiAodGhpcy5wcm9taXNlLiQkc3RhdGUuc3RhdHVzKSByZXR1cm47CiAgICAgIGlmICh2YWwgPT09IHRoaXMucHJvbWlzZSkgewogICAgICAgIHRoaXMuJCRyZWplY3QoJHFNaW5FcnIoCiAgICAgICAgICAncWN5Y2xlJywKICAgICAgICAgICJFeHBlY3RlZCBwcm9taXNlIHRvIGJlIHJlc29sdmVkIHdpdGggdmFsdWUgb3RoZXIgdGhhbiBpdHNlbGYgJ3swfSciLAogICAgICAgICAgdmFsKSk7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgdGhpcy4kJHJlc29sdmUodmFsKTsKICAgICAgfQoKICAgIH0sCgogICAgJCRyZXNvbHZlOiBmdW5jdGlvbih2YWwpIHsKICAgICAgdmFyIHRoZW4sIGZuczsKCiAgICAgIGZucyA9IGNhbGxPbmNlKHRoaXMsIHRoaXMuJCRyZXNvbHZlLCB0aGlzLiQkcmVqZWN0KTsKICAgICAgdHJ5IHsKICAgICAgICBpZiAoKGlzT2JqZWN0KHZhbCkgfHwgaXNGdW5jdGlvbih2YWwpKSkgdGhlbiA9IHZhbCAmJiB2YWwudGhlbjsKICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGVuKSkgewogICAgICAgICAgdGhpcy5wcm9taXNlLiQkc3RhdGUuc3RhdHVzID0gLTE7CiAgICAgICAgICB0aGVuLmNhbGwodmFsLCBmbnNbMF0sIGZuc1sxXSwgdGhpcy5ub3RpZnkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLnByb21pc2UuJCRzdGF0ZS52YWx1ZSA9IHZhbDsKICAgICAgICAgIHRoaXMucHJvbWlzZS4kJHN0YXRlLnN0YXR1cyA9IDE7CiAgICAgICAgICBzY2hlZHVsZVByb2Nlc3NRdWV1ZSh0aGlzLnByb21pc2UuJCRzdGF0ZSk7CiAgICAgICAgfQogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgZm5zWzFdKGUpOwogICAgICAgIGV4Y2VwdGlvbkhhbmRsZXIoZSk7CiAgICAgIH0KICAgIH0sCgogICAgcmVqZWN0OiBmdW5jdGlvbihyZWFzb24pIHsKICAgICAgaWYgKHRoaXMucHJvbWlzZS4kJHN0YXRlLnN0YXR1cykgcmV0dXJuOwogICAgICB0aGlzLiQkcmVqZWN0KHJlYXNvbik7CiAgICB9LAoKICAgICQkcmVqZWN0OiBmdW5jdGlvbihyZWFzb24pIHsKICAgICAgdGhpcy5wcm9taXNlLiQkc3RhdGUudmFsdWUgPSByZWFzb247CiAgICAgIHRoaXMucHJvbWlzZS4kJHN0YXRlLnN0YXR1cyA9IDI7CiAgICAgIHNjaGVkdWxlUHJvY2Vzc1F1ZXVlKHRoaXMucHJvbWlzZS4kJHN0YXRlKTsKICAgIH0sCgogICAgbm90aWZ5OiBmdW5jdGlvbihwcm9ncmVzcykgewogICAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5wcm9taXNlLiQkc3RhdGUucGVuZGluZzsKCiAgICAgIGlmICgodGhpcy5wcm9taXNlLiQkc3RhdGUuc3RhdHVzIDw9IDApICYmIGNhbGxiYWNrcyAmJiBjYWxsYmFja3MubGVuZ3RoKSB7CiAgICAgICAgbmV4dFRpY2soZnVuY3Rpb24oKSB7CiAgICAgICAgICB2YXIgY2FsbGJhY2ssIHJlc3VsdDsKICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrc1tpXVswXTsKICAgICAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFja3NbaV1bM107CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgcmVzdWx0Lm5vdGlmeShpc0Z1bmN0aW9uKGNhbGxiYWNrKSA/IGNhbGxiYWNrKHByb2dyZXNzKSA6IHByb2dyZXNzKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgIGV4Y2VwdGlvbkhhbmRsZXIoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkcSNyZWplY3QKICAgKiBAa2luZCBmdW5jdGlvbgogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ3JlYXRlcyBhIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCBhcyByZWplY3RlZCB3aXRoIHRoZSBzcGVjaWZpZWQgYHJlYXNvbmAuIFRoaXMgYXBpIHNob3VsZCBiZQogICAqIHVzZWQgdG8gZm9yd2FyZCByZWplY3Rpb24gaW4gYSBjaGFpbiBvZiBwcm9taXNlcy4gSWYgeW91IGFyZSBkZWFsaW5nIHdpdGggdGhlIGxhc3QgcHJvbWlzZSBpbgogICAqIGEgcHJvbWlzZSBjaGFpbiwgeW91IGRvbid0IG5lZWQgdG8gd29ycnkgYWJvdXQgaXQuCiAgICoKICAgKiBXaGVuIGNvbXBhcmluZyBkZWZlcnJlZHMvcHJvbWlzZXMgdG8gdGhlIGZhbWlsaWFyIGJlaGF2aW9yIG9mIHRyeS9jYXRjaC90aHJvdywgdGhpbmsgb2YKICAgKiBgcmVqZWN0YCBhcyB0aGUgYHRocm93YCBrZXl3b3JkIGluIEphdmFTY3JpcHQuIFRoaXMgYWxzbyBtZWFucyB0aGF0IGlmIHlvdSAiY2F0Y2giIGFuIGVycm9yIHZpYQogICAqIGEgcHJvbWlzZSBlcnJvciBjYWxsYmFjayBhbmQgeW91IHdhbnQgdG8gZm9yd2FyZCB0aGUgZXJyb3IgdG8gdGhlIHByb21pc2UgZGVyaXZlZCBmcm9tIHRoZQogICAqIGN1cnJlbnQgcHJvbWlzZSwgeW91IGhhdmUgdG8gInJldGhyb3ciIHRoZSBlcnJvciBieSByZXR1cm5pbmcgYSByZWplY3Rpb24gY29uc3RydWN0ZWQgdmlhCiAgICogYHJlamVjdGAuCiAgICoKICAgKiBgYGBqcwogICAqICAgcHJvbWlzZUIgPSBwcm9taXNlQS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkgewogICAqICAgICAvLyBzdWNjZXNzOiBkbyBzb21ldGhpbmcgYW5kIHJlc29sdmUgcHJvbWlzZUIKICAgKiAgICAgLy8gICAgICAgICAgd2l0aCB0aGUgb2xkIG9yIGEgbmV3IHJlc3VsdAogICAqICAgICByZXR1cm4gcmVzdWx0OwogICAqICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7CiAgICogICAgIC8vIGVycm9yOiBoYW5kbGUgdGhlIGVycm9yIGlmIHBvc3NpYmxlIGFuZAogICAqICAgICAvLyAgICAgICAgcmVzb2x2ZSBwcm9taXNlQiB3aXRoIG5ld1Byb21pc2VPclZhbHVlLAogICAqICAgICAvLyAgICAgICAgb3RoZXJ3aXNlIGZvcndhcmQgdGhlIHJlamVjdGlvbiB0byBwcm9taXNlQgogICAqICAgICBpZiAoY2FuSGFuZGxlKHJlYXNvbikpIHsKICAgKiAgICAgIC8vIGhhbmRsZSB0aGUgZXJyb3IgYW5kIHJlY292ZXIKICAgKiAgICAgIHJldHVybiBuZXdQcm9taXNlT3JWYWx1ZTsKICAgKiAgICAgfQogICAqICAgICByZXR1cm4gJHEucmVqZWN0KHJlYXNvbik7CiAgICogICB9KTsKICAgKiBgYGAKICAgKgogICAqIEBwYXJhbSB7Kn0gcmVhc29uIENvbnN0YW50LCBtZXNzYWdlLCBleGNlcHRpb24gb3IgYW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcmVqZWN0aW9uIHJlYXNvbi4KICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmV0dXJucyBhIHByb21pc2UgdGhhdCB3YXMgYWxyZWFkeSByZXNvbHZlZCBhcyByZWplY3RlZCB3aXRoIHRoZSBgcmVhc29uYC4KICAgKi8KICB2YXIgcmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7CiAgICB2YXIgcmVzdWx0ID0gbmV3IERlZmVycmVkKCk7CiAgICByZXN1bHQucmVqZWN0KHJlYXNvbik7CiAgICByZXR1cm4gcmVzdWx0LnByb21pc2U7CiAgfTsKCiAgdmFyIG1ha2VQcm9taXNlID0gZnVuY3Rpb24gbWFrZVByb21pc2UodmFsdWUsIHJlc29sdmVkKSB7CiAgICB2YXIgcmVzdWx0ID0gbmV3IERlZmVycmVkKCk7CiAgICBpZiAocmVzb2x2ZWQpIHsKICAgICAgcmVzdWx0LnJlc29sdmUodmFsdWUpOwogICAgfSBlbHNlIHsKICAgICAgcmVzdWx0LnJlamVjdCh2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0LnByb21pc2U7CiAgfTsKCiAgdmFyIGhhbmRsZUNhbGxiYWNrID0gZnVuY3Rpb24gaGFuZGxlQ2FsbGJhY2sodmFsdWUsIGlzUmVzb2x2ZWQsIGNhbGxiYWNrKSB7CiAgICB2YXIgY2FsbGJhY2tPdXRwdXQgPSBudWxsOwogICAgdHJ5IHsKICAgICAgaWYgKGlzRnVuY3Rpb24oY2FsbGJhY2spKSBjYWxsYmFja091dHB1dCA9IGNhbGxiYWNrKCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHJldHVybiBtYWtlUHJvbWlzZShlLCBmYWxzZSk7CiAgICB9CiAgICBpZiAoaXNQcm9taXNlTGlrZShjYWxsYmFja091dHB1dCkpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrT3V0cHV0LnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIG1ha2VQcm9taXNlKHZhbHVlLCBpc1Jlc29sdmVkKTsKICAgICAgfSwgZnVuY3Rpb24oZXJyb3IpIHsKICAgICAgICByZXR1cm4gbWFrZVByb21pc2UoZXJyb3IsIGZhbHNlKTsKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gbWFrZVByb21pc2UodmFsdWUsIGlzUmVzb2x2ZWQpOwogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkcSN3aGVuCiAgICogQGtpbmQgZnVuY3Rpb24KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFdyYXBzIGFuIG9iamVjdCB0aGF0IG1pZ2h0IGJlIGEgdmFsdWUgb3IgYSAoM3JkIHBhcnR5KSB0aGVuLWFibGUgcHJvbWlzZSBpbnRvIGEgJHEgcHJvbWlzZS4KICAgKiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmUgZGVhbGluZyB3aXRoIGFuIG9iamVjdCB0aGF0IG1pZ2h0IG9yIG1pZ2h0IG5vdCBiZSBhIHByb21pc2UsIG9yIGlmCiAgICogdGhlIHByb21pc2UgY29tZXMgZnJvbSBhIHNvdXJjZSB0aGF0IGNhbid0IGJlIHRydXN0ZWQuCiAgICoKICAgKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIG9yIGEgcHJvbWlzZQogICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZXR1cm5zIGEgcHJvbWlzZSBvZiB0aGUgcGFzc2VkIHZhbHVlIG9yIHByb21pc2UKICAgKi8KCgogIHZhciB3aGVuID0gZnVuY3Rpb24odmFsdWUsIGNhbGxiYWNrLCBlcnJiYWNrLCBwcm9ncmVzc0JhY2spIHsKICAgIHZhciByZXN1bHQgPSBuZXcgRGVmZXJyZWQoKTsKICAgIHJlc3VsdC5yZXNvbHZlKHZhbHVlKTsKICAgIHJldHVybiByZXN1bHQucHJvbWlzZS50aGVuKGNhbGxiYWNrLCBlcnJiYWNrLCBwcm9ncmVzc0JhY2spOwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkcSNhbGwKICAgKiBAa2luZCBmdW5jdGlvbgogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ29tYmluZXMgbXVsdGlwbGUgcHJvbWlzZXMgaW50byBhIHNpbmdsZSBwcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgd2hlbiBhbGwgb2YgdGhlIGlucHV0CiAgICogcHJvbWlzZXMgYXJlIHJlc29sdmVkLgogICAqCiAgICogQHBhcmFtIHtBcnJheS48UHJvbWlzZT58T2JqZWN0LjxQcm9taXNlPn0gcHJvbWlzZXMgQW4gYXJyYXkgb3IgaGFzaCBvZiBwcm9taXNlcy4KICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmV0dXJucyBhIHNpbmdsZSBwcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aXRoIGFuIGFycmF5L2hhc2ggb2YgdmFsdWVzLAogICAqICAgZWFjaCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9taXNlIGF0IHRoZSBzYW1lIGluZGV4L2tleSBpbiB0aGUgYHByb21pc2VzYCBhcnJheS9oYXNoLgogICAqICAgSWYgYW55IG9mIHRoZSBwcm9taXNlcyBpcyByZXNvbHZlZCB3aXRoIGEgcmVqZWN0aW9uLCB0aGlzIHJlc3VsdGluZyBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQKICAgKiAgIHdpdGggdGhlIHNhbWUgcmVqZWN0aW9uIHZhbHVlLgogICAqLwoKICBmdW5jdGlvbiBhbGwocHJvbWlzZXMpIHsKICAgIHZhciBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZCgpLAogICAgICAgIGNvdW50ZXIgPSAwLAogICAgICAgIHJlc3VsdHMgPSBpc0FycmF5KHByb21pc2VzKSA/IFtdIDoge307CgogICAgZm9yRWFjaChwcm9taXNlcywgZnVuY3Rpb24ocHJvbWlzZSwga2V5KSB7CiAgICAgIGNvdW50ZXIrKzsKICAgICAgd2hlbihwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgaWYgKHJlc3VsdHMuaGFzT3duUHJvcGVydHkoa2V5KSkgcmV0dXJuOwogICAgICAgIHJlc3VsdHNba2V5XSA9IHZhbHVlOwogICAgICAgIGlmICghKC0tY291bnRlcikpIGRlZmVycmVkLnJlc29sdmUocmVzdWx0cyk7CiAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbikgewogICAgICAgIGlmIChyZXN1bHRzLmhhc093blByb3BlcnR5KGtleSkpIHJldHVybjsKICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVhc29uKTsKICAgICAgfSk7CiAgICB9KTsKCiAgICBpZiAoY291bnRlciA9PT0gMCkgewogICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdHMpOwogICAgfQoKICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlOwogIH0KCiAgdmFyICRRID0gZnVuY3Rpb24gUShyZXNvbHZlcikgewogICAgaWYgKCFpc0Z1bmN0aW9uKHJlc29sdmVyKSkgewogICAgICB0aHJvdyAkcU1pbkVycignbm9yc2x2cicsICJFeHBlY3RlZCByZXNvbHZlckZuLCBnb3QgJ3swfSciLCByZXNvbHZlcik7CiAgICB9CgogICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFEpKSB7CiAgICAgIC8vIE1vcmUgdXNlZnVsIHdoZW4gJFEgaXMgdGhlIFByb21pc2UgaXRzZWxmLgogICAgICByZXR1cm4gbmV3IFEocmVzb2x2ZXIpOwogICAgfQoKICAgIHZhciBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZCgpOwoKICAgIGZ1bmN0aW9uIHJlc29sdmVGbih2YWx1ZSkgewogICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTsKICAgIH0KCiAgICBmdW5jdGlvbiByZWplY3RGbihyZWFzb24pIHsKICAgICAgZGVmZXJyZWQucmVqZWN0KHJlYXNvbik7CiAgICB9CgogICAgcmVzb2x2ZXIocmVzb2x2ZUZuLCByZWplY3RGbik7CgogICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7CiAgfTsKCiAgJFEuZGVmZXIgPSBkZWZlcjsKICAkUS5yZWplY3QgPSByZWplY3Q7CiAgJFEud2hlbiA9IHdoZW47CiAgJFEuYWxsID0gYWxsOwoKICByZXR1cm4gJFE7Cn0KCmZ1bmN0aW9uICQkUkFGUHJvdmlkZXIoKSB7IC8vckFGCiAgdGhpcy4kZ2V0ID0gWyckd2luZG93JywgJyR0aW1lb3V0JywgZnVuY3Rpb24oJHdpbmRvdywgJHRpbWVvdXQpIHsKICAgIHZhciByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSAkd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lOwoKICAgIHZhciBjYW5jZWxBbmltYXRpb25GcmFtZSA9ICR3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3aW5kb3cud2Via2l0Q2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3aW5kb3cud2Via2l0Q2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lOwoKICAgIHZhciByYWZTdXBwb3J0ZWQgPSAhIXJlcXVlc3RBbmltYXRpb25GcmFtZTsKICAgIHZhciByYWYgPSByYWZTdXBwb3J0ZWQKICAgICAgPyBmdW5jdGlvbihmbikgewogICAgICAgICAgdmFyIGlkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZuKTsKICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoaWQpOwogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIDogZnVuY3Rpb24oZm4pIHsKICAgICAgICAgIHZhciB0aW1lciA9ICR0aW1lb3V0KGZuLCAxNi42NiwgZmFsc2UpOyAvLyAxMDAwIC8gNjAgPSAxNi42NjYKICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgJHRpbWVvdXQuY2FuY2VsKHRpbWVyKTsKICAgICAgICAgIH07CiAgICAgICAgfTsKCiAgICByYWYuc3VwcG9ydGVkID0gcmFmU3VwcG9ydGVkOwoKICAgIHJldHVybiByYWY7CiAgfV07Cn0KCi8qKgogKiBERVNJR04gTk9URVMKICoKICogVGhlIGRlc2lnbiBkZWNpc2lvbnMgYmVoaW5kIHRoZSBzY29wZSBhcmUgaGVhdmlseSBmYXZvcmVkIGZvciBzcGVlZCBhbmQgbWVtb3J5IGNvbnN1bXB0aW9uLgogKgogKiBUaGUgdHlwaWNhbCB1c2Ugb2Ygc2NvcGUgaXMgdG8gd2F0Y2ggdGhlIGV4cHJlc3Npb25zLCB3aGljaCBtb3N0IG9mIHRoZSB0aW1lIHJldHVybiB0aGUgc2FtZQogKiB2YWx1ZSBhcyBsYXN0IHRpbWUgc28gd2Ugb3B0aW1pemUgdGhlIG9wZXJhdGlvbi4KICoKICogQ2xvc3VyZXMgY29uc3RydWN0aW9uIGlzIGV4cGVuc2l2ZSBpbiB0ZXJtcyBvZiBzcGVlZCBhcyB3ZWxsIGFzIG1lbW9yeToKICogICAtIE5vIGNsb3N1cmVzLCBpbnN0ZWFkIHVzZSBwcm90b3R5cGljYWwgaW5oZXJpdGFuY2UgZm9yIEFQSQogKiAgIC0gSW50ZXJuYWwgc3RhdGUgbmVlZHMgdG8gYmUgc3RvcmVkIG9uIHNjb3BlIGRpcmVjdGx5LCB3aGljaCBtZWFucyB0aGF0IHByaXZhdGUgc3RhdGUgaXMKICogICAgIGV4cG9zZWQgYXMgJCRfX19fIHByb3BlcnRpZXMKICoKICogTG9vcCBvcGVyYXRpb25zIGFyZSBvcHRpbWl6ZWQgYnkgdXNpbmcgd2hpbGUoY291bnQtLSkgeyAuLi4gfQogKiAgIC0gdGhpcyBtZWFucyB0aGF0IGluIG9yZGVyIHRvIGtlZXAgdGhlIHNhbWUgb3JkZXIgb2YgZXhlY3V0aW9uIGFzIGFkZGl0aW9uIHdlIGhhdmUgdG8gYWRkCiAqICAgICBpdGVtcyB0byB0aGUgYXJyYXkgYXQgdGhlIGJlZ2lubmluZyAodW5zaGlmdCkgaW5zdGVhZCBvZiBhdCB0aGUgZW5kIChwdXNoKQogKgogKiBDaGlsZCBzY29wZXMgYXJlIGNyZWF0ZWQgYW5kIHJlbW92ZWQgb2Z0ZW4KICogICAtIFVzaW5nIGFuIGFycmF5IHdvdWxkIGJlIHNsb3cgc2luY2UgaW5zZXJ0cyBpbiBtaWRkbGUgYXJlIGV4cGVuc2l2ZSBzbyB3ZSB1c2UgbGlua2VkIGxpc3QKICoKICogVGhlcmUgYXJlIGZldyB3YXRjaGVzIHRoZW4gYSBsb3Qgb2Ygb2JzZXJ2ZXJzLiBUaGlzIGlzIHdoeSB5b3UgZG9uJ3Qgd2FudCB0aGUgb2JzZXJ2ZXIgdG8gYmUKICogaW1wbGVtZW50ZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHdhdGNoLiBXYXRjaCByZXF1aXJlcyByZXR1cm4gb2YgaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24gd2hpY2gKICogYXJlIGV4cGVuc2l2ZSB0byBjb25zdHJ1Y3QuCiAqLwoKCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJHJvb3RTY29wZVByb3ZpZGVyCiAqIEBkZXNjcmlwdGlvbgogKgogKiBQcm92aWRlciBmb3IgdGhlICRyb290U2NvcGUgc2VydmljZS4KICovCgovKioKICogQG5nZG9jIG1ldGhvZAogKiBAbmFtZSAkcm9vdFNjb3BlUHJvdmlkZXIjZGlnZXN0VHRsCiAqIEBkZXNjcmlwdGlvbgogKgogKiBTZXRzIHRoZSBudW1iZXIgb2YgYCRkaWdlc3RgIGl0ZXJhdGlvbnMgdGhlIHNjb3BlIHNob3VsZCBhdHRlbXB0IHRvIGV4ZWN1dGUgYmVmb3JlIGdpdmluZyB1cCBhbmQKICogYXNzdW1pbmcgdGhhdCB0aGUgbW9kZWwgaXMgdW5zdGFibGUuCiAqCiAqIFRoZSBjdXJyZW50IGRlZmF1bHQgaXMgMTAgaXRlcmF0aW9ucy4KICoKICogSW4gY29tcGxleCBhcHBsaWNhdGlvbnMgaXQncyBwb3NzaWJsZSB0aGF0IHRoZSBkZXBlbmRlbmNpZXMgYmV0d2VlbiBgJHdhdGNoYHMgd2lsbCByZXN1bHQgaW4KICogc2V2ZXJhbCBkaWdlc3QgaXRlcmF0aW9ucy4gSG93ZXZlciBpZiBhbiBhcHBsaWNhdGlvbiBuZWVkcyBtb3JlIHRoYW4gdGhlIGRlZmF1bHQgMTAgZGlnZXN0CiAqIGl0ZXJhdGlvbnMgZm9yIGl0cyBtb2RlbCB0byBzdGFiaWxpemUgdGhlbiB5b3Ugc2hvdWxkIGludmVzdGlnYXRlIHdoYXQgaXMgY2F1c2luZyB0aGUgbW9kZWwgdG8KICogY29udGludW91c2x5IGNoYW5nZSBkdXJpbmcgdGhlIGRpZ2VzdC4KICoKICogSW5jcmVhc2luZyB0aGUgVFRMIGNvdWxkIGhhdmUgcGVyZm9ybWFuY2UgaW1wbGljYXRpb25zLCBzbyB5b3Ugc2hvdWxkIG5vdCBjaGFuZ2UgaXQgd2l0aG91dAogKiBwcm9wZXIganVzdGlmaWNhdGlvbi4KICoKICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IFRoZSBudW1iZXIgb2YgZGlnZXN0IGl0ZXJhdGlvbnMuCiAqLwoKCi8qKgogKiBAbmdkb2Mgc2VydmljZQogKiBAbmFtZSAkcm9vdFNjb3BlCiAqIEBkZXNjcmlwdGlvbgogKgogKiBFdmVyeSBhcHBsaWNhdGlvbiBoYXMgYSBzaW5nbGUgcm9vdCB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSBzY29wZX0uCiAqIEFsbCBvdGhlciBzY29wZXMgYXJlIGRlc2NlbmRhbnQgc2NvcGVzIG9mIHRoZSByb290IHNjb3BlLiBTY29wZXMgcHJvdmlkZSBzZXBhcmF0aW9uCiAqIGJldHdlZW4gdGhlIG1vZGVsIGFuZCB0aGUgdmlldywgdmlhIGEgbWVjaGFuaXNtIGZvciB3YXRjaGluZyB0aGUgbW9kZWwgZm9yIGNoYW5nZXMuCiAqIFRoZXkgYWxzbyBwcm92aWRlIGFuIGV2ZW50IGVtaXNzaW9uL2Jyb2FkY2FzdCBhbmQgc3Vic2NyaXB0aW9uIGZhY2lsaXR5LiBTZWUgdGhlCiAqIHtAbGluayBndWlkZS9zY29wZSBkZXZlbG9wZXIgZ3VpZGUgb24gc2NvcGVzfS4KICovCmZ1bmN0aW9uICRSb290U2NvcGVQcm92aWRlcigpIHsKICB2YXIgVFRMID0gMTA7CiAgdmFyICRyb290U2NvcGVNaW5FcnIgPSBtaW5FcnIoJyRyb290U2NvcGUnKTsKICB2YXIgbGFzdERpcnR5V2F0Y2ggPSBudWxsOwogIHZhciBhcHBseUFzeW5jSWQgPSBudWxsOwoKICB0aGlzLmRpZ2VzdFR0bCA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkgewogICAgICBUVEwgPSB2YWx1ZTsKICAgIH0KICAgIHJldHVybiBUVEw7CiAgfTsKCiAgdGhpcy4kZ2V0ID0gWyckaW5qZWN0b3InLCAnJGV4Y2VwdGlvbkhhbmRsZXInLCAnJHBhcnNlJywgJyRicm93c2VyJywKICAgICAgZnVuY3Rpb24oJGluamVjdG9yLCAkZXhjZXB0aW9uSGFuZGxlciwgJHBhcnNlLCAkYnJvd3NlcikgewoKICAgIC8qKgogICAgICogQG5nZG9jIHR5cGUKICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIEEgcm9vdCBzY29wZSBjYW4gYmUgcmV0cmlldmVkIHVzaW5nIHRoZSB7QGxpbmsgbmcuJHJvb3RTY29wZSAkcm9vdFNjb3BlfSBrZXkgZnJvbSB0aGUKICAgICAqIHtAbGluayBhdXRvLiRpbmplY3RvciAkaW5qZWN0b3J9LiBDaGlsZCBzY29wZXMgYXJlIGNyZWF0ZWQgdXNpbmcgdGhlCiAgICAgKiB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkbmV3ICRuZXcoKX0gbWV0aG9kLiAoTW9zdCBzY29wZXMgYXJlIGNyZWF0ZWQgYXV0b21hdGljYWxseSB3aGVuCiAgICAgKiBjb21waWxlZCBIVE1MIHRlbXBsYXRlIGlzIGV4ZWN1dGVkLikKICAgICAqCiAgICAgKiBIZXJlIGlzIGEgc2ltcGxlIHNjb3BlIHNuaXBwZXQgdG8gc2hvdyBob3cgeW91IGNhbiBpbnRlcmFjdCB3aXRoIHRoZSBzY29wZS4KICAgICAqIGBgYGh0bWwKICAgICAqIDxmaWxlIHNyYz0iLi90ZXN0L25nL3Jvb3RTY29wZVNwZWMuanMiIHRhZz0iZG9jczEiIC8+CiAgICAgKiBgYGAKICAgICAqCiAgICAgKiAjIEluaGVyaXRhbmNlCiAgICAgKiBBIHNjb3BlIGNhbiBpbmhlcml0IGZyb20gYSBwYXJlbnQgc2NvcGUsIGFzIGluIHRoaXMgZXhhbXBsZToKICAgICAqIGBgYGpzCiAgICAgICAgIHZhciBwYXJlbnQgPSAkcm9vdFNjb3BlOwogICAgICAgICB2YXIgY2hpbGQgPSBwYXJlbnQuJG5ldygpOwoKICAgICAgICAgcGFyZW50LnNhbHV0YXRpb24gPSAiSGVsbG8iOwogICAgICAgICBleHBlY3QoY2hpbGQuc2FsdXRhdGlvbikudG9FcXVhbCgnSGVsbG8nKTsKCiAgICAgICAgIGNoaWxkLnNhbHV0YXRpb24gPSAiV2VsY29tZSI7CiAgICAgICAgIGV4cGVjdChjaGlsZC5zYWx1dGF0aW9uKS50b0VxdWFsKCdXZWxjb21lJyk7CiAgICAgICAgIGV4cGVjdChwYXJlbnQuc2FsdXRhdGlvbikudG9FcXVhbCgnSGVsbG8nKTsKICAgICAqIGBgYAogICAgICoKICAgICAqIFdoZW4gaW50ZXJhY3Rpbmcgd2l0aCBgU2NvcGVgIGluIHRlc3RzLCBhZGRpdGlvbmFsIGhlbHBlciBtZXRob2RzIGFyZSBhdmFpbGFibGUgb24gdGhlCiAgICAgKiBpbnN0YW5jZXMgb2YgYFNjb3BlYCB0eXBlLiBTZWUge0BsaW5rIG5nTW9jay4kcm9vdFNjb3BlLlNjb3BlIG5nTW9jayBTY29wZX0gZm9yIGFkZGl0aW9uYWwKICAgICAqIGRldGFpbHMuCiAgICAgKgogICAgICoKICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsIGZ1bmN0aW9uKCk+PX0gcHJvdmlkZXJzIE1hcCBvZiBzZXJ2aWNlIGZhY3Rvcnkgd2hpY2ggbmVlZCB0byBiZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlZCBmb3IgdGhlIGN1cnJlbnQgc2NvcGUuIERlZmF1bHRzIHRvIHtAbGluayBuZ30uCiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCAqPj19IGluc3RhbmNlQ2FjaGUgUHJvdmlkZXMgcHJlLWluc3RhbnRpYXRlZCBzZXJ2aWNlcyB3aGljaCBzaG91bGQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kL292ZXJyaWRlIHNlcnZpY2VzIHByb3ZpZGVkIGJ5IGBwcm92aWRlcnNgLiBUaGlzIGlzIGhhbmR5CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZW4gdW5pdC10ZXN0aW5nIGFuZCBoYXZpbmcgdGhlIG5lZWQgdG8gb3ZlcnJpZGUgYSBkZWZhdWx0CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2UuCiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBOZXdseSBjcmVhdGVkIHNjb3BlLgogICAgICoKICAgICAqLwogICAgZnVuY3Rpb24gU2NvcGUoKSB7CiAgICAgIHRoaXMuJGlkID0gbmV4dFVpZCgpOwogICAgICB0aGlzLiQkcGhhc2UgPSB0aGlzLiRwYXJlbnQgPSB0aGlzLiQkd2F0Y2hlcnMgPQogICAgICAgICAgICAgICAgICAgICB0aGlzLiQkbmV4dFNpYmxpbmcgPSB0aGlzLiQkcHJldlNpYmxpbmcgPQogICAgICAgICAgICAgICAgICAgICB0aGlzLiQkY2hpbGRIZWFkID0gdGhpcy4kJGNoaWxkVGFpbCA9IG51bGw7CiAgICAgIHRoaXMuJHJvb3QgPSB0aGlzOwogICAgICB0aGlzLiQkZGVzdHJveWVkID0gZmFsc2U7CiAgICAgIHRoaXMuJCRsaXN0ZW5lcnMgPSB7fTsKICAgICAgdGhpcy4kJGxpc3RlbmVyQ291bnQgPSB7fTsKICAgICAgdGhpcy4kJGlzb2xhdGVCaW5kaW5ncyA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAbmdkb2MgcHJvcGVydHkKICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJGlkCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBVbmlxdWUgc2NvcGUgSUQgKG1vbm90b25pY2FsbHkgaW5jcmVhc2luZykgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuCiAgICAgKi8KCiAgICAgLyoqCiAgICAgICogQG5nZG9jIHByb3BlcnR5CiAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkcGFyZW50CiAgICAgICoKICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBzY29wZS4KICAgICAgKi8KCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgcHJvcGVydHkKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkcm9vdAogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogUmVmZXJlbmNlIHRvIHRoZSByb290IHNjb3BlLgogICAgICAgKi8KCiAgICBTY29wZS5wcm90b3R5cGUgPSB7CiAgICAgIGNvbnN0cnVjdG9yOiBTY29wZSwKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkbmV3CiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBDcmVhdGVzIGEgbmV3IGNoaWxkIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIHNjb3BlfS4KICAgICAgICoKICAgICAgICogVGhlIHBhcmVudCBzY29wZSB3aWxsIHByb3BhZ2F0ZSB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0KCl9IGV2ZW50LgogICAgICAgKiBUaGUgc2NvcGUgY2FuIGJlIHJlbW92ZWQgZnJvbSB0aGUgc2NvcGUgaGllcmFyY2h5IHVzaW5nIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRkZXN0cm95ICRkZXN0cm95KCl9LgogICAgICAgKgogICAgICAgKiB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkZGVzdHJveSAkZGVzdHJveSgpfSBtdXN0IGJlIGNhbGxlZCBvbiBhIHNjb3BlIHdoZW4gaXQgaXMKICAgICAgICogZGVzaXJlZCBmb3IgdGhlIHNjb3BlIGFuZCBpdHMgY2hpbGQgc2NvcGVzIHRvIGJlIHBlcm1hbmVudGx5IGRldGFjaGVkIGZyb20gdGhlIHBhcmVudCBhbmQKICAgICAgICogdGh1cyBzdG9wIHBhcnRpY2lwYXRpbmcgaW4gbW9kZWwgY2hhbmdlIGRldGVjdGlvbiBhbmQgbGlzdGVuZXIgbm90aWZpY2F0aW9uIGJ5IGludm9raW5nLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzb2xhdGUgSWYgdHJ1ZSwgdGhlbiB0aGUgc2NvcGUgZG9lcyBub3QgcHJvdG90eXBpY2FsbHkgaW5oZXJpdCBmcm9tIHRoZQogICAgICAgKiAgICAgICAgIHBhcmVudCBzY29wZS4gVGhlIHNjb3BlIGlzIGlzb2xhdGVkLCBhcyBpdCBjYW4gbm90IHNlZSBwYXJlbnQgc2NvcGUgcHJvcGVydGllcy4KICAgICAgICogICAgICAgICBXaGVuIGNyZWF0aW5nIHdpZGdldHMsIGl0IGlzIHVzZWZ1bCBmb3IgdGhlIHdpZGdldCB0byBub3QgYWNjaWRlbnRhbGx5IHJlYWQgcGFyZW50CiAgICAgICAqICAgICAgICAgc3RhdGUuCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7U2NvcGV9IFtwYXJlbnQ9dGhpc10gVGhlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIGBTY29wZWB9IHRoYXQgd2lsbCBiZSB0aGUgYCRwYXJlbnRgCiAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgc2NvcGUuIERlZmF1bHRzIHRvIGB0aGlzYCBzY29wZSBpZiBub3QgcHJvdmlkZWQuCiAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyB1c2VkIHdoZW4gY3JlYXRpbmcgYSB0cmFuc2NsdWRlIHNjb3BlIHRvIGNvcnJlY3RseSBwbGFjZSBpdAogICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBzY29wZSBoaWVyYXJjaHkgd2hpbGUgbWFpbnRhaW5pbmcgdGhlIGNvcnJlY3QgcHJvdG90eXBpY2FsCiAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdGFuY2UuCiAgICAgICAqCiAgICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBuZXdseSBjcmVhdGVkIGNoaWxkIHNjb3BlLgogICAgICAgKgogICAgICAgKi8KICAgICAgJG5ldzogZnVuY3Rpb24oaXNvbGF0ZSwgcGFyZW50KSB7CiAgICAgICAgdmFyIGNoaWxkOwoKICAgICAgICBwYXJlbnQgPSBwYXJlbnQgfHwgdGhpczsKCiAgICAgICAgaWYgKGlzb2xhdGUpIHsKICAgICAgICAgIGNoaWxkID0gbmV3IFNjb3BlKCk7CiAgICAgICAgICBjaGlsZC4kcm9vdCA9IHRoaXMuJHJvb3Q7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIE9ubHkgY3JlYXRlIGEgY2hpbGQgc2NvcGUgY2xhc3MgaWYgc29tZWJvZHkgYXNrcyBmb3Igb25lLAogICAgICAgICAgLy8gYnV0IGNhY2hlIGl0IHRvIGFsbG93IHRoZSBWTSB0byBvcHRpbWl6ZSBsb29rdXBzLgogICAgICAgICAgaWYgKCF0aGlzLiQkQ2hpbGRTY29wZSkgewogICAgICAgICAgICB0aGlzLiQkQ2hpbGRTY29wZSA9IGZ1bmN0aW9uIENoaWxkU2NvcGUoKSB7CiAgICAgICAgICAgICAgdGhpcy4kJHdhdGNoZXJzID0gdGhpcy4kJG5leHRTaWJsaW5nID0KICAgICAgICAgICAgICAgICAgdGhpcy4kJGNoaWxkSGVhZCA9IHRoaXMuJCRjaGlsZFRhaWwgPSBudWxsOwogICAgICAgICAgICAgIHRoaXMuJCRsaXN0ZW5lcnMgPSB7fTsKICAgICAgICAgICAgICB0aGlzLiQkbGlzdGVuZXJDb3VudCA9IHt9OwogICAgICAgICAgICAgIHRoaXMuJGlkID0gbmV4dFVpZCgpOwogICAgICAgICAgICAgIHRoaXMuJCRDaGlsZFNjb3BlID0gbnVsbDsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy4kJENoaWxkU2NvcGUucHJvdG90eXBlID0gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkID0gbmV3IHRoaXMuJCRDaGlsZFNjb3BlKCk7CiAgICAgICAgfQogICAgICAgIGNoaWxkLiRwYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgY2hpbGQuJCRwcmV2U2libGluZyA9IHBhcmVudC4kJGNoaWxkVGFpbDsKICAgICAgICBpZiAocGFyZW50LiQkY2hpbGRIZWFkKSB7CiAgICAgICAgICBwYXJlbnQuJCRjaGlsZFRhaWwuJCRuZXh0U2libGluZyA9IGNoaWxkOwogICAgICAgICAgcGFyZW50LiQkY2hpbGRUYWlsID0gY2hpbGQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBhcmVudC4kJGNoaWxkSGVhZCA9IHBhcmVudC4kJGNoaWxkVGFpbCA9IGNoaWxkOwogICAgICAgIH0KCiAgICAgICAgLy8gV2hlbiB0aGUgbmV3IHNjb3BlIGlzIG5vdCBpc29sYXRlZCBvciB3ZSBpbmhlcml0IGZyb20gYHRoaXNgLCBhbmQKICAgICAgICAvLyB0aGUgcGFyZW50IHNjb3BlIGlzIGRlc3Ryb3llZCwgdGhlIHByb3BlcnR5IGAkJGRlc3Ryb3llZGAgaXMgaW5oZXJpdGVkCiAgICAgICAgLy8gcHJvdG90eXBpY2FsbHkuIEluIGFsbCBvdGhlciBjYXNlcywgdGhpcyBwcm9wZXJ0eSBuZWVkcyB0byBiZSBzZXQKICAgICAgICAvLyB3aGVuIHRoZSBwYXJlbnQgc2NvcGUgaXMgZGVzdHJveWVkLgogICAgICAgIC8vIFRoZSBsaXN0ZW5lciBuZWVkcyB0byBiZSBhZGRlZCBhZnRlciB0aGUgcGFyZW50IGlzIHNldAogICAgICAgIGlmIChpc29sYXRlIHx8IHBhcmVudCAhPSB0aGlzKSBjaGlsZC4kb24oJyRkZXN0cm95JywgZGVzdHJveUNoaWxkKTsKCiAgICAgICAgcmV0dXJuIGNoaWxkOwoKICAgICAgICBmdW5jdGlvbiBkZXN0cm95Q2hpbGQoKSB7CiAgICAgICAgICBjaGlsZC4kJGRlc3Ryb3llZCA9IHRydWU7CiAgICAgICAgfQogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkd2F0Y2gKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIFJlZ2lzdGVycyBhIGBsaXN0ZW5lcmAgY2FsbGJhY2sgdG8gYmUgZXhlY3V0ZWQgd2hlbmV2ZXIgdGhlIGB3YXRjaEV4cHJlc3Npb25gIGNoYW5nZXMuCiAgICAgICAqCiAgICAgICAqIC0gVGhlIGB3YXRjaEV4cHJlc3Npb25gIGlzIGNhbGxlZCBvbiBldmVyeSBjYWxsIHRvIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRkaWdlc3QKICAgICAgICogICAkZGlnZXN0KCl9IGFuZCBzaG91bGQgcmV0dXJuIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgd2F0Y2hlZC4gKFNpbmNlCiAgICAgICAqICAge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0KCl9IHJlcnVucyB3aGVuIGl0IGRldGVjdHMgY2hhbmdlcyB0aGUKICAgICAgICogICBgd2F0Y2hFeHByZXNzaW9uYCBjYW4gZXhlY3V0ZSBtdWx0aXBsZSB0aW1lcyBwZXIKICAgICAgICogICB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkZGlnZXN0ICRkaWdlc3QoKX0gYW5kIHNob3VsZCBiZSBpZGVtcG90ZW50LikKICAgICAgICogLSBUaGUgYGxpc3RlbmVyYCBpcyBjYWxsZWQgb25seSB3aGVuIHRoZSB2YWx1ZSBmcm9tIHRoZSBjdXJyZW50IGB3YXRjaEV4cHJlc3Npb25gIGFuZCB0aGUKICAgICAgICogICBwcmV2aW91cyBjYWxsIHRvIGB3YXRjaEV4cHJlc3Npb25gIGFyZSBub3QgZXF1YWwgKHdpdGggdGhlIGV4Y2VwdGlvbiBvZiB0aGUgaW5pdGlhbCBydW4sCiAgICAgICAqICAgc2VlIGJlbG93KS4gSW5lcXVhbGl0eSBpcyBkZXRlcm1pbmVkIGFjY29yZGluZyB0byByZWZlcmVuY2UgaW5lcXVhbGl0eSwKICAgICAgICogICBbc3RyaWN0IGNvbXBhcmlzb25dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL09wZXJhdG9ycy9Db21wYXJpc29uX09wZXJhdG9ycykKICAgICAgICogICAgdmlhIHRoZSBgIT09YCBKYXZhc2NyaXB0IG9wZXJhdG9yLCB1bmxlc3MgYG9iamVjdEVxdWFsaXR5ID09IHRydWVgCiAgICAgICAqICAgKHNlZSBuZXh0IHBvaW50KQogICAgICAgKiAtIFdoZW4gYG9iamVjdEVxdWFsaXR5ID09IHRydWVgLCBpbmVxdWFsaXR5IG9mIHRoZSBgd2F0Y2hFeHByZXNzaW9uYCBpcyBkZXRlcm1pbmVkCiAgICAgICAqICAgYWNjb3JkaW5nIHRvIHRoZSB7QGxpbmsgYW5ndWxhci5lcXVhbHN9IGZ1bmN0aW9uLiBUbyBzYXZlIHRoZSB2YWx1ZSBvZiB0aGUgb2JqZWN0IGZvcgogICAgICAgKiAgIGxhdGVyIGNvbXBhcmlzb24sIHRoZSB7QGxpbmsgYW5ndWxhci5jb3B5fSBmdW5jdGlvbiBpcyB1c2VkLiBUaGlzIHRoZXJlZm9yZSBtZWFucyB0aGF0CiAgICAgICAqICAgd2F0Y2hpbmcgY29tcGxleCBvYmplY3RzIHdpbGwgaGF2ZSBhZHZlcnNlIG1lbW9yeSBhbmQgcGVyZm9ybWFuY2UgaW1wbGljYXRpb25zLgogICAgICAgKiAtIFRoZSB3YXRjaCBgbGlzdGVuZXJgIG1heSBjaGFuZ2UgdGhlIG1vZGVsLCB3aGljaCBtYXkgdHJpZ2dlciBvdGhlciBgbGlzdGVuZXJgcyB0byBmaXJlLgogICAgICAgKiAgIFRoaXMgaXMgYWNoaWV2ZWQgYnkgcmVydW5uaW5nIHRoZSB3YXRjaGVycyB1bnRpbCBubyBjaGFuZ2VzIGFyZSBkZXRlY3RlZC4gVGhlIHJlcnVuCiAgICAgICAqICAgaXRlcmF0aW9uIGxpbWl0IGlzIDEwIHRvIHByZXZlbnQgYW4gaW5maW5pdGUgbG9vcCBkZWFkbG9jay4KICAgICAgICoKICAgICAgICoKICAgICAgICogSWYgeW91IHdhbnQgdG8gYmUgbm90aWZpZWQgd2hlbmV2ZXIge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0fSBpcyBjYWxsZWQsCiAgICAgICAqIHlvdSBjYW4gcmVnaXN0ZXIgYSBgd2F0Y2hFeHByZXNzaW9uYCBmdW5jdGlvbiB3aXRoIG5vIGBsaXN0ZW5lcmAuIChTaW5jZSBgd2F0Y2hFeHByZXNzaW9uYAogICAgICAgKiBjYW4gZXhlY3V0ZSBtdWx0aXBsZSB0aW1lcyBwZXIge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0fSBjeWNsZSB3aGVuIGEKICAgICAgICogY2hhbmdlIGlzIGRldGVjdGVkLCBiZSBwcmVwYXJlZCBmb3IgbXVsdGlwbGUgY2FsbHMgdG8geW91ciBsaXN0ZW5lci4pCiAgICAgICAqCiAgICAgICAqIEFmdGVyIGEgd2F0Y2hlciBpcyByZWdpc3RlcmVkIHdpdGggdGhlIHNjb3BlLCB0aGUgYGxpc3RlbmVyYCBmbiBpcyBjYWxsZWQgYXN5bmNocm9ub3VzbHkKICAgICAgICogKHZpYSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkZXZhbEFzeW5jICRldmFsQXN5bmN9KSB0byBpbml0aWFsaXplIHRoZQogICAgICAgKiB3YXRjaGVyLiBJbiByYXJlIGNhc2VzLCB0aGlzIGlzIHVuZGVzaXJhYmxlIGJlY2F1c2UgdGhlIGxpc3RlbmVyIGlzIGNhbGxlZCB3aGVuIHRoZSByZXN1bHQKICAgICAgICogb2YgYHdhdGNoRXhwcmVzc2lvbmAgZGlkbid0IGNoYW5nZS4gVG8gZGV0ZWN0IHRoaXMgc2NlbmFyaW8gd2l0aGluIHRoZSBgbGlzdGVuZXJgIGZuLCB5b3UKICAgICAgICogY2FuIGNvbXBhcmUgdGhlIGBuZXdWYWxgIGFuZCBgb2xkVmFsYC4gSWYgdGhlc2UgdHdvIHZhbHVlcyBhcmUgaWRlbnRpY2FsIChgPT09YCkgdGhlbiB0aGUKICAgICAgICogbGlzdGVuZXIgd2FzIGNhbGxlZCBkdWUgdG8gaW5pdGlhbGl6YXRpb24uCiAgICAgICAqCiAgICAgICAqCiAgICAgICAqCiAgICAgICAqICMgRXhhbXBsZQogICAgICAgKiBgYGBqcwogICAgICAgICAgIC8vIGxldCdzIGFzc3VtZSB0aGF0IHNjb3BlIHdhcyBkZXBlbmRlbmN5IGluamVjdGVkIGFzIHRoZSAkcm9vdFNjb3BlCiAgICAgICAgICAgdmFyIHNjb3BlID0gJHJvb3RTY29wZTsKICAgICAgICAgICBzY29wZS5uYW1lID0gJ21pc2tvJzsKICAgICAgICAgICBzY29wZS5jb3VudGVyID0gMDsKCiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmNvdW50ZXIpLnRvRXF1YWwoMCk7CiAgICAgICAgICAgc2NvcGUuJHdhdGNoKCduYW1lJywgZnVuY3Rpb24obmV3VmFsdWUsIG9sZFZhbHVlKSB7CiAgICAgICAgICAgICBzY29wZS5jb3VudGVyID0gc2NvcGUuY291bnRlciArIDE7CiAgICAgICAgICAgfSk7CiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmNvdW50ZXIpLnRvRXF1YWwoMCk7CgogICAgICAgICAgIHNjb3BlLiRkaWdlc3QoKTsKICAgICAgICAgICAvLyB0aGUgbGlzdGVuZXIgaXMgYWx3YXlzIGNhbGxlZCBkdXJpbmcgdGhlIGZpcnN0ICRkaWdlc3QgbG9vcCBhZnRlciBpdCB3YXMgcmVnaXN0ZXJlZAogICAgICAgICAgIGV4cGVjdChzY29wZS5jb3VudGVyKS50b0VxdWFsKDEpOwoKICAgICAgICAgICBzY29wZS4kZGlnZXN0KCk7CiAgICAgICAgICAgLy8gYnV0IG5vdyBpdCB3aWxsIG5vdCBiZSBjYWxsZWQgdW5sZXNzIHRoZSB2YWx1ZSBjaGFuZ2VzCiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmNvdW50ZXIpLnRvRXF1YWwoMSk7CgogICAgICAgICAgIHNjb3BlLm5hbWUgPSAnYWRhbSc7CiAgICAgICAgICAgc2NvcGUuJGRpZ2VzdCgpOwogICAgICAgICAgIGV4cGVjdChzY29wZS5jb3VudGVyKS50b0VxdWFsKDIpOwoKCgogICAgICAgICAgIC8vIFVzaW5nIGEgZnVuY3Rpb24gYXMgYSB3YXRjaEV4cHJlc3Npb24KICAgICAgICAgICB2YXIgZm9vZDsKICAgICAgICAgICBzY29wZS5mb29kQ291bnRlciA9IDA7CiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmZvb2RDb3VudGVyKS50b0VxdWFsKDApOwogICAgICAgICAgIHNjb3BlLiR3YXRjaCgKICAgICAgICAgICAgIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgdmFsdWUgYmVpbmcgd2F0Y2hlZC4gSXQgaXMgY2FsbGVkIGZvciBlYWNoIHR1cm4gb2YgdGhlICRkaWdlc3QgbG9vcAogICAgICAgICAgICAgZnVuY3Rpb24oKSB7IHJldHVybiBmb29kOyB9LAogICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgY2hhbmdlIGxpc3RlbmVyLCBjYWxsZWQgd2hlbiB0aGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB0aGUgYWJvdmUgZnVuY3Rpb24gY2hhbmdlcwogICAgICAgICAgICAgZnVuY3Rpb24obmV3VmFsdWUsIG9sZFZhbHVlKSB7CiAgICAgICAgICAgICAgIGlmICggbmV3VmFsdWUgIT09IG9sZFZhbHVlICkgewogICAgICAgICAgICAgICAgIC8vIE9ubHkgaW5jcmVtZW50IHRoZSBjb3VudGVyIGlmIHRoZSB2YWx1ZSBjaGFuZ2VkCiAgICAgICAgICAgICAgICAgc2NvcGUuZm9vZENvdW50ZXIgPSBzY29wZS5mb29kQ291bnRlciArIDE7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICApOwogICAgICAgICAgIC8vIE5vIGRpZ2VzdCBoYXMgYmVlbiBydW4gc28gdGhlIGNvdW50ZXIgd2lsbCBiZSB6ZXJvCiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmZvb2RDb3VudGVyKS50b0VxdWFsKDApOwoKICAgICAgICAgICAvLyBSdW4gdGhlIGRpZ2VzdCBidXQgc2luY2UgZm9vZCBoYXMgbm90IGNoYW5nZWQgY291bnQgd2lsbCBzdGlsbCBiZSB6ZXJvCiAgICAgICAgICAgc2NvcGUuJGRpZ2VzdCgpOwogICAgICAgICAgIGV4cGVjdChzY29wZS5mb29kQ291bnRlcikudG9FcXVhbCgwKTsKCiAgICAgICAgICAgLy8gVXBkYXRlIGZvb2QgYW5kIHJ1biBkaWdlc3QuICBOb3cgdGhlIGNvdW50ZXIgd2lsbCBpbmNyZW1lbnQKICAgICAgICAgICBmb29kID0gJ2NoZWVzZWJ1cmdlcic7CiAgICAgICAgICAgc2NvcGUuJGRpZ2VzdCgpOwogICAgICAgICAgIGV4cGVjdChzY29wZS5mb29kQ291bnRlcikudG9FcXVhbCgxKTsKCiAgICAgICAqIGBgYAogICAgICAgKgogICAgICAgKgogICAgICAgKgogICAgICAgKiBAcGFyYW0geyhmdW5jdGlvbigpfHN0cmluZyl9IHdhdGNoRXhwcmVzc2lvbiBFeHByZXNzaW9uIHRoYXQgaXMgZXZhbHVhdGVkIG9uIGVhY2gKICAgICAgICogICAge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0fSBjeWNsZS4gQSBjaGFuZ2UgaW4gdGhlIHJldHVybiB2YWx1ZSB0cmlnZ2VycwogICAgICAgKiAgICBhIGNhbGwgdG8gdGhlIGBsaXN0ZW5lcmAuCiAgICAgICAqCiAgICAgICAqICAgIC0gYHN0cmluZ2A6IEV2YWx1YXRlZCBhcyB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufQogICAgICAgKiAgICAtIGBmdW5jdGlvbihzY29wZSlgOiBjYWxsZWQgd2l0aCBjdXJyZW50IGBzY29wZWAgYXMgYSBwYXJhbWV0ZXIuCiAgICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24obmV3VmFsLCBvbGRWYWwsIHNjb3BlKX0gbGlzdGVuZXIgQ2FsbGJhY2sgY2FsbGVkIHdoZW5ldmVyIHRoZSB2YWx1ZQogICAgICAgKiAgICBvZiBgd2F0Y2hFeHByZXNzaW9uYCBjaGFuZ2VzLgogICAgICAgKgogICAgICAgKiAgICAtIGBuZXdWYWxgIGNvbnRhaW5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBgd2F0Y2hFeHByZXNzaW9uYAogICAgICAgKiAgICAtIGBvbGRWYWxgIGNvbnRhaW5zIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiB0aGUgYHdhdGNoRXhwcmVzc2lvbmAKICAgICAgICogICAgLSBgc2NvcGVgIHJlZmVycyB0byB0aGUgY3VycmVudCBzY29wZQogICAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvYmplY3RFcXVhbGl0eSBDb21wYXJlIGZvciBvYmplY3QgZXF1YWxpdHkgdXNpbmcge0BsaW5rIGFuZ3VsYXIuZXF1YWxzfSBpbnN0ZWFkIG9mCiAgICAgICAqICAgICBjb21wYXJpbmcgZm9yIHJlZmVyZW5jZSBlcXVhbGl0eS4KICAgICAgICogQHJldHVybnMge2Z1bmN0aW9uKCl9IFJldHVybnMgYSBkZXJlZ2lzdHJhdGlvbiBmdW5jdGlvbiBmb3IgdGhpcyBsaXN0ZW5lci4KICAgICAgICovCiAgICAgICR3YXRjaDogZnVuY3Rpb24od2F0Y2hFeHAsIGxpc3RlbmVyLCBvYmplY3RFcXVhbGl0eSkgewogICAgICAgIHZhciBnZXQgPSAkcGFyc2Uod2F0Y2hFeHApOwoKICAgICAgICBpZiAoZ2V0LiQkd2F0Y2hEZWxlZ2F0ZSkgewogICAgICAgICAgcmV0dXJuIGdldC4kJHdhdGNoRGVsZWdhdGUodGhpcywgbGlzdGVuZXIsIG9iamVjdEVxdWFsaXR5LCBnZXQpOwogICAgICAgIH0KICAgICAgICB2YXIgc2NvcGUgPSB0aGlzLAogICAgICAgICAgICBhcnJheSA9IHNjb3BlLiQkd2F0Y2hlcnMsCiAgICAgICAgICAgIHdhdGNoZXIgPSB7CiAgICAgICAgICAgICAgZm46IGxpc3RlbmVyLAogICAgICAgICAgICAgIGxhc3Q6IGluaXRXYXRjaFZhbCwKICAgICAgICAgICAgICBnZXQ6IGdldCwKICAgICAgICAgICAgICBleHA6IHdhdGNoRXhwLAogICAgICAgICAgICAgIGVxOiAhIW9iamVjdEVxdWFsaXR5CiAgICAgICAgICAgIH07CgogICAgICAgIGxhc3REaXJ0eVdhdGNoID0gbnVsbDsKCiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSkgewogICAgICAgICAgd2F0Y2hlci5mbiA9IG5vb3A7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWFycmF5KSB7CiAgICAgICAgICBhcnJheSA9IHNjb3BlLiQkd2F0Y2hlcnMgPSBbXTsKICAgICAgICB9CiAgICAgICAgLy8gd2UgdXNlIHVuc2hpZnQgc2luY2Ugd2UgdXNlIGEgd2hpbGUgbG9vcCBpbiAkZGlnZXN0IGZvciBzcGVlZC4KICAgICAgICAvLyB0aGUgd2hpbGUgbG9vcCByZWFkcyBpbiByZXZlcnNlIG9yZGVyLgogICAgICAgIGFycmF5LnVuc2hpZnQod2F0Y2hlcik7CgogICAgICAgIHJldHVybiBmdW5jdGlvbiBkZXJlZ2lzdGVyV2F0Y2goKSB7CiAgICAgICAgICBhcnJheVJlbW92ZShhcnJheSwgd2F0Y2hlcik7CiAgICAgICAgICBsYXN0RGlydHlXYXRjaCA9IG51bGw7CiAgICAgICAgfTsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJHdhdGNoR3JvdXAKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIEEgdmFyaWFudCBvZiB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkd2F0Y2ggJHdhdGNoKCl9IHdoZXJlIGl0IHdhdGNoZXMgYW4gYXJyYXkgb2YgYHdhdGNoRXhwcmVzc2lvbnNgLgogICAgICAgKiBJZiBhbnkgb25lIGV4cHJlc3Npb24gaW4gdGhlIGNvbGxlY3Rpb24gY2hhbmdlcyB0aGUgYGxpc3RlbmVyYCBpcyBleGVjdXRlZC4KICAgICAgICoKICAgICAgICogLSBUaGUgaXRlbXMgaW4gdGhlIGB3YXRjaEV4cHJlc3Npb25zYCBhcnJheSBhcmUgb2JzZXJ2ZWQgdmlhIHN0YW5kYXJkICR3YXRjaCBvcGVyYXRpb24gYW5kIGFyZSBleGFtaW5lZCBvbiBldmVyeQogICAgICAgKiAgIGNhbGwgdG8gJGRpZ2VzdCgpIHRvIHNlZSBpZiBhbnkgaXRlbXMgY2hhbmdlcy4KICAgICAgICogLSBUaGUgYGxpc3RlbmVyYCBpcyBjYWxsZWQgd2hlbmV2ZXIgYW55IGV4cHJlc3Npb24gaW4gdGhlIGB3YXRjaEV4cHJlc3Npb25zYCBhcnJheSBjaGFuZ2VzLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge0FycmF5LjxzdHJpbmd8RnVuY3Rpb24oc2NvcGUpPn0gd2F0Y2hFeHByZXNzaW9ucyBBcnJheSBvZiBleHByZXNzaW9ucyB0aGF0IHdpbGwgYmUgaW5kaXZpZHVhbGx5CiAgICAgICAqIHdhdGNoZWQgdXNpbmcge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJHdhdGNoICR3YXRjaCgpfQogICAgICAgKgogICAgICAgKiBAcGFyYW0ge2Z1bmN0aW9uKG5ld1ZhbHVlcywgb2xkVmFsdWVzLCBzY29wZSl9IGxpc3RlbmVyIENhbGxiYWNrIGNhbGxlZCB3aGVuZXZlciB0aGUgcmV0dXJuIHZhbHVlIG9mIGFueQogICAgICAgKiAgICBleHByZXNzaW9uIGluIGB3YXRjaEV4cHJlc3Npb25zYCBjaGFuZ2VzCiAgICAgICAqICAgIFRoZSBgbmV3VmFsdWVzYCBhcnJheSBjb250YWlucyB0aGUgY3VycmVudCB2YWx1ZXMgb2YgdGhlIGB3YXRjaEV4cHJlc3Npb25zYCwgd2l0aCB0aGUgaW5kZXhlcyBtYXRjaGluZwogICAgICAgKiAgICB0aG9zZSBvZiBgd2F0Y2hFeHByZXNzaW9uYAogICAgICAgKiAgICBhbmQgdGhlIGBvbGRWYWx1ZXNgIGFycmF5IGNvbnRhaW5zIHRoZSBwcmV2aW91cyB2YWx1ZXMgb2YgdGhlIGB3YXRjaEV4cHJlc3Npb25zYCwgd2l0aCB0aGUgaW5kZXhlcyBtYXRjaGluZwogICAgICAgKiAgICB0aG9zZSBvZiBgd2F0Y2hFeHByZXNzaW9uYAogICAgICAgKiAgICBUaGUgYHNjb3BlYCByZWZlcnMgdG8gdGhlIGN1cnJlbnQgc2NvcGUuCiAgICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbigpfSBSZXR1cm5zIGEgZGUtcmVnaXN0cmF0aW9uIGZ1bmN0aW9uIGZvciBhbGwgbGlzdGVuZXJzLgogICAgICAgKi8KICAgICAgJHdhdGNoR3JvdXA6IGZ1bmN0aW9uKHdhdGNoRXhwcmVzc2lvbnMsIGxpc3RlbmVyKSB7CiAgICAgICAgdmFyIG9sZFZhbHVlcyA9IG5ldyBBcnJheSh3YXRjaEV4cHJlc3Npb25zLmxlbmd0aCk7CiAgICAgICAgdmFyIG5ld1ZhbHVlcyA9IG5ldyBBcnJheSh3YXRjaEV4cHJlc3Npb25zLmxlbmd0aCk7CiAgICAgICAgdmFyIGRlcmVnaXN0ZXJGbnMgPSBbXTsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgdmFyIGNoYW5nZVJlYWN0aW9uU2NoZWR1bGVkID0gZmFsc2U7CiAgICAgICAgdmFyIGZpcnN0UnVuID0gdHJ1ZTsKCiAgICAgICAgaWYgKCF3YXRjaEV4cHJlc3Npb25zLmxlbmd0aCkgewogICAgICAgICAgLy8gTm8gZXhwcmVzc2lvbnMgbWVhbnMgd2UgY2FsbCB0aGUgbGlzdGVuZXIgQVNBUAogICAgICAgICAgdmFyIHNob3VsZENhbGwgPSB0cnVlOwogICAgICAgICAgc2VsZi4kZXZhbEFzeW5jKGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAoc2hvdWxkQ2FsbCkgbGlzdGVuZXIobmV3VmFsdWVzLCBuZXdWYWx1ZXMsIHNlbGYpOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gZGVyZWdpc3RlcldhdGNoR3JvdXAoKSB7CiAgICAgICAgICAgIHNob3VsZENhbGwgPSBmYWxzZTsKICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBpZiAod2F0Y2hFeHByZXNzaW9ucy5sZW5ndGggPT09IDEpIHsKICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBzaXplIG9mIG9uZQogICAgICAgICAgcmV0dXJuIHRoaXMuJHdhdGNoKHdhdGNoRXhwcmVzc2lvbnNbMF0sIGZ1bmN0aW9uIHdhdGNoR3JvdXBBY3Rpb24odmFsdWUsIG9sZFZhbHVlLCBzY29wZSkgewogICAgICAgICAgICBuZXdWYWx1ZXNbMF0gPSB2YWx1ZTsKICAgICAgICAgICAgb2xkVmFsdWVzWzBdID0gb2xkVmFsdWU7CiAgICAgICAgICAgIGxpc3RlbmVyKG5ld1ZhbHVlcywgKHZhbHVlID09PSBvbGRWYWx1ZSkgPyBuZXdWYWx1ZXMgOiBvbGRWYWx1ZXMsIHNjb3BlKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZm9yRWFjaCh3YXRjaEV4cHJlc3Npb25zLCBmdW5jdGlvbihleHByLCBpKSB7CiAgICAgICAgICB2YXIgdW53YXRjaEZuID0gc2VsZi4kd2F0Y2goZXhwciwgZnVuY3Rpb24gd2F0Y2hHcm91cFN1YkFjdGlvbih2YWx1ZSwgb2xkVmFsdWUpIHsKICAgICAgICAgICAgbmV3VmFsdWVzW2ldID0gdmFsdWU7CiAgICAgICAgICAgIG9sZFZhbHVlc1tpXSA9IG9sZFZhbHVlOwogICAgICAgICAgICBpZiAoIWNoYW5nZVJlYWN0aW9uU2NoZWR1bGVkKSB7CiAgICAgICAgICAgICAgY2hhbmdlUmVhY3Rpb25TY2hlZHVsZWQgPSB0cnVlOwogICAgICAgICAgICAgIHNlbGYuJGV2YWxBc3luYyh3YXRjaEdyb3VwQWN0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBkZXJlZ2lzdGVyRm5zLnB1c2godW53YXRjaEZuKTsKICAgICAgICB9KTsKCiAgICAgICAgZnVuY3Rpb24gd2F0Y2hHcm91cEFjdGlvbigpIHsKICAgICAgICAgIGNoYW5nZVJlYWN0aW9uU2NoZWR1bGVkID0gZmFsc2U7CgogICAgICAgICAgaWYgKGZpcnN0UnVuKSB7CiAgICAgICAgICAgIGZpcnN0UnVuID0gZmFsc2U7CiAgICAgICAgICAgIGxpc3RlbmVyKG5ld1ZhbHVlcywgbmV3VmFsdWVzLCBzZWxmKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxpc3RlbmVyKG5ld1ZhbHVlcywgb2xkVmFsdWVzLCBzZWxmKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmdW5jdGlvbiBkZXJlZ2lzdGVyV2F0Y2hHcm91cCgpIHsKICAgICAgICAgIHdoaWxlIChkZXJlZ2lzdGVyRm5zLmxlbmd0aCkgewogICAgICAgICAgICBkZXJlZ2lzdGVyRm5zLnNoaWZ0KCkoKTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICB9LAoKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJHdhdGNoQ29sbGVjdGlvbgogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogU2hhbGxvdyB3YXRjaGVzIHRoZSBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBhbmQgZmlyZXMgd2hlbmV2ZXIgYW55IG9mIHRoZSBwcm9wZXJ0aWVzIGNoYW5nZQogICAgICAgKiAoZm9yIGFycmF5cywgdGhpcyBpbXBsaWVzIHdhdGNoaW5nIHRoZSBhcnJheSBpdGVtczsgZm9yIG9iamVjdCBtYXBzLCB0aGlzIGltcGxpZXMgd2F0Y2hpbmcKICAgICAgICogdGhlIHByb3BlcnRpZXMpLiBJZiBhIGNoYW5nZSBpcyBkZXRlY3RlZCwgdGhlIGBsaXN0ZW5lcmAgY2FsbGJhY2sgaXMgZmlyZWQuCiAgICAgICAqCiAgICAgICAqIC0gVGhlIGBvYmpgIGNvbGxlY3Rpb24gaXMgb2JzZXJ2ZWQgdmlhIHN0YW5kYXJkICR3YXRjaCBvcGVyYXRpb24gYW5kIGlzIGV4YW1pbmVkIG9uIGV2ZXJ5CiAgICAgICAqICAgY2FsbCB0byAkZGlnZXN0KCkgdG8gc2VlIGlmIGFueSBpdGVtcyBoYXZlIGJlZW4gYWRkZWQsIHJlbW92ZWQsIG9yIG1vdmVkLgogICAgICAgKiAtIFRoZSBgbGlzdGVuZXJgIGlzIGNhbGxlZCB3aGVuZXZlciBhbnl0aGluZyB3aXRoaW4gdGhlIGBvYmpgIGhhcyBjaGFuZ2VkLiBFeGFtcGxlcyBpbmNsdWRlCiAgICAgICAqICAgYWRkaW5nLCByZW1vdmluZywgYW5kIG1vdmluZyBpdGVtcyBiZWxvbmdpbmcgdG8gYW4gb2JqZWN0IG9yIGFycmF5LgogICAgICAgKgogICAgICAgKgogICAgICAgKiAjIEV4YW1wbGUKICAgICAgICogYGBganMKICAgICAgICAgICRzY29wZS5uYW1lcyA9IFsnaWdvcicsICdtYXRpYXMnLCAnbWlza28nLCAnamFtZXMnXTsKICAgICAgICAgICRzY29wZS5kYXRhQ291bnQgPSA0OwoKICAgICAgICAgICRzY29wZS4kd2F0Y2hDb2xsZWN0aW9uKCduYW1lcycsIGZ1bmN0aW9uKG5ld05hbWVzLCBvbGROYW1lcykgewogICAgICAgICAgICAkc2NvcGUuZGF0YUNvdW50ID0gbmV3TmFtZXMubGVuZ3RoOwogICAgICAgICAgfSk7CgogICAgICAgICAgZXhwZWN0KCRzY29wZS5kYXRhQ291bnQpLnRvRXF1YWwoNCk7CiAgICAgICAgICAkc2NvcGUuJGRpZ2VzdCgpOwoKICAgICAgICAgIC8vc3RpbGwgYXQgNCAuLi4gbm8gY2hhbmdlcwogICAgICAgICAgZXhwZWN0KCRzY29wZS5kYXRhQ291bnQpLnRvRXF1YWwoNCk7CgogICAgICAgICAgJHNjb3BlLm5hbWVzLnBvcCgpOwogICAgICAgICAgJHNjb3BlLiRkaWdlc3QoKTsKCiAgICAgICAgICAvL25vdyB0aGVyZSdzIGJlZW4gYSBjaGFuZ2UKICAgICAgICAgIGV4cGVjdCgkc2NvcGUuZGF0YUNvdW50KS50b0VxdWFsKDMpOwogICAgICAgKiBgYGAKICAgICAgICoKICAgICAgICoKICAgICAgICogQHBhcmFtIHtzdHJpbmd8ZnVuY3Rpb24oc2NvcGUpfSBvYmogRXZhbHVhdGVkIGFzIHtAbGluayBndWlkZS9leHByZXNzaW9uIGV4cHJlc3Npb259LiBUaGUKICAgICAgICogICAgZXhwcmVzc2lvbiB2YWx1ZSBzaG91bGQgZXZhbHVhdGUgdG8gYW4gb2JqZWN0IG9yIGFuIGFycmF5IHdoaWNoIGlzIG9ic2VydmVkIG9uIGVhY2gKICAgICAgICogICAge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0fSBjeWNsZS4gQW55IHNoYWxsb3cgY2hhbmdlIHdpdGhpbiB0aGUKICAgICAgICogICAgY29sbGVjdGlvbiB3aWxsIHRyaWdnZXIgYSBjYWxsIHRvIHRoZSBgbGlzdGVuZXJgLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge2Z1bmN0aW9uKG5ld0NvbGxlY3Rpb24sIG9sZENvbGxlY3Rpb24sIHNjb3BlKX0gbGlzdGVuZXIgYSBjYWxsYmFjayBmdW5jdGlvbiBjYWxsZWQKICAgICAgICogICAgd2hlbiBhIGNoYW5nZSBpcyBkZXRlY3RlZC4KICAgICAgICogICAgLSBUaGUgYG5ld0NvbGxlY3Rpb25gIG9iamVjdCBpcyB0aGUgbmV3bHkgbW9kaWZpZWQgZGF0YSBvYnRhaW5lZCBmcm9tIHRoZSBgb2JqYCBleHByZXNzaW9uCiAgICAgICAqICAgIC0gVGhlIGBvbGRDb2xsZWN0aW9uYCBvYmplY3QgaXMgYSBjb3B5IG9mIHRoZSBmb3JtZXIgY29sbGVjdGlvbiBkYXRhLgogICAgICAgKiAgICAgIER1ZSB0byBwZXJmb3JtYW5jZSBjb25zaWRlcmF0aW9ucywgdGhlYG9sZENvbGxlY3Rpb25gIHZhbHVlIGlzIGNvbXB1dGVkIG9ubHkgaWYgdGhlCiAgICAgICAqICAgICAgYGxpc3RlbmVyYCBmdW5jdGlvbiBkZWNsYXJlcyB0d28gb3IgbW9yZSBhcmd1bWVudHMuCiAgICAgICAqICAgIC0gVGhlIGBzY29wZWAgYXJndW1lbnQgcmVmZXJzIHRvIHRoZSBjdXJyZW50IHNjb3BlLgogICAgICAgKgogICAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oKX0gUmV0dXJucyBhIGRlLXJlZ2lzdHJhdGlvbiBmdW5jdGlvbiBmb3IgdGhpcyBsaXN0ZW5lci4gV2hlbiB0aGUKICAgICAgICogICAgZGUtcmVnaXN0cmF0aW9uIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkLCB0aGUgaW50ZXJuYWwgd2F0Y2ggb3BlcmF0aW9uIGlzIHRlcm1pbmF0ZWQuCiAgICAgICAqLwogICAgICAkd2F0Y2hDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmosIGxpc3RlbmVyKSB7CiAgICAgICAgJHdhdGNoQ29sbGVjdGlvbkludGVyY2VwdG9yLiRzdGF0ZWZ1bCA9IHRydWU7CgogICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICAvLyB0aGUgY3VycmVudCB2YWx1ZSwgdXBkYXRlZCBvbiBlYWNoIGRpcnR5LWNoZWNrIHJ1bgogICAgICAgIHZhciBuZXdWYWx1ZTsKICAgICAgICAvLyBhIHNoYWxsb3cgY29weSBvZiB0aGUgbmV3VmFsdWUgZnJvbSB0aGUgbGFzdCBkaXJ0eS1jaGVjayBydW4sCiAgICAgICAgLy8gdXBkYXRlZCB0byBtYXRjaCBuZXdWYWx1ZSBkdXJpbmcgZGlydHktY2hlY2sgcnVuCiAgICAgICAgdmFyIG9sZFZhbHVlOwogICAgICAgIC8vIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBuZXdWYWx1ZSBmcm9tIHdoZW4gdGhlIGxhc3QgY2hhbmdlIGhhcHBlbmVkCiAgICAgICAgdmFyIHZlcnlPbGRWYWx1ZTsKICAgICAgICAvLyBvbmx5IHRyYWNrIHZlcnlPbGRWYWx1ZSBpZiB0aGUgbGlzdGVuZXIgaXMgYXNraW5nIGZvciBpdAogICAgICAgIHZhciB0cmFja1ZlcnlPbGRWYWx1ZSA9IChsaXN0ZW5lci5sZW5ndGggPiAxKTsKICAgICAgICB2YXIgY2hhbmdlRGV0ZWN0ZWQgPSAwOwogICAgICAgIHZhciBjaGFuZ2VEZXRlY3RvciA9ICRwYXJzZShvYmosICR3YXRjaENvbGxlY3Rpb25JbnRlcmNlcHRvcik7CiAgICAgICAgdmFyIGludGVybmFsQXJyYXkgPSBbXTsKICAgICAgICB2YXIgaW50ZXJuYWxPYmplY3QgPSB7fTsKICAgICAgICB2YXIgaW5pdFJ1biA9IHRydWU7CiAgICAgICAgdmFyIG9sZExlbmd0aCA9IDA7CgogICAgICAgIGZ1bmN0aW9uICR3YXRjaENvbGxlY3Rpb25JbnRlcmNlcHRvcihfdmFsdWUpIHsKICAgICAgICAgIG5ld1ZhbHVlID0gX3ZhbHVlOwogICAgICAgICAgdmFyIG5ld0xlbmd0aCwga2V5LCBib3RoTmFOLCBuZXdJdGVtLCBvbGRJdGVtOwoKICAgICAgICAgIC8vIElmIHRoZSBuZXcgdmFsdWUgaXMgdW5kZWZpbmVkLCB0aGVuIHJldHVybiB1bmRlZmluZWQgYXMgdGhlIHdhdGNoIG1heSBiZSBhIG9uZS10aW1lIHdhdGNoCiAgICAgICAgICBpZiAoaXNVbmRlZmluZWQobmV3VmFsdWUpKSByZXR1cm47CgogICAgICAgICAgaWYgKCFpc09iamVjdChuZXdWYWx1ZSkpIHsgLy8gaWYgcHJpbWl0aXZlCiAgICAgICAgICAgIGlmIChvbGRWYWx1ZSAhPT0gbmV3VmFsdWUpIHsKICAgICAgICAgICAgICBvbGRWYWx1ZSA9IG5ld1ZhbHVlOwogICAgICAgICAgICAgIGNoYW5nZURldGVjdGVkKys7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheUxpa2UobmV3VmFsdWUpKSB7CiAgICAgICAgICAgIGlmIChvbGRWYWx1ZSAhPT0gaW50ZXJuYWxBcnJheSkgewogICAgICAgICAgICAgIC8vIHdlIGFyZSB0cmFuc2l0aW9uaW5nIGZyb20gc29tZXRoaW5nIHdoaWNoIHdhcyBub3QgYW4gYXJyYXkgaW50byBhcnJheS4KICAgICAgICAgICAgICBvbGRWYWx1ZSA9IGludGVybmFsQXJyYXk7CiAgICAgICAgICAgICAgb2xkTGVuZ3RoID0gb2xkVmFsdWUubGVuZ3RoID0gMDsKICAgICAgICAgICAgICBjaGFuZ2VEZXRlY3RlZCsrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBuZXdMZW5ndGggPSBuZXdWYWx1ZS5sZW5ndGg7CgogICAgICAgICAgICBpZiAob2xkTGVuZ3RoICE9PSBuZXdMZW5ndGgpIHsKICAgICAgICAgICAgICAvLyBpZiBsZW5ndGhzIGRvIG5vdCBtYXRjaCB3ZSBuZWVkIHRvIHRyaWdnZXIgY2hhbmdlIG5vdGlmaWNhdGlvbgogICAgICAgICAgICAgIGNoYW5nZURldGVjdGVkKys7CiAgICAgICAgICAgICAgb2xkVmFsdWUubGVuZ3RoID0gb2xkTGVuZ3RoID0gbmV3TGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNvcHkgdGhlIGl0ZW1zIHRvIG9sZFZhbHVlIGFuZCBsb29rIGZvciBjaGFuZ2VzLgogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld0xlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgb2xkSXRlbSA9IG9sZFZhbHVlW2ldOwogICAgICAgICAgICAgIG5ld0l0ZW0gPSBuZXdWYWx1ZVtpXTsKCiAgICAgICAgICAgICAgYm90aE5hTiA9IChvbGRJdGVtICE9PSBvbGRJdGVtKSAmJiAobmV3SXRlbSAhPT0gbmV3SXRlbSk7CiAgICAgICAgICAgICAgaWYgKCFib3RoTmFOICYmIChvbGRJdGVtICE9PSBuZXdJdGVtKSkgewogICAgICAgICAgICAgICAgY2hhbmdlRGV0ZWN0ZWQrKzsKICAgICAgICAgICAgICAgIG9sZFZhbHVlW2ldID0gbmV3SXRlbTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChvbGRWYWx1ZSAhPT0gaW50ZXJuYWxPYmplY3QpIHsKICAgICAgICAgICAgICAvLyB3ZSBhcmUgdHJhbnNpdGlvbmluZyBmcm9tIHNvbWV0aGluZyB3aGljaCB3YXMgbm90IGFuIG9iamVjdCBpbnRvIG9iamVjdC4KICAgICAgICAgICAgICBvbGRWYWx1ZSA9IGludGVybmFsT2JqZWN0ID0ge307CiAgICAgICAgICAgICAgb2xkTGVuZ3RoID0gMDsKICAgICAgICAgICAgICBjaGFuZ2VEZXRlY3RlZCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNvcHkgdGhlIGl0ZW1zIHRvIG9sZFZhbHVlIGFuZCBsb29rIGZvciBjaGFuZ2VzLgogICAgICAgICAgICBuZXdMZW5ndGggPSAwOwogICAgICAgICAgICBmb3IgKGtleSBpbiBuZXdWYWx1ZSkgewogICAgICAgICAgICAgIGlmIChuZXdWYWx1ZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CiAgICAgICAgICAgICAgICBuZXdMZW5ndGgrKzsKICAgICAgICAgICAgICAgIG5ld0l0ZW0gPSBuZXdWYWx1ZVtrZXldOwogICAgICAgICAgICAgICAgb2xkSXRlbSA9IG9sZFZhbHVlW2tleV07CgogICAgICAgICAgICAgICAgaWYgKGtleSBpbiBvbGRWYWx1ZSkgewogICAgICAgICAgICAgICAgICBib3RoTmFOID0gKG9sZEl0ZW0gIT09IG9sZEl0ZW0pICYmIChuZXdJdGVtICE9PSBuZXdJdGVtKTsKICAgICAgICAgICAgICAgICAgaWYgKCFib3RoTmFOICYmIChvbGRJdGVtICE9PSBuZXdJdGVtKSkgewogICAgICAgICAgICAgICAgICAgIGNoYW5nZURldGVjdGVkKys7CiAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWVba2V5XSA9IG5ld0l0ZW07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIG9sZExlbmd0aCsrOwogICAgICAgICAgICAgICAgICBvbGRWYWx1ZVtrZXldID0gbmV3SXRlbTsKICAgICAgICAgICAgICAgICAgY2hhbmdlRGV0ZWN0ZWQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9sZExlbmd0aCA+IG5ld0xlbmd0aCkgewogICAgICAgICAgICAgIC8vIHdlIHVzZWQgdG8gaGF2ZSBtb3JlIGtleXMsIG5lZWQgdG8gZmluZCB0aGVtIGFuZCBkZXN0cm95IHRoZW0uCiAgICAgICAgICAgICAgY2hhbmdlRGV0ZWN0ZWQrKzsKICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvbGRWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKCFuZXdWYWx1ZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CiAgICAgICAgICAgICAgICAgIG9sZExlbmd0aC0tOwogICAgICAgICAgICAgICAgICBkZWxldGUgb2xkVmFsdWVba2V5XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBjaGFuZ2VEZXRlY3RlZDsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uICR3YXRjaENvbGxlY3Rpb25BY3Rpb24oKSB7CiAgICAgICAgICBpZiAoaW5pdFJ1bikgewogICAgICAgICAgICBpbml0UnVuID0gZmFsc2U7CiAgICAgICAgICAgIGxpc3RlbmVyKG5ld1ZhbHVlLCBuZXdWYWx1ZSwgc2VsZik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsaXN0ZW5lcihuZXdWYWx1ZSwgdmVyeU9sZFZhbHVlLCBzZWxmKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBtYWtlIGEgY29weSBmb3IgdGhlIG5leHQgdGltZSBhIGNvbGxlY3Rpb24gaXMgY2hhbmdlZAogICAgICAgICAgaWYgKHRyYWNrVmVyeU9sZFZhbHVlKSB7CiAgICAgICAgICAgIGlmICghaXNPYmplY3QobmV3VmFsdWUpKSB7CiAgICAgICAgICAgICAgLy9wcmltaXRpdmUKICAgICAgICAgICAgICB2ZXJ5T2xkVmFsdWUgPSBuZXdWYWx1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5TGlrZShuZXdWYWx1ZSkpIHsKICAgICAgICAgICAgICB2ZXJ5T2xkVmFsdWUgPSBuZXcgQXJyYXkobmV3VmFsdWUubGVuZ3RoKTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld1ZhbHVlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2ZXJ5T2xkVmFsdWVbaV0gPSBuZXdWYWx1ZVtpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGlmIG9iamVjdAogICAgICAgICAgICAgIHZlcnlPbGRWYWx1ZSA9IHt9OwogICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBuZXdWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwobmV3VmFsdWUsIGtleSkpIHsKICAgICAgICAgICAgICAgICAgdmVyeU9sZFZhbHVlW2tleV0gPSBuZXdWYWx1ZVtrZXldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRoaXMuJHdhdGNoKGNoYW5nZURldGVjdG9yLCAkd2F0Y2hDb2xsZWN0aW9uQWN0aW9uKTsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdAogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogUHJvY2Vzc2VzIGFsbCBvZiB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJHdhdGNoIHdhdGNoZXJzfSBvZiB0aGUgY3VycmVudCBzY29wZSBhbmQKICAgICAgICogaXRzIGNoaWxkcmVuLiBCZWNhdXNlIGEge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJHdhdGNoIHdhdGNoZXJ9J3MgbGlzdGVuZXIgY2FuIGNoYW5nZQogICAgICAgKiB0aGUgbW9kZWwsIHRoZSBgJGRpZ2VzdCgpYCBrZWVwcyBjYWxsaW5nIHRoZSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkd2F0Y2ggd2F0Y2hlcnN9CiAgICAgICAqIHVudGlsIG5vIG1vcmUgbGlzdGVuZXJzIGFyZSBmaXJpbmcuIFRoaXMgbWVhbnMgdGhhdCBpdCBpcyBwb3NzaWJsZSB0byBnZXQgaW50byBhbiBpbmZpbml0ZQogICAgICAgKiBsb29wLiBUaGlzIGZ1bmN0aW9uIHdpbGwgdGhyb3cgYCdNYXhpbXVtIGl0ZXJhdGlvbiBsaW1pdCBleGNlZWRlZC4nYCBpZiB0aGUgbnVtYmVyIG9mCiAgICAgICAqIGl0ZXJhdGlvbnMgZXhjZWVkcyAxMC4KICAgICAgICoKICAgICAgICogVXN1YWxseSwgeW91IGRvbid0IGNhbGwgYCRkaWdlc3QoKWAgZGlyZWN0bHkgaW4KICAgICAgICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ0NvbnRyb2xsZXIgY29udHJvbGxlcnN9IG9yIGluCiAgICAgICAqIHtAbGluayBuZy4kY29tcGlsZVByb3ZpZGVyI2RpcmVjdGl2ZSBkaXJlY3RpdmVzfS4KICAgICAgICogSW5zdGVhZCwgeW91IHNob3VsZCBjYWxsIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRhcHBseSAkYXBwbHkoKX0gKHR5cGljYWxseSBmcm9tIHdpdGhpbgogICAgICAgKiBhIHtAbGluayBuZy4kY29tcGlsZVByb3ZpZGVyI2RpcmVjdGl2ZSBkaXJlY3RpdmV9KSwgd2hpY2ggd2lsbCBmb3JjZSBhIGAkZGlnZXN0KClgLgogICAgICAgKgogICAgICAgKiBJZiB5b3Ugd2FudCB0byBiZSBub3RpZmllZCB3aGVuZXZlciBgJGRpZ2VzdCgpYCBpcyBjYWxsZWQsCiAgICAgICAqIHlvdSBjYW4gcmVnaXN0ZXIgYSBgd2F0Y2hFeHByZXNzaW9uYCBmdW5jdGlvbiB3aXRoCiAgICAgICAqIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyR3YXRjaCAkd2F0Y2goKX0gd2l0aCBubyBgbGlzdGVuZXJgLgogICAgICAgKgogICAgICAgKiBJbiB1bml0IHRlc3RzLCB5b3UgbWF5IG5lZWQgdG8gY2FsbCBgJGRpZ2VzdCgpYCB0byBzaW11bGF0ZSB0aGUgc2NvcGUgbGlmZSBjeWNsZS4KICAgICAgICoKICAgICAgICogIyBFeGFtcGxlCiAgICAgICAqIGBgYGpzCiAgICAgICAgICAgdmFyIHNjb3BlID0gLi4uOwogICAgICAgICAgIHNjb3BlLm5hbWUgPSAnbWlza28nOwogICAgICAgICAgIHNjb3BlLmNvdW50ZXIgPSAwOwoKICAgICAgICAgICBleHBlY3Qoc2NvcGUuY291bnRlcikudG9FcXVhbCgwKTsKICAgICAgICAgICBzY29wZS4kd2F0Y2goJ25hbWUnLCBmdW5jdGlvbihuZXdWYWx1ZSwgb2xkVmFsdWUpIHsKICAgICAgICAgICAgIHNjb3BlLmNvdW50ZXIgPSBzY29wZS5jb3VudGVyICsgMTsKICAgICAgICAgICB9KTsKICAgICAgICAgICBleHBlY3Qoc2NvcGUuY291bnRlcikudG9FcXVhbCgwKTsKCiAgICAgICAgICAgc2NvcGUuJGRpZ2VzdCgpOwogICAgICAgICAgIC8vIHRoZSBsaXN0ZW5lciBpcyBhbHdheXMgY2FsbGVkIGR1cmluZyB0aGUgZmlyc3QgJGRpZ2VzdCBsb29wIGFmdGVyIGl0IHdhcyByZWdpc3RlcmVkCiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmNvdW50ZXIpLnRvRXF1YWwoMSk7CgogICAgICAgICAgIHNjb3BlLiRkaWdlc3QoKTsKICAgICAgICAgICAvLyBidXQgbm93IGl0IHdpbGwgbm90IGJlIGNhbGxlZCB1bmxlc3MgdGhlIHZhbHVlIGNoYW5nZXMKICAgICAgICAgICBleHBlY3Qoc2NvcGUuY291bnRlcikudG9FcXVhbCgxKTsKCiAgICAgICAgICAgc2NvcGUubmFtZSA9ICdhZGFtJzsKICAgICAgICAgICBzY29wZS4kZGlnZXN0KCk7CiAgICAgICAgICAgZXhwZWN0KHNjb3BlLmNvdW50ZXIpLnRvRXF1YWwoMik7CiAgICAgICAqIGBgYAogICAgICAgKgogICAgICAgKi8KICAgICAgJGRpZ2VzdDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHdhdGNoLCB2YWx1ZSwgbGFzdCwKICAgICAgICAgICAgd2F0Y2hlcnMsCiAgICAgICAgICAgIGxlbmd0aCwKICAgICAgICAgICAgZGlydHksIHR0bCA9IFRUTCwKICAgICAgICAgICAgbmV4dCwgY3VycmVudCwgdGFyZ2V0ID0gdGhpcywKICAgICAgICAgICAgd2F0Y2hMb2cgPSBbXSwKICAgICAgICAgICAgbG9nSWR4LCBsb2dNc2csIGFzeW5jVGFzazsKCiAgICAgICAgYmVnaW5QaGFzZSgnJGRpZ2VzdCcpOwogICAgICAgIC8vIENoZWNrIGZvciBjaGFuZ2VzIHRvIGJyb3dzZXIgdXJsIHRoYXQgaGFwcGVuZWQgaW4gc3luYyBiZWZvcmUgdGhlIGNhbGwgdG8gJGRpZ2VzdAogICAgICAgICRicm93c2VyLiQkY2hlY2tVcmxDaGFuZ2UoKTsKCiAgICAgICAgaWYgKHRoaXMgPT09ICRyb290U2NvcGUgJiYgYXBwbHlBc3luY0lkICE9PSBudWxsKSB7CiAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IHNjb3BlLCBhbmQgJGFwcGx5QXN5bmMgaGFzIHNjaGVkdWxlZCBhIGRlZmVycmVkICRhcHBseSgpLCB0aGVuCiAgICAgICAgICAvLyBjYW5jZWwgdGhlIHNjaGVkdWxlZCAkYXBwbHkgYW5kIGZsdXNoIHRoZSBxdWV1ZSBvZiBleHByZXNzaW9ucyB0byBiZSBldmFsdWF0ZWQuCiAgICAgICAgICAkYnJvd3Nlci5kZWZlci5jYW5jZWwoYXBwbHlBc3luY0lkKTsKICAgICAgICAgIGZsdXNoQXBwbHlBc3luYygpOwogICAgICAgIH0KCiAgICAgICAgbGFzdERpcnR5V2F0Y2ggPSBudWxsOwoKICAgICAgICBkbyB7IC8vICJ3aGlsZSBkaXJ0eSIgbG9vcAogICAgICAgICAgZGlydHkgPSBmYWxzZTsKICAgICAgICAgIGN1cnJlbnQgPSB0YXJnZXQ7CgogICAgICAgICAgd2hpbGUgKGFzeW5jUXVldWUubGVuZ3RoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYXN5bmNUYXNrID0gYXN5bmNRdWV1ZS5zaGlmdCgpOwogICAgICAgICAgICAgIGFzeW5jVGFzay5zY29wZS4kZXZhbChhc3luY1Rhc2suZXhwcmVzc2lvbiwgYXN5bmNUYXNrLmxvY2Fscyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAkZXhjZXB0aW9uSGFuZGxlcihlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0RGlydHlXYXRjaCA9IG51bGw7CiAgICAgICAgICB9CgogICAgICAgICAgdHJhdmVyc2VTY29wZXNMb29wOgogICAgICAgICAgZG8geyAvLyAidHJhdmVyc2UgdGhlIHNjb3BlcyIgbG9vcAogICAgICAgICAgICBpZiAoKHdhdGNoZXJzID0gY3VycmVudC4kJHdhdGNoZXJzKSkgewogICAgICAgICAgICAgIC8vIHByb2Nlc3Mgb3VyIHdhdGNoZXMKICAgICAgICAgICAgICBsZW5ndGggPSB3YXRjaGVycy5sZW5ndGg7CiAgICAgICAgICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICB3YXRjaCA9IHdhdGNoZXJzW2xlbmd0aF07CiAgICAgICAgICAgICAgICAgIC8vIE1vc3QgY29tbW9uIHdhdGNoZXMgYXJlIG9uIHByaW1pdGl2ZXMsIGluIHdoaWNoIGNhc2Ugd2UgY2FuIHNob3J0CiAgICAgICAgICAgICAgICAgIC8vIGNpcmN1aXQgaXQgd2l0aCA9PT0gb3BlcmF0b3IsIG9ubHkgd2hlbiA9PT0gZmFpbHMgZG8gd2UgdXNlIC5lcXVhbHMKICAgICAgICAgICAgICAgICAgaWYgKHdhdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCh2YWx1ZSA9IHdhdGNoLmdldChjdXJyZW50KSkgIT09IChsYXN0ID0gd2F0Y2gubGFzdCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgISh3YXRjaC5lcQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBlcXVhbHModmFsdWUsIGxhc3QpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHR5cGVvZiBsYXN0ID09PSAnbnVtYmVyJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgaXNOYU4odmFsdWUpICYmIGlzTmFOKGxhc3QpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgIGxhc3REaXJ0eVdhdGNoID0gd2F0Y2g7CiAgICAgICAgICAgICAgICAgICAgICB3YXRjaC5sYXN0ID0gd2F0Y2guZXEgPyBjb3B5KHZhbHVlLCBudWxsKSA6IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgd2F0Y2guZm4odmFsdWUsICgobGFzdCA9PT0gaW5pdFdhdGNoVmFsKSA/IHZhbHVlIDogbGFzdCksIGN1cnJlbnQpOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHR0bCA8IDUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nSWR4ID0gNCAtIHR0bDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3YXRjaExvZ1tsb2dJZHhdKSB3YXRjaExvZ1tsb2dJZHhdID0gW107CiAgICAgICAgICAgICAgICAgICAgICAgIHdhdGNoTG9nW2xvZ0lkeF0ucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnOiBpc0Z1bmN0aW9uKHdhdGNoLmV4cCkgPyAnZm46ICcgKyAod2F0Y2guZXhwLm5hbWUgfHwgd2F0Y2guZXhwLnRvU3RyaW5nKCkpIDogd2F0Y2guZXhwLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbDogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsOiBsYXN0CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2F0Y2ggPT09IGxhc3REaXJ0eVdhdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbW9zdCByZWNlbnRseSBkaXJ0eSB3YXRjaGVyIGlzIG5vdyBjbGVhbiwgc2hvcnQgY2lyY3VpdCBzaW5jZSB0aGUgcmVtYWluaW5nIHdhdGNoZXJzCiAgICAgICAgICAgICAgICAgICAgICAvLyBoYXZlIGFscmVhZHkgYmVlbiB0ZXN0ZWQuCiAgICAgICAgICAgICAgICAgICAgICBkaXJ0eSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgYnJlYWsgdHJhdmVyc2VTY29wZXNMb29wOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAkZXhjZXB0aW9uSGFuZGxlcihlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEluc2FuaXR5IFdhcm5pbmc6IHNjb3BlIGRlcHRoLWZpcnN0IHRyYXZlcnNhbAogICAgICAgICAgICAvLyB5ZXMsIHRoaXMgY29kZSBpcyBhIGJpdCBjcmF6eSwgYnV0IGl0IHdvcmtzIGFuZCB3ZSBoYXZlIHRlc3RzIHRvIHByb3ZlIGl0IQogICAgICAgICAgICAvLyB0aGlzIHBpZWNlIHNob3VsZCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgdHJhdmVyc2FsIGluICRicm9hZGNhc3QKICAgICAgICAgICAgaWYgKCEobmV4dCA9IChjdXJyZW50LiQkY2hpbGRIZWFkIHx8CiAgICAgICAgICAgICAgICAoY3VycmVudCAhPT0gdGFyZ2V0ICYmIGN1cnJlbnQuJCRuZXh0U2libGluZykpKSkgewogICAgICAgICAgICAgIHdoaWxlIChjdXJyZW50ICE9PSB0YXJnZXQgJiYgIShuZXh0ID0gY3VycmVudC4kJG5leHRTaWJsaW5nKSkgewogICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuJHBhcmVudDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gd2hpbGUgKChjdXJyZW50ID0gbmV4dCkpOwoKICAgICAgICAgIC8vIGBicmVhayB0cmF2ZXJzZVNjb3Blc0xvb3A7YCB0YWtlcyB1cyB0byBoZXJlCgogICAgICAgICAgaWYgKChkaXJ0eSB8fCBhc3luY1F1ZXVlLmxlbmd0aCkgJiYgISh0dGwtLSkpIHsKICAgICAgICAgICAgY2xlYXJQaGFzZSgpOwogICAgICAgICAgICB0aHJvdyAkcm9vdFNjb3BlTWluRXJyKCdpbmZkaWcnLAogICAgICAgICAgICAgICAgJ3swfSAkZGlnZXN0KCkgaXRlcmF0aW9ucyByZWFjaGVkLiBBYm9ydGluZyFcbicgKwogICAgICAgICAgICAgICAgJ1dhdGNoZXJzIGZpcmVkIGluIHRoZSBsYXN0IDUgaXRlcmF0aW9uczogezF9JywKICAgICAgICAgICAgICAgIFRUTCwgd2F0Y2hMb2cpOwogICAgICAgICAgfQoKICAgICAgICB9IHdoaWxlIChkaXJ0eSB8fCBhc3luY1F1ZXVlLmxlbmd0aCk7CgogICAgICAgIGNsZWFyUGhhc2UoKTsKCiAgICAgICAgd2hpbGUgKHBvc3REaWdlc3RRdWV1ZS5sZW5ndGgpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIHBvc3REaWdlc3RRdWV1ZS5zaGlmdCgpKCk7CiAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKCgogICAgICAvKioKICAgICAgICogQG5nZG9jIGV2ZW50CiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJGRlc3Ryb3kKICAgICAgICogQGV2ZW50VHlwZSBicm9hZGNhc3Qgb24gc2NvcGUgYmVpbmcgZGVzdHJveWVkCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBCcm9hZGNhc3RlZCB3aGVuIGEgc2NvcGUgYW5kIGl0cyBjaGlsZHJlbiBhcmUgYmVpbmcgZGVzdHJveWVkLgogICAgICAgKgogICAgICAgKiBOb3RlIHRoYXQsIGluIEFuZ3VsYXJKUywgdGhlcmUgaXMgYWxzbyBhIGAkZGVzdHJveWAgalF1ZXJ5IGV2ZW50LCB3aGljaCBjYW4gYmUgdXNlZCB0bwogICAgICAgKiBjbGVhbiB1cCBET00gYmluZGluZ3MgYmVmb3JlIGFuIGVsZW1lbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBET00uCiAgICAgICAqLwoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkZGVzdHJveQogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogUmVtb3ZlcyB0aGUgY3VycmVudCBzY29wZSAoYW5kIGFsbCBvZiBpdHMgY2hpbGRyZW4pIGZyb20gdGhlIHBhcmVudCBzY29wZS4gUmVtb3ZhbCBpbXBsaWVzCiAgICAgICAqIHRoYXQgY2FsbHMgdG8ge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCAkZGlnZXN0KCl9IHdpbGwgbm8gbG9uZ2VyCiAgICAgICAqIHByb3BhZ2F0ZSB0byB0aGUgY3VycmVudCBzY29wZSBhbmQgaXRzIGNoaWxkcmVuLiBSZW1vdmFsIGFsc28gaW1wbGllcyB0aGF0IHRoZSBjdXJyZW50CiAgICAgICAqIHNjb3BlIGlzIGVsaWdpYmxlIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24uCiAgICAgICAqCiAgICAgICAqIFRoZSBgJGRlc3Ryb3koKWAgaXMgdXN1YWxseSB1c2VkIGJ5IGRpcmVjdGl2ZXMgc3VjaCBhcwogICAgICAgKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nUmVwZWF0IG5nUmVwZWF0fSBmb3IgbWFuYWdpbmcgdGhlCiAgICAgICAqIHVucm9sbGluZyBvZiB0aGUgbG9vcC4KICAgICAgICoKICAgICAgICogSnVzdCBiZWZvcmUgYSBzY29wZSBpcyBkZXN0cm95ZWQsIGEgYCRkZXN0cm95YCBldmVudCBpcyBicm9hZGNhc3RlZCBvbiB0aGlzIHNjb3BlLgogICAgICAgKiBBcHBsaWNhdGlvbiBjb2RlIGNhbiByZWdpc3RlciBhIGAkZGVzdHJveWAgZXZlbnQgaGFuZGxlciB0aGF0IHdpbGwgZ2l2ZSBpdCBhIGNoYW5jZSB0bwogICAgICAgKiBwZXJmb3JtIGFueSBuZWNlc3NhcnkgY2xlYW51cC4KICAgICAgICoKICAgICAgICogTm90ZSB0aGF0LCBpbiBBbmd1bGFySlMsIHRoZXJlIGlzIGFsc28gYSBgJGRlc3Ryb3lgIGpRdWVyeSBldmVudCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8KICAgICAgICogY2xlYW4gdXAgRE9NIGJpbmRpbmdzIGJlZm9yZSBhbiBlbGVtZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLgogICAgICAgKi8KICAgICAgJGRlc3Ryb3k6IGZ1bmN0aW9uKCkgewogICAgICAgIC8vIHdlIGNhbid0IGRlc3Ryb3kgdGhlIHJvb3Qgc2NvcGUgb3IgYSBzY29wZSB0aGF0IGhhcyBiZWVuIGFscmVhZHkgZGVzdHJveWVkCiAgICAgICAgaWYgKHRoaXMuJCRkZXN0cm95ZWQpIHJldHVybjsKICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy4kcGFyZW50OwoKICAgICAgICB0aGlzLiRicm9hZGNhc3QoJyRkZXN0cm95Jyk7CiAgICAgICAgdGhpcy4kJGRlc3Ryb3llZCA9IHRydWU7CiAgICAgICAgaWYgKHRoaXMgPT09ICRyb290U2NvcGUpIHJldHVybjsKCiAgICAgICAgZm9yICh2YXIgZXZlbnROYW1lIGluIHRoaXMuJCRsaXN0ZW5lckNvdW50KSB7CiAgICAgICAgICBkZWNyZW1lbnRMaXN0ZW5lckNvdW50KHRoaXMsIHRoaXMuJCRsaXN0ZW5lckNvdW50W2V2ZW50TmFtZV0sIGV2ZW50TmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBzZXZlciBhbGwgdGhlIHJlZmVyZW5jZXMgdG8gcGFyZW50IHNjb3BlcyAoYWZ0ZXIgdGhpcyBjbGVhbnVwLCB0aGUgY3VycmVudCBzY29wZSBzaG91bGQKICAgICAgICAvLyBub3QgYmUgcmV0YWluZWQgYnkgYW55IG9mIG91ciByZWZlcmVuY2VzIGFuZCBzaG91bGQgYmUgZWxpZ2libGUgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbikKICAgICAgICBpZiAocGFyZW50LiQkY2hpbGRIZWFkID09IHRoaXMpIHBhcmVudC4kJGNoaWxkSGVhZCA9IHRoaXMuJCRuZXh0U2libGluZzsKICAgICAgICBpZiAocGFyZW50LiQkY2hpbGRUYWlsID09IHRoaXMpIHBhcmVudC4kJGNoaWxkVGFpbCA9IHRoaXMuJCRwcmV2U2libGluZzsKICAgICAgICBpZiAodGhpcy4kJHByZXZTaWJsaW5nKSB0aGlzLiQkcHJldlNpYmxpbmcuJCRuZXh0U2libGluZyA9IHRoaXMuJCRuZXh0U2libGluZzsKICAgICAgICBpZiAodGhpcy4kJG5leHRTaWJsaW5nKSB0aGlzLiQkbmV4dFNpYmxpbmcuJCRwcmV2U2libGluZyA9IHRoaXMuJCRwcmV2U2libGluZzsKCiAgICAgICAgLy8gRGlzYWJsZSBsaXN0ZW5lcnMsIHdhdGNoZXJzIGFuZCBhcHBseS9kaWdlc3QgbWV0aG9kcwogICAgICAgIHRoaXMuJGRlc3Ryb3kgPSB0aGlzLiRkaWdlc3QgPSB0aGlzLiRhcHBseSA9IHRoaXMuJGV2YWxBc3luYyA9IHRoaXMuJGFwcGx5QXN5bmMgPSBub29wOwogICAgICAgIHRoaXMuJG9uID0gdGhpcy4kd2F0Y2ggPSB0aGlzLiR3YXRjaEdyb3VwID0gZnVuY3Rpb24oKSB7IHJldHVybiBub29wOyB9OwogICAgICAgIHRoaXMuJCRsaXN0ZW5lcnMgPSB7fTsKCiAgICAgICAgLy8gQWxsIG9mIHRoZSBjb2RlIGJlbG93IGlzIGJvZ3VzIGNvZGUgdGhhdCB3b3JrcyBhcm91bmQgVjgncyBtZW1vcnkgbGVhayB2aWEgb3B0aW1pemVkIGNvZGUKICAgICAgICAvLyBhbmQgaW5saW5lIGNhY2hlcy4KICAgICAgICAvLwogICAgICAgIC8vIHNlZToKICAgICAgICAvLyAtIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDczI2MyNgogICAgICAgIC8vIC0gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9pc3N1ZXMvNjc5NCNpc3N1ZWNvbW1lbnQtMzg2NDg5MDkKICAgICAgICAvLyAtIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvaXNzdWVzLzEzMTMjaXNzdWVjb21tZW50LTEwMzc4NDUxCgogICAgICAgIHRoaXMuJHBhcmVudCA9IHRoaXMuJCRuZXh0U2libGluZyA9IHRoaXMuJCRwcmV2U2libGluZyA9IHRoaXMuJCRjaGlsZEhlYWQgPQogICAgICAgICAgICB0aGlzLiQkY2hpbGRUYWlsID0gdGhpcy4kcm9vdCA9IHRoaXMuJCR3YXRjaGVycyA9IG51bGw7CiAgICAgIH0sCgogICAgICAvKioKICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgKiBAbmFtZSAkcm9vdFNjb3BlLlNjb3BlIyRldmFsCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBFeGVjdXRlcyB0aGUgYGV4cHJlc3Npb25gIG9uIHRoZSBjdXJyZW50IHNjb3BlIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuIEFueSBleGNlcHRpb25zIGluCiAgICAgICAqIHRoZSBleHByZXNzaW9uIGFyZSBwcm9wYWdhdGVkICh1bmNhdWdodCkuIFRoaXMgaXMgdXNlZnVsIHdoZW4gZXZhbHVhdGluZyBBbmd1bGFyCiAgICAgICAqIGV4cHJlc3Npb25zLgogICAgICAgKgogICAgICAgKiAjIEV4YW1wbGUKICAgICAgICogYGBganMKICAgICAgICAgICB2YXIgc2NvcGUgPSBuZy4kcm9vdFNjb3BlLlNjb3BlKCk7CiAgICAgICAgICAgc2NvcGUuYSA9IDE7CiAgICAgICAgICAgc2NvcGUuYiA9IDI7CgogICAgICAgICAgIGV4cGVjdChzY29wZS4kZXZhbCgnYStiJykpLnRvRXF1YWwoMyk7CiAgICAgICAgICAgZXhwZWN0KHNjb3BlLiRldmFsKGZ1bmN0aW9uKHNjb3BlKXsgcmV0dXJuIHNjb3BlLmEgKyBzY29wZS5iOyB9KSkudG9FcXVhbCgzKTsKICAgICAgICogYGBgCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7KHN0cmluZ3xmdW5jdGlvbigpKT19IGV4cHJlc3Npb24gQW4gYW5ndWxhciBleHByZXNzaW9uIHRvIGJlIGV4ZWN1dGVkLgogICAgICAgKgogICAgICAgKiAgICAtIGBzdHJpbmdgOiBleGVjdXRlIHVzaW5nIHRoZSBydWxlcyBhcyBkZWZpbmVkIGluICB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufS4KICAgICAgICogICAgLSBgZnVuY3Rpb24oc2NvcGUpYDogZXhlY3V0ZSB0aGUgZnVuY3Rpb24gd2l0aCB0aGUgY3VycmVudCBgc2NvcGVgIHBhcmFtZXRlci4KICAgICAgICoKICAgICAgICogQHBhcmFtIHsob2JqZWN0KT19IGxvY2FscyBMb2NhbCB2YXJpYWJsZXMgb2JqZWN0LCB1c2VmdWwgZm9yIG92ZXJyaWRpbmcgdmFsdWVzIGluIHNjb3BlLgogICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uLgogICAgICAgKi8KICAgICAgJGV2YWw6IGZ1bmN0aW9uKGV4cHIsIGxvY2FscykgewogICAgICAgIHJldHVybiAkcGFyc2UoZXhwcikodGhpcywgbG9jYWxzKTsKICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJGV2YWxBc3luYwogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogRXhlY3V0ZXMgdGhlIGV4cHJlc3Npb24gb24gdGhlIGN1cnJlbnQgc2NvcGUgYXQgYSBsYXRlciBwb2ludCBpbiB0aW1lLgogICAgICAgKgogICAgICAgKiBUaGUgYCRldmFsQXN5bmNgIG1ha2VzIG5vIGd1YXJhbnRlZXMgYXMgdG8gd2hlbiB0aGUgYGV4cHJlc3Npb25gIHdpbGwgYmUgZXhlY3V0ZWQsIG9ubHkKICAgICAgICogdGhhdDoKICAgICAgICoKICAgICAgICogICAtIGl0IHdpbGwgZXhlY3V0ZSBhZnRlciB0aGUgZnVuY3Rpb24gdGhhdCBzY2hlZHVsZWQgdGhlIGV2YWx1YXRpb24gKHByZWZlcmFibHkgYmVmb3JlIERPTQogICAgICAgKiAgICAgcmVuZGVyaW5nKS4KICAgICAgICogICAtIGF0IGxlYXN0IG9uZSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkZGlnZXN0ICRkaWdlc3QgY3ljbGV9IHdpbGwgYmUgcGVyZm9ybWVkIGFmdGVyCiAgICAgICAqICAgICBgZXhwcmVzc2lvbmAgZXhlY3V0aW9uLgogICAgICAgKgogICAgICAgKiBBbnkgZXhjZXB0aW9ucyBmcm9tIHRoZSBleGVjdXRpb24gb2YgdGhlIGV4cHJlc3Npb24gYXJlIGZvcndhcmRlZCB0byB0aGUKICAgICAgICoge0BsaW5rIG5nLiRleGNlcHRpb25IYW5kbGVyICRleGNlcHRpb25IYW5kbGVyfSBzZXJ2aWNlLgogICAgICAgKgogICAgICAgKiBfX05vdGU6X18gaWYgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb3V0c2lkZSBvZiBhIGAkZGlnZXN0YCBjeWNsZSwgYSBuZXcgYCRkaWdlc3RgIGN5Y2xlCiAgICAgICAqIHdpbGwgYmUgc2NoZWR1bGVkLiBIb3dldmVyLCBpdCBpcyBlbmNvdXJhZ2VkIHRvIGFsd2F5cyBjYWxsIGNvZGUgdGhhdCBjaGFuZ2VzIHRoZSBtb2RlbAogICAgICAgKiBmcm9tIHdpdGhpbiBhbiBgJGFwcGx5YCBjYWxsLiBUaGF0IGluY2x1ZGVzIGNvZGUgZXZhbHVhdGVkIHZpYSBgJGV2YWxBc3luY2AuCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7KHN0cmluZ3xmdW5jdGlvbigpKT19IGV4cHJlc3Npb24gQW4gYW5ndWxhciBleHByZXNzaW9uIHRvIGJlIGV4ZWN1dGVkLgogICAgICAgKgogICAgICAgKiAgICAtIGBzdHJpbmdgOiBleGVjdXRlIHVzaW5nIHRoZSBydWxlcyBhcyBkZWZpbmVkIGluIHtAbGluayBndWlkZS9leHByZXNzaW9uIGV4cHJlc3Npb259LgogICAgICAgKiAgICAtIGBmdW5jdGlvbihzY29wZSlgOiBleGVjdXRlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBjdXJyZW50IGBzY29wZWAgcGFyYW1ldGVyLgogICAgICAgKgogICAgICAgKiBAcGFyYW0geyhvYmplY3QpPX0gbG9jYWxzIExvY2FsIHZhcmlhYmxlcyBvYmplY3QsIHVzZWZ1bCBmb3Igb3ZlcnJpZGluZyB2YWx1ZXMgaW4gc2NvcGUuCiAgICAgICAqLwogICAgICAkZXZhbEFzeW5jOiBmdW5jdGlvbihleHByLCBsb2NhbHMpIHsKICAgICAgICAvLyBpZiB3ZSBhcmUgb3V0c2lkZSBvZiBhbiAkZGlnZXN0IGxvb3AgYW5kIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgd2UgYXJlIHNjaGVkdWxpbmcgYXN5bmMKICAgICAgICAvLyB0YXNrIGFsc28gc2NoZWR1bGUgYXN5bmMgYXV0by1mbHVzaAogICAgICAgIGlmICghJHJvb3RTY29wZS4kJHBoYXNlICYmICFhc3luY1F1ZXVlLmxlbmd0aCkgewogICAgICAgICAgJGJyb3dzZXIuZGVmZXIoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmIChhc3luY1F1ZXVlLmxlbmd0aCkgewogICAgICAgICAgICAgICRyb290U2NvcGUuJGRpZ2VzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIGFzeW5jUXVldWUucHVzaCh7c2NvcGU6IHRoaXMsIGV4cHJlc3Npb246IGV4cHIsIGxvY2FsczogbG9jYWxzfSk7CiAgICAgIH0sCgogICAgICAkJHBvc3REaWdlc3Q6IGZ1bmN0aW9uKGZuKSB7CiAgICAgICAgcG9zdERpZ2VzdFF1ZXVlLnB1c2goZm4pOwogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkYXBwbHkKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIGAkYXBwbHkoKWAgaXMgdXNlZCB0byBleGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gYW5ndWxhciBmcm9tIG91dHNpZGUgb2YgdGhlIGFuZ3VsYXIKICAgICAgICogZnJhbWV3b3JrLiAoRm9yIGV4YW1wbGUgZnJvbSBicm93c2VyIERPTSBldmVudHMsIHNldFRpbWVvdXQsIFhIUiBvciB0aGlyZCBwYXJ0eSBsaWJyYXJpZXMpLgogICAgICAgKiBCZWNhdXNlIHdlIGFyZSBjYWxsaW5nIGludG8gdGhlIGFuZ3VsYXIgZnJhbWV3b3JrIHdlIG5lZWQgdG8gcGVyZm9ybSBwcm9wZXIgc2NvcGUgbGlmZQogICAgICAgKiBjeWNsZSBvZiB7QGxpbmsgbmcuJGV4Y2VwdGlvbkhhbmRsZXIgZXhjZXB0aW9uIGhhbmRsaW5nfSwKICAgICAgICoge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJGRpZ2VzdCBleGVjdXRpbmcgd2F0Y2hlc30uCiAgICAgICAqCiAgICAgICAqICMjIExpZmUgY3ljbGUKICAgICAgICoKICAgICAgICogIyBQc2V1ZG8tQ29kZSBvZiBgJGFwcGx5KClgCiAgICAgICAqIGBgYGpzCiAgICAgICAgICAgZnVuY3Rpb24gJGFwcGx5KGV4cHIpIHsKICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgIHJldHVybiAkZXZhbChleHByKTsKICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgJGV4Y2VwdGlvbkhhbmRsZXIoZSk7CiAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAkcm9vdC4kZGlnZXN0KCk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgfQogICAgICAgKiBgYGAKICAgICAgICoKICAgICAgICoKICAgICAgICogU2NvcGUncyBgJGFwcGx5KClgIG1ldGhvZCB0cmFuc2l0aW9ucyB0aHJvdWdoIHRoZSBmb2xsb3dpbmcgc3RhZ2VzOgogICAgICAgKgogICAgICAgKiAxLiBUaGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgZXhlY3V0ZWQgdXNpbmcgdGhlCiAgICAgICAqICAgIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRldmFsICRldmFsKCl9IG1ldGhvZC4KICAgICAgICogMi4gQW55IGV4Y2VwdGlvbnMgZnJvbSB0aGUgZXhlY3V0aW9uIG9mIHRoZSBleHByZXNzaW9uIGFyZSBmb3J3YXJkZWQgdG8gdGhlCiAgICAgICAqICAgIHtAbGluayBuZy4kZXhjZXB0aW9uSGFuZGxlciAkZXhjZXB0aW9uSGFuZGxlcn0gc2VydmljZS4KICAgICAgICogMy4gVGhlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyR3YXRjaCB3YXRjaH0gbGlzdGVuZXJzIGFyZSBmaXJlZCBpbW1lZGlhdGVseSBhZnRlciB0aGUKICAgICAgICogICAgZXhwcmVzc2lvbiB3YXMgZXhlY3V0ZWQgdXNpbmcgdGhlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRkaWdlc3QgJGRpZ2VzdCgpfSBtZXRob2QuCiAgICAgICAqCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7KHN0cmluZ3xmdW5jdGlvbigpKT19IGV4cCBBbiBhbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQuCiAgICAgICAqCiAgICAgICAqICAgIC0gYHN0cmluZ2A6IGV4ZWN1dGUgdXNpbmcgdGhlIHJ1bGVzIGFzIGRlZmluZWQgaW4ge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0uCiAgICAgICAqICAgIC0gYGZ1bmN0aW9uKHNjb3BlKWA6IGV4ZWN1dGUgdGhlIGZ1bmN0aW9uIHdpdGggY3VycmVudCBgc2NvcGVgIHBhcmFtZXRlci4KICAgICAgICoKICAgICAgICogQHJldHVybnMgeyp9IFRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbi4KICAgICAgICovCiAgICAgICRhcHBseTogZnVuY3Rpb24oZXhwcikgewogICAgICAgIHRyeSB7CiAgICAgICAgICBiZWdpblBoYXNlKCckYXBwbHknKTsKICAgICAgICAgIHJldHVybiB0aGlzLiRldmFsKGV4cHIpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBjbGVhclBoYXNlKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICAkcm9vdFNjb3BlLiRkaWdlc3QoKTsKICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgJGV4Y2VwdGlvbkhhbmRsZXIoZSk7CiAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkYXBwbHlBc3luYwogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogU2NoZWR1bGUgdGhlIGludm9rYXRpb24gb2YgJGFwcGx5IHRvIG9jY3VyIGF0IGEgbGF0ZXIgdGltZS4gVGhlIGFjdHVhbCB0aW1lIGRpZmZlcmVuY2UKICAgICAgICogdmFyaWVzIGFjcm9zcyBicm93c2VycywgYnV0IGlzIHR5cGljYWxseSBhcm91bmQgfjEwIG1pbGxpc2Vjb25kcy4KICAgICAgICoKICAgICAgICogVGhpcyBjYW4gYmUgdXNlZCB0byBxdWV1ZSB1cCBtdWx0aXBsZSBleHByZXNzaW9ucyB3aGljaCBuZWVkIHRvIGJlIGV2YWx1YXRlZCBpbiB0aGUgc2FtZQogICAgICAgKiBkaWdlc3QuCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSB7KHN0cmluZ3xmdW5jdGlvbigpKT19IGV4cCBBbiBhbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQuCiAgICAgICAqCiAgICAgICAqICAgIC0gYHN0cmluZ2A6IGV4ZWN1dGUgdXNpbmcgdGhlIHJ1bGVzIGFzIGRlZmluZWQgaW4ge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0uCiAgICAgICAqICAgIC0gYGZ1bmN0aW9uKHNjb3BlKWA6IGV4ZWN1dGUgdGhlIGZ1bmN0aW9uIHdpdGggY3VycmVudCBgc2NvcGVgIHBhcmFtZXRlci4KICAgICAgICovCiAgICAgICRhcHBseUFzeW5jOiBmdW5jdGlvbihleHByKSB7CiAgICAgICAgdmFyIHNjb3BlID0gdGhpczsKICAgICAgICBleHByICYmIGFwcGx5QXN5bmNRdWV1ZS5wdXNoKCRhcHBseUFzeW5jRXhwcmVzc2lvbik7CiAgICAgICAgc2NoZWR1bGVBcHBseUFzeW5jKCk7CgogICAgICAgIGZ1bmN0aW9uICRhcHBseUFzeW5jRXhwcmVzc2lvbigpIHsKICAgICAgICAgIHNjb3BlLiRldmFsKGV4cHIpOwogICAgICAgIH0KICAgICAgfSwKCiAgICAgIC8qKgogICAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgICAqIEBuYW1lICRyb290U2NvcGUuU2NvcGUjJG9uCiAgICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgICAqCiAgICAgICAqIEBkZXNjcmlwdGlvbgogICAgICAgKiBMaXN0ZW5zIG9uIGV2ZW50cyBvZiBhIGdpdmVuIHR5cGUuIFNlZSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkZW1pdCAkZW1pdH0gZm9yCiAgICAgICAqIGRpc2N1c3Npb24gb2YgZXZlbnQgbGlmZSBjeWNsZS4KICAgICAgICoKICAgICAgICogVGhlIGV2ZW50IGxpc3RlbmVyIGZ1bmN0aW9uIGZvcm1hdCBpczogYGZ1bmN0aW9uKGV2ZW50LCBhcmdzLi4uKWAuIFRoZSBgZXZlbnRgIG9iamVjdAogICAgICAgKiBwYXNzZWQgaW50byB0aGUgbGlzdGVuZXIgaGFzIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczoKICAgICAgICoKICAgICAgICogICAtIGB0YXJnZXRTY29wZWAgLSBge1Njb3BlfWA6IHRoZSBzY29wZSBvbiB3aGljaCB0aGUgZXZlbnQgd2FzIGAkZW1pdGAtZWQgb3IKICAgICAgICogICAgIGAkYnJvYWRjYXN0YC1lZC4KICAgICAgICogICAtIGBjdXJyZW50U2NvcGVgIC0gYHtTY29wZX1gOiB0aGUgc2NvcGUgdGhhdCBpcyBjdXJyZW50bHkgaGFuZGxpbmcgdGhlIGV2ZW50LiBPbmNlIHRoZQogICAgICAgKiAgICAgZXZlbnQgcHJvcGFnYXRlcyB0aHJvdWdoIHRoZSBzY29wZSBoaWVyYXJjaHksIHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvIG51bGwuCiAgICAgICAqICAgLSBgbmFtZWAgLSBge3N0cmluZ31gOiBuYW1lIG9mIHRoZSBldmVudC4KICAgICAgICogICAtIGBzdG9wUHJvcGFnYXRpb25gIC0gYHtmdW5jdGlvbj19YDogY2FsbGluZyBgc3RvcFByb3BhZ2F0aW9uYCBmdW5jdGlvbiB3aWxsIGNhbmNlbAogICAgICAgKiAgICAgZnVydGhlciBldmVudCBwcm9wYWdhdGlvbiAoYXZhaWxhYmxlIG9ubHkgZm9yIGV2ZW50cyB0aGF0IHdlcmUgYCRlbWl0YC1lZCkuCiAgICAgICAqICAgLSBgcHJldmVudERlZmF1bHRgIC0gYHtmdW5jdGlvbn1gOiBjYWxsaW5nIGBwcmV2ZW50RGVmYXVsdGAgc2V0cyBgZGVmYXVsdFByZXZlbnRlZGAgZmxhZwogICAgICAgKiAgICAgdG8gdHJ1ZS4KICAgICAgICogICAtIGBkZWZhdWx0UHJldmVudGVkYCAtIGB7Ym9vbGVhbn1gOiB0cnVlIGlmIGBwcmV2ZW50RGVmYXVsdGAgd2FzIGNhbGxlZC4KICAgICAgICoKICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRXZlbnQgbmFtZSB0byBsaXN0ZW4gb24uCiAgICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oZXZlbnQsIC4uLmFyZ3MpfSBsaXN0ZW5lciBGdW5jdGlvbiB0byBjYWxsIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuCiAgICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbigpfSBSZXR1cm5zIGEgZGVyZWdpc3RyYXRpb24gZnVuY3Rpb24gZm9yIHRoaXMgbGlzdGVuZXIuCiAgICAgICAqLwogICAgICAkb246IGZ1bmN0aW9uKG5hbWUsIGxpc3RlbmVyKSB7CiAgICAgICAgdmFyIG5hbWVkTGlzdGVuZXJzID0gdGhpcy4kJGxpc3RlbmVyc1tuYW1lXTsKICAgICAgICBpZiAoIW5hbWVkTGlzdGVuZXJzKSB7CiAgICAgICAgICB0aGlzLiQkbGlzdGVuZXJzW25hbWVdID0gbmFtZWRMaXN0ZW5lcnMgPSBbXTsKICAgICAgICB9CiAgICAgICAgbmFtZWRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7CgogICAgICAgIHZhciBjdXJyZW50ID0gdGhpczsKICAgICAgICBkbyB7CiAgICAgICAgICBpZiAoIWN1cnJlbnQuJCRsaXN0ZW5lckNvdW50W25hbWVdKSB7CiAgICAgICAgICAgIGN1cnJlbnQuJCRsaXN0ZW5lckNvdW50W25hbWVdID0gMDsKICAgICAgICAgIH0KICAgICAgICAgIGN1cnJlbnQuJCRsaXN0ZW5lckNvdW50W25hbWVdKys7CiAgICAgICAgfSB3aGlsZSAoKGN1cnJlbnQgPSBjdXJyZW50LiRwYXJlbnQpKTsKCiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgICAgIHZhciBpbmRleE9mTGlzdGVuZXIgPSBuYW1lZExpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKTsKICAgICAgICAgIGlmIChpbmRleE9mTGlzdGVuZXIgIT09IC0xKSB7CiAgICAgICAgICAgIG5hbWVkTGlzdGVuZXJzW2luZGV4T2ZMaXN0ZW5lcl0gPSBudWxsOwogICAgICAgICAgICBkZWNyZW1lbnRMaXN0ZW5lckNvdW50KHNlbGYsIDEsIG5hbWUpOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgIH0sCgoKICAgICAgLyoqCiAgICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAgICogQG5hbWUgJHJvb3RTY29wZS5TY29wZSMkZW1pdAogICAgICAgKiBAa2luZCBmdW5jdGlvbgogICAgICAgKgogICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICogRGlzcGF0Y2hlcyBhbiBldmVudCBgbmFtZWAgdXB3YXJkcyB0aHJvdWdoIHRoZSBzY29wZSBoaWVyYXJjaHkgbm90aWZ5aW5nIHRoZQogICAgICAgKiByZWdpc3RlcmVkIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRvbn0gbGlzdGVuZXJzLgogICAgICAgKgogICAgICAgKiBUaGUgZXZlbnQgbGlmZSBjeWNsZSBzdGFydHMgYXQgdGhlIHNjb3BlIG9uIHdoaWNoIGAkZW1pdGAgd2FzIGNhbGxlZC4gQWxsCiAgICAgICAqIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRvbiBsaXN0ZW5lcnN9IGxpc3RlbmluZyBmb3IgYG5hbWVgIGV2ZW50IG9uIHRoaXMgc2NvcGUgZ2V0CiAgICAgICAqIG5vdGlmaWVkLiBBZnRlcndhcmRzLCB0aGUgZXZlbnQgdHJhdmVyc2VzIHVwd2FyZHMgdG93YXJkIHRoZSByb290IHNjb3BlIGFuZCBjYWxscyBhbGwKICAgICAgICogcmVnaXN0ZXJlZCBsaXN0ZW5lcnMgYWxvbmcgdGhlIHdheS4gVGhlIGV2ZW50IHdpbGwgc3RvcCBwcm9wYWdhdGluZyBpZiBvbmUgb2YgdGhlIGxpc3RlbmVycwogICAgICAgKiBjYW5jZWxzIGl0LgogICAgICAgKgogICAgICAgKiBBbnkgZXhjZXB0aW9uIGVtaXR0ZWQgZnJvbSB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJG9uIGxpc3RlbmVyc30gd2lsbCBiZSBwYXNzZWQKICAgICAgICogb250byB0aGUge0BsaW5rIG5nLiRleGNlcHRpb25IYW5kbGVyICRleGNlcHRpb25IYW5kbGVyfSBzZXJ2aWNlLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBFdmVudCBuYW1lIHRvIGVtaXQuCiAgICAgICAqIEBwYXJhbSB7Li4uKn0gYXJncyBPcHRpb25hbCBvbmUgb3IgbW9yZSBhcmd1bWVudHMgd2hpY2ggd2lsbCBiZSBwYXNzZWQgb250byB0aGUgZXZlbnQgbGlzdGVuZXJzLgogICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEV2ZW50IG9iamVjdCAoc2VlIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRvbn0pLgogICAgICAgKi8KICAgICAgJGVtaXQ6IGZ1bmN0aW9uKG5hbWUsIGFyZ3MpIHsKICAgICAgICB2YXIgZW1wdHkgPSBbXSwKICAgICAgICAgICAgbmFtZWRMaXN0ZW5lcnMsCiAgICAgICAgICAgIHNjb3BlID0gdGhpcywKICAgICAgICAgICAgc3RvcFByb3BhZ2F0aW9uID0gZmFsc2UsCiAgICAgICAgICAgIGV2ZW50ID0gewogICAgICAgICAgICAgIG5hbWU6IG5hbWUsCiAgICAgICAgICAgICAgdGFyZ2V0U2NvcGU6IHNjb3BlLAogICAgICAgICAgICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7c3RvcFByb3BhZ2F0aW9uID0gdHJ1ZTt9LAogICAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOwogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgZGVmYXVsdFByZXZlbnRlZDogZmFsc2UKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbGlzdGVuZXJBcmdzID0gY29uY2F0KFtldmVudF0sIGFyZ3VtZW50cywgMSksCiAgICAgICAgICAgIGksIGxlbmd0aDsKCiAgICAgICAgZG8gewogICAgICAgICAgbmFtZWRMaXN0ZW5lcnMgPSBzY29wZS4kJGxpc3RlbmVyc1tuYW1lXSB8fCBlbXB0eTsKICAgICAgICAgIGV2ZW50LmN1cnJlbnRTY29wZSA9IHNjb3BlOwogICAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gbmFtZWRMaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKCiAgICAgICAgICAgIC8vIGlmIGxpc3RlbmVycyB3ZXJlIGRlcmVnaXN0ZXJlZCwgZGVmcmFnbWVudCB0aGUgYXJyYXkKICAgICAgICAgICAgaWYgKCFuYW1lZExpc3RlbmVyc1tpXSkgewogICAgICAgICAgICAgIG5hbWVkTGlzdGVuZXJzLnNwbGljZShpLCAxKTsKICAgICAgICAgICAgICBpLS07CiAgICAgICAgICAgICAgbGVuZ3RoLS07CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAvL2FsbG93IGFsbCBsaXN0ZW5lcnMgYXR0YWNoZWQgdG8gdGhlIGN1cnJlbnQgc2NvcGUgdG8gcnVuCiAgICAgICAgICAgICAgbmFtZWRMaXN0ZW5lcnNbaV0uYXBwbHkobnVsbCwgbGlzdGVuZXJBcmdzKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvL2lmIGFueSBsaXN0ZW5lciBvbiB0aGUgY3VycmVudCBzY29wZSBzdG9wcyBwcm9wYWdhdGlvbiwgcHJldmVudCBidWJibGluZwogICAgICAgICAgaWYgKHN0b3BQcm9wYWdhdGlvbikgewogICAgICAgICAgICBldmVudC5jdXJyZW50U2NvcGUgPSBudWxsOwogICAgICAgICAgICByZXR1cm4gZXZlbnQ7CiAgICAgICAgICB9CiAgICAgICAgICAvL3RyYXZlcnNlIHVwd2FyZHMKICAgICAgICAgIHNjb3BlID0gc2NvcGUuJHBhcmVudDsKICAgICAgICB9IHdoaWxlIChzY29wZSk7CgogICAgICAgIGV2ZW50LmN1cnJlbnRTY29wZSA9IG51bGw7CgogICAgICAgIHJldHVybiBldmVudDsKICAgICAgfSwKCgogICAgICAvKioKICAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAgKiBAbmFtZSAkcm9vdFNjb3BlLlNjb3BlIyRicm9hZGNhc3QKICAgICAgICogQGtpbmQgZnVuY3Rpb24KICAgICAgICoKICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAqIERpc3BhdGNoZXMgYW4gZXZlbnQgYG5hbWVgIGRvd253YXJkcyB0byBhbGwgY2hpbGQgc2NvcGVzIChhbmQgdGhlaXIgY2hpbGRyZW4pIG5vdGlmeWluZyB0aGUKICAgICAgICogcmVnaXN0ZXJlZCB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkb259IGxpc3RlbmVycy4KICAgICAgICoKICAgICAgICogVGhlIGV2ZW50IGxpZmUgY3ljbGUgc3RhcnRzIGF0IHRoZSBzY29wZSBvbiB3aGljaCBgJGJyb2FkY2FzdGAgd2FzIGNhbGxlZC4gQWxsCiAgICAgICAqIHtAbGluayBuZy4kcm9vdFNjb3BlLlNjb3BlIyRvbiBsaXN0ZW5lcnN9IGxpc3RlbmluZyBmb3IgYG5hbWVgIGV2ZW50IG9uIHRoaXMgc2NvcGUgZ2V0CiAgICAgICAqIG5vdGlmaWVkLiBBZnRlcndhcmRzLCB0aGUgZXZlbnQgcHJvcGFnYXRlcyB0byBhbGwgZGlyZWN0IGFuZCBpbmRpcmVjdCBzY29wZXMgb2YgdGhlIGN1cnJlbnQKICAgICAgICogc2NvcGUgYW5kIGNhbGxzIGFsbCByZWdpc3RlcmVkIGxpc3RlbmVycyBhbG9uZyB0aGUgd2F5LiBUaGUgZXZlbnQgY2Fubm90IGJlIGNhbmNlbGVkLgogICAgICAgKgogICAgICAgKiBBbnkgZXhjZXB0aW9uIGVtaXR0ZWQgZnJvbSB0aGUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJG9uIGxpc3RlbmVyc30gd2lsbCBiZSBwYXNzZWQKICAgICAgICogb250byB0aGUge0BsaW5rIG5nLiRleGNlcHRpb25IYW5kbGVyICRleGNlcHRpb25IYW5kbGVyfSBzZXJ2aWNlLgogICAgICAgKgogICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBFdmVudCBuYW1lIHRvIGJyb2FkY2FzdC4KICAgICAgICogQHBhcmFtIHsuLi4qfSBhcmdzIE9wdGlvbmFsIG9uZSBvciBtb3JlIGFyZ3VtZW50cyB3aGljaCB3aWxsIGJlIHBhc3NlZCBvbnRvIHRoZSBldmVudCBsaXN0ZW5lcnMuCiAgICAgICAqIEByZXR1cm4ge09iamVjdH0gRXZlbnQgb2JqZWN0LCBzZWUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJG9ufQogICAgICAgKi8KICAgICAgJGJyb2FkY2FzdDogZnVuY3Rpb24obmFtZSwgYXJncykgewogICAgICAgIHZhciB0YXJnZXQgPSB0aGlzLAogICAgICAgICAgICBjdXJyZW50ID0gdGFyZ2V0LAogICAgICAgICAgICBuZXh0ID0gdGFyZ2V0LAogICAgICAgICAgICBldmVudCA9IHsKICAgICAgICAgICAgICBuYW1lOiBuYW1lLAogICAgICAgICAgICAgIHRhcmdldFNjb3BlOiB0YXJnZXQsCiAgICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICBkZWZhdWx0UHJldmVudGVkOiBmYWxzZQogICAgICAgICAgICB9OwoKICAgICAgICBpZiAoIXRhcmdldC4kJGxpc3RlbmVyQ291bnRbbmFtZV0pIHJldHVybiBldmVudDsKCiAgICAgICAgdmFyIGxpc3RlbmVyQXJncyA9IGNvbmNhdChbZXZlbnRdLCBhcmd1bWVudHMsIDEpLAogICAgICAgICAgICBsaXN0ZW5lcnMsIGksIGxlbmd0aDsKCiAgICAgICAgLy9kb3duIHdoaWxlIHlvdSBjYW4sIHRoZW4gdXAgYW5kIG5leHQgc2libGluZyBvciB1cCBhbmQgbmV4dCBzaWJsaW5nIHVudGlsIGJhY2sgYXQgcm9vdAogICAgICAgIHdoaWxlICgoY3VycmVudCA9IG5leHQpKSB7CiAgICAgICAgICBldmVudC5jdXJyZW50U2NvcGUgPSBjdXJyZW50OwogICAgICAgICAgbGlzdGVuZXJzID0gY3VycmVudC4kJGxpc3RlbmVyc1tuYW1lXSB8fCBbXTsKICAgICAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgICAgICAvLyBpZiBsaXN0ZW5lcnMgd2VyZSBkZXJlZ2lzdGVyZWQsIGRlZnJhZ21lbnQgdGhlIGFycmF5CiAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7CiAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTsKICAgICAgICAgICAgICBpLS07CiAgICAgICAgICAgICAgbGVuZ3RoLS07CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KG51bGwsIGxpc3RlbmVyQXJncyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAkZXhjZXB0aW9uSGFuZGxlcihlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIEluc2FuaXR5IFdhcm5pbmc6IHNjb3BlIGRlcHRoLWZpcnN0IHRyYXZlcnNhbAogICAgICAgICAgLy8geWVzLCB0aGlzIGNvZGUgaXMgYSBiaXQgY3JhenksIGJ1dCBpdCB3b3JrcyBhbmQgd2UgaGF2ZSB0ZXN0cyB0byBwcm92ZSBpdCEKICAgICAgICAgIC8vIHRoaXMgcGllY2Ugc2hvdWxkIGJlIGtlcHQgaW4gc3luYyB3aXRoIHRoZSB0cmF2ZXJzYWwgaW4gJGRpZ2VzdAogICAgICAgICAgLy8gKHRob3VnaCBpdCBkaWZmZXJzIGR1ZSB0byBoYXZpbmcgdGhlIGV4dHJhIGNoZWNrIGZvciAkJGxpc3RlbmVyQ291bnQpCiAgICAgICAgICBpZiAoIShuZXh0ID0gKChjdXJyZW50LiQkbGlzdGVuZXJDb3VudFtuYW1lXSAmJiBjdXJyZW50LiQkY2hpbGRIZWFkKSB8fAogICAgICAgICAgICAgIChjdXJyZW50ICE9PSB0YXJnZXQgJiYgY3VycmVudC4kJG5leHRTaWJsaW5nKSkpKSB7CiAgICAgICAgICAgIHdoaWxlIChjdXJyZW50ICE9PSB0YXJnZXQgJiYgIShuZXh0ID0gY3VycmVudC4kJG5leHRTaWJsaW5nKSkgewogICAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LiRwYXJlbnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGV2ZW50LmN1cnJlbnRTY29wZSA9IG51bGw7CiAgICAgICAgcmV0dXJuIGV2ZW50OwogICAgICB9CiAgICB9OwoKICAgIHZhciAkcm9vdFNjb3BlID0gbmV3IFNjb3BlKCk7CgogICAgLy9UaGUgaW50ZXJuYWwgcXVldWVzLiBFeHBvc2UgdGhlbSBvbiB0aGUgJHJvb3RTY29wZSBmb3IgZGVidWdnaW5nL3Rlc3RpbmcgcHVycG9zZXMuCiAgICB2YXIgYXN5bmNRdWV1ZSA9ICRyb290U2NvcGUuJCRhc3luY1F1ZXVlID0gW107CiAgICB2YXIgcG9zdERpZ2VzdFF1ZXVlID0gJHJvb3RTY29wZS4kJHBvc3REaWdlc3RRdWV1ZSA9IFtdOwogICAgdmFyIGFwcGx5QXN5bmNRdWV1ZSA9ICRyb290U2NvcGUuJCRhcHBseUFzeW5jUXVldWUgPSBbXTsKCiAgICByZXR1cm4gJHJvb3RTY29wZTsKCgogICAgZnVuY3Rpb24gYmVnaW5QaGFzZShwaGFzZSkgewogICAgICBpZiAoJHJvb3RTY29wZS4kJHBoYXNlKSB7CiAgICAgICAgdGhyb3cgJHJvb3RTY29wZU1pbkVycignaW5wcm9nJywgJ3swfSBhbHJlYWR5IGluIHByb2dyZXNzJywgJHJvb3RTY29wZS4kJHBoYXNlKTsKICAgICAgfQoKICAgICAgJHJvb3RTY29wZS4kJHBoYXNlID0gcGhhc2U7CiAgICB9CgogICAgZnVuY3Rpb24gY2xlYXJQaGFzZSgpIHsKICAgICAgJHJvb3RTY29wZS4kJHBoYXNlID0gbnVsbDsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVjcmVtZW50TGlzdGVuZXJDb3VudChjdXJyZW50LCBjb3VudCwgbmFtZSkgewogICAgICBkbyB7CiAgICAgICAgY3VycmVudC4kJGxpc3RlbmVyQ291bnRbbmFtZV0gLT0gY291bnQ7CgogICAgICAgIGlmIChjdXJyZW50LiQkbGlzdGVuZXJDb3VudFtuYW1lXSA9PT0gMCkgewogICAgICAgICAgZGVsZXRlIGN1cnJlbnQuJCRsaXN0ZW5lckNvdW50W25hbWVdOwogICAgICAgIH0KICAgICAgfSB3aGlsZSAoKGN1cnJlbnQgPSBjdXJyZW50LiRwYXJlbnQpKTsKICAgIH0KCiAgICAvKioKICAgICAqIGZ1bmN0aW9uIHVzZWQgYXMgYW4gaW5pdGlhbCB2YWx1ZSBmb3Igd2F0Y2hlcnMuCiAgICAgKiBiZWNhdXNlIGl0J3MgdW5pcXVlIHdlIGNhbiBlYXNpbHkgdGVsbCBpdCBhcGFydCBmcm9tIG90aGVyIHZhbHVlcwogICAgICovCiAgICBmdW5jdGlvbiBpbml0V2F0Y2hWYWwoKSB7fQoKICAgIGZ1bmN0aW9uIGZsdXNoQXBwbHlBc3luYygpIHsKICAgICAgd2hpbGUgKGFwcGx5QXN5bmNRdWV1ZS5sZW5ndGgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgYXBwbHlBc3luY1F1ZXVlLnNoaWZ0KCkoKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAkZXhjZXB0aW9uSGFuZGxlcihlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYXBwbHlBc3luY0lkID0gbnVsbDsKICAgIH0KCiAgICBmdW5jdGlvbiBzY2hlZHVsZUFwcGx5QXN5bmMoKSB7CiAgICAgIGlmIChhcHBseUFzeW5jSWQgPT09IG51bGwpIHsKICAgICAgICBhcHBseUFzeW5jSWQgPSAkYnJvd3Nlci5kZWZlcihmdW5jdGlvbigpIHsKICAgICAgICAgICRyb290U2NvcGUuJGFwcGx5KGZsdXNoQXBwbHlBc3luYyk7CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICB9XTsKfQoKLyoqCiAqIEBkZXNjcmlwdGlvbgogKiBQcml2YXRlIHNlcnZpY2UgdG8gc2FuaXRpemUgdXJpcyBmb3IgbGlua3MgYW5kIGltYWdlcy4gVXNlZCBieSAkY29tcGlsZSBhbmQgJHNhbml0aXplLgogKi8KZnVuY3Rpb24gJCRTYW5pdGl6ZVVyaVByb3ZpZGVyKCkgewogIHZhciBhSHJlZlNhbml0aXphdGlvbldoaXRlbGlzdCA9IC9eXHMqKGh0dHBzP3xmdHB8bWFpbHRvfHRlbHxmaWxlKTovLAogICAgaW1nU3JjU2FuaXRpemF0aW9uV2hpdGVsaXN0ID0gL15ccyooKGh0dHBzP3xmdHB8ZmlsZXxibG9iKTp8ZGF0YTppbWFnZVwvKS87CgogIC8qKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJldHJpZXZlcyBvciBvdmVycmlkZXMgdGhlIGRlZmF1bHQgcmVndWxhciBleHByZXNzaW9uIHRoYXQgaXMgdXNlZCBmb3Igd2hpdGVsaXN0aW5nIG9mIHNhZmUKICAgKiB1cmxzIGR1cmluZyBhW2hyZWZdIHNhbml0aXphdGlvbi4KICAgKgogICAqIFRoZSBzYW5pdGl6YXRpb24gaXMgYSBzZWN1cml0eSBtZWFzdXJlIGFpbWVkIGF0IHByZXZlbnQgWFNTIGF0dGFja3MgdmlhIGh0bWwgbGlua3MuCiAgICoKICAgKiBBbnkgdXJsIGFib3V0IHRvIGJlIGFzc2lnbmVkIHRvIGFbaHJlZl0gdmlhIGRhdGEtYmluZGluZyBpcyBmaXJzdCBub3JtYWxpemVkIGFuZCB0dXJuZWQgaW50bwogICAqIGFuIGFic29sdXRlIHVybC4gQWZ0ZXJ3YXJkcywgdGhlIHVybCBpcyBtYXRjaGVkIGFnYWluc3QgdGhlIGBhSHJlZlNhbml0aXphdGlvbldoaXRlbGlzdGAKICAgKiByZWd1bGFyIGV4cHJlc3Npb24uIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoZSBvcmlnaW5hbCB1cmwgaXMgd3JpdHRlbiBpbnRvIHRoZSBkb20uIE90aGVyd2lzZSwKICAgKiB0aGUgYWJzb2x1dGUgdXJsIGlzIHByZWZpeGVkIHdpdGggYCd1bnNhZmU6J2Agc3RyaW5nIGFuZCBvbmx5IHRoZW4gaXMgaXQgd3JpdHRlbiBpbnRvIHRoZSBET00uCiAgICoKICAgKiBAcGFyYW0ge1JlZ0V4cD19IHJlZ2V4cCBOZXcgcmVnZXhwIHRvIHdoaXRlbGlzdCB1cmxzIHdpdGguCiAgICogQHJldHVybnMge1JlZ0V4cHxuZy4kY29tcGlsZVByb3ZpZGVyfSBDdXJyZW50IFJlZ0V4cCBpZiBjYWxsZWQgd2l0aG91dCB2YWx1ZSBvciBzZWxmIGZvcgogICAqICAgIGNoYWluaW5nIG90aGVyd2lzZS4KICAgKi8KICB0aGlzLmFIcmVmU2FuaXRpemF0aW9uV2hpdGVsaXN0ID0gZnVuY3Rpb24ocmVnZXhwKSB7CiAgICBpZiAoaXNEZWZpbmVkKHJlZ2V4cCkpIHsKICAgICAgYUhyZWZTYW5pdGl6YXRpb25XaGl0ZWxpc3QgPSByZWdleHA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcmV0dXJuIGFIcmVmU2FuaXRpemF0aW9uV2hpdGVsaXN0OwogIH07CgoKICAvKioKICAgKiBAZGVzY3JpcHRpb24KICAgKiBSZXRyaWV2ZXMgb3Igb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IGlzIHVzZWQgZm9yIHdoaXRlbGlzdGluZyBvZiBzYWZlCiAgICogdXJscyBkdXJpbmcgaW1nW3NyY10gc2FuaXRpemF0aW9uLgogICAqCiAgICogVGhlIHNhbml0aXphdGlvbiBpcyBhIHNlY3VyaXR5IG1lYXN1cmUgYWltZWQgYXQgcHJldmVudCBYU1MgYXR0YWNrcyB2aWEgaHRtbCBsaW5rcy4KICAgKgogICAqIEFueSB1cmwgYWJvdXQgdG8gYmUgYXNzaWduZWQgdG8gaW1nW3NyY10gdmlhIGRhdGEtYmluZGluZyBpcyBmaXJzdCBub3JtYWxpemVkIGFuZCB0dXJuZWQgaW50bwogICAqIGFuIGFic29sdXRlIHVybC4gQWZ0ZXJ3YXJkcywgdGhlIHVybCBpcyBtYXRjaGVkIGFnYWluc3QgdGhlIGBpbWdTcmNTYW5pdGl6YXRpb25XaGl0ZWxpc3RgCiAgICogcmVndWxhciBleHByZXNzaW9uLiBJZiBhIG1hdGNoIGlzIGZvdW5kLCB0aGUgb3JpZ2luYWwgdXJsIGlzIHdyaXR0ZW4gaW50byB0aGUgZG9tLiBPdGhlcndpc2UsCiAgICogdGhlIGFic29sdXRlIHVybCBpcyBwcmVmaXhlZCB3aXRoIGAndW5zYWZlOidgIHN0cmluZyBhbmQgb25seSB0aGVuIGlzIGl0IHdyaXR0ZW4gaW50byB0aGUgRE9NLgogICAqCiAgICogQHBhcmFtIHtSZWdFeHA9fSByZWdleHAgTmV3IHJlZ2V4cCB0byB3aGl0ZWxpc3QgdXJscyB3aXRoLgogICAqIEByZXR1cm5zIHtSZWdFeHB8bmcuJGNvbXBpbGVQcm92aWRlcn0gQ3VycmVudCBSZWdFeHAgaWYgY2FsbGVkIHdpdGhvdXQgdmFsdWUgb3Igc2VsZiBmb3IKICAgKiAgICBjaGFpbmluZyBvdGhlcndpc2UuCiAgICovCiAgdGhpcy5pbWdTcmNTYW5pdGl6YXRpb25XaGl0ZWxpc3QgPSBmdW5jdGlvbihyZWdleHApIHsKICAgIGlmIChpc0RlZmluZWQocmVnZXhwKSkgewogICAgICBpbWdTcmNTYW5pdGl6YXRpb25XaGl0ZWxpc3QgPSByZWdleHA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcmV0dXJuIGltZ1NyY1Nhbml0aXphdGlvbldoaXRlbGlzdDsKICB9OwoKICB0aGlzLiRnZXQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBmdW5jdGlvbiBzYW5pdGl6ZVVyaSh1cmksIGlzSW1hZ2UpIHsKICAgICAgdmFyIHJlZ2V4ID0gaXNJbWFnZSA/IGltZ1NyY1Nhbml0aXphdGlvbldoaXRlbGlzdCA6IGFIcmVmU2FuaXRpemF0aW9uV2hpdGVsaXN0OwogICAgICB2YXIgbm9ybWFsaXplZFZhbDsKICAgICAgbm9ybWFsaXplZFZhbCA9IHVybFJlc29sdmUodXJpKS5ocmVmOwogICAgICBpZiAobm9ybWFsaXplZFZhbCAhPT0gJycgJiYgIW5vcm1hbGl6ZWRWYWwubWF0Y2gocmVnZXgpKSB7CiAgICAgICAgcmV0dXJuICd1bnNhZmU6JyArIG5vcm1hbGl6ZWRWYWw7CiAgICAgIH0KICAgICAgcmV0dXJuIHVyaTsKICAgIH07CiAgfTsKfQoKdmFyICRzY2VNaW5FcnIgPSBtaW5FcnIoJyRzY2UnKTsKCnZhciBTQ0VfQ09OVEVYVFMgPSB7CiAgSFRNTDogJ2h0bWwnLAogIENTUzogJ2NzcycsCiAgVVJMOiAndXJsJywKICAvLyBSRVNPVVJDRV9VUkwgaXMgYSBzdWJ0eXBlIG9mIFVSTCB1c2VkIGluIGNvbnRleHRzIHdoZXJlIGEgcHJpdmlsZWdlZCByZXNvdXJjZSBpcyBzb3VyY2VkIGZyb20gYQogIC8vIHVybC4gIChlLmcuIG5nLWluY2x1ZGUsIHNjcmlwdCBzcmMsIHRlbXBsYXRlVXJsKQogIFJFU09VUkNFX1VSTDogJ3Jlc291cmNlVXJsJywKICBKUzogJ2pzJwp9OwoKLy8gSGVscGVyIGZ1bmN0aW9ucyBmb2xsb3cuCgpmdW5jdGlvbiBhZGp1c3RNYXRjaGVyKG1hdGNoZXIpIHsKICBpZiAobWF0Y2hlciA9PT0gJ3NlbGYnKSB7CiAgICByZXR1cm4gbWF0Y2hlcjsKICB9IGVsc2UgaWYgKGlzU3RyaW5nKG1hdGNoZXIpKSB7CiAgICAvLyBTdHJpbmdzIG1hdGNoIGV4YWN0bHkgZXhjZXB0IGZvciAyIHdpbGRjYXJkcyAtICcqJyBhbmQgJyoqJy4KICAgIC8vICcqJyBtYXRjaGVzIGFueSBjaGFyYWN0ZXIgZXhjZXB0IHRob3NlIGZyb20gdGhlIHNldCAnOi8uPyYnLgogICAgLy8gJyoqJyBtYXRjaGVzIGFueSBjaGFyYWN0ZXIgKGxpa2UgLiogaW4gYSBSZWdFeHApLgogICAgLy8gTW9yZSB0aGFuIDIgKidzIHJhaXNlcyBhbiBlcnJvciBhcyBpdCdzIGlsbCBkZWZpbmVkLgogICAgaWYgKG1hdGNoZXIuaW5kZXhPZignKioqJykgPiAtMSkgewogICAgICB0aHJvdyAkc2NlTWluRXJyKCdpd2NhcmQnLAogICAgICAgICAgJ0lsbGVnYWwgc2VxdWVuY2UgKioqIGluIHN0cmluZyBtYXRjaGVyLiAgU3RyaW5nOiB7MH0nLCBtYXRjaGVyKTsKICAgIH0KICAgIG1hdGNoZXIgPSBlc2NhcGVGb3JSZWdleHAobWF0Y2hlcikuCiAgICAgICAgICAgICAgICAgIHJlcGxhY2UoJ1xcKlxcKicsICcuKicpLgogICAgICAgICAgICAgICAgICByZXBsYWNlKCdcXConLCAnW146Ly4/JjtdKicpOwogICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14nICsgbWF0Y2hlciArICckJyk7CiAgfSBlbHNlIGlmIChpc1JlZ0V4cChtYXRjaGVyKSkgewogICAgLy8gVGhlIG9ubHkgb3RoZXIgdHlwZSBvZiBtYXRjaGVyIGFsbG93ZWQgaXMgYSBSZWdleHAuCiAgICAvLyBNYXRjaCBlbnRpcmUgVVJMIC8gZGlzYWxsb3cgcGFydGlhbCBtYXRjaGVzLgogICAgLy8gRmxhZ3MgYXJlIHJlc2V0IChpLmUuIG5vIGdsb2JhbCwgaWdub3JlQ2FzZSBvciBtdWx0aWxpbmUpCiAgICByZXR1cm4gbmV3IFJlZ0V4cCgnXicgKyBtYXRjaGVyLnNvdXJjZSArICckJyk7CiAgfSBlbHNlIHsKICAgIHRocm93ICRzY2VNaW5FcnIoJ2ltYXRjaGVyJywKICAgICAgICAnTWF0Y2hlcnMgbWF5IG9ubHkgYmUgInNlbGYiLCBzdHJpbmcgcGF0dGVybnMgb3IgUmVnRXhwIG9iamVjdHMnKTsKICB9Cn0KCgpmdW5jdGlvbiBhZGp1c3RNYXRjaGVycyhtYXRjaGVycykgewogIHZhciBhZGp1c3RlZE1hdGNoZXJzID0gW107CiAgaWYgKGlzRGVmaW5lZChtYXRjaGVycykpIHsKICAgIGZvckVhY2gobWF0Y2hlcnMsIGZ1bmN0aW9uKG1hdGNoZXIpIHsKICAgICAgYWRqdXN0ZWRNYXRjaGVycy5wdXNoKGFkanVzdE1hdGNoZXIobWF0Y2hlcikpOwogICAgfSk7CiAgfQogIHJldHVybiBhZGp1c3RlZE1hdGNoZXJzOwp9CgoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICRzY2VEZWxlZ2F0ZQogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICoKICogYCRzY2VEZWxlZ2F0ZWAgaXMgYSBzZXJ2aWNlIHRoYXQgaXMgdXNlZCBieSB0aGUgYCRzY2VgIHNlcnZpY2UgdG8gcHJvdmlkZSB7QGxpbmsgbmcuJHNjZSBTdHJpY3QKICogQ29udGV4dHVhbCBFc2NhcGluZyAoU0NFKX0gc2VydmljZXMgdG8gQW5ndWxhckpTLgogKgogKiBUeXBpY2FsbHksIHlvdSB3b3VsZCBjb25maWd1cmUgb3Igb3ZlcnJpZGUgdGhlIHtAbGluayBuZy4kc2NlRGVsZWdhdGUgJHNjZURlbGVnYXRlfSBpbnN0ZWFkIG9mCiAqIHRoZSBgJHNjZWAgc2VydmljZSB0byBjdXN0b21pemUgdGhlIHdheSBTdHJpY3QgQ29udGV4dHVhbCBFc2NhcGluZyB3b3JrcyBpbiBBbmd1bGFySlMuICBUaGlzIGlzCiAqIGJlY2F1c2UsIHdoaWxlIHRoZSBgJHNjZWAgcHJvdmlkZXMgbnVtZXJvdXMgc2hvcnRoYW5kIG1ldGhvZHMsIGV0Yy4sIHlvdSByZWFsbHkgb25seSBuZWVkIHRvCiAqIG92ZXJyaWRlIDMgY29yZSBmdW5jdGlvbnMgKGB0cnVzdEFzYCwgYGdldFRydXN0ZWRgIGFuZCBgdmFsdWVPZmApIHRvIHJlcGxhY2UgdGhlIHdheSB0aGluZ3MKICogd29yayBiZWNhdXNlIGAkc2NlYCBkZWxlZ2F0ZXMgdG8gYCRzY2VEZWxlZ2F0ZWAgZm9yIHRoZXNlIG9wZXJhdGlvbnMuCiAqCiAqIFJlZmVyIHtAbGluayBuZy4kc2NlRGVsZWdhdGVQcm92aWRlciAkc2NlRGVsZWdhdGVQcm92aWRlcn0gdG8gY29uZmlndXJlIHRoaXMgc2VydmljZS4KICoKICogVGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgYCRzY2VEZWxlZ2F0ZWAgc2hvdWxkIHdvcmsgb3V0IG9mIHRoZSBib3ggd2l0aCBsaXR0bGUgcGFpbi4gIFdoaWxlIHlvdQogKiBjYW4gb3ZlcnJpZGUgaXQgY29tcGxldGVseSB0byBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGAkc2NlYCwgdGhlIGNvbW1vbiBjYXNlIHdvdWxkCiAqIGludm9sdmUgY29uZmlndXJpbmcgdGhlIHtAbGluayBuZy4kc2NlRGVsZWdhdGVQcm92aWRlciAkc2NlRGVsZWdhdGVQcm92aWRlcn0gaW5zdGVhZCBieSBzZXR0aW5nCiAqIHlvdXIgb3duIHdoaXRlbGlzdHMgYW5kIGJsYWNrbGlzdHMgZm9yIHRydXN0aW5nIFVSTHMgdXNlZCBmb3IgbG9hZGluZyBBbmd1bGFySlMgcmVzb3VyY2VzIHN1Y2ggYXMKICogdGVtcGxhdGVzLiAgUmVmZXIge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsV2hpdGVsaXN0CiAqICRzY2VEZWxlZ2F0ZVByb3ZpZGVyLnJlc291cmNlVXJsV2hpdGVsaXN0fSBhbmQge0BsaW5rCiAqIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsQmxhY2tsaXN0ICRzY2VEZWxlZ2F0ZVByb3ZpZGVyLnJlc291cmNlVXJsQmxhY2tsaXN0fQogKi8KCi8qKgogKiBAbmdkb2MgcHJvdmlkZXIKICogQG5hbWUgJHNjZURlbGVnYXRlUHJvdmlkZXIKICogQGRlc2NyaXB0aW9uCiAqCiAqIFRoZSBgJHNjZURlbGVnYXRlUHJvdmlkZXJgIHByb3ZpZGVyIGFsbG93cyBkZXZlbG9wZXJzIHRvIGNvbmZpZ3VyZSB0aGUge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZQogKiAkc2NlRGVsZWdhdGV9IHNlcnZpY2UuICBUaGlzIGFsbG93cyBvbmUgdG8gZ2V0L3NldCB0aGUgd2hpdGVsaXN0cyBhbmQgYmxhY2tsaXN0cyB1c2VkIHRvIGVuc3VyZQogKiB0aGF0IHRoZSBVUkxzIHVzZWQgZm9yIHNvdXJjaW5nIEFuZ3VsYXIgdGVtcGxhdGVzIGFyZSBzYWZlLiAgUmVmZXIge0BsaW5rCiAqIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsV2hpdGVsaXN0ICRzY2VEZWxlZ2F0ZVByb3ZpZGVyLnJlc291cmNlVXJsV2hpdGVsaXN0fSBhbmQKICoge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsQmxhY2tsaXN0ICRzY2VEZWxlZ2F0ZVByb3ZpZGVyLnJlc291cmNlVXJsQmxhY2tsaXN0fQogKgogKiBGb3IgdGhlIGdlbmVyYWwgZGV0YWlscyBhYm91dCB0aGlzIHNlcnZpY2UgaW4gQW5ndWxhciwgcmVhZCB0aGUgbWFpbiBwYWdlIGZvciB7QGxpbmsgbmcuJHNjZQogKiBTdHJpY3QgQ29udGV4dHVhbCBFc2NhcGluZyAoU0NFKX0uCiAqCiAqICoqRXhhbXBsZSoqOiAgQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBjYXNlLiA8YSBuYW1lPSJleGFtcGxlIj48L2E+CiAqCiAqIC0geW91ciBhcHAgaXMgaG9zdGVkIGF0IHVybCBgaHR0cDovL215YXBwLmV4YW1wbGUuY29tL2AKICogLSBidXQgc29tZSBvZiB5b3VyIHRlbXBsYXRlcyBhcmUgaG9zdGVkIG9uIG90aGVyIGRvbWFpbnMgeW91IGNvbnRyb2wgc3VjaCBhcwogKiAgIGBodHRwOi8vc3J2MDEuYXNzZXRzLmV4YW1wbGUuY29tL2AswqAgYGh0dHA6Ly9zcnYwMi5hc3NldHMuZXhhbXBsZS5jb20vYCwgZXRjLgogKiAtIGFuZCB5b3UgaGF2ZSBhbiBvcGVuIHJlZGlyZWN0IGF0IGBodHRwOi8vbXlhcHAuZXhhbXBsZS5jb20vY2xpY2tUaHJ1Py4uLmAuCiAqCiAqIEhlcmUgaXMgd2hhdCBhIHNlY3VyZSBjb25maWd1cmF0aW9uIGZvciB0aGlzIHNjZW5hcmlvIG1pZ2h0IGxvb2sgbGlrZToKICoKICogYGBgCiAqICBhbmd1bGFyLm1vZHVsZSgnbXlBcHAnLCBbXSkuY29uZmlnKGZ1bmN0aW9uKCRzY2VEZWxlZ2F0ZVByb3ZpZGVyKSB7CiAqICAgICRzY2VEZWxlZ2F0ZVByb3ZpZGVyLnJlc291cmNlVXJsV2hpdGVsaXN0KFsKICogICAgICAvLyBBbGxvdyBzYW1lIG9yaWdpbiByZXNvdXJjZSBsb2Fkcy4KICogICAgICAnc2VsZicsCiAqICAgICAgLy8gQWxsb3cgbG9hZGluZyBmcm9tIG91ciBhc3NldHMgZG9tYWluLiAgTm90aWNlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gKiBhbmQgKiouCiAqICAgICAgJ2h0dHA6Ly9zcnYqLmFzc2V0cy5leGFtcGxlLmNvbS8qKicKICogICAgXSk7CiAqCiAqICAgIC8vIFRoZSBibGFja2xpc3Qgb3ZlcnJpZGVzIHRoZSB3aGl0ZWxpc3Qgc28gdGhlIG9wZW4gcmVkaXJlY3QgaGVyZSBpcyBibG9ja2VkLgogKiAgICAkc2NlRGVsZWdhdGVQcm92aWRlci5yZXNvdXJjZVVybEJsYWNrbGlzdChbCiAqICAgICAgJ2h0dHA6Ly9teWFwcC5leGFtcGxlLmNvbS9jbGlja1RocnUqKicKICogICAgXSk7CiAqICB9KTsKICogYGBgCiAqLwoKZnVuY3Rpb24gJFNjZURlbGVnYXRlUHJvdmlkZXIoKSB7CiAgdGhpcy5TQ0VfQ09OVEVYVFMgPSBTQ0VfQ09OVEVYVFM7CgogIC8vIFJlc291cmNlIFVSTHMgY2FuIGFsc28gYmUgdHJ1c3RlZCBieSBwb2xpY3kuCiAgdmFyIHJlc291cmNlVXJsV2hpdGVsaXN0ID0gWydzZWxmJ10sCiAgICAgIHJlc291cmNlVXJsQmxhY2tsaXN0ID0gW107CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkc2NlRGVsZWdhdGVQcm92aWRlciNyZXNvdXJjZVVybFdoaXRlbGlzdAogICAqIEBraW5kIGZ1bmN0aW9uCiAgICoKICAgKiBAcGFyYW0ge0FycmF5PX0gd2hpdGVsaXN0IFdoZW4gcHJvdmlkZWQsIHJlcGxhY2VzIHRoZSByZXNvdXJjZVVybFdoaXRlbGlzdCB3aXRoIHRoZSB2YWx1ZQogICAqICAgICBwcm92aWRlZC4gIFRoaXMgbXVzdCBiZSBhbiBhcnJheSBvciBudWxsLiAgQSBzbmFwc2hvdCBvZiB0aGlzIGFycmF5IGlzIHVzZWQgc28gZnVydGhlcgogICAqICAgICBjaGFuZ2VzIHRvIHRoZSBhcnJheSBhcmUgaWdub3JlZC4KICAgKgogICAqICAgICBGb2xsb3cge0BsaW5rIG5nLiRzY2UjcmVzb3VyY2VVcmxQYXR0ZXJuSXRlbSB0aGlzIGxpbmt9IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBpdGVtcwogICAqICAgICBhbGxvd2VkIGluIHRoaXMgYXJyYXkuCiAgICoKICAgKiAgICAgTm90ZTogKiphbiBlbXB0eSB3aGl0ZWxpc3QgYXJyYXkgd2lsbCBibG9jayBhbGwgVVJMcyoqIQogICAqCiAgICogQHJldHVybiB7QXJyYXl9IHRoZSBjdXJyZW50bHkgc2V0IHdoaXRlbGlzdCBhcnJheS4KICAgKgogICAqIFRoZSAqKmRlZmF1bHQgdmFsdWUqKiB3aGVuIG5vIHdoaXRlbGlzdCBoYXMgYmVlbiBleHBsaWNpdGx5IHNldCBpcyBgWydzZWxmJ11gIGFsbG93aW5nIG9ubHkKICAgKiBzYW1lIG9yaWdpbiByZXNvdXJjZSByZXF1ZXN0cy4KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFNldHMvR2V0cyB0aGUgd2hpdGVsaXN0IG9mIHRydXN0ZWQgcmVzb3VyY2UgVVJMcy4KICAgKi8KICB0aGlzLnJlc291cmNlVXJsV2hpdGVsaXN0ID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7CiAgICAgIHJlc291cmNlVXJsV2hpdGVsaXN0ID0gYWRqdXN0TWF0Y2hlcnModmFsdWUpOwogICAgfQogICAgcmV0dXJuIHJlc291cmNlVXJsV2hpdGVsaXN0OwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSAkc2NlRGVsZWdhdGVQcm92aWRlciNyZXNvdXJjZVVybEJsYWNrbGlzdAogICAqIEBraW5kIGZ1bmN0aW9uCiAgICoKICAgKiBAcGFyYW0ge0FycmF5PX0gYmxhY2tsaXN0IFdoZW4gcHJvdmlkZWQsIHJlcGxhY2VzIHRoZSByZXNvdXJjZVVybEJsYWNrbGlzdCB3aXRoIHRoZSB2YWx1ZQogICAqICAgICBwcm92aWRlZC4gIFRoaXMgbXVzdCBiZSBhbiBhcnJheSBvciBudWxsLiAgQSBzbmFwc2hvdCBvZiB0aGlzIGFycmF5IGlzIHVzZWQgc28gZnVydGhlcgogICAqICAgICBjaGFuZ2VzIHRvIHRoZSBhcnJheSBhcmUgaWdub3JlZC4KICAgKgogICAqICAgICBGb2xsb3cge0BsaW5rIG5nLiRzY2UjcmVzb3VyY2VVcmxQYXR0ZXJuSXRlbSB0aGlzIGxpbmt9IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBpdGVtcwogICAqICAgICBhbGxvd2VkIGluIHRoaXMgYXJyYXkuCiAgICoKICAgKiAgICAgVGhlIHR5cGljYWwgdXNhZ2UgZm9yIHRoZSBibGFja2xpc3QgaXMgdG8gKipibG9jawogICAqICAgICBbb3BlbiByZWRpcmVjdHNdKGh0dHA6Ly9jd2UubWl0cmUub3JnL2RhdGEvZGVmaW5pdGlvbnMvNjAxLmh0bWwpKiogc2VydmVkIGJ5IHlvdXIgZG9tYWluIGFzCiAgICogICAgIHRoZXNlIHdvdWxkIG90aGVyd2lzZSBiZSB0cnVzdGVkIGJ1dCBhY3R1YWxseSByZXR1cm4gY29udGVudCBmcm9tIHRoZSByZWRpcmVjdGVkIGRvbWFpbi4KICAgKgogICAqICAgICBGaW5hbGx5LCAqKnRoZSBibGFja2xpc3Qgb3ZlcnJpZGVzIHRoZSB3aGl0ZWxpc3QqKiBhbmQgaGFzIHRoZSBmaW5hbCBzYXkuCiAgICoKICAgKiBAcmV0dXJuIHtBcnJheX0gdGhlIGN1cnJlbnRseSBzZXQgYmxhY2tsaXN0IGFycmF5LgogICAqCiAgICogVGhlICoqZGVmYXVsdCB2YWx1ZSoqIHdoZW4gbm8gd2hpdGVsaXN0IGhhcyBiZWVuIGV4cGxpY2l0bHkgc2V0IGlzIHRoZSBlbXB0eSBhcnJheSAoaS5lLiB0aGVyZQogICAqIGlzIG5vIGJsYWNrbGlzdC4pCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBTZXRzL0dldHMgdGhlIGJsYWNrbGlzdCBvZiB0cnVzdGVkIHJlc291cmNlIFVSTHMuCiAgICovCgogIHRoaXMucmVzb3VyY2VVcmxCbGFja2xpc3QgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHsKICAgICAgcmVzb3VyY2VVcmxCbGFja2xpc3QgPSBhZGp1c3RNYXRjaGVycyh2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gcmVzb3VyY2VVcmxCbGFja2xpc3Q7CiAgfTsKCiAgdGhpcy4kZ2V0ID0gWyckaW5qZWN0b3InLCBmdW5jdGlvbigkaW5qZWN0b3IpIHsKCiAgICB2YXIgaHRtbFNhbml0aXplciA9IGZ1bmN0aW9uIGh0bWxTYW5pdGl6ZXIoaHRtbCkgewogICAgICB0aHJvdyAkc2NlTWluRXJyKCd1bnNhZmUnLCAnQXR0ZW1wdGluZyB0byB1c2UgYW4gdW5zYWZlIHZhbHVlIGluIGEgc2FmZSBjb250ZXh0LicpOwogICAgfTsKCiAgICBpZiAoJGluamVjdG9yLmhhcygnJHNhbml0aXplJykpIHsKICAgICAgaHRtbFNhbml0aXplciA9ICRpbmplY3Rvci5nZXQoJyRzYW5pdGl6ZScpOwogICAgfQoKCiAgICBmdW5jdGlvbiBtYXRjaFVybChtYXRjaGVyLCBwYXJzZWRVcmwpIHsKICAgICAgaWYgKG1hdGNoZXIgPT09ICdzZWxmJykgewogICAgICAgIHJldHVybiB1cmxJc1NhbWVPcmlnaW4ocGFyc2VkVXJsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBkZWZpbml0ZWx5IGEgcmVnZXguICBTZWUgYWRqdXN0TWF0Y2hlcnMoKQogICAgICAgIHJldHVybiAhIW1hdGNoZXIuZXhlYyhwYXJzZWRVcmwuaHJlZik7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpc1Jlc291cmNlVXJsQWxsb3dlZEJ5UG9saWN5KHVybCkgewogICAgICB2YXIgcGFyc2VkVXJsID0gdXJsUmVzb2x2ZSh1cmwudG9TdHJpbmcoKSk7CiAgICAgIHZhciBpLCBuLCBhbGxvd2VkID0gZmFsc2U7CiAgICAgIC8vIEVuc3VyZSB0aGF0IGF0IGxlYXN0IG9uZSBpdGVtIGZyb20gdGhlIHdoaXRlbGlzdCBhbGxvd3MgdGhpcyB1cmwuCiAgICAgIGZvciAoaSA9IDAsIG4gPSByZXNvdXJjZVVybFdoaXRlbGlzdC5sZW5ndGg7IGkgPCBuOyBpKyspIHsKICAgICAgICBpZiAobWF0Y2hVcmwocmVzb3VyY2VVcmxXaGl0ZWxpc3RbaV0sIHBhcnNlZFVybCkpIHsKICAgICAgICAgIGFsbG93ZWQgPSB0cnVlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChhbGxvd2VkKSB7CiAgICAgICAgLy8gRW5zdXJlIHRoYXQgbm8gaXRlbSBmcm9tIHRoZSBibGFja2xpc3QgYmxvY2tlZCB0aGlzIHVybC4KICAgICAgICBmb3IgKGkgPSAwLCBuID0gcmVzb3VyY2VVcmxCbGFja2xpc3QubGVuZ3RoOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgICBpZiAobWF0Y2hVcmwocmVzb3VyY2VVcmxCbGFja2xpc3RbaV0sIHBhcnNlZFVybCkpIHsKICAgICAgICAgICAgYWxsb3dlZCA9IGZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIGFsbG93ZWQ7CiAgICB9CgogICAgZnVuY3Rpb24gZ2VuZXJhdGVIb2xkZXJUeXBlKEJhc2UpIHsKICAgICAgdmFyIGhvbGRlclR5cGUgPSBmdW5jdGlvbiBUcnVzdGVkVmFsdWVIb2xkZXJUeXBlKHRydXN0ZWRWYWx1ZSkgewogICAgICAgIHRoaXMuJCR1bndyYXBUcnVzdGVkVmFsdWUgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIHJldHVybiB0cnVzdGVkVmFsdWU7CiAgICAgICAgfTsKICAgICAgfTsKICAgICAgaWYgKEJhc2UpIHsKICAgICAgICBob2xkZXJUeXBlLnByb3RvdHlwZSA9IG5ldyBCYXNlKCk7CiAgICAgIH0KICAgICAgaG9sZGVyVHlwZS5wcm90b3R5cGUudmFsdWVPZiA9IGZ1bmN0aW9uIHNjZVZhbHVlT2YoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJCR1bndyYXBUcnVzdGVkVmFsdWUoKTsKICAgICAgfTsKICAgICAgaG9sZGVyVHlwZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiBzY2VUb1N0cmluZygpIHsKICAgICAgICByZXR1cm4gdGhpcy4kJHVud3JhcFRydXN0ZWRWYWx1ZSgpLnRvU3RyaW5nKCk7CiAgICAgIH07CiAgICAgIHJldHVybiBob2xkZXJUeXBlOwogICAgfQoKICAgIHZhciB0cnVzdGVkVmFsdWVIb2xkZXJCYXNlID0gZ2VuZXJhdGVIb2xkZXJUeXBlKCksCiAgICAgICAgYnlUeXBlID0ge307CgogICAgYnlUeXBlW1NDRV9DT05URVhUUy5IVE1MXSA9IGdlbmVyYXRlSG9sZGVyVHlwZSh0cnVzdGVkVmFsdWVIb2xkZXJCYXNlKTsKICAgIGJ5VHlwZVtTQ0VfQ09OVEVYVFMuQ1NTXSA9IGdlbmVyYXRlSG9sZGVyVHlwZSh0cnVzdGVkVmFsdWVIb2xkZXJCYXNlKTsKICAgIGJ5VHlwZVtTQ0VfQ09OVEVYVFMuVVJMXSA9IGdlbmVyYXRlSG9sZGVyVHlwZSh0cnVzdGVkVmFsdWVIb2xkZXJCYXNlKTsKICAgIGJ5VHlwZVtTQ0VfQ09OVEVYVFMuSlNdID0gZ2VuZXJhdGVIb2xkZXJUeXBlKHRydXN0ZWRWYWx1ZUhvbGRlckJhc2UpOwogICAgYnlUeXBlW1NDRV9DT05URVhUUy5SRVNPVVJDRV9VUkxdID0gZ2VuZXJhdGVIb2xkZXJUeXBlKGJ5VHlwZVtTQ0VfQ09OVEVYVFMuVVJMXSk7CgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlRGVsZWdhdGUjdHJ1c3RBcwogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBpcyB0cnVzdGVkIGJ5IGFuZ3VsYXIgZm9yIHVzZSBpbiBzcGVjaWZpZWQgc3RyaWN0CiAgICAgKiBjb250ZXh0dWFsIGVzY2FwaW5nIGNvbnRleHRzIChzdWNoIGFzIG5nLWJpbmQtaHRtbCwgbmctaW5jbHVkZSwgYW55IHNyYwogICAgICogYXR0cmlidXRlIGludGVycG9sYXRpb24sIGFueSBkb20gZXZlbnQgYmluZGluZyBhdHRyaWJ1dGUgaW50ZXJwb2xhdGlvbgogICAgICogc3VjaCBhcyBmb3Igb25jbGljaywgIGV0Yy4pIHRoYXQgdXNlcyB0aGUgcHJvdmlkZWQgdmFsdWUuCiAgICAgKiBTZWUge0BsaW5rIG5nLiRzY2UgJHNjZX0gZm9yIGVuYWJsaW5nIHN0cmljdCBjb250ZXh0dWFsIGVzY2FwaW5nLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBraW5kIG9mIGNvbnRleHQgaW4gd2hpY2ggdGhpcyB2YWx1ZSBpcyBzYWZlIGZvciB1c2UuICBlLmcuIHVybCwKICAgICAqICAgcmVzb3VyY2VVcmwsIGh0bWwsIGpzIGFuZCBjc3MuCiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0aGF0IHRoYXQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgdHJ1c3RlZC9zYWZlLgogICAgICogQHJldHVybnMgeyp9IEEgdmFsdWUgdGhhdCBjYW4gYmUgdXNlZCB0byBzdGFuZCBpbiBmb3IgdGhlIHByb3ZpZGVkIGB2YWx1ZWAgaW4gcGxhY2VzCiAgICAgKiB3aGVyZSBBbmd1bGFyIGV4cGVjdHMgYSAkc2NlLnRydXN0QXMoKSByZXR1cm4gdmFsdWUuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRydXN0QXModHlwZSwgdHJ1c3RlZFZhbHVlKSB7CiAgICAgIHZhciBDb25zdHJ1Y3RvciA9IChieVR5cGUuaGFzT3duUHJvcGVydHkodHlwZSkgPyBieVR5cGVbdHlwZV0gOiBudWxsKTsKICAgICAgaWYgKCFDb25zdHJ1Y3RvcikgewogICAgICAgIHRocm93ICRzY2VNaW5FcnIoJ2ljb250ZXh0JywKICAgICAgICAgICAgJ0F0dGVtcHRlZCB0byB0cnVzdCBhIHZhbHVlIGluIGludmFsaWQgY29udGV4dC4gQ29udGV4dDogezB9OyBWYWx1ZTogezF9JywKICAgICAgICAgICAgdHlwZSwgdHJ1c3RlZFZhbHVlKTsKICAgICAgfQogICAgICBpZiAodHJ1c3RlZFZhbHVlID09PSBudWxsIHx8IHRydXN0ZWRWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHRydXN0ZWRWYWx1ZSA9PT0gJycpIHsKICAgICAgICByZXR1cm4gdHJ1c3RlZFZhbHVlOwogICAgICB9CiAgICAgIC8vIEFsbCB0aGUgY3VycmVudCBjb250ZXh0cyBpbiBTQ0VfQ09OVEVYVFMgaGFwcGVuIHRvIGJlIHN0cmluZ3MuICBJbiBvcmRlciB0byBhdm9pZCB0cnVzdGluZwogICAgICAvLyBtdXRhYmxlIG9iamVjdHMsIHdlIGVuc3VyZSBoZXJlIHRoYXQgdGhlIHZhbHVlIHBhc3NlZCBpbiBpcyBhY3R1YWxseSBhIHN0cmluZy4KICAgICAgaWYgKHR5cGVvZiB0cnVzdGVkVmFsdWUgIT09ICdzdHJpbmcnKSB7CiAgICAgICAgdGhyb3cgJHNjZU1pbkVycignaXR5cGUnLAogICAgICAgICAgICAnQXR0ZW1wdGVkIHRvIHRydXN0IGEgbm9uLXN0cmluZyB2YWx1ZSBpbiBhIGNvbnRlbnQgcmVxdWlyaW5nIGEgc3RyaW5nOiBDb250ZXh0OiB7MH0nLAogICAgICAgICAgICB0eXBlKTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRydXN0ZWRWYWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlRGVsZWdhdGUjdmFsdWVPZgogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogSWYgdGhlIHBhc3NlZCBwYXJhbWV0ZXIgaGFkIGJlZW4gcmV0dXJuZWQgYnkgYSBwcmlvciBjYWxsIHRvIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjdHJ1c3RBcwogICAgICogYCRzY2VEZWxlZ2F0ZS50cnVzdEFzYH0sIHJldHVybnMgdGhlIHZhbHVlIHRoYXQgaGFkIGJlZW4gcGFzc2VkIHRvIHtAbGluawogICAgICogbmcuJHNjZURlbGVnYXRlI3RydXN0QXMgYCRzY2VEZWxlZ2F0ZS50cnVzdEFzYH0uCiAgICAgKgogICAgICogSWYgdGhlIHBhc3NlZCBwYXJhbWV0ZXIgaXMgbm90IGEgdmFsdWUgdGhhdCBoYWQgYmVlbiByZXR1cm5lZCBieSB7QGxpbmsKICAgICAqIG5nLiRzY2VEZWxlZ2F0ZSN0cnVzdEFzIGAkc2NlRGVsZWdhdGUudHJ1c3RBc2B9LCByZXR1cm5zIGl0IGFzLWlzLgogICAgICoKICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHJlc3VsdCBvZiBhIHByaW9yIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjdHJ1c3RBcyBgJHNjZURlbGVnYXRlLnRydXN0QXNgfQogICAgICogICAgICBjYWxsIG9yIGFueXRoaW5nIGVsc2UuCiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGB2YWx1ZWAgdGhhdCB3YXMgb3JpZ2luYWxseSBwcm92aWRlZCB0byB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI3RydXN0QXMKICAgICAqICAgICBgJHNjZURlbGVnYXRlLnRydXN0QXNgfSBpZiBgdmFsdWVgIGlzIHRoZSByZXN1bHQgb2Ygc3VjaCBhIGNhbGwuICBPdGhlcndpc2UsIHJldHVybnMKICAgICAqICAgICBgdmFsdWVgIHVuY2hhbmdlZC4KICAgICAqLwogICAgZnVuY3Rpb24gdmFsdWVPZihtYXliZVRydXN0ZWQpIHsKICAgICAgaWYgKG1heWJlVHJ1c3RlZCBpbnN0YW5jZW9mIHRydXN0ZWRWYWx1ZUhvbGRlckJhc2UpIHsKICAgICAgICByZXR1cm4gbWF5YmVUcnVzdGVkLiQkdW53cmFwVHJ1c3RlZFZhbHVlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIG1heWJlVHJ1c3RlZDsKICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZURlbGVnYXRlI2dldFRydXN0ZWQKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFRha2VzIHRoZSByZXN1bHQgb2YgYSB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI3RydXN0QXMgYCRzY2VEZWxlZ2F0ZS50cnVzdEFzYH0gY2FsbCBhbmQKICAgICAqIHJldHVybnMgdGhlIG9yaWdpbmFsbHkgc3VwcGxpZWQgdmFsdWUgaWYgdGhlIHF1ZXJpZWQgY29udGV4dCB0eXBlIGlzIGEgc3VwZXJ0eXBlIG9mIHRoZQogICAgICogY3JlYXRlZCB0eXBlLiAgSWYgdGhpcyBjb25kaXRpb24gaXNuJ3Qgc2F0aXNmaWVkLCB0aHJvd3MgYW4gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBraW5kIG9mIGNvbnRleHQgaW4gd2hpY2ggdGhpcyB2YWx1ZSBpcyB0byBiZSB1c2VkLgogICAgICogQHBhcmFtIHsqfSBtYXliZVRydXN0ZWQgVGhlIHJlc3VsdCBvZiBhIHByaW9yIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjdHJ1c3RBcwogICAgICogICAgIGAkc2NlRGVsZWdhdGUudHJ1c3RBc2B9IGNhbGwuCiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHZhbHVlIHRoZSB3YXMgb3JpZ2luYWxseSBwcm92aWRlZCB0byB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI3RydXN0QXMKICAgICAqICAgICBgJHNjZURlbGVnYXRlLnRydXN0QXNgfSBpZiB2YWxpZCBpbiB0aGlzIGNvbnRleHQuICBPdGhlcndpc2UsIHRocm93cyBhbiBleGNlcHRpb24uCiAgICAgKi8KICAgIGZ1bmN0aW9uIGdldFRydXN0ZWQodHlwZSwgbWF5YmVUcnVzdGVkKSB7CiAgICAgIGlmIChtYXliZVRydXN0ZWQgPT09IG51bGwgfHwgbWF5YmVUcnVzdGVkID09PSB1bmRlZmluZWQgfHwgbWF5YmVUcnVzdGVkID09PSAnJykgewogICAgICAgIHJldHVybiBtYXliZVRydXN0ZWQ7CiAgICAgIH0KICAgICAgdmFyIGNvbnN0cnVjdG9yID0gKGJ5VHlwZS5oYXNPd25Qcm9wZXJ0eSh0eXBlKSA/IGJ5VHlwZVt0eXBlXSA6IG51bGwpOwogICAgICBpZiAoY29uc3RydWN0b3IgJiYgbWF5YmVUcnVzdGVkIGluc3RhbmNlb2YgY29uc3RydWN0b3IpIHsKICAgICAgICByZXR1cm4gbWF5YmVUcnVzdGVkLiQkdW53cmFwVHJ1c3RlZFZhbHVlKCk7CiAgICAgIH0KICAgICAgLy8gSWYgd2UgZ2V0IGhlcmUsIHRoZW4gd2UgbWF5IG9ubHkgdGFrZSBvbmUgb2YgdHdvIGFjdGlvbnMuCiAgICAgIC8vIDEuIHNhbml0aXplIHRoZSB2YWx1ZSBmb3IgdGhlIHJlcXVlc3RlZCB0eXBlLCBvcgogICAgICAvLyAyLiB0aHJvdyBhbiBleGNlcHRpb24uCiAgICAgIGlmICh0eXBlID09PSBTQ0VfQ09OVEVYVFMuUkVTT1VSQ0VfVVJMKSB7CiAgICAgICAgaWYgKGlzUmVzb3VyY2VVcmxBbGxvd2VkQnlQb2xpY3kobWF5YmVUcnVzdGVkKSkgewogICAgICAgICAgcmV0dXJuIG1heWJlVHJ1c3RlZDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhyb3cgJHNjZU1pbkVycignaW5zZWN1cmwnLAogICAgICAgICAgICAgICdCbG9ja2VkIGxvYWRpbmcgcmVzb3VyY2UgZnJvbSB1cmwgbm90IGFsbG93ZWQgYnkgJHNjZURlbGVnYXRlIHBvbGljeS4gIFVSTDogezB9JywKICAgICAgICAgICAgICBtYXliZVRydXN0ZWQudG9TdHJpbmcoKSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFNDRV9DT05URVhUUy5IVE1MKSB7CiAgICAgICAgcmV0dXJuIGh0bWxTYW5pdGl6ZXIobWF5YmVUcnVzdGVkKTsKICAgICAgfQogICAgICB0aHJvdyAkc2NlTWluRXJyKCd1bnNhZmUnLCAnQXR0ZW1wdGluZyB0byB1c2UgYW4gdW5zYWZlIHZhbHVlIGluIGEgc2FmZSBjb250ZXh0LicpOwogICAgfQoKICAgIHJldHVybiB7IHRydXN0QXM6IHRydXN0QXMsCiAgICAgICAgICAgICBnZXRUcnVzdGVkOiBnZXRUcnVzdGVkLAogICAgICAgICAgICAgdmFsdWVPZjogdmFsdWVPZiB9OwogIH1dOwp9CgoKLyoqCiAqIEBuZ2RvYyBwcm92aWRlcgogKiBAbmFtZSAkc2NlUHJvdmlkZXIKICogQGRlc2NyaXB0aW9uCiAqCiAqIFRoZSAkc2NlUHJvdmlkZXIgcHJvdmlkZXIgYWxsb3dzIGRldmVsb3BlcnMgdG8gY29uZmlndXJlIHRoZSB7QGxpbmsgbmcuJHNjZSAkc2NlfSBzZXJ2aWNlLgogKiAtICAgZW5hYmxlL2Rpc2FibGUgU3RyaWN0IENvbnRleHR1YWwgRXNjYXBpbmcgKFNDRSkgaW4gYSBtb2R1bGUKICogLSAgIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHdpdGggYSBjdXN0b20gZGVsZWdhdGUKICoKICogUmVhZCBtb3JlIGFib3V0IHtAbGluayBuZy4kc2NlIFN0cmljdCBDb250ZXh0dWFsIEVzY2FwaW5nIChTQ0UpfS4KICovCgovKiBqc2hpbnQgbWF4bGVuOiBmYWxzZSovCgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJHNjZQogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICoKICogYCRzY2VgIGlzIGEgc2VydmljZSB0aGF0IHByb3ZpZGVzIFN0cmljdCBDb250ZXh0dWFsIEVzY2FwaW5nIHNlcnZpY2VzIHRvIEFuZ3VsYXJKUy4KICoKICogIyBTdHJpY3QgQ29udGV4dHVhbCBFc2NhcGluZwogKgogKiBTdHJpY3QgQ29udGV4dHVhbCBFc2NhcGluZyAoU0NFKSBpcyBhIG1vZGUgaW4gd2hpY2ggQW5ndWxhckpTIHJlcXVpcmVzIGJpbmRpbmdzIGluIGNlcnRhaW4KICogY29udGV4dHMgdG8gcmVzdWx0IGluIGEgdmFsdWUgdGhhdCBpcyBtYXJrZWQgYXMgc2FmZSB0byB1c2UgZm9yIHRoYXQgY29udGV4dC4gIE9uZSBleGFtcGxlIG9mCiAqIHN1Y2ggYSBjb250ZXh0IGlzIGJpbmRpbmcgYXJiaXRyYXJ5IGh0bWwgY29udHJvbGxlZCBieSB0aGUgdXNlciB2aWEgYG5nLWJpbmQtaHRtbGAuICBXZSByZWZlcgogKiB0byB0aGVzZSBjb250ZXh0cyBhcyBwcml2aWxlZ2VkIG9yIFNDRSBjb250ZXh0cy4KICoKICogQXMgb2YgdmVyc2lvbiAxLjIsIEFuZ3VsYXIgc2hpcHMgd2l0aCBTQ0UgZW5hYmxlZCBieSBkZWZhdWx0LgogKgogKiBOb3RlOiAgV2hlbiBlbmFibGVkICh0aGUgZGVmYXVsdCksIElFPDExIGluIHF1aXJrcyBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQuICBJbiB0aGlzIG1vZGUsIElFPDExIGFsbG93CiAqIG9uZSB0byBleGVjdXRlIGFyYml0cmFyeSBqYXZhc2NyaXB0IGJ5IHRoZSB1c2Ugb2YgdGhlIGV4cHJlc3Npb24oKSBzeW50YXguICBSZWZlcgogKiA8aHR0cDovL2Jsb2dzLm1zZG4uY29tL2IvaWUvYXJjaGl2ZS8yMDA4LzEwLzE2L2VuZGluZy1leHByZXNzaW9ucy5hc3B4PiB0byBsZWFybiBtb3JlIGFib3V0IHRoZW0uCiAqIFlvdSBjYW4gZW5zdXJlIHlvdXIgZG9jdW1lbnQgaXMgaW4gc3RhbmRhcmRzIG1vZGUgYW5kIG5vdCBxdWlya3MgbW9kZSBieSBhZGRpbmcgYDwhZG9jdHlwZSBodG1sPmAKICogdG8gdGhlIHRvcCBvZiB5b3VyIEhUTUwgZG9jdW1lbnQuCiAqCiAqIFNDRSBhc3Npc3RzIGluIHdyaXRpbmcgY29kZSBpbiB3YXkgdGhhdCAoYSkgaXMgc2VjdXJlIGJ5IGRlZmF1bHQgYW5kIChiKSBtYWtlcyBhdWRpdGluZyBmb3IKICogc2VjdXJpdHkgdnVsbmVyYWJpbGl0aWVzIHN1Y2ggYXMgWFNTLCBjbGlja2phY2tpbmcsIGV0Yy4gYSBsb3QgZWFzaWVyLgogKgogKiBIZXJlJ3MgYW4gZXhhbXBsZSBvZiBhIGJpbmRpbmcgaW4gYSBwcml2aWxlZ2VkIGNvbnRleHQ6CiAqCiAqIGBgYAogKiA8aW5wdXQgbmctbW9kZWw9InVzZXJIdG1sIj4KICogPGRpdiBuZy1iaW5kLWh0bWw9InVzZXJIdG1sIj48L2Rpdj4KICogYGBgCiAqCiAqIE5vdGljZSB0aGF0IGBuZy1iaW5kLWh0bWxgIGlzIGJvdW5kIHRvIGB1c2VySHRtbGAgY29udHJvbGxlZCBieSB0aGUgdXNlci4gIFdpdGggU0NFCiAqIGRpc2FibGVkLCB0aGlzIGFwcGxpY2F0aW9uIGFsbG93cyB0aGUgdXNlciB0byByZW5kZXIgYXJiaXRyYXJ5IEhUTUwgaW50byB0aGUgRElWLgogKiBJbiBhIG1vcmUgcmVhbGlzdGljIGV4YW1wbGUsIG9uZSBtYXkgYmUgcmVuZGVyaW5nIHVzZXIgY29tbWVudHMsIGJsb2cgYXJ0aWNsZXMsIGV0Yy4gdmlhCiAqIGJpbmRpbmdzLiAgKEhUTUwgaXMganVzdCBvbmUgZXhhbXBsZSBvZiBhIGNvbnRleHQgd2hlcmUgcmVuZGVyaW5nIHVzZXIgY29udHJvbGxlZCBpbnB1dCBjcmVhdGVzCiAqIHNlY3VyaXR5IHZ1bG5lcmFiaWxpdGllcy4pCiAqCiAqIEZvciB0aGUgY2FzZSBvZiBIVE1MLCB5b3UgbWlnaHQgdXNlIGEgbGlicmFyeSwgZWl0aGVyIG9uIHRoZSBjbGllbnQgc2lkZSwgb3Igb24gdGhlIHNlcnZlciBzaWRlLAogKiB0byBzYW5pdGl6ZSB1bnNhZmUgSFRNTCBiZWZvcmUgYmluZGluZyB0byB0aGUgdmFsdWUgYW5kIHJlbmRlcmluZyBpdCBpbiB0aGUgZG9jdW1lbnQuCiAqCiAqIEhvdyB3b3VsZCB5b3UgZW5zdXJlIHRoYXQgZXZlcnkgcGxhY2UgdGhhdCB1c2VkIHRoZXNlIHR5cGVzIG9mIGJpbmRpbmdzIHdhcyBib3VuZCB0byBhIHZhbHVlIHRoYXQKICogd2FzIHNhbml0aXplZCBieSB5b3VyIGxpYnJhcnkgKG9yIHJldHVybmVkIGFzIHNhZmUgZm9yIHJlbmRlcmluZyBieSB5b3VyIHNlcnZlcj8pICBIb3cgY2FuIHlvdQogKiBlbnN1cmUgdGhhdCB5b3UgZGlkbid0IGFjY2lkZW50YWxseSBkZWxldGUgdGhlIGxpbmUgdGhhdCBzYW5pdGl6ZWQgdGhlIHZhbHVlLCBvciByZW5hbWVkIHNvbWUKICogcHJvcGVydGllcy9maWVsZHMgYW5kIGZvcmdvdCB0byB1cGRhdGUgdGhlIGJpbmRpbmcgdG8gdGhlIHNhbml0aXplZCB2YWx1ZT8KICoKICogVG8gYmUgc2VjdXJlIGJ5IGRlZmF1bHQsIHlvdSB3YW50IHRvIGVuc3VyZSB0aGF0IGFueSBzdWNoIGJpbmRpbmdzIGFyZSBkaXNhbGxvd2VkIHVubGVzcyB5b3UgY2FuCiAqIGRldGVybWluZSB0aGF0IHNvbWV0aGluZyBleHBsaWNpdGx5IHNheXMgaXQncyBzYWZlIHRvIHVzZSBhIHZhbHVlIGZvciBiaW5kaW5nIGluIHRoYXQKICogY29udGV4dC4gIFlvdSBjYW4gdGhlbiBhdWRpdCB5b3VyIGNvZGUgKGEgc2ltcGxlIGdyZXAgd291bGQgZG8pIHRvIGVuc3VyZSB0aGF0IHRoaXMgaXMgb25seSBkb25lCiAqIGZvciB0aG9zZSB2YWx1ZXMgdGhhdCB5b3UgY2FuIGVhc2lseSB0ZWxsIGFyZSBzYWZlIC0gYmVjYXVzZSB0aGV5IHdlcmUgcmVjZWl2ZWQgZnJvbSB5b3VyIHNlcnZlciwKICogc2FuaXRpemVkIGJ5IHlvdXIgbGlicmFyeSwgZXRjLiAgWW91IGNhbiBvcmdhbml6ZSB5b3VyIGNvZGViYXNlIHRvIGhlbHAgd2l0aCB0aGlzIC0gcGVyaGFwcwogKiBhbGxvd2luZyBvbmx5IHRoZSBmaWxlcyBpbiBhIHNwZWNpZmljIGRpcmVjdG9yeSB0byBkbyB0aGlzLiAgRW5zdXJpbmcgdGhhdCB0aGUgaW50ZXJuYWwgQVBJCiAqIGV4cG9zZWQgYnkgdGhhdCBjb2RlIGRvZXNuJ3QgbWFya3VwIGFyYml0cmFyeSB2YWx1ZXMgYXMgc2FmZSB0aGVuIGJlY29tZXMgYSBtb3JlIG1hbmFnZWFibGUgdGFzay4KICoKICogSW4gdGhlIGNhc2Ugb2YgQW5ndWxhckpTJyBTQ0Ugc2VydmljZSwgb25lIHVzZXMge0BsaW5rIG5nLiRzY2UjdHJ1c3RBcyAkc2NlLnRydXN0QXN9CiAqIChhbmQgc2hvcnRoYW5kIG1ldGhvZHMgc3VjaCBhcyB7QGxpbmsgbmcuJHNjZSN0cnVzdEFzSHRtbCAkc2NlLnRydXN0QXNIdG1sfSwgZXRjLikgdG8KICogb2J0YWluIHZhbHVlcyB0aGF0IHdpbGwgYmUgYWNjZXB0ZWQgYnkgU0NFIC8gcHJpdmlsZWdlZCBjb250ZXh0cy4KICoKICoKICogIyMgSG93IGRvZXMgaXQgd29yaz8KICoKICogSW4gcHJpdmlsZWdlZCBjb250ZXh0cywgZGlyZWN0aXZlcyBhbmQgY29kZSB3aWxsIGJpbmQgdG8gdGhlIHJlc3VsdCBvZiB7QGxpbmsgbmcuJHNjZSNnZXRUcnVzdGVkCiAqICRzY2UuZ2V0VHJ1c3RlZChjb250ZXh0LCB2YWx1ZSl9IHJhdGhlciB0aGFuIHRvIHRoZSB2YWx1ZSBkaXJlY3RseS4gIERpcmVjdGl2ZXMgdXNlIHtAbGluawogKiBuZy4kc2NlI3BhcnNlQXMgJHNjZS5wYXJzZUFzfSByYXRoZXIgdGhhbiBgJHBhcnNlYCB0byB3YXRjaCBhdHRyaWJ1dGUgYmluZGluZ3MsIHdoaWNoIHBlcmZvcm1zIHRoZQogKiB7QGxpbmsgbmcuJHNjZSNnZXRUcnVzdGVkICRzY2UuZ2V0VHJ1c3RlZH0gYmVoaW5kIHRoZSBzY2VuZXMgb24gbm9uLWNvbnN0YW50IGxpdGVyYWxzLgogKgogKiBBcyBhbiBleGFtcGxlLCB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQmluZEh0bWwgbmdCaW5kSHRtbH0gdXNlcyB7QGxpbmsKICogbmcuJHNjZSNwYXJzZUFzSHRtbCAkc2NlLnBhcnNlQXNIdG1sKGJpbmRpbmcgZXhwcmVzc2lvbil9LiAgSGVyZSdzIHRoZSBhY3R1YWwgY29kZSAoc2xpZ2h0bHkKICogc2ltcGxpZmllZCk6CiAqCiAqIGBgYAogKiB2YXIgbmdCaW5kSHRtbERpcmVjdGl2ZSA9IFsnJHNjZScsIGZ1bmN0aW9uKCRzY2UpIHsKICogICByZXR1cm4gZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIpIHsKICogICAgIHNjb3BlLiR3YXRjaCgkc2NlLnBhcnNlQXNIdG1sKGF0dHIubmdCaW5kSHRtbCksIGZ1bmN0aW9uKHZhbHVlKSB7CiAqICAgICAgIGVsZW1lbnQuaHRtbCh2YWx1ZSB8fCAnJyk7CiAqICAgICB9KTsKICogICB9OwogKiB9XTsKICogYGBgCiAqCiAqICMjIEltcGFjdCBvbiBsb2FkaW5nIHRlbXBsYXRlcwogKgogKiBUaGlzIGFwcGxpZXMgYm90aCB0byB0aGUge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ0luY2x1ZGUgYG5nLWluY2x1ZGVgfSBkaXJlY3RpdmUgYXMgd2VsbCBhcwogKiBgdGVtcGxhdGVVcmxgJ3Mgc3BlY2lmaWVkIGJ5IHtAbGluayBndWlkZS9kaXJlY3RpdmUgZGlyZWN0aXZlc30uCiAqCiAqIEJ5IGRlZmF1bHQsIEFuZ3VsYXIgb25seSBsb2FkcyB0ZW1wbGF0ZXMgZnJvbSB0aGUgc2FtZSBkb21haW4gYW5kIHByb3RvY29sIGFzIHRoZSBhcHBsaWNhdGlvbgogKiBkb2N1bWVudC4gIFRoaXMgaXMgZG9uZSBieSBjYWxsaW5nIHtAbGluayBuZy4kc2NlI2dldFRydXN0ZWRSZXNvdXJjZVVybAogKiAkc2NlLmdldFRydXN0ZWRSZXNvdXJjZVVybH0gb24gdGhlIHRlbXBsYXRlIFVSTC4gIFRvIGxvYWQgdGVtcGxhdGVzIGZyb20gb3RoZXIgZG9tYWlucyBhbmQvb3IKICogcHJvdG9jb2xzLCB5b3UgbWF5IGVpdGhlciBlaXRoZXIge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsV2hpdGVsaXN0IHdoaXRlbGlzdAogKiB0aGVtfSBvciB7QGxpbmsgbmcuJHNjZSN0cnVzdEFzUmVzb3VyY2VVcmwgd3JhcCBpdH0gaW50byBhIHRydXN0ZWQgdmFsdWUuCiAqCiAqICpQbGVhc2Ugbm90ZSo6CiAqIFRoZSBicm93c2VyJ3MKICogW1NhbWUgT3JpZ2luIFBvbGljeV0oaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9icm93c2Vyc2VjL3dpa2kvUGFydDIjU2FtZS1vcmlnaW5fcG9saWN5X2Zvcl9YTUxIdHRwUmVxdWVzdCkKICogYW5kIFtDcm9zcy1PcmlnaW4gUmVzb3VyY2UgU2hhcmluZyAoQ09SUyldKGh0dHA6Ly93d3cudzMub3JnL1RSL2NvcnMvKQogKiBwb2xpY3kgYXBwbHkgaW4gYWRkaXRpb24gdG8gdGhpcyBhbmQgbWF5IGZ1cnRoZXIgcmVzdHJpY3Qgd2hldGhlciB0aGUgdGVtcGxhdGUgaXMgc3VjY2Vzc2Z1bGx5CiAqIGxvYWRlZC4gIFRoaXMgbWVhbnMgdGhhdCB3aXRob3V0IHRoZSByaWdodCBDT1JTIHBvbGljeSwgbG9hZGluZyB0ZW1wbGF0ZXMgZnJvbSBhIGRpZmZlcmVudCBkb21haW4KICogd29uJ3Qgd29yayBvbiBhbGwgYnJvd3NlcnMuICBBbHNvLCBsb2FkaW5nIHRlbXBsYXRlcyBmcm9tIGBmaWxlOi8vYCBVUkwgZG9lcyBub3Qgd29yayBvbiBzb21lCiAqIGJyb3dzZXJzLgogKgogKiAjIyBUaGlzIGZlZWxzIGxpa2UgdG9vIG11Y2ggb3ZlcmhlYWQKICoKICogSXQncyBpbXBvcnRhbnQgdG8gcmVtZW1iZXIgdGhhdCBTQ0Ugb25seSBhcHBsaWVzIHRvIGludGVycG9sYXRpb24gZXhwcmVzc2lvbnMuCiAqCiAqIElmIHlvdXIgZXhwcmVzc2lvbnMgYXJlIGNvbnN0YW50IGxpdGVyYWxzLCB0aGV5J3JlIGF1dG9tYXRpY2FsbHkgdHJ1c3RlZCBhbmQgeW91IGRvbid0IG5lZWQgdG8KICogY2FsbCBgJHNjZS50cnVzdEFzYCBvbiB0aGVtIChyZW1lbWJlciB0byBpbmNsdWRlIHRoZSBgbmdTYW5pdGl6ZWAgbW9kdWxlKSAoZS5nLgogKiBgPGRpdiBuZy1iaW5kLWh0bWw9Iic8Yj5pbXBsaWNpdGx5IHRydXN0ZWQ8L2I+JyI+PC9kaXY+YCkganVzdCB3b3Jrcy4KICoKICogQWRkaXRpb25hbGx5LCBgYVtocmVmXWAgYW5kIGBpbWdbc3JjXWAgYXV0b21hdGljYWxseSBzYW5pdGl6ZSB0aGVpciBVUkxzIGFuZCBkbyBub3QgcGFzcyB0aGVtCiAqIHRocm91Z2gge0BsaW5rIG5nLiRzY2UjZ2V0VHJ1c3RlZCAkc2NlLmdldFRydXN0ZWR9LiAgU0NFIGRvZXNuJ3QgcGxheSBhIHJvbGUgaGVyZS4KICoKICogVGhlIGluY2x1ZGVkIHtAbGluayBuZy4kc2NlRGVsZWdhdGUgJHNjZURlbGVnYXRlfSBjb21lcyB3aXRoIHNhbmUgZGVmYXVsdHMgdG8gYWxsb3cgeW91IHRvIGxvYWQKICogdGVtcGxhdGVzIGluIGBuZy1pbmNsdWRlYCBmcm9tIHlvdXIgYXBwbGljYXRpb24ncyBkb21haW4gd2l0aG91dCBoYXZpbmcgdG8gZXZlbiBrbm93IGFib3V0IFNDRS4KICogSXQgYmxvY2tzIGxvYWRpbmcgdGVtcGxhdGVzIGZyb20gb3RoZXIgZG9tYWlucyBvciBsb2FkaW5nIHRlbXBsYXRlcyBvdmVyIGh0dHAgZnJvbSBhbiBodHRwcwogKiBzZXJ2ZWQgZG9jdW1lbnQuICBZb3UgY2FuIGNoYW5nZSB0aGVzZSBieSBzZXR0aW5nIHlvdXIgb3duIGN1c3RvbSB7QGxpbmsKICogbmcuJHNjZURlbGVnYXRlUHJvdmlkZXIjcmVzb3VyY2VVcmxXaGl0ZWxpc3Qgd2hpdGVsaXN0c30gYW5kIHtAbGluawogKiBuZy4kc2NlRGVsZWdhdGVQcm92aWRlciNyZXNvdXJjZVVybEJsYWNrbGlzdCBibGFja2xpc3RzfSBmb3IgbWF0Y2hpbmcgc3VjaCBVUkxzLgogKgogKiBUaGlzIHNpZ25pZmljYW50bHkgcmVkdWNlcyB0aGUgb3ZlcmhlYWQuICBJdCBpcyBmYXIgZWFzaWVyIHRvIHBheSB0aGUgc21hbGwgb3ZlcmhlYWQgYW5kIGhhdmUgYW4KICogYXBwbGljYXRpb24gdGhhdCdzIHNlY3VyZSBhbmQgY2FuIGJlIGF1ZGl0ZWQgdG8gdmVyaWZ5IHRoYXQgd2l0aCBtdWNoIG1vcmUgZWFzZSB0aGFuIGJvbHRpbmcKICogc2VjdXJpdHkgb250byBhbiBhcHBsaWNhdGlvbiBsYXRlci4KICoKICogPGEgbmFtZT0iY29udGV4dHMiPjwvYT4KICogIyMgV2hhdCB0cnVzdGVkIGNvbnRleHQgdHlwZXMgYXJlIHN1cHBvcnRlZD8KICoKICogfCBDb250ZXh0ICAgICAgICAgICAgIHwgTm90ZXMgICAgICAgICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18CiAqIHwgYCRzY2UuSFRNTGAgICAgICAgICB8IEZvciBIVE1MIHRoYXQncyBzYWZlIHRvIHNvdXJjZSBpbnRvIHRoZSBhcHBsaWNhdGlvbi4gIFRoZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQmluZEh0bWwgbmdCaW5kSHRtbH0gZGlyZWN0aXZlIHVzZXMgdGhpcyBjb250ZXh0IGZvciBiaW5kaW5ncy4gSWYgYW4gdW5zYWZlIHZhbHVlIGlzIGVuY291bnRlcmVkIGFuZCB0aGUge0BsaW5rIG5nU2FuaXRpemUgJHNhbml0aXplfSBtb2R1bGUgaXMgcHJlc2VudCB0aGlzIHdpbGwgc2FuaXRpemUgdGhlIHZhbHVlIGluc3RlYWQgb2YgdGhyb3dpbmcgYW4gZXJyb3IuIHwKICogfCBgJHNjZS5DU1NgICAgICAgICAgIHwgRm9yIENTUyB0aGF0J3Mgc2FmZSB0byBzb3VyY2UgaW50byB0aGUgYXBwbGljYXRpb24uICBDdXJyZW50bHkgdW51c2VkLiAgRmVlbCBmcmVlIHRvIHVzZSBpdCBpbiB5b3VyIG93biBkaXJlY3RpdmVzLiB8CiAqIHwgYCRzY2UuVVJMYCAgICAgICAgICB8IEZvciBVUkxzIHRoYXQgYXJlIHNhZmUgdG8gZm9sbG93IGFzIGxpbmtzLiAgQ3VycmVudGx5IHVudXNlZCAoYDxhIGhyZWY9YCBhbmQgYDxpbWcgc3JjPWAgc2FuaXRpemUgdGhlaXIgdXJscyBhbmQgZG9uJ3QgY29uc3RpdHV0ZSBhbiBTQ0UgY29udGV4dC4gfAogKiB8IGAkc2NlLlJFU09VUkNFX1VSTGAgfCBGb3IgVVJMcyB0aGF0IGFyZSBub3Qgb25seSBzYWZlIHRvIGZvbGxvdyBhcyBsaW5rcywgYnV0IHdob3NlIGNvbnRlbnRzIGFyZSBhbHNvIHNhZmUgdG8gaW5jbHVkZSBpbiB5b3VyIGFwcGxpY2F0aW9uLiAgRXhhbXBsZXMgaW5jbHVkZSBgbmctaW5jbHVkZWAsIGBzcmNgIC8gYG5nU3JjYCBiaW5kaW5ncyBmb3IgdGFncyBvdGhlciB0aGFuIGBJTUdgIChlLmcuIGBJRlJBTUVgLCBgT0JKRUNUYCwgZXRjLikgIDxicj48YnI+Tm90ZSB0aGF0IGAkc2NlLlJFU09VUkNFX1VSTGAgbWFrZXMgYSBzdHJvbmdlciBzdGF0ZW1lbnQgYWJvdXQgdGhlIFVSTCB0aGFuIGAkc2NlLlVSTGAgZG9lcyBhbmQgdGhlcmVmb3JlIGNvbnRleHRzIHJlcXVpcmluZyB2YWx1ZXMgdHJ1c3RlZCBmb3IgYCRzY2UuUkVTT1VSQ0VfVVJMYCBjYW4gYmUgdXNlZCBhbnl3aGVyZSB0aGF0IHZhbHVlcyB0cnVzdGVkIGZvciBgJHNjZS5VUkxgIGFyZSByZXF1aXJlZC4gfAogKiB8IGAkc2NlLkpTYCAgICAgICAgICAgfCBGb3IgSmF2YVNjcmlwdCB0aGF0IGlzIHNhZmUgdG8gZXhlY3V0ZSBpbiB5b3VyIGFwcGxpY2F0aW9uJ3MgY29udGV4dC4gIEN1cnJlbnRseSB1bnVzZWQuICBGZWVsIGZyZWUgdG8gdXNlIGl0IGluIHlvdXIgb3duIGRpcmVjdGl2ZXMuIHwKICoKICogIyMgRm9ybWF0IG9mIGl0ZW1zIGluIHtAbGluayBuZy4kc2NlRGVsZWdhdGVQcm92aWRlciNyZXNvdXJjZVVybFdoaXRlbGlzdCByZXNvdXJjZVVybFdoaXRlbGlzdH0ve0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZVByb3ZpZGVyI3Jlc291cmNlVXJsQmxhY2tsaXN0IEJsYWNrbGlzdH0gPGEgbmFtZT0icmVzb3VyY2VVcmxQYXR0ZXJuSXRlbSI+PC9hPgogKgogKiAgRWFjaCBlbGVtZW50IGluIHRoZXNlIGFycmF5cyBtdXN0IGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOgogKgogKiAgLSAqKidzZWxmJyoqCiAqICAgIC0gVGhlIHNwZWNpYWwgKipzdHJpbmcqKiwgYCdzZWxmJ2AsIGNhbiBiZSB1c2VkIHRvIG1hdGNoIGFnYWluc3QgYWxsIFVSTHMgb2YgdGhlICoqc2FtZQogKiAgICAgIGRvbWFpbioqIGFzIHRoZSBhcHBsaWNhdGlvbiBkb2N1bWVudCB1c2luZyB0aGUgKipzYW1lIHByb3RvY29sKiouCiAqICAtICoqU3RyaW5nKiogKGV4Y2VwdCB0aGUgc3BlY2lhbCB2YWx1ZSBgJ3NlbGYnYCkKICogICAgLSBUaGUgc3RyaW5nIGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgZnVsbCAqbm9ybWFsaXplZCAvIGFic29sdXRlIFVSTCogb2YgdGhlIHJlc291cmNlCiAqICAgICAgYmVpbmcgdGVzdGVkIChzdWJzdHJpbmcgbWF0Y2hlcyBhcmUgbm90IGdvb2QgZW5vdWdoLikKICogICAgLSBUaGVyZSBhcmUgZXhhY3RseSAqKnR3byB3aWxkY2FyZCBzZXF1ZW5jZXMqKiAtIGAqYCBhbmQgYCoqYC4gIEFsbCBvdGhlciBjaGFyYWN0ZXJzCiAqICAgICAgbWF0Y2ggdGhlbXNlbHZlcy4KICogICAgLSBgKmA6IG1hdGNoZXMgemVybyBvciBtb3JlIG9jY3VycmVuY2VzIG9mIGFueSBjaGFyYWN0ZXIgb3RoZXIgdGhhbiBvbmUgb2YgdGhlIGZvbGxvd2luZyA2CiAqICAgICAgY2hhcmFjdGVyczogJ2A6YCcsICdgL2AnLCAnYC5gJywgJ2A/YCcsICdgJmAnIGFuZCAnOycuICBJdCdzIGEgdXNlZnVsIHdpbGRjYXJkIGZvciB1c2UKICogICAgICBpbiBhIHdoaXRlbGlzdC4KICogICAgLSBgKipgOiBtYXRjaGVzIHplcm8gb3IgbW9yZSBvY2N1cnJlbmNlcyBvZiAqYW55KiBjaGFyYWN0ZXIuICBBcyBzdWNoLCBpdCdzIG5vdAogKiAgICAgIG5vdCBhcHByb3ByaWF0ZSB0byB1c2UgaW4gZm9yIGEgc2NoZW1lLCBkb21haW4sIGV0Yy4gYXMgaXQgd291bGQgbWF0Y2ggdG9vIG11Y2guICAoZS5nLgogKiAgICAgIGh0dHA6Ly8qKi5leGFtcGxlLmNvbS8gd291bGQgbWF0Y2ggaHR0cDovL2V2aWwuY29tLz9pZ25vcmU9LmV4YW1wbGUuY29tLyBhbmQgdGhhdCBtaWdodAogKiAgICAgIG5vdCBoYXZlIGJlZW4gdGhlIGludGVudGlvbi4pICBJdHMgdXNhZ2UgYXQgdGhlIHZlcnkgZW5kIG9mIHRoZSBwYXRoIGlzIG9rLiAgKGUuZy4KICogICAgICBodHRwOi8vZm9vLmV4YW1wbGUuY29tL3RlbXBsYXRlcy8qKikuCiAqICAtICoqUmVnRXhwKiogKCpzZWUgY2F2ZWF0IGJlbG93KikKICogICAgLSAqQ2F2ZWF0KjogIFdoaWxlIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIHBvd2VyZnVsIGFuZCBvZmZlciBncmVhdCBmbGV4aWJpbGl0eSwgIHRoZWlyIHN5bnRheAogKiAgICAgIChhbmQgYWxsIHRoZSBpbmV2aXRhYmxlIGVzY2FwaW5nKSBtYWtlcyB0aGVtICpoYXJkZXIgdG8gbWFpbnRhaW4qLiAgSXQncyBlYXN5IHRvCiAqICAgICAgYWNjaWRlbnRhbGx5IGludHJvZHVjZSBhIGJ1ZyB3aGVuIG9uZSB1cGRhdGVzIGEgY29tcGxleCBleHByZXNzaW9uIChpbWhvLCBhbGwgcmVnZXhlcyBzaG91bGQKICogICAgICBoYXZlIGdvb2QgdGVzdCBjb3ZlcmFnZS4pLiAgRm9yIGluc3RhbmNlLCB0aGUgdXNlIG9mIGAuYCBpbiB0aGUgcmVnZXggaXMgY29ycmVjdCBvbmx5IGluIGEKICogICAgICBzbWFsbCBudW1iZXIgb2YgY2FzZXMuICBBIGAuYCBjaGFyYWN0ZXIgaW4gdGhlIHJlZ2V4IHVzZWQgd2hlbiBtYXRjaGluZyB0aGUgc2NoZW1lIG9yIGEKICogICAgICBzdWJkb21haW4gY291bGQgYmUgbWF0Y2hlZCBhZ2FpbnN0IGEgYDpgIG9yIGxpdGVyYWwgYC5gIHRoYXQgd2FzIGxpa2VseSBub3QgaW50ZW5kZWQuICAgSXQKICogICAgICBpcyBoaWdobHkgcmVjb21tZW5kZWQgdG8gdXNlIHRoZSBzdHJpbmcgcGF0dGVybnMgYW5kIG9ubHkgZmFsbCBiYWNrIHRvIHJlZ3VsYXIgZXhwcmVzc2lvbnMKICogICAgICBpZiB0aGV5IGFzIGEgbGFzdCByZXNvcnQuCiAqICAgIC0gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFJlZ0V4cCAoaS5lLiBub3QgYSBzdHJpbmcuKSAgSXQgaXMKICogICAgICBtYXRjaGVkIGFnYWluc3QgdGhlICoqZW50aXJlKiogKm5vcm1hbGl6ZWQgLyBhYnNvbHV0ZSBVUkwqIG9mIHRoZSByZXNvdXJjZSBiZWluZyB0ZXN0ZWQKICogICAgICAoZXZlbiB3aGVuIHRoZSBSZWdFeHAgZGlkIG5vdCBoYXZlIHRoZSBgXmAgYW5kIGAkYCBjb2Rlcy4pICBJbiBhZGRpdGlvbiwgYW55IGZsYWdzCiAqICAgICAgcHJlc2VudCBvbiB0aGUgUmVnRXhwIChzdWNoIGFzIG11bHRpbGluZSwgZ2xvYmFsLCBpZ25vcmVDYXNlKSBhcmUgaWdub3JlZC4KICogICAgLSBJZiB5b3UgYXJlIGdlbmVyYXRpbmcgeW91ciBKYXZhU2NyaXB0IGZyb20gc29tZSBvdGhlciB0ZW1wbGF0aW5nIGVuZ2luZSAobm90CiAqICAgICAgcmVjb21tZW5kZWQsIGUuZy4gaW4gaXNzdWUgWyM0MDA2XShodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2lzc3Vlcy80MDA2KSksCiAqICAgICAgcmVtZW1iZXIgdG8gZXNjYXBlIHlvdXIgcmVndWxhciBleHByZXNzaW9uIChhbmQgYmUgYXdhcmUgdGhhdCB5b3UgbWlnaHQgbmVlZCBtb3JlIHRoYW4KICogICAgICBvbmUgbGV2ZWwgb2YgZXNjYXBpbmcgZGVwZW5kaW5nIG9uIHlvdXIgdGVtcGxhdGluZyBlbmdpbmUgYW5kIHRoZSB3YXkgeW91IGludGVycG9sYXRlZAogKiAgICAgIHRoZSB2YWx1ZS4pICBEbyBtYWtlIHVzZSBvZiB5b3VyIHBsYXRmb3JtJ3MgZXNjYXBpbmcgbWVjaGFuaXNtIGFzIGl0IG1pZ2h0IGJlIGdvb2QKICogICAgICBlbm91Z2ggYmVmb3JlIGNvZGluZyB5b3VyIG93bi4gIGUuZy4gUnVieSBoYXMKICogICAgICBbUmVnZXhwLmVzY2FwZShzdHIpXShodHRwOi8vd3d3LnJ1YnktZG9jLm9yZy9jb3JlLTIuMC4wL1JlZ2V4cC5odG1sI21ldGhvZC1jLWVzY2FwZSkKICogICAgICBhbmQgUHl0aG9uIGhhcyBbcmUuZXNjYXBlXShodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvcmUuaHRtbCNyZS5lc2NhcGUpLgogKiAgICAgIEphdmFzY3JpcHQgbGFja3MgYSBzaW1pbGFyIGJ1aWx0IGluIGZ1bmN0aW9uIGZvciBlc2NhcGluZy4gIFRha2UgYSBsb29rIGF0IEdvb2dsZQogKiAgICAgIENsb3N1cmUgbGlicmFyeSdzIFtnb29nLnN0cmluZy5yZWdFeHBFc2NhcGUocyldKAogKiAgICAgIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX3N0cmluZ19zdHJpbmcuanMuc291cmNlLmh0bWwjbGluZTk2MikuCiAqCiAqIFJlZmVyIHtAbGluayBuZy4kc2NlRGVsZWdhdGVQcm92aWRlciAkc2NlRGVsZWdhdGVQcm92aWRlcn0gZm9yIGFuIGV4YW1wbGUuCiAqCiAqICMjIFNob3cgbWUgYW4gZXhhbXBsZSB1c2luZyBTQ0UuCiAqCiAqIDxleGFtcGxlIG1vZHVsZT0ibXlTY2VBcHAiIGRlcHM9ImFuZ3VsYXItc2FuaXRpemUuanMiPgogKiA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICogICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkFwcENvbnRyb2xsZXIgYXMgbXlDdHJsIj4KICogICAgIDxpIG5nLWJpbmQtaHRtbD0ibXlDdHJsLmV4cGxpY2l0bHlUcnVzdGVkSHRtbCIgaWQ9ImV4cGxpY2l0bHlUcnVzdGVkSHRtbCI+PC9pPjxicj48YnI+CiAqICAgICA8Yj5Vc2VyIGNvbW1lbnRzPC9iPjxicj4KICogICAgIEJ5IGRlZmF1bHQsIEhUTUwgdGhhdCBpc24ndCBleHBsaWNpdGx5IHRydXN0ZWQgKGUuZy4gQWxpY2UncyBjb21tZW50KSBpcyBzYW5pdGl6ZWQgd2hlbgogKiAgICAgJHNhbml0aXplIGlzIGF2YWlsYWJsZS4gIElmICRzYW5pdGl6ZSBpc24ndCBhdmFpbGFibGUsIHRoaXMgcmVzdWx0cyBpbiBhbiBlcnJvciBpbnN0ZWFkIG9mIGFuCiAqICAgICBleHBsb2l0LgogKiAgICAgPGRpdiBjbGFzcz0id2VsbCI+CiAqICAgICAgIDxkaXYgbmctcmVwZWF0PSJ1c2VyQ29tbWVudCBpbiBteUN0cmwudXNlckNvbW1lbnRzIj4KICogICAgICAgICA8Yj57e3VzZXJDb21tZW50Lm5hbWV9fTwvYj46CiAqICAgICAgICAgPHNwYW4gbmctYmluZC1odG1sPSJ1c2VyQ29tbWVudC5odG1sQ29tbWVudCIgY2xhc3M9Imh0bWxDb21tZW50Ij48L3NwYW4+CiAqICAgICAgICAgPGJyPgogKiAgICAgICA8L2Rpdj4KICogICAgIDwvZGl2PgogKiAgIDwvZGl2PgogKiA8L2ZpbGU+CiAqCiAqIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+CiAqICAgYW5ndWxhci5tb2R1bGUoJ215U2NlQXBwJywgWyduZ1Nhbml0aXplJ10pCiAqICAgICAuY29udHJvbGxlcignQXBwQ29udHJvbGxlcicsIFsnJGh0dHAnLCAnJHRlbXBsYXRlQ2FjaGUnLCAnJHNjZScsCiAqICAgICAgIGZ1bmN0aW9uKCRodHRwLCAkdGVtcGxhdGVDYWNoZSwgJHNjZSkgewogKiAgICAgICAgIHZhciBzZWxmID0gdGhpczsKICogICAgICAgICAkaHR0cC5nZXQoInRlc3RfZGF0YS5qc29uIiwge2NhY2hlOiAkdGVtcGxhdGVDYWNoZX0pLnN1Y2Nlc3MoZnVuY3Rpb24odXNlckNvbW1lbnRzKSB7CiAqICAgICAgICAgICBzZWxmLnVzZXJDb21tZW50cyA9IHVzZXJDb21tZW50czsKICogICAgICAgICB9KTsKICogICAgICAgICBzZWxmLmV4cGxpY2l0bHlUcnVzdGVkSHRtbCA9ICRzY2UudHJ1c3RBc0h0bWwoCiAqICAgICAgICAgICAgICc8c3BhbiBvbm1vdXNlb3Zlcj0idGhpcy50ZXh0Q29udGVudD0mcXVvdDtFeHBsaWNpdGx5IHRydXN0ZWQgSFRNTCBieXBhc3NlcyAnICsKICogICAgICAgICAgICAgJ3Nhbml0aXphdGlvbi4mcXVvdDsiPkhvdmVyIG92ZXIgdGhpcyB0ZXh0Ljwvc3Bhbj4nKTsKICogICAgICAgfV0pOwogKiA8L2ZpbGU+CiAqCiAqIDxmaWxlIG5hbWU9InRlc3RfZGF0YS5qc29uIj4KICogWwogKiAgIHsgIm5hbWUiOiAiQWxpY2UiLAogKiAgICAgImh0bWxDb21tZW50IjoKICogICAgICAgICAiPHNwYW4gb25tb3VzZW92ZXI9J3RoaXMudGV4dENvbnRlbnQ9XCJQV04zRCFcIic+SXMgPGk+YW55b25lPC9pPiByZWFkaW5nIHRoaXM/PC9zcGFuPiIKICogICB9LAogKiAgIHsgIm5hbWUiOiAiQm9iIiwKICogICAgICJodG1sQ29tbWVudCI6ICI8aT5ZZXMhPC9pPiAgQW0gSSB0aGUgb25seSBvdGhlciBvbmU/IgogKiAgIH0KICogXQogKiA8L2ZpbGU+CiAqCiAqIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogKiAgIGRlc2NyaWJlKCdTQ0UgZG9jIGRlbW8nLCBmdW5jdGlvbigpIHsKICogICAgIGl0KCdzaG91bGQgc2FuaXRpemUgdW50cnVzdGVkIHZhbHVlcycsIGZ1bmN0aW9uKCkgewogKiAgICAgICBleHBlY3QoZWxlbWVudC5hbGwoYnkuY3NzKCcuaHRtbENvbW1lbnQnKSkuZmlyc3QoKS5nZXRJbm5lckh0bWwoKSkKICogICAgICAgICAgIC50b0JlKCc8c3Bhbj5JcyA8aT5hbnlvbmU8L2k+IHJlYWRpbmcgdGhpcz88L3NwYW4+Jyk7CiAqICAgICB9KTsKICoKICogICAgIGl0KCdzaG91bGQgTk9UIHNhbml0aXplIGV4cGxpY2l0bHkgdHJ1c3RlZCB2YWx1ZXMnLCBmdW5jdGlvbigpIHsKICogICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2V4cGxpY2l0bHlUcnVzdGVkSHRtbCcpKS5nZXRJbm5lckh0bWwoKSkudG9CZSgKICogICAgICAgICAgICc8c3BhbiBvbm1vdXNlb3Zlcj0idGhpcy50ZXh0Q29udGVudD0mcXVvdDtFeHBsaWNpdGx5IHRydXN0ZWQgSFRNTCBieXBhc3NlcyAnICsKICogICAgICAgICAgICdzYW5pdGl6YXRpb24uJnF1b3Q7Ij5Ib3ZlciBvdmVyIHRoaXMgdGV4dC48L3NwYW4+Jyk7CiAqICAgICB9KTsKICogICB9KTsKICogPC9maWxlPgogKiA8L2V4YW1wbGU+CiAqCiAqCiAqCiAqICMjIENhbiBJIGRpc2FibGUgU0NFIGNvbXBsZXRlbHk/CiAqCiAqIFllcywgeW91IGNhbi4gIEhvd2V2ZXIsIHRoaXMgaXMgc3Ryb25nbHkgZGlzY291cmFnZWQuICBTQ0UgZ2l2ZXMgeW91IGEgbG90IG9mIHNlY3VyaXR5IGJlbmVmaXRzCiAqIGZvciBsaXR0bGUgY29kaW5nIG92ZXJoZWFkLiAgSXQgd2lsbCBiZSBtdWNoIGhhcmRlciB0byB0YWtlIGFuIFNDRSBkaXNhYmxlZCBhcHBsaWNhdGlvbiBhbmQKICogZWl0aGVyIHNlY3VyZSBpdCBvbiB5b3VyIG93biBvciBlbmFibGUgU0NFIGF0IGEgbGF0ZXIgc3RhZ2UuICBJdCBtaWdodCBtYWtlIHNlbnNlIHRvIGRpc2FibGUgU0NFCiAqIGZvciBjYXNlcyB3aGVyZSB5b3UgaGF2ZSBhIGxvdCBvZiBleGlzdGluZyBjb2RlIHRoYXQgd2FzIHdyaXR0ZW4gYmVmb3JlIFNDRSB3YXMgaW50cm9kdWNlZCBhbmQKICogeW91J3JlIG1pZ3JhdGluZyB0aGVtIGEgbW9kdWxlIGF0IGEgdGltZS4KICoKICogVGhhdCBzYWlkLCBoZXJlJ3MgaG93IHlvdSBjYW4gY29tcGxldGVseSBkaXNhYmxlIFNDRToKICoKICogYGBgCiAqIGFuZ3VsYXIubW9kdWxlKCdteUFwcFdpdGhTY2VEaXNhYmxlZG15QXBwJywgW10pLmNvbmZpZyhmdW5jdGlvbigkc2NlUHJvdmlkZXIpIHsKICogICAvLyBDb21wbGV0ZWx5IGRpc2FibGUgU0NFLiAgRm9yIGRlbW9uc3RyYXRpb24gcHVycG9zZXMgb25seSEKICogICAvLyBEbyBub3QgdXNlIGluIG5ldyBwcm9qZWN0cy4KICogICAkc2NlUHJvdmlkZXIuZW5hYmxlZChmYWxzZSk7CiAqIH0pOwogKiBgYGAKICoKICovCi8qIGpzaGludCBtYXhsZW46IDEwMCAqLwoKZnVuY3Rpb24gJFNjZVByb3ZpZGVyKCkgewogIHZhciBlbmFibGVkID0gdHJ1ZTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lICRzY2VQcm92aWRlciNlbmFibGVkCiAgICogQGtpbmQgZnVuY3Rpb24KICAgKgogICAqIEBwYXJhbSB7Ym9vbGVhbj19IHZhbHVlIElmIHByb3ZpZGVkLCB0aGVuIGVuYWJsZXMvZGlzYWJsZXMgU0NFLgogICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgU0NFIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZS4KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIEVuYWJsZXMvZGlzYWJsZXMgU0NFIGFuZCByZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlLgogICAqLwogIHRoaXMuZW5hYmxlZCA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkgewogICAgICBlbmFibGVkID0gISF2YWx1ZTsKICAgIH0KICAgIHJldHVybiBlbmFibGVkOwogIH07CgoKICAvKiBEZXNpZ24gbm90ZXMgb24gdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIFNDRS4KICAgKgogICAqIFRoZSBBUEkgY29udHJhY3QgZm9yIHRoZSBTQ0UgZGVsZWdhdGUKICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICogVGhlIFNDRSBkZWxlZ2F0ZSBvYmplY3QgbXVzdCBwcm92aWRlIHRoZSBmb2xsb3dpbmcgMyBtZXRob2RzOgogICAqCiAgICogLSB0cnVzdEFzKGNvbnRleHRFbnVtLCB2YWx1ZSkKICAgKiAgICAgVGhpcyBtZXRob2QgaXMgdXNlZCB0byB0ZWxsIHRoZSBTQ0Ugc2VydmljZSB0aGF0IHRoZSBwcm92aWRlZCB2YWx1ZSBpcyBPSyB0byB1c2UgaW4gdGhlCiAgICogICAgIGNvbnRleHRzIHNwZWNpZmllZCBieSBjb250ZXh0RW51bS4gIEl0IG11c3QgcmV0dXJuIGFuIG9iamVjdCB0aGF0IHdpbGwgYmUgYWNjZXB0ZWQgYnkKICAgKiAgICAgZ2V0VHJ1c3RlZCgpIGZvciBhIGNvbXBhdGlibGUgY29udGV4dEVudW0gYW5kIHJldHVybiB0aGlzIHZhbHVlLgogICAqCiAgICogLSB2YWx1ZU9mKHZhbHVlKQogICAqICAgICBGb3IgdmFsdWVzIHRoYXQgd2VyZSBub3QgcHJvZHVjZWQgYnkgdHJ1c3RBcygpLCByZXR1cm4gdGhlbSBhcyBpcy4gIEZvciB2YWx1ZXMgdGhhdCB3ZXJlCiAgICogICAgIHByb2R1Y2VkIGJ5IHRydXN0QXMoKSwgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIGlucHV0IHZhbHVlIHRvIHRydXN0QXMuICBCYXNpY2FsbHksIGlmCiAgICogICAgIHRydXN0QXMgaXMgd3JhcHBpbmcgdGhlIGdpdmVuIHZhbHVlcyBpbnRvIHNvbWUgdHlwZSwgdGhpcyBvcGVyYXRpb24gdW53cmFwcyBpdCB3aGVuIGdpdmVuCiAgICogICAgIHN1Y2ggYSB2YWx1ZS4KICAgKgogICAqIC0gZ2V0VHJ1c3RlZChjb250ZXh0RW51bSwgdmFsdWUpCiAgICogICAgIFRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiB0aGUgYSB2YWx1ZSB0aGF0IGlzIHNhZmUgdG8gdXNlIGluIHRoZSBjb250ZXh0IHNwZWNpZmllZCBieQogICAqICAgICBjb250ZXh0RW51bSBvciB0aHJvdyBhbmQgZXhjZXB0aW9uIG90aGVyd2lzZS4KICAgKgogICAqIE5PVEU6IFRoaXMgY29udHJhY3QgZGVsaWJlcmF0ZWx5IGRvZXMgTk9UIHN0YXRlIHRoYXQgdmFsdWVzIHJldHVybmVkIGJ5IHRydXN0QXMoKSBtdXN0IGJlCiAgICogb3BhcXVlIG9yIHdyYXBwZWQgaW4gc29tZSBob2xkZXIgb2JqZWN0LiAgVGhhdCBoYXBwZW5zIHRvIGJlIGFuIGltcGxlbWVudGF0aW9uIGRldGFpbC4gIEZvcgogICAqIGluc3RhbmNlLCBhbiBpbXBsZW1lbnRhdGlvbiBjb3VsZCBtYWludGFpbiBhIHJlZ2lzdHJ5IG9mIGFsbCB0cnVzdGVkIG9iamVjdHMgYnkgY29udGV4dC4gIEluCiAgICogc3VjaCBhIGNhc2UsIHRydXN0QXMoKSB3b3VsZCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IHRoYXQgd2FzIHBhc3NlZCBpbi4gIGdldFRydXN0ZWQoKSB3b3VsZAogICAqIHJldHVybiB0aGUgc2FtZSBvYmplY3QgcGFzc2VkIGluIGlmIGl0IHdhcyBmb3VuZCBpbiB0aGUgcmVnaXN0cnkgdW5kZXIgYSBjb21wYXRpYmxlIGNvbnRleHQgb3IKICAgKiB0aHJvdyBhbiBleGNlcHRpb24gb3RoZXJ3aXNlLiAgQW4gaW1wbGVtZW50YXRpb24gbWlnaHQgb25seSB3cmFwIHZhbHVlcyBzb21lIG9mIHRoZSB0aW1lIGJhc2VkCiAgICogb24gc29tZSBjcml0ZXJpYS4gIGdldFRydXN0ZWQoKSBtaWdodCByZXR1cm4gYSB2YWx1ZSBhbmQgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBmb3Igc3BlY2lhbAogICAqIGNvbnN0YW50cyBvciBvYmplY3RzIGV2ZW4gaWYgbm90IHdyYXBwZWQuICBBbGwgc3VjaCBpbXBsZW1lbnRhdGlvbnMgZnVsZmlsbCB0aGlzIGNvbnRyYWN0LgogICAqCiAgICoKICAgKiBBIG5vdGUgb24gdGhlIGluaGVyaXRhbmNlIG1vZGVsIGZvciBTQ0UgY29udGV4dHMKICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgKiBJJ3ZlIHVzZWQgaW5oZXJpdGFuY2UgYW5kIG1hZGUgUkVTT1VSQ0VfVVJMIHdyYXBwZWQgdHlwZXMgYSBzdWJ0eXBlIG9mIFVSTCB3cmFwcGVkIHR5cGVzLiAgVGhpcwogICAqIGlzIHB1cmVseSBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzLgogICAqCiAgICogVGhlIGNvbnRyYWN0IGlzIHNpbXBseSB0aGlzOgogICAqCiAgICogICAgIGdldFRydXN0ZWQoJHNjZS5SRVNPVVJDRV9VUkwsIHZhbHVlKSBzdWNjZWVkaW5nIGltcGxpZXMgdGhhdCBnZXRUcnVzdGVkKCRzY2UuVVJMLCB2YWx1ZSkKICAgKiAgICAgd2lsbCBhbHNvIHN1Y2NlZWQuCiAgICoKICAgKiBJbmhlcml0YW5jZSBoYXBwZW5zIHRvIGNhcHR1cmUgdGhpcyBpbiBhIG5hdHVyYWwgd2F5LiAgSW4gc29tZSBmdXR1cmUsIHdlCiAgICogbWF5IG5vdCB1c2UgaW5oZXJpdGFuY2UgYW55bW9yZS4gIFRoYXQgaXMgT0sgYmVjYXVzZSBubyBjb2RlIG91dHNpZGUgb2YKICAgKiBzY2UuanMgYW5kIHNjZVNwZWNzLmpzIHdvdWxkIG5lZWQgdG8gYmUgYXdhcmUgb2YgdGhpcyBkZXRhaWwuCiAgICovCgogIHRoaXMuJGdldCA9IFsnJHBhcnNlJywgJyRzY2VEZWxlZ2F0ZScsIGZ1bmN0aW9uKAogICAgICAgICAgICAgICAgJHBhcnNlLCAgICRzY2VEZWxlZ2F0ZSkgewogICAgLy8gUHJlcmVxOiBFbnN1cmUgdGhhdCB3ZSdyZSBub3QgcnVubmluZyBpbiBJRTwxMSBxdWlya3MgbW9kZS4gIEluIHRoYXQgbW9kZSwgSUUgPCAxMSBhbGxvdwogICAgLy8gdGhlICJleHByZXNzaW9uKGphdmFzY3JpcHQgZXhwcmVzc2lvbikiIHN5bnRheCB3aGljaCBpcyBpbnNlY3VyZS4KICAgIGlmIChlbmFibGVkICYmIG1zaWUgPCA4KSB7CiAgICAgIHRocm93ICRzY2VNaW5FcnIoJ2llcXVpcmtzJywKICAgICAgICAnU3RyaWN0IENvbnRleHR1YWwgRXNjYXBpbmcgZG9lcyBub3Qgc3VwcG9ydCBJbnRlcm5ldCBFeHBsb3JlciB2ZXJzaW9uIDwgMTEgaW4gcXVpcmtzICcgKwogICAgICAgICdtb2RlLiAgWW91IGNhbiBmaXggdGhpcyBieSBhZGRpbmcgdGhlIHRleHQgPCFkb2N0eXBlIGh0bWw+IHRvIHRoZSB0b3Agb2YgeW91ciBIVE1MICcgKwogICAgICAgICdkb2N1bWVudC4gIFNlZSBodHRwOi8vZG9jcy5hbmd1bGFyanMub3JnL2FwaS9uZy4kc2NlIGZvciBtb3JlIGluZm9ybWF0aW9uLicpOwogICAgfQoKICAgIHZhciBzY2UgPSBzaGFsbG93Q29weShTQ0VfQ09OVEVYVFMpOwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNpc0VuYWJsZWQKICAgICAqIEBraW5kIGZ1bmN0aW9uCiAgICAgKgogICAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiBTQ0UgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLiAgSWYgeW91IHdhbnQgdG8gc2V0IHRoZSB2YWx1ZSwgeW91CiAgICAgKiBoYXZlIHRvIGRvIGl0IGF0IG1vZHVsZSBjb25maWcgdGltZSBvbiB7QGxpbmsgbmcuJHNjZVByb3ZpZGVyICRzY2VQcm92aWRlcn0uCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIFNDRSBpcyBlbmFibGVkLgogICAgICovCiAgICBzY2UuaXNFbmFibGVkID0gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBlbmFibGVkOwogICAgfTsKICAgIHNjZS50cnVzdEFzID0gJHNjZURlbGVnYXRlLnRydXN0QXM7CiAgICBzY2UuZ2V0VHJ1c3RlZCA9ICRzY2VEZWxlZ2F0ZS5nZXRUcnVzdGVkOwogICAgc2NlLnZhbHVlT2YgPSAkc2NlRGVsZWdhdGUudmFsdWVPZjsKCiAgICBpZiAoIWVuYWJsZWQpIHsKICAgICAgc2NlLnRydXN0QXMgPSBzY2UuZ2V0VHJ1c3RlZCA9IGZ1bmN0aW9uKHR5cGUsIHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTsKICAgICAgc2NlLnZhbHVlT2YgPSBpZGVudGl0eTsKICAgIH0KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRzY2UjcGFyc2VBcwogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogQ29udmVydHMgQW5ndWxhciB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufSBpbnRvIGEgZnVuY3Rpb24uICBUaGlzIGlzIGxpa2Uge0BsaW5rCiAgICAgKiBuZy4kcGFyc2UgJHBhcnNlfSBhbmQgaXMgaWRlbnRpY2FsIHdoZW4gdGhlIGV4cHJlc3Npb24gaXMgYSBsaXRlcmFsIGNvbnN0YW50LiAgT3RoZXJ3aXNlLCBpdAogICAgICogd3JhcHMgdGhlIGV4cHJlc3Npb24gaW4gYSBjYWxsIHRvIHtAbGluayBuZy4kc2NlI2dldFRydXN0ZWQgJHNjZS5nZXRUcnVzdGVkKCp0eXBlKiwKICAgICAqICpyZXN1bHQqKX0KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUga2luZCBvZiBTQ0UgY29udGV4dCBpbiB3aGljaCB0aGlzIHJlc3VsdCB3aWxsIGJlIHVzZWQuCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXhwcmVzc2lvbiBTdHJpbmcgZXhwcmVzc2lvbiB0byBjb21waWxlLgogICAgICogQHJldHVybnMge2Z1bmN0aW9uKGNvbnRleHQsIGxvY2Fscyl9IGEgZnVuY3Rpb24gd2hpY2ggcmVwcmVzZW50cyB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbjoKICAgICAqCiAgICAgKiAgICAqIGBjb250ZXh0YCDigD8gYHtvYmplY3R9YCDigD8gYW4gb2JqZWN0IGFnYWluc3Qgd2hpY2ggYW55IGV4cHJlc3Npb25zIGVtYmVkZGVkIGluIHRoZSBzdHJpbmdzCiAgICAgKiAgICAgIGFyZSBldmFsdWF0ZWQgYWdhaW5zdCAodHlwaWNhbGx5IGEgc2NvcGUgb2JqZWN0KS4KICAgICAqICAgICogYGxvY2Fsc2Ag4oA/IGB7b2JqZWN0PX1gIOKAPyBsb2NhbCB2YXJpYWJsZXMgY29udGV4dCBvYmplY3QsIHVzZWZ1bCBmb3Igb3ZlcnJpZGluZyB2YWx1ZXMgaW4KICAgICAqICAgICAgYGNvbnRleHRgLgogICAgICovCiAgICBzY2UucGFyc2VBcyA9IGZ1bmN0aW9uIHNjZVBhcnNlQXModHlwZSwgZXhwcikgewogICAgICB2YXIgcGFyc2VkID0gJHBhcnNlKGV4cHIpOwogICAgICBpZiAocGFyc2VkLmxpdGVyYWwgJiYgcGFyc2VkLmNvbnN0YW50KSB7CiAgICAgICAgcmV0dXJuIHBhcnNlZDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gJHBhcnNlKGV4cHIsIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc2NlLmdldFRydXN0ZWQodHlwZSwgdmFsdWUpOwogICAgICAgIH0pOwogICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSN0cnVzdEFzCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBEZWxlZ2F0ZXMgdG8ge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZSN0cnVzdEFzIGAkc2NlRGVsZWdhdGUudHJ1c3RBc2B9LiAgQXMgc3VjaCwKICAgICAqIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgaXMgdHJ1c3RlZCBieSBhbmd1bGFyIGZvciB1c2UgaW4gc3BlY2lmaWVkIHN0cmljdCBjb250ZXh0dWFsCiAgICAgKiBlc2NhcGluZyBjb250ZXh0cyAoc3VjaCBhcyBuZy1iaW5kLWh0bWwsIG5nLWluY2x1ZGUsIGFueSBzcmMgYXR0cmlidXRlCiAgICAgKiBpbnRlcnBvbGF0aW9uLCBhbnkgZG9tIGV2ZW50IGJpbmRpbmcgYXR0cmlidXRlIGludGVycG9sYXRpb24gc3VjaCBhcyBmb3Igb25jbGljaywgIGV0Yy4pCiAgICAgKiB0aGF0IHVzZXMgdGhlIHByb3ZpZGVkIHZhbHVlLiAgU2VlICoge0BsaW5rIG5nLiRzY2UgJHNjZX0gZm9yIGVuYWJsaW5nIHN0cmljdCBjb250ZXh0dWFsCiAgICAgKiBlc2NhcGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUga2luZCBvZiBjb250ZXh0IGluIHdoaWNoIHRoaXMgdmFsdWUgaXMgc2FmZSBmb3IgdXNlLiAgZS5nLiB1cmwsCiAgICAgKiAgIHJlc291cmNlX3VybCwgaHRtbCwganMgYW5kIGNzcy4KICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRoYXQgdGhhdCBzaG91bGQgYmUgY29uc2lkZXJlZCB0cnVzdGVkL3NhZmUuCiAgICAgKiBAcmV0dXJucyB7Kn0gQSB2YWx1ZSB0aGF0IGNhbiBiZSB1c2VkIHRvIHN0YW5kIGluIGZvciB0aGUgcHJvdmlkZWQgYHZhbHVlYCBpbiBwbGFjZXMKICAgICAqIHdoZXJlIEFuZ3VsYXIgZXhwZWN0cyBhICRzY2UudHJ1c3RBcygpIHJldHVybiB2YWx1ZS4KICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSN0cnVzdEFzSHRtbAogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRoYW5kIG1ldGhvZC4gIGAkc2NlLnRydXN0QXNIdG1sKHZhbHVlKWAg4oY/CiAgICAgKiAgICAge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZSN0cnVzdEFzIGAkc2NlRGVsZWdhdGUudHJ1c3RBcygkc2NlLkhUTUwsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gdHJ1c3RBcy4KICAgICAqIEByZXR1cm5zIHsqfSBBbiBvYmplY3QgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHtAbGluayBuZy4kc2NlI2dldFRydXN0ZWRIdG1sCiAgICAgKiAgICAgJHNjZS5nZXRUcnVzdGVkSHRtbCh2YWx1ZSl9IHRvIG9idGFpbiB0aGUgb3JpZ2luYWwgdmFsdWUuICAocHJpdmlsZWdlZCBkaXJlY3RpdmVzCiAgICAgKiAgICAgb25seSBhY2NlcHQgZXhwcmVzc2lvbnMgdGhhdCBhcmUgZWl0aGVyIGxpdGVyYWwgY29uc3RhbnRzIG9yIGFyZSB0aGUKICAgICAqICAgICByZXR1cm4gdmFsdWUgb2Yge0BsaW5rIG5nLiRzY2UjdHJ1c3RBcyAkc2NlLnRydXN0QXN9LikKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSN0cnVzdEFzVXJsCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UudHJ1c3RBc1VybCh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjdHJ1c3RBcyBgJHNjZURlbGVnYXRlLnRydXN0QXMoJHNjZS5VUkwsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gdHJ1c3RBcy4KICAgICAqIEByZXR1cm5zIHsqfSBBbiBvYmplY3QgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHtAbGluayBuZy4kc2NlI2dldFRydXN0ZWRVcmwKICAgICAqICAgICAkc2NlLmdldFRydXN0ZWRVcmwodmFsdWUpfSB0byBvYnRhaW4gdGhlIG9yaWdpbmFsIHZhbHVlLiAgKHByaXZpbGVnZWQgZGlyZWN0aXZlcwogICAgICogICAgIG9ubHkgYWNjZXB0IGV4cHJlc3Npb25zIHRoYXQgYXJlIGVpdGhlciBsaXRlcmFsIGNvbnN0YW50cyBvciBhcmUgdGhlCiAgICAgKiAgICAgcmV0dXJuIHZhbHVlIG9mIHtAbGluayBuZy4kc2NlI3RydXN0QXMgJHNjZS50cnVzdEFzfS4pCiAgICAgKi8KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRzY2UjdHJ1c3RBc1Jlc291cmNlVXJsCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UudHJ1c3RBc1Jlc291cmNlVXJsKHZhbHVlKWAg4oY/CiAgICAgKiAgICAge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZSN0cnVzdEFzIGAkc2NlRGVsZWdhdGUudHJ1c3RBcygkc2NlLlJFU09VUkNFX1VSTCwgdmFsdWUpYH0KICAgICAqCiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB0cnVzdEFzLgogICAgICogQHJldHVybnMgeyp9IEFuIG9iamVjdCB0aGF0IGNhbiBiZSBwYXNzZWQgdG8ge0BsaW5rIG5nLiRzY2UjZ2V0VHJ1c3RlZFJlc291cmNlVXJsCiAgICAgKiAgICAgJHNjZS5nZXRUcnVzdGVkUmVzb3VyY2VVcmwodmFsdWUpfSB0byBvYnRhaW4gdGhlIG9yaWdpbmFsIHZhbHVlLiAgKHByaXZpbGVnZWQgZGlyZWN0aXZlcwogICAgICogICAgIG9ubHkgYWNjZXB0IGV4cHJlc3Npb25zIHRoYXQgYXJlIGVpdGhlciBsaXRlcmFsIGNvbnN0YW50cyBvciBhcmUgdGhlIHJldHVybgogICAgICogICAgIHZhbHVlIG9mIHtAbGluayBuZy4kc2NlI3RydXN0QXMgJHNjZS50cnVzdEFzfS4pCiAgICAgKi8KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRzY2UjdHJ1c3RBc0pzCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UudHJ1c3RBc0pzKHZhbHVlKWAg4oY/CiAgICAgKiAgICAge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZSN0cnVzdEFzIGAkc2NlRGVsZWdhdGUudHJ1c3RBcygkc2NlLkpTLCB2YWx1ZSlgfQogICAgICoKICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHRydXN0QXMuCiAgICAgKiBAcmV0dXJucyB7Kn0gQW4gb2JqZWN0IHRoYXQgY2FuIGJlIHBhc3NlZCB0byB7QGxpbmsgbmcuJHNjZSNnZXRUcnVzdGVkSnMKICAgICAqICAgICAkc2NlLmdldFRydXN0ZWRKcyh2YWx1ZSl9IHRvIG9idGFpbiB0aGUgb3JpZ2luYWwgdmFsdWUuICAocHJpdmlsZWdlZCBkaXJlY3RpdmVzCiAgICAgKiAgICAgb25seSBhY2NlcHQgZXhwcmVzc2lvbnMgdGhhdCBhcmUgZWl0aGVyIGxpdGVyYWwgY29uc3RhbnRzIG9yIGFyZSB0aGUKICAgICAqICAgICByZXR1cm4gdmFsdWUgb2Yge0BsaW5rIG5nLiRzY2UjdHJ1c3RBcyAkc2NlLnRydXN0QXN9LikKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNnZXRUcnVzdGVkCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBEZWxlZ2F0ZXMgdG8ge0BsaW5rIG5nLiRzY2VEZWxlZ2F0ZSNnZXRUcnVzdGVkIGAkc2NlRGVsZWdhdGUuZ2V0VHJ1c3RlZGB9LiAgQXMgc3VjaCwKICAgICAqIHRha2VzIHRoZSByZXN1bHQgb2YgYSB7QGxpbmsgbmcuJHNjZSN0cnVzdEFzIGAkc2NlLnRydXN0QXNgfSgpIGNhbGwgYW5kIHJldHVybnMgdGhlCiAgICAgKiBvcmlnaW5hbGx5IHN1cHBsaWVkIHZhbHVlIGlmIHRoZSBxdWVyaWVkIGNvbnRleHQgdHlwZSBpcyBhIHN1cGVydHlwZSBvZiB0aGUgY3JlYXRlZCB0eXBlLgogICAgICogSWYgdGhpcyBjb25kaXRpb24gaXNuJ3Qgc2F0aXNmaWVkLCB0aHJvd3MgYW4gZXhjZXB0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBraW5kIG9mIGNvbnRleHQgaW4gd2hpY2ggdGhpcyB2YWx1ZSBpcyB0byBiZSB1c2VkLgogICAgICogQHBhcmFtIHsqfSBtYXliZVRydXN0ZWQgVGhlIHJlc3VsdCBvZiBhIHByaW9yIHtAbGluayBuZy4kc2NlI3RydXN0QXMgYCRzY2UudHJ1c3RBc2B9CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsLgogICAgICogQHJldHVybnMgeyp9IFRoZSB2YWx1ZSB0aGUgd2FzIG9yaWdpbmFsbHkgcHJvdmlkZWQgdG8KICAgICAqICAgICAgICAgICAgICB7QGxpbmsgbmcuJHNjZSN0cnVzdEFzIGAkc2NlLnRydXN0QXNgfSBpZiB2YWxpZCBpbiB0aGlzIGNvbnRleHQuCiAgICAgKiAgICAgICAgICAgICAgT3RoZXJ3aXNlLCB0aHJvd3MgYW4gZXhjZXB0aW9uLgogICAgICovCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlI2dldFRydXN0ZWRIdG1sCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UuZ2V0VHJ1c3RlZEh0bWwodmFsdWUpYCDihj8KICAgICAqICAgICB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI2dldFRydXN0ZWQgYCRzY2VEZWxlZ2F0ZS5nZXRUcnVzdGVkKCRzY2UuSFRNTCwgdmFsdWUpYH0KICAgICAqCiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwYXNzIHRvIGAkc2NlLmdldFRydXN0ZWRgLgogICAgICogQHJldHVybnMgeyp9IFRoZSByZXR1cm4gdmFsdWUgb2YgYCRzY2UuZ2V0VHJ1c3RlZCgkc2NlLkhUTUwsIHZhbHVlKWAKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNnZXRUcnVzdGVkQ3NzCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UuZ2V0VHJ1c3RlZENzcyh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjZ2V0VHJ1c3RlZCBgJHNjZURlbGVnYXRlLmdldFRydXN0ZWQoJHNjZS5DU1MsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGFzcyB0byBgJHNjZS5nZXRUcnVzdGVkYC4KICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIGAkc2NlLmdldFRydXN0ZWQoJHNjZS5DU1MsIHZhbHVlKWAKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNnZXRUcnVzdGVkVXJsCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UuZ2V0VHJ1c3RlZFVybCh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlRGVsZWdhdGUjZ2V0VHJ1c3RlZCBgJHNjZURlbGVnYXRlLmdldFRydXN0ZWQoJHNjZS5VUkwsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGFzcyB0byBgJHNjZS5nZXRUcnVzdGVkYC4KICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIGAkc2NlLmdldFRydXN0ZWQoJHNjZS5VUkwsIHZhbHVlKWAKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNnZXRUcnVzdGVkUmVzb3VyY2VVcmwKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFNob3J0aGFuZCBtZXRob2QuICBgJHNjZS5nZXRUcnVzdGVkUmVzb3VyY2VVcmwodmFsdWUpYCDihj8KICAgICAqICAgICB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI2dldFRydXN0ZWQgYCRzY2VEZWxlZ2F0ZS5nZXRUcnVzdGVkKCRzY2UuUkVTT1VSQ0VfVVJMLCB2YWx1ZSlgfQogICAgICoKICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHBhc3MgdG8gYCRzY2VEZWxlZ2F0ZS5nZXRUcnVzdGVkYC4KICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIGAkc2NlLmdldFRydXN0ZWQoJHNjZS5SRVNPVVJDRV9VUkwsIHZhbHVlKWAKICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNnZXRUcnVzdGVkSnMKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFNob3J0aGFuZCBtZXRob2QuICBgJHNjZS5nZXRUcnVzdGVkSnModmFsdWUpYCDihj8KICAgICAqICAgICB7QGxpbmsgbmcuJHNjZURlbGVnYXRlI2dldFRydXN0ZWQgYCRzY2VEZWxlZ2F0ZS5nZXRUcnVzdGVkKCRzY2UuSlMsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGFzcyB0byBgJHNjZS5nZXRUcnVzdGVkYC4KICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIGAkc2NlLmdldFRydXN0ZWQoJHNjZS5KUywgdmFsdWUpYAogICAgICovCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlI3BhcnNlQXNIdG1sCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UucGFyc2VBc0h0bWwoZXhwcmVzc2lvbiBzdHJpbmcpYCDihj8KICAgICAqICAgICB7QGxpbmsgbmcuJHNjZSNwYXJzZUFzIGAkc2NlLnBhcnNlQXMoJHNjZS5IVE1MLCB2YWx1ZSlgfQogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBleHByZXNzaW9uIFN0cmluZyBleHByZXNzaW9uIHRvIGNvbXBpbGUuCiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oY29udGV4dCwgbG9jYWxzKX0gYSBmdW5jdGlvbiB3aGljaCByZXByZXNlbnRzIHRoZSBjb21waWxlZCBleHByZXNzaW9uOgogICAgICoKICAgICAqICAgICogYGNvbnRleHRgIOKAPyBge29iamVjdH1gIOKAPyBhbiBvYmplY3QgYWdhaW5zdCB3aGljaCBhbnkgZXhwcmVzc2lvbnMgZW1iZWRkZWQgaW4gdGhlIHN0cmluZ3MKICAgICAqICAgICAgYXJlIGV2YWx1YXRlZCBhZ2FpbnN0ICh0eXBpY2FsbHkgYSBzY29wZSBvYmplY3QpLgogICAgICogICAgKiBgbG9jYWxzYCDigD8gYHtvYmplY3Q9fWAg4oA/IGxvY2FsIHZhcmlhYmxlcyBjb250ZXh0IG9iamVjdCwgdXNlZnVsIGZvciBvdmVycmlkaW5nIHZhbHVlcyBpbgogICAgICogICAgICBgY29udGV4dGAuCiAgICAgKi8KCiAgICAvKioKICAgICAqIEBuZ2RvYyBtZXRob2QKICAgICAqIEBuYW1lICRzY2UjcGFyc2VBc0NzcwogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRoYW5kIG1ldGhvZC4gIGAkc2NlLnBhcnNlQXNDc3ModmFsdWUpYCDihj8KICAgICAqICAgICB7QGxpbmsgbmcuJHNjZSNwYXJzZUFzIGAkc2NlLnBhcnNlQXMoJHNjZS5DU1MsIHZhbHVlKWB9CiAgICAgKgogICAgICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gU3RyaW5nIGV4cHJlc3Npb24gdG8gY29tcGlsZS4KICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbihjb250ZXh0LCBsb2NhbHMpfSBhIGZ1bmN0aW9uIHdoaWNoIHJlcHJlc2VudHMgdGhlIGNvbXBpbGVkIGV4cHJlc3Npb246CiAgICAgKgogICAgICogICAgKiBgY29udGV4dGAg4oA/IGB7b2JqZWN0fWAg4oA/IGFuIG9iamVjdCBhZ2FpbnN0IHdoaWNoIGFueSBleHByZXNzaW9ucyBlbWJlZGRlZCBpbiB0aGUgc3RyaW5ncwogICAgICogICAgICBhcmUgZXZhbHVhdGVkIGFnYWluc3QgKHR5cGljYWxseSBhIHNjb3BlIG9iamVjdCkuCiAgICAgKiAgICAqIGBsb2NhbHNgIOKAPyBge29iamVjdD19YCDigD8gbG9jYWwgdmFyaWFibGVzIGNvbnRleHQgb2JqZWN0LCB1c2VmdWwgZm9yIG92ZXJyaWRpbmcgdmFsdWVzIGluCiAgICAgKiAgICAgIGBjb250ZXh0YC4KICAgICAqLwoKICAgIC8qKgogICAgICogQG5nZG9jIG1ldGhvZAogICAgICogQG5hbWUgJHNjZSNwYXJzZUFzVXJsCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBTaG9ydGhhbmQgbWV0aG9kLiAgYCRzY2UucGFyc2VBc1VybCh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlI3BhcnNlQXMgYCRzY2UucGFyc2VBcygkc2NlLlVSTCwgdmFsdWUpYH0KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXhwcmVzc2lvbiBTdHJpbmcgZXhwcmVzc2lvbiB0byBjb21waWxlLgogICAgICogQHJldHVybnMge2Z1bmN0aW9uKGNvbnRleHQsIGxvY2Fscyl9IGEgZnVuY3Rpb24gd2hpY2ggcmVwcmVzZW50cyB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbjoKICAgICAqCiAgICAgKiAgICAqIGBjb250ZXh0YCDigD8gYHtvYmplY3R9YCDigD8gYW4gb2JqZWN0IGFnYWluc3Qgd2hpY2ggYW55IGV4cHJlc3Npb25zIGVtYmVkZGVkIGluIHRoZSBzdHJpbmdzCiAgICAgKiAgICAgIGFyZSBldmFsdWF0ZWQgYWdhaW5zdCAodHlwaWNhbGx5IGEgc2NvcGUgb2JqZWN0KS4KICAgICAqICAgICogYGxvY2Fsc2Ag4oA/IGB7b2JqZWN0PX1gIOKAPyBsb2NhbCB2YXJpYWJsZXMgY29udGV4dCBvYmplY3QsIHVzZWZ1bCBmb3Igb3ZlcnJpZGluZyB2YWx1ZXMgaW4KICAgICAqICAgICAgYGNvbnRleHRgLgogICAgICovCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlI3BhcnNlQXNSZXNvdXJjZVVybAogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRoYW5kIG1ldGhvZC4gIGAkc2NlLnBhcnNlQXNSZXNvdXJjZVVybCh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlI3BhcnNlQXMgYCRzY2UucGFyc2VBcygkc2NlLlJFU09VUkNFX1VSTCwgdmFsdWUpYH0KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXhwcmVzc2lvbiBTdHJpbmcgZXhwcmVzc2lvbiB0byBjb21waWxlLgogICAgICogQHJldHVybnMge2Z1bmN0aW9uKGNvbnRleHQsIGxvY2Fscyl9IGEgZnVuY3Rpb24gd2hpY2ggcmVwcmVzZW50cyB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbjoKICAgICAqCiAgICAgKiAgICAqIGBjb250ZXh0YCDigD8gYHtvYmplY3R9YCDigD8gYW4gb2JqZWN0IGFnYWluc3Qgd2hpY2ggYW55IGV4cHJlc3Npb25zIGVtYmVkZGVkIGluIHRoZSBzdHJpbmdzCiAgICAgKiAgICAgIGFyZSBldmFsdWF0ZWQgYWdhaW5zdCAodHlwaWNhbGx5IGEgc2NvcGUgb2JqZWN0KS4KICAgICAqICAgICogYGxvY2Fsc2Ag4oA/IGB7b2JqZWN0PX1gIOKAPyBsb2NhbCB2YXJpYWJsZXMgY29udGV4dCBvYmplY3QsIHVzZWZ1bCBmb3Igb3ZlcnJpZGluZyB2YWx1ZXMgaW4KICAgICAqICAgICAgYGNvbnRleHRgLgogICAgICovCgogICAgLyoqCiAgICAgKiBAbmdkb2MgbWV0aG9kCiAgICAgKiBAbmFtZSAkc2NlI3BhcnNlQXNKcwogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRoYW5kIG1ldGhvZC4gIGAkc2NlLnBhcnNlQXNKcyh2YWx1ZSlgIOKGPwogICAgICogICAgIHtAbGluayBuZy4kc2NlI3BhcnNlQXMgYCRzY2UucGFyc2VBcygkc2NlLkpTLCB2YWx1ZSlgfQogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBleHByZXNzaW9uIFN0cmluZyBleHByZXNzaW9uIHRvIGNvbXBpbGUuCiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oY29udGV4dCwgbG9jYWxzKX0gYSBmdW5jdGlvbiB3aGljaCByZXByZXNlbnRzIHRoZSBjb21waWxlZCBleHByZXNzaW9uOgogICAgICoKICAgICAqICAgICogYGNvbnRleHRgIOKAPyBge29iamVjdH1gIOKAPyBhbiBvYmplY3QgYWdhaW5zdCB3aGljaCBhbnkgZXhwcmVzc2lvbnMgZW1iZWRkZWQgaW4gdGhlIHN0cmluZ3MKICAgICAqICAgICAgYXJlIGV2YWx1YXRlZCBhZ2FpbnN0ICh0eXBpY2FsbHkgYSBzY29wZSBvYmplY3QpLgogICAgICogICAgKiBgbG9jYWxzYCDigD8gYHtvYmplY3Q9fWAg4oA/IGxvY2FsIHZhcmlhYmxlcyBjb250ZXh0IG9iamVjdCwgdXNlZnVsIGZvciBvdmVycmlkaW5nIHZhbHVlcyBpbgogICAgICogICAgICBgY29udGV4dGAuCiAgICAgKi8KCiAgICAvLyBTaG9ydGhhbmQgZGVsZWdhdGlvbnMuCiAgICB2YXIgcGFyc2UgPSBzY2UucGFyc2VBcywKICAgICAgICBnZXRUcnVzdGVkID0gc2NlLmdldFRydXN0ZWQsCiAgICAgICAgdHJ1c3RBcyA9IHNjZS50cnVzdEFzOwoKICAgIGZvckVhY2goU0NFX0NPTlRFWFRTLCBmdW5jdGlvbihlbnVtVmFsdWUsIG5hbWUpIHsKICAgICAgdmFyIGxOYW1lID0gbG93ZXJjYXNlKG5hbWUpOwogICAgICBzY2VbY2FtZWxDYXNlKCJwYXJzZV9hc18iICsgbE5hbWUpXSA9IGZ1bmN0aW9uKGV4cHIpIHsKICAgICAgICByZXR1cm4gcGFyc2UoZW51bVZhbHVlLCBleHByKTsKICAgICAgfTsKICAgICAgc2NlW2NhbWVsQ2FzZSgiZ2V0X3RydXN0ZWRfIiArIGxOYW1lKV0gPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgIHJldHVybiBnZXRUcnVzdGVkKGVudW1WYWx1ZSwgdmFsdWUpOwogICAgICB9OwogICAgICBzY2VbY2FtZWxDYXNlKCJ0cnVzdF9hc18iICsgbE5hbWUpXSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHRydXN0QXMoZW51bVZhbHVlLCB2YWx1ZSk7CiAgICAgIH07CiAgICB9KTsKCiAgICByZXR1cm4gc2NlOwogIH1dOwp9CgovKioKICogISEhIFRoaXMgaXMgYW4gdW5kb2N1bWVudGVkICJwcml2YXRlIiBzZXJ2aWNlICEhIQogKgogKiBAbmFtZSAkc25pZmZlcgogKiBAcmVxdWlyZXMgJHdpbmRvdwogKiBAcmVxdWlyZXMgJGRvY3VtZW50CiAqCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaGlzdG9yeSBEb2VzIHRoZSBicm93c2VyIHN1cHBvcnQgaHRtbDUgaGlzdG9yeSBhcGkgPwogKiBAcHJvcGVydHkge2Jvb2xlYW59IHRyYW5zaXRpb25zIERvZXMgdGhlIGJyb3dzZXIgc3VwcG9ydCBDU1MgdHJhbnNpdGlvbiBldmVudHMgPwogKiBAcHJvcGVydHkge2Jvb2xlYW59IGFuaW1hdGlvbnMgRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IENTUyBhbmltYXRpb24gZXZlbnRzID8KICoKICogQGRlc2NyaXB0aW9uCiAqIFRoaXMgaXMgdmVyeSBzaW1wbGUgaW1wbGVtZW50YXRpb24gb2YgdGVzdGluZyBicm93c2VyJ3MgZmVhdHVyZXMuCiAqLwpmdW5jdGlvbiAkU25pZmZlclByb3ZpZGVyKCkgewogIHRoaXMuJGdldCA9IFsnJHdpbmRvdycsICckZG9jdW1lbnQnLCBmdW5jdGlvbigkd2luZG93LCAkZG9jdW1lbnQpIHsKICAgIHZhciBldmVudFN1cHBvcnQgPSB7fSwKICAgICAgICBhbmRyb2lkID0KICAgICAgICAgIGludCgoL2FuZHJvaWQgKFxkKykvLmV4ZWMobG93ZXJjYXNlKCgkd2luZG93Lm5hdmlnYXRvciB8fCB7fSkudXNlckFnZW50KSkgfHwgW10pWzFdKSwKICAgICAgICBib3hlZSA9IC9Cb3hlZS9pLnRlc3QoKCR3aW5kb3cubmF2aWdhdG9yIHx8IHt9KS51c2VyQWdlbnQpLAogICAgICAgIGRvY3VtZW50ID0gJGRvY3VtZW50WzBdIHx8IHt9LAogICAgICAgIHZlbmRvclByZWZpeCwKICAgICAgICB2ZW5kb3JSZWdleCA9IC9eKE1venx3ZWJraXR8bXMpKD89W0EtWl0pLywKICAgICAgICBib2R5U3R5bGUgPSBkb2N1bWVudC5ib2R5ICYmIGRvY3VtZW50LmJvZHkuc3R5bGUsCiAgICAgICAgdHJhbnNpdGlvbnMgPSBmYWxzZSwKICAgICAgICBhbmltYXRpb25zID0gZmFsc2UsCiAgICAgICAgbWF0Y2g7CgogICAgaWYgKGJvZHlTdHlsZSkgewogICAgICBmb3IgKHZhciBwcm9wIGluIGJvZHlTdHlsZSkgewogICAgICAgIGlmIChtYXRjaCA9IHZlbmRvclJlZ2V4LmV4ZWMocHJvcCkpIHsKICAgICAgICAgIHZlbmRvclByZWZpeCA9IG1hdGNoWzBdOwogICAgICAgICAgdmVuZG9yUHJlZml4ID0gdmVuZG9yUHJlZml4LnN1YnN0cigwLCAxKS50b1VwcGVyQ2FzZSgpICsgdmVuZG9yUHJlZml4LnN1YnN0cigxKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKCF2ZW5kb3JQcmVmaXgpIHsKICAgICAgICB2ZW5kb3JQcmVmaXggPSAoJ1dlYmtpdE9wYWNpdHknIGluIGJvZHlTdHlsZSkgJiYgJ3dlYmtpdCc7CiAgICAgIH0KCiAgICAgIHRyYW5zaXRpb25zID0gISEoKCd0cmFuc2l0aW9uJyBpbiBib2R5U3R5bGUpIHx8ICh2ZW5kb3JQcmVmaXggKyAnVHJhbnNpdGlvbicgaW4gYm9keVN0eWxlKSk7CiAgICAgIGFuaW1hdGlvbnMgID0gISEoKCdhbmltYXRpb24nIGluIGJvZHlTdHlsZSkgfHwgKHZlbmRvclByZWZpeCArICdBbmltYXRpb24nIGluIGJvZHlTdHlsZSkpOwoKICAgICAgaWYgKGFuZHJvaWQgJiYgKCF0cmFuc2l0aW9ucyB8fCAgIWFuaW1hdGlvbnMpKSB7CiAgICAgICAgdHJhbnNpdGlvbnMgPSBpc1N0cmluZyhkb2N1bWVudC5ib2R5LnN0eWxlLndlYmtpdFRyYW5zaXRpb24pOwogICAgICAgIGFuaW1hdGlvbnMgPSBpc1N0cmluZyhkb2N1bWVudC5ib2R5LnN0eWxlLndlYmtpdEFuaW1hdGlvbik7CiAgICAgIH0KICAgIH0KCgogICAgcmV0dXJuIHsKICAgICAgLy8gQW5kcm9pZCBoYXMgaGlzdG9yeS5wdXNoU3RhdGUsIGJ1dCBpdCBkb2VzIG5vdCB1cGRhdGUgbG9jYXRpb24gY29ycmVjdGx5CiAgICAgIC8vIHNvIGxldCdzIG5vdCB1c2UgdGhlIGhpc3RvcnkgQVBJIGF0IGFsbC4KICAgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0xNzQ3MQogICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL2lzc3Vlcy85MDQKCiAgICAgIC8vIG9sZGVyIHdlYmtpdCBicm93c2VyICg1MzMuOSkgb24gQm94ZWUgYm94IGhhcyBleGFjdGx5IHRoZSBzYW1lIHByb2JsZW0gYXMgQW5kcm9pZCBoYXMKICAgICAgLy8gc28gbGV0J3Mgbm90IHVzZSB0aGUgaGlzdG9yeSBBUEkgYWxzbwogICAgICAvLyBXZSBhcmUgcHVycG9zZWZ1bGx5IHVzaW5nIGAhKGFuZHJvaWQgPCA0KWAgdG8gY292ZXIgdGhlIGNhc2Ugd2hlbiBgYW5kcm9pZGAgaXMgdW5kZWZpbmVkCiAgICAgIC8vIGpzaGludCAtVzAxOAogICAgICBoaXN0b3J5OiAhISgkd2luZG93Lmhpc3RvcnkgJiYgJHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSAmJiAhKGFuZHJvaWQgPCA0KSAmJiAhYm94ZWUpLAogICAgICAvLyBqc2hpbnQgK1cwMTgKICAgICAgaGFzRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgLy8gSUU5IGltcGxlbWVudHMgJ2lucHV0JyBldmVudCBpdCdzIHNvIGZ1YmFyZWQgdGhhdCB3ZSByYXRoZXIgcHJldGVuZCB0aGF0IGl0IGRvZXNuJ3QgaGF2ZQogICAgICAgIC8vIGl0LiBJbiBwYXJ0aWN1bGFyIHRoZSBldmVudCBpcyBub3QgZmlyZWQgd2hlbiBiYWNrc3BhY2Ugb3IgZGVsZXRlIGtleSBhcmUgcHJlc3NlZCBvcgogICAgICAgIC8vIHdoZW4gY3V0IG9wZXJhdGlvbiBpcyBwZXJmb3JtZWQuCiAgICAgICAgLy8gSUUxMCsgaW1wbGVtZW50cyAnaW5wdXQnIGV2ZW50IGJ1dCBpdCBlcnJvbmVvdXNseSBmaXJlcyB1bmRlciB2YXJpb3VzIHNpdHVhdGlvbnMsCiAgICAgICAgLy8gZS5nLiB3aGVuIHBsYWNlaG9sZGVyIGNoYW5nZXMsIG9yIGEgZm9ybSBpcyBmb2N1c2VkLgogICAgICAgIGlmIChldmVudCA9PT0gJ2lucHV0JyAmJiBtc2llIDw9IDExKSByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmIChpc1VuZGVmaW5lZChldmVudFN1cHBvcnRbZXZlbnRdKSkgewogICAgICAgICAgdmFyIGRpdkVsbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgICAgZXZlbnRTdXBwb3J0W2V2ZW50XSA9ICdvbicgKyBldmVudCBpbiBkaXZFbG07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZXZlbnRTdXBwb3J0W2V2ZW50XTsKICAgICAgfSwKICAgICAgY3NwOiBjc3AoKSwKICAgICAgdmVuZG9yUHJlZml4OiB2ZW5kb3JQcmVmaXgsCiAgICAgIHRyYW5zaXRpb25zOiB0cmFuc2l0aW9ucywKICAgICAgYW5pbWF0aW9uczogYW5pbWF0aW9ucywKICAgICAgYW5kcm9pZDogYW5kcm9pZAogICAgfTsKICB9XTsKfQoKdmFyICRjb21waWxlTWluRXJyID0gbWluRXJyKCckY29tcGlsZScpOwoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICR0ZW1wbGF0ZVJlcXVlc3QKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgJHRlbXBsYXRlUmVxdWVzdGAgc2VydmljZSBkb3dubG9hZHMgdGhlIHByb3ZpZGVkIHRlbXBsYXRlIHVzaW5nIGAkaHR0cGAgYW5kLCB1cG9uIHN1Y2Nlc3MsCiAqIHN0b3JlcyB0aGUgY29udGVudHMgaW5zaWRlIG9mIGAkdGVtcGxhdGVDYWNoZWAuIElmIHRoZSBIVFRQIHJlcXVlc3QgZmFpbHMgb3IgdGhlIHJlc3BvbnNlIGRhdGEKICogb2YgdGhlIEhUVFAgcmVxdWVzdCBpcyBlbXB0eSwgYSBgJGNvbXBpbGVgIGVycm9yIHdpbGwgYmUgdGhyb3duICh0aGUgZXhjZXB0aW9uIGNhbiBiZSB0aHdhcnRlZAogKiBieSBzZXR0aW5nIHRoZSAybmQgcGFyYW1ldGVyIG9mIHRoZSBmdW5jdGlvbiB0byB0cnVlKS4KICoKICogQHBhcmFtIHtzdHJpbmd9IHRwbCBUaGUgSFRUUCByZXF1ZXN0IHRlbXBsYXRlIFVSTAogKiBAcGFyYW0ge2Jvb2xlYW49fSBpZ25vcmVSZXF1ZXN0RXJyb3IgV2hldGhlciBvciBub3QgdG8gaWdub3JlIHRoZSBleGNlcHRpb24gd2hlbiB0aGUgcmVxdWVzdCBmYWlscyBvciB0aGUgdGVtcGxhdGUgaXMgZW1wdHkKICoKICogQHJldHVybiB7UHJvbWlzZX0gdGhlIEhUVFAgUHJvbWlzZSBmb3IgdGhlIGdpdmVuLgogKgogKiBAcHJvcGVydHkge251bWJlcn0gdG90YWxQZW5kaW5nUmVxdWVzdHMgdG90YWwgYW1vdW50IG9mIHBlbmRpbmcgdGVtcGxhdGUgcmVxdWVzdHMgYmVpbmcgZG93bmxvYWRlZC4KICovCmZ1bmN0aW9uICRUZW1wbGF0ZVJlcXVlc3RQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyR0ZW1wbGF0ZUNhY2hlJywgJyRodHRwJywgJyRxJywgZnVuY3Rpb24oJHRlbXBsYXRlQ2FjaGUsICRodHRwLCAkcSkgewogICAgZnVuY3Rpb24gaGFuZGxlUmVxdWVzdEZuKHRwbCwgaWdub3JlUmVxdWVzdEVycm9yKSB7CiAgICAgIHZhciBzZWxmID0gaGFuZGxlUmVxdWVzdEZuOwogICAgICBzZWxmLnRvdGFsUGVuZGluZ1JlcXVlc3RzKys7CgogICAgICB2YXIgdHJhbnNmb3JtUmVzcG9uc2UgPSAkaHR0cC5kZWZhdWx0cyAmJiAkaHR0cC5kZWZhdWx0cy50cmFuc2Zvcm1SZXNwb25zZTsKCiAgICAgIGlmIChpc0FycmF5KHRyYW5zZm9ybVJlc3BvbnNlKSkgewogICAgICAgIHRyYW5zZm9ybVJlc3BvbnNlID0gdHJhbnNmb3JtUmVzcG9uc2UuZmlsdGVyKGZ1bmN0aW9uKHRyYW5zZm9ybWVyKSB7CiAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZXIgIT09IGRlZmF1bHRIdHRwUmVzcG9uc2VUcmFuc2Zvcm07CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSBpZiAodHJhbnNmb3JtUmVzcG9uc2UgPT09IGRlZmF1bHRIdHRwUmVzcG9uc2VUcmFuc2Zvcm0pIHsKICAgICAgICB0cmFuc2Zvcm1SZXNwb25zZSA9IG51bGw7CiAgICAgIH0KCiAgICAgIHZhciBodHRwT3B0aW9ucyA9IHsKICAgICAgICBjYWNoZTogJHRlbXBsYXRlQ2FjaGUsCiAgICAgICAgdHJhbnNmb3JtUmVzcG9uc2U6IHRyYW5zZm9ybVJlc3BvbnNlCiAgICAgIH07CgogICAgICByZXR1cm4gJGh0dHAuZ2V0KHRwbCwgaHR0cE9wdGlvbnMpCiAgICAgICAgLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICAgIHNlbGYudG90YWxQZW5kaW5nUmVxdWVzdHMtLTsKICAgICAgICAgIHJldHVybiByZXNwb25zZS5kYXRhOwogICAgICAgIH0sIGhhbmRsZUVycm9yKTsKCiAgICAgIGZ1bmN0aW9uIGhhbmRsZUVycm9yKHJlc3ApIHsKICAgICAgICBzZWxmLnRvdGFsUGVuZGluZ1JlcXVlc3RzLS07CiAgICAgICAgaWYgKCFpZ25vcmVSZXF1ZXN0RXJyb3IpIHsKICAgICAgICAgIHRocm93ICRjb21waWxlTWluRXJyKCd0cGxvYWQnLCAnRmFpbGVkIHRvIGxvYWQgdGVtcGxhdGU6IHswfScsIHRwbCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcS5yZWplY3QocmVzcCk7CiAgICAgIH0KICAgIH0KCiAgICBoYW5kbGVSZXF1ZXN0Rm4udG90YWxQZW5kaW5nUmVxdWVzdHMgPSAwOwoKICAgIHJldHVybiBoYW5kbGVSZXF1ZXN0Rm47CiAgfV07Cn0KCmZ1bmN0aW9uICQkVGVzdGFiaWxpdHlQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyRyb290U2NvcGUnLCAnJGJyb3dzZXInLCAnJGxvY2F0aW9uJywKICAgICAgIGZ1bmN0aW9uKCRyb290U2NvcGUsICAgJGJyb3dzZXIsICAgJGxvY2F0aW9uKSB7CgogICAgLyoqCiAgICAgKiBAbmFtZSAkdGVzdGFiaWxpdHkKICAgICAqCiAgICAgKiBAZGVzY3JpcHRpb24KICAgICAqIFRoZSBwcml2YXRlICQkdGVzdGFiaWxpdHkgc2VydmljZSBwcm92aWRlcyBhIGNvbGxlY3Rpb24gb2YgbWV0aG9kcyBmb3IgdXNlIHdoZW4gZGVidWdnaW5nCiAgICAgKiBvciBieSBhdXRvbWF0ZWQgdGVzdCBhbmQgZGVidWdnaW5nIHRvb2xzLgogICAgICovCiAgICB2YXIgdGVzdGFiaWxpdHkgPSB7fTsKCiAgICAvKioKICAgICAqIEBuYW1lICQkdGVzdGFiaWxpdHkjZmluZEJpbmRpbmdzCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIGJvdW5kICh2aWEgbmctYmluZCBvciB7e319KQogICAgICogdG8gZXhwcmVzc2lvbnMgbWF0Y2hpbmcgdGhlIGlucHV0LgogICAgICoKICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCByb290IHRvIHNlYXJjaCBmcm9tLgogICAgICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gVGhlIGJpbmRpbmcgZXhwcmVzc2lvbiB0byBtYXRjaC4KICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0X2V4YWN0TWF0Y2ggSWYgdHJ1ZSwgb25seSByZXR1cm5zIGV4YWN0IG1hdGNoZXMKICAgICAqICAgICBmb3IgdGhlIGV4cHJlc3Npb24uIEZpbHRlcnMgYW5kIHdoaXRlc3BhY2UgYXJlIGlnbm9yZWQuCiAgICAgKi8KICAgIHRlc3RhYmlsaXR5LmZpbmRCaW5kaW5ncyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGV4cHJlc3Npb24sIG9wdF9leGFjdE1hdGNoKSB7CiAgICAgIHZhciBiaW5kaW5ncyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbmctYmluZGluZycpOwogICAgICB2YXIgbWF0Y2hlcyA9IFtdOwogICAgICBmb3JFYWNoKGJpbmRpbmdzLCBmdW5jdGlvbihiaW5kaW5nKSB7CiAgICAgICAgdmFyIGRhdGFCaW5kaW5nID0gYW5ndWxhci5lbGVtZW50KGJpbmRpbmcpLmRhdGEoJyRiaW5kaW5nJyk7CiAgICAgICAgaWYgKGRhdGFCaW5kaW5nKSB7CiAgICAgICAgICBmb3JFYWNoKGRhdGFCaW5kaW5nLCBmdW5jdGlvbihiaW5kaW5nTmFtZSkgewogICAgICAgICAgICBpZiAob3B0X2V4YWN0TWF0Y2gpIHsKICAgICAgICAgICAgICB2YXIgbWF0Y2hlciA9IG5ldyBSZWdFeHAoJyhefFxccyknICsgZXNjYXBlRm9yUmVnZXhwKGV4cHJlc3Npb24pICsgJyhcXHN8XFx8fCQpJyk7CiAgICAgICAgICAgICAgaWYgKG1hdGNoZXIudGVzdChiaW5kaW5nTmFtZSkpIHsKICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChiaW5kaW5nKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGJpbmRpbmdOYW1lLmluZGV4T2YoZXhwcmVzc2lvbikgIT0gLTEpIHsKICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChiaW5kaW5nKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBtYXRjaGVzOwogICAgfTsKCiAgICAvKioKICAgICAqIEBuYW1lICQkdGVzdGFiaWxpdHkjZmluZE1vZGVscwogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBlbGVtZW50cyB0aGF0IGFyZSB0d28td2F5IGZvdW5kIHZpYSBuZy1tb2RlbCB0bwogICAgICogZXhwcmVzc2lvbnMgbWF0Y2hpbmcgdGhlIGlucHV0LgogICAgICoKICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCByb290IHRvIHNlYXJjaCBmcm9tLgogICAgICogQHBhcmFtIHtzdHJpbmd9IGV4cHJlc3Npb24gVGhlIG1vZGVsIGV4cHJlc3Npb24gdG8gbWF0Y2guCiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdF9leGFjdE1hdGNoIElmIHRydWUsIG9ubHkgcmV0dXJucyBleGFjdCBtYXRjaGVzCiAgICAgKiAgICAgZm9yIHRoZSBleHByZXNzaW9uLgogICAgICovCiAgICB0ZXN0YWJpbGl0eS5maW5kTW9kZWxzID0gZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgb3B0X2V4YWN0TWF0Y2gpIHsKICAgICAgdmFyIHByZWZpeGVzID0gWyduZy0nLCAnZGF0YS1uZy0nLCAnbmdcXDonXTsKICAgICAgZm9yICh2YXIgcCA9IDA7IHAgPCBwcmVmaXhlcy5sZW5ndGg7ICsrcCkgewogICAgICAgIHZhciBhdHRyaWJ1dGVFcXVhbHMgPSBvcHRfZXhhY3RNYXRjaCA/ICc9JyA6ICcqPSc7CiAgICAgICAgdmFyIHNlbGVjdG9yID0gJ1snICsgcHJlZml4ZXNbcF0gKyAnbW9kZWwnICsgYXR0cmlidXRlRXF1YWxzICsgJyInICsgZXhwcmVzc2lvbiArICciXSc7CiAgICAgICAgdmFyIGVsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTsKICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoKSB7CiAgICAgICAgICByZXR1cm4gZWxlbWVudHM7CiAgICAgICAgfQogICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogQG5hbWUgJCR0ZXN0YWJpbGl0eSNnZXRMb2NhdGlvbgogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRjdXQgZm9yIGdldHRpbmcgdGhlIGxvY2F0aW9uIGluIGEgYnJvd3NlciBhZ25vc3RpYyB3YXkuIFJldHVybnMKICAgICAqICAgICB0aGUgcGF0aCwgc2VhcmNoLCBhbmQgaGFzaC4gKGUuZy4gL3BhdGg/YT1iI2hhc2gpCiAgICAgKi8KICAgIHRlc3RhYmlsaXR5LmdldExvY2F0aW9uID0gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAkbG9jYXRpb24udXJsKCk7CiAgICB9OwoKICAgIC8qKgogICAgICogQG5hbWUgJCR0ZXN0YWJpbGl0eSNzZXRMb2NhdGlvbgogICAgICoKICAgICAqIEBkZXNjcmlwdGlvbgogICAgICogU2hvcnRjdXQgZm9yIG5hdmlnYXRpbmcgdG8gYSBsb2NhdGlvbiB3aXRob3V0IGRvaW5nIGEgZnVsbCBwYWdlIHJlbG9hZC4KICAgICAqCiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSBsb2NhdGlvbiB1cmwgKHBhdGgsIHNlYXJjaCBhbmQgaGFzaCwKICAgICAqICAgICBlLmcuIC9wYXRoP2E9YiNoYXNoKSB0byBnbyB0by4KICAgICAqLwogICAgdGVzdGFiaWxpdHkuc2V0TG9jYXRpb24gPSBmdW5jdGlvbih1cmwpIHsKICAgICAgaWYgKHVybCAhPT0gJGxvY2F0aW9uLnVybCgpKSB7CiAgICAgICAgJGxvY2F0aW9uLnVybCh1cmwpOwogICAgICAgICRyb290U2NvcGUuJGRpZ2VzdCgpOwogICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogQG5hbWUgJCR0ZXN0YWJpbGl0eSN3aGVuU3RhYmxlCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBDYWxscyB0aGUgY2FsbGJhY2sgd2hlbiAkdGltZW91dCBhbmQgJGh0dHAgcmVxdWVzdHMgYXJlIGNvbXBsZXRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjawogICAgICovCiAgICB0ZXN0YWJpbGl0eS53aGVuU3RhYmxlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgJGJyb3dzZXIubm90aWZ5V2hlbk5vT3V0c3RhbmRpbmdSZXF1ZXN0cyhjYWxsYmFjayk7CiAgICB9OwoKICAgIHJldHVybiB0ZXN0YWJpbGl0eTsKICB9XTsKfQoKZnVuY3Rpb24gJFRpbWVvdXRQcm92aWRlcigpIHsKICB0aGlzLiRnZXQgPSBbJyRyb290U2NvcGUnLCAnJGJyb3dzZXInLCAnJHEnLCAnJCRxJywgJyRleGNlcHRpb25IYW5kbGVyJywKICAgICAgIGZ1bmN0aW9uKCRyb290U2NvcGUsICAgJGJyb3dzZXIsICAgJHEsICAgJCRxLCAgICRleGNlcHRpb25IYW5kbGVyKSB7CiAgICB2YXIgZGVmZXJyZWRzID0ge307CgoKICAgICAvKioKICAgICAgKiBAbmdkb2Mgc2VydmljZQogICAgICAqIEBuYW1lICR0aW1lb3V0CiAgICAgICoKICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgKiBBbmd1bGFyJ3Mgd3JhcHBlciBmb3IgYHdpbmRvdy5zZXRUaW1lb3V0YC4gVGhlIGBmbmAgZnVuY3Rpb24gaXMgd3JhcHBlZCBpbnRvIGEgdHJ5L2NhdGNoCiAgICAgICogYmxvY2sgYW5kIGRlbGVnYXRlcyBhbnkgZXhjZXB0aW9ucyB0bwogICAgICAqIHtAbGluayBuZy4kZXhjZXB0aW9uSGFuZGxlciAkZXhjZXB0aW9uSGFuZGxlcn0gc2VydmljZS4KICAgICAgKgogICAgICAqIFRoZSByZXR1cm4gdmFsdWUgb2YgcmVnaXN0ZXJpbmcgYSB0aW1lb3V0IGZ1bmN0aW9uIGlzIGEgcHJvbWlzZSwgd2hpY2ggd2lsbCBiZSByZXNvbHZlZCB3aGVuCiAgICAgICogdGhlIHRpbWVvdXQgaXMgcmVhY2hlZCBhbmQgdGhlIHRpbWVvdXQgZnVuY3Rpb24gaXMgZXhlY3V0ZWQuCiAgICAgICoKICAgICAgKiBUbyBjYW5jZWwgYSB0aW1lb3V0IHJlcXVlc3QsIGNhbGwgYCR0aW1lb3V0LmNhbmNlbChwcm9taXNlKWAuCiAgICAgICoKICAgICAgKiBJbiB0ZXN0cyB5b3UgY2FuIHVzZSB7QGxpbmsgbmdNb2NrLiR0aW1lb3V0IGAkdGltZW91dC5mbHVzaCgpYH0gdG8KICAgICAgKiBzeW5jaHJvbm91c2x5IGZsdXNoIHRoZSBxdWV1ZSBvZiBkZWZlcnJlZCBmdW5jdGlvbnMuCiAgICAgICoKICAgICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGZuIEEgZnVuY3Rpb24sIHdob3NlIGV4ZWN1dGlvbiBzaG91bGQgYmUgZGVsYXllZC4KICAgICAgKiBAcGFyYW0ge251bWJlcj19IFtkZWxheT0wXSBEZWxheSBpbiBtaWxsaXNlY29uZHMuCiAgICAgICogQHBhcmFtIHtib29sZWFuPX0gW2ludm9rZUFwcGx5PXRydWVdIElmIHNldCB0byBgZmFsc2VgIHNraXBzIG1vZGVsIGRpcnR5IGNoZWNraW5nLCBvdGhlcndpc2UKICAgICAgKiAgIHdpbGwgaW52b2tlIGBmbmAgd2l0aGluIHRoZSB7QGxpbmsgbmcuJHJvb3RTY29wZS5TY29wZSMkYXBwbHkgJGFwcGx5fSBibG9jay4KICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgd2hlbiB0aGUgdGltZW91dCBpcyByZWFjaGVkLiBUaGUgdmFsdWUgdGhpcwogICAgICAqICAgcHJvbWlzZSB3aWxsIGJlIHJlc29sdmVkIHdpdGggaXMgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgYGZuYCBmdW5jdGlvbi4KICAgICAgKgogICAgICAqLwogICAgZnVuY3Rpb24gdGltZW91dChmbiwgZGVsYXksIGludm9rZUFwcGx5KSB7CiAgICAgIHZhciBza2lwQXBwbHkgPSAoaXNEZWZpbmVkKGludm9rZUFwcGx5KSAmJiAhaW52b2tlQXBwbHkpLAogICAgICAgICAgZGVmZXJyZWQgPSAoc2tpcEFwcGx5ID8gJCRxIDogJHEpLmRlZmVyKCksCiAgICAgICAgICBwcm9taXNlID0gZGVmZXJyZWQucHJvbWlzZSwKICAgICAgICAgIHRpbWVvdXRJZDsKCiAgICAgIHRpbWVvdXRJZCA9ICRicm93c2VyLmRlZmVyKGZ1bmN0aW9uKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKGZuKCkpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIGRlZmVycmVkLnJlamVjdChlKTsKICAgICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgIGRlbGV0ZSBkZWZlcnJlZHNbcHJvbWlzZS4kJHRpbWVvdXRJZF07CiAgICAgICAgfQoKICAgICAgICBpZiAoIXNraXBBcHBseSkgJHJvb3RTY29wZS4kYXBwbHkoKTsKICAgICAgfSwgZGVsYXkpOwoKICAgICAgcHJvbWlzZS4kJHRpbWVvdXRJZCA9IHRpbWVvdXRJZDsKICAgICAgZGVmZXJyZWRzW3RpbWVvdXRJZF0gPSBkZWZlcnJlZDsKCiAgICAgIHJldHVybiBwcm9taXNlOwogICAgfQoKCiAgICAgLyoqCiAgICAgICogQG5nZG9jIG1ldGhvZAogICAgICAqIEBuYW1lICR0aW1lb3V0I2NhbmNlbAogICAgICAqCiAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICogQ2FuY2VscyBhIHRhc2sgYXNzb2NpYXRlZCB3aXRoIHRoZSBgcHJvbWlzZWAuIEFzIGEgcmVzdWx0IG9mIHRoaXMsIHRoZSBwcm9taXNlIHdpbGwgYmUKICAgICAgKiByZXNvbHZlZCB3aXRoIGEgcmVqZWN0aW9uLgogICAgICAqCiAgICAgICogQHBhcmFtIHtQcm9taXNlPX0gcHJvbWlzZSBQcm9taXNlIHJldHVybmVkIGJ5IHRoZSBgJHRpbWVvdXRgIGZ1bmN0aW9uLgogICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdGFzayBoYXNuJ3QgZXhlY3V0ZWQgeWV0IGFuZCB3YXMgc3VjY2Vzc2Z1bGx5CiAgICAgICogICBjYW5jZWxlZC4KICAgICAgKi8KICAgIHRpbWVvdXQuY2FuY2VsID0gZnVuY3Rpb24ocHJvbWlzZSkgewogICAgICBpZiAocHJvbWlzZSAmJiBwcm9taXNlLiQkdGltZW91dElkIGluIGRlZmVycmVkcykgewogICAgICAgIGRlZmVycmVkc1twcm9taXNlLiQkdGltZW91dElkXS5yZWplY3QoJ2NhbmNlbGVkJyk7CiAgICAgICAgZGVsZXRlIGRlZmVycmVkc1twcm9taXNlLiQkdGltZW91dElkXTsKICAgICAgICByZXR1cm4gJGJyb3dzZXIuZGVmZXIuY2FuY2VsKHByb21pc2UuJCR0aW1lb3V0SWQpOwogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgcmV0dXJuIHRpbWVvdXQ7CiAgfV07Cn0KCi8vIE5PVEU6ICBUaGUgdXNhZ2Ugb2Ygd2luZG93IGFuZCBkb2N1bWVudCBpbnN0ZWFkIG9mICR3aW5kb3cgYW5kICRkb2N1bWVudCBoZXJlIGlzCi8vIGRlbGliZXJhdGUuICBUaGlzIHNlcnZpY2UgZGVwZW5kcyBvbiB0aGUgc3BlY2lmaWMgYmVoYXZpb3Igb2YgYW5jaG9yIG5vZGVzIGNyZWF0ZWQgYnkgdGhlCi8vIGJyb3dzZXIgKHJlc29sdmluZyBhbmQgcGFyc2luZyBVUkxzKSB0aGF0IGlzIHVubGlrZWx5IHRvIGJlIHByb3ZpZGVkIGJ5IG1vY2sgb2JqZWN0cyBhbmQKLy8gY2F1c2UgdXMgdG8gYnJlYWsgdGVzdHMuICBJbiBhZGRpdGlvbiwgd2hlbiB0aGUgYnJvd3NlciByZXNvbHZlcyBhIFVSTCBmb3IgWEhSLCBpdAovLyBkb2Vzbid0IGtub3cgYWJvdXQgbW9ja2VkIGxvY2F0aW9ucyBhbmQgcmVzb2x2ZXMgVVJMcyB0byB0aGUgcmVhbCBkb2N1bWVudCAtIHdoaWNoIGlzCi8vIGV4YWN0bHkgdGhlIGJlaGF2aW9yIG5lZWRlZCBoZXJlLiAgVGhlcmUgaXMgbGl0dGxlIHZhbHVlIGlzIG1vY2tpbmcgdGhlc2Ugb3V0IGZvciB0aGlzCi8vIHNlcnZpY2UuCnZhciB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsKdmFyIG9yaWdpblVybCA9IHVybFJlc29sdmUod2luZG93LmxvY2F0aW9uLmhyZWYpOwoKCi8qKgogKgogKiBJbXBsZW1lbnRhdGlvbiBOb3RlcyBmb3Igbm9uLUlFIGJyb3dzZXJzCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQXNzaWduaW5nIGEgVVJMIHRvIHRoZSBocmVmIHByb3BlcnR5IG9mIGFuIGFuY2hvciBET00gbm9kZSwgZXZlbiBvbmUgYXR0YWNoZWQgdG8gdGhlIERPTSwKICogcmVzdWx0cyBib3RoIGluIHRoZSBub3JtYWxpemluZyBhbmQgcGFyc2luZyBvZiB0aGUgVVJMLiAgTm9ybWFsaXppbmcgbWVhbnMgdGhhdCBhIHJlbGF0aXZlCiAqIFVSTCB3aWxsIGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJMIGluIHRoZSBjb250ZXh0IG9mIHRoZSBhcHBsaWNhdGlvbiBkb2N1bWVudC4KICogUGFyc2luZyBtZWFucyB0aGF0IHRoZSBhbmNob3Igbm9kZSdzIGhvc3QsIGhvc3RuYW1lLCBwcm90b2NvbCwgcG9ydCwgcGF0aG5hbWUgYW5kIHJlbGF0ZWQKICogcHJvcGVydGllcyBhcmUgYWxsIHBvcHVsYXRlZCB0byByZWZsZWN0IHRoZSBub3JtYWxpemVkIFVSTC4gIFRoaXMgYXBwcm9hY2ggaGFzIHdpZGUKICogY29tcGF0aWJpbGl0eSAtIFNhZmFyaSAxKywgTW96aWxsYSAxKywgT3BlcmEgNyssZSBldGMuICBTZWUKICogaHR0cDovL3d3dy5hcHRhbmEuY29tL3JlZmVyZW5jZS9odG1sL2FwaS9IVE1MQW5jaG9yRWxlbWVudC5odG1sCiAqCiAqIEltcGxlbWVudGF0aW9uIE5vdGVzIGZvciBJRQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogSUUgPj0gOCBhbmQgPD0gMTAgbm9ybWFsaXplcyB0aGUgVVJMIHdoZW4gYXNzaWduZWQgdG8gdGhlIGFuY2hvciBub2RlIHNpbWlsYXIgdG8gdGhlIG90aGVyCiAqIGJyb3dzZXJzLiAgSG93ZXZlciwgdGhlIHBhcnNlZCBjb21wb25lbnRzIHdpbGwgbm90IGJlIHNldCBpZiB0aGUgVVJMIGFzc2lnbmVkIGRpZCBub3Qgc3BlY2lmeQogKiB0aGVtLiAgKGUuZy4gaWYgeW91IGFzc2lnbiBhLmhyZWYgPSAiZm9vIiwgdGhlbiBhLnByb3RvY29sLCBhLmhvc3QsIGV0Yy4gd2lsbCBiZSBlbXB0eS4pICBXZQogKiB3b3JrIGFyb3VuZCB0aGF0IGJ5IHBlcmZvcm1pbmcgdGhlIHBhcnNpbmcgaW4gYSAybmQgc3RlcCBieSB0YWtpbmcgYSBwcmV2aW91c2x5IG5vcm1hbGl6ZWQKICogVVJMIChlLmcuIGJ5IGFzc2lnbmluZyB0byBhLmhyZWYpIGFuZCBhc3NpZ25pbmcgaXQgYS5ocmVmIGFnYWluLiAgVGhpcyBjb3JyZWN0bHkgcG9wdWxhdGVzIHRoZQogKiBwcm9wZXJ0aWVzIHN1Y2ggYXMgcHJvdG9jb2wsIGhvc3RuYW1lLCBwb3J0LCBldGMuCiAqCiAqIElFNyBkb2VzIG5vdCBub3JtYWxpemUgdGhlIFVSTCB3aGVuIGFzc2lnbmVkIHRvIGFuIGFuY2hvciBub2RlLiAgKEFwcGFyZW50bHksIGl0IGRvZXMsIGlmIG9uZQogKiB1c2VzIHRoZSBpbm5lciBIVE1MIGFwcHJvYWNoIHRvIGFzc2lnbiB0aGUgVVJMIGFzIHBhcnQgb2YgYW4gSFRNTCBzbmlwcGV0IC0KICogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNDcyNzI5KSAgSG93ZXZlciwgc2V0dGluZyBpbWdbc3JjXSBkb2VzIG5vcm1hbGl6ZSB0aGUgVVJMLgogKiBVbmZvcnR1bmF0ZWx5LCBzZXR0aW5nIGltZ1tzcmNdIHRvIHNvbWV0aGluZyBsaWtlICJqYXZhc2NyaXB0OmZvbyIgb24gSUUgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KICogU2luY2UgdGhlIHByaW1hcnkgdXNhZ2UgZm9yIG5vcm1hbGl6aW5nIFVSTHMgaXMgdG8gc2FuaXRpemUgc3VjaCBVUkxzLCB3ZSBjYW4ndCB1c2UgdGhhdAogKiBtZXRob2QgYW5kIElFIDwgOCBpcyB1bnN1cHBvcnRlZC4KICoKICogUmVmZXJlbmNlczoKICogICBodHRwOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MQW5jaG9yRWxlbWVudAogKiAgIGh0dHA6Ly93d3cuYXB0YW5hLmNvbS9yZWZlcmVuY2UvaHRtbC9hcGkvSFRNTEFuY2hvckVsZW1lbnQuaHRtbAogKiAgIGh0dHA6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmx1dGlscwogKiAgIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvcHVsbC8yOTAyCiAqICAgaHR0cDovL2phbWVzLnBhZG9sc2V5LmNvbS9qYXZhc2NyaXB0L3BhcnNpbmctdXJscy13aXRoLXRoZS1kb20vCiAqCiAqIEBraW5kIGZ1bmN0aW9uCiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIFVSTCB0byBiZSBwYXJzZWQuCiAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIGFuZCBwYXJzZXMgYSBVUkwuCiAqIEByZXR1cm5zIHtvYmplY3R9IFJldHVybnMgdGhlIG5vcm1hbGl6ZWQgVVJMIGFzIGEgZGljdGlvbmFyeS4KICoKICogICB8IG1lbWJlciBuYW1lICAgfCBEZXNjcmlwdGlvbiAgICB8CiAqICAgfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfAogKiAgIHwgaHJlZiAgICAgICAgICB8IEEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBwcm92aWRlZCBVUkwgaWYgaXQgd2FzIG5vdCBhbiBhYnNvbHV0ZSBVUkwgfAogKiAgIHwgcHJvdG9jb2wgICAgICB8IFRoZSBwcm90b2NvbCBpbmNsdWRpbmcgdGhlIHRyYWlsaW5nIGNvbG9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgIHwgaG9zdCAgICAgICAgICB8IFRoZSBob3N0IGFuZCBwb3J0IChpZiB0aGUgcG9ydCBpcyBub24tZGVmYXVsdCkgb2YgdGhlIG5vcm1hbGl6ZWRVcmwgICAgfAogKiAgIHwgc2VhcmNoICAgICAgICB8IFRoZSBzZWFyY2ggcGFyYW1zLCBtaW51cyB0aGUgcXVlc3Rpb24gbWFyayAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgIHwgaGFzaCAgICAgICAgICB8IFRoZSBoYXNoIHN0cmluZywgbWludXMgdGhlIGhhc2ggc3ltYm9sCiAqICAgfCBob3N0bmFtZSAgICAgIHwgVGhlIGhvc3RuYW1lCiAqICAgfCBwb3J0ICAgICAgICAgIHwgVGhlIHBvcnQsIHdpdGhvdXQgIjoiCiAqICAgfCBwYXRobmFtZSAgICAgIHwgVGhlIHBhdGhuYW1lLCBiZWdpbm5pbmcgd2l0aCAiLyIKICoKICovCmZ1bmN0aW9uIHVybFJlc29sdmUodXJsKSB7CiAgdmFyIGhyZWYgPSB1cmw7CgogIGlmIChtc2llKSB7CiAgICAvLyBOb3JtYWxpemUgYmVmb3JlIHBhcnNlLiAgUmVmZXIgSW1wbGVtZW50YXRpb24gTm90ZXMgb24gd2h5IHRoaXMgaXMKICAgIC8vIGRvbmUgaW4gdHdvIHN0ZXBzIG9uIElFLgogICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCJocmVmIiwgaHJlZik7CiAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjsKICB9CgogIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpOwoKICAvLyB1cmxQYXJzaW5nTm9kZSBwcm92aWRlcyB0aGUgVXJsVXRpbHMgaW50ZXJmYWNlIC0gaHR0cDovL3VybC5zcGVjLndoYXR3Zy5vcmcvI3VybHV0aWxzCiAgcmV0dXJuIHsKICAgIGhyZWY6IHVybFBhcnNpbmdOb2RlLmhyZWYsCiAgICBwcm90b2NvbDogdXJsUGFyc2luZ05vZGUucHJvdG9jb2wgPyB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbC5yZXBsYWNlKC86JC8sICcnKSA6ICcnLAogICAgaG9zdDogdXJsUGFyc2luZ05vZGUuaG9zdCwKICAgIHNlYXJjaDogdXJsUGFyc2luZ05vZGUuc2VhcmNoID8gdXJsUGFyc2luZ05vZGUuc2VhcmNoLnJlcGxhY2UoL15cPy8sICcnKSA6ICcnLAogICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJywKICAgIGhvc3RuYW1lOiB1cmxQYXJzaW5nTm9kZS5ob3N0bmFtZSwKICAgIHBvcnQ6IHVybFBhcnNpbmdOb2RlLnBvcnQsCiAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKQogICAgICA/IHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lCiAgICAgIDogJy8nICsgdXJsUGFyc2luZ05vZGUucGF0aG5hbWUKICB9Owp9CgovKioKICogUGFyc2UgYSByZXF1ZXN0IFVSTCBhbmQgZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIHNhbWUtb3JpZ2luIHJlcXVlc3QgYXMgdGhlIGFwcGxpY2F0aW9uIGRvY3VtZW50LgogKgogKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHJlcXVlc3RVcmwgVGhlIHVybCBvZiB0aGUgcmVxdWVzdCBhcyBhIHN0cmluZyB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQKICogb3IgYSBwYXJzZWQgVVJMIG9iamVjdC4KICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlcXVlc3QgaXMgZm9yIHRoZSBzYW1lIG9yaWdpbiBhcyB0aGUgYXBwbGljYXRpb24gZG9jdW1lbnQuCiAqLwpmdW5jdGlvbiB1cmxJc1NhbWVPcmlnaW4ocmVxdWVzdFVybCkgewogIHZhciBwYXJzZWQgPSAoaXNTdHJpbmcocmVxdWVzdFVybCkpID8gdXJsUmVzb2x2ZShyZXF1ZXN0VXJsKSA6IHJlcXVlc3RVcmw7CiAgcmV0dXJuIChwYXJzZWQucHJvdG9jb2wgPT09IG9yaWdpblVybC5wcm90b2NvbCAmJgogICAgICAgICAgcGFyc2VkLmhvc3QgPT09IG9yaWdpblVybC5ob3N0KTsKfQoKLyoqCiAqIEBuZ2RvYyBzZXJ2aWNlCiAqIEBuYW1lICR3aW5kb3cKICoKICogQGRlc2NyaXB0aW9uCiAqIEEgcmVmZXJlbmNlIHRvIHRoZSBicm93c2VyJ3MgYHdpbmRvd2Agb2JqZWN0LiBXaGlsZSBgd2luZG93YAogKiBpcyBnbG9iYWxseSBhdmFpbGFibGUgaW4gSmF2YVNjcmlwdCwgaXQgY2F1c2VzIHRlc3RhYmlsaXR5IHByb2JsZW1zLCBiZWNhdXNlCiAqIGl0IGlzIGEgZ2xvYmFsIHZhcmlhYmxlLiBJbiBhbmd1bGFyIHdlIGFsd2F5cyByZWZlciB0byBpdCB0aHJvdWdoIHRoZQogKiBgJHdpbmRvd2Agc2VydmljZSwgc28gaXQgbWF5IGJlIG92ZXJyaWRkZW4sIHJlbW92ZWQgb3IgbW9ja2VkIGZvciB0ZXN0aW5nLgogKgogKiBFeHByZXNzaW9ucywgbGlrZSB0aGUgb25lIGRlZmluZWQgZm9yIHRoZSBgbmdDbGlja2AgZGlyZWN0aXZlIGluIHRoZSBleGFtcGxlCiAqIGJlbG93LCBhcmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdCB0byB0aGUgY3VycmVudCBzY29wZS4gIFRoZXJlZm9yZSwgdGhlcmUgaXMKICogbm8gcmlzayBvZiBpbmFkdmVydGVudGx5IGNvZGluZyBpbiBhIGRlcGVuZGVuY3kgb24gYSBnbG9iYWwgdmFsdWUgaW4gc3VjaCBhbgogKiBleHByZXNzaW9uLgogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZSBtb2R1bGU9IndpbmRvd0V4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNjcmlwdD4KICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ3dpbmRvd0V4YW1wbGUnLCBbXSkKICAgICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsICckd2luZG93JywgZnVuY3Rpb24oJHNjb3BlLCAkd2luZG93KSB7CiAgICAgICAgICAgICAkc2NvcGUuZ3JlZXRpbmcgPSAnSGVsbG8sIFdvcmxkISc7CiAgICAgICAgICAgICAkc2NvcGUuZG9HcmVldGluZyA9IGZ1bmN0aW9uKGdyZWV0aW5nKSB7CiAgICAgICAgICAgICAgICR3aW5kb3cuYWxlcnQoZ3JlZXRpbmcpOwogICAgICAgICAgICAgfTsKICAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9ImdyZWV0aW5nIiAvPgogICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSJkb0dyZWV0aW5nKGdyZWV0aW5nKSI+QUxFUlQ8L2J1dHRvbj4KICAgICAgIDwvZGl2PgogICAgIDwvZmlsZT4KICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgaXQoJ3Nob3VsZCBkaXNwbGF5IHRoZSBncmVldGluZyBpbiB0aGUgaW5wdXQgYm94JywgZnVuY3Rpb24oKSB7CiAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdncmVldGluZycpKS5zZW5kS2V5cygnSGVsbG8sIEUyRSBUZXN0cycpOwogICAgICAgLy8gSWYgd2UgY2xpY2sgdGhlIGJ1dHRvbiBpdCB3aWxsIGJsb2NrIHRoZSB0ZXN0IHJ1bm5lcgogICAgICAgLy8gZWxlbWVudCgnOmJ1dHRvbicpLmNsaWNrKCk7CiAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KZnVuY3Rpb24gJFdpbmRvd1Byb3ZpZGVyKCkgewogIHRoaXMuJGdldCA9IHZhbHVlRm4od2luZG93KTsKfQoKLyogZ2xvYmFsIGN1cnJlbmN5RmlsdGVyOiB0cnVlLAogZGF0ZUZpbHRlcjogdHJ1ZSwKIGZpbHRlckZpbHRlcjogdHJ1ZSwKIGpzb25GaWx0ZXI6IHRydWUsCiBsaW1pdFRvRmlsdGVyOiB0cnVlLAogbG93ZXJjYXNlRmlsdGVyOiB0cnVlLAogbnVtYmVyRmlsdGVyOiB0cnVlLAogb3JkZXJCeUZpbHRlcjogdHJ1ZSwKIHVwcGVyY2FzZUZpbHRlcjogdHJ1ZSwKICovCgovKioKICogQG5nZG9jIHByb3ZpZGVyCiAqIEBuYW1lICRmaWx0ZXJQcm92aWRlcgogKiBAZGVzY3JpcHRpb24KICoKICogRmlsdGVycyBhcmUganVzdCBmdW5jdGlvbnMgd2hpY2ggdHJhbnNmb3JtIGlucHV0IHRvIGFuIG91dHB1dC4gSG93ZXZlciBmaWx0ZXJzIG5lZWQgdG8gYmUKICogRGVwZW5kZW5jeSBJbmplY3RlZC4gVG8gYWNoaWV2ZSB0aGlzIGEgZmlsdGVyIGRlZmluaXRpb24gY29uc2lzdHMgb2YgYSBmYWN0b3J5IGZ1bmN0aW9uIHdoaWNoIGlzCiAqIGFubm90YXRlZCB3aXRoIGRlcGVuZGVuY2llcyBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGNyZWF0aW5nIGEgZmlsdGVyIGZ1bmN0aW9uLgogKgogKiBgYGBqcwogKiAgIC8vIEZpbHRlciByZWdpc3RyYXRpb24KICogICBmdW5jdGlvbiBNeU1vZHVsZSgkcHJvdmlkZSwgJGZpbHRlclByb3ZpZGVyKSB7CiAqICAgICAvLyBjcmVhdGUgYSBzZXJ2aWNlIHRvIGRlbW9uc3RyYXRlIGluamVjdGlvbiAobm90IGFsd2F5cyBuZWVkZWQpCiAqICAgICAkcHJvdmlkZS52YWx1ZSgnZ3JlZXQnLCBmdW5jdGlvbihuYW1lKXsKICogICAgICAgcmV0dXJuICdIZWxsbyAnICsgbmFtZSArICchJzsKICogICAgIH0pOwogKgogKiAgICAgLy8gcmVnaXN0ZXIgYSBmaWx0ZXIgZmFjdG9yeSB3aGljaCB1c2VzIHRoZQogKiAgICAgLy8gZ3JlZXQgc2VydmljZSB0byBkZW1vbnN0cmF0ZSBESS4KICogICAgICRmaWx0ZXJQcm92aWRlci5yZWdpc3RlcignZ3JlZXQnLCBmdW5jdGlvbihncmVldCl7CiAqICAgICAgIC8vIHJldHVybiB0aGUgZmlsdGVyIGZ1bmN0aW9uIHdoaWNoIHVzZXMgdGhlIGdyZWV0IHNlcnZpY2UKICogICAgICAgLy8gdG8gZ2VuZXJhdGUgc2FsdXRhdGlvbgogKiAgICAgICByZXR1cm4gZnVuY3Rpb24odGV4dCkgewogKiAgICAgICAgIC8vIGZpbHRlcnMgbmVlZCB0byBiZSBmb3JnaXZpbmcgc28gY2hlY2sgaW5wdXQgdmFsaWRpdHkKICogICAgICAgICByZXR1cm4gdGV4dCAmJiBncmVldCh0ZXh0KSB8fCB0ZXh0OwogKiAgICAgICB9OwogKiAgICAgfSk7CiAqICAgfQogKiBgYGAKICoKICogVGhlIGZpbHRlciBmdW5jdGlvbiBpcyByZWdpc3RlcmVkIHdpdGggdGhlIGAkaW5qZWN0b3JgIHVuZGVyIHRoZSBmaWx0ZXIgbmFtZSBzdWZmaXggd2l0aAogKiBgRmlsdGVyYC4KICoKICogYGBganMKICogICBpdCgnc2hvdWxkIGJlIHRoZSBzYW1lIGluc3RhbmNlJywgaW5qZWN0KAogKiAgICAgZnVuY3Rpb24oJGZpbHRlclByb3ZpZGVyKSB7CiAqICAgICAgICRmaWx0ZXJQcm92aWRlci5yZWdpc3RlcigncmV2ZXJzZScsIGZ1bmN0aW9uKCl7CiAqICAgICAgICAgcmV0dXJuIC4uLjsKICogICAgICAgfSk7CiAqICAgICB9LAogKiAgICAgZnVuY3Rpb24oJGZpbHRlciwgcmV2ZXJzZUZpbHRlcikgewogKiAgICAgICBleHBlY3QoJGZpbHRlcigncmV2ZXJzZScpKS50b0JlKHJldmVyc2VGaWx0ZXIpOwogKiAgICAgfSk7CiAqIGBgYAogKgogKgogKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBob3cgYW5ndWxhciBmaWx0ZXJzIHdvcmssIGFuZCBob3cgdG8gY3JlYXRlIHlvdXIgb3duIGZpbHRlcnMsIHNlZQogKiB7QGxpbmsgZ3VpZGUvZmlsdGVyIEZpbHRlcnN9IGluIHRoZSBBbmd1bGFyIERldmVsb3BlciBHdWlkZS4KICovCgovKioKICogQG5nZG9jIHNlcnZpY2UKICogQG5hbWUgJGZpbHRlcgogKiBAa2luZCBmdW5jdGlvbgogKiBAZGVzY3JpcHRpb24KICogRmlsdGVycyBhcmUgdXNlZCBmb3IgZm9ybWF0dGluZyBkYXRhIGRpc3BsYXllZCB0byB0aGUgdXNlci4KICoKICogVGhlIGdlbmVyYWwgc3ludGF4IGluIHRlbXBsYXRlcyBpcyBhcyBmb2xsb3dzOgogKgogKiAgICAgICAgIHt7IGV4cHJlc3Npb24gW3wgZmlsdGVyX25hbWVbOnBhcmFtZXRlcl92YWx1ZV0gLi4uIF0gfX0KICoKICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgZmlsdGVyIGZ1bmN0aW9uIHRvIHJldHJpZXZlCiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgZmlsdGVyIGZ1bmN0aW9uCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG5hbWU9IiRmaWx0ZXIiIG1vZHVsZT0iZmlsdGVyRXhhbXBsZSI+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9Ik1haW5DdHJsIj4KICAgICAgICA8aDM+e3sgb3JpZ2luYWxUZXh0IH19PC9oMz4KICAgICAgICA8aDM+e3sgZmlsdGVyZWRUZXh0IH19PC9oMz4KICAgICAgIDwvZGl2PgogICAgIDwvZmlsZT4KCiAgICAgPGZpbGUgbmFtZT0ic2NyaXB0LmpzIj4KICAgICAgYW5ndWxhci5tb2R1bGUoJ2ZpbHRlckV4YW1wbGUnLCBbXSkKICAgICAgLmNvbnRyb2xsZXIoJ01haW5DdHJsJywgZnVuY3Rpb24oJHNjb3BlLCAkZmlsdGVyKSB7CiAgICAgICAgJHNjb3BlLm9yaWdpbmFsVGV4dCA9ICdoZWxsbyc7CiAgICAgICAgJHNjb3BlLmZpbHRlcmVkVGV4dCA9ICRmaWx0ZXIoJ3VwcGVyY2FzZScpKCRzY29wZS5vcmlnaW5hbFRleHQpOwogICAgICB9KTsKICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICAqLwokRmlsdGVyUHJvdmlkZXIuJGluamVjdCA9IFsnJHByb3ZpZGUnXTsKZnVuY3Rpb24gJEZpbHRlclByb3ZpZGVyKCRwcm92aWRlKSB7CiAgdmFyIHN1ZmZpeCA9ICdGaWx0ZXInOwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgJGZpbHRlclByb3ZpZGVyI3JlZ2lzdGVyCiAgICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBuYW1lIE5hbWUgb2YgdGhlIGZpbHRlciBmdW5jdGlvbiwgb3IgYW4gb2JqZWN0IG1hcCBvZiBmaWx0ZXJzIHdoZXJlCiAgICogICAgdGhlIGtleXMgYXJlIHRoZSBmaWx0ZXIgbmFtZXMgYW5kIHRoZSB2YWx1ZXMgYXJlIHRoZSBmaWx0ZXIgZmFjdG9yaWVzLgogICAqIEByZXR1cm5zIHtPYmplY3R9IFJlZ2lzdGVyZWQgZmlsdGVyIGluc3RhbmNlLCBvciBpZiBhIG1hcCBvZiBmaWx0ZXJzIHdhcyBwcm92aWRlZCB0aGVuIGEgbWFwCiAgICogICAgb2YgdGhlIHJlZ2lzdGVyZWQgZmlsdGVyIGluc3RhbmNlcy4KICAgKi8KICBmdW5jdGlvbiByZWdpc3RlcihuYW1lLCBmYWN0b3J5KSB7CiAgICBpZiAoaXNPYmplY3QobmFtZSkpIHsKICAgICAgdmFyIGZpbHRlcnMgPSB7fTsKICAgICAgZm9yRWFjaChuYW1lLCBmdW5jdGlvbihmaWx0ZXIsIGtleSkgewogICAgICAgIGZpbHRlcnNba2V5XSA9IHJlZ2lzdGVyKGtleSwgZmlsdGVyKTsKICAgICAgfSk7CiAgICAgIHJldHVybiBmaWx0ZXJzOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuICRwcm92aWRlLmZhY3RvcnkobmFtZSArIHN1ZmZpeCwgZmFjdG9yeSk7CiAgICB9CiAgfQogIHRoaXMucmVnaXN0ZXIgPSByZWdpc3RlcjsKCiAgdGhpcy4kZ2V0ID0gWyckaW5qZWN0b3InLCBmdW5jdGlvbigkaW5qZWN0b3IpIHsKICAgIHJldHVybiBmdW5jdGlvbihuYW1lKSB7CiAgICAgIHJldHVybiAkaW5qZWN0b3IuZ2V0KG5hbWUgKyBzdWZmaXgpOwogICAgfTsKICB9XTsKCiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKICAvKiBnbG9iYWwKICAgIGN1cnJlbmN5RmlsdGVyOiBmYWxzZSwKICAgIGRhdGVGaWx0ZXI6IGZhbHNlLAogICAgZmlsdGVyRmlsdGVyOiBmYWxzZSwKICAgIGpzb25GaWx0ZXI6IGZhbHNlLAogICAgbGltaXRUb0ZpbHRlcjogZmFsc2UsCiAgICBsb3dlcmNhc2VGaWx0ZXI6IGZhbHNlLAogICAgbnVtYmVyRmlsdGVyOiBmYWxzZSwKICAgIG9yZGVyQnlGaWx0ZXI6IGZhbHNlLAogICAgdXBwZXJjYXNlRmlsdGVyOiBmYWxzZSwKICAqLwoKICByZWdpc3RlcignY3VycmVuY3knLCBjdXJyZW5jeUZpbHRlcik7CiAgcmVnaXN0ZXIoJ2RhdGUnLCBkYXRlRmlsdGVyKTsKICByZWdpc3RlcignZmlsdGVyJywgZmlsdGVyRmlsdGVyKTsKICByZWdpc3RlcignanNvbicsIGpzb25GaWx0ZXIpOwogIHJlZ2lzdGVyKCdsaW1pdFRvJywgbGltaXRUb0ZpbHRlcik7CiAgcmVnaXN0ZXIoJ2xvd2VyY2FzZScsIGxvd2VyY2FzZUZpbHRlcik7CiAgcmVnaXN0ZXIoJ251bWJlcicsIG51bWJlckZpbHRlcik7CiAgcmVnaXN0ZXIoJ29yZGVyQnknLCBvcmRlckJ5RmlsdGVyKTsKICByZWdpc3RlcigndXBwZXJjYXNlJywgdXBwZXJjYXNlRmlsdGVyKTsKfQoKLyoqCiAqIEBuZ2RvYyBmaWx0ZXIKICogQG5hbWUgZmlsdGVyCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBTZWxlY3RzIGEgc3Vic2V0IG9mIGl0ZW1zIGZyb20gYGFycmF5YCBhbmQgcmV0dXJucyBpdCBhcyBhIG5ldyBhcnJheS4KICoKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvdXJjZSBhcnJheS4KICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fGZ1bmN0aW9uKCl9IGV4cHJlc3Npb24gVGhlIHByZWRpY2F0ZSB0byBiZSB1c2VkIGZvciBzZWxlY3RpbmcgaXRlbXMgZnJvbQogKiAgIGBhcnJheWAuCiAqCiAqICAgQ2FuIGJlIG9uZSBvZjoKICoKICogICAtIGBzdHJpbmdgOiBUaGUgc3RyaW5nIGlzIHVzZWQgZm9yIG1hdGNoaW5nIGFnYWluc3QgdGhlIGNvbnRlbnRzIG9mIHRoZSBgYXJyYXlgLiBBbGwgc3RyaW5ncyBvcgogKiAgICAgb2JqZWN0cyB3aXRoIHN0cmluZyBwcm9wZXJ0aWVzIGluIGBhcnJheWAgdGhhdCBtYXRjaCB0aGlzIHN0cmluZyB3aWxsIGJlIHJldHVybmVkLiBUaGlzIGFsc28KICogICAgIGFwcGxpZXMgdG8gbmVzdGVkIG9iamVjdCBwcm9wZXJ0aWVzLgogKiAgICAgVGhlIHByZWRpY2F0ZSBjYW4gYmUgbmVnYXRlZCBieSBwcmVmaXhpbmcgdGhlIHN0cmluZyB3aXRoIGAhYC4KICoKICogICAtIGBPYmplY3RgOiBBIHBhdHRlcm4gb2JqZWN0IGNhbiBiZSB1c2VkIHRvIGZpbHRlciBzcGVjaWZpYyBwcm9wZXJ0aWVzIG9uIG9iamVjdHMgY29udGFpbmVkCiAqICAgICBieSBgYXJyYXlgLiBGb3IgZXhhbXBsZSBge25hbWU6Ik0iLCBwaG9uZToiMSJ9YCBwcmVkaWNhdGUgd2lsbCByZXR1cm4gYW4gYXJyYXkgb2YgaXRlbXMKICogICAgIHdoaWNoIGhhdmUgcHJvcGVydHkgYG5hbWVgIGNvbnRhaW5pbmcgIk0iIGFuZCBwcm9wZXJ0eSBgcGhvbmVgIGNvbnRhaW5pbmcgIjEiLiBBIHNwZWNpYWwKICogICAgIHByb3BlcnR5IG5hbWUgYCRgIGNhbiBiZSB1c2VkIChhcyBpbiBgeyQ6InRleHQifWApIHRvIGFjY2VwdCBhIG1hdGNoIGFnYWluc3QgYW55CiAqICAgICBwcm9wZXJ0eSBvZiB0aGUgb2JqZWN0IG9yIGl0cyBuZXN0ZWQgb2JqZWN0IHByb3BlcnRpZXMuIFRoYXQncyBlcXVpdmFsZW50IHRvIHRoZSBzaW1wbGUKICogICAgIHN1YnN0cmluZyBtYXRjaCB3aXRoIGEgYHN0cmluZ2AgYXMgZGVzY3JpYmVkIGFib3ZlLiBUaGUgcHJlZGljYXRlIGNhbiBiZSBuZWdhdGVkIGJ5IHByZWZpeGluZwogKiAgICAgdGhlIHN0cmluZyB3aXRoIGAhYC4KICogICAgIEZvciBleGFtcGxlIGB7bmFtZTogIiFNIn1gIHByZWRpY2F0ZSB3aWxsIHJldHVybiBhbiBhcnJheSBvZiBpdGVtcyB3aGljaCBoYXZlIHByb3BlcnR5IGBuYW1lYAogKiAgICAgbm90IGNvbnRhaW5pbmcgIk0iLgogKgogKiAgICAgTm90ZSB0aGF0IGEgbmFtZWQgcHJvcGVydHkgd2lsbCBtYXRjaCBwcm9wZXJ0aWVzIG9uIHRoZSBzYW1lIGxldmVsIG9ubHksIHdoaWxlIHRoZSBzcGVjaWFsCiAqICAgICBgJGAgcHJvcGVydHkgd2lsbCBtYXRjaCBwcm9wZXJ0aWVzIG9uIHRoZSBzYW1lIGxldmVsIG9yIGRlZXBlci4gRS5nLiBhbiBhcnJheSBpdGVtIGxpa2UKICogICAgIGB7bmFtZToge2ZpcnN0OiAnSm9obicsIGxhc3Q6ICdEb2UnfX1gIHdpbGwgKipub3QqKiBiZSBtYXRjaGVkIGJ5IGB7bmFtZTogJ0pvaG4nfWAsIGJ1dAogKiAgICAgKip3aWxsKiogYmUgbWF0Y2hlZCBieSBgeyQ6ICdKb2huJ31gLgogKgogKiAgIC0gYGZ1bmN0aW9uKHZhbHVlLCBpbmRleClgOiBBIHByZWRpY2F0ZSBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byB3cml0ZSBhcmJpdHJhcnkgZmlsdGVycy4gVGhlCiAqICAgICBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIGVhY2ggZWxlbWVudCBvZiBgYXJyYXlgLiBUaGUgZmluYWwgcmVzdWx0IGlzIGFuIGFycmF5IG9mIHRob3NlCiAqICAgICBlbGVtZW50cyB0aGF0IHRoZSBwcmVkaWNhdGUgcmV0dXJuZWQgdHJ1ZSBmb3IuCiAqCiAqIEBwYXJhbSB7ZnVuY3Rpb24oYWN0dWFsLCBleHBlY3RlZCl8dHJ1ZXx1bmRlZmluZWR9IGNvbXBhcmF0b3IgQ29tcGFyYXRvciB3aGljaCBpcyB1c2VkIGluCiAqICAgICBkZXRlcm1pbmluZyBpZiB0aGUgZXhwZWN0ZWQgdmFsdWUgKGZyb20gdGhlIGZpbHRlciBleHByZXNzaW9uKSBhbmQgYWN0dWFsIHZhbHVlIChmcm9tCiAqICAgICB0aGUgb2JqZWN0IGluIHRoZSBhcnJheSkgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYSBtYXRjaC4KICoKICogICBDYW4gYmUgb25lIG9mOgogKgogKiAgIC0gYGZ1bmN0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpYDoKICogICAgIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGdpdmVuIHRoZSBvYmplY3QgdmFsdWUgYW5kIHRoZSBwcmVkaWNhdGUgdmFsdWUgdG8gY29tcGFyZSBhbmQKICogICAgIHNob3VsZCByZXR1cm4gdHJ1ZSBpZiBib3RoIHZhbHVlcyBzaG91bGQgYmUgY29uc2lkZXJlZCBlcXVhbC4KICoKICogICAtIGB0cnVlYDogQSBzaG9ydGhhbmQgZm9yIGBmdW5jdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7IHJldHVybiBhbmd1bGFyLmVxdWFscyhhY3R1YWwsIGV4cGVjdGVkKX1gLgogKiAgICAgVGhpcyBpcyBlc3NlbnRpYWxseSBzdHJpY3QgY29tcGFyaXNvbiBvZiBleHBlY3RlZCBhbmQgYWN0dWFsLgogKgogKiAgIC0gYGZhbHNlfHVuZGVmaW5lZGA6IEEgc2hvcnQgaGFuZCBmb3IgYSBmdW5jdGlvbiB3aGljaCB3aWxsIGxvb2sgZm9yIGEgc3Vic3RyaW5nIG1hdGNoIGluIGNhc2UKICogICAgIGluc2Vuc2l0aXZlIHdheS4KICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8ZGl2IG5nLWluaXQ9ImZyaWVuZHMgPSBbe25hbWU6J0pvaG4nLCBwaG9uZTonNTU1LTEyNzYnfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7bmFtZTonTWFyeScsIHBob25lOic4MDAtQklHLU1BUlknfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7bmFtZTonTWlrZScsIHBob25lOic1NTUtNDMyMSd9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtuYW1lOidBZGFtJywgcGhvbmU6JzU1NS01Njc4J30sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge25hbWU6J0p1bGllJywgcGhvbmU6JzU1NS04NzY1J30sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge25hbWU6J0p1bGlldHRlJywgcGhvbmU6JzU1NS01Njc4J31dIj48L2Rpdj4KCiAgICAgICBTZWFyY2g6IDxpbnB1dCBuZy1tb2RlbD0ic2VhcmNoVGV4dCI+CiAgICAgICA8dGFibGUgaWQ9InNlYXJjaFRleHRSZXN1bHRzIj4KICAgICAgICAgPHRyPjx0aD5OYW1lPC90aD48dGg+UGhvbmU8L3RoPjwvdHI+CiAgICAgICAgIDx0ciBuZy1yZXBlYXQ9ImZyaWVuZCBpbiBmcmllbmRzIHwgZmlsdGVyOnNlYXJjaFRleHQiPgogICAgICAgICAgIDx0ZD57e2ZyaWVuZC5uYW1lfX08L3RkPgogICAgICAgICAgIDx0ZD57e2ZyaWVuZC5waG9uZX19PC90ZD4KICAgICAgICAgPC90cj4KICAgICAgIDwvdGFibGU+CiAgICAgICA8aHI+CiAgICAgICBBbnk6IDxpbnB1dCBuZy1tb2RlbD0ic2VhcmNoLiQiPiA8YnI+CiAgICAgICBOYW1lIG9ubHkgPGlucHV0IG5nLW1vZGVsPSJzZWFyY2gubmFtZSI+PGJyPgogICAgICAgUGhvbmUgb25seSA8aW5wdXQgbmctbW9kZWw9InNlYXJjaC5waG9uZSI+PGJyPgogICAgICAgRXF1YWxpdHkgPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0ic3RyaWN0Ij48YnI+CiAgICAgICA8dGFibGUgaWQ9InNlYXJjaE9ialJlc3VsdHMiPgogICAgICAgICA8dHI+PHRoPk5hbWU8L3RoPjx0aD5QaG9uZTwvdGg+PC90cj4KICAgICAgICAgPHRyIG5nLXJlcGVhdD0iZnJpZW5kT2JqIGluIGZyaWVuZHMgfCBmaWx0ZXI6c2VhcmNoOnN0cmljdCI+CiAgICAgICAgICAgPHRkPnt7ZnJpZW5kT2JqLm5hbWV9fTwvdGQ+CiAgICAgICAgICAgPHRkPnt7ZnJpZW5kT2JqLnBob25lfX08L3RkPgogICAgICAgICA8L3RyPgogICAgICAgPC90YWJsZT4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICB2YXIgZXhwZWN0RnJpZW5kTmFtZXMgPSBmdW5jdGlvbihleHBlY3RlZE5hbWVzLCBrZXkpIHsKICAgICAgICAgZWxlbWVudC5hbGwoYnkucmVwZWF0ZXIoa2V5ICsgJyBpbiBmcmllbmRzJykuY29sdW1uKGtleSArICcubmFtZScpKS50aGVuKGZ1bmN0aW9uKGFycikgewogICAgICAgICAgIGFyci5mb3JFYWNoKGZ1bmN0aW9uKHdkLCBpKSB7CiAgICAgICAgICAgICBleHBlY3Qod2QuZ2V0VGV4dCgpKS50b01hdGNoKGV4cGVjdGVkTmFtZXNbaV0pOwogICAgICAgICAgIH0pOwogICAgICAgICB9KTsKICAgICAgIH07CgogICAgICAgaXQoJ3Nob3VsZCBzZWFyY2ggYWNyb3NzIGFsbCBmaWVsZHMgd2hlbiBmaWx0ZXJpbmcgd2l0aCBhIHN0cmluZycsIGZ1bmN0aW9uKCkgewogICAgICAgICB2YXIgc2VhcmNoVGV4dCA9IGVsZW1lbnQoYnkubW9kZWwoJ3NlYXJjaFRleHQnKSk7CiAgICAgICAgIHNlYXJjaFRleHQuY2xlYXIoKTsKICAgICAgICAgc2VhcmNoVGV4dC5zZW5kS2V5cygnbScpOwogICAgICAgICBleHBlY3RGcmllbmROYW1lcyhbJ01hcnknLCAnTWlrZScsICdBZGFtJ10sICdmcmllbmQnKTsKCiAgICAgICAgIHNlYXJjaFRleHQuY2xlYXIoKTsKICAgICAgICAgc2VhcmNoVGV4dC5zZW5kS2V5cygnNzYnKTsKICAgICAgICAgZXhwZWN0RnJpZW5kTmFtZXMoWydKb2huJywgJ0p1bGllJ10sICdmcmllbmQnKTsKICAgICAgIH0pOwoKICAgICAgIGl0KCdzaG91bGQgc2VhcmNoIGluIHNwZWNpZmljIGZpZWxkcyB3aGVuIGZpbHRlcmluZyB3aXRoIGEgcHJlZGljYXRlIG9iamVjdCcsIGZ1bmN0aW9uKCkgewogICAgICAgICB2YXIgc2VhcmNoQW55ID0gZWxlbWVudChieS5tb2RlbCgnc2VhcmNoLiQnKSk7CiAgICAgICAgIHNlYXJjaEFueS5jbGVhcigpOwogICAgICAgICBzZWFyY2hBbnkuc2VuZEtleXMoJ2knKTsKICAgICAgICAgZXhwZWN0RnJpZW5kTmFtZXMoWydNYXJ5JywgJ01pa2UnLCAnSnVsaWUnLCAnSnVsaWV0dGUnXSwgJ2ZyaWVuZE9iaicpOwogICAgICAgfSk7CiAgICAgICBpdCgnc2hvdWxkIHVzZSBhIGVxdWFsIGNvbXBhcmlzb24gd2hlbiBjb21wYXJhdG9yIGlzIHRydWUnLCBmdW5jdGlvbigpIHsKICAgICAgICAgdmFyIHNlYXJjaE5hbWUgPSBlbGVtZW50KGJ5Lm1vZGVsKCdzZWFyY2gubmFtZScpKTsKICAgICAgICAgdmFyIHN0cmljdCA9IGVsZW1lbnQoYnkubW9kZWwoJ3N0cmljdCcpKTsKICAgICAgICAgc2VhcmNoTmFtZS5jbGVhcigpOwogICAgICAgICBzZWFyY2hOYW1lLnNlbmRLZXlzKCdKdWxpZScpOwogICAgICAgICBzdHJpY3QuY2xpY2soKTsKICAgICAgICAgZXhwZWN0RnJpZW5kTmFtZXMoWydKdWxpZSddLCAnZnJpZW5kT2JqJyk7CiAgICAgICB9KTsKICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCmZ1bmN0aW9uIGZpbHRlckZpbHRlcigpIHsKICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIGV4cHJlc3Npb24sIGNvbXBhcmF0b3IpIHsKICAgIGlmICghaXNBcnJheShhcnJheSkpIHJldHVybiBhcnJheTsKCiAgICB2YXIgcHJlZGljYXRlRm47CiAgICB2YXIgbWF0Y2hBZ2FpbnN0QW55UHJvcDsKCiAgICBzd2l0Y2ggKHR5cGVvZiBleHByZXNzaW9uKSB7CiAgICAgIGNhc2UgJ2Z1bmN0aW9uJzoKICAgICAgICBwcmVkaWNhdGVGbiA9IGV4cHJlc3Npb247CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ2Jvb2xlYW4nOgogICAgICBjYXNlICdudW1iZXInOgogICAgICBjYXNlICdzdHJpbmcnOgogICAgICAgIG1hdGNoQWdhaW5zdEFueVByb3AgPSB0cnVlOwogICAgICAgIC8vanNoaW50IC1XMDg2CiAgICAgIGNhc2UgJ29iamVjdCc6CiAgICAgICAgLy9qc2hpbnQgK1cwODYKICAgICAgICBwcmVkaWNhdGVGbiA9IGNyZWF0ZVByZWRpY2F0ZUZuKGV4cHJlc3Npb24sIGNvbXBhcmF0b3IsIG1hdGNoQWdhaW5zdEFueVByb3ApOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBhcnJheTsKICAgIH0KCiAgICByZXR1cm4gYXJyYXkuZmlsdGVyKHByZWRpY2F0ZUZuKTsKICB9Owp9CgovLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBgZmlsdGVyRmlsdGVyYApmdW5jdGlvbiBjcmVhdGVQcmVkaWNhdGVGbihleHByZXNzaW9uLCBjb21wYXJhdG9yLCBtYXRjaEFnYWluc3RBbnlQcm9wKSB7CiAgdmFyIHNob3VsZE1hdGNoUHJpbWl0aXZlcyA9IGlzT2JqZWN0KGV4cHJlc3Npb24pICYmICgnJCcgaW4gZXhwcmVzc2lvbik7CiAgdmFyIHByZWRpY2F0ZUZuOwoKICBpZiAoY29tcGFyYXRvciA9PT0gdHJ1ZSkgewogICAgY29tcGFyYXRvciA9IGVxdWFsczsKICB9IGVsc2UgaWYgKCFpc0Z1bmN0aW9uKGNvbXBhcmF0b3IpKSB7CiAgICBjb21wYXJhdG9yID0gZnVuY3Rpb24oYWN0dWFsLCBleHBlY3RlZCkgewogICAgICBpZiAoaXNPYmplY3QoYWN0dWFsKSB8fCBpc09iamVjdChleHBlY3RlZCkpIHsKICAgICAgICAvLyBQcmV2ZW50IGFuIG9iamVjdCB0byBiZSBjb25zaWRlcmVkIGVxdWFsIHRvIGEgc3RyaW5nIGxpa2UgYCdbb2JqZWN0J2AKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIGFjdHVhbCA9IGxvd2VyY2FzZSgnJyArIGFjdHVhbCk7CiAgICAgIGV4cGVjdGVkID0gbG93ZXJjYXNlKCcnICsgZXhwZWN0ZWQpOwogICAgICByZXR1cm4gYWN0dWFsLmluZGV4T2YoZXhwZWN0ZWQpICE9PSAtMTsKICAgIH07CiAgfQoKICBwcmVkaWNhdGVGbiA9IGZ1bmN0aW9uKGl0ZW0pIHsKICAgIGlmIChzaG91bGRNYXRjaFByaW1pdGl2ZXMgJiYgIWlzT2JqZWN0KGl0ZW0pKSB7CiAgICAgIHJldHVybiBkZWVwQ29tcGFyZShpdGVtLCBleHByZXNzaW9uLiQsIGNvbXBhcmF0b3IsIGZhbHNlKTsKICAgIH0KICAgIHJldHVybiBkZWVwQ29tcGFyZShpdGVtLCBleHByZXNzaW9uLCBjb21wYXJhdG9yLCBtYXRjaEFnYWluc3RBbnlQcm9wKTsKICB9OwoKICByZXR1cm4gcHJlZGljYXRlRm47Cn0KCmZ1bmN0aW9uIGRlZXBDb21wYXJlKGFjdHVhbCwgZXhwZWN0ZWQsIGNvbXBhcmF0b3IsIG1hdGNoQWdhaW5zdEFueVByb3AsIGRvbnRNYXRjaFdob2xlT2JqZWN0KSB7CiAgdmFyIGFjdHVhbFR5cGUgPSB0eXBlb2YgYWN0dWFsOwogIHZhciBleHBlY3RlZFR5cGUgPSB0eXBlb2YgZXhwZWN0ZWQ7CgogIGlmICgoZXhwZWN0ZWRUeXBlID09PSAnc3RyaW5nJykgJiYgKGV4cGVjdGVkLmNoYXJBdCgwKSA9PT0gJyEnKSkgewogICAgcmV0dXJuICFkZWVwQ29tcGFyZShhY3R1YWwsIGV4cGVjdGVkLnN1YnN0cmluZygxKSwgY29tcGFyYXRvciwgbWF0Y2hBZ2FpbnN0QW55UHJvcCk7CiAgfSBlbHNlIGlmIChhY3R1YWxUeXBlID09PSAnYXJyYXknKSB7CiAgICAvLyBJbiBjYXNlIGBhY3R1YWxgIGlzIGFuIGFycmF5LCBjb25zaWRlciBpdCBhIG1hdGNoCiAgICAvLyBpZiBBTlkgb2YgaXQncyBpdGVtcyBtYXRjaGVzIGBleHBlY3RlZGAKICAgIHJldHVybiBhY3R1YWwuc29tZShmdW5jdGlvbihpdGVtKSB7CiAgICAgIHJldHVybiBkZWVwQ29tcGFyZShpdGVtLCBleHBlY3RlZCwgY29tcGFyYXRvciwgbWF0Y2hBZ2FpbnN0QW55UHJvcCk7CiAgICB9KTsKICB9CgogIHN3aXRjaCAoYWN0dWFsVHlwZSkgewogICAgY2FzZSAnb2JqZWN0JzoKICAgICAgdmFyIGtleTsKICAgICAgaWYgKG1hdGNoQWdhaW5zdEFueVByb3ApIHsKICAgICAgICBmb3IgKGtleSBpbiBhY3R1YWwpIHsKICAgICAgICAgIGlmICgoa2V5LmNoYXJBdCgwKSAhPT0gJyQnKSAmJiBkZWVwQ29tcGFyZShhY3R1YWxba2V5XSwgZXhwZWN0ZWQsIGNvbXBhcmF0b3IsIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZG9udE1hdGNoV2hvbGVPYmplY3QgPyBmYWxzZSA6IGRlZXBDb21wYXJlKGFjdHVhbCwgZXhwZWN0ZWQsIGNvbXBhcmF0b3IsIGZhbHNlKTsKICAgICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdvYmplY3QnKSB7CiAgICAgICAgZm9yIChrZXkgaW4gZXhwZWN0ZWQpIHsKICAgICAgICAgIHZhciBleHBlY3RlZFZhbCA9IGV4cGVjdGVkW2tleV07CiAgICAgICAgICBpZiAoaXNGdW5jdGlvbihleHBlY3RlZFZhbCkpIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CgogICAgICAgICAgdmFyIG1hdGNoQW55UHJvcGVydHkgPSBrZXkgPT09ICckJzsKICAgICAgICAgIHZhciBhY3R1YWxWYWwgPSBtYXRjaEFueVByb3BlcnR5ID8gYWN0dWFsIDogYWN0dWFsW2tleV07CiAgICAgICAgICBpZiAoIWRlZXBDb21wYXJlKGFjdHVhbFZhbCwgZXhwZWN0ZWRWYWwsIGNvbXBhcmF0b3IsIG1hdGNoQW55UHJvcGVydHksIG1hdGNoQW55UHJvcGVydHkpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmF0b3IoYWN0dWFsLCBleHBlY3RlZCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlICdmdW5jdGlvbic6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBjb21wYXJhdG9yKGFjdHVhbCwgZXhwZWN0ZWQpOwogIH0KfQoKLyoqCiAqIEBuZ2RvYyBmaWx0ZXIKICogQG5hbWUgY3VycmVuY3kKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIEZvcm1hdHMgYSBudW1iZXIgYXMgYSBjdXJyZW5jeSAoaWUgJDEsMjM0LjU2KS4gV2hlbiBubyBjdXJyZW5jeSBzeW1ib2wgaXMgcHJvdmlkZWQsIGRlZmF1bHQKICogc3ltYm9sIGZvciBjdXJyZW50IGxvY2FsZSBpcyB1c2VkLgogKgogKiBAcGFyYW0ge251bWJlcn0gYW1vdW50IElucHV0IHRvIGZpbHRlci4KICogQHBhcmFtIHtzdHJpbmc9fSBzeW1ib2wgQ3VycmVuY3kgc3ltYm9sIG9yIGlkZW50aWZpZXIgdG8gYmUgZGlzcGxheWVkLgogKiBAcGFyYW0ge251bWJlcj19IGZyYWN0aW9uU2l6ZSBOdW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdGhlIGFtb3VudCB0bywgZGVmYXVsdHMgdG8gZGVmYXVsdCBtYXggZnJhY3Rpb24gc2l6ZSBmb3IgY3VycmVudCBsb2NhbGUKICogQHJldHVybnMge3N0cmluZ30gRm9ybWF0dGVkIG51bWJlci4KICoKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGUgbW9kdWxlPSJjdXJyZW5jeUV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNjcmlwdD4KICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ2N1cnJlbmN5RXhhbXBsZScsIFtdKQogICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAkc2NvcGUuYW1vdW50ID0gMTIzNC41NjsKICAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICA8aW5wdXQgdHlwZT0ibnVtYmVyIiBuZy1tb2RlbD0iYW1vdW50Ij4gPGJyPgogICAgICAgICBkZWZhdWx0IGN1cnJlbmN5IHN5bWJvbCAoJCk6IDxzcGFuIGlkPSJjdXJyZW5jeS1kZWZhdWx0Ij57e2Ftb3VudCB8IGN1cnJlbmN5fX08L3NwYW4+PGJyPgogICAgICAgICBjdXN0b20gY3VycmVuY3kgaWRlbnRpZmllciAoVVNEJCk6IDxzcGFuIGlkPSJjdXJyZW5jeS1jdXN0b20iPnt7YW1vdW50IHwgY3VycmVuY3k6IlVTRCQifX08L3NwYW4+CiAgICAgICAgIG5vIGZyYWN0aW9ucyAoMCk6IDxzcGFuIGlkPSJjdXJyZW5jeS1uby1mcmFjdGlvbnMiPnt7YW1vdW50IHwgY3VycmVuY3k6IlVTRCQiOjB9fTwvc3Bhbj4KICAgICAgIDwvZGl2PgogICAgIDwvZmlsZT4KICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgIGl0KCdzaG91bGQgaW5pdCB3aXRoIDEyMzQuNTYnLCBmdW5jdGlvbigpIHsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2N1cnJlbmN5LWRlZmF1bHQnKSkuZ2V0VGV4dCgpKS50b0JlKCckMSwyMzQuNTYnKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2N1cnJlbmN5LWN1c3RvbScpKS5nZXRUZXh0KCkpLnRvQmUoJ1VTRCQxLDIzNC41NicpOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnY3VycmVuY3ktbm8tZnJhY3Rpb25zJykpLmdldFRleHQoKSkudG9CZSgnVVNEJDEsMjM1Jyk7CiAgICAgICB9KTsKICAgICAgIGl0KCdzaG91bGQgdXBkYXRlJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIGlmIChicm93c2VyLnBhcmFtcy5icm93c2VyID09ICdzYWZhcmknKSB7CiAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IHVuZGVyc3RhbmQgdGhlIG1pbnVzIGtleS4gU2VlCiAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvcHJvdHJhY3Rvci9pc3N1ZXMvNDgxCiAgICAgICAgICAgcmV0dXJuOwogICAgICAgICB9CiAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ2Ftb3VudCcpKS5jbGVhcigpOwogICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdhbW91bnQnKSkuc2VuZEtleXMoJy0xMjM0Jyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmlkKCdjdXJyZW5jeS1kZWZhdWx0JykpLmdldFRleHQoKSkudG9CZSgnKCQxLDIzNC4wMCknKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2N1cnJlbmN5LWN1c3RvbScpKS5nZXRUZXh0KCkpLnRvQmUoJyhVU0QkMSwyMzQuMDApJyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmlkKCdjdXJyZW5jeS1uby1mcmFjdGlvbnMnKSkuZ2V0VGV4dCgpKS50b0JlKCcoVVNEJDEsMjM0KScpOwogICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwpjdXJyZW5jeUZpbHRlci4kaW5qZWN0ID0gWyckbG9jYWxlJ107CmZ1bmN0aW9uIGN1cnJlbmN5RmlsdGVyKCRsb2NhbGUpIHsKICB2YXIgZm9ybWF0cyA9ICRsb2NhbGUuTlVNQkVSX0ZPUk1BVFM7CiAgcmV0dXJuIGZ1bmN0aW9uKGFtb3VudCwgY3VycmVuY3lTeW1ib2wsIGZyYWN0aW9uU2l6ZSkgewogICAgaWYgKGlzVW5kZWZpbmVkKGN1cnJlbmN5U3ltYm9sKSkgewogICAgICBjdXJyZW5jeVN5bWJvbCA9IGZvcm1hdHMuQ1VSUkVOQ1lfU1lNOwogICAgfQoKICAgIGlmIChpc1VuZGVmaW5lZChmcmFjdGlvblNpemUpKSB7CiAgICAgIGZyYWN0aW9uU2l6ZSA9IGZvcm1hdHMuUEFUVEVSTlNbMV0ubWF4RnJhYzsKICAgIH0KCiAgICAvLyBpZiBudWxsIG9yIHVuZGVmaW5lZCBwYXNzIGl0IHRocm91Z2gKICAgIHJldHVybiAoYW1vdW50ID09IG51bGwpCiAgICAgICAgPyBhbW91bnQKICAgICAgICA6IGZvcm1hdE51bWJlcihhbW91bnQsIGZvcm1hdHMuUEFUVEVSTlNbMV0sIGZvcm1hdHMuR1JPVVBfU0VQLCBmb3JtYXRzLkRFQ0lNQUxfU0VQLCBmcmFjdGlvblNpemUpLgogICAgICAgICAgICByZXBsYWNlKC9cdTAwQTQvZywgY3VycmVuY3lTeW1ib2wpOwogIH07Cn0KCi8qKgogKiBAbmdkb2MgZmlsdGVyCiAqIEBuYW1lIG51bWJlcgogKiBAa2luZCBmdW5jdGlvbgogKgogKiBAZGVzY3JpcHRpb24KICogRm9ybWF0cyBhIG51bWJlciBhcyB0ZXh0LgogKgogKiBJZiB0aGUgaW5wdXQgaXMgbm90IGEgbnVtYmVyIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KICoKICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfSBudW1iZXIgTnVtYmVyIHRvIGZvcm1hdC4KICogQHBhcmFtIHsobnVtYmVyfHN0cmluZyk9fSBmcmFjdGlvblNpemUgTnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHJvdW5kIHRoZSBudW1iZXIgdG8uCiAqIElmIHRoaXMgaXMgbm90IHByb3ZpZGVkIHRoZW4gdGhlIGZyYWN0aW9uIHNpemUgaXMgY29tcHV0ZWQgZnJvbSB0aGUgY3VycmVudCBsb2NhbGUncyBudW1iZXIKICogZm9ybWF0dGluZyBwYXR0ZXJuLiBJbiB0aGUgY2FzZSBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIGl0IHdpbGwgYmUgMy4KICogQHJldHVybnMge3N0cmluZ30gTnVtYmVyIHJvdW5kZWQgdG8gZGVjaW1hbFBsYWNlcyBhbmQgcGxhY2VzIGEg4oA/LOKAPyBhZnRlciBlYWNoIHRoaXJkIGRpZ2l0LgogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZSBtb2R1bGU9Im51bWJlckZpbHRlckV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNjcmlwdD4KICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ251bWJlckZpbHRlckV4YW1wbGUnLCBbXSkKICAgICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICAgJHNjb3BlLnZhbCA9IDEyMzQuNTY3ODk7CiAgICAgICAgICAgfV0pOwogICAgICAgPC9zY3JpcHQ+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICAgRW50ZXIgbnVtYmVyOiA8aW5wdXQgbmctbW9kZWw9J3ZhbCc+PGJyPgogICAgICAgICBEZWZhdWx0IGZvcm1hdHRpbmc6IDxzcGFuIGlkPSdudW1iZXItZGVmYXVsdCc+e3t2YWwgfCBudW1iZXJ9fTwvc3Bhbj48YnI+CiAgICAgICAgIE5vIGZyYWN0aW9uczogPHNwYW4+e3t2YWwgfCBudW1iZXI6MH19PC9zcGFuPjxicj4KICAgICAgICAgTmVnYXRpdmUgbnVtYmVyOiA8c3Bhbj57ey12YWwgfCBudW1iZXI6NH19PC9zcGFuPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgaXQoJ3Nob3VsZCBmb3JtYXQgbnVtYmVycycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnbnVtYmVyLWRlZmF1bHQnKSkuZ2V0VGV4dCgpKS50b0JlKCcxLDIzNC41NjgnKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygndmFsIHwgbnVtYmVyOjAnKSkuZ2V0VGV4dCgpKS50b0JlKCcxLDIzNScpOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCctdmFsIHwgbnVtYmVyOjQnKSkuZ2V0VGV4dCgpKS50b0JlKCctMSwyMzQuNTY3OScpOwogICAgICAgfSk7CgogICAgICAgaXQoJ3Nob3VsZCB1cGRhdGUnLCBmdW5jdGlvbigpIHsKICAgICAgICAgZWxlbWVudChieS5tb2RlbCgndmFsJykpLmNsZWFyKCk7CiAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3ZhbCcpKS5zZW5kS2V5cygnMzM3NC4zMzMnKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ251bWJlci1kZWZhdWx0JykpLmdldFRleHQoKSkudG9CZSgnMywzNzQuMzMzJyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ3ZhbCB8IG51bWJlcjowJykpLmdldFRleHQoKSkudG9CZSgnMywzNzQnKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygnLXZhbCB8IG51bWJlcjo0JykpLmdldFRleHQoKSkudG9CZSgnLTMsMzc0LjMzMzAnKTsKICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKCm51bWJlckZpbHRlci4kaW5qZWN0ID0gWyckbG9jYWxlJ107CmZ1bmN0aW9uIG51bWJlckZpbHRlcigkbG9jYWxlKSB7CiAgdmFyIGZvcm1hdHMgPSAkbG9jYWxlLk5VTUJFUl9GT1JNQVRTOwogIHJldHVybiBmdW5jdGlvbihudW1iZXIsIGZyYWN0aW9uU2l6ZSkgewoKICAgIC8vIGlmIG51bGwgb3IgdW5kZWZpbmVkIHBhc3MgaXQgdGhyb3VnaAogICAgcmV0dXJuIChudW1iZXIgPT0gbnVsbCkKICAgICAgICA/IG51bWJlcgogICAgICAgIDogZm9ybWF0TnVtYmVyKG51bWJlciwgZm9ybWF0cy5QQVRURVJOU1swXSwgZm9ybWF0cy5HUk9VUF9TRVAsIGZvcm1hdHMuREVDSU1BTF9TRVAsCiAgICAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb25TaXplKTsKICB9Owp9Cgp2YXIgREVDSU1BTF9TRVAgPSAnLic7CmZ1bmN0aW9uIGZvcm1hdE51bWJlcihudW1iZXIsIHBhdHRlcm4sIGdyb3VwU2VwLCBkZWNpbWFsU2VwLCBmcmFjdGlvblNpemUpIHsKICBpZiAoIWlzRmluaXRlKG51bWJlcikgfHwgaXNPYmplY3QobnVtYmVyKSkgcmV0dXJuICcnOwoKICB2YXIgaXNOZWdhdGl2ZSA9IG51bWJlciA8IDA7CiAgbnVtYmVyID0gTWF0aC5hYnMobnVtYmVyKTsKICB2YXIgbnVtU3RyID0gbnVtYmVyICsgJycsCiAgICAgIGZvcm1hdGVkVGV4dCA9ICcnLAogICAgICBwYXJ0cyA9IFtdOwoKICB2YXIgaGFzRXhwb25lbnQgPSBmYWxzZTsKICBpZiAobnVtU3RyLmluZGV4T2YoJ2UnKSAhPT0gLTEpIHsKICAgIHZhciBtYXRjaCA9IG51bVN0ci5tYXRjaCgvKFtcZFwuXSspZSgtPykoXGQrKS8pOwogICAgaWYgKG1hdGNoICYmIG1hdGNoWzJdID09ICctJyAmJiBtYXRjaFszXSA+IGZyYWN0aW9uU2l6ZSArIDEpIHsKICAgICAgbnVtYmVyID0gMDsKICAgIH0gZWxzZSB7CiAgICAgIGZvcm1hdGVkVGV4dCA9IG51bVN0cjsKICAgICAgaGFzRXhwb25lbnQgPSB0cnVlOwogICAgfQogIH0KCiAgaWYgKCFoYXNFeHBvbmVudCkgewogICAgdmFyIGZyYWN0aW9uTGVuID0gKG51bVN0ci5zcGxpdChERUNJTUFMX1NFUClbMV0gfHwgJycpLmxlbmd0aDsKCiAgICAvLyBkZXRlcm1pbmUgZnJhY3Rpb25TaXplIGlmIGl0IGlzIG5vdCBzcGVjaWZpZWQKICAgIGlmIChpc1VuZGVmaW5lZChmcmFjdGlvblNpemUpKSB7CiAgICAgIGZyYWN0aW9uU2l6ZSA9IE1hdGgubWluKE1hdGgubWF4KHBhdHRlcm4ubWluRnJhYywgZnJhY3Rpb25MZW4pLCBwYXR0ZXJuLm1heEZyYWMpOwogICAgfQoKICAgIC8vIHNhZmVseSByb3VuZCBudW1iZXJzIGluIEpTIHdpdGhvdXQgaGl0dGluZyBpbXByZWNpc2lvbnMgb2YgZmxvYXRpbmctcG9pbnQgYXJpdGhtZXRpY3MKICAgIC8vIGluc3BpcmVkIGJ5OgogICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWF0aC9yb3VuZAogICAgbnVtYmVyID0gKyhNYXRoLnJvdW5kKCsobnVtYmVyLnRvU3RyaW5nKCkgKyAnZScgKyBmcmFjdGlvblNpemUpKS50b1N0cmluZygpICsgJ2UnICsgLWZyYWN0aW9uU2l6ZSk7CgogICAgdmFyIGZyYWN0aW9uID0gKCcnICsgbnVtYmVyKS5zcGxpdChERUNJTUFMX1NFUCk7CiAgICB2YXIgd2hvbGUgPSBmcmFjdGlvblswXTsKICAgIGZyYWN0aW9uID0gZnJhY3Rpb25bMV0gfHwgJyc7CgogICAgdmFyIGksIHBvcyA9IDAsCiAgICAgICAgbGdyb3VwID0gcGF0dGVybi5sZ1NpemUsCiAgICAgICAgZ3JvdXAgPSBwYXR0ZXJuLmdTaXplOwoKICAgIGlmICh3aG9sZS5sZW5ndGggPj0gKGxncm91cCArIGdyb3VwKSkgewogICAgICBwb3MgPSB3aG9sZS5sZW5ndGggLSBsZ3JvdXA7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBwb3M7IGkrKykgewogICAgICAgIGlmICgocG9zIC0gaSkgJSBncm91cCA9PT0gMCAmJiBpICE9PSAwKSB7CiAgICAgICAgICBmb3JtYXRlZFRleHQgKz0gZ3JvdXBTZXA7CiAgICAgICAgfQogICAgICAgIGZvcm1hdGVkVGV4dCArPSB3aG9sZS5jaGFyQXQoaSk7CiAgICAgIH0KICAgIH0KCiAgICBmb3IgKGkgPSBwb3M7IGkgPCB3aG9sZS5sZW5ndGg7IGkrKykgewogICAgICBpZiAoKHdob2xlLmxlbmd0aCAtIGkpICUgbGdyb3VwID09PSAwICYmIGkgIT09IDApIHsKICAgICAgICBmb3JtYXRlZFRleHQgKz0gZ3JvdXBTZXA7CiAgICAgIH0KICAgICAgZm9ybWF0ZWRUZXh0ICs9IHdob2xlLmNoYXJBdChpKTsKICAgIH0KCiAgICAvLyBmb3JtYXQgZnJhY3Rpb24gcGFydC4KICAgIHdoaWxlIChmcmFjdGlvbi5sZW5ndGggPCBmcmFjdGlvblNpemUpIHsKICAgICAgZnJhY3Rpb24gKz0gJzAnOwogICAgfQoKICAgIGlmIChmcmFjdGlvblNpemUgJiYgZnJhY3Rpb25TaXplICE9PSAiMCIpIGZvcm1hdGVkVGV4dCArPSBkZWNpbWFsU2VwICsgZnJhY3Rpb24uc3Vic3RyKDAsIGZyYWN0aW9uU2l6ZSk7CiAgfSBlbHNlIHsKICAgIGlmIChmcmFjdGlvblNpemUgPiAwICYmIG51bWJlciA8IDEpIHsKICAgICAgZm9ybWF0ZWRUZXh0ID0gbnVtYmVyLnRvRml4ZWQoZnJhY3Rpb25TaXplKTsKICAgICAgbnVtYmVyID0gcGFyc2VGbG9hdChmb3JtYXRlZFRleHQpOwogICAgfQogIH0KCiAgaWYgKG51bWJlciA9PT0gMCkgewogICAgaXNOZWdhdGl2ZSA9IGZhbHNlOwogIH0KCiAgcGFydHMucHVzaChpc05lZ2F0aXZlID8gcGF0dGVybi5uZWdQcmUgOiBwYXR0ZXJuLnBvc1ByZSwKICAgICAgICAgICAgIGZvcm1hdGVkVGV4dCwKICAgICAgICAgICAgIGlzTmVnYXRpdmUgPyBwYXR0ZXJuLm5lZ1N1ZiA6IHBhdHRlcm4ucG9zU3VmKTsKICByZXR1cm4gcGFydHMuam9pbignJyk7Cn0KCmZ1bmN0aW9uIHBhZE51bWJlcihudW0sIGRpZ2l0cywgdHJpbSkgewogIHZhciBuZWcgPSAnJzsKICBpZiAobnVtIDwgMCkgewogICAgbmVnID0gICctJzsKICAgIG51bSA9IC1udW07CiAgfQogIG51bSA9ICcnICsgbnVtOwogIHdoaWxlIChudW0ubGVuZ3RoIDwgZGlnaXRzKSBudW0gPSAnMCcgKyBudW07CiAgaWYgKHRyaW0pCiAgICBudW0gPSBudW0uc3Vic3RyKG51bS5sZW5ndGggLSBkaWdpdHMpOwogIHJldHVybiBuZWcgKyBudW07Cn0KCgpmdW5jdGlvbiBkYXRlR2V0dGVyKG5hbWUsIHNpemUsIG9mZnNldCwgdHJpbSkgewogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHJldHVybiBmdW5jdGlvbihkYXRlKSB7CiAgICB2YXIgdmFsdWUgPSBkYXRlWydnZXQnICsgbmFtZV0oKTsKICAgIGlmIChvZmZzZXQgPiAwIHx8IHZhbHVlID4gLW9mZnNldCkKICAgICAgdmFsdWUgKz0gb2Zmc2V0OwogICAgaWYgKHZhbHVlID09PSAwICYmIG9mZnNldCA9PSAtMTIpIHZhbHVlID0gMTI7CiAgICByZXR1cm4gcGFkTnVtYmVyKHZhbHVlLCBzaXplLCB0cmltKTsKICB9Owp9CgpmdW5jdGlvbiBkYXRlU3RyR2V0dGVyKG5hbWUsIHNob3J0Rm9ybSkgewogIHJldHVybiBmdW5jdGlvbihkYXRlLCBmb3JtYXRzKSB7CiAgICB2YXIgdmFsdWUgPSBkYXRlWydnZXQnICsgbmFtZV0oKTsKICAgIHZhciBnZXQgPSB1cHBlcmNhc2Uoc2hvcnRGb3JtID8gKCdTSE9SVCcgKyBuYW1lKSA6IG5hbWUpOwoKICAgIHJldHVybiBmb3JtYXRzW2dldF1bdmFsdWVdOwogIH07Cn0KCmZ1bmN0aW9uIHRpbWVab25lR2V0dGVyKGRhdGUpIHsKICB2YXIgem9uZSA9IC0xICogZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpOwogIHZhciBwYWRkZWRab25lID0gKHpvbmUgPj0gMCkgPyAiKyIgOiAiIjsKCiAgcGFkZGVkWm9uZSArPSBwYWROdW1iZXIoTWF0aFt6b25lID4gMCA/ICdmbG9vcicgOiAnY2VpbCddKHpvbmUgLyA2MCksIDIpICsKICAgICAgICAgICAgICAgIHBhZE51bWJlcihNYXRoLmFicyh6b25lICUgNjApLCAyKTsKCiAgcmV0dXJuIHBhZGRlZFpvbmU7Cn0KCmZ1bmN0aW9uIGdldEZpcnN0VGh1cnNkYXlPZlllYXIoeWVhcikgewogICAgLy8gMCA9IGluZGV4IG9mIEphbnVhcnkKICAgIHZhciBkYXlPZldlZWtPbkZpcnN0ID0gKG5ldyBEYXRlKHllYXIsIDAsIDEpKS5nZXREYXkoKTsKICAgIC8vIDQgPSBpbmRleCBvZiBUaHVyc2RheSAoKzEgdG8gYWNjb3VudCBmb3IgMXN0ID0gNSkKICAgIC8vIDExID0gaW5kZXggb2YgKm5leHQqIFRodXJzZGF5ICgrMSBhY2NvdW50IGZvciAxc3QgPSAxMikKICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCAwLCAoKGRheU9mV2Vla09uRmlyc3QgPD0gNCkgPyA1IDogMTIpIC0gZGF5T2ZXZWVrT25GaXJzdCk7Cn0KCmZ1bmN0aW9uIGdldFRodXJzZGF5VGhpc1dlZWsoZGF0ZXRpbWUpIHsKICAgIHJldHVybiBuZXcgRGF0ZShkYXRldGltZS5nZXRGdWxsWWVhcigpLCBkYXRldGltZS5nZXRNb250aCgpLAogICAgICAvLyA0ID0gaW5kZXggb2YgVGh1cnNkYXkKICAgICAgZGF0ZXRpbWUuZ2V0RGF0ZSgpICsgKDQgLSBkYXRldGltZS5nZXREYXkoKSkpOwp9CgpmdW5jdGlvbiB3ZWVrR2V0dGVyKHNpemUpIHsKICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHsKICAgICAgdmFyIGZpcnN0VGh1cnMgPSBnZXRGaXJzdFRodXJzZGF5T2ZZZWFyKGRhdGUuZ2V0RnVsbFllYXIoKSksCiAgICAgICAgIHRoaXNUaHVycyA9IGdldFRodXJzZGF5VGhpc1dlZWsoZGF0ZSk7CgogICAgICB2YXIgZGlmZiA9ICt0aGlzVGh1cnMgLSArZmlyc3RUaHVycywKICAgICAgICAgcmVzdWx0ID0gMSArIE1hdGgucm91bmQoZGlmZiAvIDYuMDQ4ZTgpOyAvLyA2LjA0OGU4IG1zIHBlciB3ZWVrCgogICAgICByZXR1cm4gcGFkTnVtYmVyKHJlc3VsdCwgc2l6ZSk7CiAgIH07Cn0KCmZ1bmN0aW9uIGFtcG1HZXR0ZXIoZGF0ZSwgZm9ybWF0cykgewogIHJldHVybiBkYXRlLmdldEhvdXJzKCkgPCAxMiA/IGZvcm1hdHMuQU1QTVNbMF0gOiBmb3JtYXRzLkFNUE1TWzFdOwp9Cgp2YXIgREFURV9GT1JNQVRTID0gewogIHl5eXk6IGRhdGVHZXR0ZXIoJ0Z1bGxZZWFyJywgNCksCiAgICB5eTogZGF0ZUdldHRlcignRnVsbFllYXInLCAyLCAwLCB0cnVlKSwKICAgICB5OiBkYXRlR2V0dGVyKCdGdWxsWWVhcicsIDEpLAogIE1NTU06IGRhdGVTdHJHZXR0ZXIoJ01vbnRoJyksCiAgIE1NTTogZGF0ZVN0ckdldHRlcignTW9udGgnLCB0cnVlKSwKICAgIE1NOiBkYXRlR2V0dGVyKCdNb250aCcsIDIsIDEpLAogICAgIE06IGRhdGVHZXR0ZXIoJ01vbnRoJywgMSwgMSksCiAgICBkZDogZGF0ZUdldHRlcignRGF0ZScsIDIpLAogICAgIGQ6IGRhdGVHZXR0ZXIoJ0RhdGUnLCAxKSwKICAgIEhIOiBkYXRlR2V0dGVyKCdIb3VycycsIDIpLAogICAgIEg6IGRhdGVHZXR0ZXIoJ0hvdXJzJywgMSksCiAgICBoaDogZGF0ZUdldHRlcignSG91cnMnLCAyLCAtMTIpLAogICAgIGg6IGRhdGVHZXR0ZXIoJ0hvdXJzJywgMSwgLTEyKSwKICAgIG1tOiBkYXRlR2V0dGVyKCdNaW51dGVzJywgMiksCiAgICAgbTogZGF0ZUdldHRlcignTWludXRlcycsIDEpLAogICAgc3M6IGRhdGVHZXR0ZXIoJ1NlY29uZHMnLCAyKSwKICAgICBzOiBkYXRlR2V0dGVyKCdTZWNvbmRzJywgMSksCiAgICAgLy8gd2hpbGUgSVNPIDg2MDEgcmVxdWlyZXMgZnJhY3Rpb25zIHRvIGJlIHByZWZpeGVkIHdpdGggYC5gIG9yIGAsYAogICAgIC8vIHdlIGNhbiBiZSBqdXN0IHNhZmVseSByZWx5IG9uIHVzaW5nIGBzc3NgIHNpbmNlIHdlIGN1cnJlbnRseSBkb24ndCBzdXBwb3J0IHNpbmdsZSBvciB0d28gZGlnaXQgZnJhY3Rpb25zCiAgIHNzczogZGF0ZUdldHRlcignTWlsbGlzZWNvbmRzJywgMyksCiAgRUVFRTogZGF0ZVN0ckdldHRlcignRGF5JyksCiAgIEVFRTogZGF0ZVN0ckdldHRlcignRGF5JywgdHJ1ZSksCiAgICAgYTogYW1wbUdldHRlciwKICAgICBaOiB0aW1lWm9uZUdldHRlciwKICAgIHd3OiB3ZWVrR2V0dGVyKDIpLAogICAgIHc6IHdlZWtHZXR0ZXIoMSkKfTsKCnZhciBEQVRFX0ZPUk1BVFNfU1BMSVQgPSAvKCg/OlteeU1kSGhtc2FaRXcnXSspfCg/OicoPzpbXiddfCcnKSonKXwoPzpFK3x5K3xNK3xkK3xIK3xoK3xtK3xzK3xhfFp8dyspKSguKikvLAogICAgTlVNQkVSX1NUUklORyA9IC9eXC0/XGQrJC87CgovKioKICogQG5nZG9jIGZpbHRlcgogKiBAbmFtZSBkYXRlCiAqIEBraW5kIGZ1bmN0aW9uCiAqCiAqIEBkZXNjcmlwdGlvbgogKiAgIEZvcm1hdHMgYGRhdGVgIHRvIGEgc3RyaW5nIGJhc2VkIG9uIHRoZSByZXF1ZXN0ZWQgYGZvcm1hdGAuCiAqCiAqICAgYGZvcm1hdGAgc3RyaW5nIGNhbiBiZSBjb21wb3NlZCBvZiB0aGUgZm9sbG93aW5nIGVsZW1lbnRzOgogKgogKiAgICogYCd5eXl5J2A6IDQgZGlnaXQgcmVwcmVzZW50YXRpb24gb2YgeWVhciAoZS5nLiBBRCAxID0+IDAwMDEsIEFEIDIwMTAgPT4gMjAxMCkKICogICAqIGAneXknYDogMiBkaWdpdCByZXByZXNlbnRhdGlvbiBvZiB5ZWFyLCBwYWRkZWQgKDAwLTk5KS4gKGUuZy4gQUQgMjAwMSA9PiAwMSwgQUQgMjAxMCA9PiAxMCkKICogICAqIGAneSdgOiAxIGRpZ2l0IHJlcHJlc2VudGF0aW9uIG9mIHllYXIsIGUuZy4gKEFEIDEgPT4gMSwgQUQgMTk5ID0+IDE5OSkKICogICAqIGAnTU1NTSdgOiBNb250aCBpbiB5ZWFyIChKYW51YXJ5LURlY2VtYmVyKQogKiAgICogYCdNTU0nYDogTW9udGggaW4geWVhciAoSmFuLURlYykKICogICAqIGAnTU0nYDogTW9udGggaW4geWVhciwgcGFkZGVkICgwMS0xMikKICogICAqIGAnTSdgOiBNb250aCBpbiB5ZWFyICgxLTEyKQogKiAgICogYCdkZCdgOiBEYXkgaW4gbW9udGgsIHBhZGRlZCAoMDEtMzEpCiAqICAgKiBgJ2QnYDogRGF5IGluIG1vbnRoICgxLTMxKQogKiAgICogYCdFRUVFJ2A6IERheSBpbiBXZWVrLChTdW5kYXktU2F0dXJkYXkpCiAqICAgKiBgJ0VFRSdgOiBEYXkgaW4gV2VlaywgKFN1bi1TYXQpCiAqICAgKiBgJ0hIJ2A6IEhvdXIgaW4gZGF5LCBwYWRkZWQgKDAwLTIzKQogKiAgICogYCdIJ2A6IEhvdXIgaW4gZGF5ICgwLTIzKQogKiAgICogYCdoaCdgOiBIb3VyIGluIEFNL1BNLCBwYWRkZWQgKDAxLTEyKQogKiAgICogYCdoJ2A6IEhvdXIgaW4gQU0vUE0sICgxLTEyKQogKiAgICogYCdtbSdgOiBNaW51dGUgaW4gaG91ciwgcGFkZGVkICgwMC01OSkKICogICAqIGAnbSdgOiBNaW51dGUgaW4gaG91ciAoMC01OSkKICogICAqIGAnc3MnYDogU2Vjb25kIGluIG1pbnV0ZSwgcGFkZGVkICgwMC01OSkKICogICAqIGAncydgOiBTZWNvbmQgaW4gbWludXRlICgwLTU5KQogKiAgICogYCcuc3NzJyBvciAnLHNzcydgOiBNaWxsaXNlY29uZCBpbiBzZWNvbmQsIHBhZGRlZCAoMDAwLTk5OSkKICogICAqIGAnYSdgOiBBTS9QTSBtYXJrZXIKICogICAqIGAnWidgOiA0IGRpZ2l0ICgrc2lnbikgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRpbWV6b25lIG9mZnNldCAoLTEyMDAtKzEyMDApCiAqICAgKiBgJ3d3J2A6IFdlZWsgb2YgeWVhciwgcGFkZGVkICgwMC01MykuIFdlZWsgMDEgaXMgdGhlIHdlZWsgd2l0aCB0aGUgZmlyc3QgVGh1cnNkYXkgb2YgdGhlIHllYXIKICogICAqIGAndydgOiBXZWVrIG9mIHllYXIgKDAtNTMpLiBXZWVrIDEgaXMgdGhlIHdlZWsgd2l0aCB0aGUgZmlyc3QgVGh1cnNkYXkgb2YgdGhlIHllYXIKICoKICogICBgZm9ybWF0YCBzdHJpbmcgY2FuIGFsc28gYmUgb25lIG9mIHRoZSBmb2xsb3dpbmcgcHJlZGVmaW5lZAogKiAgIHtAbGluayBndWlkZS9pMThuIGxvY2FsaXphYmxlIGZvcm1hdHN9OgogKgogKiAgICogYCdtZWRpdW0nYDogZXF1aXZhbGVudCB0byBgJ01NTSBkLCB5IGg6bW06c3MgYSdgIGZvciBlbl9VUyBsb2NhbGUKICogICAgIChlLmcuIFNlcCAzLCAyMDEwIDEyOjA1OjA4IFBNKQogKiAgICogYCdzaG9ydCdgOiBlcXVpdmFsZW50IHRvIGAnTS9kL3l5IGg6bW0gYSdgIGZvciBlbl9VUyAgbG9jYWxlIChlLmcuIDkvMy8xMCAxMjowNSBQTSkKICogICAqIGAnZnVsbERhdGUnYDogZXF1aXZhbGVudCB0byBgJ0VFRUUsIE1NTU0gZCwgeSdgIGZvciBlbl9VUyAgbG9jYWxlCiAqICAgICAoZS5nLiBGcmlkYXksIFNlcHRlbWJlciAzLCAyMDEwKQogKiAgICogYCdsb25nRGF0ZSdgOiBlcXVpdmFsZW50IHRvIGAnTU1NTSBkLCB5J2AgZm9yIGVuX1VTICBsb2NhbGUgKGUuZy4gU2VwdGVtYmVyIDMsIDIwMTApCiAqICAgKiBgJ21lZGl1bURhdGUnYDogZXF1aXZhbGVudCB0byBgJ01NTSBkLCB5J2AgZm9yIGVuX1VTICBsb2NhbGUgKGUuZy4gU2VwIDMsIDIwMTApCiAqICAgKiBgJ3Nob3J0RGF0ZSdgOiBlcXVpdmFsZW50IHRvIGAnTS9kL3l5J2AgZm9yIGVuX1VTIGxvY2FsZSAoZS5nLiA5LzMvMTApCiAqICAgKiBgJ21lZGl1bVRpbWUnYDogZXF1aXZhbGVudCB0byBgJ2g6bW06c3MgYSdgIGZvciBlbl9VUyBsb2NhbGUgKGUuZy4gMTI6MDU6MDggUE0pCiAqICAgKiBgJ3Nob3J0VGltZSdgOiBlcXVpdmFsZW50IHRvIGAnaDptbSBhJ2AgZm9yIGVuX1VTIGxvY2FsZSAoZS5nLiAxMjowNSBQTSkKICoKICogICBgZm9ybWF0YCBzdHJpbmcgY2FuIGNvbnRhaW4gbGl0ZXJhbCB2YWx1ZXMuIFRoZXNlIG5lZWQgdG8gYmUgZXNjYXBlZCBieSBzdXJyb3VuZGluZyB3aXRoIHNpbmdsZSBxdW90ZXMgKGUuZy4KICogICBgImggJ2luIHRoZSBtb3JuaW5nJyJgKS4gSW4gb3JkZXIgdG8gb3V0cHV0IGEgc2luZ2xlIHF1b3RlLCBlc2NhcGUgaXQgLSBpLmUuLCB0d28gc2luZ2xlIHF1b3RlcyBpbiBhIHNlcXVlbmNlCiAqICAgKGUuZy4gYCJoICdvJydjbG9jayciYCkuCiAqCiAqIEBwYXJhbSB7KERhdGV8bnVtYmVyfHN0cmluZyl9IGRhdGUgRGF0ZSB0byBmb3JtYXQgZWl0aGVyIGFzIERhdGUgb2JqZWN0LCBtaWxsaXNlY29uZHMgKHN0cmluZyBvcgogKiAgICBudW1iZXIpIG9yIHZhcmlvdXMgSVNPIDg2MDEgZGF0ZXRpbWUgc3RyaW5nIGZvcm1hdHMgKGUuZy4geXl5eS1NTS1kZFRISDptbTpzcy5zc3NaIGFuZCBpdHMKICogICAgc2hvcnRlciB2ZXJzaW9ucyBsaWtlIHl5eXktTU0tZGRUSEg6bW1aLCB5eXl5LU1NLWRkIG9yIHl5eXlNTWRkVEhIbW1zc1opLiBJZiBubyB0aW1lem9uZSBpcwogKiAgICBzcGVjaWZpZWQgaW4gdGhlIHN0cmluZyBpbnB1dCwgdGhlIHRpbWUgaXMgY29uc2lkZXJlZCB0byBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuCiAqIEBwYXJhbSB7c3RyaW5nPX0gZm9ybWF0IEZvcm1hdHRpbmcgcnVsZXMgKHNlZSBEZXNjcmlwdGlvbikuIElmIG5vdCBzcGVjaWZpZWQsCiAqICAgIGBtZWRpdW1EYXRlYCBpcyB1c2VkLgogKiBAcGFyYW0ge3N0cmluZz19IHRpbWV6b25lIFRpbWV6b25lIHRvIGJlIHVzZWQgZm9yIGZvcm1hdHRpbmcuIFJpZ2h0IG5vdywgb25seSBgJ1VUQydgIGlzIHN1cHBvcnRlZC4KICogICAgSWYgbm90IHNwZWNpZmllZCwgdGhlIHRpbWV6b25lIG9mIHRoZSBicm93c2VyIHdpbGwgYmUgdXNlZC4KICogQHJldHVybnMge3N0cmluZ30gRm9ybWF0dGVkIHN0cmluZyBvciB0aGUgaW5wdXQgaWYgaW5wdXQgaXMgbm90IHJlY29nbml6ZWQgYXMgZGF0ZS9taWxsaXMuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNwYW4gbmctbm9uLWJpbmRhYmxlPnt7MTI4ODMyMzYyMzAwNiB8IGRhdGU6J21lZGl1bSd9fTwvc3Bhbj46CiAgICAgICAgICAgPHNwYW4+e3sxMjg4MzIzNjIzMDA2IHwgZGF0ZTonbWVkaXVtJ319PC9zcGFuPjxicj4KICAgICAgIDxzcGFuIG5nLW5vbi1iaW5kYWJsZT57ezEyODgzMjM2MjMwMDYgfCBkYXRlOid5eXl5LU1NLWRkIEhIOm1tOnNzIFonfX08L3NwYW4+OgogICAgICAgICAgPHNwYW4+e3sxMjg4MzIzNjIzMDA2IHwgZGF0ZToneXl5eS1NTS1kZCBISDptbTpzcyBaJ319PC9zcGFuPjxicj4KICAgICAgIDxzcGFuIG5nLW5vbi1iaW5kYWJsZT57ezEyODgzMjM2MjMwMDYgfCBkYXRlOidNTS9kZC95eXl5IEAgaDptbWEnfX08L3NwYW4+OgogICAgICAgICAgPHNwYW4+e3snMTI4ODMyMzYyMzAwNicgfCBkYXRlOidNTS9kZC95eXl5IEAgaDptbWEnfX08L3NwYW4+PGJyPgogICAgICAgPHNwYW4gbmctbm9uLWJpbmRhYmxlPnt7MTI4ODMyMzYyMzAwNiB8IGRhdGU6Ik1NL2RkL3l5eXkgJ2F0JyBoOm1tYSJ9fTwvc3Bhbj46CiAgICAgICAgICA8c3Bhbj57eycxMjg4MzIzNjIzMDA2JyB8IGRhdGU6Ik1NL2RkL3l5eXkgJ2F0JyBoOm1tYSJ9fTwvc3Bhbj48YnI+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgaXQoJ3Nob3VsZCBmb3JtYXQgZGF0ZScsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCIxMjg4MzIzNjIzMDA2IHwgZGF0ZTonbWVkaXVtJyIpKS5nZXRUZXh0KCkpLgogICAgICAgICAgICB0b01hdGNoKC9PY3QgMlxkLCAyMDEwIFxkezEsMn06XGR7Mn06XGR7Mn0gKEFNfFBNKS8pOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCIxMjg4MzIzNjIzMDA2IHwgZGF0ZToneXl5eS1NTS1kZCBISDptbTpzcyBaJyIpKS5nZXRUZXh0KCkpLgogICAgICAgICAgICB0b01hdGNoKC8yMDEwXC0xMFwtMlxkIFxkezJ9OlxkezJ9OlxkezJ9IChcLXxcKyk/XGR7NH0vKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygiJzEyODgzMjM2MjMwMDYnIHwgZGF0ZTonTU0vZGQveXl5eSBAIGg6bW1hJyIpKS5nZXRUZXh0KCkpLgogICAgICAgICAgICB0b01hdGNoKC8xMFwvMlxkXC8yMDEwIEAgXGR7MSwyfTpcZHsyfShBTXxQTSkvKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygiJzEyODgzMjM2MjMwMDYnIHwgZGF0ZTpcIk1NL2RkL3l5eXkgJ2F0JyBoOm1tYVwiIikpLmdldFRleHQoKSkuCiAgICAgICAgICAgIHRvTWF0Y2goLzEwXC8yXGRcLzIwMTAgYXQgXGR7MSwyfTpcZHsyfShBTXxQTSkvKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KZGF0ZUZpbHRlci4kaW5qZWN0ID0gWyckbG9jYWxlJ107CmZ1bmN0aW9uIGRhdGVGaWx0ZXIoJGxvY2FsZSkgewoKCiAgdmFyIFJfSVNPODYwMV9TVFIgPSAvXihcZHs0fSktPyhcZFxkKS0/KFxkXGQpKD86VChcZFxkKSg/Ojo/KFxkXGQpKD86Oj8oXGRcZCkoPzpcLihcZCspKT8pPyk/KFp8KFsrLV0pKFxkXGQpOj8oXGRcZCkpPyk/JC87CiAgICAgICAgICAgICAgICAgICAgIC8vIDEgICAgICAgIDIgICAgICAgMyAgICAgICAgIDQgICAgICAgICAgNSAgICAgICAgICA2ICAgICAgICAgIDcgICAgICAgICAgOCAgOSAgICAgMTAgICAgICAxMQogIGZ1bmN0aW9uIGpzb25TdHJpbmdUb0RhdGUoc3RyaW5nKSB7CiAgICB2YXIgbWF0Y2g7CiAgICBpZiAobWF0Y2ggPSBzdHJpbmcubWF0Y2goUl9JU084NjAxX1NUUikpIHsKICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgwKSwKICAgICAgICAgIHR6SG91ciA9IDAsCiAgICAgICAgICB0ek1pbiAgPSAwLAogICAgICAgICAgZGF0ZVNldHRlciA9IG1hdGNoWzhdID8gZGF0ZS5zZXRVVENGdWxsWWVhciA6IGRhdGUuc2V0RnVsbFllYXIsCiAgICAgICAgICB0aW1lU2V0dGVyID0gbWF0Y2hbOF0gPyBkYXRlLnNldFVUQ0hvdXJzIDogZGF0ZS5zZXRIb3VyczsKCiAgICAgIGlmIChtYXRjaFs5XSkgewogICAgICAgIHR6SG91ciA9IGludChtYXRjaFs5XSArIG1hdGNoWzEwXSk7CiAgICAgICAgdHpNaW4gPSBpbnQobWF0Y2hbOV0gKyBtYXRjaFsxMV0pOwogICAgICB9CiAgICAgIGRhdGVTZXR0ZXIuY2FsbChkYXRlLCBpbnQobWF0Y2hbMV0pLCBpbnQobWF0Y2hbMl0pIC0gMSwgaW50KG1hdGNoWzNdKSk7CiAgICAgIHZhciBoID0gaW50KG1hdGNoWzRdIHx8IDApIC0gdHpIb3VyOwogICAgICB2YXIgbSA9IGludChtYXRjaFs1XSB8fCAwKSAtIHR6TWluOwogICAgICB2YXIgcyA9IGludChtYXRjaFs2XSB8fCAwKTsKICAgICAgdmFyIG1zID0gTWF0aC5yb3VuZChwYXJzZUZsb2F0KCcwLicgKyAobWF0Y2hbN10gfHwgMCkpICogMTAwMCk7CiAgICAgIHRpbWVTZXR0ZXIuY2FsbChkYXRlLCBoLCBtLCBzLCBtcyk7CiAgICAgIHJldHVybiBkYXRlOwogICAgfQogICAgcmV0dXJuIHN0cmluZzsKICB9CgoKICByZXR1cm4gZnVuY3Rpb24oZGF0ZSwgZm9ybWF0LCB0aW1lem9uZSkgewogICAgdmFyIHRleHQgPSAnJywKICAgICAgICBwYXJ0cyA9IFtdLAogICAgICAgIGZuLCBtYXRjaDsKCiAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJ21lZGl1bURhdGUnOwogICAgZm9ybWF0ID0gJGxvY2FsZS5EQVRFVElNRV9GT1JNQVRTW2Zvcm1hdF0gfHwgZm9ybWF0OwogICAgaWYgKGlzU3RyaW5nKGRhdGUpKSB7CiAgICAgIGRhdGUgPSBOVU1CRVJfU1RSSU5HLnRlc3QoZGF0ZSkgPyBpbnQoZGF0ZSkgOiBqc29uU3RyaW5nVG9EYXRlKGRhdGUpOwogICAgfQoKICAgIGlmIChpc051bWJlcihkYXRlKSkgewogICAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7CiAgICB9CgogICAgaWYgKCFpc0RhdGUoZGF0ZSkpIHsKICAgICAgcmV0dXJuIGRhdGU7CiAgICB9CgogICAgd2hpbGUgKGZvcm1hdCkgewogICAgICBtYXRjaCA9IERBVEVfRk9STUFUU19TUExJVC5leGVjKGZvcm1hdCk7CiAgICAgIGlmIChtYXRjaCkgewogICAgICAgIHBhcnRzID0gY29uY2F0KHBhcnRzLCBtYXRjaCwgMSk7CiAgICAgICAgZm9ybWF0ID0gcGFydHMucG9wKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcGFydHMucHVzaChmb3JtYXQpOwogICAgICAgIGZvcm1hdCA9IG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBpZiAodGltZXpvbmUgJiYgdGltZXpvbmUgPT09ICdVVEMnKSB7CiAgICAgIGRhdGUgPSBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSk7CiAgICAgIGRhdGUuc2V0TWludXRlcyhkYXRlLmdldE1pbnV0ZXMoKSArIGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKSk7CiAgICB9CiAgICBmb3JFYWNoKHBhcnRzLCBmdW5jdGlvbih2YWx1ZSkgewogICAgICBmbiA9IERBVEVfRk9STUFUU1t2YWx1ZV07CiAgICAgIHRleHQgKz0gZm4gPyBmbihkYXRlLCAkbG9jYWxlLkRBVEVUSU1FX0ZPUk1BVFMpCiAgICAgICAgICAgICAgICAgOiB2YWx1ZS5yZXBsYWNlKC8oXid8JyQpL2csICcnKS5yZXBsYWNlKC8nJy9nLCAiJyIpOwogICAgfSk7CgogICAgcmV0dXJuIHRleHQ7CiAgfTsKfQoKCi8qKgogKiBAbmdkb2MgZmlsdGVyCiAqIEBuYW1lIGpzb24KICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqICAgQWxsb3dzIHlvdSB0byBjb252ZXJ0IGEgSmF2YVNjcmlwdCBvYmplY3QgaW50byBKU09OIHN0cmluZy4KICoKICogICBUaGlzIGZpbHRlciBpcyBtb3N0bHkgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuIFdoZW4gdXNpbmcgdGhlIGRvdWJsZSBjdXJseSB7e3ZhbHVlfX0gbm90YXRpb24KICogICB0aGUgYmluZGluZyBpcyBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBKU09OLgogKgogKiBAcGFyYW0geyp9IG9iamVjdCBBbnkgSmF2YVNjcmlwdCBvYmplY3QgKGluY2x1ZGluZyBhcnJheXMgYW5kIHByaW1pdGl2ZSB0eXBlcykgdG8gZmlsdGVyLgogKiBAcGFyYW0ge251bWJlcj19IHNwYWNpbmcgVGhlIG51bWJlciBvZiBzcGFjZXMgdG8gdXNlIHBlciBpbmRlbnRhdGlvbiwgZGVmYXVsdHMgdG8gMi4KICogQHJldHVybnMge3N0cmluZ30gSlNPTiBzdHJpbmcuCiAqCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHByZSBpZD0iZGVmYXVsdC1zcGFjaW5nIj57eyB7J25hbWUnOid2YWx1ZSd9IHwganNvbiB9fTwvcHJlPgogICAgICAgPHByZSBpZD0iY3VzdG9tLXNwYWNpbmciPnt7IHsnbmFtZSc6J3ZhbHVlJ30gfCBqc29uOjQgfX08L3ByZT4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGpzb25pZnkgZmlsdGVyZWQgb2JqZWN0cycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnZGVmYXVsdC1zcGFjaW5nJykpLmdldFRleHQoKSkudG9NYXRjaCgvXHtcbiAgIm5hbWUiOiA/InZhbHVlIlxufS8pOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnY3VzdG9tLXNwYWNpbmcnKSkuZ2V0VGV4dCgpKS50b01hdGNoKC9ce1xuICAgICJuYW1lIjogPyJ2YWx1ZSJcbn0vKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKgogKi8KZnVuY3Rpb24ganNvbkZpbHRlcigpIHsKICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBzcGFjaW5nKSB7CiAgICBpZiAoaXNVbmRlZmluZWQoc3BhY2luZykpIHsKICAgICAgICBzcGFjaW5nID0gMjsKICAgIH0KICAgIHJldHVybiB0b0pzb24ob2JqZWN0LCBzcGFjaW5nKTsKICB9Owp9CgoKLyoqCiAqIEBuZ2RvYyBmaWx0ZXIKICogQG5hbWUgbG93ZXJjYXNlCiAqIEBraW5kIGZ1bmN0aW9uCiAqIEBkZXNjcmlwdGlvbgogKiBDb252ZXJ0cyBzdHJpbmcgdG8gbG93ZXJjYXNlLgogKiBAc2VlIGFuZ3VsYXIubG93ZXJjYXNlCiAqLwp2YXIgbG93ZXJjYXNlRmlsdGVyID0gdmFsdWVGbihsb3dlcmNhc2UpOwoKCi8qKgogKiBAbmdkb2MgZmlsdGVyCiAqIEBuYW1lIHVwcGVyY2FzZQogKiBAa2luZCBmdW5jdGlvbgogKiBAZGVzY3JpcHRpb24KICogQ29udmVydHMgc3RyaW5nIHRvIHVwcGVyY2FzZS4KICogQHNlZSBhbmd1bGFyLnVwcGVyY2FzZQogKi8KdmFyIHVwcGVyY2FzZUZpbHRlciA9IHZhbHVlRm4odXBwZXJjYXNlKTsKCi8qKgogKiBAbmdkb2MgZmlsdGVyCiAqIEBuYW1lIGxpbWl0VG8KICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIENyZWF0ZXMgYSBuZXcgYXJyYXkgb3Igc3RyaW5nIGNvbnRhaW5pbmcgb25seSBhIHNwZWNpZmllZCBudW1iZXIgb2YgZWxlbWVudHMuIFRoZSBlbGVtZW50cwogKiBhcmUgdGFrZW4gZnJvbSBlaXRoZXIgdGhlIGJlZ2lubmluZyBvciB0aGUgZW5kIG9mIHRoZSBzb3VyY2UgYXJyYXksIHN0cmluZyBvciBudW1iZXIsIGFzIHNwZWNpZmllZCBieQogKiB0aGUgdmFsdWUgYW5kIHNpZ24gKHBvc2l0aXZlIG9yIG5lZ2F0aXZlKSBvZiBgbGltaXRgLiBJZiBhIG51bWJlciBpcyB1c2VkIGFzIGlucHV0LCBpdCBpcwogKiBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfG51bWJlcn0gaW5wdXQgU291cmNlIGFycmF5LCBzdHJpbmcgb3IgbnVtYmVyIHRvIGJlIGxpbWl0ZWQuCiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gbGltaXQgVGhlIGxlbmd0aCBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgb3Igc3RyaW5nLiBJZiB0aGUgYGxpbWl0YCBudW1iZXIKICogICAgIGlzIHBvc2l0aXZlLCBgbGltaXRgIG51bWJlciBvZiBpdGVtcyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNvdXJjZSBhcnJheS9zdHJpbmcgYXJlIGNvcGllZC4KICogICAgIElmIHRoZSBudW1iZXIgaXMgbmVnYXRpdmUsIGBsaW1pdGAgbnVtYmVyICBvZiBpdGVtcyBmcm9tIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBhcnJheS9zdHJpbmcKICogICAgIGFyZSBjb3BpZWQuIFRoZSBgbGltaXRgIHdpbGwgYmUgdHJpbW1lZCBpZiBpdCBleGNlZWRzIGBhcnJheS5sZW5ndGhgCiAqIEByZXR1cm5zIHtBcnJheXxzdHJpbmd9IEEgbmV3IHN1Yi1hcnJheSBvciBzdWJzdHJpbmcgb2YgbGVuZ3RoIGBsaW1pdGAgb3IgbGVzcyBpZiBpbnB1dCBhcnJheQogKiAgICAgaGFkIGxlc3MgdGhhbiBgbGltaXRgIGVsZW1lbnRzLgogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZSBtb2R1bGU9ImxpbWl0VG9FeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgIDxzY3JpcHQ+CiAgICAgICAgIGFuZ3VsYXIubW9kdWxlKCdsaW1pdFRvRXhhbXBsZScsIFtdKQogICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAkc2NvcGUubnVtYmVycyA9IFsxLDIsMyw0LDUsNiw3LDgsOV07CiAgICAgICAgICAgICAkc2NvcGUubGV0dGVycyA9ICJhYmNkZWZnaGkiOwogICAgICAgICAgICAgJHNjb3BlLmxvbmdOdW1iZXIgPSAyMzQ1NDMyMzQyOwogICAgICAgICAgICAgJHNjb3BlLm51bUxpbWl0ID0gMzsKICAgICAgICAgICAgICRzY29wZS5sZXR0ZXJMaW1pdCA9IDM7CiAgICAgICAgICAgICAkc2NvcGUubG9uZ051bWJlckxpbWl0ID0gMzsKICAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICBMaW1pdCB7e251bWJlcnN9fSB0bzogPGlucHV0IHR5cGU9Im51bWJlciIgc3RlcD0iMSIgbmctbW9kZWw9Im51bUxpbWl0Ij4KICAgICAgICAgPHA+T3V0cHV0IG51bWJlcnM6IHt7IG51bWJlcnMgfCBsaW1pdFRvOm51bUxpbWl0IH19PC9wPgogICAgICAgICBMaW1pdCB7e2xldHRlcnN9fSB0bzogPGlucHV0IHR5cGU9Im51bWJlciIgc3RlcD0iMSIgbmctbW9kZWw9ImxldHRlckxpbWl0Ij4KICAgICAgICAgPHA+T3V0cHV0IGxldHRlcnM6IHt7IGxldHRlcnMgfCBsaW1pdFRvOmxldHRlckxpbWl0IH19PC9wPgogICAgICAgICBMaW1pdCB7e2xvbmdOdW1iZXJ9fSB0bzogPGlucHV0IHR5cGU9Im51bWJlciIgc3RlcD0iMSIgbmctbW9kZWw9ImxvbmdOdW1iZXJMaW1pdCI+CiAgICAgICAgIDxwPk91dHB1dCBsb25nIG51bWJlcjoge3sgbG9uZ051bWJlciB8IGxpbWl0VG86bG9uZ051bWJlckxpbWl0IH19PC9wPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgdmFyIG51bUxpbWl0SW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCdudW1MaW1pdCcpKTsKICAgICAgIHZhciBsZXR0ZXJMaW1pdElucHV0ID0gZWxlbWVudChieS5tb2RlbCgnbGV0dGVyTGltaXQnKSk7CiAgICAgICB2YXIgbG9uZ051bWJlckxpbWl0SW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCdsb25nTnVtYmVyTGltaXQnKSk7CiAgICAgICB2YXIgbGltaXRlZE51bWJlcnMgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ251bWJlcnMgfCBsaW1pdFRvOm51bUxpbWl0JykpOwogICAgICAgdmFyIGxpbWl0ZWRMZXR0ZXJzID0gZWxlbWVudChieS5iaW5kaW5nKCdsZXR0ZXJzIHwgbGltaXRUbzpsZXR0ZXJMaW1pdCcpKTsKICAgICAgIHZhciBsaW1pdGVkTG9uZ051bWJlciA9IGVsZW1lbnQoYnkuYmluZGluZygnbG9uZ051bWJlciB8IGxpbWl0VG86bG9uZ051bWJlckxpbWl0JykpOwoKICAgICAgIGl0KCdzaG91bGQgbGltaXQgdGhlIG51bWJlciBhcnJheSB0byBmaXJzdCB0aHJlZSBpdGVtcycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QobnVtTGltaXRJbnB1dC5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpLnRvQmUoJzMnKTsKICAgICAgICAgZXhwZWN0KGxldHRlckxpbWl0SW5wdXQuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKS50b0JlKCczJyk7CiAgICAgICAgIGV4cGVjdChsb25nTnVtYmVyTGltaXRJbnB1dC5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpLnRvQmUoJzMnKTsKICAgICAgICAgZXhwZWN0KGxpbWl0ZWROdW1iZXJzLmdldFRleHQoKSkudG9FcXVhbCgnT3V0cHV0IG51bWJlcnM6IFsxLDIsM10nKTsKICAgICAgICAgZXhwZWN0KGxpbWl0ZWRMZXR0ZXJzLmdldFRleHQoKSkudG9FcXVhbCgnT3V0cHV0IGxldHRlcnM6IGFiYycpOwogICAgICAgICBleHBlY3QobGltaXRlZExvbmdOdW1iZXIuZ2V0VGV4dCgpKS50b0VxdWFsKCdPdXRwdXQgbG9uZyBudW1iZXI6IDIzNCcpOwogICAgICAgfSk7CgogICAgICAgLy8gVGhlcmUgaXMgYSBidWcgaW4gc2FmYXJpIGFuZCBwcm90cmFjdG9yIHRoYXQgZG9lc24ndCBsaWtlIHRoZSBtaW51cyBrZXkKICAgICAgIC8vIGl0KCdzaG91bGQgdXBkYXRlIHRoZSBvdXRwdXQgd2hlbiAtMyBpcyBlbnRlcmVkJywgZnVuY3Rpb24oKSB7CiAgICAgICAvLyAgIG51bUxpbWl0SW5wdXQuY2xlYXIoKTsKICAgICAgIC8vICAgbnVtTGltaXRJbnB1dC5zZW5kS2V5cygnLTMnKTsKICAgICAgIC8vICAgbGV0dGVyTGltaXRJbnB1dC5jbGVhcigpOwogICAgICAgLy8gICBsZXR0ZXJMaW1pdElucHV0LnNlbmRLZXlzKCctMycpOwogICAgICAgLy8gICBsb25nTnVtYmVyTGltaXRJbnB1dC5jbGVhcigpOwogICAgICAgLy8gICBsb25nTnVtYmVyTGltaXRJbnB1dC5zZW5kS2V5cygnLTMnKTsKICAgICAgIC8vICAgZXhwZWN0KGxpbWl0ZWROdW1iZXJzLmdldFRleHQoKSkudG9FcXVhbCgnT3V0cHV0IG51bWJlcnM6IFs3LDgsOV0nKTsKICAgICAgIC8vICAgZXhwZWN0KGxpbWl0ZWRMZXR0ZXJzLmdldFRleHQoKSkudG9FcXVhbCgnT3V0cHV0IGxldHRlcnM6IGdoaScpOwogICAgICAgLy8gICBleHBlY3QobGltaXRlZExvbmdOdW1iZXIuZ2V0VGV4dCgpKS50b0VxdWFsKCdPdXRwdXQgbG9uZyBudW1iZXI6IDM0MicpOwogICAgICAgLy8gfSk7CgogICAgICAgaXQoJ3Nob3VsZCBub3QgZXhjZWVkIHRoZSBtYXhpbXVtIHNpemUgb2YgaW5wdXQgYXJyYXknLCBmdW5jdGlvbigpIHsKICAgICAgICAgbnVtTGltaXRJbnB1dC5jbGVhcigpOwogICAgICAgICBudW1MaW1pdElucHV0LnNlbmRLZXlzKCcxMDAnKTsKICAgICAgICAgbGV0dGVyTGltaXRJbnB1dC5jbGVhcigpOwogICAgICAgICBsZXR0ZXJMaW1pdElucHV0LnNlbmRLZXlzKCcxMDAnKTsKICAgICAgICAgbG9uZ051bWJlckxpbWl0SW5wdXQuY2xlYXIoKTsKICAgICAgICAgbG9uZ051bWJlckxpbWl0SW5wdXQuc2VuZEtleXMoJzEwMCcpOwogICAgICAgICBleHBlY3QobGltaXRlZE51bWJlcnMuZ2V0VGV4dCgpKS50b0VxdWFsKCdPdXRwdXQgbnVtYmVyczogWzEsMiwzLDQsNSw2LDcsOCw5XScpOwogICAgICAgICBleHBlY3QobGltaXRlZExldHRlcnMuZ2V0VGV4dCgpKS50b0VxdWFsKCdPdXRwdXQgbGV0dGVyczogYWJjZGVmZ2hpJyk7CiAgICAgICAgIGV4cGVjdChsaW1pdGVkTG9uZ051bWJlci5nZXRUZXh0KCkpLnRvRXF1YWwoJ091dHB1dCBsb25nIG51bWJlcjogMjM0NTQzMjM0MicpOwogICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiovCmZ1bmN0aW9uIGxpbWl0VG9GaWx0ZXIoKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGlucHV0LCBsaW1pdCkgewogICAgaWYgKGlzTnVtYmVyKGlucHV0KSkgaW5wdXQgPSBpbnB1dC50b1N0cmluZygpOwogICAgaWYgKCFpc0FycmF5KGlucHV0KSAmJiAhaXNTdHJpbmcoaW5wdXQpKSByZXR1cm4gaW5wdXQ7CgogICAgaWYgKE1hdGguYWJzKE51bWJlcihsaW1pdCkpID09PSBJbmZpbml0eSkgewogICAgICBsaW1pdCA9IE51bWJlcihsaW1pdCk7CiAgICB9IGVsc2UgewogICAgICBsaW1pdCA9IGludChsaW1pdCk7CiAgICB9CgogICAgaWYgKGlzU3RyaW5nKGlucHV0KSkgewogICAgICAvL05hTiBjaGVjayBvbiBsaW1pdAogICAgICBpZiAobGltaXQpIHsKICAgICAgICByZXR1cm4gbGltaXQgPj0gMCA/IGlucHV0LnNsaWNlKDAsIGxpbWl0KSA6IGlucHV0LnNsaWNlKGxpbWl0LCBpbnB1dC5sZW5ndGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAiIjsKICAgICAgfQogICAgfQoKICAgIHZhciBpLCBuOwoKICAgIC8vIGlmIGFicyhsaW1pdCkgZXhjZWVkcyBtYXhpbXVtIGxlbmd0aCwgdHJpbSBpdAogICAgaWYgKGxpbWl0ID4gaW5wdXQubGVuZ3RoKQogICAgICBsaW1pdCA9IGlucHV0Lmxlbmd0aDsKICAgIGVsc2UgaWYgKGxpbWl0IDwgLWlucHV0Lmxlbmd0aCkKICAgICAgbGltaXQgPSAtaW5wdXQubGVuZ3RoOwoKICAgIGlmIChsaW1pdCA+IDApIHsKICAgICAgaSA9IDA7CiAgICAgIG4gPSBsaW1pdDsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHplcm8gYW5kIE5hTiBjaGVjayBvbiBsaW1pdCAtIHJldHVybiBlbXB0eSBhcnJheQogICAgICBpZiAoIWxpbWl0KSByZXR1cm4gW107CgogICAgICBpID0gaW5wdXQubGVuZ3RoICsgbGltaXQ7CiAgICAgIG4gPSBpbnB1dC5sZW5ndGg7CiAgICB9CgogICAgcmV0dXJuIGlucHV0LnNsaWNlKGksIG4pOwogIH07Cn0KCi8qKgogKiBAbmdkb2MgZmlsdGVyCiAqIEBuYW1lIG9yZGVyQnkKICogQGtpbmQgZnVuY3Rpb24KICoKICogQGRlc2NyaXB0aW9uCiAqIE9yZGVycyBhIHNwZWNpZmllZCBgYXJyYXlgIGJ5IHRoZSBgZXhwcmVzc2lvbmAgcHJlZGljYXRlLiBJdCBpcyBvcmRlcmVkIGFscGhhYmV0aWNhbGx5CiAqIGZvciBzdHJpbmdzIGFuZCBudW1lcmljYWxseSBmb3IgbnVtYmVycy4gTm90ZTogaWYgeW91IG5vdGljZSBudW1iZXJzIGFyZSBub3QgYmVpbmcgc29ydGVkCiAqIGNvcnJlY3RseSwgbWFrZSBzdXJlIHRoZXkgYXJlIGFjdHVhbGx5IGJlaW5nIHNhdmVkIGFzIG51bWJlcnMgYW5kIG5vdCBzdHJpbmdzLgogKgogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc29ydC4KICogQHBhcmFtIHtmdW5jdGlvbigqKXxzdHJpbmd8QXJyYXkuPChmdW5jdGlvbigqKXxzdHJpbmcpPj19IGV4cHJlc3Npb24gQSBwcmVkaWNhdGUgdG8gYmUKICogICAgdXNlZCBieSB0aGUgY29tcGFyYXRvciB0byBkZXRlcm1pbmUgdGhlIG9yZGVyIG9mIGVsZW1lbnRzLgogKgogKiAgICBDYW4gYmUgb25lIG9mOgogKgogKiAgICAtIGBmdW5jdGlvbmA6IEdldHRlciBmdW5jdGlvbi4gVGhlIHJlc3VsdCBvZiB0aGlzIGZ1bmN0aW9uIHdpbGwgYmUgc29ydGVkIHVzaW5nIHRoZQogKiAgICAgIGA8YCwgYD1gLCBgPmAgb3BlcmF0b3IuCiAqICAgIC0gYHN0cmluZ2A6IEFuIEFuZ3VsYXIgZXhwcmVzc2lvbi4gVGhlIHJlc3VsdCBvZiB0aGlzIGV4cHJlc3Npb24gaXMgdXNlZCB0byBjb21wYXJlIGVsZW1lbnRzCiAqICAgICAgKGZvciBleGFtcGxlIGBuYW1lYCB0byBzb3J0IGJ5IGEgcHJvcGVydHkgY2FsbGVkIGBuYW1lYCBvciBgbmFtZS5zdWJzdHIoMCwgMylgIHRvIHNvcnQgYnkKICogICAgICAzIGZpcnN0IGNoYXJhY3RlcnMgb2YgYSBwcm9wZXJ0eSBjYWxsZWQgYG5hbWVgKS4gVGhlIHJlc3VsdCBvZiBhIGNvbnN0YW50IGV4cHJlc3Npb24KICogICAgICBpcyBpbnRlcnByZXRlZCBhcyBhIHByb3BlcnR5IG5hbWUgdG8gYmUgdXNlZCBpbiBjb21wYXJpc29ucyAoZm9yIGV4YW1wbGUgYCJzcGVjaWFsIG5hbWUiYAogKiAgICAgIHRvIHNvcnQgb2JqZWN0IGJ5IHRoZSB2YWx1ZSBvZiB0aGVpciBgc3BlY2lhbCBuYW1lYCBwcm9wZXJ0eSkuIEFuIGV4cHJlc3Npb24gY2FuIGJlCiAqICAgICAgb3B0aW9uYWxseSBwcmVmaXhlZCB3aXRoIGArYCBvciBgLWAgdG8gY29udHJvbCBhc2NlbmRpbmcgb3IgZGVzY2VuZGluZyBzb3J0IG9yZGVyCiAqICAgICAgKGZvciBleGFtcGxlLCBgK25hbWVgIG9yIGAtbmFtZWApLiBJZiBubyBwcm9wZXJ0eSBpcyBwcm92aWRlZCwgKGUuZy4gYCcrJ2ApIHRoZW4gdGhlIGFycmF5CiAqICAgICAgZWxlbWVudCBpdHNlbGYgaXMgdXNlZCB0byBjb21wYXJlIHdoZXJlIHNvcnRpbmcuCiAqICAgIC0gYEFycmF5YDogQW4gYXJyYXkgb2YgZnVuY3Rpb24gb3Igc3RyaW5nIHByZWRpY2F0ZXMuIFRoZSBmaXJzdCBwcmVkaWNhdGUgaW4gdGhlIGFycmF5CiAqICAgICAgaXMgdXNlZCBmb3Igc29ydGluZywgYnV0IHdoZW4gdHdvIGl0ZW1zIGFyZSBlcXVpdmFsZW50LCB0aGUgbmV4dCBwcmVkaWNhdGUgaXMgdXNlZC4KICoKICogICAgSWYgdGhlIHByZWRpY2F0ZSBpcyBtaXNzaW5nIG9yIGVtcHR5IHRoZW4gaXQgZGVmYXVsdHMgdG8gYCcrJ2AuCiAqCiAqIEBwYXJhbSB7Ym9vbGVhbj19IHJldmVyc2UgUmV2ZXJzZSB0aGUgb3JkZXIgb2YgdGhlIGFycmF5LgogKiBAcmV0dXJucyB7QXJyYXl9IFNvcnRlZCBjb3B5IG9mIHRoZSBzb3VyY2UgYXJyYXkuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG1vZHVsZT0ib3JkZXJCeUV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNjcmlwdD4KICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ29yZGVyQnlFeGFtcGxlJywgW10pCiAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICRzY29wZS5mcmllbmRzID0KICAgICAgICAgICAgICAgICBbe25hbWU6J0pvaG4nLCBwaG9uZTonNTU1LTEyMTInLCBhZ2U6MTB9LAogICAgICAgICAgICAgICAgICB7bmFtZTonTWFyeScsIHBob25lOic1NTUtOTg3NicsIGFnZToxOX0sCiAgICAgICAgICAgICAgICAgIHtuYW1lOidNaWtlJywgcGhvbmU6JzU1NS00MzIxJywgYWdlOjIxfSwKICAgICAgICAgICAgICAgICAge25hbWU6J0FkYW0nLCBwaG9uZTonNTU1LTU2NzgnLCBhZ2U6MzV9LAogICAgICAgICAgICAgICAgICB7bmFtZTonSnVsaWUnLCBwaG9uZTonNTU1LTg3NjUnLCBhZ2U6Mjl9XTsKICAgICAgICAgICAgICRzY29wZS5wcmVkaWNhdGUgPSAnLWFnZSc7CiAgICAgICAgICAgfV0pOwogICAgICAgPC9zY3JpcHQ+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICAgPHByZT5Tb3J0aW5nIHByZWRpY2F0ZSA9IHt7cHJlZGljYXRlfX07IHJldmVyc2UgPSB7e3JldmVyc2V9fTwvcHJlPgogICAgICAgICA8aHIvPgogICAgICAgICBbIDxhIGhyZWY9IiIgbmctY2xpY2s9InByZWRpY2F0ZT0nJyI+dW5zb3J0ZWQ8L2E+IF0KICAgICAgICAgPHRhYmxlIGNsYXNzPSJmcmllbmQiPgogICAgICAgICAgIDx0cj4KICAgICAgICAgICAgIDx0aD48YSBocmVmPSIiIG5nLWNsaWNrPSJwcmVkaWNhdGUgPSAnbmFtZSc7IHJldmVyc2U9ZmFsc2UiPk5hbWU8L2E+CiAgICAgICAgICAgICAgICAgKDxhIGhyZWY9IiIgbmctY2xpY2s9InByZWRpY2F0ZSA9ICctbmFtZSc7IHJldmVyc2U9ZmFsc2UiPl48L2E+KTwvdGg+CiAgICAgICAgICAgICA8dGg+PGEgaHJlZj0iIiBuZy1jbGljaz0icHJlZGljYXRlID0gJ3Bob25lJzsgcmV2ZXJzZT0hcmV2ZXJzZSI+UGhvbmUgTnVtYmVyPC9hPjwvdGg+CiAgICAgICAgICAgICA8dGg+PGEgaHJlZj0iIiBuZy1jbGljaz0icHJlZGljYXRlID0gJ2FnZSc7IHJldmVyc2U9IXJldmVyc2UiPkFnZTwvYT48L3RoPgogICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgPHRyIG5nLXJlcGVhdD0iZnJpZW5kIGluIGZyaWVuZHMgfCBvcmRlckJ5OnByZWRpY2F0ZTpyZXZlcnNlIj4KICAgICAgICAgICAgIDx0ZD57e2ZyaWVuZC5uYW1lfX08L3RkPgogICAgICAgICAgICAgPHRkPnt7ZnJpZW5kLnBob25lfX08L3RkPgogICAgICAgICAgICAgPHRkPnt7ZnJpZW5kLmFnZX19PC90ZD4KICAgICAgICAgICA8L3RyPgogICAgICAgICA8L3RhYmxlPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqCiAqIEl0J3MgYWxzbyBwb3NzaWJsZSB0byBjYWxsIHRoZSBvcmRlckJ5IGZpbHRlciBtYW51YWxseSwgYnkgaW5qZWN0aW5nIGAkZmlsdGVyYCwgcmV0cmlldmluZyB0aGUKICogZmlsdGVyIHJvdXRpbmUgd2l0aCBgJGZpbHRlcignb3JkZXJCeScpYCwgYW5kIGNhbGxpbmcgdGhlIHJldHVybmVkIGZpbHRlciByb3V0aW5lIHdpdGggdGhlCiAqIGRlc2lyZWQgcGFyYW1ldGVycy4KICoKICogRXhhbXBsZToKICoKICogQGV4YW1wbGUKICA8ZXhhbXBsZSBtb2R1bGU9Im9yZGVyQnlFeGFtcGxlIj4KICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICA8dGFibGUgY2xhc3M9ImZyaWVuZCI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0aD48YSBocmVmPSIiIG5nLWNsaWNrPSJyZXZlcnNlPWZhbHNlO29yZGVyKCduYW1lJywgZmFsc2UpIj5OYW1lPC9hPgogICAgICAgICAgICAgICg8YSBocmVmPSIiIG5nLWNsaWNrPSJvcmRlcignLW5hbWUnLGZhbHNlKSI+XjwvYT4pPC90aD4KICAgICAgICAgICAgPHRoPjxhIGhyZWY9IiIgbmctY2xpY2s9InJldmVyc2U9IXJldmVyc2U7b3JkZXIoJ3Bob25lJywgcmV2ZXJzZSkiPlBob25lIE51bWJlcjwvYT48L3RoPgogICAgICAgICAgICA8dGg+PGEgaHJlZj0iIiBuZy1jbGljaz0icmV2ZXJzZT0hcmV2ZXJzZTtvcmRlcignYWdlJyxyZXZlcnNlKSI+QWdlPC9hPjwvdGg+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyIG5nLXJlcGVhdD0iZnJpZW5kIGluIGZyaWVuZHMiPgogICAgICAgICAgICA8dGQ+e3tmcmllbmQubmFtZX19PC90ZD4KICAgICAgICAgICAgPHRkPnt7ZnJpZW5kLnBob25lfX08L3RkPgogICAgICAgICAgICA8dGQ+e3tmcmllbmQuYWdlfX08L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Rpdj4KICAgIDwvZmlsZT4KCiAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICBhbmd1bGFyLm1vZHVsZSgnb3JkZXJCeUV4YW1wbGUnLCBbXSkKICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsICckZmlsdGVyJywgZnVuY3Rpb24oJHNjb3BlLCAkZmlsdGVyKSB7CiAgICAgICAgICB2YXIgb3JkZXJCeSA9ICRmaWx0ZXIoJ29yZGVyQnknKTsKICAgICAgICAgICRzY29wZS5mcmllbmRzID0gWwogICAgICAgICAgICB7IG5hbWU6ICdKb2huJywgICAgcGhvbmU6ICc1NTUtMTIxMicsICAgIGFnZTogMTAgfSwKICAgICAgICAgICAgeyBuYW1lOiAnTWFyeScsICAgIHBob25lOiAnNTU1LTk4NzYnLCAgICBhZ2U6IDE5IH0sCiAgICAgICAgICAgIHsgbmFtZTogJ01pa2UnLCAgICBwaG9uZTogJzU1NS00MzIxJywgICAgYWdlOiAyMSB9LAogICAgICAgICAgICB7IG5hbWU6ICdBZGFtJywgICAgcGhvbmU6ICc1NTUtNTY3OCcsICAgIGFnZTogMzUgfSwKICAgICAgICAgICAgeyBuYW1lOiAnSnVsaWUnLCAgIHBob25lOiAnNTU1LTg3NjUnLCAgICBhZ2U6IDI5IH0KICAgICAgICAgIF07CiAgICAgICAgICAkc2NvcGUub3JkZXIgPSBmdW5jdGlvbihwcmVkaWNhdGUsIHJldmVyc2UpIHsKICAgICAgICAgICAgJHNjb3BlLmZyaWVuZHMgPSBvcmRlckJ5KCRzY29wZS5mcmllbmRzLCBwcmVkaWNhdGUsIHJldmVyc2UpOwogICAgICAgICAgfTsKICAgICAgICAgICRzY29wZS5vcmRlcignLWFnZScsZmFsc2UpOwogICAgICAgIH1dKTsKICAgIDwvZmlsZT4KPC9leGFtcGxlPgogKi8Kb3JkZXJCeUZpbHRlci4kaW5qZWN0ID0gWyckcGFyc2UnXTsKZnVuY3Rpb24gb3JkZXJCeUZpbHRlcigkcGFyc2UpIHsKICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIHNvcnRQcmVkaWNhdGUsIHJldmVyc2VPcmRlcikgewogICAgaWYgKCEoaXNBcnJheUxpa2UoYXJyYXkpKSkgcmV0dXJuIGFycmF5OwogICAgc29ydFByZWRpY2F0ZSA9IGlzQXJyYXkoc29ydFByZWRpY2F0ZSkgPyBzb3J0UHJlZGljYXRlIDogW3NvcnRQcmVkaWNhdGVdOwogICAgaWYgKHNvcnRQcmVkaWNhdGUubGVuZ3RoID09PSAwKSB7IHNvcnRQcmVkaWNhdGUgPSBbJysnXTsgfQogICAgc29ydFByZWRpY2F0ZSA9IHNvcnRQcmVkaWNhdGUubWFwKGZ1bmN0aW9uKHByZWRpY2F0ZSkgewogICAgICB2YXIgZGVzY2VuZGluZyA9IGZhbHNlLCBnZXQgPSBwcmVkaWNhdGUgfHwgaWRlbnRpdHk7CiAgICAgIGlmIChpc1N0cmluZyhwcmVkaWNhdGUpKSB7CiAgICAgICAgaWYgKChwcmVkaWNhdGUuY2hhckF0KDApID09ICcrJyB8fCBwcmVkaWNhdGUuY2hhckF0KDApID09ICctJykpIHsKICAgICAgICAgIGRlc2NlbmRpbmcgPSBwcmVkaWNhdGUuY2hhckF0KDApID09ICctJzsKICAgICAgICAgIHByZWRpY2F0ZSA9IHByZWRpY2F0ZS5zdWJzdHJpbmcoMSk7CiAgICAgICAgfQogICAgICAgIGlmIChwcmVkaWNhdGUgPT09ICcnKSB7CiAgICAgICAgICAvLyBFZmZlY3RpdmVseSBubyBwcmVkaWNhdGUgd2FzIHBhc3NlZCBzbyB3ZSBjb21wYXJlIGlkZW50aXR5CiAgICAgICAgICByZXR1cm4gcmV2ZXJzZUNvbXBhcmF0b3IoY29tcGFyZSwgZGVzY2VuZGluZyk7CiAgICAgICAgfQogICAgICAgIGdldCA9ICRwYXJzZShwcmVkaWNhdGUpOwogICAgICAgIGlmIChnZXQuY29uc3RhbnQpIHsKICAgICAgICAgIHZhciBrZXkgPSBnZXQoKTsKICAgICAgICAgIHJldHVybiByZXZlcnNlQ29tcGFyYXRvcihmdW5jdGlvbihhLCBiKSB7CiAgICAgICAgICAgIHJldHVybiBjb21wYXJlKGFba2V5XSwgYltrZXldKTsKICAgICAgICAgIH0sIGRlc2NlbmRpbmcpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcmV2ZXJzZUNvbXBhcmF0b3IoZnVuY3Rpb24oYSwgYikgewogICAgICAgIHJldHVybiBjb21wYXJlKGdldChhKSxnZXQoYikpOwogICAgICB9LCBkZXNjZW5kaW5nKTsKICAgIH0pOwogICAgcmV0dXJuIHNsaWNlLmNhbGwoYXJyYXkpLnNvcnQocmV2ZXJzZUNvbXBhcmF0b3IoY29tcGFyYXRvciwgcmV2ZXJzZU9yZGVyKSk7CgogICAgZnVuY3Rpb24gY29tcGFyYXRvcihvMSwgbzIpIHsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3J0UHJlZGljYXRlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGNvbXAgPSBzb3J0UHJlZGljYXRlW2ldKG8xLCBvMik7CiAgICAgICAgaWYgKGNvbXAgIT09IDApIHJldHVybiBjb21wOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQogICAgZnVuY3Rpb24gcmV2ZXJzZUNvbXBhcmF0b3IoY29tcCwgZGVzY2VuZGluZykgewogICAgICByZXR1cm4gZGVzY2VuZGluZwogICAgICAgICAgPyBmdW5jdGlvbihhLCBiKSB7cmV0dXJuIGNvbXAoYixhKTt9CiAgICAgICAgICA6IGNvbXA7CiAgICB9CgogICAgZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWUpIHsKICAgICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHsKICAgICAgICBjYXNlICdudW1iZXInOiAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSAnYm9vbGVhbic6IC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlICdzdHJpbmcnOgogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuICdudWxsJzsKICAgICAgaWYgKHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgdmFsdWUgPSB2YWx1ZS52YWx1ZU9mKCk7CiAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkgcmV0dXJuIHZhbHVlOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgdmFsdWUudG9TdHJpbmcgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7CiAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbHVlKSkgcmV0dXJuIHZhbHVlOwogICAgICB9CiAgICAgIHJldHVybiAnJzsKICAgIH0KCiAgICBmdW5jdGlvbiBjb21wYXJlKHYxLCB2MikgewogICAgICB2YXIgdDEgPSB0eXBlb2YgdjE7CiAgICAgIHZhciB0MiA9IHR5cGVvZiB2MjsKICAgICAgaWYgKHQxID09PSB0MiAmJiB0MSA9PT0gIm9iamVjdCIpIHsKICAgICAgICB2MSA9IG9iamVjdFRvU3RyaW5nKHYxKTsKICAgICAgICB2MiA9IG9iamVjdFRvU3RyaW5nKHYyKTsKICAgICAgfQogICAgICBpZiAodDEgPT09IHQyKSB7CiAgICAgICAgaWYgKHQxID09PSAic3RyaW5nIikgewogICAgICAgICAgIHYxID0gdjEudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICB2MiA9IHYyLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgfQogICAgICAgIGlmICh2MSA9PT0gdjIpIHJldHVybiAwOwogICAgICAgIHJldHVybiB2MSA8IHYyID8gLTEgOiAxOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB0MSA8IHQyID8gLTEgOiAxOwogICAgICB9CiAgICB9CiAgfTsKfQoKZnVuY3Rpb24gbmdEaXJlY3RpdmUoZGlyZWN0aXZlKSB7CiAgaWYgKGlzRnVuY3Rpb24oZGlyZWN0aXZlKSkgewogICAgZGlyZWN0aXZlID0gewogICAgICBsaW5rOiBkaXJlY3RpdmUKICAgIH07CiAgfQogIGRpcmVjdGl2ZS5yZXN0cmljdCA9IGRpcmVjdGl2ZS5yZXN0cmljdCB8fCAnQUMnOwogIHJldHVybiB2YWx1ZUZuKGRpcmVjdGl2ZSk7Cn0KCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIGEKICogQHJlc3RyaWN0IEUKICoKICogQGRlc2NyaXB0aW9uCiAqIE1vZGlmaWVzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoZSBodG1sIEEgdGFnIHNvIHRoYXQgdGhlIGRlZmF1bHQgYWN0aW9uIGlzIHByZXZlbnRlZCB3aGVuCiAqIHRoZSBocmVmIGF0dHJpYnV0ZSBpcyBlbXB0eS4KICoKICogVGhpcyBjaGFuZ2UgcGVybWl0cyB0aGUgZWFzeSBjcmVhdGlvbiBvZiBhY3Rpb24gbGlua3Mgd2l0aCB0aGUgYG5nQ2xpY2tgIGRpcmVjdGl2ZQogKiB3aXRob3V0IGNoYW5naW5nIHRoZSBsb2NhdGlvbiBvciBjYXVzaW5nIHBhZ2UgcmVsb2FkcywgZS5nLjoKICogYDxhIGhyZWY9IiIgbmctY2xpY2s9Imxpc3QuYWRkSXRlbSgpIj5BZGQgSXRlbTwvYT5gCiAqLwp2YXIgaHRtbEFuY2hvckRpcmVjdGl2ZSA9IHZhbHVlRm4oewogIHJlc3RyaWN0OiAnRScsCiAgY29tcGlsZTogZnVuY3Rpb24oZWxlbWVudCwgYXR0cikgewogICAgaWYgKCFhdHRyLmhyZWYgJiYgIWF0dHIueGxpbmtIcmVmICYmICFhdHRyLm5hbWUpIHsKICAgICAgcmV0dXJuIGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50KSB7CiAgICAgICAgLy8gU1ZHQUVsZW1lbnQgZG9lcyBub3QgdXNlIHRoZSBocmVmIGF0dHJpYnV0ZSwgYnV0IHJhdGhlciB0aGUgJ3hsaW5rSHJlZicgYXR0cmlidXRlLgogICAgICAgIHZhciBocmVmID0gdG9TdHJpbmcuY2FsbChlbGVtZW50LnByb3AoJ2hyZWYnKSkgPT09ICdbb2JqZWN0IFNWR0FuaW1hdGVkU3RyaW5nXScgPwogICAgICAgICAgICAgICAgICAgJ3hsaW5rOmhyZWYnIDogJ2hyZWYnOwogICAgICAgIGVsZW1lbnQub24oJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgIC8vIGlmIHdlIGhhdmUgbm8gaHJlZiB1cmwsIHRoZW4gZG9uJ3QgbmF2aWdhdGUgYW55d2hlcmUuCiAgICAgICAgICBpZiAoIWVsZW1lbnQuYXR0cihocmVmKSkgewogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9OwogICAgfQogIH0KfSk7CgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0hyZWYKICogQHJlc3RyaWN0IEEKICogQHByaW9yaXR5IDk5CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBVc2luZyBBbmd1bGFyIG1hcmt1cCBsaWtlIGB7e2hhc2h9fWAgaW4gYW4gaHJlZiBhdHRyaWJ1dGUgd2lsbAogKiBtYWtlIHRoZSBsaW5rIGdvIHRvIHRoZSB3cm9uZyBVUkwgaWYgdGhlIHVzZXIgY2xpY2tzIGl0IGJlZm9yZQogKiBBbmd1bGFyIGhhcyBhIGNoYW5jZSB0byByZXBsYWNlIHRoZSBge3toYXNofX1gIG1hcmt1cCB3aXRoIGl0cwogKiB2YWx1ZS4gVW50aWwgQW5ndWxhciByZXBsYWNlcyB0aGUgbWFya3VwIHRoZSBsaW5rIHdpbGwgYmUgYnJva2VuCiAqIGFuZCB3aWxsIG1vc3QgbGlrZWx5IHJldHVybiBhIDQwNCBlcnJvci4gVGhlIGBuZ0hyZWZgIGRpcmVjdGl2ZQogKiBzb2x2ZXMgdGhpcyBwcm9ibGVtLgogKgogKiBUaGUgd3Jvbmcgd2F5IHRvIHdyaXRlIGl0OgogKiBgYGBodG1sCiAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ3JhdmF0YXIuY29tL2F2YXRhci97e2hhc2h9fSI+bGluazE8L2E+CiAqIGBgYAogKgogKiBUaGUgY29ycmVjdCB3YXkgdG8gd3JpdGUgaXQ6CiAqIGBgYGh0bWwKICogPGEgbmctaHJlZj0iaHR0cDovL3d3dy5ncmF2YXRhci5jb20vYXZhdGFyL3t7aGFzaH19Ij5saW5rMTwvYT4KICogYGBgCiAqCiAqIEBlbGVtZW50IEEKICogQHBhcmFtIHt0ZW1wbGF0ZX0gbmdIcmVmIGFueSBzdHJpbmcgd2hpY2ggY2FuIGNvbnRhaW4gYHt7fX1gIG1hcmt1cC4KICoKICogQGV4YW1wbGUKICogVGhpcyBleGFtcGxlIHNob3dzIHZhcmlvdXMgY29tYmluYXRpb25zIG9mIGBocmVmYCwgYG5nLWhyZWZgIGFuZCBgbmctY2xpY2tgIGF0dHJpYnV0ZXMKICogaW4gbGlua3MgYW5kIHRoZWlyIGRpZmZlcmVudCBiZWhhdmlvcnM6CiAgICA8ZXhhbXBsZT4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgPGlucHV0IG5nLW1vZGVsPSJ2YWx1ZSIgLz48YnIgLz4KICAgICAgICA8YSBpZD0ibGluay0xIiBocmVmIG5nLWNsaWNrPSJ2YWx1ZSA9IDEiPmxpbmsgMTwvYT4gKGxpbmssIGRvbid0IHJlbG9hZCk8YnIgLz4KICAgICAgICA8YSBpZD0ibGluay0yIiBocmVmPSIiIG5nLWNsaWNrPSJ2YWx1ZSA9IDIiPmxpbmsgMjwvYT4gKGxpbmssIGRvbid0IHJlbG9hZCk8YnIgLz4KICAgICAgICA8YSBpZD0ibGluay0zIiBuZy1ocmVmPSIve3snMTIzJ319Ij5saW5rIDM8L2E+IChsaW5rLCByZWxvYWQhKTxiciAvPgogICAgICAgIDxhIGlkPSJsaW5rLTQiIGhyZWY9IiIgbmFtZT0ieHgiIG5nLWNsaWNrPSJ2YWx1ZSA9IDQiPmFuY2hvcjwvYT4gKGxpbmssIGRvbid0IHJlbG9hZCk8YnIgLz4KICAgICAgICA8YSBpZD0ibGluay01IiBuYW1lPSJ4eHgiIG5nLWNsaWNrPSJ2YWx1ZSA9IDUiPmFuY2hvcjwvYT4gKG5vIGxpbmspPGJyIC8+CiAgICAgICAgPGEgaWQ9ImxpbmstNiIgbmctaHJlZj0ie3t2YWx1ZX19Ij5saW5rPC9hPiAobGluaywgY2hhbmdlIGxvY2F0aW9uKQogICAgICA8L2ZpbGU+CiAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgIGl0KCdzaG91bGQgZXhlY3V0ZSBuZy1jbGljayBidXQgbm90IHJlbG9hZCB3aGVuIGhyZWYgd2l0aG91dCB2YWx1ZScsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZWxlbWVudChieS5pZCgnbGluay0xJykpLmNsaWNrKCk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5tb2RlbCgndmFsdWUnKSkuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKS50b0VxdWFsKCcxJyk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnbGluay0xJykpLmdldEF0dHJpYnV0ZSgnaHJlZicpKS50b0JlKCcnKTsKICAgICAgICB9KTsKCiAgICAgICAgaXQoJ3Nob3VsZCBleGVjdXRlIG5nLWNsaWNrIGJ1dCBub3QgcmVsb2FkIHdoZW4gaHJlZiBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIGVsZW1lbnQoYnkuaWQoJ2xpbmstMicpKS5jbGljaygpOwogICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkubW9kZWwoJ3ZhbHVlJykpLmdldEF0dHJpYnV0ZSgndmFsdWUnKSkudG9FcXVhbCgnMicpOwogICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2xpbmstMicpKS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSkudG9CZSgnJyk7CiAgICAgICAgfSk7CgogICAgICAgIGl0KCdzaG91bGQgZXhlY3V0ZSBuZy1jbGljayBhbmQgY2hhbmdlIHVybCB3aGVuIG5nLWhyZWYgc3BlY2lmaWVkJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnbGluay0zJykpLmdldEF0dHJpYnV0ZSgnaHJlZicpKS50b01hdGNoKC9cLzEyMyQvKTsKCiAgICAgICAgICBlbGVtZW50KGJ5LmlkKCdsaW5rLTMnKSkuY2xpY2soKTsKCiAgICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBuYXZpZ2F0ZSBhd2F5IGZyb20gYW4gQW5ndWxhciBwYWdlLCBzbyB3ZSBuZWVkCiAgICAgICAgICAvLyB0byB1c2UgYnJvd3Nlci5kcml2ZXIgdG8gZ2V0IHRoZSBiYXNlIHdlYmRyaXZlci4KCiAgICAgICAgICBicm93c2VyLndhaXQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBicm93c2VyLmRyaXZlci5nZXRDdXJyZW50VXJsKCkudGhlbihmdW5jdGlvbih1cmwpIHsKICAgICAgICAgICAgICByZXR1cm4gdXJsLm1hdGNoKC9cLzEyMyQvKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9LCA1MDAwLCAncGFnZSBzaG91bGQgbmF2aWdhdGUgdG8gLzEyMycpOwogICAgICAgIH0pOwoKICAgICAgICB4aXQoJ3Nob3VsZCBleGVjdXRlIG5nLWNsaWNrIGJ1dCBub3QgcmVsb2FkIHdoZW4gaHJlZiBlbXB0eSBzdHJpbmcgYW5kIG5hbWUgc3BlY2lmaWVkJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBlbGVtZW50KGJ5LmlkKCdsaW5rLTQnKSkuY2xpY2soKTsKICAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKS5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpLnRvRXF1YWwoJzQnKTsKICAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmlkKCdsaW5rLTQnKSkuZ2V0QXR0cmlidXRlKCdocmVmJykpLnRvQmUoJycpOwogICAgICAgIH0pOwoKICAgICAgICBpdCgnc2hvdWxkIGV4ZWN1dGUgbmctY2xpY2sgYnV0IG5vdCByZWxvYWQgd2hlbiBubyBocmVmIGJ1dCBuYW1lIHNwZWNpZmllZCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZWxlbWVudChieS5pZCgnbGluay01JykpLmNsaWNrKCk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5tb2RlbCgndmFsdWUnKSkuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKS50b0VxdWFsKCc1Jyk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnbGluay01JykpLmdldEF0dHJpYnV0ZSgnaHJlZicpKS50b0JlKG51bGwpOwogICAgICAgIH0pOwoKICAgICAgICBpdCgnc2hvdWxkIG9ubHkgY2hhbmdlIHVybCB3aGVuIG9ubHkgbmctaHJlZicsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZWxlbWVudChieS5tb2RlbCgndmFsdWUnKSkuY2xlYXIoKTsKICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3ZhbHVlJykpLnNlbmRLZXlzKCc2Jyk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnbGluay02JykpLmdldEF0dHJpYnV0ZSgnaHJlZicpKS50b01hdGNoKC9cLzYkLyk7CgogICAgICAgICAgZWxlbWVudChieS5pZCgnbGluay02JykpLmNsaWNrKCk7CgogICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgbmF2aWdhdGUgYXdheSBmcm9tIGFuIEFuZ3VsYXIgcGFnZSwgc28gd2UgbmVlZAogICAgICAgICAgLy8gdG8gdXNlIGJyb3dzZXIuZHJpdmVyIHRvIGdldCB0aGUgYmFzZSB3ZWJkcml2ZXIuCiAgICAgICAgICBicm93c2VyLndhaXQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBicm93c2VyLmRyaXZlci5nZXRDdXJyZW50VXJsKCkudGhlbihmdW5jdGlvbih1cmwpIHsKICAgICAgICAgICAgICByZXR1cm4gdXJsLm1hdGNoKC9cLzYkLyk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSwgNTAwMCwgJ3BhZ2Ugc2hvdWxkIG5hdmlnYXRlIHRvIC82Jyk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICovCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ1NyYwogKiBAcmVzdHJpY3QgQQogKiBAcHJpb3JpdHkgOTkKICoKICogQGRlc2NyaXB0aW9uCiAqIFVzaW5nIEFuZ3VsYXIgbWFya3VwIGxpa2UgYHt7aGFzaH19YCBpbiBhIGBzcmNgIGF0dHJpYnV0ZSBkb2Vzbid0CiAqIHdvcmsgcmlnaHQ6IFRoZSBicm93c2VyIHdpbGwgZmV0Y2ggZnJvbSB0aGUgVVJMIHdpdGggdGhlIGxpdGVyYWwKICogdGV4dCBge3toYXNofX1gIHVudGlsIEFuZ3VsYXIgcmVwbGFjZXMgdGhlIGV4cHJlc3Npb24gaW5zaWRlCiAqIGB7e2hhc2h9fWAuIFRoZSBgbmdTcmNgIGRpcmVjdGl2ZSBzb2x2ZXMgdGhpcyBwcm9ibGVtLgogKgogKiBUaGUgYnVnZ3kgd2F5IHRvIHdyaXRlIGl0OgogKiBgYGBodG1sCiAqIDxpbWcgc3JjPSJodHRwOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIve3toYXNofX0iLz4KICogYGBgCiAqCiAqIFRoZSBjb3JyZWN0IHdheSB0byB3cml0ZSBpdDoKICogYGBgaHRtbAogKiA8aW1nIG5nLXNyYz0iaHR0cDovL3d3dy5ncmF2YXRhci5jb20vYXZhdGFyL3t7aGFzaH19Ii8+CiAqIGBgYAogKgogKiBAZWxlbWVudCBJTUcKICogQHBhcmFtIHt0ZW1wbGF0ZX0gbmdTcmMgYW55IHN0cmluZyB3aGljaCBjYW4gY29udGFpbiBge3t9fWAgbWFya3VwLgogKi8KCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nU3Jjc2V0CiAqIEByZXN0cmljdCBBCiAqIEBwcmlvcml0eSA5OQogKgogKiBAZGVzY3JpcHRpb24KICogVXNpbmcgQW5ndWxhciBtYXJrdXAgbGlrZSBge3toYXNofX1gIGluIGEgYHNyY3NldGAgYXR0cmlidXRlIGRvZXNuJ3QKICogd29yayByaWdodDogVGhlIGJyb3dzZXIgd2lsbCBmZXRjaCBmcm9tIHRoZSBVUkwgd2l0aCB0aGUgbGl0ZXJhbAogKiB0ZXh0IGB7e2hhc2h9fWAgdW50aWwgQW5ndWxhciByZXBsYWNlcyB0aGUgZXhwcmVzc2lvbiBpbnNpZGUKICogYHt7aGFzaH19YC4gVGhlIGBuZ1NyY3NldGAgZGlyZWN0aXZlIHNvbHZlcyB0aGlzIHByb2JsZW0uCiAqCiAqIFRoZSBidWdneSB3YXkgdG8gd3JpdGUgaXQ6CiAqIGBgYGh0bWwKICogPGltZyBzcmNzZXQ9Imh0dHA6Ly93d3cuZ3JhdmF0YXIuY29tL2F2YXRhci97e2hhc2h9fSAyeCIvPgogKiBgYGAKICoKICogVGhlIGNvcnJlY3Qgd2F5IHRvIHdyaXRlIGl0OgogKiBgYGBodG1sCiAqIDxpbWcgbmctc3Jjc2V0PSJodHRwOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIve3toYXNofX0gMngiLz4KICogYGBgCiAqCiAqIEBlbGVtZW50IElNRwogKiBAcGFyYW0ge3RlbXBsYXRlfSBuZ1NyY3NldCBhbnkgc3RyaW5nIHdoaWNoIGNhbiBjb250YWluIGB7e319YCBtYXJrdXAuCiAqLwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdEaXNhYmxlZAogKiBAcmVzdHJpY3QgQQogKiBAcHJpb3JpdHkgMTAwCiAqCiAqIEBkZXNjcmlwdGlvbgogKgogKiBXZSBzaG91bGRuJ3QgZG8gdGhpcywgYmVjYXVzZSBpdCB3aWxsIG1ha2UgdGhlIGJ1dHRvbiBlbmFibGVkIG9uIENocm9tZS9GaXJlZm94IGJ1dCBub3Qgb24gSUU4IGFuZCBvbGRlciBJRXM6CiAqIGBgYGh0bWwKICogPGRpdiBuZy1pbml0PSJzY29wZSA9IHsgaXNEaXNhYmxlZDogZmFsc2UgfSI+CiAqICA8YnV0dG9uIGRpc2FibGVkPSJ7e3Njb3BlLmlzRGlzYWJsZWR9fSI+RGlzYWJsZWQ8L2J1dHRvbj4KICogPC9kaXY+CiAqIGBgYAogKgogKiBUaGUgSFRNTCBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IHJlcXVpcmUgYnJvd3NlcnMgdG8gcHJlc2VydmUgdGhlIHZhbHVlcyBvZiBib29sZWFuIGF0dHJpYnV0ZXMKICogc3VjaCBhcyBkaXNhYmxlZC4gKFRoZWlyIHByZXNlbmNlIG1lYW5zIHRydWUgYW5kIHRoZWlyIGFic2VuY2UgbWVhbnMgZmFsc2UuKQogKiBJZiB3ZSBwdXQgYW4gQW5ndWxhciBpbnRlcnBvbGF0aW9uIGV4cHJlc3Npb24gaW50byBzdWNoIGFuIGF0dHJpYnV0ZSB0aGVuIHRoZQogKiBiaW5kaW5nIGluZm9ybWF0aW9uIHdvdWxkIGJlIGxvc3Qgd2hlbiB0aGUgYnJvd3NlciByZW1vdmVzIHRoZSBhdHRyaWJ1dGUuCiAqIFRoZSBgbmdEaXNhYmxlZGAgZGlyZWN0aXZlIHNvbHZlcyB0aGlzIHByb2JsZW0gZm9yIHRoZSBgZGlzYWJsZWRgIGF0dHJpYnV0ZS4KICogVGhpcyBjb21wbGVtZW50YXJ5IGRpcmVjdGl2ZSBpcyBub3QgcmVtb3ZlZCBieSB0aGUgYnJvd3NlciBhbmQgc28gcHJvdmlkZXMKICogYSBwZXJtYW5lbnQgcmVsaWFibGUgcGxhY2UgdG8gc3RvcmUgdGhlIGJpbmRpbmcgaW5mb3JtYXRpb24uCiAqCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZT4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgQ2xpY2sgbWUgdG8gdG9nZ2xlOiA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJjaGVja2VkIj48YnIvPgogICAgICAgIDxidXR0b24gbmctbW9kZWw9ImJ1dHRvbiIgbmctZGlzYWJsZWQ9ImNoZWNrZWQiPkJ1dHRvbjwvYnV0dG9uPgogICAgICA8L2ZpbGU+CiAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgIGl0KCdzaG91bGQgdG9nZ2xlIGJ1dHRvbicsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuY3NzKCdidXR0b24nKSkuZ2V0QXR0cmlidXRlKCdkaXNhYmxlZCcpKS50b0JlRmFsc3koKTsKICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ2NoZWNrZWQnKSkuY2xpY2soKTsKICAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmNzcygnYnV0dG9uJykpLmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSkudG9CZVRydXRoeSgpOwogICAgICAgIH0pOwogICAgICA8L2ZpbGU+CiAgICA8L2V4YW1wbGU+CiAqCiAqIEBlbGVtZW50IElOUFVUCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdEaXNhYmxlZCBJZiB0aGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgdHJ1dGh5LAogKiAgICAgdGhlbiBzcGVjaWFsIGF0dHJpYnV0ZSAiZGlzYWJsZWQiIHdpbGwgYmUgc2V0IG9uIHRoZSBlbGVtZW50CiAqLwoKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQ2hlY2tlZAogKiBAcmVzdHJpY3QgQQogKiBAcHJpb3JpdHkgMTAwCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgSFRNTCBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IHJlcXVpcmUgYnJvd3NlcnMgdG8gcHJlc2VydmUgdGhlIHZhbHVlcyBvZiBib29sZWFuIGF0dHJpYnV0ZXMKICogc3VjaCBhcyBjaGVja2VkLiAoVGhlaXIgcHJlc2VuY2UgbWVhbnMgdHJ1ZSBhbmQgdGhlaXIgYWJzZW5jZSBtZWFucyBmYWxzZS4pCiAqIElmIHdlIHB1dCBhbiBBbmd1bGFyIGludGVycG9sYXRpb24gZXhwcmVzc2lvbiBpbnRvIHN1Y2ggYW4gYXR0cmlidXRlIHRoZW4gdGhlCiAqIGJpbmRpbmcgaW5mb3JtYXRpb24gd291bGQgYmUgbG9zdCB3aGVuIHRoZSBicm93c2VyIHJlbW92ZXMgdGhlIGF0dHJpYnV0ZS4KICogVGhlIGBuZ0NoZWNrZWRgIGRpcmVjdGl2ZSBzb2x2ZXMgdGhpcyBwcm9ibGVtIGZvciB0aGUgYGNoZWNrZWRgIGF0dHJpYnV0ZS4KICogVGhpcyBjb21wbGVtZW50YXJ5IGRpcmVjdGl2ZSBpcyBub3QgcmVtb3ZlZCBieSB0aGUgYnJvd3NlciBhbmQgc28gcHJvdmlkZXMKICogYSBwZXJtYW5lbnQgcmVsaWFibGUgcGxhY2UgdG8gc3RvcmUgdGhlIGJpbmRpbmcgaW5mb3JtYXRpb24uCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZT4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgQ2hlY2sgbWUgdG8gY2hlY2sgYm90aDogPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0ibWFzdGVyIj48YnIvPgogICAgICAgIDxpbnB1dCBpZD0iY2hlY2tTbGF2ZSIgdHlwZT0iY2hlY2tib3giIG5nLWNoZWNrZWQ9Im1hc3RlciI+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgaXQoJ3Nob3VsZCBjaGVjayBib3RoIGNoZWNrQm94ZXMnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmlkKCdjaGVja1NsYXZlJykpLmdldEF0dHJpYnV0ZSgnY2hlY2tlZCcpKS50b0JlRmFsc3koKTsKICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ21hc3RlcicpKS5jbGljaygpOwogICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2NoZWNrU2xhdmUnKSkuZ2V0QXR0cmlidXRlKCdjaGVja2VkJykpLnRvQmVUcnV0aHkoKTsKICAgICAgICB9KTsKICAgICAgPC9maWxlPgogICAgPC9leGFtcGxlPgogKgogKiBAZWxlbWVudCBJTlBVVAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQ2hlY2tlZCBJZiB0aGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgdHJ1dGh5LAogKiAgICAgdGhlbiBzcGVjaWFsIGF0dHJpYnV0ZSAiY2hlY2tlZCIgd2lsbCBiZSBzZXQgb24gdGhlIGVsZW1lbnQKICovCgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdSZWFkb25seQogKiBAcmVzdHJpY3QgQQogKiBAcHJpb3JpdHkgMTAwCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgSFRNTCBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IHJlcXVpcmUgYnJvd3NlcnMgdG8gcHJlc2VydmUgdGhlIHZhbHVlcyBvZiBib29sZWFuIGF0dHJpYnV0ZXMKICogc3VjaCBhcyByZWFkb25seS4gKFRoZWlyIHByZXNlbmNlIG1lYW5zIHRydWUgYW5kIHRoZWlyIGFic2VuY2UgbWVhbnMgZmFsc2UuKQogKiBJZiB3ZSBwdXQgYW4gQW5ndWxhciBpbnRlcnBvbGF0aW9uIGV4cHJlc3Npb24gaW50byBzdWNoIGFuIGF0dHJpYnV0ZSB0aGVuIHRoZQogKiBiaW5kaW5nIGluZm9ybWF0aW9uIHdvdWxkIGJlIGxvc3Qgd2hlbiB0aGUgYnJvd3NlciByZW1vdmVzIHRoZSBhdHRyaWJ1dGUuCiAqIFRoZSBgbmdSZWFkb25seWAgZGlyZWN0aXZlIHNvbHZlcyB0aGlzIHByb2JsZW0gZm9yIHRoZSBgcmVhZG9ubHlgIGF0dHJpYnV0ZS4KICogVGhpcyBjb21wbGVtZW50YXJ5IGRpcmVjdGl2ZSBpcyBub3QgcmVtb3ZlZCBieSB0aGUgYnJvd3NlciBhbmQgc28gcHJvdmlkZXMKICogYSBwZXJtYW5lbnQgcmVsaWFibGUgcGxhY2UgdG8gc3RvcmUgdGhlIGJpbmRpbmcgaW5mb3JtYXRpb24uCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZT4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgQ2hlY2sgbWUgdG8gbWFrZSB0ZXh0IHJlYWRvbmx5OiA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJjaGVja2VkIj48YnIvPgogICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1yZWFkb25seT0iY2hlY2tlZCIgdmFsdWU9IkknbSBBbmd1bGFyIi8+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgaXQoJ3Nob3VsZCB0b2dnbGUgcmVhZG9ubHkgYXR0cicsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuY3NzKCdbdHlwZT0idGV4dCJdJykpLmdldEF0dHJpYnV0ZSgncmVhZG9ubHknKSkudG9CZUZhbHN5KCk7CiAgICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdjaGVja2VkJykpLmNsaWNrKCk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5jc3MoJ1t0eXBlPSJ0ZXh0Il0nKSkuZ2V0QXR0cmlidXRlKCdyZWFkb25seScpKS50b0JlVHJ1dGh5KCk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICoKICogQGVsZW1lbnQgSU5QVVQKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ1JlYWRvbmx5IElmIHRoZSB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufSBpcyB0cnV0aHksCiAqICAgICB0aGVuIHNwZWNpYWwgYXR0cmlidXRlICJyZWFkb25seSIgd2lsbCBiZSBzZXQgb24gdGhlIGVsZW1lbnQKICovCgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdTZWxlY3RlZAogKiBAcmVzdHJpY3QgQQogKiBAcHJpb3JpdHkgMTAwCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgSFRNTCBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IHJlcXVpcmUgYnJvd3NlcnMgdG8gcHJlc2VydmUgdGhlIHZhbHVlcyBvZiBib29sZWFuIGF0dHJpYnV0ZXMKICogc3VjaCBhcyBzZWxlY3RlZC4gKFRoZWlyIHByZXNlbmNlIG1lYW5zIHRydWUgYW5kIHRoZWlyIGFic2VuY2UgbWVhbnMgZmFsc2UuKQogKiBJZiB3ZSBwdXQgYW4gQW5ndWxhciBpbnRlcnBvbGF0aW9uIGV4cHJlc3Npb24gaW50byBzdWNoIGFuIGF0dHJpYnV0ZSB0aGVuIHRoZQogKiBiaW5kaW5nIGluZm9ybWF0aW9uIHdvdWxkIGJlIGxvc3Qgd2hlbiB0aGUgYnJvd3NlciByZW1vdmVzIHRoZSBhdHRyaWJ1dGUuCiAqIFRoZSBgbmdTZWxlY3RlZGAgZGlyZWN0aXZlIHNvbHZlcyB0aGlzIHByb2JsZW0gZm9yIHRoZSBgc2VsZWN0ZWRgIGF0dHJpYnV0ZS4KICogVGhpcyBjb21wbGVtZW50YXJ5IGRpcmVjdGl2ZSBpcyBub3QgcmVtb3ZlZCBieSB0aGUgYnJvd3NlciBhbmQgc28gcHJvdmlkZXMKICogYSBwZXJtYW5lbnQgcmVsaWFibGUgcGxhY2UgdG8gc3RvcmUgdGhlIGJpbmRpbmcgaW5mb3JtYXRpb24uCiAqCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZT4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgQ2hlY2sgbWUgdG8gc2VsZWN0OiA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJzZWxlY3RlZCI+PGJyLz4KICAgICAgICA8c2VsZWN0PgogICAgICAgICAgPG9wdGlvbj5IZWxsbyE8L29wdGlvbj4KICAgICAgICAgIDxvcHRpb24gaWQ9ImdyZWV0IiBuZy1zZWxlY3RlZD0ic2VsZWN0ZWQiPkdyZWV0aW5ncyE8L29wdGlvbj4KICAgICAgICA8L3NlbGVjdD4KICAgICAgPC9maWxlPgogICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgICBpdCgnc2hvdWxkIHNlbGVjdCBHcmVldGluZ3MhJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnZ3JlZXQnKSkuZ2V0QXR0cmlidXRlKCdzZWxlY3RlZCcpKS50b0JlRmFsc3koKTsKICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3NlbGVjdGVkJykpLmNsaWNrKCk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnZ3JlZXQnKSkuZ2V0QXR0cmlidXRlKCdzZWxlY3RlZCcpKS50b0JlVHJ1dGh5KCk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICoKICogQGVsZW1lbnQgT1BUSU9OCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdTZWxlY3RlZCBJZiB0aGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgdHJ1dGh5LAogKiAgICAgdGhlbiBzcGVjaWFsIGF0dHJpYnV0ZSAic2VsZWN0ZWQiIHdpbGwgYmUgc2V0IG9uIHRoZSBlbGVtZW50CiAqLwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdPcGVuCiAqIEByZXN0cmljdCBBCiAqIEBwcmlvcml0eSAxMDAKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBIVE1MIHNwZWNpZmljYXRpb24gZG9lcyBub3QgcmVxdWlyZSBicm93c2VycyB0byBwcmVzZXJ2ZSB0aGUgdmFsdWVzIG9mIGJvb2xlYW4gYXR0cmlidXRlcwogKiBzdWNoIGFzIG9wZW4uIChUaGVpciBwcmVzZW5jZSBtZWFucyB0cnVlIGFuZCB0aGVpciBhYnNlbmNlIG1lYW5zIGZhbHNlLikKICogSWYgd2UgcHV0IGFuIEFuZ3VsYXIgaW50ZXJwb2xhdGlvbiBleHByZXNzaW9uIGludG8gc3VjaCBhbiBhdHRyaWJ1dGUgdGhlbiB0aGUKICogYmluZGluZyBpbmZvcm1hdGlvbiB3b3VsZCBiZSBsb3N0IHdoZW4gdGhlIGJyb3dzZXIgcmVtb3ZlcyB0aGUgYXR0cmlidXRlLgogKiBUaGUgYG5nT3BlbmAgZGlyZWN0aXZlIHNvbHZlcyB0aGlzIHByb2JsZW0gZm9yIHRoZSBgb3BlbmAgYXR0cmlidXRlLgogKiBUaGlzIGNvbXBsZW1lbnRhcnkgZGlyZWN0aXZlIGlzIG5vdCByZW1vdmVkIGJ5IHRoZSBicm93c2VyIGFuZCBzbyBwcm92aWRlcwogKiBhIHBlcm1hbmVudCByZWxpYWJsZSBwbGFjZSB0byBzdG9yZSB0aGUgYmluZGluZyBpbmZvcm1hdGlvbi4KICogQGV4YW1wbGUKICAgICA8ZXhhbXBsZT4KICAgICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgICBDaGVjayBtZSBjaGVjayBtdWx0aXBsZTogPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0ib3BlbiI+PGJyLz4KICAgICAgICAgPGRldGFpbHMgaWQ9ImRldGFpbHMiIG5nLW9wZW49Im9wZW4iPgogICAgICAgICAgICA8c3VtbWFyeT5TaG93L0hpZGUgbWU8L3N1bW1hcnk+CiAgICAgICAgIDwvZGV0YWlscz4KICAgICAgIDwvZmlsZT4KICAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgICBpdCgnc2hvdWxkIHRvZ2dsZSBvcGVuJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuaWQoJ2RldGFpbHMnKSkuZ2V0QXR0cmlidXRlKCdvcGVuJykpLnRvQmVGYWxzeSgpOwogICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ29wZW4nKSkuY2xpY2soKTsKICAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5pZCgnZGV0YWlscycpKS5nZXRBdHRyaWJ1dGUoJ29wZW4nKSkudG9CZVRydXRoeSgpOwogICAgICAgICB9KTsKICAgICAgIDwvZmlsZT4KICAgICA8L2V4YW1wbGU+CiAqCiAqIEBlbGVtZW50IERFVEFJTFMKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ09wZW4gSWYgdGhlIHtAbGluayBndWlkZS9leHByZXNzaW9uIGV4cHJlc3Npb259IGlzIHRydXRoeSwKICogICAgIHRoZW4gc3BlY2lhbCBhdHRyaWJ1dGUgIm9wZW4iIHdpbGwgYmUgc2V0IG9uIHRoZSBlbGVtZW50CiAqLwoKdmFyIG5nQXR0cmlidXRlQWxpYXNEaXJlY3RpdmVzID0ge307CgoKLy8gYm9vbGVhbiBhdHRycyBhcmUgZXZhbHVhdGVkCmZvckVhY2goQk9PTEVBTl9BVFRSLCBmdW5jdGlvbihwcm9wTmFtZSwgYXR0ck5hbWUpIHsKICAvLyBiaW5kaW5nIHRvIG11bHRpcGxlIGlzIG5vdCBzdXBwb3J0ZWQKICBpZiAocHJvcE5hbWUgPT0gIm11bHRpcGxlIikgcmV0dXJuOwoKICB2YXIgbm9ybWFsaXplZCA9IGRpcmVjdGl2ZU5vcm1hbGl6ZSgnbmctJyArIGF0dHJOYW1lKTsKICBuZ0F0dHJpYnV0ZUFsaWFzRGlyZWN0aXZlc1tub3JtYWxpemVkXSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHsKICAgICAgcmVzdHJpY3Q6ICdBJywKICAgICAgcHJpb3JpdHk6IDEwMCwKICAgICAgbGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIpIHsKICAgICAgICBzY29wZS4kd2F0Y2goYXR0cltub3JtYWxpemVkXSwgZnVuY3Rpb24gbmdCb29sZWFuQXR0cldhdGNoQWN0aW9uKHZhbHVlKSB7CiAgICAgICAgICBhdHRyLiRzZXQoYXR0ck5hbWUsICEhdmFsdWUpOwogICAgICAgIH0pOwogICAgICB9CiAgICB9OwogIH07Cn0pOwoKLy8gYWxpYXNlZCBpbnB1dCBhdHRycyBhcmUgZXZhbHVhdGVkCmZvckVhY2goQUxJQVNFRF9BVFRSLCBmdW5jdGlvbihodG1sQXR0ciwgbmdBdHRyKSB7CiAgbmdBdHRyaWJ1dGVBbGlhc0RpcmVjdGl2ZXNbbmdBdHRyXSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHsKICAgICAgcHJpb3JpdHk6IDEwMCwKICAgICAgbGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIpIHsKICAgICAgICAvL3NwZWNpYWwgY2FzZSBuZ1BhdHRlcm4gd2hlbiBhIGxpdGVyYWwgcmVndWxhciBleHByZXNzaW9uIHZhbHVlCiAgICAgICAgLy9pcyB1c2VkIGFzIHRoZSBleHByZXNzaW9uICh0aGlzIHdheSB3ZSBkb24ndCBoYXZlIHRvIHdhdGNoIGFueXRoaW5nKS4KICAgICAgICBpZiAobmdBdHRyID09PSAibmdQYXR0ZXJuIiAmJiBhdHRyLm5nUGF0dGVybi5jaGFyQXQoMCkgPT0gIi8iKSB7CiAgICAgICAgICB2YXIgbWF0Y2ggPSBhdHRyLm5nUGF0dGVybi5tYXRjaChSRUdFWF9TVFJJTkdfUkVHRVhQKTsKICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICBhdHRyLiRzZXQoIm5nUGF0dGVybiIsIG5ldyBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHNjb3BlLiR3YXRjaChhdHRyW25nQXR0cl0sIGZ1bmN0aW9uIG5nQXR0ckFsaWFzV2F0Y2hBY3Rpb24odmFsdWUpIHsKICAgICAgICAgIGF0dHIuJHNldChuZ0F0dHIsIHZhbHVlKTsKICAgICAgICB9KTsKICAgICAgfQogICAgfTsKICB9Owp9KTsKCi8vIG5nLXNyYywgbmctc3Jjc2V0LCBuZy1ocmVmIGFyZSBpbnRlcnBvbGF0ZWQKZm9yRWFjaChbJ3NyYycsICdzcmNzZXQnLCAnaHJlZiddLCBmdW5jdGlvbihhdHRyTmFtZSkgewogIHZhciBub3JtYWxpemVkID0gZGlyZWN0aXZlTm9ybWFsaXplKCduZy0nICsgYXR0ck5hbWUpOwogIG5nQXR0cmlidXRlQWxpYXNEaXJlY3RpdmVzW25vcm1hbGl6ZWRdID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gewogICAgICBwcmlvcml0eTogOTksIC8vIGl0IG5lZWRzIHRvIHJ1biBhZnRlciB0aGUgYXR0cmlidXRlcyBhcmUgaW50ZXJwb2xhdGVkCiAgICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyKSB7CiAgICAgICAgdmFyIHByb3BOYW1lID0gYXR0ck5hbWUsCiAgICAgICAgICAgIG5hbWUgPSBhdHRyTmFtZTsKCiAgICAgICAgaWYgKGF0dHJOYW1lID09PSAnaHJlZicgJiYKICAgICAgICAgICAgdG9TdHJpbmcuY2FsbChlbGVtZW50LnByb3AoJ2hyZWYnKSkgPT09ICdbb2JqZWN0IFNWR0FuaW1hdGVkU3RyaW5nXScpIHsKICAgICAgICAgIG5hbWUgPSAneGxpbmtIcmVmJzsKICAgICAgICAgIGF0dHIuJGF0dHJbbmFtZV0gPSAneGxpbms6aHJlZic7CiAgICAgICAgICBwcm9wTmFtZSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBhdHRyLiRvYnNlcnZlKG5vcm1hbGl6ZWQsIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICBpZiAoIXZhbHVlKSB7CiAgICAgICAgICAgIGlmIChhdHRyTmFtZSA9PT0gJ2hyZWYnKSB7CiAgICAgICAgICAgICAgYXR0ci4kc2V0KG5hbWUsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KCiAgICAgICAgICBhdHRyLiRzZXQobmFtZSwgdmFsdWUpOwoKICAgICAgICAgIC8vIG9uIElFLCBpZiAibmc6c3JjIiBkaXJlY3RpdmUgZGVjbGFyYXRpb24gaXMgdXNlZCBhbmQgInNyYyIgYXR0cmlidXRlIGRvZXNuJ3QgZXhpc3QKICAgICAgICAgIC8vIHRoZW4gY2FsbGluZyBlbGVtZW50LnNldEF0dHJpYnV0ZSgnc3JjJywgJ2ZvbycpIGRvZXNuJ3QgZG8gYW55dGhpbmcsIHNvIHdlIG5lZWQKICAgICAgICAgIC8vIHRvIHNldCB0aGUgcHJvcGVydHkgYXMgd2VsbCB0byBhY2hpZXZlIHRoZSBkZXNpcmVkIGVmZmVjdC4KICAgICAgICAgIC8vIHdlIHVzZSBhdHRyW2F0dHJOYW1lXSB2YWx1ZSBzaW5jZSAkc2V0IGNhbiBzYW5pdGl6ZSB0aGUgdXJsLgogICAgICAgICAgaWYgKG1zaWUgJiYgcHJvcE5hbWUpIGVsZW1lbnQucHJvcChwcm9wTmFtZSwgYXR0cltuYW1lXSk7CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH07CiAgfTsKfSk7CgovKiBnbG9iYWwgLW51bGxGb3JtQ3RybCwgLVNVQk1JVFRFRF9DTEFTUywgYWRkU2V0VmFsaWRpdHlNZXRob2Q6IHRydWUKICovCnZhciBudWxsRm9ybUN0cmwgPSB7CiAgJGFkZENvbnRyb2w6IG5vb3AsCiAgJCRyZW5hbWVDb250cm9sOiBudWxsRm9ybVJlbmFtZUNvbnRyb2wsCiAgJHJlbW92ZUNvbnRyb2w6IG5vb3AsCiAgJHNldFZhbGlkaXR5OiBub29wLAogICRzZXREaXJ0eTogbm9vcCwKICAkc2V0UHJpc3RpbmU6IG5vb3AsCiAgJHNldFN1Ym1pdHRlZDogbm9vcAp9LApTVUJNSVRURURfQ0xBU1MgPSAnbmctc3VibWl0dGVkJzsKCmZ1bmN0aW9uIG51bGxGb3JtUmVuYW1lQ29udHJvbChjb250cm9sLCBuYW1lKSB7CiAgY29udHJvbC4kbmFtZSA9IG5hbWU7Cn0KCi8qKgogKiBAbmdkb2MgdHlwZQogKiBAbmFtZSBmb3JtLkZvcm1Db250cm9sbGVyCiAqCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gJHByaXN0aW5lIFRydWUgaWYgdXNlciBoYXMgbm90IGludGVyYWN0ZWQgd2l0aCB0aGUgZm9ybSB5ZXQuCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gJGRpcnR5IFRydWUgaWYgdXNlciBoYXMgYWxyZWFkeSBpbnRlcmFjdGVkIHdpdGggdGhlIGZvcm0uCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gJHZhbGlkIFRydWUgaWYgYWxsIG9mIHRoZSBjb250YWluaW5nIGZvcm1zIGFuZCBjb250cm9scyBhcmUgdmFsaWQuCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gJGludmFsaWQgVHJ1ZSBpZiBhdCBsZWFzdCBvbmUgY29udGFpbmluZyBjb250cm9sIG9yIGZvcm0gaXMgaW52YWxpZC4KICogQHByb3BlcnR5IHtib29sZWFufSAkc3VibWl0dGVkIFRydWUgaWYgdXNlciBoYXMgc3VibWl0dGVkIHRoZSBmb3JtIGV2ZW4gaWYgaXRzIGludmFsaWQuCiAqCiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSAkZXJyb3IgSXMgYW4gb2JqZWN0IGhhc2gsIGNvbnRhaW5pbmcgcmVmZXJlbmNlcyB0byBjb250cm9scyBvcgogKiAgZm9ybXMgd2l0aCBmYWlsaW5nIHZhbGlkYXRvcnMsIHdoZXJlOgogKgogKiAgLSBrZXlzIGFyZSB2YWxpZGF0aW9uIHRva2VucyAoZXJyb3IgbmFtZXMpLAogKiAgLSB2YWx1ZXMgYXJlIGFycmF5cyBvZiBjb250cm9scyBvciBmb3JtcyB0aGF0IGhhdmUgYSBmYWlsaW5nIHZhbGlkYXRvciBmb3IgZ2l2ZW4gZXJyb3IgbmFtZS4KICoKICogIEJ1aWx0LWluIHZhbGlkYXRpb24gdG9rZW5zOgogKgogKiAgLSBgZW1haWxgCiAqICAtIGBtYXhgCiAqICAtIGBtYXhsZW5ndGhgCiAqICAtIGBtaW5gCiAqICAtIGBtaW5sZW5ndGhgCiAqICAtIGBudW1iZXJgCiAqICAtIGBwYXR0ZXJuYAogKiAgLSBgcmVxdWlyZWRgCiAqICAtIGB1cmxgCiAqICAtIGBkYXRlYAogKiAgLSBgZGF0ZXRpbWVsb2NhbGAKICogIC0gYHRpbWVgCiAqICAtIGB3ZWVrYAogKiAgLSBgbW9udGhgCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBgRm9ybUNvbnRyb2xsZXJgIGtlZXBzIHRyYWNrIG9mIGFsbCBpdHMgY29udHJvbHMgYW5kIG5lc3RlZCBmb3JtcyBhcyB3ZWxsIGFzIHRoZSBzdGF0ZSBvZiB0aGVtLAogKiBzdWNoIGFzIGJlaW5nIHZhbGlkL2ludmFsaWQgb3IgZGlydHkvcHJpc3RpbmUuCiAqCiAqIEVhY2gge0BsaW5rIG5nLmRpcmVjdGl2ZTpmb3JtIGZvcm19IGRpcmVjdGl2ZSBjcmVhdGVzIGFuIGluc3RhbmNlCiAqIG9mIGBGb3JtQ29udHJvbGxlcmAuCiAqCiAqLwovL2Fza3MgZm9yICRzY29wZSB0byBmb29sIHRoZSBCQyBjb250cm9sbGVyIG1vZHVsZQpGb3JtQ29udHJvbGxlci4kaW5qZWN0ID0gWyckZWxlbWVudCcsICckYXR0cnMnLCAnJHNjb3BlJywgJyRhbmltYXRlJywgJyRpbnRlcnBvbGF0ZSddOwpmdW5jdGlvbiBGb3JtQ29udHJvbGxlcihlbGVtZW50LCBhdHRycywgJHNjb3BlLCAkYW5pbWF0ZSwgJGludGVycG9sYXRlKSB7CiAgdmFyIGZvcm0gPSB0aGlzLAogICAgICBjb250cm9scyA9IFtdOwoKICB2YXIgcGFyZW50Rm9ybSA9IGZvcm0uJCRwYXJlbnRGb3JtID0gZWxlbWVudC5wYXJlbnQoKS5jb250cm9sbGVyKCdmb3JtJykgfHwgbnVsbEZvcm1DdHJsOwoKICAvLyBpbml0IHN0YXRlCiAgZm9ybS4kZXJyb3IgPSB7fTsKICBmb3JtLiQkc3VjY2VzcyA9IHt9OwogIGZvcm0uJHBlbmRpbmcgPSB1bmRlZmluZWQ7CiAgZm9ybS4kbmFtZSA9ICRpbnRlcnBvbGF0ZShhdHRycy5uYW1lIHx8IGF0dHJzLm5nRm9ybSB8fCAnJykoJHNjb3BlKTsKICBmb3JtLiRkaXJ0eSA9IGZhbHNlOwogIGZvcm0uJHByaXN0aW5lID0gdHJ1ZTsKICBmb3JtLiR2YWxpZCA9IHRydWU7CiAgZm9ybS4kaW52YWxpZCA9IGZhbHNlOwogIGZvcm0uJHN1Ym1pdHRlZCA9IGZhbHNlOwoKICBwYXJlbnRGb3JtLiRhZGRDb250cm9sKGZvcm0pOwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgZm9ybS5Gb3JtQ29udHJvbGxlciMkcm9sbGJhY2tWaWV3VmFsdWUKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJvbGxiYWNrIGFsbCBmb3JtIGNvbnRyb2xzIHBlbmRpbmcgdXBkYXRlcyB0byB0aGUgYCRtb2RlbFZhbHVlYC4KICAgKgogICAqIFVwZGF0ZXMgbWF5IGJlIHBlbmRpbmcgYnkgYSBkZWJvdW5jZWQgZXZlbnQgb3IgYmVjYXVzZSB0aGUgaW5wdXQgaXMgd2FpdGluZyBmb3IgYSBzb21lIGZ1dHVyZQogICAqIGV2ZW50IGRlZmluZWQgaW4gYG5nLW1vZGVsLW9wdGlvbnNgLiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgbmVlZGVkIGJ5IHRoZSByZXNldCBidXR0b24gb2YKICAgKiBhIGZvcm0gdGhhdCB1c2VzIGBuZy1tb2RlbC1vcHRpb25zYCB0byBwZW5kIHVwZGF0ZXMuCiAgICovCiAgZm9ybS4kcm9sbGJhY2tWaWV3VmFsdWUgPSBmdW5jdGlvbigpIHsKICAgIGZvckVhY2goY29udHJvbHMsIGZ1bmN0aW9uKGNvbnRyb2wpIHsKICAgICAgY29udHJvbC4kcm9sbGJhY2tWaWV3VmFsdWUoKTsKICAgIH0pOwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBmb3JtLkZvcm1Db250cm9sbGVyIyRjb21taXRWaWV3VmFsdWUKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIENvbW1pdCBhbGwgZm9ybSBjb250cm9scyBwZW5kaW5nIHVwZGF0ZXMgdG8gdGhlIGAkbW9kZWxWYWx1ZWAuCiAgICoKICAgKiBVcGRhdGVzIG1heSBiZSBwZW5kaW5nIGJ5IGEgZGVib3VuY2VkIGV2ZW50IG9yIGJlY2F1c2UgdGhlIGlucHV0IGlzIHdhaXRpbmcgZm9yIGEgc29tZSBmdXR1cmUKICAgKiBldmVudCBkZWZpbmVkIGluIGBuZy1tb2RlbC1vcHRpb25zYC4gVGhpcyBtZXRob2QgaXMgcmFyZWx5IG5lZWRlZCBhcyBgTmdNb2RlbENvbnRyb2xsZXJgCiAgICogdXN1YWxseSBoYW5kbGVzIGNhbGxpbmcgdGhpcyBpbiByZXNwb25zZSB0byBpbnB1dCBldmVudHMuCiAgICovCiAgZm9ybS4kY29tbWl0Vmlld1ZhbHVlID0gZnVuY3Rpb24oKSB7CiAgICBmb3JFYWNoKGNvbnRyb2xzLCBmdW5jdGlvbihjb250cm9sKSB7CiAgICAgIGNvbnRyb2wuJGNvbW1pdFZpZXdWYWx1ZSgpOwogICAgfSk7CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIGZvcm0uRm9ybUNvbnRyb2xsZXIjJGFkZENvbnRyb2wKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJlZ2lzdGVyIGEgY29udHJvbCB3aXRoIHRoZSBmb3JtLgogICAqCiAgICogSW5wdXQgZWxlbWVudHMgdXNpbmcgbmdNb2RlbENvbnRyb2xsZXIgZG8gdGhpcyBhdXRvbWF0aWNhbGx5IHdoZW4gdGhleSBhcmUgbGlua2VkLgogICAqLwogIGZvcm0uJGFkZENvbnRyb2wgPSBmdW5jdGlvbihjb250cm9sKSB7CiAgICAvLyBCcmVha2luZyBjaGFuZ2UgLSBiZWZvcmUsIGlucHV0cyB3aG9zZSBuYW1lIHdhcyAiaGFzT3duUHJvcGVydHkiIHdlcmUgcXVpZXRseSBpZ25vcmVkCiAgICAvLyBhbmQgbm90IGFkZGVkIHRvIHRoZSBzY29wZS4gIE5vdyB3ZSB0aHJvdyBhbiBlcnJvci4KICAgIGFzc2VydE5vdEhhc093blByb3BlcnR5KGNvbnRyb2wuJG5hbWUsICdpbnB1dCcpOwogICAgY29udHJvbHMucHVzaChjb250cm9sKTsKCiAgICBpZiAoY29udHJvbC4kbmFtZSkgewogICAgICBmb3JtW2NvbnRyb2wuJG5hbWVdID0gY29udHJvbDsKICAgIH0KICB9OwoKICAvLyBQcml2YXRlIEFQSTogcmVuYW1lIGEgZm9ybSBjb250cm9sCiAgZm9ybS4kJHJlbmFtZUNvbnRyb2wgPSBmdW5jdGlvbihjb250cm9sLCBuZXdOYW1lKSB7CiAgICB2YXIgb2xkTmFtZSA9IGNvbnRyb2wuJG5hbWU7CgogICAgaWYgKGZvcm1bb2xkTmFtZV0gPT09IGNvbnRyb2wpIHsKICAgICAgZGVsZXRlIGZvcm1bb2xkTmFtZV07CiAgICB9CiAgICBmb3JtW25ld05hbWVdID0gY29udHJvbDsKICAgIGNvbnRyb2wuJG5hbWUgPSBuZXdOYW1lOwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBmb3JtLkZvcm1Db250cm9sbGVyIyRyZW1vdmVDb250cm9sCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBEZXJlZ2lzdGVyIGEgY29udHJvbCBmcm9tIHRoZSBmb3JtLgogICAqCiAgICogSW5wdXQgZWxlbWVudHMgdXNpbmcgbmdNb2RlbENvbnRyb2xsZXIgZG8gdGhpcyBhdXRvbWF0aWNhbGx5IHdoZW4gdGhleSBhcmUgZGVzdHJveWVkLgogICAqLwogIGZvcm0uJHJlbW92ZUNvbnRyb2wgPSBmdW5jdGlvbihjb250cm9sKSB7CiAgICBpZiAoY29udHJvbC4kbmFtZSAmJiBmb3JtW2NvbnRyb2wuJG5hbWVdID09PSBjb250cm9sKSB7CiAgICAgIGRlbGV0ZSBmb3JtW2NvbnRyb2wuJG5hbWVdOwogICAgfQogICAgZm9yRWFjaChmb3JtLiRwZW5kaW5nLCBmdW5jdGlvbih2YWx1ZSwgbmFtZSkgewogICAgICBmb3JtLiRzZXRWYWxpZGl0eShuYW1lLCBudWxsLCBjb250cm9sKTsKICAgIH0pOwogICAgZm9yRWFjaChmb3JtLiRlcnJvciwgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsKICAgICAgZm9ybS4kc2V0VmFsaWRpdHkobmFtZSwgbnVsbCwgY29udHJvbCk7CiAgICB9KTsKCiAgICBhcnJheVJlbW92ZShjb250cm9scywgY29udHJvbCk7CiAgfTsKCgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBmb3JtLkZvcm1Db250cm9sbGVyIyRzZXRWYWxpZGl0eQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyB0aGUgdmFsaWRpdHkgb2YgYSBmb3JtIGNvbnRyb2wuCiAgICoKICAgKiBUaGlzIG1ldGhvZCB3aWxsIGFsc28gcHJvcGFnYXRlIHRvIHBhcmVudCBmb3Jtcy4KICAgKi8KICBhZGRTZXRWYWxpZGl0eU1ldGhvZCh7CiAgICBjdHJsOiB0aGlzLAogICAgJGVsZW1lbnQ6IGVsZW1lbnQsCiAgICBzZXQ6IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHksIGNvbnRyb2wpIHsKICAgICAgdmFyIGxpc3QgPSBvYmplY3RbcHJvcGVydHldOwogICAgICBpZiAoIWxpc3QpIHsKICAgICAgICBvYmplY3RbcHJvcGVydHldID0gW2NvbnRyb2xdOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBpbmRleCA9IGxpc3QuaW5kZXhPZihjb250cm9sKTsKICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7CiAgICAgICAgICBsaXN0LnB1c2goY29udHJvbCk7CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgdW5zZXQ6IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHksIGNvbnRyb2wpIHsKICAgICAgdmFyIGxpc3QgPSBvYmplY3RbcHJvcGVydHldOwogICAgICBpZiAoIWxpc3QpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgYXJyYXlSZW1vdmUobGlzdCwgY29udHJvbCk7CiAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkgewogICAgICAgIGRlbGV0ZSBvYmplY3RbcHJvcGVydHldOwogICAgICB9CiAgICB9LAogICAgcGFyZW50Rm9ybTogcGFyZW50Rm9ybSwKICAgICRhbmltYXRlOiAkYW5pbWF0ZQogIH0pOwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgZm9ybS5Gb3JtQ29udHJvbGxlciMkc2V0RGlydHkKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFNldHMgdGhlIGZvcm0gdG8gYSBkaXJ0eSBzdGF0ZS4KICAgKgogICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgdG8gYWRkIHRoZSAnbmctZGlydHknIGNsYXNzIGFuZCBzZXQgdGhlIGZvcm0gdG8gYSBkaXJ0eQogICAqIHN0YXRlIChuZy1kaXJ0eSBjbGFzcykuIFRoaXMgbWV0aG9kIHdpbGwgYWxzbyBwcm9wYWdhdGUgdG8gcGFyZW50IGZvcm1zLgogICAqLwogIGZvcm0uJHNldERpcnR5ID0gZnVuY3Rpb24oKSB7CiAgICAkYW5pbWF0ZS5yZW1vdmVDbGFzcyhlbGVtZW50LCBQUklTVElORV9DTEFTUyk7CiAgICAkYW5pbWF0ZS5hZGRDbGFzcyhlbGVtZW50LCBESVJUWV9DTEFTUyk7CiAgICBmb3JtLiRkaXJ0eSA9IHRydWU7CiAgICBmb3JtLiRwcmlzdGluZSA9IGZhbHNlOwogICAgcGFyZW50Rm9ybS4kc2V0RGlydHkoKTsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgZm9ybS5Gb3JtQ29udHJvbGxlciMkc2V0UHJpc3RpbmUKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFNldHMgdGhlIGZvcm0gdG8gaXRzIHByaXN0aW5lIHN0YXRlLgogICAqCiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCB0byByZW1vdmUgdGhlICduZy1kaXJ0eScgY2xhc3MgYW5kIHNldCB0aGUgZm9ybSB0byBpdHMgcHJpc3RpbmUKICAgKiBzdGF0ZSAobmctcHJpc3RpbmUgY2xhc3MpLiBUaGlzIG1ldGhvZCB3aWxsIGFsc28gcHJvcGFnYXRlIHRvIGFsbCB0aGUgY29udHJvbHMgY29udGFpbmVkCiAgICogaW4gdGhpcyBmb3JtLgogICAqCiAgICogU2V0dGluZyBhIGZvcm0gYmFjayB0byBhIHByaXN0aW5lIHN0YXRlIGlzIG9mdGVuIHVzZWZ1bCB3aGVuIHdlIHdhbnQgdG8gJ3JldXNlJyBhIGZvcm0gYWZ0ZXIKICAgKiBzYXZpbmcgb3IgcmVzZXR0aW5nIGl0LgogICAqLwogIGZvcm0uJHNldFByaXN0aW5lID0gZnVuY3Rpb24oKSB7CiAgICAkYW5pbWF0ZS5zZXRDbGFzcyhlbGVtZW50LCBQUklTVElORV9DTEFTUywgRElSVFlfQ0xBU1MgKyAnICcgKyBTVUJNSVRURURfQ0xBU1MpOwogICAgZm9ybS4kZGlydHkgPSBmYWxzZTsKICAgIGZvcm0uJHByaXN0aW5lID0gdHJ1ZTsKICAgIGZvcm0uJHN1Ym1pdHRlZCA9IGZhbHNlOwogICAgZm9yRWFjaChjb250cm9scywgZnVuY3Rpb24oY29udHJvbCkgewogICAgICBjb250cm9sLiRzZXRQcmlzdGluZSgpOwogICAgfSk7CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIGZvcm0uRm9ybUNvbnRyb2xsZXIjJHNldFVudG91Y2hlZAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyB0aGUgZm9ybSB0byBpdHMgdW50b3VjaGVkIHN0YXRlLgogICAqCiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCB0byByZW1vdmUgdGhlICduZy10b3VjaGVkJyBjbGFzcyBhbmQgc2V0IHRoZSBmb3JtIGNvbnRyb2xzIHRvIHRoZWlyCiAgICogdW50b3VjaGVkIHN0YXRlIChuZy11bnRvdWNoZWQgY2xhc3MpLgogICAqCiAgICogU2V0dGluZyBhIGZvcm0gY29udHJvbHMgYmFjayB0byB0aGVpciB1bnRvdWNoZWQgc3RhdGUgaXMgb2Z0ZW4gdXNlZnVsIHdoZW4gc2V0dGluZyB0aGUgZm9ybQogICAqIGJhY2sgdG8gaXRzIHByaXN0aW5lIHN0YXRlLgogICAqLwogIGZvcm0uJHNldFVudG91Y2hlZCA9IGZ1bmN0aW9uKCkgewogICAgZm9yRWFjaChjb250cm9scywgZnVuY3Rpb24oY29udHJvbCkgewogICAgICBjb250cm9sLiRzZXRVbnRvdWNoZWQoKTsKICAgIH0pOwogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBmb3JtLkZvcm1Db250cm9sbGVyIyRzZXRTdWJtaXR0ZWQKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFNldHMgdGhlIGZvcm0gdG8gaXRzIHN1Ym1pdHRlZCBzdGF0ZS4KICAgKi8KICBmb3JtLiRzZXRTdWJtaXR0ZWQgPSBmdW5jdGlvbigpIHsKICAgICRhbmltYXRlLmFkZENsYXNzKGVsZW1lbnQsIFNVQk1JVFRFRF9DTEFTUyk7CiAgICBmb3JtLiRzdWJtaXR0ZWQgPSB0cnVlOwogICAgcGFyZW50Rm9ybS4kc2V0U3VibWl0dGVkKCk7CiAgfTsKfQoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdGb3JtCiAqIEByZXN0cmljdCBFQUMKICoKICogQGRlc2NyaXB0aW9uCiAqIE5lc3RhYmxlIGFsaWFzIG9mIHtAbGluayBuZy5kaXJlY3RpdmU6Zm9ybSBgZm9ybWB9IGRpcmVjdGl2ZS4gSFRNTAogKiBkb2VzIG5vdCBhbGxvdyBuZXN0aW5nIG9mIGZvcm0gZWxlbWVudHMuIEl0IGlzIHVzZWZ1bCB0byBuZXN0IGZvcm1zLCBmb3IgZXhhbXBsZSBpZiB0aGUgdmFsaWRpdHkgb2YgYQogKiBzdWItZ3JvdXAgb2YgY29udHJvbHMgbmVlZHMgdG8gYmUgZGV0ZXJtaW5lZC4KICoKICogTm90ZTogdGhlIHB1cnBvc2Ugb2YgYG5nRm9ybWAgaXMgdG8gZ3JvdXAgY29udHJvbHMsCiAqIGJ1dCBub3QgdG8gYmUgYSByZXBsYWNlbWVudCBmb3IgdGhlIGA8Zm9ybT5gIHRhZyB3aXRoIGFsbCBvZiBpdHMgY2FwYWJpbGl0aWVzCiAqIChlLmcuIHBvc3RpbmcgdG8gdGhlIHNlcnZlciwgLi4uKS4KICoKICogQHBhcmFtIHtzdHJpbmc9fSBuZ0Zvcm18bmFtZSBOYW1lIG9mIHRoZSBmb3JtLiBJZiBzcGVjaWZpZWQsIHRoZSBmb3JtIGNvbnRyb2xsZXIgd2lsbCBiZSBwdWJsaXNoZWQgaW50bwogKiAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZCBzY29wZSwgdW5kZXIgdGhpcyBuYW1lLgogKgogKi8KCiAvKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBmb3JtCiAqIEByZXN0cmljdCBFCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBEaXJlY3RpdmUgdGhhdCBpbnN0YW50aWF0ZXMKICoge0BsaW5rIGZvcm0uRm9ybUNvbnRyb2xsZXIgRm9ybUNvbnRyb2xsZXJ9LgogKgogKiBJZiB0aGUgYG5hbWVgIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQsIHRoZSBmb3JtIGNvbnRyb2xsZXIgaXMgcHVibGlzaGVkIG9udG8gdGhlIGN1cnJlbnQgc2NvcGUgdW5kZXIKICogdGhpcyBuYW1lLgogKgogKiAjIEFsaWFzOiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nRm9ybSBgbmdGb3JtYH0KICoKICogSW4gQW5ndWxhciBmb3JtcyBjYW4gYmUgbmVzdGVkLiBUaGlzIG1lYW5zIHRoYXQgdGhlIG91dGVyIGZvcm0gaXMgdmFsaWQgd2hlbiBhbGwgb2YgdGhlIGNoaWxkCiAqIGZvcm1zIGFyZSB2YWxpZCBhcyB3ZWxsLiBIb3dldmVyLCBicm93c2VycyBkbyBub3QgYWxsb3cgbmVzdGluZyBvZiBgPGZvcm0+YCBlbGVtZW50cywgc28KICogQW5ndWxhciBwcm92aWRlcyB0aGUge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ0Zvcm0gYG5nRm9ybWB9IGRpcmVjdGl2ZSB3aGljaCBiZWhhdmVzIGlkZW50aWNhbGx5IHRvCiAqIGA8Zm9ybT5gIGJ1dCBjYW4gYmUgbmVzdGVkLiAgVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbmVzdGVkIGZvcm1zLCB3aGljaCBpcyB2ZXJ5IHVzZWZ1bCB3aGVuCiAqIHVzaW5nIEFuZ3VsYXIgdmFsaWRhdGlvbiBkaXJlY3RpdmVzIGluIGZvcm1zIHRoYXQgYXJlIGR5bmFtaWNhbGx5IGdlbmVyYXRlZCB1c2luZyB0aGUKICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ1JlcGVhdCBgbmdSZXBlYXRgfSBkaXJlY3RpdmUuIFNpbmNlIHlvdSBjYW5ub3QgZHluYW1pY2FsbHkgZ2VuZXJhdGUgdGhlIGBuYW1lYAogKiBhdHRyaWJ1dGUgb2YgaW5wdXQgZWxlbWVudHMgdXNpbmcgaW50ZXJwb2xhdGlvbiwgeW91IGhhdmUgdG8gd3JhcCBlYWNoIHNldCBvZiByZXBlYXRlZCBpbnB1dHMgaW4gYW4KICogYG5nRm9ybWAgZGlyZWN0aXZlIGFuZCBuZXN0IHRoZXNlIGluIGFuIG91dGVyIGBmb3JtYCBlbGVtZW50LgogKgogKgogKiAjIENTUyBjbGFzc2VzCiAqICAtIGBuZy12YWxpZGAgaXMgc2V0IGlmIHRoZSBmb3JtIGlzIHZhbGlkLgogKiAgLSBgbmctaW52YWxpZGAgaXMgc2V0IGlmIHRoZSBmb3JtIGlzIGludmFsaWQuCiAqICAtIGBuZy1wcmlzdGluZWAgaXMgc2V0IGlmIHRoZSBmb3JtIGlzIHByaXN0aW5lLgogKiAgLSBgbmctZGlydHlgIGlzIHNldCBpZiB0aGUgZm9ybSBpcyBkaXJ0eS4KICogIC0gYG5nLXN1Ym1pdHRlZGAgaXMgc2V0IGlmIHRoZSBmb3JtIHdhcyBzdWJtaXR0ZWQuCiAqCiAqIEtlZXAgaW4gbWluZCB0aGF0IG5nQW5pbWF0ZSBjYW4gZGV0ZWN0IGVhY2ggb2YgdGhlc2UgY2xhc3NlcyB3aGVuIGFkZGVkIGFuZCByZW1vdmVkLgogKgogKgogKiAjIFN1Ym1pdHRpbmcgYSBmb3JtIGFuZCBwcmV2ZW50aW5nIHRoZSBkZWZhdWx0IGFjdGlvbgogKgogKiBTaW5jZSB0aGUgcm9sZSBvZiBmb3JtcyBpbiBjbGllbnQtc2lkZSBBbmd1bGFyIGFwcGxpY2F0aW9ucyBpcyBkaWZmZXJlbnQgdGhhbiBpbiBjbGFzc2ljYWwKICogcm91bmR0cmlwIGFwcHMsIGl0IGlzIGRlc2lyYWJsZSBmb3IgdGhlIGJyb3dzZXIgbm90IHRvIHRyYW5zbGF0ZSB0aGUgZm9ybSBzdWJtaXNzaW9uIGludG8gYSBmdWxsCiAqIHBhZ2UgcmVsb2FkIHRoYXQgc2VuZHMgdGhlIGRhdGEgdG8gdGhlIHNlcnZlci4gSW5zdGVhZCBzb21lIGphdmFzY3JpcHQgbG9naWMgc2hvdWxkIGJlIHRyaWdnZXJlZAogKiB0byBoYW5kbGUgdGhlIGZvcm0gc3VibWlzc2lvbiBpbiBhbiBhcHBsaWNhdGlvbi1zcGVjaWZpYyB3YXkuCiAqCiAqIEZvciB0aGlzIHJlYXNvbiwgQW5ndWxhciBwcmV2ZW50cyB0aGUgZGVmYXVsdCBhY3Rpb24gKGZvcm0gc3VibWlzc2lvbiB0byB0aGUgc2VydmVyKSB1bmxlc3MgdGhlCiAqIGA8Zm9ybT5gIGVsZW1lbnQgaGFzIGFuIGBhY3Rpb25gIGF0dHJpYnV0ZSBzcGVjaWZpZWQuCiAqCiAqIFlvdSBjYW4gdXNlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHR3byB3YXlzIHRvIHNwZWNpZnkgd2hhdCBqYXZhc2NyaXB0IG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIHdoZW4KICogYSBmb3JtIGlzIHN1Ym1pdHRlZDoKICoKICogLSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nU3VibWl0IG5nU3VibWl0fSBkaXJlY3RpdmUgb24gdGhlIGZvcm0gZWxlbWVudAogKiAtIHtAbGluayBuZy5kaXJlY3RpdmU6bmdDbGljayBuZ0NsaWNrfSBkaXJlY3RpdmUgb24gdGhlIGZpcnN0CiAgKiAgYnV0dG9uIG9yIGlucHV0IGZpZWxkIG9mIHR5cGUgc3VibWl0IChpbnB1dFt0eXBlPXN1Ym1pdF0pCiAqCiAqIFRvIHByZXZlbnQgZG91YmxlIGV4ZWN1dGlvbiBvZiB0aGUgaGFuZGxlciwgdXNlIG9ubHkgb25lIG9mIHRoZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nU3VibWl0IG5nU3VibWl0fQogKiBvciB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQ2xpY2sgbmdDbGlja30gZGlyZWN0aXZlcy4KICogVGhpcyBpcyBiZWNhdXNlIG9mIHRoZSBmb2xsb3dpbmcgZm9ybSBzdWJtaXNzaW9uIHJ1bGVzIGluIHRoZSBIVE1MIHNwZWNpZmljYXRpb246CiAqCiAqIC0gSWYgYSBmb3JtIGhhcyBvbmx5IG9uZSBpbnB1dCBmaWVsZCB0aGVuIGhpdHRpbmcgZW50ZXIgaW4gdGhpcyBmaWVsZCB0cmlnZ2VycyBmb3JtIHN1Ym1pdAogKiAoYG5nU3VibWl0YCkKICogLSBpZiBhIGZvcm0gaGFzIDIrIGlucHV0IGZpZWxkcyBhbmQgbm8gYnV0dG9ucyBvciBpbnB1dFt0eXBlPXN1Ym1pdF0gdGhlbiBoaXR0aW5nIGVudGVyCiAqIGRvZXNuJ3QgdHJpZ2dlciBzdWJtaXQKICogLSBpZiBhIGZvcm0gaGFzIG9uZSBvciBtb3JlIGlucHV0IGZpZWxkcyBhbmQgb25lIG9yIG1vcmUgYnV0dG9ucyBvciBpbnB1dFt0eXBlPXN1Ym1pdF0gdGhlbgogKiBoaXR0aW5nIGVudGVyIGluIGFueSBvZiB0aGUgaW5wdXQgZmllbGRzIHdpbGwgdHJpZ2dlciB0aGUgY2xpY2sgaGFuZGxlciBvbiB0aGUgKmZpcnN0KiBidXR0b24gb3IKICogaW5wdXRbdHlwZT1zdWJtaXRdIChgbmdDbGlja2ApICphbmQqIGEgc3VibWl0IGhhbmRsZXIgb24gdGhlIGVuY2xvc2luZyBmb3JtIChgbmdTdWJtaXRgKQogKgogKiBBbnkgcGVuZGluZyBgbmdNb2RlbE9wdGlvbnNgIGNoYW5nZXMgd2lsbCB0YWtlIHBsYWNlIGltbWVkaWF0ZWx5IHdoZW4gYW4gZW5jbG9zaW5nIGZvcm0gaXMKICogc3VibWl0dGVkLiBOb3RlIHRoYXQgYG5nQ2xpY2tgIGV2ZW50cyB3aWxsIG9jY3VyIGJlZm9yZSB0aGUgbW9kZWwgaXMgdXBkYXRlZC4gVXNlIGBuZ1N1Ym1pdGAKICogdG8gaGF2ZSBhY2Nlc3MgdG8gdGhlIHVwZGF0ZWQgbW9kZWwuCiAqCiAqICMjIEFuaW1hdGlvbiBIb29rcwogKgogKiBBbmltYXRpb25zIGluIG5nRm9ybSBhcmUgdHJpZ2dlcmVkIHdoZW4gYW55IG9mIHRoZSBhc3NvY2lhdGVkIENTUyBjbGFzc2VzIGFyZSBhZGRlZCBhbmQgcmVtb3ZlZC4KICogVGhlc2UgY2xhc3NlcyBhcmU6IGAubmctcHJpc3RpbmVgLCBgLm5nLWRpcnR5YCwgYC5uZy1pbnZhbGlkYCBhbmQgYC5uZy12YWxpZGAgYXMgd2VsbCBhcyBhbnkKICogb3RoZXIgdmFsaWRhdGlvbnMgdGhhdCBhcmUgcGVyZm9ybWVkIHdpdGhpbiB0aGUgZm9ybS4gQW5pbWF0aW9ucyBpbiBuZ0Zvcm0gYXJlIHNpbWlsYXIgdG8gaG93CiAqIHRoZXkgd29yayBpbiBuZ0NsYXNzIGFuZCBhbmltYXRpb25zIGNhbiBiZSBob29rZWQgaW50byB1c2luZyBDU1MgdHJhbnNpdGlvbnMsIGtleWZyYW1lcyBhcyB3ZWxsCiAqIGFzIEpTIGFuaW1hdGlvbnMuCiAqCiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBhIHNpbXBsZSB3YXkgdG8gdXRpbGl6ZSBDU1MgdHJhbnNpdGlvbnMgdG8gc3R5bGUgYSBmb3JtIGVsZW1lbnQKICogdGhhdCBoYXMgYmVlbiByZW5kZXJlZCBhcyBpbnZhbGlkIGFmdGVyIGl0IGhhcyBiZWVuIHZhbGlkYXRlZDoKICoKICogPHByZT4KICogLy9iZSBzdXJlIHRvIGluY2x1ZGUgbmdBbmltYXRlIGFzIGEgbW9kdWxlIHRvIGhvb2sgaW50byBtb3JlCiAqIC8vYWR2YW5jZWQgYW5pbWF0aW9ucwogKiAubXktZm9ybSB7CiAqICAgdHJhbnNpdGlvbjowLjVzIGxpbmVhciBhbGw7CiAqICAgYmFja2dyb3VuZDogd2hpdGU7CiAqIH0KICogLm15LWZvcm0ubmctaW52YWxpZCB7CiAqICAgYmFja2dyb3VuZDogcmVkOwogKiAgIGNvbG9yOndoaXRlOwogKiB9CiAqIDwvcHJlPgogKgogKiBAZXhhbXBsZQogICAgPGV4YW1wbGUgZGVwcz0iYW5ndWxhci1hbmltYXRlLmpzIiBhbmltYXRpb25zPSJ0cnVlIiBmaXhCYXNlPSJ0cnVlIiBtb2R1bGU9ImZvcm1FeGFtcGxlIj4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8c2NyaXB0PgogICAgICAgICBhbmd1bGFyLm1vZHVsZSgnZm9ybUV4YW1wbGUnLCBbXSkKICAgICAgICAgICAuY29udHJvbGxlcignRm9ybUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICAgJHNjb3BlLnVzZXJUeXBlID0gJ2d1ZXN0JzsKICAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgIDxzdHlsZT4KICAgICAgICAubXktZm9ybSB7CiAgICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246YWxsIGxpbmVhciAwLjVzOwogICAgICAgICAgdHJhbnNpdGlvbjphbGwgbGluZWFyIDAuNXM7CiAgICAgICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsKICAgICAgICB9CiAgICAgICAgLm15LWZvcm0ubmctaW52YWxpZCB7CiAgICAgICAgICBiYWNrZ3JvdW5kOiByZWQ7CiAgICAgICAgfQogICAgICAgPC9zdHlsZT4KICAgICAgIDxmb3JtIG5hbWU9Im15Rm9ybSIgbmctY29udHJvbGxlcj0iRm9ybUNvbnRyb2xsZXIiIGNsYXNzPSJteS1mb3JtIj4KICAgICAgICAgdXNlclR5cGU6IDxpbnB1dCBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InVzZXJUeXBlIiByZXF1aXJlZD4KICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnJlcXVpcmVkIj5SZXF1aXJlZCE8L3NwYW4+PGJyPgogICAgICAgICA8dHQ+dXNlclR5cGUgPSB7e3VzZXJUeXBlfX08L3R0Pjxicj4KICAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kdmFsaWQgPSB7e215Rm9ybS5pbnB1dC4kdmFsaWR9fTwvdHQ+PGJyPgogICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiRlcnJvciA9IHt7bXlGb3JtLmlucHV0LiRlcnJvcn19PC90dD48YnI+CiAgICAgICAgIDx0dD5teUZvcm0uJHZhbGlkID0ge3tteUZvcm0uJHZhbGlkfX08L3R0Pjxicj4KICAgICAgICAgPHR0Pm15Rm9ybS4kZXJyb3IucmVxdWlyZWQgPSB7eyEhbXlGb3JtLiRlcnJvci5yZXF1aXJlZH19PC90dD48YnI+CiAgICAgICAgPC9mb3JtPgogICAgICA8L2ZpbGU+CiAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSB0byBtb2RlbCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgdmFyIHVzZXJUeXBlID0gZWxlbWVudChieS5iaW5kaW5nKCd1c2VyVHlwZScpKTsKICAgICAgICAgIHZhciB2YWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmlucHV0LiR2YWxpZCcpKTsKCiAgICAgICAgICBleHBlY3QodXNlclR5cGUuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2d1ZXN0Jyk7CiAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3RydWUnKTsKICAgICAgICB9KTsKCiAgICAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIGVtcHR5JywgZnVuY3Rpb24oKSB7CiAgICAgICAgICB2YXIgdXNlclR5cGUgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3VzZXJUeXBlJykpOwogICAgICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICAgICAgdmFyIHVzZXJJbnB1dCA9IGVsZW1lbnQoYnkubW9kZWwoJ3VzZXJUeXBlJykpOwoKICAgICAgICAgIHVzZXJJbnB1dC5jbGVhcigpOwogICAgICAgICAgdXNlcklucHV0LnNlbmRLZXlzKCcnKTsKCiAgICAgICAgICBleHBlY3QodXNlclR5cGUuZ2V0VGV4dCgpKS50b0VxdWFsKCd1c2VyVHlwZSA9Jyk7CiAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICoKICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIE5hbWUgb2YgdGhlIGZvcm0uIElmIHNwZWNpZmllZCwgdGhlIGZvcm0gY29udHJvbGxlciB3aWxsIGJlIHB1Ymxpc2hlZCBpbnRvCiAqICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkIHNjb3BlLCB1bmRlciB0aGlzIG5hbWUuCiAqLwp2YXIgZm9ybURpcmVjdGl2ZUZhY3RvcnkgPSBmdW5jdGlvbihpc05nRm9ybSkgewogIHJldHVybiBbJyR0aW1lb3V0JywgZnVuY3Rpb24oJHRpbWVvdXQpIHsKICAgIHZhciBmb3JtRGlyZWN0aXZlID0gewogICAgICBuYW1lOiAnZm9ybScsCiAgICAgIHJlc3RyaWN0OiBpc05nRm9ybSA/ICdFQUMnIDogJ0UnLAogICAgICBjb250cm9sbGVyOiBGb3JtQ29udHJvbGxlciwKICAgICAgY29tcGlsZTogZnVuY3Rpb24gbmdGb3JtQ29tcGlsZShmb3JtRWxlbWVudCkgewogICAgICAgIC8vIFNldHVwIGluaXRpYWwgc3RhdGUgb2YgdGhlIGNvbnRyb2wKICAgICAgICBmb3JtRWxlbWVudC5hZGRDbGFzcyhQUklTVElORV9DTEFTUykuYWRkQ2xhc3MoVkFMSURfQ0xBU1MpOwoKICAgICAgICByZXR1cm4gewogICAgICAgICAgcHJlOiBmdW5jdGlvbiBuZ0Zvcm1QcmVMaW5rKHNjb3BlLCBmb3JtRWxlbWVudCwgYXR0ciwgY29udHJvbGxlcikgewogICAgICAgICAgICAvLyBpZiBgYWN0aW9uYCBhdHRyIGlzIG5vdCBwcmVzZW50IG9uIHRoZSBmb3JtLCBwcmV2ZW50IHRoZSBkZWZhdWx0IGFjdGlvbiAoc3VibWlzc2lvbikKICAgICAgICAgICAgaWYgKCEoJ2FjdGlvbicgaW4gYXR0cikpIHsKICAgICAgICAgICAgICAvLyB3ZSBjYW4ndCB1c2UganEgZXZlbnRzIGJlY2F1c2UgaWYgYSBmb3JtIGlzIGRlc3Ryb3llZCBkdXJpbmcgc3VibWlzc2lvbiB0aGUgZGVmYXVsdAogICAgICAgICAgICAgIC8vIGFjdGlvbiBpcyBub3QgcHJldmVudGVkLiBzZWUgIzEyMzgKICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgIC8vIElFIDkgaXMgbm90IGFmZmVjdGVkIGJlY2F1c2UgaXQgZG9lc24ndCBmaXJlIGEgc3VibWl0IGV2ZW50IGFuZCB0cnkgdG8gZG8gYSBmdWxsCiAgICAgICAgICAgICAgLy8gcGFnZSByZWxvYWQgaWYgdGhlIGZvcm0gd2FzIGRlc3Ryb3llZCBieSBzdWJtaXNzaW9uIG9mIHRoZSBmb3JtIHZpYSBhIGNsaWNrIGhhbmRsZXIKICAgICAgICAgICAgICAvLyBvbiBhIGJ1dHRvbiBpbiB0aGUgZm9ybS4gTG9va3MgbGlrZSBhbiBJRTkgc3BlY2lmaWMgYnVnLgogICAgICAgICAgICAgIHZhciBoYW5kbGVGb3JtU3VibWlzc2lvbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgICAgICBzY29wZS4kYXBwbHkoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuJGNvbW1pdFZpZXdWYWx1ZSgpOwogICAgICAgICAgICAgICAgICBjb250cm9sbGVyLiRzZXRTdWJtaXR0ZWQoKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lckZuKGZvcm1FbGVtZW50WzBdLCAnc3VibWl0JywgaGFuZGxlRm9ybVN1Ym1pc3Npb24pOwoKICAgICAgICAgICAgICAvLyB1bnJlZ2lzdGVyIHRoZSBwcmV2ZW50RGVmYXVsdCBsaXN0ZW5lciBzbyB0aGF0IHdlIGRvbid0IG5vdCBsZWFrIG1lbW9yeSBidXQgaW4gYQogICAgICAgICAgICAgIC8vIHdheSB0aGF0IHdpbGwgYWNoaWV2ZSB0aGUgcHJldmVudGlvbiBvZiB0aGUgZGVmYXVsdCBhY3Rpb24uCiAgICAgICAgICAgICAgZm9ybUVsZW1lbnQub24oJyRkZXN0cm95JywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAkdGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lckZuKGZvcm1FbGVtZW50WzBdLCAnc3VibWl0JywgaGFuZGxlRm9ybVN1Ym1pc3Npb24pOwogICAgICAgICAgICAgICAgfSwgMCwgZmFsc2UpOwogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcGFyZW50Rm9ybUN0cmwgPSBjb250cm9sbGVyLiQkcGFyZW50Rm9ybSwKICAgICAgICAgICAgICAgIGFsaWFzID0gY29udHJvbGxlci4kbmFtZTsKCiAgICAgICAgICAgIGlmIChhbGlhcykgewogICAgICAgICAgICAgIHNldHRlcihzY29wZSwgYWxpYXMsIGNvbnRyb2xsZXIsIGFsaWFzKTsKICAgICAgICAgICAgICBhdHRyLiRvYnNlcnZlKGF0dHIubmFtZSA/ICduYW1lJyA6ICduZ0Zvcm0nLCBmdW5jdGlvbihuZXdWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKGFsaWFzID09PSBuZXdWYWx1ZSkgcmV0dXJuOwogICAgICAgICAgICAgICAgc2V0dGVyKHNjb3BlLCBhbGlhcywgdW5kZWZpbmVkLCBhbGlhcyk7CiAgICAgICAgICAgICAgICBhbGlhcyA9IG5ld1ZhbHVlOwogICAgICAgICAgICAgICAgc2V0dGVyKHNjb3BlLCBhbGlhcywgY29udHJvbGxlciwgYWxpYXMpOwogICAgICAgICAgICAgICAgcGFyZW50Rm9ybUN0cmwuJCRyZW5hbWVDb250cm9sKGNvbnRyb2xsZXIsIGFsaWFzKTsKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JtRWxlbWVudC5vbignJGRlc3Ryb3knLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICBwYXJlbnRGb3JtQ3RybC4kcmVtb3ZlQ29udHJvbChjb250cm9sbGVyKTsKICAgICAgICAgICAgICBpZiAoYWxpYXMpIHsKICAgICAgICAgICAgICAgIHNldHRlcihzY29wZSwgYWxpYXMsIHVuZGVmaW5lZCwgYWxpYXMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBleHRlbmQoY29udHJvbGxlciwgbnVsbEZvcm1DdHJsKTsgLy9zdG9wIHByb3BhZ2F0aW5nIGNoaWxkIGRlc3RydWN0aW9uIGhhbmRsZXJzIHVwd2FyZHMKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfQogICAgfTsKCiAgICByZXR1cm4gZm9ybURpcmVjdGl2ZTsKICB9XTsKfTsKCnZhciBmb3JtRGlyZWN0aXZlID0gZm9ybURpcmVjdGl2ZUZhY3RvcnkoKTsKdmFyIG5nRm9ybURpcmVjdGl2ZSA9IGZvcm1EaXJlY3RpdmVGYWN0b3J5KHRydWUpOwoKLyogZ2xvYmFsIFZBTElEX0NMQVNTOiB0cnVlLAogIElOVkFMSURfQ0xBU1M6IHRydWUsCiAgUFJJU1RJTkVfQ0xBU1M6IHRydWUsCiAgRElSVFlfQ0xBU1M6IHRydWUsCiAgVU5UT1VDSEVEX0NMQVNTOiB0cnVlLAogIFRPVUNIRURfQ0xBU1M6IHRydWUsCiovCgovLyBSZWdleCBjb2RlIGlzIG9idGFpbmVkIGZyb20gU086IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMxNDMwNzAvamF2YXNjcmlwdC1yZWdleC1pc28tZGF0ZXRpbWUjYW5zd2VyLTMxNDMyMzEKdmFyIElTT19EQVRFX1JFR0VYUCA9IC9cZHs0fS1bMDFdXGQtWzAtM11cZFRbMC0yXVxkOlswLTVdXGQ6WzAtNV1cZFwuXGQrKFsrLV1bMC0yXVxkOlswLTVdXGR8WikvOwp2YXIgVVJMX1JFR0VYUCA9IC9eKGZ0cHxodHRwfGh0dHBzKTpcL1wvKFx3Kzp7MCwxfVx3KkApPyhcUyspKDpbMC05XSspPyhcL3xcLyhbXHcjITouPys9JiVAIVwtXC9dKSk/JC87CnZhciBFTUFJTF9SRUdFWFAgPSAvXlthLXowLTkhIyQlJicqK1wvPT9eX2B7fH1+Li1dK0BbYS16MC05XShbYS16MC05LV0qW2EtejAtOV0pPyhcLlthLXowLTldKFthLXowLTktXSpbYS16MC05XSk/KSokL2k7CnZhciBOVU1CRVJfUkVHRVhQID0gL15ccyooXC18XCspPyhcZCt8KFxkKihcLlxkKikpKVxzKiQvOwp2YXIgREFURV9SRUdFWFAgPSAvXihcZHs0fSktKFxkezJ9KS0oXGR7Mn0pJC87CnZhciBEQVRFVElNRUxPQ0FMX1JFR0VYUCA9IC9eKFxkezR9KS0oXGRcZCktKFxkXGQpVChcZFxkKTooXGRcZCkoPzo6KFxkXGQpKFwuXGR7MSwzfSk/KT8kLzsKdmFyIFdFRUtfUkVHRVhQID0gL14oXGR7NH0pLVcoXGRcZCkkLzsKdmFyIE1PTlRIX1JFR0VYUCA9IC9eKFxkezR9KS0oXGRcZCkkLzsKdmFyIFRJTUVfUkVHRVhQID0gL14oXGRcZCk6KFxkXGQpKD86OihcZFxkKShcLlxkezEsM30pPyk/JC87CnZhciBERUZBVUxUX1JFR0VYUCA9IC8oXHMrfF4pZGVmYXVsdChccyt8JCkvOwoKdmFyICRuZ01vZGVsTWluRXJyID0gbmV3IG1pbkVycignbmdNb2RlbCcpOwoKdmFyIGlucHV0VHlwZSA9IHsKCiAgLyoqCiAgICogQG5nZG9jIGlucHV0CiAgICogQG5hbWUgaW5wdXRbdGV4dF0KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFN0YW5kYXJkIEhUTUwgdGV4dCBpbnB1dCB3aXRoIGFuZ3VsYXIgZGF0YSBiaW5kaW5nLCBpbmhlcml0ZWQgYnkgbW9zdCBvZiB0aGUgYGlucHV0YCBlbGVtZW50cy4KICAgKgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHJlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgaXMgbm90IGVudGVyZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAgICogICAgdGhlIGVsZW1lbnQgd2hlbiB0aGUgbmdSZXF1aXJlZCBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLiBVc2UgYG5nUmVxdWlyZWRgIGluc3RlYWQgb2YKICAgKiAgICBgcmVxdWlyZWRgIHdoZW4geW91IHdhbnQgdG8gZGF0YS1iaW5kIHRvIHRoZSBgcmVxdWlyZWRgIGF0dHJpYnV0ZS4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWlubGVuZ3RoIFNldHMgYG1pbmxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIHNob3J0ZXIgdGhhbgogICAqICAgIG1pbmxlbmd0aC4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWF4bGVuZ3RoIFNldHMgYG1heGxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIGxvbmdlciB0aGFuCiAgICogICAgbWF4bGVuZ3RoLiBTZXR0aW5nIHRoZSBhdHRyaWJ1dGUgdG8gYSBuZWdhdGl2ZSBvciBub24tbnVtZXJpYyB2YWx1ZSwgYWxsb3dzIHZpZXcgdmFsdWVzIG9mCiAgICogICAgYW55IGxlbmd0aC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHBhdHRlcm4gU2ltaWxhciB0byBgbmdQYXR0ZXJuYCBleGNlcHQgdGhhdCB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIHRoZSBhY3R1YWwgc3RyaW5nCiAgICogICAgdGhhdCBjb250YWlucyB0aGUgcmVndWxhciBleHByZXNzaW9uIGJvZHkgdGhhdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIHJlZ3VsYXIgZXhwcmVzc2lvbgogICAqICAgIGFzIGluIHRoZSBuZ1BhdHRlcm4gZGlyZWN0aXZlLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdQYXR0ZXJuIFNldHMgYHBhdHRlcm5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSBuZ01vZGVsIHZhbHVlIGRvZXMgbm90IG1hdGNoCiAgICogICAgYSBSZWdFeHAgZm91bmQgYnkgZXZhbHVhdGluZyB0aGUgQW5ndWxhciBleHByZXNzaW9uIGdpdmVuIGluIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCiAgICogICAgSWYgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGEgUmVnRXhwIG9iamVjdCB0aGVuIHRoaXMgaXMgdXNlZCBkaXJlY3RseS4KICAgKiAgICBJZiB0aGUgZXhwcmVzc2lvbiBpcyBhIHN0cmluZyB0aGVuIGl0IHdpbGwgYmUgY29udmVydGVkIHRvIGEgUmVnRXhwIGFmdGVyIHdyYXBwaW5nIGl0IGluIGBeYCBhbmQgYCRgCiAgICogICAgY2hhcmFjdGVycy4gRm9yIGluc3RhbmNlLCBgImFiYyJgIHdpbGwgYmUgY29udmVydGVkIHRvIGBuZXcgUmVnRXhwKCdeYWJjJCcpYC4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgKiAgICBpbnRlcmFjdGlvbiB3aXRoIHRoZSBpbnB1dCBlbGVtZW50LgogICAqIEBwYXJhbSB7Ym9vbGVhbj19IFtuZ1RyaW09dHJ1ZV0gSWYgc2V0IHRvIGZhbHNlIEFuZ3VsYXIgd2lsbCBub3QgYXV0b21hdGljYWxseSB0cmltIHRoZSBpbnB1dC4KICAgKiAgICBUaGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkIGZvciBpbnB1dFt0eXBlPXBhc3N3b3JkXSBjb250cm9scywgd2hpY2ggd2lsbCBuZXZlciB0cmltIHRoZQogICAqICAgIGlucHV0LgogICAqCiAgICogQGV4YW1wbGUKICAgICAgPGV4YW1wbGUgbmFtZT0idGV4dC1pbnB1dC1kaXJlY3RpdmUiIG1vZHVsZT0idGV4dElucHV0RXhhbXBsZSI+CiAgICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgIDxzY3JpcHQ+CiAgICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ3RleHRJbnB1dEV4YW1wbGUnLCBbXSkKICAgICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAgICRzY29wZS50ZXh0ID0gJ2d1ZXN0JzsKICAgICAgICAgICAgICAgJHNjb3BlLndvcmQgPSAvXlxzKlx3KlxzKiQvOwogICAgICAgICAgICAgfV0pOwogICAgICAgICA8L3NjcmlwdD4KICAgICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgICAgU2luZ2xlIHdvcmQ6IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InRleHQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZy1wYXR0ZXJuPSJ3b3JkIiByZXF1aXJlZCBuZy10cmltPSJmYWxzZSI+CiAgICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnJlcXVpcmVkIj4KICAgICAgICAgICAgIFJlcXVpcmVkITwvc3Bhbj4KICAgICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5pbnB1dC4kZXJyb3IucGF0dGVybiI+CiAgICAgICAgICAgICBTaW5nbGUgd29yZCBvbmx5ITwvc3Bhbj4KCiAgICAgICAgICAgPHR0PnRleHQgPSB7e3RleHR9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiR2YWxpZCA9IHt7bXlGb3JtLmlucHV0LiR2YWxpZH19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJGVycm9yID0ge3tteUZvcm0uaW5wdXQuJGVycm9yfX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0Pm15Rm9ybS4kdmFsaWQgPSB7e215Rm9ybS4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5yZXF1aXJlZCA9IHt7ISFteUZvcm0uJGVycm9yLnJlcXVpcmVkfX08L3R0Pjxici8+CiAgICAgICAgICA8L2Zvcm0+CiAgICAgICAgPC9maWxlPgogICAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgICAgdmFyIHRleHQgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3RleHQnKSk7CiAgICAgICAgICB2YXIgdmFsaWQgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ215Rm9ybS5pbnB1dC4kdmFsaWQnKSk7CiAgICAgICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd0ZXh0JykpOwoKICAgICAgICAgIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSB0byBtb2RlbCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBleHBlY3QodGV4dC5nZXRUZXh0KCkpLnRvQ29udGFpbignZ3Vlc3QnKTsKICAgICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAgICAgICAgICB9KTsKCiAgICAgICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgZW1wdHknLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaW5wdXQuY2xlYXIoKTsKICAgICAgICAgICAgaW5wdXQuc2VuZEtleXMoJycpOwoKICAgICAgICAgICAgZXhwZWN0KHRleHQuZ2V0VGV4dCgpKS50b0VxdWFsKCd0ZXh0ID0nKTsKICAgICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdmYWxzZScpOwogICAgICAgICAgfSk7CgogICAgICAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIG11bHRpIHdvcmQnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaW5wdXQuY2xlYXIoKTsKICAgICAgICAgICAgaW5wdXQuc2VuZEtleXMoJ2hlbGxvIHdvcmxkJyk7CgogICAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgICB9KTsKICAgICAgICA8L2ZpbGU+CiAgICAgIDwvZXhhbXBsZT4KICAgKi8KICAndGV4dCc6IHRleHRJbnB1dFR5cGUsCgogICAgLyoqCiAgICAgKiBAbmdkb2MgaW5wdXQKICAgICAqIEBuYW1lIGlucHV0W2RhdGVdCiAgICAgKgogICAgICogQGRlc2NyaXB0aW9uCiAgICAgKiBJbnB1dCB3aXRoIGRhdGUgdmFsaWRhdGlvbiBhbmQgdHJhbnNmb3JtYXRpb24uIEluIGJyb3dzZXJzIHRoYXQgZG8gbm90IHlldCBzdXBwb3J0CiAgICAgKiB0aGUgSFRNTDUgZGF0ZSBpbnB1dCwgYSB0ZXh0IGVsZW1lbnQgd2lsbCBiZSB1c2VkLiBJbiB0aGF0IGNhc2UsIHRleHQgbXVzdCBiZSBlbnRlcmVkIGluIGEgdmFsaWQgSVNPLTg2MDEKICAgICAqIGRhdGUgZm9ybWF0ICh5eXl5LU1NLWRkKSwgZm9yIGV4YW1wbGU6IGAyMDA5LTAxLTA2YC4gU2luY2UgbWFueQogICAgICogbW9kZXJuIGJyb3dzZXJzIGRvIG5vdCB5ZXQgc3VwcG9ydCB0aGlzIGlucHV0IHR5cGUsIGl0IGlzIGltcG9ydGFudCB0byBwcm92aWRlIGN1ZXMgdG8gdXNlcnMgb24gdGhlCiAgICAgKiBleHBlY3RlZCBpbnB1dCBmb3JtYXQgdmlhIGEgcGxhY2Vob2xkZXIgb3IgbGFiZWwuCiAgICAgKgogICAgICogVGhlIG1vZGVsIG11c3QgYWx3YXlzIGJlIGEgRGF0ZSBvYmplY3QsIG90aGVyd2lzZSBBbmd1bGFyIHdpbGwgdGhyb3cgYW4gZXJyb3IuCiAgICAgKiBJbnZhbGlkIGBEYXRlYCBvYmplY3RzIChkYXRlcyB3aG9zZSBgZ2V0VGltZSgpYCBpcyBgTmFOYCkgd2lsbCBiZSByZW5kZXJlZCBhcyBhbiBlbXB0eSBzdHJpbmcuCiAgICAgKgogICAgICogVGhlIHRpbWV6b25lIHRvIGJlIHVzZWQgdG8gcmVhZC93cml0ZSB0aGUgYERhdGVgIGluc3RhbmNlIGluIHRoZSBtb2RlbCBjYW4gYmUgZGVmaW5lZCB1c2luZwogICAgICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ01vZGVsT3B0aW9ucyBuZ01vZGVsT3B0aW9uc30uIEJ5IGRlZmF1bHQsIHRoaXMgaXMgdGhlIHRpbWV6b25lIG9mIHRoZSBicm93c2VyLgogICAgICoKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuZ01vZGVsIEFzc2lnbmFibGUgYW5ndWxhciBleHByZXNzaW9uIHRvIGRhdGEtYmluZCB0by4KICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbWluIFNldHMgdGhlIGBtaW5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGxlc3MgdGhhbiBgbWluYC4gVGhpcyBtdXN0IGJlIGEKICAgICAqIHZhbGlkIElTTyBkYXRlIHN0cmluZyAoeXl5eS1NTS1kZCkuCiAgICAgKiBAcGFyYW0ge3N0cmluZz19IG1heCBTZXRzIHRoZSBgbWF4YCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZW50ZXJlZCBpcyBncmVhdGVyIHRoYW4gYG1heGAuIFRoaXMgbXVzdCBiZQogICAgICogYSB2YWxpZCBJU08gZGF0ZSBzdHJpbmcgKHl5eXktTU0tZGQpLgogICAgICogQHBhcmFtIHtzdHJpbmc9fSByZXF1aXJlZCBTZXRzIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIG5vdCBlbnRlcmVkLgogICAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAgICAgKiAgICB0aGUgZWxlbWVudCB3aGVuIHRoZSBuZ1JlcXVpcmVkIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIHRydWUuIFVzZSBgbmdSZXF1aXJlZGAgaW5zdGVhZCBvZgogICAgICogICAgYHJlcXVpcmVkYCB3aGVuIHlvdSB3YW50IHRvIGRhdGEtYmluZCB0byB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUuCiAgICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgICAqICAgIGludGVyYWN0aW9uIHdpdGggdGhlIGlucHV0IGVsZW1lbnQuCiAgICAgKgogICAgICogQGV4YW1wbGUKICAgICA8ZXhhbXBsZSBuYW1lPSJkYXRlLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJkYXRlSW5wdXRFeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgIDxzY3JpcHQ+CiAgICAgICAgICBhbmd1bGFyLm1vZHVsZSgnZGF0ZUlucHV0RXhhbXBsZScsIFtdKQogICAgICAgICAgICAuY29udHJvbGxlcignRGF0ZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICAgICRzY29wZS52YWx1ZSA9IG5ldyBEYXRlKDIwMTMsIDksIDIyKTsKICAgICAgICAgICAgfV0pOwogICAgICAgPC9zY3JpcHQ+CiAgICAgICA8Zm9ybSBuYW1lPSJteUZvcm0iIG5nLWNvbnRyb2xsZXI9IkRhdGVDb250cm9sbGVyIGFzIGRhdGVDdHJsIj4KICAgICAgICAgIFBpY2sgYSBkYXRlIGluIDIwMTM6CiAgICAgICAgICA8aW5wdXQgdHlwZT0iZGF0ZSIgaWQ9ImV4YW1wbGVJbnB1dCIgbmFtZT0iaW5wdXQiIG5nLW1vZGVsPSJ2YWx1ZSIKICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0ieXl5eS1NTS1kZCIgbWluPSIyMDEzLTAxLTAxIiBtYXg9IjIwMTMtMTItMzEiIHJlcXVpcmVkIC8+CiAgICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5pbnB1dC4kZXJyb3IucmVxdWlyZWQiPgogICAgICAgICAgICAgIFJlcXVpcmVkITwvc3Bhbj4KICAgICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci5kYXRlIj4KICAgICAgICAgICAgICBOb3QgYSB2YWxpZCBkYXRlITwvc3Bhbj4KICAgICAgICAgICA8dHQ+dmFsdWUgPSB7e3ZhbHVlIHwgZGF0ZTogInl5eXktTU0tZGQifX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kdmFsaWQgPSB7e215Rm9ybS5pbnB1dC4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiRlcnJvciA9IHt7bXlGb3JtLmlucHV0LiRlcnJvcn19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uJHZhbGlkID0ge3tteUZvcm0uJHZhbGlkfX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0Pm15Rm9ybS4kZXJyb3IucmVxdWlyZWQgPSB7eyEhbXlGb3JtLiRlcnJvci5yZXF1aXJlZH19PC90dD48YnIvPgogICAgICAgPC9mb3JtPgogICAgIDwvZmlsZT4KICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgICB2YXIgdmFsdWUgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3ZhbHVlIHwgZGF0ZTogInl5eXktTU0tZGQiJykpOwogICAgICAgIHZhciB2YWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmlucHV0LiR2YWxpZCcpKTsKICAgICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKTsKCiAgICAgICAgLy8gY3VycmVudGx5IHByb3RyYWN0b3Ivd2ViZHJpdmVyIGRvZXMgbm90IHN1cHBvcnQKICAgICAgICAvLyBzZW5kaW5nIGtleXMgdG8gYWxsIGtub3duIEhUTUw1IGlucHV0IGNvbnRyb2xzCiAgICAgICAgLy8gZm9yIHZhcmlvdXMgYnJvd3NlcnMgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9wcm90cmFjdG9yL2lzc3Vlcy81NjIpLgogICAgICAgIGZ1bmN0aW9uIHNldElucHV0KHZhbCkgewogICAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgZWxlbWVudCBhbmQgZm9yY2UgdmFsaWRhdGlvbi4KICAgICAgICAgIHZhciBzY3IgPSAidmFyIGlwdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdleGFtcGxlSW5wdXQnKTsgIiArCiAgICAgICAgICAiaXB0LnZhbHVlID0gJyIgKyB2YWwgKyAiJzsiICsKICAgICAgICAgICJhbmd1bGFyLmVsZW1lbnQoaXB0KS5zY29wZSgpLiRhcHBseShmdW5jdGlvbihzKSB7IHMubXlGb3JtW2lwdC5uYW1lXS4kc2V0Vmlld1ZhbHVlKCciICsgdmFsICsgIicpOyB9KTsiOwogICAgICAgICAgYnJvd3Nlci5leGVjdXRlU2NyaXB0KHNjcik7CiAgICAgICAgfQoKICAgICAgICBpdCgnc2hvdWxkIGluaXRpYWxpemUgdG8gbW9kZWwnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvQ29udGFpbignMjAxMy0xMC0yMicpOwogICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gdHJ1ZScpOwogICAgICAgIH0pOwoKICAgICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgZW1wdHknLCBmdW5jdGlvbigpIHsKICAgICAgICAgIHNldElucHV0KCcnKTsKICAgICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvRXF1YWwoJ3ZhbHVlID0nKTsKICAgICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignbXlGb3JtLmlucHV0LiR2YWxpZCA9IGZhbHNlJyk7CiAgICAgICAgfSk7CgogICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBvdmVyIG1heCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgc2V0SW5wdXQoJzIwMTUtMDEtMDEnKTsKICAgICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvQ29udGFpbignJyk7CiAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ215Rm9ybS5pbnB1dC4kdmFsaWQgPSBmYWxzZScpOwogICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgICA8L2V4YW1wbGU+CiAgICAgKi8KICAnZGF0ZSc6IGNyZWF0ZURhdGVJbnB1dFR5cGUoJ2RhdGUnLCBEQVRFX1JFR0VYUCwKICAgICAgICAgY3JlYXRlRGF0ZVBhcnNlcihEQVRFX1JFR0VYUCwgWyd5eXl5JywgJ01NJywgJ2RkJ10pLAogICAgICAgICAneXl5eS1NTS1kZCcpLAoKICAgLyoqCiAgICAqIEBuZ2RvYyBpbnB1dAogICAgKiBAbmFtZSBpbnB1dFtkYXRldGltZS1sb2NhbF0KICAgICoKICAgICogQGRlc2NyaXB0aW9uCiAgICAqIElucHV0IHdpdGggZGF0ZXRpbWUgdmFsaWRhdGlvbiBhbmQgdHJhbnNmb3JtYXRpb24uIEluIGJyb3dzZXJzIHRoYXQgZG8gbm90IHlldCBzdXBwb3J0CiAgICAqIHRoZSBIVE1MNSBkYXRlIGlucHV0LCBhIHRleHQgZWxlbWVudCB3aWxsIGJlIHVzZWQuIEluIHRoYXQgY2FzZSwgdGhlIHRleHQgbXVzdCBiZSBlbnRlcmVkIGluIGEgdmFsaWQgSVNPLTg2MDEKICAgICogbG9jYWwgZGF0ZXRpbWUgZm9ybWF0ICh5eXl5LU1NLWRkVEhIOm1tOnNzKSwgZm9yIGV4YW1wbGU6IGAyMDEwLTEyLTI4VDE0OjU3OjAwYC4KICAgICoKICAgICogVGhlIG1vZGVsIG11c3QgYWx3YXlzIGJlIGEgRGF0ZSBvYmplY3QsIG90aGVyd2lzZSBBbmd1bGFyIHdpbGwgdGhyb3cgYW4gZXJyb3IuCiAgICAqIEludmFsaWQgYERhdGVgIG9iamVjdHMgKGRhdGVzIHdob3NlIGBnZXRUaW1lKClgIGlzIGBOYU5gKSB3aWxsIGJlIHJlbmRlcmVkIGFzIGFuIGVtcHR5IHN0cmluZy4KICAgICoKICAgICogVGhlIHRpbWV6b25lIHRvIGJlIHVzZWQgdG8gcmVhZC93cml0ZSB0aGUgYERhdGVgIGluc3RhbmNlIGluIHRoZSBtb2RlbCBjYW4gYmUgZGVmaW5lZCB1c2luZwogICAgKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nTW9kZWxPcHRpb25zIG5nTW9kZWxPcHRpb25zfS4gQnkgZGVmYXVsdCwgdGhpcyBpcyB0aGUgdGltZXpvbmUgb2YgdGhlIGJyb3dzZXIuCiAgICAqCiAgICAqIEBwYXJhbSB7c3RyaW5nfSBuZ01vZGVsIEFzc2lnbmFibGUgYW5ndWxhciBleHByZXNzaW9uIHRvIGRhdGEtYmluZCB0by4KICAgICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIFByb3BlcnR5IG5hbWUgb2YgdGhlIGZvcm0gdW5kZXIgd2hpY2ggdGhlIGNvbnRyb2wgaXMgcHVibGlzaGVkLgogICAgKiBAcGFyYW0ge3N0cmluZz19IG1pbiBTZXRzIHRoZSBgbWluYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZW50ZXJlZCBpcyBsZXNzIHRoYW4gYG1pbmAuIFRoaXMgbXVzdCBiZSBhCiAgICAqIHZhbGlkIElTTyBkYXRldGltZSBmb3JtYXQgKHl5eXktTU0tZGRUSEg6bW06c3MpLgogICAgKiBAcGFyYW0ge3N0cmluZz19IG1heCBTZXRzIHRoZSBgbWF4YCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZW50ZXJlZCBpcyBncmVhdGVyIHRoYW4gYG1heGAuIFRoaXMgbXVzdCBiZQogICAgKiBhIHZhbGlkIElTTyBkYXRldGltZSBmb3JtYXQgKHl5eXktTU0tZGRUSEg6bW06c3MpLgogICAgKiBAcGFyYW0ge3N0cmluZz19IHJlcXVpcmVkIFNldHMgYHJlcXVpcmVkYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgaXMgbm90IGVudGVyZWQuCiAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdSZXF1aXJlZCBBZGRzIGByZXF1aXJlZGAgYXR0cmlidXRlIGFuZCBgcmVxdWlyZWRgIHZhbGlkYXRpb24gY29uc3RyYWludCB0bwogICAgKiAgICB0aGUgZWxlbWVudCB3aGVuIHRoZSBuZ1JlcXVpcmVkIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIHRydWUuIFVzZSBgbmdSZXF1aXJlZGAgaW5zdGVhZCBvZgogICAgKiAgICBgcmVxdWlyZWRgIHdoZW4geW91IHdhbnQgdG8gZGF0YS1iaW5kIHRvIHRoZSBgcmVxdWlyZWRgIGF0dHJpYnV0ZS4KICAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ0NoYW5nZSBBbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiBpbnB1dCBjaGFuZ2VzIGR1ZSB0byB1c2VyCiAgICAqICAgIGludGVyYWN0aW9uIHdpdGggdGhlIGlucHV0IGVsZW1lbnQuCiAgICAqCiAgICAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZSBuYW1lPSJkYXRldGltZWxvY2FsLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJkYXRlRXhhbXBsZSI+CiAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPHNjcmlwdD4KICAgICAgICBhbmd1bGFyLm1vZHVsZSgnZGF0ZUV4YW1wbGUnLCBbXSkKICAgICAgICAgIC5jb250cm9sbGVyKCdEYXRlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICRzY29wZS52YWx1ZSA9IG5ldyBEYXRlKDIwMTAsIDExLCAyOCwgMTQsIDU3KTsKICAgICAgICAgIH1dKTsKICAgICAgPC9zY3JpcHQ+CiAgICAgIDxmb3JtIG5hbWU9Im15Rm9ybSIgbmctY29udHJvbGxlcj0iRGF0ZUNvbnRyb2xsZXIgYXMgZGF0ZUN0cmwiPgogICAgICAgIFBpY2sgYSBkYXRlIGJldHdlZW4gaW4gMjAxMzoKICAgICAgICA8aW5wdXQgdHlwZT0iZGF0ZXRpbWUtbG9jYWwiIGlkPSJleGFtcGxlSW5wdXQiIG5hbWU9ImlucHV0IiBuZy1tb2RlbD0idmFsdWUiCiAgICAgICAgICAgIHBsYWNlaG9sZGVyPSJ5eXl5LU1NLWRkVEhIOm1tOnNzIiBtaW49IjIwMDEtMDEtMDFUMDA6MDA6MDAiIG1heD0iMjAxMy0xMi0zMVQwMDowMDowMCIgcmVxdWlyZWQgLz4KICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5pbnB1dC4kZXJyb3IucmVxdWlyZWQiPgogICAgICAgICAgICBSZXF1aXJlZCE8L3NwYW4+CiAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLmRhdGV0aW1lbG9jYWwiPgogICAgICAgICAgICBOb3QgYSB2YWxpZCBkYXRlITwvc3Bhbj4KICAgICAgICA8dHQ+dmFsdWUgPSB7e3ZhbHVlIHwgZGF0ZTogInl5eXktTU0tZGRUSEg6bW06c3MifX08L3R0Pjxici8+CiAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kdmFsaWQgPSB7e215Rm9ybS5pbnB1dC4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiRlcnJvciA9IHt7bXlGb3JtLmlucHV0LiRlcnJvcn19PC90dD48YnIvPgogICAgICAgIDx0dD5teUZvcm0uJHZhbGlkID0ge3tteUZvcm0uJHZhbGlkfX08L3R0Pjxici8+CiAgICAgICAgPHR0Pm15Rm9ybS4kZXJyb3IucmVxdWlyZWQgPSB7eyEhbXlGb3JtLiRlcnJvci5yZXF1aXJlZH19PC90dD48YnIvPgogICAgICA8L2Zvcm0+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgdmFyIHZhbHVlID0gZWxlbWVudChieS5iaW5kaW5nKCd2YWx1ZSB8IGRhdGU6ICJ5eXl5LU1NLWRkVEhIOm1tOnNzIicpKTsKICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKTsKCiAgICAgIC8vIGN1cnJlbnRseSBwcm90cmFjdG9yL3dlYmRyaXZlciBkb2VzIG5vdCBzdXBwb3J0CiAgICAgIC8vIHNlbmRpbmcga2V5cyB0byBhbGwga25vd24gSFRNTDUgaW5wdXQgY29udHJvbHMKICAgICAgLy8gZm9yIHZhcmlvdXMgYnJvd3NlcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL3Byb3RyYWN0b3IvaXNzdWVzLzU2MikuCiAgICAgIGZ1bmN0aW9uIHNldElucHV0KHZhbCkgewogICAgICAgIC8vIHNldCB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgYW5kIGZvcmNlIHZhbGlkYXRpb24uCiAgICAgICAgdmFyIHNjciA9ICJ2YXIgaXB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V4YW1wbGVJbnB1dCcpOyAiICsKICAgICAgICAiaXB0LnZhbHVlID0gJyIgKyB2YWwgKyAiJzsiICsKICAgICAgICAiYW5ndWxhci5lbGVtZW50KGlwdCkuc2NvcGUoKS4kYXBwbHkoZnVuY3Rpb24ocykgeyBzLm15Rm9ybVtpcHQubmFtZV0uJHNldFZpZXdWYWx1ZSgnIiArIHZhbCArICInKTsgfSk7IjsKICAgICAgICBicm93c2VyLmV4ZWN1dGVTY3JpcHQoc2NyKTsKICAgICAgfQoKICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcyMDEwLTEyLTI4VDE0OjU3OjAwJyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gdHJ1ZScpOwogICAgICB9KTsKCiAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBlbXB0eScsIGZ1bmN0aW9uKCkgewogICAgICAgIHNldElucHV0KCcnKTsKICAgICAgICBleHBlY3QodmFsdWUuZ2V0VGV4dCgpKS50b0VxdWFsKCd2YWx1ZSA9Jyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gZmFsc2UnKTsKICAgICAgfSk7CgogICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgb3ZlciBtYXgnLCBmdW5jdGlvbigpIHsKICAgICAgICBzZXRJbnB1dCgnMjAxNS0wMS0wMVQyMzo1OTowMCcpOwogICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvQ29udGFpbignJyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gZmFsc2UnKTsKICAgICAgfSk7CiAgICA8L2ZpbGU+CiAgICA8L2V4YW1wbGU+CiAgICAqLwogICdkYXRldGltZS1sb2NhbCc6IGNyZWF0ZURhdGVJbnB1dFR5cGUoJ2RhdGV0aW1lbG9jYWwnLCBEQVRFVElNRUxPQ0FMX1JFR0VYUCwKICAgICAgY3JlYXRlRGF0ZVBhcnNlcihEQVRFVElNRUxPQ0FMX1JFR0VYUCwgWyd5eXl5JywgJ01NJywgJ2RkJywgJ0hIJywgJ21tJywgJ3NzJywgJ3NzcyddKSwKICAgICAgJ3l5eXktTU0tZGRUSEg6bW06c3Muc3NzJyksCgogIC8qKgogICAqIEBuZ2RvYyBpbnB1dAogICAqIEBuYW1lIGlucHV0W3RpbWVdCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBJbnB1dCB3aXRoIHRpbWUgdmFsaWRhdGlvbiBhbmQgdHJhbnNmb3JtYXRpb24uIEluIGJyb3dzZXJzIHRoYXQgZG8gbm90IHlldCBzdXBwb3J0CiAgICogdGhlIEhUTUw1IGRhdGUgaW5wdXQsIGEgdGV4dCBlbGVtZW50IHdpbGwgYmUgdXNlZC4gSW4gdGhhdCBjYXNlLCB0aGUgdGV4dCBtdXN0IGJlIGVudGVyZWQgaW4gYSB2YWxpZCBJU08tODYwMQogICAqIGxvY2FsIHRpbWUgZm9ybWF0IChISDptbTpzcyksIGZvciBleGFtcGxlOiBgMTQ6NTc6MDBgLiBNb2RlbCBtdXN0IGJlIGEgRGF0ZSBvYmplY3QuIFRoaXMgYmluZGluZyB3aWxsIGFsd2F5cyBvdXRwdXQgYQogICAqIERhdGUgb2JqZWN0IHRvIHRoZSBtb2RlbCBvZiBKYW51YXJ5IDEsIDE5NzAsIG9yIGxvY2FsIGRhdGUgYG5ldyBEYXRlKDE5NzAsIDAsIDEsIEhILCBtbSwgc3MpYC4KICAgKgogICAqIFRoZSBtb2RlbCBtdXN0IGFsd2F5cyBiZSBhIERhdGUgb2JqZWN0LCBvdGhlcndpc2UgQW5ndWxhciB3aWxsIHRocm93IGFuIGVycm9yLgogICAqIEludmFsaWQgYERhdGVgIG9iamVjdHMgKGRhdGVzIHdob3NlIGBnZXRUaW1lKClgIGlzIGBOYU5gKSB3aWxsIGJlIHJlbmRlcmVkIGFzIGFuIGVtcHR5IHN0cmluZy4KICAgKgogICAqIFRoZSB0aW1lem9uZSB0byBiZSB1c2VkIHRvIHJlYWQvd3JpdGUgdGhlIGBEYXRlYCBpbnN0YW5jZSBpbiB0aGUgbW9kZWwgY2FuIGJlIGRlZmluZWQgdXNpbmcKICAgKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nTW9kZWxPcHRpb25zIG5nTW9kZWxPcHRpb25zfS4gQnkgZGVmYXVsdCwgdGhpcyBpcyB0aGUgdGltZXpvbmUgb2YgdGhlIGJyb3dzZXIuCiAgICoKICAgKiBAcGFyYW0ge3N0cmluZ30gbmdNb2RlbCBBc3NpZ25hYmxlIGFuZ3VsYXIgZXhwcmVzc2lvbiB0byBkYXRhLWJpbmQgdG8uCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIFByb3BlcnR5IG5hbWUgb2YgdGhlIGZvcm0gdW5kZXIgd2hpY2ggdGhlIGNvbnRyb2wgaXMgcHVibGlzaGVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbWluIFNldHMgdGhlIGBtaW5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGxlc3MgdGhhbiBgbWluYC4gVGhpcyBtdXN0IGJlIGEKICAgKiB2YWxpZCBJU08gdGltZSBmb3JtYXQgKEhIOm1tOnNzKS4KICAgKiBAcGFyYW0ge3N0cmluZz19IG1heCBTZXRzIHRoZSBgbWF4YCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZW50ZXJlZCBpcyBncmVhdGVyIHRoYW4gYG1heGAuIFRoaXMgbXVzdCBiZSBhCiAgICogdmFsaWQgSVNPIHRpbWUgZm9ybWF0IChISDptbTpzcykuCiAgICogQHBhcmFtIHtzdHJpbmc9fSByZXF1aXJlZCBTZXRzIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIG5vdCBlbnRlcmVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdSZXF1aXJlZCBBZGRzIGByZXF1aXJlZGAgYXR0cmlidXRlIGFuZCBgcmVxdWlyZWRgIHZhbGlkYXRpb24gY29uc3RyYWludCB0bwogICAqICAgIHRoZSBlbGVtZW50IHdoZW4gdGhlIG5nUmVxdWlyZWQgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS4gVXNlIGBuZ1JlcXVpcmVkYCBpbnN0ZWFkIG9mCiAgICogICAgYHJlcXVpcmVkYCB3aGVuIHlvdSB3YW50IHRvIGRhdGEtYmluZCB0byB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ0NoYW5nZSBBbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiBpbnB1dCBjaGFuZ2VzIGR1ZSB0byB1c2VyCiAgICogICAgaW50ZXJhY3Rpb24gd2l0aCB0aGUgaW5wdXQgZWxlbWVudC4KICAgKgogICAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG5hbWU9InRpbWUtaW5wdXQtZGlyZWN0aXZlIiBtb2R1bGU9InRpbWVFeGFtcGxlIj4KICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgPHNjcmlwdD4KICAgICAgYW5ndWxhci5tb2R1bGUoJ3RpbWVFeGFtcGxlJywgW10pCiAgICAgICAgLmNvbnRyb2xsZXIoJ0RhdGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICRzY29wZS52YWx1ZSA9IG5ldyBEYXRlKDE5NzAsIDAsIDEsIDE0LCA1NywgMCk7CiAgICAgICAgfV0pOwogICAgIDwvc2NyaXB0PgogICAgIDxmb3JtIG5hbWU9Im15Rm9ybSIgbmctY29udHJvbGxlcj0iRGF0ZUNvbnRyb2xsZXIgYXMgZGF0ZUN0cmwiPgogICAgICAgIFBpY2sgYSBiZXR3ZWVuIDhhbSBhbmQgNXBtOgogICAgICAgIDxpbnB1dCB0eXBlPSJ0aW1lIiBpZD0iZXhhbXBsZUlucHV0IiBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InZhbHVlIgogICAgICAgICAgICBwbGFjZWhvbGRlcj0iSEg6bW06c3MiIG1pbj0iMDg6MDA6MDAiIG1heD0iMTc6MDA6MDAiIHJlcXVpcmVkIC8+CiAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnJlcXVpcmVkIj4KICAgICAgICAgICAgUmVxdWlyZWQhPC9zcGFuPgogICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci50aW1lIj4KICAgICAgICAgICAgTm90IGEgdmFsaWQgZGF0ZSE8L3NwYW4+CiAgICAgICAgPHR0PnZhbHVlID0ge3t2YWx1ZSB8IGRhdGU6ICJISDptbTpzcyJ9fTwvdHQ+PGJyLz4KICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiR2YWxpZCA9IHt7bXlGb3JtLmlucHV0LiR2YWxpZH19PC90dD48YnIvPgogICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJGVycm9yID0ge3tteUZvcm0uaW5wdXQuJGVycm9yfX08L3R0Pjxici8+CiAgICAgICAgPHR0Pm15Rm9ybS4kdmFsaWQgPSB7e215Rm9ybS4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5yZXF1aXJlZCA9IHt7ISFteUZvcm0uJGVycm9yLnJlcXVpcmVkfX08L3R0Pjxici8+CiAgICAgPC9mb3JtPgogICA8L2ZpbGU+CiAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICB2YXIgdmFsdWUgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3ZhbHVlIHwgZGF0ZTogIkhIOm1tOnNzIicpKTsKICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKTsKCiAgICAgIC8vIGN1cnJlbnRseSBwcm90cmFjdG9yL3dlYmRyaXZlciBkb2VzIG5vdCBzdXBwb3J0CiAgICAgIC8vIHNlbmRpbmcga2V5cyB0byBhbGwga25vd24gSFRNTDUgaW5wdXQgY29udHJvbHMKICAgICAgLy8gZm9yIHZhcmlvdXMgYnJvd3NlcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL3Byb3RyYWN0b3IvaXNzdWVzLzU2MikuCiAgICAgIGZ1bmN0aW9uIHNldElucHV0KHZhbCkgewogICAgICAgIC8vIHNldCB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgYW5kIGZvcmNlIHZhbGlkYXRpb24uCiAgICAgICAgdmFyIHNjciA9ICJ2YXIgaXB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V4YW1wbGVJbnB1dCcpOyAiICsKICAgICAgICAiaXB0LnZhbHVlID0gJyIgKyB2YWwgKyAiJzsiICsKICAgICAgICAiYW5ndWxhci5lbGVtZW50KGlwdCkuc2NvcGUoKS4kYXBwbHkoZnVuY3Rpb24ocykgeyBzLm15Rm9ybVtpcHQubmFtZV0uJHNldFZpZXdWYWx1ZSgnIiArIHZhbCArICInKTsgfSk7IjsKICAgICAgICBicm93c2VyLmV4ZWN1dGVTY3JpcHQoc2NyKTsKICAgICAgfQoKICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcxNDo1NzowMCcpOwogICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignbXlGb3JtLmlucHV0LiR2YWxpZCA9IHRydWUnKTsKICAgICAgfSk7CgogICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgZW1wdHknLCBmdW5jdGlvbigpIHsKICAgICAgICBzZXRJbnB1dCgnJyk7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9FcXVhbCgndmFsdWUgPScpOwogICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignbXlGb3JtLmlucHV0LiR2YWxpZCA9IGZhbHNlJyk7CiAgICAgIH0pOwoKICAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIG92ZXIgbWF4JywgZnVuY3Rpb24oKSB7CiAgICAgICAgc2V0SW5wdXQoJzIzOjU5OjAwJyk7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcnKTsKICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ215Rm9ybS5pbnB1dC4kdmFsaWQgPSBmYWxzZScpOwogICAgICB9KTsKICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAgICovCiAgJ3RpbWUnOiBjcmVhdGVEYXRlSW5wdXRUeXBlKCd0aW1lJywgVElNRV9SRUdFWFAsCiAgICAgIGNyZWF0ZURhdGVQYXJzZXIoVElNRV9SRUdFWFAsIFsnSEgnLCAnbW0nLCAnc3MnLCAnc3NzJ10pLAogICAgICdISDptbTpzcy5zc3MnKSwKCiAgIC8qKgogICAgKiBAbmdkb2MgaW5wdXQKICAgICogQG5hbWUgaW5wdXRbd2Vla10KICAgICoKICAgICogQGRlc2NyaXB0aW9uCiAgICAqIElucHV0IHdpdGggd2Vlay1vZi10aGUteWVhciB2YWxpZGF0aW9uIGFuZCB0cmFuc2Zvcm1hdGlvbiB0byBEYXRlLiBJbiBicm93c2VycyB0aGF0IGRvIG5vdCB5ZXQgc3VwcG9ydAogICAgKiB0aGUgSFRNTDUgd2VlayBpbnB1dCwgYSB0ZXh0IGVsZW1lbnQgd2lsbCBiZSB1c2VkLiBJbiB0aGF0IGNhc2UsIHRoZSB0ZXh0IG11c3QgYmUgZW50ZXJlZCBpbiBhIHZhbGlkIElTTy04NjAxCiAgICAqIHdlZWsgZm9ybWF0ICh5eXl5LVcjIyksIGZvciBleGFtcGxlOiBgMjAxMy1XMDJgLgogICAgKgogICAgKiBUaGUgbW9kZWwgbXVzdCBhbHdheXMgYmUgYSBEYXRlIG9iamVjdCwgb3RoZXJ3aXNlIEFuZ3VsYXIgd2lsbCB0aHJvdyBhbiBlcnJvci4KICAgICogSW52YWxpZCBgRGF0ZWAgb2JqZWN0cyAoZGF0ZXMgd2hvc2UgYGdldFRpbWUoKWAgaXMgYE5hTmApIHdpbGwgYmUgcmVuZGVyZWQgYXMgYW4gZW1wdHkgc3RyaW5nLgogICAgKgogICAgKiBUaGUgdGltZXpvbmUgdG8gYmUgdXNlZCB0byByZWFkL3dyaXRlIHRoZSBgRGF0ZWAgaW5zdGFuY2UgaW4gdGhlIG1vZGVsIGNhbiBiZSBkZWZpbmVkIHVzaW5nCiAgICAqIHtAbGluayBuZy5kaXJlY3RpdmU6bmdNb2RlbE9wdGlvbnMgbmdNb2RlbE9wdGlvbnN9LiBCeSBkZWZhdWx0LCB0aGlzIGlzIHRoZSB0aW1lem9uZSBvZiB0aGUgYnJvd3Nlci4KICAgICoKICAgICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogICAgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgUHJvcGVydHkgbmFtZSBvZiB0aGUgZm9ybSB1bmRlciB3aGljaCB0aGUgY29udHJvbCBpcyBwdWJsaXNoZWQuCiAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbWluIFNldHMgdGhlIGBtaW5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGxlc3MgdGhhbiBgbWluYC4gVGhpcyBtdXN0IGJlIGEKICAgICogdmFsaWQgSVNPIHdlZWsgZm9ybWF0ICh5eXl5LVcjIykuCiAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbWF4IFNldHMgdGhlIGBtYXhgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGdyZWF0ZXIgdGhhbiBgbWF4YC4gVGhpcyBtdXN0IGJlCiAgICAqIGEgdmFsaWQgSVNPIHdlZWsgZm9ybWF0ICh5eXl5LVcjIykuCiAgICAqIEBwYXJhbSB7c3RyaW5nPX0gcmVxdWlyZWQgU2V0cyBgcmVxdWlyZWRgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBpcyBub3QgZW50ZXJlZC4KICAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAgICAqICAgIHRoZSBlbGVtZW50IHdoZW4gdGhlIG5nUmVxdWlyZWQgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS4gVXNlIGBuZ1JlcXVpcmVkYCBpbnN0ZWFkIG9mCiAgICAqICAgIGByZXF1aXJlZGAgd2hlbiB5b3Ugd2FudCB0byBkYXRhLWJpbmQgdG8gdGhlIGByZXF1aXJlZGAgYXR0cmlidXRlLgogICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgICogICAgaW50ZXJhY3Rpb24gd2l0aCB0aGUgaW5wdXQgZWxlbWVudC4KICAgICoKICAgICogQGV4YW1wbGUKICAgIDxleGFtcGxlIG5hbWU9IndlZWstaW5wdXQtZGlyZWN0aXZlIiBtb2R1bGU9IndlZWtFeGFtcGxlIj4KICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8c2NyaXB0PgogICAgICBhbmd1bGFyLm1vZHVsZSgnd2Vla0V4YW1wbGUnLCBbXSkKICAgICAgICAuY29udHJvbGxlcignRGF0ZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgJHNjb3BlLnZhbHVlID0gbmV3IERhdGUoMjAxMywgMCwgMyk7CiAgICAgICAgfV0pOwogICAgICA8L3NjcmlwdD4KICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJEYXRlQ29udHJvbGxlciBhcyBkYXRlQ3RybCI+CiAgICAgICAgUGljayBhIGRhdGUgYmV0d2VlbiBpbiAyMDEzOgogICAgICAgIDxpbnB1dCBpZD0iZXhhbXBsZUlucHV0IiB0eXBlPSJ3ZWVrIiBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InZhbHVlIgogICAgICAgICAgICBwbGFjZWhvbGRlcj0iWVlZWS1XIyMiIG1pbj0iMjAxMi1XMzIiIG1heD0iMjAxMy1XNTIiIHJlcXVpcmVkIC8+CiAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnJlcXVpcmVkIj4KICAgICAgICAgICAgUmVxdWlyZWQhPC9zcGFuPgogICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci53ZWVrIj4KICAgICAgICAgICAgTm90IGEgdmFsaWQgZGF0ZSE8L3NwYW4+CiAgICAgICAgPHR0PnZhbHVlID0ge3t2YWx1ZSB8IGRhdGU6ICJ5eXl5LVd3dyJ9fTwvdHQ+PGJyLz4KICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiR2YWxpZCA9IHt7bXlGb3JtLmlucHV0LiR2YWxpZH19PC90dD48YnIvPgogICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJGVycm9yID0ge3tteUZvcm0uaW5wdXQuJGVycm9yfX08L3R0Pjxici8+CiAgICAgICAgPHR0Pm15Rm9ybS4kdmFsaWQgPSB7e215Rm9ybS4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5yZXF1aXJlZCA9IHt7ISFteUZvcm0uJGVycm9yLnJlcXVpcmVkfX08L3R0Pjxici8+CiAgICAgIDwvZm9ybT4KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICB2YXIgdmFsdWUgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3ZhbHVlIHwgZGF0ZTogInl5eXktV3d3IicpKTsKICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKTsKCiAgICAgIC8vIGN1cnJlbnRseSBwcm90cmFjdG9yL3dlYmRyaXZlciBkb2VzIG5vdCBzdXBwb3J0CiAgICAgIC8vIHNlbmRpbmcga2V5cyB0byBhbGwga25vd24gSFRNTDUgaW5wdXQgY29udHJvbHMKICAgICAgLy8gZm9yIHZhcmlvdXMgYnJvd3NlcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL3Byb3RyYWN0b3IvaXNzdWVzLzU2MikuCiAgICAgIGZ1bmN0aW9uIHNldElucHV0KHZhbCkgewogICAgICAgIC8vIHNldCB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgYW5kIGZvcmNlIHZhbGlkYXRpb24uCiAgICAgICAgdmFyIHNjciA9ICJ2YXIgaXB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V4YW1wbGVJbnB1dCcpOyAiICsKICAgICAgICAiaXB0LnZhbHVlID0gJyIgKyB2YWwgKyAiJzsiICsKICAgICAgICAiYW5ndWxhci5lbGVtZW50KGlwdCkuc2NvcGUoKS4kYXBwbHkoZnVuY3Rpb24ocykgeyBzLm15Rm9ybVtpcHQubmFtZV0uJHNldFZpZXdWYWx1ZSgnIiArIHZhbCArICInKTsgfSk7IjsKICAgICAgICBicm93c2VyLmV4ZWN1dGVTY3JpcHQoc2NyKTsKICAgICAgfQoKICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcyMDEzLVcwMScpOwogICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignbXlGb3JtLmlucHV0LiR2YWxpZCA9IHRydWUnKTsKICAgICAgfSk7CgogICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgZW1wdHknLCBmdW5jdGlvbigpIHsKICAgICAgICBzZXRJbnB1dCgnJyk7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9FcXVhbCgndmFsdWUgPScpOwogICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignbXlGb3JtLmlucHV0LiR2YWxpZCA9IGZhbHNlJyk7CiAgICAgIH0pOwoKICAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIG92ZXIgbWF4JywgZnVuY3Rpb24oKSB7CiAgICAgICAgc2V0SW5wdXQoJzIwMTUtVzAxJyk7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcnKTsKICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ215Rm9ybS5pbnB1dC4kdmFsaWQgPSBmYWxzZScpOwogICAgICB9KTsKICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICAgICovCiAgJ3dlZWsnOiBjcmVhdGVEYXRlSW5wdXRUeXBlKCd3ZWVrJywgV0VFS19SRUdFWFAsIHdlZWtQYXJzZXIsICd5eXl5LVd3dycpLAoKICAvKioKICAgKiBAbmdkb2MgaW5wdXQKICAgKiBAbmFtZSBpbnB1dFttb250aF0KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIElucHV0IHdpdGggbW9udGggdmFsaWRhdGlvbiBhbmQgdHJhbnNmb3JtYXRpb24uIEluIGJyb3dzZXJzIHRoYXQgZG8gbm90IHlldCBzdXBwb3J0CiAgICogdGhlIEhUTUw1IG1vbnRoIGlucHV0LCBhIHRleHQgZWxlbWVudCB3aWxsIGJlIHVzZWQuIEluIHRoYXQgY2FzZSwgdGhlIHRleHQgbXVzdCBiZSBlbnRlcmVkIGluIGEgdmFsaWQgSVNPLTg2MDEKICAgKiBtb250aCBmb3JtYXQgKHl5eXktTU0pLCBmb3IgZXhhbXBsZTogYDIwMDktMDFgLgogICAqCiAgICogVGhlIG1vZGVsIG11c3QgYWx3YXlzIGJlIGEgRGF0ZSBvYmplY3QsIG90aGVyd2lzZSBBbmd1bGFyIHdpbGwgdGhyb3cgYW4gZXJyb3IuCiAgICogSW52YWxpZCBgRGF0ZWAgb2JqZWN0cyAoZGF0ZXMgd2hvc2UgYGdldFRpbWUoKWAgaXMgYE5hTmApIHdpbGwgYmUgcmVuZGVyZWQgYXMgYW4gZW1wdHkgc3RyaW5nLgogICAqIElmIHRoZSBtb2RlbCBpcyBub3Qgc2V0IHRvIHRoZSBmaXJzdCBvZiB0aGUgbW9udGgsIHRoZSBuZXh0IHZpZXcgdG8gbW9kZWwgdXBkYXRlIHdpbGwgc2V0IGl0CiAgICogdG8gdGhlIGZpcnN0IG9mIHRoZSBtb250aC4KICAgKgogICAqIFRoZSB0aW1lem9uZSB0byBiZSB1c2VkIHRvIHJlYWQvd3JpdGUgdGhlIGBEYXRlYCBpbnN0YW5jZSBpbiB0aGUgbW9kZWwgY2FuIGJlIGRlZmluZWQgdXNpbmcKICAgKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nTW9kZWxPcHRpb25zIG5nTW9kZWxPcHRpb25zfS4gQnkgZGVmYXVsdCwgdGhpcyBpcyB0aGUgdGltZXpvbmUgb2YgdGhlIGJyb3dzZXIuCiAgICoKICAgKiBAcGFyYW0ge3N0cmluZ30gbmdNb2RlbCBBc3NpZ25hYmxlIGFuZ3VsYXIgZXhwcmVzc2lvbiB0byBkYXRhLWJpbmQgdG8uCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIFByb3BlcnR5IG5hbWUgb2YgdGhlIGZvcm0gdW5kZXIgd2hpY2ggdGhlIGNvbnRyb2wgaXMgcHVibGlzaGVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbWluIFNldHMgdGhlIGBtaW5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGxlc3MgdGhhbiBgbWluYC4gVGhpcyBtdXN0IGJlCiAgICogYSB2YWxpZCBJU08gbW9udGggZm9ybWF0ICh5eXl5LU1NKS4KICAgKiBAcGFyYW0ge3N0cmluZz19IG1heCBTZXRzIHRoZSBgbWF4YCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZW50ZXJlZCBpcyBncmVhdGVyIHRoYW4gYG1heGAuIFRoaXMgbXVzdAogICAqIGJlIGEgdmFsaWQgSVNPIG1vbnRoIGZvcm1hdCAoeXl5eS1NTSkuCiAgICogQHBhcmFtIHtzdHJpbmc9fSByZXF1aXJlZCBTZXRzIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIG5vdCBlbnRlcmVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdSZXF1aXJlZCBBZGRzIGByZXF1aXJlZGAgYXR0cmlidXRlIGFuZCBgcmVxdWlyZWRgIHZhbGlkYXRpb24gY29uc3RyYWludCB0bwogICAqICAgIHRoZSBlbGVtZW50IHdoZW4gdGhlIG5nUmVxdWlyZWQgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS4gVXNlIGBuZ1JlcXVpcmVkYCBpbnN0ZWFkIG9mCiAgICogICAgYHJlcXVpcmVkYCB3aGVuIHlvdSB3YW50IHRvIGRhdGEtYmluZCB0byB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ0NoYW5nZSBBbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiBpbnB1dCBjaGFuZ2VzIGR1ZSB0byB1c2VyCiAgICogICAgaW50ZXJhY3Rpb24gd2l0aCB0aGUgaW5wdXQgZWxlbWVudC4KICAgKgogICAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG5hbWU9Im1vbnRoLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJtb250aEV4YW1wbGUiPgogICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICA8c2NyaXB0PgogICAgICBhbmd1bGFyLm1vZHVsZSgnbW9udGhFeGFtcGxlJywgW10pCiAgICAgICAgLmNvbnRyb2xsZXIoJ0RhdGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICRzY29wZS52YWx1ZSA9IG5ldyBEYXRlKDIwMTMsIDksIDEpOwogICAgICAgIH1dKTsKICAgICA8L3NjcmlwdD4KICAgICA8Zm9ybSBuYW1lPSJteUZvcm0iIG5nLWNvbnRyb2xsZXI9IkRhdGVDb250cm9sbGVyIGFzIGRhdGVDdHJsIj4KICAgICAgIFBpY2sgYSBtb250aCBpbnQgMjAxMzoKICAgICAgIDxpbnB1dCBpZD0iZXhhbXBsZUlucHV0IiB0eXBlPSJtb250aCIgbmFtZT0iaW5wdXQiIG5nLW1vZGVsPSJ2YWx1ZSIKICAgICAgICAgIHBsYWNlaG9sZGVyPSJ5eXl5LU1NIiBtaW49IjIwMTMtMDEiIG1heD0iMjAxMy0xMiIgcmVxdWlyZWQgLz4KICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci5yZXF1aXJlZCI+CiAgICAgICAgICBSZXF1aXJlZCE8L3NwYW4+CiAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5pbnB1dC4kZXJyb3IubW9udGgiPgogICAgICAgICAgTm90IGEgdmFsaWQgbW9udGghPC9zcGFuPgogICAgICAgPHR0PnZhbHVlID0ge3t2YWx1ZSB8IGRhdGU6ICJ5eXl5LU1NIn19PC90dD48YnIvPgogICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kdmFsaWQgPSB7e215Rm9ybS5pbnB1dC4kdmFsaWR9fTwvdHQ+PGJyLz4KICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJGVycm9yID0ge3tteUZvcm0uaW5wdXQuJGVycm9yfX08L3R0Pjxici8+CiAgICAgICA8dHQ+bXlGb3JtLiR2YWxpZCA9IHt7bXlGb3JtLiR2YWxpZH19PC90dD48YnIvPgogICAgICAgPHR0Pm15Rm9ybS4kZXJyb3IucmVxdWlyZWQgPSB7eyEhbXlGb3JtLiRlcnJvci5yZXF1aXJlZH19PC90dD48YnIvPgogICAgIDwvZm9ybT4KICAgPC9maWxlPgogICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgdmFyIHZhbHVlID0gZWxlbWVudChieS5iaW5kaW5nKCd2YWx1ZSB8IGRhdGU6ICJ5eXl5LU1NIicpKTsKICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICB2YXIgaW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd2YWx1ZScpKTsKCiAgICAgIC8vIGN1cnJlbnRseSBwcm90cmFjdG9yL3dlYmRyaXZlciBkb2VzIG5vdCBzdXBwb3J0CiAgICAgIC8vIHNlbmRpbmcga2V5cyB0byBhbGwga25vd24gSFRNTDUgaW5wdXQgY29udHJvbHMKICAgICAgLy8gZm9yIHZhcmlvdXMgYnJvd3NlcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL3Byb3RyYWN0b3IvaXNzdWVzLzU2MikuCiAgICAgIGZ1bmN0aW9uIHNldElucHV0KHZhbCkgewogICAgICAgIC8vIHNldCB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgYW5kIGZvcmNlIHZhbGlkYXRpb24uCiAgICAgICAgdmFyIHNjciA9ICJ2YXIgaXB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2V4YW1wbGVJbnB1dCcpOyAiICsKICAgICAgICAiaXB0LnZhbHVlID0gJyIgKyB2YWwgKyAiJzsiICsKICAgICAgICAiYW5ndWxhci5lbGVtZW50KGlwdCkuc2NvcGUoKS4kYXBwbHkoZnVuY3Rpb24ocykgeyBzLm15Rm9ybVtpcHQubmFtZV0uJHNldFZpZXdWYWx1ZSgnIiArIHZhbCArICInKTsgfSk7IjsKICAgICAgICBicm93c2VyLmV4ZWN1dGVTY3JpcHQoc2NyKTsKICAgICAgfQoKICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZXhwZWN0KHZhbHVlLmdldFRleHQoKSkudG9Db250YWluKCcyMDEzLTEwJyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gdHJ1ZScpOwogICAgICB9KTsKCiAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBlbXB0eScsIGZ1bmN0aW9uKCkgewogICAgICAgIHNldElucHV0KCcnKTsKICAgICAgICBleHBlY3QodmFsdWUuZ2V0VGV4dCgpKS50b0VxdWFsKCd2YWx1ZSA9Jyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gZmFsc2UnKTsKICAgICAgfSk7CgogICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgb3ZlciBtYXgnLCBmdW5jdGlvbigpIHsKICAgICAgICBzZXRJbnB1dCgnMjAxNS0wMScpOwogICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvQ29udGFpbignJyk7CiAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdteUZvcm0uaW5wdXQuJHZhbGlkID0gZmFsc2UnKTsKICAgICAgfSk7CiAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogICAqLwogICdtb250aCc6IGNyZWF0ZURhdGVJbnB1dFR5cGUoJ21vbnRoJywgTU9OVEhfUkVHRVhQLAogICAgIGNyZWF0ZURhdGVQYXJzZXIoTU9OVEhfUkVHRVhQLCBbJ3l5eXknLCAnTU0nXSksCiAgICAgJ3l5eXktTU0nKSwKCiAgLyoqCiAgICogQG5nZG9jIGlucHV0CiAgICogQG5hbWUgaW5wdXRbbnVtYmVyXQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogVGV4dCBpbnB1dCB3aXRoIG51bWJlciB2YWxpZGF0aW9uIGFuZCB0cmFuc2Zvcm1hdGlvbi4gU2V0cyB0aGUgYG51bWJlcmAgdmFsaWRhdGlvbgogICAqIGVycm9yIGlmIG5vdCBhIHZhbGlkIG51bWJlci4KICAgKgogICAqIFRoZSBtb2RlbCBtdXN0IGFsd2F5cyBiZSBhIG51bWJlciwgb3RoZXJ3aXNlIEFuZ3VsYXIgd2lsbCB0aHJvdyBhbiBlcnJvci4KICAgKgogICAqIEBwYXJhbSB7c3RyaW5nfSBuZ01vZGVsIEFzc2lnbmFibGUgYW5ndWxhciBleHByZXNzaW9uIHRvIGRhdGEtYmluZCB0by4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgUHJvcGVydHkgbmFtZSBvZiB0aGUgZm9ybSB1bmRlciB3aGljaCB0aGUgY29udHJvbCBpcyBwdWJsaXNoZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBtaW4gU2V0cyB0aGUgYG1pbmAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGVudGVyZWQgaXMgbGVzcyB0aGFuIGBtaW5gLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbWF4IFNldHMgdGhlIGBtYXhgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBlbnRlcmVkIGlzIGdyZWF0ZXIgdGhhbiBgbWF4YC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHJlcXVpcmVkIFNldHMgYHJlcXVpcmVkYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgaXMgbm90IGVudGVyZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAgICogICAgdGhlIGVsZW1lbnQgd2hlbiB0aGUgbmdSZXF1aXJlZCBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLiBVc2UgYG5nUmVxdWlyZWRgIGluc3RlYWQgb2YKICAgKiAgICBgcmVxdWlyZWRgIHdoZW4geW91IHdhbnQgdG8gZGF0YS1iaW5kIHRvIHRoZSBgcmVxdWlyZWRgIGF0dHJpYnV0ZS4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWlubGVuZ3RoIFNldHMgYG1pbmxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIHNob3J0ZXIgdGhhbgogICAqICAgIG1pbmxlbmd0aC4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWF4bGVuZ3RoIFNldHMgYG1heGxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIGxvbmdlciB0aGFuCiAgICogICAgbWF4bGVuZ3RoLiBTZXR0aW5nIHRoZSBhdHRyaWJ1dGUgdG8gYSBuZWdhdGl2ZSBvciBub24tbnVtZXJpYyB2YWx1ZSwgYWxsb3dzIHZpZXcgdmFsdWVzIG9mCiAgICogICAgYW55IGxlbmd0aC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHBhdHRlcm4gU2ltaWxhciB0byBgbmdQYXR0ZXJuYCBleGNlcHQgdGhhdCB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIHRoZSBhY3R1YWwgc3RyaW5nCiAgICogICAgdGhhdCBjb250YWlucyB0aGUgcmVndWxhciBleHByZXNzaW9uIGJvZHkgdGhhdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIHJlZ3VsYXIgZXhwcmVzc2lvbgogICAqICAgIGFzIGluIHRoZSBuZ1BhdHRlcm4gZGlyZWN0aXZlLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdQYXR0ZXJuIFNldHMgYHBhdHRlcm5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSBuZ01vZGVsIHZhbHVlIGRvZXMgbm90IG1hdGNoCiAgICogICAgYSBSZWdFeHAgZm91bmQgYnkgZXZhbHVhdGluZyB0aGUgQW5ndWxhciBleHByZXNzaW9uIGdpdmVuIGluIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCiAgICogICAgSWYgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGEgUmVnRXhwIG9iamVjdCB0aGVuIHRoaXMgaXMgdXNlZCBkaXJlY3RseS4KICAgKiAgICBJZiB0aGUgZXhwcmVzc2lvbiBpcyBhIHN0cmluZyB0aGVuIGl0IHdpbGwgYmUgY29udmVydGVkIHRvIGEgUmVnRXhwIGFmdGVyIHdyYXBwaW5nIGl0IGluIGBeYCBhbmQgYCRgCiAgICogICAgY2hhcmFjdGVycy4gRm9yIGluc3RhbmNlLCBgImFiYyJgIHdpbGwgYmUgY29udmVydGVkIHRvIGBuZXcgUmVnRXhwKCdeYWJjJCcpYC4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgKiAgICBpbnRlcmFjdGlvbiB3aXRoIHRoZSBpbnB1dCBlbGVtZW50LgogICAqCiAgICogQGV4YW1wbGUKICAgICAgPGV4YW1wbGUgbmFtZT0ibnVtYmVyLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJudW1iZXJFeGFtcGxlIj4KICAgICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICBhbmd1bGFyLm1vZHVsZSgnbnVtYmVyRXhhbXBsZScsIFtdKQogICAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICAgJHNjb3BlLnZhbHVlID0gMTI7CiAgICAgICAgICAgICB9XSk7CiAgICAgICAgIDwvc2NyaXB0PgogICAgICAgICA8Zm9ybSBuYW1lPSJteUZvcm0iIG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICAgICBOdW1iZXI6IDxpbnB1dCB0eXBlPSJudW1iZXIiIG5hbWU9ImlucHV0IiBuZy1tb2RlbD0idmFsdWUiCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWluPSIwIiBtYXg9Ijk5IiByZXF1aXJlZD4KICAgICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5pbnB1dC4kZXJyb3IucmVxdWlyZWQiPgogICAgICAgICAgICAgUmVxdWlyZWQhPC9zcGFuPgogICAgICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci5udW1iZXIiPgogICAgICAgICAgICAgTm90IHZhbGlkIG51bWJlciE8L3NwYW4+CiAgICAgICAgICAgPHR0PnZhbHVlID0ge3t2YWx1ZX19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJHZhbGlkID0ge3tteUZvcm0uaW5wdXQuJHZhbGlkfX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kZXJyb3IgPSB7e215Rm9ybS5pbnB1dC4kZXJyb3J9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLiR2YWxpZCA9IHt7bXlGb3JtLiR2YWxpZH19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uJGVycm9yLnJlcXVpcmVkID0ge3shIW15Rm9ybS4kZXJyb3IucmVxdWlyZWR9fTwvdHQ+PGJyLz4KICAgICAgICAgIDwvZm9ybT4KICAgICAgICA8L2ZpbGU+CiAgICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgICB2YXIgdmFsdWUgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ3ZhbHVlJykpOwogICAgICAgICAgdmFyIHZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uaW5wdXQuJHZhbGlkJykpOwogICAgICAgICAgdmFyIGlucHV0ID0gZWxlbWVudChieS5tb2RlbCgndmFsdWUnKSk7CgogICAgICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvQ29udGFpbignMTInKTsKICAgICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAgICAgICAgICB9KTsKCiAgICAgICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgZW1wdHknLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaW5wdXQuY2xlYXIoKTsKICAgICAgICAgICAgaW5wdXQuc2VuZEtleXMoJycpOwogICAgICAgICAgICBleHBlY3QodmFsdWUuZ2V0VGV4dCgpKS50b0VxdWFsKCd2YWx1ZSA9Jyk7CiAgICAgICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICAgIH0pOwoKICAgICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBvdmVyIG1heCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpbnB1dC5jbGVhcigpOwogICAgICAgICAgICBpbnB1dC5zZW5kS2V5cygnMTIzJyk7CiAgICAgICAgICAgIGV4cGVjdCh2YWx1ZS5nZXRUZXh0KCkpLnRvRXF1YWwoJ3ZhbHVlID0nKTsKICAgICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdmYWxzZScpOwogICAgICAgICAgfSk7CiAgICAgICAgPC9maWxlPgogICAgICA8L2V4YW1wbGU+CiAgICovCiAgJ251bWJlcic6IG51bWJlcklucHV0VHlwZSwKCgogIC8qKgogICAqIEBuZ2RvYyBpbnB1dAogICAqIEBuYW1lIGlucHV0W3VybF0KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRleHQgaW5wdXQgd2l0aCBVUkwgdmFsaWRhdGlvbi4gU2V0cyB0aGUgYHVybGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIGNvbnRlbnQgaXMgbm90IGEKICAgKiB2YWxpZCBVUkwuCiAgICoKICAgKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICAgKiAqKk5vdGU6KiogYGlucHV0W3VybF1gIHVzZXMgYSByZWdleCB0byB2YWxpZGF0ZSB1cmxzIHRoYXQgaXMgZGVyaXZlZCBmcm9tIHRoZSByZWdleAogICAqIHVzZWQgaW4gQ2hyb21pdW0uIElmIHlvdSBuZWVkIHN0cmljdGVyIHZhbGlkYXRpb24sIHlvdSBjYW4gdXNlIGBuZy1wYXR0ZXJuYCBvciBtb2RpZnkKICAgKiB0aGUgYnVpbHQtaW4gdmFsaWRhdG9ycyAoc2VlIHRoZSB7QGxpbmsgZ3VpZGUvZm9ybXMgRm9ybXMgZ3VpZGV9KQogICAqIDwvZGl2PgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHJlcXVpcmVkIFNldHMgYHJlcXVpcmVkYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgaXMgbm90IGVudGVyZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAgICogICAgdGhlIGVsZW1lbnQgd2hlbiB0aGUgbmdSZXF1aXJlZCBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLiBVc2UgYG5nUmVxdWlyZWRgIGluc3RlYWQgb2YKICAgKiAgICBgcmVxdWlyZWRgIHdoZW4geW91IHdhbnQgdG8gZGF0YS1iaW5kIHRvIHRoZSBgcmVxdWlyZWRgIGF0dHJpYnV0ZS4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWlubGVuZ3RoIFNldHMgYG1pbmxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIHNob3J0ZXIgdGhhbgogICAqICAgIG1pbmxlbmd0aC4KICAgKiBAcGFyYW0ge251bWJlcj19IG5nTWF4bGVuZ3RoIFNldHMgYG1heGxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIGxvbmdlciB0aGFuCiAgICogICAgbWF4bGVuZ3RoLiBTZXR0aW5nIHRoZSBhdHRyaWJ1dGUgdG8gYSBuZWdhdGl2ZSBvciBub24tbnVtZXJpYyB2YWx1ZSwgYWxsb3dzIHZpZXcgdmFsdWVzIG9mCiAgICogICAgYW55IGxlbmd0aC4KICAgKiBAcGFyYW0ge3N0cmluZz19IHBhdHRlcm4gU2ltaWxhciB0byBgbmdQYXR0ZXJuYCBleGNlcHQgdGhhdCB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIHRoZSBhY3R1YWwgc3RyaW5nCiAgICogICAgdGhhdCBjb250YWlucyB0aGUgcmVndWxhciBleHByZXNzaW9uIGJvZHkgdGhhdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIHJlZ3VsYXIgZXhwcmVzc2lvbgogICAqICAgIGFzIGluIHRoZSBuZ1BhdHRlcm4gZGlyZWN0aXZlLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdQYXR0ZXJuIFNldHMgYHBhdHRlcm5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSBuZ01vZGVsIHZhbHVlIGRvZXMgbm90IG1hdGNoCiAgICogICAgYSBSZWdFeHAgZm91bmQgYnkgZXZhbHVhdGluZyB0aGUgQW5ndWxhciBleHByZXNzaW9uIGdpdmVuIGluIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCiAgICogICAgSWYgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGEgUmVnRXhwIG9iamVjdCB0aGVuIHRoaXMgaXMgdXNlZCBkaXJlY3RseS4KICAgKiAgICBJZiB0aGUgZXhwcmVzc2lvbiBpcyBhIHN0cmluZyB0aGVuIGl0IHdpbGwgYmUgY29udmVydGVkIHRvIGEgUmVnRXhwIGFmdGVyIHdyYXBwaW5nIGl0IGluIGBeYCBhbmQgYCRgCiAgICogICAgY2hhcmFjdGVycy4gRm9yIGluc3RhbmNlLCBgImFiYyJgIHdpbGwgYmUgY29udmVydGVkIHRvIGBuZXcgUmVnRXhwKCdeYWJjJCcpYC4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgKiAgICBpbnRlcmFjdGlvbiB3aXRoIHRoZSBpbnB1dCBlbGVtZW50LgogICAqCiAgICogQGV4YW1wbGUKICAgICAgPGV4YW1wbGUgbmFtZT0idXJsLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJ1cmxFeGFtcGxlIj4KICAgICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICBhbmd1bGFyLm1vZHVsZSgndXJsRXhhbXBsZScsIFtdKQogICAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICAgJHNjb3BlLnRleHQgPSAnaHR0cDovL2dvb2dsZS5jb20nOwogICAgICAgICAgICAgfV0pOwogICAgICAgICA8L3NjcmlwdD4KICAgICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgICAgVVJMOiA8aW5wdXQgdHlwZT0idXJsIiBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InRleHQiIHJlcXVpcmVkPgogICAgICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLmlucHV0LiRlcnJvci5yZXF1aXJlZCI+CiAgICAgICAgICAgICBSZXF1aXJlZCE8L3NwYW4+CiAgICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnVybCI+CiAgICAgICAgICAgICBOb3QgdmFsaWQgdXJsITwvc3Bhbj4KICAgICAgICAgICA8dHQ+dGV4dCA9IHt7dGV4dH19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uaW5wdXQuJHZhbGlkID0ge3tteUZvcm0uaW5wdXQuJHZhbGlkfX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kZXJyb3IgPSB7e215Rm9ybS5pbnB1dC4kZXJyb3J9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLiR2YWxpZCA9IHt7bXlGb3JtLiR2YWxpZH19PC90dD48YnIvPgogICAgICAgICAgIDx0dD5teUZvcm0uJGVycm9yLnJlcXVpcmVkID0ge3shIW15Rm9ybS4kZXJyb3IucmVxdWlyZWR9fTwvdHQ+PGJyLz4KICAgICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci51cmwgPSB7eyEhbXlGb3JtLiRlcnJvci51cmx9fTwvdHQ+PGJyLz4KICAgICAgICAgIDwvZm9ybT4KICAgICAgICA8L2ZpbGU+CiAgICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgICB2YXIgdGV4dCA9IGVsZW1lbnQoYnkuYmluZGluZygndGV4dCcpKTsKICAgICAgICAgIHZhciB2YWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmlucHV0LiR2YWxpZCcpKTsKICAgICAgICAgIHZhciBpbnB1dCA9IGVsZW1lbnQoYnkubW9kZWwoJ3RleHQnKSk7CgogICAgICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGV4cGVjdCh0ZXh0LmdldFRleHQoKSkudG9Db250YWluKCdodHRwOi8vZ29vZ2xlLmNvbScpOwogICAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3RydWUnKTsKICAgICAgICAgIH0pOwoKICAgICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBlbXB0eScsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpbnB1dC5jbGVhcigpOwogICAgICAgICAgICBpbnB1dC5zZW5kS2V5cygnJyk7CgogICAgICAgICAgICBleHBlY3QodGV4dC5nZXRUZXh0KCkpLnRvRXF1YWwoJ3RleHQgPScpOwogICAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgICB9KTsKCiAgICAgICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgbm90IHVybCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpbnB1dC5jbGVhcigpOwogICAgICAgICAgICBpbnB1dC5zZW5kS2V5cygnYm94Jyk7CgogICAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgICB9KTsKICAgICAgICA8L2ZpbGU+CiAgICAgIDwvZXhhbXBsZT4KICAgKi8KICAndXJsJzogdXJsSW5wdXRUeXBlLAoKCiAgLyoqCiAgICogQG5nZG9jIGlucHV0CiAgICogQG5hbWUgaW5wdXRbZW1haWxdCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBUZXh0IGlucHV0IHdpdGggZW1haWwgdmFsaWRhdGlvbi4gU2V0cyB0aGUgYGVtYWlsYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiBub3QgYSB2YWxpZCBlbWFpbAogICAqIGFkZHJlc3MuCiAgICoKICAgKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICAgKiAqKk5vdGU6KiogYGlucHV0W2VtYWlsXWAgdXNlcyBhIHJlZ2V4IHRvIHZhbGlkYXRlIGVtYWlsIGFkZHJlc3NlcyB0aGF0IGlzIGRlcml2ZWQgZnJvbSB0aGUgcmVnZXgKICAgKiB1c2VkIGluIENocm9taXVtLiBJZiB5b3UgbmVlZCBzdHJpY3RlciB2YWxpZGF0aW9uIChlLmcuIHJlcXVpcmluZyBhIHRvcC1sZXZlbCBkb21haW4pLCB5b3UgY2FuCiAgICogdXNlIGBuZy1wYXR0ZXJuYCBvciBtb2RpZnkgdGhlIGJ1aWx0LWluIHZhbGlkYXRvcnMgKHNlZSB0aGUge0BsaW5rIGd1aWRlL2Zvcm1zIEZvcm1zIGd1aWRlfSkKICAgKiA8L2Rpdj4KICAgKgogICAqIEBwYXJhbSB7c3RyaW5nfSBuZ01vZGVsIEFzc2lnbmFibGUgYW5ndWxhciBleHByZXNzaW9uIHRvIGRhdGEtYmluZCB0by4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgUHJvcGVydHkgbmFtZSBvZiB0aGUgZm9ybSB1bmRlciB3aGljaCB0aGUgY29udHJvbCBpcyBwdWJsaXNoZWQuCiAgICogQHBhcmFtIHtzdHJpbmc9fSByZXF1aXJlZCBTZXRzIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIG5vdCBlbnRlcmVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmdSZXF1aXJlZCBBZGRzIGByZXF1aXJlZGAgYXR0cmlidXRlIGFuZCBgcmVxdWlyZWRgIHZhbGlkYXRpb24gY29uc3RyYWludCB0bwogICAqICAgIHRoZSBlbGVtZW50IHdoZW4gdGhlIG5nUmVxdWlyZWQgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS4gVXNlIGBuZ1JlcXVpcmVkYCBpbnN0ZWFkIG9mCiAgICogICAgYHJlcXVpcmVkYCB3aGVuIHlvdSB3YW50IHRvIGRhdGEtYmluZCB0byB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUuCiAgICogQHBhcmFtIHtudW1iZXI9fSBuZ01pbmxlbmd0aCBTZXRzIGBtaW5sZW5ndGhgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBpcyBzaG9ydGVyIHRoYW4KICAgKiAgICBtaW5sZW5ndGguCiAgICogQHBhcmFtIHtudW1iZXI9fSBuZ01heGxlbmd0aCBTZXRzIGBtYXhsZW5ndGhgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBpcyBsb25nZXIgdGhhbgogICAqICAgIG1heGxlbmd0aC4gU2V0dGluZyB0aGUgYXR0cmlidXRlIHRvIGEgbmVnYXRpdmUgb3Igbm9uLW51bWVyaWMgdmFsdWUsIGFsbG93cyB2aWV3IHZhbHVlcyBvZgogICAqICAgIGFueSBsZW5ndGguCiAgICogQHBhcmFtIHtzdHJpbmc9fSBwYXR0ZXJuIFNpbWlsYXIgdG8gYG5nUGF0dGVybmAgZXhjZXB0IHRoYXQgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyB0aGUgYWN0dWFsIHN0cmluZwogICAqICAgIHRoYXQgY29udGFpbnMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBib2R5IHRoYXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYSByZWd1bGFyIGV4cHJlc3Npb24KICAgKiAgICBhcyBpbiB0aGUgbmdQYXR0ZXJuIGRpcmVjdGl2ZS4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nUGF0dGVybiBTZXRzIGBwYXR0ZXJuYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgbmdNb2RlbCB2YWx1ZSBkb2VzIG5vdCBtYXRjaAogICAqICAgIGEgUmVnRXhwIGZvdW5kIGJ5IGV2YWx1YXRpbmcgdGhlIEFuZ3VsYXIgZXhwcmVzc2lvbiBnaXZlbiBpbiB0aGUgYXR0cmlidXRlIHZhbHVlLgogICAqICAgIElmIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBhIFJlZ0V4cCBvYmplY3QgdGhlbiB0aGlzIGlzIHVzZWQgZGlyZWN0bHkuCiAgICogICAgSWYgdGhlIGV4cHJlc3Npb24gaXMgYSBzdHJpbmcgdGhlbiBpdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIFJlZ0V4cCBhZnRlciB3cmFwcGluZyBpdCBpbiBgXmAgYW5kIGAkYAogICAqICAgIGNoYXJhY3RlcnMuIEZvciBpbnN0YW5jZSwgYCJhYmMiYCB3aWxsIGJlIGNvbnZlcnRlZCB0byBgbmV3IFJlZ0V4cCgnXmFiYyQnKWAuCiAgICogQHBhcmFtIHtzdHJpbmc9fSBuZ0NoYW5nZSBBbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiBpbnB1dCBjaGFuZ2VzIGR1ZSB0byB1c2VyCiAgICogICAgaW50ZXJhY3Rpb24gd2l0aCB0aGUgaW5wdXQgZWxlbWVudC4KICAgKgogICAqIEBleGFtcGxlCiAgICAgIDxleGFtcGxlIG5hbWU9ImVtYWlsLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJlbWFpbEV4YW1wbGUiPgogICAgICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgICA8c2NyaXB0PgogICAgICAgICAgIGFuZ3VsYXIubW9kdWxlKCdlbWFpbEV4YW1wbGUnLCBbXSkKICAgICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAgICRzY29wZS50ZXh0ID0gJ21lQGV4YW1wbGUuY29tJzsKICAgICAgICAgICAgIH1dKTsKICAgICAgICAgPC9zY3JpcHQ+CiAgICAgICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgICAgICBFbWFpbDogPGlucHV0IHR5cGU9ImVtYWlsIiBuYW1lPSJpbnB1dCIgbmctbW9kZWw9InRleHQiIHJlcXVpcmVkPgogICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLnJlcXVpcmVkIj4KICAgICAgICAgICAgICAgUmVxdWlyZWQhPC9zcGFuPgogICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0uaW5wdXQuJGVycm9yLmVtYWlsIj4KICAgICAgICAgICAgICAgTm90IHZhbGlkIGVtYWlsITwvc3Bhbj4KICAgICAgICAgICAgIDx0dD50ZXh0ID0ge3t0ZXh0fX08L3R0Pjxici8+CiAgICAgICAgICAgICA8dHQ+bXlGb3JtLmlucHV0LiR2YWxpZCA9IHt7bXlGb3JtLmlucHV0LiR2YWxpZH19PC90dD48YnIvPgogICAgICAgICAgICAgPHR0Pm15Rm9ybS5pbnB1dC4kZXJyb3IgPSB7e215Rm9ybS5pbnB1dC4kZXJyb3J9fTwvdHQ+PGJyLz4KICAgICAgICAgICAgIDx0dD5teUZvcm0uJHZhbGlkID0ge3tteUZvcm0uJHZhbGlkfX08L3R0Pjxici8+CiAgICAgICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5yZXF1aXJlZCA9IHt7ISFteUZvcm0uJGVycm9yLnJlcXVpcmVkfX08L3R0Pjxici8+CiAgICAgICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5lbWFpbCA9IHt7ISFteUZvcm0uJGVycm9yLmVtYWlsfX08L3R0Pjxici8+CiAgICAgICAgICAgPC9mb3JtPgogICAgICAgICA8L2ZpbGU+CiAgICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgICB2YXIgdGV4dCA9IGVsZW1lbnQoYnkuYmluZGluZygndGV4dCcpKTsKICAgICAgICAgIHZhciB2YWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmlucHV0LiR2YWxpZCcpKTsKICAgICAgICAgIHZhciBpbnB1dCA9IGVsZW1lbnQoYnkubW9kZWwoJ3RleHQnKSk7CgogICAgICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGV4cGVjdCh0ZXh0LmdldFRleHQoKSkudG9Db250YWluKCdtZUBleGFtcGxlLmNvbScpOwogICAgICAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3RydWUnKTsKICAgICAgICAgIH0pOwoKICAgICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBlbXB0eScsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpbnB1dC5jbGVhcigpOwogICAgICAgICAgICBpbnB1dC5zZW5kS2V5cygnJyk7CiAgICAgICAgICAgIGV4cGVjdCh0ZXh0LmdldFRleHQoKSkudG9FcXVhbCgndGV4dCA9Jyk7CiAgICAgICAgICAgIGV4cGVjdCh2YWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICAgIH0pOwoKICAgICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBub3QgZW1haWwnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaW5wdXQuY2xlYXIoKTsKICAgICAgICAgICAgaW5wdXQuc2VuZEtleXMoJ3h4eCcpOwoKICAgICAgICAgICAgZXhwZWN0KHZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdmYWxzZScpOwogICAgICAgICAgfSk7CiAgICAgICAgPC9maWxlPgogICAgICA8L2V4YW1wbGU+CiAgICovCiAgJ2VtYWlsJzogZW1haWxJbnB1dFR5cGUsCgoKICAvKioKICAgKiBAbmdkb2MgaW5wdXQKICAgKiBAbmFtZSBpbnB1dFtyYWRpb10KICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIEhUTUwgcmFkaW8gYnV0dG9uLgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gc2hvdWxkIGJlIHNldCB3aGVuIHNlbGVjdGVkLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgKiAgICBpbnRlcmFjdGlvbiB3aXRoIHRoZSBpbnB1dCBlbGVtZW50LgogICAqIEBwYXJhbSB7c3RyaW5nfSBuZ1ZhbHVlIEFuZ3VsYXIgZXhwcmVzc2lvbiB3aGljaCBzZXRzIHRoZSB2YWx1ZSB0byB3aGljaCB0aGUgZXhwcmVzc2lvbiBzaG91bGQKICAgKiAgICBiZSBzZXQgd2hlbiBzZWxlY3RlZC4KICAgKgogICAqIEBleGFtcGxlCiAgICAgIDxleGFtcGxlIG5hbWU9InJhZGlvLWlucHV0LWRpcmVjdGl2ZSIgbW9kdWxlPSJyYWRpb0V4YW1wbGUiPgogICAgICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgICA8c2NyaXB0PgogICAgICAgICAgIGFuZ3VsYXIubW9kdWxlKCdyYWRpb0V4YW1wbGUnLCBbXSkKICAgICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAgICRzY29wZS5jb2xvciA9ICdibHVlJzsKICAgICAgICAgICAgICAgJHNjb3BlLnNwZWNpYWxWYWx1ZSA9IHsKICAgICAgICAgICAgICAgICAiaWQiOiAiMTIzNDUiLAogICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJncmVlbiIKICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgIH1dKTsKICAgICAgICAgPC9zY3JpcHQ+CiAgICAgICAgIDxmb3JtIG5hbWU9Im15Rm9ybSIgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmctbW9kZWw9ImNvbG9yIiB2YWx1ZT0icmVkIj4gIFJlZCA8YnIvPgogICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmctbW9kZWw9ImNvbG9yIiBuZy12YWx1ZT0ic3BlY2lhbFZhbHVlIj4gR3JlZW4gPGJyLz4KICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5nLW1vZGVsPSJjb2xvciIgdmFsdWU9ImJsdWUiPiBCbHVlIDxici8+CiAgICAgICAgICAgPHR0PmNvbG9yID0ge3tjb2xvciB8IGpzb259fTwvdHQ+PGJyLz4KICAgICAgICAgIDwvZm9ybT4KICAgICAgICAgIE5vdGUgdGhhdCBgbmctdmFsdWU9InNwZWNpYWxWYWx1ZSJgIHNldHMgcmFkaW8gaXRlbSdzIHZhbHVlIHRvIGJlIHRoZSB2YWx1ZSBvZiBgJHNjb3BlLnNwZWNpYWxWYWx1ZWAuCiAgICAgICAgPC9maWxlPgogICAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgICAgaXQoJ3Nob3VsZCBjaGFuZ2Ugc3RhdGUnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNvbG9yID0gZWxlbWVudChieS5iaW5kaW5nKCdjb2xvcicpKTsKCiAgICAgICAgICAgIGV4cGVjdChjb2xvci5nZXRUZXh0KCkpLnRvQ29udGFpbignYmx1ZScpOwoKICAgICAgICAgICAgZWxlbWVudC5hbGwoYnkubW9kZWwoJ2NvbG9yJykpLmdldCgwKS5jbGljaygpOwoKICAgICAgICAgICAgZXhwZWN0KGNvbG9yLmdldFRleHQoKSkudG9Db250YWluKCdyZWQnKTsKICAgICAgICAgIH0pOwogICAgICAgIDwvZmlsZT4KICAgICAgPC9leGFtcGxlPgogICAqLwogICdyYWRpbyc6IHJhZGlvSW5wdXRUeXBlLAoKCiAgLyoqCiAgICogQG5nZG9jIGlucHV0CiAgICogQG5hbWUgaW5wdXRbY2hlY2tib3hdCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBIVE1MIGNoZWNrYm94LgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogICAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICAgKiBAcGFyYW0ge2V4cHJlc3Npb249fSBuZ1RydWVWYWx1ZSBUaGUgdmFsdWUgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gc2hvdWxkIGJlIHNldCB3aGVuIHNlbGVjdGVkLgogICAqIEBwYXJhbSB7ZXhwcmVzc2lvbj19IG5nRmFsc2VWYWx1ZSBUaGUgdmFsdWUgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gc2hvdWxkIGJlIHNldCB3aGVuIG5vdCBzZWxlY3RlZC4KICAgKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICAgKiAgICBpbnRlcmFjdGlvbiB3aXRoIHRoZSBpbnB1dCBlbGVtZW50LgogICAqCiAgICogQGV4YW1wbGUKICAgICAgPGV4YW1wbGUgbmFtZT0iY2hlY2tib3gtaW5wdXQtZGlyZWN0aXZlIiBtb2R1bGU9ImNoZWNrYm94RXhhbXBsZSI+CiAgICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgIDxzY3JpcHQ+CiAgICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ2NoZWNrYm94RXhhbXBsZScsIFtdKQogICAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICAgJHNjb3BlLnZhbHVlMSA9IHRydWU7CiAgICAgICAgICAgICAgICRzY29wZS52YWx1ZTIgPSAnWUVTJwogICAgICAgICAgICAgfV0pOwogICAgICAgICA8L3NjcmlwdD4KICAgICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgICAgVmFsdWUxOiA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJ2YWx1ZTEiPiA8YnIvPgogICAgICAgICAgIFZhbHVlMjogPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0idmFsdWUyIgogICAgICAgICAgICAgICAgICAgICAgICAgIG5nLXRydWUtdmFsdWU9IidZRVMnIiBuZy1mYWxzZS12YWx1ZT0iJ05PJyI+IDxici8+CiAgICAgICAgICAgPHR0PnZhbHVlMSA9IHt7dmFsdWUxfX08L3R0Pjxici8+CiAgICAgICAgICAgPHR0PnZhbHVlMiA9IHt7dmFsdWUyfX08L3R0Pjxici8+CiAgICAgICAgICA8L2Zvcm0+CiAgICAgICAgPC9maWxlPgogICAgICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgICAgaXQoJ3Nob3VsZCBjaGFuZ2Ugc3RhdGUnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHZhbHVlMSA9IGVsZW1lbnQoYnkuYmluZGluZygndmFsdWUxJykpOwogICAgICAgICAgICB2YXIgdmFsdWUyID0gZWxlbWVudChieS5iaW5kaW5nKCd2YWx1ZTInKSk7CgogICAgICAgICAgICBleHBlY3QodmFsdWUxLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAgICAgICAgICAgIGV4cGVjdCh2YWx1ZTIuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ1lFUycpOwoKICAgICAgICAgICAgZWxlbWVudChieS5tb2RlbCgndmFsdWUxJykpLmNsaWNrKCk7CiAgICAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3ZhbHVlMicpKS5jbGljaygpOwoKICAgICAgICAgICAgZXhwZWN0KHZhbHVlMS5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICAgICAgZXhwZWN0KHZhbHVlMi5nZXRUZXh0KCkpLnRvQ29udGFpbignTk8nKTsKICAgICAgICAgIH0pOwogICAgICAgIDwvZmlsZT4KICAgICAgPC9leGFtcGxlPgogICAqLwogICdjaGVja2JveCc6IGNoZWNrYm94SW5wdXRUeXBlLAoKICAnaGlkZGVuJzogbm9vcCwKICAnYnV0dG9uJzogbm9vcCwKICAnc3VibWl0Jzogbm9vcCwKICAncmVzZXQnOiBub29wLAogICdmaWxlJzogbm9vcAp9OwoKZnVuY3Rpb24gc3RyaW5nQmFzZWRJbnB1dFR5cGUoY3RybCkgewogIGN0cmwuJGZvcm1hdHRlcnMucHVzaChmdW5jdGlvbih2YWx1ZSkgewogICAgcmV0dXJuIGN0cmwuJGlzRW1wdHkodmFsdWUpID8gdmFsdWUgOiB2YWx1ZS50b1N0cmluZygpOwogIH0pOwp9CgpmdW5jdGlvbiB0ZXh0SW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIpIHsKICBiYXNlSW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIpOwogIHN0cmluZ0Jhc2VkSW5wdXRUeXBlKGN0cmwpOwp9CgpmdW5jdGlvbiBiYXNlSW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIpIHsKICB2YXIgdHlwZSA9IGxvd2VyY2FzZShlbGVtZW50WzBdLnR5cGUpOwoKICAvLyBJbiBjb21wb3NpdGlvbiBtb2RlLCB1c2VycyBhcmUgc3RpbGwgaW5wdXRpbmcgaW50ZXJtZWRpYXRlIHRleHQgYnVmZmVyLAogIC8vIGhvbGQgdGhlIGxpc3RlbmVyIHVudGlsIGNvbXBvc2l0aW9uIGlzIGRvbmUuCiAgLy8gTW9yZSBhYm91dCBjb21wb3NpdGlvbiBldmVudHM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Db21wb3NpdGlvbkV2ZW50CiAgaWYgKCEkc25pZmZlci5hbmRyb2lkKSB7CiAgICB2YXIgY29tcG9zaW5nID0gZmFsc2U7CgogICAgZWxlbWVudC5vbignY29tcG9zaXRpb25zdGFydCcsIGZ1bmN0aW9uKGRhdGEpIHsKICAgICAgY29tcG9zaW5nID0gdHJ1ZTsKICAgIH0pOwoKICAgIGVsZW1lbnQub24oJ2NvbXBvc2l0aW9uZW5kJywgZnVuY3Rpb24oKSB7CiAgICAgIGNvbXBvc2luZyA9IGZhbHNlOwogICAgICBsaXN0ZW5lcigpOwogICAgfSk7CiAgfQoKICB2YXIgbGlzdGVuZXIgPSBmdW5jdGlvbihldikgewogICAgaWYgKHRpbWVvdXQpIHsKICAgICAgJGJyb3dzZXIuZGVmZXIuY2FuY2VsKHRpbWVvdXQpOwogICAgICB0aW1lb3V0ID0gbnVsbDsKICAgIH0KICAgIGlmIChjb21wb3NpbmcpIHJldHVybjsKICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQudmFsKCksCiAgICAgICAgZXZlbnQgPSBldiAmJiBldi50eXBlOwoKICAgIC8vIEJ5IGRlZmF1bHQgd2Ugd2lsbCB0cmltIHRoZSB2YWx1ZQogICAgLy8gSWYgdGhlIGF0dHJpYnV0ZSBuZy10cmltIGV4aXN0cyB3ZSB3aWxsIGF2b2lkIHRyaW1taW5nCiAgICAvLyBJZiBpbnB1dCB0eXBlIGlzICdwYXNzd29yZCcsIHRoZSB2YWx1ZSBpcyBuZXZlciB0cmltbWVkCiAgICBpZiAodHlwZSAhPT0gJ3Bhc3N3b3JkJyAmJiAoIWF0dHIubmdUcmltIHx8IGF0dHIubmdUcmltICE9PSAnZmFsc2UnKSkgewogICAgICB2YWx1ZSA9IHRyaW0odmFsdWUpOwogICAgfQoKICAgIC8vIElmIGEgY29udHJvbCBpcyBzdWZmZXJpbmcgZnJvbSBiYWQgaW5wdXQgKGR1ZSB0byBuYXRpdmUgdmFsaWRhdG9ycyksIGJyb3dzZXJzIGRpc2NhcmQgaXRzCiAgICAvLyB2YWx1ZSwgc28gaXQgbWF5IGJlIG5lY2Vzc2FyeSB0byByZXZhbGlkYXRlIChieSBjYWxsaW5nICRzZXRWaWV3VmFsdWUgYWdhaW4pIGV2ZW4gaWYgdGhlCiAgICAvLyBjb250cm9sJ3MgdmFsdWUgaXMgdGhlIHNhbWUgZW1wdHkgdmFsdWUgdHdpY2UgaW4gYSByb3cuCiAgICBpZiAoY3RybC4kdmlld1ZhbHVlICE9PSB2YWx1ZSB8fCAodmFsdWUgPT09ICcnICYmIGN0cmwuJCRoYXNOYXRpdmVWYWxpZGF0b3JzKSkgewogICAgICBjdHJsLiRzZXRWaWV3VmFsdWUodmFsdWUsIGV2ZW50KTsKICAgIH0KICB9OwoKICAvLyBpZiB0aGUgYnJvd3NlciBkb2VzIHN1cHBvcnQgImlucHV0IiBldmVudCwgd2UgYXJlIGZpbmUgLSBleGNlcHQgb24gSUU5IHdoaWNoIGRvZXNuJ3QgZmlyZSB0aGUKICAvLyBpbnB1dCBldmVudCBvbiBiYWNrc3BhY2UsIGRlbGV0ZSBvciBjdXQKICBpZiAoJHNuaWZmZXIuaGFzRXZlbnQoJ2lucHV0JykpIHsKICAgIGVsZW1lbnQub24oJ2lucHV0JywgbGlzdGVuZXIpOwogIH0gZWxzZSB7CiAgICB2YXIgdGltZW91dDsKCiAgICB2YXIgZGVmZXJMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2LCBpbnB1dCwgb3JpZ1ZhbHVlKSB7CiAgICAgIGlmICghdGltZW91dCkgewogICAgICAgIHRpbWVvdXQgPSAkYnJvd3Nlci5kZWZlcihmdW5jdGlvbigpIHsKICAgICAgICAgIHRpbWVvdXQgPSBudWxsOwogICAgICAgICAgaWYgKCFpbnB1dCB8fCBpbnB1dC52YWx1ZSAhPT0gb3JpZ1ZhbHVlKSB7CiAgICAgICAgICAgIGxpc3RlbmVyKGV2KTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgfTsKCiAgICBlbGVtZW50Lm9uKCdrZXlkb3duJywgZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgdmFyIGtleSA9IGV2ZW50LmtleUNvZGU7CgogICAgICAvLyBpZ25vcmUKICAgICAgLy8gICAgY29tbWFuZCAgICAgICAgICAgIG1vZGlmaWVycyAgICAgICAgICAgICAgICAgICBhcnJvd3MKICAgICAgaWYgKGtleSA9PT0gOTEgfHwgKDE1IDwga2V5ICYmIGtleSA8IDE5KSB8fCAoMzcgPD0ga2V5ICYmIGtleSA8PSA0MCkpIHJldHVybjsKCiAgICAgIGRlZmVyTGlzdGVuZXIoZXZlbnQsIHRoaXMsIHRoaXMudmFsdWUpOwogICAgfSk7CgogICAgLy8gaWYgdXNlciBtb2RpZmllcyBpbnB1dCB2YWx1ZSB1c2luZyBjb250ZXh0IG1lbnUgaW4gSUUsIHdlIG5lZWQgInBhc3RlIiBhbmQgImN1dCIgZXZlbnRzIHRvIGNhdGNoIGl0CiAgICBpZiAoJHNuaWZmZXIuaGFzRXZlbnQoJ3Bhc3RlJykpIHsKICAgICAgZWxlbWVudC5vbigncGFzdGUgY3V0JywgZGVmZXJMaXN0ZW5lcik7CiAgICB9CiAgfQoKICAvLyBpZiB1c2VyIHBhc3RlIGludG8gaW5wdXQgdXNpbmcgbW91c2Ugb24gb2xkZXIgYnJvd3NlcgogIC8vIG9yIGZvcm0gYXV0b2NvbXBsZXRlIG9uIG5ld2VyIGJyb3dzZXIsIHdlIG5lZWQgImNoYW5nZSIgZXZlbnQgdG8gY2F0Y2ggaXQKICBlbGVtZW50Lm9uKCdjaGFuZ2UnLCBsaXN0ZW5lcik7CgogIGN0cmwuJHJlbmRlciA9IGZ1bmN0aW9uKCkgewogICAgZWxlbWVudC52YWwoY3RybC4kaXNFbXB0eShjdHJsLiR2aWV3VmFsdWUpID8gJycgOiBjdHJsLiR2aWV3VmFsdWUpOwogIH07Cn0KCmZ1bmN0aW9uIHdlZWtQYXJzZXIoaXNvV2VlaywgZXhpc3RpbmdEYXRlKSB7CiAgaWYgKGlzRGF0ZShpc29XZWVrKSkgewogICAgcmV0dXJuIGlzb1dlZWs7CiAgfQoKICBpZiAoaXNTdHJpbmcoaXNvV2VlaykpIHsKICAgIFdFRUtfUkVHRVhQLmxhc3RJbmRleCA9IDA7CiAgICB2YXIgcGFydHMgPSBXRUVLX1JFR0VYUC5leGVjKGlzb1dlZWspOwogICAgaWYgKHBhcnRzKSB7CiAgICAgIHZhciB5ZWFyID0gK3BhcnRzWzFdLAogICAgICAgICAgd2VlayA9ICtwYXJ0c1syXSwKICAgICAgICAgIGhvdXJzID0gMCwKICAgICAgICAgIG1pbnV0ZXMgPSAwLAogICAgICAgICAgc2Vjb25kcyA9IDAsCiAgICAgICAgICBtaWxsaXNlY29uZHMgPSAwLAogICAgICAgICAgZmlyc3RUaHVycyA9IGdldEZpcnN0VGh1cnNkYXlPZlllYXIoeWVhciksCiAgICAgICAgICBhZGREYXlzID0gKHdlZWsgLSAxKSAqIDc7CgogICAgICBpZiAoZXhpc3RpbmdEYXRlKSB7CiAgICAgICAgaG91cnMgPSBleGlzdGluZ0RhdGUuZ2V0SG91cnMoKTsKICAgICAgICBtaW51dGVzID0gZXhpc3RpbmdEYXRlLmdldE1pbnV0ZXMoKTsKICAgICAgICBzZWNvbmRzID0gZXhpc3RpbmdEYXRlLmdldFNlY29uZHMoKTsKICAgICAgICBtaWxsaXNlY29uZHMgPSBleGlzdGluZ0RhdGUuZ2V0TWlsbGlzZWNvbmRzKCk7CiAgICAgIH0KCiAgICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCAwLCBmaXJzdFRodXJzLmdldERhdGUoKSArIGFkZERheXMsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtaWxsaXNlY29uZHMpOwogICAgfQogIH0KCiAgcmV0dXJuIE5hTjsKfQoKZnVuY3Rpb24gY3JlYXRlRGF0ZVBhcnNlcihyZWdleHAsIG1hcHBpbmcpIHsKICByZXR1cm4gZnVuY3Rpb24oaXNvLCBkYXRlKSB7CiAgICB2YXIgcGFydHMsIG1hcDsKCiAgICBpZiAoaXNEYXRlKGlzbykpIHsKICAgICAgcmV0dXJuIGlzbzsKICAgIH0KCiAgICBpZiAoaXNTdHJpbmcoaXNvKSkgewogICAgICAvLyBXaGVuIGEgZGF0ZSBpcyBKU09OJ2lmaWVkIHRvIHdyYXBzIGl0c2VsZiBpbnNpZGUgb2YgYW4gZXh0cmEKICAgICAgLy8gc2V0IG9mIGRvdWJsZSBxdW90ZXMuIFRoaXMgbWFrZXMgdGhlIGRhdGUgcGFyc2luZyBjb2RlIHVuYWJsZQogICAgICAvLyB0byBtYXRjaCB0aGUgZGF0ZSBzdHJpbmcgYW5kIHBhcnNlIGl0IGFzIGEgZGF0ZS4KICAgICAgaWYgKGlzby5jaGFyQXQoMCkgPT0gJyInICYmIGlzby5jaGFyQXQoaXNvLmxlbmd0aCAtIDEpID09ICciJykgewogICAgICAgIGlzbyA9IGlzby5zdWJzdHJpbmcoMSwgaXNvLmxlbmd0aCAtIDEpOwogICAgICB9CiAgICAgIGlmIChJU09fREFURV9SRUdFWFAudGVzdChpc28pKSB7CiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGlzbyk7CiAgICAgIH0KICAgICAgcmVnZXhwLmxhc3RJbmRleCA9IDA7CiAgICAgIHBhcnRzID0gcmVnZXhwLmV4ZWMoaXNvKTsKCiAgICAgIGlmIChwYXJ0cykgewogICAgICAgIHBhcnRzLnNoaWZ0KCk7CiAgICAgICAgaWYgKGRhdGUpIHsKICAgICAgICAgIG1hcCA9IHsKICAgICAgICAgICAgeXl5eTogZGF0ZS5nZXRGdWxsWWVhcigpLAogICAgICAgICAgICBNTTogZGF0ZS5nZXRNb250aCgpICsgMSwKICAgICAgICAgICAgZGQ6IGRhdGUuZ2V0RGF0ZSgpLAogICAgICAgICAgICBISDogZGF0ZS5nZXRIb3VycygpLAogICAgICAgICAgICBtbTogZGF0ZS5nZXRNaW51dGVzKCksCiAgICAgICAgICAgIHNzOiBkYXRlLmdldFNlY29uZHMoKSwKICAgICAgICAgICAgc3NzOiBkYXRlLmdldE1pbGxpc2Vjb25kcygpIC8gMTAwMAogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWFwID0geyB5eXl5OiAxOTcwLCBNTTogMSwgZGQ6IDEsIEhIOiAwLCBtbTogMCwgc3M6IDAsIHNzczogMCB9OwogICAgICAgIH0KCiAgICAgICAgZm9yRWFjaChwYXJ0cywgZnVuY3Rpb24ocGFydCwgaW5kZXgpIHsKICAgICAgICAgIGlmIChpbmRleCA8IG1hcHBpbmcubGVuZ3RoKSB7CiAgICAgICAgICAgIG1hcFttYXBwaW5nW2luZGV4XV0gPSArcGFydDsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICByZXR1cm4gbmV3IERhdGUobWFwLnl5eXksIG1hcC5NTSAtIDEsIG1hcC5kZCwgbWFwLkhILCBtYXAubW0sIG1hcC5zcyB8fCAwLCBtYXAuc3NzICogMTAwMCB8fCAwKTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBOYU47CiAgfTsKfQoKZnVuY3Rpb24gY3JlYXRlRGF0ZUlucHV0VHlwZSh0eXBlLCByZWdleHAsIHBhcnNlRGF0ZSwgZm9ybWF0KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIGR5bmFtaWNEYXRlSW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIsICRmaWx0ZXIpIHsKICAgIGJhZElucHV0Q2hlY2tlcihzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybCk7CiAgICBiYXNlSW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIpOwogICAgdmFyIHRpbWV6b25lID0gY3RybCAmJiBjdHJsLiRvcHRpb25zICYmIGN0cmwuJG9wdGlvbnMudGltZXpvbmU7CiAgICB2YXIgcHJldmlvdXNEYXRlOwoKICAgIGN0cmwuJCRwYXJzZXJOYW1lID0gdHlwZTsKICAgIGN0cmwuJHBhcnNlcnMucHVzaChmdW5jdGlvbih2YWx1ZSkgewogICAgICBpZiAoY3RybC4kaXNFbXB0eSh2YWx1ZSkpIHJldHVybiBudWxsOwogICAgICBpZiAocmVnZXhwLnRlc3QodmFsdWUpKSB7CiAgICAgICAgLy8gTm90ZTogV2UgY2Fubm90IHJlYWQgY3RybC4kbW9kZWxWYWx1ZSwgYXMgdGhlcmUgbWlnaHQgYmUgYSBkaWZmZXJlbnQKICAgICAgICAvLyBwYXJzZXIvZm9ybWF0dGVyIGluIHRoZSBwcm9jZXNzaW5nIGNoYWluIHNvIHRoYXQgdGhlIG1vZGVsCiAgICAgICAgLy8gY29udGFpbnMgc29tZSBkaWZmZXJlbnQgZGF0YSBmb3JtYXQhCiAgICAgICAgdmFyIHBhcnNlZERhdGUgPSBwYXJzZURhdGUodmFsdWUsIHByZXZpb3VzRGF0ZSk7CiAgICAgICAgaWYgKHRpbWV6b25lID09PSAnVVRDJykgewogICAgICAgICAgcGFyc2VkRGF0ZS5zZXRNaW51dGVzKHBhcnNlZERhdGUuZ2V0TWludXRlcygpIC0gcGFyc2VkRGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhcnNlZERhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgIH0pOwoKICAgIGN0cmwuJGZvcm1hdHRlcnMucHVzaChmdW5jdGlvbih2YWx1ZSkgewogICAgICBpZiAodmFsdWUgJiYgIWlzRGF0ZSh2YWx1ZSkpIHsKICAgICAgICB0aHJvdyAkbmdNb2RlbE1pbkVycignZGF0ZWZtdCcsICdFeHBlY3RlZCBgezB9YCB0byBiZSBhIGRhdGUnLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGlzVmFsaWREYXRlKHZhbHVlKSkgewogICAgICAgIHByZXZpb3VzRGF0ZSA9IHZhbHVlOwogICAgICAgIGlmIChwcmV2aW91c0RhdGUgJiYgdGltZXpvbmUgPT09ICdVVEMnKSB7CiAgICAgICAgICB2YXIgdGltZXpvbmVPZmZzZXQgPSA2MDAwMCAqIHByZXZpb3VzRGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpOwogICAgICAgICAgcHJldmlvdXNEYXRlID0gbmV3IERhdGUocHJldmlvdXNEYXRlLmdldFRpbWUoKSArIHRpbWV6b25lT2Zmc2V0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRmaWx0ZXIoJ2RhdGUnKSh2YWx1ZSwgZm9ybWF0LCB0aW1lem9uZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJldmlvdXNEYXRlID0gbnVsbDsKICAgICAgICByZXR1cm4gJyc7CiAgICAgIH0KICAgIH0pOwoKICAgIGlmIChpc0RlZmluZWQoYXR0ci5taW4pIHx8IGF0dHIubmdNaW4pIHsKICAgICAgdmFyIG1pblZhbDsKICAgICAgY3RybC4kdmFsaWRhdG9ycy5taW4gPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgIHJldHVybiAhaXNWYWxpZERhdGUodmFsdWUpIHx8IGlzVW5kZWZpbmVkKG1pblZhbCkgfHwgcGFyc2VEYXRlKHZhbHVlKSA+PSBtaW5WYWw7CiAgICAgIH07CiAgICAgIGF0dHIuJG9ic2VydmUoJ21pbicsIGZ1bmN0aW9uKHZhbCkgewogICAgICAgIG1pblZhbCA9IHBhcnNlT2JzZXJ2ZWREYXRlVmFsdWUodmFsKTsKICAgICAgICBjdHJsLiR2YWxpZGF0ZSgpOwogICAgICB9KTsKICAgIH0KCiAgICBpZiAoaXNEZWZpbmVkKGF0dHIubWF4KSB8fCBhdHRyLm5nTWF4KSB7CiAgICAgIHZhciBtYXhWYWw7CiAgICAgIGN0cmwuJHZhbGlkYXRvcnMubWF4ID0gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICByZXR1cm4gIWlzVmFsaWREYXRlKHZhbHVlKSB8fCBpc1VuZGVmaW5lZChtYXhWYWwpIHx8IHBhcnNlRGF0ZSh2YWx1ZSkgPD0gbWF4VmFsOwogICAgICB9OwogICAgICBhdHRyLiRvYnNlcnZlKCdtYXgnLCBmdW5jdGlvbih2YWwpIHsKICAgICAgICBtYXhWYWwgPSBwYXJzZU9ic2VydmVkRGF0ZVZhbHVlKHZhbCk7CiAgICAgICAgY3RybC4kdmFsaWRhdGUoKTsKICAgICAgfSk7CiAgICB9CgogICAgZnVuY3Rpb24gaXNWYWxpZERhdGUodmFsdWUpIHsKICAgICAgLy8gSW52YWxpZCBEYXRlOiBnZXRUaW1lKCkgcmV0dXJucyBOYU4KICAgICAgcmV0dXJuIHZhbHVlICYmICEodmFsdWUuZ2V0VGltZSAmJiB2YWx1ZS5nZXRUaW1lKCkgIT09IHZhbHVlLmdldFRpbWUoKSk7CiAgICB9CgogICAgZnVuY3Rpb24gcGFyc2VPYnNlcnZlZERhdGVWYWx1ZSh2YWwpIHsKICAgICAgcmV0dXJuIGlzRGVmaW5lZCh2YWwpID8gKGlzRGF0ZSh2YWwpID8gdmFsIDogcGFyc2VEYXRlKHZhbCkpIDogdW5kZWZpbmVkOwogICAgfQogIH07Cn0KCmZ1bmN0aW9uIGJhZElucHV0Q2hlY2tlcihzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybCkgewogIHZhciBub2RlID0gZWxlbWVudFswXTsKICB2YXIgbmF0aXZlVmFsaWRhdGlvbiA9IGN0cmwuJCRoYXNOYXRpdmVWYWxpZGF0b3JzID0gaXNPYmplY3Qobm9kZS52YWxpZGl0eSk7CiAgaWYgKG5hdGl2ZVZhbGlkYXRpb24pIHsKICAgIGN0cmwuJHBhcnNlcnMucHVzaChmdW5jdGlvbih2YWx1ZSkgewogICAgICB2YXIgdmFsaWRpdHkgPSBlbGVtZW50LnByb3AoVkFMSURJVFlfU1RBVEVfUFJPUEVSVFkpIHx8IHt9OwogICAgICAvLyBEZXRlY3QgYnVnIGluIEZGMzUgZm9yIGlucHV0W2VtYWlsXSAoaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTA2NDQzMCk6CiAgICAgIC8vIC0gYWxzbyBzZXRzIHZhbGlkaXR5LmJhZElucHV0IChzaG91bGQgb25seSBiZSB2YWxpZGl0eS50eXBlTWlzbWF0Y2gpLgogICAgICAvLyAtIHNlZSBodHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS9mb3Jtcy5odG1sI2UtbWFpbC1zdGF0ZS0odHlwZT1lbWFpbCkKICAgICAgLy8gLSBjYW4gaWdub3JlIHRoaXMgY2FzZSBhcyB3ZSBjYW4gc3RpbGwgcmVhZCBvdXQgdGhlIGVycm9uZW91cyBlbWFpbC4uLgogICAgICByZXR1cm4gdmFsaWRpdHkuYmFkSW5wdXQgJiYgIXZhbGlkaXR5LnR5cGVNaXNtYXRjaCA/IHVuZGVmaW5lZCA6IHZhbHVlOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBudW1iZXJJbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwsICRzbmlmZmVyLCAkYnJvd3NlcikgewogIGJhZElucHV0Q2hlY2tlcihzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybCk7CiAgYmFzZUlucHV0VHlwZShzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybCwgJHNuaWZmZXIsICRicm93c2VyKTsKCiAgY3RybC4kJHBhcnNlck5hbWUgPSAnbnVtYmVyJzsKICBjdHJsLiRwYXJzZXJzLnB1c2goZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmIChjdHJsLiRpc0VtcHR5KHZhbHVlKSkgICAgICByZXR1cm4gbnVsbDsKICAgIGlmIChOVU1CRVJfUkVHRVhQLnRlc3QodmFsdWUpKSByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSk7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0pOwoKICBjdHJsLiRmb3JtYXR0ZXJzLnB1c2goZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmICghY3RybC4kaXNFbXB0eSh2YWx1ZSkpIHsKICAgICAgaWYgKCFpc051bWJlcih2YWx1ZSkpIHsKICAgICAgICB0aHJvdyAkbmdNb2RlbE1pbkVycignbnVtZm10JywgJ0V4cGVjdGVkIGB7MH1gIHRvIGJlIGEgbnVtYmVyJywgdmFsdWUpOwogICAgICB9CiAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTsKICAgIH0KICAgIHJldHVybiB2YWx1ZTsKICB9KTsKCiAgaWYgKGF0dHIubWluIHx8IGF0dHIubmdNaW4pIHsKICAgIHZhciBtaW5WYWw7CiAgICBjdHJsLiR2YWxpZGF0b3JzLm1pbiA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiBjdHJsLiRpc0VtcHR5KHZhbHVlKSB8fCBpc1VuZGVmaW5lZChtaW5WYWwpIHx8IHZhbHVlID49IG1pblZhbDsKICAgIH07CgogICAgYXR0ci4kb2JzZXJ2ZSgnbWluJywgZnVuY3Rpb24odmFsKSB7CiAgICAgIGlmIChpc0RlZmluZWQodmFsKSAmJiAhaXNOdW1iZXIodmFsKSkgewogICAgICAgIHZhbCA9IHBhcnNlRmxvYXQodmFsLCAxMCk7CiAgICAgIH0KICAgICAgbWluVmFsID0gaXNOdW1iZXIodmFsKSAmJiAhaXNOYU4odmFsKSA/IHZhbCA6IHVuZGVmaW5lZDsKICAgICAgLy8gVE9ETyhtYXRza28pOiBpbXBsZW1lbnQgdmFsaWRhdGVMYXRlciB0byByZWR1Y2UgbnVtYmVyIG9mIHZhbGlkYXRpb25zCiAgICAgIGN0cmwuJHZhbGlkYXRlKCk7CiAgICB9KTsKICB9CgogIGlmIChhdHRyLm1heCB8fCBhdHRyLm5nTWF4KSB7CiAgICB2YXIgbWF4VmFsOwogICAgY3RybC4kdmFsaWRhdG9ycy5tYXggPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICByZXR1cm4gY3RybC4kaXNFbXB0eSh2YWx1ZSkgfHwgaXNVbmRlZmluZWQobWF4VmFsKSB8fCB2YWx1ZSA8PSBtYXhWYWw7CiAgICB9OwoKICAgIGF0dHIuJG9ic2VydmUoJ21heCcsIGZ1bmN0aW9uKHZhbCkgewogICAgICBpZiAoaXNEZWZpbmVkKHZhbCkgJiYgIWlzTnVtYmVyKHZhbCkpIHsKICAgICAgICB2YWwgPSBwYXJzZUZsb2F0KHZhbCwgMTApOwogICAgICB9CiAgICAgIG1heFZhbCA9IGlzTnVtYmVyKHZhbCkgJiYgIWlzTmFOKHZhbCkgPyB2YWwgOiB1bmRlZmluZWQ7CiAgICAgIC8vIFRPRE8obWF0c2tvKTogaW1wbGVtZW50IHZhbGlkYXRlTGF0ZXIgdG8gcmVkdWNlIG51bWJlciBvZiB2YWxpZGF0aW9ucwogICAgICBjdHJsLiR2YWxpZGF0ZSgpOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiB1cmxJbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwsICRzbmlmZmVyLCAkYnJvd3NlcikgewogIC8vIE5vdGU6IG5vIGJhZElucHV0Q2hlY2tlciBoZXJlIGJ5IHB1cnBvc2UgYXMgYHVybGAgaXMgb25seSBhIHZhbGlkYXRpb24KICAvLyBpbiBicm93c2VycywgaS5lLiB3ZSBjYW4gYWx3YXlzIHJlYWQgb3V0IGlucHV0LnZhbHVlIGV2ZW4gaWYgaXQgaXMgbm90IHZhbGlkIQogIGJhc2VJbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwsICRzbmlmZmVyLCAkYnJvd3Nlcik7CiAgc3RyaW5nQmFzZWRJbnB1dFR5cGUoY3RybCk7CgogIGN0cmwuJCRwYXJzZXJOYW1lID0gJ3VybCc7CiAgY3RybC4kdmFsaWRhdG9ycy51cmwgPSBmdW5jdGlvbihtb2RlbFZhbHVlLCB2aWV3VmFsdWUpIHsKICAgIHZhciB2YWx1ZSA9IG1vZGVsVmFsdWUgfHwgdmlld1ZhbHVlOwogICAgcmV0dXJuIGN0cmwuJGlzRW1wdHkodmFsdWUpIHx8IFVSTF9SRUdFWFAudGVzdCh2YWx1ZSk7CiAgfTsKfQoKZnVuY3Rpb24gZW1haWxJbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwsICRzbmlmZmVyLCAkYnJvd3NlcikgewogIC8vIE5vdGU6IG5vIGJhZElucHV0Q2hlY2tlciBoZXJlIGJ5IHB1cnBvc2UgYXMgYHVybGAgaXMgb25seSBhIHZhbGlkYXRpb24KICAvLyBpbiBicm93c2VycywgaS5lLiB3ZSBjYW4gYWx3YXlzIHJlYWQgb3V0IGlucHV0LnZhbHVlIGV2ZW4gaWYgaXQgaXMgbm90IHZhbGlkIQogIGJhc2VJbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwsICRzbmlmZmVyLCAkYnJvd3Nlcik7CiAgc3RyaW5nQmFzZWRJbnB1dFR5cGUoY3RybCk7CgogIGN0cmwuJCRwYXJzZXJOYW1lID0gJ2VtYWlsJzsKICBjdHJsLiR2YWxpZGF0b3JzLmVtYWlsID0gZnVuY3Rpb24obW9kZWxWYWx1ZSwgdmlld1ZhbHVlKSB7CiAgICB2YXIgdmFsdWUgPSBtb2RlbFZhbHVlIHx8IHZpZXdWYWx1ZTsKICAgIHJldHVybiBjdHJsLiRpc0VtcHR5KHZhbHVlKSB8fCBFTUFJTF9SRUdFWFAudGVzdCh2YWx1ZSk7CiAgfTsKfQoKZnVuY3Rpb24gcmFkaW9JbnB1dFR5cGUoc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwpIHsKICAvLyBtYWtlIHRoZSBuYW1lIHVuaXF1ZSwgaWYgbm90IGRlZmluZWQKICBpZiAoaXNVbmRlZmluZWQoYXR0ci5uYW1lKSkgewogICAgZWxlbWVudC5hdHRyKCduYW1lJywgbmV4dFVpZCgpKTsKICB9CgogIHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2KSB7CiAgICBpZiAoZWxlbWVudFswXS5jaGVja2VkKSB7CiAgICAgIGN0cmwuJHNldFZpZXdWYWx1ZShhdHRyLnZhbHVlLCBldiAmJiBldi50eXBlKTsKICAgIH0KICB9OwoKICBlbGVtZW50Lm9uKCdjbGljaycsIGxpc3RlbmVyKTsKCiAgY3RybC4kcmVuZGVyID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgdmFsdWUgPSBhdHRyLnZhbHVlOwogICAgZWxlbWVudFswXS5jaGVja2VkID0gKHZhbHVlID09IGN0cmwuJHZpZXdWYWx1ZSk7CiAgfTsKCiAgYXR0ci4kb2JzZXJ2ZSgndmFsdWUnLCBjdHJsLiRyZW5kZXIpOwp9CgpmdW5jdGlvbiBwYXJzZUNvbnN0YW50RXhwcigkcGFyc2UsIGNvbnRleHQsIG5hbWUsIGV4cHJlc3Npb24sIGZhbGxiYWNrKSB7CiAgdmFyIHBhcnNlRm47CiAgaWYgKGlzRGVmaW5lZChleHByZXNzaW9uKSkgewogICAgcGFyc2VGbiA9ICRwYXJzZShleHByZXNzaW9uKTsKICAgIGlmICghcGFyc2VGbi5jb25zdGFudCkgewogICAgICB0aHJvdyBtaW5FcnIoJ25nTW9kZWwnKSgnY29uc3RleHByJywgJ0V4cGVjdGVkIGNvbnN0YW50IGV4cHJlc3Npb24gZm9yIGB7MH1gLCBidXQgc2F3ICcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdgezF9YC4nLCBuYW1lLCBleHByZXNzaW9uKTsKICAgIH0KICAgIHJldHVybiBwYXJzZUZuKGNvbnRleHQpOwogIH0KICByZXR1cm4gZmFsbGJhY2s7Cn0KCmZ1bmN0aW9uIGNoZWNrYm94SW5wdXRUeXBlKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkc25pZmZlciwgJGJyb3dzZXIsICRmaWx0ZXIsICRwYXJzZSkgewogIHZhciB0cnVlVmFsdWUgPSBwYXJzZUNvbnN0YW50RXhwcigkcGFyc2UsIHNjb3BlLCAnbmdUcnVlVmFsdWUnLCBhdHRyLm5nVHJ1ZVZhbHVlLCB0cnVlKTsKICB2YXIgZmFsc2VWYWx1ZSA9IHBhcnNlQ29uc3RhbnRFeHByKCRwYXJzZSwgc2NvcGUsICduZ0ZhbHNlVmFsdWUnLCBhdHRyLm5nRmFsc2VWYWx1ZSwgZmFsc2UpOwoKICB2YXIgbGlzdGVuZXIgPSBmdW5jdGlvbihldikgewogICAgY3RybC4kc2V0Vmlld1ZhbHVlKGVsZW1lbnRbMF0uY2hlY2tlZCwgZXYgJiYgZXYudHlwZSk7CiAgfTsKCiAgZWxlbWVudC5vbignY2xpY2snLCBsaXN0ZW5lcik7CgogIGN0cmwuJHJlbmRlciA9IGZ1bmN0aW9uKCkgewogICAgZWxlbWVudFswXS5jaGVja2VkID0gY3RybC4kdmlld1ZhbHVlOwogIH07CgogIC8vIE92ZXJyaWRlIHRoZSBzdGFuZGFyZCBgJGlzRW1wdHlgIGJlY2F1c2UgdGhlICR2aWV3VmFsdWUgb2YgYW4gZW1wdHkgY2hlY2tib3ggaXMgYWx3YXlzIHNldCB0byBgZmFsc2VgCiAgLy8gVGhpcyBpcyBiZWNhdXNlIG9mIHRoZSBwYXJzZXIgYmVsb3csIHdoaWNoIGNvbXBhcmVzIHRoZSBgJG1vZGVsVmFsdWVgIHdpdGggYHRydWVWYWx1ZWAgdG8gY29udmVydAogIC8vIGl0IHRvIGEgYm9vbGVhbi4KICBjdHJsLiRpc0VtcHR5ID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gZmFsc2U7CiAgfTsKCiAgY3RybC4kZm9ybWF0dGVycy5wdXNoKGZ1bmN0aW9uKHZhbHVlKSB7CiAgICByZXR1cm4gZXF1YWxzKHZhbHVlLCB0cnVlVmFsdWUpOwogIH0pOwoKICBjdHJsLiRwYXJzZXJzLnB1c2goZnVuY3Rpb24odmFsdWUpIHsKICAgIHJldHVybiB2YWx1ZSA/IHRydWVWYWx1ZSA6IGZhbHNlVmFsdWU7CiAgfSk7Cn0KCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSB0ZXh0YXJlYQogKiBAcmVzdHJpY3QgRQogKgogKiBAZGVzY3JpcHRpb24KICogSFRNTCB0ZXh0YXJlYSBlbGVtZW50IGNvbnRyb2wgd2l0aCBhbmd1bGFyIGRhdGEtYmluZGluZy4gVGhlIGRhdGEtYmluZGluZyBhbmQgdmFsaWRhdGlvbgogKiBwcm9wZXJ0aWVzIG9mIHRoaXMgZWxlbWVudCBhcmUgZXhhY3RseSB0aGUgc2FtZSBhcyB0aG9zZSBvZiB0aGUKICoge0BsaW5rIG5nLmRpcmVjdGl2ZTppbnB1dCBpbnB1dCBlbGVtZW50fS4KICoKICogQHBhcmFtIHtzdHJpbmd9IG5nTW9kZWwgQXNzaWduYWJsZSBhbmd1bGFyIGV4cHJlc3Npb24gdG8gZGF0YS1iaW5kIHRvLgogKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgUHJvcGVydHkgbmFtZSBvZiB0aGUgZm9ybSB1bmRlciB3aGljaCB0aGUgY29udHJvbCBpcyBwdWJsaXNoZWQuCiAqIEBwYXJhbSB7c3RyaW5nPX0gcmVxdWlyZWQgU2V0cyBgcmVxdWlyZWRgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBpcyBub3QgZW50ZXJlZC4KICogQHBhcmFtIHtzdHJpbmc9fSBuZ1JlcXVpcmVkIEFkZHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgYW5kIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBjb25zdHJhaW50IHRvCiAqICAgIHRoZSBlbGVtZW50IHdoZW4gdGhlIG5nUmVxdWlyZWQgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS4gVXNlIGBuZ1JlcXVpcmVkYCBpbnN0ZWFkIG9mCiAqICAgIGByZXF1aXJlZGAgd2hlbiB5b3Ugd2FudCB0byBkYXRhLWJpbmQgdG8gdGhlIGByZXF1aXJlZGAgYXR0cmlidXRlLgogKiBAcGFyYW0ge251bWJlcj19IG5nTWlubGVuZ3RoIFNldHMgYG1pbmxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIHNob3J0ZXIgdGhhbgogKiAgICBtaW5sZW5ndGguCiAqIEBwYXJhbSB7bnVtYmVyPX0gbmdNYXhsZW5ndGggU2V0cyBgbWF4bGVuZ3RoYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgaXMgbG9uZ2VyIHRoYW4KICogICAgbWF4bGVuZ3RoLiBTZXR0aW5nIHRoZSBhdHRyaWJ1dGUgdG8gYSBuZWdhdGl2ZSBvciBub24tbnVtZXJpYyB2YWx1ZSwgYWxsb3dzIHZpZXcgdmFsdWVzIG9mIGFueQogKiAgICBsZW5ndGguCiAqIEBwYXJhbSB7c3RyaW5nPX0gbmdQYXR0ZXJuIFNldHMgYHBhdHRlcm5gIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBkb2VzIG5vdCBtYXRjaCB0aGUKICogICAgUmVnRXhwIHBhdHRlcm4gZXhwcmVzc2lvbi4gRXhwZWN0ZWQgdmFsdWUgaXMgYC9yZWdleHAvYCBmb3IgaW5saW5lIHBhdHRlcm5zIG9yIGByZWdleHBgIGZvcgogKiAgICBwYXR0ZXJucyBkZWZpbmVkIGFzIHNjb3BlIGV4cHJlc3Npb25zLgogKiBAcGFyYW0ge3N0cmluZz19IG5nQ2hhbmdlIEFuZ3VsYXIgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCB3aGVuIGlucHV0IGNoYW5nZXMgZHVlIHRvIHVzZXIKICogICAgaW50ZXJhY3Rpb24gd2l0aCB0aGUgaW5wdXQgZWxlbWVudC4KICogQHBhcmFtIHtib29sZWFuPX0gW25nVHJpbT10cnVlXSBJZiBzZXQgdG8gZmFsc2UgQW5ndWxhciB3aWxsIG5vdCBhdXRvbWF0aWNhbGx5IHRyaW0gdGhlIGlucHV0LgogKi8KCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBpbnB1dAogKiBAcmVzdHJpY3QgRQogKgogKiBAZGVzY3JpcHRpb24KICogSFRNTCBpbnB1dCBlbGVtZW50IGNvbnRyb2wuIFdoZW4gdXNlZCB0b2dldGhlciB3aXRoIHtAbGluayBuZ01vZGVsIGBuZ01vZGVsYH0sIGl0IHByb3ZpZGVzIGRhdGEtYmluZGluZywKICogaW5wdXQgc3RhdGUgY29udHJvbCwgYW5kIHZhbGlkYXRpb24uCiAqIElucHV0IGNvbnRyb2wgZm9sbG93cyBIVE1MNSBpbnB1dCB0eXBlcyBhbmQgcG9seWZpbGxzIHRoZSBIVE1MNSB2YWxpZGF0aW9uIGJlaGF2aW9yIGZvciBvbGRlciBicm93c2Vycy4KICoKICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CiAqICoqTm90ZToqKiBOb3QgZXZlcnkgZmVhdHVyZSBvZmZlcmVkIGlzIGF2YWlsYWJsZSBmb3IgYWxsIGlucHV0IHR5cGVzLgogKiBTcGVjaWZpY2FsbHksIGRhdGEgYmluZGluZyBhbmQgZXZlbnQgaGFuZGxpbmcgdmlhIGBuZy1tb2RlbGAgaXMgdW5zdXBwb3J0ZWQgZm9yIGBpbnB1dFtmaWxlXWAuCiAqIDwvZGl2PgogKgogKiBAcGFyYW0ge3N0cmluZ30gbmdNb2RlbCBBc3NpZ25hYmxlIGFuZ3VsYXIgZXhwcmVzc2lvbiB0byBkYXRhLWJpbmQgdG8uCiAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBuYW1lIG9mIHRoZSBmb3JtIHVuZGVyIHdoaWNoIHRoZSBjb250cm9sIGlzIHB1Ymxpc2hlZC4KICogQHBhcmFtIHtzdHJpbmc9fSByZXF1aXJlZCBTZXRzIGByZXF1aXJlZGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIG5vdCBlbnRlcmVkLgogKiBAcGFyYW0ge2Jvb2xlYW49fSBuZ1JlcXVpcmVkIFNldHMgYHJlcXVpcmVkYCBhdHRyaWJ1dGUgaWYgc2V0IHRvIHRydWUKICogQHBhcmFtIHtudW1iZXI9fSBuZ01pbmxlbmd0aCBTZXRzIGBtaW5sZW5ndGhgIHZhbGlkYXRpb24gZXJyb3Iga2V5IGlmIHRoZSB2YWx1ZSBpcyBzaG9ydGVyIHRoYW4KICogICAgbWlubGVuZ3RoLgogKiBAcGFyYW0ge251bWJlcj19IG5nTWF4bGVuZ3RoIFNldHMgYG1heGxlbmd0aGAgdmFsaWRhdGlvbiBlcnJvciBrZXkgaWYgdGhlIHZhbHVlIGlzIGxvbmdlciB0aGFuCiAqICAgIG1heGxlbmd0aC4gU2V0dGluZyB0aGUgYXR0cmlidXRlIHRvIGEgbmVnYXRpdmUgb3Igbm9uLW51bWVyaWMgdmFsdWUsIGFsbG93cyB2aWV3IHZhbHVlcyBvZiBhbnkKICogICAgbGVuZ3RoLgogKiBAcGFyYW0ge3N0cmluZz19IG5nUGF0dGVybiBTZXRzIGBwYXR0ZXJuYCB2YWxpZGF0aW9uIGVycm9yIGtleSBpZiB0aGUgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlCiAqICAgIFJlZ0V4cCBwYXR0ZXJuIGV4cHJlc3Npb24uIEV4cGVjdGVkIHZhbHVlIGlzIGAvcmVnZXhwL2AgZm9yIGlubGluZSBwYXR0ZXJucyBvciBgcmVnZXhwYCBmb3IKICogICAgcGF0dGVybnMgZGVmaW5lZCBhcyBzY29wZSBleHByZXNzaW9ucy4KICogQHBhcmFtIHtzdHJpbmc9fSBuZ0NoYW5nZSBBbmd1bGFyIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiBpbnB1dCBjaGFuZ2VzIGR1ZSB0byB1c2VyCiAqICAgIGludGVyYWN0aW9uIHdpdGggdGhlIGlucHV0IGVsZW1lbnQuCiAqIEBwYXJhbSB7Ym9vbGVhbj19IFtuZ1RyaW09dHJ1ZV0gSWYgc2V0IHRvIGZhbHNlIEFuZ3VsYXIgd2lsbCBub3QgYXV0b21hdGljYWxseSB0cmltIHRoZSBpbnB1dC4KICogICAgVGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZCBmb3IgaW5wdXRbdHlwZT1wYXNzd29yZF0gY29udHJvbHMsIHdoaWNoIHdpbGwgbmV2ZXIgdHJpbSB0aGUKICogICAgaW5wdXQuCiAqCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZSBuYW1lPSJpbnB1dC1kaXJlY3RpdmUiIG1vZHVsZT0iaW5wdXRFeGFtcGxlIj4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8c2NyaXB0PgogICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ2lucHV0RXhhbXBsZScsIFtdKQogICAgICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICAgICRzY29wZS51c2VyID0ge25hbWU6ICdndWVzdCcsIGxhc3Q6ICd2aXNpdG9yJ307CiAgICAgICAgICAgIH1dKTsKICAgICAgIDwvc2NyaXB0PgogICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgIDxmb3JtIG5hbWU9Im15Rm9ybSI+CiAgICAgICAgICAgVXNlciBuYW1lOiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0idXNlck5hbWUiIG5nLW1vZGVsPSJ1c2VyLm5hbWUiIHJlcXVpcmVkPgogICAgICAgICAgIDxzcGFuIGNsYXNzPSJlcnJvciIgbmctc2hvdz0ibXlGb3JtLnVzZXJOYW1lLiRlcnJvci5yZXF1aXJlZCI+CiAgICAgICAgICAgICBSZXF1aXJlZCE8L3NwYW4+PGJyPgogICAgICAgICAgIExhc3QgbmFtZTogPGlucHV0IHR5cGU9InRleHQiIG5hbWU9Imxhc3ROYW1lIiBuZy1tb2RlbD0idXNlci5sYXN0IgogICAgICAgICAgICAgbmctbWlubGVuZ3RoPSIzIiBuZy1tYXhsZW5ndGg9IjEwIj4KICAgICAgICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5sYXN0TmFtZS4kZXJyb3IubWlubGVuZ3RoIj4KICAgICAgICAgICAgIFRvbyBzaG9ydCE8L3NwYW4+CiAgICAgICAgICAgPHNwYW4gY2xhc3M9ImVycm9yIiBuZy1zaG93PSJteUZvcm0ubGFzdE5hbWUuJGVycm9yLm1heGxlbmd0aCI+CiAgICAgICAgICAgICBUb28gbG9uZyE8L3NwYW4+PGJyPgogICAgICAgICA8L2Zvcm0+CiAgICAgICAgIDxocj4KICAgICAgICAgPHR0PnVzZXIgPSB7e3VzZXJ9fTwvdHQ+PGJyLz4KICAgICAgICAgPHR0Pm15Rm9ybS51c2VyTmFtZS4kdmFsaWQgPSB7e215Rm9ybS51c2VyTmFtZS4kdmFsaWR9fTwvdHQ+PGJyPgogICAgICAgICA8dHQ+bXlGb3JtLnVzZXJOYW1lLiRlcnJvciA9IHt7bXlGb3JtLnVzZXJOYW1lLiRlcnJvcn19PC90dD48YnI+CiAgICAgICAgIDx0dD5teUZvcm0ubGFzdE5hbWUuJHZhbGlkID0ge3tteUZvcm0ubGFzdE5hbWUuJHZhbGlkfX08L3R0Pjxicj4KICAgICAgICAgPHR0Pm15Rm9ybS5sYXN0TmFtZS4kZXJyb3IgPSB7e215Rm9ybS5sYXN0TmFtZS4kZXJyb3J9fTwvdHQ+PGJyPgogICAgICAgICA8dHQ+bXlGb3JtLiR2YWxpZCA9IHt7bXlGb3JtLiR2YWxpZH19PC90dD48YnI+CiAgICAgICAgIDx0dD5teUZvcm0uJGVycm9yLnJlcXVpcmVkID0ge3shIW15Rm9ybS4kZXJyb3IucmVxdWlyZWR9fTwvdHQ+PGJyPgogICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5taW5sZW5ndGggPSB7eyEhbXlGb3JtLiRlcnJvci5taW5sZW5ndGh9fTwvdHQ+PGJyPgogICAgICAgICA8dHQ+bXlGb3JtLiRlcnJvci5tYXhsZW5ndGggPSB7eyEhbXlGb3JtLiRlcnJvci5tYXhsZW5ndGh9fTwvdHQ+PGJyPgogICAgICAgPC9kaXY+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgdmFyIHVzZXIgPSBlbGVtZW50KGJ5LmV4YWN0QmluZGluZygndXNlcicpKTsKICAgICAgICB2YXIgdXNlck5hbWVWYWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLnVzZXJOYW1lLiR2YWxpZCcpKTsKICAgICAgICB2YXIgbGFzdE5hbWVWYWxpZCA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmxhc3ROYW1lLiR2YWxpZCcpKTsKICAgICAgICB2YXIgbGFzdE5hbWVFcnJvciA9IGVsZW1lbnQoYnkuYmluZGluZygnbXlGb3JtLmxhc3ROYW1lLiRlcnJvcicpKTsKICAgICAgICB2YXIgZm9ybVZhbGlkID0gZWxlbWVudChieS5iaW5kaW5nKCdteUZvcm0uJHZhbGlkJykpOwogICAgICAgIHZhciB1c2VyTmFtZUlucHV0ID0gZWxlbWVudChieS5tb2RlbCgndXNlci5uYW1lJykpOwogICAgICAgIHZhciB1c2VyTGFzdElucHV0ID0gZWxlbWVudChieS5tb2RlbCgndXNlci5sYXN0JykpOwoKICAgICAgICBpdCgnc2hvdWxkIGluaXRpYWxpemUgdG8gbW9kZWwnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIGV4cGVjdCh1c2VyLmdldFRleHQoKSkudG9Db250YWluKCd7Im5hbWUiOiJndWVzdCIsImxhc3QiOiJ2aXNpdG9yIn0nKTsKICAgICAgICAgIGV4cGVjdCh1c2VyTmFtZVZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAgICAgICAgICBleHBlY3QoZm9ybVZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAgICAgICAgfSk7CgogICAgICAgIGl0KCdzaG91bGQgYmUgaW52YWxpZCBpZiBlbXB0eSB3aGVuIHJlcXVpcmVkJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICB1c2VyTmFtZUlucHV0LmNsZWFyKCk7CiAgICAgICAgICB1c2VyTmFtZUlucHV0LnNlbmRLZXlzKCcnKTsKCiAgICAgICAgICBleHBlY3QodXNlci5nZXRUZXh0KCkpLnRvQ29udGFpbigneyJsYXN0IjoidmlzaXRvciJ9Jyk7CiAgICAgICAgICBleHBlY3QodXNlck5hbWVWYWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICAgIGV4cGVjdChmb3JtVmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgfSk7CgogICAgICAgIGl0KCdzaG91bGQgYmUgdmFsaWQgaWYgZW1wdHkgd2hlbiBtaW4gbGVuZ3RoIGlzIHNldCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgdXNlckxhc3RJbnB1dC5jbGVhcigpOwogICAgICAgICAgdXNlckxhc3RJbnB1dC5zZW5kS2V5cygnJyk7CgogICAgICAgICAgZXhwZWN0KHVzZXIuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3sibmFtZSI6Imd1ZXN0IiwibGFzdCI6IiJ9Jyk7CiAgICAgICAgICBleHBlY3QobGFzdE5hbWVWYWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbigndHJ1ZScpOwogICAgICAgICAgZXhwZWN0KGZvcm1WYWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbigndHJ1ZScpOwogICAgICAgIH0pOwoKICAgICAgICBpdCgnc2hvdWxkIGJlIGludmFsaWQgaWYgbGVzcyB0aGFuIHJlcXVpcmVkIG1pbiBsZW5ndGgnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIHVzZXJMYXN0SW5wdXQuY2xlYXIoKTsKICAgICAgICAgIHVzZXJMYXN0SW5wdXQuc2VuZEtleXMoJ3h4Jyk7CgogICAgICAgICAgZXhwZWN0KHVzZXIuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3sibmFtZSI6Imd1ZXN0In0nKTsKICAgICAgICAgIGV4cGVjdChsYXN0TmFtZVZhbGlkLmdldFRleHQoKSkudG9Db250YWluKCdmYWxzZScpOwogICAgICAgICAgZXhwZWN0KGxhc3ROYW1lRXJyb3IuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ21pbmxlbmd0aCcpOwogICAgICAgICAgZXhwZWN0KGZvcm1WYWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICB9KTsKCiAgICAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIGxvbmdlciB0aGFuIG1heCBsZW5ndGgnLCBmdW5jdGlvbigpIHsKICAgICAgICAgIHVzZXJMYXN0SW5wdXQuY2xlYXIoKTsKICAgICAgICAgIHVzZXJMYXN0SW5wdXQuc2VuZEtleXMoJ3NvbWUgcmlkaWN1bG91c2x5IGxvbmcgbmFtZScpOwoKICAgICAgICAgIGV4cGVjdCh1c2VyLmdldFRleHQoKSkudG9Db250YWluKCd7Im5hbWUiOiJndWVzdCJ9Jyk7CiAgICAgICAgICBleHBlY3QobGFzdE5hbWVWYWxpZC5nZXRUZXh0KCkpLnRvQ29udGFpbignZmFsc2UnKTsKICAgICAgICAgIGV4cGVjdChsYXN0TmFtZUVycm9yLmdldFRleHQoKSkudG9Db250YWluKCdtYXhsZW5ndGgnKTsKICAgICAgICAgIGV4cGVjdChmb3JtVmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICovCnZhciBpbnB1dERpcmVjdGl2ZSA9IFsnJGJyb3dzZXInLCAnJHNuaWZmZXInLCAnJGZpbHRlcicsICckcGFyc2UnLAogICAgZnVuY3Rpb24oJGJyb3dzZXIsICRzbmlmZmVyLCAkZmlsdGVyLCAkcGFyc2UpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdFJywKICAgIHJlcXVpcmU6IFsnP25nTW9kZWwnXSwKICAgIGxpbms6IHsKICAgICAgcHJlOiBmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybHMpIHsKICAgICAgICBpZiAoY3RybHNbMF0pIHsKICAgICAgICAgIChpbnB1dFR5cGVbbG93ZXJjYXNlKGF0dHIudHlwZSldIHx8IGlucHV0VHlwZS50ZXh0KShzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybHNbMF0sICRzbmlmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRicm93c2VyLCAkZmlsdGVyLCAkcGFyc2UpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn1dOwoKdmFyIFZBTElEX0NMQVNTID0gJ25nLXZhbGlkJywKICAgIElOVkFMSURfQ0xBU1MgPSAnbmctaW52YWxpZCcsCiAgICBQUklTVElORV9DTEFTUyA9ICduZy1wcmlzdGluZScsCiAgICBESVJUWV9DTEFTUyA9ICduZy1kaXJ0eScsCiAgICBVTlRPVUNIRURfQ0xBU1MgPSAnbmctdW50b3VjaGVkJywKICAgIFRPVUNIRURfQ0xBU1MgPSAnbmctdG91Y2hlZCcsCiAgICBQRU5ESU5HX0NMQVNTID0gJ25nLXBlbmRpbmcnOwoKLyoqCiAqIEBuZ2RvYyB0eXBlCiAqIEBuYW1lIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIKICoKICogQHByb3BlcnR5IHtzdHJpbmd9ICR2aWV3VmFsdWUgQWN0dWFsIHN0cmluZyB2YWx1ZSBpbiB0aGUgdmlldy4KICogQHByb3BlcnR5IHsqfSAkbW9kZWxWYWx1ZSBUaGUgdmFsdWUgaW4gdGhlIG1vZGVsIHRoYXQgdGhlIGNvbnRyb2wgaXMgYm91bmQgdG8uCiAqIEBwcm9wZXJ0eSB7QXJyYXkuPEZ1bmN0aW9uPn0gJHBhcnNlcnMgQXJyYXkgb2YgZnVuY3Rpb25zIHRvIGV4ZWN1dGUsIGFzIGEgcGlwZWxpbmUsIHdoZW5ldmVyCiAgICAgICB0aGUgY29udHJvbCByZWFkcyB2YWx1ZSBmcm9tIHRoZSBET00uIFRoZSBmdW5jdGlvbnMgYXJlIGNhbGxlZCBpbiBhcnJheSBvcmRlciwgZWFjaCBwYXNzaW5nCiAgICAgICBpdHMgcmV0dXJuIHZhbHVlIHRocm91Z2ggdG8gdGhlIG5leHQuIFRoZSBsYXN0IHJldHVybiB2YWx1ZSBpcyBmb3J3YXJkZWQgdG8gdGhlCiAgICAgICB7QGxpbmsgbmdNb2RlbC5OZ01vZGVsQ29udHJvbGxlciMkdmFsaWRhdG9ycyBgJHZhbGlkYXRvcnNgfSBjb2xsZWN0aW9uLgoKUGFyc2VycyBhcmUgdXNlZCB0byBzYW5pdGl6ZSAvIGNvbnZlcnQgdGhlIHtAbGluayBuZ01vZGVsLk5nTW9kZWxDb250cm9sbGVyIyR2aWV3VmFsdWUKYCR2aWV3VmFsdWVgfS4KClJldHVybmluZyBgdW5kZWZpbmVkYCBmcm9tIGEgcGFyc2VyIG1lYW5zIGEgcGFyc2UgZXJyb3Igb2NjdXJyZWQuIEluIHRoYXQgY2FzZSwKbm8ge0BsaW5rIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjJHZhbGlkYXRvcnMgYCR2YWxpZGF0b3JzYH0gd2lsbCBydW4gYW5kIHRoZSBgbmdNb2RlbGAKd2lsbCBiZSBzZXQgdG8gYHVuZGVmaW5lZGAgdW5sZXNzIHtAbGluayBuZ01vZGVsT3B0aW9ucyBgbmdNb2RlbE9wdGlvbnMuYWxsb3dJbnZhbGlkYH0KaXMgc2V0IHRvIGB0cnVlYC4gVGhlIHBhcnNlIGVycm9yIGlzIHN0b3JlZCBpbiBgbmdNb2RlbC4kZXJyb3IucGFyc2VgLgoKICoKICogQHByb3BlcnR5IHtBcnJheS48RnVuY3Rpb24+fSAkZm9ybWF0dGVycyBBcnJheSBvZiBmdW5jdGlvbnMgdG8gZXhlY3V0ZSwgYXMgYSBwaXBlbGluZSwgd2hlbmV2ZXIKICAgICAgIHRoZSBtb2RlbCB2YWx1ZSBjaGFuZ2VzLiBUaGUgZnVuY3Rpb25zIGFyZSBjYWxsZWQgaW4gcmV2ZXJzZSBhcnJheSBvcmRlciwgZWFjaCBwYXNzaW5nIHRoZSB2YWx1ZSB0aHJvdWdoIHRvIHRoZQogICAgICAgbmV4dC4gVGhlIGxhc3QgcmV0dXJuIHZhbHVlIGlzIHVzZWQgYXMgdGhlIGFjdHVhbCBET00gdmFsdWUuCiAgICAgICBVc2VkIHRvIGZvcm1hdCAvIGNvbnZlcnQgdmFsdWVzIGZvciBkaXNwbGF5IGluIHRoZSBjb250cm9sLgogKiBgYGBqcwogKiBmdW5jdGlvbiBmb3JtYXR0ZXIodmFsdWUpIHsKICogICBpZiAodmFsdWUpIHsKICogICAgIHJldHVybiB2YWx1ZS50b1VwcGVyQ2FzZSgpOwogKiAgIH0KICogfQogKiBuZ01vZGVsLiRmb3JtYXR0ZXJzLnB1c2goZm9ybWF0dGVyKTsKICogYGBgCiAqCiAqIEBwcm9wZXJ0eSB7T2JqZWN0LjxzdHJpbmcsIGZ1bmN0aW9uPn0gJHZhbGlkYXRvcnMgQSBjb2xsZWN0aW9uIG9mIHZhbGlkYXRvcnMgdGhhdCBhcmUgYXBwbGllZAogKiAgICAgIHdoZW5ldmVyIHRoZSBtb2RlbCB2YWx1ZSBjaGFuZ2VzLiBUaGUga2V5IHZhbHVlIHdpdGhpbiB0aGUgb2JqZWN0IHJlZmVycyB0byB0aGUgbmFtZSBvZiB0aGUKICogICAgICB2YWxpZGF0b3Igd2hpbGUgdGhlIGZ1bmN0aW9uIHJlZmVycyB0byB0aGUgdmFsaWRhdGlvbiBvcGVyYXRpb24uIFRoZSB2YWxpZGF0aW9uIG9wZXJhdGlvbiBpcwogKiAgICAgIHByb3ZpZGVkIHdpdGggdGhlIG1vZGVsIHZhbHVlIGFzIGFuIGFyZ3VtZW50IGFuZCBtdXN0IHJldHVybiBhIHRydWUgb3IgZmFsc2UgdmFsdWUgZGVwZW5kaW5nCiAqICAgICAgb24gdGhlIHJlc3BvbnNlIG9mIHRoYXQgdmFsaWRhdGlvbi4KICoKICogYGBganMKICogbmdNb2RlbC4kdmFsaWRhdG9ycy52YWxpZENoYXJhY3RlcnMgPSBmdW5jdGlvbihtb2RlbFZhbHVlLCB2aWV3VmFsdWUpIHsKICogICB2YXIgdmFsdWUgPSBtb2RlbFZhbHVlIHx8IHZpZXdWYWx1ZTsKICogICByZXR1cm4gL1swLTldKy8udGVzdCh2YWx1ZSkgJiYKICogICAgICAgICAgL1thLXpdKy8udGVzdCh2YWx1ZSkgJiYKICogICAgICAgICAgL1tBLVpdKy8udGVzdCh2YWx1ZSkgJiYKICogICAgICAgICAgL1xXKy8udGVzdCh2YWx1ZSk7CiAqIH07CiAqIGBgYAogKgogKiBAcHJvcGVydHkge09iamVjdC48c3RyaW5nLCBmdW5jdGlvbj59ICRhc3luY1ZhbGlkYXRvcnMgQSBjb2xsZWN0aW9uIG9mIHZhbGlkYXRpb25zIHRoYXQgYXJlIGV4cGVjdGVkIHRvCiAqICAgICAgcGVyZm9ybSBhbiBhc3luY2hyb25vdXMgdmFsaWRhdGlvbiAoZS5nLiBhIEhUVFAgcmVxdWVzdCkuIFRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uIHRoYXQgaXMgcHJvdmlkZWQKICogICAgICBpcyBleHBlY3RlZCB0byByZXR1cm4gYSBwcm9taXNlIHdoZW4gaXQgaXMgcnVuIGR1cmluZyB0aGUgbW9kZWwgdmFsaWRhdGlvbiBwcm9jZXNzLiBPbmNlIHRoZSBwcm9taXNlCiAqICAgICAgaXMgZGVsaXZlcmVkIHRoZW4gdGhlIHZhbGlkYXRpb24gc3RhdHVzIHdpbGwgYmUgc2V0IHRvIHRydWUgd2hlbiBmdWxmaWxsZWQgYW5kIGZhbHNlIHdoZW4gcmVqZWN0ZWQuCiAqICAgICAgV2hlbiB0aGUgYXN5bmNocm9ub3VzIHZhbGlkYXRvcnMgYXJlIHRyaWdnZXJlZCwgZWFjaCBvZiB0aGUgdmFsaWRhdG9ycyB3aWxsIHJ1biBpbiBwYXJhbGxlbCBhbmQgdGhlIG1vZGVsCiAqICAgICAgdmFsdWUgd2lsbCBvbmx5IGJlIHVwZGF0ZWQgb25jZSBhbGwgdmFsaWRhdG9ycyBoYXZlIGJlZW4gZnVsZmlsbGVkLiBBcyBsb25nIGFzIGFuIGFzeW5jaHJvbm91cyB2YWxpZGF0b3IKICogICAgICBpcyB1bmZ1bGZpbGxlZCwgaXRzIGtleSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjb250cm9sbGVycyBgJHBlbmRpbmdgIHByb3BlcnR5LiBBbHNvLCBhbGwgYXN5bmNocm9ub3VzIHZhbGlkYXRvcnMKICogICAgICB3aWxsIG9ubHkgcnVuIG9uY2UgYWxsIHN5bmNocm9ub3VzIHZhbGlkYXRvcnMgaGF2ZSBwYXNzZWQuCiAqCiAqIFBsZWFzZSBub3RlIHRoYXQgaWYgJGh0dHAgaXMgdXNlZCB0aGVuIGl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSBzZXJ2ZXIgcmV0dXJucyBhIHN1Y2Nlc3MgSFRUUCByZXNwb25zZSBjb2RlCiAqIGluIG9yZGVyIHRvIGZ1bGZpbGwgdGhlIHZhbGlkYXRpb24gYW5kIGEgc3RhdHVzIGxldmVsIG9mIGA0eHhgIGluIG9yZGVyIHRvIHJlamVjdCB0aGUgdmFsaWRhdGlvbi4KICoKICogYGBganMKICogbmdNb2RlbC4kYXN5bmNWYWxpZGF0b3JzLnVuaXF1ZVVzZXJuYW1lID0gZnVuY3Rpb24obW9kZWxWYWx1ZSwgdmlld1ZhbHVlKSB7CiAqICAgdmFyIHZhbHVlID0gbW9kZWxWYWx1ZSB8fCB2aWV3VmFsdWU7CiAqCiAqICAgLy8gTG9va3VwIHVzZXIgYnkgdXNlcm5hbWUKICogICByZXR1cm4gJGh0dHAuZ2V0KCcvYXBpL3VzZXJzLycgKyB2YWx1ZSkuCiAqICAgICAgdGhlbihmdW5jdGlvbiByZXNvbHZlZCgpIHsKICogICAgICAgIC8vdXNlcm5hbWUgZXhpc3RzLCB0aGlzIG1lYW5zIHZhbGlkYXRpb24gZmFpbHMKICogICAgICAgIHJldHVybiAkcS5yZWplY3QoJ2V4aXN0cycpOwogKiAgICAgIH0sIGZ1bmN0aW9uIHJlamVjdGVkKCkgewogKiAgICAgICAgLy91c2VybmFtZSBkb2VzIG5vdCBleGlzdCwgdGhlcmVmb3JlIHRoaXMgdmFsaWRhdGlvbiBwYXNzZXMKICogICAgICAgIHJldHVybiB0cnVlOwogKiAgICAgIH0pOwogKiB9OwogKiBgYGAKICoKICogQHByb3BlcnR5IHtBcnJheS48RnVuY3Rpb24+fSAkdmlld0NoYW5nZUxpc3RlbmVycyBBcnJheSBvZiBmdW5jdGlvbnMgdG8gZXhlY3V0ZSB3aGVuZXZlciB0aGUKICogICAgIHZpZXcgdmFsdWUgaGFzIGNoYW5nZWQuIEl0IGlzIGNhbGxlZCB3aXRoIG5vIGFyZ3VtZW50cywgYW5kIGl0cyByZXR1cm4gdmFsdWUgaXMgaWdub3JlZC4KICogICAgIFRoaXMgY2FuIGJlIHVzZWQgaW4gcGxhY2Ugb2YgYWRkaXRpb25hbCAkd2F0Y2hlcyBhZ2FpbnN0IHRoZSBtb2RlbCB2YWx1ZS4KICoKICogQHByb3BlcnR5IHtPYmplY3R9ICRlcnJvciBBbiBvYmplY3QgaGFzaCB3aXRoIGFsbCBmYWlsaW5nIHZhbGlkYXRvciBpZHMgYXMga2V5cy4KICogQHByb3BlcnR5IHtPYmplY3R9ICRwZW5kaW5nIEFuIG9iamVjdCBoYXNoIHdpdGggYWxsIHBlbmRpbmcgdmFsaWRhdG9yIGlkcyBhcyBrZXlzLgogKgogKiBAcHJvcGVydHkge2Jvb2xlYW59ICR1bnRvdWNoZWQgVHJ1ZSBpZiBjb250cm9sIGhhcyBub3QgbG9zdCBmb2N1cyB5ZXQuCiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gJHRvdWNoZWQgVHJ1ZSBpZiBjb250cm9sIGhhcyBsb3N0IGZvY3VzLgogKiBAcHJvcGVydHkge2Jvb2xlYW59ICRwcmlzdGluZSBUcnVlIGlmIHVzZXIgaGFzIG5vdCBpbnRlcmFjdGVkIHdpdGggdGhlIGNvbnRyb2wgeWV0LgogKiBAcHJvcGVydHkge2Jvb2xlYW59ICRkaXJ0eSBUcnVlIGlmIHVzZXIgaGFzIGFscmVhZHkgaW50ZXJhY3RlZCB3aXRoIHRoZSBjb250cm9sLgogKiBAcHJvcGVydHkge2Jvb2xlYW59ICR2YWxpZCBUcnVlIGlmIHRoZXJlIGlzIG5vIGVycm9yLgogKiBAcHJvcGVydHkge2Jvb2xlYW59ICRpbnZhbGlkIFRydWUgaWYgYXQgbGVhc3Qgb25lIGVycm9yIG9uIHRoZSBjb250cm9sLgogKiBAcHJvcGVydHkge3N0cmluZ30gJG5hbWUgVGhlIG5hbWUgYXR0cmlidXRlIG9mIHRoZSBjb250cm9sLgogKgogKiBAZGVzY3JpcHRpb24KICoKICogYE5nTW9kZWxDb250cm9sbGVyYCBwcm92aWRlcyBBUEkgZm9yIHRoZSB7QGxpbmsgbmdNb2RlbCBgbmdNb2RlbGB9IGRpcmVjdGl2ZS4KICogVGhlIGNvbnRyb2xsZXIgY29udGFpbnMgc2VydmljZXMgZm9yIGRhdGEtYmluZGluZywgdmFsaWRhdGlvbiwgQ1NTIHVwZGF0ZXMsIGFuZCB2YWx1ZSBmb3JtYXR0aW5nCiAqIGFuZCBwYXJzaW5nLiBJdCBwdXJwb3NlZnVsbHkgZG9lcyBub3QgY29udGFpbiBhbnkgbG9naWMgd2hpY2ggZGVhbHMgd2l0aCBET00gcmVuZGVyaW5nIG9yCiAqIGxpc3RlbmluZyB0byBET00gZXZlbnRzLgogKiBTdWNoIERPTSByZWxhdGVkIGxvZ2ljIHNob3VsZCBiZSBwcm92aWRlZCBieSBvdGhlciBkaXJlY3RpdmVzIHdoaWNoIG1ha2UgdXNlIG9mCiAqIGBOZ01vZGVsQ29udHJvbGxlcmAgZm9yIGRhdGEtYmluZGluZyB0byBjb250cm9sIGVsZW1lbnRzLgogKiBBbmd1bGFyIHByb3ZpZGVzIHRoaXMgRE9NIGxvZ2ljIGZvciBtb3N0IHtAbGluayBpbnB1dCBgaW5wdXRgfSBlbGVtZW50cy4KICogQXQgdGhlIGVuZCBvZiB0aGlzIHBhZ2UgeW91IGNhbiBmaW5kIGEge0BsaW5rIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjY3VzdG9tLWNvbnRyb2wtZXhhbXBsZQogKiBjdXN0b20gY29udHJvbCBleGFtcGxlfSB0aGF0IHVzZXMgYG5nTW9kZWxDb250cm9sbGVyYCB0byBiaW5kIHRvIGBjb250ZW50ZWRpdGFibGVgIGVsZW1lbnRzLgogKgogKiBAZXhhbXBsZQogKiAjIyMgQ3VzdG9tIENvbnRyb2wgRXhhbXBsZQogKiBUaGlzIGV4YW1wbGUgc2hvd3MgaG93IHRvIHVzZSBgTmdNb2RlbENvbnRyb2xsZXJgIHdpdGggYSBjdXN0b20gY29udHJvbCB0byBhY2hpZXZlCiAqIGRhdGEtYmluZGluZy4gTm90aWNlIGhvdyBkaWZmZXJlbnQgZGlyZWN0aXZlcyAoYGNvbnRlbnRlZGl0YWJsZWAsIGBuZy1tb2RlbGAsIGFuZCBgcmVxdWlyZWRgKQogKiBjb2xsYWJvcmF0ZSB0b2dldGhlciB0byBhY2hpZXZlIHRoZSBkZXNpcmVkIHJlc3VsdC4KICoKICogTm90ZSB0aGF0IGBjb250ZW50ZWRpdGFibGVgIGlzIGFuIEhUTUw1IGF0dHJpYnV0ZSwgd2hpY2ggdGVsbHMgdGhlIGJyb3dzZXIgdG8gbGV0IHRoZSBlbGVtZW50CiAqIGNvbnRlbnRzIGJlIGVkaXRlZCBpbiBwbGFjZSBieSB0aGUgdXNlci4gIFRoaXMgd2lsbCBub3Qgd29yayBvbiBvbGRlciBicm93c2Vycy4KICoKICogV2UgYXJlIHVzaW5nIHRoZSB7QGxpbmsgbmcuc2VydmljZTokc2NlICRzY2V9IHNlcnZpY2UgaGVyZSBhbmQgaW5jbHVkZSB0aGUge0BsaW5rIG5nU2FuaXRpemUgJHNhbml0aXplfQogKiBtb2R1bGUgdG8gYXV0b21hdGljYWxseSByZW1vdmUgImJhZCIgY29udGVudCBsaWtlIGlubGluZSBldmVudCBsaXN0ZW5lciAoZS5nLiBgPHNwYW4gb25jbGljaz0iLi4uIj5gKS4KICogSG93ZXZlciwgYXMgd2UgYXJlIHVzaW5nIGAkc2NlYCB0aGUgbW9kZWwgY2FuIHN0aWxsIGRlY2lkZSB0byBwcm92aWRlIHVuc2FmZSBjb250ZW50IGlmIGl0IG1hcmtzCiAqIHRoYXQgY29udGVudCB1c2luZyB0aGUgYCRzY2VgIHNlcnZpY2UuCiAqCiAqIDxleGFtcGxlIG5hbWU9Ik5nTW9kZWxDb250cm9sbGVyIiBtb2R1bGU9ImN1c3RvbUNvbnRyb2wiIGRlcHM9ImFuZ3VsYXItc2FuaXRpemUuanMiPgogICAgPGZpbGUgbmFtZT0ic3R5bGUuY3NzIj4KICAgICAgW2NvbnRlbnRlZGl0YWJsZV0gewogICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrOwogICAgICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOwogICAgICAgIG1pbi1oZWlnaHQ6IDIwcHg7CiAgICAgIH0KCiAgICAgIC5uZy1pbnZhbGlkIHsKICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZWQ7CiAgICAgIH0KCiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICBhbmd1bGFyLm1vZHVsZSgnY3VzdG9tQ29udHJvbCcsIFsnbmdTYW5pdGl6ZSddKS4KICAgICAgICBkaXJlY3RpdmUoJ2NvbnRlbnRlZGl0YWJsZScsIFsnJHNjZScsIGZ1bmN0aW9uKCRzY2UpIHsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHJlc3RyaWN0OiAnQScsIC8vIG9ubHkgYWN0aXZhdGUgb24gZWxlbWVudCBhdHRyaWJ1dGUKICAgICAgICAgICAgcmVxdWlyZTogJz9uZ01vZGVsJywgLy8gZ2V0IGEgaG9sZCBvZiBOZ01vZGVsQ29udHJvbGxlcgogICAgICAgICAgICBsaW5rOiBmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0cnMsIG5nTW9kZWwpIHsKICAgICAgICAgICAgICBpZiAoIW5nTW9kZWwpIHJldHVybjsgLy8gZG8gbm90aGluZyBpZiBubyBuZy1tb2RlbAoKICAgICAgICAgICAgICAvLyBTcGVjaWZ5IGhvdyBVSSBzaG91bGQgYmUgdXBkYXRlZAogICAgICAgICAgICAgIG5nTW9kZWwuJHJlbmRlciA9IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgZWxlbWVudC5odG1sKCRzY2UuZ2V0VHJ1c3RlZEh0bWwobmdNb2RlbC4kdmlld1ZhbHVlIHx8ICcnKSk7CiAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgLy8gTGlzdGVuIGZvciBjaGFuZ2UgZXZlbnRzIHRvIGVuYWJsZSBiaW5kaW5nCiAgICAgICAgICAgICAgZWxlbWVudC5vbignYmx1ciBrZXl1cCBjaGFuZ2UnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHNjb3BlLiRldmFsQXN5bmMocmVhZCk7CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgcmVhZCgpOyAvLyBpbml0aWFsaXplCgogICAgICAgICAgICAgIC8vIFdyaXRlIGRhdGEgdG8gdGhlIG1vZGVsCiAgICAgICAgICAgICAgZnVuY3Rpb24gcmVhZCgpIHsKICAgICAgICAgICAgICAgIHZhciBodG1sID0gZWxlbWVudC5odG1sKCk7CiAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGNsZWFyIHRoZSBjb250ZW50IGVkaXRhYmxlIHRoZSBicm93c2VyIGxlYXZlcyBhIDxicj4gYmVoaW5kCiAgICAgICAgICAgICAgICAvLyBJZiBzdHJpcC1iciBhdHRyaWJ1dGUgaXMgcHJvdmlkZWQgdGhlbiB3ZSBzdHJpcCB0aGlzIG91dAogICAgICAgICAgICAgICAgaWYgKCBhdHRycy5zdHJpcEJyICYmIGh0bWwgPT0gJzxicj4nICkgewogICAgICAgICAgICAgICAgICBodG1sID0gJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZ01vZGVsLiRzZXRWaWV3VmFsdWUoaHRtbCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgIH1dKTsKICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8Zm9ybSBuYW1lPSJteUZvcm0iPgogICAgICAgPGRpdiBjb250ZW50ZWRpdGFibGUKICAgICAgICAgICAgbmFtZT0ibXlXaWRnZXQiIG5nLW1vZGVsPSJ1c2VyQ29udGVudCIKICAgICAgICAgICAgc3RyaXAtYnI9InRydWUiCiAgICAgICAgICAgIHJlcXVpcmVkPkNoYW5nZSBtZSE8L2Rpdj4KICAgICAgICA8c3BhbiBuZy1zaG93PSJteUZvcm0ubXlXaWRnZXQuJGVycm9yLnJlcXVpcmVkIj5SZXF1aXJlZCE8L3NwYW4+CiAgICAgICA8aHI+CiAgICAgICA8dGV4dGFyZWEgbmctbW9kZWw9InVzZXJDb250ZW50Ij48L3RleHRhcmVhPgogICAgICA8L2Zvcm0+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgIGl0KCdzaG91bGQgZGF0YS1iaW5kIGFuZCBiZWNvbWUgaW52YWxpZCcsIGZ1bmN0aW9uKCkgewogICAgICBpZiAoYnJvd3Nlci5wYXJhbXMuYnJvd3NlciA9PSAnc2FmYXJpJyB8fCBicm93c2VyLnBhcmFtcy5icm93c2VyID09ICdmaXJlZm94JykgewogICAgICAgIC8vIFNhZmFyaURyaXZlciBjYW4ndCBoYW5kbGUgY29udGVudGVkaXRhYmxlCiAgICAgICAgLy8gYW5kIEZpcmVmb3ggZHJpdmVyIGNhbid0IGNsZWFyIGNvbnRlbnRlZGl0YWJsZXMgdmVyeSB3ZWxsCiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIHZhciBjb250ZW50RWRpdGFibGUgPSBlbGVtZW50KGJ5LmNzcygnW2NvbnRlbnRlZGl0YWJsZV0nKSk7CiAgICAgIHZhciBjb250ZW50ID0gJ0NoYW5nZSBtZSEnOwoKICAgICAgZXhwZWN0KGNvbnRlbnRFZGl0YWJsZS5nZXRUZXh0KCkpLnRvRXF1YWwoY29udGVudCk7CgogICAgICBjb250ZW50RWRpdGFibGUuY2xlYXIoKTsKICAgICAgY29udGVudEVkaXRhYmxlLnNlbmRLZXlzKHByb3RyYWN0b3IuS2V5LkJBQ0tfU1BBQ0UpOwogICAgICBleHBlY3QoY29udGVudEVkaXRhYmxlLmdldFRleHQoKSkudG9FcXVhbCgnJyk7CiAgICAgIGV4cGVjdChjb250ZW50RWRpdGFibGUuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS50b01hdGNoKC9uZy1pbnZhbGlkLXJlcXVpcmVkLyk7CiAgICB9KTsKICAgIDwvZmlsZT4KICogPC9leGFtcGxlPgogKgogKgogKi8KdmFyIE5nTW9kZWxDb250cm9sbGVyID0gWyckc2NvcGUnLCAnJGV4Y2VwdGlvbkhhbmRsZXInLCAnJGF0dHJzJywgJyRlbGVtZW50JywgJyRwYXJzZScsICckYW5pbWF0ZScsICckdGltZW91dCcsICckcm9vdFNjb3BlJywgJyRxJywgJyRpbnRlcnBvbGF0ZScsCiAgICBmdW5jdGlvbigkc2NvcGUsICRleGNlcHRpb25IYW5kbGVyLCAkYXR0ciwgJGVsZW1lbnQsICRwYXJzZSwgJGFuaW1hdGUsICR0aW1lb3V0LCAkcm9vdFNjb3BlLCAkcSwgJGludGVycG9sYXRlKSB7CiAgdGhpcy4kdmlld1ZhbHVlID0gTnVtYmVyLk5hTjsKICB0aGlzLiRtb2RlbFZhbHVlID0gTnVtYmVyLk5hTjsKICB0aGlzLiQkcmF3TW9kZWxWYWx1ZSA9IHVuZGVmaW5lZDsgLy8gc3RvcmVzIHRoZSBwYXJzZWQgbW9kZWxWYWx1ZSAvIG1vZGVsIHNldCBmcm9tIHNjb3BlIHJlZ2FyZGxlc3Mgb2YgdmFsaWRpdHkuCiAgdGhpcy4kdmFsaWRhdG9ycyA9IHt9OwogIHRoaXMuJGFzeW5jVmFsaWRhdG9ycyA9IHt9OwogIHRoaXMuJHBhcnNlcnMgPSBbXTsKICB0aGlzLiRmb3JtYXR0ZXJzID0gW107CiAgdGhpcy4kdmlld0NoYW5nZUxpc3RlbmVycyA9IFtdOwogIHRoaXMuJHVudG91Y2hlZCA9IHRydWU7CiAgdGhpcy4kdG91Y2hlZCA9IGZhbHNlOwogIHRoaXMuJHByaXN0aW5lID0gdHJ1ZTsKICB0aGlzLiRkaXJ0eSA9IGZhbHNlOwogIHRoaXMuJHZhbGlkID0gdHJ1ZTsKICB0aGlzLiRpbnZhbGlkID0gZmFsc2U7CiAgdGhpcy4kZXJyb3IgPSB7fTsgLy8ga2VlcCBpbnZhbGlkIGtleXMgaGVyZQogIHRoaXMuJCRzdWNjZXNzID0ge307IC8vIGtlZXAgdmFsaWQga2V5cyBoZXJlCiAgdGhpcy4kcGVuZGluZyA9IHVuZGVmaW5lZDsgLy8ga2VlcCBwZW5kaW5nIGtleXMgaGVyZQogIHRoaXMuJG5hbWUgPSAkaW50ZXJwb2xhdGUoJGF0dHIubmFtZSB8fCAnJywgZmFsc2UpKCRzY29wZSk7CgoKICB2YXIgcGFyc2VkTmdNb2RlbCA9ICRwYXJzZSgkYXR0ci5uZ01vZGVsKSwKICAgICAgcGFyc2VkTmdNb2RlbEFzc2lnbiA9IHBhcnNlZE5nTW9kZWwuYXNzaWduLAogICAgICBuZ01vZGVsR2V0ID0gcGFyc2VkTmdNb2RlbCwKICAgICAgbmdNb2RlbFNldCA9IHBhcnNlZE5nTW9kZWxBc3NpZ24sCiAgICAgIHBlbmRpbmdEZWJvdW5jZSA9IG51bGwsCiAgICAgIGN0cmwgPSB0aGlzOwoKICB0aGlzLiQkc2V0T3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIGN0cmwuJG9wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5nZXR0ZXJTZXR0ZXIpIHsKICAgICAgdmFyIGludm9rZU1vZGVsR2V0dGVyID0gJHBhcnNlKCRhdHRyLm5nTW9kZWwgKyAnKCknKSwKICAgICAgICAgIGludm9rZU1vZGVsU2V0dGVyID0gJHBhcnNlKCRhdHRyLm5nTW9kZWwgKyAnKCQkJHApJyk7CgogICAgICBuZ01vZGVsR2V0ID0gZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgdmFyIG1vZGVsVmFsdWUgPSBwYXJzZWROZ01vZGVsKCRzY29wZSk7CiAgICAgICAgaWYgKGlzRnVuY3Rpb24obW9kZWxWYWx1ZSkpIHsKICAgICAgICAgIG1vZGVsVmFsdWUgPSBpbnZva2VNb2RlbEdldHRlcigkc2NvcGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbW9kZWxWYWx1ZTsKICAgICAgfTsKICAgICAgbmdNb2RlbFNldCA9IGZ1bmN0aW9uKCRzY29wZSwgbmV3VmFsdWUpIHsKICAgICAgICBpZiAoaXNGdW5jdGlvbihwYXJzZWROZ01vZGVsKCRzY29wZSkpKSB7CiAgICAgICAgICBpbnZva2VNb2RlbFNldHRlcigkc2NvcGUsIHskJCRwOiBjdHJsLiRtb2RlbFZhbHVlfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBhcnNlZE5nTW9kZWxBc3NpZ24oJHNjb3BlLCBjdHJsLiRtb2RlbFZhbHVlKTsKICAgICAgICB9CiAgICAgIH07CiAgICB9IGVsc2UgaWYgKCFwYXJzZWROZ01vZGVsLmFzc2lnbikgewogICAgICB0aHJvdyAkbmdNb2RlbE1pbkVycignbm9uYXNzaWduJywgIkV4cHJlc3Npb24gJ3swfScgaXMgbm9uLWFzc2lnbmFibGUuIEVsZW1lbnQ6IHsxfSIsCiAgICAgICAgICAkYXR0ci5uZ01vZGVsLCBzdGFydGluZ1RhZygkZWxlbWVudCkpOwogICAgfQogIH07CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBuZ01vZGVsLk5nTW9kZWxDb250cm9sbGVyIyRyZW5kZXIKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIENhbGxlZCB3aGVuIHRoZSB2aWV3IG5lZWRzIHRvIGJlIHVwZGF0ZWQuIEl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIHVzZXIgb2YgdGhlIG5nLW1vZGVsCiAgICogZGlyZWN0aXZlIHdpbGwgaW1wbGVtZW50IHRoaXMgbWV0aG9kLgogICAqCiAgICogVGhlIGAkcmVuZGVyKClgIG1ldGhvZCBpcyBpbnZva2VkIGluIHRoZSBmb2xsb3dpbmcgc2l0dWF0aW9uczoKICAgKgogICAqICogYCRyb2xsYmFja1ZpZXdWYWx1ZSgpYCBpcyBjYWxsZWQuICBJZiB3ZSBhcmUgcm9sbGluZyBiYWNrIHRoZSB2aWV3IHZhbHVlIHRvIHRoZSBsYXN0CiAgICogICBjb21taXR0ZWQgdmFsdWUgdGhlbiBgJHJlbmRlcigpYCBpcyBjYWxsZWQgdG8gdXBkYXRlIHRoZSBpbnB1dCBjb250cm9sLgogICAqICogVGhlIHZhbHVlIHJlZmVyZW5jZWQgYnkgYG5nLW1vZGVsYCBpcyBjaGFuZ2VkIHByb2dyYW1tYXRpY2FsbHkgYW5kIGJvdGggdGhlIGAkbW9kZWxWYWx1ZWAgYW5kCiAgICogICB0aGUgYCR2aWV3VmFsdWVgIGFyZSBkaWZmZXJlbnQgdG8gbGFzdCB0aW1lLgogICAqCiAgICogU2luY2UgYG5nLW1vZGVsYCBkb2VzIG5vdCBkbyBhIGRlZXAgd2F0Y2gsIGAkcmVuZGVyKClgIGlzIG9ubHkgaW52b2tlZCBpZiB0aGUgdmFsdWVzIG9mCiAgICogYCRtb2RlbFZhbHVlYCBhbmQgYCR2aWV3VmFsdWVgIGFyZSBhY3R1YWxseSBkaWZmZXJlbnQgdG8gdGhlaXIgcHJldmlvdXMgdmFsdWUuIElmIGAkbW9kZWxWYWx1ZWAKICAgKiBvciBgJHZpZXdWYWx1ZWAgYXJlIG9iamVjdHMgKHJhdGhlciB0aGFuIGEgc3RyaW5nIG9yIG51bWJlcikgdGhlbiBgJHJlbmRlcigpYCB3aWxsIG5vdCBiZQogICAqIGludm9rZWQgaWYgeW91IG9ubHkgY2hhbmdlIGEgcHJvcGVydHkgb24gdGhlIG9iamVjdHMuCiAgICovCiAgdGhpcy4kcmVuZGVyID0gbm9vcDsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjJGlzRW1wdHkKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gd2UgbmVlZCB0byBkZXRlcm1pbmUgaWYgdGhlIHZhbHVlIG9mIGFuIGlucHV0IGlzIGVtcHR5LgogICAqCiAgICogRm9yIGluc3RhbmNlLCB0aGUgcmVxdWlyZWQgZGlyZWN0aXZlIGRvZXMgdGhpcyB0byB3b3JrIG91dCBpZiB0aGUgaW5wdXQgaGFzIGRhdGEgb3Igbm90LgogICAqCiAgICogVGhlIGRlZmF1bHQgYCRpc0VtcHR5YCBmdW5jdGlvbiBjaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgaXMgYHVuZGVmaW5lZGAsIGAnJ2AsIGBudWxsYCBvciBgTmFOYC4KICAgKgogICAqIFlvdSBjYW4gb3ZlcnJpZGUgdGhpcyBmb3IgaW5wdXQgZGlyZWN0aXZlcyB3aG9zZSBjb25jZXB0IG9mIGJlaW5nIGVtcHR5IGlzIGRpZmZlcmVudCB0byB0aGUKICAgKiBkZWZhdWx0LiBUaGUgYGNoZWNrYm94SW5wdXRUeXBlYCBkaXJlY3RpdmUgZG9lcyB0aGlzIGJlY2F1c2UgaW4gaXRzIGNhc2UgYSB2YWx1ZSBvZiBgZmFsc2VgCiAgICogaW1wbGllcyBlbXB0eS4KICAgKgogICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBpbnB1dCB0byBjaGVjayBmb3IgZW1wdGluZXNzLgogICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGB2YWx1ZWAgaXMgImVtcHR5Ii4KICAgKi8KICB0aGlzLiRpc0VtcHR5ID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHJldHVybiBpc1VuZGVmaW5lZCh2YWx1ZSkgfHwgdmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSBudWxsIHx8IHZhbHVlICE9PSB2YWx1ZTsKICB9OwoKICB2YXIgcGFyZW50Rm9ybSA9ICRlbGVtZW50LmluaGVyaXRlZERhdGEoJyRmb3JtQ29udHJvbGxlcicpIHx8IG51bGxGb3JtQ3RybCwKICAgICAgY3VycmVudFZhbGlkYXRpb25SdW5JZCA9IDA7CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBuZ01vZGVsLk5nTW9kZWxDb250cm9sbGVyIyRzZXRWYWxpZGl0eQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ2hhbmdlIHRoZSB2YWxpZGl0eSBzdGF0ZSwgYW5kIG5vdGlmeSB0aGUgZm9ybS4KICAgKgogICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgd2l0aGluICRwYXJzZXJzLyRmb3JtYXR0ZXJzIG9yIGEgY3VzdG9tIHZhbGlkYXRpb24gaW1wbGVtZW50YXRpb24uCiAgICogSG93ZXZlciwgaW4gbW9zdCBjYXNlcyBpdCBzaG91bGQgYmUgc3VmZmljaWVudCB0byB1c2UgdGhlIGBuZ01vZGVsLiR2YWxpZGF0b3JzYCBhbmQKICAgKiBgbmdNb2RlbC4kYXN5bmNWYWxpZGF0b3JzYCBjb2xsZWN0aW9ucyB3aGljaCB3aWxsIGNhbGwgYCRzZXRWYWxpZGl0eWAgYXV0b21hdGljYWxseS4KICAgKgogICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0aW9uRXJyb3JLZXkgTmFtZSBvZiB0aGUgdmFsaWRhdG9yLiBUaGUgYHZhbGlkYXRpb25FcnJvcktleWAgd2lsbCBiZSBhc3NpZ25lZAogICAqICAgICAgICB0byBlaXRoZXIgYCRlcnJvclt2YWxpZGF0aW9uRXJyb3JLZXldYCBvciBgJHBlbmRpbmdbdmFsaWRhdGlvbkVycm9yS2V5XWAKICAgKiAgICAgICAgKGZvciB1bmZ1bGZpbGxlZCBgJGFzeW5jVmFsaWRhdG9yc2ApLCBzbyB0aGF0IGl0IGlzIGF2YWlsYWJsZSBmb3IgZGF0YS1iaW5kaW5nLgogICAqICAgICAgICBUaGUgYHZhbGlkYXRpb25FcnJvcktleWAgc2hvdWxkIGJlIGluIGNhbWVsQ2FzZSBhbmQgd2lsbCBnZXQgY29udmVydGVkIGludG8gZGFzaC1jYXNlCiAgICogICAgICAgIGZvciBjbGFzcyBuYW1lLiBFeGFtcGxlOiBgbXlFcnJvcmAgd2lsbCByZXN1bHQgaW4gYG5nLXZhbGlkLW15LWVycm9yYCBhbmQgYG5nLWludmFsaWQtbXktZXJyb3JgCiAgICogICAgICAgIGNsYXNzIGFuZCBjYW4gYmUgYm91bmQgdG8gYXMgIGB7e3NvbWVGb3JtLnNvbWVDb250cm9sLiRlcnJvci5teUVycm9yfX1gIC4KICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzVmFsaWQgV2hldGhlciB0aGUgY3VycmVudCBzdGF0ZSBpcyB2YWxpZCAodHJ1ZSksIGludmFsaWQgKGZhbHNlKSwgcGVuZGluZyAodW5kZWZpbmVkKSwKICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3Igc2tpcHBlZCAobnVsbCkuIFBlbmRpbmcgaXMgdXNlZCBmb3IgdW5mdWxmaWxsZWQgYCRhc3luY1ZhbGlkYXRvcnNgLgogICAqICAgICAgICAgICAgICAgICAgICAgICAgICBTa2lwcGVkIGlzIHVzZWQgYnkgQW5ndWxhciB3aGVuIHZhbGlkYXRvcnMgZG8gbm90IHJ1biBiZWNhdXNlIG9mIHBhcnNlIGVycm9ycyBhbmQKICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiBgJGFzeW5jVmFsaWRhdG9yc2AgZG8gbm90IHJ1biBiZWNhdXNlIGFueSBvZiB0aGUgYCR2YWxpZGF0b3JzYCBmYWlsZWQuCiAgICovCiAgYWRkU2V0VmFsaWRpdHlNZXRob2QoewogICAgY3RybDogdGhpcywKICAgICRlbGVtZW50OiAkZWxlbWVudCwKICAgIHNldDogZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgewogICAgICBvYmplY3RbcHJvcGVydHldID0gdHJ1ZTsKICAgIH0sCiAgICB1bnNldDogZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgewogICAgICBkZWxldGUgb2JqZWN0W3Byb3BlcnR5XTsKICAgIH0sCiAgICBwYXJlbnRGb3JtOiBwYXJlbnRGb3JtLAogICAgJGFuaW1hdGU6ICRhbmltYXRlCiAgfSk7CgogIC8qKgogICAqIEBuZ2RvYyBtZXRob2QKICAgKiBAbmFtZSBuZ01vZGVsLk5nTW9kZWxDb250cm9sbGVyIyRzZXRQcmlzdGluZQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyB0aGUgY29udHJvbCB0byBpdHMgcHJpc3RpbmUgc3RhdGUuCiAgICoKICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIHRvIHJlbW92ZSB0aGUgYG5nLWRpcnR5YCBjbGFzcyBhbmQgc2V0IHRoZSBjb250cm9sIHRvIGl0cyBwcmlzdGluZQogICAqIHN0YXRlIChgbmctcHJpc3RpbmVgIGNsYXNzKS4gQSBtb2RlbCBpcyBjb25zaWRlcmVkIHRvIGJlIHByaXN0aW5lIHdoZW4gdGhlIGNvbnRyb2wKICAgKiBoYXMgbm90IGJlZW4gY2hhbmdlZCBmcm9tIHdoZW4gZmlyc3QgY29tcGlsZWQuCiAgICovCiAgdGhpcy4kc2V0UHJpc3RpbmUgPSBmdW5jdGlvbigpIHsKICAgIGN0cmwuJGRpcnR5ID0gZmFsc2U7CiAgICBjdHJsLiRwcmlzdGluZSA9IHRydWU7CiAgICAkYW5pbWF0ZS5yZW1vdmVDbGFzcygkZWxlbWVudCwgRElSVFlfQ0xBU1MpOwogICAgJGFuaW1hdGUuYWRkQ2xhc3MoJGVsZW1lbnQsIFBSSVNUSU5FX0NMQVNTKTsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgbmdNb2RlbC5OZ01vZGVsQ29udHJvbGxlciMkc2V0RGlydHkKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFNldHMgdGhlIGNvbnRyb2wgdG8gaXRzIGRpcnR5IHN0YXRlLgogICAqCiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCB0byByZW1vdmUgdGhlIGBuZy1wcmlzdGluZWAgY2xhc3MgYW5kIHNldCB0aGUgY29udHJvbCB0byBpdHMgZGlydHkKICAgKiBzdGF0ZSAoYG5nLWRpcnR5YCBjbGFzcykuIEEgbW9kZWwgaXMgY29uc2lkZXJlZCB0byBiZSBkaXJ0eSB3aGVuIHRoZSBjb250cm9sIGhhcyBiZWVuIGNoYW5nZWQKICAgKiBmcm9tIHdoZW4gZmlyc3QgY29tcGlsZWQuCiAgICovCiAgdGhpcy4kc2V0RGlydHkgPSBmdW5jdGlvbigpIHsKICAgIGN0cmwuJGRpcnR5ID0gdHJ1ZTsKICAgIGN0cmwuJHByaXN0aW5lID0gZmFsc2U7CiAgICAkYW5pbWF0ZS5yZW1vdmVDbGFzcygkZWxlbWVudCwgUFJJU1RJTkVfQ0xBU1MpOwogICAgJGFuaW1hdGUuYWRkQ2xhc3MoJGVsZW1lbnQsIERJUlRZX0NMQVNTKTsKICAgIHBhcmVudEZvcm0uJHNldERpcnR5KCk7CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjJHNldFVudG91Y2hlZAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyB0aGUgY29udHJvbCB0byBpdHMgdW50b3VjaGVkIHN0YXRlLgogICAqCiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCB0byByZW1vdmUgdGhlIGBuZy10b3VjaGVkYCBjbGFzcyBhbmQgc2V0IHRoZSBjb250cm9sIHRvIGl0cwogICAqIHVudG91Y2hlZCBzdGF0ZSAoYG5nLXVudG91Y2hlZGAgY2xhc3MpLiBVcG9uIGNvbXBpbGF0aW9uLCBhIG1vZGVsIGlzIHNldCBhcyB1bnRvdWNoZWQKICAgKiBieSBkZWZhdWx0LCBob3dldmVyIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gcmVzdG9yZSB0aGF0IHN0YXRlIGlmIHRoZSBtb2RlbCBoYXMKICAgKiBhbHJlYWR5IGJlZW4gdG91Y2hlZCBieSB0aGUgdXNlci4KICAgKi8KICB0aGlzLiRzZXRVbnRvdWNoZWQgPSBmdW5jdGlvbigpIHsKICAgIGN0cmwuJHRvdWNoZWQgPSBmYWxzZTsKICAgIGN0cmwuJHVudG91Y2hlZCA9IHRydWU7CiAgICAkYW5pbWF0ZS5zZXRDbGFzcygkZWxlbWVudCwgVU5UT1VDSEVEX0NMQVNTLCBUT1VDSEVEX0NMQVNTKTsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgbmdNb2RlbC5OZ01vZGVsQ29udHJvbGxlciMkc2V0VG91Y2hlZAogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogU2V0cyB0aGUgY29udHJvbCB0byBpdHMgdG91Y2hlZCBzdGF0ZS4KICAgKgogICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgdG8gcmVtb3ZlIHRoZSBgbmctdW50b3VjaGVkYCBjbGFzcyBhbmQgc2V0IHRoZSBjb250cm9sIHRvIGl0cwogICAqIHRvdWNoZWQgc3RhdGUgKGBuZy10b3VjaGVkYCBjbGFzcykuIEEgbW9kZWwgaXMgY29uc2lkZXJlZCB0byBiZSB0b3VjaGVkIHdoZW4gdGhlIHVzZXIgaGFzCiAgICogZmlyc3QgZm9jdXNlZCB0aGUgY29udHJvbCBlbGVtZW50IGFuZCB0aGVuIHNoaWZ0ZWQgZm9jdXMgYXdheSBmcm9tIHRoZSBjb250cm9sIChibHVyIGV2ZW50KS4KICAgKi8KICB0aGlzLiRzZXRUb3VjaGVkID0gZnVuY3Rpb24oKSB7CiAgICBjdHJsLiR0b3VjaGVkID0gdHJ1ZTsKICAgIGN0cmwuJHVudG91Y2hlZCA9IGZhbHNlOwogICAgJGFuaW1hdGUuc2V0Q2xhc3MoJGVsZW1lbnQsIFRPVUNIRURfQ0xBU1MsIFVOVE9VQ0hFRF9DTEFTUyk7CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjJHJvbGxiYWNrVmlld1ZhbHVlCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBDYW5jZWwgYW4gdXBkYXRlIGFuZCByZXNldCB0aGUgaW5wdXQgZWxlbWVudCdzIHZhbHVlIHRvIHByZXZlbnQgYW4gdXBkYXRlIHRvIHRoZSBgJG1vZGVsVmFsdWVgLAogICAqIHdoaWNoIG1heSBiZSBjYXVzZWQgYnkgYSBwZW5kaW5nIGRlYm91bmNlZCBldmVudCBvciBiZWNhdXNlIHRoZSBpbnB1dCBpcyB3YWl0aW5nIGZvciBhIHNvbWUKICAgKiBmdXR1cmUgZXZlbnQuCiAgICoKICAgKiBJZiB5b3UgaGF2ZSBhbiBpbnB1dCB0aGF0IHVzZXMgYG5nLW1vZGVsLW9wdGlvbnNgIHRvIHNldCB1cCBkZWJvdW5jZWQgZXZlbnRzIG9yIGV2ZW50cyBzdWNoCiAgICogYXMgYmx1ciB5b3UgY2FuIGhhdmUgYSBzaXR1YXRpb24gd2hlcmUgdGhlcmUgaXMgYSBwZXJpb2Qgd2hlbiB0aGUgYCR2aWV3VmFsdWVgCiAgICogaXMgb3V0IG9mIHN5bmNoIHdpdGggdGhlIG5nTW9kZWwncyBgJG1vZGVsVmFsdWVgLgogICAqCiAgICogSW4gdGhpcyBjYXNlLCB5b3UgY2FuIHJ1biBpbnRvIGRpZmZpY3VsdGllcyBpZiB5b3UgdHJ5IHRvIHVwZGF0ZSB0aGUgbmdNb2RlbCdzIGAkbW9kZWxWYWx1ZWAKICAgKiBwcm9ncmFtbWF0aWNhbGx5IGJlZm9yZSB0aGVzZSBkZWJvdW5jZWQvZnV0dXJlIGV2ZW50cyBoYXZlIHJlc29sdmVkL29jY3VycmVkLCBiZWNhdXNlIEFuZ3VsYXIncwogICAqIGRpcnR5IGNoZWNraW5nIG1lY2hhbmlzbSBpcyBub3QgYWJsZSB0byB0ZWxsIHdoZXRoZXIgdGhlIG1vZGVsIGhhcyBhY3R1YWxseSBjaGFuZ2VkIG9yIG5vdC4KICAgKgogICAqIFRoZSBgJHJvbGxiYWNrVmlld1ZhbHVlKClgIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIGJlZm9yZSBwcm9ncmFtbWF0aWNhbGx5IGNoYW5naW5nIHRoZSBtb2RlbCBvZiBhbgogICAqIGlucHV0IHdoaWNoIG1heSBoYXZlIHN1Y2ggZXZlbnRzIHBlbmRpbmcuIFRoaXMgaXMgaW1wb3J0YW50IGluIG9yZGVyIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZQogICAqIGlucHV0IGZpZWxkIHdpbGwgYmUgdXBkYXRlZCB3aXRoIHRoZSBuZXcgbW9kZWwgdmFsdWUgYW5kIGFueSBwZW5kaW5nIG9wZXJhdGlvbnMgYXJlIGNhbmNlbGxlZC4KICAgKgogICAqIDxleGFtcGxlIG5hbWU9Im5nLW1vZGVsLWNhbmNlbC11cGRhdGUiIG1vZHVsZT0iY2FuY2VsLXVwZGF0ZS1leGFtcGxlIj4KICAgKiAgIDxmaWxlIG5hbWU9ImFwcC5qcyI+CiAgICogICAgIGFuZ3VsYXIubW9kdWxlKCdjYW5jZWwtdXBkYXRlLWV4YW1wbGUnLCBbXSkKICAgKgogICAqICAgICAuY29udHJvbGxlcignQ2FuY2VsVXBkYXRlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICogICAgICAgJHNjb3BlLnJlc2V0V2l0aENhbmNlbCA9IGZ1bmN0aW9uKGUpIHsKICAgKiAgICAgICAgIGlmIChlLmtleUNvZGUgPT0gMjcpIHsKICAgKiAgICAgICAgICAgJHNjb3BlLm15Rm9ybS5teUlucHV0MS4kcm9sbGJhY2tWaWV3VmFsdWUoKTsKICAgKiAgICAgICAgICAgJHNjb3BlLm15VmFsdWUgPSAnJzsKICAgKiAgICAgICAgIH0KICAgKiAgICAgICB9OwogICAqICAgICAgICRzY29wZS5yZXNldFdpdGhvdXRDYW5jZWwgPSBmdW5jdGlvbihlKSB7CiAgICogICAgICAgICBpZiAoZS5rZXlDb2RlID09IDI3KSB7CiAgICogICAgICAgICAgICRzY29wZS5teVZhbHVlID0gJyc7CiAgICogICAgICAgICB9CiAgICogICAgICAgfTsKICAgKiAgICAgfV0pOwogICAqICAgPC9maWxlPgogICAqICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICogICAgIDxkaXYgbmctY29udHJvbGxlcj0iQ2FuY2VsVXBkYXRlQ29udHJvbGxlciI+CiAgICogICAgICAgPHA+VHJ5IHR5cGluZyBzb21ldGhpbmcgaW4gZWFjaCBpbnB1dC4gIFNlZSB0aGF0IHRoZSBtb2RlbCBvbmx5IHVwZGF0ZXMgd2hlbiB5b3UKICAgKiAgICAgICAgICBibHVyIG9mZiB0aGUgaW5wdXQuCiAgICogICAgICAgIDwvcD4KICAgKiAgICAgICAgPHA+Tm93IHNlZSB3aGF0IGhhcHBlbnMgaWYgeW91IHN0YXJ0IHR5cGluZyB0aGVuIHByZXNzIHRoZSBFc2NhcGUga2V5PC9wPgogICAqCiAgICogICAgICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1tb2RlbC1vcHRpb25zPSJ7IHVwZGF0ZU9uOiAnYmx1cicgfSI+CiAgICogICAgICAgICA8cD5XaXRoICRyb2xsYmFja1ZpZXdWYWx1ZSgpPC9wPgogICAqICAgICAgICAgPGlucHV0IG5hbWU9Im15SW5wdXQxIiBuZy1tb2RlbD0ibXlWYWx1ZSIgbmcta2V5ZG93bj0icmVzZXRXaXRoQ2FuY2VsKCRldmVudCkiPjxici8+CiAgICogICAgICAgICBteVZhbHVlOiAie3sgbXlWYWx1ZSB9fSIKICAgKgogICAqICAgICAgICAgPHA+V2l0aG91dCAkcm9sbGJhY2tWaWV3VmFsdWUoKTwvcD4KICAgKiAgICAgICAgIDxpbnB1dCBuYW1lPSJteUlucHV0MiIgbmctbW9kZWw9Im15VmFsdWUiIG5nLWtleWRvd249InJlc2V0V2l0aG91dENhbmNlbCgkZXZlbnQpIj48YnIvPgogICAqICAgICAgICAgbXlWYWx1ZTogInt7IG15VmFsdWUgfX0iCiAgICogICAgICAgPC9mb3JtPgogICAqICAgICA8L2Rpdj4KICAgKiAgIDwvZmlsZT4KICAgKiA8L2V4YW1wbGU+CiAgICovCiAgdGhpcy4kcm9sbGJhY2tWaWV3VmFsdWUgPSBmdW5jdGlvbigpIHsKICAgICR0aW1lb3V0LmNhbmNlbChwZW5kaW5nRGVib3VuY2UpOwogICAgY3RybC4kdmlld1ZhbHVlID0gY3RybC4kJGxhc3RDb21taXR0ZWRWaWV3VmFsdWU7CiAgICBjdHJsLiRyZW5kZXIoKTsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgbmdNb2RlbC5OZ01vZGVsQ29udHJvbGxlciMkdmFsaWRhdGUKICAgKgogICAqIEBkZXNjcmlwdGlvbgogICAqIFJ1bnMgZWFjaCBvZiB0aGUgcmVnaXN0ZXJlZCB2YWxpZGF0b3JzIChmaXJzdCBzeW5jaHJvbm91cyB2YWxpZGF0b3JzIGFuZCB0aGVuCiAgICogYXN5bmNocm9ub3VzIHZhbGlkYXRvcnMpLgogICAqIElmIHRoZSB2YWxpZGl0eSBjaGFuZ2VzIHRvIGludmFsaWQsIHRoZSBtb2RlbCB3aWxsIGJlIHNldCB0byBgdW5kZWZpbmVkYCwKICAgKiB1bmxlc3Mge0BsaW5rIG5nTW9kZWxPcHRpb25zIGBuZ01vZGVsT3B0aW9ucy5hbGxvd0ludmFsaWRgfSBpcyBgdHJ1ZWAuCiAgICogSWYgdGhlIHZhbGlkaXR5IGNoYW5nZXMgdG8gdmFsaWQsIGl0IHdpbGwgc2V0IHRoZSBtb2RlbCB0byB0aGUgbGFzdCBhdmFpbGFibGUgdmFsaWQKICAgKiBtb2RlbFZhbHVlLCBpLmUuIGVpdGhlciB0aGUgbGFzdCBwYXJzZWQgdmFsdWUgb3IgdGhlIGxhc3QgdmFsdWUgc2V0IGZyb20gdGhlIHNjb3BlLgogICAqLwogIHRoaXMuJHZhbGlkYXRlID0gZnVuY3Rpb24oKSB7CiAgICAvLyBpZ25vcmUgJHZhbGlkYXRlIGJlZm9yZSBtb2RlbCBpcyBpbml0aWFsaXplZAogICAgaWYgKGlzTnVtYmVyKGN0cmwuJG1vZGVsVmFsdWUpICYmIGlzTmFOKGN0cmwuJG1vZGVsVmFsdWUpKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICB2YXIgdmlld1ZhbHVlID0gY3RybC4kJGxhc3RDb21taXR0ZWRWaWV3VmFsdWU7CiAgICAvLyBOb3RlOiB3ZSB1c2UgdGhlICQkcmF3TW9kZWxWYWx1ZSBhcyAkbW9kZWxWYWx1ZSBtaWdodCBoYXZlIGJlZW4KICAgIC8vIHNldCB0byB1bmRlZmluZWQgZHVyaW5nIGEgdmlldyAtPiBtb2RlbCB1cGRhdGUgdGhhdCBmb3VuZCB2YWxpZGF0aW9uCiAgICAvLyBlcnJvcnMuIFdlIGNhbid0IHBhcnNlIHRoZSB2aWV3IGhlcmUsIHNpbmNlIHRoYXQgY291bGQgY2hhbmdlCiAgICAvLyB0aGUgbW9kZWwgYWx0aG91Z2ggbmVpdGhlciB2aWV3VmFsdWUgbm9yIHRoZSBtb2RlbCBvbiB0aGUgc2NvcGUgY2hhbmdlZAogICAgdmFyIG1vZGVsVmFsdWUgPSBjdHJsLiQkcmF3TW9kZWxWYWx1ZTsKCiAgICAvLyBDaGVjayBpZiB0aGUgdGhlcmUncyBhIHBhcnNlIGVycm9yLCBzbyB3ZSBkb24ndCB1bnNldCBpdCBhY2NpZGVudGlhbGx5CiAgICB2YXIgcGFyc2VyTmFtZSA9IGN0cmwuJCRwYXJzZXJOYW1lIHx8ICdwYXJzZSc7CiAgICB2YXIgcGFyc2VyVmFsaWQgPSBjdHJsLiRlcnJvcltwYXJzZXJOYW1lXSA/IGZhbHNlIDogdW5kZWZpbmVkOwoKICAgIHZhciBwcmV2VmFsaWQgPSBjdHJsLiR2YWxpZDsKICAgIHZhciBwcmV2TW9kZWxWYWx1ZSA9IGN0cmwuJG1vZGVsVmFsdWU7CgogICAgdmFyIGFsbG93SW52YWxpZCA9IGN0cmwuJG9wdGlvbnMgJiYgY3RybC4kb3B0aW9ucy5hbGxvd0ludmFsaWQ7CgogICAgY3RybC4kJHJ1blZhbGlkYXRvcnMocGFyc2VyVmFsaWQsIG1vZGVsVmFsdWUsIHZpZXdWYWx1ZSwgZnVuY3Rpb24oYWxsVmFsaWQpIHsKICAgICAgLy8gSWYgdGhlcmUgd2FzIG5vIGNoYW5nZSBpbiB2YWxpZGl0eSwgZG9uJ3QgdXBkYXRlIHRoZSBtb2RlbAogICAgICAvLyBUaGlzIHByZXZlbnRzIGNoYW5naW5nIGFuIGludmFsaWQgbW9kZWxWYWx1ZSB0byB1bmRlZmluZWQKICAgICAgaWYgKCFhbGxvd0ludmFsaWQgJiYgcHJldlZhbGlkICE9PSBhbGxWYWxpZCkgewogICAgICAgIC8vIE5vdGU6IERvbid0IGNoZWNrIGN0cmwuJHZhbGlkIGhlcmUsIGFzIHdlIGNvdWxkIGhhdmUKICAgICAgICAvLyBleHRlcm5hbCB2YWxpZGF0b3JzIChlLmcuIGNhbGN1bGF0ZWQgb24gdGhlIHNlcnZlciksCiAgICAgICAgLy8gdGhhdCBqdXN0IGNhbGwgJHNldFZhbGlkaXR5IGFuZCBuZWVkIHRoZSBtb2RlbCB2YWx1ZQogICAgICAgIC8vIHRvIGNhbGN1bGF0ZSB0aGVpciB2YWxpZGl0eS4KICAgICAgICBjdHJsLiRtb2RlbFZhbHVlID0gYWxsVmFsaWQgPyBtb2RlbFZhbHVlIDogdW5kZWZpbmVkOwoKICAgICAgICBpZiAoY3RybC4kbW9kZWxWYWx1ZSAhPT0gcHJldk1vZGVsVmFsdWUpIHsKICAgICAgICAgIGN0cmwuJCR3cml0ZU1vZGVsVG9TY29wZSgpOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CgogIH07CgogIHRoaXMuJCRydW5WYWxpZGF0b3JzID0gZnVuY3Rpb24ocGFyc2VWYWxpZCwgbW9kZWxWYWx1ZSwgdmlld1ZhbHVlLCBkb25lQ2FsbGJhY2spIHsKICAgIGN1cnJlbnRWYWxpZGF0aW9uUnVuSWQrKzsKICAgIHZhciBsb2NhbFZhbGlkYXRpb25SdW5JZCA9IGN1cnJlbnRWYWxpZGF0aW9uUnVuSWQ7CgogICAgLy8gY2hlY2sgcGFyc2VyIGVycm9yCiAgICBpZiAoIXByb2Nlc3NQYXJzZUVycm9ycyhwYXJzZVZhbGlkKSkgewogICAgICB2YWxpZGF0aW9uRG9uZShmYWxzZSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghcHJvY2Vzc1N5bmNWYWxpZGF0b3JzKCkpIHsKICAgICAgdmFsaWRhdGlvbkRvbmUoZmFsc2UpOwogICAgICByZXR1cm47CiAgICB9CiAgICBwcm9jZXNzQXN5bmNWYWxpZGF0b3JzKCk7CgogICAgZnVuY3Rpb24gcHJvY2Vzc1BhcnNlRXJyb3JzKHBhcnNlVmFsaWQpIHsKICAgICAgdmFyIGVycm9yS2V5ID0gY3RybC4kJHBhcnNlck5hbWUgfHwgJ3BhcnNlJzsKICAgICAgaWYgKHBhcnNlVmFsaWQgPT09IHVuZGVmaW5lZCkgewogICAgICAgIHNldFZhbGlkaXR5KGVycm9yS2V5LCBudWxsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZXRWYWxpZGl0eShlcnJvcktleSwgcGFyc2VWYWxpZCk7CiAgICAgICAgaWYgKCFwYXJzZVZhbGlkKSB7CiAgICAgICAgICBmb3JFYWNoKGN0cmwuJHZhbGlkYXRvcnMsIGZ1bmN0aW9uKHYsIG5hbWUpIHsKICAgICAgICAgICAgc2V0VmFsaWRpdHkobmFtZSwgbnVsbCk7CiAgICAgICAgICB9KTsKICAgICAgICAgIGZvckVhY2goY3RybC4kYXN5bmNWYWxpZGF0b3JzLCBmdW5jdGlvbih2LCBuYW1lKSB7CiAgICAgICAgICAgIHNldFZhbGlkaXR5KG5hbWUsIG51bGwpOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIHByb2Nlc3NTeW5jVmFsaWRhdG9ycygpIHsKICAgICAgdmFyIHN5bmNWYWxpZGF0b3JzVmFsaWQgPSB0cnVlOwogICAgICBmb3JFYWNoKGN0cmwuJHZhbGlkYXRvcnMsIGZ1bmN0aW9uKHZhbGlkYXRvciwgbmFtZSkgewogICAgICAgIHZhciByZXN1bHQgPSB2YWxpZGF0b3IobW9kZWxWYWx1ZSwgdmlld1ZhbHVlKTsKICAgICAgICBzeW5jVmFsaWRhdG9yc1ZhbGlkID0gc3luY1ZhbGlkYXRvcnNWYWxpZCAmJiByZXN1bHQ7CiAgICAgICAgc2V0VmFsaWRpdHkobmFtZSwgcmVzdWx0KTsKICAgICAgfSk7CiAgICAgIGlmICghc3luY1ZhbGlkYXRvcnNWYWxpZCkgewogICAgICAgIGZvckVhY2goY3RybC4kYXN5bmNWYWxpZGF0b3JzLCBmdW5jdGlvbih2LCBuYW1lKSB7CiAgICAgICAgICBzZXRWYWxpZGl0eShuYW1lLCBudWxsKTsKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcHJvY2Vzc0FzeW5jVmFsaWRhdG9ycygpIHsKICAgICAgdmFyIHZhbGlkYXRvclByb21pc2VzID0gW107CiAgICAgIHZhciBhbGxWYWxpZCA9IHRydWU7CiAgICAgIGZvckVhY2goY3RybC4kYXN5bmNWYWxpZGF0b3JzLCBmdW5jdGlvbih2YWxpZGF0b3IsIG5hbWUpIHsKICAgICAgICB2YXIgcHJvbWlzZSA9IHZhbGlkYXRvcihtb2RlbFZhbHVlLCB2aWV3VmFsdWUpOwogICAgICAgIGlmICghaXNQcm9taXNlTGlrZShwcm9taXNlKSkgewogICAgICAgICAgdGhyb3cgJG5nTW9kZWxNaW5FcnIoIiRhc3luY1ZhbGlkYXRvcnMiLAogICAgICAgICAgICAiRXhwZWN0ZWQgYXN5bmNocm9ub3VzIHZhbGlkYXRvciB0byByZXR1cm4gYSBwcm9taXNlIGJ1dCBnb3QgJ3swfScgaW5zdGVhZC4iLCBwcm9taXNlKTsKICAgICAgICB9CiAgICAgICAgc2V0VmFsaWRpdHkobmFtZSwgdW5kZWZpbmVkKTsKICAgICAgICB2YWxpZGF0b3JQcm9taXNlcy5wdXNoKHByb21pc2UudGhlbihmdW5jdGlvbigpIHsKICAgICAgICAgIHNldFZhbGlkaXR5KG5hbWUsIHRydWUpOwogICAgICAgIH0sIGZ1bmN0aW9uKGVycm9yKSB7CiAgICAgICAgICBhbGxWYWxpZCA9IGZhbHNlOwogICAgICAgICAgc2V0VmFsaWRpdHkobmFtZSwgZmFsc2UpOwogICAgICAgIH0pKTsKICAgICAgfSk7CiAgICAgIGlmICghdmFsaWRhdG9yUHJvbWlzZXMubGVuZ3RoKSB7CiAgICAgICAgdmFsaWRhdGlvbkRvbmUodHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgJHEuYWxsKHZhbGlkYXRvclByb21pc2VzKS50aGVuKGZ1bmN0aW9uKCkgewogICAgICAgICAgdmFsaWRhdGlvbkRvbmUoYWxsVmFsaWQpOwogICAgICAgIH0sIG5vb3ApOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gc2V0VmFsaWRpdHkobmFtZSwgaXNWYWxpZCkgewogICAgICBpZiAobG9jYWxWYWxpZGF0aW9uUnVuSWQgPT09IGN1cnJlbnRWYWxpZGF0aW9uUnVuSWQpIHsKICAgICAgICBjdHJsLiRzZXRWYWxpZGl0eShuYW1lLCBpc1ZhbGlkKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHZhbGlkYXRpb25Eb25lKGFsbFZhbGlkKSB7CiAgICAgIGlmIChsb2NhbFZhbGlkYXRpb25SdW5JZCA9PT0gY3VycmVudFZhbGlkYXRpb25SdW5JZCkgewoKICAgICAgICBkb25lQ2FsbGJhY2soYWxsVmFsaWQpOwogICAgICB9CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQG5nZG9jIG1ldGhvZAogICAqIEBuYW1lIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIjJGNvbW1pdFZpZXdWYWx1ZQogICAqCiAgICogQGRlc2NyaXB0aW9uCiAgICogQ29tbWl0IGEgcGVuZGluZyB1cGRhdGUgdG8gdGhlIGAkbW9kZWxWYWx1ZWAuCiAgICoKICAgKiBVcGRhdGVzIG1heSBiZSBwZW5kaW5nIGJ5IGEgZGVib3VuY2VkIGV2ZW50IG9yIGJlY2F1c2UgdGhlIGlucHV0IGlzIHdhaXRpbmcgZm9yIGEgc29tZSBmdXR1cmUKICAgKiBldmVudCBkZWZpbmVkIGluIGBuZy1tb2RlbC1vcHRpb25zYC4gdGhpcyBtZXRob2QgaXMgcmFyZWx5IG5lZWRlZCBhcyBgTmdNb2RlbENvbnRyb2xsZXJgCiAgICogdXN1YWxseSBoYW5kbGVzIGNhbGxpbmcgdGhpcyBpbiByZXNwb25zZSB0byBpbnB1dCBldmVudHMuCiAgICovCiAgdGhpcy4kY29tbWl0Vmlld1ZhbHVlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgdmlld1ZhbHVlID0gY3RybC4kdmlld1ZhbHVlOwoKICAgICR0aW1lb3V0LmNhbmNlbChwZW5kaW5nRGVib3VuY2UpOwoKICAgIC8vIElmIHRoZSB2aWV3IHZhbHVlIGhhcyBub3QgY2hhbmdlZCB0aGVuIHdlIHNob3VsZCBqdXN0IGV4aXQsIGV4Y2VwdCBpbiB0aGUgY2FzZSB3aGVyZSB0aGVyZSBpcwogICAgLy8gYSBuYXRpdmUgdmFsaWRhdG9yIG9uIHRoZSBlbGVtZW50LiBJbiB0aGlzIGNhc2UgdGhlIHZhbGlkYXRpb24gc3RhdGUgbWF5IGhhdmUgY2hhbmdlZCBldmVuIHRob3VnaAogICAgLy8gdGhlIHZpZXdWYWx1ZSBoYXMgc3RheWVkIGVtcHR5LgogICAgaWYgKGN0cmwuJCRsYXN0Q29tbWl0dGVkVmlld1ZhbHVlID09PSB2aWV3VmFsdWUgJiYgKHZpZXdWYWx1ZSAhPT0gJycgfHwgIWN0cmwuJCRoYXNOYXRpdmVWYWxpZGF0b3JzKSkgewogICAgICByZXR1cm47CiAgICB9CiAgICBjdHJsLiQkbGFzdENvbW1pdHRlZFZpZXdWYWx1ZSA9IHZpZXdWYWx1ZTsKCiAgICAvLyBjaGFuZ2UgdG8gZGlydHkKICAgIGlmIChjdHJsLiRwcmlzdGluZSkgewogICAgICB0aGlzLiRzZXREaXJ0eSgpOwogICAgfQogICAgdGhpcy4kJHBhcnNlQW5kVmFsaWRhdGUoKTsKICB9OwoKICB0aGlzLiQkcGFyc2VBbmRWYWxpZGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIHZpZXdWYWx1ZSA9IGN0cmwuJCRsYXN0Q29tbWl0dGVkVmlld1ZhbHVlOwogICAgdmFyIG1vZGVsVmFsdWUgPSB2aWV3VmFsdWU7CiAgICB2YXIgcGFyc2VyVmFsaWQgPSBpc1VuZGVmaW5lZChtb2RlbFZhbHVlKSA/IHVuZGVmaW5lZCA6IHRydWU7CgogICAgaWYgKHBhcnNlclZhbGlkKSB7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY3RybC4kcGFyc2Vycy5sZW5ndGg7IGkrKykgewogICAgICAgIG1vZGVsVmFsdWUgPSBjdHJsLiRwYXJzZXJzW2ldKG1vZGVsVmFsdWUpOwogICAgICAgIGlmIChpc1VuZGVmaW5lZChtb2RlbFZhbHVlKSkgewogICAgICAgICAgcGFyc2VyVmFsaWQgPSBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgaWYgKGlzTnVtYmVyKGN0cmwuJG1vZGVsVmFsdWUpICYmIGlzTmFOKGN0cmwuJG1vZGVsVmFsdWUpKSB7CiAgICAgIC8vIGN0cmwuJG1vZGVsVmFsdWUgaGFzIG5vdCBiZWVuIHRvdWNoZWQgeWV0Li4uCiAgICAgIGN0cmwuJG1vZGVsVmFsdWUgPSBuZ01vZGVsR2V0KCRzY29wZSk7CiAgICB9CiAgICB2YXIgcHJldk1vZGVsVmFsdWUgPSBjdHJsLiRtb2RlbFZhbHVlOwogICAgdmFyIGFsbG93SW52YWxpZCA9IGN0cmwuJG9wdGlvbnMgJiYgY3RybC4kb3B0aW9ucy5hbGxvd0ludmFsaWQ7CiAgICBjdHJsLiQkcmF3TW9kZWxWYWx1ZSA9IG1vZGVsVmFsdWU7CgogICAgaWYgKGFsbG93SW52YWxpZCkgewogICAgICBjdHJsLiRtb2RlbFZhbHVlID0gbW9kZWxWYWx1ZTsKICAgICAgd3JpdGVUb01vZGVsSWZOZWVkZWQoKTsKICAgIH0KCiAgICAvLyBQYXNzIHRoZSAkJGxhc3RDb21taXR0ZWRWaWV3VmFsdWUgaGVyZSwgYmVjYXVzZSB0aGUgY2FjaGVkIHZpZXdWYWx1ZSBtaWdodCBiZSBvdXQgb2YgZGF0ZS4KICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBpZiBlLmcuICRzZXRWaWV3VmFsdWUgaXMgY2FsbGVkIGZyb20gaW5zaWRlIGEgcGFyc2VyCiAgICBjdHJsLiQkcnVuVmFsaWRhdG9ycyhwYXJzZXJWYWxpZCwgbW9kZWxWYWx1ZSwgY3RybC4kJGxhc3RDb21taXR0ZWRWaWV3VmFsdWUsIGZ1bmN0aW9uKGFsbFZhbGlkKSB7CiAgICAgIGlmICghYWxsb3dJbnZhbGlkKSB7CiAgICAgICAgLy8gTm90ZTogRG9uJ3QgY2hlY2sgY3RybC4kdmFsaWQgaGVyZSwgYXMgd2UgY291bGQgaGF2ZQogICAgICAgIC8vIGV4dGVybmFsIHZhbGlkYXRvcnMgKGUuZy4gY2FsY3VsYXRlZCBvbiB0aGUgc2VydmVyKSwKICAgICAgICAvLyB0aGF0IGp1c3QgY2FsbCAkc2V0VmFsaWRpdHkgYW5kIG5lZWQgdGhlIG1vZGVsIHZhbHVlCiAgICAgICAgLy8gdG8gY2FsY3VsYXRlIHRoZWlyIHZhbGlkaXR5LgogICAgICAgIGN0cmwuJG1vZGVsVmFsdWUgPSBhbGxWYWxpZCA/IG1vZGVsVmFsdWUgOiB1bmRlZmluZWQ7CiAgICAgICAgd3JpdGVUb01vZGVsSWZOZWVkZWQoKTsKICAgICAgfQogICAgfSk7CgogICAgZnVuY3Rpb24gd3JpdGVUb01vZGVsSWZOZWVkZWQoKSB7CiAgICAgIGlmIChjdHJsLiRtb2RlbFZhbHVlICE9PSBwcmV2TW9kZWxWYWx1ZSkgewogICAgICAgIGN0cmwuJCR3cml0ZU1vZGVsVG9TY29wZSgpOwogICAgICB9CiAgICB9CiAgfTsKCiAgdGhpcy4kJHdyaXRlTW9kZWxUb1Njb3BlID0gZnVuY3Rpb24oKSB7CiAgICBuZ01vZGVsU2V0KCRzY29wZSwgY3RybC4kbW9kZWxWYWx1ZSk7CiAgICBmb3JFYWNoKGN0cmwuJHZpZXdDaGFuZ2VMaXN0ZW5lcnMsIGZ1bmN0aW9uKGxpc3RlbmVyKSB7CiAgICAgIHRyeSB7CiAgICAgICAgbGlzdGVuZXIoKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICRleGNlcHRpb25IYW5kbGVyKGUpOwogICAgICB9CiAgICB9KTsKICB9OwoKICAvKioKICAgKiBAbmdkb2MgbWV0aG9kCiAgICogQG5hbWUgbmdNb2RlbC5OZ01vZGVsQ29udHJvbGxlciMkc2V0Vmlld1ZhbHVlCiAgICoKICAgKiBAZGVzY3JpcHRpb24KICAgKiBVcGRhdGUgdGhlIHZpZXcgdmFsdWUuCiAgICoKICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYW4gaW5wdXQgZGlyZWN0aXZlIHdhbnQgdG8gY2hhbmdlIHRoZSB2aWV3IHZhbHVlOyB0eXBpY2FsbHksCiAgICogdGhpcyBpcyBkb25lIGZyb20gd2l0aGluIGEgRE9NIGV2ZW50IGhhbmRsZXIuCiAgICoKICAgKiBGb3IgZXhhbXBsZSB7QGxpbmsgbmcuZGlyZWN0aXZlOmlucHV0IGlucHV0fSBjYWxscyBpdCB3aGVuIHRoZSB2YWx1ZSBvZiB0aGUgaW5wdXQgY2hhbmdlcyBhbmQKICAgKiB7QGxpbmsgbmcuZGlyZWN0aXZlOnNlbGVjdCBzZWxlY3R9IGNhbGxzIGl0IHdoZW4gYW4gb3B0aW9uIGlzIHNlbGVjdGVkLgogICAqCiAgICogSWYgdGhlIG5ldyBgdmFsdWVgIGlzIGFuIG9iamVjdCAocmF0aGVyIHRoYW4gYSBzdHJpbmcgb3IgYSBudW1iZXIpLCB3ZSBzaG91bGQgbWFrZSBhIGNvcHkgb2YgdGhlCiAgICogb2JqZWN0IGJlZm9yZSBwYXNzaW5nIGl0IHRvIGAkc2V0Vmlld1ZhbHVlYC4gIFRoaXMgaXMgYmVjYXVzZSBgbmdNb2RlbGAgZG9lcyBub3QgcGVyZm9ybSBhIGRlZXAKICAgKiB3YXRjaCBvZiBvYmplY3RzLCBpdCBvbmx5IGxvb2tzIGZvciBhIGNoYW5nZSBvZiBpZGVudGl0eS4gSWYgeW91IG9ubHkgY2hhbmdlIHRoZSBwcm9wZXJ0eSBvZgogICAqIHRoZSBvYmplY3QgdGhlbiBuZ01vZGVsIHdpbGwgbm90IHJlYWxpc2UgdGhhdCB0aGUgb2JqZWN0IGhhcyBjaGFuZ2VkIGFuZCB3aWxsIG5vdCBpbnZva2UgdGhlCiAgICogYCRwYXJzZXJzYCBhbmQgYCR2YWxpZGF0b3JzYCBwaXBlbGluZXMuCiAgICoKICAgKiBGb3IgdGhpcyByZWFzb24sIHlvdSBzaG91bGQgbm90IGNoYW5nZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb3B5IG9uY2UgaXQgaGFzIGJlZW4gcGFzc2VkIHRvCiAgICogYCRzZXRWaWV3VmFsdWVgLiBPdGhlcndpc2UgeW91IG1heSBjYXVzZSB0aGUgbW9kZWwgdmFsdWUgb24gdGhlIHNjb3BlIHRvIGNoYW5nZSBpbmNvcnJlY3RseS4KICAgKgogICAqIFdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLCB0aGUgbmV3IGB2YWx1ZWAgd2lsbCBiZSBzdGFnZWQgZm9yIGNvbW1pdHRpbmcgdGhyb3VnaCB0aGUgYCRwYXJzZXJzYAogICAqIGFuZCBgJHZhbGlkYXRvcnNgIHBpcGVsaW5lcy4gSWYgdGhlcmUgYXJlIG5vIHNwZWNpYWwge0BsaW5rIG5nTW9kZWxPcHRpb25zfSBzcGVjaWZpZWQgdGhlbiB0aGUgc3RhZ2VkCiAgICogdmFsdWUgc2VudCBkaXJlY3RseSBmb3IgcHJvY2Vzc2luZywgZmluYWxseSB0byBiZSBhcHBsaWVkIHRvIGAkbW9kZWxWYWx1ZWAgYW5kIHRoZW4gdGhlCiAgICogKipleHByZXNzaW9uKiogc3BlY2lmaWVkIGluIHRoZSBgbmctbW9kZWxgIGF0dHJpYnV0ZS4KICAgKgogICAqIExhc3RseSwgYWxsIHRoZSByZWdpc3RlcmVkIGNoYW5nZSBsaXN0ZW5lcnMsIGluIHRoZSBgJHZpZXdDaGFuZ2VMaXN0ZW5lcnNgIGxpc3QsIGFyZSBjYWxsZWQuCiAgICoKICAgKiBJbiBjYXNlIHRoZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nTW9kZWxPcHRpb25zIG5nTW9kZWxPcHRpb25zfSBkaXJlY3RpdmUgaXMgdXNlZCB3aXRoIGB1cGRhdGVPbmAKICAgKiBhbmQgdGhlIGBkZWZhdWx0YCB0cmlnZ2VyIGlzIG5vdCBsaXN0ZWQsIGFsbCB0aG9zZSBhY3Rpb25zIHdpbGwgcmVtYWluIHBlbmRpbmcgdW50aWwgb25lIG9mIHRoZQogICAqIGB1cGRhdGVPbmAgZXZlbnRzIGlzIHRyaWdnZXJlZCBvbiB0aGUgRE9NIGVsZW1lbnQuCiAgICogQWxsIHRoZXNlIGFjdGlvbnMgd2lsbCBiZSBkZWJvdW5jZWQgaWYgdGhlIHtAbGluayBuZy5kaXJlY3RpdmU6bmdNb2RlbE9wdGlvbnMgbmdNb2RlbE9wdGlvbnN9CiAgICogZGlyZWN0aXZlIGlzIHVzZWQgd2l0aCBhIGN1c3RvbSBkZWJvdW5jZSBmb3IgdGhpcyBwYXJ0aWN1bGFyIGV2ZW50LgogICAqCiAgICogTm90ZSB0aGF0IGNhbGxpbmcgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCB0cmlnZ2VyIGEgYCRkaWdlc3RgLgogICAqCiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIFZhbHVlIGZyb20gdGhlIHZpZXcuCiAgICogQHBhcmFtIHtzdHJpbmd9IHRyaWdnZXIgRXZlbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIHVwZGF0ZS4KICAgKi8KICB0aGlzLiRzZXRWaWV3VmFsdWUgPSBmdW5jdGlvbih2YWx1ZSwgdHJpZ2dlcikgewogICAgY3RybC4kdmlld1ZhbHVlID0gdmFsdWU7CiAgICBpZiAoIWN0cmwuJG9wdGlvbnMgfHwgY3RybC4kb3B0aW9ucy51cGRhdGVPbkRlZmF1bHQpIHsKICAgICAgY3RybC4kJGRlYm91bmNlVmlld1ZhbHVlQ29tbWl0KHRyaWdnZXIpOwogICAgfQogIH07CgogIHRoaXMuJCRkZWJvdW5jZVZpZXdWYWx1ZUNvbW1pdCA9IGZ1bmN0aW9uKHRyaWdnZXIpIHsKICAgIHZhciBkZWJvdW5jZURlbGF5ID0gMCwKICAgICAgICBvcHRpb25zID0gY3RybC4kb3B0aW9ucywKICAgICAgICBkZWJvdW5jZTsKCiAgICBpZiAob3B0aW9ucyAmJiBpc0RlZmluZWQob3B0aW9ucy5kZWJvdW5jZSkpIHsKICAgICAgZGVib3VuY2UgPSBvcHRpb25zLmRlYm91bmNlOwogICAgICBpZiAoaXNOdW1iZXIoZGVib3VuY2UpKSB7CiAgICAgICAgZGVib3VuY2VEZWxheSA9IGRlYm91bmNlOwogICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGRlYm91bmNlW3RyaWdnZXJdKSkgewogICAgICAgIGRlYm91bmNlRGVsYXkgPSBkZWJvdW5jZVt0cmlnZ2VyXTsKICAgICAgfSBlbHNlIGlmIChpc051bWJlcihkZWJvdW5jZVsnZGVmYXVsdCddKSkgewogICAgICAgIGRlYm91bmNlRGVsYXkgPSBkZWJvdW5jZVsnZGVmYXVsdCddOwogICAgICB9CiAgICB9CgogICAgJHRpbWVvdXQuY2FuY2VsKHBlbmRpbmdEZWJvdW5jZSk7CiAgICBpZiAoZGVib3VuY2VEZWxheSkgewogICAgICBwZW5kaW5nRGVib3VuY2UgPSAkdGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICBjdHJsLiRjb21taXRWaWV3VmFsdWUoKTsKICAgICAgfSwgZGVib3VuY2VEZWxheSk7CiAgICB9IGVsc2UgaWYgKCRyb290U2NvcGUuJCRwaGFzZSkgewogICAgICBjdHJsLiRjb21taXRWaWV3VmFsdWUoKTsKICAgIH0gZWxzZSB7CiAgICAgICRzY29wZS4kYXBwbHkoZnVuY3Rpb24oKSB7CiAgICAgICAgY3RybC4kY29tbWl0Vmlld1ZhbHVlKCk7CiAgICAgIH0pOwogICAgfQogIH07CgogIC8vIG1vZGVsIC0+IHZhbHVlCiAgLy8gTm90ZTogd2UgY2Fubm90IHVzZSBhIG5vcm1hbCBzY29wZS4kd2F0Y2ggYXMgd2Ugd2FudCB0byBkZXRlY3QgdGhlIGZvbGxvd2luZzoKICAvLyAxLiBzY29wZSB2YWx1ZSBpcyAnYScKICAvLyAyLiB1c2VyIGVudGVycyAnYicKICAvLyAzLiBuZy1jaGFuZ2Uga2lja3MgaW4gYW5kIHJldmVydHMgc2NvcGUgdmFsdWUgdG8gJ2EnCiAgLy8gICAgLT4gc2NvcGUgdmFsdWUgZGlkIG5vdCBjaGFuZ2Ugc2luY2UgdGhlIGxhc3QgZGlnZXN0IGFzCiAgLy8gICAgICAgbmctY2hhbmdlIGV4ZWN1dGVzIGluIGFwcGx5IHBoYXNlCiAgLy8gNC4gdmlldyBzaG91bGQgYmUgY2hhbmdlZCBiYWNrIHRvICdhJwogICRzY29wZS4kd2F0Y2goZnVuY3Rpb24gbmdNb2RlbFdhdGNoKCkgewogICAgdmFyIG1vZGVsVmFsdWUgPSBuZ01vZGVsR2V0KCRzY29wZSk7CgogICAgLy8gaWYgc2NvcGUgbW9kZWwgdmFsdWUgYW5kIG5nTW9kZWwgdmFsdWUgYXJlIG91dCBvZiBzeW5jCiAgICAvLyBUT0RPKHBlcmYpOiB3aHkgbm90IG1vdmUgdGhpcyB0byB0aGUgYWN0aW9uIGZuPwogICAgaWYgKG1vZGVsVmFsdWUgIT09IGN0cmwuJG1vZGVsVmFsdWUpIHsKICAgICAgY3RybC4kbW9kZWxWYWx1ZSA9IGN0cmwuJCRyYXdNb2RlbFZhbHVlID0gbW9kZWxWYWx1ZTsKCiAgICAgIHZhciBmb3JtYXR0ZXJzID0gY3RybC4kZm9ybWF0dGVycywKICAgICAgICAgIGlkeCA9IGZvcm1hdHRlcnMubGVuZ3RoOwoKICAgICAgdmFyIHZpZXdWYWx1ZSA9IG1vZGVsVmFsdWU7CiAgICAgIHdoaWxlIChpZHgtLSkgewogICAgICAgIHZpZXdWYWx1ZSA9IGZvcm1hdHRlcnNbaWR4XSh2aWV3VmFsdWUpOwogICAgICB9CiAgICAgIGlmIChjdHJsLiR2aWV3VmFsdWUgIT09IHZpZXdWYWx1ZSkgewogICAgICAgIGN0cmwuJHZpZXdWYWx1ZSA9IGN0cmwuJCRsYXN0Q29tbWl0dGVkVmlld1ZhbHVlID0gdmlld1ZhbHVlOwogICAgICAgIGN0cmwuJHJlbmRlcigpOwoKICAgICAgICBjdHJsLiQkcnVuVmFsaWRhdG9ycyh1bmRlZmluZWQsIG1vZGVsVmFsdWUsIHZpZXdWYWx1ZSwgbm9vcCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gbW9kZWxWYWx1ZTsKICB9KTsKfV07CgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdNb2RlbAogKgogKiBAZWxlbWVudCBpbnB1dAogKiBAcHJpb3JpdHkgMQogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ01vZGVsYCBkaXJlY3RpdmUgYmluZHMgYW4gYGlucHV0YCxgc2VsZWN0YCwgYHRleHRhcmVhYCAob3IgY3VzdG9tIGZvcm0gY29udHJvbCkgdG8gYQogKiBwcm9wZXJ0eSBvbiB0aGUgc2NvcGUgdXNpbmcge0BsaW5rIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIgTmdNb2RlbENvbnRyb2xsZXJ9LAogKiB3aGljaCBpcyBjcmVhdGVkIGFuZCBleHBvc2VkIGJ5IHRoaXMgZGlyZWN0aXZlLgogKgogKiBgbmdNb2RlbGAgaXMgcmVzcG9uc2libGUgZm9yOgogKgogKiAtIEJpbmRpbmcgdGhlIHZpZXcgaW50byB0aGUgbW9kZWwsIHdoaWNoIG90aGVyIGRpcmVjdGl2ZXMgc3VjaCBhcyBgaW5wdXRgLCBgdGV4dGFyZWFgIG9yIGBzZWxlY3RgCiAqICAgcmVxdWlyZS4KICogLSBQcm92aWRpbmcgdmFsaWRhdGlvbiBiZWhhdmlvciAoaS5lLiByZXF1aXJlZCwgbnVtYmVyLCBlbWFpbCwgdXJsKS4KICogLSBLZWVwaW5nIHRoZSBzdGF0ZSBvZiB0aGUgY29udHJvbCAodmFsaWQvaW52YWxpZCwgZGlydHkvcHJpc3RpbmUsIHRvdWNoZWQvdW50b3VjaGVkLCB2YWxpZGF0aW9uIGVycm9ycykuCiAqIC0gU2V0dGluZyByZWxhdGVkIGNzcyBjbGFzc2VzIG9uIHRoZSBlbGVtZW50IChgbmctdmFsaWRgLCBgbmctaW52YWxpZGAsIGBuZy1kaXJ0eWAsIGBuZy1wcmlzdGluZWAsIGBuZy10b3VjaGVkYCwgYG5nLXVudG91Y2hlZGApIGluY2x1ZGluZyBhbmltYXRpb25zLgogKiAtIFJlZ2lzdGVyaW5nIHRoZSBjb250cm9sIHdpdGggaXRzIHBhcmVudCB7QGxpbmsgbmcuZGlyZWN0aXZlOmZvcm0gZm9ybX0uCiAqCiAqIE5vdGU6IGBuZ01vZGVsYCB3aWxsIHRyeSB0byBiaW5kIHRvIHRoZSBwcm9wZXJ0eSBnaXZlbiBieSBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uIG9uIHRoZQogKiBjdXJyZW50IHNjb3BlLiBJZiB0aGUgcHJvcGVydHkgZG9lc24ndCBhbHJlYWR5IGV4aXN0IG9uIHRoaXMgc2NvcGUsIGl0IHdpbGwgYmUgY3JlYXRlZAogKiBpbXBsaWNpdGx5IGFuZCBhZGRlZCB0byB0aGUgc2NvcGUuCiAqCiAqIEZvciBiZXN0IHByYWN0aWNlcyBvbiB1c2luZyBgbmdNb2RlbGAsIHNlZToKICoKICogIC0gW1VuZGVyc3RhbmRpbmcgU2NvcGVzXShodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL3dpa2kvVW5kZXJzdGFuZGluZy1TY29wZXMpCiAqCiAqIEZvciBiYXNpYyBleGFtcGxlcywgaG93IHRvIHVzZSBgbmdNb2RlbGAsIHNlZToKICoKICogIC0ge0BsaW5rIG5nLmRpcmVjdGl2ZTppbnB1dCBpbnB1dH0KICogICAgLSB7QGxpbmsgaW5wdXRbdGV4dF0gdGV4dH0KICogICAgLSB7QGxpbmsgaW5wdXRbY2hlY2tib3hdIGNoZWNrYm94fQogKiAgICAtIHtAbGluayBpbnB1dFtyYWRpb10gcmFkaW99CiAqICAgIC0ge0BsaW5rIGlucHV0W251bWJlcl0gbnVtYmVyfQogKiAgICAtIHtAbGluayBpbnB1dFtlbWFpbF0gZW1haWx9CiAqICAgIC0ge0BsaW5rIGlucHV0W3VybF0gdXJsfQogKiAgICAtIHtAbGluayBpbnB1dFtkYXRlXSBkYXRlfQogKiAgICAtIHtAbGluayBpbnB1dFtkYXRldGltZS1sb2NhbF0gZGF0ZXRpbWUtbG9jYWx9CiAqICAgIC0ge0BsaW5rIGlucHV0W3RpbWVdIHRpbWV9CiAqICAgIC0ge0BsaW5rIGlucHV0W21vbnRoXSBtb250aH0KICogICAgLSB7QGxpbmsgaW5wdXRbd2Vla10gd2Vla30KICogIC0ge0BsaW5rIG5nLmRpcmVjdGl2ZTpzZWxlY3Qgc2VsZWN0fQogKiAgLSB7QGxpbmsgbmcuZGlyZWN0aXZlOnRleHRhcmVhIHRleHRhcmVhfQogKgogKiAjIENTUyBjbGFzc2VzCiAqIFRoZSBmb2xsb3dpbmcgQ1NTIGNsYXNzZXMgYXJlIGFkZGVkIGFuZCByZW1vdmVkIG9uIHRoZSBhc3NvY2lhdGVkIGlucHV0L3NlbGVjdC90ZXh0YXJlYSBlbGVtZW50CiAqIGRlcGVuZGluZyBvbiB0aGUgdmFsaWRpdHkgb2YgdGhlIG1vZGVsLgogKgogKiAgLSBgbmctdmFsaWRgOiB0aGUgbW9kZWwgaXMgdmFsaWQKICogIC0gYG5nLWludmFsaWRgOiB0aGUgbW9kZWwgaXMgaW52YWxpZAogKiAgLSBgbmctdmFsaWQtW2tleV1gOiBmb3IgZWFjaCB2YWxpZCBrZXkgYWRkZWQgYnkgYCRzZXRWYWxpZGl0eWAKICogIC0gYG5nLWludmFsaWQtW2tleV1gOiBmb3IgZWFjaCBpbnZhbGlkIGtleSBhZGRlZCBieSBgJHNldFZhbGlkaXR5YAogKiAgLSBgbmctcHJpc3RpbmVgOiB0aGUgY29udHJvbCBoYXNuJ3QgYmVlbiBpbnRlcmFjdGVkIHdpdGggeWV0CiAqICAtIGBuZy1kaXJ0eWA6IHRoZSBjb250cm9sIGhhcyBiZWVuIGludGVyYWN0ZWQgd2l0aAogKiAgLSBgbmctdG91Y2hlZGA6IHRoZSBjb250cm9sIGhhcyBiZWVuIGJsdXJyZWQKICogIC0gYG5nLXVudG91Y2hlZGA6IHRoZSBjb250cm9sIGhhc24ndCBiZWVuIGJsdXJyZWQKICogIC0gYG5nLXBlbmRpbmdgOiBhbnkgYCRhc3luY1ZhbGlkYXRvcnNgIGFyZSB1bmZ1bGZpbGxlZAogKgogKiBLZWVwIGluIG1pbmQgdGhhdCBuZ0FuaW1hdGUgY2FuIGRldGVjdCBlYWNoIG9mIHRoZXNlIGNsYXNzZXMgd2hlbiBhZGRlZCBhbmQgcmVtb3ZlZC4KICoKICogIyMgQW5pbWF0aW9uIEhvb2tzCiAqCiAqIEFuaW1hdGlvbnMgd2l0aGluIG1vZGVscyBhcmUgdHJpZ2dlcmVkIHdoZW4gYW55IG9mIHRoZSBhc3NvY2lhdGVkIENTUyBjbGFzc2VzIGFyZSBhZGRlZCBhbmQgcmVtb3ZlZAogKiBvbiB0aGUgaW5wdXQgZWxlbWVudCB3aGljaCBpcyBhdHRhY2hlZCB0byB0aGUgbW9kZWwuIFRoZXNlIGNsYXNzZXMgYXJlOiBgLm5nLXByaXN0aW5lYCwgYC5uZy1kaXJ0eWAsCiAqIGAubmctaW52YWxpZGAgYW5kIGAubmctdmFsaWRgIGFzIHdlbGwgYXMgYW55IG90aGVyIHZhbGlkYXRpb25zIHRoYXQgYXJlIHBlcmZvcm1lZCBvbiB0aGUgbW9kZWwgaXRzZWxmLgogKiBUaGUgYW5pbWF0aW9ucyB0aGF0IGFyZSB0cmlnZ2VyZWQgd2l0aGluIG5nTW9kZWwgYXJlIHNpbWlsYXIgdG8gaG93IHRoZXkgd29yayBpbiBuZ0NsYXNzIGFuZAogKiBhbmltYXRpb25zIGNhbiBiZSBob29rZWQgaW50byB1c2luZyBDU1MgdHJhbnNpdGlvbnMsIGtleWZyYW1lcyBhcyB3ZWxsIGFzIEpTIGFuaW1hdGlvbnMuCiAqCiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBhIHNpbXBsZSB3YXkgdG8gdXRpbGl6ZSBDU1MgdHJhbnNpdGlvbnMgdG8gc3R5bGUgYW4gaW5wdXQgZWxlbWVudAogKiB0aGF0IGhhcyBiZWVuIHJlbmRlcmVkIGFzIGludmFsaWQgYWZ0ZXIgaXQgaGFzIGJlZW4gdmFsaWRhdGVkOgogKgogKiA8cHJlPgogKiAvL2JlIHN1cmUgdG8gaW5jbHVkZSBuZ0FuaW1hdGUgYXMgYSBtb2R1bGUgdG8gaG9vayBpbnRvIG1vcmUKICogLy9hZHZhbmNlZCBhbmltYXRpb25zCiAqIC5teS1pbnB1dCB7CiAqICAgdHJhbnNpdGlvbjowLjVzIGxpbmVhciBhbGw7CiAqICAgYmFja2dyb3VuZDogd2hpdGU7CiAqIH0KICogLm15LWlucHV0Lm5nLWludmFsaWQgewogKiAgIGJhY2tncm91bmQ6IHJlZDsKICogICBjb2xvcjp3aGl0ZTsKICogfQogKiA8L3ByZT4KICoKICogQGV4YW1wbGUKICogPGV4YW1wbGUgZGVwcz0iYW5ndWxhci1hbmltYXRlLmpzIiBhbmltYXRpb25zPSJ0cnVlIiBmaXhCYXNlPSJ0cnVlIiBtb2R1bGU9ImlucHV0RXhhbXBsZSI+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8c2NyaXB0PgogICAgICAgIGFuZ3VsYXIubW9kdWxlKCdpbnB1dEV4YW1wbGUnLCBbXSkKICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICRzY29wZS52YWwgPSAnMSc7CiAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgIDxzdHlsZT4KICAgICAgICAgLm15LWlucHV0IHsKICAgICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246YWxsIGxpbmVhciAwLjVzOwogICAgICAgICAgIHRyYW5zaXRpb246YWxsIGxpbmVhciAwLjVzOwogICAgICAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OwogICAgICAgICB9CiAgICAgICAgIC5teS1pbnB1dC5uZy1pbnZhbGlkIHsKICAgICAgICAgICBjb2xvcjp3aGl0ZTsKICAgICAgICAgICBiYWNrZ3JvdW5kOiByZWQ7CiAgICAgICAgIH0KICAgICAgIDwvc3R5bGU+CiAgICAgICBVcGRhdGUgaW5wdXQgdG8gc2VlIHRyYW5zaXRpb25zIHdoZW4gdmFsaWQvaW52YWxpZC4KICAgICAgIEludGVnZXIgaXMgYSB2YWxpZCB2YWx1ZS4KICAgICAgIDxmb3JtIG5hbWU9InRlc3RGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgIDxpbnB1dCBuZy1tb2RlbD0idmFsIiBuZy1wYXR0ZXJuPSIvXlxkKyQvIiBuYW1lPSJhbmltIiBjbGFzcz0ibXktaW5wdXQiIC8+CiAgICAgICA8L2Zvcm0+CiAgICAgPC9maWxlPgogKiA8L2V4YW1wbGU+CiAqCiAqICMjIEJpbmRpbmcgdG8gYSBnZXR0ZXIvc2V0dGVyCiAqCiAqIFNvbWV0aW1lcyBpdCdzIGhlbHBmdWwgdG8gYmluZCBgbmdNb2RlbGAgdG8gYSBnZXR0ZXIvc2V0dGVyIGZ1bmN0aW9uLiAgQSBnZXR0ZXIvc2V0dGVyIGlzIGEKICogZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIHdoZW4gY2FsbGVkIHdpdGggemVybyBhcmd1bWVudHMsIGFuZCBzZXRzCiAqIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiBhIG1vZGVsIHdoZW4gY2FsbGVkIHdpdGggYW4gYXJndW1lbnQuIEl0J3Mgc29tZXRpbWVzIHVzZWZ1bCB0byB1c2UgdGhpcwogKiBmb3IgbW9kZWxzIHRoYXQgaGF2ZSBhbiBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiB0aGF0J3MgZGlmZmVyZW50IHRoYW4gd2hhdCB0aGUgbW9kZWwgZXhwb3NlcwogKiB0byB0aGUgdmlldy4KICoKICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtc3VjY2VzcyI+CiAqICoqQmVzdCBQcmFjdGljZToqKiBJdCdzIGJlc3QgdG8ga2VlcCBnZXR0ZXJzIGZhc3QgYmVjYXVzZSBBbmd1bGFyIGlzIGxpa2VseSB0byBjYWxsIHRoZW0gbW9yZQogKiBmcmVxdWVudGx5IHRoYW4gb3RoZXIgcGFydHMgb2YgeW91ciBjb2RlLgogKiA8L2Rpdj4KICoKICogWW91IHVzZSB0aGlzIGJlaGF2aW9yIGJ5IGFkZGluZyBgbmctbW9kZWwtb3B0aW9ucz0ieyBnZXR0ZXJTZXR0ZXI6IHRydWUgfSJgIHRvIGFuIGVsZW1lbnQgdGhhdAogKiBoYXMgYG5nLW1vZGVsYCBhdHRhY2hlZCB0byBpdC4gWW91IGNhbiBhbHNvIGFkZCBgbmctbW9kZWwtb3B0aW9ucz0ieyBnZXR0ZXJTZXR0ZXI6IHRydWUgfSJgIHRvCiAqIGEgYDxmb3JtPmAsIHdoaWNoIHdpbGwgZW5hYmxlIHRoaXMgYmVoYXZpb3IgZm9yIGFsbCBgPGlucHV0PmBzIHdpdGhpbiBpdC4gU2VlCiAqIHtAbGluayBuZy5kaXJlY3RpdmU6bmdNb2RlbE9wdGlvbnMgYG5nTW9kZWxPcHRpb25zYH0gZm9yIG1vcmUuCiAqCiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gdXNlIGBuZ01vZGVsYCB3aXRoIGEgZ2V0dGVyL3NldHRlcjoKICoKICogQGV4YW1wbGUKICogPGV4YW1wbGUgbmFtZT0ibmdNb2RlbC1nZXR0ZXItc2V0dGVyIiBtb2R1bGU9ImdldHRlclNldHRlckV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgIDxmb3JtIG5hbWU9InVzZXJGb3JtIj4KICAgICAgICAgICBOYW1lOgogICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VyTmFtZSIKICAgICAgICAgICAgICAgICAgbmctbW9kZWw9InVzZXIubmFtZSIKICAgICAgICAgICAgICAgICAgbmctbW9kZWwtb3B0aW9ucz0ieyBnZXR0ZXJTZXR0ZXI6IHRydWUgfSIgLz4KICAgICAgICAgPC9mb3JtPgogICAgICAgICA8cHJlPnVzZXIubmFtZSA9IDxzcGFuIG5nLWJpbmQ9InVzZXIubmFtZSgpIj48L3NwYW4+PC9wcmU+CiAgICAgICA8L2Rpdj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0iYXBwLmpzIj4KICAgICAgIGFuZ3VsYXIubW9kdWxlKCdnZXR0ZXJTZXR0ZXJFeGFtcGxlJywgW10pCiAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgdmFyIF9uYW1lID0gJ0JyaWFuJzsKICAgICAgICAgICAkc2NvcGUudXNlciA9IHsKICAgICAgICAgICAgIG5hbWU6IGZ1bmN0aW9uKG5ld05hbWUpIHsKICAgICAgICAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKG5ld05hbWUpKSB7CiAgICAgICAgICAgICAgICAgX25hbWUgPSBuZXdOYW1lOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIHJldHVybiBfbmFtZTsKICAgICAgICAgICAgIH0KICAgICAgICAgICB9OwogICAgICAgICB9XSk7CiAgICAgPC9maWxlPgogKiA8L2V4YW1wbGU+CiAqLwp2YXIgbmdNb2RlbERpcmVjdGl2ZSA9IFsnJHJvb3RTY29wZScsIGZ1bmN0aW9uKCRyb290U2NvcGUpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIHJlcXVpcmU6IFsnbmdNb2RlbCcsICdeP2Zvcm0nLCAnXj9uZ01vZGVsT3B0aW9ucyddLAogICAgY29udHJvbGxlcjogTmdNb2RlbENvbnRyb2xsZXIsCiAgICAvLyBQcmVsaW5rIG5lZWRzIHRvIHJ1biBiZWZvcmUgYW55IGlucHV0IGRpcmVjdGl2ZQogICAgLy8gc28gdGhhdCB3ZSBjYW4gc2V0IHRoZSBOZ01vZGVsT3B0aW9ucyBpbiBOZ01vZGVsQ29udHJvbGxlcgogICAgLy8gYmVmb3JlIGFueW9uZSBlbHNlIHVzZXMgaXQuCiAgICBwcmlvcml0eTogMSwKICAgIGNvbXBpbGU6IGZ1bmN0aW9uIG5nTW9kZWxDb21waWxlKGVsZW1lbnQpIHsKICAgICAgLy8gU2V0dXAgaW5pdGlhbCBzdGF0ZSBvZiB0aGUgY29udHJvbAogICAgICBlbGVtZW50LmFkZENsYXNzKFBSSVNUSU5FX0NMQVNTKS5hZGRDbGFzcyhVTlRPVUNIRURfQ0xBU1MpLmFkZENsYXNzKFZBTElEX0NMQVNTKTsKCiAgICAgIHJldHVybiB7CiAgICAgICAgcHJlOiBmdW5jdGlvbiBuZ01vZGVsUHJlTGluayhzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybHMpIHsKICAgICAgICAgIHZhciBtb2RlbEN0cmwgPSBjdHJsc1swXSwKICAgICAgICAgICAgICBmb3JtQ3RybCA9IGN0cmxzWzFdIHx8IG51bGxGb3JtQ3RybDsKCiAgICAgICAgICBtb2RlbEN0cmwuJCRzZXRPcHRpb25zKGN0cmxzWzJdICYmIGN0cmxzWzJdLiRvcHRpb25zKTsKCiAgICAgICAgICAvLyBub3RpZnkgb3RoZXJzLCBlc3BlY2lhbGx5IHBhcmVudCBmb3JtcwogICAgICAgICAgZm9ybUN0cmwuJGFkZENvbnRyb2wobW9kZWxDdHJsKTsKCiAgICAgICAgICBhdHRyLiRvYnNlcnZlKCduYW1lJywgZnVuY3Rpb24obmV3VmFsdWUpIHsKICAgICAgICAgICAgaWYgKG1vZGVsQ3RybC4kbmFtZSAhPT0gbmV3VmFsdWUpIHsKICAgICAgICAgICAgICBmb3JtQ3RybC4kJHJlbmFtZUNvbnRyb2wobW9kZWxDdHJsLCBuZXdWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIHNjb3BlLiRvbignJGRlc3Ryb3knLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgZm9ybUN0cmwuJHJlbW92ZUNvbnRyb2wobW9kZWxDdHJsKTsKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICAgcG9zdDogZnVuY3Rpb24gbmdNb2RlbFBvc3RMaW5rKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJscykgewogICAgICAgICAgdmFyIG1vZGVsQ3RybCA9IGN0cmxzWzBdOwogICAgICAgICAgaWYgKG1vZGVsQ3RybC4kb3B0aW9ucyAmJiBtb2RlbEN0cmwuJG9wdGlvbnMudXBkYXRlT24pIHsKICAgICAgICAgICAgZWxlbWVudC5vbihtb2RlbEN0cmwuJG9wdGlvbnMudXBkYXRlT24sIGZ1bmN0aW9uKGV2KSB7CiAgICAgICAgICAgICAgbW9kZWxDdHJsLiQkZGVib3VuY2VWaWV3VmFsdWVDb21taXQoZXYgJiYgZXYudHlwZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQoKICAgICAgICAgIGVsZW1lbnQub24oJ2JsdXInLCBmdW5jdGlvbihldikgewogICAgICAgICAgICBpZiAobW9kZWxDdHJsLiR0b3VjaGVkKSByZXR1cm47CgogICAgICAgICAgICBpZiAoJHJvb3RTY29wZS4kJHBoYXNlKSB7CiAgICAgICAgICAgICAgc2NvcGUuJGV2YWxBc3luYyhtb2RlbEN0cmwuJHNldFRvdWNoZWQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHNjb3BlLiRhcHBseShtb2RlbEN0cmwuJHNldFRvdWNoZWQpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH07CiAgICB9CiAgfTsKfV07CgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdDaGFuZ2UKICoKICogQGRlc2NyaXB0aW9uCiAqIEV2YWx1YXRlIHRoZSBnaXZlbiBleHByZXNzaW9uIHdoZW4gdGhlIHVzZXIgY2hhbmdlcyB0aGUgaW5wdXQuCiAqIFRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZCBpbW1lZGlhdGVseSwgdW5saWtlIHRoZSBKYXZhU2NyaXB0IG9uY2hhbmdlIGV2ZW50CiAqIHdoaWNoIG9ubHkgdHJpZ2dlcnMgYXQgdGhlIGVuZCBvZiBhIGNoYW5nZSAodXN1YWxseSwgd2hlbiB0aGUgdXNlciBsZWF2ZXMgdGhlCiAqIGZvcm0gZWxlbWVudCBvciBwcmVzc2VzIHRoZSByZXR1cm4ga2V5KS4KICoKICogVGhlIGBuZ0NoYW5nZWAgZXhwcmVzc2lvbiBpcyBvbmx5IGV2YWx1YXRlZCB3aGVuIGEgY2hhbmdlIGluIHRoZSBpbnB1dCB2YWx1ZSBjYXVzZXMKICogYSBuZXcgdmFsdWUgdG8gYmUgY29tbWl0dGVkIHRvIHRoZSBtb2RlbC4KICoKICogSXQgd2lsbCBub3QgYmUgZXZhbHVhdGVkOgogKiAqIGlmIHRoZSB2YWx1ZSByZXR1cm5lZCBmcm9tIHRoZSBgJHBhcnNlcnNgIHRyYW5zZm9ybWF0aW9uIHBpcGVsaW5lIGhhcyBub3QgY2hhbmdlZAogKiAqIGlmIHRoZSBpbnB1dCBoYXMgY29udGludWVkIHRvIGJlIGludmFsaWQgc2luY2UgdGhlIG1vZGVsIHdpbGwgc3RheSBgbnVsbGAKICogKiBpZiB0aGUgbW9kZWwgaXMgY2hhbmdlZCBwcm9ncmFtbWF0aWNhbGx5IGFuZCBub3QgYnkgYSBjaGFuZ2UgdG8gdGhlIGlucHV0IHZhbHVlCiAqCiAqCiAqIE5vdGUsIHRoaXMgZGlyZWN0aXZlIHJlcXVpcmVzIGBuZ01vZGVsYCB0byBiZSBwcmVzZW50LgogKgogKiBAZWxlbWVudCBpbnB1dAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQ2hhbmdlIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24gY2hhbmdlCiAqIGluIGlucHV0IHZhbHVlLgogKgogKiBAZXhhbXBsZQogKiA8ZXhhbXBsZSBuYW1lPSJuZ0NoYW5nZS1kaXJlY3RpdmUiIG1vZHVsZT0iY2hhbmdlRXhhbXBsZSI+CiAqICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAqICAgICA8c2NyaXB0PgogKiAgICAgICBhbmd1bGFyLm1vZHVsZSgnY2hhbmdlRXhhbXBsZScsIFtdKQogKiAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAqICAgICAgICAgICAkc2NvcGUuY291bnRlciA9IDA7CiAqICAgICAgICAgICAkc2NvcGUuY2hhbmdlID0gZnVuY3Rpb24oKSB7CiAqICAgICAgICAgICAgICRzY29wZS5jb3VudGVyKys7CiAqICAgICAgICAgICB9OwogKiAgICAgICAgIH1dKTsKICogICAgIDwvc2NyaXB0PgogKiAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAqICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmctbW9kZWw9ImNvbmZpcm1lZCIgbmctY2hhbmdlPSJjaGFuZ2UoKSIgaWQ9Im5nLWNoYW5nZS1leGFtcGxlMSIgLz4KICogICAgICAgPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0iY29uZmlybWVkIiBpZD0ibmctY2hhbmdlLWV4YW1wbGUyIiAvPgogKiAgICAgICA8bGFiZWwgZm9yPSJuZy1jaGFuZ2UtZXhhbXBsZTIiPkNvbmZpcm1lZDwvbGFiZWw+PGJyIC8+CiAqICAgICAgIDx0dD5kZWJ1ZyA9IHt7Y29uZmlybWVkfX08L3R0Pjxici8+CiAqICAgICAgIDx0dD5jb3VudGVyID0ge3tjb3VudGVyfX08L3R0Pjxici8+CiAqICAgICA8L2Rpdj4KICogICA8L2ZpbGU+CiAqICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAqICAgICB2YXIgY291bnRlciA9IGVsZW1lbnQoYnkuYmluZGluZygnY291bnRlcicpKTsKICogICAgIHZhciBkZWJ1ZyA9IGVsZW1lbnQoYnkuYmluZGluZygnY29uZmlybWVkJykpOwogKgogKiAgICAgaXQoJ3Nob3VsZCBldmFsdWF0ZSB0aGUgZXhwcmVzc2lvbiBpZiBjaGFuZ2luZyBmcm9tIHZpZXcnLCBmdW5jdGlvbigpIHsKICogICAgICAgZXhwZWN0KGNvdW50ZXIuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJzAnKTsKICoKICogICAgICAgZWxlbWVudChieS5pZCgnbmctY2hhbmdlLWV4YW1wbGUxJykpLmNsaWNrKCk7CiAqCiAqICAgICAgIGV4cGVjdChjb3VudGVyLmdldFRleHQoKSkudG9Db250YWluKCcxJyk7CiAqICAgICAgIGV4cGVjdChkZWJ1Zy5nZXRUZXh0KCkpLnRvQ29udGFpbigndHJ1ZScpOwogKiAgICAgfSk7CiAqCiAqICAgICBpdCgnc2hvdWxkIG5vdCBldmFsdWF0ZSB0aGUgZXhwcmVzc2lvbiBpZiBjaGFuZ2luZyBmcm9tIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAqICAgICAgIGVsZW1lbnQoYnkuaWQoJ25nLWNoYW5nZS1leGFtcGxlMicpKS5jbGljaygpOwoKICogICAgICAgZXhwZWN0KGNvdW50ZXIuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJzAnKTsKICogICAgICAgZXhwZWN0KGRlYnVnLmdldFRleHQoKSkudG9Db250YWluKCd0cnVlJyk7CiAqICAgICB9KTsKICogICA8L2ZpbGU+CiAqIDwvZXhhbXBsZT4KICovCnZhciBuZ0NoYW5nZURpcmVjdGl2ZSA9IHZhbHVlRm4oewogIHJlc3RyaWN0OiAnQScsCiAgcmVxdWlyZTogJ25nTW9kZWwnLAogIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsKSB7CiAgICBjdHJsLiR2aWV3Q2hhbmdlTGlzdGVuZXJzLnB1c2goZnVuY3Rpb24oKSB7CiAgICAgIHNjb3BlLiRldmFsKGF0dHIubmdDaGFuZ2UpOwogICAgfSk7CiAgfQp9KTsKCgp2YXIgcmVxdWlyZWREaXJlY3RpdmUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIHJlcXVpcmU6ICc/bmdNb2RlbCcsCiAgICBsaW5rOiBmdW5jdGlvbihzY29wZSwgZWxtLCBhdHRyLCBjdHJsKSB7CiAgICAgIGlmICghY3RybCkgcmV0dXJuOwogICAgICBhdHRyLnJlcXVpcmVkID0gdHJ1ZTsgLy8gZm9yY2UgdHJ1dGh5IGluIGNhc2Ugd2UgYXJlIG9uIG5vbiBpbnB1dCBlbGVtZW50CgogICAgICBjdHJsLiR2YWxpZGF0b3JzLnJlcXVpcmVkID0gZnVuY3Rpb24obW9kZWxWYWx1ZSwgdmlld1ZhbHVlKSB7CiAgICAgICAgcmV0dXJuICFhdHRyLnJlcXVpcmVkIHx8ICFjdHJsLiRpc0VtcHR5KHZpZXdWYWx1ZSk7CiAgICAgIH07CgogICAgICBhdHRyLiRvYnNlcnZlKCdyZXF1aXJlZCcsIGZ1bmN0aW9uKCkgewogICAgICAgIGN0cmwuJHZhbGlkYXRlKCk7CiAgICAgIH0pOwogICAgfQogIH07Cn07CgoKdmFyIHBhdHRlcm5EaXJlY3RpdmUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIHJlcXVpcmU6ICc/bmdNb2RlbCcsCiAgICBsaW5rOiBmdW5jdGlvbihzY29wZSwgZWxtLCBhdHRyLCBjdHJsKSB7CiAgICAgIGlmICghY3RybCkgcmV0dXJuOwoKICAgICAgdmFyIHJlZ2V4cCwgcGF0dGVybkV4cCA9IGF0dHIubmdQYXR0ZXJuIHx8IGF0dHIucGF0dGVybjsKICAgICAgYXR0ci4kb2JzZXJ2ZSgncGF0dGVybicsIGZ1bmN0aW9uKHJlZ2V4KSB7CiAgICAgICAgaWYgKGlzU3RyaW5nKHJlZ2V4KSAmJiByZWdleC5sZW5ndGggPiAwKSB7CiAgICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAoJ14nICsgcmVnZXggKyAnJCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHJlZ2V4ICYmICFyZWdleC50ZXN0KSB7CiAgICAgICAgICB0aHJvdyBtaW5FcnIoJ25nUGF0dGVybicpKCdub3JlZ2V4cCcsCiAgICAgICAgICAgICdFeHBlY3RlZCB7MH0gdG8gYmUgYSBSZWdFeHAgYnV0IHdhcyB7MX0uIEVsZW1lbnQ6IHsyfScsIHBhdHRlcm5FeHAsCiAgICAgICAgICAgIHJlZ2V4LCBzdGFydGluZ1RhZyhlbG0pKTsKICAgICAgICB9CgogICAgICAgIHJlZ2V4cCA9IHJlZ2V4IHx8IHVuZGVmaW5lZDsKICAgICAgICBjdHJsLiR2YWxpZGF0ZSgpOwogICAgICB9KTsKCiAgICAgIGN0cmwuJHZhbGlkYXRvcnMucGF0dGVybiA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGN0cmwuJGlzRW1wdHkodmFsdWUpIHx8IGlzVW5kZWZpbmVkKHJlZ2V4cCkgfHwgcmVnZXhwLnRlc3QodmFsdWUpOwogICAgICB9OwogICAgfQogIH07Cn07CgoKdmFyIG1heGxlbmd0aERpcmVjdGl2ZSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0EnLAogICAgcmVxdWlyZTogJz9uZ01vZGVsJywKICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbG0sIGF0dHIsIGN0cmwpIHsKICAgICAgaWYgKCFjdHJsKSByZXR1cm47CgogICAgICB2YXIgbWF4bGVuZ3RoID0gLTE7CiAgICAgIGF0dHIuJG9ic2VydmUoJ21heGxlbmd0aCcsIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgdmFyIGludFZhbCA9IGludCh2YWx1ZSk7CiAgICAgICAgbWF4bGVuZ3RoID0gaXNOYU4oaW50VmFsKSA/IC0xIDogaW50VmFsOwogICAgICAgIGN0cmwuJHZhbGlkYXRlKCk7CiAgICAgIH0pOwogICAgICBjdHJsLiR2YWxpZGF0b3JzLm1heGxlbmd0aCA9IGZ1bmN0aW9uKG1vZGVsVmFsdWUsIHZpZXdWYWx1ZSkgewogICAgICAgIHJldHVybiAobWF4bGVuZ3RoIDwgMCkgfHwgY3RybC4kaXNFbXB0eShtb2RlbFZhbHVlKSB8fCAodmlld1ZhbHVlLmxlbmd0aCA8PSBtYXhsZW5ndGgpOwogICAgICB9OwogICAgfQogIH07Cn07Cgp2YXIgbWlubGVuZ3RoRGlyZWN0aXZlID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHsKICAgIHJlc3RyaWN0OiAnQScsCiAgICByZXF1aXJlOiAnP25nTW9kZWwnLAogICAgbGluazogZnVuY3Rpb24oc2NvcGUsIGVsbSwgYXR0ciwgY3RybCkgewogICAgICBpZiAoIWN0cmwpIHJldHVybjsKCiAgICAgIHZhciBtaW5sZW5ndGggPSAwOwogICAgICBhdHRyLiRvYnNlcnZlKCdtaW5sZW5ndGgnLCBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgIG1pbmxlbmd0aCA9IGludCh2YWx1ZSkgfHwgMDsKICAgICAgICBjdHJsLiR2YWxpZGF0ZSgpOwogICAgICB9KTsKICAgICAgY3RybC4kdmFsaWRhdG9ycy5taW5sZW5ndGggPSBmdW5jdGlvbihtb2RlbFZhbHVlLCB2aWV3VmFsdWUpIHsKICAgICAgICByZXR1cm4gY3RybC4kaXNFbXB0eSh2aWV3VmFsdWUpIHx8IHZpZXdWYWx1ZS5sZW5ndGggPj0gbWlubGVuZ3RoOwogICAgICB9OwogICAgfQogIH07Cn07CgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdMaXN0CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUZXh0IGlucHV0IHRoYXQgY29udmVydHMgYmV0d2VlbiBhIGRlbGltaXRlZCBzdHJpbmcgYW5kIGFuIGFycmF5IG9mIHN0cmluZ3MuIFRoZSBkZWZhdWx0CiAqIGRlbGltaXRlciBpcyBhIGNvbW1hIGZvbGxvd2VkIGJ5IGEgc3BhY2UgLSBlcXVpdmFsZW50IHRvIGBuZy1saXN0PSIsICJgLiBZb3UgY2FuIHNwZWNpZnkgYSBjdXN0b20KICogZGVsaW1pdGVyIGFzIHRoZSB2YWx1ZSBvZiB0aGUgYG5nTGlzdGAgYXR0cmlidXRlIC0gZm9yIGV4YW1wbGUsIGBuZy1saXN0PSIgfCAiYC4KICoKICogVGhlIGJlaGF2aW91ciBvZiB0aGUgZGlyZWN0aXZlIGlzIGFmZmVjdGVkIGJ5IHRoZSB1c2Ugb2YgdGhlIGBuZ1RyaW1gIGF0dHJpYnV0ZS4KICogKiBJZiBgbmdUcmltYCBpcyBzZXQgdG8gYCJmYWxzZSJgIHRoZW4gd2hpdGVzcGFjZSBhcm91bmQgYm90aCB0aGUgc2VwYXJhdG9yIGFuZCBlYWNoCiAqICAgbGlzdCBpdGVtIGlzIHJlc3BlY3RlZC4gVGhpcyBpbXBsaWVzIHRoYXQgdGhlIHVzZXIgb2YgdGhlIGRpcmVjdGl2ZSBpcyByZXNwb25zaWJsZSBmb3IKICogICBkZWFsaW5nIHdpdGggd2hpdGVzcGFjZSBidXQgYWxzbyBhbGxvd3MgeW91IHRvIHVzZSB3aGl0ZXNwYWNlIGFzIGEgZGVsaW1pdGVyLCBzdWNoIGFzIGEKICogICB0YWIgb3IgbmV3bGluZSBjaGFyYWN0ZXIuCiAqICogT3RoZXJ3aXNlIHdoaXRlc3BhY2UgYXJvdW5kIHRoZSBkZWxpbWl0ZXIgaXMgaWdub3JlZCB3aGVuIHNwbGl0dGluZyAoYWx0aG91Z2ggaXQgaXMgcmVzcGVjdGVkCiAqICAgd2hlbiBqb2luaW5nIHRoZSBsaXN0IGl0ZW1zIGJhY2sgdG9nZXRoZXIpIGFuZCB3aGl0ZXNwYWNlIGFyb3VuZCBlYWNoIGxpc3QgaXRlbSBpcyBzdHJpcHBlZAogKiAgIGJlZm9yZSBpdCBpcyBhZGRlZCB0byB0aGUgbW9kZWwuCiAqCiAqICMjIyBFeGFtcGxlIHdpdGggVmFsaWRhdGlvbgogKgogKiA8ZXhhbXBsZSBuYW1lPSJuZ0xpc3QtZGlyZWN0aXZlIiBtb2R1bGU9Imxpc3RFeGFtcGxlIj4KICogICA8ZmlsZSBuYW1lPSJhcHAuanMiPgogKiAgICAgIGFuZ3VsYXIubW9kdWxlKCdsaXN0RXhhbXBsZScsIFtdKQogKiAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICogICAgICAgICAgJHNjb3BlLm5hbWVzID0gWydtb3JwaGV1cycsICduZW8nLCAndHJpbml0eSddOwogKiAgICAgICAgfV0pOwogKiAgIDwvZmlsZT4KICogICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICogICAgPGZvcm0gbmFtZT0ibXlGb3JtIiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAqICAgICAgTGlzdDogPGlucHV0IG5hbWU9Im5hbWVzSW5wdXQiIG5nLW1vZGVsPSJuYW1lcyIgbmctbGlzdCByZXF1aXJlZD4KICogICAgICA8c3BhbiBjbGFzcz0iZXJyb3IiIG5nLXNob3c9Im15Rm9ybS5uYW1lc0lucHV0LiRlcnJvci5yZXF1aXJlZCI+CiAqICAgICAgICBSZXF1aXJlZCE8L3NwYW4+CiAqICAgICAgPGJyPgogKiAgICAgIDx0dD5uYW1lcyA9IHt7bmFtZXN9fTwvdHQ+PGJyLz4KICogICAgICA8dHQ+bXlGb3JtLm5hbWVzSW5wdXQuJHZhbGlkID0ge3tteUZvcm0ubmFtZXNJbnB1dC4kdmFsaWR9fTwvdHQ+PGJyLz4KICogICAgICA8dHQ+bXlGb3JtLm5hbWVzSW5wdXQuJGVycm9yID0ge3tteUZvcm0ubmFtZXNJbnB1dC4kZXJyb3J9fTwvdHQ+PGJyLz4KICogICAgICA8dHQ+bXlGb3JtLiR2YWxpZCA9IHt7bXlGb3JtLiR2YWxpZH19PC90dD48YnIvPgogKiAgICAgIDx0dD5teUZvcm0uJGVycm9yLnJlcXVpcmVkID0ge3shIW15Rm9ybS4kZXJyb3IucmVxdWlyZWR9fTwvdHQ+PGJyLz4KICogICAgIDwvZm9ybT4KICogICA8L2ZpbGU+CiAqICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAqICAgICB2YXIgbGlzdElucHV0ID0gZWxlbWVudChieS5tb2RlbCgnbmFtZXMnKSk7CiAqICAgICB2YXIgbmFtZXMgPSBlbGVtZW50KGJ5LmV4YWN0QmluZGluZygnbmFtZXMnKSk7CiAqICAgICB2YXIgdmFsaWQgPSBlbGVtZW50KGJ5LmJpbmRpbmcoJ215Rm9ybS5uYW1lc0lucHV0LiR2YWxpZCcpKTsKICogICAgIHZhciBlcnJvciA9IGVsZW1lbnQoYnkuY3NzKCdzcGFuLmVycm9yJykpOwogKgogKiAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAqICAgICAgIGV4cGVjdChuYW1lcy5nZXRUZXh0KCkpLnRvQ29udGFpbignWyJtb3JwaGV1cyIsIm5lbyIsInRyaW5pdHkiXScpOwogKiAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3RydWUnKTsKICogICAgICAgZXhwZWN0KGVycm9yLmdldENzc1ZhbHVlKCdkaXNwbGF5JykpLnRvQmUoJ25vbmUnKTsKICogICAgIH0pOwogKgogKiAgICAgaXQoJ3Nob3VsZCBiZSBpbnZhbGlkIGlmIGVtcHR5JywgZnVuY3Rpb24oKSB7CiAqICAgICAgIGxpc3RJbnB1dC5jbGVhcigpOwogKiAgICAgICBsaXN0SW5wdXQuc2VuZEtleXMoJycpOwogKgogKiAgICAgICBleHBlY3QobmFtZXMuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJycpOwogKiAgICAgICBleHBlY3QodmFsaWQuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2ZhbHNlJyk7CiAqICAgICAgIGV4cGVjdChlcnJvci5nZXRDc3NWYWx1ZSgnZGlzcGxheScpKS5ub3QudG9CZSgnbm9uZScpOwogKiAgICAgfSk7CiAqICAgPC9maWxlPgogKiA8L2V4YW1wbGU+CiAqCiAqICMjIyBFeGFtcGxlIC0gc3BsaXR0aW5nIG9uIHdoaXRlc3BhY2UKICogPGV4YW1wbGUgbmFtZT0ibmdMaXN0LWRpcmVjdGl2ZS1uZXdsaW5lcyI+CiAqICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAqICAgIDx0ZXh0YXJlYSBuZy1tb2RlbD0ibGlzdCIgbmctbGlzdD0iJiMxMDsiIG5nLXRyaW09ImZhbHNlIj48L3RleHRhcmVhPgogKiAgICA8cHJlPnt7IGxpc3QgfCBqc29uIH19PC9wcmU+CiAqICAgPC9maWxlPgogKiAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogKiAgICAgaXQoInNob3VsZCBzcGxpdCB0aGUgdGV4dCBieSBuZXdsaW5lcyIsIGZ1bmN0aW9uKCkgewogKiAgICAgICB2YXIgbGlzdElucHV0ID0gZWxlbWVudChieS5tb2RlbCgnbGlzdCcpKTsKICogICAgICAgdmFyIG91dHB1dCA9IGVsZW1lbnQoYnkuYmluZGluZygnbGlzdCB8IGpzb24nKSk7CiAqICAgICAgIGxpc3RJbnB1dC5zZW5kS2V5cygnYWJjXG5kZWZcbmdoaScpOwogKiAgICAgICBleHBlY3Qob3V0cHV0LmdldFRleHQoKSkudG9Db250YWluKCdbXG4gICJhYmMiLFxuICAiZGVmIixcbiAgImdoaSJcbl0nKTsKICogICAgIH0pOwogKiAgIDwvZmlsZT4KICogPC9leGFtcGxlPgogKgogKiBAZWxlbWVudCBpbnB1dAogKiBAcGFyYW0ge3N0cmluZz19IG5nTGlzdCBvcHRpb25hbCBkZWxpbWl0ZXIgdGhhdCBzaG91bGQgYmUgdXNlZCB0byBzcGxpdCB0aGUgdmFsdWUuCiAqLwp2YXIgbmdMaXN0RGlyZWN0aXZlID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHsKICAgIHJlc3RyaWN0OiAnQScsCiAgICBwcmlvcml0eTogMTAwLAogICAgcmVxdWlyZTogJ25nTW9kZWwnLAogICAgbGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIsIGN0cmwpIHsKICAgICAgLy8gV2Ugd2FudCB0byBjb250cm9sIHdoaXRlc3BhY2UgdHJpbW1pbmcgc28gd2UgdXNlIHRoaXMgY29udm9sdXRlZCBhcHByb2FjaAogICAgICAvLyB0byBhY2Nlc3MgdGhlIG5nTGlzdCBhdHRyaWJ1dGUsIHdoaWNoIGRvZXNuJ3QgcHJlLXRyaW0gdGhlIGF0dHJpYnV0ZQogICAgICB2YXIgbmdMaXN0ID0gZWxlbWVudC5hdHRyKGF0dHIuJGF0dHIubmdMaXN0KSB8fCAnLCAnOwogICAgICB2YXIgdHJpbVZhbHVlcyA9IGF0dHIubmdUcmltICE9PSAnZmFsc2UnOwogICAgICB2YXIgc2VwYXJhdG9yID0gdHJpbVZhbHVlcyA/IHRyaW0obmdMaXN0KSA6IG5nTGlzdDsKCiAgICAgIHZhciBwYXJzZSA9IGZ1bmN0aW9uKHZpZXdWYWx1ZSkgewogICAgICAgIC8vIElmIHRoZSB2aWV3VmFsdWUgaXMgaW52YWxpZCAoc2F5IHJlcXVpcmVkIGJ1dCBlbXB0eSkgaXQgd2lsbCBiZSBgdW5kZWZpbmVkYAogICAgICAgIGlmIChpc1VuZGVmaW5lZCh2aWV3VmFsdWUpKSByZXR1cm47CgogICAgICAgIHZhciBsaXN0ID0gW107CgogICAgICAgIGlmICh2aWV3VmFsdWUpIHsKICAgICAgICAgIGZvckVhY2godmlld1ZhbHVlLnNwbGl0KHNlcGFyYXRvciksIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSkgbGlzdC5wdXNoKHRyaW1WYWx1ZXMgPyB0cmltKHZhbHVlKSA6IHZhbHVlKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgIH07CgogICAgICBjdHJsLiRwYXJzZXJzLnB1c2gocGFyc2UpOwogICAgICBjdHJsLiRmb3JtYXR0ZXJzLnB1c2goZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsKICAgICAgICAgIHJldHVybiB2YWx1ZS5qb2luKG5nTGlzdCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICB9KTsKCiAgICAgIC8vIE92ZXJyaWRlIHRoZSBzdGFuZGFyZCAkaXNFbXB0eSBiZWNhdXNlIGFuIGVtcHR5IGFycmF5IG1lYW5zIHRoZSBpbnB1dCBpcyBlbXB0eS4KICAgICAgY3RybC4kaXNFbXB0eSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuICF2YWx1ZSB8fCAhdmFsdWUubGVuZ3RoOwogICAgICB9OwogICAgfQogIH07Cn07CgoKdmFyIENPTlNUQU5UX1ZBTFVFX1JFR0VYUCA9IC9eKHRydWV8ZmFsc2V8XGQrKSQvOwovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ1ZhbHVlCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBCaW5kcyB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiB0byB0aGUgdmFsdWUgb2YgYDxvcHRpb24+YCBvciB7QGxpbmsgaW5wdXRbcmFkaW9dIGBpbnB1dFtyYWRpb11gfSwKICogc28gdGhhdCB3aGVuIHRoZSBlbGVtZW50IGlzIHNlbGVjdGVkLCB0aGUge0BsaW5rIG5nTW9kZWwgYG5nTW9kZWxgfSBvZiB0aGF0IGVsZW1lbnQgaXMgc2V0IHRvCiAqIHRoZSBib3VuZCB2YWx1ZS4KICoKICogYG5nVmFsdWVgIGlzIHVzZWZ1bCB3aGVuIGR5bmFtaWNhbGx5IGdlbmVyYXRpbmcgbGlzdHMgb2YgcmFkaW8gYnV0dG9ucyB1c2luZwogKiB7QGxpbmsgbmdSZXBlYXQgYG5nUmVwZWF0YH0sIGFzIHNob3duIGJlbG93LgogKgogKiBMaWtld2lzZSwgYG5nVmFsdWVgIGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGA8b3B0aW9uPmAgZWxlbWVudHMgZm9yCiAqIHRoZSB7QGxpbmsgc2VsZWN0IGBzZWxlY3RgfSBlbGVtZW50LiBJbiB0aGF0IGNhc2UgaG93ZXZlciwgb25seSBzdHJpbmdzIGFyZSBzdXBwb3J0ZWQKICogZm9yIHRoZSBgdmFsdWUgYGF0dHJpYnV0ZSwgc28gdGhlIHJlc3VsdGluZyBgbmdNb2RlbGAgd2lsbCBhbHdheXMgYmUgYSBzdHJpbmcuCiAqIFN1cHBvcnQgZm9yIGBzZWxlY3RgIG1vZGVscyB3aXRoIG5vbi1zdHJpbmcgdmFsdWVzIGlzIGF2YWlsYWJsZSB2aWEgYG5nT3B0aW9uc2AuCiAqCiAqIEBlbGVtZW50IGlucHV0CiAqIEBwYXJhbSB7c3RyaW5nPX0gbmdWYWx1ZSBhbmd1bGFyIGV4cHJlc3Npb24sIHdob3NlIHZhbHVlIHdpbGwgYmUgYm91bmQgdG8gdGhlIGB2YWx1ZWAgYXR0cmlidXRlCiAqICAgb2YgdGhlIGBpbnB1dGAgZWxlbWVudAogKgogKiBAZXhhbXBsZQogICAgPGV4YW1wbGUgbmFtZT0ibmdWYWx1ZS1kaXJlY3RpdmUiIG1vZHVsZT0idmFsdWVFeGFtcGxlIj4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8c2NyaXB0PgogICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ3ZhbHVlRXhhbXBsZScsIFtdKQogICAgICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICAgICRzY29wZS5uYW1lcyA9IFsncGl6emEnLCAndW5pY29ybnMnLCAncm9ib3RzJ107CiAgICAgICAgICAgICAgJHNjb3BlLm15ID0geyBmYXZvcml0ZTogJ3VuaWNvcm5zJyB9OwogICAgICAgICAgICB9XSk7CiAgICAgICA8L3NjcmlwdD4KICAgICAgICA8Zm9ybSBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgICA8aDI+V2hpY2ggaXMgeW91ciBmYXZvcml0ZT88L2gyPgogICAgICAgICAgICA8bGFiZWwgbmctcmVwZWF0PSJuYW1lIGluIG5hbWVzIiBmb3I9Int7bmFtZX19Ij4KICAgICAgICAgICAgICB7e25hbWV9fQogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIKICAgICAgICAgICAgICAgICAgICAgbmctbW9kZWw9Im15LmZhdm9yaXRlIgogICAgICAgICAgICAgICAgICAgICBuZy12YWx1ZT0ibmFtZSIKICAgICAgICAgICAgICAgICAgICAgaWQ9Int7bmFtZX19IgogICAgICAgICAgICAgICAgICAgICBuYW1lPSJmYXZvcml0ZSI+CiAgICAgICAgICAgIDwvbGFiZWw+CiAgICAgICAgICA8ZGl2PllvdSBjaG9zZSB7e215LmZhdm9yaXRlfX08L2Rpdj4KICAgICAgICA8L2Zvcm0+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgdmFyIGZhdm9yaXRlID0gZWxlbWVudChieS5iaW5kaW5nKCdteS5mYXZvcml0ZScpKTsKCiAgICAgICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHRvIG1vZGVsJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBleHBlY3QoZmF2b3JpdGUuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ3VuaWNvcm5zJyk7CiAgICAgICAgfSk7CiAgICAgICAgaXQoJ3Nob3VsZCBiaW5kIHRoZSB2YWx1ZXMgdG8gdGhlIGlucHV0cycsIGZ1bmN0aW9uKCkgewogICAgICAgICAgZWxlbWVudC5hbGwoYnkubW9kZWwoJ215LmZhdm9yaXRlJykpLmdldCgwKS5jbGljaygpOwogICAgICAgICAgZXhwZWN0KGZhdm9yaXRlLmdldFRleHQoKSkudG9Db250YWluKCdwaXp6YScpOwogICAgICAgIH0pOwogICAgICA8L2ZpbGU+CiAgICA8L2V4YW1wbGU+CiAqLwp2YXIgbmdWYWx1ZURpcmVjdGl2ZSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0EnLAogICAgcHJpb3JpdHk6IDEwMCwKICAgIGNvbXBpbGU6IGZ1bmN0aW9uKHRwbCwgdHBsQXR0cikgewogICAgICBpZiAoQ09OU1RBTlRfVkFMVUVfUkVHRVhQLnRlc3QodHBsQXR0ci5uZ1ZhbHVlKSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiBuZ1ZhbHVlQ29uc3RhbnRMaW5rKHNjb3BlLCBlbG0sIGF0dHIpIHsKICAgICAgICAgIGF0dHIuJHNldCgndmFsdWUnLCBzY29wZS4kZXZhbChhdHRyLm5nVmFsdWUpKTsKICAgICAgICB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmdW5jdGlvbiBuZ1ZhbHVlTGluayhzY29wZSwgZWxtLCBhdHRyKSB7CiAgICAgICAgICBzY29wZS4kd2F0Y2goYXR0ci5uZ1ZhbHVlLCBmdW5jdGlvbiB2YWx1ZVdhdGNoQWN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGF0dHIuJHNldCgndmFsdWUnLCB2YWx1ZSk7CiAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgfTsKfTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nTW9kZWxPcHRpb25zCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBBbGxvd3MgdHVuaW5nIGhvdyBtb2RlbCB1cGRhdGVzIGFyZSBkb25lLiBVc2luZyBgbmdNb2RlbE9wdGlvbnNgIHlvdSBjYW4gc3BlY2lmeSBhIGN1c3RvbSBsaXN0IG9mCiAqIGV2ZW50cyB0aGF0IHdpbGwgdHJpZ2dlciBhIG1vZGVsIHVwZGF0ZSBhbmQvb3IgYSBkZWJvdW5jaW5nIGRlbGF5IHNvIHRoYXQgdGhlIGFjdHVhbCB1cGRhdGUgb25seQogKiB0YWtlcyBwbGFjZSB3aGVuIGEgdGltZXIgZXhwaXJlczsgdGhpcyB0aW1lciB3aWxsIGJlIHJlc2V0IGFmdGVyIGFub3RoZXIgY2hhbmdlIHRha2VzIHBsYWNlLgogKgogKiBHaXZlbiB0aGUgbmF0dXJlIG9mIGBuZ01vZGVsT3B0aW9uc2AsIHRoZSB2YWx1ZSBkaXNwbGF5ZWQgaW5zaWRlIGlucHV0IGZpZWxkcyBpbiB0aGUgdmlldyBtaWdodAogKiBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgdmFsdWUgaW4gdGhlIGFjdHVhbCBtb2RlbC4gVGhpcyBtZWFucyB0aGF0IGlmIHlvdSB1cGRhdGUgdGhlIG1vZGVsIHlvdQogKiBzaG91bGQgYWxzbyBpbnZva2Uge0BsaW5rIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIgYCRyb2xsYmFja1ZpZXdWYWx1ZWB9IG9uIHRoZSByZWxldmFudCBpbnB1dCBmaWVsZCBpbgogKiBvcmRlciB0byBtYWtlIHN1cmUgaXQgaXMgc3luY2hyb25pemVkIHdpdGggdGhlIG1vZGVsIGFuZCB0aGF0IGFueSBkZWJvdW5jZWQgYWN0aW9uIGlzIGNhbmNlbGVkLgogKgogKiBUaGUgZWFzaWVzdCB3YXkgdG8gcmVmZXJlbmNlIHRoZSBjb250cm9sJ3Mge0BsaW5rIG5nTW9kZWwuTmdNb2RlbENvbnRyb2xsZXIgYCRyb2xsYmFja1ZpZXdWYWx1ZWB9CiAqIG1ldGhvZCBpcyBieSBtYWtpbmcgc3VyZSB0aGUgaW5wdXQgaXMgcGxhY2VkIGluc2lkZSBhIGZvcm0gdGhhdCBoYXMgYSBgbmFtZWAgYXR0cmlidXRlLiBUaGlzIGlzCiAqIGltcG9ydGFudCBiZWNhdXNlIGBmb3JtYCBjb250cm9sbGVycyBhcmUgcHVibGlzaGVkIHRvIHRoZSByZWxhdGVkIHNjb3BlIHVuZGVyIHRoZSBuYW1lIGluIHRoZWlyCiAqIGBuYW1lYCBhdHRyaWJ1dGUuCiAqCiAqIEFueSBwZW5kaW5nIGNoYW5nZXMgd2lsbCB0YWtlIHBsYWNlIGltbWVkaWF0ZWx5IHdoZW4gYW4gZW5jbG9zaW5nIGZvcm0gaXMgc3VibWl0dGVkIHZpYSB0aGUKICogYHN1Ym1pdGAgZXZlbnQuIE5vdGUgdGhhdCBgbmdDbGlja2AgZXZlbnRzIHdpbGwgb2NjdXIgYmVmb3JlIHRoZSBtb2RlbCBpcyB1cGRhdGVkLiBVc2UgYG5nU3VibWl0YAogKiB0byBoYXZlIGFjY2VzcyB0byB0aGUgdXBkYXRlZCBtb2RlbC4KICoKICogYG5nTW9kZWxPcHRpb25zYCBoYXMgYW4gZWZmZWN0IG9uIHRoZSBlbGVtZW50IGl0J3MgZGVjbGFyZWQgb24gYW5kIGl0cyBkZXNjZW5kYW50cy4KICoKICogQHBhcmFtIHtPYmplY3R9IG5nTW9kZWxPcHRpb25zIG9wdGlvbnMgdG8gYXBwbHkgdG8gdGhlIGN1cnJlbnQgbW9kZWwuIFZhbGlkIGtleXMgYXJlOgogKiAgIC0gYHVwZGF0ZU9uYDogc3RyaW5nIHNwZWNpZnlpbmcgd2hpY2ggZXZlbnQgc2hvdWxkIHRoZSBpbnB1dCBiZSBib3VuZCB0by4gWW91IGNhbiBzZXQgc2V2ZXJhbAogKiAgICAgZXZlbnRzIHVzaW5nIGFuIHNwYWNlIGRlbGltaXRlZCBsaXN0LiBUaGVyZSBpcyBhIHNwZWNpYWwgZXZlbnQgY2FsbGVkIGBkZWZhdWx0YCB0aGF0CiAqICAgICBtYXRjaGVzIHRoZSBkZWZhdWx0IGV2ZW50cyBiZWxvbmdpbmcgb2YgdGhlIGNvbnRyb2wuCiAqICAgLSBgZGVib3VuY2VgOiBpbnRlZ2VyIHZhbHVlIHdoaWNoIGNvbnRhaW5zIHRoZSBkZWJvdW5jZSBtb2RlbCB1cGRhdGUgdmFsdWUgaW4gbWlsbGlzZWNvbmRzLiBBCiAqICAgICB2YWx1ZSBvZiAwIHRyaWdnZXJzIGFuIGltbWVkaWF0ZSB1cGRhdGUuIElmIGFuIG9iamVjdCBpcyBzdXBwbGllZCBpbnN0ZWFkLCB5b3UgY2FuIHNwZWNpZnkgYQogKiAgICAgY3VzdG9tIHZhbHVlIGZvciBlYWNoIGV2ZW50LiBGb3IgZXhhbXBsZToKICogICAgIGBuZy1tb2RlbC1vcHRpb25zPSJ7IHVwZGF0ZU9uOiAnZGVmYXVsdCBibHVyJywgZGVib3VuY2U6IHsnZGVmYXVsdCc6IDUwMCwgJ2JsdXInOiAwfSB9ImAKICogICAtIGBhbGxvd0ludmFsaWRgOiBib29sZWFuIHZhbHVlIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSBtb2RlbCBjYW4gYmUgc2V0IHdpdGggdmFsdWVzIHRoYXQgZGlkCiAqICAgICBub3QgdmFsaWRhdGUgY29ycmVjdGx5IGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2Ygc2V0dGluZyB0aGUgbW9kZWwgdG8gdW5kZWZpbmVkLgogKiAgIC0gYGdldHRlclNldHRlcmA6IGJvb2xlYW4gdmFsdWUgd2hpY2ggZGV0ZXJtaW5lcyB3aGV0aGVyIG9yIG5vdCB0byB0cmVhdCBmdW5jdGlvbnMgYm91bmQgdG8KICAgICAgIGBuZ01vZGVsYCBhcyBnZXR0ZXJzL3NldHRlcnMuCiAqICAgLSBgdGltZXpvbmVgOiBEZWZpbmVzIHRoZSB0aW1lem9uZSB0byBiZSB1c2VkIHRvIHJlYWQvd3JpdGUgdGhlIGBEYXRlYCBpbnN0YW5jZSBpbiB0aGUgbW9kZWwgZm9yCiAqICAgICBgPGlucHV0IHR5cGU9ImRhdGUiPmAsIGA8aW5wdXQgdHlwZT0idGltZSI+YCwgLi4uIC4gUmlnaHQgbm93LCB0aGUgb25seSBzdXBwb3J0ZWQgdmFsdWUgaXMgYCdVVEMnYCwKICogICAgIG90aGVyd2lzZSB0aGUgZGVmYXVsdCB0aW1lem9uZSBvZiB0aGUgYnJvd3NlciB3aWxsIGJlIHVzZWQuCiAqCiAqIEBleGFtcGxlCgogIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gb3ZlcnJpZGUgaW1tZWRpYXRlIHVwZGF0ZXMuIENoYW5nZXMgb24gdGhlIGlucHV0cyB3aXRoaW4gdGhlCiAgZm9ybSB3aWxsIHVwZGF0ZSB0aGUgbW9kZWwgb25seSB3aGVuIHRoZSBjb250cm9sIGxvc2VzIGZvY3VzIChibHVyIGV2ZW50KS4gSWYgYGVzY2FwZWAga2V5IGlzCiAgcHJlc3NlZCB3aGlsZSB0aGUgaW5wdXQgZmllbGQgaXMgZm9jdXNlZCwgdGhlIHZhbHVlIGlzIHJlc2V0IHRvIHRoZSB2YWx1ZSBpbiB0aGUgY3VycmVudCBtb2RlbC4KCiAgPGV4YW1wbGUgbmFtZT0ibmdNb2RlbE9wdGlvbnMtZGlyZWN0aXZlLWJsdXIiIG1vZHVsZT0ib3B0aW9uc0V4YW1wbGUiPgogICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgIDxmb3JtIG5hbWU9InVzZXJGb3JtIj4KICAgICAgICAgIE5hbWU6CiAgICAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0idXNlck5hbWUiCiAgICAgICAgICAgICAgICAgbmctbW9kZWw9InVzZXIubmFtZSIKICAgICAgICAgICAgICAgICBuZy1tb2RlbC1vcHRpb25zPSJ7IHVwZGF0ZU9uOiAnYmx1cicgfSIKICAgICAgICAgICAgICAgICBuZy1rZXl1cD0iY2FuY2VsKCRldmVudCkiIC8+PGJyIC8+CgogICAgICAgICAgT3RoZXIgZGF0YToKICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1tb2RlbD0idXNlci5kYXRhIiAvPjxiciAvPgogICAgICAgIDwvZm9ybT4KICAgICAgICA8cHJlPnVzZXIubmFtZSA9IDxzcGFuIG5nLWJpbmQ9InVzZXIubmFtZSI+PC9zcGFuPjwvcHJlPgogICAgICA8L2Rpdj4KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImFwcC5qcyI+CiAgICAgIGFuZ3VsYXIubW9kdWxlKCdvcHRpb25zRXhhbXBsZScsIFtdKQogICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAkc2NvcGUudXNlciA9IHsgbmFtZTogJ3NheScsIGRhdGE6ICcnIH07CgogICAgICAgICAgJHNjb3BlLmNhbmNlbCA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PSAyNykgewogICAgICAgICAgICAgICRzY29wZS51c2VyRm9ybS51c2VyTmFtZS4kcm9sbGJhY2tWaWV3VmFsdWUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICB9XSk7CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgdmFyIG1vZGVsID0gZWxlbWVudChieS5iaW5kaW5nKCd1c2VyLm5hbWUnKSk7CiAgICAgIHZhciBpbnB1dCA9IGVsZW1lbnQoYnkubW9kZWwoJ3VzZXIubmFtZScpKTsKICAgICAgdmFyIG90aGVyID0gZWxlbWVudChieS5tb2RlbCgndXNlci5kYXRhJykpOwoKICAgICAgaXQoJ3Nob3VsZCBhbGxvdyBjdXN0b20gZXZlbnRzJywgZnVuY3Rpb24oKSB7CiAgICAgICAgaW5wdXQuc2VuZEtleXMoJyBoZWxsbycpOwogICAgICAgIGlucHV0LmNsaWNrKCk7CiAgICAgICAgZXhwZWN0KG1vZGVsLmdldFRleHQoKSkudG9FcXVhbCgnc2F5Jyk7CiAgICAgICAgb3RoZXIuY2xpY2soKTsKICAgICAgICBleHBlY3QobW9kZWwuZ2V0VGV4dCgpKS50b0VxdWFsKCdzYXkgaGVsbG8nKTsKICAgICAgfSk7CgogICAgICBpdCgnc2hvdWxkICRyb2xsYmFja1ZpZXdWYWx1ZSB3aGVuIG1vZGVsIGNoYW5nZXMnLCBmdW5jdGlvbigpIHsKICAgICAgICBpbnB1dC5zZW5kS2V5cygnIGhlbGxvJyk7CiAgICAgICAgZXhwZWN0KGlucHV0LmdldEF0dHJpYnV0ZSgndmFsdWUnKSkudG9FcXVhbCgnc2F5IGhlbGxvJyk7CiAgICAgICAgaW5wdXQuc2VuZEtleXMocHJvdHJhY3Rvci5LZXkuRVNDQVBFKTsKICAgICAgICBleHBlY3QoaW5wdXQuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKS50b0VxdWFsKCdzYXknKTsKICAgICAgICBvdGhlci5jbGljaygpOwogICAgICAgIGV4cGVjdChtb2RlbC5nZXRUZXh0KCkpLnRvRXF1YWwoJ3NheScpOwogICAgICB9KTsKICAgIDwvZmlsZT4KICA8L2V4YW1wbGU+CgogIFRoaXMgb25lIHNob3dzIGhvdyB0byBkZWJvdW5jZSBtb2RlbCBjaGFuZ2VzLiBNb2RlbCB3aWxsIGJlIHVwZGF0ZWQgb25seSAxIHNlYyBhZnRlciBsYXN0IGNoYW5nZS4KICBJZiB0aGUgYENsZWFyYCBidXR0b24gaXMgcHJlc3NlZCwgYW55IGRlYm91bmNlZCBhY3Rpb24gaXMgY2FuY2VsZWQgYW5kIHRoZSB2YWx1ZSBiZWNvbWVzIGVtcHR5LgoKICA8ZXhhbXBsZSBuYW1lPSJuZ01vZGVsT3B0aW9ucy1kaXJlY3RpdmUtZGVib3VuY2UiIG1vZHVsZT0ib3B0aW9uc0V4YW1wbGUiPgogICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgIDxmb3JtIG5hbWU9InVzZXJGb3JtIj4KICAgICAgICAgIE5hbWU6CiAgICAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0idXNlck5hbWUiCiAgICAgICAgICAgICAgICAgbmctbW9kZWw9InVzZXIubmFtZSIKICAgICAgICAgICAgICAgICBuZy1tb2RlbC1vcHRpb25zPSJ7IGRlYm91bmNlOiAxMDAwIH0iIC8+CiAgICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSJ1c2VyRm9ybS51c2VyTmFtZS4kcm9sbGJhY2tWaWV3VmFsdWUoKTsgdXNlci5uYW1lPScnIj5DbGVhcjwvYnV0dG9uPjxiciAvPgogICAgICAgIDwvZm9ybT4KICAgICAgICA8cHJlPnVzZXIubmFtZSA9IDxzcGFuIG5nLWJpbmQ9InVzZXIubmFtZSI+PC9zcGFuPjwvcHJlPgogICAgICA8L2Rpdj4KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImFwcC5qcyI+CiAgICAgIGFuZ3VsYXIubW9kdWxlKCdvcHRpb25zRXhhbXBsZScsIFtdKQogICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAkc2NvcGUudXNlciA9IHsgbmFtZTogJ3NheScgfTsKICAgICAgICB9XSk7CiAgICA8L2ZpbGU+CiAgPC9leGFtcGxlPgoKICBUaGlzIG9uZSBzaG93cyBob3cgdG8gYmluZCB0byBnZXR0ZXIvc2V0dGVyczoKCiAgPGV4YW1wbGUgbmFtZT0ibmdNb2RlbE9wdGlvbnMtZGlyZWN0aXZlLWdldHRlci1zZXR0ZXIiIG1vZHVsZT0iZ2V0dGVyU2V0dGVyRXhhbXBsZSI+CiAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgPGZvcm0gbmFtZT0idXNlckZvcm0iPgogICAgICAgICAgTmFtZToKICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ1c2VyTmFtZSIKICAgICAgICAgICAgICAgICBuZy1tb2RlbD0idXNlci5uYW1lIgogICAgICAgICAgICAgICAgIG5nLW1vZGVsLW9wdGlvbnM9InsgZ2V0dGVyU2V0dGVyOiB0cnVlIH0iIC8+CiAgICAgICAgPC9mb3JtPgogICAgICAgIDxwcmU+dXNlci5uYW1lID0gPHNwYW4gbmctYmluZD0idXNlci5uYW1lKCkiPjwvc3Bhbj48L3ByZT4KICAgICAgPC9kaXY+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJhcHAuanMiPgogICAgICBhbmd1bGFyLm1vZHVsZSgnZ2V0dGVyU2V0dGVyRXhhbXBsZScsIFtdKQogICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICB2YXIgX25hbWUgPSAnQnJpYW4nOwogICAgICAgICAgJHNjb3BlLnVzZXIgPSB7CiAgICAgICAgICAgIG5hbWU6IGZ1bmN0aW9uKG5ld05hbWUpIHsKICAgICAgICAgICAgICByZXR1cm4gYW5ndWxhci5pc0RlZmluZWQobmV3TmFtZSkgPyAoX25hbWUgPSBuZXdOYW1lKSA6IF9uYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgIH1dKTsKICAgIDwvZmlsZT4KICA8L2V4YW1wbGU+CiAqLwp2YXIgbmdNb2RlbE9wdGlvbnNEaXJlY3RpdmUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIGNvbnRyb2xsZXI6IFsnJHNjb3BlJywgJyRhdHRycycsIGZ1bmN0aW9uKCRzY29wZSwgJGF0dHJzKSB7CiAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgdGhpcy4kb3B0aW9ucyA9ICRzY29wZS4kZXZhbCgkYXR0cnMubmdNb2RlbE9wdGlvbnMpOwogICAgICAvLyBBbGxvdyBhZGRpbmcvb3ZlcnJpZGluZyBib3VuZCBldmVudHMKICAgICAgaWYgKHRoaXMuJG9wdGlvbnMudXBkYXRlT24gIT09IHVuZGVmaW5lZCkgewogICAgICAgIHRoaXMuJG9wdGlvbnMudXBkYXRlT25EZWZhdWx0ID0gZmFsc2U7CiAgICAgICAgLy8gZXh0cmFjdCAiZGVmYXVsdCIgcHNldWRvLWV2ZW50IGZyb20gbGlzdCBvZiBldmVudHMgdGhhdCBjYW4gdHJpZ2dlciBhIG1vZGVsIHVwZGF0ZQogICAgICAgIHRoaXMuJG9wdGlvbnMudXBkYXRlT24gPSB0cmltKHRoaXMuJG9wdGlvbnMudXBkYXRlT24ucmVwbGFjZShERUZBVUxUX1JFR0VYUCwgZnVuY3Rpb24oKSB7CiAgICAgICAgICB0aGF0LiRvcHRpb25zLnVwZGF0ZU9uRGVmYXVsdCA9IHRydWU7CiAgICAgICAgICByZXR1cm4gJyAnOwogICAgICAgIH0pKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aGlzLiRvcHRpb25zLnVwZGF0ZU9uRGVmYXVsdCA9IHRydWU7CiAgICAgIH0KICAgIH1dCiAgfTsKfTsKCi8vIGhlbHBlciBtZXRob2RzCmZ1bmN0aW9uIGFkZFNldFZhbGlkaXR5TWV0aG9kKGNvbnRleHQpIHsKICB2YXIgY3RybCA9IGNvbnRleHQuY3RybCwKICAgICAgJGVsZW1lbnQgPSBjb250ZXh0LiRlbGVtZW50LAogICAgICBjbGFzc0NhY2hlID0ge30sCiAgICAgIHNldCA9IGNvbnRleHQuc2V0LAogICAgICB1bnNldCA9IGNvbnRleHQudW5zZXQsCiAgICAgIHBhcmVudEZvcm0gPSBjb250ZXh0LnBhcmVudEZvcm0sCiAgICAgICRhbmltYXRlID0gY29udGV4dC4kYW5pbWF0ZTsKCiAgY2xhc3NDYWNoZVtJTlZBTElEX0NMQVNTXSA9ICEoY2xhc3NDYWNoZVtWQUxJRF9DTEFTU10gPSAkZWxlbWVudC5oYXNDbGFzcyhWQUxJRF9DTEFTUykpOwoKICBjdHJsLiRzZXRWYWxpZGl0eSA9IHNldFZhbGlkaXR5OwoKICBmdW5jdGlvbiBzZXRWYWxpZGl0eSh2YWxpZGF0aW9uRXJyb3JLZXksIHN0YXRlLCBvcHRpb25zKSB7CiAgICBpZiAoc3RhdGUgPT09IHVuZGVmaW5lZCkgewogICAgICBjcmVhdGVBbmRTZXQoJyRwZW5kaW5nJywgdmFsaWRhdGlvbkVycm9yS2V5LCBvcHRpb25zKTsKICAgIH0gZWxzZSB7CiAgICAgIHVuc2V0QW5kQ2xlYW51cCgnJHBlbmRpbmcnLCB2YWxpZGF0aW9uRXJyb3JLZXksIG9wdGlvbnMpOwogICAgfQogICAgaWYgKCFpc0Jvb2xlYW4oc3RhdGUpKSB7CiAgICAgIHVuc2V0KGN0cmwuJGVycm9yLCB2YWxpZGF0aW9uRXJyb3JLZXksIG9wdGlvbnMpOwogICAgICB1bnNldChjdHJsLiQkc3VjY2VzcywgdmFsaWRhdGlvbkVycm9yS2V5LCBvcHRpb25zKTsKICAgIH0gZWxzZSB7CiAgICAgIGlmIChzdGF0ZSkgewogICAgICAgIHVuc2V0KGN0cmwuJGVycm9yLCB2YWxpZGF0aW9uRXJyb3JLZXksIG9wdGlvbnMpOwogICAgICAgIHNldChjdHJsLiQkc3VjY2VzcywgdmFsaWRhdGlvbkVycm9yS2V5LCBvcHRpb25zKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZXQoY3RybC4kZXJyb3IsIHZhbGlkYXRpb25FcnJvcktleSwgb3B0aW9ucyk7CiAgICAgICAgdW5zZXQoY3RybC4kJHN1Y2Nlc3MsIHZhbGlkYXRpb25FcnJvcktleSwgb3B0aW9ucyk7CiAgICAgIH0KICAgIH0KICAgIGlmIChjdHJsLiRwZW5kaW5nKSB7CiAgICAgIGNhY2hlZFRvZ2dsZUNsYXNzKFBFTkRJTkdfQ0xBU1MsIHRydWUpOwogICAgICBjdHJsLiR2YWxpZCA9IGN0cmwuJGludmFsaWQgPSB1bmRlZmluZWQ7CiAgICAgIHRvZ2dsZVZhbGlkYXRpb25Dc3MoJycsIG51bGwpOwogICAgfSBlbHNlIHsKICAgICAgY2FjaGVkVG9nZ2xlQ2xhc3MoUEVORElOR19DTEFTUywgZmFsc2UpOwogICAgICBjdHJsLiR2YWxpZCA9IGlzT2JqZWN0RW1wdHkoY3RybC4kZXJyb3IpOwogICAgICBjdHJsLiRpbnZhbGlkID0gIWN0cmwuJHZhbGlkOwogICAgICB0b2dnbGVWYWxpZGF0aW9uQ3NzKCcnLCBjdHJsLiR2YWxpZCk7CiAgICB9CgogICAgLy8gcmUtcmVhZCB0aGUgc3RhdGUgYXMgdGhlIHNldC91bnNldCBtZXRob2RzIGNvdWxkIGhhdmUKICAgIC8vIGNvbWJpbmVkIHN0YXRlIGluIGN0cmwuJGVycm9yW3ZhbGlkYXRpb25FcnJvcl0gKHVzZWQgZm9yIGZvcm1zKSwKICAgIC8vIHdoZXJlIHNldHRpbmcvdW5zZXR0aW5nIG9ubHkgaW5jcmVtZW50cy9kZWNyZW1lbnRzIHRoZSB2YWx1ZSwKICAgIC8vIGFuZCBkb2VzIG5vdCByZXBsYWNlIGl0LgogICAgdmFyIGNvbWJpbmVkU3RhdGU7CiAgICBpZiAoY3RybC4kcGVuZGluZyAmJiBjdHJsLiRwZW5kaW5nW3ZhbGlkYXRpb25FcnJvcktleV0pIHsKICAgICAgY29tYmluZWRTdGF0ZSA9IHVuZGVmaW5lZDsKICAgIH0gZWxzZSBpZiAoY3RybC4kZXJyb3JbdmFsaWRhdGlvbkVycm9yS2V5XSkgewogICAgICBjb21iaW5lZFN0YXRlID0gZmFsc2U7CiAgICB9IGVsc2UgaWYgKGN0cmwuJCRzdWNjZXNzW3ZhbGlkYXRpb25FcnJvcktleV0pIHsKICAgICAgY29tYmluZWRTdGF0ZSA9IHRydWU7CiAgICB9IGVsc2UgewogICAgICBjb21iaW5lZFN0YXRlID0gbnVsbDsKICAgIH0KICAgIHRvZ2dsZVZhbGlkYXRpb25Dc3ModmFsaWRhdGlvbkVycm9yS2V5LCBjb21iaW5lZFN0YXRlKTsKICAgIHBhcmVudEZvcm0uJHNldFZhbGlkaXR5KHZhbGlkYXRpb25FcnJvcktleSwgY29tYmluZWRTdGF0ZSwgY3RybCk7CiAgfQoKICBmdW5jdGlvbiBjcmVhdGVBbmRTZXQobmFtZSwgdmFsdWUsIG9wdGlvbnMpIHsKICAgIGlmICghY3RybFtuYW1lXSkgewogICAgICBjdHJsW25hbWVdID0ge307CiAgICB9CiAgICBzZXQoY3RybFtuYW1lXSwgdmFsdWUsIG9wdGlvbnMpOwogIH0KCiAgZnVuY3Rpb24gdW5zZXRBbmRDbGVhbnVwKG5hbWUsIHZhbHVlLCBvcHRpb25zKSB7CiAgICBpZiAoY3RybFtuYW1lXSkgewogICAgICB1bnNldChjdHJsW25hbWVdLCB2YWx1ZSwgb3B0aW9ucyk7CiAgICB9CiAgICBpZiAoaXNPYmplY3RFbXB0eShjdHJsW25hbWVdKSkgewogICAgICBjdHJsW25hbWVdID0gdW5kZWZpbmVkOwogICAgfQogIH0KCiAgZnVuY3Rpb24gY2FjaGVkVG9nZ2xlQ2xhc3MoY2xhc3NOYW1lLCBzd2l0Y2hWYWx1ZSkgewogICAgaWYgKHN3aXRjaFZhbHVlICYmICFjbGFzc0NhY2hlW2NsYXNzTmFtZV0pIHsKICAgICAgJGFuaW1hdGUuYWRkQ2xhc3MoJGVsZW1lbnQsIGNsYXNzTmFtZSk7CiAgICAgIGNsYXNzQ2FjaGVbY2xhc3NOYW1lXSA9IHRydWU7CiAgICB9IGVsc2UgaWYgKCFzd2l0Y2hWYWx1ZSAmJiBjbGFzc0NhY2hlW2NsYXNzTmFtZV0pIHsKICAgICAgJGFuaW1hdGUucmVtb3ZlQ2xhc3MoJGVsZW1lbnQsIGNsYXNzTmFtZSk7CiAgICAgIGNsYXNzQ2FjaGVbY2xhc3NOYW1lXSA9IGZhbHNlOwogICAgfQogIH0KCiAgZnVuY3Rpb24gdG9nZ2xlVmFsaWRhdGlvbkNzcyh2YWxpZGF0aW9uRXJyb3JLZXksIGlzVmFsaWQpIHsKICAgIHZhbGlkYXRpb25FcnJvcktleSA9IHZhbGlkYXRpb25FcnJvcktleSA/ICctJyArIHNuYWtlX2Nhc2UodmFsaWRhdGlvbkVycm9yS2V5LCAnLScpIDogJyc7CgogICAgY2FjaGVkVG9nZ2xlQ2xhc3MoVkFMSURfQ0xBU1MgKyB2YWxpZGF0aW9uRXJyb3JLZXksIGlzVmFsaWQgPT09IHRydWUpOwogICAgY2FjaGVkVG9nZ2xlQ2xhc3MoSU5WQUxJRF9DTEFTUyArIHZhbGlkYXRpb25FcnJvcktleSwgaXNWYWxpZCA9PT0gZmFsc2UpOwogIH0KfQoKZnVuY3Rpb24gaXNPYmplY3RFbXB0eShvYmopIHsKICBpZiAob2JqKSB7CiAgICBmb3IgKHZhciBwcm9wIGluIG9iaikgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIHJldHVybiB0cnVlOwp9CgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0JpbmQKICogQHJlc3RyaWN0IEFDCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgYG5nQmluZGAgYXR0cmlidXRlIHRlbGxzIEFuZ3VsYXIgdG8gcmVwbGFjZSB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBzcGVjaWZpZWQgSFRNTCBlbGVtZW50CiAqIHdpdGggdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gZXhwcmVzc2lvbiwgYW5kIHRvIHVwZGF0ZSB0aGUgdGV4dCBjb250ZW50IHdoZW4gdGhlIHZhbHVlIG9mIHRoYXQKICogZXhwcmVzc2lvbiBjaGFuZ2VzLgogKgogKiBUeXBpY2FsbHksIHlvdSBkb24ndCB1c2UgYG5nQmluZGAgZGlyZWN0bHksIGJ1dCBpbnN0ZWFkIHlvdSB1c2UgdGhlIGRvdWJsZSBjdXJseSBtYXJrdXAgbGlrZQogKiBge3sgZXhwcmVzc2lvbiB9fWAgd2hpY2ggaXMgc2ltaWxhciBidXQgbGVzcyB2ZXJib3NlLgogKgogKiBJdCBpcyBwcmVmZXJhYmxlIHRvIHVzZSBgbmdCaW5kYCBpbnN0ZWFkIG9mIGB7eyBleHByZXNzaW9uIH19YCBpZiBhIHRlbXBsYXRlIGlzIG1vbWVudGFyaWx5CiAqIGRpc3BsYXllZCBieSB0aGUgYnJvd3NlciBpbiBpdHMgcmF3IHN0YXRlIGJlZm9yZSBBbmd1bGFyIGNvbXBpbGVzIGl0LiBTaW5jZSBgbmdCaW5kYCBpcyBhbgogKiBlbGVtZW50IGF0dHJpYnV0ZSwgaXQgbWFrZXMgdGhlIGJpbmRpbmdzIGludmlzaWJsZSB0byB0aGUgdXNlciB3aGlsZSB0aGUgcGFnZSBpcyBsb2FkaW5nLgogKgogKiBBbiBhbHRlcm5hdGl2ZSBzb2x1dGlvbiB0byB0aGlzIHByb2JsZW0gd291bGQgYmUgdXNpbmcgdGhlCiAqIHtAbGluayBuZy5kaXJlY3RpdmU6bmdDbG9hayBuZ0Nsb2FrfSBkaXJlY3RpdmUuCiAqCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQmluZCB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsdWF0ZS4KICoKICogQGV4YW1wbGUKICogRW50ZXIgYSBuYW1lIGluIHRoZSBMaXZlIFByZXZpZXcgdGV4dCBib3g7IHRoZSBncmVldGluZyBiZWxvdyB0aGUgdGV4dCBib3ggY2hhbmdlcyBpbnN0YW50bHkuCiAgIDxleGFtcGxlIG1vZHVsZT0iYmluZEV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgPHNjcmlwdD4KICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ2JpbmRFeGFtcGxlJywgW10pCiAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICRzY29wZS5uYW1lID0gJ1doaXJsZWQnOwogICAgICAgICAgIH1dKTsKICAgICAgIDwvc2NyaXB0PgogICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgIEVudGVyIG5hbWU6IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1tb2RlbD0ibmFtZSI+PGJyPgogICAgICAgICBIZWxsbyA8c3BhbiBuZy1iaW5kPSJuYW1lIj48L3NwYW4+IQogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgaXQoJ3Nob3VsZCBjaGVjayBuZy1iaW5kJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIHZhciBuYW1lSW5wdXQgPSBlbGVtZW50KGJ5Lm1vZGVsKCduYW1lJykpOwoKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygnbmFtZScpKS5nZXRUZXh0KCkpLnRvQmUoJ1doaXJsZWQnKTsKICAgICAgICAgbmFtZUlucHV0LmNsZWFyKCk7CiAgICAgICAgIG5hbWVJbnB1dC5zZW5kS2V5cygnd29ybGQnKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygnbmFtZScpKS5nZXRUZXh0KCkpLnRvQmUoJ3dvcmxkJyk7CiAgICAgICB9KTsKICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCnZhciBuZ0JpbmREaXJlY3RpdmUgPSBbJyRjb21waWxlJywgZnVuY3Rpb24oJGNvbXBpbGUpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBQycsCiAgICBjb21waWxlOiBmdW5jdGlvbiBuZ0JpbmRDb21waWxlKHRlbXBsYXRlRWxlbWVudCkgewogICAgICAkY29tcGlsZS4kJGFkZEJpbmRpbmdDbGFzcyh0ZW1wbGF0ZUVsZW1lbnQpOwogICAgICByZXR1cm4gZnVuY3Rpb24gbmdCaW5kTGluayhzY29wZSwgZWxlbWVudCwgYXR0cikgewogICAgICAgICRjb21waWxlLiQkYWRkQmluZGluZ0luZm8oZWxlbWVudCwgYXR0ci5uZ0JpbmQpOwogICAgICAgIGVsZW1lbnQgPSBlbGVtZW50WzBdOwogICAgICAgIHNjb3BlLiR3YXRjaChhdHRyLm5nQmluZCwgZnVuY3Rpb24gbmdCaW5kV2F0Y2hBY3Rpb24odmFsdWUpIHsKICAgICAgICAgIGVsZW1lbnQudGV4dENvbnRlbnQgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gJycgOiB2YWx1ZTsKICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9Owp9XTsKCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0JpbmRUZW1wbGF0ZQogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0JpbmRUZW1wbGF0ZWAgZGlyZWN0aXZlIHNwZWNpZmllcyB0aGF0IHRoZSBlbGVtZW50CiAqIHRleHQgY29udGVudCBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCB0aGUgaW50ZXJwb2xhdGlvbiBvZiB0aGUgdGVtcGxhdGUKICogaW4gdGhlIGBuZ0JpbmRUZW1wbGF0ZWAgYXR0cmlidXRlLgogKiBVbmxpa2UgYG5nQmluZGAsIHRoZSBgbmdCaW5kVGVtcGxhdGVgIGNhbiBjb250YWluIG11bHRpcGxlIGB7e2AgYH19YAogKiBleHByZXNzaW9ucy4gVGhpcyBkaXJlY3RpdmUgaXMgbmVlZGVkIHNpbmNlIHNvbWUgSFRNTCBlbGVtZW50cwogKiAoc3VjaCBhcyBUSVRMRSBhbmQgT1BUSU9OKSBjYW5ub3QgY29udGFpbiBTUEFOIGVsZW1lbnRzLgogKgogKiBAZWxlbWVudCBBTlkKICogQHBhcmFtIHtzdHJpbmd9IG5nQmluZFRlbXBsYXRlIHRlbXBsYXRlIG9mIGZvcm0KICogICA8dHQ+e3s8L3R0PiA8dHQ+ZXhwcmVzc2lvbjwvdHQ+IDx0dD59fTwvdHQ+IHRvIGV2YWwuCiAqCiAqIEBleGFtcGxlCiAqIFRyeSBpdCBoZXJlOiBlbnRlciB0ZXh0IGluIHRleHQgYm94IGFuZCB3YXRjaCB0aGUgZ3JlZXRpbmcgY2hhbmdlLgogICA8ZXhhbXBsZSBtb2R1bGU9ImJpbmRFeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgIDxzY3JpcHQ+CiAgICAgICAgIGFuZ3VsYXIubW9kdWxlKCdiaW5kRXhhbXBsZScsIFtdKQogICAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgICAkc2NvcGUuc2FsdXRhdGlvbiA9ICdIZWxsbyc7CiAgICAgICAgICAgICAkc2NvcGUubmFtZSA9ICdXb3JsZCc7CiAgICAgICAgICAgfV0pOwogICAgICAgPC9zY3JpcHQ+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICBTYWx1dGF0aW9uOiA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9InNhbHV0YXRpb24iPjxicj4KICAgICAgICBOYW1lOiA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9Im5hbWUiPjxicj4KICAgICAgICA8cHJlIG5nLWJpbmQtdGVtcGxhdGU9Int7c2FsdXRhdGlvbn19IHt7bmFtZX19ISI+PC9wcmU+CiAgICAgICA8L2Rpdj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLWJpbmQnLCBmdW5jdGlvbigpIHsKICAgICAgICAgdmFyIHNhbHV0YXRpb25FbGVtID0gZWxlbWVudChieS5iaW5kaW5nKCdzYWx1dGF0aW9uJykpOwogICAgICAgICB2YXIgc2FsdXRhdGlvbklucHV0ID0gZWxlbWVudChieS5tb2RlbCgnc2FsdXRhdGlvbicpKTsKICAgICAgICAgdmFyIG5hbWVJbnB1dCA9IGVsZW1lbnQoYnkubW9kZWwoJ25hbWUnKSk7CgogICAgICAgICBleHBlY3Qoc2FsdXRhdGlvbkVsZW0uZ2V0VGV4dCgpKS50b0JlKCdIZWxsbyBXb3JsZCEnKTsKCiAgICAgICAgIHNhbHV0YXRpb25JbnB1dC5jbGVhcigpOwogICAgICAgICBzYWx1dGF0aW9uSW5wdXQuc2VuZEtleXMoJ0dyZWV0aW5ncycpOwogICAgICAgICBuYW1lSW5wdXQuY2xlYXIoKTsKICAgICAgICAgbmFtZUlucHV0LnNlbmRLZXlzKCd1c2VyJyk7CgogICAgICAgICBleHBlY3Qoc2FsdXRhdGlvbkVsZW0uZ2V0VGV4dCgpKS50b0JlKCdHcmVldGluZ3MgdXNlciEnKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KdmFyIG5nQmluZFRlbXBsYXRlRGlyZWN0aXZlID0gWyckaW50ZXJwb2xhdGUnLCAnJGNvbXBpbGUnLCBmdW5jdGlvbigkaW50ZXJwb2xhdGUsICRjb21waWxlKSB7CiAgcmV0dXJuIHsKICAgIGNvbXBpbGU6IGZ1bmN0aW9uIG5nQmluZFRlbXBsYXRlQ29tcGlsZSh0ZW1wbGF0ZUVsZW1lbnQpIHsKICAgICAgJGNvbXBpbGUuJCRhZGRCaW5kaW5nQ2xhc3ModGVtcGxhdGVFbGVtZW50KTsKICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5nQmluZFRlbXBsYXRlTGluayhzY29wZSwgZWxlbWVudCwgYXR0cikgewogICAgICAgIHZhciBpbnRlcnBvbGF0ZUZuID0gJGludGVycG9sYXRlKGVsZW1lbnQuYXR0cihhdHRyLiRhdHRyLm5nQmluZFRlbXBsYXRlKSk7CiAgICAgICAgJGNvbXBpbGUuJCRhZGRCaW5kaW5nSW5mbyhlbGVtZW50LCBpbnRlcnBvbGF0ZUZuLmV4cHJlc3Npb25zKTsKICAgICAgICBlbGVtZW50ID0gZWxlbWVudFswXTsKICAgICAgICBhdHRyLiRvYnNlcnZlKCduZ0JpbmRUZW1wbGF0ZScsIGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdmFsdWUgPT09IHVuZGVmaW5lZCA/ICcnIDogdmFsdWU7CiAgICAgICAgfSk7CiAgICAgIH07CiAgICB9CiAgfTsKfV07CgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdCaW5kSHRtbAogKgogKiBAZGVzY3JpcHRpb24KICogRXZhbHVhdGVzIHRoZSBleHByZXNzaW9uIGFuZCBpbnNlcnRzIHRoZSByZXN1bHRpbmcgSFRNTCBpbnRvIHRoZSBlbGVtZW50IGluIGEgc2VjdXJlIHdheS4gQnkgZGVmYXVsdCwKICogdGhlIHJlc3VsdGluZyBIVE1MIGNvbnRlbnQgd2lsbCBiZSBzYW5pdGl6ZWQgdXNpbmcgdGhlIHtAbGluayBuZ1Nhbml0aXplLiRzYW5pdGl6ZSAkc2FuaXRpemV9IHNlcnZpY2UuCiAqIFRvIHV0aWxpemUgdGhpcyBmdW5jdGlvbmFsaXR5LCBlbnN1cmUgdGhhdCBgJHNhbml0aXplYCBpcyBhdmFpbGFibGUsIGZvciBleGFtcGxlLCBieSBpbmNsdWRpbmcge0BsaW5rCiAqIG5nU2FuaXRpemV9IGluIHlvdXIgbW9kdWxlJ3MgZGVwZW5kZW5jaWVzIChub3QgaW4gY29yZSBBbmd1bGFyKS4gSW4gb3JkZXIgdG8gdXNlIHtAbGluayBuZ1Nhbml0aXplfQogKiBpbiB5b3VyIG1vZHVsZSdzIGRlcGVuZGVuY2llcywgeW91IG5lZWQgdG8gaW5jbHVkZSAiYW5ndWxhci1zYW5pdGl6ZS5qcyIgaW4geW91ciBhcHBsaWNhdGlvbi4KICoKICogWW91IG1heSBhbHNvIGJ5cGFzcyBzYW5pdGl6YXRpb24gZm9yIHZhbHVlcyB5b3Uga25vdyBhcmUgc2FmZS4gVG8gZG8gc28sIGJpbmQgdG8KICogYW4gZXhwbGljaXRseSB0cnVzdGVkIHZhbHVlIHZpYSB7QGxpbmsgbmcuJHNjZSN0cnVzdEFzSHRtbCAkc2NlLnRydXN0QXNIdG1sfS4gIFNlZSB0aGUgZXhhbXBsZQogKiB1bmRlciB7QGxpbmsgbmcuJHNjZSNzaG93LW1lLWFuLWV4YW1wbGUtdXNpbmctc2NlLSBTdHJpY3QgQ29udGV4dHVhbCBFc2NhcGluZyAoU0NFKX0uCiAqCiAqIE5vdGU6IElmIGEgYCRzYW5pdGl6ZWAgc2VydmljZSBpcyB1bmF2YWlsYWJsZSBhbmQgdGhlIGJvdW5kIHZhbHVlIGlzbid0IGV4cGxpY2l0bHkgdHJ1c3RlZCwgeW91CiAqIHdpbGwgaGF2ZSBhbiBleGNlcHRpb24gKGluc3RlYWQgb2YgYW4gZXhwbG9pdC4pCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQmluZEh0bWwge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUuCiAqCiAqIEBleGFtcGxlCgogICA8ZXhhbXBsZSBtb2R1bGU9ImJpbmRIdG1sRXhhbXBsZSIgZGVwcz0iYW5ndWxhci1zYW5pdGl6ZS5qcyI+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICA8cCBuZy1iaW5kLWh0bWw9Im15SFRNTCI+PC9wPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgoKICAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICAgYW5ndWxhci5tb2R1bGUoJ2JpbmRIdG1sRXhhbXBsZScsIFsnbmdTYW5pdGl6ZSddKQogICAgICAgICAuY29udHJvbGxlcignRXhhbXBsZUNvbnRyb2xsZXInLCBbJyRzY29wZScsIGZ1bmN0aW9uKCRzY29wZSkgewogICAgICAgICAgICRzY29wZS5teUhUTUwgPQogICAgICAgICAgICAgICdJIGFtIGFuIDxjb2RlPkhUTUw8L2NvZGU+c3RyaW5nIHdpdGggJyArCiAgICAgICAgICAgICAgJzxhIGhyZWY9IiMiPmxpbmtzITwvYT4gYW5kIG90aGVyIDxlbT5zdHVmZjwvZW0+JzsKICAgICAgICAgfV0pOwogICAgIDwvZmlsZT4KCiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLWJpbmQtaHRtbCcsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCdteUhUTUwnKSkuZ2V0VGV4dCgpKS50b0JlKAogICAgICAgICAgICAgJ0kgYW0gYW4gSFRNTHN0cmluZyB3aXRoIGxpbmtzISBhbmQgb3RoZXIgc3R1ZmYnKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KdmFyIG5nQmluZEh0bWxEaXJlY3RpdmUgPSBbJyRzY2UnLCAnJHBhcnNlJywgJyRjb21waWxlJywgZnVuY3Rpb24oJHNjZSwgJHBhcnNlLCAkY29tcGlsZSkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0EnLAogICAgY29tcGlsZTogZnVuY3Rpb24gbmdCaW5kSHRtbENvbXBpbGUodEVsZW1lbnQsIHRBdHRycykgewogICAgICB2YXIgbmdCaW5kSHRtbEdldHRlciA9ICRwYXJzZSh0QXR0cnMubmdCaW5kSHRtbCk7CiAgICAgIHZhciBuZ0JpbmRIdG1sV2F0Y2ggPSAkcGFyc2UodEF0dHJzLm5nQmluZEh0bWwsIGZ1bmN0aW9uIGdldFN0cmluZ1ZhbHVlKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuICh2YWx1ZSB8fCAnJykudG9TdHJpbmcoKTsKICAgICAgfSk7CiAgICAgICRjb21waWxlLiQkYWRkQmluZGluZ0NsYXNzKHRFbGVtZW50KTsKCiAgICAgIHJldHVybiBmdW5jdGlvbiBuZ0JpbmRIdG1sTGluayhzY29wZSwgZWxlbWVudCwgYXR0cikgewogICAgICAgICRjb21waWxlLiQkYWRkQmluZGluZ0luZm8oZWxlbWVudCwgYXR0ci5uZ0JpbmRIdG1sKTsKCiAgICAgICAgc2NvcGUuJHdhdGNoKG5nQmluZEh0bWxXYXRjaCwgZnVuY3Rpb24gbmdCaW5kSHRtbFdhdGNoQWN0aW9uKCkgewogICAgICAgICAgLy8gd2UgcmUtZXZhbHVhdGUgdGhlIGV4cHIgYmVjYXVzZSB3ZSB3YW50IGEgVHJ1c3RlZFZhbHVlSG9sZGVyVHlwZQogICAgICAgICAgLy8gZm9yICRzY2UsIG5vdCBhIHN0cmluZwogICAgICAgICAgZWxlbWVudC5odG1sKCRzY2UuZ2V0VHJ1c3RlZEh0bWwobmdCaW5kSHRtbEdldHRlcihzY29wZSkpIHx8ICcnKTsKICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9Owp9XTsKCmZ1bmN0aW9uIGNsYXNzRGlyZWN0aXZlKG5hbWUsIHNlbGVjdG9yKSB7CiAgbmFtZSA9ICduZ0NsYXNzJyArIG5hbWU7CiAgcmV0dXJuIFsnJGFuaW1hdGUnLCBmdW5jdGlvbigkYW5pbWF0ZSkgewogICAgcmV0dXJuIHsKICAgICAgcmVzdHJpY3Q6ICdBQycsCiAgICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyKSB7CiAgICAgICAgdmFyIG9sZFZhbDsKCiAgICAgICAgc2NvcGUuJHdhdGNoKGF0dHJbbmFtZV0sIG5nQ2xhc3NXYXRjaEFjdGlvbiwgdHJ1ZSk7CgogICAgICAgIGF0dHIuJG9ic2VydmUoJ2NsYXNzJywgZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgIG5nQ2xhc3NXYXRjaEFjdGlvbihzY29wZS4kZXZhbChhdHRyW25hbWVdKSk7CiAgICAgICAgfSk7CgoKICAgICAgICBpZiAobmFtZSAhPT0gJ25nQ2xhc3MnKSB7CiAgICAgICAgICBzY29wZS4kd2F0Y2goJyRpbmRleCcsIGZ1bmN0aW9uKCRpbmRleCwgb2xkJGluZGV4KSB7CiAgICAgICAgICAgIC8vIGpzaGludCBiaXR3aXNlOiBmYWxzZQogICAgICAgICAgICB2YXIgbW9kID0gJGluZGV4ICYgMTsKICAgICAgICAgICAgaWYgKG1vZCAhPT0gKG9sZCRpbmRleCAmIDEpKSB7CiAgICAgICAgICAgICAgdmFyIGNsYXNzZXMgPSBhcnJheUNsYXNzZXMoc2NvcGUuJGV2YWwoYXR0cltuYW1lXSkpOwogICAgICAgICAgICAgIG1vZCA9PT0gc2VsZWN0b3IgPwogICAgICAgICAgICAgICAgYWRkQ2xhc3NlcyhjbGFzc2VzKSA6CiAgICAgICAgICAgICAgICByZW1vdmVDbGFzc2VzKGNsYXNzZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGFkZENsYXNzZXMoY2xhc3NlcykgewogICAgICAgICAgdmFyIG5ld0NsYXNzZXMgPSBkaWdlc3RDbGFzc0NvdW50cyhjbGFzc2VzLCAxKTsKICAgICAgICAgIGF0dHIuJGFkZENsYXNzKG5ld0NsYXNzZXMpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlQ2xhc3NlcyhjbGFzc2VzKSB7CiAgICAgICAgICB2YXIgbmV3Q2xhc3NlcyA9IGRpZ2VzdENsYXNzQ291bnRzKGNsYXNzZXMsIC0xKTsKICAgICAgICAgIGF0dHIuJHJlbW92ZUNsYXNzKG5ld0NsYXNzZXMpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZGlnZXN0Q2xhc3NDb3VudHMoY2xhc3NlcywgY291bnQpIHsKICAgICAgICAgIHZhciBjbGFzc0NvdW50cyA9IGVsZW1lbnQuZGF0YSgnJGNsYXNzQ291bnRzJykgfHwge307CiAgICAgICAgICB2YXIgY2xhc3Nlc1RvVXBkYXRlID0gW107CiAgICAgICAgICBmb3JFYWNoKGNsYXNzZXMsIGZ1bmN0aW9uKGNsYXNzTmFtZSkgewogICAgICAgICAgICBpZiAoY291bnQgPiAwIHx8IGNsYXNzQ291bnRzW2NsYXNzTmFtZV0pIHsKICAgICAgICAgICAgICBjbGFzc0NvdW50c1tjbGFzc05hbWVdID0gKGNsYXNzQ291bnRzW2NsYXNzTmFtZV0gfHwgMCkgKyBjb3VudDsKICAgICAgICAgICAgICBpZiAoY2xhc3NDb3VudHNbY2xhc3NOYW1lXSA9PT0gKyhjb3VudCA+IDApKSB7CiAgICAgICAgICAgICAgICBjbGFzc2VzVG9VcGRhdGUucHVzaChjbGFzc05hbWUpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBlbGVtZW50LmRhdGEoJyRjbGFzc0NvdW50cycsIGNsYXNzQ291bnRzKTsKICAgICAgICAgIHJldHVybiBjbGFzc2VzVG9VcGRhdGUuam9pbignICcpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQ2xhc3NlcyhvbGRDbGFzc2VzLCBuZXdDbGFzc2VzKSB7CiAgICAgICAgICB2YXIgdG9BZGQgPSBhcnJheURpZmZlcmVuY2UobmV3Q2xhc3Nlcywgb2xkQ2xhc3Nlcyk7CiAgICAgICAgICB2YXIgdG9SZW1vdmUgPSBhcnJheURpZmZlcmVuY2Uob2xkQ2xhc3NlcywgbmV3Q2xhc3Nlcyk7CiAgICAgICAgICB0b0FkZCA9IGRpZ2VzdENsYXNzQ291bnRzKHRvQWRkLCAxKTsKICAgICAgICAgIHRvUmVtb3ZlID0gZGlnZXN0Q2xhc3NDb3VudHModG9SZW1vdmUsIC0xKTsKICAgICAgICAgIGlmICh0b0FkZCAmJiB0b0FkZC5sZW5ndGgpIHsKICAgICAgICAgICAgJGFuaW1hdGUuYWRkQ2xhc3MoZWxlbWVudCwgdG9BZGQpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHRvUmVtb3ZlICYmIHRvUmVtb3ZlLmxlbmd0aCkgewogICAgICAgICAgICAkYW5pbWF0ZS5yZW1vdmVDbGFzcyhlbGVtZW50LCB0b1JlbW92ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBuZ0NsYXNzV2F0Y2hBY3Rpb24obmV3VmFsKSB7CiAgICAgICAgICBpZiAoc2VsZWN0b3IgPT09IHRydWUgfHwgc2NvcGUuJGluZGV4ICUgMiA9PT0gc2VsZWN0b3IpIHsKICAgICAgICAgICAgdmFyIG5ld0NsYXNzZXMgPSBhcnJheUNsYXNzZXMobmV3VmFsIHx8IFtdKTsKICAgICAgICAgICAgaWYgKCFvbGRWYWwpIHsKICAgICAgICAgICAgICBhZGRDbGFzc2VzKG5ld0NsYXNzZXMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFlcXVhbHMobmV3VmFsLG9sZFZhbCkpIHsKICAgICAgICAgICAgICB2YXIgb2xkQ2xhc3NlcyA9IGFycmF5Q2xhc3NlcyhvbGRWYWwpOwogICAgICAgICAgICAgIHVwZGF0ZUNsYXNzZXMob2xkQ2xhc3NlcywgbmV3Q2xhc3Nlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIG9sZFZhbCA9IHNoYWxsb3dDb3B5KG5ld1ZhbCk7CiAgICAgICAgfQogICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGFycmF5RGlmZmVyZW5jZSh0b2tlbnMxLCB0b2tlbnMyKSB7CiAgICAgIHZhciB2YWx1ZXMgPSBbXTsKCiAgICAgIG91dGVyOgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2VuczEubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgdG9rZW4gPSB0b2tlbnMxW2ldOwogICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdG9rZW5zMi5sZW5ndGg7IGorKykgewogICAgICAgICAgaWYgKHRva2VuID09IHRva2VuczJbal0pIGNvbnRpbnVlIG91dGVyOwogICAgICAgIH0KICAgICAgICB2YWx1ZXMucHVzaCh0b2tlbik7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlczsKICAgIH0KCiAgICBmdW5jdGlvbiBhcnJheUNsYXNzZXMoY2xhc3NWYWwpIHsKICAgICAgaWYgKGlzQXJyYXkoY2xhc3NWYWwpKSB7CiAgICAgICAgcmV0dXJuIGNsYXNzVmFsOwogICAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKGNsYXNzVmFsKSkgewogICAgICAgIHJldHVybiBjbGFzc1ZhbC5zcGxpdCgnICcpOwogICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGNsYXNzVmFsKSkgewogICAgICAgIHZhciBjbGFzc2VzID0gW107CiAgICAgICAgZm9yRWFjaChjbGFzc1ZhbCwgZnVuY3Rpb24odiwgaykgewogICAgICAgICAgaWYgKHYpIHsKICAgICAgICAgICAgY2xhc3NlcyA9IGNsYXNzZXMuY29uY2F0KGsuc3BsaXQoJyAnKSk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGNsYXNzZXM7CiAgICAgIH0KICAgICAgcmV0dXJuIGNsYXNzVmFsOwogICAgfQogIH1dOwp9CgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0NsYXNzCiAqIEByZXN0cmljdCBBQwogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0NsYXNzYCBkaXJlY3RpdmUgYWxsb3dzIHlvdSB0byBkeW5hbWljYWxseSBzZXQgQ1NTIGNsYXNzZXMgb24gYW4gSFRNTCBlbGVtZW50IGJ5IGRhdGFiaW5kaW5nCiAqIGFuIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIGFsbCBjbGFzc2VzIHRvIGJlIGFkZGVkLgogKgogKiBUaGUgZGlyZWN0aXZlIG9wZXJhdGVzIGluIHRocmVlIGRpZmZlcmVudCB3YXlzLCBkZXBlbmRpbmcgb24gd2hpY2ggb2YgdGhyZWUgdHlwZXMgdGhlIGV4cHJlc3Npb24KICogZXZhbHVhdGVzIHRvOgogKgogKiAxLiBJZiB0aGUgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gYSBzdHJpbmcsIHRoZSBzdHJpbmcgc2hvdWxkIGJlIG9uZSBvciBtb3JlIHNwYWNlLWRlbGltaXRlZCBjbGFzcwogKiBuYW1lcy4KICoKICogMi4gSWYgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGFuIGFycmF5LCBlYWNoIGVsZW1lbnQgb2YgdGhlIGFycmF5IHNob3VsZCBiZSBhIHN0cmluZyB0aGF0IGlzCiAqIG9uZSBvciBtb3JlIHNwYWNlLWRlbGltaXRlZCBjbGFzcyBuYW1lcy4KICoKICogMy4gSWYgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGFuIG9iamVjdCwgdGhlbiBmb3IgZWFjaCBrZXktdmFsdWUgcGFpciBvZiB0aGUKICogb2JqZWN0IHdpdGggYSB0cnV0aHkgdmFsdWUgdGhlIGNvcnJlc3BvbmRpbmcga2V5IGlzIHVzZWQgYXMgYSBjbGFzcyBuYW1lLgogKgogKiBUaGUgZGlyZWN0aXZlIHdvbid0IGFkZCBkdXBsaWNhdGUgY2xhc3NlcyBpZiBhIHBhcnRpY3VsYXIgY2xhc3Mgd2FzIGFscmVhZHkgc2V0LgogKgogKiBXaGVuIHRoZSBleHByZXNzaW9uIGNoYW5nZXMsIHRoZSBwcmV2aW91c2x5IGFkZGVkIGNsYXNzZXMgYXJlIHJlbW92ZWQgYW5kIG9ubHkgdGhlbiB0aGUKICogbmV3IGNsYXNzZXMgYXJlIGFkZGVkLgogKgogKiBAYW5pbWF0aW9ucwogKiBhZGQgLSBoYXBwZW5zIGp1c3QgYmVmb3JlIHRoZSBjbGFzcyBpcyBhcHBsaWVkIHRvIHRoZSBlbGVtZW50CiAqIHJlbW92ZSAtIGhhcHBlbnMganVzdCBiZWZvcmUgdGhlIGNsYXNzIGlzIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudAogKgogKiBAZWxlbWVudCBBTlkKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ0NsYXNzIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWwuIFRoZSByZXN1bHQKICogICBvZiB0aGUgZXZhbHVhdGlvbiBjYW4gYmUgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHNwYWNlIGRlbGltaXRlZCBjbGFzcwogKiAgIG5hbWVzLCBhbiBhcnJheSwgb3IgYSBtYXAgb2YgY2xhc3MgbmFtZXMgdG8gYm9vbGVhbiB2YWx1ZXMuIEluIHRoZSBjYXNlIG9mIGEgbWFwLCB0aGUKICogICBuYW1lcyBvZiB0aGUgcHJvcGVydGllcyB3aG9zZSB2YWx1ZXMgYXJlIHRydXRoeSB3aWxsIGJlIGFkZGVkIGFzIGNzcyBjbGFzc2VzIHRvIHRoZQogKiAgIGVsZW1lbnQuCiAqCiAqIEBleGFtcGxlIEV4YW1wbGUgdGhhdCBkZW1vbnN0cmF0ZXMgYmFzaWMgYmluZGluZ3MgdmlhIG5nQ2xhc3MgZGlyZWN0aXZlLgogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgIDxwIG5nLWNsYXNzPSJ7c3RyaWtlOiBkZWxldGVkLCBib2xkOiBpbXBvcnRhbnQsIHJlZDogZXJyb3J9Ij5NYXAgU3ludGF4IEV4YW1wbGU8L3A+CiAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJkZWxldGVkIj4gZGVsZXRlZCAoYXBwbHkgInN0cmlrZSIgY2xhc3MpPGJyPgogICAgICAgPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0iaW1wb3J0YW50Ij4gaW1wb3J0YW50IChhcHBseSAiYm9sZCIgY2xhc3MpPGJyPgogICAgICAgPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0iZXJyb3IiPiBlcnJvciAoYXBwbHkgInJlZCIgY2xhc3MpCiAgICAgICA8aHI+CiAgICAgICA8cCBuZy1jbGFzcz0ic3R5bGUiPlVzaW5nIFN0cmluZyBTeW50YXg8L3A+CiAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9InN0eWxlIiBwbGFjZWhvbGRlcj0iVHlwZTogYm9sZCBzdHJpa2UgcmVkIj4KICAgICAgIDxocj4KICAgICAgIDxwIG5nLWNsYXNzPSJbc3R5bGUxLCBzdHlsZTIsIHN0eWxlM10iPlVzaW5nIEFycmF5IFN5bnRheDwvcD4KICAgICAgIDxpbnB1dCBuZy1tb2RlbD0ic3R5bGUxIiBwbGFjZWhvbGRlcj0iVHlwZTogYm9sZCwgc3RyaWtlIG9yIHJlZCI+PGJyPgogICAgICAgPGlucHV0IG5nLW1vZGVsPSJzdHlsZTIiIHBsYWNlaG9sZGVyPSJUeXBlOiBib2xkLCBzdHJpa2Ugb3IgcmVkIj48YnI+CiAgICAgICA8aW5wdXQgbmctbW9kZWw9InN0eWxlMyIgcGxhY2Vob2xkZXI9IlR5cGU6IGJvbGQsIHN0cmlrZSBvciByZWQiPjxicj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0ic3R5bGUuY3NzIj4KICAgICAgIC5zdHJpa2UgewogICAgICAgICB0ZXh0LWRlY29yYXRpb246IGxpbmUtdGhyb3VnaDsKICAgICAgIH0KICAgICAgIC5ib2xkIHsKICAgICAgICAgICBmb250LXdlaWdodDogYm9sZDsKICAgICAgIH0KICAgICAgIC5yZWQgewogICAgICAgICAgIGNvbG9yOiByZWQ7CiAgICAgICB9CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgdmFyIHBzID0gZWxlbWVudC5hbGwoYnkuY3NzKCdwJykpOwoKICAgICAgIGl0KCdzaG91bGQgbGV0IHlvdSB0b2dnbGUgdGhlIGNsYXNzJywgZnVuY3Rpb24oKSB7CgogICAgICAgICBleHBlY3QocHMuZmlyc3QoKS5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpLm5vdC50b01hdGNoKC9ib2xkLyk7CiAgICAgICAgIGV4cGVjdChwcy5maXJzdCgpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkubm90LnRvTWF0Y2goL3JlZC8pOwoKICAgICAgICAgZWxlbWVudChieS5tb2RlbCgnaW1wb3J0YW50JykpLmNsaWNrKCk7CiAgICAgICAgIGV4cGVjdChwcy5maXJzdCgpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkudG9NYXRjaCgvYm9sZC8pOwoKICAgICAgICAgZWxlbWVudChieS5tb2RlbCgnZXJyb3InKSkuY2xpY2soKTsKICAgICAgICAgZXhwZWN0KHBzLmZpcnN0KCkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS50b01hdGNoKC9yZWQvKTsKICAgICAgIH0pOwoKICAgICAgIGl0KCdzaG91bGQgbGV0IHlvdSB0b2dnbGUgc3RyaW5nIGV4YW1wbGUnLCBmdW5jdGlvbigpIHsKICAgICAgICAgZXhwZWN0KHBzLmdldCgxKS5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykpLnRvQmUoJycpOwogICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdzdHlsZScpKS5jbGVhcigpOwogICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdzdHlsZScpKS5zZW5kS2V5cygncmVkJyk7CiAgICAgICAgIGV4cGVjdChwcy5nZXQoMSkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS50b0JlKCdyZWQnKTsKICAgICAgIH0pOwoKICAgICAgIGl0KCdhcnJheSBleGFtcGxlIHNob3VsZCBoYXZlIDMgY2xhc3NlcycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QocHMubGFzdCgpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkudG9CZSgnJyk7CiAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3N0eWxlMScpKS5zZW5kS2V5cygnYm9sZCcpOwogICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdzdHlsZTInKSkuc2VuZEtleXMoJ3N0cmlrZScpOwogICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdzdHlsZTMnKSkuc2VuZEtleXMoJ3JlZCcpOwogICAgICAgICBleHBlY3QocHMubGFzdCgpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkudG9CZSgnYm9sZCBzdHJpa2UgcmVkJyk7CiAgICAgICB9KTsKICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KCiAgICMjIEFuaW1hdGlvbnMKCiAgIFRoZSBleGFtcGxlIGJlbG93IGRlbW9uc3RyYXRlcyBob3cgdG8gcGVyZm9ybSBhbmltYXRpb25zIHVzaW5nIG5nQ2xhc3MuCgogICA8ZXhhbXBsZSBtb2R1bGU9Im5nQW5pbWF0ZSIgZGVwcz0iYW5ndWxhci1hbmltYXRlLmpzIiBhbmltYXRpb25zPSJ0cnVlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGlucHV0IGlkPSJzZXRidG4iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9InNldCIgbmctY2xpY2s9Im15VmFyPSdteS1jbGFzcyciPgogICAgICA8aW5wdXQgaWQ9ImNsZWFyYnRuIiB0eXBlPSJidXR0b24iIHZhbHVlPSJjbGVhciIgbmctY2xpY2s9Im15VmFyPScnIj4KICAgICAgPGJyPgogICAgICA8c3BhbiBjbGFzcz0iYmFzZS1jbGFzcyIgbmctY2xhc3M9Im15VmFyIj5TYW1wbGUgVGV4dDwvc3Bhbj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0ic3R5bGUuY3NzIj4KICAgICAgIC5iYXNlLWNsYXNzIHsKICAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOmFsbCBjdWJpYy1iZXppZXIoMC4yNTAsIDAuNDYwLCAwLjQ1MCwgMC45NDApIDAuNXM7CiAgICAgICAgIHRyYW5zaXRpb246YWxsIGN1YmljLWJlemllcigwLjI1MCwgMC40NjAsIDAuNDUwLCAwLjk0MCkgMC41czsKICAgICAgIH0KCiAgICAgICAuYmFzZS1jbGFzcy5teS1jbGFzcyB7CiAgICAgICAgIGNvbG9yOiByZWQ7CiAgICAgICAgIGZvbnQtc2l6ZTozZW07CiAgICAgICB9CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgaXQoJ3Nob3VsZCBjaGVjayBuZy1jbGFzcycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5jc3MoJy5iYXNlLWNsYXNzJykpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkubm90LgogICAgICAgICAgIHRvTWF0Y2goL215LWNsYXNzLyk7CgogICAgICAgICBlbGVtZW50KGJ5LmlkKCdzZXRidG4nKSkuY2xpY2soKTsKCiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmNzcygnLmJhc2UtY2xhc3MnKSkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS4KICAgICAgICAgICB0b01hdGNoKC9teS1jbGFzcy8pOwoKICAgICAgICAgZWxlbWVudChieS5pZCgnY2xlYXJidG4nKSkuY2xpY2soKTsKCiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmNzcygnLmJhc2UtY2xhc3MnKSkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS5ub3QuCiAgICAgICAgICAgdG9NYXRjaCgvbXktY2xhc3MvKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgoKCiAgICMjIG5nQ2xhc3MgYW5kIHByZS1leGlzdGluZyBDU1MzIFRyYW5zaXRpb25zL0FuaW1hdGlvbnMKICAgVGhlIG5nQ2xhc3MgZGlyZWN0aXZlIHN0aWxsIHN1cHBvcnRzIENTUzMgVHJhbnNpdGlvbnMvQW5pbWF0aW9ucyBldmVuIGlmIHRoZXkgZG8gbm90IGZvbGxvdyB0aGUgbmdBbmltYXRlIENTUyBuYW1pbmcgc3RydWN0dXJlLgogICBVcG9uIGFuaW1hdGlvbiBuZ0FuaW1hdGUgd2lsbCBhcHBseSBzdXBwbGVtZW50YXJ5IENTUyBjbGFzc2VzIHRvIHRyYWNrIHRoZSBzdGFydCBhbmQgZW5kIG9mIGFuIGFuaW1hdGlvbiwgYnV0IHRoaXMgd2lsbCBub3QgaGluZGVyCiAgIGFueSBwcmUtZXhpc3RpbmcgQ1NTIHRyYW5zaXRpb25zIGFscmVhZHkgb24gdGhlIGVsZW1lbnQuIFRvIGdldCBhbiBpZGVhIG9mIHdoYXQgaGFwcGVucyBkdXJpbmcgYSBjbGFzcy1iYXNlZCBhbmltYXRpb24sIGJlIHN1cmUKICAgdG8gdmlldyB0aGUgc3RlcCBieSBzdGVwIGRldGFpbHMgb2Yge0BsaW5rIG5nLiRhbmltYXRlI2FkZENsYXNzICRhbmltYXRlLmFkZENsYXNzfSBhbmQKICAge0BsaW5rIG5nLiRhbmltYXRlI3JlbW92ZUNsYXNzICRhbmltYXRlLnJlbW92ZUNsYXNzfS4KICovCnZhciBuZ0NsYXNzRGlyZWN0aXZlID0gY2xhc3NEaXJlY3RpdmUoJycsIHRydWUpOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdDbGFzc09kZAogKiBAcmVzdHJpY3QgQUMKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgbmdDbGFzc09kZGAgYW5kIGBuZ0NsYXNzRXZlbmAgZGlyZWN0aXZlcyB3b3JrIGV4YWN0bHkgYXMKICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ0NsYXNzIG5nQ2xhc3N9LCBleGNlcHQgdGhleSB3b3JrIGluCiAqIGNvbmp1bmN0aW9uIHdpdGggYG5nUmVwZWF0YCBhbmQgdGFrZSBlZmZlY3Qgb25seSBvbiBvZGQgKGV2ZW4pIHJvd3MuCiAqCiAqIFRoaXMgZGlyZWN0aXZlIGNhbiBiZSBhcHBsaWVkIG9ubHkgd2l0aGluIHRoZSBzY29wZSBvZiBhbgogKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nUmVwZWF0IG5nUmVwZWF0fS4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdDbGFzc09kZCB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsLiBUaGUgcmVzdWx0CiAqICAgb2YgdGhlIGV2YWx1YXRpb24gY2FuIGJlIGEgc3RyaW5nIHJlcHJlc2VudGluZyBzcGFjZSBkZWxpbWl0ZWQgY2xhc3MgbmFtZXMgb3IgYW4gYXJyYXkuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgIDxvbCBuZy1pbml0PSJuYW1lcz1bJ0pvaG4nLCAnTWFyeScsICdDYXRlJywgJ1N1eiddIj4KICAgICAgICAgIDxsaSBuZy1yZXBlYXQ9Im5hbWUgaW4gbmFtZXMiPgogICAgICAgICAgIDxzcGFuIG5nLWNsYXNzLW9kZD0iJ29kZCciIG5nLWNsYXNzLWV2ZW49IidldmVuJyI+CiAgICAgICAgICAgICB7e25hbWV9fQogICAgICAgICAgIDwvc3Bhbj4KICAgICAgICAgIDwvbGk+CiAgICAgICAgPC9vbD4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0ic3R5bGUuY3NzIj4KICAgICAgIC5vZGQgewogICAgICAgICBjb2xvcjogcmVkOwogICAgICAgfQogICAgICAgLmV2ZW4gewogICAgICAgICBjb2xvcjogYmx1ZTsKICAgICAgIH0KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLWNsYXNzLW9kZCBhbmQgbmctY2xhc3MtZXZlbicsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5yZXBlYXRlcignbmFtZSBpbiBuYW1lcycpLnJvdygwKS5jb2x1bW4oJ25hbWUnKSkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS4KICAgICAgICAgICB0b01hdGNoKC9vZGQvKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkucmVwZWF0ZXIoJ25hbWUgaW4gbmFtZXMnKS5yb3coMSkuY29sdW1uKCduYW1lJykpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkuCiAgICAgICAgICAgdG9NYXRjaCgvZXZlbi8pOwogICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwp2YXIgbmdDbGFzc09kZERpcmVjdGl2ZSA9IGNsYXNzRGlyZWN0aXZlKCdPZGQnLCAwKTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQ2xhc3NFdmVuCiAqIEByZXN0cmljdCBBQwogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0NsYXNzT2RkYCBhbmQgYG5nQ2xhc3NFdmVuYCBkaXJlY3RpdmVzIHdvcmsgZXhhY3RseSBhcwogKiB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQ2xhc3MgbmdDbGFzc30sIGV4Y2VwdCB0aGV5IHdvcmsgaW4KICogY29uanVuY3Rpb24gd2l0aCBgbmdSZXBlYXRgIGFuZCB0YWtlIGVmZmVjdCBvbmx5IG9uIG9kZCAoZXZlbikgcm93cy4KICoKICogVGhpcyBkaXJlY3RpdmUgY2FuIGJlIGFwcGxpZWQgb25seSB3aXRoaW4gdGhlIHNjb3BlIG9mIGFuCiAqIHtAbGluayBuZy5kaXJlY3RpdmU6bmdSZXBlYXQgbmdSZXBlYXR9LgogKgogKiBAZWxlbWVudCBBTlkKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ0NsYXNzRXZlbiB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsLiBUaGUKICogICByZXN1bHQgb2YgdGhlIGV2YWx1YXRpb24gY2FuIGJlIGEgc3RyaW5nIHJlcHJlc2VudGluZyBzcGFjZSBkZWxpbWl0ZWQgY2xhc3MgbmFtZXMgb3IgYW4gYXJyYXkuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICAgIDxvbCBuZy1pbml0PSJuYW1lcz1bJ0pvaG4nLCAnTWFyeScsICdDYXRlJywgJ1N1eiddIj4KICAgICAgICAgIDxsaSBuZy1yZXBlYXQ9Im5hbWUgaW4gbmFtZXMiPgogICAgICAgICAgIDxzcGFuIG5nLWNsYXNzLW9kZD0iJ29kZCciIG5nLWNsYXNzLWV2ZW49IidldmVuJyI+CiAgICAgICAgICAgICB7e25hbWV9fSAmbmJzcDsgJm5ic3A7ICZuYnNwOwogICAgICAgICAgIDwvc3Bhbj4KICAgICAgICAgIDwvbGk+CiAgICAgICAgPC9vbD4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0ic3R5bGUuY3NzIj4KICAgICAgIC5vZGQgewogICAgICAgICBjb2xvcjogcmVkOwogICAgICAgfQogICAgICAgLmV2ZW4gewogICAgICAgICBjb2xvcjogYmx1ZTsKICAgICAgIH0KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLWNsYXNzLW9kZCBhbmQgbmctY2xhc3MtZXZlbicsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5yZXBlYXRlcignbmFtZSBpbiBuYW1lcycpLnJvdygwKS5jb2x1bW4oJ25hbWUnKSkuZ2V0QXR0cmlidXRlKCdjbGFzcycpKS4KICAgICAgICAgICB0b01hdGNoKC9vZGQvKTsKICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkucmVwZWF0ZXIoJ25hbWUgaW4gbmFtZXMnKS5yb3coMSkuY29sdW1uKCduYW1lJykpLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSkuCiAgICAgICAgICAgdG9NYXRjaCgvZXZlbi8pOwogICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwp2YXIgbmdDbGFzc0V2ZW5EaXJlY3RpdmUgPSBjbGFzc0RpcmVjdGl2ZSgnRXZlbicsIDEpOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdDbG9hawogKiBAcmVzdHJpY3QgQUMKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgbmdDbG9ha2AgZGlyZWN0aXZlIGlzIHVzZWQgdG8gcHJldmVudCB0aGUgQW5ndWxhciBodG1sIHRlbXBsYXRlIGZyb20gYmVpbmcgYnJpZWZseQogKiBkaXNwbGF5ZWQgYnkgdGhlIGJyb3dzZXIgaW4gaXRzIHJhdyAodW5jb21waWxlZCkgZm9ybSB3aGlsZSB5b3VyIGFwcGxpY2F0aW9uIGlzIGxvYWRpbmcuIFVzZSB0aGlzCiAqIGRpcmVjdGl2ZSB0byBhdm9pZCB0aGUgdW5kZXNpcmFibGUgZmxpY2tlciBlZmZlY3QgY2F1c2VkIGJ5IHRoZSBodG1sIHRlbXBsYXRlIGRpc3BsYXkuCiAqCiAqIFRoZSBkaXJlY3RpdmUgY2FuIGJlIGFwcGxpZWQgdG8gdGhlIGA8Ym9keT5gIGVsZW1lbnQsIGJ1dCB0aGUgcHJlZmVycmVkIHVzYWdlIGlzIHRvIGFwcGx5CiAqIG11bHRpcGxlIGBuZ0Nsb2FrYCBkaXJlY3RpdmVzIHRvIHNtYWxsIHBvcnRpb25zIG9mIHRoZSBwYWdlIHRvIHBlcm1pdCBwcm9ncmVzc2l2ZSByZW5kZXJpbmcKICogb2YgdGhlIGJyb3dzZXIgdmlldy4KICoKICogYG5nQ2xvYWtgIHdvcmtzIGluIGNvb3BlcmF0aW9uIHdpdGggdGhlIGZvbGxvd2luZyBjc3MgcnVsZSBlbWJlZGRlZCB3aXRoaW4gYGFuZ3VsYXIuanNgIGFuZAogKiBgYW5ndWxhci5taW4uanNgLgogKiBGb3IgQ1NQIG1vZGUgcGxlYXNlIGFkZCBgYW5ndWxhci1jc3AuY3NzYCB0byB5b3VyIGh0bWwgZmlsZSAoc2VlIHtAbGluayBuZy5kaXJlY3RpdmU6bmdDc3AgbmdDc3B9KS4KICoKICogYGBgY3NzCiAqIFtuZ1w6Y2xvYWtdLCBbbmctY2xvYWtdLCBbZGF0YS1uZy1jbG9ha10sIFt4LW5nLWNsb2FrXSwgLm5nLWNsb2FrLCAueC1uZy1jbG9hayB7CiAqICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50OwogKiB9CiAqIGBgYAogKgogKiBXaGVuIHRoaXMgY3NzIHJ1bGUgaXMgbG9hZGVkIGJ5IHRoZSBicm93c2VyLCBhbGwgaHRtbCBlbGVtZW50cyAoaW5jbHVkaW5nIHRoZWlyIGNoaWxkcmVuKSB0aGF0CiAqIGFyZSB0YWdnZWQgd2l0aCB0aGUgYG5nQ2xvYWtgIGRpcmVjdGl2ZSBhcmUgaGlkZGVuLiBXaGVuIEFuZ3VsYXIgZW5jb3VudGVycyB0aGlzIGRpcmVjdGl2ZQogKiBkdXJpbmcgdGhlIGNvbXBpbGF0aW9uIG9mIHRoZSB0ZW1wbGF0ZSBpdCBkZWxldGVzIHRoZSBgbmdDbG9ha2AgZWxlbWVudCBhdHRyaWJ1dGUsIG1ha2luZwogKiB0aGUgY29tcGlsZWQgZWxlbWVudCB2aXNpYmxlLgogKgogKiBGb3IgdGhlIGJlc3QgcmVzdWx0LCB0aGUgYGFuZ3VsYXIuanNgIHNjcmlwdCBtdXN0IGJlIGxvYWRlZCBpbiB0aGUgaGVhZCBzZWN0aW9uIG9mIHRoZSBodG1sCiAqIGRvY3VtZW50OyBhbHRlcm5hdGl2ZWx5LCB0aGUgY3NzIHJ1bGUgYWJvdmUgbXVzdCBiZSBpbmNsdWRlZCBpbiB0aGUgZXh0ZXJuYWwgc3R5bGVzaGVldCBvZiB0aGUKICogYXBwbGljYXRpb24uCiAqCiAqIExlZ2FjeSBicm93c2VycywgbGlrZSBJRTcsIGRvIG5vdCBwcm92aWRlIGF0dHJpYnV0ZSBzZWxlY3RvciBzdXBwb3J0IChhZGRlZCBpbiBDU1MgMi4xKSBzbyB0aGV5CiAqIGNhbm5vdCBtYXRjaCB0aGUgYFtuZ1w6Y2xvYWtdYCBzZWxlY3Rvci4gVG8gd29yayBhcm91bmQgdGhpcyBsaW1pdGF0aW9uLCB5b3UgbXVzdCBhZGQgdGhlIGNzcwogKiBjbGFzcyBgbmctY2xvYWtgIGluIGFkZGl0aW9uIHRvIHRoZSBgbmdDbG9ha2AgZGlyZWN0aXZlIGFzIHNob3duIGluIHRoZSBleGFtcGxlIGJlbG93LgogKgogKiBAZWxlbWVudCBBTlkKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgPGRpdiBpZD0idGVtcGxhdGUxIiBuZy1jbG9haz57eyAnaGVsbG8nIH19PC9kaXY+CiAgICAgICAgPGRpdiBpZD0idGVtcGxhdGUyIiBuZy1jbG9hayBjbGFzcz0ibmctY2xvYWsiPnt7ICdoZWxsbyBJRTcnIH19PC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgaXQoJ3Nob3VsZCByZW1vdmUgdGhlIHRlbXBsYXRlIGRpcmVjdGl2ZSBhbmQgY3NzIGNsYXNzJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIGV4cGVjdCgkKCcjdGVtcGxhdGUxJykuZ2V0QXR0cmlidXRlKCduZy1jbG9haycpKS4KICAgICAgICAgICB0b0JlTnVsbCgpOwogICAgICAgICBleHBlY3QoJCgnI3RlbXBsYXRlMicpLmdldEF0dHJpYnV0ZSgnbmctY2xvYWsnKSkuCiAgICAgICAgICAgdG9CZU51bGwoKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKgogKi8KdmFyIG5nQ2xvYWtEaXJlY3RpdmUgPSBuZ0RpcmVjdGl2ZSh7CiAgY29tcGlsZTogZnVuY3Rpb24oZWxlbWVudCwgYXR0cikgewogICAgYXR0ci4kc2V0KCduZ0Nsb2FrJywgdW5kZWZpbmVkKTsKICAgIGVsZW1lbnQucmVtb3ZlQ2xhc3MoJ25nLWNsb2FrJyk7CiAgfQp9KTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQ29udHJvbGxlcgogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0NvbnRyb2xsZXJgIGRpcmVjdGl2ZSBhdHRhY2hlcyBhIGNvbnRyb2xsZXIgY2xhc3MgdG8gdGhlIHZpZXcuIFRoaXMgaXMgYSBrZXkgYXNwZWN0IG9mIGhvdyBhbmd1bGFyCiAqIHN1cHBvcnRzIHRoZSBwcmluY2lwbGVzIGJlaGluZCB0aGUgTW9kZWwtVmlldy1Db250cm9sbGVyIGRlc2lnbiBwYXR0ZXJuLgogKgogKiBNVkMgY29tcG9uZW50cyBpbiBhbmd1bGFyOgogKgogKiAqIE1vZGVsIOKAPyBNb2RlbHMgYXJlIHRoZSBwcm9wZXJ0aWVzIG9mIGEgc2NvcGU7IHNjb3BlcyBhcmUgYXR0YWNoZWQgdG8gdGhlIERPTSB3aGVyZSBzY29wZSBwcm9wZXJ0aWVzCiAqICAgYXJlIGFjY2Vzc2VkIHRocm91Z2ggYmluZGluZ3MuCiAqICogVmlldyDigD8gVGhlIHRlbXBsYXRlIChIVE1MIHdpdGggZGF0YSBiaW5kaW5ncykgdGhhdCBpcyByZW5kZXJlZCBpbnRvIHRoZSBWaWV3LgogKiAqIENvbnRyb2xsZXIg4oA/IFRoZSBgbmdDb250cm9sbGVyYCBkaXJlY3RpdmUgc3BlY2lmaWVzIGEgQ29udHJvbGxlciBjbGFzczsgdGhlIGNsYXNzIGNvbnRhaW5zIGJ1c2luZXNzCiAqICAgbG9naWMgYmVoaW5kIHRoZSBhcHBsaWNhdGlvbiB0byBkZWNvcmF0ZSB0aGUgc2NvcGUgd2l0aCBmdW5jdGlvbnMgYW5kIHZhbHVlcwogKgogKiBOb3RlIHRoYXQgeW91IGNhbiBhbHNvIGF0dGFjaCBjb250cm9sbGVycyB0byB0aGUgRE9NIGJ5IGRlY2xhcmluZyBpdCBpbiBhIHJvdXRlIGRlZmluaXRpb24KICogdmlhIHRoZSB7QGxpbmsgbmdSb3V0ZS4kcm91dGUgJHJvdXRlfSBzZXJ2aWNlLiBBIGNvbW1vbiBtaXN0YWtlIGlzIHRvIGRlY2xhcmUgdGhlIGNvbnRyb2xsZXIKICogYWdhaW4gdXNpbmcgYG5nLWNvbnRyb2xsZXJgIGluIHRoZSB0ZW1wbGF0ZSBpdHNlbGYuICBUaGlzIHdpbGwgY2F1c2UgdGhlIGNvbnRyb2xsZXIgdG8gYmUgYXR0YWNoZWQKICogYW5kIGV4ZWN1dGVkIHR3aWNlLgogKgogKiBAZWxlbWVudCBBTlkKICogQHNjb3BlCiAqIEBwcmlvcml0eSA1MDAKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ0NvbnRyb2xsZXIgTmFtZSBvZiBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgd2l0aCB0aGUgY3VycmVudAogKiB7QGxpbmsgbmcuJGNvbnRyb2xsZXJQcm92aWRlciAkY29udHJvbGxlclByb3ZpZGVyfSBvciBhbiB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufQogKiB0aGF0IG9uIHRoZSBjdXJyZW50IHNjb3BlIGV2YWx1YXRlcyB0byBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLgogKgogKiBUaGUgY29udHJvbGxlciBpbnN0YW5jZSBjYW4gYmUgcHVibGlzaGVkIGludG8gYSBzY29wZSBwcm9wZXJ0eSBieSBzcGVjaWZ5aW5nCiAqIGBuZy1jb250cm9sbGVyPSJhcyBwcm9wZXJ0eU5hbWUiYC4KICoKICogSWYgdGhlIGN1cnJlbnQgYCRjb250cm9sbGVyUHJvdmlkZXJgIGlzIGNvbmZpZ3VyZWQgdG8gdXNlIGdsb2JhbHMgKHZpYQogKiB7QGxpbmsgbmcuJGNvbnRyb2xsZXJQcm92aWRlciNhbGxvd0dsb2JhbHMgYCRjb250cm9sbGVyUHJvdmlkZXIuYWxsb3dHbG9iYWxzKClgIH0pLCB0aGlzIG1heQogKiBhbHNvIGJlIHRoZSBuYW1lIG9mIGEgZ2xvYmFsbHkgYWNjZXNzaWJsZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiAobm90IHJlY29tbWVuZGVkKS4KICoKICogQGV4YW1wbGUKICogSGVyZSBpcyBhIHNpbXBsZSBmb3JtIGZvciBlZGl0aW5nIHVzZXIgY29udGFjdCBpbmZvcm1hdGlvbi4gQWRkaW5nLCByZW1vdmluZywgY2xlYXJpbmcsIGFuZAogKiBncmVldGluZyBhcmUgbWV0aG9kcyBkZWNsYXJlZCBvbiB0aGUgY29udHJvbGxlciAoc2VlIHNvdXJjZSB0YWIpLiBUaGVzZSBtZXRob2RzIGNhbgogKiBlYXNpbHkgYmUgY2FsbGVkIGZyb20gdGhlIGFuZ3VsYXIgbWFya3VwLiBBbnkgY2hhbmdlcyB0byB0aGUgZGF0YSBhcmUgYXV0b21hdGljYWxseSByZWZsZWN0ZWQKICogaW4gdGhlIFZpZXcgd2l0aG91dCB0aGUgbmVlZCBmb3IgYSBtYW51YWwgdXBkYXRlLgogKgogKiBUd28gZGlmZmVyZW50IGRlY2xhcmF0aW9uIHN0eWxlcyBhcmUgaW5jbHVkZWQgYmVsb3c6CiAqCiAqICogb25lIGJpbmRzIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMgZGlyZWN0bHkgb250byB0aGUgY29udHJvbGxlciB1c2luZyBgdGhpc2A6CiAqIGBuZy1jb250cm9sbGVyPSJTZXR0aW5nc0NvbnRyb2xsZXIxIGFzIHNldHRpbmdzImAKICogKiBvbmUgaW5qZWN0cyBgJHNjb3BlYCBpbnRvIHRoZSBjb250cm9sbGVyOgogKiBgbmctY29udHJvbGxlcj0iU2V0dGluZ3NDb250cm9sbGVyMiJgCiAqCiAqIFRoZSBzZWNvbmQgb3B0aW9uIGlzIG1vcmUgY29tbW9uIGluIHRoZSBBbmd1bGFyIGNvbW11bml0eSwgYW5kIGlzIGdlbmVyYWxseSB1c2VkIGluIGJvaWxlcnBsYXRlcwogKiBhbmQgaW4gdGhpcyBndWlkZS4gSG93ZXZlciwgdGhlcmUgYXJlIGFkdmFudGFnZXMgdG8gYmluZGluZyBwcm9wZXJ0aWVzIGRpcmVjdGx5IHRvIHRoZSBjb250cm9sbGVyCiAqIGFuZCBhdm9pZGluZyBzY29wZS4KICoKICogKiBVc2luZyBgY29udHJvbGxlciBhc2AgbWFrZXMgaXQgb2J2aW91cyB3aGljaCBjb250cm9sbGVyIHlvdSBhcmUgYWNjZXNzaW5nIGluIHRoZSB0ZW1wbGF0ZSB3aGVuCiAqIG11bHRpcGxlIGNvbnRyb2xsZXJzIGFwcGx5IHRvIGFuIGVsZW1lbnQuCiAqICogSWYgeW91IGFyZSB3cml0aW5nIHlvdXIgY29udHJvbGxlcnMgYXMgY2xhc3NlcyB5b3UgaGF2ZSBlYXNpZXIgYWNjZXNzIHRvIHRoZSBwcm9wZXJ0aWVzIGFuZAogKiBtZXRob2RzLCB3aGljaCB3aWxsIGFwcGVhciBvbiB0aGUgc2NvcGUsIGZyb20gaW5zaWRlIHRoZSBjb250cm9sbGVyIGNvZGUuCiAqICogU2luY2UgdGhlcmUgaXMgYWx3YXlzIGEgYC5gIGluIHRoZSBiaW5kaW5ncywgeW91IGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgcHJvdG90eXBhbAogKiBpbmhlcml0YW5jZSBtYXNraW5nIHByaW1pdGl2ZXMuCiAqCiAqIFRoaXMgZXhhbXBsZSBkZW1vbnN0cmF0ZXMgdGhlIGBjb250cm9sbGVyIGFzYCBzeW50YXguCiAqCiAqIDxleGFtcGxlIG5hbWU9Im5nQ29udHJvbGxlckFzIiBtb2R1bGU9ImNvbnRyb2xsZXJBc0V4YW1wbGUiPgogKiAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogKiAgICA8ZGl2IGlkPSJjdHJsLWFzLWV4bXBsIiBuZy1jb250cm9sbGVyPSJTZXR0aW5nc0NvbnRyb2xsZXIxIGFzIHNldHRpbmdzIj4KICogICAgICBOYW1lOiA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9InNldHRpbmdzLm5hbWUiLz4KICogICAgICBbIDxhIGhyZWY9IiIgbmctY2xpY2s9InNldHRpbmdzLmdyZWV0KCkiPmdyZWV0PC9hPiBdPGJyLz4KICogICAgICBDb250YWN0OgogKiAgICAgIDx1bD4KICogICAgICAgIDxsaSBuZy1yZXBlYXQ9ImNvbnRhY3QgaW4gc2V0dGluZ3MuY29udGFjdHMiPgogKiAgICAgICAgICA8c2VsZWN0IG5nLW1vZGVsPSJjb250YWN0LnR5cGUiPgogKiAgICAgICAgICAgICA8b3B0aW9uPnBob25lPC9vcHRpb24+CiAqICAgICAgICAgICAgIDxvcHRpb24+ZW1haWw8L29wdGlvbj4KICogICAgICAgICAgPC9zZWxlY3Q+CiAqICAgICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuZy1tb2RlbD0iY29udGFjdC52YWx1ZSIvPgogKiAgICAgICAgICBbIDxhIGhyZWY9IiIgbmctY2xpY2s9InNldHRpbmdzLmNsZWFyQ29udGFjdChjb250YWN0KSI+Y2xlYXI8L2E+CiAqICAgICAgICAgIHwgPGEgaHJlZj0iIiBuZy1jbGljaz0ic2V0dGluZ3MucmVtb3ZlQ29udGFjdChjb250YWN0KSI+WDwvYT4gXQogKiAgICAgICAgPC9saT4KICogICAgICAgIDxsaT5bIDxhIGhyZWY9IiIgbmctY2xpY2s9InNldHRpbmdzLmFkZENvbnRhY3QoKSI+YWRkPC9hPiBdPC9saT4KICogICAgIDwvdWw+CiAqICAgIDwvZGl2PgogKiAgIDwvZmlsZT4KICogICA8ZmlsZSBuYW1lPSJhcHAuanMiPgogKiAgICBhbmd1bGFyLm1vZHVsZSgnY29udHJvbGxlckFzRXhhbXBsZScsIFtdKQogKiAgICAgIC5jb250cm9sbGVyKCdTZXR0aW5nc0NvbnRyb2xsZXIxJywgU2V0dGluZ3NDb250cm9sbGVyMSk7CiAqCiAqICAgIGZ1bmN0aW9uIFNldHRpbmdzQ29udHJvbGxlcjEoKSB7CiAqICAgICAgdGhpcy5uYW1lID0gIkpvaG4gU21pdGgiOwogKiAgICAgIHRoaXMuY29udGFjdHMgPSBbCiAqICAgICAgICB7dHlwZTogJ3Bob25lJywgdmFsdWU6ICc0MDggNTU1IDEyMTInfSwKICogICAgICAgIHt0eXBlOiAnZW1haWwnLCB2YWx1ZTogJ2pvaG4uc21pdGhAZXhhbXBsZS5vcmcnfSBdOwogKiAgICB9CiAqCiAqICAgIFNldHRpbmdzQ29udHJvbGxlcjEucHJvdG90eXBlLmdyZWV0ID0gZnVuY3Rpb24oKSB7CiAqICAgICAgYWxlcnQodGhpcy5uYW1lKTsKICogICAgfTsKICoKICogICAgU2V0dGluZ3NDb250cm9sbGVyMS5wcm90b3R5cGUuYWRkQ29udGFjdCA9IGZ1bmN0aW9uKCkgewogKiAgICAgIHRoaXMuY29udGFjdHMucHVzaCh7dHlwZTogJ2VtYWlsJywgdmFsdWU6ICd5b3VybmFtZUBleGFtcGxlLm9yZyd9KTsKICogICAgfTsKICoKICogICAgU2V0dGluZ3NDb250cm9sbGVyMS5wcm90b3R5cGUucmVtb3ZlQ29udGFjdCA9IGZ1bmN0aW9uKGNvbnRhY3RUb1JlbW92ZSkgewogKiAgICAgdmFyIGluZGV4ID0gdGhpcy5jb250YWN0cy5pbmRleE9mKGNvbnRhY3RUb1JlbW92ZSk7CiAqICAgICAgdGhpcy5jb250YWN0cy5zcGxpY2UoaW5kZXgsIDEpOwogKiAgICB9OwogKgogKiAgICBTZXR0aW5nc0NvbnRyb2xsZXIxLnByb3RvdHlwZS5jbGVhckNvbnRhY3QgPSBmdW5jdGlvbihjb250YWN0KSB7CiAqICAgICAgY29udGFjdC50eXBlID0gJ3Bob25lJzsKICogICAgICBjb250YWN0LnZhbHVlID0gJyc7CiAqICAgIH07CiAqICAgPC9maWxlPgogKiAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogKiAgICAgaXQoJ3Nob3VsZCBjaGVjayBjb250cm9sbGVyIGFzJywgZnVuY3Rpb24oKSB7CiAqICAgICAgIHZhciBjb250YWluZXIgPSBlbGVtZW50KGJ5LmlkKCdjdHJsLWFzLWV4bXBsJykpOwogKiAgICAgICAgIGV4cGVjdChjb250YWluZXIuZWxlbWVudChieS5tb2RlbCgnc2V0dGluZ3MubmFtZScpKQogKiAgICAgICAgICAgLmdldEF0dHJpYnV0ZSgndmFsdWUnKSkudG9CZSgnSm9obiBTbWl0aCcpOwogKgogKiAgICAgICB2YXIgZmlyc3RSZXBlYXQgPQogKiAgICAgICAgICAgY29udGFpbmVyLmVsZW1lbnQoYnkucmVwZWF0ZXIoJ2NvbnRhY3QgaW4gc2V0dGluZ3MuY29udGFjdHMnKS5yb3coMCkpOwogKiAgICAgICB2YXIgc2Vjb25kUmVwZWF0ID0KICogICAgICAgICAgIGNvbnRhaW5lci5lbGVtZW50KGJ5LnJlcGVhdGVyKCdjb250YWN0IGluIHNldHRpbmdzLmNvbnRhY3RzJykucm93KDEpKTsKICoKICogICAgICAgZXhwZWN0KGZpcnN0UmVwZWF0LmVsZW1lbnQoYnkubW9kZWwoJ2NvbnRhY3QudmFsdWUnKSkuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKQogKiAgICAgICAgICAgLnRvQmUoJzQwOCA1NTUgMTIxMicpOwogKgogKiAgICAgICBleHBlY3Qoc2Vjb25kUmVwZWF0LmVsZW1lbnQoYnkubW9kZWwoJ2NvbnRhY3QudmFsdWUnKSkuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKQogKiAgICAgICAgICAgLnRvQmUoJ2pvaG4uc21pdGhAZXhhbXBsZS5vcmcnKTsKICoKICogICAgICAgZmlyc3RSZXBlYXQuZWxlbWVudChieS5saW5rVGV4dCgnY2xlYXInKSkuY2xpY2soKTsKICoKICogICAgICAgZXhwZWN0KGZpcnN0UmVwZWF0LmVsZW1lbnQoYnkubW9kZWwoJ2NvbnRhY3QudmFsdWUnKSkuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKQogKiAgICAgICAgICAgLnRvQmUoJycpOwogKgogKiAgICAgICBjb250YWluZXIuZWxlbWVudChieS5saW5rVGV4dCgnYWRkJykpLmNsaWNrKCk7CiAqCiAqICAgICAgIGV4cGVjdChjb250YWluZXIuZWxlbWVudChieS5yZXBlYXRlcignY29udGFjdCBpbiBzZXR0aW5ncy5jb250YWN0cycpLnJvdygyKSkKICogICAgICAgICAgIC5lbGVtZW50KGJ5Lm1vZGVsKCdjb250YWN0LnZhbHVlJykpCiAqICAgICAgICAgICAuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKQogKiAgICAgICAgICAgLnRvQmUoJ3lvdXJuYW1lQGV4YW1wbGUub3JnJyk7CiAqICAgICB9KTsKICogICA8L2ZpbGU+CiAqIDwvZXhhbXBsZT4KICoKICogVGhpcyBleGFtcGxlIGRlbW9uc3RyYXRlcyB0aGUgImF0dGFjaCB0byBgJHNjb3BlYCIgc3R5bGUgb2YgY29udHJvbGxlci4KICoKICogPGV4YW1wbGUgbmFtZT0ibmdDb250cm9sbGVyIiBtb2R1bGU9ImNvbnRyb2xsZXJFeGFtcGxlIj4KICogIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogKiAgIDxkaXYgaWQ9ImN0cmwtZXhtcGwiIG5nLWNvbnRyb2xsZXI9IlNldHRpbmdzQ29udHJvbGxlcjIiPgogKiAgICAgTmFtZTogPGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJuYW1lIi8+CiAqICAgICBbIDxhIGhyZWY9IiIgbmctY2xpY2s9ImdyZWV0KCkiPmdyZWV0PC9hPiBdPGJyLz4KICogICAgIENvbnRhY3Q6CiAqICAgICA8dWw+CiAqICAgICAgIDxsaSBuZy1yZXBlYXQ9ImNvbnRhY3QgaW4gY29udGFjdHMiPgogKiAgICAgICAgIDxzZWxlY3QgbmctbW9kZWw9ImNvbnRhY3QudHlwZSI+CiAqICAgICAgICAgICAgPG9wdGlvbj5waG9uZTwvb3B0aW9uPgogKiAgICAgICAgICAgIDxvcHRpb24+ZW1haWw8L29wdGlvbj4KICogICAgICAgICA8L3NlbGVjdD4KICogICAgICAgICA8aW5wdXQgdHlwZT0idGV4dCIgbmctbW9kZWw9ImNvbnRhY3QudmFsdWUiLz4KICogICAgICAgICBbIDxhIGhyZWY9IiIgbmctY2xpY2s9ImNsZWFyQ29udGFjdChjb250YWN0KSI+Y2xlYXI8L2E+CiAqICAgICAgICAgfCA8YSBocmVmPSIiIG5nLWNsaWNrPSJyZW1vdmVDb250YWN0KGNvbnRhY3QpIj5YPC9hPiBdCiAqICAgICAgIDwvbGk+CiAqICAgICAgIDxsaT5bIDxhIGhyZWY9IiIgbmctY2xpY2s9ImFkZENvbnRhY3QoKSI+YWRkPC9hPiBdPC9saT4KICogICAgPC91bD4KICogICA8L2Rpdj4KICogIDwvZmlsZT4KICogIDxmaWxlIG5hbWU9ImFwcC5qcyI+CiAqICAgYW5ndWxhci5tb2R1bGUoJ2NvbnRyb2xsZXJFeGFtcGxlJywgW10pCiAqICAgICAuY29udHJvbGxlcignU2V0dGluZ3NDb250cm9sbGVyMicsIFsnJHNjb3BlJywgU2V0dGluZ3NDb250cm9sbGVyMl0pOwogKgogKiAgIGZ1bmN0aW9uIFNldHRpbmdzQ29udHJvbGxlcjIoJHNjb3BlKSB7CiAqICAgICAkc2NvcGUubmFtZSA9ICJKb2huIFNtaXRoIjsKICogICAgICRzY29wZS5jb250YWN0cyA9IFsKICogICAgICAge3R5cGU6J3Bob25lJywgdmFsdWU6JzQwOCA1NTUgMTIxMid9LAogKiAgICAgICB7dHlwZTonZW1haWwnLCB2YWx1ZTonam9obi5zbWl0aEBleGFtcGxlLm9yZyd9IF07CiAqCiAqICAgICAkc2NvcGUuZ3JlZXQgPSBmdW5jdGlvbigpIHsKICogICAgICAgYWxlcnQoJHNjb3BlLm5hbWUpOwogKiAgICAgfTsKICoKICogICAgICRzY29wZS5hZGRDb250YWN0ID0gZnVuY3Rpb24oKSB7CiAqICAgICAgICRzY29wZS5jb250YWN0cy5wdXNoKHt0eXBlOidlbWFpbCcsIHZhbHVlOid5b3VybmFtZUBleGFtcGxlLm9yZyd9KTsKICogICAgIH07CiAqCiAqICAgICAkc2NvcGUucmVtb3ZlQ29udGFjdCA9IGZ1bmN0aW9uKGNvbnRhY3RUb1JlbW92ZSkgewogKiAgICAgICB2YXIgaW5kZXggPSAkc2NvcGUuY29udGFjdHMuaW5kZXhPZihjb250YWN0VG9SZW1vdmUpOwogKiAgICAgICAkc2NvcGUuY29udGFjdHMuc3BsaWNlKGluZGV4LCAxKTsKICogICAgIH07CiAqCiAqICAgICAkc2NvcGUuY2xlYXJDb250YWN0ID0gZnVuY3Rpb24oY29udGFjdCkgewogKiAgICAgICBjb250YWN0LnR5cGUgPSAncGhvbmUnOwogKiAgICAgICBjb250YWN0LnZhbHVlID0gJyc7CiAqICAgICB9OwogKiAgIH0KICogIDwvZmlsZT4KICogIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogKiAgICBpdCgnc2hvdWxkIGNoZWNrIGNvbnRyb2xsZXInLCBmdW5jdGlvbigpIHsKICogICAgICB2YXIgY29udGFpbmVyID0gZWxlbWVudChieS5pZCgnY3RybC1leG1wbCcpKTsKICoKICogICAgICBleHBlY3QoY29udGFpbmVyLmVsZW1lbnQoYnkubW9kZWwoJ25hbWUnKSkKICogICAgICAgICAgLmdldEF0dHJpYnV0ZSgndmFsdWUnKSkudG9CZSgnSm9obiBTbWl0aCcpOwogKgogKiAgICAgIHZhciBmaXJzdFJlcGVhdCA9CiAqICAgICAgICAgIGNvbnRhaW5lci5lbGVtZW50KGJ5LnJlcGVhdGVyKCdjb250YWN0IGluIGNvbnRhY3RzJykucm93KDApKTsKICogICAgICB2YXIgc2Vjb25kUmVwZWF0ID0KICogICAgICAgICAgY29udGFpbmVyLmVsZW1lbnQoYnkucmVwZWF0ZXIoJ2NvbnRhY3QgaW4gY29udGFjdHMnKS5yb3coMSkpOwogKgogKiAgICAgIGV4cGVjdChmaXJzdFJlcGVhdC5lbGVtZW50KGJ5Lm1vZGVsKCdjb250YWN0LnZhbHVlJykpLmdldEF0dHJpYnV0ZSgndmFsdWUnKSkKICogICAgICAgICAgLnRvQmUoJzQwOCA1NTUgMTIxMicpOwogKiAgICAgIGV4cGVjdChzZWNvbmRSZXBlYXQuZWxlbWVudChieS5tb2RlbCgnY29udGFjdC52YWx1ZScpKS5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpCiAqICAgICAgICAgIC50b0JlKCdqb2huLnNtaXRoQGV4YW1wbGUub3JnJyk7CiAqCiAqICAgICAgZmlyc3RSZXBlYXQuZWxlbWVudChieS5saW5rVGV4dCgnY2xlYXInKSkuY2xpY2soKTsKICoKICogICAgICBleHBlY3QoZmlyc3RSZXBlYXQuZWxlbWVudChieS5tb2RlbCgnY29udGFjdC52YWx1ZScpKS5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpCiAqICAgICAgICAgIC50b0JlKCcnKTsKICoKICogICAgICBjb250YWluZXIuZWxlbWVudChieS5saW5rVGV4dCgnYWRkJykpLmNsaWNrKCk7CiAqCiAqICAgICAgZXhwZWN0KGNvbnRhaW5lci5lbGVtZW50KGJ5LnJlcGVhdGVyKCdjb250YWN0IGluIGNvbnRhY3RzJykucm93KDIpKQogKiAgICAgICAgICAuZWxlbWVudChieS5tb2RlbCgnY29udGFjdC52YWx1ZScpKQogKiAgICAgICAgICAuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKQogKiAgICAgICAgICAudG9CZSgneW91cm5hbWVAZXhhbXBsZS5vcmcnKTsKICogICAgfSk7CiAqICA8L2ZpbGU+CiAqPC9leGFtcGxlPgoKICovCnZhciBuZ0NvbnRyb2xsZXJEaXJlY3RpdmUgPSBbZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHsKICAgIHJlc3RyaWN0OiAnQScsCiAgICBzY29wZTogdHJ1ZSwKICAgIGNvbnRyb2xsZXI6ICdAJywKICAgIHByaW9yaXR5OiA1MDAKICB9Owp9XTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQ3NwCiAqCiAqIEBlbGVtZW50IGh0bWwKICogQGRlc2NyaXB0aW9uCiAqIEVuYWJsZXMgW0NTUCAoQ29udGVudCBTZWN1cml0eSBQb2xpY3kpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9TZWN1cml0eS9DU1ApIHN1cHBvcnQuCiAqCiAqIFRoaXMgaXMgbmVjZXNzYXJ5IHdoZW4gZGV2ZWxvcGluZyB0aGluZ3MgbGlrZSBHb29nbGUgQ2hyb21lIEV4dGVuc2lvbnMgb3IgVW5pdmVyc2FsIFdpbmRvd3MgQXBwcy4KICoKICogQ1NQIGZvcmJpZHMgYXBwcyB0byB1c2UgYGV2YWxgIG9yIGBGdW5jdGlvbihzdHJpbmcpYCBnZW5lcmF0ZWQgZnVuY3Rpb25zIChhbW9uZyBvdGhlciB0aGluZ3MpLgogKiBGb3IgQW5ndWxhciB0byBiZSBDU1AgY29tcGF0aWJsZSB0aGVyZSBhcmUgb25seSB0d28gdGhpbmdzIHRoYXQgd2UgbmVlZCB0byBkbyBkaWZmZXJlbnRseToKICoKICogLSBkb24ndCB1c2UgYEZ1bmN0aW9uYCBjb25zdHJ1Y3RvciB0byBnZW5lcmF0ZSBvcHRpbWl6ZWQgdmFsdWUgZ2V0dGVycwogKiAtIGRvbid0IGluamVjdCBjdXN0b20gc3R5bGVzaGVldCBpbnRvIHRoZSBkb2N1bWVudAogKgogKiBBbmd1bGFySlMgdXNlcyBgRnVuY3Rpb24oc3RyaW5nKWAgZ2VuZXJhdGVkIGZ1bmN0aW9ucyBhcyBhIHNwZWVkIG9wdGltaXphdGlvbi4gQXBwbHlpbmcgdGhlIGBuZ0NzcGAKICogZGlyZWN0aXZlIHdpbGwgY2F1c2UgQW5ndWxhciB0byB1c2UgQ1NQIGNvbXBhdGliaWxpdHkgbW9kZS4gV2hlbiB0aGlzIG1vZGUgaXMgb24gQW5ndWxhckpTIHdpbGwKICogZXZhbHVhdGUgYWxsIGV4cHJlc3Npb25zIHVwIHRvIDMwJSBzbG93ZXIgdGhhbiBpbiBub24tQ1NQIG1vZGUsIGJ1dCBubyBzZWN1cml0eSB2aW9sYXRpb25zIHdpbGwKICogYmUgcmFpc2VkLgogKgogKiBDU1AgZm9yYmlkcyBKYXZhU2NyaXB0IHRvIGlubGluZSBzdHlsZXNoZWV0IHJ1bGVzLiBJbiBub24gQ1NQIG1vZGUgQW5ndWxhciBhdXRvbWF0aWNhbGx5CiAqIGluY2x1ZGVzIHNvbWUgQ1NTIHJ1bGVzIChlLmcuIHtAbGluayBuZy5kaXJlY3RpdmU6bmdDbG9hayBuZ0Nsb2FrfSkuCiAqIFRvIG1ha2UgdGhvc2UgZGlyZWN0aXZlcyB3b3JrIGluIENTUCBtb2RlLCBpbmNsdWRlIHRoZSBgYW5ndWxhci1jc3AuY3NzYCBtYW51YWxseS4KICoKICogQW5ndWxhciB0cmllcyB0byBhdXRvZGV0ZWN0IGlmIENTUCBpcyBhY3RpdmUgYW5kIGF1dG9tYXRpY2FsbHkgdHVybiBvbiB0aGUgQ1NQLXNhZmUgbW9kZS4gVGhpcwogKiBhdXRvZGV0ZWN0aW9uIGhvd2V2ZXIgdHJpZ2dlcnMgYSBDU1AgZXJyb3IgdG8gYmUgbG9nZ2VkIGluIHRoZSBjb25zb2xlOgogKgogKiBgYGAKICogUmVmdXNlZCB0byBldmFsdWF0ZSBhIHN0cmluZyBhcyBKYXZhU2NyaXB0IGJlY2F1c2UgJ3Vuc2FmZS1ldmFsJyBpcyBub3QgYW4gYWxsb3dlZCBzb3VyY2Ugb2YKICogc2NyaXB0IGluIHRoZSBmb2xsb3dpbmcgQ29udGVudCBTZWN1cml0eSBQb2xpY3kgZGlyZWN0aXZlOiAiZGVmYXVsdC1zcmMgJ3NlbGYnIi4gTm90ZSB0aGF0CiAqICdzY3JpcHQtc3JjJyB3YXMgbm90IGV4cGxpY2l0bHkgc2V0LCBzbyAnZGVmYXVsdC1zcmMnIGlzIHVzZWQgYXMgYSBmYWxsYmFjay4KICogYGBgCiAqCiAqIFRoaXMgZXJyb3IgaXMgaGFybWxlc3MgYnV0IGFubm95aW5nLiBUbyBwcmV2ZW50IHRoZSBlcnJvciBmcm9tIHNob3dpbmcgdXAsIHB1dCB0aGUgYG5nQ3NwYAogKiBkaXJlY3RpdmUgb24gdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgYXBwbGljYXRpb24gb3Igb24gdGhlIGBhbmd1bGFyLmpzYCBzY3JpcHQgdGFnLCB3aGljaGV2ZXIKICogYXBwZWFycyBmaXJzdCBpbiB0aGUgaHRtbCBkb2N1bWVudC4KICoKICogKk5vdGU6IFRoaXMgZGlyZWN0aXZlIGlzIG9ubHkgYXZhaWxhYmxlIGluIHRoZSBgbmctY3NwYCBhbmQgYGRhdGEtbmctY3NwYCBhdHRyaWJ1dGUgZm9ybS4qCiAqCiAqIEBleGFtcGxlCiAqIFRoaXMgZXhhbXBsZSBzaG93cyBob3cgdG8gYXBwbHkgdGhlIGBuZ0NzcGAgZGlyZWN0aXZlIHRvIHRoZSBgaHRtbGAgdGFnLgogICBgYGBodG1sCiAgICAgPCFkb2N0eXBlIGh0bWw+CiAgICAgPGh0bWwgbmctYXBwIG5nLWNzcD4KICAgICAuLi4KICAgICAuLi4KICAgICA8L2h0bWw+CiAgIGBgYAogICogQGV4YW1wbGUKICAgICAgLy8gTm90ZTogdGhlIHN1ZmZpeCBgLmNzcGAgaW4gdGhlIGV4YW1wbGUgbmFtZSB0cmlnZ2VycwogICAgICAvLyBjc3AgbW9kZSBpbiBvdXIgaHR0cCBzZXJ2ZXIhCiAgICAgIDxleGFtcGxlIG5hbWU9ImV4YW1wbGUuY3NwIiBtb2R1bGU9ImNzcEV4YW1wbGUiIG5nLWNzcD0idHJ1ZSI+CiAgICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9Ik1haW5Db250cm9sbGVyIGFzIGN0cmwiPgogICAgICAgICAgICA8ZGl2PgogICAgICAgICAgICAgIDxidXR0b24gbmctY2xpY2s9ImN0cmwuaW5jKCkiIGlkPSJpbmMiPkluY3JlbWVudDwvYnV0dG9uPgogICAgICAgICAgICAgIDxzcGFuIGlkPSJjb3VudGVyIj4KICAgICAgICAgICAgICAgIHt7Y3RybC5jb3VudGVyfX0KICAgICAgICAgICAgICA8L3NwYW4+CiAgICAgICAgICAgIDwvZGl2PgoKICAgICAgICAgICAgPGRpdj4KICAgICAgICAgICAgICA8YnV0dG9uIG5nLWNsaWNrPSJjdHJsLmV2aWwoKSIgaWQ9ImV2aWwiPkV2aWw8L2J1dHRvbj4KICAgICAgICAgICAgICA8c3BhbiBpZD0iZXZpbEVycm9yIj4KICAgICAgICAgICAgICAgIHt7Y3RybC5ldmlsRXJyb3J9fQogICAgICAgICAgICAgIDwvc3Bhbj4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2ZpbGU+CiAgICAgICAgPGZpbGUgbmFtZT0ic2NyaXB0LmpzIj4KICAgICAgICAgICBhbmd1bGFyLm1vZHVsZSgnY3NwRXhhbXBsZScsIFtdKQogICAgICAgICAgICAgLmNvbnRyb2xsZXIoJ01haW5Db250cm9sbGVyJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvdW50ZXIgPSAwOwogICAgICAgICAgICAgICAgdGhpcy5pbmMgPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgdGhpcy5jb3VudGVyKys7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdGhpcy5ldmlsID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgIC8vIGpzaGludCBldmlsOnRydWUKICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBldmFsKCcxKzInKTsKICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZXZpbEVycm9yID0gZS5tZXNzYWdlOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgIH0pOwogICAgICAgIDwvZmlsZT4KICAgICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgICAgIHZhciB1dGlsLCB3ZWJkcml2ZXI7CgogICAgICAgICAgdmFyIGluY0J0biA9IGVsZW1lbnQoYnkuaWQoJ2luYycpKTsKICAgICAgICAgIHZhciBjb3VudGVyID0gZWxlbWVudChieS5pZCgnY291bnRlcicpKTsKICAgICAgICAgIHZhciBldmlsQnRuID0gZWxlbWVudChieS5pZCgnZXZpbCcpKTsKICAgICAgICAgIHZhciBldmlsRXJyb3IgPSBlbGVtZW50KGJ5LmlkKCdldmlsRXJyb3InKSk7CgogICAgICAgICAgZnVuY3Rpb24gZ2V0QW5kQ2xlYXJTZXZlcmVFcnJvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBicm93c2VyLm1hbmFnZSgpLmxvZ3MoKS5nZXQoJ2Jyb3dzZXInKS50aGVuKGZ1bmN0aW9uKGJyb3dzZXJMb2cpIHsKICAgICAgICAgICAgICByZXR1cm4gYnJvd3NlckxvZy5maWx0ZXIoZnVuY3Rpb24obG9nRW50cnkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBsb2dFbnRyeS5sZXZlbC52YWx1ZSA+IHdlYmRyaXZlci5sb2dnaW5nLkxldmVsLldBUk5JTkcudmFsdWU7CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQoKICAgICAgICAgIGZ1bmN0aW9uIGNsZWFyRXJyb3JzKCkgewogICAgICAgICAgICBnZXRBbmRDbGVhclNldmVyZUVycm9ycygpOwogICAgICAgICAgfQoKICAgICAgICAgIGZ1bmN0aW9uIGV4cGVjdE5vRXJyb3JzKCkgewogICAgICAgICAgICBnZXRBbmRDbGVhclNldmVyZUVycm9ycygpLnRoZW4oZnVuY3Rpb24oZmlsdGVyZWRMb2cpIHsKICAgICAgICAgICAgICBleHBlY3QoZmlsdGVyZWRMb2cubGVuZ3RoKS50b0VxdWFsKDApOwogICAgICAgICAgICAgIGlmIChmaWx0ZXJlZExvZy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdicm93c2VyIGNvbnNvbGUgZXJyb3JzOiAnICsgdXRpbC5pbnNwZWN0KGZpbHRlcmVkTG9nKSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KCiAgICAgICAgICBmdW5jdGlvbiBleHBlY3RFcnJvcihyZWdleCkgewogICAgICAgICAgICBnZXRBbmRDbGVhclNldmVyZUVycm9ycygpLnRoZW4oZnVuY3Rpb24oZmlsdGVyZWRMb2cpIHsKICAgICAgICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICBmaWx0ZXJlZExvZy5mb3JFYWNoKGZ1bmN0aW9uKGxvZykgewogICAgICAgICAgICAgICAgaWYgKGxvZy5tZXNzYWdlLm1hdGNoKHJlZ2V4KSkgewogICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RlZCBhbiBlcnJvciB0aGF0IG1hdGNoZXMgJyArIHJlZ2V4KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQoKICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7CiAgICAgICAgICAgIHdlYmRyaXZlciA9IHJlcXVpcmUoJ3Byb3RyYWN0b3Ivbm9kZV9tb2R1bGVzL3NlbGVuaXVtLXdlYmRyaXZlcicpOwogICAgICAgICAgfSk7CgogICAgICAgICAgLy8gRm9yIG5vdywgd2Ugb25seSB0ZXN0IG9uIENocm9tZSwKICAgICAgICAgIC8vIGFzIFNhZmFyaSBkb2VzIG5vdCBsb2FkIHRoZSBwYWdlIHdpdGggUHJvdHJhY3RvcidzIGluamVjdGVkIHNjcmlwdHMsCiAgICAgICAgICAvLyBhbmQgRmlyZWZveCB3ZWJkcml2ZXIgYWx3YXlzIGRpc2FibGVzIGNvbnRlbnQgc2VjdXJpdHkgcG9saWN5ICgjNjM1OCkKICAgICAgICAgIGlmIChicm93c2VyLnBhcmFtcy5icm93c2VyICE9PSAnY2hyb21lJykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CgogICAgICAgICAgaXQoJ3Nob3VsZCBub3QgcmVwb3J0IGVycm9ycyB3aGVuIHRoZSBwYWdlIGlzIGxvYWRlZCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvLyBjbGVhciBlcnJvcnMgc28gd2UgYXJlIG5vdCBkZXBlbmRlbnQgb24gcHJldmlvdXMgdGVzdHMKICAgICAgICAgICAgY2xlYXJFcnJvcnMoKTsKICAgICAgICAgICAgLy8gTmVlZCB0byByZWxvYWQgdGhlIHBhZ2UgYXMgdGhlIHBhZ2UgaXMgYWxyZWFkeSBsb2FkZWQgd2hlbgogICAgICAgICAgICAvLyB3ZSBjb21lIGhlcmUKICAgICAgICAgICAgYnJvd3Nlci5kcml2ZXIuZ2V0Q3VycmVudFVybCgpLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgICAgICAgICAgYnJvd3Nlci5nZXQodXJsKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGV4cGVjdE5vRXJyb3JzKCk7CiAgICAgICAgICB9KTsKCiAgICAgICAgICBpdCgnc2hvdWxkIGV2YWx1YXRlIGV4cHJlc3Npb25zJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGV4cGVjdChjb3VudGVyLmdldFRleHQoKSkudG9FcXVhbCgnMCcpOwogICAgICAgICAgICBpbmNCdG4uY2xpY2soKTsKICAgICAgICAgICAgZXhwZWN0KGNvdW50ZXIuZ2V0VGV4dCgpKS50b0VxdWFsKCcxJyk7CiAgICAgICAgICAgIGV4cGVjdE5vRXJyb3JzKCk7CiAgICAgICAgICB9KTsKCiAgICAgICAgICBpdCgnc2hvdWxkIHRocm93IGFuZCByZXBvcnQgYW4gZXJyb3Igd2hlbiB1c2luZyAiZXZhbCInLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgZXZpbEJ0bi5jbGljaygpOwogICAgICAgICAgICBleHBlY3QoZXZpbEVycm9yLmdldFRleHQoKSkudG9NYXRjaCgvQ29udGVudCBTZWN1cml0eSBQb2xpY3kvKTsKICAgICAgICAgICAgZXhwZWN0RXJyb3IoL0NvbnRlbnQgU2VjdXJpdHkgUG9saWN5Lyk7CiAgICAgICAgICB9KTsKICAgICAgICA8L2ZpbGU+CiAgICAgIDwvZXhhbXBsZT4KICAqLwoKLy8gbmdDc3AgaXMgbm90IGltcGxlbWVudGVkIGFzIGEgcHJvcGVyIGRpcmVjdGl2ZSBhbnkgbW9yZSwgYmVjYXVzZSB3ZSBuZWVkIGl0IGJlIHByb2Nlc3NlZCB3aGlsZSB3ZQovLyBib290c3RyYXAgdGhlIHN5c3RlbSAoYmVmb3JlICRwYXJzZSBpcyBpbnN0YW50aWF0ZWQpLCBmb3IgdGhpcyByZWFzb24gd2UganVzdCBoYXZlCi8vIHRoZSBjc3AuaXNBY3RpdmUoKSBmbiB0aGF0IGxvb2tzIGZvciBuZy1jc3AgYXR0cmlidXRlIGFueXdoZXJlIGluIHRoZSBjdXJyZW50IGRvYwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdDbGljawogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIG5nQ2xpY2sgZGlyZWN0aXZlIGFsbG93cyB5b3UgdG8gc3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igd2hlbgogKiBhbiBlbGVtZW50IGlzIGNsaWNrZWQuCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQ2xpY2sge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBjbGljay4gKHtAbGluayBndWlkZS9leHByZXNzaW9uIy1ldmVudC0gRXZlbnQgb2JqZWN0IGlzIGF2YWlsYWJsZSBhcyBgJGV2ZW50YH0pCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8YnV0dG9uIG5nLWNsaWNrPSJjb3VudCA9IGNvdW50ICsgMSIgbmctaW5pdD0iY291bnQ9MCI+CiAgICAgICAgSW5jcmVtZW50CiAgICAgIDwvYnV0dG9uPgogICAgICA8c3Bhbj4KICAgICAgICBjb3VudDoge3tjb3VudH19CiAgICAgIDwvc3Bhbj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLWNsaWNrJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ2NvdW50JykpLmdldFRleHQoKSkudG9NYXRjaCgnMCcpOwogICAgICAgICBlbGVtZW50KGJ5LmNzcygnYnV0dG9uJykpLmNsaWNrKCk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ2NvdW50JykpLmdldFRleHQoKSkudG9NYXRjaCgnMScpOwogICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwovKgogKiBBIGNvbGxlY3Rpb24gb2YgZGlyZWN0aXZlcyB0aGF0IGFsbG93cyBjcmVhdGlvbiBvZiBjdXN0b20gZXZlbnQgaGFuZGxlcnMgdGhhdCBhcmUgZGVmaW5lZCBhcwogKiBhbmd1bGFyIGV4cHJlc3Npb25zIGFuZCBhcmUgY29tcGlsZWQgYW5kIGV4ZWN1dGVkIHdpdGhpbiB0aGUgY3VycmVudCBzY29wZS4KICovCnZhciBuZ0V2ZW50RGlyZWN0aXZlcyA9IHt9OwoKLy8gRm9yIGV2ZW50cyB0aGF0IG1pZ2h0IGZpcmUgc3luY2hyb25vdXNseSBkdXJpbmcgRE9NIG1hbmlwdWxhdGlvbgovLyB3ZSBuZWVkIHRvIGV4ZWN1dGUgdGhlaXIgZXZlbnQgaGFuZGxlcnMgYXN5bmNocm9ub3VzbHkgdXNpbmcgJGV2YWxBc3luYywKLy8gc28gdGhhdCB0aGV5IGFyZSBub3QgZXhlY3V0ZWQgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLgp2YXIgZm9yY2VBc3luY0V2ZW50cyA9IHsKICAnYmx1cic6IHRydWUsCiAgJ2ZvY3VzJzogdHJ1ZQp9Owpmb3JFYWNoKAogICdjbGljayBkYmxjbGljayBtb3VzZWRvd24gbW91c2V1cCBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2Vtb3ZlIG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBrZXlkb3duIGtleXVwIGtleXByZXNzIHN1Ym1pdCBmb2N1cyBibHVyIGNvcHkgY3V0IHBhc3RlJy5zcGxpdCgnICcpLAogIGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgdmFyIGRpcmVjdGl2ZU5hbWUgPSBkaXJlY3RpdmVOb3JtYWxpemUoJ25nLScgKyBldmVudE5hbWUpOwogICAgbmdFdmVudERpcmVjdGl2ZXNbZGlyZWN0aXZlTmFtZV0gPSBbJyRwYXJzZScsICckcm9vdFNjb3BlJywgZnVuY3Rpb24oJHBhcnNlLCAkcm9vdFNjb3BlKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgcmVzdHJpY3Q6ICdBJywKICAgICAgICBjb21waWxlOiBmdW5jdGlvbigkZWxlbWVudCwgYXR0cikgewogICAgICAgICAgLy8gV2UgZXhwb3NlIHRoZSBwb3dlcmZ1bCAkZXZlbnQgb2JqZWN0IG9uIHRoZSBzY29wZSB0aGF0IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgV2luZG93LAogICAgICAgICAgLy8gZXRjLiB0aGF0IGlzbid0IHByb3RlY3RlZCBieSB0aGUgZmFzdCBwYXRocyBpbiAkcGFyc2UuICBXZSBleHBsaWNpdGx5IHJlcXVlc3QgYmV0dGVyCiAgICAgICAgICAvLyBjaGVja3MgYXQgdGhlIGNvc3Qgb2Ygc3BlZWQgc2luY2UgZXZlbnQgaGFuZGxlciBleHByZXNzaW9ucyBhcmUgbm90IGV4ZWN1dGVkIGFzCiAgICAgICAgICAvLyBmcmVxdWVudGx5IGFzIHJlZ3VsYXIgY2hhbmdlIGRldGVjdGlvbi4KICAgICAgICAgIHZhciBmbiA9ICRwYXJzZShhdHRyW2RpcmVjdGl2ZU5hbWVdLCAvKiBpbnRlcmNlcHRvckZuICovIG51bGwsIC8qIGV4cGVuc2l2ZUNoZWNrcyAqLyB0cnVlKTsKICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBuZ0V2ZW50SGFuZGxlcihzY29wZSwgZWxlbWVudCkgewogICAgICAgICAgICBlbGVtZW50Lm9uKGV2ZW50TmFtZSwgZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGZuKHNjb3BlLCB7JGV2ZW50OmV2ZW50fSk7CiAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICBpZiAoZm9yY2VBc3luY0V2ZW50c1tldmVudE5hbWVdICYmICRyb290U2NvcGUuJCRwaGFzZSkgewogICAgICAgICAgICAgICAgc2NvcGUuJGV2YWxBc3luYyhjYWxsYmFjayk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNjb3BlLiRhcHBseShjYWxsYmFjayk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9OwogICAgfV07CiAgfQopOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdEYmxjbGljawogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0RibGNsaWNrYCBkaXJlY3RpdmUgYWxsb3dzIHlvdSB0byBzcGVjaWZ5IGN1c3RvbSBiZWhhdmlvciBvbiBhIGRibGNsaWNrIGV2ZW50LgogKgogKiBAZWxlbWVudCBBTlkKICogQHByaW9yaXR5IDAKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ0RibGNsaWNrIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICogYSBkYmxjbGljay4gKFRoZSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgKQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGJ1dHRvbiBuZy1kYmxjbGljaz0iY291bnQgPSBjb3VudCArIDEiIG5nLWluaXQ9ImNvdW50PTAiPgogICAgICAgIEluY3JlbWVudCAob24gZG91YmxlIGNsaWNrKQogICAgICA8L2J1dHRvbj4KICAgICAgY291bnQ6IHt7Y291bnR9fQogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ01vdXNlZG93bgogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIG5nTW91c2Vkb3duIGRpcmVjdGl2ZSBhbGxvd3MgeW91IHRvIHNwZWNpZnkgY3VzdG9tIGJlaGF2aW9yIG9uIG1vdXNlZG93biBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwcmlvcml0eSAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdNb3VzZWRvd24ge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBtb3VzZWRvd24uICh7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiMtZXZlbnQtIEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGB9KQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGJ1dHRvbiBuZy1tb3VzZWRvd249ImNvdW50ID0gY291bnQgKyAxIiBuZy1pbml0PSJjb3VudD0wIj4KICAgICAgICBJbmNyZW1lbnQgKG9uIG1vdXNlIGRvd24pCiAgICAgIDwvYnV0dG9uPgogICAgICBjb3VudDoge3tjb3VudH19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nTW91c2V1cAogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24gbW91c2V1cCBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwcmlvcml0eSAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdNb3VzZXVwIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICogbW91c2V1cC4gKHtAbGluayBndWlkZS9leHByZXNzaW9uIy1ldmVudC0gRXZlbnQgb2JqZWN0IGlzIGF2YWlsYWJsZSBhcyBgJGV2ZW50YH0pCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8YnV0dG9uIG5nLW1vdXNldXA9ImNvdW50ID0gY291bnQgKyAxIiBuZy1pbml0PSJjb3VudD0wIj4KICAgICAgICBJbmNyZW1lbnQgKG9uIG1vdXNlIHVwKQogICAgICA8L2J1dHRvbj4KICAgICAgY291bnQ6IHt7Y291bnR9fQogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nTW91c2VvdmVyCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBTcGVjaWZ5IGN1c3RvbSBiZWhhdmlvciBvbiBtb3VzZW92ZXIgZXZlbnQuCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nTW91c2VvdmVyIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICogbW91c2VvdmVyLiAoe0BsaW5rIGd1aWRlL2V4cHJlc3Npb24jLWV2ZW50LSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgfSkKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxidXR0b24gbmctbW91c2VvdmVyPSJjb3VudCA9IGNvdW50ICsgMSIgbmctaW5pdD0iY291bnQ9MCI+CiAgICAgICAgSW5jcmVtZW50ICh3aGVuIG1vdXNlIGlzIG92ZXIpCiAgICAgIDwvYnV0dG9uPgogICAgICBjb3VudDoge3tjb3VudH19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nTW91c2VlbnRlcgogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24gbW91c2VlbnRlciBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwcmlvcml0eSAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdNb3VzZWVudGVyIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICogbW91c2VlbnRlci4gKHtAbGluayBndWlkZS9leHByZXNzaW9uIy1ldmVudC0gRXZlbnQgb2JqZWN0IGlzIGF2YWlsYWJsZSBhcyBgJGV2ZW50YH0pCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8YnV0dG9uIG5nLW1vdXNlZW50ZXI9ImNvdW50ID0gY291bnQgKyAxIiBuZy1pbml0PSJjb3VudD0wIj4KICAgICAgICBJbmNyZW1lbnQgKHdoZW4gbW91c2UgZW50ZXJzKQogICAgICA8L2J1dHRvbj4KICAgICAgY291bnQ6IHt7Y291bnR9fQogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ01vdXNlbGVhdmUKICoKICogQGRlc2NyaXB0aW9uCiAqIFNwZWNpZnkgY3VzdG9tIGJlaGF2aW9yIG9uIG1vdXNlbGVhdmUgZXZlbnQuCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nTW91c2VsZWF2ZSB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsdWF0ZSB1cG9uCiAqIG1vdXNlbGVhdmUuICh7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiMtZXZlbnQtIEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGB9KQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGJ1dHRvbiBuZy1tb3VzZWxlYXZlPSJjb3VudCA9IGNvdW50ICsgMSIgbmctaW5pdD0iY291bnQ9MCI+CiAgICAgICAgSW5jcmVtZW50ICh3aGVuIG1vdXNlIGxlYXZlcykKICAgICAgPC9idXR0b24+CiAgICAgIGNvdW50OiB7e2NvdW50fX0KICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdNb3VzZW1vdmUKICoKICogQGRlc2NyaXB0aW9uCiAqIFNwZWNpZnkgY3VzdG9tIGJlaGF2aW9yIG9uIG1vdXNlbW92ZSBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwcmlvcml0eSAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdNb3VzZW1vdmUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBtb3VzZW1vdmUuICh7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiMtZXZlbnQtIEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGB9KQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGJ1dHRvbiBuZy1tb3VzZW1vdmU9ImNvdW50ID0gY291bnQgKyAxIiBuZy1pbml0PSJjb3VudD0wIj4KICAgICAgICBJbmNyZW1lbnQgKHdoZW4gbW91c2UgbW92ZXMpCiAgICAgIDwvYnV0dG9uPgogICAgICBjb3VudDoge3tjb3VudH19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nS2V5ZG93bgogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24ga2V5ZG93biBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwcmlvcml0eSAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdLZXlkb3duIHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICoga2V5ZG93bi4gKEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGAgYW5kIGNhbiBiZSBpbnRlcnJvZ2F0ZWQgZm9yIGtleUNvZGUsIGFsdEtleSwgZXRjLikKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxpbnB1dCBuZy1rZXlkb3duPSJjb3VudCA9IGNvdW50ICsgMSIgbmctaW5pdD0iY291bnQ9MCI+CiAgICAgIGtleSBkb3duIGNvdW50OiB7e2NvdW50fX0KICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdLZXl1cAogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24ga2V5dXAgZXZlbnQuCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nS2V5dXAge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBrZXl1cC4gKEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGAgYW5kIGNhbiBiZSBpbnRlcnJvZ2F0ZWQgZm9yIGtleUNvZGUsIGFsdEtleSwgZXRjLikKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8cD5UeXBpbmcgaW4gdGhlIGlucHV0IGJveCBiZWxvdyB1cGRhdGVzIHRoZSBrZXkgY291bnQ8L3A+CiAgICAgICA8aW5wdXQgbmcta2V5dXA9ImNvdW50ID0gY291bnQgKyAxIiBuZy1pbml0PSJjb3VudD0wIj4ga2V5IHVwIGNvdW50OiB7e2NvdW50fX0KCiAgICAgICA8cD5UeXBpbmcgaW4gdGhlIGlucHV0IGJveCBiZWxvdyB1cGRhdGVzIHRoZSBrZXljb2RlPC9wPgogICAgICAgPGlucHV0IG5nLWtleXVwPSJldmVudD0kZXZlbnQiPgogICAgICAgPHA+ZXZlbnQga2V5Q29kZToge3sgZXZlbnQua2V5Q29kZSB9fTwvcD4KICAgICAgIDxwPmV2ZW50IGFsdEtleToge3sgZXZlbnQuYWx0S2V5IH19PC9wPgogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0tleXByZXNzCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBTcGVjaWZ5IGN1c3RvbSBiZWhhdmlvciBvbiBrZXlwcmVzcyBldmVudC4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdLZXlwcmVzcyB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsdWF0ZSB1cG9uCiAqIGtleXByZXNzLiAoe0BsaW5rIGd1aWRlL2V4cHJlc3Npb24jLWV2ZW50LSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgfQogKiBhbmQgY2FuIGJlIGludGVycm9nYXRlZCBmb3Iga2V5Q29kZSwgYWx0S2V5LCBldGMuKQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGlucHV0IG5nLWtleXByZXNzPSJjb3VudCA9IGNvdW50ICsgMSIgbmctaW5pdD0iY291bnQ9MCI+CiAgICAgIGtleSBwcmVzcyBjb3VudDoge3tjb3VudH19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nU3VibWl0CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBFbmFibGVzIGJpbmRpbmcgYW5ndWxhciBleHByZXNzaW9ucyB0byBvbnN1Ym1pdCBldmVudHMuCiAqCiAqIEFkZGl0aW9uYWxseSBpdCBwcmV2ZW50cyB0aGUgZGVmYXVsdCBhY3Rpb24gKHdoaWNoIGZvciBmb3JtIG1lYW5zIHNlbmRpbmcgdGhlIHJlcXVlc3QgdG8gdGhlCiAqIHNlcnZlciBhbmQgcmVsb2FkaW5nIHRoZSBjdXJyZW50IHBhZ2UpLCBidXQgb25seSBpZiB0aGUgZm9ybSBkb2VzIG5vdCBjb250YWluIGBhY3Rpb25gLAogKiBgZGF0YS1hY3Rpb25gLCBvciBgeC1hY3Rpb25gIGF0dHJpYnV0ZXMuCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXdhcm5pbmciPgogKiAqKldhcm5pbmc6KiogQmUgY2FyZWZ1bCBub3QgdG8gY2F1c2UgImRvdWJsZS1zdWJtaXNzaW9uIiBieSB1c2luZyBib3RoIHRoZSBgbmdDbGlja2AgYW5kCiAqIGBuZ1N1Ym1pdGAgaGFuZGxlcnMgdG9nZXRoZXIuIFNlZSB0aGUKICoge0BsaW5rIGZvcm0jc3VibWl0dGluZy1hLWZvcm0tYW5kLXByZXZlbnRpbmctdGhlLWRlZmF1bHQtYWN0aW9uIGBmb3JtYCBkaXJlY3RpdmUgZG9jdW1lbnRhdGlvbn0KICogZm9yIGEgZGV0YWlsZWQgZGlzY3Vzc2lvbiBvZiB3aGVuIGBuZ1N1Ym1pdGAgbWF5IGJlIHRyaWdnZXJlZC4KICogPC9kaXY+CiAqCiAqIEBlbGVtZW50IGZvcm0KICogQHByaW9yaXR5IDAKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ1N1Ym1pdCB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsLgogKiAoe0BsaW5rIGd1aWRlL2V4cHJlc3Npb24jLWV2ZW50LSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgfSkKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGUgbW9kdWxlPSJzdWJtaXRFeGFtcGxlIj4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPHNjcmlwdD4KICAgICAgICBhbmd1bGFyLm1vZHVsZSgnc3VibWl0RXhhbXBsZScsIFtdKQogICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgJHNjb3BlLmxpc3QgPSBbXTsKICAgICAgICAgICAgJHNjb3BlLnRleHQgPSAnaGVsbG8nOwogICAgICAgICAgICAkc2NvcGUuc3VibWl0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgaWYgKCRzY29wZS50ZXh0KSB7CiAgICAgICAgICAgICAgICAkc2NvcGUubGlzdC5wdXNoKHRoaXMudGV4dCk7CiAgICAgICAgICAgICAgICAkc2NvcGUudGV4dCA9ICcnOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICAgIH1dKTsKICAgICAgPC9zY3JpcHQ+CiAgICAgIDxmb3JtIG5nLXN1Ym1pdD0ic3VibWl0KCkiIG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICBFbnRlciB0ZXh0IGFuZCBoaXQgZW50ZXI6CiAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJ0ZXh0IiBuYW1lPSJ0ZXh0IiAvPgogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIGlkPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiIC8+CiAgICAgICAgPHByZT5saXN0PXt7bGlzdH19PC9wcmU+CiAgICAgIDwvZm9ybT4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLXN1Ym1pdCcsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCdsaXN0JykpLmdldFRleHQoKSkudG9CZSgnbGlzdD1bXScpOwogICAgICAgICBlbGVtZW50KGJ5LmNzcygnI3N1Ym1pdCcpKS5jbGljaygpOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCdsaXN0JykpLmdldFRleHQoKSkudG9Db250YWluKCdoZWxsbycpOwogICAgICAgICBleHBlY3QoZWxlbWVudChieS5tb2RlbCgndGV4dCcpKS5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykpLnRvQmUoJycpOwogICAgICAgfSk7CiAgICAgICBpdCgnc2hvdWxkIGlnbm9yZSBlbXB0eSBzdHJpbmdzJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ2xpc3QnKSkuZ2V0VGV4dCgpKS50b0JlKCdsaXN0PVtdJyk7CiAgICAgICAgIGVsZW1lbnQoYnkuY3NzKCcjc3VibWl0JykpLmNsaWNrKCk7CiAgICAgICAgIGVsZW1lbnQoYnkuY3NzKCcjc3VibWl0JykpLmNsaWNrKCk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ2xpc3QnKSkuZ2V0VGV4dCgpKS50b0NvbnRhaW4oJ2hlbGxvJyk7CiAgICAgICAgfSk7CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdGb2N1cwogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24gZm9jdXMgZXZlbnQuCiAqCiAqIE5vdGU6IEFzIHRoZSBgZm9jdXNgIGV2ZW50IGlzIGV4ZWN1dGVkIHN5bmNocm9ub3VzbHkgd2hlbiBjYWxsaW5nIGBpbnB1dC5mb2N1cygpYAogKiBBbmd1bGFySlMgZXhlY3V0ZXMgdGhlIGV4cHJlc3Npb24gdXNpbmcgYHNjb3BlLiRldmFsQXN5bmNgIGlmIHRoZSBldmVudCBpcyBmaXJlZAogKiBkdXJpbmcgYW4gYCRhcHBseWAgdG8gZW5zdXJlIGEgY29uc2lzdGVudCBzdGF0ZS4KICoKICogQGVsZW1lbnQgd2luZG93LCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgYQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nRm9jdXMge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBmb2N1cy4gKHtAbGluayBndWlkZS9leHByZXNzaW9uIy1ldmVudC0gRXZlbnQgb2JqZWN0IGlzIGF2YWlsYWJsZSBhcyBgJGV2ZW50YH0pCiAqCiAqIEBleGFtcGxlCiAqIFNlZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQ2xpY2sgbmdDbGlja30KICovCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0JsdXIKICoKICogQGRlc2NyaXB0aW9uCiAqIFNwZWNpZnkgY3VzdG9tIGJlaGF2aW9yIG9uIGJsdXIgZXZlbnQuCiAqCiAqIEEgW2JsdXIgZXZlbnRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0V2ZW50cy9ibHVyKSBmaXJlcyB3aGVuCiAqIGFuIGVsZW1lbnQgaGFzIGxvc3QgZm9jdXMuCiAqCiAqIE5vdGU6IEFzIHRoZSBgYmx1cmAgZXZlbnQgaXMgZXhlY3V0ZWQgc3luY2hyb25vdXNseSBhbHNvIGR1cmluZyBET00gbWFuaXB1bGF0aW9ucwogKiAoZS5nLiByZW1vdmluZyBhIGZvY3Vzc2VkIGlucHV0KSwKICogQW5ndWxhckpTIGV4ZWN1dGVzIHRoZSBleHByZXNzaW9uIHVzaW5nIGBzY29wZS4kZXZhbEFzeW5jYCBpZiB0aGUgZXZlbnQgaXMgZmlyZWQKICogZHVyaW5nIGFuIGAkYXBwbHlgIHRvIGVuc3VyZSBhIGNvbnNpc3RlbnQgc3RhdGUuCiAqCiAqIEBlbGVtZW50IHdpbmRvdywgaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEsIGEKICogQHByaW9yaXR5IDAKICogQHBhcmFtIHtleHByZXNzaW9ufSBuZ0JsdXIge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBibHVyLiAoe0BsaW5rIGd1aWRlL2V4cHJlc3Npb24jLWV2ZW50LSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgfSkKICoKICogQGV4YW1wbGUKICogU2VlIHtAbGluayBuZy5kaXJlY3RpdmU6bmdDbGljayBuZ0NsaWNrfQogKi8KCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nQ29weQogKgogKiBAZGVzY3JpcHRpb24KICogU3BlY2lmeSBjdXN0b20gYmVoYXZpb3Igb24gY29weSBldmVudC4KICoKICogQGVsZW1lbnQgd2luZG93LCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgYQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQ29weSB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB0byBldmFsdWF0ZSB1cG9uCiAqIGNvcHkuICh7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiMtZXZlbnQtIEV2ZW50IG9iamVjdCBpcyBhdmFpbGFibGUgYXMgYCRldmVudGB9KQogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGlucHV0IG5nLWNvcHk9ImNvcGllZD10cnVlIiBuZy1pbml0PSJjb3BpZWQ9ZmFsc2U7IHZhbHVlPSdjb3B5IG1lJyIgbmctbW9kZWw9InZhbHVlIj4KICAgICAgY29waWVkOiB7e2NvcGllZH19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdDdXQKICoKICogQGRlc2NyaXB0aW9uCiAqIFNwZWNpZnkgY3VzdG9tIGJlaGF2aW9yIG9uIGN1dCBldmVudC4KICoKICogQGVsZW1lbnQgd2luZG93LCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgYQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nQ3V0IHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWx1YXRlIHVwb24KICogY3V0LiAoe0BsaW5rIGd1aWRlL2V4cHJlc3Npb24jLWV2ZW50LSBFdmVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGFzIGAkZXZlbnRgfSkKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGU+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxpbnB1dCBuZy1jdXQ9ImN1dD10cnVlIiBuZy1pbml0PSJjdXQ9ZmFsc2U7IHZhbHVlPSdjdXQgbWUnIiBuZy1tb2RlbD0idmFsdWUiPgogICAgICBjdXQ6IHt7Y3V0fX0KICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ1Bhc3RlCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBTcGVjaWZ5IGN1c3RvbSBiZWhhdmlvciBvbiBwYXN0ZSBldmVudC4KICoKICogQGVsZW1lbnQgd2luZG93LCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgYQogKiBAcHJpb3JpdHkgMAogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nUGFzdGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gRXhwcmVzc2lvbn0gdG8gZXZhbHVhdGUgdXBvbgogKiBwYXN0ZS4gKHtAbGluayBndWlkZS9leHByZXNzaW9uIy1ldmVudC0gRXZlbnQgb2JqZWN0IGlzIGF2YWlsYWJsZSBhcyBgJGV2ZW50YH0pCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICA8aW5wdXQgbmctcGFzdGU9InBhc3RlPXRydWUiIG5nLWluaXQ9InBhc3RlPWZhbHNlIiBwbGFjZWhvbGRlcj0ncGFzdGUgaGVyZSc+CiAgICAgIHBhc3RlZDoge3twYXN0ZX19CiAgICAgPC9maWxlPgogICA8L2V4YW1wbGU+CiAqLwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdJZgogKiBAcmVzdHJpY3QgQQogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0lmYCBkaXJlY3RpdmUgcmVtb3ZlcyBvciByZWNyZWF0ZXMgYSBwb3J0aW9uIG9mIHRoZSBET00gdHJlZSBiYXNlZCBvbiBhbgogKiB7ZXhwcmVzc2lvbn0uIElmIHRoZSBleHByZXNzaW9uIGFzc2lnbmVkIHRvIGBuZ0lmYCBldmFsdWF0ZXMgdG8gYSBmYWxzZQogKiB2YWx1ZSB0aGVuIHRoZSBlbGVtZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLCBvdGhlcndpc2UgYSBjbG9uZSBvZiB0aGUKICogZWxlbWVudCBpcyByZWluc2VydGVkIGludG8gdGhlIERPTS4KICoKICogYG5nSWZgIGRpZmZlcnMgZnJvbSBgbmdTaG93YCBhbmQgYG5nSGlkZWAgaW4gdGhhdCBgbmdJZmAgY29tcGxldGVseSByZW1vdmVzIGFuZCByZWNyZWF0ZXMgdGhlCiAqIGVsZW1lbnQgaW4gdGhlIERPTSByYXRoZXIgdGhhbiBjaGFuZ2luZyBpdHMgdmlzaWJpbGl0eSB2aWEgdGhlIGBkaXNwbGF5YCBjc3MgcHJvcGVydHkuICBBIGNvbW1vbgogKiBjYXNlIHdoZW4gdGhpcyBkaWZmZXJlbmNlIGlzIHNpZ25pZmljYW50IGlzIHdoZW4gdXNpbmcgY3NzIHNlbGVjdG9ycyB0aGF0IHJlbHkgb24gYW4gZWxlbWVudCdzCiAqIHBvc2l0aW9uIHdpdGhpbiB0aGUgRE9NLCBzdWNoIGFzIHRoZSBgOmZpcnN0LWNoaWxkYCBvciBgOmxhc3QtY2hpbGRgIHBzZXVkby1jbGFzc2VzLgogKgogKiBOb3RlIHRoYXQgd2hlbiBhbiBlbGVtZW50IGlzIHJlbW92ZWQgdXNpbmcgYG5nSWZgIGl0cyBzY29wZSBpcyBkZXN0cm95ZWQgYW5kIGEgbmV3IHNjb3BlCiAqIGlzIGNyZWF0ZWQgd2hlbiB0aGUgZWxlbWVudCBpcyByZXN0b3JlZC4gIFRoZSBzY29wZSBjcmVhdGVkIHdpdGhpbiBgbmdJZmAgaW5oZXJpdHMgZnJvbQogKiBpdHMgcGFyZW50IHNjb3BlIHVzaW5nCiAqIFtwcm90b3R5cGFsIGluaGVyaXRhbmNlXShodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyLmpzL3dpa2kvVW5kZXJzdGFuZGluZy1TY29wZXMjamF2YXNjcmlwdC1wcm90b3R5cGFsLWluaGVyaXRhbmNlKS4KICogQW4gaW1wb3J0YW50IGltcGxpY2F0aW9uIG9mIHRoaXMgaXMgaWYgYG5nTW9kZWxgIGlzIHVzZWQgd2l0aGluIGBuZ0lmYCB0byBiaW5kIHRvCiAqIGEgamF2YXNjcmlwdCBwcmltaXRpdmUgZGVmaW5lZCBpbiB0aGUgcGFyZW50IHNjb3BlLiBJbiB0aGlzIGNhc2UgYW55IG1vZGlmaWNhdGlvbnMgbWFkZSB0byB0aGUKICogdmFyaWFibGUgd2l0aGluIHRoZSBjaGlsZCBzY29wZSB3aWxsIG92ZXJyaWRlIChoaWRlKSB0aGUgdmFsdWUgaW4gdGhlIHBhcmVudCBzY29wZS4KICoKICogQWxzbywgYG5nSWZgIHJlY3JlYXRlcyBlbGVtZW50cyB1c2luZyB0aGVpciBjb21waWxlZCBzdGF0ZS4gQW4gZXhhbXBsZSBvZiB0aGlzIGJlaGF2aW9yCiAqIGlzIGlmIGFuIGVsZW1lbnQncyBjbGFzcyBhdHRyaWJ1dGUgaXMgZGlyZWN0bHkgbW9kaWZpZWQgYWZ0ZXIgaXQncyBjb21waWxlZCwgdXNpbmcgc29tZXRoaW5nIGxpa2UKICogalF1ZXJ5J3MgYC5hZGRDbGFzcygpYCBtZXRob2QsIGFuZCB0aGUgZWxlbWVudCBpcyBsYXRlciByZW1vdmVkLiBXaGVuIGBuZ0lmYCByZWNyZWF0ZXMgdGhlIGVsZW1lbnQKICogdGhlIGFkZGVkIGNsYXNzIHdpbGwgYmUgbG9zdCBiZWNhdXNlIHRoZSBvcmlnaW5hbCBjb21waWxlZCBzdGF0ZSBpcyB1c2VkIHRvIHJlZ2VuZXJhdGUgdGhlIGVsZW1lbnQuCiAqCiAqIEFkZGl0aW9uYWxseSwgeW91IGNhbiBwcm92aWRlIGFuaW1hdGlvbnMgdmlhIHRoZSBgbmdBbmltYXRlYCBtb2R1bGUgdG8gYW5pbWF0ZSB0aGUgYGVudGVyYAogKiBhbmQgYGxlYXZlYCBlZmZlY3RzLgogKgogKiBAYW5pbWF0aW9ucwogKiBlbnRlciAtIGhhcHBlbnMganVzdCBhZnRlciB0aGUgYG5nSWZgIGNvbnRlbnRzIGNoYW5nZSBhbmQgYSBuZXcgRE9NIGVsZW1lbnQgaXMgY3JlYXRlZCBhbmQgaW5qZWN0ZWQgaW50byB0aGUgYG5nSWZgIGNvbnRhaW5lcgogKiBsZWF2ZSAtIGhhcHBlbnMganVzdCBiZWZvcmUgdGhlIGBuZ0lmYCBjb250ZW50cyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBET00KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBzY29wZQogKiBAcHJpb3JpdHkgNjAwCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdJZiBJZiB0aGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgZmFsc3kgdGhlbgogKiAgICAgdGhlIGVsZW1lbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBET00gdHJlZS4gSWYgaXQgaXMgdHJ1dGh5IGEgY29weSBvZiB0aGUgY29tcGlsZWQKICogICAgIGVsZW1lbnQgaXMgYWRkZWQgdG8gdGhlIERPTSB0cmVlLgogKgogKiBAZXhhbXBsZQogIDxleGFtcGxlIG1vZHVsZT0ibmdBbmltYXRlIiBkZXBzPSJhbmd1bGFyLWFuaW1hdGUuanMiIGFuaW1hdGlvbnM9InRydWUiPgogICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIENsaWNrIG1lOiA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5nLW1vZGVsPSJjaGVja2VkIiBuZy1pbml0PSJjaGVja2VkPXRydWUiIC8+PGJyLz4KICAgICAgU2hvdyB3aGVuIGNoZWNrZWQ6CiAgICAgIDxzcGFuIG5nLWlmPSJjaGVja2VkIiBjbGFzcz0iYW5pbWF0ZS1pZiI+CiAgICAgICAgVGhpcyBpcyByZW1vdmVkIHdoZW4gdGhlIGNoZWNrYm94IGlzIHVuY2hlY2tlZC4KICAgICAgPC9zcGFuPgogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0iYW5pbWF0aW9ucy5jc3MiPgogICAgICAuYW5pbWF0ZS1pZiB7CiAgICAgICAgYmFja2dyb3VuZDp3aGl0ZTsKICAgICAgICBib3JkZXI6MXB4IHNvbGlkIGJsYWNrOwogICAgICAgIHBhZGRpbmc6MTBweDsKICAgICAgfQoKICAgICAgLmFuaW1hdGUtaWYubmctZW50ZXIsIC5hbmltYXRlLWlmLm5nLWxlYXZlIHsKICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246YWxsIGN1YmljLWJlemllcigwLjI1MCwgMC40NjAsIDAuNDUwLCAwLjk0MCkgMC41czsKICAgICAgICB0cmFuc2l0aW9uOmFsbCBjdWJpYy1iZXppZXIoMC4yNTAsIDAuNDYwLCAwLjQ1MCwgMC45NDApIDAuNXM7CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLWlmLm5nLWVudGVyLAogICAgICAuYW5pbWF0ZS1pZi5uZy1sZWF2ZS5uZy1sZWF2ZS1hY3RpdmUgewogICAgICAgIG9wYWNpdHk6MDsKICAgICAgfQoKICAgICAgLmFuaW1hdGUtaWYubmctbGVhdmUsCiAgICAgIC5hbmltYXRlLWlmLm5nLWVudGVyLm5nLWVudGVyLWFjdGl2ZSB7CiAgICAgICAgb3BhY2l0eToxOwogICAgICB9CiAgICA8L2ZpbGU+CiAgPC9leGFtcGxlPgogKi8KdmFyIG5nSWZEaXJlY3RpdmUgPSBbJyRhbmltYXRlJywgZnVuY3Rpb24oJGFuaW1hdGUpIHsKICByZXR1cm4gewogICAgbXVsdGlFbGVtZW50OiB0cnVlLAogICAgdHJhbnNjbHVkZTogJ2VsZW1lbnQnLAogICAgcHJpb3JpdHk6IDYwMCwKICAgIHRlcm1pbmFsOiB0cnVlLAogICAgcmVzdHJpY3Q6ICdBJywKICAgICQkdGxiOiB0cnVlLAogICAgbGluazogZnVuY3Rpb24oJHNjb3BlLCAkZWxlbWVudCwgJGF0dHIsIGN0cmwsICR0cmFuc2NsdWRlKSB7CiAgICAgICAgdmFyIGJsb2NrLCBjaGlsZFNjb3BlLCBwcmV2aW91c0VsZW1lbnRzOwogICAgICAgICRzY29wZS4kd2F0Y2goJGF0dHIubmdJZiwgZnVuY3Rpb24gbmdJZldhdGNoQWN0aW9uKHZhbHVlKSB7CgogICAgICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghY2hpbGRTY29wZSkgewogICAgICAgICAgICAgICR0cmFuc2NsdWRlKGZ1bmN0aW9uKGNsb25lLCBuZXdTY29wZSkgewogICAgICAgICAgICAgICAgY2hpbGRTY29wZSA9IG5ld1Njb3BlOwogICAgICAgICAgICAgICAgY2xvbmVbY2xvbmUubGVuZ3RoKytdID0gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgnIGVuZCBuZ0lmOiAnICsgJGF0dHIubmdJZiArICcgJyk7CiAgICAgICAgICAgICAgICAvLyBOb3RlOiBXZSBvbmx5IG5lZWQgdGhlIGZpcnN0L2xhc3Qgbm9kZSBvZiB0aGUgY2xvbmVkIG5vZGVzLgogICAgICAgICAgICAgICAgLy8gSG93ZXZlciwgd2UgbmVlZCB0byBrZWVwIHRoZSByZWZlcmVuY2UgdG8gdGhlIGpxbGl0ZSB3cmFwcGVyIGFzIGl0IG1pZ2h0IGJlIGNoYW5nZWQgbGF0ZXIKICAgICAgICAgICAgICAgIC8vIGJ5IGEgZGlyZWN0aXZlIHdpdGggdGVtcGxhdGVVcmwgd2hlbiBpdHMgdGVtcGxhdGUgYXJyaXZlcy4KICAgICAgICAgICAgICAgIGJsb2NrID0gewogICAgICAgICAgICAgICAgICBjbG9uZTogY2xvbmUKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAkYW5pbWF0ZS5lbnRlcihjbG9uZSwgJGVsZW1lbnQucGFyZW50KCksICRlbGVtZW50KTsKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHByZXZpb3VzRWxlbWVudHMpIHsKICAgICAgICAgICAgICBwcmV2aW91c0VsZW1lbnRzLnJlbW92ZSgpOwogICAgICAgICAgICAgIHByZXZpb3VzRWxlbWVudHMgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjaGlsZFNjb3BlKSB7CiAgICAgICAgICAgICAgY2hpbGRTY29wZS4kZGVzdHJveSgpOwogICAgICAgICAgICAgIGNoaWxkU2NvcGUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChibG9jaykgewogICAgICAgICAgICAgIHByZXZpb3VzRWxlbWVudHMgPSBnZXRCbG9ja05vZGVzKGJsb2NrLmNsb25lKTsKICAgICAgICAgICAgICAkYW5pbWF0ZS5sZWF2ZShwcmV2aW91c0VsZW1lbnRzKS50aGVuKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50cyA9IG51bGw7CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgYmxvY2sgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CiAgfTsKfV07CgovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ0luY2x1ZGUKICogQHJlc3RyaWN0IEVDQQogKgogKiBAZGVzY3JpcHRpb24KICogRmV0Y2hlcywgY29tcGlsZXMgYW5kIGluY2x1ZGVzIGFuIGV4dGVybmFsIEhUTUwgZnJhZ21lbnQuCiAqCiAqIEJ5IGRlZmF1bHQsIHRoZSB0ZW1wbGF0ZSBVUkwgaXMgcmVzdHJpY3RlZCB0byB0aGUgc2FtZSBkb21haW4gYW5kIHByb3RvY29sIGFzIHRoZQogKiBhcHBsaWNhdGlvbiBkb2N1bWVudC4gVGhpcyBpcyBkb25lIGJ5IGNhbGxpbmcge0BsaW5rICRzY2UjZ2V0VHJ1c3RlZFJlc291cmNlVXJsCiAqICRzY2UuZ2V0VHJ1c3RlZFJlc291cmNlVXJsfSBvbiBpdC4gVG8gbG9hZCB0ZW1wbGF0ZXMgZnJvbSBvdGhlciBkb21haW5zIG9yIHByb3RvY29scwogKiB5b3UgbWF5IGVpdGhlciB7QGxpbmsgbmcuJHNjZURlbGVnYXRlUHJvdmlkZXIjcmVzb3VyY2VVcmxXaGl0ZWxpc3Qgd2hpdGVsaXN0IHRoZW19IG9yCiAqIHtAbGluayAkc2NlI3RydXN0QXNSZXNvdXJjZVVybCB3cmFwIHRoZW19IGFzIHRydXN0ZWQgdmFsdWVzLiBSZWZlciB0byBBbmd1bGFyJ3Mge0BsaW5rCiAqIG5nLiRzY2UgU3RyaWN0IENvbnRleHR1YWwgRXNjYXBpbmd9LgogKgogKiBJbiBhZGRpdGlvbiwgdGhlIGJyb3dzZXIncwogKiBbU2FtZSBPcmlnaW4gUG9saWN5XShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Jyb3dzZXJzZWMvd2lraS9QYXJ0MiNTYW1lLW9yaWdpbl9wb2xpY3lfZm9yX1hNTEh0dHBSZXF1ZXN0KQogKiBhbmQgW0Nyb3NzLU9yaWdpbiBSZXNvdXJjZSBTaGFyaW5nIChDT1JTKV0oaHR0cDovL3d3dy53My5vcmcvVFIvY29ycy8pCiAqIHBvbGljeSBtYXkgZnVydGhlciByZXN0cmljdCB3aGV0aGVyIHRoZSB0ZW1wbGF0ZSBpcyBzdWNjZXNzZnVsbHkgbG9hZGVkLgogKiBGb3IgZXhhbXBsZSwgYG5nSW5jbHVkZWAgd29uJ3Qgd29yayBmb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzIG9uIGFsbCBicm93c2VycyBhbmQgZm9yIGBmaWxlOi8vYAogKiBhY2Nlc3Mgb24gc29tZSBicm93c2Vycy4KICoKICogQGFuaW1hdGlvbnMKICogZW50ZXIgLSBhbmltYXRpb24gaXMgdXNlZCB0byBicmluZyBuZXcgY29udGVudCBpbnRvIHRoZSBicm93c2VyLgogKiBsZWF2ZSAtIGFuaW1hdGlvbiBpcyB1c2VkIHRvIGFuaW1hdGUgZXhpc3RpbmcgY29udGVudCBhd2F5LgogKgogKiBUaGUgZW50ZXIgYW5kIGxlYXZlIGFuaW1hdGlvbiBvY2N1ciBjb25jdXJyZW50bHkuCiAqCiAqIEBzY29wZQogKiBAcHJpb3JpdHkgNDAwCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuZ0luY2x1ZGV8c3JjIGFuZ3VsYXIgZXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIFVSTC4gSWYgdGhlIHNvdXJjZSBpcyBhIHN0cmluZyBjb25zdGFudCwKICogICAgICAgICAgICAgICAgIG1ha2Ugc3VyZSB5b3Ugd3JhcCBpdCBpbiAqKnNpbmdsZSoqIHF1b3RlcywgZS5nLiBgc3JjPSInbXlQYXJ0aWFsVGVtcGxhdGUuaHRtbCciYC4KICogQHBhcmFtIHtzdHJpbmc9fSBvbmxvYWQgRXhwcmVzc2lvbiB0byBldmFsdWF0ZSB3aGVuIGEgbmV3IHBhcnRpYWwgaXMgbG9hZGVkLgogKgogKiBAcGFyYW0ge3N0cmluZz19IGF1dG9zY3JvbGwgV2hldGhlciBgbmdJbmNsdWRlYCBzaG91bGQgY2FsbCB7QGxpbmsgbmcuJGFuY2hvclNjcm9sbAogKiAgICAgICAgICAgICAgICAgICRhbmNob3JTY3JvbGx9IHRvIHNjcm9sbCB0aGUgdmlld3BvcnQgYWZ0ZXIgdGhlIGNvbnRlbnQgaXMgbG9hZGVkLgogKgogKiAgICAgICAgICAgICAgICAgIC0gSWYgdGhlIGF0dHJpYnV0ZSBpcyBub3Qgc2V0LCBkaXNhYmxlIHNjcm9sbGluZy4KICogICAgICAgICAgICAgICAgICAtIElmIHRoZSBhdHRyaWJ1dGUgaXMgc2V0IHdpdGhvdXQgdmFsdWUsIGVuYWJsZSBzY3JvbGxpbmcuCiAqICAgICAgICAgICAgICAgICAgLSBPdGhlcndpc2UgZW5hYmxlIHNjcm9sbGluZyBvbmx5IGlmIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnV0aHkgdmFsdWUuCiAqCiAqIEBleGFtcGxlCiAgPGV4YW1wbGUgbW9kdWxlPSJpbmNsdWRlRXhhbXBsZSIgZGVwcz0iYW5ndWxhci1hbmltYXRlLmpzIiBhbmltYXRpb25zPSJ0cnVlIj4KICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgPHNlbGVjdCBuZy1tb2RlbD0idGVtcGxhdGUiIG5nLW9wdGlvbnM9InQubmFtZSBmb3IgdCBpbiB0ZW1wbGF0ZXMiPgogICAgICAgIDxvcHRpb24gdmFsdWU9IiI+KGJsYW5rKTwvb3B0aW9uPgogICAgICAgPC9zZWxlY3Q+CiAgICAgICB1cmwgb2YgdGhlIHRlbXBsYXRlOiA8dHQ+e3t0ZW1wbGF0ZS51cmx9fTwvdHQ+CiAgICAgICA8aHIvPgogICAgICAgPGRpdiBjbGFzcz0ic2xpZGUtYW5pbWF0ZS1jb250YWluZXIiPgogICAgICAgICA8ZGl2IGNsYXNzPSJzbGlkZS1hbmltYXRlIiBuZy1pbmNsdWRlPSJ0ZW1wbGF0ZS51cmwiPjwvZGl2PgogICAgICAgPC9kaXY+CiAgICAgPC9kaXY+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICBhbmd1bGFyLm1vZHVsZSgnaW5jbHVkZUV4YW1wbGUnLCBbJ25nQW5pbWF0ZSddKQogICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAkc2NvcGUudGVtcGxhdGVzID0KICAgICAgICAgICAgWyB7IG5hbWU6ICd0ZW1wbGF0ZTEuaHRtbCcsIHVybDogJ3RlbXBsYXRlMS5odG1sJ30sCiAgICAgICAgICAgICAgeyBuYW1lOiAndGVtcGxhdGUyLmh0bWwnLCB1cmw6ICd0ZW1wbGF0ZTIuaHRtbCd9IF07CiAgICAgICAgICAkc2NvcGUudGVtcGxhdGUgPSAkc2NvcGUudGVtcGxhdGVzWzBdOwogICAgICAgIH1dKTsKICAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJ0ZW1wbGF0ZTEuaHRtbCI+CiAgICAgIENvbnRlbnQgb2YgdGVtcGxhdGUxLmh0bWwKICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9InRlbXBsYXRlMi5odG1sIj4KICAgICAgQ29udGVudCBvZiB0ZW1wbGF0ZTIuaHRtbAogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0iYW5pbWF0aW9ucy5jc3MiPgogICAgICAuc2xpZGUtYW5pbWF0ZS1jb250YWluZXIgewogICAgICAgIHBvc2l0aW9uOnJlbGF0aXZlOwogICAgICAgIGJhY2tncm91bmQ6d2hpdGU7CiAgICAgICAgYm9yZGVyOjFweCBzb2xpZCBibGFjazsKICAgICAgICBoZWlnaHQ6NDBweDsKICAgICAgICBvdmVyZmxvdzpoaWRkZW47CiAgICAgIH0KCiAgICAgIC5zbGlkZS1hbmltYXRlIHsKICAgICAgICBwYWRkaW5nOjEwcHg7CiAgICAgIH0KCiAgICAgIC5zbGlkZS1hbmltYXRlLm5nLWVudGVyLCAuc2xpZGUtYW5pbWF0ZS5uZy1sZWF2ZSB7CiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOmFsbCBjdWJpYy1iZXppZXIoMC4yNTAsIDAuNDYwLCAwLjQ1MCwgMC45NDApIDAuNXM7CiAgICAgICAgdHJhbnNpdGlvbjphbGwgY3ViaWMtYmV6aWVyKDAuMjUwLCAwLjQ2MCwgMC40NTAsIDAuOTQwKSAwLjVzOwoKICAgICAgICBwb3NpdGlvbjphYnNvbHV0ZTsKICAgICAgICB0b3A6MDsKICAgICAgICBsZWZ0OjA7CiAgICAgICAgcmlnaHQ6MDsKICAgICAgICBib3R0b206MDsKICAgICAgICBkaXNwbGF5OmJsb2NrOwogICAgICAgIHBhZGRpbmc6MTBweDsKICAgICAgfQoKICAgICAgLnNsaWRlLWFuaW1hdGUubmctZW50ZXIgewogICAgICAgIHRvcDotNTBweDsKICAgICAgfQogICAgICAuc2xpZGUtYW5pbWF0ZS5uZy1lbnRlci5uZy1lbnRlci1hY3RpdmUgewogICAgICAgIHRvcDowOwogICAgICB9CgogICAgICAuc2xpZGUtYW5pbWF0ZS5uZy1sZWF2ZSB7CiAgICAgICAgdG9wOjA7CiAgICAgIH0KICAgICAgLnNsaWRlLWFuaW1hdGUubmctbGVhdmUubmctbGVhdmUtYWN0aXZlIHsKICAgICAgICB0b3A6NTBweDsKICAgICAgfQogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgIHZhciB0ZW1wbGF0ZVNlbGVjdCA9IGVsZW1lbnQoYnkubW9kZWwoJ3RlbXBsYXRlJykpOwogICAgICB2YXIgaW5jbHVkZUVsZW0gPSBlbGVtZW50KGJ5LmNzcygnW25nLWluY2x1ZGVdJykpOwoKICAgICAgaXQoJ3Nob3VsZCBsb2FkIHRlbXBsYXRlMS5odG1sJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZXhwZWN0KGluY2x1ZGVFbGVtLmdldFRleHQoKSkudG9NYXRjaCgvQ29udGVudCBvZiB0ZW1wbGF0ZTEuaHRtbC8pOwogICAgICB9KTsKCiAgICAgIGl0KCdzaG91bGQgbG9hZCB0ZW1wbGF0ZTIuaHRtbCcsIGZ1bmN0aW9uKCkgewogICAgICAgIGlmIChicm93c2VyLnBhcmFtcy5icm93c2VyID09ICdmaXJlZm94JykgewogICAgICAgICAgLy8gRmlyZWZveCBjYW4ndCBoYW5kbGUgdXNpbmcgc2VsZWN0cwogICAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL3Byb3RyYWN0b3IvaXNzdWVzLzQ4MAogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZVNlbGVjdC5jbGljaygpOwogICAgICAgIHRlbXBsYXRlU2VsZWN0LmFsbChieS5jc3MoJ29wdGlvbicpKS5nZXQoMikuY2xpY2soKTsKICAgICAgICBleHBlY3QoaW5jbHVkZUVsZW0uZ2V0VGV4dCgpKS50b01hdGNoKC9Db250ZW50IG9mIHRlbXBsYXRlMi5odG1sLyk7CiAgICAgIH0pOwoKICAgICAgaXQoJ3Nob3VsZCBjaGFuZ2UgdG8gYmxhbmsnLCBmdW5jdGlvbigpIHsKICAgICAgICBpZiAoYnJvd3Nlci5wYXJhbXMuYnJvd3NlciA9PSAnZmlyZWZveCcpIHsKICAgICAgICAgIC8vIEZpcmVmb3ggY2FuJ3QgaGFuZGxlIHVzaW5nIHNlbGVjdHMKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVTZWxlY3QuY2xpY2soKTsKICAgICAgICB0ZW1wbGF0ZVNlbGVjdC5hbGwoYnkuY3NzKCdvcHRpb24nKSkuZ2V0KDApLmNsaWNrKCk7CiAgICAgICAgZXhwZWN0KGluY2x1ZGVFbGVtLmlzUHJlc2VudCgpKS50b0JlKGZhbHNlKTsKICAgICAgfSk7CiAgICA8L2ZpbGU+CiAgPC9leGFtcGxlPgogKi8KCgovKioKICogQG5nZG9jIGV2ZW50CiAqIEBuYW1lIG5nSW5jbHVkZSMkaW5jbHVkZUNvbnRlbnRSZXF1ZXN0ZWQKICogQGV2ZW50VHlwZSBlbWl0IG9uIHRoZSBzY29wZSBuZ0luY2x1ZGUgd2FzIGRlY2xhcmVkIGluCiAqIEBkZXNjcmlwdGlvbgogKiBFbWl0dGVkIGV2ZXJ5IHRpbWUgdGhlIG5nSW5jbHVkZSBjb250ZW50IGlzIHJlcXVlc3RlZC4KICoKICogQHBhcmFtIHtPYmplY3R9IGFuZ3VsYXJFdmVudCBTeW50aGV0aWMgZXZlbnQgb2JqZWN0LgogKiBAcGFyYW0ge1N0cmluZ30gc3JjIFVSTCBvZiBjb250ZW50IHRvIGxvYWQuCiAqLwoKCi8qKgogKiBAbmdkb2MgZXZlbnQKICogQG5hbWUgbmdJbmNsdWRlIyRpbmNsdWRlQ29udGVudExvYWRlZAogKiBAZXZlbnRUeXBlIGVtaXQgb24gdGhlIGN1cnJlbnQgbmdJbmNsdWRlIHNjb3BlCiAqIEBkZXNjcmlwdGlvbgogKiBFbWl0dGVkIGV2ZXJ5IHRpbWUgdGhlIG5nSW5jbHVkZSBjb250ZW50IGlzIHJlbG9hZGVkLgogKgogKiBAcGFyYW0ge09iamVjdH0gYW5ndWxhckV2ZW50IFN5bnRoZXRpYyBldmVudCBvYmplY3QuCiAqIEBwYXJhbSB7U3RyaW5nfSBzcmMgVVJMIG9mIGNvbnRlbnQgdG8gbG9hZC4KICovCgoKLyoqCiAqIEBuZ2RvYyBldmVudAogKiBAbmFtZSBuZ0luY2x1ZGUjJGluY2x1ZGVDb250ZW50RXJyb3IKICogQGV2ZW50VHlwZSBlbWl0IG9uIHRoZSBzY29wZSBuZ0luY2x1ZGUgd2FzIGRlY2xhcmVkIGluCiAqIEBkZXNjcmlwdGlvbgogKiBFbWl0dGVkIHdoZW4gYSB0ZW1wbGF0ZSBIVFRQIHJlcXVlc3QgeWllbGRzIGFuIGVycm9ub3VzIHJlc3BvbnNlIChzdGF0dXMgPCAyMDAgfHwgc3RhdHVzID4gMjk5KQogKgogKiBAcGFyYW0ge09iamVjdH0gYW5ndWxhckV2ZW50IFN5bnRoZXRpYyBldmVudCBvYmplY3QuCiAqIEBwYXJhbSB7U3RyaW5nfSBzcmMgVVJMIG9mIGNvbnRlbnQgdG8gbG9hZC4KICovCnZhciBuZ0luY2x1ZGVEaXJlY3RpdmUgPSBbJyR0ZW1wbGF0ZVJlcXVlc3QnLCAnJGFuY2hvclNjcm9sbCcsICckYW5pbWF0ZScsICckc2NlJywKICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oJHRlbXBsYXRlUmVxdWVzdCwgICAkYW5jaG9yU2Nyb2xsLCAgICRhbmltYXRlLCAgICRzY2UpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdFQ0EnLAogICAgcHJpb3JpdHk6IDQwMCwKICAgIHRlcm1pbmFsOiB0cnVlLAogICAgdHJhbnNjbHVkZTogJ2VsZW1lbnQnLAogICAgY29udHJvbGxlcjogYW5ndWxhci5ub29wLAogICAgY29tcGlsZTogZnVuY3Rpb24oZWxlbWVudCwgYXR0cikgewogICAgICB2YXIgc3JjRXhwID0gYXR0ci5uZ0luY2x1ZGUgfHwgYXR0ci5zcmMsCiAgICAgICAgICBvbmxvYWRFeHAgPSBhdHRyLm9ubG9hZCB8fCAnJywKICAgICAgICAgIGF1dG9TY3JvbGxFeHAgPSBhdHRyLmF1dG9zY3JvbGw7CgogICAgICByZXR1cm4gZnVuY3Rpb24oc2NvcGUsICRlbGVtZW50LCAkYXR0ciwgY3RybCwgJHRyYW5zY2x1ZGUpIHsKICAgICAgICB2YXIgY2hhbmdlQ291bnRlciA9IDAsCiAgICAgICAgICAgIGN1cnJlbnRTY29wZSwKICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50LAogICAgICAgICAgICBjdXJyZW50RWxlbWVudDsKCiAgICAgICAgdmFyIGNsZWFudXBMYXN0SW5jbHVkZUNvbnRlbnQgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIGlmIChwcmV2aW91c0VsZW1lbnQpIHsKICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50LnJlbW92ZSgpOwogICAgICAgICAgICBwcmV2aW91c0VsZW1lbnQgPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGN1cnJlbnRTY29wZSkgewogICAgICAgICAgICBjdXJyZW50U2NvcGUuJGRlc3Ryb3koKTsKICAgICAgICAgICAgY3VycmVudFNjb3BlID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChjdXJyZW50RWxlbWVudCkgewogICAgICAgICAgICAkYW5pbWF0ZS5sZWF2ZShjdXJyZW50RWxlbWVudCkudGhlbihmdW5jdGlvbigpIHsKICAgICAgICAgICAgICBwcmV2aW91c0VsZW1lbnQgPSBudWxsOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50ID0gY3VycmVudEVsZW1lbnQ7CiAgICAgICAgICAgIGN1cnJlbnRFbGVtZW50ID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBzY29wZS4kd2F0Y2goJHNjZS5wYXJzZUFzUmVzb3VyY2VVcmwoc3JjRXhwKSwgZnVuY3Rpb24gbmdJbmNsdWRlV2F0Y2hBY3Rpb24oc3JjKSB7CiAgICAgICAgICB2YXIgYWZ0ZXJBbmltYXRpb24gPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChhdXRvU2Nyb2xsRXhwKSAmJiAoIWF1dG9TY3JvbGxFeHAgfHwgc2NvcGUuJGV2YWwoYXV0b1Njcm9sbEV4cCkpKSB7CiAgICAgICAgICAgICAgJGFuY2hvclNjcm9sbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgICAgdmFyIHRoaXNDaGFuZ2VJZCA9ICsrY2hhbmdlQ291bnRlcjsKCiAgICAgICAgICBpZiAoc3JjKSB7CiAgICAgICAgICAgIC8vc2V0IHRoZSAybmQgcGFyYW0gdG8gdHJ1ZSB0byBpZ25vcmUgdGhlIHRlbXBsYXRlIHJlcXVlc3QgZXJyb3Igc28gdGhhdCB0aGUgaW5uZXIKICAgICAgICAgICAgLy9jb250ZW50cyBhbmQgc2NvcGUgY2FuIGJlIGNsZWFuZWQgdXAuCiAgICAgICAgICAgICR0ZW1wbGF0ZVJlcXVlc3Qoc3JjLCB0cnVlKS50aGVuKGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgaWYgKHRoaXNDaGFuZ2VJZCAhPT0gY2hhbmdlQ291bnRlcikgcmV0dXJuOwogICAgICAgICAgICAgIHZhciBuZXdTY29wZSA9IHNjb3BlLiRuZXcoKTsKICAgICAgICAgICAgICBjdHJsLnRlbXBsYXRlID0gcmVzcG9uc2U7CgogICAgICAgICAgICAgIC8vIE5vdGU6IFRoaXMgd2lsbCBhbHNvIGxpbmsgYWxsIGNoaWxkcmVuIG9mIG5nLWluY2x1ZGUgdGhhdCB3ZXJlIGNvbnRhaW5lZCBpbiB0aGUgb3JpZ2luYWwKICAgICAgICAgICAgICAvLyBodG1sLiBJZiB0aGF0IGNvbnRlbnQgY29udGFpbnMgY29udHJvbGxlcnMsIC4uLiB0aGV5IGNvdWxkIHBvbGx1dGUvY2hhbmdlIHRoZSBzY29wZS4KICAgICAgICAgICAgICAvLyBIb3dldmVyLCB1c2luZyBuZy1pbmNsdWRlIG9uIGFuIGVsZW1lbnQgd2l0aCBhZGRpdGlvbmFsIGNvbnRlbnQgZG9lcyBub3QgbWFrZSBzZW5zZS4uLgogICAgICAgICAgICAgIC8vIE5vdGU6IFdlIGNhbid0IHJlbW92ZSB0aGVtIGluIHRoZSBjbG9uZUF0dGNoRm4gb2YgJHRyYW5zY2x1ZGUgYXMgdGhhdAogICAgICAgICAgICAgIC8vIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgbGlua2luZyB0aGUgY29udGVudCwgd2hpY2ggd291bGQgYXBwbHkgY2hpbGQKICAgICAgICAgICAgICAvLyBkaXJlY3RpdmVzIHRvIG5vbiBleGlzdGluZyBlbGVtZW50cy4KICAgICAgICAgICAgICB2YXIgY2xvbmUgPSAkdHJhbnNjbHVkZShuZXdTY29wZSwgZnVuY3Rpb24oY2xvbmUpIHsKICAgICAgICAgICAgICAgIGNsZWFudXBMYXN0SW5jbHVkZUNvbnRlbnQoKTsKICAgICAgICAgICAgICAgICRhbmltYXRlLmVudGVyKGNsb25lLCBudWxsLCAkZWxlbWVudCkudGhlbihhZnRlckFuaW1hdGlvbik7CiAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgIGN1cnJlbnRTY29wZSA9IG5ld1Njb3BlOwogICAgICAgICAgICAgIGN1cnJlbnRFbGVtZW50ID0gY2xvbmU7CgogICAgICAgICAgICAgIGN1cnJlbnRTY29wZS4kZW1pdCgnJGluY2x1ZGVDb250ZW50TG9hZGVkJywgc3JjKTsKICAgICAgICAgICAgICBzY29wZS4kZXZhbChvbmxvYWRFeHApOwogICAgICAgICAgICB9LCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICBpZiAodGhpc0NoYW5nZUlkID09PSBjaGFuZ2VDb3VudGVyKSB7CiAgICAgICAgICAgICAgICBjbGVhbnVwTGFzdEluY2x1ZGVDb250ZW50KCk7CiAgICAgICAgICAgICAgICBzY29wZS4kZW1pdCgnJGluY2x1ZGVDb250ZW50RXJyb3InLCBzcmMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHNjb3BlLiRlbWl0KCckaW5jbHVkZUNvbnRlbnRSZXF1ZXN0ZWQnLCBzcmMpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2xlYW51cExhc3RJbmNsdWRlQ29udGVudCgpOwogICAgICAgICAgICBjdHJsLnRlbXBsYXRlID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9Owp9XTsKCi8vIFRoaXMgZGlyZWN0aXZlIGlzIGNhbGxlZCBkdXJpbmcgdGhlICR0cmFuc2NsdWRlIGNhbGwgb2YgdGhlIGZpcnN0IGBuZ0luY2x1ZGVgIGRpcmVjdGl2ZS4KLy8gSXQgd2lsbCByZXBsYWNlIGFuZCBjb21waWxlIHRoZSBjb250ZW50IG9mIHRoZSBlbGVtZW50IHdpdGggdGhlIGxvYWRlZCB0ZW1wbGF0ZS4KLy8gV2UgbmVlZCB0aGlzIGRpcmVjdGl2ZSBzbyB0aGF0IHRoZSBlbGVtZW50IGNvbnRlbnQgaXMgYWxyZWFkeSBmaWxsZWQgd2hlbgovLyB0aGUgbGluayBmdW5jdGlvbiBvZiBhbm90aGVyIGRpcmVjdGl2ZSBvbiB0aGUgc2FtZSBlbGVtZW50IGFzIG5nSW5jbHVkZQovLyBpcyBjYWxsZWQuCnZhciBuZ0luY2x1ZGVGaWxsQ29udGVudERpcmVjdGl2ZSA9IFsnJGNvbXBpbGUnLAogIGZ1bmN0aW9uKCRjb21waWxlKSB7CiAgICByZXR1cm4gewogICAgICByZXN0cmljdDogJ0VDQScsCiAgICAgIHByaW9yaXR5OiAtNDAwLAogICAgICByZXF1aXJlOiAnbmdJbmNsdWRlJywKICAgICAgbGluazogZnVuY3Rpb24oc2NvcGUsICRlbGVtZW50LCAkYXR0ciwgY3RybCkgewogICAgICAgIGlmICgvU1ZHLy50ZXN0KCRlbGVtZW50WzBdLnRvU3RyaW5nKCkpKSB7CiAgICAgICAgICAvLyBXZWJLaXQ6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzU2OTggLS0tIFNWRyBlbGVtZW50cyBkbyBub3QKICAgICAgICAgIC8vIHN1cHBvcnQgaW5uZXJIVE1MLCBzbyBkZXRlY3QgdGhpcyBoZXJlIGFuZCB0cnkgdG8gZ2VuZXJhdGUgdGhlIGNvbnRlbnRzCiAgICAgICAgICAvLyBzcGVjaWFsbHkuCiAgICAgICAgICAkZWxlbWVudC5lbXB0eSgpOwogICAgICAgICAgJGNvbXBpbGUoanFMaXRlQnVpbGRGcmFnbWVudChjdHJsLnRlbXBsYXRlLCBkb2N1bWVudCkuY2hpbGROb2Rlcykoc2NvcGUsCiAgICAgICAgICAgICAgZnVuY3Rpb24gbmFtZXNwYWNlQWRhcHRlZENsb25lKGNsb25lKSB7CiAgICAgICAgICAgICRlbGVtZW50LmFwcGVuZChjbG9uZSk7CiAgICAgICAgICB9LCB7ZnV0dXJlUGFyZW50RWxlbWVudDogJGVsZW1lbnR9KTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICRlbGVtZW50Lmh0bWwoY3RybC50ZW1wbGF0ZSk7CiAgICAgICAgJGNvbXBpbGUoJGVsZW1lbnQuY29udGVudHMoKSkoc2NvcGUpOwogICAgICB9CiAgICB9OwogIH1dOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdJbml0CiAqIEByZXN0cmljdCBBQwogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ0luaXRgIGRpcmVjdGl2ZSBhbGxvd3MgeW91IHRvIGV2YWx1YXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlCiAqIGN1cnJlbnQgc2NvcGUuCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWVycm9yIj4KICogVGhlIG9ubHkgYXBwcm9wcmlhdGUgdXNlIG9mIGBuZ0luaXRgIGlzIGZvciBhbGlhc2luZyBzcGVjaWFsIHByb3BlcnRpZXMgb2YKICoge0BsaW5rIG5nLmRpcmVjdGl2ZTpuZ1JlcGVhdCBgbmdSZXBlYXRgfSwgYXMgc2VlbiBpbiB0aGUgZGVtbyBiZWxvdy4gQmVzaWRlcyB0aGlzIGNhc2UsIHlvdQogKiBzaG91bGQgdXNlIHtAbGluayBndWlkZS9jb250cm9sbGVyIGNvbnRyb2xsZXJzfSByYXRoZXIgdGhhbiBgbmdJbml0YAogKiB0byBpbml0aWFsaXplIHZhbHVlcyBvbiBhIHNjb3BlLgogKiA8L2Rpdj4KICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CiAqICoqTm90ZSoqOiBJZiB5b3UgaGF2ZSBhc3NpZ25tZW50IGluIGBuZ0luaXRgIGFsb25nIHdpdGgge0BsaW5rIG5nLiRmaWx0ZXIgYCRmaWx0ZXJgfSwgbWFrZQogKiBzdXJlIHlvdSBoYXZlIHBhcmVudGhlc2lzIGZvciBjb3JyZWN0IHByZWNlZGVuY2U6CiAqIDxwcmUgY2xhc3M9InByZXR0eXByaW50Ij4KICogICA8ZGl2IG5nLWluaXQ9InRlc3QxID0gKGRhdGEgfCBvcmRlckJ5OiduYW1lJykiPjwvZGl2PgogKiA8L3ByZT4KICogPC9kaXY+CiAqCiAqIEBwcmlvcml0eSA0NTAKICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdJbml0IHtAbGluayBndWlkZS9leHByZXNzaW9uIEV4cHJlc3Npb259IHRvIGV2YWwuCiAqCiAqIEBleGFtcGxlCiAgIDxleGFtcGxlIG1vZHVsZT0iaW5pdEV4YW1wbGUiPgogICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICA8c2NyaXB0PgogICAgIGFuZ3VsYXIubW9kdWxlKCdpbml0RXhhbXBsZScsIFtdKQogICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgJHNjb3BlLmxpc3QgPSBbWydhJywgJ2InXSwgWydjJywgJ2QnXV07CiAgICAgICB9XSk7CiAgIDwvc2NyaXB0PgogICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICA8ZGl2IG5nLXJlcGVhdD0iaW5uZXJMaXN0IGluIGxpc3QiIG5nLWluaXQ9Im91dGVySW5kZXggPSAkaW5kZXgiPgogICAgICAgPGRpdiBuZy1yZXBlYXQ9InZhbHVlIGluIGlubmVyTGlzdCIgbmctaW5pdD0iaW5uZXJJbmRleCA9ICRpbmRleCI+CiAgICAgICAgICA8c3BhbiBjbGFzcz0iZXhhbXBsZS1pbml0Ij5saXN0WyB7e291dGVySW5kZXh9fSBdWyB7e2lubmVySW5kZXh9fSBdID0ge3t2YWx1ZX19Ozwvc3Bhbj4KICAgICAgIDwvZGl2PgogICAgIDwvZGl2PgogICA8L2Rpdj4KICAgICA8L2ZpbGU+CiAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGFsaWFzIGluZGV4IHBvc2l0aW9ucycsIGZ1bmN0aW9uKCkgewogICAgICAgICB2YXIgZWxlbWVudHMgPSBlbGVtZW50LmFsbChieS5jc3MoJy5leGFtcGxlLWluaXQnKSk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50cy5nZXQoMCkuZ2V0VGV4dCgpKS50b0JlKCdsaXN0WyAwIF1bIDAgXSA9IGE7Jyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50cy5nZXQoMSkuZ2V0VGV4dCgpKS50b0JlKCdsaXN0WyAwIF1bIDEgXSA9IGI7Jyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50cy5nZXQoMikuZ2V0VGV4dCgpKS50b0JlKCdsaXN0WyAxIF1bIDAgXSA9IGM7Jyk7CiAgICAgICAgIGV4cGVjdChlbGVtZW50cy5nZXQoMykuZ2V0VGV4dCgpKS50b0JlKCdsaXN0WyAxIF1bIDEgXSA9IGQ7Jyk7CiAgICAgICB9KTsKICAgICA8L2ZpbGU+CiAgIDwvZXhhbXBsZT4KICovCnZhciBuZ0luaXREaXJlY3RpdmUgPSBuZ0RpcmVjdGl2ZSh7CiAgcHJpb3JpdHk6IDQ1MCwKICBjb21waWxlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB7CiAgICAgIHByZTogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHJzKSB7CiAgICAgICAgc2NvcGUuJGV2YWwoYXR0cnMubmdJbml0KTsKICAgICAgfQogICAgfTsKICB9Cn0pOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdOb25CaW5kYWJsZQogKiBAcmVzdHJpY3QgQUMKICogQHByaW9yaXR5IDEwMDAKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgbmdOb25CaW5kYWJsZWAgZGlyZWN0aXZlIHRlbGxzIEFuZ3VsYXIgbm90IHRvIGNvbXBpbGUgb3IgYmluZCB0aGUgY29udGVudHMgb2YgdGhlIGN1cnJlbnQKICogRE9NIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIGlmIHRoZSBlbGVtZW50IGNvbnRhaW5zIHdoYXQgYXBwZWFycyB0byBiZSBBbmd1bGFyIGRpcmVjdGl2ZXMgYW5kCiAqIGJpbmRpbmdzIGJ1dCB3aGljaCBzaG91bGQgYmUgaWdub3JlZCBieSBBbmd1bGFyLiBUaGlzIGNvdWxkIGJlIHRoZSBjYXNlIGlmIHlvdSBoYXZlIGEgc2l0ZSB0aGF0CiAqIGRpc3BsYXlzIHNuaXBwZXRzIG9mIGNvZGUsIGZvciBpbnN0YW5jZS4KICoKICogQGVsZW1lbnQgQU5ZCiAqCiAqIEBleGFtcGxlCiAqIEluIHRoaXMgZXhhbXBsZSB0aGVyZSBhcmUgdHdvIGxvY2F0aW9ucyB3aGVyZSBhIHNpbXBsZSBpbnRlcnBvbGF0aW9uIGJpbmRpbmcgKGB7e319YCkgaXMgcHJlc2VudCwKICogYnV0IHRoZSBvbmUgd3JhcHBlZCBpbiBgbmdOb25CaW5kYWJsZWAgaXMgbGVmdCBhbG9uZS4KICoKICogQGV4YW1wbGUKICAgIDxleGFtcGxlPgogICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICA8ZGl2Pk5vcm1hbDoge3sxICsgMn19PC9kaXY+CiAgICAgICAgPGRpdiBuZy1ub24tYmluZGFibGU+SWdub3JlZDoge3sxICsgMn19PC9kaXY+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLW5vbi1iaW5kYWJsZScsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCcxICsgMicpKS5nZXRUZXh0KCkpLnRvQ29udGFpbignMycpOwogICAgICAgICBleHBlY3QoZWxlbWVudC5hbGwoYnkuY3NzKCdkaXYnKSkubGFzdCgpLmdldFRleHQoKSkudG9NYXRjaCgvMSBcKyAyLyk7CiAgICAgICB9KTsKICAgICAgPC9maWxlPgogICAgPC9leGFtcGxlPgogKi8KdmFyIG5nTm9uQmluZGFibGVEaXJlY3RpdmUgPSBuZ0RpcmVjdGl2ZSh7IHRlcm1pbmFsOiB0cnVlLCBwcmlvcml0eTogMTAwMCB9KTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nUGx1cmFsaXplCiAqIEByZXN0cmljdCBFQQogKgogKiBAZGVzY3JpcHRpb24KICogYG5nUGx1cmFsaXplYCBpcyBhIGRpcmVjdGl2ZSB0aGF0IGRpc3BsYXlzIG1lc3NhZ2VzIGFjY29yZGluZyB0byBlbi1VUyBsb2NhbGl6YXRpb24gcnVsZXMuCiAqIFRoZXNlIHJ1bGVzIGFyZSBidW5kbGVkIHdpdGggYW5ndWxhci5qcywgYnV0IGNhbiBiZSBvdmVycmlkZGVuCiAqIChzZWUge0BsaW5rIGd1aWRlL2kxOG4gQW5ndWxhciBpMThufSBkZXYgZ3VpZGUpLiBZb3UgY29uZmlndXJlIG5nUGx1cmFsaXplIGRpcmVjdGl2ZQogKiBieSBzcGVjaWZ5aW5nIHRoZSBtYXBwaW5ncyBiZXR3ZWVuCiAqIFtwbHVyYWwgY2F0ZWdvcmllc10oaHR0cDovL3VuaWNvZGUub3JnL3JlcG9zL2NsZHItdG1wL3RydW5rL2RpZmYvc3VwcGxlbWVudGFsL2xhbmd1YWdlX3BsdXJhbF9ydWxlcy5odG1sKQogKiBhbmQgdGhlIHN0cmluZ3MgdG8gYmUgZGlzcGxheWVkLgogKgogKiAjIFBsdXJhbCBjYXRlZ29yaWVzIGFuZCBleHBsaWNpdCBudW1iZXIgcnVsZXMKICogVGhlcmUgYXJlIHR3bwogKiBbcGx1cmFsIGNhdGVnb3JpZXNdKGh0dHA6Ly91bmljb2RlLm9yZy9yZXBvcy9jbGRyLXRtcC90cnVuay9kaWZmL3N1cHBsZW1lbnRhbC9sYW5ndWFnZV9wbHVyYWxfcnVsZXMuaHRtbCkKICogaW4gQW5ndWxhcidzIGRlZmF1bHQgZW4tVVMgbG9jYWxlOiAib25lIiBhbmQgIm90aGVyIi4KICoKICogV2hpbGUgYSBwbHVyYWwgY2F0ZWdvcnkgbWF5IG1hdGNoIG1hbnkgbnVtYmVycyAoZm9yIGV4YW1wbGUsIGluIGVuLVVTIGxvY2FsZSwgIm90aGVyIiBjYW4gbWF0Y2gKICogYW55IG51bWJlciB0aGF0IGlzIG5vdCAxKSwgYW4gZXhwbGljaXQgbnVtYmVyIHJ1bGUgY2FuIG9ubHkgbWF0Y2ggb25lIG51bWJlci4gRm9yIGV4YW1wbGUsIHRoZQogKiBleHBsaWNpdCBudW1iZXIgcnVsZSBmb3IgIjMiIG1hdGNoZXMgdGhlIG51bWJlciAzLiBUaGVyZSBhcmUgZXhhbXBsZXMgb2YgcGx1cmFsIGNhdGVnb3JpZXMKICogYW5kIGV4cGxpY2l0IG51bWJlciBydWxlcyB0aHJvdWdob3V0IHRoZSByZXN0IG9mIHRoaXMgZG9jdW1lbnRhdGlvbi4KICoKICogIyBDb25maWd1cmluZyBuZ1BsdXJhbGl6ZQogKiBZb3UgY29uZmlndXJlIG5nUGx1cmFsaXplIGJ5IHByb3ZpZGluZyAyIGF0dHJpYnV0ZXM6IGBjb3VudGAgYW5kIGB3aGVuYC4KICogWW91IGNhbiBhbHNvIHByb3ZpZGUgYW4gb3B0aW9uYWwgYXR0cmlidXRlLCBgb2Zmc2V0YC4KICoKICogVGhlIHZhbHVlIG9mIHRoZSBgY291bnRgIGF0dHJpYnV0ZSBjYW4gYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIHtAbGluayBndWlkZS9leHByZXNzaW9uCiAqIEFuZ3VsYXIgZXhwcmVzc2lvbn07IHRoZXNlIGFyZSBldmFsdWF0ZWQgb24gdGhlIGN1cnJlbnQgc2NvcGUgZm9yIGl0cyBib3VuZCB2YWx1ZS4KICoKICogVGhlIGB3aGVuYCBhdHRyaWJ1dGUgc3BlY2lmaWVzIHRoZSBtYXBwaW5ncyBiZXR3ZWVuIHBsdXJhbCBjYXRlZ29yaWVzIGFuZCB0aGUgYWN0dWFsCiAqIHN0cmluZyB0byBiZSBkaXNwbGF5ZWQuIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIHNob3VsZCBiZSBhIEpTT04gb2JqZWN0LgogKgogKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIGNvbmZpZ3VyZSBuZ1BsdXJhbGl6ZToKICoKICogYGBgaHRtbAogKiA8bmctcGx1cmFsaXplIGNvdW50PSJwZXJzb25Db3VudCIKICAgICAgICAgICAgICAgICB3aGVuPSJ7JzAnOiAnTm9ib2R5IGlzIHZpZXdpbmcuJywKICogICAgICAgICAgICAgICAgICAgICAgJ29uZSc6ICcxIHBlcnNvbiBpcyB2aWV3aW5nLicsCiAqICAgICAgICAgICAgICAgICAgICAgICdvdGhlcic6ICd7fSBwZW9wbGUgYXJlIHZpZXdpbmcuJ30iPgogKiA8L25nLXBsdXJhbGl6ZT4KICpgYGAKICoKICogSW4gdGhlIGV4YW1wbGUsIGAiMDogTm9ib2R5IGlzIHZpZXdpbmcuImAgaXMgYW4gZXhwbGljaXQgbnVtYmVyIHJ1bGUuIElmIHlvdSBkaWQgbm90CiAqIHNwZWNpZnkgdGhpcyBydWxlLCAwIHdvdWxkIGJlIG1hdGNoZWQgdG8gdGhlICJvdGhlciIgY2F0ZWdvcnkgYW5kICIwIHBlb3BsZSBhcmUgdmlld2luZyIKICogd291bGQgYmUgc2hvd24gaW5zdGVhZCBvZiAiTm9ib2R5IGlzIHZpZXdpbmciLiBZb3UgY2FuIHNwZWNpZnkgYW4gZXhwbGljaXQgbnVtYmVyIHJ1bGUgZm9yCiAqIG90aGVyIG51bWJlcnMsIGZvciBleGFtcGxlIDEyLCBzbyB0aGF0IGluc3RlYWQgb2Ygc2hvd2luZyAiMTIgcGVvcGxlIGFyZSB2aWV3aW5nIiwgeW91IGNhbgogKiBzaG93ICJhIGRvemVuIHBlb3BsZSBhcmUgdmlld2luZyIuCiAqCiAqIFlvdSBjYW4gdXNlIGEgc2V0IG9mIGNsb3NlZCBicmFjZXMgKGB7fWApIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHRoZSBudW1iZXIgdGhhdCB5b3Ugd2FudCBzdWJzdGl0dXRlZAogKiBpbnRvIHBsdXJhbGl6ZWQgc3RyaW5ncy4gSW4gdGhlIHByZXZpb3VzIGV4YW1wbGUsIEFuZ3VsYXIgd2lsbCByZXBsYWNlIGB7fWAgd2l0aAogKiA8c3BhbiBuZy1ub24tYmluZGFibGU+YHt7cGVyc29uQ291bnR9fWA8L3NwYW4+LiBUaGUgY2xvc2VkIGJyYWNlcyBge31gIGlzIGEgcGxhY2Vob2xkZXIKICogZm9yIDxzcGFuIG5nLW5vbi1iaW5kYWJsZT57e251bWJlckV4cHJlc3Npb259fTwvc3Bhbj4uCiAqCiAqICMgQ29uZmlndXJpbmcgbmdQbHVyYWxpemUgd2l0aCBvZmZzZXQKICogVGhlIGBvZmZzZXRgIGF0dHJpYnV0ZSBhbGxvd3MgZnVydGhlciBjdXN0b21pemF0aW9uIG9mIHBsdXJhbGl6ZWQgdGV4dCwgd2hpY2ggY2FuIHJlc3VsdCBpbgogKiBhIGJldHRlciB1c2VyIGV4cGVyaWVuY2UuIEZvciBleGFtcGxlLCBpbnN0ZWFkIG9mIHRoZSBtZXNzYWdlICI0IHBlb3BsZSBhcmUgdmlld2luZyB0aGlzIGRvY3VtZW50IiwKICogeW91IG1pZ2h0IGRpc3BsYXkgIkpvaG4sIEthdGUgYW5kIDIgb3RoZXJzIGFyZSB2aWV3aW5nIHRoaXMgZG9jdW1lbnQiLgogKiBUaGUgb2Zmc2V0IGF0dHJpYnV0ZSBhbGxvd3MgeW91IHRvIG9mZnNldCBhIG51bWJlciBieSBhbnkgZGVzaXJlZCB2YWx1ZS4KICogTGV0J3MgdGFrZSBhIGxvb2sgYXQgYW4gZXhhbXBsZToKICoKICogYGBgaHRtbAogKiA8bmctcGx1cmFsaXplIGNvdW50PSJwZXJzb25Db3VudCIgb2Zmc2V0PTIKICogICAgICAgICAgICAgICB3aGVuPSJ7JzAnOiAnTm9ib2R5IGlzIHZpZXdpbmcuJywKICogICAgICAgICAgICAgICAgICAgICAgJzEnOiAne3twZXJzb24xfX0gaXMgdmlld2luZy4nLAogKiAgICAgICAgICAgICAgICAgICAgICAnMic6ICd7e3BlcnNvbjF9fSBhbmQge3twZXJzb24yfX0gYXJlIHZpZXdpbmcuJywKICogICAgICAgICAgICAgICAgICAgICAgJ29uZSc6ICd7e3BlcnNvbjF9fSwge3twZXJzb24yfX0gYW5kIG9uZSBvdGhlciBwZXJzb24gYXJlIHZpZXdpbmcuJywKICogICAgICAgICAgICAgICAgICAgICAgJ290aGVyJzogJ3t7cGVyc29uMX19LCB7e3BlcnNvbjJ9fSBhbmQge30gb3RoZXIgcGVvcGxlIGFyZSB2aWV3aW5nLid9Ij4KICogPC9uZy1wbHVyYWxpemU+CiAqIGBgYAogKgogKiBOb3RpY2UgdGhhdCB3ZSBhcmUgc3RpbGwgdXNpbmcgdHdvIHBsdXJhbCBjYXRlZ29yaWVzKG9uZSwgb3RoZXIpLCBidXQgd2UgYWRkZWQKICogdGhyZWUgZXhwbGljaXQgbnVtYmVyIHJ1bGVzIDAsIDEgYW5kIDIuCiAqIFdoZW4gb25lIHBlcnNvbiwgcGVyaGFwcyBKb2huLCB2aWV3cyB0aGUgZG9jdW1lbnQsICJKb2huIGlzIHZpZXdpbmciIHdpbGwgYmUgc2hvd24uCiAqIFdoZW4gdGhyZWUgcGVvcGxlIHZpZXcgdGhlIGRvY3VtZW50LCBubyBleHBsaWNpdCBudW1iZXIgcnVsZSBpcyBmb3VuZCwgc28KICogYW4gb2Zmc2V0IG9mIDIgaXMgdGFrZW4gb2ZmIDMsIGFuZCBBbmd1bGFyIHVzZXMgMSB0byBkZWNpZGUgdGhlIHBsdXJhbCBjYXRlZ29yeS4KICogSW4gdGhpcyBjYXNlLCBwbHVyYWwgY2F0ZWdvcnkgJ29uZScgaXMgbWF0Y2hlZCBhbmQgIkpvaG4sIE1hcnkgYW5kIG9uZSBvdGhlciBwZXJzb24gYXJlIHZpZXdpbmciCiAqIGlzIHNob3duLgogKgogKiBOb3RlIHRoYXQgd2hlbiB5b3Ugc3BlY2lmeSBvZmZzZXRzLCB5b3UgbXVzdCBwcm92aWRlIGV4cGxpY2l0IG51bWJlciBydWxlcyBmb3IKICogbnVtYmVycyBmcm9tIDAgdXAgdG8gYW5kIGluY2x1ZGluZyB0aGUgb2Zmc2V0LiBJZiB5b3UgdXNlIGFuIG9mZnNldCBvZiAzLCBmb3IgZXhhbXBsZSwKICogeW91IG11c3QgcHJvdmlkZSBleHBsaWNpdCBudW1iZXIgcnVsZXMgZm9yIDAsIDEsIDIgYW5kIDMuIFlvdSBtdXN0IGFsc28gcHJvdmlkZSBwbHVyYWwgc3RyaW5ncyBmb3IKICogcGx1cmFsIGNhdGVnb3JpZXMgIm9uZSIgYW5kICJvdGhlciIuCiAqCiAqIEBwYXJhbSB7c3RyaW5nfGV4cHJlc3Npb259IGNvdW50IFRoZSB2YXJpYWJsZSB0byBiZSBib3VuZCB0by4KICogQHBhcmFtIHtzdHJpbmd9IHdoZW4gVGhlIG1hcHBpbmcgYmV0d2VlbiBwbHVyYWwgY2F0ZWdvcnkgdG8gaXRzIGNvcnJlc3BvbmRpbmcgc3RyaW5ncy4KICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIGRlZHVjdCBmcm9tIHRoZSB0b3RhbCBudW1iZXIuCiAqCiAqIEBleGFtcGxlCiAgICA8ZXhhbXBsZSBtb2R1bGU9InBsdXJhbGl6ZUV4YW1wbGUiPgogICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICA8c2NyaXB0PgogICAgICAgICAgYW5ndWxhci5tb2R1bGUoJ3BsdXJhbGl6ZUV4YW1wbGUnLCBbXSkKICAgICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgICAkc2NvcGUucGVyc29uMSA9ICdJZ29yJzsKICAgICAgICAgICAgICAkc2NvcGUucGVyc29uMiA9ICdNaXNrbyc7CiAgICAgICAgICAgICAgJHNjb3BlLnBlcnNvbkNvdW50ID0gMTsKICAgICAgICAgICAgfV0pOwogICAgICAgIDwvc2NyaXB0PgogICAgICAgIDxkaXYgbmctY29udHJvbGxlcj0iRXhhbXBsZUNvbnRyb2xsZXIiPgogICAgICAgICAgUGVyc29uIDE6PGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJwZXJzb24xIiB2YWx1ZT0iSWdvciIgLz48YnIvPgogICAgICAgICAgUGVyc29uIDI6PGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJwZXJzb24yIiB2YWx1ZT0iTWlza28iIC8+PGJyLz4KICAgICAgICAgIE51bWJlciBvZiBQZW9wbGU6PGlucHV0IHR5cGU9InRleHQiIG5nLW1vZGVsPSJwZXJzb25Db3VudCIgdmFsdWU9IjEiIC8+PGJyLz4KCiAgICAgICAgICA8IS0tLSBFeGFtcGxlIHdpdGggc2ltcGxlIHBsdXJhbGl6YXRpb24gcnVsZXMgZm9yIGVuIGxvY2FsZSAtLS0+CiAgICAgICAgICBXaXRob3V0IE9mZnNldDoKICAgICAgICAgIDxuZy1wbHVyYWxpemUgY291bnQ9InBlcnNvbkNvdW50IgogICAgICAgICAgICAgICAgICAgICAgICB3aGVuPSJ7JzAnOiAnTm9ib2R5IGlzIHZpZXdpbmcuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvbmUnOiAnMSBwZXJzb24gaXMgdmlld2luZy4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ290aGVyJzogJ3t9IHBlb3BsZSBhcmUgdmlld2luZy4nfSI+CiAgICAgICAgICA8L25nLXBsdXJhbGl6ZT48YnI+CgogICAgICAgICAgPCEtLS0gRXhhbXBsZSB3aXRoIG9mZnNldCAtLS0+CiAgICAgICAgICBXaXRoIE9mZnNldCgyKToKICAgICAgICAgIDxuZy1wbHVyYWxpemUgY291bnQ9InBlcnNvbkNvdW50IiBvZmZzZXQ9MgogICAgICAgICAgICAgICAgICAgICAgICB3aGVuPSJ7JzAnOiAnTm9ib2R5IGlzIHZpZXdpbmcuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcxJzogJ3t7cGVyc29uMX19IGlzIHZpZXdpbmcuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcyJzogJ3t7cGVyc29uMX19IGFuZCB7e3BlcnNvbjJ9fSBhcmUgdmlld2luZy4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29uZSc6ICd7e3BlcnNvbjF9fSwge3twZXJzb24yfX0gYW5kIG9uZSBvdGhlciBwZXJzb24gYXJlIHZpZXdpbmcuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvdGhlcic6ICd7e3BlcnNvbjF9fSwge3twZXJzb24yfX0gYW5kIHt9IG90aGVyIHBlb3BsZSBhcmUgdmlld2luZy4nfSI+CiAgICAgICAgICA8L25nLXBsdXJhbGl6ZT4KICAgICAgICA8L2Rpdj4KICAgICAgPC9maWxlPgogICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgICBpdCgnc2hvdWxkIHNob3cgY29ycmVjdCBwbHVyYWxpemVkIHN0cmluZycsIGZ1bmN0aW9uKCkgewogICAgICAgICAgdmFyIHdpdGhvdXRPZmZzZXQgPSBlbGVtZW50LmFsbChieS5jc3MoJ25nLXBsdXJhbGl6ZScpKS5nZXQoMCk7CiAgICAgICAgICB2YXIgd2l0aE9mZnNldCA9IGVsZW1lbnQuYWxsKGJ5LmNzcygnbmctcGx1cmFsaXplJykpLmdldCgxKTsKICAgICAgICAgIHZhciBjb3VudElucHV0ID0gZWxlbWVudChieS5tb2RlbCgncGVyc29uQ291bnQnKSk7CgogICAgICAgICAgZXhwZWN0KHdpdGhvdXRPZmZzZXQuZ2V0VGV4dCgpKS50b0VxdWFsKCcxIHBlcnNvbiBpcyB2aWV3aW5nLicpOwogICAgICAgICAgZXhwZWN0KHdpdGhPZmZzZXQuZ2V0VGV4dCgpKS50b0VxdWFsKCdJZ29yIGlzIHZpZXdpbmcuJyk7CgogICAgICAgICAgY291bnRJbnB1dC5jbGVhcigpOwogICAgICAgICAgY291bnRJbnB1dC5zZW5kS2V5cygnMCcpOwoKICAgICAgICAgIGV4cGVjdCh3aXRob3V0T2Zmc2V0LmdldFRleHQoKSkudG9FcXVhbCgnTm9ib2R5IGlzIHZpZXdpbmcuJyk7CiAgICAgICAgICBleHBlY3Qod2l0aE9mZnNldC5nZXRUZXh0KCkpLnRvRXF1YWwoJ05vYm9keSBpcyB2aWV3aW5nLicpOwoKICAgICAgICAgIGNvdW50SW5wdXQuY2xlYXIoKTsKICAgICAgICAgIGNvdW50SW5wdXQuc2VuZEtleXMoJzInKTsKCiAgICAgICAgICBleHBlY3Qod2l0aG91dE9mZnNldC5nZXRUZXh0KCkpLnRvRXF1YWwoJzIgcGVvcGxlIGFyZSB2aWV3aW5nLicpOwogICAgICAgICAgZXhwZWN0KHdpdGhPZmZzZXQuZ2V0VGV4dCgpKS50b0VxdWFsKCdJZ29yIGFuZCBNaXNrbyBhcmUgdmlld2luZy4nKTsKCiAgICAgICAgICBjb3VudElucHV0LmNsZWFyKCk7CiAgICAgICAgICBjb3VudElucHV0LnNlbmRLZXlzKCczJyk7CgogICAgICAgICAgZXhwZWN0KHdpdGhvdXRPZmZzZXQuZ2V0VGV4dCgpKS50b0VxdWFsKCczIHBlb3BsZSBhcmUgdmlld2luZy4nKTsKICAgICAgICAgIGV4cGVjdCh3aXRoT2Zmc2V0LmdldFRleHQoKSkudG9FcXVhbCgnSWdvciwgTWlza28gYW5kIG9uZSBvdGhlciBwZXJzb24gYXJlIHZpZXdpbmcuJyk7CgogICAgICAgICAgY291bnRJbnB1dC5jbGVhcigpOwogICAgICAgICAgY291bnRJbnB1dC5zZW5kS2V5cygnNCcpOwoKICAgICAgICAgIGV4cGVjdCh3aXRob3V0T2Zmc2V0LmdldFRleHQoKSkudG9FcXVhbCgnNCBwZW9wbGUgYXJlIHZpZXdpbmcuJyk7CiAgICAgICAgICBleHBlY3Qod2l0aE9mZnNldC5nZXRUZXh0KCkpLnRvRXF1YWwoJ0lnb3IsIE1pc2tvIGFuZCAyIG90aGVyIHBlb3BsZSBhcmUgdmlld2luZy4nKTsKICAgICAgICB9KTsKICAgICAgICBpdCgnc2hvdWxkIHNob3cgZGF0YS1ib3VuZCBuYW1lcycsIGZ1bmN0aW9uKCkgewogICAgICAgICAgdmFyIHdpdGhPZmZzZXQgPSBlbGVtZW50LmFsbChieS5jc3MoJ25nLXBsdXJhbGl6ZScpKS5nZXQoMSk7CiAgICAgICAgICB2YXIgcGVyc29uQ291bnQgPSBlbGVtZW50KGJ5Lm1vZGVsKCdwZXJzb25Db3VudCcpKTsKICAgICAgICAgIHZhciBwZXJzb24xID0gZWxlbWVudChieS5tb2RlbCgncGVyc29uMScpKTsKICAgICAgICAgIHZhciBwZXJzb24yID0gZWxlbWVudChieS5tb2RlbCgncGVyc29uMicpKTsKICAgICAgICAgIHBlcnNvbkNvdW50LmNsZWFyKCk7CiAgICAgICAgICBwZXJzb25Db3VudC5zZW5kS2V5cygnNCcpOwogICAgICAgICAgcGVyc29uMS5jbGVhcigpOwogICAgICAgICAgcGVyc29uMS5zZW5kS2V5cygnRGknKTsKICAgICAgICAgIHBlcnNvbjIuY2xlYXIoKTsKICAgICAgICAgIHBlcnNvbjIuc2VuZEtleXMoJ1ZvanRhJyk7CiAgICAgICAgICBleHBlY3Qod2l0aE9mZnNldC5nZXRUZXh0KCkpLnRvRXF1YWwoJ0RpLCBWb2p0YSBhbmQgMiBvdGhlciBwZW9wbGUgYXJlIHZpZXdpbmcuJyk7CiAgICAgICAgfSk7CiAgICAgIDwvZmlsZT4KICAgIDwvZXhhbXBsZT4KICovCnZhciBuZ1BsdXJhbGl6ZURpcmVjdGl2ZSA9IFsnJGxvY2FsZScsICckaW50ZXJwb2xhdGUnLCBmdW5jdGlvbigkbG9jYWxlLCAkaW50ZXJwb2xhdGUpIHsKICB2YXIgQlJBQ0UgPSAve30vZywKICAgICAgSVNfV0hFTiA9IC9ed2hlbihNaW51cyk/KC4rKSQvOwoKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdFQScsCiAgICBsaW5rOiBmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0cikgewogICAgICB2YXIgbnVtYmVyRXhwID0gYXR0ci5jb3VudCwKICAgICAgICAgIHdoZW5FeHAgPSBhdHRyLiRhdHRyLndoZW4gJiYgZWxlbWVudC5hdHRyKGF0dHIuJGF0dHIud2hlbiksIC8vIHdlIGhhdmUge3t9fSBpbiBhdHRycwogICAgICAgICAgb2Zmc2V0ID0gYXR0ci5vZmZzZXQgfHwgMCwKICAgICAgICAgIHdoZW5zID0gc2NvcGUuJGV2YWwod2hlbkV4cCkgfHwge30sCiAgICAgICAgICB3aGVuc0V4cEZucyA9IHt9LAogICAgICAgICAgc3RhcnRTeW1ib2wgPSAkaW50ZXJwb2xhdGUuc3RhcnRTeW1ib2woKSwKICAgICAgICAgIGVuZFN5bWJvbCA9ICRpbnRlcnBvbGF0ZS5lbmRTeW1ib2woKSwKICAgICAgICAgIGJyYWNlUmVwbGFjZW1lbnQgPSBzdGFydFN5bWJvbCArIG51bWJlckV4cCArICctJyArIG9mZnNldCArIGVuZFN5bWJvbCwKICAgICAgICAgIHdhdGNoUmVtb3ZlciA9IGFuZ3VsYXIubm9vcCwKICAgICAgICAgIGxhc3RDb3VudDsKCiAgICAgIGZvckVhY2goYXR0ciwgZnVuY3Rpb24oZXhwcmVzc2lvbiwgYXR0cmlidXRlTmFtZSkgewogICAgICAgIHZhciB0bXBNYXRjaCA9IElTX1dIRU4uZXhlYyhhdHRyaWJ1dGVOYW1lKTsKICAgICAgICBpZiAodG1wTWF0Y2gpIHsKICAgICAgICAgIHZhciB3aGVuS2V5ID0gKHRtcE1hdGNoWzFdID8gJy0nIDogJycpICsgbG93ZXJjYXNlKHRtcE1hdGNoWzJdKTsKICAgICAgICAgIHdoZW5zW3doZW5LZXldID0gZWxlbWVudC5hdHRyKGF0dHIuJGF0dHJbYXR0cmlidXRlTmFtZV0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIGZvckVhY2god2hlbnMsIGZ1bmN0aW9uKGV4cHJlc3Npb24sIGtleSkgewogICAgICAgIHdoZW5zRXhwRm5zW2tleV0gPSAkaW50ZXJwb2xhdGUoZXhwcmVzc2lvbi5yZXBsYWNlKEJSQUNFLCBicmFjZVJlcGxhY2VtZW50KSk7CgogICAgICB9KTsKCiAgICAgIHNjb3BlLiR3YXRjaChudW1iZXJFeHAsIGZ1bmN0aW9uIG5nUGx1cmFsaXplV2F0Y2hBY3Rpb24obmV3VmFsKSB7CiAgICAgICAgdmFyIGNvdW50ID0gcGFyc2VGbG9hdChuZXdWYWwpOwogICAgICAgIHZhciBjb3VudElzTmFOID0gaXNOYU4oY291bnQpOwoKICAgICAgICBpZiAoIWNvdW50SXNOYU4gJiYgIShjb3VudCBpbiB3aGVucykpIHsKICAgICAgICAgIC8vIElmIGFuIGV4cGxpY2l0IG51bWJlciBydWxlIHN1Y2ggYXMgMSwgMiwgMy4uLiBpcyBkZWZpbmVkLCBqdXN0IHVzZSBpdC4KICAgICAgICAgIC8vIE90aGVyd2lzZSwgY2hlY2sgaXQgYWdhaW5zdCBwbHVyYWxpemF0aW9uIHJ1bGVzIGluICRsb2NhbGUgc2VydmljZS4KICAgICAgICAgIGNvdW50ID0gJGxvY2FsZS5wbHVyYWxDYXQoY291bnQgLSBvZmZzZXQpOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgYm90aCBgY291bnRgIGFuZCBgbGFzdENvdW50YCBhcmUgTmFOLCB3ZSBkb24ndCBuZWVkIHRvIHJlLXJlZ2lzdGVyIGEgd2F0Y2guCiAgICAgICAgLy8gSW4gSlMgYE5hTiAhPT0gTmFOYCwgc28gd2UgaGF2ZSB0byBleGxpY2l0bHkgY2hlY2suCiAgICAgICAgaWYgKChjb3VudCAhPT0gbGFzdENvdW50KSAmJiAhKGNvdW50SXNOYU4gJiYgaXNOYU4obGFzdENvdW50KSkpIHsKICAgICAgICAgIHdhdGNoUmVtb3ZlcigpOwogICAgICAgICAgd2F0Y2hSZW1vdmVyID0gc2NvcGUuJHdhdGNoKHdoZW5zRXhwRm5zW2NvdW50XSwgdXBkYXRlRWxlbWVudFRleHQpOwogICAgICAgICAgbGFzdENvdW50ID0gY291bnQ7CiAgICAgICAgfQogICAgICB9KTsKCiAgICAgIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnRUZXh0KG5ld1RleHQpIHsKICAgICAgICBlbGVtZW50LnRleHQobmV3VGV4dCB8fCAnJyk7CiAgICAgIH0KICAgIH0KICB9Owp9XTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nUmVwZWF0CiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgYG5nUmVwZWF0YCBkaXJlY3RpdmUgaW5zdGFudGlhdGVzIGEgdGVtcGxhdGUgb25jZSBwZXIgaXRlbSBmcm9tIGEgY29sbGVjdGlvbi4gRWFjaCB0ZW1wbGF0ZQogKiBpbnN0YW5jZSBnZXRzIGl0cyBvd24gc2NvcGUsIHdoZXJlIHRoZSBnaXZlbiBsb29wIHZhcmlhYmxlIGlzIHNldCB0byB0aGUgY3VycmVudCBjb2xsZWN0aW9uIGl0ZW0sCiAqIGFuZCBgJGluZGV4YCBpcyBzZXQgdG8gdGhlIGl0ZW0gaW5kZXggb3Iga2V5LgogKgogKiBTcGVjaWFsIHByb3BlcnRpZXMgYXJlIGV4cG9zZWQgb24gdGhlIGxvY2FsIHNjb3BlIG9mIGVhY2ggdGVtcGxhdGUgaW5zdGFuY2UsIGluY2x1ZGluZzoKICoKICogfCBWYXJpYWJsZSAgfCBUeXBlICAgICAgICAgICAgfCBEZXRhaWxzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiB8LS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgYCRpbmRleGAgIHwge0B0eXBlIG51bWJlcn0gIHwgaXRlcmF0b3Igb2Zmc2V0IG9mIHRoZSByZXBlYXRlZCBlbGVtZW50ICgwLi5sZW5ndGgtMSkgICAgICAgICAgICAgICAgICAgICAgIHwKICogfCBgJGZpcnN0YCAgfCB7QHR5cGUgYm9vbGVhbn0gfCB0cnVlIGlmIHRoZSByZXBlYXRlZCBlbGVtZW50IGlzIGZpcnN0IGluIHRoZSBpdGVyYXRvci4gICAgICAgICAgICAgICAgICAgICAgfAogKiB8IGAkbWlkZGxlYCB8IHtAdHlwZSBib29sZWFufSB8IHRydWUgaWYgdGhlIHJlcGVhdGVkIGVsZW1lbnQgaXMgYmV0d2VlbiB0aGUgZmlyc3QgYW5kIGxhc3QgaW4gdGhlIGl0ZXJhdG9yLiB8CiAqIHwgYCRsYXN0YCAgIHwge0B0eXBlIGJvb2xlYW59IHwgdHJ1ZSBpZiB0aGUgcmVwZWF0ZWQgZWxlbWVudCBpcyBsYXN0IGluIHRoZSBpdGVyYXRvci4gICAgICAgICAgICAgICAgICAgICAgIHwKICogfCBgJGV2ZW5gICAgfCB7QHR5cGUgYm9vbGVhbn0gfCB0cnVlIGlmIHRoZSBpdGVyYXRvciBwb3NpdGlvbiBgJGluZGV4YCBpcyBldmVuIChvdGhlcndpc2UgZmFsc2UpLiAgICAgICAgICAgfAogKiB8IGAkb2RkYCAgICB8IHtAdHlwZSBib29sZWFufSB8IHRydWUgaWYgdGhlIGl0ZXJhdG9yIHBvc2l0aW9uIGAkaW5kZXhgIGlzIG9kZCAob3RoZXJ3aXNlIGZhbHNlKS4gICAgICAgICAgICB8CiAqCiAqIENyZWF0aW5nIGFsaWFzZXMgZm9yIHRoZXNlIHByb3BlcnRpZXMgaXMgcG9zc2libGUgd2l0aCB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nSW5pdCBgbmdJbml0YH0uCiAqIFRoaXMgbWF5IGJlIHVzZWZ1bCB3aGVuLCBmb3IgaW5zdGFuY2UsIG5lc3RpbmcgbmdSZXBlYXRzLgogKgogKiAjIFNwZWNpYWwgcmVwZWF0IHN0YXJ0IGFuZCBlbmQgcG9pbnRzCiAqIFRvIHJlcGVhdCBhIHNlcmllcyBvZiBlbGVtZW50cyBpbnN0ZWFkIG9mIGp1c3Qgb25lIHBhcmVudCBlbGVtZW50LCBuZ1JlcGVhdCAoYXMgd2VsbCBhcyBvdGhlciBuZyBkaXJlY3RpdmVzKSBzdXBwb3J0cyBleHRlbmRpbmcKICogdGhlIHJhbmdlIG9mIHRoZSByZXBlYXRlciBieSBkZWZpbmluZyBleHBsaWNpdCBzdGFydCBhbmQgZW5kIHBvaW50cyBieSB1c2luZyAqKm5nLXJlcGVhdC1zdGFydCoqIGFuZCAqKm5nLXJlcGVhdC1lbmQqKiByZXNwZWN0aXZlbHkuCiAqIFRoZSAqKm5nLXJlcGVhdC1zdGFydCoqIGRpcmVjdGl2ZSB3b3JrcyB0aGUgc2FtZSBhcyAqKm5nLXJlcGVhdCoqLCBidXQgd2lsbCByZXBlYXQgYWxsIHRoZSBIVE1MIGNvZGUgKGluY2x1ZGluZyB0aGUgdGFnIGl0J3MgZGVmaW5lZCBvbikKICogdXAgdG8gYW5kIGluY2x1ZGluZyB0aGUgZW5kaW5nIEhUTUwgdGFnIHdoZXJlICoqbmctcmVwZWF0LWVuZCoqIGlzIHBsYWNlZC4KICoKICogVGhlIGV4YW1wbGUgYmVsb3cgbWFrZXMgdXNlIG9mIHRoaXMgZmVhdHVyZToKICogYGBgaHRtbAogKiAgIDxoZWFkZXIgbmctcmVwZWF0LXN0YXJ0PSJpdGVtIGluIGl0ZW1zIj4KICogICAgIEhlYWRlciB7eyBpdGVtIH19CiAqICAgPC9oZWFkZXI+CiAqICAgPGRpdiBjbGFzcz0iYm9keSI+CiAqICAgICBCb2R5IHt7IGl0ZW0gfX0KICogICA8L2Rpdj4KICogICA8Zm9vdGVyIG5nLXJlcGVhdC1lbmQ+CiAqICAgICBGb290ZXIge3sgaXRlbSB9fQogKiAgIDwvZm9vdGVyPgogKiBgYGAKICoKICogQW5kIHdpdGggYW4gaW5wdXQgb2Yge0B0eXBlIFsnQScsJ0InXX0gZm9yIHRoZSBpdGVtcyB2YXJpYWJsZSBpbiB0aGUgZXhhbXBsZSBhYm92ZSwgdGhlIG91dHB1dCB3aWxsIGV2YWx1YXRlIHRvOgogKiBgYGBodG1sCiAqICAgPGhlYWRlcj4KICogICAgIEhlYWRlciBBCiAqICAgPC9oZWFkZXI+CiAqICAgPGRpdiBjbGFzcz0iYm9keSI+CiAqICAgICBCb2R5IEEKICogICA8L2Rpdj4KICogICA8Zm9vdGVyPgogKiAgICAgRm9vdGVyIEEKICogICA8L2Zvb3Rlcj4KICogICA8aGVhZGVyPgogKiAgICAgSGVhZGVyIEIKICogICA8L2hlYWRlcj4KICogICA8ZGl2IGNsYXNzPSJib2R5Ij4KICogICAgIEJvZHkgQgogKiAgIDwvZGl2PgogKiAgIDxmb290ZXI+CiAqICAgICBGb290ZXIgQgogKiAgIDwvZm9vdGVyPgogKiBgYGAKICoKICogVGhlIGN1c3RvbSBzdGFydCBhbmQgZW5kIHBvaW50cyBmb3IgbmdSZXBlYXQgYWxzbyBzdXBwb3J0IGFsbCBvdGhlciBIVE1MIGRpcmVjdGl2ZSBzeW50YXggZmxhdm9ycyBwcm92aWRlZCBpbiBBbmd1bGFySlMgKHN1Y2gKICogYXMgKipkYXRhLW5nLXJlcGVhdC1zdGFydCoqLCAqKngtbmctcmVwZWF0LXN0YXJ0KiogYW5kICoqbmc6cmVwZWF0LXN0YXJ0KiopLgogKgogKiBAYW5pbWF0aW9ucwogKiAqKi5lbnRlcioqIC0gd2hlbiBhIG5ldyBpdGVtIGlzIGFkZGVkIHRvIHRoZSBsaXN0IG9yIHdoZW4gYW4gaXRlbSBpcyByZXZlYWxlZCBhZnRlciBhIGZpbHRlcgogKgogKiAqKi5sZWF2ZSoqIC0gd2hlbiBhbiBpdGVtIGlzIHJlbW92ZWQgZnJvbSB0aGUgbGlzdCBvciB3aGVuIGFuIGl0ZW0gaXMgZmlsdGVyZWQgb3V0CiAqCiAqICoqLm1vdmUqKiAtIHdoZW4gYW4gYWRqYWNlbnQgaXRlbSBpcyBmaWx0ZXJlZCBvdXQgY2F1c2luZyBhIHJlb3JkZXIgb3Igd2hlbiB0aGUgaXRlbSBjb250ZW50cyBhcmUgcmVvcmRlcmVkCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAc2NvcGUKICogQHByaW9yaXR5IDEwMDAKICogQHBhcmFtIHtyZXBlYXRfZXhwcmVzc2lvbn0gbmdSZXBlYXQgVGhlIGV4cHJlc3Npb24gaW5kaWNhdGluZyBob3cgdG8gZW51bWVyYXRlIGEgY29sbGVjdGlvbi4gVGhlc2UKICogICBmb3JtYXRzIGFyZSBjdXJyZW50bHkgc3VwcG9ydGVkOgogKgogKiAgICogYHZhcmlhYmxlIGluIGV4cHJlc3Npb25gIOKAPyB3aGVyZSB2YXJpYWJsZSBpcyB0aGUgdXNlciBkZWZpbmVkIGxvb3AgdmFyaWFibGUgYW5kIGBleHByZXNzaW9uYAogKiAgICAgaXMgYSBzY29wZSBleHByZXNzaW9uIGdpdmluZyB0aGUgY29sbGVjdGlvbiB0byBlbnVtZXJhdGUuCiAqCiAqICAgICBGb3IgZXhhbXBsZTogYGFsYnVtIGluIGFydGlzdC5hbGJ1bXNgLgogKgogKiAgICogYChrZXksIHZhbHVlKSBpbiBleHByZXNzaW9uYCDigD8gd2hlcmUgYGtleWAgYW5kIGB2YWx1ZWAgY2FuIGJlIGFueSB1c2VyIGRlZmluZWQgaWRlbnRpZmllcnMsCiAqICAgICBhbmQgYGV4cHJlc3Npb25gIGlzIHRoZSBzY29wZSBleHByZXNzaW9uIGdpdmluZyB0aGUgY29sbGVjdGlvbiB0byBlbnVtZXJhdGUuCiAqCiAqICAgICBGb3IgZXhhbXBsZTogYChuYW1lLCBhZ2UpIGluIHsnYWRhbSc6MTAsICdhbWFsaWUnOjEyfWAuCiAqCiAqICAgKiBgdmFyaWFibGUgaW4gZXhwcmVzc2lvbiB0cmFjayBieSB0cmFja2luZ19leHByZXNzaW9uYCDigD8gWW91IGNhbiBhbHNvIHByb3ZpZGUgYW4gb3B0aW9uYWwgdHJhY2tpbmcgZnVuY3Rpb24KICogICAgIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGFzc29jaWF0ZSB0aGUgb2JqZWN0cyBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSBET00gZWxlbWVudHMuIElmIG5vIHRyYWNraW5nIGZ1bmN0aW9uCiAqICAgICBpcyBzcGVjaWZpZWQgdGhlIG5nLXJlcGVhdCBhc3NvY2lhdGVzIGVsZW1lbnRzIGJ5IGlkZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uLiBJdCBpcyBhbiBlcnJvciB0byBoYXZlCiAqICAgICBtb3JlIHRoYW4gb25lIHRyYWNraW5nIGZ1bmN0aW9uIHRvIHJlc29sdmUgdG8gdGhlIHNhbWUga2V5LiAoVGhpcyB3b3VsZCBtZWFuIHRoYXQgdHdvIGRpc3RpbmN0IG9iamVjdHMgYXJlCiAqICAgICBtYXBwZWQgdG8gdGhlIHNhbWUgRE9NIGVsZW1lbnQsIHdoaWNoIGlzIG5vdCBwb3NzaWJsZS4pICBGaWx0ZXJzIHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoZSBleHByZXNzaW9uLAogKiAgICAgYmVmb3JlIHNwZWNpZnlpbmcgYSB0cmFja2luZyBleHByZXNzaW9uLgogKgogKiAgICAgRm9yIGV4YW1wbGU6IGBpdGVtIGluIGl0ZW1zYCBpcyBlcXVpdmFsZW50IHRvIGBpdGVtIGluIGl0ZW1zIHRyYWNrIGJ5ICRpZChpdGVtKWAuIFRoaXMgaW1wbGllcyB0aGF0IHRoZSBET00gZWxlbWVudHMKICogICAgIHdpbGwgYmUgYXNzb2NpYXRlZCBieSBpdGVtIGlkZW50aXR5IGluIHRoZSBhcnJheS4KICoKICogICAgIEZvciBleGFtcGxlOiBgaXRlbSBpbiBpdGVtcyB0cmFjayBieSAkaWQoaXRlbSlgLiBBIGJ1aWx0IGluIGAkaWQoKWAgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gYXNzaWduIGEgdW5pcXVlCiAqICAgICBgJCRoYXNoS2V5YCBwcm9wZXJ0eSB0byBlYWNoIGl0ZW0gaW4gdGhlIGFycmF5LiBUaGlzIHByb3BlcnR5IGlzIHRoZW4gdXNlZCBhcyBhIGtleSB0byBhc3NvY2lhdGVkIERPTSBlbGVtZW50cwogKiAgICAgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBpdGVtIGluIHRoZSBhcnJheSBieSBpZGVudGl0eS4gTW92aW5nIHRoZSBzYW1lIG9iamVjdCBpbiBhcnJheSB3b3VsZCBtb3ZlIHRoZSBET00KICogICAgIGVsZW1lbnQgaW4gdGhlIHNhbWUgd2F5IGluIHRoZSBET00uCiAqCiAqICAgICBGb3IgZXhhbXBsZTogYGl0ZW0gaW4gaXRlbXMgdHJhY2sgYnkgaXRlbS5pZGAgaXMgYSB0eXBpY2FsIHBhdHRlcm4gd2hlbiB0aGUgaXRlbXMgY29tZSBmcm9tIHRoZSBkYXRhYmFzZS4gSW4gdGhpcwogKiAgICAgY2FzZSB0aGUgb2JqZWN0IGlkZW50aXR5IGRvZXMgbm90IG1hdHRlci4gVHdvIG9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZXF1aXZhbGVudCBhcyBsb25nIGFzIHRoZWlyIGBpZGAKICogICAgIHByb3BlcnR5IGlzIHNhbWUuCiAqCiAqICAgICBGb3IgZXhhbXBsZTogYGl0ZW0gaW4gaXRlbXMgfCBmaWx0ZXI6c2VhcmNoVGV4dCB0cmFjayBieSBpdGVtLmlkYCBpcyBhIHBhdHRlcm4gdGhhdCBtaWdodCBiZSB1c2VkIHRvIGFwcGx5IGEgZmlsdGVyCiAqICAgICB0byBpdGVtcyBpbiBjb25qdW5jdGlvbiB3aXRoIGEgdHJhY2tpbmcgZXhwcmVzc2lvbi4KICoKICogICAqIGB2YXJpYWJsZSBpbiBleHByZXNzaW9uIGFzIGFsaWFzX2V4cHJlc3Npb25gIOKAPyBZb3UgY2FuIGFsc28gcHJvdmlkZSBhbiBvcHRpb25hbCBhbGlhcyBleHByZXNzaW9uIHdoaWNoIHdpbGwgdGhlbiBzdG9yZSB0aGUKICogICAgIGludGVybWVkaWF0ZSByZXN1bHRzIG9mIHRoZSByZXBlYXRlciBhZnRlciB0aGUgZmlsdGVycyBoYXZlIGJlZW4gYXBwbGllZC4gVHlwaWNhbGx5IHRoaXMgaXMgdXNlZCB0byByZW5kZXIgYSBzcGVjaWFsIG1lc3NhZ2UKICogICAgIHdoZW4gYSBmaWx0ZXIgaXMgYWN0aXZlIG9uIHRoZSByZXBlYXRlciwgYnV0IHRoZSBmaWx0ZXJlZCByZXN1bHQgc2V0IGlzIGVtcHR5LgogKgogKiAgICAgRm9yIGV4YW1wbGU6IGBpdGVtIGluIGl0ZW1zIHwgZmlsdGVyOnggYXMgcmVzdWx0c2Agd2lsbCBzdG9yZSB0aGUgZnJhZ21lbnQgb2YgdGhlIHJlcGVhdGVkIGl0ZW1zIGFzIGByZXN1bHRzYCwgYnV0IG9ubHkgYWZ0ZXIKICogICAgIHRoZSBpdGVtcyBoYXZlIGJlZW4gcHJvY2Vzc2VkIHRocm91Z2ggdGhlIGZpbHRlci4KICoKICogQGV4YW1wbGUKICogVGhpcyBleGFtcGxlIGluaXRpYWxpemVzIHRoZSBzY29wZSB0byBhIGxpc3Qgb2YgbmFtZXMgYW5kCiAqIHRoZW4gdXNlcyBgbmdSZXBlYXRgIHRvIGRpc3BsYXkgZXZlcnkgcGVyc29uOgogIDxleGFtcGxlIG1vZHVsZT0ibmdBbmltYXRlIiBkZXBzPSJhbmd1bGFyLWFuaW1hdGUuanMiIGFuaW1hdGlvbnM9InRydWUiPgogICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxkaXYgbmctaW5pdD0iZnJpZW5kcyA9IFsKICAgICAgICB7bmFtZTonSm9obicsIGFnZToyNSwgZ2VuZGVyOidib3knfSwKICAgICAgICB7bmFtZTonSmVzc2llJywgYWdlOjMwLCBnZW5kZXI6J2dpcmwnfSwKICAgICAgICB7bmFtZTonSm9oYW5uYScsIGFnZToyOCwgZ2VuZGVyOidnaXJsJ30sCiAgICAgICAge25hbWU6J0pveScsIGFnZToxNSwgZ2VuZGVyOidnaXJsJ30sCiAgICAgICAge25hbWU6J01hcnknLCBhZ2U6MjgsIGdlbmRlcjonZ2lybCd9LAogICAgICAgIHtuYW1lOidQZXRlcicsIGFnZTo5NSwgZ2VuZGVyOidib3knfSwKICAgICAgICB7bmFtZTonU2ViYXN0aWFuJywgYWdlOjUwLCBnZW5kZXI6J2JveSd9LAogICAgICAgIHtuYW1lOidFcmlrYScsIGFnZToyNywgZ2VuZGVyOidnaXJsJ30sCiAgICAgICAge25hbWU6J1BhdHJpY2snLCBhZ2U6NDAsIGdlbmRlcjonYm95J30sCiAgICAgICAge25hbWU6J1NhbWFudGhhJywgYWdlOjYwLCBnZW5kZXI6J2dpcmwnfQogICAgICBdIj4KICAgICAgICBJIGhhdmUge3tmcmllbmRzLmxlbmd0aH19IGZyaWVuZHMuIFRoZXkgYXJlOgogICAgICAgIDxpbnB1dCB0eXBlPSJzZWFyY2giIG5nLW1vZGVsPSJxIiBwbGFjZWhvbGRlcj0iZmlsdGVyIGZyaWVuZHMuLi4iIC8+CiAgICAgICAgPHVsIGNsYXNzPSJleGFtcGxlLWFuaW1hdGUtY29udGFpbmVyIj4KICAgICAgICAgIDxsaSBjbGFzcz0iYW5pbWF0ZS1yZXBlYXQiIG5nLXJlcGVhdD0iZnJpZW5kIGluIGZyaWVuZHMgfCBmaWx0ZXI6cSBhcyByZXN1bHRzIj4KICAgICAgICAgICAgW3t7JGluZGV4ICsgMX19XSB7e2ZyaWVuZC5uYW1lfX0gd2hvIGlzIHt7ZnJpZW5kLmFnZX19IHllYXJzIG9sZC4KICAgICAgICAgIDwvbGk+CiAgICAgICAgICA8bGkgY2xhc3M9ImFuaW1hdGUtcmVwZWF0IiBuZy1pZj0icmVzdWx0cy5sZW5ndGggPT0gMCI+CiAgICAgICAgICAgIDxzdHJvbmc+Tm8gcmVzdWx0cyBmb3VuZC4uLjwvc3Ryb25nPgogICAgICAgICAgPC9saT4KICAgICAgICA8L3VsPgogICAgICA8L2Rpdj4KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImFuaW1hdGlvbnMuY3NzIj4KICAgICAgLmV4YW1wbGUtYW5pbWF0ZS1jb250YWluZXIgewogICAgICAgIGJhY2tncm91bmQ6d2hpdGU7CiAgICAgICAgYm9yZGVyOjFweCBzb2xpZCBibGFjazsKICAgICAgICBsaXN0LXN0eWxlOm5vbmU7CiAgICAgICAgbWFyZ2luOjA7CiAgICAgICAgcGFkZGluZzowIDEwcHg7CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLXJlcGVhdCB7CiAgICAgICAgbGluZS1oZWlnaHQ6NDBweDsKICAgICAgICBsaXN0LXN0eWxlOm5vbmU7CiAgICAgICAgYm94LXNpemluZzpib3JkZXItYm94OwogICAgICB9CgogICAgICAuYW5pbWF0ZS1yZXBlYXQubmctbW92ZSwKICAgICAgLmFuaW1hdGUtcmVwZWF0Lm5nLWVudGVyLAogICAgICAuYW5pbWF0ZS1yZXBlYXQubmctbGVhdmUgewogICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbjphbGwgbGluZWFyIDAuNXM7CiAgICAgICAgdHJhbnNpdGlvbjphbGwgbGluZWFyIDAuNXM7CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLXJlcGVhdC5uZy1sZWF2ZS5uZy1sZWF2ZS1hY3RpdmUsCiAgICAgIC5hbmltYXRlLXJlcGVhdC5uZy1tb3ZlLAogICAgICAuYW5pbWF0ZS1yZXBlYXQubmctZW50ZXIgewogICAgICAgIG9wYWNpdHk6MDsKICAgICAgICBtYXgtaGVpZ2h0OjA7CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLXJlcGVhdC5uZy1sZWF2ZSwKICAgICAgLmFuaW1hdGUtcmVwZWF0Lm5nLW1vdmUubmctbW92ZS1hY3RpdmUsCiAgICAgIC5hbmltYXRlLXJlcGVhdC5uZy1lbnRlci5uZy1lbnRlci1hY3RpdmUgewogICAgICAgIG9wYWNpdHk6MTsKICAgICAgICBtYXgtaGVpZ2h0OjQwcHg7CiAgICAgIH0KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICB2YXIgZnJpZW5kcyA9IGVsZW1lbnQuYWxsKGJ5LnJlcGVhdGVyKCdmcmllbmQgaW4gZnJpZW5kcycpKTsKCiAgICAgIGl0KCdzaG91bGQgcmVuZGVyIGluaXRpYWwgZGF0YSBzZXQnLCBmdW5jdGlvbigpIHsKICAgICAgICBleHBlY3QoZnJpZW5kcy5jb3VudCgpKS50b0JlKDEwKTsKICAgICAgICBleHBlY3QoZnJpZW5kcy5nZXQoMCkuZ2V0VGV4dCgpKS50b0VxdWFsKCdbMV0gSm9obiB3aG8gaXMgMjUgeWVhcnMgb2xkLicpOwogICAgICAgIGV4cGVjdChmcmllbmRzLmdldCgxKS5nZXRUZXh0KCkpLnRvRXF1YWwoJ1syXSBKZXNzaWUgd2hvIGlzIDMwIHllYXJzIG9sZC4nKTsKICAgICAgICBleHBlY3QoZnJpZW5kcy5sYXN0KCkuZ2V0VGV4dCgpKS50b0VxdWFsKCdbMTBdIFNhbWFudGhhIHdobyBpcyA2MCB5ZWFycyBvbGQuJyk7CiAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygnZnJpZW5kcy5sZW5ndGgnKSkuZ2V0VGV4dCgpKQogICAgICAgICAgICAudG9NYXRjaCgiSSBoYXZlIDEwIGZyaWVuZHMuIFRoZXkgYXJlOiIpOwogICAgICB9KTsKCiAgICAgICBpdCgnc2hvdWxkIHVwZGF0ZSByZXBlYXRlciB3aGVuIGZpbHRlciBwcmVkaWNhdGUgY2hhbmdlcycsIGZ1bmN0aW9uKCkgewogICAgICAgICBleHBlY3QoZnJpZW5kcy5jb3VudCgpKS50b0JlKDEwKTsKCiAgICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ3EnKSkuc2VuZEtleXMoJ21hJyk7CgogICAgICAgICBleHBlY3QoZnJpZW5kcy5jb3VudCgpKS50b0JlKDIpOwogICAgICAgICBleHBlY3QoZnJpZW5kcy5nZXQoMCkuZ2V0VGV4dCgpKS50b0VxdWFsKCdbMV0gTWFyeSB3aG8gaXMgMjggeWVhcnMgb2xkLicpOwogICAgICAgICBleHBlY3QoZnJpZW5kcy5sYXN0KCkuZ2V0VGV4dCgpKS50b0VxdWFsKCdbMl0gU2FtYW50aGEgd2hvIGlzIDYwIHllYXJzIG9sZC4nKTsKICAgICAgIH0pOwogICAgICA8L2ZpbGU+CiAgICA8L2V4YW1wbGU+CiAqLwp2YXIgbmdSZXBlYXREaXJlY3RpdmUgPSBbJyRwYXJzZScsICckYW5pbWF0ZScsIGZ1bmN0aW9uKCRwYXJzZSwgJGFuaW1hdGUpIHsKICB2YXIgTkdfUkVNT1ZFRCA9ICckJE5HX1JFTU9WRUQnOwogIHZhciBuZ1JlcGVhdE1pbkVyciA9IG1pbkVycignbmdSZXBlYXQnKTsKCiAgdmFyIHVwZGF0ZVNjb3BlID0gZnVuY3Rpb24oc2NvcGUsIGluZGV4LCB2YWx1ZUlkZW50aWZpZXIsIHZhbHVlLCBrZXlJZGVudGlmaWVyLCBrZXksIGFycmF5TGVuZ3RoKSB7CiAgICAvLyBUT0RPKHBlcmYpOiBnZW5lcmF0ZSBzZXR0ZXJzIHRvIHNoYXZlIG9mZiB+NDBtcyBvciAxLTEuNSUKICAgIHNjb3BlW3ZhbHVlSWRlbnRpZmllcl0gPSB2YWx1ZTsKICAgIGlmIChrZXlJZGVudGlmaWVyKSBzY29wZVtrZXlJZGVudGlmaWVyXSA9IGtleTsKICAgIHNjb3BlLiRpbmRleCA9IGluZGV4OwogICAgc2NvcGUuJGZpcnN0ID0gKGluZGV4ID09PSAwKTsKICAgIHNjb3BlLiRsYXN0ID0gKGluZGV4ID09PSAoYXJyYXlMZW5ndGggLSAxKSk7CiAgICBzY29wZS4kbWlkZGxlID0gIShzY29wZS4kZmlyc3QgfHwgc2NvcGUuJGxhc3QpOwogICAgLy8ganNoaW50IGJpdHdpc2U6IGZhbHNlCiAgICBzY29wZS4kb2RkID0gIShzY29wZS4kZXZlbiA9IChpbmRleCYxKSA9PT0gMCk7CiAgICAvLyBqc2hpbnQgYml0d2lzZTogdHJ1ZQogIH07CgogIHZhciBnZXRCbG9ja1N0YXJ0ID0gZnVuY3Rpb24oYmxvY2spIHsKICAgIHJldHVybiBibG9jay5jbG9uZVswXTsKICB9OwoKICB2YXIgZ2V0QmxvY2tFbmQgPSBmdW5jdGlvbihibG9jaykgewogICAgcmV0dXJuIGJsb2NrLmNsb25lW2Jsb2NrLmNsb25lLmxlbmd0aCAtIDFdOwogIH07CgoKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIG11bHRpRWxlbWVudDogdHJ1ZSwKICAgIHRyYW5zY2x1ZGU6ICdlbGVtZW50JywKICAgIHByaW9yaXR5OiAxMDAwLAogICAgdGVybWluYWw6IHRydWUsCiAgICAkJHRsYjogdHJ1ZSwKICAgIGNvbXBpbGU6IGZ1bmN0aW9uIG5nUmVwZWF0Q29tcGlsZSgkZWxlbWVudCwgJGF0dHIpIHsKICAgICAgdmFyIGV4cHJlc3Npb24gPSAkYXR0ci5uZ1JlcGVhdDsKICAgICAgdmFyIG5nUmVwZWF0RW5kQ29tbWVudCA9IGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoJyBlbmQgbmdSZXBlYXQ6ICcgKyBleHByZXNzaW9uICsgJyAnKTsKCiAgICAgIHZhciBtYXRjaCA9IGV4cHJlc3Npb24ubWF0Y2goL15ccyooW1xzXFNdKz8pXHMraW5ccysoW1xzXFNdKz8pKD86XHMrYXNccysoW1xzXFNdKz8pKT8oPzpccyt0cmFja1xzK2J5XHMrKFtcc1xTXSs/KSk/XHMqJC8pOwoKICAgICAgaWYgKCFtYXRjaCkgewogICAgICAgIHRocm93IG5nUmVwZWF0TWluRXJyKCdpZXhwJywgIkV4cGVjdGVkIGV4cHJlc3Npb24gaW4gZm9ybSBvZiAnX2l0ZW1fIGluIF9jb2xsZWN0aW9uX1sgdHJhY2sgYnkgX2lkX10nIGJ1dCBnb3QgJ3swfScuIiwKICAgICAgICAgICAgZXhwcmVzc2lvbik7CiAgICAgIH0KCiAgICAgIHZhciBsaHMgPSBtYXRjaFsxXTsKICAgICAgdmFyIHJocyA9IG1hdGNoWzJdOwogICAgICB2YXIgYWxpYXNBcyA9IG1hdGNoWzNdOwogICAgICB2YXIgdHJhY2tCeUV4cCA9IG1hdGNoWzRdOwoKICAgICAgbWF0Y2ggPSBsaHMubWF0Y2goL14oPzooXHMqW1wkXHddKyl8XChccyooW1wkXHddKylccyosXHMqKFtcJFx3XSspXHMqXCkpJC8pOwoKICAgICAgaWYgKCFtYXRjaCkgewogICAgICAgIHRocm93IG5nUmVwZWF0TWluRXJyKCdpaWRleHAnLCAiJ19pdGVtXycgaW4gJ19pdGVtXyBpbiBfY29sbGVjdGlvbl8nIHNob3VsZCBiZSBhbiBpZGVudGlmaWVyIG9yICcoX2tleV8sIF92YWx1ZV8pJyBleHByZXNzaW9uLCBidXQgZ290ICd7MH0nLiIsCiAgICAgICAgICAgIGxocyk7CiAgICAgIH0KICAgICAgdmFyIHZhbHVlSWRlbnRpZmllciA9IG1hdGNoWzNdIHx8IG1hdGNoWzFdOwogICAgICB2YXIga2V5SWRlbnRpZmllciA9IG1hdGNoWzJdOwoKICAgICAgaWYgKGFsaWFzQXMgJiYgKCEvXlskYS16QS1aX11bJGEtekEtWjAtOV9dKiQvLnRlc3QoYWxpYXNBcykgfHwKICAgICAgICAgIC9eKG51bGx8dW5kZWZpbmVkfHRoaXN8XCRpbmRleHxcJGZpcnN0fFwkbWlkZGxlfFwkbGFzdHxcJGV2ZW58XCRvZGR8XCRwYXJlbnQpJC8udGVzdChhbGlhc0FzKSkpIHsKICAgICAgICB0aHJvdyBuZ1JlcGVhdE1pbkVycignYmFkaWRlbnQnLCAiYWxpYXMgJ3swfScgaXMgaW52YWxpZCAtLS0gbXVzdCBiZSBhIHZhbGlkIEpTIGlkZW50aWZpZXIgd2hpY2ggaXMgbm90IGEgcmVzZXJ2ZWQgbmFtZS4iLAogICAgICAgICAgYWxpYXNBcyk7CiAgICAgIH0KCiAgICAgIHZhciB0cmFja0J5RXhwR2V0dGVyLCB0cmFja0J5SWRFeHBGbiwgdHJhY2tCeUlkQXJyYXlGbiwgdHJhY2tCeUlkT2JqRm47CiAgICAgIHZhciBoYXNoRm5Mb2NhbHMgPSB7JGlkOiBoYXNoS2V5fTsKCiAgICAgIGlmICh0cmFja0J5RXhwKSB7CiAgICAgICAgdHJhY2tCeUV4cEdldHRlciA9ICRwYXJzZSh0cmFja0J5RXhwKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0cmFja0J5SWRBcnJheUZuID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIGhhc2hLZXkodmFsdWUpOwogICAgICAgIH07CiAgICAgICAgdHJhY2tCeUlkT2JqRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICAgIHJldHVybiBrZXk7CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5nUmVwZWF0TGluaygkc2NvcGUsICRlbGVtZW50LCAkYXR0ciwgY3RybCwgJHRyYW5zY2x1ZGUpIHsKCiAgICAgICAgaWYgKHRyYWNrQnlFeHBHZXR0ZXIpIHsKICAgICAgICAgIHRyYWNrQnlJZEV4cEZuID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSwgaW5kZXgpIHsKICAgICAgICAgICAgLy8gYXNzaWduIGtleSwgdmFsdWUsIGFuZCAkaW5kZXggdG8gdGhlIGxvY2FscyBzbyB0aGF0IHRoZXkgY2FuIGJlIHVzZWQgaW4gaGFzaCBmdW5jdGlvbnMKICAgICAgICAgICAgaWYgKGtleUlkZW50aWZpZXIpIGhhc2hGbkxvY2Fsc1trZXlJZGVudGlmaWVyXSA9IGtleTsKICAgICAgICAgICAgaGFzaEZuTG9jYWxzW3ZhbHVlSWRlbnRpZmllcl0gPSB2YWx1ZTsKICAgICAgICAgICAgaGFzaEZuTG9jYWxzLiRpbmRleCA9IGluZGV4OwogICAgICAgICAgICByZXR1cm4gdHJhY2tCeUV4cEdldHRlcigkc2NvcGUsIGhhc2hGbkxvY2Fscyk7CiAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgLy8gU3RvcmUgYSBsaXN0IG9mIGVsZW1lbnRzIGZyb20gcHJldmlvdXMgcnVuLiBUaGlzIGlzIGEgaGFzaCB3aGVyZSBrZXkgaXMgdGhlIGl0ZW0gZnJvbSB0aGUKICAgICAgICAvLyBpdGVyYXRvciwgYW5kIHRoZSB2YWx1ZSBpcyBvYmplY3RzIHdpdGggZm9sbG93aW5nIHByb3BlcnRpZXMuCiAgICAgICAgLy8gICAtIHNjb3BlOiBib3VuZCBzY29wZQogICAgICAgIC8vICAgLSBlbGVtZW50OiBwcmV2aW91cyBlbGVtZW50LgogICAgICAgIC8vICAgLSBpbmRleDogcG9zaXRpb24KICAgICAgICAvLwogICAgICAgIC8vIFdlIGFyZSB1c2luZyBuby1wcm90byBvYmplY3Qgc28gdGhhdCB3ZSBkb24ndCBuZWVkIHRvIGd1YXJkIGFnYWluc3QgaW5oZXJpdGVkIHByb3BzIHZpYQogICAgICAgIC8vIGhhc093blByb3BlcnR5LgogICAgICAgIHZhciBsYXN0QmxvY2tNYXAgPSBjcmVhdGVNYXAoKTsKCiAgICAgICAgLy93YXRjaCBwcm9wcwogICAgICAgICRzY29wZS4kd2F0Y2hDb2xsZWN0aW9uKHJocywgZnVuY3Rpb24gbmdSZXBlYXRBY3Rpb24oY29sbGVjdGlvbikgewogICAgICAgICAgdmFyIGluZGV4LCBsZW5ndGgsCiAgICAgICAgICAgICAgcHJldmlvdXNOb2RlID0gJGVsZW1lbnRbMF0sICAgICAvLyBub2RlIHRoYXQgY2xvbmVkIG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBhZnRlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZWQgdG8gdGhlIGNvbW1lbnQgbm9kZSBhbmNob3IKICAgICAgICAgICAgICBuZXh0Tm9kZSwKICAgICAgICAgICAgICAvLyBTYW1lIGFzIGxhc3RCbG9ja01hcCBidXQgaXQgaGFzIHRoZSBjdXJyZW50IHN0YXRlLiBJdCB3aWxsIGJlY29tZSB0aGUKICAgICAgICAgICAgICAvLyBsYXN0QmxvY2tNYXAgb24gdGhlIG5leHQgaXRlcmF0aW9uLgogICAgICAgICAgICAgIG5leHRCbG9ja01hcCA9IGNyZWF0ZU1hcCgpLAogICAgICAgICAgICAgIGNvbGxlY3Rpb25MZW5ndGgsCiAgICAgICAgICAgICAga2V5LCB2YWx1ZSwgLy8ga2V5L3ZhbHVlIG9mIGl0ZXJhdGlvbgogICAgICAgICAgICAgIHRyYWNrQnlJZCwKICAgICAgICAgICAgICB0cmFja0J5SWRGbiwKICAgICAgICAgICAgICBjb2xsZWN0aW9uS2V5cywKICAgICAgICAgICAgICBibG9jaywgICAgICAgLy8gbGFzdCBvYmplY3QgaW5mb3JtYXRpb24ge3Njb3BlLCBlbGVtZW50LCBpZH0KICAgICAgICAgICAgICBuZXh0QmxvY2tPcmRlciwKICAgICAgICAgICAgICBlbGVtZW50c1RvUmVtb3ZlOwoKICAgICAgICAgIGlmIChhbGlhc0FzKSB7CiAgICAgICAgICAgICRzY29wZVthbGlhc0FzXSA9IGNvbGxlY3Rpb247CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7CiAgICAgICAgICAgIGNvbGxlY3Rpb25LZXlzID0gY29sbGVjdGlvbjsKICAgICAgICAgICAgdHJhY2tCeUlkRm4gPSB0cmFja0J5SWRFeHBGbiB8fCB0cmFja0J5SWRBcnJheUZuOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJhY2tCeUlkRm4gPSB0cmFja0J5SWRFeHBGbiB8fCB0cmFja0J5SWRPYmpGbjsKICAgICAgICAgICAgLy8gaWYgb2JqZWN0LCBleHRyYWN0IGtleXMsIHNvcnQgdGhlbSBhbmQgdXNlIHRvIGRldGVybWluZSBvcmRlciBvZiBpdGVyYXRpb24gb3ZlciBvYmogcHJvcHMKICAgICAgICAgICAgY29sbGVjdGlvbktleXMgPSBbXTsKICAgICAgICAgICAgZm9yICh2YXIgaXRlbUtleSBpbiBjb2xsZWN0aW9uKSB7CiAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb24uaGFzT3duUHJvcGVydHkoaXRlbUtleSkgJiYgaXRlbUtleS5jaGFyQXQoMCkgIT0gJyQnKSB7CiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uS2V5cy5wdXNoKGl0ZW1LZXkpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjb2xsZWN0aW9uS2V5cy5zb3J0KCk7CiAgICAgICAgICB9CgogICAgICAgICAgY29sbGVjdGlvbkxlbmd0aCA9IGNvbGxlY3Rpb25LZXlzLmxlbmd0aDsKICAgICAgICAgIG5leHRCbG9ja09yZGVyID0gbmV3IEFycmF5KGNvbGxlY3Rpb25MZW5ndGgpOwoKICAgICAgICAgIC8vIGxvY2F0ZSBleGlzdGluZyBpdGVtcwogICAgICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgY29sbGVjdGlvbkxlbmd0aDsgaW5kZXgrKykgewogICAgICAgICAgICBrZXkgPSAoY29sbGVjdGlvbiA9PT0gY29sbGVjdGlvbktleXMpID8gaW5kZXggOiBjb2xsZWN0aW9uS2V5c1tpbmRleF07CiAgICAgICAgICAgIHZhbHVlID0gY29sbGVjdGlvbltrZXldOwogICAgICAgICAgICB0cmFja0J5SWQgPSB0cmFja0J5SWRGbihrZXksIHZhbHVlLCBpbmRleCk7CiAgICAgICAgICAgIGlmIChsYXN0QmxvY2tNYXBbdHJhY2tCeUlkXSkgewogICAgICAgICAgICAgIC8vIGZvdW5kIHByZXZpb3VzbHkgc2VlbiBibG9jawogICAgICAgICAgICAgIGJsb2NrID0gbGFzdEJsb2NrTWFwW3RyYWNrQnlJZF07CiAgICAgICAgICAgICAgZGVsZXRlIGxhc3RCbG9ja01hcFt0cmFja0J5SWRdOwogICAgICAgICAgICAgIG5leHRCbG9ja01hcFt0cmFja0J5SWRdID0gYmxvY2s7CiAgICAgICAgICAgICAgbmV4dEJsb2NrT3JkZXJbaW5kZXhdID0gYmxvY2s7CiAgICAgICAgICAgIH0gZWxzZSBpZiAobmV4dEJsb2NrTWFwW3RyYWNrQnlJZF0pIHsKICAgICAgICAgICAgICAvLyBpZiBjb2xsaXNpb24gZGV0ZWN0ZWQuIHJlc3RvcmUgbGFzdEJsb2NrTWFwIGFuZCB0aHJvdyBhbiBlcnJvcgogICAgICAgICAgICAgIGZvckVhY2gobmV4dEJsb2NrT3JkZXIsIGZ1bmN0aW9uKGJsb2NrKSB7CiAgICAgICAgICAgICAgICBpZiAoYmxvY2sgJiYgYmxvY2suc2NvcGUpIGxhc3RCbG9ja01hcFtibG9jay5pZF0gPSBibG9jazsKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB0aHJvdyBuZ1JlcGVhdE1pbkVycignZHVwZXMnLAogICAgICAgICAgICAgICAgICAiRHVwbGljYXRlcyBpbiBhIHJlcGVhdGVyIGFyZSBub3QgYWxsb3dlZC4gVXNlICd0cmFjayBieScgZXhwcmVzc2lvbiB0byBzcGVjaWZ5IHVuaXF1ZSBrZXlzLiBSZXBlYXRlcjogezB9LCBEdXBsaWNhdGUga2V5OiB7MX0sIER1cGxpY2F0ZSB2YWx1ZTogezJ9IiwKICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbiwgdHJhY2tCeUlkLCB2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gbmV3IG5ldmVyIGJlZm9yZSBzZWVuIGJsb2NrCiAgICAgICAgICAgICAgbmV4dEJsb2NrT3JkZXJbaW5kZXhdID0ge2lkOiB0cmFja0J5SWQsIHNjb3BlOiB1bmRlZmluZWQsIGNsb25lOiB1bmRlZmluZWR9OwogICAgICAgICAgICAgIG5leHRCbG9ja01hcFt0cmFja0J5SWRdID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIHJlbW92ZSBsZWZ0b3ZlciBpdGVtcwogICAgICAgICAgZm9yICh2YXIgYmxvY2tLZXkgaW4gbGFzdEJsb2NrTWFwKSB7CiAgICAgICAgICAgIGJsb2NrID0gbGFzdEJsb2NrTWFwW2Jsb2NrS2V5XTsKICAgICAgICAgICAgZWxlbWVudHNUb1JlbW92ZSA9IGdldEJsb2NrTm9kZXMoYmxvY2suY2xvbmUpOwogICAgICAgICAgICAkYW5pbWF0ZS5sZWF2ZShlbGVtZW50c1RvUmVtb3ZlKTsKICAgICAgICAgICAgaWYgKGVsZW1lbnRzVG9SZW1vdmVbMF0ucGFyZW50Tm9kZSkgewogICAgICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IHdhcyBub3QgcmVtb3ZlZCB5ZXQgYmVjYXVzZSBvZiBwZW5kaW5nIGFuaW1hdGlvbiwgbWFyayBpdCBhcyBkZWxldGVkCiAgICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBjYW4gaWdub3JlIGl0IGxhdGVyCiAgICAgICAgICAgICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGVsZW1lbnRzVG9SZW1vdmUubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgewogICAgICAgICAgICAgICAgZWxlbWVudHNUb1JlbW92ZVtpbmRleF1bTkdfUkVNT1ZFRF0gPSB0cnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBibG9jay5zY29wZS4kZGVzdHJveSgpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIHdlIGFyZSBub3QgdXNpbmcgZm9yRWFjaCBmb3IgcGVyZiByZWFzb25zICh0cnlpbmcgdG8gYXZvaWQgI2NhbGwpCiAgICAgICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBjb2xsZWN0aW9uTGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgIGtleSA9IChjb2xsZWN0aW9uID09PSBjb2xsZWN0aW9uS2V5cykgPyBpbmRleCA6IGNvbGxlY3Rpb25LZXlzW2luZGV4XTsKICAgICAgICAgICAgdmFsdWUgPSBjb2xsZWN0aW9uW2tleV07CiAgICAgICAgICAgIGJsb2NrID0gbmV4dEJsb2NrT3JkZXJbaW5kZXhdOwoKICAgICAgICAgICAgaWYgKGJsb2NrLnNjb3BlKSB7CiAgICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZSBhbHJlYWR5IHNlZW4gdGhpcyBvYmplY3QsIHRoZW4gd2UgbmVlZCB0byByZXVzZSB0aGUKICAgICAgICAgICAgICAvLyBhc3NvY2lhdGVkIHNjb3BlL2VsZW1lbnQKCiAgICAgICAgICAgICAgbmV4dE5vZGUgPSBwcmV2aW91c05vZGU7CgogICAgICAgICAgICAgIC8vIHNraXAgbm9kZXMgdGhhdCBhcmUgYWxyZWFkeSBwZW5kaW5nIHJlbW92YWwgdmlhIGxlYXZlIGFuaW1hdGlvbgogICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIG5leHROb2RlID0gbmV4dE5vZGUubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgfSB3aGlsZSAobmV4dE5vZGUgJiYgbmV4dE5vZGVbTkdfUkVNT1ZFRF0pOwoKICAgICAgICAgICAgICBpZiAoZ2V0QmxvY2tTdGFydChibG9jaykgIT0gbmV4dE5vZGUpIHsKICAgICAgICAgICAgICAgIC8vIGV4aXN0aW5nIGl0ZW0gd2hpY2ggZ290IG1vdmVkCiAgICAgICAgICAgICAgICAkYW5pbWF0ZS5tb3ZlKGdldEJsb2NrTm9kZXMoYmxvY2suY2xvbmUpLCBudWxsLCBqcUxpdGUocHJldmlvdXNOb2RlKSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHByZXZpb3VzTm9kZSA9IGdldEJsb2NrRW5kKGJsb2NrKTsKICAgICAgICAgICAgICB1cGRhdGVTY29wZShibG9jay5zY29wZSwgaW5kZXgsIHZhbHVlSWRlbnRpZmllciwgdmFsdWUsIGtleUlkZW50aWZpZXIsIGtleSwgY29sbGVjdGlvbkxlbmd0aCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gbmV3IGl0ZW0gd2hpY2ggd2UgZG9uJ3Qga25vdyBhYm91dAogICAgICAgICAgICAgICR0cmFuc2NsdWRlKGZ1bmN0aW9uIG5nUmVwZWF0VHJhbnNjbHVkZShjbG9uZSwgc2NvcGUpIHsKICAgICAgICAgICAgICAgIGJsb2NrLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgICAgICAvLyBodHRwOi8vanNwZXJmLmNvbS9jbG9uZS12cy1jcmVhdGVjb21tZW50CiAgICAgICAgICAgICAgICB2YXIgZW5kTm9kZSA9IG5nUmVwZWF0RW5kQ29tbWVudC5jbG9uZU5vZGUoZmFsc2UpOwogICAgICAgICAgICAgICAgY2xvbmVbY2xvbmUubGVuZ3RoKytdID0gZW5kTm9kZTsKCiAgICAgICAgICAgICAgICAvLyBUT0RPKHBlcmYpOiBzdXBwb3J0IG5ha2VkIHByZXZpb3VzTm9kZSBpbiBgZW50ZXJgIHRvIGF2b2lkIGNyZWF0aW9uIG9mIGpxTGl0ZSB3cmFwcGVyPwogICAgICAgICAgICAgICAgJGFuaW1hdGUuZW50ZXIoY2xvbmUsIG51bGwsIGpxTGl0ZShwcmV2aW91c05vZGUpKTsKICAgICAgICAgICAgICAgIHByZXZpb3VzTm9kZSA9IGVuZE5vZGU7CiAgICAgICAgICAgICAgICAvLyBOb3RlOiBXZSBvbmx5IG5lZWQgdGhlIGZpcnN0L2xhc3Qgbm9kZSBvZiB0aGUgY2xvbmVkIG5vZGVzLgogICAgICAgICAgICAgICAgLy8gSG93ZXZlciwgd2UgbmVlZCB0byBrZWVwIHRoZSByZWZlcmVuY2UgdG8gdGhlIGpxbGl0ZSB3cmFwcGVyIGFzIGl0IG1pZ2h0IGJlIGNoYW5nZWQgbGF0ZXIKICAgICAgICAgICAgICAgIC8vIGJ5IGEgZGlyZWN0aXZlIHdpdGggdGVtcGxhdGVVcmwgd2hlbiBpdHMgdGVtcGxhdGUgYXJyaXZlcy4KICAgICAgICAgICAgICAgIGJsb2NrLmNsb25lID0gY2xvbmU7CiAgICAgICAgICAgICAgICBuZXh0QmxvY2tNYXBbYmxvY2suaWRdID0gYmxvY2s7CiAgICAgICAgICAgICAgICB1cGRhdGVTY29wZShibG9jay5zY29wZSwgaW5kZXgsIHZhbHVlSWRlbnRpZmllciwgdmFsdWUsIGtleUlkZW50aWZpZXIsIGtleSwgY29sbGVjdGlvbkxlbmd0aCk7CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGxhc3RCbG9ja01hcCA9IG5leHRCbG9ja01hcDsKICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9Owp9XTsKCnZhciBOR19ISURFX0NMQVNTID0gJ25nLWhpZGUnOwp2YXIgTkdfSElERV9JTl9QUk9HUkVTU19DTEFTUyA9ICduZy1oaWRlLWFuaW1hdGUnOwovKioKICogQG5nZG9jIGRpcmVjdGl2ZQogKiBAbmFtZSBuZ1Nob3cKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgbmdTaG93YCBkaXJlY3RpdmUgc2hvd3Mgb3IgaGlkZXMgdGhlIGdpdmVuIEhUTUwgZWxlbWVudCBiYXNlZCBvbiB0aGUgZXhwcmVzc2lvbgogKiBwcm92aWRlZCB0byB0aGUgYG5nU2hvd2AgYXR0cmlidXRlLiBUaGUgZWxlbWVudCBpcyBzaG93biBvciBoaWRkZW4gYnkgcmVtb3Zpbmcgb3IgYWRkaW5nCiAqIHRoZSBgLm5nLWhpZGVgIENTUyBjbGFzcyBvbnRvIHRoZSBlbGVtZW50LiBUaGUgYC5uZy1oaWRlYCBDU1MgY2xhc3MgaXMgcHJlZGVmaW5lZAogKiBpbiBBbmd1bGFySlMgYW5kIHNldHMgdGhlIGRpc3BsYXkgc3R5bGUgdG8gbm9uZSAodXNpbmcgYW4gIWltcG9ydGFudCBmbGFnKS4KICogRm9yIENTUCBtb2RlIHBsZWFzZSBhZGQgYGFuZ3VsYXItY3NwLmNzc2AgdG8geW91ciBodG1sIGZpbGUgKHNlZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQ3NwIG5nQ3NwfSkuCiAqCiAqIGBgYGh0bWwKICogPCEtLSB3aGVuICRzY29wZS5teVZhbHVlIGlzIHRydXRoeSAoZWxlbWVudCBpcyB2aXNpYmxlKSAtLT4KICogPGRpdiBuZy1zaG93PSJteVZhbHVlIj48L2Rpdj4KICoKICogPCEtLSB3aGVuICRzY29wZS5teVZhbHVlIGlzIGZhbHN5IChlbGVtZW50IGlzIGhpZGRlbikgLS0+CiAqIDxkaXYgbmctc2hvdz0ibXlWYWx1ZSIgY2xhc3M9Im5nLWhpZGUiPjwvZGl2PgogKiBgYGAKICoKICogV2hlbiB0aGUgYG5nU2hvd2AgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gYSBmYWxzeSB2YWx1ZSB0aGVuIHRoZSBgLm5nLWhpZGVgIENTUyBjbGFzcyBpcyBhZGRlZCB0byB0aGUgY2xhc3MKICogYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50IGNhdXNpbmcgaXQgdG8gYmVjb21lIGhpZGRlbi4gV2hlbiB0cnV0aHksIHRoZSBgLm5nLWhpZGVgIENTUyBjbGFzcyBpcyByZW1vdmVkCiAqIGZyb20gdGhlIGVsZW1lbnQgY2F1c2luZyB0aGUgZWxlbWVudCBub3QgdG8gYXBwZWFyIGhpZGRlbi4KICoKICogIyMgV2h5IGlzICFpbXBvcnRhbnQgdXNlZD8KICoKICogWW91IG1heSBiZSB3b25kZXJpbmcgd2h5ICFpbXBvcnRhbnQgaXMgdXNlZCBmb3IgdGhlIGAubmctaGlkZWAgQ1NTIGNsYXNzLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGAubmctaGlkZWAgc2VsZWN0b3IKICogY2FuIGJlIGVhc2lseSBvdmVycmlkZGVuIGJ5IGhlYXZpZXIgc2VsZWN0b3JzLiBGb3IgZXhhbXBsZSwgc29tZXRoaW5nIGFzIHNpbXBsZQogKiBhcyBjaGFuZ2luZyB0aGUgZGlzcGxheSBzdHlsZSBvbiBhIEhUTUwgbGlzdCBpdGVtIHdvdWxkIG1ha2UgaGlkZGVuIGVsZW1lbnRzIGFwcGVhciB2aXNpYmxlLgogKiBUaGlzIGFsc28gYmVjb21lcyBhIGJpZ2dlciBpc3N1ZSB3aGVuIGRlYWxpbmcgd2l0aCBDU1MgZnJhbWV3b3Jrcy4KICoKICogQnkgdXNpbmcgIWltcG9ydGFudCwgdGhlIHNob3cgYW5kIGhpZGUgYmVoYXZpb3Igd2lsbCB3b3JrIGFzIGV4cGVjdGVkIGRlc3BpdGUgYW55IGNsYXNoIGJldHdlZW4gQ1NTIHNlbGVjdG9yCiAqIHNwZWNpZmljaXR5ICh3aGVuICFpbXBvcnRhbnQgaXNuJ3QgdXNlZCB3aXRoIGFueSBjb25mbGljdGluZyBzdHlsZXMpLiBJZiBhIGRldmVsb3BlciBjaG9vc2VzIHRvIG92ZXJyaWRlIHRoZQogKiBzdHlsaW5nIHRvIGNoYW5nZSBob3cgdG8gaGlkZSBhbiBlbGVtZW50IHRoZW4gaXQgaXMganVzdCBhIG1hdHRlciBvZiB1c2luZyAhaW1wb3J0YW50IGluIHRoZWlyIG93biBDU1MgY29kZS4KICoKICogIyMjIE92ZXJyaWRpbmcgYC5uZy1oaWRlYAogKgogKiBCeSBkZWZhdWx0LCB0aGUgYC5uZy1oaWRlYCBjbGFzcyB3aWxsIHN0eWxlIHRoZSBlbGVtZW50IHdpdGggYGRpc3BsYXk6IG5vbmUhaW1wb3J0YW50YC4gSWYgeW91IHdpc2ggdG8gY2hhbmdlCiAqIHRoZSBoaWRlIGJlaGF2aW9yIHdpdGggbmdTaG93L25nSGlkZSB0aGVuIHRoaXMgY2FuIGJlIGFjaGlldmVkIGJ5IHJlc3RhdGluZyB0aGUgc3R5bGVzIGZvciB0aGUgYC5uZy1oaWRlYAogKiBjbGFzcyBpbiBDU1M6CiAqCiAqIGBgYGNzcwogKiAubmctaGlkZSB7CiAqICAgLyYjNDI7IHRoaXMgaXMganVzdCBhbm90aGVyIGZvcm0gb2YgaGlkaW5nIGFuIGVsZW1lbnQgJiM0MjsvCiAqICAgZGlzcGxheTogYmxvY2shaW1wb3J0YW50OwogKiAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICogICB0b3A6IC05OTk5cHg7CiAqICAgbGVmdDogLTk5OTlweDsKICogfQogKiBgYGAKICoKICogQnkgZGVmYXVsdCB5b3UgZG9uJ3QgbmVlZCB0byBvdmVycmlkZSBpbiBDU1MgYW55dGhpbmcgYW5kIHRoZSBhbmltYXRpb25zIHdpbGwgd29yayBhcm91bmQgdGhlIGRpc3BsYXkgc3R5bGUuCiAqCiAqICMjIEEgbm90ZSBhYm91dCBhbmltYXRpb25zIHdpdGggYG5nU2hvd2AKICoKICogQW5pbWF0aW9ucyBpbiBuZ1Nob3cvbmdIaWRlIHdvcmsgd2l0aCB0aGUgc2hvdyBhbmQgaGlkZSBldmVudHMgdGhhdCBhcmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGRpcmVjdGl2ZSBleHByZXNzaW9uCiAqIGlzIHRydWUgYW5kIGZhbHNlLiBUaGlzIHN5c3RlbSB3b3JrcyBsaWtlIHRoZSBhbmltYXRpb24gc3lzdGVtIHByZXNlbnQgd2l0aCBuZ0NsYXNzIGV4Y2VwdCB0aGF0CiAqIHlvdSBtdXN0IGFsc28gaW5jbHVkZSB0aGUgIWltcG9ydGFudCBmbGFnIHRvIG92ZXJyaWRlIHRoZSBkaXNwbGF5IHByb3BlcnR5CiAqIHNvIHRoYXQgeW91IGNhbiBwZXJmb3JtIGFuIGFuaW1hdGlvbiB3aGVuIHRoZSBlbGVtZW50IGlzIGhpZGRlbiBkdXJpbmcgdGhlIHRpbWUgb2YgdGhlIGFuaW1hdGlvbi4KICoKICogYGBgY3NzCiAqIC8vCiAqIC8vYSB3b3JraW5nIGV4YW1wbGUgY2FuIGJlIGZvdW5kIGF0IHRoZSBib3R0b20gb2YgdGhpcyBwYWdlCiAqIC8vCiAqIC5teS1lbGVtZW50Lm5nLWhpZGUtYWRkLCAubXktZWxlbWVudC5uZy1oaWRlLXJlbW92ZSB7CiAqICAgLyYjNDI7IHRoaXMgaXMgcmVxdWlyZWQgYXMgb2YgMS4zeCB0byBwcm9wZXJseQogKiAgICAgIGFwcGx5IGFsbCBzdHlsaW5nIGluIGEgc2hvdy9oaWRlIGFuaW1hdGlvbiAmIzQyOy8KICogICB0cmFuc2l0aW9uOiAwcyBsaW5lYXIgYWxsOwogKiB9CiAqCiAqIC5teS1lbGVtZW50Lm5nLWhpZGUtYWRkLWFjdGl2ZSwKICogLm15LWVsZW1lbnQubmctaGlkZS1yZW1vdmUtYWN0aXZlIHsKICogICAvJiM0MjsgdGhlIHRyYW5zaXRpb24gaXMgZGVmaW5lZCBpbiB0aGUgYWN0aXZlIGNsYXNzICYjNDI7LwogKiAgIHRyYW5zaXRpb246IDFzIGxpbmVhciBhbGw7CiAqIH0KICoKICogLm15LWVsZW1lbnQubmctaGlkZS1hZGQgeyAuLi4gfQogKiAubXktZWxlbWVudC5uZy1oaWRlLWFkZC5uZy1oaWRlLWFkZC1hY3RpdmUgeyAuLi4gfQogKiAubXktZWxlbWVudC5uZy1oaWRlLXJlbW92ZSB7IC4uLiB9CiAqIC5teS1lbGVtZW50Lm5nLWhpZGUtcmVtb3ZlLm5nLWhpZGUtcmVtb3ZlLWFjdGl2ZSB7IC4uLiB9CiAqIGBgYAogKgogKiBLZWVwIGluIG1pbmQgdGhhdCwgYXMgb2YgQW5ndWxhckpTIHZlcnNpb24gMS4zLjAtYmV0YS4xMSwgdGhlcmUgaXMgbm8gbmVlZCB0byBjaGFuZ2UgdGhlIGRpc3BsYXkKICogcHJvcGVydHkgdG8gYmxvY2sgZHVyaW5nIGFuaW1hdGlvbiBzdGF0ZXMtLW5nQW5pbWF0ZSB3aWxsIGhhbmRsZSB0aGUgc3R5bGUgdG9nZ2xpbmcgYXV0b21hdGljYWxseSBmb3IgeW91LgogKgogKiBAYW5pbWF0aW9ucwogKiBhZGRDbGFzczogYC5uZy1oaWRlYCAtIGhhcHBlbnMgYWZ0ZXIgdGhlIGBuZ1Nob3dgIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIGEgdHJ1dGh5IHZhbHVlIGFuZCB0aGUganVzdCBiZWZvcmUgY29udGVudHMgYXJlIHNldCB0byB2aXNpYmxlCiAqIHJlbW92ZUNsYXNzOiBgLm5nLWhpZGVgIC0gaGFwcGVucyBhZnRlciB0aGUgYG5nU2hvd2AgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gYSBub24gdHJ1dGh5IHZhbHVlIGFuZCBqdXN0IGJlZm9yZSB0aGUgY29udGVudHMgYXJlIHNldCB0byBoaWRkZW4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdTaG93IElmIHRoZSB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBleHByZXNzaW9ufSBpcyB0cnV0aHkKICogICAgIHRoZW4gdGhlIGVsZW1lbnQgaXMgc2hvd24gb3IgaGlkZGVuIHJlc3BlY3RpdmVseS4KICoKICogQGV4YW1wbGUKICA8ZXhhbXBsZSBtb2R1bGU9Im5nQW5pbWF0ZSIgZGVwcz0iYW5ndWxhci1hbmltYXRlLmpzIiBhbmltYXRpb25zPSJ0cnVlIj4KICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPgogICAgICBDbGljayBtZTogPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuZy1tb2RlbD0iY2hlY2tlZCI+PGJyLz4KICAgICAgPGRpdj4KICAgICAgICBTaG93OgogICAgICAgIDxkaXYgY2xhc3M9ImNoZWNrLWVsZW1lbnQgYW5pbWF0ZS1zaG93IiBuZy1zaG93PSJjaGVja2VkIj4KICAgICAgICAgIDxzcGFuIGNsYXNzPSJnbHlwaGljb24gZ2x5cGhpY29uLXRodW1icy11cCI+PC9zcGFuPiBJIHNob3cgdXAgd2hlbiB5b3VyIGNoZWNrYm94IGlzIGNoZWNrZWQuCiAgICAgICAgPC9kaXY+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2PgogICAgICAgIEhpZGU6CiAgICAgICAgPGRpdiBjbGFzcz0iY2hlY2stZWxlbWVudCBhbmltYXRlLXNob3ciIG5nLWhpZGU9ImNoZWNrZWQiPgogICAgICAgICAgPHNwYW4gY2xhc3M9ImdseXBoaWNvbiBnbHlwaGljb24tdGh1bWJzLWRvd24iPjwvc3Bhbj4gSSBoaWRlIHdoZW4geW91ciBjaGVja2JveCBpcyBjaGVja2VkLgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImdseXBoaWNvbnMuY3NzIj4KICAgICAgQGltcG9ydCB1cmwoLi4vLi4vY29tcG9uZW50cy9ib290c3RyYXAtMy4xLjEvY3NzL2Jvb3RzdHJhcC5jc3MpOwogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0iYW5pbWF0aW9ucy5jc3MiPgogICAgICAuYW5pbWF0ZS1zaG93IHsKICAgICAgICBsaW5lLWhlaWdodDogMjBweDsKICAgICAgICBvcGFjaXR5OiAxOwogICAgICAgIHBhZGRpbmc6IDEwcHg7CiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7CiAgICAgICAgYmFja2dyb3VuZDogd2hpdGU7CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLXNob3cubmctaGlkZS1hZGQubmctaGlkZS1hZGQtYWN0aXZlLAogICAgICAuYW5pbWF0ZS1zaG93Lm5nLWhpZGUtcmVtb3ZlLm5nLWhpZGUtcmVtb3ZlLWFjdGl2ZSB7CiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuNXM7CiAgICAgICAgdHJhbnNpdGlvbjogYWxsIGxpbmVhciAwLjVzOwogICAgICB9CgogICAgICAuYW5pbWF0ZS1zaG93Lm5nLWhpZGUgewogICAgICAgIGxpbmUtaGVpZ2h0OiAwOwogICAgICAgIG9wYWNpdHk6IDA7CiAgICAgICAgcGFkZGluZzogMCAxMHB4OwogICAgICB9CgogICAgICAuY2hlY2stZWxlbWVudCB7CiAgICAgICAgcGFkZGluZzogMTBweDsKICAgICAgICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsKICAgICAgICBiYWNrZ3JvdW5kOiB3aGl0ZTsKICAgICAgfQogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgIHZhciB0aHVtYnNVcCA9IGVsZW1lbnQoYnkuY3NzKCdzcGFuLmdseXBoaWNvbi10aHVtYnMtdXAnKSk7CiAgICAgIHZhciB0aHVtYnNEb3duID0gZWxlbWVudChieS5jc3MoJ3NwYW4uZ2x5cGhpY29uLXRodW1icy1kb3duJykpOwoKICAgICAgaXQoJ3Nob3VsZCBjaGVjayBuZy1zaG93IC8gbmctaGlkZScsIGZ1bmN0aW9uKCkgewogICAgICAgIGV4cGVjdCh0aHVtYnNVcC5pc0Rpc3BsYXllZCgpKS50b0JlRmFsc3koKTsKICAgICAgICBleHBlY3QodGh1bWJzRG93bi5pc0Rpc3BsYXllZCgpKS50b0JlVHJ1dGh5KCk7CgogICAgICAgIGVsZW1lbnQoYnkubW9kZWwoJ2NoZWNrZWQnKSkuY2xpY2soKTsKCiAgICAgICAgZXhwZWN0KHRodW1ic1VwLmlzRGlzcGxheWVkKCkpLnRvQmVUcnV0aHkoKTsKICAgICAgICBleHBlY3QodGh1bWJzRG93bi5pc0Rpc3BsYXllZCgpKS50b0JlRmFsc3koKTsKICAgICAgfSk7CiAgICA8L2ZpbGU+CiAgPC9leGFtcGxlPgogKi8KdmFyIG5nU2hvd0RpcmVjdGl2ZSA9IFsnJGFuaW1hdGUnLCBmdW5jdGlvbigkYW5pbWF0ZSkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0EnLAogICAgbXVsdGlFbGVtZW50OiB0cnVlLAogICAgbGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIpIHsKICAgICAgc2NvcGUuJHdhdGNoKGF0dHIubmdTaG93LCBmdW5jdGlvbiBuZ1Nob3dXYXRjaEFjdGlvbih2YWx1ZSkgewogICAgICAgIC8vIHdlJ3JlIGFkZGluZyBhIHRlbXBvcmFyeSwgYW5pbWF0aW9uLXNwZWNpZmljIGNsYXNzIGZvciBuZy1oaWRlIHNpbmNlIHRoaXMgd2F5CiAgICAgICAgLy8gd2UgY2FuIGNvbnRyb2wgd2hlbiB0aGUgZWxlbWVudCBpcyBhY3R1YWxseSBkaXNwbGF5ZWQgb24gc2NyZWVuIHdpdGhvdXQgaGF2aW5nCiAgICAgICAgLy8gdG8gaGF2ZSBhIGdsb2JhbC9ncmVlZHkgQ1NTIHNlbGVjdG9yIHRoYXQgYnJlYWtzIHdoZW4gb3RoZXIgYW5pbWF0aW9ucyBhcmUgcnVuLgogICAgICAgIC8vIFJlYWQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIuanMvaXNzdWVzLzkxMDMjaXNzdWVjb21tZW50LTU4MzM1ODQ1CiAgICAgICAgJGFuaW1hdGVbdmFsdWUgPyAncmVtb3ZlQ2xhc3MnIDogJ2FkZENsYXNzJ10oZWxlbWVudCwgTkdfSElERV9DTEFTUywgewogICAgICAgICAgdGVtcENsYXNzZXM6IE5HX0hJREVfSU5fUFJPR1JFU1NfQ0xBU1MKICAgICAgICB9KTsKICAgICAgfSk7CiAgICB9CiAgfTsKfV07CgoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdIaWRlCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBUaGUgYG5nSGlkZWAgZGlyZWN0aXZlIHNob3dzIG9yIGhpZGVzIHRoZSBnaXZlbiBIVE1MIGVsZW1lbnQgYmFzZWQgb24gdGhlIGV4cHJlc3Npb24KICogcHJvdmlkZWQgdG8gdGhlIGBuZ0hpZGVgIGF0dHJpYnV0ZS4gVGhlIGVsZW1lbnQgaXMgc2hvd24gb3IgaGlkZGVuIGJ5IHJlbW92aW5nIG9yIGFkZGluZwogKiB0aGUgYG5nLWhpZGVgIENTUyBjbGFzcyBvbnRvIHRoZSBlbGVtZW50LiBUaGUgYC5uZy1oaWRlYCBDU1MgY2xhc3MgaXMgcHJlZGVmaW5lZAogKiBpbiBBbmd1bGFySlMgYW5kIHNldHMgdGhlIGRpc3BsYXkgc3R5bGUgdG8gbm9uZSAodXNpbmcgYW4gIWltcG9ydGFudCBmbGFnKS4KICogRm9yIENTUCBtb2RlIHBsZWFzZSBhZGQgYGFuZ3VsYXItY3NwLmNzc2AgdG8geW91ciBodG1sIGZpbGUgKHNlZSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nQ3NwIG5nQ3NwfSkuCiAqCiAqIGBgYGh0bWwKICogPCEtLSB3aGVuICRzY29wZS5teVZhbHVlIGlzIHRydXRoeSAoZWxlbWVudCBpcyBoaWRkZW4pIC0tPgogKiA8ZGl2IG5nLWhpZGU9Im15VmFsdWUiIGNsYXNzPSJuZy1oaWRlIj48L2Rpdj4KICoKICogPCEtLSB3aGVuICRzY29wZS5teVZhbHVlIGlzIGZhbHN5IChlbGVtZW50IGlzIHZpc2libGUpIC0tPgogKiA8ZGl2IG5nLWhpZGU9Im15VmFsdWUiPjwvZGl2PgogKiBgYGAKICoKICogV2hlbiB0aGUgYG5nSGlkZWAgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gYSB0cnV0aHkgdmFsdWUgdGhlbiB0aGUgYC5uZy1oaWRlYCBDU1MgY2xhc3MgaXMgYWRkZWQgdG8gdGhlIGNsYXNzCiAqIGF0dHJpYnV0ZSBvbiB0aGUgZWxlbWVudCBjYXVzaW5nIGl0IHRvIGJlY29tZSBoaWRkZW4uIFdoZW4gZmFsc3ksIHRoZSBgLm5nLWhpZGVgIENTUyBjbGFzcyBpcyByZW1vdmVkCiAqIGZyb20gdGhlIGVsZW1lbnQgY2F1c2luZyB0aGUgZWxlbWVudCBub3QgdG8gYXBwZWFyIGhpZGRlbi4KICoKICogIyMgV2h5IGlzICFpbXBvcnRhbnQgdXNlZD8KICoKICogWW91IG1heSBiZSB3b25kZXJpbmcgd2h5ICFpbXBvcnRhbnQgaXMgdXNlZCBmb3IgdGhlIGAubmctaGlkZWAgQ1NTIGNsYXNzLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGAubmctaGlkZWAgc2VsZWN0b3IKICogY2FuIGJlIGVhc2lseSBvdmVycmlkZGVuIGJ5IGhlYXZpZXIgc2VsZWN0b3JzLiBGb3IgZXhhbXBsZSwgc29tZXRoaW5nIGFzIHNpbXBsZQogKiBhcyBjaGFuZ2luZyB0aGUgZGlzcGxheSBzdHlsZSBvbiBhIEhUTUwgbGlzdCBpdGVtIHdvdWxkIG1ha2UgaGlkZGVuIGVsZW1lbnRzIGFwcGVhciB2aXNpYmxlLgogKiBUaGlzIGFsc28gYmVjb21lcyBhIGJpZ2dlciBpc3N1ZSB3aGVuIGRlYWxpbmcgd2l0aCBDU1MgZnJhbWV3b3Jrcy4KICoKICogQnkgdXNpbmcgIWltcG9ydGFudCwgdGhlIHNob3cgYW5kIGhpZGUgYmVoYXZpb3Igd2lsbCB3b3JrIGFzIGV4cGVjdGVkIGRlc3BpdGUgYW55IGNsYXNoIGJldHdlZW4gQ1NTIHNlbGVjdG9yCiAqIHNwZWNpZmljaXR5ICh3aGVuICFpbXBvcnRhbnQgaXNuJ3QgdXNlZCB3aXRoIGFueSBjb25mbGljdGluZyBzdHlsZXMpLiBJZiBhIGRldmVsb3BlciBjaG9vc2VzIHRvIG92ZXJyaWRlIHRoZQogKiBzdHlsaW5nIHRvIGNoYW5nZSBob3cgdG8gaGlkZSBhbiBlbGVtZW50IHRoZW4gaXQgaXMganVzdCBhIG1hdHRlciBvZiB1c2luZyAhaW1wb3J0YW50IGluIHRoZWlyIG93biBDU1MgY29kZS4KICoKICogIyMjIE92ZXJyaWRpbmcgYC5uZy1oaWRlYAogKgogKiBCeSBkZWZhdWx0LCB0aGUgYC5uZy1oaWRlYCBjbGFzcyB3aWxsIHN0eWxlIHRoZSBlbGVtZW50IHdpdGggYGRpc3BsYXk6IG5vbmUhaW1wb3J0YW50YC4gSWYgeW91IHdpc2ggdG8gY2hhbmdlCiAqIHRoZSBoaWRlIGJlaGF2aW9yIHdpdGggbmdTaG93L25nSGlkZSB0aGVuIHRoaXMgY2FuIGJlIGFjaGlldmVkIGJ5IHJlc3RhdGluZyB0aGUgc3R5bGVzIGZvciB0aGUgYC5uZy1oaWRlYAogKiBjbGFzcyBpbiBDU1M6CiAqCiAqIGBgYGNzcwogKiAubmctaGlkZSB7CiAqICAgLyYjNDI7IHRoaXMgaXMganVzdCBhbm90aGVyIGZvcm0gb2YgaGlkaW5nIGFuIGVsZW1lbnQgJiM0MjsvCiAqICAgZGlzcGxheTogYmxvY2shaW1wb3J0YW50OwogKiAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICogICB0b3A6IC05OTk5cHg7CiAqICAgbGVmdDogLTk5OTlweDsKICogfQogKiBgYGAKICoKICogQnkgZGVmYXVsdCB5b3UgZG9uJ3QgbmVlZCB0byBvdmVycmlkZSBpbiBDU1MgYW55dGhpbmcgYW5kIHRoZSBhbmltYXRpb25zIHdpbGwgd29yayBhcm91bmQgdGhlIGRpc3BsYXkgc3R5bGUuCiAqCiAqICMjIEEgbm90ZSBhYm91dCBhbmltYXRpb25zIHdpdGggYG5nSGlkZWAKICoKICogQW5pbWF0aW9ucyBpbiBuZ1Nob3cvbmdIaWRlIHdvcmsgd2l0aCB0aGUgc2hvdyBhbmQgaGlkZSBldmVudHMgdGhhdCBhcmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGRpcmVjdGl2ZSBleHByZXNzaW9uCiAqIGlzIHRydWUgYW5kIGZhbHNlLiBUaGlzIHN5c3RlbSB3b3JrcyBsaWtlIHRoZSBhbmltYXRpb24gc3lzdGVtIHByZXNlbnQgd2l0aCBuZ0NsYXNzLCBleGNlcHQgdGhhdCB0aGUgYC5uZy1oaWRlYAogKiBDU1MgY2xhc3MgaXMgYWRkZWQgYW5kIHJlbW92ZWQgZm9yIHlvdSBpbnN0ZWFkIG9mIHlvdXIgb3duIENTUyBjbGFzcy4KICoKICogYGBgY3NzCiAqIC8vCiAqIC8vYSB3b3JraW5nIGV4YW1wbGUgY2FuIGJlIGZvdW5kIGF0IHRoZSBib3R0b20gb2YgdGhpcyBwYWdlCiAqIC8vCiAqIC5teS1lbGVtZW50Lm5nLWhpZGUtYWRkLCAubXktZWxlbWVudC5uZy1oaWRlLXJlbW92ZSB7CiAqICAgdHJhbnNpdGlvbjogMC41cyBsaW5lYXIgYWxsOwogKiB9CiAqCiAqIC5teS1lbGVtZW50Lm5nLWhpZGUtYWRkIHsgLi4uIH0KICogLm15LWVsZW1lbnQubmctaGlkZS1hZGQubmctaGlkZS1hZGQtYWN0aXZlIHsgLi4uIH0KICogLm15LWVsZW1lbnQubmctaGlkZS1yZW1vdmUgeyAuLi4gfQogKiAubXktZWxlbWVudC5uZy1oaWRlLXJlbW92ZS5uZy1oaWRlLXJlbW92ZS1hY3RpdmUgeyAuLi4gfQogKiBgYGAKICoKICogS2VlcCBpbiBtaW5kIHRoYXQsIGFzIG9mIEFuZ3VsYXJKUyB2ZXJzaW9uIDEuMy4wLWJldGEuMTEsIHRoZXJlIGlzIG5vIG5lZWQgdG8gY2hhbmdlIHRoZSBkaXNwbGF5CiAqIHByb3BlcnR5IHRvIGJsb2NrIGR1cmluZyBhbmltYXRpb24gc3RhdGVzLS1uZ0FuaW1hdGUgd2lsbCBoYW5kbGUgdGhlIHN0eWxlIHRvZ2dsaW5nIGF1dG9tYXRpY2FsbHkgZm9yIHlvdS4KICoKICogQGFuaW1hdGlvbnMKICogcmVtb3ZlQ2xhc3M6IGAubmctaGlkZWAgLSBoYXBwZW5zIGFmdGVyIHRoZSBgbmdIaWRlYCBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBhIHRydXRoeSB2YWx1ZSBhbmQganVzdCBiZWZvcmUgdGhlIGNvbnRlbnRzIGFyZSBzZXQgdG8gaGlkZGVuCiAqIGFkZENsYXNzOiBgLm5nLWhpZGVgIC0gaGFwcGVucyBhZnRlciB0aGUgYG5nSGlkZWAgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gYSBub24gdHJ1dGh5IHZhbHVlIGFuZCBqdXN0IGJlZm9yZSB0aGUgY29udGVudHMgYXJlIHNldCB0byB2aXNpYmxlCiAqCiAqIEBlbGVtZW50IEFOWQogKiBAcGFyYW0ge2V4cHJlc3Npb259IG5nSGlkZSBJZiB0aGUge0BsaW5rIGd1aWRlL2V4cHJlc3Npb24gZXhwcmVzc2lvbn0gaXMgdHJ1dGh5IHRoZW4KICogICAgIHRoZSBlbGVtZW50IGlzIHNob3duIG9yIGhpZGRlbiByZXNwZWN0aXZlbHkuCiAqCiAqIEBleGFtcGxlCiAgPGV4YW1wbGUgbW9kdWxlPSJuZ0FuaW1hdGUiIGRlcHM9ImFuZ3VsYXItYW5pbWF0ZS5qcyIgYW5pbWF0aW9ucz0idHJ1ZSI+CiAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgQ2xpY2sgbWU6IDxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmctbW9kZWw9ImNoZWNrZWQiPjxici8+CiAgICAgIDxkaXY+CiAgICAgICAgU2hvdzoKICAgICAgICA8ZGl2IGNsYXNzPSJjaGVjay1lbGVtZW50IGFuaW1hdGUtaGlkZSIgbmctc2hvdz0iY2hlY2tlZCI+CiAgICAgICAgICA8c3BhbiBjbGFzcz0iZ2x5cGhpY29uIGdseXBoaWNvbi10aHVtYnMtdXAiPjwvc3Bhbj4gSSBzaG93IHVwIHdoZW4geW91ciBjaGVja2JveCBpcyBjaGVja2VkLgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgICAgPGRpdj4KICAgICAgICBIaWRlOgogICAgICAgIDxkaXYgY2xhc3M9ImNoZWNrLWVsZW1lbnQgYW5pbWF0ZS1oaWRlIiBuZy1oaWRlPSJjaGVja2VkIj4KICAgICAgICAgIDxzcGFuIGNsYXNzPSJnbHlwaGljb24gZ2x5cGhpY29uLXRodW1icy1kb3duIj48L3NwYW4+IEkgaGlkZSB3aGVuIHlvdXIgY2hlY2tib3ggaXMgY2hlY2tlZC4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJnbHlwaGljb25zLmNzcyI+CiAgICAgIEBpbXBvcnQgdXJsKC4uLy4uL2NvbXBvbmVudHMvYm9vdHN0cmFwLTMuMS4xL2Nzcy9ib290c3RyYXAuY3NzKTsKICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9ImFuaW1hdGlvbnMuY3NzIj4KICAgICAgLmFuaW1hdGUtaGlkZSB7CiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuNXM7CiAgICAgICAgdHJhbnNpdGlvbjogYWxsIGxpbmVhciAwLjVzOwogICAgICAgIGxpbmUtaGVpZ2h0OiAyMHB4OwogICAgICAgIG9wYWNpdHk6IDE7CiAgICAgICAgcGFkZGluZzogMTBweDsKICAgICAgICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsKICAgICAgICBiYWNrZ3JvdW5kOiB3aGl0ZTsKICAgICAgfQoKICAgICAgLmFuaW1hdGUtaGlkZS5uZy1oaWRlIHsKICAgICAgICBsaW5lLWhlaWdodDogMDsKICAgICAgICBvcGFjaXR5OiAwOwogICAgICAgIHBhZGRpbmc6IDAgMTBweDsKICAgICAgfQoKICAgICAgLmNoZWNrLWVsZW1lbnQgewogICAgICAgIHBhZGRpbmc6IDEwcHg7CiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7CiAgICAgICAgYmFja2dyb3VuZDogd2hpdGU7CiAgICAgIH0KICAgIDwvZmlsZT4KICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICB2YXIgdGh1bWJzVXAgPSBlbGVtZW50KGJ5LmNzcygnc3Bhbi5nbHlwaGljb24tdGh1bWJzLXVwJykpOwogICAgICB2YXIgdGh1bWJzRG93biA9IGVsZW1lbnQoYnkuY3NzKCdzcGFuLmdseXBoaWNvbi10aHVtYnMtZG93bicpKTsKCiAgICAgIGl0KCdzaG91bGQgY2hlY2sgbmctc2hvdyAvIG5nLWhpZGUnLCBmdW5jdGlvbigpIHsKICAgICAgICBleHBlY3QodGh1bWJzVXAuaXNEaXNwbGF5ZWQoKSkudG9CZUZhbHN5KCk7CiAgICAgICAgZXhwZWN0KHRodW1ic0Rvd24uaXNEaXNwbGF5ZWQoKSkudG9CZVRydXRoeSgpOwoKICAgICAgICBlbGVtZW50KGJ5Lm1vZGVsKCdjaGVja2VkJykpLmNsaWNrKCk7CgogICAgICAgIGV4cGVjdCh0aHVtYnNVcC5pc0Rpc3BsYXllZCgpKS50b0JlVHJ1dGh5KCk7CiAgICAgICAgZXhwZWN0KHRodW1ic0Rvd24uaXNEaXNwbGF5ZWQoKSkudG9CZUZhbHN5KCk7CiAgICAgIH0pOwogICAgPC9maWxlPgogIDwvZXhhbXBsZT4KICovCnZhciBuZ0hpZGVEaXJlY3RpdmUgPSBbJyRhbmltYXRlJywgZnVuY3Rpb24oJGFuaW1hdGUpIHsKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdBJywKICAgIG11bHRpRWxlbWVudDogdHJ1ZSwKICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyKSB7CiAgICAgIHNjb3BlLiR3YXRjaChhdHRyLm5nSGlkZSwgZnVuY3Rpb24gbmdIaWRlV2F0Y2hBY3Rpb24odmFsdWUpIHsKICAgICAgICAvLyBUaGUgY29tbWVudCBpbnNpZGUgb2YgdGhlIG5nU2hvd0RpcmVjdGl2ZSBleHBsYWlucyB3aHkgd2UgYWRkIGFuZAogICAgICAgIC8vIHJlbW92ZSBhIHRlbXBvcmFyeSBjbGFzcyBmb3IgdGhlIHNob3cvaGlkZSBhbmltYXRpb24KICAgICAgICAkYW5pbWF0ZVt2YWx1ZSA/ICdhZGRDbGFzcycgOiAncmVtb3ZlQ2xhc3MnXShlbGVtZW50LE5HX0hJREVfQ0xBU1MsIHsKICAgICAgICAgIHRlbXBDbGFzc2VzOiBOR19ISURFX0lOX1BST0dSRVNTX0NMQVNTCiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQogIH07Cn1dOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdTdHlsZQogKiBAcmVzdHJpY3QgQUMKICoKICogQGRlc2NyaXB0aW9uCiAqIFRoZSBgbmdTdHlsZWAgZGlyZWN0aXZlIGFsbG93cyB5b3UgdG8gc2V0IENTUyBzdHlsZSBvbiBhbiBIVE1MIGVsZW1lbnQgY29uZGl0aW9uYWxseS4KICoKICogQGVsZW1lbnQgQU5ZCiAqIEBwYXJhbSB7ZXhwcmVzc2lvbn0gbmdTdHlsZQogKgogKiB7QGxpbmsgZ3VpZGUvZXhwcmVzc2lvbiBFeHByZXNzaW9ufSB3aGljaCBldmFscyB0byBhbgogKiBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgQ1NTIHN0eWxlIG5hbWVzIGFuZCB2YWx1ZXMgYXJlIGNvcnJlc3BvbmRpbmcgdmFsdWVzIGZvciB0aG9zZSBDU1MKICoga2V5cy4KICoKICogU2luY2Ugc29tZSBDU1Mgc3R5bGUgbmFtZXMgYXJlIG5vdCB2YWxpZCBrZXlzIGZvciBhbiBvYmplY3QsIHRoZXkgbXVzdCBiZSBxdW90ZWQuCiAqIFNlZSB0aGUgJ2JhY2tncm91bmQtY29sb3InIHN0eWxlIGluIHRoZSBleGFtcGxlIGJlbG93LgogKgogKiBAZXhhbXBsZQogICA8ZXhhbXBsZT4KICAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0ic2V0IGNvbG9yIiBuZy1jbGljaz0ibXlTdHlsZT17Y29sb3I6J3JlZCd9Ij4KICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0ic2V0IGJhY2tncm91bmQiIG5nLWNsaWNrPSJteVN0eWxlPXsnYmFja2dyb3VuZC1jb2xvcic6J2JsdWUnfSI+CiAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9ImNsZWFyIiBuZy1jbGljaz0ibXlTdHlsZT17fSI+CiAgICAgICAgPGJyLz4KICAgICAgICA8c3BhbiBuZy1zdHlsZT0ibXlTdHlsZSI+U2FtcGxlIFRleHQ8L3NwYW4+CiAgICAgICAgPHByZT5teVN0eWxlPXt7bXlTdHlsZX19PC9wcmU+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InN0eWxlLmNzcyI+CiAgICAgICBzcGFuIHsKICAgICAgICAgY29sb3I6IGJsYWNrOwogICAgICAgfQogICAgIDwvZmlsZT4KICAgICA8ZmlsZSBuYW1lPSJwcm90cmFjdG9yLmpzIiB0eXBlPSJwcm90cmFjdG9yIj4KICAgICAgIHZhciBjb2xvclNwYW4gPSBlbGVtZW50KGJ5LmNzcygnc3BhbicpKTsKCiAgICAgICBpdCgnc2hvdWxkIGNoZWNrIG5nLXN0eWxlJywgZnVuY3Rpb24oKSB7CiAgICAgICAgIGV4cGVjdChjb2xvclNwYW4uZ2V0Q3NzVmFsdWUoJ2NvbG9yJykpLnRvQmUoJ3JnYmEoMCwgMCwgMCwgMSknKTsKICAgICAgICAgZWxlbWVudChieS5jc3MoJ2lucHV0W3ZhbHVlPVwnc2V0IGNvbG9yXCddJykpLmNsaWNrKCk7CiAgICAgICAgIGV4cGVjdChjb2xvclNwYW4uZ2V0Q3NzVmFsdWUoJ2NvbG9yJykpLnRvQmUoJ3JnYmEoMjU1LCAwLCAwLCAxKScpOwogICAgICAgICBlbGVtZW50KGJ5LmNzcygnaW5wdXRbdmFsdWU9Y2xlYXJdJykpLmNsaWNrKCk7CiAgICAgICAgIGV4cGVjdChjb2xvclNwYW4uZ2V0Q3NzVmFsdWUoJ2NvbG9yJykpLnRvQmUoJ3JnYmEoMCwgMCwgMCwgMSknKTsKICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKi8KdmFyIG5nU3R5bGVEaXJlY3RpdmUgPSBuZ0RpcmVjdGl2ZShmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0cikgewogIHNjb3BlLiR3YXRjaChhdHRyLm5nU3R5bGUsIGZ1bmN0aW9uIG5nU3R5bGVXYXRjaEFjdGlvbihuZXdTdHlsZXMsIG9sZFN0eWxlcykgewogICAgaWYgKG9sZFN0eWxlcyAmJiAobmV3U3R5bGVzICE9PSBvbGRTdHlsZXMpKSB7CiAgICAgIGZvckVhY2gob2xkU3R5bGVzLCBmdW5jdGlvbih2YWwsIHN0eWxlKSB7IGVsZW1lbnQuY3NzKHN0eWxlLCAnJyk7fSk7CiAgICB9CiAgICBpZiAobmV3U3R5bGVzKSBlbGVtZW50LmNzcyhuZXdTdHlsZXMpOwogIH0sIHRydWUpOwp9KTsKCi8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIG5nU3dpdGNoCiAqIEByZXN0cmljdCBFQQogKgogKiBAZGVzY3JpcHRpb24KICogVGhlIGBuZ1N3aXRjaGAgZGlyZWN0aXZlIGlzIHVzZWQgdG8gY29uZGl0aW9uYWxseSBzd2FwIERPTSBzdHJ1Y3R1cmUgb24geW91ciB0ZW1wbGF0ZSBiYXNlZCBvbiBhIHNjb3BlIGV4cHJlc3Npb24uCiAqIEVsZW1lbnRzIHdpdGhpbiBgbmdTd2l0Y2hgIGJ1dCB3aXRob3V0IGBuZ1N3aXRjaFdoZW5gIG9yIGBuZ1N3aXRjaERlZmF1bHRgIGRpcmVjdGl2ZXMgd2lsbCBiZSBwcmVzZXJ2ZWQgYXQgdGhlIGxvY2F0aW9uCiAqIGFzIHNwZWNpZmllZCBpbiB0aGUgdGVtcGxhdGUuCiAqCiAqIFRoZSBkaXJlY3RpdmUgaXRzZWxmIHdvcmtzIHNpbWlsYXIgdG8gbmdJbmNsdWRlLCBob3dldmVyLCBpbnN0ZWFkIG9mIGRvd25sb2FkaW5nIHRlbXBsYXRlIGNvZGUgKG9yIGxvYWRpbmcgaXQKICogZnJvbSB0aGUgdGVtcGxhdGUgY2FjaGUpLCBgbmdTd2l0Y2hgIHNpbXBseSBjaG9vc2VzIG9uZSBvZiB0aGUgbmVzdGVkIGVsZW1lbnRzIGFuZCBtYWtlcyBpdCB2aXNpYmxlIGJhc2VkIG9uIHdoaWNoIGVsZW1lbnQKICogbWF0Y2hlcyB0aGUgdmFsdWUgb2J0YWluZWQgZnJvbSB0aGUgZXZhbHVhdGVkIGV4cHJlc3Npb24uIEluIG90aGVyIHdvcmRzLCB5b3UgZGVmaW5lIGEgY29udGFpbmVyIGVsZW1lbnQKICogKHdoZXJlIHlvdSBwbGFjZSB0aGUgZGlyZWN0aXZlKSwgcGxhY2UgYW4gZXhwcmVzc2lvbiBvbiB0aGUgKipgb249Ii4uLiJgIGF0dHJpYnV0ZSoqCiAqIChvciB0aGUgKipgbmctc3dpdGNoPSIuLi4iYCBhdHRyaWJ1dGUqKiksIGRlZmluZSBhbnkgaW5uZXIgZWxlbWVudHMgaW5zaWRlIG9mIHRoZSBkaXJlY3RpdmUgYW5kIHBsYWNlCiAqIGEgd2hlbiBhdHRyaWJ1dGUgcGVyIGVsZW1lbnQuIFRoZSB3aGVuIGF0dHJpYnV0ZSBpcyB1c2VkIHRvIGluZm9ybSBuZ1N3aXRjaCB3aGljaCBlbGVtZW50IHRvIGRpc3BsYXkgd2hlbiB0aGUgb24KICogZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQuIElmIGEgbWF0Y2hpbmcgZXhwcmVzc2lvbiBpcyBub3QgZm91bmQgdmlhIGEgd2hlbiBhdHRyaWJ1dGUgdGhlbiBhbiBlbGVtZW50IHdpdGggdGhlIGRlZmF1bHQKICogYXR0cmlidXRlIGlzIGRpc3BsYXllZC4KICoKICogPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CiAqIEJlIGF3YXJlIHRoYXQgdGhlIGF0dHJpYnV0ZSB2YWx1ZXMgdG8gbWF0Y2ggYWdhaW5zdCBjYW5ub3QgYmUgZXhwcmVzc2lvbnMuIFRoZXkgYXJlIGludGVycHJldGVkCiAqIGFzIGxpdGVyYWwgc3RyaW5nIHZhbHVlcyB0byBtYXRjaCBhZ2FpbnN0LgogKiBGb3IgZXhhbXBsZSwgKipgbmctc3dpdGNoLXdoZW49InNvbWVWYWwiYCoqIHdpbGwgbWF0Y2ggYWdhaW5zdCB0aGUgc3RyaW5nIGAic29tZVZhbCJgIG5vdCBhZ2FpbnN0IHRoZQogKiB2YWx1ZSBvZiB0aGUgZXhwcmVzc2lvbiBgJHNjb3BlLnNvbWVWYWxgLgogKiA8L2Rpdj4KCiAqIEBhbmltYXRpb25zCiAqIGVudGVyIC0gaGFwcGVucyBhZnRlciB0aGUgbmdTd2l0Y2ggY29udGVudHMgY2hhbmdlIGFuZCB0aGUgbWF0Y2hlZCBjaGlsZCBlbGVtZW50IGlzIHBsYWNlZCBpbnNpZGUgdGhlIGNvbnRhaW5lcgogKiBsZWF2ZSAtIGhhcHBlbnMganVzdCBhZnRlciB0aGUgbmdTd2l0Y2ggY29udGVudHMgY2hhbmdlIGFuZCBqdXN0IGJlZm9yZSB0aGUgZm9ybWVyIGNvbnRlbnRzIGFyZSByZW1vdmVkIGZyb20gdGhlIERPTQogKgogKiBAdXNhZ2UKICoKICogYGBgCiAqIDxBTlkgbmctc3dpdGNoPSJleHByZXNzaW9uIj4KICogICA8QU5ZIG5nLXN3aXRjaC13aGVuPSJtYXRjaFZhbHVlMSI+Li4uPC9BTlk+CiAqICAgPEFOWSBuZy1zd2l0Y2gtd2hlbj0ibWF0Y2hWYWx1ZTIiPi4uLjwvQU5ZPgogKiAgIDxBTlkgbmctc3dpdGNoLWRlZmF1bHQ+Li4uPC9BTlk+CiAqIDwvQU5ZPgogKiBgYGAKICoKICoKICogQHNjb3BlCiAqIEBwcmlvcml0eSAxMjAwCiAqIEBwYXJhbSB7Kn0gbmdTd2l0Y2h8b24gZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0IDx0dD5uZy1zd2l0Y2gtd2hlbjwvdHQ+LgogKiBPbiBjaGlsZCBlbGVtZW50cyBhZGQ6CiAqCiAqICogYG5nU3dpdGNoV2hlbmA6IHRoZSBjYXNlIHN0YXRlbWVudCB0byBtYXRjaCBhZ2FpbnN0LiBJZiBtYXRjaCB0aGVuIHRoaXMKICogICBjYXNlIHdpbGwgYmUgZGlzcGxheWVkLiBJZiB0aGUgc2FtZSBtYXRjaCBhcHBlYXJzIG11bHRpcGxlIHRpbWVzLCBhbGwgdGhlCiAqICAgZWxlbWVudHMgd2lsbCBiZSBkaXNwbGF5ZWQuCiAqICogYG5nU3dpdGNoRGVmYXVsdGA6IHRoZSBkZWZhdWx0IGNhc2Ugd2hlbiBubyBvdGhlciBjYXNlIG1hdGNoLiBJZiB0aGVyZQogKiAgIGFyZSBtdWx0aXBsZSBkZWZhdWx0IGNhc2VzLCBhbGwgb2YgdGhlbSB3aWxsIGJlIGRpc3BsYXllZCB3aGVuIG5vIG90aGVyCiAqICAgY2FzZSBtYXRjaC4KICoKICoKICogQGV4YW1wbGUKICA8ZXhhbXBsZSBtb2R1bGU9InN3aXRjaEV4YW1wbGUiIGRlcHM9ImFuZ3VsYXItYW5pbWF0ZS5qcyIgYW5pbWF0aW9ucz0idHJ1ZSI+CiAgICA8ZmlsZSBuYW1lPSJpbmRleC5odG1sIj4KICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgPHNlbGVjdCBuZy1tb2RlbD0ic2VsZWN0aW9uIiBuZy1vcHRpb25zPSJpdGVtIGZvciBpdGVtIGluIGl0ZW1zIj4KICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8dHQ+c2VsZWN0aW9uPXt7c2VsZWN0aW9ufX08L3R0PgogICAgICAgIDxoci8+CiAgICAgICAgPGRpdiBjbGFzcz0iYW5pbWF0ZS1zd2l0Y2gtY29udGFpbmVyIgogICAgICAgICAgbmctc3dpdGNoIG9uPSJzZWxlY3Rpb24iPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJhbmltYXRlLXN3aXRjaCIgbmctc3dpdGNoLXdoZW49InNldHRpbmdzIj5TZXR0aW5ncyBEaXY8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYW5pbWF0ZS1zd2l0Y2giIG5nLXN3aXRjaC13aGVuPSJob21lIj5Ib21lIFNwYW48L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYW5pbWF0ZS1zd2l0Y2giIG5nLXN3aXRjaC1kZWZhdWx0PmRlZmF1bHQ8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJzY3JpcHQuanMiPgogICAgICBhbmd1bGFyLm1vZHVsZSgnc3dpdGNoRXhhbXBsZScsIFsnbmdBbmltYXRlJ10pCiAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICRzY29wZS5pdGVtcyA9IFsnc2V0dGluZ3MnLCAnaG9tZScsICdvdGhlciddOwogICAgICAgICAgJHNjb3BlLnNlbGVjdGlvbiA9ICRzY29wZS5pdGVtc1swXTsKICAgICAgICB9XSk7CiAgICA8L2ZpbGU+CiAgICA8ZmlsZSBuYW1lPSJhbmltYXRpb25zLmNzcyI+CiAgICAgIC5hbmltYXRlLXN3aXRjaC1jb250YWluZXIgewogICAgICAgIHBvc2l0aW9uOnJlbGF0aXZlOwogICAgICAgIGJhY2tncm91bmQ6d2hpdGU7CiAgICAgICAgYm9yZGVyOjFweCBzb2xpZCBibGFjazsKICAgICAgICBoZWlnaHQ6NDBweDsKICAgICAgICBvdmVyZmxvdzpoaWRkZW47CiAgICAgIH0KCiAgICAgIC5hbmltYXRlLXN3aXRjaCB7CiAgICAgICAgcGFkZGluZzoxMHB4OwogICAgICB9CgogICAgICAuYW5pbWF0ZS1zd2l0Y2gubmctYW5pbWF0ZSB7CiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOmFsbCBjdWJpYy1iZXppZXIoMC4yNTAsIDAuNDYwLCAwLjQ1MCwgMC45NDApIDAuNXM7CiAgICAgICAgdHJhbnNpdGlvbjphbGwgY3ViaWMtYmV6aWVyKDAuMjUwLCAwLjQ2MCwgMC40NTAsIDAuOTQwKSAwLjVzOwoKICAgICAgICBwb3NpdGlvbjphYnNvbHV0ZTsKICAgICAgICB0b3A6MDsKICAgICAgICBsZWZ0OjA7CiAgICAgICAgcmlnaHQ6MDsKICAgICAgICBib3R0b206MDsKICAgICAgfQoKICAgICAgLmFuaW1hdGUtc3dpdGNoLm5nLWxlYXZlLm5nLWxlYXZlLWFjdGl2ZSwKICAgICAgLmFuaW1hdGUtc3dpdGNoLm5nLWVudGVyIHsKICAgICAgICB0b3A6LTUwcHg7CiAgICAgIH0KICAgICAgLmFuaW1hdGUtc3dpdGNoLm5nLWxlYXZlLAogICAgICAuYW5pbWF0ZS1zd2l0Y2gubmctZW50ZXIubmctZW50ZXItYWN0aXZlIHsKICAgICAgICB0b3A6MDsKICAgICAgfQogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgIHZhciBzd2l0Y2hFbGVtID0gZWxlbWVudChieS5jc3MoJ1tuZy1zd2l0Y2hdJykpOwogICAgICB2YXIgc2VsZWN0ID0gZWxlbWVudChieS5tb2RlbCgnc2VsZWN0aW9uJykpOwoKICAgICAgaXQoJ3Nob3VsZCBzdGFydCBpbiBzZXR0aW5ncycsIGZ1bmN0aW9uKCkgewogICAgICAgIGV4cGVjdChzd2l0Y2hFbGVtLmdldFRleHQoKSkudG9NYXRjaCgvU2V0dGluZ3MgRGl2Lyk7CiAgICAgIH0pOwogICAgICBpdCgnc2hvdWxkIGNoYW5nZSB0byBob21lJywgZnVuY3Rpb24oKSB7CiAgICAgICAgc2VsZWN0LmFsbChieS5jc3MoJ29wdGlvbicpKS5nZXQoMSkuY2xpY2soKTsKICAgICAgICBleHBlY3Qoc3dpdGNoRWxlbS5nZXRUZXh0KCkpLnRvTWF0Y2goL0hvbWUgU3Bhbi8pOwogICAgICB9KTsKICAgICAgaXQoJ3Nob3VsZCBzZWxlY3QgZGVmYXVsdCcsIGZ1bmN0aW9uKCkgewogICAgICAgIHNlbGVjdC5hbGwoYnkuY3NzKCdvcHRpb24nKSkuZ2V0KDIpLmNsaWNrKCk7CiAgICAgICAgZXhwZWN0KHN3aXRjaEVsZW0uZ2V0VGV4dCgpKS50b01hdGNoKC9kZWZhdWx0Lyk7CiAgICAgIH0pOwogICAgPC9maWxlPgogIDwvZXhhbXBsZT4KICovCnZhciBuZ1N3aXRjaERpcmVjdGl2ZSA9IFsnJGFuaW1hdGUnLCBmdW5jdGlvbigkYW5pbWF0ZSkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0VBJywKICAgIHJlcXVpcmU6ICduZ1N3aXRjaCcsCgogICAgLy8gYXNrcyBmb3IgJHNjb3BlIHRvIGZvb2wgdGhlIEJDIGNvbnRyb2xsZXIgbW9kdWxlCiAgICBjb250cm9sbGVyOiBbJyRzY29wZScsIGZ1bmN0aW9uIG5nU3dpdGNoQ29udHJvbGxlcigpIHsKICAgICB0aGlzLmNhc2VzID0ge307CiAgICB9XSwKICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBuZ1N3aXRjaENvbnRyb2xsZXIpIHsKICAgICAgdmFyIHdhdGNoRXhwciA9IGF0dHIubmdTd2l0Y2ggfHwgYXR0ci5vbiwKICAgICAgICAgIHNlbGVjdGVkVHJhbnNjbHVkZXMgPSBbXSwKICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMgPSBbXSwKICAgICAgICAgIHByZXZpb3VzTGVhdmVBbmltYXRpb25zID0gW10sCiAgICAgICAgICBzZWxlY3RlZFNjb3BlcyA9IFtdOwoKICAgICAgdmFyIHNwbGljZUZhY3RvcnkgPSBmdW5jdGlvbihhcnJheSwgaW5kZXgpIHsKICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsgYXJyYXkuc3BsaWNlKGluZGV4LCAxKTsgfTsKICAgICAgfTsKCiAgICAgIHNjb3BlLiR3YXRjaCh3YXRjaEV4cHIsIGZ1bmN0aW9uIG5nU3dpdGNoV2F0Y2hBY3Rpb24odmFsdWUpIHsKICAgICAgICB2YXIgaSwgaWk7CiAgICAgICAgZm9yIChpID0gMCwgaWkgPSBwcmV2aW91c0xlYXZlQW5pbWF0aW9ucy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7CiAgICAgICAgICAkYW5pbWF0ZS5jYW5jZWwocHJldmlvdXNMZWF2ZUFuaW1hdGlvbnNbaV0pOwogICAgICAgIH0KICAgICAgICBwcmV2aW91c0xlYXZlQW5pbWF0aW9ucy5sZW5ndGggPSAwOwoKICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IHNlbGVjdGVkU2NvcGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHsKICAgICAgICAgIHZhciBzZWxlY3RlZCA9IGdldEJsb2NrTm9kZXMoc2VsZWN0ZWRFbGVtZW50c1tpXS5jbG9uZSk7CiAgICAgICAgICBzZWxlY3RlZFNjb3Blc1tpXS4kZGVzdHJveSgpOwogICAgICAgICAgdmFyIHByb21pc2UgPSBwcmV2aW91c0xlYXZlQW5pbWF0aW9uc1tpXSA9ICRhbmltYXRlLmxlYXZlKHNlbGVjdGVkKTsKICAgICAgICAgIHByb21pc2UudGhlbihzcGxpY2VGYWN0b3J5KHByZXZpb3VzTGVhdmVBbmltYXRpb25zLCBpKSk7CiAgICAgICAgfQoKICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9IDA7CiAgICAgICAgc2VsZWN0ZWRTY29wZXMubGVuZ3RoID0gMDsKCiAgICAgICAgaWYgKChzZWxlY3RlZFRyYW5zY2x1ZGVzID0gbmdTd2l0Y2hDb250cm9sbGVyLmNhc2VzWychJyArIHZhbHVlXSB8fCBuZ1N3aXRjaENvbnRyb2xsZXIuY2FzZXNbJz8nXSkpIHsKICAgICAgICAgIGZvckVhY2goc2VsZWN0ZWRUcmFuc2NsdWRlcywgZnVuY3Rpb24oc2VsZWN0ZWRUcmFuc2NsdWRlKSB7CiAgICAgICAgICAgIHNlbGVjdGVkVHJhbnNjbHVkZS50cmFuc2NsdWRlKGZ1bmN0aW9uKGNhc2VFbGVtZW50LCBzZWxlY3RlZFNjb3BlKSB7CiAgICAgICAgICAgICAgc2VsZWN0ZWRTY29wZXMucHVzaChzZWxlY3RlZFNjb3BlKTsKICAgICAgICAgICAgICB2YXIgYW5jaG9yID0gc2VsZWN0ZWRUcmFuc2NsdWRlLmVsZW1lbnQ7CiAgICAgICAgICAgICAgY2FzZUVsZW1lbnRbY2FzZUVsZW1lbnQubGVuZ3RoKytdID0gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgnIGVuZCBuZ1N3aXRjaFdoZW46ICcpOwogICAgICAgICAgICAgIHZhciBibG9jayA9IHsgY2xvbmU6IGNhc2VFbGVtZW50IH07CgogICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMucHVzaChibG9jayk7CiAgICAgICAgICAgICAgJGFuaW1hdGUuZW50ZXIoY2FzZUVsZW1lbnQsIGFuY2hvci5wYXJlbnQoKSwgYW5jaG9yKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogIH07Cn1dOwoKdmFyIG5nU3dpdGNoV2hlbkRpcmVjdGl2ZSA9IG5nRGlyZWN0aXZlKHsKICB0cmFuc2NsdWRlOiAnZWxlbWVudCcsCiAgcHJpb3JpdHk6IDEyMDAsCiAgcmVxdWlyZTogJ15uZ1N3aXRjaCcsCiAgbXVsdGlFbGVtZW50OiB0cnVlLAogIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRycywgY3RybCwgJHRyYW5zY2x1ZGUpIHsKICAgIGN0cmwuY2FzZXNbJyEnICsgYXR0cnMubmdTd2l0Y2hXaGVuXSA9IChjdHJsLmNhc2VzWychJyArIGF0dHJzLm5nU3dpdGNoV2hlbl0gfHwgW10pOwogICAgY3RybC5jYXNlc1snIScgKyBhdHRycy5uZ1N3aXRjaFdoZW5dLnB1c2goeyB0cmFuc2NsdWRlOiAkdHJhbnNjbHVkZSwgZWxlbWVudDogZWxlbWVudCB9KTsKICB9Cn0pOwoKdmFyIG5nU3dpdGNoRGVmYXVsdERpcmVjdGl2ZSA9IG5nRGlyZWN0aXZlKHsKICB0cmFuc2NsdWRlOiAnZWxlbWVudCcsCiAgcHJpb3JpdHk6IDEyMDAsCiAgcmVxdWlyZTogJ15uZ1N3aXRjaCcsCiAgbXVsdGlFbGVtZW50OiB0cnVlLAogIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50LCBhdHRyLCBjdHJsLCAkdHJhbnNjbHVkZSkgewogICAgY3RybC5jYXNlc1snPyddID0gKGN0cmwuY2FzZXNbJz8nXSB8fCBbXSk7CiAgICBjdHJsLmNhc2VzWyc/J10ucHVzaCh7IHRyYW5zY2x1ZGU6ICR0cmFuc2NsdWRlLCBlbGVtZW50OiBlbGVtZW50IH0pOwogICB9Cn0pOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgbmdUcmFuc2NsdWRlCiAqIEByZXN0cmljdCBFQUMKICoKICogQGRlc2NyaXB0aW9uCiAqIERpcmVjdGl2ZSB0aGF0IG1hcmtzIHRoZSBpbnNlcnRpb24gcG9pbnQgZm9yIHRoZSB0cmFuc2NsdWRlZCBET00gb2YgdGhlIG5lYXJlc3QgcGFyZW50IGRpcmVjdGl2ZSB0aGF0IHVzZXMgdHJhbnNjbHVzaW9uLgogKgogKiBBbnkgZXhpc3RpbmcgY29udGVudCBvZiB0aGUgZWxlbWVudCB0aGF0IHRoaXMgZGlyZWN0aXZlIGlzIHBsYWNlZCBvbiB3aWxsIGJlIHJlbW92ZWQgYmVmb3JlIHRoZSB0cmFuc2NsdWRlZCBjb250ZW50IGlzIGluc2VydGVkLgogKgogKiBAZWxlbWVudCBBTlkKICoKICogQGV4YW1wbGUKICAgPGV4YW1wbGUgbW9kdWxlPSJ0cmFuc2NsdWRlRXhhbXBsZSI+CiAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICA8c2NyaXB0PgogICAgICAgICBhbmd1bGFyLm1vZHVsZSgndHJhbnNjbHVkZUV4YW1wbGUnLCBbXSkKICAgICAgICAgIC5kaXJlY3RpdmUoJ3BhbmUnLCBmdW5jdGlvbigpewogICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgcmVzdHJpY3Q6ICdFJywKICAgICAgICAgICAgICAgdHJhbnNjbHVkZTogdHJ1ZSwKICAgICAgICAgICAgICAgc2NvcGU6IHsgdGl0bGU6J0AnIH0sCiAgICAgICAgICAgICAgIHRlbXBsYXRlOiAnPGRpdiBzdHlsZT0iYm9yZGVyOiAxcHggc29saWQgYmxhY2s7Ij4nICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6IGdyYXkiPnt7dGl0bGV9fTwvZGl2PicgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAnPG5nLXRyYW5zY2x1ZGU+PC9uZy10cmFuc2NsdWRlPicgKwogICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicKICAgICAgICAgICAgIH07CiAgICAgICAgIH0pCiAgICAgICAgIC5jb250cm9sbGVyKCdFeGFtcGxlQ29udHJvbGxlcicsIFsnJHNjb3BlJywgZnVuY3Rpb24oJHNjb3BlKSB7CiAgICAgICAgICAgJHNjb3BlLnRpdGxlID0gJ0xvcmVtIElwc3VtJzsKICAgICAgICAgICAkc2NvcGUudGV4dCA9ICdOZXF1ZSBwb3JybyBxdWlzcXVhbSBlc3QgcXVpIGRvbG9yZW0gaXBzdW0gcXVpYSBkb2xvci4uLic7CiAgICAgICAgIH1dKTsKICAgICAgIDwvc2NyaXB0PgogICAgICAgPGRpdiBuZy1jb250cm9sbGVyPSJFeGFtcGxlQ29udHJvbGxlciI+CiAgICAgICAgIDxpbnB1dCBuZy1tb2RlbD0idGl0bGUiPiA8YnIvPgogICAgICAgICA8dGV4dGFyZWEgbmctbW9kZWw9InRleHQiPjwvdGV4dGFyZWE+IDxici8+CiAgICAgICAgIDxwYW5lIHRpdGxlPSJ7e3RpdGxlfX0iPnt7dGV4dH19PC9wYW5lPgogICAgICAgPC9kaXY+CiAgICAgPC9maWxlPgogICAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPgogICAgICAgIGl0KCdzaG91bGQgaGF2ZSB0cmFuc2NsdWRlZCcsIGZ1bmN0aW9uKCkgewogICAgICAgICAgdmFyIHRpdGxlRWxlbWVudCA9IGVsZW1lbnQoYnkubW9kZWwoJ3RpdGxlJykpOwogICAgICAgICAgdGl0bGVFbGVtZW50LmNsZWFyKCk7CiAgICAgICAgICB0aXRsZUVsZW1lbnQuc2VuZEtleXMoJ1RJVExFJyk7CiAgICAgICAgICB2YXIgdGV4dEVsZW1lbnQgPSBlbGVtZW50KGJ5Lm1vZGVsKCd0ZXh0JykpOwogICAgICAgICAgdGV4dEVsZW1lbnQuY2xlYXIoKTsKICAgICAgICAgIHRleHRFbGVtZW50LnNlbmRLZXlzKCdURVhUJyk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCd0aXRsZScpKS5nZXRUZXh0KCkpLnRvRXF1YWwoJ1RJVExFJyk7CiAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCd0ZXh0JykpLmdldFRleHQoKSkudG9FcXVhbCgnVEVYVCcpOwogICAgICAgIH0pOwogICAgIDwvZmlsZT4KICAgPC9leGFtcGxlPgogKgogKi8KdmFyIG5nVHJhbnNjbHVkZURpcmVjdGl2ZSA9IG5nRGlyZWN0aXZlKHsKICByZXN0cmljdDogJ0VBQycsCiAgbGluazogZnVuY3Rpb24oJHNjb3BlLCAkZWxlbWVudCwgJGF0dHJzLCBjb250cm9sbGVyLCAkdHJhbnNjbHVkZSkgewogICAgaWYgKCEkdHJhbnNjbHVkZSkgewogICAgICB0aHJvdyBtaW5FcnIoJ25nVHJhbnNjbHVkZScpKCdvcnBoYW4nLAogICAgICAgJ0lsbGVnYWwgdXNlIG9mIG5nVHJhbnNjbHVkZSBkaXJlY3RpdmUgaW4gdGhlIHRlbXBsYXRlISAnICsKICAgICAgICdObyBwYXJlbnQgZGlyZWN0aXZlIHRoYXQgcmVxdWlyZXMgYSB0cmFuc2NsdXNpb24gZm91bmQuICcgKwogICAgICAgJ0VsZW1lbnQ6IHswfScsCiAgICAgICBzdGFydGluZ1RhZygkZWxlbWVudCkpOwogICAgfQoKICAgICR0cmFuc2NsdWRlKGZ1bmN0aW9uKGNsb25lKSB7CiAgICAgICRlbGVtZW50LmVtcHR5KCk7CiAgICAgICRlbGVtZW50LmFwcGVuZChjbG9uZSk7CiAgICB9KTsKICB9Cn0pOwoKLyoqCiAqIEBuZ2RvYyBkaXJlY3RpdmUKICogQG5hbWUgc2NyaXB0CiAqIEByZXN0cmljdCBFCiAqCiAqIEBkZXNjcmlwdGlvbgogKiBMb2FkIHRoZSBjb250ZW50IG9mIGEgYDxzY3JpcHQ+YCBlbGVtZW50IGludG8ge0BsaW5rIG5nLiR0ZW1wbGF0ZUNhY2hlIGAkdGVtcGxhdGVDYWNoZWB9LCBzbyB0aGF0IHRoZQogKiB0ZW1wbGF0ZSBjYW4gYmUgdXNlZCBieSB7QGxpbmsgbmcuZGlyZWN0aXZlOm5nSW5jbHVkZSBgbmdJbmNsdWRlYH0sCiAqIHtAbGluayBuZ1JvdXRlLmRpcmVjdGl2ZTpuZ1ZpZXcgYG5nVmlld2B9LCBvciB7QGxpbmsgZ3VpZGUvZGlyZWN0aXZlIGRpcmVjdGl2ZXN9LiBUaGUgdHlwZSBvZiB0aGUKICogYDxzY3JpcHQ+YCBlbGVtZW50IG11c3QgYmUgc3BlY2lmaWVkIGFzIGB0ZXh0L25nLXRlbXBsYXRlYCwgYW5kIGEgY2FjaGUgbmFtZSBmb3IgdGhlIHRlbXBsYXRlIG11c3QgYmUKICogYXNzaWduZWQgdGhyb3VnaCB0aGUgZWxlbWVudCdzIGBpZGAsIHdoaWNoIGNhbiB0aGVuIGJlIHVzZWQgYXMgYSBkaXJlY3RpdmUncyBgdGVtcGxhdGVVcmxgLgogKgogKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBNdXN0IGJlIHNldCB0byBgJ3RleHQvbmctdGVtcGxhdGUnYC4KICogQHBhcmFtIHtzdHJpbmd9IGlkIENhY2hlIG5hbWUgb2YgdGhlIHRlbXBsYXRlLgogKgogKiBAZXhhbXBsZQogIDxleGFtcGxlPgogICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgIDxzY3JpcHQgdHlwZT0idGV4dC9uZy10ZW1wbGF0ZSIgaWQ9Ii90cGwuaHRtbCI+CiAgICAgICAgQ29udGVudCBvZiB0aGUgdGVtcGxhdGUuCiAgICAgIDwvc2NyaXB0PgoKICAgICAgPGEgbmctY2xpY2s9ImN1cnJlbnRUcGw9Jy90cGwuaHRtbCciIGlkPSJ0cGwtbGluayI+TG9hZCBpbmxpbmVkIHRlbXBsYXRlPC9hPgogICAgICA8ZGl2IGlkPSJ0cGwtY29udGVudCIgbmctaW5jbHVkZSBzcmM9ImN1cnJlbnRUcGwiPjwvZGl2PgogICAgPC9maWxlPgogICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgIGl0KCdzaG91bGQgbG9hZCB0ZW1wbGF0ZSBkZWZpbmVkIGluc2lkZSBzY3JpcHQgdGFnJywgZnVuY3Rpb24oKSB7CiAgICAgICAgZWxlbWVudChieS5jc3MoJyN0cGwtbGluaycpKS5jbGljaygpOwogICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmNzcygnI3RwbC1jb250ZW50JykpLmdldFRleHQoKSkudG9NYXRjaCgvQ29udGVudCBvZiB0aGUgdGVtcGxhdGUvKTsKICAgICAgfSk7CiAgICA8L2ZpbGU+CiAgPC9leGFtcGxlPgogKi8KdmFyIHNjcmlwdERpcmVjdGl2ZSA9IFsnJHRlbXBsYXRlQ2FjaGUnLCBmdW5jdGlvbigkdGVtcGxhdGVDYWNoZSkgewogIHJldHVybiB7CiAgICByZXN0cmljdDogJ0UnLAogICAgdGVybWluYWw6IHRydWUsCiAgICBjb21waWxlOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyKSB7CiAgICAgIGlmIChhdHRyLnR5cGUgPT0gJ3RleHQvbmctdGVtcGxhdGUnKSB7CiAgICAgICAgdmFyIHRlbXBsYXRlVXJsID0gYXR0ci5pZCwKICAgICAgICAgICAgdGV4dCA9IGVsZW1lbnRbMF0udGV4dDsKCiAgICAgICAgJHRlbXBsYXRlQ2FjaGUucHV0KHRlbXBsYXRlVXJsLCB0ZXh0KTsKICAgICAgfQogICAgfQogIH07Cn1dOwoKdmFyIG5nT3B0aW9uc01pbkVyciA9IG1pbkVycignbmdPcHRpb25zJyk7Ci8qKgogKiBAbmdkb2MgZGlyZWN0aXZlCiAqIEBuYW1lIHNlbGVjdAogKiBAcmVzdHJpY3QgRQogKgogKiBAZGVzY3JpcHRpb24KICogSFRNTCBgU0VMRUNUYCBlbGVtZW50IHdpdGggYW5ndWxhciBkYXRhLWJpbmRpbmcuCiAqCiAqICMgYG5nT3B0aW9uc2AKICoKICogVGhlIGBuZ09wdGlvbnNgIGF0dHJpYnV0ZSBjYW4gYmUgdXNlZCB0byBkeW5hbWljYWxseSBnZW5lcmF0ZSBhIGxpc3Qgb2YgYDxvcHRpb24+YAogKiBlbGVtZW50cyBmb3IgdGhlIGA8c2VsZWN0PmAgZWxlbWVudCB1c2luZyB0aGUgYXJyYXkgb3Igb2JqZWN0IG9idGFpbmVkIGJ5IGV2YWx1YXRpbmcgdGhlCiAqIGBuZ09wdGlvbnNgIGNvbXByZWhlbnNpb24gZXhwcmVzc2lvbi4KICoKICogSW4gbWFueSBjYXNlcywgYG5nUmVwZWF0YCBjYW4gYmUgdXNlZCBvbiBgPG9wdGlvbj5gIGVsZW1lbnRzIGluc3RlYWQgb2YgYG5nT3B0aW9uc2AgdG8gYWNoaWV2ZSBhCiAqIHNpbWlsYXIgcmVzdWx0LiBIb3dldmVyLCBgbmdPcHRpb25zYCBwcm92aWRlcyBzb21lIGJlbmVmaXRzIHN1Y2ggYXMgcmVkdWNpbmcgbWVtb3J5IGFuZAogKiBpbmNyZWFzaW5nIHNwZWVkIGJ5IG5vdCBjcmVhdGluZyBhIG5ldyBzY29wZSBmb3IgZWFjaCByZXBlYXRlZCBpbnN0YW5jZSwgYXMgd2VsbCBhcyBwcm92aWRpbmcKICogbW9yZSBmbGV4aWJpbGl0eSBpbiBob3cgdGhlIGA8c2VsZWN0PmAncyBtb2RlbCBpcyBhc3NpZ25lZCB2aWEgdGhlIGBzZWxlY3RgICoqYGFzYCoqIHBhcnQgb2YgdGhlCiAqIGNvbXByZWhlbnNpb24gZXhwcmVzc2lvbi4gYG5nT3B0aW9uc2Agc2hvdWxkIGJlIHVzZWQgd2hlbiB0aGUgYDxzZWxlY3Q+YCBtb2RlbCBuZWVkcyB0byBiZSBib3VuZAogKiAgdG8gYSBub24tc3RyaW5nIHZhbHVlLiBUaGlzIGlzIGJlY2F1c2UgYW4gb3B0aW9uIGVsZW1lbnQgY2FuIG9ubHkgYmUgYm91bmQgdG8gc3RyaW5nIHZhbHVlcyBhdAogKiBwcmVzZW50LgogKgogKiBXaGVuIGFuIGl0ZW0gaW4gdGhlIGA8c2VsZWN0PmAgbWVudSBpcyBzZWxlY3RlZCwgdGhlIGFycmF5IGVsZW1lbnQgb3Igb2JqZWN0IHByb3BlcnR5CiAqIHJlcHJlc2VudGVkIGJ5IHRoZSBzZWxlY3RlZCBvcHRpb24gd2lsbCBiZSBib3VuZCB0byB0aGUgbW9kZWwgaWRlbnRpZmllZCBieSB0aGUgYG5nTW9kZWxgCiAqIGRpcmVjdGl2ZS4KICoKICogT3B0aW9uYWxseSwgYSBzaW5nbGUgaGFyZC1jb2RlZCBgPG9wdGlvbj5gIGVsZW1lbnQsIHdpdGggdGhlIHZhbHVlIHNldCB0byBhbiBlbXB0eSBzdHJpbmcsIGNhbgogKiBiZSBuZXN0ZWQgaW50byB0aGUgYDxzZWxlY3Q+YCBlbGVtZW50LiBUaGlzIGVsZW1lbnQgd2lsbCB0aGVuIHJlcHJlc2VudCB0aGUgYG51bGxgIG9yICJub3Qgc2VsZWN0ZWQiCiAqIG9wdGlvbi4gU2VlIGV4YW1wbGUgYmVsb3cgZm9yIGRlbW9uc3RyYXRpb24uCiAqCiAqIDxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXdhcm5pbmciPgogKiAqKk5vdGU6KiogYG5nTW9kZWxgIGNvbXBhcmVzIGJ5IHJlZmVyZW5jZSwgbm90IHZhbHVlLiBUaGlzIGlzIGltcG9ydGFudCB3aGVuIGJpbmRpbmcgdG8gYW4KICogYXJyYXkgb2Ygb2JqZWN0cy4gU2VlIGFuIGV4YW1wbGUgW2luIHRoaXMganNmaWRkbGVdKGh0dHA6Ly9qc2ZpZGRsZS5uZXQvcVd6VGIvKS4KICogPC9kaXY+CiAqCiAqICMjIGBzZWxlY3RgICoqYGFzYCoqCiAqCiAqIFVzaW5nIGBzZWxlY3RgICoqYGFzYCoqIHdpbGwgYmluZCB0aGUgcmVzdWx0IG9mIHRoZSBgc2VsZWN0YCBleHByZXNzaW9uIHRvIHRoZSBtb2RlbCwgYnV0CiAqIHRoZSB2YWx1ZSBvZiB0aGUgYDxzZWxlY3Q+YCBhbmQgYDxvcHRpb24+YCBodG1sIGVsZW1lbnRzIHdpbGwgYmUgZWl0aGVyIHRoZSBpbmRleCAoZm9yIGFycmF5IGRhdGEgc291cmNlcykKICogb3IgcHJvcGVydHkgbmFtZSAoZm9yIG9iamVjdCBkYXRhIHNvdXJjZXMpIG9mIHRoZSB2YWx1ZSB3aXRoaW4gdGhlIGNvbGxlY3Rpb24uIElmIGEgKipgdHJhY2sgYnlgKiogZXhwcmVzc2lvbgogKiBpcyB1c2VkLCB0aGUgcmVzdWx0IG9mIHRoYXQgZXhwcmVzc2lvbiB3aWxsIGJlIHNldCBhcyB0aGUgdmFsdWUgb2YgdGhlIGBvcHRpb25gIGFuZCBgc2VsZWN0YCBlbGVtZW50cy4KICoKICoKICogIyMjIGBzZWxlY3RgICoqYGFzYCoqIGFuZCAqKmB0cmFjayBieWAqKgogKgogKiA8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KICogRG8gbm90IHVzZSBgc2VsZWN0YCAqKmBhc2AqKiBhbmQgKipgdHJhY2sgYnlgKiogaW4gdGhlIHNhbWUgZXhwcmVzc2lvbi4gVGhleSBhcmUgbm90IGRlc2lnbmVkIHRvIHdvcmsgdG9nZXRoZXIuCiAqIDwvZGl2PgogKgogKiBDb25zaWRlciB0aGUgZm9sbG93aW5nIGV4YW1wbGU6CiAqCiAqIGBgYGh0bWwKICogPHNlbGVjdCBuZy1vcHRpb25zPSJpdGVtLnN1Ykl0ZW0gYXMgaXRlbS5sYWJlbCBmb3IgaXRlbSBpbiB2YWx1ZXMgdHJhY2sgYnkgaXRlbS5pZCIgbmctbW9kZWw9InNlbGVjdGVkIj4KICogYGBgCiAqCiAqIGBgYGpzCiAqICRzY29wZS52YWx1ZXMgPSBbewogKiAgIGlkOiAxLAogKiAgIGxhYmVsOiAnYUxhYmVsJywKICogICBzdWJJdGVtOiB7IG5hbWU6ICdhU3ViSXRlbScgfQogKiB9LCB7CiAqICAgaWQ6IDIsCiAqICAgbGFiZWw6ICdiTGFiZWwnLAogKiAgIHN1Ykl0ZW06IHsgbmFtZTogJ2JTdWJJdGVtJyB9CiAqIH1dOwogKgogKiAkc2NvcGUuc2VsZWN0ZWQgPSB7IG5hbWU6ICdhU3ViSXRlbScgfTsKICogYGBgCiAqCiAqIFdpdGggdGhlIHB1cnBvc2Ugb2YgcHJlc2VydmluZyB0aGUgc2VsZWN0aW9uLCB0aGUgKipgdHJhY2sgYnlgKiogZXhwcmVzc2lvbiBpcyBhbHdheXMgYXBwbGllZCB0byB0aGUgZWxlbWVudAogKiBvZiB0aGUgZGF0YSBzb3VyY2UgKHRvIGBpdGVtYCBpbiB0aGlzIGV4YW1wbGUpLiBUbyBjYWxjdWxhdGUgd2hldGhlciBhbiBlbGVtZW50IGlzIHNlbGVjdGVkLCB3ZSBkbyB0aGUKICogZm9sbG93aW5nOgogKgogKiAxLiBBcHBseSAqKmB0cmFjayBieWAqKiB0byB0aGUgZWxlbWVudHMgaW4gdGhlIGFycmF5LiBJbiB0aGUgZXhhbXBsZTogYFsxLCAyXWAKICogMi4gQXBwbHkgKipgdHJhY2sgYnlgKiogdG8gdGhlIGFscmVhZHkgc2VsZWN0ZWQgdmFsdWUgaW4gYG5nTW9kZWxgLgogKiAgICBJbiB0aGUgZXhhbXBsZTogdGhpcyBpcyBub3QgcG9zc2libGUgYXMgKipgdHJhY2sgYnlgKiogcmVmZXJzIHRvIGBpdGVtLmlkYCwgYnV0IHRoZSBzZWxlY3RlZAogKiAgICB2YWx1ZSBmcm9tIGBuZ01vZGVsYCBpcyBge25hbWU6ICdhU3ViSXRlbSd9YCwgc28gdGhlICoqYHRyYWNrIGJ5YCoqIGV4cHJlc3Npb24gaXMgYXBwbGllZCB0bwogKiAgICBhIHdyb25nIG9iamVjdCwgdGhlIHNlbGVjdGVkIGVsZW1lbnQgY2FuJ3QgYmUgZm91bmQsIGA8c2VsZWN0PmAgaXMgYWx3YXlzIHJlc2V0IHRvIHRoZSAibm90CiAqICAgIHNlbGVjdGVkIiBvcHRpb24uCiAqCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBuZ01vZGVsIEFzc2lnbmFibGUgYW5ndWxhciBleHByZXNzaW9uIHRvIGRhdGEtYmluZCB0by4KICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIFByb3BlcnR5IG5hbWUgb2YgdGhlIGZvcm0gdW5kZXIgd2hpY2ggdGhlIGNvbnRyb2wgaXMgcHVibGlzaGVkLgogKiBAcGFyYW0ge3N0cmluZz19IHJlcXVpcmVkIFRoZSBjb250cm9sIGlzIGNvbnNpZGVyZWQgdmFsaWQgb25seSBpZiB2YWx1ZSBpcyBlbnRlcmVkLgogKiBAcGFyYW0ge3N0cmluZz19IG5nUmVxdWlyZWQgQWRkcyBgcmVxdWlyZWRgIGF0dHJpYnV0ZSBhbmQgYHJlcXVpcmVkYCB2YWxpZGF0aW9uIGNvbnN0cmFpbnQgdG8KICogICAgdGhlIGVsZW1lbnQgd2hlbiB0aGUgbmdSZXF1aXJlZCBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLiBVc2UgYG5nUmVxdWlyZWRgIGluc3RlYWQgb2YKICogICAgYHJlcXVpcmVkYCB3aGVuIHlvdSB3YW50IHRvIGRhdGEtYmluZCB0byB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUuCiAqIEBwYXJhbSB7Y29tcHJlaGVuc2lvbl9leHByZXNzaW9uPX0gbmdPcHRpb25zIGluIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1zOgogKgogKiAgICogZm9yIGFycmF5IGRhdGEgc291cmNlczoKICogICAgICogYGxhYmVsYCAqKmBmb3JgKiogYHZhbHVlYCAqKmBpbmAqKiBgYXJyYXlgCiAqICAgICAqIGBzZWxlY3RgICoqYGFzYCoqIGBsYWJlbGAgKipgZm9yYCoqIGB2YWx1ZWAgKipgaW5gKiogYGFycmF5YAogKiAgICAgKiBgbGFiZWxgICoqYGdyb3VwIGJ5YCoqIGBncm91cGAgKipgZm9yYCoqIGB2YWx1ZWAgKipgaW5gKiogYGFycmF5YAogKiAgICAgKiBgbGFiZWxgICoqYGdyb3VwIGJ5YCoqIGBncm91cGAgKipgZm9yYCoqIGB2YWx1ZWAgKipgaW5gKiogYGFycmF5YCAqKmB0cmFjayBieWAqKiBgdHJhY2tleHByYAogKiAgICAgKiBgbGFiZWxgICoqYGZvcmAqKiBgdmFsdWVgICoqYGluYCoqIGBhcnJheWAgfCBvcmRlckJ5OmBvcmRlcmV4cHJgICoqYHRyYWNrIGJ5YCoqIGB0cmFja2V4cHJgCiAqICAgICAgICAoZm9yIGluY2x1ZGluZyBhIGZpbHRlciB3aXRoIGB0cmFjayBieWApCiAqICAgKiBmb3Igb2JqZWN0IGRhdGEgc291cmNlczoKICogICAgICogYGxhYmVsYCAqKmBmb3IgKGAqKmBrZXlgICoqYCxgKiogYHZhbHVlYCoqYCkgaW5gKiogYG9iamVjdGAKICogICAgICogYHNlbGVjdGAgKipgYXNgKiogYGxhYmVsYCAqKmBmb3IgKGAqKmBrZXlgICoqYCxgKiogYHZhbHVlYCoqYCkgaW5gKiogYG9iamVjdGAKICogICAgICogYGxhYmVsYCAqKmBncm91cCBieWAqKiBgZ3JvdXBgICoqYGZvciAoYCoqYGtleWAqKmAsYCoqIGB2YWx1ZWAqKmApIGluYCoqIGBvYmplY3RgCiAqICAgICAqIGBzZWxlY3RgICoqYGFzYCoqIGBsYWJlbGAgKipgZ3JvdXAgYnlgKiogYGdyb3VwYAogKiAgICAgICAgICoqYGZvcmAgYChgKipga2V5YCoqYCxgKiogYHZhbHVlYCoqYCkgaW5gKiogYG9iamVjdGAKICoKICogV2hlcmU6CiAqCiAqICAgKiBgYXJyYXlgIC8gYG9iamVjdGA6IGFuIGV4cHJlc3Npb24gd2hpY2ggZXZhbHVhdGVzIHRvIGFuIGFycmF5IC8gb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogICAqIGB2YWx1ZWA6IGxvY2FsIHZhcmlhYmxlIHdoaWNoIHdpbGwgcmVmZXIgdG8gZWFjaCBpdGVtIGluIHRoZSBgYXJyYXlgIG9yIGVhY2ggcHJvcGVydHkgdmFsdWUKICogICAgICBvZiBgb2JqZWN0YCBkdXJpbmcgaXRlcmF0aW9uLgogKiAgICogYGtleWA6IGxvY2FsIHZhcmlhYmxlIHdoaWNoIHdpbGwgcmVmZXIgdG8gYSBwcm9wZXJ0eSBuYW1lIGluIGBvYmplY3RgIGR1cmluZyBpdGVyYXRpb24uCiAqICAgKiBgbGFiZWxgOiBUaGUgcmVzdWx0IG9mIHRoaXMgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBsYWJlbCBmb3IgYDxvcHRpb24+YCBlbGVtZW50LiBUaGUKICogICAgIGBleHByZXNzaW9uYCB3aWxsIG1vc3QgbGlrZWx5IHJlZmVyIHRvIHRoZSBgdmFsdWVgIHZhcmlhYmxlIChlLmcuIGB2YWx1ZS5wcm9wZXJ0eU5hbWVgKS4KICogICAqIGBzZWxlY3RgOiBUaGUgcmVzdWx0IG9mIHRoaXMgZXhwcmVzc2lvbiB3aWxsIGJlIGJvdW5kIHRvIHRoZSBtb2RlbCBvZiB0aGUgcGFyZW50IGA8c2VsZWN0PmAKICogICAgICBlbGVtZW50LiBJZiBub3Qgc3BlY2lmaWVkLCBgc2VsZWN0YCBleHByZXNzaW9uIHdpbGwgZGVmYXVsdCB0byBgdmFsdWVgLgogKiAgICogYGdyb3VwYDogVGhlIHJlc3VsdCBvZiB0aGlzIGV4cHJlc3Npb24gd2lsbCBiZSB1c2VkIHRvIGdyb3VwIG9wdGlvbnMgdXNpbmcgdGhlIGA8b3B0Z3JvdXA+YAogKiAgICAgIERPTSBlbGVtZW50LgogKiAgICogYHRyYWNrZXhwcmA6IFVzZWQgd2hlbiB3b3JraW5nIHdpdGggYW4gYXJyYXkgb2Ygb2JqZWN0cy4gVGhlIHJlc3VsdCBvZiB0aGlzIGV4cHJlc3Npb24gd2lsbCBiZQogKiAgICAgIHVzZWQgdG8gaWRlbnRpZnkgdGhlIG9iamVjdHMgaW4gdGhlIGFycmF5LiBUaGUgYHRyYWNrZXhwcmAgd2lsbCBtb3N0IGxpa2VseSByZWZlciB0byB0aGUKICogICAgIGB2YWx1ZWAgdmFyaWFibGUgKGUuZy4gYHZhbHVlLnByb3BlcnR5TmFtZWApLiBXaXRoIHRoaXMgdGhlIHNlbGVjdGlvbiBpcyBwcmVzZXJ2ZWQKICogICAgICBldmVuIHdoZW4gdGhlIG9wdGlvbnMgYXJlIHJlY3JlYXRlZCAoZS5nLiByZWxvYWRlZCBmcm9tIHRoZSBzZXJ2ZXIpLgogKgogKiBAZXhhbXBsZQogICAgPGV4YW1wbGUgbW9kdWxlPSJzZWxlY3RFeGFtcGxlIj4KICAgICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+CiAgICAgICAgPHNjcmlwdD4KICAgICAgICBhbmd1bGFyLm1vZHVsZSgnc2VsZWN0RXhhbXBsZScsIFtdKQogICAgICAgICAgLmNvbnRyb2xsZXIoJ0V4YW1wbGVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHsKICAgICAgICAgICAgJHNjb3BlLmNvbG9ycyA9IFsKICAgICAgICAgICAgICB7bmFtZTonYmxhY2snLCBzaGFkZTonZGFyayd9LAogICAgICAgICAgICAgIHtuYW1lOid3aGl0ZScsIHNoYWRlOidsaWdodCd9LAogICAgICAgICAgICAgIHtuYW1lOidyZWQnLCBzaGFkZTonZGFyayd9LAogICAgICAgICAgICAgIHtuYW1lOidibHVlJywgc2hhZGU6J2RhcmsnfSwKICAgICAgICAgICAgICB7bmFtZToneWVsbG93Jywgc2hhZGU6J2xpZ2h0J30KICAgICAgICAgICAgXTsKICAgICAgICAgICAgJHNjb3BlLm15Q29sb3IgPSAkc2NvcGUuY29sb3JzWzJdOyAvLyByZWQKICAgICAgICAgIH1dKTsKICAgICAgICA8L3NjcmlwdD4KICAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9IkV4YW1wbGVDb250cm9sbGVyIj4KICAgICAgICAgIDx1bD4KICAgICAgICAgICAgPGxpIG5nLXJlcGVhdD0iY29sb3IgaW4gY29sb3JzIj4KICAgICAgICAgICAgICBOYW1lOiA8aW5wdXQgbmctbW9kZWw9ImNvbG9yLm5hbWUiPgogICAgICAgICAgICAgIFs8YSBocmVmIG5nLWNsaWNrPSJjb2xvcnMuc3BsaWNlKCRpbmRleCwgMSkiPlg8L2E+XQogICAgICAgICAgICA8L2xpPgogICAgICAgICAgICA8bGk+CiAgICAgICAgICAgICAgWzxhIGhyZWYgbmctY2xpY2s9ImNvbG9ycy5wdXNoKHt9KSI+YWRkPC9hPl0KICAgICAgICAgICAgPC9saT4KICAgICAgICAgIDwvdWw+CiAgICAgICAgICA8aHIvPgogICAgICAgICAgQ29sb3IgKG51bGwgbm90IGFsbG93ZWQpOgogICAgICAgICAgPHNlbGVjdCBuZy1tb2RlbD0ibXlDb2xvciIgbmctb3B0aW9ucz0iY29sb3IubmFtZSBmb3IgY29sb3IgaW4gY29sb3JzIj48L3NlbGVjdD48YnI+CgogICAgICAgICAgQ29sb3IgKG51bGwgYWxsb3dlZCk6CiAgICAgICAgICA8c3BhbiAgY2xhc3M9Im51bGxhYmxlIj4KICAgICAgICAgICAgPHNlbGVjdCBuZy1tb2RlbD0ibXlDb2xvciIgbmctb3B0aW9ucz0iY29sb3IubmFtZSBmb3IgY29sb3IgaW4gY29sb3JzIj4KICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIiPi0tIGNob29zZSBjb2xvciAtLTwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICAgIDwvc3Bhbj48YnIvPgoKICAgICAgICAgIENvbG9yIGdyb3VwZWQgYnkgc2hhZGU6CiAgICAgICAgICA8c2VsZWN0IG5nLW1vZGVsPSJteUNvbG9yIiBuZy1vcHRpb25zPSJjb2xvci5uYW1lIGdyb3VwIGJ5IGNvbG9yLnNoYWRlIGZvciBjb2xvciBpbiBjb2xvcnMiPgogICAgICAgICAgPC9zZWxlY3Q+PGJyLz4KCgogICAgICAgICAgU2VsZWN0IDxhIGhyZWYgbmctY2xpY2s9Im15Q29sb3IgPSB7IG5hbWU6J25vdCBpbiBsaXN0Jywgc2hhZGU6ICdvdGhlcicgfSI+Ym9ndXM8L2E+Ljxicj4KICAgICAgICAgIDxoci8+CiAgICAgICAgICBDdXJyZW50bHkgc2VsZWN0ZWQ6IHt7IHtzZWxlY3RlZF9jb2xvcjpteUNvbG9yfSB9fQogICAgICAgICAgPGRpdiBzdHlsZT0iYm9yZGVyOnNvbGlkIDFweCBibGFjazsgaGVpZ2h0OjIwcHgiCiAgICAgICAgICAgICAgIG5nLXN0eWxlPSJ7J2JhY2tncm91bmQtY29sb3InOm15Q29sb3IubmFtZX0iPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICAgIDwvZmlsZT4KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+CiAgICAgICAgIGl0KCdzaG91bGQgY2hlY2sgbmctb3B0aW9ucycsIGZ1bmN0aW9uKCkgewogICAgICAgICAgIGV4cGVjdChlbGVtZW50KGJ5LmJpbmRpbmcoJ3tzZWxlY3RlZF9jb2xvcjpteUNvbG9yfScpKS5nZXRUZXh0KCkpLnRvTWF0Y2goJ3JlZCcpOwogICAgICAgICAgIGVsZW1lbnQuYWxsKGJ5Lm1vZGVsKCdteUNvbG9yJykpLmZpcnN0KCkuY2xpY2soKTsKICAgICAgICAgICBlbGVtZW50LmFsbChieS5jc3MoJ3NlbGVjdFtuZy1tb2RlbD0ibXlDb2xvciJdIG9wdGlvbicpKS5maXJzdCgpLmNsaWNrKCk7CiAgICAgICAgICAgZXhwZWN0KGVsZW1lbnQoYnkuYmluZGluZygne3NlbGVjdGVkX2NvbG9yOm15Q29sb3J9JykpLmdldFRleHQoKSkudG9NYXRjaCgnYmxhY2snKTsKICAgICAgICAgICBlbGVtZW50KGJ5LmNzcygnLm51bGxhYmxlIHNlbGVjdFtuZy1tb2RlbD0ibXlDb2xvciJdJykpLmNsaWNrKCk7CiAgICAgICAgICAgZWxlbWVudC5hbGwoYnkuY3NzKCcubnVsbGFibGUgc2VsZWN0W25nLW1vZGVsPSJteUNvbG9yIl0gb3B0aW9uJykpLmZpcnN0KCkuY2xpY2soKTsKICAgICAgICAgICBleHBlY3QoZWxlbWVudChieS5iaW5kaW5nKCd7c2VsZWN0ZWRfY29sb3I6bXlDb2xvcn0nKSkuZ2V0VGV4dCgpKS50b01hdGNoKCdudWxsJyk7CiAgICAgICAgIH0pOwogICAgICA8L2ZpbGU+CiAgICA8L2V4YW1wbGU+CiAqLwoKdmFyIG5nT3B0aW9uc0RpcmVjdGl2ZSA9IHZhbHVlRm4oewogIHJlc3RyaWN0OiAnQScsCiAgdGVybWluYWw6IHRydWUKfSk7CgovLyBqc2hpbnQgbWF4bGVuOiBmYWxzZQp2YXIgc2VsZWN0RGlyZWN0aXZlID0gWyckY29tcGlsZScsICckcGFyc2UnLCBmdW5jdGlvbigkY29tcGlsZSwgICAkcGFyc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8vMDAwMDExMTExMTExMTEwMDAwMDAwMDAwMDIyMjIyMjIyMjIwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMzMzMzMzMzMzMDAwMDAwMDAwMDAwMDA0NDQ0NDQ0NDQ0NDQ0NDQwMDAwMDAwMDA1NTU1NTU1NTU1NTU1NTUwMDAwMDAwNjY2NjY2NjY2NjY2NjY2MDAwMDAwMDAwMDAwMDAwNzc3Nzc3Nzc3NzAwMDAwMDAwMDAwMDAwMDAwMDA4ODg4ODg4ODg4CiAgdmFyIE5HX09QVElPTlNfUkVHRVhQID0gL15ccyooW1xzXFNdKz8pKD86XHMrYXNccysoW1xzXFNdKz8pKT8oPzpccytncm91cFxzK2J5XHMrKFtcc1xTXSs/KSk/XHMrZm9yXHMrKD86KFtcJFx3XVtcJFx3XSopfCg/OlwoXHMqKFtcJFx3XVtcJFx3XSopXHMqLFxzKihbXCRcd11bXCRcd10qKVxzKlwpKSlccytpblxzKyhbXHNcU10rPykoPzpccyt0cmFja1xzK2J5XHMrKFtcc1xTXSs/KSk/JC8sCiAgICAgIG51bGxNb2RlbEN0cmwgPSB7JHNldFZpZXdWYWx1ZTogbm9vcH07Ci8vIGpzaGludCBtYXhsZW46IDEwMAoKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdFJywKICAgIHJlcXVpcmU6IFsnc2VsZWN0JywgJz9uZ01vZGVsJ10sCiAgICBjb250cm9sbGVyOiBbJyRlbGVtZW50JywgJyRzY29wZScsICckYXR0cnMnLCBmdW5jdGlvbigkZWxlbWVudCwgJHNjb3BlLCAkYXR0cnMpIHsKICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgb3B0aW9uc01hcCA9IHt9LAogICAgICAgICAgbmdNb2RlbEN0cmwgPSBudWxsTW9kZWxDdHJsLAogICAgICAgICAgbnVsbE9wdGlvbiwKICAgICAgICAgIHVua25vd25PcHRpb247CgoKICAgICAgc2VsZi5kYXRhYm91bmQgPSAkYXR0cnMubmdNb2RlbDsKCgogICAgICBzZWxmLmluaXQgPSBmdW5jdGlvbihuZ01vZGVsQ3RybF8sIG51bGxPcHRpb25fLCB1bmtub3duT3B0aW9uXykgewogICAgICAgIG5nTW9kZWxDdHJsID0gbmdNb2RlbEN0cmxfOwogICAgICAgIG51bGxPcHRpb24gPSBudWxsT3B0aW9uXzsKICAgICAgICB1bmtub3duT3B0aW9uID0gdW5rbm93bk9wdGlvbl87CiAgICAgIH07CgoKICAgICAgc2VsZi5hZGRPcHRpb24gPSBmdW5jdGlvbih2YWx1ZSwgZWxlbWVudCkgewogICAgICAgIGFzc2VydE5vdEhhc093blByb3BlcnR5KHZhbHVlLCAnIm9wdGlvbiB2YWx1ZSInKTsKICAgICAgICBvcHRpb25zTWFwW3ZhbHVlXSA9IHRydWU7CgogICAgICAgIGlmIChuZ01vZGVsQ3RybC4kdmlld1ZhbHVlID09IHZhbHVlKSB7CiAgICAgICAgICAkZWxlbWVudC52YWwodmFsdWUpOwogICAgICAgICAgaWYgKHVua25vd25PcHRpb24ucGFyZW50KCkpIHVua25vd25PcHRpb24ucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIC8vIFdvcmthcm91bmQgZm9yIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zODE0NTkKICAgICAgICAvLyBBZGRpbmcgYW4gPG9wdGlvbiBzZWxlY3RlZD0ic2VsZWN0ZWQiPiBlbGVtZW50IHRvIGEgPHNlbGVjdCByZXF1aXJlZD0icmVxdWlyZWQiPiBzaG91bGQKICAgICAgICAvLyBhdXRvbWF0aWNhbGx5IHNlbGVjdCB0aGUgbmV3IGVsZW1lbnQKICAgICAgICBpZiAoZWxlbWVudCAmJiBlbGVtZW50WzBdLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKSkgewogICAgICAgICAgZWxlbWVudFswXS5zZWxlY3RlZCA9IHRydWU7CiAgICAgICAgfQogICAgICB9OwoKCiAgICAgIHNlbGYucmVtb3ZlT3B0aW9uID0gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICBpZiAodGhpcy5oYXNPcHRpb24odmFsdWUpKSB7CiAgICAgICAgICBkZWxldGUgb3B0aW9uc01hcFt2YWx1ZV07CiAgICAgICAgICBpZiAobmdNb2RlbEN0cmwuJHZpZXdWYWx1ZSA9PT0gdmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5yZW5kZXJVbmtub3duT3B0aW9uKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH07CgoKICAgICAgc2VsZi5yZW5kZXJVbmtub3duT3B0aW9uID0gZnVuY3Rpb24odmFsKSB7CiAgICAgICAgdmFyIHVua25vd25WYWwgPSAnPyAnICsgaGFzaEtleSh2YWwpICsgJyA/JzsKICAgICAgICB1bmtub3duT3B0aW9uLnZhbCh1bmtub3duVmFsKTsKICAgICAgICAkZWxlbWVudC5wcmVwZW5kKHVua25vd25PcHRpb24pOwogICAgICAgICRlbGVtZW50LnZhbCh1bmtub3duVmFsKTsKICAgICAgICB1bmtub3duT3B0aW9uLnByb3AoJ3NlbGVjdGVkJywgdHJ1ZSk7IC8vIG5lZWRlZCBmb3IgSUUKICAgICAgfTsKCgogICAgICBzZWxmLmhhc09wdGlvbiA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnNNYXAuaGFzT3duUHJvcGVydHkodmFsdWUpOwogICAgICB9OwoKICAgICAgJHNjb3BlLiRvbignJGRlc3Ryb3knLCBmdW5jdGlvbigpIHsKICAgICAgICAvLyBkaXNhYmxlIHVua25vd24gb3B0aW9uIHNvIHRoYXQgd2UgZG9uJ3QgZG8gd29yayB3aGVuIHRoZSB3aG9sZSBzZWxlY3QgaXMgYmVpbmcgZGVzdHJveWVkCiAgICAgICAgc2VsZi5yZW5kZXJVbmtub3duT3B0aW9uID0gbm9vcDsKICAgICAgfSk7CiAgICB9XSwKCiAgICBsaW5rOiBmdW5jdGlvbihzY29wZSwgZWxlbWVudCwgYXR0ciwgY3RybHMpIHsKICAgICAgLy8gaWYgbmdNb2RlbCBpcyBub3QgZGVmaW5lZCwgd2UgZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZwogICAgICBpZiAoIWN0cmxzWzFdKSByZXR1cm47CgogICAgICB2YXIgc2VsZWN0Q3RybCA9IGN0cmxzWzBdLAogICAgICAgICAgbmdNb2RlbEN0cmwgPSBjdHJsc1sxXSwKICAgICAgICAgIG11bHRpcGxlID0gYXR0ci5tdWx0aXBsZSwKICAgICAgICAgIG9wdGlvbnNFeHAgPSBhdHRyLm5nT3B0aW9ucywKICAgICAgICAgIG51bGxPcHRpb24gPSBmYWxzZSwgLy8gaWYgZmFsc2UsIHVzZXIgd2lsbCBub3QgYmUgYWJsZSB0byBzZWxlY3QgaXQgKHVzZWQgYnkgbmdPcHRpb25zKQogICAgICAgICAgZW1wdHlPcHRpb24sCiAgICAgICAgICByZW5kZXJTY2hlZHVsZWQgPSBmYWxzZSwKICAgICAgICAgIC8vIHdlIGNhbid0IGp1c3QganFMaXRlKCc8b3B0aW9uPicpIHNpbmNlIGpxTGl0ZSBpcyBub3Qgc21hcnQgZW5vdWdoCiAgICAgICAgICAvLyB0byBjcmVhdGUgaXQgaW4gPHNlbGVjdD4gYW5kIElFIGJhcmZzIG90aGVyd2lzZS4KICAgICAgICAgIG9wdGlvblRlbXBsYXRlID0ganFMaXRlKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ29wdGlvbicpKSwKICAgICAgICAgIG9wdEdyb3VwVGVtcGxhdGUgPWpxTGl0ZShkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRncm91cCcpKSwKICAgICAgICAgIHVua25vd25PcHRpb24gPSBvcHRpb25UZW1wbGF0ZS5jbG9uZSgpOwoKICAgICAgLy8gZmluZCAibnVsbCIgb3B0aW9uCiAgICAgIGZvciAodmFyIGkgPSAwLCBjaGlsZHJlbiA9IGVsZW1lbnQuY2hpbGRyZW4oKSwgaWkgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7CiAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnZhbHVlID09PSAnJykgewogICAgICAgICAgZW1wdHlPcHRpb24gPSBudWxsT3B0aW9uID0gY2hpbGRyZW4uZXEoaSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHNlbGVjdEN0cmwuaW5pdChuZ01vZGVsQ3RybCwgbnVsbE9wdGlvbiwgdW5rbm93bk9wdGlvbik7CgogICAgICAvLyByZXF1aXJlZCB2YWxpZGF0b3IKICAgICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgbmdNb2RlbEN0cmwuJGlzRW1wdHkgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgcmV0dXJuICF2YWx1ZSB8fCB2YWx1ZS5sZW5ndGggPT09IDA7CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgaWYgKG9wdGlvbnNFeHApIHNldHVwQXNPcHRpb25zKHNjb3BlLCBlbGVtZW50LCBuZ01vZGVsQ3RybCk7CiAgICAgIGVsc2UgaWYgKG11bHRpcGxlKSBzZXR1cEFzTXVsdGlwbGUoc2NvcGUsIGVsZW1lbnQsIG5nTW9kZWxDdHJsKTsKICAgICAgZWxzZSBzZXR1cEFzU2luZ2xlKHNjb3BlLCBlbGVtZW50LCBuZ01vZGVsQ3RybCwgc2VsZWN0Q3RybCk7CgoKICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKCgogICAgICBmdW5jdGlvbiBzZXR1cEFzU2luZ2xlKHNjb3BlLCBzZWxlY3RFbGVtZW50LCBuZ01vZGVsQ3RybCwgc2VsZWN0Q3RybCkgewogICAgICAgIG5nTW9kZWxDdHJsLiRyZW5kZXIgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIHZhciB2aWV3VmFsdWUgPSBuZ01vZGVsQ3RybC4kdmlld1ZhbHVlOwoKICAgICAgICAgIGlmIChzZWxlY3RDdHJsLmhhc09wdGlvbih2aWV3VmFsdWUpKSB7CiAgICAgICAgICAgIGlmICh1bmtub3duT3B0aW9uLnBhcmVudCgpKSB1bmtub3duT3B0aW9uLnJlbW92ZSgpOwogICAgICAgICAgICBzZWxlY3RFbGVtZW50LnZhbCh2aWV3VmFsdWUpOwogICAgICAgICAgICBpZiAodmlld1ZhbHVlID09PSAnJykgZW1wdHlPcHRpb24ucHJvcCgnc2VsZWN0ZWQnLCB0cnVlKTsgLy8gdG8gbWFrZSBJRTkgaGFwcHkKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChpc1VuZGVmaW5lZCh2aWV3VmFsdWUpICYmIGVtcHR5T3B0aW9uKSB7CiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC52YWwoJycpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHNlbGVjdEN0cmwucmVuZGVyVW5rbm93bk9wdGlvbih2aWV3VmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgc2VsZWN0RWxlbWVudC5vbignY2hhbmdlJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBzY29wZS4kYXBwbHkoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh1bmtub3duT3B0aW9uLnBhcmVudCgpKSB1bmtub3duT3B0aW9uLnJlbW92ZSgpOwogICAgICAgICAgICBuZ01vZGVsQ3RybC4kc2V0Vmlld1ZhbHVlKHNlbGVjdEVsZW1lbnQudmFsKCkpOwogICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGZ1bmN0aW9uIHNldHVwQXNNdWx0aXBsZShzY29wZSwgc2VsZWN0RWxlbWVudCwgY3RybCkgewogICAgICAgIHZhciBsYXN0VmlldzsKICAgICAgICBjdHJsLiRyZW5kZXIgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIHZhciBpdGVtcyA9IG5ldyBIYXNoTWFwKGN0cmwuJHZpZXdWYWx1ZSk7CiAgICAgICAgICBmb3JFYWNoKHNlbGVjdEVsZW1lbnQuZmluZCgnb3B0aW9uJyksIGZ1bmN0aW9uKG9wdGlvbikgewogICAgICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSBpc0RlZmluZWQoaXRlbXMuZ2V0KG9wdGlvbi52YWx1ZSkpOwogICAgICAgICAgfSk7CiAgICAgICAgfTsKCiAgICAgICAgLy8gd2UgaGF2ZSB0byBkbyBpdCBvbiBlYWNoIHdhdGNoIHNpbmNlIG5nTW9kZWwgd2F0Y2hlcyByZWZlcmVuY2UsIGJ1dAogICAgICAgIC8vIHdlIG5lZWQgdG8gd29yayBvZiBhbiBhcnJheSwgc28gd2UgbmVlZCB0byBzZWUgaWYgYW55dGhpbmcgd2FzIGluc2VydGVkL3JlbW92ZWQKICAgICAgICBzY29wZS4kd2F0Y2goZnVuY3Rpb24gc2VsZWN0TXVsdGlwbGVXYXRjaCgpIHsKICAgICAgICAgIGlmICghZXF1YWxzKGxhc3RWaWV3LCBjdHJsLiR2aWV3VmFsdWUpKSB7CiAgICAgICAgICAgIGxhc3RWaWV3ID0gc2hhbGxvd0NvcHkoY3RybC4kdmlld1ZhbHVlKTsKICAgICAgICAgICAgY3RybC4kcmVuZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIHNlbGVjdEVsZW1lbnQub24oJ2NoYW5nZScsIGZ1bmN0aW9uKCkgewogICAgICAgICAgc2NvcGUuJGFwcGx5KGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgYXJyYXkgPSBbXTsKICAgICAgICAgICAgZm9yRWFjaChzZWxlY3RFbGVtZW50LmZpbmQoJ29wdGlvbicpLCBmdW5jdGlvbihvcHRpb24pIHsKICAgICAgICAgICAgICBpZiAob3B0aW9uLnNlbGVjdGVkKSB7CiAgICAgICAgICAgICAgICBhcnJheS5wdXNoKG9wdGlvbi52YWx1ZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgY3RybC4kc2V0Vmlld1ZhbHVlKGFycmF5KTsKICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgICB9CgogICAgICBmdW5jdGlvbiBzZXR1cEFzT3B0aW9ucyhzY29wZSwgc2VsZWN0RWxlbWVudCwgY3RybCkgewogICAgICAgIHZhciBtYXRjaDsKCiAgICAgICAgaWYgKCEobWF0Y2ggPSBvcHRpb25zRXhwLm1hdGNoKE5HX09QVElPTlNfUkVHRVhQKSkpIHsKICAgICAgICAgIHRocm93IG5nT3B0aW9uc01pbkVycignaWV4cCcsCiAgICAgICAgICAgICJFeHBlY3RlZCBleHByZXNzaW9uIGluIGZvcm0gb2YgIiArCiAgICAgICAgICAgICInX3NlbGVjdF8gKGFzIF9sYWJlbF8pPyBmb3IgKF9rZXlfLCk/X3ZhbHVlXyBpbiBfY29sbGVjdGlvbl8nIiArCiAgICAgICAgICAgICIgYnV0IGdvdCAnezB9Jy4gRWxlbWVudDogezF9IiwKICAgICAgICAgICAgb3B0aW9uc0V4cCwgc3RhcnRpbmdUYWcoc2VsZWN0RWxlbWVudCkpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGRpc3BsYXlGbiA9ICRwYXJzZShtYXRjaFsyXSB8fCBtYXRjaFsxXSksCiAgICAgICAgICAgIHZhbHVlTmFtZSA9IG1hdGNoWzRdIHx8IG1hdGNoWzZdLAogICAgICAgICAgICBzZWxlY3RBcyA9IC8gYXMgLy50ZXN0KG1hdGNoWzBdKSAmJiBtYXRjaFsxXSwKICAgICAgICAgICAgc2VsZWN0QXNGbiA9IHNlbGVjdEFzID8gJHBhcnNlKHNlbGVjdEFzKSA6IG51bGwsCiAgICAgICAgICAgIGtleU5hbWUgPSBtYXRjaFs1XSwKICAgICAgICAgICAgZ3JvdXBCeUZuID0gJHBhcnNlKG1hdGNoWzNdIHx8ICcnKSwKICAgICAgICAgICAgdmFsdWVGbiA9ICRwYXJzZShtYXRjaFsyXSA/IG1hdGNoWzFdIDogdmFsdWVOYW1lKSwKICAgICAgICAgICAgdmFsdWVzRm4gPSAkcGFyc2UobWF0Y2hbN10pLAogICAgICAgICAgICB0cmFjayA9IG1hdGNoWzhdLAogICAgICAgICAgICB0cmFja0ZuID0gdHJhY2sgPyAkcGFyc2UobWF0Y2hbOF0pIDogbnVsbCwKICAgICAgICAgICAgdHJhY2tLZXlzQ2FjaGUgPSB7fSwKICAgICAgICAgICAgLy8gVGhpcyBpcyBhbiBhcnJheSBvZiBhcnJheSBvZiBleGlzdGluZyBvcHRpb24gZ3JvdXBzIGluIERPTS4KICAgICAgICAgICAgLy8gV2UgdHJ5IHRvIHJldXNlIHRoZXNlIGlmIHBvc3NpYmxlCiAgICAgICAgICAgIC8vIC0gb3B0aW9uR3JvdXBzQ2FjaGVbMF0gaXMgdGhlIG9wdGlvbnMgd2l0aCBubyBvcHRpb24gZ3JvdXAKICAgICAgICAgICAgLy8gLSBvcHRpb25Hcm91cHNDYWNoZVs/XVswXSBpcyB0aGUgcGFyZW50OiBlaXRoZXIgdGhlIFNFTEVDVCBvciBPUFRHUk9VUCBlbGVtZW50CiAgICAgICAgICAgIG9wdGlvbkdyb3Vwc0NhY2hlID0gW1t7ZWxlbWVudDogc2VsZWN0RWxlbWVudCwgbGFiZWw6Jyd9XV0sCiAgICAgICAgICAgIC8vcmUtdXNhYmxlIG9iamVjdCB0byByZXByZXNlbnQgb3B0aW9uJ3MgbG9jYWxzCiAgICAgICAgICAgIGxvY2FscyA9IHt9OwoKICAgICAgICBpZiAobnVsbE9wdGlvbikgewogICAgICAgICAgLy8gY29tcGlsZSB0aGUgZWxlbWVudCBzaW5jZSB0aGVyZSBtaWdodCBiZSBiaW5kaW5ncyBpbiBpdAogICAgICAgICAgJGNvbXBpbGUobnVsbE9wdGlvbikoc2NvcGUpOwoKICAgICAgICAgIC8vIHJlbW92ZSB0aGUgY2xhc3MsIHdoaWNoIGlzIGFkZGVkIGF1dG9tYXRpY2FsbHkgYmVjYXVzZSB3ZSByZWNvbXBpbGUgdGhlIGVsZW1lbnQgYW5kIGl0CiAgICAgICAgICAvLyBiZWNvbWVzIHRoZSBjb21waWxhdGlvbiByb290CiAgICAgICAgICBudWxsT3B0aW9uLnJlbW92ZUNsYXNzKCduZy1zY29wZScpOwoKICAgICAgICAgIC8vIHdlIG5lZWQgdG8gcmVtb3ZlIGl0IGJlZm9yZSBjYWxsaW5nIHNlbGVjdEVsZW1lbnQuZW1wdHkoKSBiZWNhdXNlIG90aGVyd2lzZSBJRSB3aWxsCiAgICAgICAgICAvLyByZW1vdmUgdGhlIGxhYmVsIGZyb20gdGhlIGVsZW1lbnQuIHd0Zj8KICAgICAgICAgIG51bGxPcHRpb24ucmVtb3ZlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBjbGVhciBjb250ZW50cywgd2UnbGwgYWRkIHdoYXQncyBuZWVkZWQgYmFzZWQgb24gdGhlIG1vZGVsCiAgICAgICAgc2VsZWN0RWxlbWVudC5lbXB0eSgpOwoKICAgICAgICBzZWxlY3RFbGVtZW50Lm9uKCdjaGFuZ2UnLCBzZWxlY3Rpb25DaGFuZ2VkKTsKCiAgICAgICAgY3RybC4kcmVuZGVyID0gcmVuZGVyOwoKICAgICAgICBzY29wZS4kd2F0Y2hDb2xsZWN0aW9uKHZhbHVlc0ZuLCBzY2hlZHVsZVJlbmRlcmluZyk7CiAgICAgICAgc2NvcGUuJHdhdGNoQ29sbGVjdGlvbihnZXRMYWJlbHMsIHNjaGVkdWxlUmVuZGVyaW5nKTsKCiAgICAgICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgICBzY29wZS4kd2F0Y2hDb2xsZWN0aW9uKGZ1bmN0aW9uKCkgeyByZXR1cm4gY3RybC4kbW9kZWxWYWx1ZTsgfSwgc2NoZWR1bGVSZW5kZXJpbmcpOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vCgogICAgICAgIGZ1bmN0aW9uIGNhbGxFeHByZXNzaW9uKGV4cHJGbiwga2V5LCB2YWx1ZSkgewogICAgICAgICAgbG9jYWxzW3ZhbHVlTmFtZV0gPSB2YWx1ZTsKICAgICAgICAgIGlmIChrZXlOYW1lKSBsb2NhbHNba2V5TmFtZV0gPSBrZXk7CiAgICAgICAgICByZXR1cm4gZXhwckZuKHNjb3BlLCBsb2NhbHMpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gc2VsZWN0aW9uQ2hhbmdlZCgpIHsKICAgICAgICAgIHNjb3BlLiRhcHBseShmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSB2YWx1ZXNGbihzY29wZSkgfHwgW107CiAgICAgICAgICAgIHZhciB2aWV3VmFsdWU7CiAgICAgICAgICAgIGlmIChtdWx0aXBsZSkgewogICAgICAgICAgICAgIHZpZXdWYWx1ZSA9IFtdOwogICAgICAgICAgICAgIGZvckVhY2goc2VsZWN0RWxlbWVudC52YWwoKSwgZnVuY3Rpb24oc2VsZWN0ZWRLZXkpIHsKICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRLZXkgPSB0cmFja0ZuID8gdHJhY2tLZXlzQ2FjaGVbc2VsZWN0ZWRLZXldIDogc2VsZWN0ZWRLZXk7CiAgICAgICAgICAgICAgICB2aWV3VmFsdWUucHVzaChnZXRWaWV3VmFsdWUoc2VsZWN0ZWRLZXksIGNvbGxlY3Rpb25bc2VsZWN0ZWRLZXldKSk7CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkS2V5ID0gdHJhY2tGbiA/IHRyYWNrS2V5c0NhY2hlW3NlbGVjdEVsZW1lbnQudmFsKCldIDogc2VsZWN0RWxlbWVudC52YWwoKTsKICAgICAgICAgICAgICB2aWV3VmFsdWUgPSBnZXRWaWV3VmFsdWUoc2VsZWN0ZWRLZXksIGNvbGxlY3Rpb25bc2VsZWN0ZWRLZXldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdHJsLiRzZXRWaWV3VmFsdWUodmlld1ZhbHVlKTsKICAgICAgICAgICAgcmVuZGVyKCk7CiAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGdldFZpZXdWYWx1ZShrZXksIHZhbHVlKSB7CiAgICAgICAgICBpZiAoa2V5ID09PSAnPycpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAnJykgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciB2aWV3VmFsdWVGbiA9IHNlbGVjdEFzRm4gPyBzZWxlY3RBc0ZuIDogdmFsdWVGbjsKICAgICAgICAgICAgcmV0dXJuIGNhbGxFeHByZXNzaW9uKHZpZXdWYWx1ZUZuLCBrZXksIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGdldExhYmVscygpIHsKICAgICAgICAgIHZhciB2YWx1ZXMgPSB2YWx1ZXNGbihzY29wZSk7CiAgICAgICAgICB2YXIgdG9EaXNwbGF5OwogICAgICAgICAgaWYgKHZhbHVlcyAmJiBpc0FycmF5KHZhbHVlcykpIHsKICAgICAgICAgICAgdG9EaXNwbGF5ID0gbmV3IEFycmF5KHZhbHVlcy5sZW5ndGgpOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSB2YWx1ZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykgewogICAgICAgICAgICAgIHRvRGlzcGxheVtpXSA9IGNhbGxFeHByZXNzaW9uKGRpc3BsYXlGbiwgaSwgdmFsdWVzW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdG9EaXNwbGF5OwogICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZXMpIHsKICAgICAgICAgICAgLy8gVE9ETzogQWRkIGEgdGVzdCBmb3IgdGhpcyBjYXNlCiAgICAgICAgICAgIHRvRGlzcGxheSA9IHt9OwogICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHZhbHVlcykgewogICAgICAgICAgICAgIGlmICh2YWx1ZXMuaGFzT3duUHJvcGVydHkocHJvcCkpIHsKICAgICAgICAgICAgICAgIHRvRGlzcGxheVtwcm9wXSA9IGNhbGxFeHByZXNzaW9uKGRpc3BsYXlGbiwgcHJvcCwgdmFsdWVzW3Byb3BdKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0b0Rpc3BsYXk7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBjcmVhdGVJc1NlbGVjdGVkRm4odmlld1ZhbHVlKSB7CiAgICAgICAgICB2YXIgc2VsZWN0ZWRTZXQ7CiAgICAgICAgICBpZiAobXVsdGlwbGUpIHsKICAgICAgICAgICAgaWYgKHRyYWNrRm4gJiYgaXNBcnJheSh2aWV3VmFsdWUpKSB7CgogICAgICAgICAgICAgIHNlbGVjdGVkU2V0ID0gbmV3IEhhc2hNYXAoW10pOwogICAgICAgICAgICAgIGZvciAodmFyIHRyYWNrSW5kZXggPSAwOyB0cmFja0luZGV4IDwgdmlld1ZhbHVlLmxlbmd0aDsgdHJhY2tJbmRleCsrKSB7CiAgICAgICAgICAgICAgICAvLyB0cmFja2luZyBieSBrZXkKICAgICAgICAgICAgICAgIHNlbGVjdGVkU2V0LnB1dChjYWxsRXhwcmVzc2lvbih0cmFja0ZuLCBudWxsLCB2aWV3VmFsdWVbdHJhY2tJbmRleF0pLCB0cnVlKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgc2VsZWN0ZWRTZXQgPSBuZXcgSGFzaE1hcCh2aWV3VmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgaWYgKHRyYWNrRm4pIHsKICAgICAgICAgICAgdmlld1ZhbHVlID0gY2FsbEV4cHJlc3Npb24odHJhY2tGbiwgbnVsbCwgdmlld1ZhbHVlKTsKICAgICAgICAgIH0KCiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gaXNTZWxlY3RlZChrZXksIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBjb21wYXJlVmFsdWVGbjsKICAgICAgICAgICAgaWYgKHRyYWNrRm4pIHsKICAgICAgICAgICAgICBjb21wYXJlVmFsdWVGbiA9IHRyYWNrRm47CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VsZWN0QXNGbikgewogICAgICAgICAgICAgIGNvbXBhcmVWYWx1ZUZuID0gc2VsZWN0QXNGbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBjb21wYXJlVmFsdWVGbiA9IHZhbHVlRm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChtdWx0aXBsZSkgewogICAgICAgICAgICAgIHJldHVybiBpc0RlZmluZWQoc2VsZWN0ZWRTZXQucmVtb3ZlKGNhbGxFeHByZXNzaW9uKGNvbXBhcmVWYWx1ZUZuLCBrZXksIHZhbHVlKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJldHVybiB2aWV3VmFsdWUgPT09IGNhbGxFeHByZXNzaW9uKGNvbXBhcmVWYWx1ZUZuLCBrZXksIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHNjaGVkdWxlUmVuZGVyaW5nKCkgewogICAgICAgICAgaWYgKCFyZW5kZXJTY2hlZHVsZWQpIHsKICAgICAgICAgICAgc2NvcGUuJCRwb3N0RGlnZXN0KHJlbmRlcik7CiAgICAgICAgICAgIHJlbmRlclNjaGVkdWxlZCA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBBIG5ldyBsYWJlbE1hcCBpcyBjcmVhdGVkIHdpdGggZWFjaCByZW5kZXIuCiAgICAgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIGVhY2ggZXhpc3Rpbmcgb3B0aW9uIHdpdGggYWRkZWQ9ZmFsc2UsCiAgICAgICAgICogYW5kIGVhY2ggbmV3IG9wdGlvbiB3aXRoIGFkZGVkPXRydWUuCiAgICAgICAgICogLSBMYWJlbHMgdGhhdCBhcmUgcGFzc2VkIHRvIHRoaXMgbWV0aG9kIHR3aWNlLAogICAgICAgICAqIChvbmNlIHdpdGggYWRkZWQ9dHJ1ZSBhbmQgb25jZSB3aXRoIGFkZGVkPWZhbHNlKSB3aWxsIGVuZCB1cCB3aXRoIGEgdmFsdWUgb2YgMCwgYW5kCiAgICAgICAgICogd2lsbCBjYXVzZSBubyBjaGFuZ2UgdG8gaGFwcGVuIHRvIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbi4KICAgICAgICAgKiAtIExhYmVscyB0aGF0IGFyZSBwYXNzZWQgdG8gdGhpcyBtZXRob2Qgb25seSBvbmNlIHdpdGggYWRkZWQ9ZmFsc2Ugd2lsbCBlbmQgdXAgd2l0aCBhCiAgICAgICAgICogdmFsdWUgb2YgLTEgYW5kIHdpbGwgZXZlbnR1YWxseSBiZSBwYXNzZWQgdG8gc2VsZWN0Q3RybC5yZW1vdmVPcHRpb24oKQogICAgICAgICAqIC0gTGFiZWxzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGlzIG1ldGhvZCBvbmx5IG9uY2Ugd2l0aCBhZGRlZD10cnVlIHdpbGwgZW5kIHVwIHdpdGggYQogICAgICAgICAqIHZhbHVlIG9mIDEgYW5kIHdpbGwgZXZlbnR1YWxseSBiZSBwYXNzZWQgdG8gc2VsZWN0Q3RybC5hZGRPcHRpb24oKQogICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlTGFiZWxNYXAobGFiZWxNYXAsIGxhYmVsLCBhZGRlZCkgewogICAgICAgICAgbGFiZWxNYXBbbGFiZWxdID0gbGFiZWxNYXBbbGFiZWxdIHx8IDA7CiAgICAgICAgICBsYWJlbE1hcFtsYWJlbF0gKz0gKGFkZGVkID8gMSA6IC0xKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHJlbmRlcigpIHsKICAgICAgICAgIHJlbmRlclNjaGVkdWxlZCA9IGZhbHNlOwoKICAgICAgICAgIC8vIFRlbXBvcmFyeSBsb2NhdGlvbiBmb3IgdGhlIG9wdGlvbiBncm91cHMgYmVmb3JlIHdlIHJlbmRlciB0aGVtCiAgICAgICAgICB2YXIgb3B0aW9uR3JvdXBzID0geycnOltdfSwKICAgICAgICAgICAgICBvcHRpb25Hcm91cE5hbWVzID0gWycnXSwKICAgICAgICAgICAgICBvcHRpb25Hcm91cE5hbWUsCiAgICAgICAgICAgICAgb3B0aW9uR3JvdXAsCiAgICAgICAgICAgICAgb3B0aW9uLAogICAgICAgICAgICAgIGV4aXN0aW5nUGFyZW50LCBleGlzdGluZ09wdGlvbnMsIGV4aXN0aW5nT3B0aW9uLAogICAgICAgICAgICAgIHZpZXdWYWx1ZSA9IGN0cmwuJHZpZXdWYWx1ZSwKICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXNGbihzY29wZSkgfHwgW10sCiAgICAgICAgICAgICAga2V5cyA9IGtleU5hbWUgPyBzb3J0ZWRLZXlzKHZhbHVlcykgOiB2YWx1ZXMsCiAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgIHZhbHVlLAogICAgICAgICAgICAgIGdyb3VwTGVuZ3RoLCBsZW5ndGgsCiAgICAgICAgICAgICAgZ3JvdXBJbmRleCwgaW5kZXgsCiAgICAgICAgICAgICAgbGFiZWxNYXAgPSB7fSwKICAgICAgICAgICAgICBzZWxlY3RlZCwKICAgICAgICAgICAgICBpc1NlbGVjdGVkID0gY3JlYXRlSXNTZWxlY3RlZEZuKHZpZXdWYWx1ZSksCiAgICAgICAgICAgICAgYW55U2VsZWN0ZWQgPSBmYWxzZSwKICAgICAgICAgICAgICBsYXN0RWxlbWVudCwKICAgICAgICAgICAgICBlbGVtZW50LAogICAgICAgICAgICAgIGxhYmVsLAogICAgICAgICAgICAgIG9wdGlvbklkOwoKICAgICAgICAgIHRyYWNrS2V5c0NhY2hlID0ge307CgogICAgICAgICAgLy8gV2Ugbm93IGJ1aWxkIHVwIHRoZSBsaXN0IG9mIG9wdGlvbnMgd2UgbmVlZCAod2UgbWVyZ2UgbGF0ZXIpCiAgICAgICAgICBmb3IgKGluZGV4ID0gMDsgbGVuZ3RoID0ga2V5cy5sZW5ndGgsIGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgIGtleSA9IGluZGV4OwogICAgICAgICAgICBpZiAoa2V5TmFtZSkgewogICAgICAgICAgICAgIGtleSA9IGtleXNbaW5kZXhdOwogICAgICAgICAgICAgIGlmIChrZXkuY2hhckF0KDApID09PSAnJCcpIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVzW2tleV07CgogICAgICAgICAgICBvcHRpb25Hcm91cE5hbWUgPSBjYWxsRXhwcmVzc2lvbihncm91cEJ5Rm4sIGtleSwgdmFsdWUpIHx8ICcnOwogICAgICAgICAgICBpZiAoIShvcHRpb25Hcm91cCA9IG9wdGlvbkdyb3Vwc1tvcHRpb25Hcm91cE5hbWVdKSkgewogICAgICAgICAgICAgIG9wdGlvbkdyb3VwID0gb3B0aW9uR3JvdXBzW29wdGlvbkdyb3VwTmFtZV0gPSBbXTsKICAgICAgICAgICAgICBvcHRpb25Hcm91cE5hbWVzLnB1c2gob3B0aW9uR3JvdXBOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2VsZWN0ZWQgPSBpc1NlbGVjdGVkKGtleSwgdmFsdWUpOwogICAgICAgICAgICBhbnlTZWxlY3RlZCA9IGFueVNlbGVjdGVkIHx8IHNlbGVjdGVkOwoKICAgICAgICAgICAgbGFiZWwgPSBjYWxsRXhwcmVzc2lvbihkaXNwbGF5Rm4sIGtleSwgdmFsdWUpOyAvLyB3aGF0IHdpbGwgYmUgc2VlbiBieSB0aGUgdXNlcgoKICAgICAgICAgICAgLy8gZG9pbmcgZGlzcGxheUZuKHNjb3BlLCBsb2NhbHMpIHx8ICcnIG92ZXJ3cml0ZXMgemVybyB2YWx1ZXMKICAgICAgICAgICAgbGFiZWwgPSBpc0RlZmluZWQobGFiZWwpID8gbGFiZWwgOiAnJzsKICAgICAgICAgICAgb3B0aW9uSWQgPSB0cmFja0ZuID8gdHJhY2tGbihzY29wZSwgbG9jYWxzKSA6IChrZXlOYW1lID8ga2V5c1tpbmRleF0gOiBpbmRleCk7CiAgICAgICAgICAgIGlmICh0cmFja0ZuKSB7CiAgICAgICAgICAgICAgdHJhY2tLZXlzQ2FjaGVbb3B0aW9uSWRdID0ga2V5OwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcHRpb25Hcm91cC5wdXNoKHsKICAgICAgICAgICAgICAvLyBlaXRoZXIgdGhlIGluZGV4IGludG8gYXJyYXkgb3Iga2V5IGZyb20gb2JqZWN0CiAgICAgICAgICAgICAgaWQ6IG9wdGlvbklkLAogICAgICAgICAgICAgIGxhYmVsOiBsYWJlbCwKICAgICAgICAgICAgICBzZWxlY3RlZDogc2VsZWN0ZWQgICAgICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIGlmIHdlIHNob3VsZCBiZSBzZWxlY3RlZAogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghbXVsdGlwbGUpIHsKICAgICAgICAgICAgaWYgKG51bGxPcHRpb24gfHwgdmlld1ZhbHVlID09PSBudWxsKSB7CiAgICAgICAgICAgICAgLy8gaW5zZXJ0IG51bGwgb3B0aW9uIGlmIHdlIGhhdmUgYSBwbGFjZWhvbGRlciwgb3IgdGhlIG1vZGVsIGlzIG51bGwKICAgICAgICAgICAgICBvcHRpb25Hcm91cHNbJyddLnVuc2hpZnQoe2lkOicnLCBsYWJlbDonJywgc2VsZWN0ZWQ6IWFueVNlbGVjdGVkfSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWFueVNlbGVjdGVkKSB7CiAgICAgICAgICAgICAgLy8gb3B0aW9uIGNvdWxkIG5vdCBiZSBmb3VuZCwgd2UgaGF2ZSB0byBpbnNlcnQgdGhlIHVuZGVmaW5lZCBpdGVtCiAgICAgICAgICAgICAgb3B0aW9uR3JvdXBzWycnXS51bnNoaWZ0KHtpZDonPycsIGxhYmVsOicnLCBzZWxlY3RlZDp0cnVlfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyBOb3cgd2UgbmVlZCB0byB1cGRhdGUgdGhlIGxpc3Qgb2YgRE9NIG5vZGVzIHRvIG1hdGNoIHRoZSBvcHRpb25Hcm91cHMgd2UgY29tcHV0ZWQgYWJvdmUKICAgICAgICAgIGZvciAoZ3JvdXBJbmRleCA9IDAsIGdyb3VwTGVuZ3RoID0gb3B0aW9uR3JvdXBOYW1lcy5sZW5ndGg7CiAgICAgICAgICAgICAgIGdyb3VwSW5kZXggPCBncm91cExlbmd0aDsKICAgICAgICAgICAgICAgZ3JvdXBJbmRleCsrKSB7CiAgICAgICAgICAgIC8vIGN1cnJlbnQgb3B0aW9uIGdyb3VwIG5hbWUgb3IgJycgaWYgbm8gZ3JvdXAKICAgICAgICAgICAgb3B0aW9uR3JvdXBOYW1lID0gb3B0aW9uR3JvdXBOYW1lc1tncm91cEluZGV4XTsKCiAgICAgICAgICAgIC8vIGxpc3Qgb2Ygb3B0aW9ucyBmb3IgdGhhdCBncm91cC4gKGZpcnN0IGl0ZW0gaGFzIHRoZSBwYXJlbnQpCiAgICAgICAgICAgIG9wdGlvbkdyb3VwID0gb3B0aW9uR3JvdXBzW29wdGlvbkdyb3VwTmFtZV07CgogICAgICAgICAgICBpZiAob3B0aW9uR3JvdXBzQ2FjaGUubGVuZ3RoIDw9IGdyb3VwSW5kZXgpIHsKICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGdyb3cgdGhlIG9wdGlvbkdyb3VwcwogICAgICAgICAgICAgIGV4aXN0aW5nUGFyZW50ID0gewogICAgICAgICAgICAgICAgZWxlbWVudDogb3B0R3JvdXBUZW1wbGF0ZS5jbG9uZSgpLmF0dHIoJ2xhYmVsJywgb3B0aW9uR3JvdXBOYW1lKSwKICAgICAgICAgICAgICAgIGxhYmVsOiBvcHRpb25Hcm91cC5sYWJlbAogICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgZXhpc3RpbmdPcHRpb25zID0gW2V4aXN0aW5nUGFyZW50XTsKICAgICAgICAgICAgICBvcHRpb25Hcm91cHNDYWNoZS5wdXNoKGV4aXN0aW5nT3B0aW9ucyk7CiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5hcHBlbmQoZXhpc3RpbmdQYXJlbnQuZWxlbWVudCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZXhpc3RpbmdPcHRpb25zID0gb3B0aW9uR3JvdXBzQ2FjaGVbZ3JvdXBJbmRleF07CiAgICAgICAgICAgICAgZXhpc3RpbmdQYXJlbnQgPSBleGlzdGluZ09wdGlvbnNbMF07ICAvLyBlaXRoZXIgU0VMRUNUIChubyBncm91cCkgb3IgT1BUR1JPVVAgZWxlbWVudAoKICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIE9QVEdST1VQIGxhYmVsIGlmIG5vdCB0aGUgc2FtZS4KICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdQYXJlbnQubGFiZWwgIT0gb3B0aW9uR3JvdXBOYW1lKSB7CiAgICAgICAgICAgICAgICBleGlzdGluZ1BhcmVudC5lbGVtZW50LmF0dHIoJ2xhYmVsJywgZXhpc3RpbmdQYXJlbnQubGFiZWwgPSBvcHRpb25Hcm91cE5hbWUpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBudWxsOyAgLy8gc3RhcnQgYXQgdGhlIGJlZ2lubmluZwogICAgICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb3B0aW9uR3JvdXAubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgewogICAgICAgICAgICAgIG9wdGlvbiA9IG9wdGlvbkdyb3VwW2luZGV4XTsKICAgICAgICAgICAgICBpZiAoKGV4aXN0aW5nT3B0aW9uID0gZXhpc3RpbmdPcHRpb25zW2luZGV4ICsgMV0pKSB7CiAgICAgICAgICAgICAgICAvLyByZXVzZSBlbGVtZW50cwogICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBleGlzdGluZ09wdGlvbi5lbGVtZW50OwogICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nT3B0aW9uLmxhYmVsICE9PSBvcHRpb24ubGFiZWwpIHsKICAgICAgICAgICAgICAgICAgdXBkYXRlTGFiZWxNYXAobGFiZWxNYXAsIGV4aXN0aW5nT3B0aW9uLmxhYmVsLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgIHVwZGF0ZUxhYmVsTWFwKGxhYmVsTWFwLCBvcHRpb24ubGFiZWwsIHRydWUpOwogICAgICAgICAgICAgICAgICBsYXN0RWxlbWVudC50ZXh0KGV4aXN0aW5nT3B0aW9uLmxhYmVsID0gb3B0aW9uLmxhYmVsKTsKICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQucHJvcCgnbGFiZWwnLCBleGlzdGluZ09wdGlvbi5sYWJlbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdPcHRpb24uaWQgIT09IG9wdGlvbi5pZCkgewogICAgICAgICAgICAgICAgICBsYXN0RWxlbWVudC52YWwoZXhpc3RpbmdPcHRpb24uaWQgPSBvcHRpb24uaWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gbGFzdEVsZW1lbnQucHJvcCgnc2VsZWN0ZWQnKSBwcm92aWRlZCBieSBqUXVlcnkgaGFzIHNpZGUtZWZmZWN0cwogICAgICAgICAgICAgICAgaWYgKGxhc3RFbGVtZW50WzBdLnNlbGVjdGVkICE9PSBvcHRpb24uc2VsZWN0ZWQpIHsKICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQucHJvcCgnc2VsZWN0ZWQnLCAoZXhpc3RpbmdPcHRpb24uc2VsZWN0ZWQgPSBvcHRpb24uc2VsZWN0ZWQpKTsKICAgICAgICAgICAgICAgICAgaWYgKG1zaWUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTZWUgIzc2OTIKICAgICAgICAgICAgICAgICAgICAvLyBUaGUgc2VsZWN0ZWQgaXRlbSB3b3VsZG4ndCB2aXN1YWxseSB1cGRhdGUgb24gSUUgd2l0aG91dCB0aGlzLgogICAgICAgICAgICAgICAgICAgIC8vIFRlc3RlZCBvbiBXaW43OiBJRTksIElFMTAgYW5kIElFMTEuIEZ1dHVyZSBJRXMgc2hvdWxkIGJlIHRlc3RlZCBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQucHJvcCgnc2VsZWN0ZWQnLCBleGlzdGluZ09wdGlvbi5zZWxlY3RlZCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gZ3JvdyBlbGVtZW50cwoKICAgICAgICAgICAgICAgIC8vIGlmIGl0J3MgYSBudWxsIG9wdGlvbgogICAgICAgICAgICAgICAgaWYgKG9wdGlvbi5pZCA9PT0gJycgJiYgbnVsbE9wdGlvbikgewogICAgICAgICAgICAgICAgICAvLyBwdXQgYmFjayB0aGUgcHJlLWNvbXBpbGVkIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IG51bGxPcHRpb247CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvLyBqUXVlcnkodjEuNC4yKSBCdWc6IFdlIHNob3VsZCBiZSBhYmxlIHRvIGNoYWluIHRoZSBtZXRob2QgY2FsbHMsIGJ1dAogICAgICAgICAgICAgICAgICAvLyBpbiB0aGlzIHZlcnNpb24gb2YgalF1ZXJ5IG9uIHNvbWUgYnJvd3NlciB0aGUgLnRleHQoKSByZXR1cm5zIGEgc3RyaW5nCiAgICAgICAgICAgICAgICAgIC8vIHJhdGhlciB0aGVuIHRoZSBlbGVtZW50LgogICAgICAgICAgICAgICAgICAoZWxlbWVudCA9IG9wdGlvblRlbXBsYXRlLmNsb25lKCkpCiAgICAgICAgICAgICAgICAgICAgICAudmFsKG9wdGlvbi5pZCkKICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCdzZWxlY3RlZCcsIG9wdGlvbi5zZWxlY3RlZCkKICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCdzZWxlY3RlZCcsIG9wdGlvbi5zZWxlY3RlZCkKICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCdsYWJlbCcsIG9wdGlvbi5sYWJlbCkKICAgICAgICAgICAgICAgICAgICAgIC50ZXh0KG9wdGlvbi5sYWJlbCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZXhpc3RpbmdPcHRpb25zLnB1c2goZXhpc3RpbmdPcHRpb24gPSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudCwKICAgICAgICAgICAgICAgICAgICBsYWJlbDogb3B0aW9uLmxhYmVsLAogICAgICAgICAgICAgICAgICAgIGlkOiBvcHRpb24uaWQsCiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IG9wdGlvbi5zZWxlY3RlZAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB1cGRhdGVMYWJlbE1hcChsYWJlbE1hcCwgb3B0aW9uLmxhYmVsLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmIChsYXN0RWxlbWVudCkgewogICAgICAgICAgICAgICAgICBsYXN0RWxlbWVudC5hZnRlcihlbGVtZW50KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFyZW50LmVsZW1lbnQuYXBwZW5kKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBlbGVtZW50OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyByZW1vdmUgYW55IGV4Y2Vzc2l2ZSBPUFRJT05zIGluIGEgZ3JvdXAKICAgICAgICAgICAgaW5kZXgrKzsgLy8gaW5jcmVtZW50IHNpbmNlIHRoZSBleGlzdGluZ09wdGlvbnNbMF0gaXMgcGFyZW50IGVsZW1lbnQgbm90IE9QVElPTgogICAgICAgICAgICB3aGlsZSAoZXhpc3RpbmdPcHRpb25zLmxlbmd0aCA+IGluZGV4KSB7CiAgICAgICAgICAgICAgb3B0aW9uID0gZXhpc3RpbmdPcHRpb25zLnBvcCgpOwogICAgICAgICAgICAgIHVwZGF0ZUxhYmVsTWFwKGxhYmVsTWFwLCBvcHRpb24ubGFiZWwsIGZhbHNlKTsKICAgICAgICAgICAgICBvcHRpb24uZWxlbWVudC5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLy8gcmVtb3ZlIGFueSBleGNlc3NpdmUgT1BUR1JPVVBzIGZyb20gc2VsZWN0CiAgICAgICAgICB3aGlsZSAob3B0aW9uR3JvdXBzQ2FjaGUubGVuZ3RoID4gZ3JvdXBJbmRleCkgewogICAgICAgICAgICAvLyByZW1vdmUgYWxsIHRoZSBsYWJlbHMgaW4gdGhlIG9wdGlvbiBncm91cAogICAgICAgICAgICBvcHRpb25Hcm91cCA9IG9wdGlvbkdyb3Vwc0NhY2hlLnBvcCgpOwogICAgICAgICAgICBmb3IgKGluZGV4ID0gMTsgaW5kZXggPCBvcHRpb25Hcm91cC5sZW5ndGg7ICsraW5kZXgpIHsKICAgICAgICAgICAgICB1cGRhdGVMYWJlbE1hcChsYWJlbE1hcCwgb3B0aW9uR3JvdXBbaW5kZXhdLmxhYmVsLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3B0aW9uR3JvdXBbMF0uZWxlbWVudC5yZW1vdmUoKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvckVhY2gobGFiZWxNYXAsIGZ1bmN0aW9uKGNvdW50LCBsYWJlbCkgewogICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgICAgICAgICAgc2VsZWN0Q3RybC5hZGRPcHRpb24obGFiZWwpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNvdW50IDwgMCkgewogICAgICAgICAgICAgIHNlbGVjdEN0cmwucmVtb3ZlT3B0aW9uKGxhYmVsKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfV07Cgp2YXIgb3B0aW9uRGlyZWN0aXZlID0gWyckaW50ZXJwb2xhdGUnLCBmdW5jdGlvbigkaW50ZXJwb2xhdGUpIHsKICB2YXIgbnVsbFNlbGVjdEN0cmwgPSB7CiAgICBhZGRPcHRpb246IG5vb3AsCiAgICByZW1vdmVPcHRpb246IG5vb3AKICB9OwoKICByZXR1cm4gewogICAgcmVzdHJpY3Q6ICdFJywKICAgIHByaW9yaXR5OiAxMDAsCiAgICBjb21waWxlOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyKSB7CiAgICAgIGlmIChpc1VuZGVmaW5lZChhdHRyLnZhbHVlKSkgewogICAgICAgIHZhciBpbnRlcnBvbGF0ZUZuID0gJGludGVycG9sYXRlKGVsZW1lbnQudGV4dCgpLCB0cnVlKTsKICAgICAgICBpZiAoIWludGVycG9sYXRlRm4pIHsKICAgICAgICAgIGF0dHIuJHNldCgndmFsdWUnLCBlbGVtZW50LnRleHQoKSk7CiAgICAgICAgfQogICAgICB9CgogICAgICByZXR1cm4gZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQsIGF0dHIpIHsKICAgICAgICB2YXIgc2VsZWN0Q3RybE5hbWUgPSAnJHNlbGVjdENvbnRyb2xsZXInLAogICAgICAgICAgICBwYXJlbnQgPSBlbGVtZW50LnBhcmVudCgpLAogICAgICAgICAgICBzZWxlY3RDdHJsID0gcGFyZW50LmRhdGEoc2VsZWN0Q3RybE5hbWUpIHx8CiAgICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLmRhdGEoc2VsZWN0Q3RybE5hbWUpOyAvLyBpbiBjYXNlIHdlIGFyZSBpbiBvcHRncm91cAoKICAgICAgICBpZiAoIXNlbGVjdEN0cmwgfHwgIXNlbGVjdEN0cmwuZGF0YWJvdW5kKSB7CiAgICAgICAgICBzZWxlY3RDdHJsID0gbnVsbFNlbGVjdEN0cmw7CiAgICAgICAgfQoKICAgICAgICBpZiAoaW50ZXJwb2xhdGVGbikgewogICAgICAgICAgc2NvcGUuJHdhdGNoKGludGVycG9sYXRlRm4sIGZ1bmN0aW9uIGludGVycG9sYXRlV2F0Y2hBY3Rpb24obmV3VmFsLCBvbGRWYWwpIHsKICAgICAgICAgICAgYXR0ci4kc2V0KCd2YWx1ZScsIG5ld1ZhbCk7CiAgICAgICAgICAgIGlmIChvbGRWYWwgIT09IG5ld1ZhbCkgewogICAgICAgICAgICAgIHNlbGVjdEN0cmwucmVtb3ZlT3B0aW9uKG9sZFZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VsZWN0Q3RybC5hZGRPcHRpb24obmV3VmFsLCBlbGVtZW50KTsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzZWxlY3RDdHJsLmFkZE9wdGlvbihhdHRyLnZhbHVlLCBlbGVtZW50KTsKICAgICAgICB9CgogICAgICAgIGVsZW1lbnQub24oJyRkZXN0cm95JywgZnVuY3Rpb24oKSB7CiAgICAgICAgICBzZWxlY3RDdHJsLnJlbW92ZU9wdGlvbihhdHRyLnZhbHVlKTsKICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9Owp9XTsKCnZhciBzdHlsZURpcmVjdGl2ZSA9IHZhbHVlRm4oewogIHJlc3RyaWN0OiAnRScsCiAgdGVybWluYWw6IGZhbHNlCn0pOwoKICBpZiAod2luZG93LmFuZ3VsYXIuYm9vdHN0cmFwKSB7CiAgICAvL0FuZ3VsYXJKUyBpcyBhbHJlYWR5IGxvYWRlZCwgc28gd2UgY2FuIHJldHVybiBoZXJlLi4uCiAgICBjb25zb2xlLmxvZygnV0FSTklORzogVHJpZWQgdG8gbG9hZCBhbmd1bGFyIG1vcmUgdGhhbiBvbmNlLicpOwogICAgcmV0dXJuOwogIH0KCiAgLy90cnkgdG8gYmluZCB0byBqcXVlcnkgbm93IHNvIHRoYXQgb25lIGNhbiB3cml0ZSBqcUxpdGUoZG9jdW1lbnQpLnJlYWR5KCkKICAvL2J1dCB3ZSB3aWxsIHJlYmluZCBvbiBib290c3RyYXAgYWdhaW4uCiAgYmluZEpRdWVyeSgpOwoKICBwdWJsaXNoRXh0ZXJuYWxBUEkoYW5ndWxhcik7CgogIGpxTGl0ZShkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKSB7CiAgICBhbmd1bGFySW5pdChkb2N1bWVudCwgYm9vdHN0cmFwKTsKICB9KTsKCn0pKHdpbmRvdywgZG9jdW1lbnQpOwoKIXdpbmRvdy5hbmd1bGFyLiQkY3NwKCkgJiYgd2luZG93LmFuZ3VsYXIuZWxlbWVudChkb2N1bWVudCkuZmluZCgnaGVhZCcpLnByZXBlbmQoJzxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+QGNoYXJzZXQgIlVURi04IjtbbmdcXDpjbG9ha10sW25nLWNsb2FrXSxbZGF0YS1uZy1jbG9ha10sW3gtbmctY2xvYWtdLC5uZy1jbG9haywueC1uZy1jbG9haywubmctaGlkZTpub3QoLm5nLWhpZGUtYW5pbWF0ZSl7ZGlzcGxheTpub25lICFpbXBvcnRhbnQ7fW5nXFw6Zm9ybXtkaXNwbGF5OmJsb2NrO308L3N0eWxlPicpOwo=