mage-engine 3.25.3 → 3.25.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/mage.js +13 -7
  2. package/package.json +1 -1
package/dist/mage.js CHANGED
@@ -55720,7 +55720,7 @@ function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
55720
55720
  url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
55721
55721
  return new Worker(url, options);
55722
55722
  };
55723
- }var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IExJQlJBUllfTkFNRSA9ICJhbW1vLmpzIjsKICAgIGNvbnN0IFRZUEVTID0gewogICAgICBCT1g6ICJCT1giLAogICAgICBTUEhFUkU6ICJTUEhFUkUiLAogICAgICBWRUhJQ0xFOiAiVkVISUNMRSIsCiAgICAgIE1FU0g6ICJNRVNIIiwKICAgICAgUExBWUVSOiAiUExBWUVSIgogICAgfTsKICAgIGNvbnN0IERFRkFVTFRfVkVISUNMRV9TVEFURSA9IHsKICAgICAgdmVoaWNsZVN0ZWVyaW5nOiAwLAogICAgICBhY2NlbGVyYXRpb246IGZhbHNlLAogICAgICBicmVha2luZzogZmFsc2UsCiAgICAgIHJpZ2h0OiBmYWxzZSwKICAgICAgbGVmdDogZmFsc2UKICAgIH07CiAgICBjb25zdCBERUZBVUxUX1JJR0lEQk9EWV9TVEFURSA9IHsKICAgICAgdmVsb2NpdHk6IHsKICAgICAgICB4OiAwLAogICAgICAgIHk6IDAsCiAgICAgICAgejogMAogICAgICB9LAogICAgICBtb3ZlbWVudDogewogICAgICAgIGZvcndhcmQ6IGZhbHNlLAogICAgICAgIGJhY2t3YXJkczogZmFsc2UsCiAgICAgICAgbGVmdDogZmFsc2UsCiAgICAgICAgcmlnaHQ6IGZhbHNlCiAgICAgIH0sCiAgICAgIGRpcmVjdGlvbjogewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwCiAgICAgIH0KICAgIH07CiAgICBjb25zdCBERUZBVUxUX1NDQUxFID0gewogICAgICB4OiAxLAogICAgICB5OiAxLAogICAgICB6OiAxCiAgICB9OwogICAgY29uc3QgREVGQVVMVF9MSU5FQVJfVkVMT0NJVFkgPSB7CiAgICAgIHg6IDAsCiAgICAgIHk6IDAsCiAgICAgIHo6IDAKICAgIH07CiAgICBjb25zdCBERUZBVUxUX0lNUFVMU0UgPSB7CiAgICAgIHg6IDAsCiAgICAgIHk6IDAsCiAgICAgIHo6IDAKICAgIH07CiAgICBjb25zdCBESVNBQkxFX0RFQUNUSVZBVElPTiA9IDQ7CiAgICBjb25zdCBHUkFWSVRZID0gewogICAgICB4OiAwLAogICAgICB5OiAtOS44LAogICAgICB6OiAwCiAgICB9OwogICAgY29uc3QgRlJPTlRfTEVGVCA9IDA7CiAgICBjb25zdCBGUk9OVF9SSUdIVCA9IDE7CiAgICBjb25zdCBCQUNLX0xFRlQgPSAyOwogICAgY29uc3QgQkFDS19SSUdIVCA9IDM7CiAgICBjb25zdCBERUZBVUxUX1NURUVSSU5HX0lOQ1JFTUVOVCA9IDAuMDQ7CiAgICBjb25zdCBERUZBVUxUX1NURUVSSU5HX0NMQU1QID0gMC41OwogICAgY29uc3QgREVGQVVMVF9NQVhfRU5HSU5FX0ZPUkNFID0gMjAwMDsKICAgIGNvbnN0IERFRkFVTFRfTUFYX0JSRUFLSU5HX0ZPUkNFID0gMTAwOwogICAgY29uc3QgRVhQTE9TSU9OX1NJWkVTID0gewogICAgICBTTUFMTDogNCwKICAgICAgTUVESVVNOiA2LAogICAgICBMQVJHRTogOCwKICAgICAgTUFTU0lWRTogMTIKICAgIH07CiAgICBjb25zdCBFWFBMT1NJT05fU1RSRU5HVEhTID0gewogICAgICBWRVJZX1dFQUs6IDIsCiAgICAgIFdFQUs6IDQsCiAgICAgIE1FRElVTTogOCwKICAgICAgTEFSR0U6IDE2LAogICAgICBNQVNTSVZFOiAzMiwKICAgICAgT0tfTk86IDY0CiAgICB9OwoKICAgIGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhhLCBuKSB7CiAgICAgIGlmICghKGEgaW5zdGFuY2VvZiBuKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7CiAgICB9CiAgICBmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyhlLCByKSB7CiAgICAgIGZvciAodmFyIHQgPSAwOyB0IDwgci5sZW5ndGg7IHQrKykgewogICAgICAgIHZhciBvID0gclt0XTsKICAgICAgICBvLmVudW1lcmFibGUgPSBvLmVudW1lcmFibGUgfHwgITEsIG8uY29uZmlndXJhYmxlID0gITAsICJ2YWx1ZSIgaW4gbyAmJiAoby53cml0YWJsZSA9ICEwKSwgT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsIF90b1Byb3BlcnR5S2V5KG8ua2V5KSwgbyk7CiAgICAgIH0KICAgIH0KICAgIGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhlLCByLCB0KSB7CiAgICAgIHJldHVybiByICYmIF9kZWZpbmVQcm9wZXJ0aWVzKGUucHJvdG90eXBlLCByKSwgdCAmJiBfZGVmaW5lUHJvcGVydGllcyhlLCB0KSwgT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsICJwcm90b3R5cGUiLCB7CiAgICAgICAgd3JpdGFibGU6ICExCiAgICAgIH0pLCBlOwogICAgfQogICAgZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KGUsIHIsIHQpIHsKICAgICAgcmV0dXJuIChyID0gX3RvUHJvcGVydHlLZXkocikpIGluIGUgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkoZSwgciwgewogICAgICAgIHZhbHVlOiB0LAogICAgICAgIGVudW1lcmFibGU6ICEwLAogICAgICAgIGNvbmZpZ3VyYWJsZTogITAsCiAgICAgICAgd3JpdGFibGU6ICEwCiAgICAgIH0pIDogZVtyXSA9IHQsIGU7CiAgICB9CiAgICBmdW5jdGlvbiBfdG9QcmltaXRpdmUodCwgcikgewogICAgICBpZiAoIm9iamVjdCIgIT0gdHlwZW9mIHQgfHwgIXQpIHJldHVybiB0OwogICAgICB2YXIgZSA9IHRbU3ltYm9sLnRvUHJpbWl0aXZlXTsKICAgICAgaWYgKHZvaWQgMCAhPT0gZSkgewogICAgICAgIHZhciBpID0gZS5jYWxsKHQsIHIgfHwgImRlZmF1bHQiKTsKICAgICAgICBpZiAoIm9iamVjdCIgIT0gdHlwZW9mIGkpIHJldHVybiBpOwogICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuICgic3RyaW5nIiA9PT0gciA/IFN0cmluZyA6IE51bWJlcikodCk7CiAgICB9CiAgICBmdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleSh0KSB7CiAgICAgIHZhciBpID0gX3RvUHJpbWl0aXZlKHQsICJzdHJpbmciKTsKICAgICAgcmV0dXJuICJzeW1ib2wiID09IHR5cGVvZiBpID8gaSA6IGkgKyAiIjsKICAgIH0KCiAgICBjb25zdCBQSFlTSUNTX0VWRU5UUyA9IHsKICAgICAgRElTUEFUQ0g6ICJwaHlzaWNzOmRpc3BhdGNoIiwKICAgICAgVEVSTUlOQVRFOiAicGh5c2ljczp0ZXJtaW5hdGUiLAogICAgICBMT0FEOiB7CiAgICAgICAgQU1NTzogInBoeXNpY3M6bG9hZDphbW1vIgogICAgICB9LAogICAgICBSRUFEWTogInBoeXNpY3M6cmVhZHkiLAogICAgICBJTklUOiAicGh5c2ljczppbml0IiwKICAgICAgVVBEQVRFOiAicGh5c2ljczp1cGRhdGUiLAogICAgICBBREQ6IHsKICAgICAgICBCT1g6ICJwaHlzaWNzOmFkZDpib3giLAogICAgICAgIFZFSElDTEU6ICJwaHlzaWNzOmFkZDp2ZWhpY2xlIiwKICAgICAgICBNT0RFTDogInBoeXNpY3M6YWRkOm1vZGVsIiwKICAgICAgICBQTEFZRVI6ICJwaHlzaWNzOmFkZDpwbGF5ZXIiLAogICAgICAgIFNQSEVSRTogInBoeXNpY3M6YWRkOnNwaGVyZSIKICAgICAgfSwKICAgICAgRUxFTUVOVDogewogICAgICAgIERJU1BPU0U6ICJwaHlzaWNzOmVsZW1lbnQ6ZGlzcG9zZSIsCiAgICAgICAgQ09MTElTSU9OOiAicGh5c2ljczplbGVtZW50OmNvbGxpc2lvbiIsCiAgICAgICAgVVBEQVRFOiAicGh5c2ljczplbGVtZW50OnVwZGF0ZSIsCiAgICAgICAgQ1JFQVRFRDogInBoeXNpY3M6ZWxlbWVudDpjcmVhdGVkIiwKICAgICAgICBTRVQ6IHsKICAgICAgICAgIFBPU0lUSU9OOiAicGh5c2ljczplbGVtZW50OnNldDpwb3NpdGlvbiIsCiAgICAgICAgICBRVUFURVJOSU9OOiAicGh5c2ljczplbGVtZW50OnNldDpxdWF0ZXJuaW9uIiwKICAgICAgICAgIExJTkVBUl9WRUxPQ0lUWTogInBoeXNpY3M6ZWxlbWVudDpzZXQ6bGluZWFyX3ZlbG9jaXR5IgogICAgICAgIH0sCiAgICAgICAgUkVTRVQ6ICJwaHlzaWNzOmVsZW1lbnQ6cmVzZXQiLAogICAgICAgIEFQUExZOiB7CiAgICAgICAgICBJTVBVTFNFOiAicGh5c2ljczplbGVtZW50OmFwcGx5OmltcHVsc2UiCiAgICAgICAgfQogICAgICB9LAogICAgICBWRUhJQ0xFOiB7CiAgICAgICAgU0VUOiB7CiAgICAgICAgICBQT1NJVElPTjogInBoeXNpY3M6dmVoaWNsZTpzZXQ6cG9zaXRpb24iLAogICAgICAgICAgUVVBVEVSTklPTjogInBoeXNpY3M6dmVoaWNsZTpzZXQ6cXVhdGVybmlvbiIKICAgICAgICB9LAogICAgICAgIFJFU0VUOiAicGh5c2ljczp2ZWhpY2xlOnJlc2V0IiwKICAgICAgICBTUEVFRDogInBoeXNpY3M6dmVoaWNsZTpzcGVlZCIsCiAgICAgICAgRElSRUNUSU9OOiAicGh5c2ljczp2ZWhpY2xlOmRpcmVjdGlvbiIKICAgICAgfSwKICAgICAgRUZGRUNUUzogewogICAgICAgIEVYUExPU0lPTjogInBoeXNpY3M6ZWZmZWN0czpleHBsb3Npb24iCiAgICAgIH0KICAgIH07CgogICAgbGV0IERpc3BhdGNoZXIgPSAvKiNfX1BVUkVfXyovX2NyZWF0ZUNsYXNzKGZ1bmN0aW9uIERpc3BhdGNoZXIoKSB7CiAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEaXNwYXRjaGVyKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kUGh5c2ljc1VwZGF0ZSIsIGR0ID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuVVBEQVRFLAogICAgICAgIGR0CiAgICAgIH0pKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kUmVhZHlFdmVudCIsICgpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuUkVBRFkKICAgICAgfSkpOwogICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInNlbmRUZXJtaW5hdGVFdmVudCIsICgpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuVEVSTUlOQVRFCiAgICAgIH0pKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kQm9keVVwZGF0ZSIsICh1dWlkLCBwb3NpdGlvbiwgcm90YXRpb24sIGR0LCBleHRyYURhdGEpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5VUERBVEUsCiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbjogewogICAgICAgICAgeDogcG9zaXRpb24ueCgpLAogICAgICAgICAgeTogcG9zaXRpb24ueSgpLAogICAgICAgICAgejogcG9zaXRpb24ueigpCiAgICAgICAgfSwKICAgICAgICBxdWF0ZXJuaW9uOiB7CiAgICAgICAgICB4OiByb3RhdGlvbi54KCksCiAgICAgICAgICB5OiByb3RhdGlvbi55KCksCiAgICAgICAgICB6OiByb3RhdGlvbi56KCksCiAgICAgICAgICB3OiByb3RhdGlvbi53KCkKICAgICAgICB9LAogICAgICAgIC4uLmV4dHJhRGF0YSwKICAgICAgICBkdAogICAgICB9KSk7CiAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic2VuZERpc3BhdGNoRXZlbnQiLCAodXVpZCwgZXZlbnROYW1lLCBldmVudERhdGEpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRElTUEFUQ0gsCiAgICAgICAgdXVpZCwKICAgICAgICBldmVudE5hbWUsCiAgICAgICAgZXZlbnREYXRhCiAgICAgIH0pKTsKICAgIH0pOwogICAgdmFyIGRpc3BhdGNoZXIgPSBuZXcgRGlzcGF0Y2hlcigpOwoKICAgIGNvbnN0IGFwcGx5TWF0cml4NFRvVmVjdG9yMyA9ICh7CiAgICAgIHggPSAwLAogICAgICB5ID0gMCwKICAgICAgeiA9IDAKICAgIH0sIG1hdHJpeCA9IFtdKSA9PiB7CiAgICAgIGNvbnN0IHcgPSAxIC8gKG1hdHJpeFszXSAqIHggKyBtYXRyaXhbN10gKiB5ICsgbWF0cml4WzExXSAqIHogKyBtYXRyaXhbMTVdKTsKICAgICAgcmV0dXJuIHsKICAgICAgICB4OiAobWF0cml4WzBdICogeCArIG1hdHJpeFs0XSAqIHkgKyBtYXRyaXhbOF0gKiB6ICsgbWF0cml4WzEyXSkgKiB3LAogICAgICAgIHk6IChtYXRyaXhbMV0gKiB4ICsgbWF0cml4WzVdICogeSArIG1hdHJpeFs5XSAqIHogKyBtYXRyaXhbMTNdKSAqIHcsCiAgICAgICAgejogKG1hdHJpeFsyXSAqIHggKyBtYXRyaXhbNl0gKiB5ICsgbWF0cml4WzEwXSAqIHogKyBtYXRyaXhbMTRdKSAqIHcKICAgICAgfTsKICAgIH07CgogICAgY29uc3QgY3JlYXRlUmlnaWRCb2R5ID0gKHNoYXBlLCBvcHRpb25zKSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbiwKICAgICAgICByZXN0aXR1dGlvbiA9IDAuOSwKICAgICAgICBkYW1waW5nID0gewogICAgICAgICAgbGluZWFyOiAwLjIsCiAgICAgICAgICBhbmd1bGFyOiAwLjIKICAgICAgICB9CiAgICAgIH0gPSBvcHRpb25zOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IG5ldyBBbW1vLmJ0RGVmYXVsdE1vdGlvblN0YXRlKHRyYW5zZm9ybSk7CiAgICAgIGNvbnN0IGxvY2FsSW5lcnRpYSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgc2hhcGUuY2FsY3VsYXRlTG9jYWxJbmVydGlhKG1hc3MsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IHJiSW5mbyA9IG5ldyBBbW1vLmJ0UmlnaWRCb2R5Q29uc3RydWN0aW9uSW5mbyhtYXNzLCBtb3Rpb25TdGF0ZSwgc2hhcGUsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IGJvZHkgPSBuZXcgQW1tby5idFJpZ2lkQm9keShyYkluZm8pOwogICAgICBpZiAobWFzcyA+IDApIHsKICAgICAgICBib2R5LnNldEZyaWN0aW9uKGZyaWN0aW9uKTsKICAgICAgICBib2R5LnNldFJlc3RpdHV0aW9uKHJlc3RpdHV0aW9uKTsKICAgICAgICBib2R5LnNldERhbXBpbmcoZGFtcGluZy5saW5lYXIsIGRhbXBpbmcuYW5ndWxhcik7CiAgICAgICAgYm9keS5zZXRBY3RpdmF0aW9uU3RhdGUoRElTQUJMRV9ERUFDVElWQVRJT04pOwogICAgICB9CgogICAgICAvLyBzdG9yaW5nIHV1aWQgZm9yIGZ1dHVyZSByZWZlcmVuY2UKICAgICAgYm9keS51dWlkID0gdXVpZDsKICAgICAgd29ybGQuYWRkUmlnaWRCb2R5KGJvZHkpOwogICAgICByZXR1cm4gYm9keTsKICAgIH07CiAgICBjb25zdCBhZGRNb2RlbCA9IG9wdGlvbnMgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICB2ZXJ0aWNlcywKICAgICAgICBtYXRyaWNlcywKICAgICAgICBpbmRleGVzLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24gPSAyCiAgICAgIH0gPSBvcHRpb25zOwogICAgICBjb25zdCBzY2FsZSA9IERFRkFVTFRfU0NBTEU7CiAgICAgIGNvbnN0IGJ0YSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygpOwogICAgICBjb25zdCBidGIgPSBuZXcgQW1tby5idFZlY3RvcjMoKTsKICAgICAgY29uc3QgYnRjID0gbmV3IEFtbW8uYnRWZWN0b3IzKCk7CiAgICAgIGNvbnN0IHRyaU1lc2ggPSBuZXcgQW1tby5idFRyaWFuZ2xlTWVzaCh0cnVlLCBmYWxzZSk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmVydGljZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBjb25zdCBjb21wb25lbnRzID0gdmVydGljZXNbaV07CiAgICAgICAgY29uc3QgaW5kZXggPSBpbmRleGVzW2ldID8gaW5kZXhlc1tpXSA6IG51bGw7CiAgICAgICAgY29uc3QgbWF0cml4ID0gQXJyYXkuZnJvbShtYXRyaWNlc1tpXSk7CiAgICAgICAgaWYgKGluZGV4KSB7CiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGluZGV4Lmxlbmd0aDsgaiArPSAzKSB7CiAgICAgICAgICAgIGNvbnN0IGFpID0gaW5kZXhbal0gKiAzOwogICAgICAgICAgICBjb25zdCBiaSA9IGluZGV4W2ogKyAxXSAqIDM7CiAgICAgICAgICAgIGNvbnN0IGNpID0gaW5kZXhbaiArIDJdICogMzsKICAgICAgICAgICAgY29uc3QgdmEgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbYWldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbYWkgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2FpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmIgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbYmldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbYmkgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2JpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmMgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbY2ldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbY2kgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2NpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgYnRhLnNldFZhbHVlKHZhLngsIHZhLnksIHZhLnopOwogICAgICAgICAgICBidGIuc2V0VmFsdWUodmIueCwgdmIueSwgdmIueik7CiAgICAgICAgICAgIGJ0Yy5zZXRWYWx1ZSh2Yy54LCB2Yy55LCB2Yy56KTsKICAgICAgICAgICAgdHJpTWVzaC5hZGRUcmlhbmdsZShidGEsIGJ0YiwgYnRjLCBmYWxzZSk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29tcG9uZW50cy5sZW5ndGg7IGogKz0gOSkgewogICAgICAgICAgICBjb25zdCB2YSA9IGFwcGx5TWF0cml4NFRvVmVjdG9yMyh7CiAgICAgICAgICAgICAgeDogY29tcG9uZW50c1tqICsgMF0sCiAgICAgICAgICAgICAgeTogY29tcG9uZW50c1tqICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tqICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmIgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbaiArIDNdLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbaiArIDRdLAogICAgICAgICAgICAgIHo6IGNvbXBvbmVudHNbaiArIDVdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZjID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2ogKyA2XSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2ogKyA3XSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2ogKyA4XQogICAgICAgICAgICB9LCBtYXRyaXgpOwogICAgICAgICAgICBidGEuc2V0VmFsdWUodmEueCwgdmEueSwgdmEueik7CiAgICAgICAgICAgIGJ0Yi5zZXRWYWx1ZSh2Yi54LCB2Yi55LCB2Yi56KTsKICAgICAgICAgICAgYnRjLnNldFZhbHVlKHZjLngsIHZjLnksIHZjLnopOwogICAgICAgICAgICB0cmlNZXNoLmFkZFRyaWFuZ2xlKGJ0YSwgYnRiLCBidGMsIGZhbHNlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgY29uc3QgbG9jYWxTY2FsZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhzY2FsZS54LCBzY2FsZS55LCBzY2FsZS56KTsKICAgICAgdHJpTWVzaC5zZXRTY2FsaW5nKGxvY2FsU2NhbGUpOwogICAgICBBbW1vLmRlc3Ryb3kobG9jYWxTY2FsZSk7CiAgICAgIGNvbnN0IGNvbGxpc2lvblNoYXBlID0gbmV3IEFtbW8uYnRCdmhUcmlhbmdsZU1lc2hTaGFwZSh0cmlNZXNoLCB0cnVlLCB0cnVlKTsKICAgICAgY29sbGlzaW9uU2hhcGUucmVzb3VyY2VzID0gW3RyaU1lc2hdOwogICAgICBBbW1vLmRlc3Ryb3koYnRhKTsKICAgICAgQW1tby5kZXN0cm95KGJ0Yik7CiAgICAgIEFtbW8uZGVzdHJveShidGMpOwogICAgICBjb25zdCBib2R5ID0gY3JlYXRlUmlnaWRCb2R5KGNvbGxpc2lvblNoYXBlLCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MsCiAgICAgICAgZnJpY3Rpb24KICAgICAgfSk7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHV1aWQsCiAgICAgICAgYm9keSwKICAgICAgICB0eXBlOiBUWVBFUy5NRVNILAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBhZGRCb3ggPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgd2lkdGgsCiAgICAgICAgbGVuZ3RoLAogICAgICAgIGhlaWdodCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idEJveFNoYXBlKG5ldyBBbW1vLmJ0VmVjdG9yMyh3aWR0aCAqIDAuNSwgaGVpZ2h0ICogMC41LCBsZW5ndGggKiAwLjUpKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShnZW9tZXRyeSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuQk9YLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBhZGRTcGhlcmUgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcmFkaXVzLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24gPSAyCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBBbW1vLmJ0U3BoZXJlU2hhcGUocmFkaXVzKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShnZW9tZXRyeSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuU1BIRVJFLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBzZXRMaW5lYXJWZWxvY2l0eSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICB2ZWxvY2l0eSA9IERFRkFVTFRfTElORUFSX1ZFTE9DSVRZCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIGNvbnN0IGxpbmVhclZlbG9jaXR5ID0gbmV3IEFtbW8uYnRWZWN0b3IzKHZlbG9jaXR5LngsIHZlbG9jaXR5LnksIHZlbG9jaXR5LnopOwogICAgICAgIGJvZHkuc2V0TGluZWFyVmVsb2NpdHkobGluZWFyVmVsb2NpdHkpOwogICAgICAgIEFtbW8uZGVzdHJveShsaW5lYXJWZWxvY2l0eSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBzZXRQb3NpdGlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHJlc2V0RWxlbWVudCA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0T3JpZ2luKG5ldyBBbW1vLmJ0VmVjdG9yMyhwb3NpdGlvbi54LCBwb3NpdGlvbi55LCBwb3NpdGlvbi56KSk7CiAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24ocXVhdGVybmlvbi54LCBxdWF0ZXJuaW9uLnksIHF1YXRlcm5pb24ueiwgcXVhdGVybmlvbi53KSk7CiAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgLy8gQWxzbyB1cGRhdGUgbW90aW9uIHN0YXRlIHNvIHN0YXRpYyBib2RpZXMgKG1hc3M9MCkgcmVmbGVjdCB0aGUgY2hhbmdlCiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBtb3Rpb25TdGF0ZS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgYXBwbHlJbXB1c2UgPSAoewogICAgICB1dWlkLAogICAgICBpbXB1bHNlID0gREVGQVVMVF9JTVBVTFNFCiAgICB9KSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgaWYgKCFlbGVtZW50KSB7CiAgICAgICAgICBjb25zb2xlLndhcm4oIltQaHlzaWNzIFdvcmtlcl0gYXBwbHlJbXB1bHNlOiBlbGVtZW50IG5vdCBmb3VuZCBmb3IgdXVpZDoiLCB1dWlkKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgY29uc3QgewogICAgICAgICAgYm9keQogICAgICAgIH0gPSBlbGVtZW50OwogICAgICAgIGlmICghYm9keSkgewogICAgICAgICAgY29uc29sZS53YXJuKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZTogYm9keSBpcyBudWxsIGZvciB1dWlkOiIsIHV1aWQpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBib2R5LmFjdGl2YXRlKHRydWUpOwogICAgICAgIGNvbnN0IGJ0SW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhpbXB1bHNlLngsIGltcHVsc2UueSwgaW1wdWxzZS56KTsKICAgICAgICBib2R5LmFwcGx5Q2VudHJhbEltcHVsc2UoYnRJbXB1bHNlKTsKICAgICAgICBBbW1vLmRlc3Ryb3koYnRJbXB1bHNlKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIGNvbnNvbGUuZXJyb3IoIltQaHlzaWNzIFdvcmtlcl0gYXBwbHlJbXB1bHNlIGVycm9yOiIsIGUpOwogICAgICB9CiAgICB9OwogICAgY29uc3Qgc2V0UXVhdGVybmlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGhhbmRsZUVsZW1lbnRVcGRhdGUgPSAoewogICAgICBib2R5LAogICAgICB1dWlkLAogICAgICBzdGF0ZTogX3N0YXRlID0gREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgIH0sIGR0KSA9PiB7CiAgICAgIC8vIFN0YXRpYyBib2RpZXMgKG1hc3M9MCkgbmV2ZXIgbW92ZSDigJQgc2tpcCBzZW5kaW5nIHVwZGF0ZXMgc28gdGhlCiAgICAgIC8vIHZpc3VhbCBwb3NpdGlvbiBzdGF5cyBleGFjdGx5IHdoZXJlIHRoZSBhdXRob3IgcGxhY2VkIGl0LgogICAgICBpZiAoYm9keS5pc1N0YXRpY09iamVjdCgpKSByZXR1cm47CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICAgIG1vdGlvblN0YXRlLmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgbGV0IG9yaWdpbiA9IHRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgICBsZXQgcm90YXRpb24gPSB0cmFuc2Zvcm0uZ2V0Um90YXRpb24oKTsKICAgICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIG9yaWdpbiwgcm90YXRpb24sIGR0KTsKICAgICAgICBBbW1vLmRlc3Ryb3kodHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKCiAgICBjb25zdCBhZGRQbGF5ZXIgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgd2lkdGgsCiAgICAgICAgaGVpZ2h0LAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIG1hc3MsCiAgICAgICAgZnJpY3Rpb24sCiAgICAgICAgb3JpZ2luT2Zmc2V0ID0gewogICAgICAgICAgeDogMCwKICAgICAgICAgIHk6IDAsCiAgICAgICAgICB6OiAwCiAgICAgICAgfQogICAgICB9ID0gZGF0YTsKCiAgICAgIC8vIGJ0Q2Fwc3VsZVNoYXBlIGV4cGVjdHMgKHJhZGl1cywgY3lsaW5kZXJIZWlnaHQpIOKAlCB1c2UgaGFsZi13aWR0aCBhcwogICAgICAvLyByYWRpdXMgc28gdGhlIGNhcHN1bGUgd3JhcHMgdGhlIGJvdW5kaW5nIGJveCBjb3JyZWN0bHkuCiAgICAgIGNvbnN0IHJhZGl1cyA9IHdpZHRoICogMC41OwogICAgICBjb25zdCBjYXBzdWxlID0gbmV3IEFtbW8uYnRDYXBzdWxlU2hhcGUocmFkaXVzLCBoZWlnaHQpOwoKICAgICAgLy8gQWx3YXlzIGNyZWF0ZSB0aGUgcGxheWVyIGJvZHkgdXByaWdodCAoaWRlbnRpdHkgcXVhdGVybmlvbikuCiAgICAgIC8vIFRoZSB2aXN1YWwgcm90YXRpb24gaXMgZHJpdmVuIGJ5IHRoZSBjb250cm9sLCBub3QgYnkgcGh5c2ljcy4KICAgICAgY29uc3QgdXByaWdodFF1YXRlcm5pb24gPSB7CiAgICAgICAgeDogMCwKICAgICAgICB5OiAwLAogICAgICAgIHo6IDAsCiAgICAgICAgdzogMQogICAgICB9OwoKICAgICAgLy8gUG9zaXRpb24gdGhlIGNhcHN1bGUgYXQgdGhlIG1vZGVsJ3MgQUFCQiBjZW50cmUgc28gaXQgd3JhcHMgdGhlCiAgICAgIC8vIHZpc3VhbCBtZXNoIGNvcnJlY3RseS4gIG9yaWdpbk9mZnNldCBpcyB0aGUgdmVjdG9yIGZyb20gdGhlIG1vZGVsJ3MKICAgICAgLy8gb3JpZ2luIHRvIGl0cyBBQUJCIGNlbnRyZSDigJQgY29tcHV0ZWQgb24gdGhlIG1haW4gdGhyZWFkIHdoZXJlCiAgICAgIC8vIFRocmVlLmpzIGdlb21ldHJ5IGlzIGF2YWlsYWJsZS4KICAgICAgY29uc3QgY2Fwc3VsZVBvc2l0aW9uID0gewogICAgICAgIHg6IHBvc2l0aW9uLnggKyBvcmlnaW5PZmZzZXQueCwKICAgICAgICB5OiBwb3NpdGlvbi55ICsgb3JpZ2luT2Zmc2V0LnksCiAgICAgICAgejogcG9zaXRpb24ueiArIG9yaWdpbk9mZnNldC56CiAgICAgIH07CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoY2Fwc3VsZSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb246IGNhcHN1bGVQb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uOiB1cHJpZ2h0UXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uLAogICAgICAgIHJlc3RpdHV0aW9uOiAwLAogICAgICAgIGRhbXBpbmc6IHsKICAgICAgICAgIGxpbmVhcjogMC4xLAogICAgICAgICAgYW5ndWxhcjogMQogICAgICAgIH0KICAgICAgfSk7CgogICAgICAvLyBEaXNhYmxlIHJvdGF0aW9uIG9uIGFsbCBheGVzIOKAlCB0aGUgdmlzdWFsIHJvdGF0aW9uIGlzIGRyaXZlbiBieSB0aGUgY29udHJvbC4KICAgICAgLy8gVXNlIGJ0VmVjdG9yMyBpbnN0ZWFkIG9mIHNjYWxhciBmb3IgY29tcGF0aWJpbGl0eSBhY3Jvc3MgQW1tby5qcyBidWlsZHMuCiAgICAgIGNvbnN0IHplcm9Bbmd1bGFyID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIDAsIDApOwogICAgICBib2R5LnNldEFuZ3VsYXJGYWN0b3IoemVyb0FuZ3VsYXIpOwogICAgICBBbW1vLmRlc3Ryb3koemVyb0FuZ3VsYXIpOwoKICAgICAgLy8gRW5hYmxlIGNvbnRpbnVvdXMgY29sbGlzaW9uIGRldGVjdGlvbiB0byBwcmV2ZW50IHR1bm5lbGluZyBhdCBoaWdoIHNwZWVkcy4KICAgICAgYm9keS5zZXRDY2RNb3Rpb25UaHJlc2hvbGQocmFkaXVzICogMC41KTsKICAgICAgYm9keS5zZXRDY2RTd2VwdFNwaGVyZVJhZGl1cyhyYWRpdXMgKiAwLjgpOwoKICAgICAgLy8gU3RvcmUgZm9yIHVzZSBpbiBoYW5kbGVQbGF5ZXJVcGRhdGUg4oCUIG9mZnNldCBpcyBzdWJ0cmFjdGVkIHdoZW4KICAgICAgLy8gc2VuZGluZyBwb3NpdGlvbiBiYWNrIHNvIHRoZSB2aXN1YWwgc3RheXMgYXQgdGhlIG1vZGVsIG9yaWdpbi4KICAgICAgYm9keS5fbWFzcyA9IG1hc3M7CiAgICAgIGJvZHkuX29yaWdpbk9mZnNldCA9IG9yaWdpbk9mZnNldDsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLlBMQVlFUiwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgaGFuZGxlUGxheWVyVXBkYXRlID0gKHsKICAgICAgYm9keSwKICAgICAgdXVpZCwKICAgICAgc3RhdGUgPSBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgfSwgZHQpID0+IHsKICAgICAgY29uc3QgewogICAgICAgIG1vdmVtZW50LAogICAgICAgIGNhbWVyYURpcmVjdGlvbiwKICAgICAgICBqdW1wLAogICAgICAgIGp1bXBTcGVlZCwKICAgICAgICBzcGVlZDogbW92ZVNwZWVkCiAgICAgIH0gPSBzdGF0ZTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmICghbW90aW9uU3RhdGUpIHJldHVybjsKCiAgICAgIC8vIEZvcmNlLWNsZWFyIGFuZ3VsYXIgdmVsb2NpdHkgZXZlcnkgdGljay4gVGhlIHBsYXllciBjYXBzdWxlIG11c3Qgc3RheQogICAgICAvLyB1cHJpZ2h0IOKAlCByb3RhdGlvbiBpcyBoYW5kbGVkIHZpc3VhbGx5IGJ5IHRoZSBjb250cm9sLCBub3QgYnkgcGh5c2ljcy4KICAgICAgY29uc3QgemVyb0FuZ1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgYm9keS5zZXRBbmd1bGFyVmVsb2NpdHkoemVyb0FuZ1ZlbCk7CiAgICAgIEFtbW8uZGVzdHJveSh6ZXJvQW5nVmVsKTsKCiAgICAgIC8vIEZvcmNlIHRoZSBwaHlzaWNzIGJvZHkgcm90YXRpb24gdG8gaWRlbnRpdHkgKHVwcmlnaHQpIGV2ZXJ5IHRpY2suCiAgICAgIC8vIENvbnRhY3QgZm9yY2VzIGNhbiBzdGlsbCByb3RhdGUgdGhlIGNhcHN1bGUgaW4gc29tZSBBbW1vLmpzIGJ1aWxkcwogICAgICAvLyBldmVuIHdpdGggYW5ndWxhckZhY3Rvcj0oMCwwLDApLiBXZSBtdXN0IHJlc2V0IEJPVEggdGhlIGJvZHkgd29ybGQKICAgICAgLy8gdHJhbnNmb3JtIEFORCB0aGUgbW90aW9uU3RhdGUg4oCUIHRoZXkgY2FuIGRpdmVyZ2UuCiAgICAgIGNvbnN0IHdvcmxkVHJhbnNmb3JtID0gYm9keS5nZXRXb3JsZFRyYW5zZm9ybSgpOwogICAgICBjb25zdCB1cHJpZ2h0UXVhdCA9IG5ldyBBbW1vLmJ0UXVhdGVybmlvbigwLCAwLCAwLCAxKTsKICAgICAgd29ybGRUcmFuc2Zvcm0uc2V0Um90YXRpb24odXByaWdodFF1YXQpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHdvcmxkVHJhbnNmb3JtKTsKICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0od29ybGRUcmFuc2Zvcm0pOwogICAgICBBbW1vLmRlc3Ryb3kodXByaWdodFF1YXQpOwogICAgICBjb25zdCBjaGFyYWN0ZXJTcGVlZCA9IG1vdmVTcGVlZCB8fCA1OwoKICAgICAgLy8gSnVtcCDigJQgYXBwbHkgYSBvbmUtdGltZSBpbXB1bHNlLCB0aGVuIGNsZWFyIHRoZSBmbGFnIHNvIGl0IGRvZXNuJ3QgcmVwZWF0CiAgICAgIGlmIChqdW1wICYmIGp1bXBTcGVlZCkgewogICAgICAgIGNvbnN0IG1hc3MgPSBib2R5Ll9tYXNzIHx8IDgwOwogICAgICAgIGNvbnN0IGltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwganVtcFNwZWVkICogbWFzcywgMCk7CiAgICAgICAgYm9keS5hcHBseUNlbnRyYWxJbXB1bHNlKGltcHVsc2UpOwogICAgICAgIEFtbW8uZGVzdHJveShpbXB1bHNlKTsKICAgICAgICBzdGF0ZS5qdW1wID0gZmFsc2U7CiAgICAgIH0KICAgICAgY29uc3QgaXNNb3ZpbmcgPSBtb3ZlbWVudCAmJiAobW92ZW1lbnQuZm9yd2FyZCB8fCBtb3ZlbWVudC5iYWNrd2FyZHMgfHwgbW92ZW1lbnQubGVmdCB8fCBtb3ZlbWVudC5yaWdodCk7CiAgICAgIGNvbnN0IGxpbmVhclZlbG9jaXR5ID0gYm9keS5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICBjb25zdCBjdXJyZW50WSA9IGxpbmVhclZlbG9jaXR5LnkoKTsKICAgICAgaWYgKGlzTW92aW5nICYmIGNhbWVyYURpcmVjdGlvbikgewogICAgICAgIC8vIENvbXB1dGUgY2FtZXJhLXJlbGF0aXZlIG1vdmVtZW50IGRpcmVjdGlvbgogICAgICAgIGxldCBtb3ZlWCA9IDA7CiAgICAgICAgbGV0IG1vdmVaID0gMDsKICAgICAgICBpZiAobW92ZW1lbnQuZm9yd2FyZCkgewogICAgICAgICAgbW92ZVggKz0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgICBtb3ZlWiArPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICB9CiAgICAgICAgaWYgKG1vdmVtZW50LmJhY2t3YXJkcykgewogICAgICAgICAgbW92ZVggLT0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgICBtb3ZlWiAtPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICB9CiAgICAgICAgaWYgKG1vdmVtZW50LmxlZnQpIHsKICAgICAgICAgIG1vdmVYICs9IGNhbWVyYURpcmVjdGlvbi56OwogICAgICAgICAgbW92ZVogLT0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5yaWdodCkgewogICAgICAgICAgbW92ZVggLT0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgICBtb3ZlWiArPSBjYW1lcmFEaXJlY3Rpb24ueDsKICAgICAgICB9CgogICAgICAgIC8vIE5vcm1hbGl6ZSBkaXJlY3Rpb24KICAgICAgICBjb25zdCBsZW4gPSBNYXRoLnNxcnQobW92ZVggKiBtb3ZlWCArIG1vdmVaICogbW92ZVopOwogICAgICAgIGlmIChsZW4gPiAwKSB7CiAgICAgICAgICBtb3ZlWCAvPSBsZW47CiAgICAgICAgICBtb3ZlWiAvPSBsZW47CiAgICAgICAgfQoKICAgICAgICAvLyBTZXQgaG9yaXpvbnRhbCB2ZWxvY2l0eSBkaXJlY3RseSBmb3IgcmVzcG9uc2l2ZSBtb3ZlbWVudAogICAgICAgIGNvbnN0IG5ld1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhtb3ZlWCAqIGNoYXJhY3RlclNwZWVkLCBjdXJyZW50WSwgbW92ZVogKiBjaGFyYWN0ZXJTcGVlZCk7CiAgICAgICAgYm9keS5zZXRMaW5lYXJWZWxvY2l0eShuZXdWZWwpOwogICAgICAgIEFtbW8uZGVzdHJveShuZXdWZWwpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIFdoZW4gaWRsZSwgb25seSBkYW1wZW4gaWYgdGhlcmUncyBtZWFuaW5nZnVsIGhvcml6b250YWwgdmVsb2NpdHkuCiAgICAgICAgLy8gQXZvaWQgdG91Y2hpbmcgdGhlIHZlbG9jaXR5IGV2ZXJ5IGZyYW1lIHRvIGxldCB0aGUgc29sdmVyCiAgICAgICAgLy8gaGFuZGxlIGZsb29yIGNvbnRhY3Qgd2l0aG91dCBpbnRlcmZlcmVuY2UuCiAgICAgICAgY29uc3QgdnggPSBsaW5lYXJWZWxvY2l0eS54KCk7CiAgICAgICAgY29uc3QgdnogPSBsaW5lYXJWZWxvY2l0eS56KCk7CiAgICAgICAgaWYgKE1hdGguYWJzKHZ4KSA+IDAuMDEgfHwgTWF0aC5hYnModnopID4gMC4wMSkgewogICAgICAgICAgY29uc3QgbmV3VmVsID0gbmV3IEFtbW8uYnRWZWN0b3IzKHZ4ICogMC44NSwgY3VycmVudFksIHZ6ICogMC44NSk7CiAgICAgICAgICBib2R5LnNldExpbmVhclZlbG9jaXR5KG5ld1ZlbCk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kobmV3VmVsKTsKICAgICAgICB9CiAgICAgICAgLy8gT3RoZXJ3aXNlIGxldCBwaHlzaWNzIGhhbmRsZSBldmVyeXRoaW5nIOKAlCBkb24ndCBvdmVycmlkZSB2ZWxvY2l0eQogICAgICB9CgogICAgICAvLyBSZWFkIGZyb20gdGhlIGJvZHkncyB3b3JsZCB0cmFuc2Zvcm0gKG5vdCBtb3Rpb25TdGF0ZSkgYmVjYXVzZSB3ZQogICAgICAvLyBtYWludGFpbiBpdCBkaXJlY3RseSBhYm92ZSDigJQgcG9zaXRpb24gY29tZXMgZnJvbSBwaHlzaWNzLCByb3RhdGlvbgogICAgICAvLyBpcyBhbHdheXMgaWRlbnRpdHkuCiAgICAgIGNvbnN0IGZpbmFsVHJhbnNmb3JtID0gYm9keS5nZXRXb3JsZFRyYW5zZm9ybSgpOwogICAgICBjb25zdCBvcmlnaW4gPSBmaW5hbFRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgY29uc3Qgcm90YXRpb24gPSBmaW5hbFRyYW5zZm9ybS5nZXRSb3RhdGlvbigpOwogICAgICBjb25zdCBncm91bmRlZCA9IE1hdGguYWJzKGN1cnJlbnRZKSA8IDAuNTsKCiAgICAgIC8vIFRoZSBwaHlzaWNzIGNhcHN1bGUgaXMgb2Zmc2V0IHVwd2FyZCBzbyBpdHMgYm90dG9tIGFsaWducyB3aXRoIHRoZQogICAgICAvLyBjaGFyYWN0ZXIncyBmZWV0LiAgU3VidHJhY3QgdGhlIG9mZnNldCBiZWZvcmUgc2VuZGluZyB0aGUgcG9zaXRpb24KICAgICAgLy8gYmFjayBzbyB0aGUgdmlzdWFsIHN0YXlzIGF0IHRoZSBmZWV0LCBub3QgdGhlIGNhcHN1bGUgY2VudHJlLgogICAgICAvLyBTdWJ0cmFjdCB0aGUgb3JpZ2luIG9mZnNldCBzbyB0aGUgcG9zaXRpb24gbWFwcyBiYWNrIHRvIG1vZGVsLW9yaWdpbgogICAgICAvLyBzcGFjZSAodGhlIHZpc3VhbCdzIHRyYW5zZm9ybSBvcmlnaW4pLCBub3QgdGhlIEFBQkIgY2VudHJlLgogICAgICBjb25zdCBvZmYgPSBib2R5Ll9vcmlnaW5PZmZzZXQgfHwgewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwCiAgICAgIH07CiAgICAgIGNvbnN0IGFkanVzdGVkT3JpZ2luID0gbmV3IEFtbW8uYnRWZWN0b3IzKG9yaWdpbi54KCkgLSBvZmYueCwgb3JpZ2luLnkoKSAtIG9mZi55LCBvcmlnaW4ueigpIC0gb2ZmLnopOwogICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIGFkanVzdGVkT3JpZ2luLCByb3RhdGlvbiwgZHQsIHsKICAgICAgICBncm91bmRlZAogICAgICB9KTsKICAgICAgQW1tby5kZXN0cm95KGFkanVzdGVkT3JpZ2luKTsKICAgIH07CgogICAgY29uc3QgcmVxdWVzdE5leHRGcmFtZSA9IHNlbGYucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYub1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgX2VsZW1lbnQpIHsKICAgICAgc2VsZi5zZXRUaW1lb3V0KGNhbGxiYWNrLCAxMDAwIC8gMTIwKTsKICAgIH07CiAgICBsZXQgQ2xvY2sgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkgewogICAgICBmdW5jdGlvbiBDbG9jaygpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2xvY2spOwogICAgICAgIHRoaXMudGltZXN0YW1wID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gX2NyZWF0ZUNsYXNzKENsb2NrLCBbewogICAgICAgIGtleTogImdldERlbHRhIiwKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RGVsdGEoKSB7CiAgICAgICAgICBjb25zdCB0aW1lID0gRGF0ZS5ub3coKTsKICAgICAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCkgewogICAgICAgICAgICBjb25zdCBkZWx0YSA9IHRpbWUgLSB0aGlzLnRpbWVzdGFtcDsKICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lOwogICAgICAgICAgICByZXR1cm4gZGVsdGE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWU7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfV0pOwogICAgfSgpOwogICAgbGV0IFdvcmxkID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHsKICAgICAgZnVuY3Rpb24gV29ybGQoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFdvcmxkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImluaXQiLCBvcHRpb25zID0+IHsKICAgICAgICAgIGNvbnN0IHsKICAgICAgICAgICAgZ3Jhdml0eSA9IEdSQVZJVFkKICAgICAgICAgIH0gPSBvcHRpb25zOwogICAgICAgICAgdGhpcy5jb2xsaXNpb25Db25maWd1cmF0aW9uID0gbmV3IEFtbW8uYnREZWZhdWx0Q29sbGlzaW9uQ29uZmlndXJhdGlvbigpOwogICAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gbmV3IEFtbW8uYnRDb2xsaXNpb25EaXNwYXRjaGVyKHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICB0aGlzLmJyb2FkcGhhc2UgPSBuZXcgQW1tby5idERidnRCcm9hZHBoYXNlKCk7CiAgICAgICAgICB0aGlzLnNvbHZlciA9IG5ldyBBbW1vLmJ0U2VxdWVudGlhbEltcHVsc2VDb25zdHJhaW50U29sdmVyKCk7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQgPSBuZXcgQW1tby5idERpc2NyZXRlRHluYW1pY3NXb3JsZCh0aGlzLmRpc3BhdGNoZXIsIHRoaXMuYnJvYWRwaGFzZSwgdGhpcy5zb2x2ZXIsIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuc2V0R3Jhdml0eShuZXcgQW1tby5idFZlY3RvcjMoZ3Jhdml0eS54LCBncmF2aXR5LnksIGdyYXZpdHkueikpOwoKICAgICAgICAgIC8vIHRoaXMgaXMgbmVlZGVkIGZvciBnaG9zdE9iamVjdCBjb2xsaXNpb25zCiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuZ2V0QnJvYWRwaGFzZSgpLmdldE92ZXJsYXBwaW5nUGFpckNhY2hlKCkuc2V0SW50ZXJuYWxHaG9zdFBhaXJDYWxsYmFjayhuZXcgQW1tby5idEdob3N0UGFpckNhbGxiYWNrKCkpOwogICAgICAgICAgdGhpcy5pbml0aWFsaXNlZCA9IHRydWU7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJyZW1vdmVFbGVtZW50IiwgdXVpZCA9PiB7CiAgICAgICAgICBpZiAodGhpcy5oYXNFbGVtZW50KHV1aWQpKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudHNbdXVpZF0uZGVsZXRlZCA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJyZW1vdmVEZWxldGVkRWxlbWVudHMiLCAoKSA9PiBPYmplY3Qua2V5cyh0aGlzLmVsZW1lbnRzKS5maWx0ZXIodXVpZCA9PiB0aGlzLmVsZW1lbnRzW3V1aWRdLmRlbGV0ZWQpLmZvckVhY2godXVpZCA9PiB7CiAgICAgICAgICBkZWxldGUgdGhpcy5lbGVtZW50c1t1dWlkXTsKICAgICAgICB9KSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJoYXNFbGVtZW50IiwgdXVpZCA9PiB7CiAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuaW5jbHVkZXModXVpZCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJnZXRFbGVtZW50IiwgdXVpZCA9PiB0aGlzLmVsZW1lbnRzW3V1aWRdKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImlzSW5pdGlhbGlzZWQiLCAoKSA9PiB0aGlzLmluaXRpYWxpc2VkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImdldER5bmFtaWNzV29ybGQiLCAoKSA9PiB0aGlzLmR5bmFtaWNzV29ybGQpOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkUmlnaWRCb2R5IiwgYm9keSA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkUmlnaWRCb2R5KGJvZHkpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkQWN0aW9uIiwgYWN0aW9uID0+IHsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5hZGRBY3Rpb24oYWN0aW9uKTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZENvbGxpc2lvbk9iamVjdCIsIGNvbGxpc2lvbk9iamVjdCA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkQ29sbGlzaW9uT2JqZWN0KGNvbGxpc2lvbk9iamVjdCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzdGVwU2ltdWxhdGlvbiIsIGR0ID0+IHsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5zdGVwU2ltdWxhdGlvbihkdCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzaW11bGF0ZSIsICgpID0+IHsKICAgICAgICAgIGNvbnN0IGR0ID0gdGhpcy5jbG9jay5nZXREZWx0YSgpIC8gMTAwMDsKICAgICAgICAgIHRoaXMuc3RlcFNpbXVsYXRpb24oZHQpOwogICAgICAgICAgT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuZm9yRWFjaCh1dWlkID0+IHsKICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICAgICAgaWYgKGVsZW1lbnQpIHsKICAgICAgICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5CT1g6CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVTLlNQSEVSRToKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuTUVTSDoKICAgICAgICAgICAgICAgICAgaGFuZGxlRWxlbWVudFVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5QTEFZRVI6CiAgICAgICAgICAgICAgICAgIGhhbmRsZVBsYXllclVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5WRUhJQ0xFOgogICAgICAgICAgICAgICAgICBoYW5kbGVWZWhpY2xlVXBkYXRlKGVsZW1lbnQsIGR0KTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQ29sbGlzaW9ucygpOwogICAgICAgICAgdGhpcy5yZW1vdmVEZWxldGVkRWxlbWVudHMoKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZFBoeXNpY3NVcGRhdGUoZHQpOwogICAgICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWVJZCA9IHJlcXVlc3ROZXh0RnJhbWUodGhpcy5zaW11bGF0ZS5iaW5kKHRoaXMpKTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImNhbGN1bGF0ZUNvbGxpc2lvbnMiLCAoKSA9PiB7CiAgICAgICAgICBsZXQgYW1tb0Rpc3BhdGNoZXIgPSB0aGlzLmR5bmFtaWNzV29ybGQuZ2V0RGlzcGF0Y2hlcigpOwogICAgICAgICAgbGV0IG51bU1hbmlmb2xkcyA9IGFtbW9EaXNwYXRjaGVyLmdldE51bU1hbmlmb2xkcygpOwogICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1NYW5pZm9sZHM7IGkrKykgewogICAgICAgICAgICBsZXQgY29udGFjdE1hbmlmb2xkID0gYW1tb0Rpc3BhdGNoZXIuZ2V0TWFuaWZvbGRCeUluZGV4SW50ZXJuYWwoaSk7CiAgICAgICAgICAgIGxldCByYjAgPSBBbW1vLmNhc3RPYmplY3QoY29udGFjdE1hbmlmb2xkLmdldEJvZHkwKCksIEFtbW8uYnRSaWdpZEJvZHkpOwogICAgICAgICAgICBsZXQgcmIxID0gQW1tby5jYXN0T2JqZWN0KGNvbnRhY3RNYW5pZm9sZC5nZXRCb2R5MSgpLCBBbW1vLmJ0UmlnaWRCb2R5KTsKICAgICAgICAgICAgbGV0IG51bUNvbnRhY3RzID0gY29udGFjdE1hbmlmb2xkLmdldE51bUNvbnRhY3RzKCk7CgogICAgICAgICAgICAvLyB0aGlzIGl0ZXJhdGlvbiBkb2Vzbid0IGhhdmUgdXVpZHMKICAgICAgICAgICAgaWYgKCFyYjAudXVpZCB8fCAhcmIxLnV1aWQpIGNvbnRpbnVlOwogICAgICAgICAgICBsZXQgY29udGFjdHMgPSBbXTsKICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBudW1Db250YWN0czsgaisrKSB7CiAgICAgICAgICAgICAgbGV0IGNvbnRhY3RQb2ludCA9IGNvbnRhY3RNYW5pZm9sZC5nZXRDb250YWN0UG9pbnQoaik7CiAgICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gY29udGFjdFBvaW50LmdldERpc3RhbmNlKCk7CiAgICAgICAgICAgICAgaWYgKGRpc3RhbmNlID4gMC4wKSBjb250aW51ZTsKICAgICAgICAgICAgICBsZXQgdmVsb2NpdHkwID0gcmIwLmdldExpbmVhclZlbG9jaXR5KCk7CiAgICAgICAgICAgICAgbGV0IHZlbG9jaXR5MSA9IHJiMS5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICAgICAgICAgIGxldCB3b3JsZFBvczAgPSBjb250YWN0UG9pbnQuZ2V0X21fcG9zaXRpb25Xb3JsZE9uQSgpOwogICAgICAgICAgICAgIGxldCB3b3JsZFBvczEgPSBjb250YWN0UG9pbnQuZ2V0X21fcG9zaXRpb25Xb3JsZE9uQigpOwogICAgICAgICAgICAgIGxldCBsb2NhbFBvczAgPSBjb250YWN0UG9pbnQuZ2V0X21fbG9jYWxQb2ludEEoKTsKICAgICAgICAgICAgICBsZXQgbG9jYWxQb3MxID0gY29udGFjdFBvaW50LmdldF9tX2xvY2FsUG9pbnRCKCk7CiAgICAgICAgICAgICAgY29udGFjdHMucHVzaCh7CiAgICAgICAgICAgICAgICBkaXN0YW5jZSwKICAgICAgICAgICAgICAgIGVsZW1lbnRzOiBbewogICAgICAgICAgICAgICAgICB1dWlkOiByYjAudXVpZCwKICAgICAgICAgICAgICAgICAgdmVsb2NpdHk6IHsKICAgICAgICAgICAgICAgICAgICB4OiB2ZWxvY2l0eTAueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHZlbG9jaXR5MC55KCksCiAgICAgICAgICAgICAgICAgICAgejogdmVsb2NpdHkwLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICB3b3JsZFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IHdvcmxkUG9zMC54KCksCiAgICAgICAgICAgICAgICAgICAgeTogd29ybGRQb3MwLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiB3b3JsZFBvczAueigpCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGxvY2FsUG9zOiB7CiAgICAgICAgICAgICAgICAgICAgeDogbG9jYWxQb3MwLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiBsb2NhbFBvczAueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IGxvY2FsUG9zMC56KCkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgICB1dWlkOiByYjEudXVpZCwKICAgICAgICAgICAgICAgICAgdmVsb2NpdHk6IHsKICAgICAgICAgICAgICAgICAgICB4OiB2ZWxvY2l0eTEueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHZlbG9jaXR5MS55KCksCiAgICAgICAgICAgICAgICAgICAgejogdmVsb2NpdHkxLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICB3b3JsZFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IHdvcmxkUG9zMS54KCksCiAgICAgICAgICAgICAgICAgICAgeTogd29ybGRQb3MxLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiB3b3JsZFBvczEueigpCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGxvY2FsUG9zOiB7CiAgICAgICAgICAgICAgICAgICAgeDogbG9jYWxQb3MxLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiBsb2NhbFBvczEueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IGxvY2FsUG9zMS56KCkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfV0KICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkaXNwYXRjaGVyLnNlbmREaXNwYXRjaEV2ZW50KHJiMC51dWlkLCBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkNPTExJU0lPTiwgewogICAgICAgICAgICAgIGNvbnRhY3RzCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBkaXNwYXRjaGVyLnNlbmREaXNwYXRjaEV2ZW50KHJiMS51dWlkLCBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkNPTExJU0lPTiwgewogICAgICAgICAgICAgIGNvbnRhY3RzCiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkRWxlbWVudCIsIGRhdGEgPT4gewogICAgICAgICAgdGhpcy5lbGVtZW50c1tkYXRhLnV1aWRdID0gZGF0YTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInVwZGF0ZUJvZHlTdGF0ZSIsICh7CiAgICAgICAgICB1dWlkLAogICAgICAgICAgc3RhdGUKICAgICAgICB9KSA9PiB7CiAgICAgICAgICBpZiAodGhpcy5oYXNFbGVtZW50KHV1aWQpKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudHNbdXVpZF0uc3RhdGUgPSB7CiAgICAgICAgICAgICAgLi4udGhpcy5lbGVtZW50c1t1dWlkXS5zdGF0ZSwKICAgICAgICAgICAgICAuLi5zdGF0ZQogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAidGVybWluYXRlIiwgKCkgPT4gewogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuZHluYW1pY3NXb3JsZCk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kodGhpcy5zb2x2ZXIpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuZGlzcGF0Y2hlcik7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kodGhpcy5jb2xsaXNpb25Db25maWd1cmF0aW9uKTsKICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lSWQpOwogICAgICAgICAgZGlzcGF0Y2hlci5zZW5kVGVybWluYXRlRXZlbnQoKTsKICAgICAgICB9KTsKICAgICAgICB0aGlzLmVsZW1lbnRzID0ge307CiAgICAgICAgdGhpcy5pbml0aWFsaXNlZCA9IGZhbHNlOwogICAgICAgIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbiA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLmRpc3BhdGNoZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5icm9hZHBoYXNlID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuc29sdmVyID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZCA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZUlkID0gbnVsbDsKICAgICAgICB0aGlzLmNsb2NrID0gbmV3IENsb2NrKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIF9jcmVhdGVDbGFzcyhXb3JsZCwgW3sKICAgICAgICBrZXk6ICJkaXNwb3NlQm9keSIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc3Bvc2VCb2R5KHsKICAgICAgICAgIHV1aWQKICAgICAgICB9KSB7CiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLnJlbW92ZVJpZ2lkQm9keShlbGVtZW50LmJvZHkpOwogICAgICAgICAgdGhpcy5yZW1vdmVFbGVtZW50KHV1aWQpOwogICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRWxlbWVudERpc3Bvc2VkKHsKICAgICAgICAgICAgdXVpZAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9XSk7CiAgICB9KCk7CiAgICB2YXIgd29ybGQgPSBuZXcgV29ybGQoKTsKCiAgICBjb25zdCBERUZBVUxUX1JPTExfSU5GTFVFTkNFID0gMC4yOwogICAgY29uc3QgREVGQVVMVF9GUklDVElPTiA9IDEwMDA7CiAgICBjb25zdCBERUZBVUxUX01BU1MgPSA4MDA7CiAgICBjb25zdCBhZGRWZWhpY2xlID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIHV1aWQsCiAgICAgICAgd2hlZWxzLAogICAgICAgIG1hc3MgPSBERUZBVUxUX01BU1MsCiAgICAgICAgd2lkdGggPSAxLjgsCiAgICAgICAgaGVpZ2h0ID0gMC42LAogICAgICAgIGxlbmd0aCA9IDQsCiAgICAgICAgZnJpY3Rpb24gPSBERUZBVUxUX0ZSSUNUSU9OLAogICAgICAgIHJvbGxJbmZsdWVuY2UgPSBERUZBVUxUX1JPTExfSU5GTFVFTkNFLAogICAgICAgIHdoZWVsc09wdGlvbnMgPSB7fSwKICAgICAgICBzdXNwZW5zaW9ucyA9IHt9CiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYmFjayA9IHt9LAogICAgICAgIGZyb250ID0ge30KICAgICAgfSA9IHdoZWVsc09wdGlvbnM7CiAgICAgIGNvbnN0IHsKICAgICAgICBheGlzUG9zaXRpb246IGF4aXNQb3NpdGlvbkJhY2sgPSAtMSwKICAgICAgICByYWRpdXM6IHdoZWVsUmFkaXVzQmFjayA9IDAuNCwKICAgICAgICBoYWxmVHJhY2s6IHdoZWVsSGFsZlRyYWNrQmFjayA9IDEsCiAgICAgICAgYXhpc0hlaWdodDogd2hlZWxBeGlzSGVpZ2h0QmFjayA9IDAuMwogICAgICB9ID0gYmFjazsKICAgICAgY29uc3QgewogICAgICAgIGF4aXNQb3NpdGlvbjogYXhpc1Bvc2l0aW9uRnJvbnQgPSAxLjcsCiAgICAgICAgcmFkaXVzOiB3aGVlbFJhZGl1c0Zyb250ID0gMC40LAogICAgICAgIGhhbGZUcmFjazogd2hlZWxIYWxmVHJhY2tGcm9udCA9IDEsCiAgICAgICAgYXhpc0hlaWdodDogd2hlZWxBeGlzSGVpZ2h0RnJvbnQgPSAwLjMKICAgICAgfSA9IGZyb250OwogICAgICBjb25zdCB7CiAgICAgICAgc3RpZmZuZXNzID0gMjAuMCwKICAgICAgICBkYW1waW5nID0gMi4zLAogICAgICAgIGNvbXByZXNzaW9uID0gNC40LAogICAgICAgIHJlc3RMZW5ndGggPSAwLjYKICAgICAgfSA9IHN1c3BlbnNpb25zOwoKICAgICAgLy8gQ2hhc3NpcwogICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBBbW1vLmJ0Qm94U2hhcGUobmV3IEFtbW8uYnRWZWN0b3IzKHdpZHRoICogMC41LCBoZWlnaHQgKiAwLjUsIGxlbmd0aCAqIDAuNSkpOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IG5ldyBBbW1vLmJ0RGVmYXVsdE1vdGlvblN0YXRlKHRyYW5zZm9ybSk7CiAgICAgIGNvbnN0IGxvY2FsSW5lcnRpYSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgZ2VvbWV0cnkuY2FsY3VsYXRlTG9jYWxJbmVydGlhKG1hc3MsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IGNoYXNzaXMgPSBuZXcgQW1tby5idFJpZ2lkQm9keShuZXcgQW1tby5idFJpZ2lkQm9keUNvbnN0cnVjdGlvbkluZm8obWFzcywgbW90aW9uU3RhdGUsIGdlb21ldHJ5LCBsb2NhbEluZXJ0aWEpKTsKICAgICAgY2hhc3Npcy5zZXRBY3RpdmF0aW9uU3RhdGUoRElTQUJMRV9ERUFDVElWQVRJT04pOwogICAgICB3b3JsZC5hZGRSaWdpZEJvZHkoY2hhc3Npcyk7CgogICAgICAvLyBSYXljYXN0IFZlaGljbGUKICAgICAgY29uc3QgdHVuaW5nID0gbmV3IEFtbW8uYnRWZWhpY2xlVHVuaW5nKCk7CiAgICAgIGNvbnN0IHJheUNhc3RlciA9IG5ldyBBbW1vLmJ0RGVmYXVsdFZlaGljbGVSYXljYXN0ZXIod29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpKTsKICAgICAgY29uc3QgdmVoaWNsZSA9IG5ldyBBbW1vLmJ0UmF5Y2FzdFZlaGljbGUodHVuaW5nLCBjaGFzc2lzLCByYXlDYXN0ZXIpOwogICAgICB2ZWhpY2xlLnNldENvb3JkaW5hdGVTeXN0ZW0oMCwgMSwgMik7CiAgICAgIHdvcmxkLmFkZEFjdGlvbih2ZWhpY2xlKTsKICAgICAgY29uc3Qgd2hlZWxEaXJlY3Rpb25DUzAgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgLTEsIDApOwogICAgICBjb25zdCB3aGVlbEF4bGVDUyA9IG5ldyBBbW1vLmJ0VmVjdG9yMygtMSwgMCwgMCk7CiAgICAgIGNvbnN0IGFkZFdoZWVsID0gKGlzRnJvbnQsIHBvcywgcmFkaXVzKSA9PiB7CiAgICAgICAgdmFyIHdoZWVsSW5mbyA9IHZlaGljbGUuYWRkV2hlZWwocG9zLCB3aGVlbERpcmVjdGlvbkNTMCwgd2hlZWxBeGxlQ1MsIHJlc3RMZW5ndGgsIHJhZGl1cywgdHVuaW5nLCBpc0Zyb250KTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fc3VzcGVuc2lvblN0aWZmbmVzcyhzdGlmZm5lc3MpOwogICAgICAgIHdoZWVsSW5mby5zZXRfbV93aGVlbHNEYW1waW5nUmVsYXhhdGlvbihkYW1waW5nKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fd2hlZWxzRGFtcGluZ0NvbXByZXNzaW9uKGNvbXByZXNzaW9uKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fZnJpY3Rpb25TbGlwKGZyaWN0aW9uKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fcm9sbEluZmx1ZW5jZShyb2xsSW5mbHVlbmNlKTsKICAgICAgfTsKICAgICAgYWRkV2hlZWwodHJ1ZSwgbmV3IEFtbW8uYnRWZWN0b3IzKHdoZWVsSGFsZlRyYWNrRnJvbnQsIHdoZWVsQXhpc0hlaWdodEZyb250LCBheGlzUG9zaXRpb25Gcm9udCksIHdoZWVsUmFkaXVzRnJvbnQpOwogICAgICBhZGRXaGVlbCh0cnVlLCBuZXcgQW1tby5idFZlY3RvcjMoLXdoZWVsSGFsZlRyYWNrRnJvbnQsIHdoZWVsQXhpc0hlaWdodEZyb250LCBheGlzUG9zaXRpb25Gcm9udCksIHdoZWVsUmFkaXVzRnJvbnQpOwogICAgICBhZGRXaGVlbChmYWxzZSwgbmV3IEFtbW8uYnRWZWN0b3IzKC13aGVlbEhhbGZUcmFja0JhY2ssIHdoZWVsQXhpc0hlaWdodEJhY2ssIGF4aXNQb3NpdGlvbkJhY2spLCB3aGVlbFJhZGl1c0JhY2spOwogICAgICBhZGRXaGVlbChmYWxzZSwgbmV3IEFtbW8uYnRWZWN0b3IzKHdoZWVsSGFsZlRyYWNrQmFjaywgd2hlZWxBeGlzSGVpZ2h0QmFjaywgYXhpc1Bvc2l0aW9uQmFjayksIHdoZWVsUmFkaXVzQmFjayk7CiAgICAgIHZlaGljbGUudXVpZCA9IHV1aWQ7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHR5cGU6IFRZUEVTLlZFSElDTEUsCiAgICAgICAgdXVpZCwKICAgICAgICB2ZWhpY2xlOiB2ZWhpY2xlLAogICAgICAgIHdoZWVscywKICAgICAgICBvcHRpb25zOiBkYXRhLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1ZFSElDTEVfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3Qgc2V0VmVoaWNsZVBvc2l0aW9uID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHNldFZlaGljbGVRdWF0ZXJuaW9uID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHF1YXRlcm5pb24KICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IGVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICBpZiAoZWxlbWVudC50eXBlID09PSBUWVBFUy5WRUhJQ0xFKSB7CiAgICAgICAgY29uc3QgYm9keSA9IGVsZW1lbnQudmVoaWNsZS5nZXRSaWdpZEJvZHkoKTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHJlc2V0VmVoaWNsZSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIHBvc2l0aW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24ocXVhdGVybmlvbi54LCBxdWF0ZXJuaW9uLnksIHF1YXRlcm5pb24ueiwgcXVhdGVybmlvbi53KSk7CiAgICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgaGFuZGxlVmVoaWNsZVVwZGF0ZSA9ICh7CiAgICAgIHZlaGljbGUsCiAgICAgIHdoZWVscywKICAgICAgdXVpZCwKICAgICAgc3RhdGUgPSBERUZBVUxUX1ZFSElDTEVfU1RBVEUsCiAgICAgIG9wdGlvbnMgPSB7fQogICAgfSwgZHQpID0+IHsKICAgICAgbGV0IGJyZWFraW5nRm9yY2UgPSAwOwogICAgICBsZXQgZW5naW5lRm9yY2UgPSAwOwogICAgICBjb25zdCB7CiAgICAgICAgc3RlZXJpbmdDbGFtcCA9IERFRkFVTFRfU1RFRVJJTkdfQ0xBTVAsCiAgICAgICAgc3RlZXJpbmdJbmNyZW1lbnQgPSBERUZBVUxUX1NURUVSSU5HX0lOQ1JFTUVOVCwKICAgICAgICBtYXhFbmdpbmVGb3JjZSA9IERFRkFVTFRfTUFYX0VOR0lORV9GT1JDRSwKICAgICAgICBtYXhCcmVha2luZ0ZvcmNlID0gREVGQVVMVF9NQVhfQlJFQUtJTkdfRk9SQ0UKICAgICAgfSA9IG9wdGlvbnM7CiAgICAgIGlmIChzdGF0ZS5hY2NlbGVyYXRpb24pIHsKICAgICAgICBpZiAoc3BlZWQgPCAtMSkgYnJlYWtpbmdGb3JjZSA9IG1heEJyZWFraW5nRm9yY2U7ZWxzZSBlbmdpbmVGb3JjZSA9IG1heEVuZ2luZUZvcmNlOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS5icmFraW5nKSB7CiAgICAgICAgaWYgKHNwZWVkID4gMSkgYnJlYWtpbmdGb3JjZSA9IG1heEJyZWFraW5nRm9yY2U7ZWxzZSBlbmdpbmVGb3JjZSA9IC1tYXhFbmdpbmVGb3JjZSAvIDI7CiAgICAgIH0KICAgICAgaWYgKHN0YXRlLmxlZnQpIHsKICAgICAgICBpZiAoc3RhdGUudmVoaWNsZVN0ZWVyaW5nIDwgc3RlZXJpbmdDbGFtcCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nICs9IHN0ZWVyaW5nSW5jcmVtZW50OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdGF0ZS5yaWdodCkgewogICAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA+IC1zdGVlcmluZ0NsYW1wKSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgLT0gc3RlZXJpbmdJbmNyZW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPCAtc3RlZXJpbmdJbmNyZW1lbnQpIHN0YXRlLnZlaGljbGVTdGVlcmluZyArPSBzdGVlcmluZ0luY3JlbWVudDtlbHNlIHsKICAgICAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA+IHN0ZWVyaW5nSW5jcmVtZW50KSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgLT0gc3RlZXJpbmdJbmNyZW1lbnQ7ZWxzZSB7CiAgICAgICAgICAgICAgc3RhdGUudmVoaWNsZVN0ZWVyaW5nID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICB2ZWhpY2xlLmFwcGx5RW5naW5lRm9yY2UoZW5naW5lRm9yY2UsIEJBQ0tfTEVGVCk7CiAgICAgIHZlaGljbGUuYXBwbHlFbmdpbmVGb3JjZShlbmdpbmVGb3JjZSwgQkFDS19SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSAvIDIsIEZST05UX0xFRlQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UgLyAyLCBGUk9OVF9SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSwgQkFDS19MRUZUKTsKICAgICAgdmVoaWNsZS5zZXRCcmFrZShicmVha2luZ0ZvcmNlLCBCQUNLX1JJR0hUKTsKICAgICAgdmVoaWNsZS5zZXRTdGVlcmluZ1ZhbHVlKHN0YXRlLnZlaGljbGVTdGVlcmluZywgRlJPTlRfTEVGVCk7CiAgICAgIHZlaGljbGUuc2V0U3RlZXJpbmdWYWx1ZShzdGF0ZS52ZWhpY2xlU3RlZXJpbmcsIEZST05UX1JJR0hUKTsKICAgICAgbGV0IHRtLCBwLCBxLCBpOwogICAgICBjb25zdCBuID0gdmVoaWNsZS5nZXROdW1XaGVlbHMoKTsKICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHZlaGljbGUudXBkYXRlV2hlZWxUcmFuc2Zvcm0oaSwgdHJ1ZSk7CiAgICAgICAgdG0gPSB2ZWhpY2xlLmdldFdoZWVsVHJhbnNmb3JtV1MoaSk7CiAgICAgICAgcCA9IHRtLmdldE9yaWdpbigpOwogICAgICAgIHEgPSB0bS5nZXRSb3RhdGlvbigpOwogICAgICAgIGNvbnN0IHdoZWVsVVVJRCA9IHdoZWVsc1tpXTsKICAgICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHdoZWVsVVVJRCwgcCwgcSwgZHQpOwogICAgICB9CiAgICAgIHRtID0gdmVoaWNsZS5nZXRDaGFzc2lzV29ybGRUcmFuc2Zvcm0oKTsKICAgICAgcCA9IHRtLmdldE9yaWdpbigpOwogICAgICBxID0gdG0uZ2V0Um90YXRpb24oKTsKICAgICAgY29uc3QgZGlyZWN0aW9uID0gdmVoaWNsZS5nZXRGb3J3YXJkVmVjdG9yKCk7CiAgICAgIGNvbnN0IHNwZWVkID0gdmVoaWNsZS5nZXRDdXJyZW50U3BlZWRLbUhvdXIoKTsKICAgICAgY29uc3QgZXh0cmFEYXRhID0gewogICAgICAgIGRpcmVjdGlvbjogewogICAgICAgICAgeDogZGlyZWN0aW9uLngoKSwKICAgICAgICAgIHk6IGRpcmVjdGlvbi55KCksCiAgICAgICAgICB6OiBkaXJlY3Rpb24ueigpCiAgICAgICAgfSwKICAgICAgICBzcGVlZAogICAgICB9OwogICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIHAsIHEsIGR0LCBleHRyYURhdGEpOwogICAgICB3b3JsZC51cGRhdGVCb2R5U3RhdGUodXVpZCwgc3RhdGUpOwogICAgfTsKCiAgICBjb25zdCBjcmVhdGVHaG9zdENvbGxpZGVyID0gKHJhZGl1cywgcG9zaXRpb24pID0+IHsKICAgICAgY29uc3QgZ2hvc3RDb2xsaWRlciA9IG5ldyBBbW1vLmJ0R2hvc3RPYmplY3QoKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgZ2hvc3RDb2xsaWRlci5zZXRDb2xsaXNpb25TaGFwZShuZXcgQW1tby5idFNwaGVyZVNoYXBlKHJhZGl1cykpOwogICAgICBnaG9zdENvbGxpZGVyLmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHRyYW5zZm9ybS5zZXRJZGVudGl0eSgpOwogICAgICB0cmFuc2Zvcm0uc2V0T3JpZ2luKHBvc2l0aW9uKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbigwLCAwLCAwLCAxKSk7CiAgICAgIGdob3N0Q29sbGlkZXIuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgcmV0dXJuIHsKICAgICAgICBnaG9zdENvbGxpZGVyLAogICAgICAgIHRyYW5zZm9ybQogICAgICB9OwogICAgfTsKICAgIGNvbnN0IGZvckVhY2hHaG9zdENvbGxpc2lvbiA9IChnaG9zdENvbGxpZGVyLCBmb3JFYWNoQ2FsbGJhY2sgPSAoKSA9PiB7fSkgPT4gewogICAgICBjb25zdCBjb2xsaXNpb25zID0gZ2hvc3RDb2xsaWRlci5nZXROdW1PdmVybGFwcGluZ09iamVjdHMoKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2xsaXNpb25zOyBpKyspIHsKICAgICAgICBjb25zdCBvYmplY3QgPSBBbW1vLmNhc3RPYmplY3QoZ2hvc3RDb2xsaWRlci5nZXRPdmVybGFwcGluZ09iamVjdChpKSwgQW1tby5idFJpZ2lkQm9keSk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBvYmplY3QuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICBmb3JFYWNoQ2FsbGJhY2sob2JqZWN0LCB0cmFuc2Zvcm0sIGkpOwogICAgICAgIEFtbW8uZGVzdHJveSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgZ2V0RXhwbG9zaW9uUG9zaXRpb24gPSAodXVpZCwgcG9zaXRpb24pID0+IHsKICAgICAgbGV0IGV4cGxvc2lvblBvc2l0aW9uID0gcG9zaXRpb247CiAgICAgIGlmICghZXhwbG9zaW9uUG9zaXRpb24pIHsKICAgICAgICBjb25zdCB7CiAgICAgICAgICBib2R5CiAgICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBtb3Rpb25TdGF0ZS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIGV4cGxvc2lvblBvc2l0aW9uID0gdHJhbnNmb3JtLmdldE9yaWdpbigpOwogICAgICB9CiAgICAgIHJldHVybiBleHBsb3Npb25Qb3NpdGlvbjsKICAgIH07CiAgICBjb25zdCBnZXRFeHBsb3Npb25JbXB1bHNlID0gKHBvc2l0aW9uLCBleHBsb3Npb25Qb3NpdGlvbiwgc3RyZW5ndGgpID0+IHsKICAgICAgLy8gQ2FsY3VsYXRlIGRpcmVjdGlvbiB2ZWN0b3IgV0lUSE9VVCBtdXRhdGluZyB0aGUgaW5wdXQgYnRWZWN0b3IzIG9iamVjdHMuCiAgICAgIC8vIG9wX3N1Yi9vcF9tdWwgbXV0YXRlIGluIHBsYWNlIGluIEFtbW8uanMsIHdoaWNoIHdvdWxkIGNvcnJ1cHQgdGhlIGJvZHkncyB0cmFuc2Zvcm0gb3JpZ2luLgogICAgICBjb25zdCBkeCA9IHBvc2l0aW9uLngoKSAtIGV4cGxvc2lvblBvc2l0aW9uLngoKTsKICAgICAgY29uc3QgZHkgPSBwb3NpdGlvbi55KCkgLSBleHBsb3Npb25Qb3NpdGlvbi55KCk7CiAgICAgIGNvbnN0IGR6ID0gcG9zaXRpb24ueigpIC0gZXhwbG9zaW9uUG9zaXRpb24ueigpOwogICAgICBsZXQgbGVuZ3RoID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5ICsgZHogKiBkeik7CgogICAgICAvLyBJZiB0aGUgb2JqZWN0IGlzIGF0IHRoZSBleHBsb3Npb24gY2VudGVyLCBwdXNoIGl0IHN0cmFpZ2h0IHVwIGluc3RlYWQgb2YKICAgICAgLy8gcHJvZHVjaW5nIGFuIHVuc3RhYmxlIG5lYXItemVybyBub3JtYWxpemF0aW9uLgogICAgICBpZiAobGVuZ3RoIDwgMC4wMDEpIHsKICAgICAgICBjb25zdCBpbXB1bHNlID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIHN0cmVuZ3RoICogMiwgMCk7CiAgICAgICAgcmV0dXJuIGltcHVsc2U7CiAgICAgIH0KCiAgICAgIC8vIE5vcm1hbGl6ZSBkaXJlY3Rpb24KICAgICAgY29uc3QgbnggPSBkeCAvIGxlbmd0aDsKICAgICAgY29uc3QgbnkgPSBkeSAvIGxlbmd0aDsKICAgICAgY29uc3QgbnogPSBkeiAvIGxlbmd0aDsKCiAgICAgIC8vIFNjYWxlIGJ5IHN0cmVuZ3RoIGFuZCBhZGQgdXB3YXJkIGJpYXMKICAgICAgY29uc3QgaW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhueCAqIHN0cmVuZ3RoLCBueSAqIHN0cmVuZ3RoICsgc3RyZW5ndGgsIG56ICogc3RyZW5ndGgpOwogICAgICByZXR1cm4gaW1wdWxzZTsKICAgIH07CiAgICBjb25zdCBjcmVhdGVFeHBsb3Npb24gPSAoewogICAgICB1dWlkLAogICAgICBwb3NpdGlvbiwKICAgICAgcmFkaXVzID0gRVhQTE9TSU9OX1NJWkVTLlNNQUxMLAogICAgICBzdHJlbmd0aCA9IEVYUExPU0lPTl9TVFJFTkdUSFMuTUVESVVNCiAgICB9KSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgLy8gR2V0IHRoZSBzb3VyY2UgYm9keSdzIEFtbW8gcG9pbnRlciBzbyB3ZSBjYW4gcmVsaWFibHkgc2tpcCBpdC4KICAgICAgICAvLyBBbW1vLmNhc3RPYmplY3QoKSBjcmVhdGVzIG5ldyBKUyB3cmFwcGVycywgc28gY3VzdG9tIHByb3BlcnRpZXMgbGlrZQogICAgICAgIC8vIC51dWlkIHNldCBvbiB0aGUgb3JpZ2luYWwgd3JhcHBlciBhcmUgTk9UIGF2YWlsYWJsZSBvbiBjYXN0IHJlc3VsdHMuCiAgICAgICAgLy8gV2UgY29tcGFyZSB0aGUgdW5kZXJseWluZyBDKysgcG9pbnRlciBpbnN0ZWFkLgogICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGNvbnN0IHNvdXJjZUJvZHlQdHIgPSBzb3VyY2VFbGVtZW50ICYmIHNvdXJjZUVsZW1lbnQuYm9keSA/IHNvdXJjZUVsZW1lbnQuYm9keS5hIHx8IHNvdXJjZUVsZW1lbnQuYm9keS5wdHIgOiBudWxsOwogICAgICAgIGNvbnN0IGV4cGxvc2lvblBvc2l0aW9uID0gZ2V0RXhwbG9zaW9uUG9zaXRpb24odXVpZCwgcG9zaXRpb24pOwogICAgICAgIGNvbnN0IHsKICAgICAgICAgIGdob3N0Q29sbGlkZXIsCiAgICAgICAgICB0cmFuc2Zvcm0KICAgICAgICB9ID0gY3JlYXRlR2hvc3RDb2xsaWRlcihyYWRpdXMsIGV4cGxvc2lvblBvc2l0aW9uKTsKICAgICAgICB3b3JsZC5hZGRDb2xsaXNpb25PYmplY3QoZ2hvc3RDb2xsaWRlcik7CgogICAgICAgIC8vIEZvcmNlIGEgY29sbGlzaW9uIGRldGVjdGlvbiBwYXNzIHNvIHRoZSBnaG9zdCBjb2xsaWRlciBkaXNjb3ZlcnMKICAgICAgICAvLyBvdmVybGFwcGluZyBib2RpZXMuIFdpdGhvdXQgdGhpcywgZ2V0TnVtT3ZlcmxhcHBpbmdPYmplY3RzKCkgcmV0dXJucyAwCiAgICAgICAgLy8gYmVjYXVzZSBidEdob3N0UGFpckNhbGxiYWNrIG9ubHkgdXBkYXRlcyBkdXJpbmcgYSBzaW11bGF0aW9uIHN0ZXAuCiAgICAgICAgd29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpLnBlcmZvcm1EaXNjcmV0ZUNvbGxpc2lvbkRldGVjdGlvbigpOwogICAgICAgIGZvckVhY2hHaG9zdENvbGxpc2lvbihnaG9zdENvbGxpZGVyLCAob2JqZWN0LCBvYmplY3RUcmFuc2Zvcm0pID0+IHsKICAgICAgICAgIC8vIFNraXAgdGhlIHNvdXJjZSBlbnRpdHkgdXNpbmcgcG9pbnRlciBjb21wYXJpc29uLgogICAgICAgICAgY29uc3Qgb2JqZWN0UHRyID0gb2JqZWN0LmEgfHwgb2JqZWN0LnB0cjsKICAgICAgICAgIGlmIChzb3VyY2VCb2R5UHRyICYmIG9iamVjdFB0ciA9PT0gc291cmNlQm9keVB0cikgcmV0dXJuOwogICAgICAgICAgY29uc3Qgb3JpZ2luID0gb2JqZWN0VHJhbnNmb3JtLmdldE9yaWdpbigpOwogICAgICAgICAgb2JqZWN0LmFjdGl2YXRlKHRydWUpOwogICAgICAgICAgY29uc3QgaW1wdWxzZSA9IGdldEV4cGxvc2lvbkltcHVsc2Uob3JpZ2luLCBleHBsb3Npb25Qb3NpdGlvbiwgc3RyZW5ndGgpOwogICAgICAgICAgb2JqZWN0LmFwcGx5Q2VudHJhbEltcHVsc2UoaW1wdWxzZSk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3koaW1wdWxzZSk7CiAgICAgICAgfSk7CiAgICAgICAgd29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpLnJlbW92ZUNvbGxpc2lvbk9iamVjdChnaG9zdENvbGxpZGVyKTsKICAgICAgICBBbW1vLmRlc3Ryb3koZ2hvc3RDb2xsaWRlcik7CiAgICAgICAgQW1tby5kZXN0cm95KHRyYW5zZm9ybSk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCJbUGh5c2ljcyBXb3JrZXJdIGNyZWF0ZUV4cGxvc2lvbiBlcnJvcjoiLCBlKTsKICAgICAgfQogICAgfTsKCiAgICBjb25zdCBoYW5kbGVMb2FkRXZlbnQgPSBvcHRpb25zID0+IEFtbW8gPT4gewogICAgICBzZWxmLkFtbW8gPSBBbW1vOwogICAgICBvbm1lc3NhZ2UgPSAoewogICAgICAgIGRhdGEKICAgICAgfSkgPT4gewogICAgICAgIHN3aXRjaCAoZGF0YS5ldmVudCkgewogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuQk9YOgogICAgICAgICAgICBhZGRCb3goZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuU1BIRVJFOgogICAgICAgICAgICBhZGRTcGhlcmUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuVkVISUNMRToKICAgICAgICAgICAgYWRkVmVoaWNsZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkFERC5NT0RFTDoKICAgICAgICAgICAgYWRkTW9kZWwoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuUExBWUVSOgogICAgICAgICAgICBhZGRQbGF5ZXIoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULlNFVC5MSU5FQVJfVkVMT0NJVFk6CiAgICAgICAgICAgIHNldExpbmVhclZlbG9jaXR5KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5SRVNFVDoKICAgICAgICAgICAgcmVzZXRFbGVtZW50KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuUE9TSVRJT046CiAgICAgICAgICAgIHNldFBvc2l0aW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuUVVBVEVSTklPTjoKICAgICAgICAgICAgc2V0UXVhdGVybmlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLlZFSElDTEUuU0VULlBPU0lUSU9OOgogICAgICAgICAgICBzZXRWZWhpY2xlUG9zaXRpb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlNFVC5RVUFURVJOSU9OOgogICAgICAgICAgICBzZXRWZWhpY2xlUXVhdGVybmlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLlZFSElDTEUuUkVTRVQ6CiAgICAgICAgICAgIHJlc2V0VmVoaWNsZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuQVBQTFkuSU1QVUxTRToKICAgICAgICAgICAgYXBwbHlJbXB1c2UoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULlVQREFURToKICAgICAgICAgICAgd29ybGQudXBkYXRlQm9keVN0YXRlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5ESVNQT1NFOgogICAgICAgICAgICB3b3JsZC5kaXNwb3NlQm9keShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVGRkVDVFMuRVhQTE9TSU9OOgogICAgICAgICAgICBjcmVhdGVFeHBsb3Npb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5URVJNSU5BVEU6CiAgICAgICAgICAgIHdvcmxkLnRlcm1pbmF0ZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHdvcmxkLmluaXQob3B0aW9ucyk7CiAgICAgIGRpc3BhdGNoZXIuc2VuZFJlYWR5RXZlbnQoKTsKICAgICAgd29ybGQuc2ltdWxhdGUoKTsKICAgIH07CiAgICBjb25zdCBsb2FkQW1tbyA9IG9wdGlvbnMgPT4gewogICAgICBjb25zdCBzY3JpcHRVcmwgPSBvcHRpb25zLmhvc3QgKyAiLyIgKyAob3B0aW9ucy5wYXRoIHx8IExJQlJBUllfTkFNRSk7CiAgICAgIGltcG9ydFNjcmlwdHMoc2NyaXB0VXJsKTsKICAgICAgQW1tbygpLnRoZW4oaGFuZGxlTG9hZEV2ZW50KG9wdGlvbnMpKTsKICAgIH07CiAgICBvbm1lc3NhZ2UgPSAoewogICAgICBkYXRhCiAgICB9KSA9PiB7CiAgICAgIHN3aXRjaCAoZGF0YS5ldmVudCkgewogICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuTE9BRC5BTU1POgogICAgICAgICAgbG9hZEFtbW8oZGF0YSk7CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfTsKCn0pKCk7Cgo=', null, false);
55723
+ }var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IExJQlJBUllfTkFNRSA9ICJhbW1vLmpzIjsKICAgIGNvbnN0IFRZUEVTID0gewogICAgICBCT1g6ICJCT1giLAogICAgICBTUEhFUkU6ICJTUEhFUkUiLAogICAgICBWRUhJQ0xFOiAiVkVISUNMRSIsCiAgICAgIE1FU0g6ICJNRVNIIiwKICAgICAgUExBWUVSOiAiUExBWUVSIgogICAgfTsKICAgIGNvbnN0IERFRkFVTFRfVkVISUNMRV9TVEFURSA9IHsKICAgICAgdmVoaWNsZVN0ZWVyaW5nOiAwLAogICAgICBhY2NlbGVyYXRpb246IGZhbHNlLAogICAgICBicmVha2luZzogZmFsc2UsCiAgICAgIHJpZ2h0OiBmYWxzZSwKICAgICAgbGVmdDogZmFsc2UKICAgIH07CiAgICBjb25zdCBERUZBVUxUX1JJR0lEQk9EWV9TVEFURSA9IHsKICAgICAgdmVsb2NpdHk6IHsKICAgICAgICB4OiAwLAogICAgICAgIHk6IDAsCiAgICAgICAgejogMAogICAgICB9LAogICAgICBtb3ZlbWVudDogewogICAgICAgIGZvcndhcmQ6IGZhbHNlLAogICAgICAgIGJhY2t3YXJkczogZmFsc2UsCiAgICAgICAgbGVmdDogZmFsc2UsCiAgICAgICAgcmlnaHQ6IGZhbHNlCiAgICAgIH0sCiAgICAgIGRpcmVjdGlvbjogewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwCiAgICAgIH0KICAgIH07CiAgICBjb25zdCBERUZBVUxUX1NDQUxFID0gewogICAgICB4OiAxLAogICAgICB5OiAxLAogICAgICB6OiAxCiAgICB9OwogICAgY29uc3QgREVGQVVMVF9MSU5FQVJfVkVMT0NJVFkgPSB7CiAgICAgIHg6IDAsCiAgICAgIHk6IDAsCiAgICAgIHo6IDAKICAgIH07CiAgICBjb25zdCBERUZBVUxUX0lNUFVMU0UgPSB7CiAgICAgIHg6IDAsCiAgICAgIHk6IDAsCiAgICAgIHo6IDAKICAgIH07CiAgICBjb25zdCBESVNBQkxFX0RFQUNUSVZBVElPTiA9IDQ7CiAgICBjb25zdCBHUkFWSVRZID0gewogICAgICB4OiAwLAogICAgICB5OiAtOS44LAogICAgICB6OiAwCiAgICB9OwogICAgY29uc3QgRlJPTlRfTEVGVCA9IDA7CiAgICBjb25zdCBGUk9OVF9SSUdIVCA9IDE7CiAgICBjb25zdCBCQUNLX0xFRlQgPSAyOwogICAgY29uc3QgQkFDS19SSUdIVCA9IDM7CiAgICBjb25zdCBERUZBVUxUX1NURUVSSU5HX0lOQ1JFTUVOVCA9IDAuMDQ7CiAgICBjb25zdCBERUZBVUxUX1NURUVSSU5HX0NMQU1QID0gMC41OwogICAgY29uc3QgREVGQVVMVF9NQVhfRU5HSU5FX0ZPUkNFID0gMjAwMDsKICAgIGNvbnN0IERFRkFVTFRfTUFYX0JSRUFLSU5HX0ZPUkNFID0gMTAwOwogICAgY29uc3QgRVhQTE9TSU9OX1NJWkVTID0gewogICAgICBTTUFMTDogNCwKICAgICAgTUVESVVNOiA2LAogICAgICBMQVJHRTogOCwKICAgICAgTUFTU0lWRTogMTIKICAgIH07CiAgICBjb25zdCBFWFBMT1NJT05fU1RSRU5HVEhTID0gewogICAgICBWRVJZX1dFQUs6IDIsCiAgICAgIFdFQUs6IDQsCiAgICAgIE1FRElVTTogOCwKICAgICAgTEFSR0U6IDE2LAogICAgICBNQVNTSVZFOiAzMiwKICAgICAgT0tfTk86IDY0CiAgICB9OwoKICAgIGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhhLCBuKSB7CiAgICAgIGlmICghKGEgaW5zdGFuY2VvZiBuKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7CiAgICB9CiAgICBmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyhlLCByKSB7CiAgICAgIGZvciAodmFyIHQgPSAwOyB0IDwgci5sZW5ndGg7IHQrKykgewogICAgICAgIHZhciBvID0gclt0XTsKICAgICAgICBvLmVudW1lcmFibGUgPSBvLmVudW1lcmFibGUgfHwgITEsIG8uY29uZmlndXJhYmxlID0gITAsICJ2YWx1ZSIgaW4gbyAmJiAoby53cml0YWJsZSA9ICEwKSwgT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsIF90b1Byb3BlcnR5S2V5KG8ua2V5KSwgbyk7CiAgICAgIH0KICAgIH0KICAgIGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhlLCByLCB0KSB7CiAgICAgIHJldHVybiByICYmIF9kZWZpbmVQcm9wZXJ0aWVzKGUucHJvdG90eXBlLCByKSwgdCAmJiBfZGVmaW5lUHJvcGVydGllcyhlLCB0KSwgT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsICJwcm90b3R5cGUiLCB7CiAgICAgICAgd3JpdGFibGU6ICExCiAgICAgIH0pLCBlOwogICAgfQogICAgZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KGUsIHIsIHQpIHsKICAgICAgcmV0dXJuIChyID0gX3RvUHJvcGVydHlLZXkocikpIGluIGUgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkoZSwgciwgewogICAgICAgIHZhbHVlOiB0LAogICAgICAgIGVudW1lcmFibGU6ICEwLAogICAgICAgIGNvbmZpZ3VyYWJsZTogITAsCiAgICAgICAgd3JpdGFibGU6ICEwCiAgICAgIH0pIDogZVtyXSA9IHQsIGU7CiAgICB9CiAgICBmdW5jdGlvbiBfdG9QcmltaXRpdmUodCwgcikgewogICAgICBpZiAoIm9iamVjdCIgIT0gdHlwZW9mIHQgfHwgIXQpIHJldHVybiB0OwogICAgICB2YXIgZSA9IHRbU3ltYm9sLnRvUHJpbWl0aXZlXTsKICAgICAgaWYgKHZvaWQgMCAhPT0gZSkgewogICAgICAgIHZhciBpID0gZS5jYWxsKHQsIHIgfHwgImRlZmF1bHQiKTsKICAgICAgICBpZiAoIm9iamVjdCIgIT0gdHlwZW9mIGkpIHJldHVybiBpOwogICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuICgic3RyaW5nIiA9PT0gciA/IFN0cmluZyA6IE51bWJlcikodCk7CiAgICB9CiAgICBmdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleSh0KSB7CiAgICAgIHZhciBpID0gX3RvUHJpbWl0aXZlKHQsICJzdHJpbmciKTsKICAgICAgcmV0dXJuICJzeW1ib2wiID09IHR5cGVvZiBpID8gaSA6IGkgKyAiIjsKICAgIH0KCiAgICBjb25zdCBQSFlTSUNTX0VWRU5UUyA9IHsKICAgICAgRElTUEFUQ0g6ICJwaHlzaWNzOmRpc3BhdGNoIiwKICAgICAgVEVSTUlOQVRFOiAicGh5c2ljczp0ZXJtaW5hdGUiLAogICAgICBMT0FEOiB7CiAgICAgICAgQU1NTzogInBoeXNpY3M6bG9hZDphbW1vIgogICAgICB9LAogICAgICBSRUFEWTogInBoeXNpY3M6cmVhZHkiLAogICAgICBJTklUOiAicGh5c2ljczppbml0IiwKICAgICAgVVBEQVRFOiAicGh5c2ljczp1cGRhdGUiLAogICAgICBBREQ6IHsKICAgICAgICBCT1g6ICJwaHlzaWNzOmFkZDpib3giLAogICAgICAgIFZFSElDTEU6ICJwaHlzaWNzOmFkZDp2ZWhpY2xlIiwKICAgICAgICBNT0RFTDogInBoeXNpY3M6YWRkOm1vZGVsIiwKICAgICAgICBQTEFZRVI6ICJwaHlzaWNzOmFkZDpwbGF5ZXIiLAogICAgICAgIFNQSEVSRTogInBoeXNpY3M6YWRkOnNwaGVyZSIKICAgICAgfSwKICAgICAgRUxFTUVOVDogewogICAgICAgIERJU1BPU0U6ICJwaHlzaWNzOmVsZW1lbnQ6ZGlzcG9zZSIsCiAgICAgICAgQ09MTElTSU9OOiAicGh5c2ljczplbGVtZW50OmNvbGxpc2lvbiIsCiAgICAgICAgVVBEQVRFOiAicGh5c2ljczplbGVtZW50OnVwZGF0ZSIsCiAgICAgICAgQ1JFQVRFRDogInBoeXNpY3M6ZWxlbWVudDpjcmVhdGVkIiwKICAgICAgICBTRVQ6IHsKICAgICAgICAgIFBPU0lUSU9OOiAicGh5c2ljczplbGVtZW50OnNldDpwb3NpdGlvbiIsCiAgICAgICAgICBRVUFURVJOSU9OOiAicGh5c2ljczplbGVtZW50OnNldDpxdWF0ZXJuaW9uIiwKICAgICAgICAgIExJTkVBUl9WRUxPQ0lUWTogInBoeXNpY3M6ZWxlbWVudDpzZXQ6bGluZWFyX3ZlbG9jaXR5IgogICAgICAgIH0sCiAgICAgICAgUkVTRVQ6ICJwaHlzaWNzOmVsZW1lbnQ6cmVzZXQiLAogICAgICAgIEFQUExZOiB7CiAgICAgICAgICBJTVBVTFNFOiAicGh5c2ljczplbGVtZW50OmFwcGx5OmltcHVsc2UiCiAgICAgICAgfQogICAgICB9LAogICAgICBWRUhJQ0xFOiB7CiAgICAgICAgU0VUOiB7CiAgICAgICAgICBQT1NJVElPTjogInBoeXNpY3M6dmVoaWNsZTpzZXQ6cG9zaXRpb24iLAogICAgICAgICAgUVVBVEVSTklPTjogInBoeXNpY3M6dmVoaWNsZTpzZXQ6cXVhdGVybmlvbiIKICAgICAgICB9LAogICAgICAgIFJFU0VUOiAicGh5c2ljczp2ZWhpY2xlOnJlc2V0IiwKICAgICAgICBTUEVFRDogInBoeXNpY3M6dmVoaWNsZTpzcGVlZCIsCiAgICAgICAgRElSRUNUSU9OOiAicGh5c2ljczp2ZWhpY2xlOmRpcmVjdGlvbiIKICAgICAgfSwKICAgICAgRUZGRUNUUzogewogICAgICAgIEVYUExPU0lPTjogInBoeXNpY3M6ZWZmZWN0czpleHBsb3Npb24iCiAgICAgIH0KICAgIH07CgogICAgbGV0IERpc3BhdGNoZXIgPSAvKiNfX1BVUkVfXyovX2NyZWF0ZUNsYXNzKGZ1bmN0aW9uIERpc3BhdGNoZXIoKSB7CiAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEaXNwYXRjaGVyKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kUGh5c2ljc1VwZGF0ZSIsIGR0ID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuVVBEQVRFLAogICAgICAgIGR0CiAgICAgIH0pKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kUmVhZHlFdmVudCIsICgpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuUkVBRFkKICAgICAgfSkpOwogICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInNlbmRUZXJtaW5hdGVFdmVudCIsICgpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuVEVSTUlOQVRFCiAgICAgIH0pKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kQm9keVVwZGF0ZSIsICh1dWlkLCBwb3NpdGlvbiwgcm90YXRpb24sIGR0LCBleHRyYURhdGEpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5VUERBVEUsCiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbjogewogICAgICAgICAgeDogcG9zaXRpb24ueCgpLAogICAgICAgICAgeTogcG9zaXRpb24ueSgpLAogICAgICAgICAgejogcG9zaXRpb24ueigpCiAgICAgICAgfSwKICAgICAgICBxdWF0ZXJuaW9uOiB7CiAgICAgICAgICB4OiByb3RhdGlvbi54KCksCiAgICAgICAgICB5OiByb3RhdGlvbi55KCksCiAgICAgICAgICB6OiByb3RhdGlvbi56KCksCiAgICAgICAgICB3OiByb3RhdGlvbi53KCkKICAgICAgICB9LAogICAgICAgIC4uLmV4dHJhRGF0YSwKICAgICAgICBkdAogICAgICB9KSk7CiAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic2VuZERpc3BhdGNoRXZlbnQiLCAodXVpZCwgZXZlbnROYW1lLCBldmVudERhdGEpID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRElTUEFUQ0gsCiAgICAgICAgdXVpZCwKICAgICAgICBldmVudE5hbWUsCiAgICAgICAgZXZlbnREYXRhCiAgICAgIH0pKTsKICAgIH0pOwogICAgdmFyIGRpc3BhdGNoZXIgPSBuZXcgRGlzcGF0Y2hlcigpOwoKICAgIGNvbnN0IGFwcGx5TWF0cml4NFRvVmVjdG9yMyA9ICh7CiAgICAgIHggPSAwLAogICAgICB5ID0gMCwKICAgICAgeiA9IDAKICAgIH0sIG1hdHJpeCA9IFtdKSA9PiB7CiAgICAgIGNvbnN0IHcgPSAxIC8gKG1hdHJpeFszXSAqIHggKyBtYXRyaXhbN10gKiB5ICsgbWF0cml4WzExXSAqIHogKyBtYXRyaXhbMTVdKTsKICAgICAgcmV0dXJuIHsKICAgICAgICB4OiAobWF0cml4WzBdICogeCArIG1hdHJpeFs0XSAqIHkgKyBtYXRyaXhbOF0gKiB6ICsgbWF0cml4WzEyXSkgKiB3LAogICAgICAgIHk6IChtYXRyaXhbMV0gKiB4ICsgbWF0cml4WzVdICogeSArIG1hdHJpeFs5XSAqIHogKyBtYXRyaXhbMTNdKSAqIHcsCiAgICAgICAgejogKG1hdHJpeFsyXSAqIHggKyBtYXRyaXhbNl0gKiB5ICsgbWF0cml4WzEwXSAqIHogKyBtYXRyaXhbMTRdKSAqIHcKICAgICAgfTsKICAgIH07CgogICAgY29uc3QgY3JlYXRlUmlnaWRCb2R5ID0gKHNoYXBlLCBvcHRpb25zKSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24sCiAgICAgICAgcmVzdGl0dXRpb24gPSAwLjksCiAgICAgICAgZGFtcGluZyA9IHsKICAgICAgICAgIGxpbmVhcjogMC4yLAogICAgICAgICAgYW5ndWxhcjogMC4yCiAgICAgICAgfQogICAgICB9ID0gb3B0aW9uczsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBuZXcgQW1tby5idERlZmF1bHRNb3Rpb25TdGF0ZSh0cmFuc2Zvcm0pOwogICAgICBjb25zdCBsb2NhbEluZXJ0aWEgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIHNoYXBlLmNhbGN1bGF0ZUxvY2FsSW5lcnRpYShtYXNzLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCByYkluZm8gPSBuZXcgQW1tby5idFJpZ2lkQm9keUNvbnN0cnVjdGlvbkluZm8obWFzcywgbW90aW9uU3RhdGUsIHNoYXBlLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCBib2R5ID0gbmV3IEFtbW8uYnRSaWdpZEJvZHkocmJJbmZvKTsKICAgICAgaWYgKG1hc3MgPiAwKSB7CiAgICAgICAgYm9keS5zZXRGcmljdGlvbihmcmljdGlvbik7CiAgICAgICAgYm9keS5zZXRSZXN0aXR1dGlvbihyZXN0aXR1dGlvbik7CiAgICAgICAgYm9keS5zZXREYW1waW5nKGRhbXBpbmcubGluZWFyLCBkYW1waW5nLmFuZ3VsYXIpOwogICAgICAgIGJvZHkuc2V0QWN0aXZhdGlvblN0YXRlKERJU0FCTEVfREVBQ1RJVkFUSU9OKTsKICAgICAgfQoKICAgICAgLy8gc3RvcmluZyB1dWlkIGZvciBmdXR1cmUgcmVmZXJlbmNlCiAgICAgIGJvZHkudXVpZCA9IHV1aWQ7CiAgICAgIHdvcmxkLmFkZFJpZ2lkQm9keShib2R5KTsKICAgICAgcmV0dXJuIGJvZHk7CiAgICB9OwogICAgY29uc3QgYWRkTW9kZWwgPSBvcHRpb25zID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgdmVydGljZXMsCiAgICAgICAgbWF0cmljZXMsCiAgICAgICAgaW5kZXhlcywKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gb3B0aW9uczsKICAgICAgY29uc3Qgc2NhbGUgPSBERUZBVUxUX1NDQUxFOwogICAgICBjb25zdCBidGEgPSBuZXcgQW1tby5idFZlY3RvcjMoKTsKICAgICAgY29uc3QgYnRiID0gbmV3IEFtbW8uYnRWZWN0b3IzKCk7CiAgICAgIGNvbnN0IGJ0YyA9IG5ldyBBbW1vLmJ0VmVjdG9yMygpOwogICAgICBjb25zdCB0cmlNZXNoID0gbmV3IEFtbW8uYnRUcmlhbmdsZU1lc2godHJ1ZSwgZmFsc2UpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZlcnRpY2VzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgY29uc3QgY29tcG9uZW50cyA9IHZlcnRpY2VzW2ldOwogICAgICAgIGNvbnN0IGluZGV4ID0gaW5kZXhlc1tpXSA/IGluZGV4ZXNbaV0gOiBudWxsOwogICAgICAgIGNvbnN0IG1hdHJpeCA9IEFycmF5LmZyb20obWF0cmljZXNbaV0pOwogICAgICAgIGlmIChpbmRleCkgewogICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRleC5sZW5ndGg7IGogKz0gMykgewogICAgICAgICAgICBjb25zdCBhaSA9IGluZGV4W2pdICogMzsKICAgICAgICAgICAgY29uc3QgYmkgPSBpbmRleFtqICsgMV0gKiAzOwogICAgICAgICAgICBjb25zdCBjaSA9IGluZGV4W2ogKyAyXSAqIDM7CiAgICAgICAgICAgIGNvbnN0IHZhID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2FpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2FpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1thaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZiID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2JpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2JpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tiaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZjID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2NpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2NpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tjaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGJ0YS5zZXRWYWx1ZSh2YS54LCB2YS55LCB2YS56KTsKICAgICAgICAgICAgYnRiLnNldFZhbHVlKHZiLngsIHZiLnksIHZiLnopOwogICAgICAgICAgICBidGMuc2V0VmFsdWUodmMueCwgdmMueSwgdmMueik7CiAgICAgICAgICAgIHRyaU1lc2guYWRkVHJpYW5nbGUoYnRhLCBidGIsIGJ0YywgZmFsc2UpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbXBvbmVudHMubGVuZ3RoOyBqICs9IDkpIHsKICAgICAgICAgICAgY29uc3QgdmEgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbaiArIDBdLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbaiArIDFdLAogICAgICAgICAgICAgIHo6IGNvbXBvbmVudHNbaiArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZiID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2ogKyAzXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2ogKyA0XSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2ogKyA1XQogICAgICAgICAgICB9LCBtYXRyaXgpOwogICAgICAgICAgICBjb25zdCB2YyA9IGFwcGx5TWF0cml4NFRvVmVjdG9yMyh7CiAgICAgICAgICAgICAgeDogY29tcG9uZW50c1tqICsgNl0sCiAgICAgICAgICAgICAgeTogY29tcG9uZW50c1tqICsgN10sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tqICsgOF0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgYnRhLnNldFZhbHVlKHZhLngsIHZhLnksIHZhLnopOwogICAgICAgICAgICBidGIuc2V0VmFsdWUodmIueCwgdmIueSwgdmIueik7CiAgICAgICAgICAgIGJ0Yy5zZXRWYWx1ZSh2Yy54LCB2Yy55LCB2Yy56KTsKICAgICAgICAgICAgdHJpTWVzaC5hZGRUcmlhbmdsZShidGEsIGJ0YiwgYnRjLCBmYWxzZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGNvbnN0IGxvY2FsU2NhbGUgPSBuZXcgQW1tby5idFZlY3RvcjMoc2NhbGUueCwgc2NhbGUueSwgc2NhbGUueik7CiAgICAgIHRyaU1lc2guc2V0U2NhbGluZyhsb2NhbFNjYWxlKTsKICAgICAgQW1tby5kZXN0cm95KGxvY2FsU2NhbGUpOwogICAgICBjb25zdCBjb2xsaXNpb25TaGFwZSA9IG5ldyBBbW1vLmJ0QnZoVHJpYW5nbGVNZXNoU2hhcGUodHJpTWVzaCwgdHJ1ZSwgdHJ1ZSk7CiAgICAgIGNvbGxpc2lvblNoYXBlLnJlc291cmNlcyA9IFt0cmlNZXNoXTsKICAgICAgQW1tby5kZXN0cm95KGJ0YSk7CiAgICAgIEFtbW8uZGVzdHJveShidGIpOwogICAgICBBbW1vLmRlc3Ryb3koYnRjKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShjb2xsaXNpb25TaGFwZSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuTUVTSCwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgYWRkQm94ID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHdpZHRoLAogICAgICAgIGxlbmd0aCwKICAgICAgICBoZWlnaHQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzID0gMCwKICAgICAgICBmcmljdGlvbiA9IDIKICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IGdlb21ldHJ5ID0gbmV3IEFtbW8uYnRCb3hTaGFwZShuZXcgQW1tby5idFZlY3RvcjMod2lkdGggKiAwLjUsIGhlaWdodCAqIDAuNSwgbGVuZ3RoICogMC41KSk7CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoZ2VvbWV0cnksIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbgogICAgICB9KTsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLkJPWCwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgYWRkU3BoZXJlID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHJhZGl1cywKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idFNwaGVyZVNoYXBlKHJhZGl1cyk7CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoZ2VvbWV0cnksIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbgogICAgICB9KTsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLlNQSEVSRSwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3Qgc2V0TGluZWFyVmVsb2NpdHkgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgdmVsb2NpdHkgPSBERUZBVUxUX0xJTkVBUl9WRUxPQ0lUWQogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBjb25zdCBsaW5lYXJWZWxvY2l0eSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyh2ZWxvY2l0eS54LCB2ZWxvY2l0eS55LCB2ZWxvY2l0eS56KTsKICAgICAgICBib2R5LnNldExpbmVhclZlbG9jaXR5KGxpbmVhclZlbG9jaXR5KTsKICAgICAgICBBbW1vLmRlc3Ryb3kobGluZWFyVmVsb2NpdHkpOwogICAgICB9CiAgICB9OwogICAgY29uc3Qgc2V0UG9zaXRpb24gPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24KICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IHsKICAgICAgICBib2R5CiAgICAgIH0gPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAvLyBBbHNvIHVwZGF0ZSBtb3Rpb24gc3RhdGUgc28gc3RhdGljIGJvZGllcyAobWFzcz0wKSByZWZsZWN0IHRoZSBjaGFuZ2UKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCByZXNldEVsZW1lbnQgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGFwcGx5SW1wdXNlID0gKHsKICAgICAgdXVpZCwKICAgICAgaW1wdWxzZSA9IERFRkFVTFRfSU1QVUxTRQogICAgfSkgPT4gewogICAgICB0cnkgewogICAgICAgIGNvbnN0IGVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGlmICghZWxlbWVudCkgewogICAgICAgICAgY29uc29sZS53YXJuKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZTogZWxlbWVudCBub3QgZm91bmQgZm9yIHV1aWQ6IiwgdXVpZCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IHsKICAgICAgICAgIGJvZHkKICAgICAgICB9ID0gZWxlbWVudDsKICAgICAgICBpZiAoIWJvZHkpIHsKICAgICAgICAgIGNvbnNvbGUud2FybigiW1BoeXNpY3MgV29ya2VyXSBhcHBseUltcHVsc2U6IGJvZHkgaXMgbnVsbCBmb3IgdXVpZDoiLCB1dWlkKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgYm9keS5hY3RpdmF0ZSh0cnVlKTsKICAgICAgICBjb25zdCBidEltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMoaW1wdWxzZS54LCBpbXB1bHNlLnksIGltcHVsc2Uueik7CiAgICAgICAgYm9keS5hcHBseUNlbnRyYWxJbXB1bHNlKGJ0SW1wdWxzZSk7CiAgICAgICAgQW1tby5kZXN0cm95KGJ0SW1wdWxzZSk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZSBlcnJvcjoiLCBlKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHNldFF1YXRlcm5pb24gPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcXVhdGVybmlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAvLyBBbHNvIHVwZGF0ZSBtb3Rpb24gc3RhdGUgc28gc3RhdGljIGJvZGllcyAobWFzcz0wKSByZWZsZWN0IHRoZSBjaGFuZ2UKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBoYW5kbGVFbGVtZW50VXBkYXRlID0gKHsKICAgICAgYm9keSwKICAgICAgdXVpZCwKICAgICAgc3RhdGU6IF9zdGF0ZSA9IERFRkFVTFRfUklHSURCT0RZX1NUQVRFCiAgICB9LCBkdCkgPT4gewogICAgICAvLyBTdGF0aWMgYm9kaWVzIChtYXNzPTApIG5ldmVyIG1vdmUg4oCUIHNraXAgc2VuZGluZyB1cGRhdGVzIHNvIHRoZQogICAgICAvLyB2aXN1YWwgcG9zaXRpb24gc3RheXMgZXhhY3RseSB3aGVyZSB0aGUgYXV0aG9yIHBsYWNlZCBpdC4KICAgICAgaWYgKGJvZHkuaXNTdGF0aWNPYmplY3QoKSkgcmV0dXJuOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBtb3Rpb25TdGF0ZS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIGxldCBvcmlnaW4gPSB0cmFuc2Zvcm0uZ2V0T3JpZ2luKCk7CiAgICAgICAgbGV0IHJvdGF0aW9uID0gdHJhbnNmb3JtLmdldFJvdGF0aW9uKCk7CiAgICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBvcmlnaW4sIHJvdGF0aW9uLCBkdCk7CiAgICAgICAgQW1tby5kZXN0cm95KHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CgogICAgY29uc3QgYWRkUGxheWVyID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHdpZHRoLAogICAgICAgIGhlaWdodCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uLAogICAgICAgIG9yaWdpbk9mZnNldCA9IHsKICAgICAgICAgIHg6IDAsCiAgICAgICAgICB5OiAwLAogICAgICAgICAgejogMAogICAgICAgIH0KICAgICAgfSA9IGRhdGE7CgogICAgICAvLyBidENhcHN1bGVTaGFwZSBleHBlY3RzIChyYWRpdXMsIGN5bGluZGVySGVpZ2h0KSDigJQgdXNlIGhhbGYtd2lkdGggYXMKICAgICAgLy8gcmFkaXVzIHNvIHRoZSBjYXBzdWxlIHdyYXBzIHRoZSBib3VuZGluZyBib3ggY29ycmVjdGx5LgogICAgICBjb25zdCByYWRpdXMgPSB3aWR0aCAqIDAuNTsKICAgICAgY29uc3QgY2Fwc3VsZSA9IG5ldyBBbW1vLmJ0Q2Fwc3VsZVNoYXBlKHJhZGl1cywgaGVpZ2h0KTsKCiAgICAgIC8vIEFsd2F5cyBjcmVhdGUgdGhlIHBsYXllciBib2R5IHVwcmlnaHQgKGlkZW50aXR5IHF1YXRlcm5pb24pLgogICAgICAvLyBUaGUgdmlzdWFsIHJvdGF0aW9uIGlzIGRyaXZlbiBieSB0aGUgY29udHJvbCwgbm90IGJ5IHBoeXNpY3MuCiAgICAgIGNvbnN0IHVwcmlnaHRRdWF0ZXJuaW9uID0gewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwLAogICAgICAgIHc6IDEKICAgICAgfTsKCiAgICAgIC8vIFBvc2l0aW9uIHRoZSBjYXBzdWxlIGF0IHRoZSBtb2RlbCdzIEFBQkIgY2VudHJlIHNvIGl0IHdyYXBzIHRoZQogICAgICAvLyB2aXN1YWwgbWVzaCBjb3JyZWN0bHkuICBvcmlnaW5PZmZzZXQgaXMgdGhlIHZlY3RvciBmcm9tIHRoZSBtb2RlbCdzCiAgICAgIC8vIG9yaWdpbiB0byBpdHMgQUFCQiBjZW50cmUg4oCUIGNvbXB1dGVkIG9uIHRoZSBtYWluIHRocmVhZCB3aGVyZQogICAgICAvLyBUaHJlZS5qcyBnZW9tZXRyeSBpcyBhdmFpbGFibGUuCiAgICAgIGNvbnN0IGNhcHN1bGVQb3NpdGlvbiA9IHsKICAgICAgICB4OiBwb3NpdGlvbi54ICsgb3JpZ2luT2Zmc2V0LngsCiAgICAgICAgeTogcG9zaXRpb24ueSArIG9yaWdpbk9mZnNldC55LAogICAgICAgIHo6IHBvc2l0aW9uLnogKyBvcmlnaW5PZmZzZXQuegogICAgICB9OwogICAgICBjb25zdCBib2R5ID0gY3JlYXRlUmlnaWRCb2R5KGNhcHN1bGUsIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uOiBjYXBzdWxlUG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbjogdXByaWdodFF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbiwKICAgICAgICByZXN0aXR1dGlvbjogMCwKICAgICAgICBkYW1waW5nOiB7CiAgICAgICAgICBsaW5lYXI6IDAuMSwKICAgICAgICAgIGFuZ3VsYXI6IDEKICAgICAgICB9CiAgICAgIH0pOwoKICAgICAgLy8gRGlzYWJsZSByb3RhdGlvbiBvbiBhbGwgYXhlcyDigJQgdGhlIHZpc3VhbCByb3RhdGlvbiBpcyBkcml2ZW4gYnkgdGhlIGNvbnRyb2wuCiAgICAgIC8vIFVzZSBidFZlY3RvcjMgaW5zdGVhZCBvZiBzY2FsYXIgZm9yIGNvbXBhdGliaWxpdHkgYWNyb3NzIEFtbW8uanMgYnVpbGRzLgogICAgICBjb25zdCB6ZXJvQW5ndWxhciA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgYm9keS5zZXRBbmd1bGFyRmFjdG9yKHplcm9Bbmd1bGFyKTsKICAgICAgQW1tby5kZXN0cm95KHplcm9Bbmd1bGFyKTsKCiAgICAgIC8vIEVuYWJsZSBjb250aW51b3VzIGNvbGxpc2lvbiBkZXRlY3Rpb24gdG8gcHJldmVudCB0dW5uZWxpbmcgYXQgaGlnaCBzcGVlZHMuCiAgICAgIGJvZHkuc2V0Q2NkTW90aW9uVGhyZXNob2xkKHJhZGl1cyAqIDAuNSk7CiAgICAgIGJvZHkuc2V0Q2NkU3dlcHRTcGhlcmVSYWRpdXMocmFkaXVzICogMC44KTsKCiAgICAgIC8vIFN0b3JlIGZvciB1c2UgaW4gaGFuZGxlUGxheWVyVXBkYXRlIOKAlCBvZmZzZXQgaXMgc3VidHJhY3RlZCB3aGVuCiAgICAgIC8vIHNlbmRpbmcgcG9zaXRpb24gYmFjayBzbyB0aGUgdmlzdWFsIHN0YXlzIGF0IHRoZSBtb2RlbCBvcmlnaW4uCiAgICAgIGJvZHkuX21hc3MgPSBtYXNzOwogICAgICBib2R5Ll9vcmlnaW5PZmZzZXQgPSBvcmlnaW5PZmZzZXQ7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHV1aWQsCiAgICAgICAgYm9keSwKICAgICAgICB0eXBlOiBUWVBFUy5QTEFZRVIsCiAgICAgICAgc3RhdGU6IERFRkFVTFRfUklHSURCT0RZX1NUQVRFCiAgICAgIH0pOwogICAgfTsKICAgIGNvbnN0IGhhbmRsZVBsYXllclVwZGF0ZSA9ICh7CiAgICAgIGJvZHksCiAgICAgIHV1aWQsCiAgICAgIHN0YXRlID0gREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgIH0sIGR0KSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICBtb3ZlbWVudCwKICAgICAgICBjYW1lcmFEaXJlY3Rpb24sCiAgICAgICAganVtcCwKICAgICAgICBqdW1wU3BlZWQsCiAgICAgICAgc3BlZWQ6IG1vdmVTcGVlZAogICAgICB9ID0gc3RhdGU7CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAoIW1vdGlvblN0YXRlKSByZXR1cm47CgogICAgICAvLyBGb3JjZS1jbGVhciBhbmd1bGFyIHZlbG9jaXR5IGV2ZXJ5IHRpY2suIFRoZSBwbGF5ZXIgY2Fwc3VsZSBtdXN0IHN0YXkKICAgICAgLy8gdXByaWdodCDigJQgcm90YXRpb24gaXMgaGFuZGxlZCB2aXN1YWxseSBieSB0aGUgY29udHJvbCwgbm90IGJ5IHBoeXNpY3MuCiAgICAgIGNvbnN0IHplcm9BbmdWZWwgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIGJvZHkuc2V0QW5ndWxhclZlbG9jaXR5KHplcm9BbmdWZWwpOwogICAgICBBbW1vLmRlc3Ryb3koemVyb0FuZ1ZlbCk7CgogICAgICAvLyBGb3JjZSB0aGUgcGh5c2ljcyBib2R5IHJvdGF0aW9uIHRvIGlkZW50aXR5ICh1cHJpZ2h0KSBldmVyeSB0aWNrLgogICAgICAvLyBDb250YWN0IGZvcmNlcyBjYW4gc3RpbGwgcm90YXRlIHRoZSBjYXBzdWxlIGluIHNvbWUgQW1tby5qcyBidWlsZHMKICAgICAgLy8gZXZlbiB3aXRoIGFuZ3VsYXJGYWN0b3I9KDAsMCwwKS4gV2UgbXVzdCByZXNldCBCT1RIIHRoZSBib2R5IHdvcmxkCiAgICAgIC8vIHRyYW5zZm9ybSBBTkQgdGhlIG1vdGlvblN0YXRlIOKAlCB0aGV5IGNhbiBkaXZlcmdlLgogICAgICBjb25zdCB3b3JsZFRyYW5zZm9ybSA9IGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0oKTsKICAgICAgY29uc3QgdXByaWdodFF1YXQgPSBuZXcgQW1tby5idFF1YXRlcm5pb24oMCwgMCwgMCwgMSk7CiAgICAgIHdvcmxkVHJhbnNmb3JtLnNldFJvdGF0aW9uKHVwcmlnaHRRdWF0KTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh3b3JsZFRyYW5zZm9ybSk7CiAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHdvcmxkVHJhbnNmb3JtKTsKICAgICAgQW1tby5kZXN0cm95KHVwcmlnaHRRdWF0KTsKICAgICAgY29uc3QgY2hhcmFjdGVyU3BlZWQgPSBtb3ZlU3BlZWQgfHwgNTsKCiAgICAgIC8vIEp1bXAg4oCUIGFwcGx5IGEgb25lLXRpbWUgaW1wdWxzZSwgdGhlbiBjbGVhciB0aGUgZmxhZyBzbyBpdCBkb2Vzbid0IHJlcGVhdAogICAgICBpZiAoanVtcCAmJiBqdW1wU3BlZWQpIHsKICAgICAgICBjb25zdCBtYXNzID0gYm9keS5fbWFzcyB8fCA4MDsKICAgICAgICBjb25zdCBpbXB1bHNlID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIGp1bXBTcGVlZCAqIG1hc3MsIDApOwogICAgICAgIGJvZHkuYXBwbHlDZW50cmFsSW1wdWxzZShpbXB1bHNlKTsKICAgICAgICBBbW1vLmRlc3Ryb3koaW1wdWxzZSk7CiAgICAgICAgc3RhdGUuanVtcCA9IGZhbHNlOwogICAgICB9CiAgICAgIGNvbnN0IGlzTW92aW5nID0gbW92ZW1lbnQgJiYgKG1vdmVtZW50LmZvcndhcmQgfHwgbW92ZW1lbnQuYmFja3dhcmRzIHx8IG1vdmVtZW50LmxlZnQgfHwgbW92ZW1lbnQucmlnaHQpOwogICAgICBjb25zdCBsaW5lYXJWZWxvY2l0eSA9IGJvZHkuZ2V0TGluZWFyVmVsb2NpdHkoKTsKICAgICAgY29uc3QgY3VycmVudFkgPSBsaW5lYXJWZWxvY2l0eS55KCk7CiAgICAgIGlmIChpc01vdmluZyAmJiBjYW1lcmFEaXJlY3Rpb24pIHsKICAgICAgICAvLyBDb21wdXRlIGNhbWVyYS1yZWxhdGl2ZSBtb3ZlbWVudCBkaXJlY3Rpb24KICAgICAgICBsZXQgbW92ZVggPSAwOwogICAgICAgIGxldCBtb3ZlWiA9IDA7CiAgICAgICAgaWYgKG1vdmVtZW50LmZvcndhcmQpIHsKICAgICAgICAgIG1vdmVYICs9IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgICAgbW92ZVogKz0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5iYWNrd2FyZHMpIHsKICAgICAgICAgIG1vdmVYIC09IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgICAgbW92ZVogLT0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5sZWZ0KSB7CiAgICAgICAgICBtb3ZlWCArPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICAgIG1vdmVaIC09IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgIH0KICAgICAgICBpZiAobW92ZW1lbnQucmlnaHQpIHsKICAgICAgICAgIG1vdmVYIC09IGNhbWVyYURpcmVjdGlvbi56OwogICAgICAgICAgbW92ZVogKz0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgfQoKICAgICAgICAvLyBOb3JtYWxpemUgZGlyZWN0aW9uCiAgICAgICAgY29uc3QgbGVuID0gTWF0aC5zcXJ0KG1vdmVYICogbW92ZVggKyBtb3ZlWiAqIG1vdmVaKTsKICAgICAgICBpZiAobGVuID4gMCkgewogICAgICAgICAgbW92ZVggLz0gbGVuOwogICAgICAgICAgbW92ZVogLz0gbGVuOwogICAgICAgIH0KCiAgICAgICAgLy8gU2V0IGhvcml6b250YWwgdmVsb2NpdHkgZGlyZWN0bHkgZm9yIHJlc3BvbnNpdmUgbW92ZW1lbnQKICAgICAgICBjb25zdCBuZXdWZWwgPSBuZXcgQW1tby5idFZlY3RvcjMobW92ZVggKiBjaGFyYWN0ZXJTcGVlZCwgY3VycmVudFksIG1vdmVaICogY2hhcmFjdGVyU3BlZWQpOwogICAgICAgIGJvZHkuc2V0TGluZWFyVmVsb2NpdHkobmV3VmVsKTsKICAgICAgICBBbW1vLmRlc3Ryb3kobmV3VmVsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBXaGVuIGlkbGUsIG9ubHkgZGFtcGVuIGlmIHRoZXJlJ3MgbWVhbmluZ2Z1bCBob3Jpem9udGFsIHZlbG9jaXR5LgogICAgICAgIC8vIEF2b2lkIHRvdWNoaW5nIHRoZSB2ZWxvY2l0eSBldmVyeSBmcmFtZSB0byBsZXQgdGhlIHNvbHZlcgogICAgICAgIC8vIGhhbmRsZSBmbG9vciBjb250YWN0IHdpdGhvdXQgaW50ZXJmZXJlbmNlLgogICAgICAgIGNvbnN0IHZ4ID0gbGluZWFyVmVsb2NpdHkueCgpOwogICAgICAgIGNvbnN0IHZ6ID0gbGluZWFyVmVsb2NpdHkueigpOwogICAgICAgIGlmIChNYXRoLmFicyh2eCkgPiAwLjAxIHx8IE1hdGguYWJzKHZ6KSA+IDAuMDEpIHsKICAgICAgICAgIGNvbnN0IG5ld1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMyh2eCAqIDAuODUsIGN1cnJlbnRZLCB2eiAqIDAuODUpOwogICAgICAgICAgYm9keS5zZXRMaW5lYXJWZWxvY2l0eShuZXdWZWwpOwogICAgICAgICAgQW1tby5kZXN0cm95KG5ld1ZlbCk7CiAgICAgICAgfQogICAgICAgIC8vIE90aGVyd2lzZSBsZXQgcGh5c2ljcyBoYW5kbGUgZXZlcnl0aGluZyDigJQgZG9uJ3Qgb3ZlcnJpZGUgdmVsb2NpdHkKICAgICAgfQoKICAgICAgLy8gUmVhZCBmcm9tIHRoZSBib2R5J3Mgd29ybGQgdHJhbnNmb3JtIChub3QgbW90aW9uU3RhdGUpIGJlY2F1c2Ugd2UKICAgICAgLy8gbWFpbnRhaW4gaXQgZGlyZWN0bHkgYWJvdmUg4oCUIHBvc2l0aW9uIGNvbWVzIGZyb20gcGh5c2ljcywgcm90YXRpb24KICAgICAgLy8gaXMgYWx3YXlzIGlkZW50aXR5LgogICAgICBjb25zdCBmaW5hbFRyYW5zZm9ybSA9IGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0oKTsKICAgICAgY29uc3Qgb3JpZ2luID0gZmluYWxUcmFuc2Zvcm0uZ2V0T3JpZ2luKCk7CiAgICAgIGNvbnN0IHJvdGF0aW9uID0gZmluYWxUcmFuc2Zvcm0uZ2V0Um90YXRpb24oKTsKICAgICAgY29uc3QgZ3JvdW5kZWQgPSBNYXRoLmFicyhjdXJyZW50WSkgPCAwLjU7CgogICAgICAvLyBUaGUgcGh5c2ljcyBjYXBzdWxlIGlzIG9mZnNldCB1cHdhcmQgc28gaXRzIGJvdHRvbSBhbGlnbnMgd2l0aCB0aGUKICAgICAgLy8gY2hhcmFjdGVyJ3MgZmVldC4gIFN1YnRyYWN0IHRoZSBvZmZzZXQgYmVmb3JlIHNlbmRpbmcgdGhlIHBvc2l0aW9uCiAgICAgIC8vIGJhY2sgc28gdGhlIHZpc3VhbCBzdGF5cyBhdCB0aGUgZmVldCwgbm90IHRoZSBjYXBzdWxlIGNlbnRyZS4KICAgICAgLy8gU3VidHJhY3QgdGhlIG9yaWdpbiBvZmZzZXQgc28gdGhlIHBvc2l0aW9uIG1hcHMgYmFjayB0byBtb2RlbC1vcmlnaW4KICAgICAgLy8gc3BhY2UgKHRoZSB2aXN1YWwncyB0cmFuc2Zvcm0gb3JpZ2luKSwgbm90IHRoZSBBQUJCIGNlbnRyZS4KICAgICAgY29uc3Qgb2ZmID0gYm9keS5fb3JpZ2luT2Zmc2V0IHx8IHsKICAgICAgICB4OiAwLAogICAgICAgIHk6IDAsCiAgICAgICAgejogMAogICAgICB9OwogICAgICBjb25zdCBhZGp1c3RlZE9yaWdpbiA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhvcmlnaW4ueCgpIC0gb2ZmLngsIG9yaWdpbi55KCkgLSBvZmYueSwgb3JpZ2luLnooKSAtIG9mZi56KTsKICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBhZGp1c3RlZE9yaWdpbiwgcm90YXRpb24sIGR0LCB7CiAgICAgICAgZ3JvdW5kZWQKICAgICAgfSk7CiAgICAgIEFtbW8uZGVzdHJveShhZGp1c3RlZE9yaWdpbik7CiAgICB9OwoKICAgIGNvbnN0IHJlcXVlc3ROZXh0RnJhbWUgPSBzZWxmLnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgc2VsZi5tc1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIF9lbGVtZW50KSB7CiAgICAgIHNlbGYuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDEyMCk7CiAgICB9OwogICAgbGV0IENsb2NrID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHsKICAgICAgZnVuY3Rpb24gQ2xvY2soKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENsb2NrKTsKICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIF9jcmVhdGVDbGFzcyhDbG9jaywgW3sKICAgICAgICBrZXk6ICJnZXREZWx0YSIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldERlbHRhKCkgewogICAgICAgICAgY29uc3QgdGltZSA9IERhdGUubm93KCk7CiAgICAgICAgICBpZiAodGhpcy50aW1lc3RhbXApIHsKICAgICAgICAgICAgY29uc3QgZGVsdGEgPSB0aW1lIC0gdGhpcy50aW1lc3RhbXA7CiAgICAgICAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZTsKICAgICAgICAgICAgcmV0dXJuIGRlbHRhOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH1dKTsKICAgIH0oKTsKICAgIGxldCBXb3JsZCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7CiAgICAgIGZ1bmN0aW9uIFdvcmxkKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBXb3JsZCk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJpbml0Iiwgb3B0aW9ucyA9PiB7CiAgICAgICAgICBjb25zdCB7CiAgICAgICAgICAgIGdyYXZpdHkgPSBHUkFWSVRZCiAgICAgICAgICB9ID0gb3B0aW9uczsKICAgICAgICAgIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbiA9IG5ldyBBbW1vLmJ0RGVmYXVsdENvbGxpc2lvbkNvbmZpZ3VyYXRpb24oKTsKICAgICAgICAgIHRoaXMuZGlzcGF0Y2hlciA9IG5ldyBBbW1vLmJ0Q29sbGlzaW9uRGlzcGF0Y2hlcih0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24pOwogICAgICAgICAgdGhpcy5icm9hZHBoYXNlID0gbmV3IEFtbW8uYnREYnZ0QnJvYWRwaGFzZSgpOwogICAgICAgICAgdGhpcy5zb2x2ZXIgPSBuZXcgQW1tby5idFNlcXVlbnRpYWxJbXB1bHNlQ29uc3RyYWludFNvbHZlcigpOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkID0gbmV3IEFtbW8uYnREaXNjcmV0ZUR5bmFtaWNzV29ybGQodGhpcy5kaXNwYXRjaGVyLCB0aGlzLmJyb2FkcGhhc2UsIHRoaXMuc29sdmVyLCB0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24pOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLnNldEdyYXZpdHkobmV3IEFtbW8uYnRWZWN0b3IzKGdyYXZpdHkueCwgZ3Jhdml0eS55LCBncmF2aXR5LnopKTsKCiAgICAgICAgICAvLyB0aGlzIGlzIG5lZWRlZCBmb3IgZ2hvc3RPYmplY3QgY29sbGlzaW9ucwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmdldEJyb2FkcGhhc2UoKS5nZXRPdmVybGFwcGluZ1BhaXJDYWNoZSgpLnNldEludGVybmFsR2hvc3RQYWlyQ2FsbGJhY2sobmV3IEFtbW8uYnRHaG9zdFBhaXJDYWxsYmFjaygpKTsKICAgICAgICAgIHRoaXMuaW5pdGlhbGlzZWQgPSB0cnVlOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAicmVtb3ZlRWxlbWVudCIsIHV1aWQgPT4gewogICAgICAgICAgaWYgKHRoaXMuaGFzRWxlbWVudCh1dWlkKSkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnRzW3V1aWRdLmRlbGV0ZWQgPSB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAicmVtb3ZlRGVsZXRlZEVsZW1lbnRzIiwgKCkgPT4gT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuZmlsdGVyKHV1aWQgPT4gdGhpcy5lbGVtZW50c1t1dWlkXS5kZWxldGVkKS5mb3JFYWNoKHV1aWQgPT4gewogICAgICAgICAgZGVsZXRlIHRoaXMuZWxlbWVudHNbdXVpZF07CiAgICAgICAgfSkpOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiaGFzRWxlbWVudCIsIHV1aWQgPT4gewogICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmluY2x1ZGVzKHV1aWQpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiZ2V0RWxlbWVudCIsIHV1aWQgPT4gdGhpcy5lbGVtZW50c1t1dWlkXSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJpc0luaXRpYWxpc2VkIiwgKCkgPT4gdGhpcy5pbml0aWFsaXNlZCk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJnZXREeW5hbWljc1dvcmxkIiwgKCkgPT4gdGhpcy5keW5hbWljc1dvcmxkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZFJpZ2lkQm9keSIsIGJvZHkgPT4gewogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmFkZFJpZ2lkQm9keShib2R5KTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZEFjdGlvbiIsIGFjdGlvbiA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkQWN0aW9uKGFjdGlvbik7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJhZGRDb2xsaXNpb25PYmplY3QiLCBjb2xsaXNpb25PYmplY3QgPT4gewogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmFkZENvbGxpc2lvbk9iamVjdChjb2xsaXNpb25PYmplY3QpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic3RlcFNpbXVsYXRpb24iLCBkdCA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuc3RlcFNpbXVsYXRpb24oZHQpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic2ltdWxhdGUiLCAoKSA9PiB7CiAgICAgICAgICBjb25zdCBkdCA9IHRoaXMuY2xvY2suZ2V0RGVsdGEoKSAvIDEwMDA7CiAgICAgICAgICB0aGlzLnN0ZXBTaW11bGF0aW9uKGR0KTsKICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmZvckVhY2godXVpZCA9PiB7CiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgICAgc3dpdGNoIChlbGVtZW50LnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuQk9YOgogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5TUEhFUkU6CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVTLk1FU0g6CiAgICAgICAgICAgICAgICAgIGhhbmRsZUVsZW1lbnRVcGRhdGUoZWxlbWVudCwgZHQpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuUExBWUVSOgogICAgICAgICAgICAgICAgICBoYW5kbGVQbGF5ZXJVcGRhdGUoZWxlbWVudCwgZHQpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuVkVISUNMRToKICAgICAgICAgICAgICAgICAgaGFuZGxlVmVoaWNsZVVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICB0aGlzLmNhbGN1bGF0ZUNvbGxpc2lvbnMoKTsKICAgICAgICAgIHRoaXMucmVtb3ZlRGVsZXRlZEVsZW1lbnRzKCk7CiAgICAgICAgICBkaXNwYXRjaGVyLnNlbmRQaHlzaWNzVXBkYXRlKGR0KTsKICAgICAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0TmV4dEZyYW1lKHRoaXMuc2ltdWxhdGUuYmluZCh0aGlzKSk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJjYWxjdWxhdGVDb2xsaXNpb25zIiwgKCkgPT4gewogICAgICAgICAgbGV0IGFtbW9EaXNwYXRjaGVyID0gdGhpcy5keW5hbWljc1dvcmxkLmdldERpc3BhdGNoZXIoKTsKICAgICAgICAgIGxldCBudW1NYW5pZm9sZHMgPSBhbW1vRGlzcGF0Y2hlci5nZXROdW1NYW5pZm9sZHMoKTsKICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtTWFuaWZvbGRzOyBpKyspIHsKICAgICAgICAgICAgbGV0IGNvbnRhY3RNYW5pZm9sZCA9IGFtbW9EaXNwYXRjaGVyLmdldE1hbmlmb2xkQnlJbmRleEludGVybmFsKGkpOwogICAgICAgICAgICBsZXQgcmIwID0gQW1tby5jYXN0T2JqZWN0KGNvbnRhY3RNYW5pZm9sZC5nZXRCb2R5MCgpLCBBbW1vLmJ0UmlnaWRCb2R5KTsKICAgICAgICAgICAgbGV0IHJiMSA9IEFtbW8uY2FzdE9iamVjdChjb250YWN0TWFuaWZvbGQuZ2V0Qm9keTEoKSwgQW1tby5idFJpZ2lkQm9keSk7CiAgICAgICAgICAgIGxldCBudW1Db250YWN0cyA9IGNvbnRhY3RNYW5pZm9sZC5nZXROdW1Db250YWN0cygpOwoKICAgICAgICAgICAgLy8gdGhpcyBpdGVyYXRpb24gZG9lc24ndCBoYXZlIHV1aWRzCiAgICAgICAgICAgIGlmICghcmIwLnV1aWQgfHwgIXJiMS51dWlkKSBjb250aW51ZTsKICAgICAgICAgICAgbGV0IGNvbnRhY3RzID0gW107CiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbnVtQ29udGFjdHM7IGorKykgewogICAgICAgICAgICAgIGxldCBjb250YWN0UG9pbnQgPSBjb250YWN0TWFuaWZvbGQuZ2V0Q29udGFjdFBvaW50KGopOwogICAgICAgICAgICAgIGxldCBkaXN0YW5jZSA9IGNvbnRhY3RQb2ludC5nZXREaXN0YW5jZSgpOwogICAgICAgICAgICAgIGlmIChkaXN0YW5jZSA+IDAuMCkgY29udGludWU7CiAgICAgICAgICAgICAgbGV0IHZlbG9jaXR5MCA9IHJiMC5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICAgICAgICAgIGxldCB2ZWxvY2l0eTEgPSByYjEuZ2V0TGluZWFyVmVsb2NpdHkoKTsKICAgICAgICAgICAgICBsZXQgd29ybGRQb3MwID0gY29udGFjdFBvaW50LmdldF9tX3Bvc2l0aW9uV29ybGRPbkEoKTsKICAgICAgICAgICAgICBsZXQgd29ybGRQb3MxID0gY29udGFjdFBvaW50LmdldF9tX3Bvc2l0aW9uV29ybGRPbkIoKTsKICAgICAgICAgICAgICBsZXQgbG9jYWxQb3MwID0gY29udGFjdFBvaW50LmdldF9tX2xvY2FsUG9pbnRBKCk7CiAgICAgICAgICAgICAgbGV0IGxvY2FsUG9zMSA9IGNvbnRhY3RQb2ludC5nZXRfbV9sb2NhbFBvaW50QigpOwogICAgICAgICAgICAgIGNvbnRhY3RzLnB1c2goewogICAgICAgICAgICAgICAgZGlzdGFuY2UsCiAgICAgICAgICAgICAgICBlbGVtZW50czogW3sKICAgICAgICAgICAgICAgICAgdXVpZDogcmIwLnV1aWQsCiAgICAgICAgICAgICAgICAgIHZlbG9jaXR5OiB7CiAgICAgICAgICAgICAgICAgICAgeDogdmVsb2NpdHkwLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiB2ZWxvY2l0eTAueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IHZlbG9jaXR5MC56KCkKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgd29ybGRQb3M6IHsKICAgICAgICAgICAgICAgICAgICB4OiB3b3JsZFBvczAueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHdvcmxkUG9zMC55KCksCiAgICAgICAgICAgICAgICAgICAgejogd29ybGRQb3MwLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICBsb2NhbFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IGxvY2FsUG9zMC54KCksCiAgICAgICAgICAgICAgICAgICAgeTogbG9jYWxQb3MwLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiBsb2NhbFBvczAueigpCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgICAgdXVpZDogcmIxLnV1aWQsCiAgICAgICAgICAgICAgICAgIHZlbG9jaXR5OiB7CiAgICAgICAgICAgICAgICAgICAgeDogdmVsb2NpdHkxLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiB2ZWxvY2l0eTEueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IHZlbG9jaXR5MS56KCkKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgd29ybGRQb3M6IHsKICAgICAgICAgICAgICAgICAgICB4OiB3b3JsZFBvczEueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHdvcmxkUG9zMS55KCksCiAgICAgICAgICAgICAgICAgICAgejogd29ybGRQb3MxLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICBsb2NhbFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IGxvY2FsUG9zMS54KCksCiAgICAgICAgICAgICAgICAgICAgeTogbG9jYWxQb3MxLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiBsb2NhbFBvczEueigpCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH1dCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRGlzcGF0Y2hFdmVudChyYjAudXVpZCwgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5DT0xMSVNJT04sIHsKICAgICAgICAgICAgICBjb250YWN0cwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRGlzcGF0Y2hFdmVudChyYjEudXVpZCwgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5DT0xMSVNJT04sIHsKICAgICAgICAgICAgICBjb250YWN0cwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZEVsZW1lbnQiLCBkYXRhID0+IHsKICAgICAgICAgIHRoaXMuZWxlbWVudHNbZGF0YS51dWlkXSA9IGRhdGE7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJ1cGRhdGVCb2R5U3RhdGUiLCAoewogICAgICAgICAgdXVpZCwKICAgICAgICAgIHN0YXRlCiAgICAgICAgfSkgPT4gewogICAgICAgICAgaWYgKHRoaXMuaGFzRWxlbWVudCh1dWlkKSkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnRzW3V1aWRdLnN0YXRlID0gewogICAgICAgICAgICAgIC4uLnRoaXMuZWxlbWVudHNbdXVpZF0uc3RhdGUsCiAgICAgICAgICAgICAgLi4uc3RhdGUKICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInRlcm1pbmF0ZSIsICgpID0+IHsKICAgICAgICAgIEFtbW8uZGVzdHJveSh0aGlzLmR5bmFtaWNzV29ybGQpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuc29sdmVyKTsKICAgICAgICAgIEFtbW8uZGVzdHJveSh0aGlzLmRpc3BhdGNoZXIpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZUlkKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZFRlcm1pbmF0ZUV2ZW50KCk7CiAgICAgICAgfSk7CiAgICAgICAgdGhpcy5lbGVtZW50cyA9IHt9OwogICAgICAgIHRoaXMuaW5pdGlhbGlzZWQgPSBmYWxzZTsKICAgICAgICB0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24gPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuYnJvYWRwaGFzZSA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLnNvbHZlciA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQgPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWVJZCA9IG51bGw7CiAgICAgICAgdGhpcy5jbG9jayA9IG5ldyBDbG9jaygpOwogICAgICB9CiAgICAgIHJldHVybiBfY3JlYXRlQ2xhc3MoV29ybGQsIFt7CiAgICAgICAga2V5OiAiZGlzcG9zZUJvZHkiLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNwb3NlQm9keSh7CiAgICAgICAgICB1dWlkCiAgICAgICAgfSkgewogICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5yZW1vdmVSaWdpZEJvZHkoZWxlbWVudC5ib2R5KTsKICAgICAgICAgIHRoaXMucmVtb3ZlRWxlbWVudCh1dWlkKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZEVsZW1lbnREaXNwb3NlZCh7CiAgICAgICAgICAgIHV1aWQKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfV0pOwogICAgfSgpOwogICAgdmFyIHdvcmxkID0gbmV3IFdvcmxkKCk7CgogICAgY29uc3QgREVGQVVMVF9ST0xMX0lORkxVRU5DRSA9IDAuMjsKICAgIGNvbnN0IERFRkFVTFRfRlJJQ1RJT04gPSAxMDAwOwogICAgY29uc3QgREVGQVVMVF9NQVNTID0gODAwOwogICAgY29uc3QgYWRkVmVoaWNsZSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICB1dWlkLAogICAgICAgIHdoZWVscywKICAgICAgICBtYXNzID0gREVGQVVMVF9NQVNTLAogICAgICAgIHdpZHRoID0gMS44LAogICAgICAgIGhlaWdodCA9IDAuNiwKICAgICAgICBsZW5ndGggPSA0LAogICAgICAgIGZyaWN0aW9uID0gREVGQVVMVF9GUklDVElPTiwKICAgICAgICByb2xsSW5mbHVlbmNlID0gREVGQVVMVF9ST0xMX0lORkxVRU5DRSwKICAgICAgICB3aGVlbHNPcHRpb25zID0ge30sCiAgICAgICAgc3VzcGVuc2lvbnMgPSB7fQogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJhY2sgPSB7fSwKICAgICAgICBmcm9udCA9IHt9CiAgICAgIH0gPSB3aGVlbHNPcHRpb25zOwogICAgICBjb25zdCB7CiAgICAgICAgYXhpc1Bvc2l0aW9uOiBheGlzUG9zaXRpb25CYWNrID0gLTEsCiAgICAgICAgcmFkaXVzOiB3aGVlbFJhZGl1c0JhY2sgPSAwLjQsCiAgICAgICAgaGFsZlRyYWNrOiB3aGVlbEhhbGZUcmFja0JhY2sgPSAxLAogICAgICAgIGF4aXNIZWlnaHQ6IHdoZWVsQXhpc0hlaWdodEJhY2sgPSAwLjMKICAgICAgfSA9IGJhY2s7CiAgICAgIGNvbnN0IHsKICAgICAgICBheGlzUG9zaXRpb246IGF4aXNQb3NpdGlvbkZyb250ID0gMS43LAogICAgICAgIHJhZGl1czogd2hlZWxSYWRpdXNGcm9udCA9IDAuNCwKICAgICAgICBoYWxmVHJhY2s6IHdoZWVsSGFsZlRyYWNrRnJvbnQgPSAxLAogICAgICAgIGF4aXNIZWlnaHQ6IHdoZWVsQXhpc0hlaWdodEZyb250ID0gMC4zCiAgICAgIH0gPSBmcm9udDsKICAgICAgY29uc3QgewogICAgICAgIHN0aWZmbmVzcyA9IDIwLjAsCiAgICAgICAgZGFtcGluZyA9IDIuMywKICAgICAgICBjb21wcmVzc2lvbiA9IDQuNCwKICAgICAgICByZXN0TGVuZ3RoID0gMC42CiAgICAgIH0gPSBzdXNwZW5zaW9uczsKCiAgICAgIC8vIENoYXNzaXMKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idEJveFNoYXBlKG5ldyBBbW1vLmJ0VmVjdG9yMyh3aWR0aCAqIDAuNSwgaGVpZ2h0ICogMC41LCBsZW5ndGggKiAwLjUpKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBuZXcgQW1tby5idERlZmF1bHRNb3Rpb25TdGF0ZSh0cmFuc2Zvcm0pOwogICAgICBjb25zdCBsb2NhbEluZXJ0aWEgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIGdlb21ldHJ5LmNhbGN1bGF0ZUxvY2FsSW5lcnRpYShtYXNzLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCBjaGFzc2lzID0gbmV3IEFtbW8uYnRSaWdpZEJvZHkobmV3IEFtbW8uYnRSaWdpZEJvZHlDb25zdHJ1Y3Rpb25JbmZvKG1hc3MsIG1vdGlvblN0YXRlLCBnZW9tZXRyeSwgbG9jYWxJbmVydGlhKSk7CiAgICAgIGNoYXNzaXMuc2V0QWN0aXZhdGlvblN0YXRlKERJU0FCTEVfREVBQ1RJVkFUSU9OKTsKICAgICAgd29ybGQuYWRkUmlnaWRCb2R5KGNoYXNzaXMpOwoKICAgICAgLy8gUmF5Y2FzdCBWZWhpY2xlCiAgICAgIGNvbnN0IHR1bmluZyA9IG5ldyBBbW1vLmJ0VmVoaWNsZVR1bmluZygpOwogICAgICBjb25zdCByYXlDYXN0ZXIgPSBuZXcgQW1tby5idERlZmF1bHRWZWhpY2xlUmF5Y2FzdGVyKHdvcmxkLmdldER5bmFtaWNzV29ybGQoKSk7CiAgICAgIGNvbnN0IHZlaGljbGUgPSBuZXcgQW1tby5idFJheWNhc3RWZWhpY2xlKHR1bmluZywgY2hhc3NpcywgcmF5Q2FzdGVyKTsKICAgICAgdmVoaWNsZS5zZXRDb29yZGluYXRlU3lzdGVtKDAsIDEsIDIpOwogICAgICB3b3JsZC5hZGRBY3Rpb24odmVoaWNsZSk7CiAgICAgIGNvbnN0IHdoZWVsRGlyZWN0aW9uQ1MwID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIC0xLCAwKTsKICAgICAgY29uc3Qgd2hlZWxBeGxlQ1MgPSBuZXcgQW1tby5idFZlY3RvcjMoLTEsIDAsIDApOwogICAgICBjb25zdCBhZGRXaGVlbCA9IChpc0Zyb250LCBwb3MsIHJhZGl1cykgPT4gewogICAgICAgIHZhciB3aGVlbEluZm8gPSB2ZWhpY2xlLmFkZFdoZWVsKHBvcywgd2hlZWxEaXJlY3Rpb25DUzAsIHdoZWVsQXhsZUNTLCByZXN0TGVuZ3RoLCByYWRpdXMsIHR1bmluZywgaXNGcm9udCk7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3N1c3BlbnNpb25TdGlmZm5lc3Moc3RpZmZuZXNzKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fd2hlZWxzRGFtcGluZ1JlbGF4YXRpb24oZGFtcGluZyk7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3doZWVsc0RhbXBpbmdDb21wcmVzc2lvbihjb21wcmVzc2lvbik7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX2ZyaWN0aW9uU2xpcChmcmljdGlvbik7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3JvbGxJbmZsdWVuY2Uocm9sbEluZmx1ZW5jZSk7CiAgICAgIH07CiAgICAgIGFkZFdoZWVsKHRydWUsIG5ldyBBbW1vLmJ0VmVjdG9yMyh3aGVlbEhhbGZUcmFja0Zyb250LCB3aGVlbEF4aXNIZWlnaHRGcm9udCwgYXhpc1Bvc2l0aW9uRnJvbnQpLCB3aGVlbFJhZGl1c0Zyb250KTsKICAgICAgYWRkV2hlZWwodHJ1ZSwgbmV3IEFtbW8uYnRWZWN0b3IzKC13aGVlbEhhbGZUcmFja0Zyb250LCB3aGVlbEF4aXNIZWlnaHRGcm9udCwgYXhpc1Bvc2l0aW9uRnJvbnQpLCB3aGVlbFJhZGl1c0Zyb250KTsKICAgICAgYWRkV2hlZWwoZmFsc2UsIG5ldyBBbW1vLmJ0VmVjdG9yMygtd2hlZWxIYWxmVHJhY2tCYWNrLCB3aGVlbEF4aXNIZWlnaHRCYWNrLCBheGlzUG9zaXRpb25CYWNrKSwgd2hlZWxSYWRpdXNCYWNrKTsKICAgICAgYWRkV2hlZWwoZmFsc2UsIG5ldyBBbW1vLmJ0VmVjdG9yMyh3aGVlbEhhbGZUcmFja0JhY2ssIHdoZWVsQXhpc0hlaWdodEJhY2ssIGF4aXNQb3NpdGlvbkJhY2spLCB3aGVlbFJhZGl1c0JhY2spOwogICAgICB2ZWhpY2xlLnV1aWQgPSB1dWlkOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB0eXBlOiBUWVBFUy5WRUhJQ0xFLAogICAgICAgIHV1aWQsCiAgICAgICAgdmVoaWNsZTogdmVoaWNsZSwKICAgICAgICB3aGVlbHMsCiAgICAgICAgb3B0aW9uczogZGF0YSwKICAgICAgICBzdGF0ZTogREVGQVVMVF9WRUhJQ0xFX1NUQVRFCiAgICAgIH0pOwogICAgfTsKICAgIGNvbnN0IHNldFZlaGljbGVQb3NpdGlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFRZUEVTLlZFSElDTEUpIHsKICAgICAgICBjb25zdCBib2R5ID0gZWxlbWVudC52ZWhpY2xlLmdldFJpZ2lkQm9keSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBzZXRWZWhpY2xlUXVhdGVybmlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCByZXNldFZlaGljbGUgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFRZUEVTLlZFSElDTEUpIHsKICAgICAgICBjb25zdCBib2R5ID0gZWxlbWVudC52ZWhpY2xlLmdldFJpZ2lkQm9keSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIHRyYW5zZm9ybS5zZXRJZGVudGl0eSgpOwogICAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGhhbmRsZVZlaGljbGVVcGRhdGUgPSAoewogICAgICB2ZWhpY2xlLAogICAgICB3aGVlbHMsCiAgICAgIHV1aWQsCiAgICAgIHN0YXRlID0gREVGQVVMVF9WRUhJQ0xFX1NUQVRFLAogICAgICBvcHRpb25zID0ge30KICAgIH0sIGR0KSA9PiB7CiAgICAgIGxldCBicmVha2luZ0ZvcmNlID0gMDsKICAgICAgbGV0IGVuZ2luZUZvcmNlID0gMDsKICAgICAgY29uc3QgewogICAgICAgIHN0ZWVyaW5nQ2xhbXAgPSBERUZBVUxUX1NURUVSSU5HX0NMQU1QLAogICAgICAgIHN0ZWVyaW5nSW5jcmVtZW50ID0gREVGQVVMVF9TVEVFUklOR19JTkNSRU1FTlQsCiAgICAgICAgbWF4RW5naW5lRm9yY2UgPSBERUZBVUxUX01BWF9FTkdJTkVfRk9SQ0UsCiAgICAgICAgbWF4QnJlYWtpbmdGb3JjZSA9IERFRkFVTFRfTUFYX0JSRUFLSU5HX0ZPUkNFCiAgICAgIH0gPSBvcHRpb25zOwogICAgICBpZiAoc3RhdGUuYWNjZWxlcmF0aW9uKSB7CiAgICAgICAgaWYgKHNwZWVkIDwgLTEpIGJyZWFraW5nRm9yY2UgPSBtYXhCcmVha2luZ0ZvcmNlO2Vsc2UgZW5naW5lRm9yY2UgPSBtYXhFbmdpbmVGb3JjZTsKICAgICAgfQogICAgICBpZiAoc3RhdGUuYnJha2luZykgewogICAgICAgIGlmIChzcGVlZCA+IDEpIGJyZWFraW5nRm9yY2UgPSBtYXhCcmVha2luZ0ZvcmNlO2Vsc2UgZW5naW5lRm9yY2UgPSAtbWF4RW5naW5lRm9yY2UgLyAyOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS5sZWZ0KSB7CiAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA8IHN0ZWVyaW5nQ2xhbXApIHN0YXRlLnZlaGljbGVTdGVlcmluZyArPSBzdGVlcmluZ0luY3JlbWVudDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RhdGUucmlnaHQpIHsKICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPiAtc3RlZXJpbmdDbGFtcCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nIC09IHN0ZWVyaW5nSW5jcmVtZW50OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc3RhdGUudmVoaWNsZVN0ZWVyaW5nIDwgLXN0ZWVyaW5nSW5jcmVtZW50KSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgKz0gc3RlZXJpbmdJbmNyZW1lbnQ7ZWxzZSB7CiAgICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPiBzdGVlcmluZ0luY3JlbWVudCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nIC09IHN0ZWVyaW5nSW5jcmVtZW50O2Vsc2UgewogICAgICAgICAgICAgIHN0YXRlLnZlaGljbGVTdGVlcmluZyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgdmVoaWNsZS5hcHBseUVuZ2luZUZvcmNlKGVuZ2luZUZvcmNlLCBCQUNLX0xFRlQpOwogICAgICB2ZWhpY2xlLmFwcGx5RW5naW5lRm9yY2UoZW5naW5lRm9yY2UsIEJBQ0tfUklHSFQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UgLyAyLCBGUk9OVF9MRUZUKTsKICAgICAgdmVoaWNsZS5zZXRCcmFrZShicmVha2luZ0ZvcmNlIC8gMiwgRlJPTlRfUklHSFQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UsIEJBQ0tfTEVGVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSwgQkFDS19SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0U3RlZXJpbmdWYWx1ZShzdGF0ZS52ZWhpY2xlU3RlZXJpbmcsIEZST05UX0xFRlQpOwogICAgICB2ZWhpY2xlLnNldFN0ZWVyaW5nVmFsdWUoc3RhdGUudmVoaWNsZVN0ZWVyaW5nLCBGUk9OVF9SSUdIVCk7CiAgICAgIGxldCB0bSwgcCwgcSwgaTsKICAgICAgY29uc3QgbiA9IHZlaGljbGUuZ2V0TnVtV2hlZWxzKCk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB2ZWhpY2xlLnVwZGF0ZVdoZWVsVHJhbnNmb3JtKGksIHRydWUpOwogICAgICAgIHRtID0gdmVoaWNsZS5nZXRXaGVlbFRyYW5zZm9ybVdTKGkpOwogICAgICAgIHAgPSB0bS5nZXRPcmlnaW4oKTsKICAgICAgICBxID0gdG0uZ2V0Um90YXRpb24oKTsKICAgICAgICBjb25zdCB3aGVlbFVVSUQgPSB3aGVlbHNbaV07CiAgICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh3aGVlbFVVSUQsIHAsIHEsIGR0KTsKICAgICAgfQogICAgICB0bSA9IHZlaGljbGUuZ2V0Q2hhc3Npc1dvcmxkVHJhbnNmb3JtKCk7CiAgICAgIHAgPSB0bS5nZXRPcmlnaW4oKTsKICAgICAgcSA9IHRtLmdldFJvdGF0aW9uKCk7CiAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IHZlaGljbGUuZ2V0Rm9yd2FyZFZlY3RvcigpOwogICAgICBjb25zdCBzcGVlZCA9IHZlaGljbGUuZ2V0Q3VycmVudFNwZWVkS21Ib3VyKCk7CiAgICAgIGNvbnN0IGV4dHJhRGF0YSA9IHsKICAgICAgICBkaXJlY3Rpb246IHsKICAgICAgICAgIHg6IGRpcmVjdGlvbi54KCksCiAgICAgICAgICB5OiBkaXJlY3Rpb24ueSgpLAogICAgICAgICAgejogZGlyZWN0aW9uLnooKQogICAgICAgIH0sCiAgICAgICAgc3BlZWQKICAgICAgfTsKICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBwLCBxLCBkdCwgZXh0cmFEYXRhKTsKICAgICAgd29ybGQudXBkYXRlQm9keVN0YXRlKHV1aWQsIHN0YXRlKTsKICAgIH07CgogICAgY29uc3QgY3JlYXRlR2hvc3RDb2xsaWRlciA9IChyYWRpdXMsIHBvc2l0aW9uKSA9PiB7CiAgICAgIGNvbnN0IGdob3N0Q29sbGlkZXIgPSBuZXcgQW1tby5idEdob3N0T2JqZWN0KCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGdob3N0Q29sbGlkZXIuc2V0Q29sbGlzaW9uU2hhcGUobmV3IEFtbW8uYnRTcGhlcmVTaGFwZShyYWRpdXMpKTsKICAgICAgZ2hvc3RDb2xsaWRlci5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihwb3NpdGlvbik7CiAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24oMCwgMCwgMCwgMSkpOwogICAgICBnaG9zdENvbGxpZGVyLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHJldHVybiB7CiAgICAgICAgZ2hvc3RDb2xsaWRlciwKICAgICAgICB0cmFuc2Zvcm0KICAgICAgfTsKICAgIH07CiAgICBjb25zdCBmb3JFYWNoR2hvc3RDb2xsaXNpb24gPSAoZ2hvc3RDb2xsaWRlciwgZm9yRWFjaENhbGxiYWNrID0gKCkgPT4ge30pID0+IHsKICAgICAgY29uc3QgY29sbGlzaW9ucyA9IGdob3N0Q29sbGlkZXIuZ2V0TnVtT3ZlcmxhcHBpbmdPYmplY3RzKCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sbGlzaW9uczsgaSsrKSB7CiAgICAgICAgY29uc3Qgb2JqZWN0ID0gQW1tby5jYXN0T2JqZWN0KGdob3N0Q29sbGlkZXIuZ2V0T3ZlcmxhcHBpbmdPYmplY3QoaSksIEFtbW8uYnRSaWdpZEJvZHkpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgb2JqZWN0LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgZm9yRWFjaENhbGxiYWNrKG9iamVjdCwgdHJhbnNmb3JtLCBpKTsKICAgICAgICBBbW1vLmRlc3Ryb3kodHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGdldEV4cGxvc2lvblBvc2l0aW9uID0gKHV1aWQsIHBvc2l0aW9uKSA9PiB7CiAgICAgIGxldCBleHBsb3Npb25Qb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICBpZiAoIWV4cGxvc2lvblBvc2l0aW9uKSB7CiAgICAgICAgY29uc3QgewogICAgICAgICAgYm9keQogICAgICAgIH0gPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgbW90aW9uU3RhdGUuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICBleHBsb3Npb25Qb3NpdGlvbiA9IHRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgfQogICAgICByZXR1cm4gZXhwbG9zaW9uUG9zaXRpb247CiAgICB9OwogICAgY29uc3QgZ2V0RXhwbG9zaW9uSW1wdWxzZSA9IChwb3NpdGlvbiwgZXhwbG9zaW9uUG9zaXRpb24sIHN0cmVuZ3RoKSA9PiB7CiAgICAgIC8vIENhbGN1bGF0ZSBkaXJlY3Rpb24gdmVjdG9yIFdJVEhPVVQgbXV0YXRpbmcgdGhlIGlucHV0IGJ0VmVjdG9yMyBvYmplY3RzLgogICAgICAvLyBvcF9zdWIvb3BfbXVsIG11dGF0ZSBpbiBwbGFjZSBpbiBBbW1vLmpzLCB3aGljaCB3b3VsZCBjb3JydXB0IHRoZSBib2R5J3MgdHJhbnNmb3JtIG9yaWdpbi4KICAgICAgY29uc3QgZHggPSBwb3NpdGlvbi54KCkgLSBleHBsb3Npb25Qb3NpdGlvbi54KCk7CiAgICAgIGNvbnN0IGR5ID0gcG9zaXRpb24ueSgpIC0gZXhwbG9zaW9uUG9zaXRpb24ueSgpOwogICAgICBjb25zdCBkeiA9IHBvc2l0aW9uLnooKSAtIGV4cGxvc2lvblBvc2l0aW9uLnooKTsKICAgICAgbGV0IGxlbmd0aCA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSArIGR6ICogZHopOwoKICAgICAgLy8gSWYgdGhlIG9iamVjdCBpcyBhdCB0aGUgZXhwbG9zaW9uIGNlbnRlciwgcHVzaCBpdCBzdHJhaWdodCB1cCBpbnN0ZWFkIG9mCiAgICAgIC8vIHByb2R1Y2luZyBhbiB1bnN0YWJsZSBuZWFyLXplcm8gbm9ybWFsaXphdGlvbi4KICAgICAgaWYgKGxlbmd0aCA8IDAuMDAxKSB7CiAgICAgICAgY29uc3QgaW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCBzdHJlbmd0aCAqIDIsIDApOwogICAgICAgIHJldHVybiBpbXB1bHNlOwogICAgICB9CgogICAgICAvLyBOb3JtYWxpemUgZGlyZWN0aW9uCiAgICAgIGNvbnN0IG54ID0gZHggLyBsZW5ndGg7CiAgICAgIGNvbnN0IG55ID0gZHkgLyBsZW5ndGg7CiAgICAgIGNvbnN0IG56ID0gZHogLyBsZW5ndGg7CgogICAgICAvLyBTY2FsZSBieSBzdHJlbmd0aCBhbmQgYWRkIHVwd2FyZCBiaWFzCiAgICAgIGNvbnN0IGltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMobnggKiBzdHJlbmd0aCwgbnkgKiBzdHJlbmd0aCArIHN0cmVuZ3RoLCBueiAqIHN0cmVuZ3RoKTsKICAgICAgcmV0dXJuIGltcHVsc2U7CiAgICB9OwogICAgY29uc3QgY3JlYXRlRXhwbG9zaW9uID0gKHsKICAgICAgdXVpZCwKICAgICAgcG9zaXRpb24sCiAgICAgIHJhZGl1cyA9IEVYUExPU0lPTl9TSVpFUy5TTUFMTCwKICAgICAgc3RyZW5ndGggPSBFWFBMT1NJT05fU1RSRU5HVEhTLk1FRElVTQogICAgfSkgPT4gewogICAgICB0cnkgewogICAgICAgIC8vIEdldCB0aGUgc291cmNlIGJvZHkncyBBbW1vIHBvaW50ZXIgc28gd2UgY2FuIHJlbGlhYmx5IHNraXAgaXQuCiAgICAgICAgLy8gQW1tby5jYXN0T2JqZWN0KCkgY3JlYXRlcyBuZXcgSlMgd3JhcHBlcnMsIHNvIGN1c3RvbSBwcm9wZXJ0aWVzIGxpa2UKICAgICAgICAvLyAudXVpZCBzZXQgb24gdGhlIG9yaWdpbmFsIHdyYXBwZXIgYXJlIE5PVCBhdmFpbGFibGUgb24gY2FzdCByZXN1bHRzLgogICAgICAgIC8vIFdlIGNvbXBhcmUgdGhlIHVuZGVybHlpbmcgQysrIHBvaW50ZXIgaW5zdGVhZC4KICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICBjb25zdCBzb3VyY2VCb2R5UHRyID0gc291cmNlRWxlbWVudCAmJiBzb3VyY2VFbGVtZW50LmJvZHkgPyBzb3VyY2VFbGVtZW50LmJvZHkuYSB8fCBzb3VyY2VFbGVtZW50LmJvZHkucHRyIDogbnVsbDsKICAgICAgICBjb25zdCBleHBsb3Npb25Qb3NpdGlvbiA9IGdldEV4cGxvc2lvblBvc2l0aW9uKHV1aWQsIHBvc2l0aW9uKTsKICAgICAgICBjb25zdCB7CiAgICAgICAgICBnaG9zdENvbGxpZGVyLAogICAgICAgICAgdHJhbnNmb3JtCiAgICAgICAgfSA9IGNyZWF0ZUdob3N0Q29sbGlkZXIocmFkaXVzLCBleHBsb3Npb25Qb3NpdGlvbik7CiAgICAgICAgd29ybGQuYWRkQ29sbGlzaW9uT2JqZWN0KGdob3N0Q29sbGlkZXIpOwoKICAgICAgICAvLyBGb3JjZSBhIGNvbGxpc2lvbiBkZXRlY3Rpb24gcGFzcyBzbyB0aGUgZ2hvc3QgY29sbGlkZXIgZGlzY292ZXJzCiAgICAgICAgLy8gb3ZlcmxhcHBpbmcgYm9kaWVzLiBXaXRob3V0IHRoaXMsIGdldE51bU92ZXJsYXBwaW5nT2JqZWN0cygpIHJldHVybnMgMAogICAgICAgIC8vIGJlY2F1c2UgYnRHaG9zdFBhaXJDYWxsYmFjayBvbmx5IHVwZGF0ZXMgZHVyaW5nIGEgc2ltdWxhdGlvbiBzdGVwLgogICAgICAgIHdvcmxkLmdldER5bmFtaWNzV29ybGQoKS5wZXJmb3JtRGlzY3JldGVDb2xsaXNpb25EZXRlY3Rpb24oKTsKICAgICAgICBmb3JFYWNoR2hvc3RDb2xsaXNpb24oZ2hvc3RDb2xsaWRlciwgKG9iamVjdCwgb2JqZWN0VHJhbnNmb3JtKSA9PiB7CiAgICAgICAgICAvLyBTa2lwIHRoZSBzb3VyY2UgZW50aXR5IHVzaW5nIHBvaW50ZXIgY29tcGFyaXNvbi4KICAgICAgICAgIGNvbnN0IG9iamVjdFB0ciA9IG9iamVjdC5hIHx8IG9iamVjdC5wdHI7CiAgICAgICAgICBpZiAoc291cmNlQm9keVB0ciAmJiBvYmplY3RQdHIgPT09IHNvdXJjZUJvZHlQdHIpIHJldHVybjsKICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IG9iamVjdFRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgICAgIG9iamVjdC5hY3RpdmF0ZSh0cnVlKTsKICAgICAgICAgIGNvbnN0IGltcHVsc2UgPSBnZXRFeHBsb3Npb25JbXB1bHNlKG9yaWdpbiwgZXhwbG9zaW9uUG9zaXRpb24sIHN0cmVuZ3RoKTsKICAgICAgICAgIG9iamVjdC5hcHBseUNlbnRyYWxJbXB1bHNlKGltcHVsc2UpOwogICAgICAgICAgQW1tby5kZXN0cm95KGltcHVsc2UpOwogICAgICAgIH0pOwogICAgICAgIHdvcmxkLmdldER5bmFtaWNzV29ybGQoKS5yZW1vdmVDb2xsaXNpb25PYmplY3QoZ2hvc3RDb2xsaWRlcik7CiAgICAgICAgQW1tby5kZXN0cm95KGdob3N0Q29sbGlkZXIpOwogICAgICAgIEFtbW8uZGVzdHJveSh0cmFuc2Zvcm0pOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgY29uc29sZS5lcnJvcigiW1BoeXNpY3MgV29ya2VyXSBjcmVhdGVFeHBsb3Npb24gZXJyb3I6IiwgZSk7CiAgICAgIH0KICAgIH07CgogICAgY29uc3QgaGFuZGxlTG9hZEV2ZW50ID0gb3B0aW9ucyA9PiBBbW1vID0+IHsKICAgICAgc2VsZi5BbW1vID0gQW1tbzsKICAgICAgb25tZXNzYWdlID0gKHsKICAgICAgICBkYXRhCiAgICAgIH0pID0+IHsKICAgICAgICBzd2l0Y2ggKGRhdGEuZXZlbnQpIHsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELkJPWDoKICAgICAgICAgICAgYWRkQm94KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlNQSEVSRToKICAgICAgICAgICAgYWRkU3BoZXJlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlZFSElDTEU6CiAgICAgICAgICAgIGFkZFZlaGljbGUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuTU9ERUw6CiAgICAgICAgICAgIGFkZE1vZGVsKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlBMQVlFUjoKICAgICAgICAgICAgYWRkUGxheWVyKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuTElORUFSX1ZFTE9DSVRZOgogICAgICAgICAgICBzZXRMaW5lYXJWZWxvY2l0eShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuUkVTRVQ6CiAgICAgICAgICAgIHJlc2V0RWxlbWVudChkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuU0VULlBPU0lUSU9OOgogICAgICAgICAgICBzZXRQb3NpdGlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuU0VULlFVQVRFUk5JT046CiAgICAgICAgICAgIHNldFF1YXRlcm5pb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlNFVC5QT1NJVElPTjoKICAgICAgICAgICAgc2V0VmVoaWNsZVBvc2l0aW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuVkVISUNMRS5TRVQuUVVBVEVSTklPTjoKICAgICAgICAgICAgc2V0VmVoaWNsZVF1YXRlcm5pb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlJFU0VUOgogICAgICAgICAgICByZXNldFZlaGljbGUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkFQUExZLklNUFVMU0U6CiAgICAgICAgICAgIGFwcGx5SW1wdXNlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5VUERBVEU6CiAgICAgICAgICAgIHdvcmxkLnVwZGF0ZUJvZHlTdGF0ZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuRElTUE9TRToKICAgICAgICAgICAgd29ybGQuZGlzcG9zZUJvZHkoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FRkZFQ1RTLkVYUExPU0lPTjoKICAgICAgICAgICAgY3JlYXRlRXhwbG9zaW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuVEVSTUlOQVRFOgogICAgICAgICAgICB3b3JsZC50ZXJtaW5hdGUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9OwogICAgICB3b3JsZC5pbml0KG9wdGlvbnMpOwogICAgICBkaXNwYXRjaGVyLnNlbmRSZWFkeUV2ZW50KCk7CiAgICAgIHdvcmxkLnNpbXVsYXRlKCk7CiAgICB9OwogICAgY29uc3QgbG9hZEFtbW8gPSBvcHRpb25zID0+IHsKICAgICAgY29uc3Qgc2NyaXB0VXJsID0gb3B0aW9ucy5ob3N0ICsgIi8iICsgKG9wdGlvbnMucGF0aCB8fCBMSUJSQVJZX05BTUUpOwogICAgICBpbXBvcnRTY3JpcHRzKHNjcmlwdFVybCk7CiAgICAgIEFtbW8oKS50aGVuKGhhbmRsZUxvYWRFdmVudChvcHRpb25zKSk7CiAgICB9OwogICAgb25tZXNzYWdlID0gKHsKICAgICAgZGF0YQogICAgfSkgPT4gewogICAgICBzd2l0Y2ggKGRhdGEuZXZlbnQpIHsKICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkxPQUQuQU1NTzoKICAgICAgICAgIGxvYWRBbW1vKGRhdGEpOwogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH07Cgp9KSgpOwoK', null, false);
55724
55724
  /* eslint-enable */const PHYSICS_EVENTS = {
55725
55725
  DISPATCH: "physics:dispatch",
55726
55726
  TERMINATE: "physics:terminate",
@@ -55965,7 +55965,7 @@ const EXPLOSION_STRENGTHS = {
55965
55965
  MASSIVE: 32,
55966
55966
  OK_NO: 64
55967
55967
  };var PHYSICS_CONSTANTS=/*#__PURE__*/Object.freeze({__proto__:null,LIBRARY_NAME:LIBRARY_NAME,TYPES:TYPES,COLLIDER_TYPES:COLLIDER_TYPES$2,DEFAULT_VEHICLE_STATE:DEFAULT_VEHICLE_STATE,DEFAULT_RIGIDBODY_STATE:DEFAULT_RIGIDBODY_STATE,DEFAULT_SCALE:DEFAULT_SCALE$1,DEFAULT_QUATERNION:DEFAULT_QUATERNION,DEFAULT_POSITION:DEFAULT_POSITION$8,DEFAULT_LINEAR_VELOCITY:DEFAULT_LINEAR_VELOCITY,DEFAULT_ANGULAR_VELOCITY:DEFAULT_ANGULAR_VELOCITY,DEFAULT_IMPULSE:DEFAULT_IMPULSE,DISABLE_DEACTIVATION:DISABLE_DEACTIVATION,GRAVITY:GRAVITY,FRONT_LEFT:FRONT_LEFT,FRONT_RIGHT:FRONT_RIGHT,BACK_LEFT:BACK_LEFT,BACK_RIGHT:BACK_RIGHT,DEFAULT_STEERING_INCREMENT:DEFAULT_STEERING_INCREMENT,DEFAULT_STEERING_CLAMP:DEFAULT_STEERING_CLAMP,DEFAULT_MAX_ENGINE_FORCE:DEFAULT_MAX_ENGINE_FORCE,DEFAULT_MAX_BREAKING_FORCE:DEFAULT_MAX_BREAKING_FORCE,EXPLOSION_SIZES:EXPLOSION_SIZES,EXPLOSION_STRENGTHS:EXPLOSION_STRENGTHS});const DEFAULT_DESCRIPTION$1 = {
55968
- mass: 1,
55968
+ mass: 0,
55969
55969
  friction: 1,
55970
55970
  quaternion: DEFAULT_QUATERNION,
55971
55971
  position: DEFAULT_POSITION$8
@@ -59857,11 +59857,17 @@ let Controls = /*#__PURE__*/function (_EventDispatcher) {
59857
59857
  await Physics$1.init();
59858
59858
 
59859
59859
  // Entities loaded before physics was enabled had their
59860
- // enablePhysics() calls silently skipped. Now that the
59861
- // worker is ready, add every entity that has pending
59862
- // physics options to the world.
59860
+ // enablePhysics() calls silently skipped (or the worker
59861
+ // message was dropped because the worker wasn't ready yet).
59862
+ // Now that the worker is ready, re-add every entity that
59863
+ // has pending physics options. Clear stale entries first
59864
+ // so the hasElement check doesn't incorrectly skip
59865
+ // elements whose worker message was silently dropped.
59863
59866
  Universe$1.forEach(element => {
59864
- if (element._physicsEnabled && !Physics$1.hasElement(element)) {
59867
+ if (element._physicsEnabled) {
59868
+ if (Physics$1.hasElement(element)) {
59869
+ Physics$1.removeElement(element);
59870
+ }
59865
59871
  Physics$1.add(element, element.getPhysicsOptions());
59866
59872
  }
59867
59873
  });
@@ -61295,7 +61301,7 @@ function applyMiddleware() {
61295
61301
 
61296
61302
  var thunk = createThunkMiddleware();
61297
61303
  thunk.withExtraArgument = createThunkMiddleware;var name = "mage-engine";
61298
- var version$1 = "3.25.3";
61304
+ var version$1 = "3.25.5";
61299
61305
  var description = "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.";
61300
61306
  var main = "dist/mage.js";
61301
61307
  var author$1 = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mage-engine",
3
- "version": "3.25.3",
3
+ "version": "3.25.5",
4
4
  "description": "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.",
5
5
  "main": "dist/mage.js",
6
6
  "author": {