mage-engine 3.25.4 → 3.25.6

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.
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+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRElTUEFUQ0gsCiAgICAgICAgdXVpZCwKICAgICAgICBldmVudE5hbWUsCiAgICAgICAgZXZlbnREYXRhCiAgICAgIH0pKTsKICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzZW5kRWxlbWVudERpc3Bvc2VkIiwgKHsKICAgICAgICB1dWlkCiAgICAgIH0pID0+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5ESVNQT1NFLAogICAgICAgIHV1aWQKICAgICAgfSkpOwogICAgfSk7CiAgICB2YXIgZGlzcGF0Y2hlciA9IG5ldyBEaXNwYXRjaGVyKCk7CgogICAgY29uc3QgYXBwbHlNYXRyaXg0VG9WZWN0b3IzID0gKHsKICAgICAgeCA9IDAsCiAgICAgIHkgPSAwLAogICAgICB6ID0gMAogICAgfSwgbWF0cml4ID0gW10pID0+IHsKICAgICAgY29uc3QgdyA9IDEgLyAobWF0cml4WzNdICogeCArIG1hdHJpeFs3XSAqIHkgKyBtYXRyaXhbMTFdICogeiArIG1hdHJpeFsxNV0pOwogICAgICByZXR1cm4gewogICAgICAgIHg6IChtYXRyaXhbMF0gKiB4ICsgbWF0cml4WzRdICogeSArIG1hdHJpeFs4XSAqIHogKyBtYXRyaXhbMTJdKSAqIHcsCiAgICAgICAgeTogKG1hdHJpeFsxXSAqIHggKyBtYXRyaXhbNV0gKiB5ICsgbWF0cml4WzldICogeiArIG1hdHJpeFsxM10pICogdywKICAgICAgICB6OiAobWF0cml4WzJdICogeCArIG1hdHJpeFs2XSAqIHkgKyBtYXRyaXhbMTBdICogeiArIG1hdHJpeFsxNF0pICogdwogICAgICB9OwogICAgfTsKCiAgICBjb25zdCBjcmVhdGVSaWdpZEJvZHkgPSAoc2hhcGUsIG9wdGlvbnMpID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzID0gMCwKICAgICAgICBmcmljdGlvbiwKICAgICAgICByZXN0aXR1dGlvbiA9IDAuOSwKICAgICAgICBkYW1waW5nID0gewogICAgICAgICAgbGluZWFyOiAwLjIsCiAgICAgICAgICBhbmd1bGFyOiAwLjIKICAgICAgICB9CiAgICAgIH0gPSBvcHRpb25zOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IG5ldyBBbW1vLmJ0RGVmYXVsdE1vdGlvblN0YXRlKHRyYW5zZm9ybSk7CiAgICAgIGNvbnN0IGxvY2FsSW5lcnRpYSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgc2hhcGUuY2FsY3VsYXRlTG9jYWxJbmVydGlhKG1hc3MsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IHJiSW5mbyA9IG5ldyBBbW1vLmJ0UmlnaWRCb2R5Q29uc3RydWN0aW9uSW5mbyhtYXNzLCBtb3Rpb25TdGF0ZSwgc2hhcGUsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IGJvZHkgPSBuZXcgQW1tby5idFJpZ2lkQm9keShyYkluZm8pOwogICAgICBpZiAobWFzcyA+IDApIHsKICAgICAgICBib2R5LnNldEZyaWN0aW9uKGZyaWN0aW9uKTsKICAgICAgICBib2R5LnNldFJlc3RpdHV0aW9uKHJlc3RpdHV0aW9uKTsKICAgICAgICBib2R5LnNldERhbXBpbmcoZGFtcGluZy5saW5lYXIsIGRhbXBpbmcuYW5ndWxhcik7CiAgICAgICAgYm9keS5zZXRBY3RpdmF0aW9uU3RhdGUoRElTQUJMRV9ERUFDVElWQVRJT04pOwogICAgICB9CgogICAgICAvLyBzdG9yaW5nIHV1aWQgZm9yIGZ1dHVyZSByZWZlcmVuY2UKICAgICAgYm9keS51dWlkID0gdXVpZDsKICAgICAgd29ybGQuYWRkUmlnaWRCb2R5KGJvZHkpOwogICAgICByZXR1cm4gYm9keTsKICAgIH07CiAgICBjb25zdCBhZGRNb2RlbCA9IG9wdGlvbnMgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICB2ZXJ0aWNlcywKICAgICAgICBtYXRyaWNlcywKICAgICAgICBpbmRleGVzLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24gPSAyCiAgICAgIH0gPSBvcHRpb25zOwogICAgICBjb25zdCBzY2FsZSA9IERFRkFVTFRfU0NBTEU7CiAgICAgIGNvbnN0IGJ0YSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygpOwogICAgICBjb25zdCBidGIgPSBuZXcgQW1tby5idFZlY3RvcjMoKTsKICAgICAgY29uc3QgYnRjID0gbmV3IEFtbW8uYnRWZWN0b3IzKCk7CiAgICAgIGNvbnN0IHRyaU1lc2ggPSBuZXcgQW1tby5idFRyaWFuZ2xlTWVzaCh0cnVlLCBmYWxzZSk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmVydGljZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBjb25zdCBjb21wb25lbnRzID0gdmVydGljZXNbaV07CiAgICAgICAgY29uc3QgaW5kZXggPSBpbmRleGVzW2ldID8gaW5kZXhlc1tpXSA6IG51bGw7CiAgICAgICAgY29uc3QgbWF0cml4ID0gQXJyYXkuZnJvbShtYXRyaWNlc1tpXSk7CiAgICAgICAgaWYgKGluZGV4KSB7CiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGluZGV4Lmxlbmd0aDsgaiArPSAzKSB7CiAgICAgICAgICAgIGNvbnN0IGFpID0gaW5kZXhbal0gKiAzOwogICAgICAgICAgICBjb25zdCBiaSA9IGluZGV4W2ogKyAxXSAqIDM7CiAgICAgICAgICAgIGNvbnN0IGNpID0gaW5kZXhbaiArIDJdICogMzsKICAgICAgICAgICAgY29uc3QgdmEgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbYWldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbYWkgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2FpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmIgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbYmldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbYmkgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2JpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmMgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbY2ldLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbY2kgKyAxXSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2NpICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgYnRhLnNldFZhbHVlKHZhLngsIHZhLnksIHZhLnopOwogICAgICAgICAgICBidGIuc2V0VmFsdWUodmIueCwgdmIueSwgdmIueik7CiAgICAgICAgICAgIGJ0Yy5zZXRWYWx1ZSh2Yy54LCB2Yy55LCB2Yy56KTsKICAgICAgICAgICAgdHJpTWVzaC5hZGRUcmlhbmdsZShidGEsIGJ0YiwgYnRjLCBmYWxzZSk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29tcG9uZW50cy5sZW5ndGg7IGogKz0gOSkgewogICAgICAgICAgICBjb25zdCB2YSA9IGFwcGx5TWF0cml4NFRvVmVjdG9yMyh7CiAgICAgICAgICAgICAgeDogY29tcG9uZW50c1tqICsgMF0sCiAgICAgICAgICAgICAgeTogY29tcG9uZW50c1tqICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tqICsgMl0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgY29uc3QgdmIgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbaiArIDNdLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbaiArIDRdLAogICAgICAgICAgICAgIHo6IGNvbXBvbmVudHNbaiArIDVdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZjID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2ogKyA2XSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2ogKyA3XSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2ogKyA4XQogICAgICAgICAgICB9LCBtYXRyaXgpOwogICAgICAgICAgICBidGEuc2V0VmFsdWUodmEueCwgdmEueSwgdmEueik7CiAgICAgICAgICAgIGJ0Yi5zZXRWYWx1ZSh2Yi54LCB2Yi55LCB2Yi56KTsKICAgICAgICAgICAgYnRjLnNldFZhbHVlKHZjLngsIHZjLnksIHZjLnopOwogICAgICAgICAgICB0cmlNZXNoLmFkZFRyaWFuZ2xlKGJ0YSwgYnRiLCBidGMsIGZhbHNlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgY29uc3QgbG9jYWxTY2FsZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhzY2FsZS54LCBzY2FsZS55LCBzY2FsZS56KTsKICAgICAgdHJpTWVzaC5zZXRTY2FsaW5nKGxvY2FsU2NhbGUpOwogICAgICBBbW1vLmRlc3Ryb3kobG9jYWxTY2FsZSk7CiAgICAgIGNvbnN0IGNvbGxpc2lvblNoYXBlID0gbmV3IEFtbW8uYnRCdmhUcmlhbmdsZU1lc2hTaGFwZSh0cmlNZXNoLCB0cnVlLCB0cnVlKTsKICAgICAgY29sbGlzaW9uU2hhcGUucmVzb3VyY2VzID0gW3RyaU1lc2hdOwogICAgICBBbW1vLmRlc3Ryb3koYnRhKTsKICAgICAgQW1tby5kZXN0cm95KGJ0Yik7CiAgICAgIEFtbW8uZGVzdHJveShidGMpOwogICAgICBjb25zdCBib2R5ID0gY3JlYXRlUmlnaWRCb2R5KGNvbGxpc2lvblNoYXBlLCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MsCiAgICAgICAgZnJpY3Rpb24KICAgICAgfSk7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHV1aWQsCiAgICAgICAgYm9keSwKICAgICAgICB0eXBlOiBUWVBFUy5NRVNILAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBhZGRCb3ggPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgd2lkdGgsCiAgICAgICAgbGVuZ3RoLAogICAgICAgIGhlaWdodCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idEJveFNoYXBlKG5ldyBBbW1vLmJ0VmVjdG9yMyh3aWR0aCAqIDAuNSwgaGVpZ2h0ICogMC41LCBsZW5ndGggKiAwLjUpKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShnZW9tZXRyeSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuQk9YLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBhZGRTcGhlcmUgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcmFkaXVzLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24gPSAyCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBBbW1vLmJ0U3BoZXJlU2hhcGUocmFkaXVzKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShnZW9tZXRyeSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuU1BIRVJFLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgICB9KTsKICAgIH07CiAgICBjb25zdCBzZXRMaW5lYXJWZWxvY2l0eSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICB2ZWxvY2l0eSA9IERFRkFVTFRfTElORUFSX1ZFTE9DSVRZCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIGNvbnN0IGxpbmVhclZlbG9jaXR5ID0gbmV3IEFtbW8uYnRWZWN0b3IzKHZlbG9jaXR5LngsIHZlbG9jaXR5LnksIHZlbG9jaXR5LnopOwogICAgICAgIGJvZHkuc2V0TGluZWFyVmVsb2NpdHkobGluZWFyVmVsb2NpdHkpOwogICAgICAgIEFtbW8uZGVzdHJveShsaW5lYXJWZWxvY2l0eSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBzZXRQb3NpdGlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHJlc2V0RWxlbWVudCA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0T3JpZ2luKG5ldyBBbW1vLmJ0VmVjdG9yMyhwb3NpdGlvbi54LCBwb3NpdGlvbi55LCBwb3NpdGlvbi56KSk7CiAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24ocXVhdGVybmlvbi54LCBxdWF0ZXJuaW9uLnksIHF1YXRlcm5pb24ueiwgcXVhdGVybmlvbi53KSk7CiAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgLy8gQWxzbyB1cGRhdGUgbW90aW9uIHN0YXRlIHNvIHN0YXRpYyBib2RpZXMgKG1hc3M9MCkgcmVmbGVjdCB0aGUgY2hhbmdlCiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBtb3Rpb25TdGF0ZS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgYXBwbHlJbXB1c2UgPSAoewogICAgICB1dWlkLAogICAgICBpbXB1bHNlID0gREVGQVVMVF9JTVBVTFNFCiAgICB9KSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgaWYgKCFlbGVtZW50KSB7CiAgICAgICAgICBjb25zb2xlLndhcm4oIltQaHlzaWNzIFdvcmtlcl0gYXBwbHlJbXB1bHNlOiBlbGVtZW50IG5vdCBmb3VuZCBmb3IgdXVpZDoiLCB1dWlkKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgY29uc3QgewogICAgICAgICAgYm9keQogICAgICAgIH0gPSBlbGVtZW50OwogICAgICAgIGlmICghYm9keSkgewogICAgICAgICAgY29uc29sZS53YXJuKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZTogYm9keSBpcyBudWxsIGZvciB1dWlkOiIsIHV1aWQpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBib2R5LmFjdGl2YXRlKHRydWUpOwogICAgICAgIGNvbnN0IGJ0SW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhpbXB1bHNlLngsIGltcHVsc2UueSwgaW1wdWxzZS56KTsKICAgICAgICBib2R5LmFwcGx5Q2VudHJhbEltcHVsc2UoYnRJbXB1bHNlKTsKICAgICAgICBBbW1vLmRlc3Ryb3koYnRJbXB1bHNlKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIGNvbnNvbGUuZXJyb3IoIltQaHlzaWNzIFdvcmtlcl0gYXBwbHlJbXB1bHNlIGVycm9yOiIsIGUpOwogICAgICB9CiAgICB9OwogICAgY29uc3Qgc2V0UXVhdGVybmlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYm9keQogICAgICB9ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGhhbmRsZUVsZW1lbnRVcGRhdGUgPSAoewogICAgICBib2R5LAogICAgICB1dWlkLAogICAgICBzdGF0ZTogX3N0YXRlID0gREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgIH0sIGR0KSA9PiB7CiAgICAgIC8vIFN0YXRpYyBib2RpZXMgKG1hc3M9MCkgbmV2ZXIgbW92ZSDigJQgc2tpcCBzZW5kaW5nIHVwZGF0ZXMgc28gdGhlCiAgICAgIC8vIHZpc3VhbCBwb3NpdGlvbiBzdGF5cyBleGFjdGx5IHdoZXJlIHRoZSBhdXRob3IgcGxhY2VkIGl0LgogICAgICBpZiAoYm9keS5pc1N0YXRpY09iamVjdCgpKSByZXR1cm47CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICAgIG1vdGlvblN0YXRlLmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgbGV0IG9yaWdpbiA9IHRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgICBsZXQgcm90YXRpb24gPSB0cmFuc2Zvcm0uZ2V0Um90YXRpb24oKTsKICAgICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIG9yaWdpbiwgcm90YXRpb24sIGR0KTsKICAgICAgICBBbW1vLmRlc3Ryb3kodHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKCiAgICBjb25zdCBhZGRQbGF5ZXIgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgd2lkdGgsCiAgICAgICAgaGVpZ2h0LAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIG1hc3MsCiAgICAgICAgZnJpY3Rpb24sCiAgICAgICAgb3JpZ2luT2Zmc2V0ID0gewogICAgICAgICAgeDogMCwKICAgICAgICAgIHk6IDAsCiAgICAgICAgICB6OiAwCiAgICAgICAgfQogICAgICB9ID0gZGF0YTsKCiAgICAgIC8vIGJ0Q2Fwc3VsZVNoYXBlIGV4cGVjdHMgKHJhZGl1cywgY3lsaW5kZXJIZWlnaHQpIOKAlCB1c2UgaGFsZi13aWR0aCBhcwogICAgICAvLyByYWRpdXMgc28gdGhlIGNhcHN1bGUgd3JhcHMgdGhlIGJvdW5kaW5nIGJveCBjb3JyZWN0bHkuCiAgICAgIGNvbnN0IHJhZGl1cyA9IHdpZHRoICogMC41OwogICAgICBjb25zdCBjYXBzdWxlID0gbmV3IEFtbW8uYnRDYXBzdWxlU2hhcGUocmFkaXVzLCBoZWlnaHQpOwoKICAgICAgLy8gQWx3YXlzIGNyZWF0ZSB0aGUgcGxheWVyIGJvZHkgdXByaWdodCAoaWRlbnRpdHkgcXVhdGVybmlvbikuCiAgICAgIC8vIFRoZSB2aXN1YWwgcm90YXRpb24gaXMgZHJpdmVuIGJ5IHRoZSBjb250cm9sLCBub3QgYnkgcGh5c2ljcy4KICAgICAgY29uc3QgdXByaWdodFF1YXRlcm5pb24gPSB7CiAgICAgICAgeDogMCwKICAgICAgICB5OiAwLAogICAgICAgIHo6IDAsCiAgICAgICAgdzogMQogICAgICB9OwoKICAgICAgLy8gUG9zaXRpb24gdGhlIGNhcHN1bGUgYXQgdGhlIG1vZGVsJ3MgQUFCQiBjZW50cmUgc28gaXQgd3JhcHMgdGhlCiAgICAgIC8vIHZpc3VhbCBtZXNoIGNvcnJlY3RseS4gIG9yaWdpbk9mZnNldCBpcyB0aGUgdmVjdG9yIGZyb20gdGhlIG1vZGVsJ3MKICAgICAgLy8gb3JpZ2luIHRvIGl0cyBBQUJCIGNlbnRyZSDigJQgY29tcHV0ZWQgb24gdGhlIG1haW4gdGhyZWFkIHdoZXJlCiAgICAgIC8vIFRocmVlLmpzIGdlb21ldHJ5IGlzIGF2YWlsYWJsZS4KICAgICAgY29uc3QgY2Fwc3VsZVBvc2l0aW9uID0gewogICAgICAgIHg6IHBvc2l0aW9uLnggKyBvcmlnaW5PZmZzZXQueCwKICAgICAgICB5OiBwb3NpdGlvbi55ICsgb3JpZ2luT2Zmc2V0LnksCiAgICAgICAgejogcG9zaXRpb24ueiArIG9yaWdpbk9mZnNldC56CiAgICAgIH07CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoY2Fwc3VsZSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb246IGNhcHN1bGVQb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uOiB1cHJpZ2h0UXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uLAogICAgICAgIHJlc3RpdHV0aW9uOiAwLAogICAgICAgIGRhbXBpbmc6IHsKICAgICAgICAgIGxpbmVhcjogMC4xLAogICAgICAgICAgYW5ndWxhcjogMQogICAgICAgIH0KICAgICAgfSk7CgogICAgICAvLyBEaXNhYmxlIHJvdGF0aW9uIG9uIGFsbCBheGVzIOKAlCB0aGUgdmlzdWFsIHJvdGF0aW9uIGlzIGRyaXZlbiBieSB0aGUgY29udHJvbC4KICAgICAgLy8gVXNlIGJ0VmVjdG9yMyBpbnN0ZWFkIG9mIHNjYWxhciBmb3IgY29tcGF0aWJpbGl0eSBhY3Jvc3MgQW1tby5qcyBidWlsZHMuCiAgICAgIGNvbnN0IHplcm9Bbmd1bGFyID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIDAsIDApOwogICAgICBib2R5LnNldEFuZ3VsYXJGYWN0b3IoemVyb0FuZ3VsYXIpOwogICAgICBBbW1vLmRlc3Ryb3koemVyb0FuZ3VsYXIpOwoKICAgICAgLy8gRW5hYmxlIGNvbnRpbnVvdXMgY29sbGlzaW9uIGRldGVjdGlvbiB0byBwcmV2ZW50IHR1bm5lbGluZyBhdCBoaWdoIHNwZWVkcy4KICAgICAgYm9keS5zZXRDY2RNb3Rpb25UaHJlc2hvbGQocmFkaXVzICogMC41KTsKICAgICAgYm9keS5zZXRDY2RTd2VwdFNwaGVyZVJhZGl1cyhyYWRpdXMgKiAwLjgpOwoKICAgICAgLy8gU3RvcmUgZm9yIHVzZSBpbiBoYW5kbGVQbGF5ZXJVcGRhdGUg4oCUIG9mZnNldCBpcyBzdWJ0cmFjdGVkIHdoZW4KICAgICAgLy8gc2VuZGluZyBwb3NpdGlvbiBiYWNrIHNvIHRoZSB2aXN1YWwgc3RheXMgYXQgdGhlIG1vZGVsIG9yaWdpbi4KICAgICAgYm9keS5fbWFzcyA9IG1hc3M7CiAgICAgIGJvZHkuX29yaWdpbk9mZnNldCA9IG9yaWdpbk9mZnNldDsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLlBMQVlFUiwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgaGFuZGxlUGxheWVyVXBkYXRlID0gKHsKICAgICAgYm9keSwKICAgICAgdXVpZCwKICAgICAgc3RhdGUgPSBERUZBVUxUX1JJR0lEQk9EWV9TVEFURQogICAgfSwgZHQpID0+IHsKICAgICAgY29uc3QgewogICAgICAgIG1vdmVtZW50LAogICAgICAgIGNhbWVyYURpcmVjdGlvbiwKICAgICAgICBqdW1wLAogICAgICAgIGp1bXBTcGVlZCwKICAgICAgICBzcGVlZDogbW92ZVNwZWVkCiAgICAgIH0gPSBzdGF0ZTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmICghbW90aW9uU3RhdGUpIHJldHVybjsKCiAgICAgIC8vIEZvcmNlLWNsZWFyIGFuZ3VsYXIgdmVsb2NpdHkgZXZlcnkgdGljay4gVGhlIHBsYXllciBjYXBzdWxlIG11c3Qgc3RheQogICAgICAvLyB1cHJpZ2h0IOKAlCByb3RhdGlvbiBpcyBoYW5kbGVkIHZpc3VhbGx5IGJ5IHRoZSBjb250cm9sLCBub3QgYnkgcGh5c2ljcy4KICAgICAgY29uc3QgemVyb0FuZ1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgYm9keS5zZXRBbmd1bGFyVmVsb2NpdHkoemVyb0FuZ1ZlbCk7CiAgICAgIEFtbW8uZGVzdHJveSh6ZXJvQW5nVmVsKTsKCiAgICAgIC8vIEZvcmNlIHRoZSBwaHlzaWNzIGJvZHkgcm90YXRpb24gdG8gaWRlbnRpdHkgKHVwcmlnaHQpIGV2ZXJ5IHRpY2suCiAgICAgIC8vIENvbnRhY3QgZm9yY2VzIGNhbiBzdGlsbCByb3RhdGUgdGhlIGNhcHN1bGUgaW4gc29tZSBBbW1vLmpzIGJ1aWxkcwogICAgICAvLyBldmVuIHdpdGggYW5ndWxhckZhY3Rvcj0oMCwwLDApLiBXZSBtdXN0IHJlc2V0IEJPVEggdGhlIGJvZHkgd29ybGQKICAgICAgLy8gdHJhbnNmb3JtIEFORCB0aGUgbW90aW9uU3RhdGUg4oCUIHRoZXkgY2FuIGRpdmVyZ2UuCiAgICAgIGNvbnN0IHdvcmxkVHJhbnNmb3JtID0gYm9keS5nZXRXb3JsZFRyYW5zZm9ybSgpOwogICAgICBjb25zdCB1cHJpZ2h0UXVhdCA9IG5ldyBBbW1vLmJ0UXVhdGVybmlvbigwLCAwLCAwLCAxKTsKICAgICAgd29ybGRUcmFuc2Zvcm0uc2V0Um90YXRpb24odXByaWdodFF1YXQpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHdvcmxkVHJhbnNmb3JtKTsKICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0od29ybGRUcmFuc2Zvcm0pOwogICAgICBBbW1vLmRlc3Ryb3kodXByaWdodFF1YXQpOwogICAgICBjb25zdCBjaGFyYWN0ZXJTcGVlZCA9IG1vdmVTcGVlZCB8fCA1OwoKICAgICAgLy8gSnVtcCDigJQgYXBwbHkgYSBvbmUtdGltZSBpbXB1bHNlLCB0aGVuIGNsZWFyIHRoZSBmbGFnIHNvIGl0IGRvZXNuJ3QgcmVwZWF0CiAgICAgIGlmIChqdW1wICYmIGp1bXBTcGVlZCkgewogICAgICAgIGNvbnN0IG1hc3MgPSBib2R5Ll9tYXNzIHx8IDgwOwogICAgICAgIGNvbnN0IGltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwganVtcFNwZWVkICogbWFzcywgMCk7CiAgICAgICAgYm9keS5hcHBseUNlbnRyYWxJbXB1bHNlKGltcHVsc2UpOwogICAgICAgIEFtbW8uZGVzdHJveShpbXB1bHNlKTsKICAgICAgICBzdGF0ZS5qdW1wID0gZmFsc2U7CiAgICAgIH0KICAgICAgY29uc3QgaXNNb3ZpbmcgPSBtb3ZlbWVudCAmJiAobW92ZW1lbnQuZm9yd2FyZCB8fCBtb3ZlbWVudC5iYWNrd2FyZHMgfHwgbW92ZW1lbnQubGVmdCB8fCBtb3ZlbWVudC5yaWdodCk7CiAgICAgIGNvbnN0IGxpbmVhclZlbG9jaXR5ID0gYm9keS5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICBjb25zdCBjdXJyZW50WSA9IGxpbmVhclZlbG9jaXR5LnkoKTsKICAgICAgaWYgKGlzTW92aW5nICYmIGNhbWVyYURpcmVjdGlvbikgewogICAgICAgIC8vIENvbXB1dGUgY2FtZXJhLXJlbGF0aXZlIG1vdmVtZW50IGRpcmVjdGlvbgogICAgICAgIGxldCBtb3ZlWCA9IDA7CiAgICAgICAgbGV0IG1vdmVaID0gMDsKICAgICAgICBpZiAobW92ZW1lbnQuZm9yd2FyZCkgewogICAgICAgICAgbW92ZVggKz0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgICBtb3ZlWiArPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICB9CiAgICAgICAgaWYgKG1vdmVtZW50LmJhY2t3YXJkcykgewogICAgICAgICAgbW92ZVggLT0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgICBtb3ZlWiAtPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICB9CiAgICAgICAgaWYgKG1vdmVtZW50LmxlZnQpIHsKICAgICAgICAgIG1vdmVYICs9IGNhbWVyYURpcmVjdGlvbi56OwogICAgICAgICAgbW92ZVogLT0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5yaWdodCkgewogICAgICAgICAgbW92ZVggLT0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgICBtb3ZlWiArPSBjYW1lcmFEaXJlY3Rpb24ueDsKICAgICAgICB9CgogICAgICAgIC8vIE5vcm1hbGl6ZSBkaXJlY3Rpb24KICAgICAgICBjb25zdCBsZW4gPSBNYXRoLnNxcnQobW92ZVggKiBtb3ZlWCArIG1vdmVaICogbW92ZVopOwogICAgICAgIGlmIChsZW4gPiAwKSB7CiAgICAgICAgICBtb3ZlWCAvPSBsZW47CiAgICAgICAgICBtb3ZlWiAvPSBsZW47CiAgICAgICAgfQoKICAgICAgICAvLyBTZXQgaG9yaXpvbnRhbCB2ZWxvY2l0eSBkaXJlY3RseSBmb3IgcmVzcG9uc2l2ZSBtb3ZlbWVudAogICAgICAgIGNvbnN0IG5ld1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhtb3ZlWCAqIGNoYXJhY3RlclNwZWVkLCBjdXJyZW50WSwgbW92ZVogKiBjaGFyYWN0ZXJTcGVlZCk7CiAgICAgICAgYm9keS5zZXRMaW5lYXJWZWxvY2l0eShuZXdWZWwpOwogICAgICAgIEFtbW8uZGVzdHJveShuZXdWZWwpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIFdoZW4gaWRsZSwgb25seSBkYW1wZW4gaWYgdGhlcmUncyBtZWFuaW5nZnVsIGhvcml6b250YWwgdmVsb2NpdHkuCiAgICAgICAgLy8gQXZvaWQgdG91Y2hpbmcgdGhlIHZlbG9jaXR5IGV2ZXJ5IGZyYW1lIHRvIGxldCB0aGUgc29sdmVyCiAgICAgICAgLy8gaGFuZGxlIGZsb29yIGNvbnRhY3Qgd2l0aG91dCBpbnRlcmZlcmVuY2UuCiAgICAgICAgY29uc3QgdnggPSBsaW5lYXJWZWxvY2l0eS54KCk7CiAgICAgICAgY29uc3QgdnogPSBsaW5lYXJWZWxvY2l0eS56KCk7CiAgICAgICAgaWYgKE1hdGguYWJzKHZ4KSA+IDAuMDEgfHwgTWF0aC5hYnModnopID4gMC4wMSkgewogICAgICAgICAgY29uc3QgbmV3VmVsID0gbmV3IEFtbW8uYnRWZWN0b3IzKHZ4ICogMC44NSwgY3VycmVudFksIHZ6ICogMC44NSk7CiAgICAgICAgICBib2R5LnNldExpbmVhclZlbG9jaXR5KG5ld1ZlbCk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kobmV3VmVsKTsKICAgICAgICB9CiAgICAgICAgLy8gT3RoZXJ3aXNlIGxldCBwaHlzaWNzIGhhbmRsZSBldmVyeXRoaW5nIOKAlCBkb24ndCBvdmVycmlkZSB2ZWxvY2l0eQogICAgICB9CgogICAgICAvLyBSZWFkIGZyb20gdGhlIGJvZHkncyB3b3JsZCB0cmFuc2Zvcm0gKG5vdCBtb3Rpb25TdGF0ZSkgYmVjYXVzZSB3ZQogICAgICAvLyBtYWludGFpbiBpdCBkaXJlY3RseSBhYm92ZSDigJQgcG9zaXRpb24gY29tZXMgZnJvbSBwaHlzaWNzLCByb3RhdGlvbgogICAgICAvLyBpcyBhbHdheXMgaWRlbnRpdHkuCiAgICAgIGNvbnN0IGZpbmFsVHJhbnNmb3JtID0gYm9keS5nZXRXb3JsZFRyYW5zZm9ybSgpOwogICAgICBjb25zdCBvcmlnaW4gPSBmaW5hbFRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgY29uc3Qgcm90YXRpb24gPSBmaW5hbFRyYW5zZm9ybS5nZXRSb3RhdGlvbigpOwogICAgICBjb25zdCBncm91bmRlZCA9IE1hdGguYWJzKGN1cnJlbnRZKSA8IDAuNTsKCiAgICAgIC8vIFRoZSBwaHlzaWNzIGNhcHN1bGUgaXMgb2Zmc2V0IHVwd2FyZCBzbyBpdHMgYm90dG9tIGFsaWducyB3aXRoIHRoZQogICAgICAvLyBjaGFyYWN0ZXIncyBmZWV0LiAgU3VidHJhY3QgdGhlIG9mZnNldCBiZWZvcmUgc2VuZGluZyB0aGUgcG9zaXRpb24KICAgICAgLy8gYmFjayBzbyB0aGUgdmlzdWFsIHN0YXlzIGF0IHRoZSBmZWV0LCBub3QgdGhlIGNhcHN1bGUgY2VudHJlLgogICAgICAvLyBTdWJ0cmFjdCB0aGUgb3JpZ2luIG9mZnNldCBzbyB0aGUgcG9zaXRpb24gbWFwcyBiYWNrIHRvIG1vZGVsLW9yaWdpbgogICAgICAvLyBzcGFjZSAodGhlIHZpc3VhbCdzIHRyYW5zZm9ybSBvcmlnaW4pLCBub3QgdGhlIEFBQkIgY2VudHJlLgogICAgICBjb25zdCBvZmYgPSBib2R5Ll9vcmlnaW5PZmZzZXQgfHwgewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwCiAgICAgIH07CiAgICAgIGNvbnN0IGFkanVzdGVkT3JpZ2luID0gbmV3IEFtbW8uYnRWZWN0b3IzKG9yaWdpbi54KCkgLSBvZmYueCwgb3JpZ2luLnkoKSAtIG9mZi55LCBvcmlnaW4ueigpIC0gb2ZmLnopOwogICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIGFkanVzdGVkT3JpZ2luLCByb3RhdGlvbiwgZHQsIHsKICAgICAgICBncm91bmRlZAogICAgICB9KTsKICAgICAgQW1tby5kZXN0cm95KGFkanVzdGVkT3JpZ2luKTsKICAgIH07CgogICAgY29uc3QgcmVxdWVzdE5leHRGcmFtZSA9IHNlbGYucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IHNlbGYub1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgX2VsZW1lbnQpIHsKICAgICAgc2VsZi5zZXRUaW1lb3V0KGNhbGxiYWNrLCAxMDAwIC8gMTIwKTsKICAgIH07CiAgICBsZXQgQ2xvY2sgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkgewogICAgICBmdW5jdGlvbiBDbG9jaygpIHsKICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2xvY2spOwogICAgICAgIHRoaXMudGltZXN0YW1wID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gX2NyZWF0ZUNsYXNzKENsb2NrLCBbewogICAgICAgIGtleTogImdldERlbHRhIiwKICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RGVsdGEoKSB7CiAgICAgICAgICBjb25zdCB0aW1lID0gRGF0ZS5ub3coKTsKICAgICAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCkgewogICAgICAgICAgICBjb25zdCBkZWx0YSA9IHRpbWUgLSB0aGlzLnRpbWVzdGFtcDsKICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lOwogICAgICAgICAgICByZXR1cm4gZGVsdGE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWU7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfV0pOwogICAgfSgpOwogICAgbGV0IFdvcmxkID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHsKICAgICAgZnVuY3Rpb24gV29ybGQoKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFdvcmxkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImluaXQiLCBvcHRpb25zID0+IHsKICAgICAgICAgIGNvbnN0IHsKICAgICAgICAgICAgZ3Jhdml0eSA9IEdSQVZJVFkKICAgICAgICAgIH0gPSBvcHRpb25zOwogICAgICAgICAgdGhpcy5jb2xsaXNpb25Db25maWd1cmF0aW9uID0gbmV3IEFtbW8uYnREZWZhdWx0Q29sbGlzaW9uQ29uZmlndXJhdGlvbigpOwogICAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gbmV3IEFtbW8uYnRDb2xsaXNpb25EaXNwYXRjaGVyKHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICB0aGlzLmJyb2FkcGhhc2UgPSBuZXcgQW1tby5idERidnRCcm9hZHBoYXNlKCk7CiAgICAgICAgICB0aGlzLnNvbHZlciA9IG5ldyBBbW1vLmJ0U2VxdWVudGlhbEltcHVsc2VDb25zdHJhaW50U29sdmVyKCk7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQgPSBuZXcgQW1tby5idERpc2NyZXRlRHluYW1pY3NXb3JsZCh0aGlzLmRpc3BhdGNoZXIsIHRoaXMuYnJvYWRwaGFzZSwgdGhpcy5zb2x2ZXIsIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuc2V0R3Jhdml0eShuZXcgQW1tby5idFZlY3RvcjMoZ3Jhdml0eS54LCBncmF2aXR5LnksIGdyYXZpdHkueikpOwoKICAgICAgICAgIC8vIHRoaXMgaXMgbmVlZGVkIGZvciBnaG9zdE9iamVjdCBjb2xsaXNpb25zCiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuZ2V0QnJvYWRwaGFzZSgpLmdldE92ZXJsYXBwaW5nUGFpckNhY2hlKCkuc2V0SW50ZXJuYWxHaG9zdFBhaXJDYWxsYmFjayhuZXcgQW1tby5idEdob3N0UGFpckNhbGxiYWNrKCkpOwogICAgICAgICAgdGhpcy5pbml0aWFsaXNlZCA9IHRydWU7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJyZW1vdmVFbGVtZW50IiwgdXVpZCA9PiB7CiAgICAgICAgICBpZiAodGhpcy5oYXNFbGVtZW50KHV1aWQpKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudHNbdXVpZF0uZGVsZXRlZCA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJyZW1vdmVEZWxldGVkRWxlbWVudHMiLCAoKSA9PiBPYmplY3Qua2V5cyh0aGlzLmVsZW1lbnRzKS5maWx0ZXIodXVpZCA9PiB0aGlzLmVsZW1lbnRzW3V1aWRdLmRlbGV0ZWQpLmZvckVhY2godXVpZCA9PiB7CiAgICAgICAgICBkZWxldGUgdGhpcy5lbGVtZW50c1t1dWlkXTsKICAgICAgICB9KSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJoYXNFbGVtZW50IiwgdXVpZCA9PiB7CiAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuaW5jbHVkZXModXVpZCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJnZXRFbGVtZW50IiwgdXVpZCA9PiB0aGlzLmVsZW1lbnRzW3V1aWRdKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImlzSW5pdGlhbGlzZWQiLCAoKSA9PiB0aGlzLmluaXRpYWxpc2VkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImdldER5bmFtaWNzV29ybGQiLCAoKSA9PiB0aGlzLmR5bmFtaWNzV29ybGQpOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkUmlnaWRCb2R5IiwgYm9keSA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkUmlnaWRCb2R5KGJvZHkpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkQWN0aW9uIiwgYWN0aW9uID0+IHsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5hZGRBY3Rpb24oYWN0aW9uKTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZENvbGxpc2lvbk9iamVjdCIsIGNvbGxpc2lvbk9iamVjdCA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkQ29sbGlzaW9uT2JqZWN0KGNvbGxpc2lvbk9iamVjdCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzdGVwU2ltdWxhdGlvbiIsIGR0ID0+IHsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5zdGVwU2ltdWxhdGlvbihkdCk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJzaW11bGF0ZSIsICgpID0+IHsKICAgICAgICAgIGNvbnN0IGR0ID0gdGhpcy5jbG9jay5nZXREZWx0YSgpIC8gMTAwMDsKICAgICAgICAgIHRoaXMuc3RlcFNpbXVsYXRpb24oZHQpOwogICAgICAgICAgT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuZm9yRWFjaCh1dWlkID0+IHsKICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICAgICAgaWYgKGVsZW1lbnQpIHsKICAgICAgICAgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5CT1g6CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVTLlNQSEVSRToKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuTUVTSDoKICAgICAgICAgICAgICAgICAgaGFuZGxlRWxlbWVudFVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5QTEFZRVI6CiAgICAgICAgICAgICAgICAgIGhhbmRsZVBsYXllclVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5WRUhJQ0xFOgogICAgICAgICAgICAgICAgICBoYW5kbGVWZWhpY2xlVXBkYXRlKGVsZW1lbnQsIGR0KTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQ29sbGlzaW9ucygpOwogICAgICAgICAgdGhpcy5yZW1vdmVEZWxldGVkRWxlbWVudHMoKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZFBoeXNpY3NVcGRhdGUoZHQpOwogICAgICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWVJZCA9IHJlcXVlc3ROZXh0RnJhbWUodGhpcy5zaW11bGF0ZS5iaW5kKHRoaXMpKTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImNhbGN1bGF0ZUNvbGxpc2lvbnMiLCAoKSA9PiB7CiAgICAgICAgICBsZXQgYW1tb0Rpc3BhdGNoZXIgPSB0aGlzLmR5bmFtaWNzV29ybGQuZ2V0RGlzcGF0Y2hlcigpOwogICAgICAgICAgbGV0IG51bU1hbmlmb2xkcyA9IGFtbW9EaXNwYXRjaGVyLmdldE51bU1hbmlmb2xkcygpOwogICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1NYW5pZm9sZHM7IGkrKykgewogICAgICAgICAgICBsZXQgY29udGFjdE1hbmlmb2xkID0gYW1tb0Rpc3BhdGNoZXIuZ2V0TWFuaWZvbGRCeUluZGV4SW50ZXJuYWwoaSk7CiAgICAgICAgICAgIGxldCByYjAgPSBBbW1vLmNhc3RPYmplY3QoY29udGFjdE1hbmlmb2xkLmdldEJvZHkwKCksIEFtbW8uYnRSaWdpZEJvZHkpOwogICAgICAgICAgICBsZXQgcmIxID0gQW1tby5jYXN0T2JqZWN0KGNvbnRhY3RNYW5pZm9sZC5nZXRCb2R5MSgpLCBBbW1vLmJ0UmlnaWRCb2R5KTsKICAgICAgICAgICAgbGV0IG51bUNvbnRhY3RzID0gY29udGFjdE1hbmlmb2xkLmdldE51bUNvbnRhY3RzKCk7CgogICAgICAgICAgICAvLyB0aGlzIGl0ZXJhdGlvbiBkb2Vzbid0IGhhdmUgdXVpZHMKICAgICAgICAgICAgaWYgKCFyYjAudXVpZCB8fCAhcmIxLnV1aWQpIGNvbnRpbnVlOwogICAgICAgICAgICBsZXQgY29udGFjdHMgPSBbXTsKICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBudW1Db250YWN0czsgaisrKSB7CiAgICAgICAgICAgICAgbGV0IGNvbnRhY3RQb2ludCA9IGNvbnRhY3RNYW5pZm9sZC5nZXRDb250YWN0UG9pbnQoaik7CiAgICAgICAgICAgICAgbGV0IGRpc3RhbmNlID0gY29udGFjdFBvaW50LmdldERpc3RhbmNlKCk7CiAgICAgICAgICAgICAgaWYgKGRpc3RhbmNlID4gMC4wKSBjb250aW51ZTsKICAgICAgICAgICAgICBsZXQgdmVsb2NpdHkwID0gcmIwLmdldExpbmVhclZlbG9jaXR5KCk7CiAgICAgICAgICAgICAgbGV0IHZlbG9jaXR5MSA9IHJiMS5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICAgICAgICAgIGxldCB3b3JsZFBvczAgPSBjb250YWN0UG9pbnQuZ2V0X21fcG9zaXRpb25Xb3JsZE9uQSgpOwogICAgICAgICAgICAgIGxldCB3b3JsZFBvczEgPSBjb250YWN0UG9pbnQuZ2V0X21fcG9zaXRpb25Xb3JsZE9uQigpOwogICAgICAgICAgICAgIGxldCBsb2NhbFBvczAgPSBjb250YWN0UG9pbnQuZ2V0X21fbG9jYWxQb2ludEEoKTsKICAgICAgICAgICAgICBsZXQgbG9jYWxQb3MxID0gY29udGFjdFBvaW50LmdldF9tX2xvY2FsUG9pbnRCKCk7CiAgICAgICAgICAgICAgY29udGFjdHMucHVzaCh7CiAgICAgICAgICAgICAgICBkaXN0YW5jZSwKICAgICAgICAgICAgICAgIGVsZW1lbnRzOiBbewogICAgICAgICAgICAgICAgICB1dWlkOiByYjAudXVpZCwKICAgICAgICAgICAgICAgICAgdmVsb2NpdHk6IHsKICAgICAgICAgICAgICAgICAgICB4OiB2ZWxvY2l0eTAueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHZlbG9jaXR5MC55KCksCiAgICAgICAgICAgICAgICAgICAgejogdmVsb2NpdHkwLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICB3b3JsZFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IHdvcmxkUG9zMC54KCksCiAgICAgICAgICAgICAgICAgICAgeTogd29ybGRQb3MwLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiB3b3JsZFBvczAueigpCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGxvY2FsUG9zOiB7CiAgICAgICAgICAgICAgICAgICAgeDogbG9jYWxQb3MwLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiBsb2NhbFBvczAueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IGxvY2FsUG9zMC56KCkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgICB1dWlkOiByYjEudXVpZCwKICAgICAgICAgICAgICAgICAgdmVsb2NpdHk6IHsKICAgICAgICAgICAgICAgICAgICB4OiB2ZWxvY2l0eTEueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHZlbG9jaXR5MS55KCksCiAgICAgICAgICAgICAgICAgICAgejogdmVsb2NpdHkxLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICB3b3JsZFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IHdvcmxkUG9zMS54KCksCiAgICAgICAgICAgICAgICAgICAgeTogd29ybGRQb3MxLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiB3b3JsZFBvczEueigpCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGxvY2FsUG9zOiB7CiAgICAgICAgICAgICAgICAgICAgeDogbG9jYWxQb3MxLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiBsb2NhbFBvczEueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IGxvY2FsUG9zMS56KCkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfV0KICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkaXNwYXRjaGVyLnNlbmREaXNwYXRjaEV2ZW50KHJiMC51dWlkLCBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkNPTExJU0lPTiwgewogICAgICAgICAgICAgIGNvbnRhY3RzCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBkaXNwYXRjaGVyLnNlbmREaXNwYXRjaEV2ZW50KHJiMS51dWlkLCBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkNPTExJU0lPTiwgewogICAgICAgICAgICAgIGNvbnRhY3RzCiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiYWRkRWxlbWVudCIsIGRhdGEgPT4gewogICAgICAgICAgdGhpcy5lbGVtZW50c1tkYXRhLnV1aWRdID0gZGF0YTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInVwZGF0ZUJvZHlTdGF0ZSIsICh7CiAgICAgICAgICB1dWlkLAogICAgICAgICAgc3RhdGUKICAgICAgICB9KSA9PiB7CiAgICAgICAgICBpZiAodGhpcy5oYXNFbGVtZW50KHV1aWQpKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudHNbdXVpZF0uc3RhdGUgPSB7CiAgICAgICAgICAgICAgLi4udGhpcy5lbGVtZW50c1t1dWlkXS5zdGF0ZSwKICAgICAgICAgICAgICAuLi5zdGF0ZQogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAidGVybWluYXRlIiwgKCkgPT4gewogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuZHluYW1pY3NXb3JsZCk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kodGhpcy5zb2x2ZXIpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuZGlzcGF0Y2hlcik7CiAgICAgICAgICBBbW1vLmRlc3Ryb3kodGhpcy5jb2xsaXNpb25Db25maWd1cmF0aW9uKTsKICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lSWQpOwogICAgICAgICAgZGlzcGF0Y2hlci5zZW5kVGVybWluYXRlRXZlbnQoKTsKICAgICAgICB9KTsKICAgICAgICB0aGlzLmVsZW1lbnRzID0ge307CiAgICAgICAgdGhpcy5pbml0aWFsaXNlZCA9IGZhbHNlOwogICAgICAgIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbiA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLmRpc3BhdGNoZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5icm9hZHBoYXNlID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuc29sdmVyID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZCA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZUlkID0gbnVsbDsKICAgICAgICB0aGlzLmNsb2NrID0gbmV3IENsb2NrKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIF9jcmVhdGVDbGFzcyhXb3JsZCwgW3sKICAgICAgICBrZXk6ICJkaXNwb3NlQm9keSIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc3Bvc2VCb2R5KHsKICAgICAgICAgIHV1aWQKICAgICAgICB9KSB7CiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLnJlbW92ZVJpZ2lkQm9keShlbGVtZW50LmJvZHkpOwogICAgICAgICAgdGhpcy5yZW1vdmVFbGVtZW50KHV1aWQpOwogICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRWxlbWVudERpc3Bvc2VkKHsKICAgICAgICAgICAgdXVpZAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9XSk7CiAgICB9KCk7CiAgICB2YXIgd29ybGQgPSBuZXcgV29ybGQoKTsKCiAgICBjb25zdCBERUZBVUxUX1JPTExfSU5GTFVFTkNFID0gMC4yOwogICAgY29uc3QgREVGQVVMVF9GUklDVElPTiA9IDEwMDA7CiAgICBjb25zdCBERUZBVUxUX01BU1MgPSA4MDA7CiAgICBjb25zdCBhZGRWZWhpY2xlID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIHV1aWQsCiAgICAgICAgd2hlZWxzLAogICAgICAgIG1hc3MgPSBERUZBVUxUX01BU1MsCiAgICAgICAgd2lkdGggPSAxLjgsCiAgICAgICAgaGVpZ2h0ID0gMC42LAogICAgICAgIGxlbmd0aCA9IDQsCiAgICAgICAgZnJpY3Rpb24gPSBERUZBVUxUX0ZSSUNUSU9OLAogICAgICAgIHJvbGxJbmZsdWVuY2UgPSBERUZBVUxUX1JPTExfSU5GTFVFTkNFLAogICAgICAgIHdoZWVsc09wdGlvbnMgPSB7fSwKICAgICAgICBzdXNwZW5zaW9ucyA9IHt9CiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCB7CiAgICAgICAgYmFjayA9IHt9LAogICAgICAgIGZyb250ID0ge30KICAgICAgfSA9IHdoZWVsc09wdGlvbnM7CiAgICAgIGNvbnN0IHsKICAgICAgICBheGlzUG9zaXRpb246IGF4aXNQb3NpdGlvbkJhY2sgPSAtMSwKICAgICAgICByYWRpdXM6IHdoZWVsUmFkaXVzQmFjayA9IDAuNCwKICAgICAgICBoYWxmVHJhY2s6IHdoZWVsSGFsZlRyYWNrQmFjayA9IDEsCiAgICAgICAgYXhpc0hlaWdodDogd2hlZWxBeGlzSGVpZ2h0QmFjayA9IDAuMwogICAgICB9ID0gYmFjazsKICAgICAgY29uc3QgewogICAgICAgIGF4aXNQb3NpdGlvbjogYXhpc1Bvc2l0aW9uRnJvbnQgPSAxLjcsCiAgICAgICAgcmFkaXVzOiB3aGVlbFJhZGl1c0Zyb250ID0gMC40LAogICAgICAgIGhhbGZUcmFjazogd2hlZWxIYWxmVHJhY2tGcm9udCA9IDEsCiAgICAgICAgYXhpc0hlaWdodDogd2hlZWxBeGlzSGVpZ2h0RnJvbnQgPSAwLjMKICAgICAgfSA9IGZyb250OwogICAgICBjb25zdCB7CiAgICAgICAgc3RpZmZuZXNzID0gMjAuMCwKICAgICAgICBkYW1waW5nID0gMi4zLAogICAgICAgIGNvbXByZXNzaW9uID0gNC40LAogICAgICAgIHJlc3RMZW5ndGggPSAwLjYKICAgICAgfSA9IHN1c3BlbnNpb25zOwoKICAgICAgLy8gQ2hhc3NpcwogICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBBbW1vLmJ0Qm94U2hhcGUobmV3IEFtbW8uYnRWZWN0b3IzKHdpZHRoICogMC41LCBoZWlnaHQgKiAwLjUsIGxlbmd0aCAqIDAuNSkpOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IG5ldyBBbW1vLmJ0RGVmYXVsdE1vdGlvblN0YXRlKHRyYW5zZm9ybSk7CiAgICAgIGNvbnN0IGxvY2FsSW5lcnRpYSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgZ2VvbWV0cnkuY2FsY3VsYXRlTG9jYWxJbmVydGlhKG1hc3MsIGxvY2FsSW5lcnRpYSk7CiAgICAgIGNvbnN0IGNoYXNzaXMgPSBuZXcgQW1tby5idFJpZ2lkQm9keShuZXcgQW1tby5idFJpZ2lkQm9keUNvbnN0cnVjdGlvbkluZm8obWFzcywgbW90aW9uU3RhdGUsIGdlb21ldHJ5LCBsb2NhbEluZXJ0aWEpKTsKICAgICAgY2hhc3Npcy5zZXRBY3RpdmF0aW9uU3RhdGUoRElTQUJMRV9ERUFDVElWQVRJT04pOwogICAgICB3b3JsZC5hZGRSaWdpZEJvZHkoY2hhc3Npcyk7CgogICAgICAvLyBSYXljYXN0IFZlaGljbGUKICAgICAgY29uc3QgdHVuaW5nID0gbmV3IEFtbW8uYnRWZWhpY2xlVHVuaW5nKCk7CiAgICAgIGNvbnN0IHJheUNhc3RlciA9IG5ldyBBbW1vLmJ0RGVmYXVsdFZlaGljbGVSYXljYXN0ZXIod29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpKTsKICAgICAgY29uc3QgdmVoaWNsZSA9IG5ldyBBbW1vLmJ0UmF5Y2FzdFZlaGljbGUodHVuaW5nLCBjaGFzc2lzLCByYXlDYXN0ZXIpOwogICAgICB2ZWhpY2xlLnNldENvb3JkaW5hdGVTeXN0ZW0oMCwgMSwgMik7CiAgICAgIHdvcmxkLmFkZEFjdGlvbih2ZWhpY2xlKTsKICAgICAgY29uc3Qgd2hlZWxEaXJlY3Rpb25DUzAgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgLTEsIDApOwogICAgICBjb25zdCB3aGVlbEF4bGVDUyA9IG5ldyBBbW1vLmJ0VmVjdG9yMygtMSwgMCwgMCk7CiAgICAgIGNvbnN0IGFkZFdoZWVsID0gKGlzRnJvbnQsIHBvcywgcmFkaXVzKSA9PiB7CiAgICAgICAgdmFyIHdoZWVsSW5mbyA9IHZlaGljbGUuYWRkV2hlZWwocG9zLCB3aGVlbERpcmVjdGlvbkNTMCwgd2hlZWxBeGxlQ1MsIHJlc3RMZW5ndGgsIHJhZGl1cywgdHVuaW5nLCBpc0Zyb250KTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fc3VzcGVuc2lvblN0aWZmbmVzcyhzdGlmZm5lc3MpOwogICAgICAgIHdoZWVsSW5mby5zZXRfbV93aGVlbHNEYW1waW5nUmVsYXhhdGlvbihkYW1waW5nKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fd2hlZWxzRGFtcGluZ0NvbXByZXNzaW9uKGNvbXByZXNzaW9uKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fZnJpY3Rpb25TbGlwKGZyaWN0aW9uKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fcm9sbEluZmx1ZW5jZShyb2xsSW5mbHVlbmNlKTsKICAgICAgfTsKICAgICAgYWRkV2hlZWwodHJ1ZSwgbmV3IEFtbW8uYnRWZWN0b3IzKHdoZWVsSGFsZlRyYWNrRnJvbnQsIHdoZWVsQXhpc0hlaWdodEZyb250LCBheGlzUG9zaXRpb25Gcm9udCksIHdoZWVsUmFkaXVzRnJvbnQpOwogICAgICBhZGRXaGVlbCh0cnVlLCBuZXcgQW1tby5idFZlY3RvcjMoLXdoZWVsSGFsZlRyYWNrRnJvbnQsIHdoZWVsQXhpc0hlaWdodEZyb250LCBheGlzUG9zaXRpb25Gcm9udCksIHdoZWVsUmFkaXVzRnJvbnQpOwogICAgICBhZGRXaGVlbChmYWxzZSwgbmV3IEFtbW8uYnRWZWN0b3IzKC13aGVlbEhhbGZUcmFja0JhY2ssIHdoZWVsQXhpc0hlaWdodEJhY2ssIGF4aXNQb3NpdGlvbkJhY2spLCB3aGVlbFJhZGl1c0JhY2spOwogICAgICBhZGRXaGVlbChmYWxzZSwgbmV3IEFtbW8uYnRWZWN0b3IzKHdoZWVsSGFsZlRyYWNrQmFjaywgd2hlZWxBeGlzSGVpZ2h0QmFjaywgYXhpc1Bvc2l0aW9uQmFjayksIHdoZWVsUmFkaXVzQmFjayk7CiAgICAgIHZlaGljbGUudXVpZCA9IHV1aWQ7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHR5cGU6IFRZUEVTLlZFSElDTEUsCiAgICAgICAgdXVpZCwKICAgICAgICB2ZWhpY2xlOiB2ZWhpY2xlLAogICAgICAgIHdoZWVscywKICAgICAgICBvcHRpb25zOiBkYXRhLAogICAgICAgIHN0YXRlOiBERUZBVUxUX1ZFSElDTEVfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3Qgc2V0VmVoaWNsZVBvc2l0aW9uID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHNldFZlaGljbGVRdWF0ZXJuaW9uID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHF1YXRlcm5pb24KICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IGVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICBpZiAoZWxlbWVudC50eXBlID09PSBUWVBFUy5WRUhJQ0xFKSB7CiAgICAgICAgY29uc3QgYm9keSA9IGVsZW1lbnQudmVoaWNsZS5nZXRSaWdpZEJvZHkoKTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHJlc2V0VmVoaWNsZSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIHBvc2l0aW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24ocXVhdGVybmlvbi54LCBxdWF0ZXJuaW9uLnksIHF1YXRlcm5pb24ueiwgcXVhdGVybmlvbi53KSk7CiAgICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgaGFuZGxlVmVoaWNsZVVwZGF0ZSA9ICh7CiAgICAgIHZlaGljbGUsCiAgICAgIHdoZWVscywKICAgICAgdXVpZCwKICAgICAgc3RhdGUgPSBERUZBVUxUX1ZFSElDTEVfU1RBVEUsCiAgICAgIG9wdGlvbnMgPSB7fQogICAgfSwgZHQpID0+IHsKICAgICAgbGV0IGJyZWFraW5nRm9yY2UgPSAwOwogICAgICBsZXQgZW5naW5lRm9yY2UgPSAwOwogICAgICBjb25zdCB7CiAgICAgICAgc3RlZXJpbmdDbGFtcCA9IERFRkFVTFRfU1RFRVJJTkdfQ0xBTVAsCiAgICAgICAgc3RlZXJpbmdJbmNyZW1lbnQgPSBERUZBVUxUX1NURUVSSU5HX0lOQ1JFTUVOVCwKICAgICAgICBtYXhFbmdpbmVGb3JjZSA9IERFRkFVTFRfTUFYX0VOR0lORV9GT1JDRSwKICAgICAgICBtYXhCcmVha2luZ0ZvcmNlID0gREVGQVVMVF9NQVhfQlJFQUtJTkdfRk9SQ0UKICAgICAgfSA9IG9wdGlvbnM7CiAgICAgIGlmIChzdGF0ZS5hY2NlbGVyYXRpb24pIHsKICAgICAgICBpZiAoc3BlZWQgPCAtMSkgYnJlYWtpbmdGb3JjZSA9IG1heEJyZWFraW5nRm9yY2U7ZWxzZSBlbmdpbmVGb3JjZSA9IG1heEVuZ2luZUZvcmNlOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS5icmFraW5nKSB7CiAgICAgICAgaWYgKHNwZWVkID4gMSkgYnJlYWtpbmdGb3JjZSA9IG1heEJyZWFraW5nRm9yY2U7ZWxzZSBlbmdpbmVGb3JjZSA9IC1tYXhFbmdpbmVGb3JjZSAvIDI7CiAgICAgIH0KICAgICAgaWYgKHN0YXRlLmxlZnQpIHsKICAgICAgICBpZiAoc3RhdGUudmVoaWNsZVN0ZWVyaW5nIDwgc3RlZXJpbmdDbGFtcCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nICs9IHN0ZWVyaW5nSW5jcmVtZW50OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdGF0ZS5yaWdodCkgewogICAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA+IC1zdGVlcmluZ0NsYW1wKSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgLT0gc3RlZXJpbmdJbmNyZW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPCAtc3RlZXJpbmdJbmNyZW1lbnQpIHN0YXRlLnZlaGljbGVTdGVlcmluZyArPSBzdGVlcmluZ0luY3JlbWVudDtlbHNlIHsKICAgICAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA+IHN0ZWVyaW5nSW5jcmVtZW50KSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgLT0gc3RlZXJpbmdJbmNyZW1lbnQ7ZWxzZSB7CiAgICAgICAgICAgICAgc3RhdGUudmVoaWNsZVN0ZWVyaW5nID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICB2ZWhpY2xlLmFwcGx5RW5naW5lRm9yY2UoZW5naW5lRm9yY2UsIEJBQ0tfTEVGVCk7CiAgICAgIHZlaGljbGUuYXBwbHlFbmdpbmVGb3JjZShlbmdpbmVGb3JjZSwgQkFDS19SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSAvIDIsIEZST05UX0xFRlQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UgLyAyLCBGUk9OVF9SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSwgQkFDS19MRUZUKTsKICAgICAgdmVoaWNsZS5zZXRCcmFrZShicmVha2luZ0ZvcmNlLCBCQUNLX1JJR0hUKTsKICAgICAgdmVoaWNsZS5zZXRTdGVlcmluZ1ZhbHVlKHN0YXRlLnZlaGljbGVTdGVlcmluZywgRlJPTlRfTEVGVCk7CiAgICAgIHZlaGljbGUuc2V0U3RlZXJpbmdWYWx1ZShzdGF0ZS52ZWhpY2xlU3RlZXJpbmcsIEZST05UX1JJR0hUKTsKICAgICAgbGV0IHRtLCBwLCBxLCBpOwogICAgICBjb25zdCBuID0gdmVoaWNsZS5nZXROdW1XaGVlbHMoKTsKICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHZlaGljbGUudXBkYXRlV2hlZWxUcmFuc2Zvcm0oaSwgdHJ1ZSk7CiAgICAgICAgdG0gPSB2ZWhpY2xlLmdldFdoZWVsVHJhbnNmb3JtV1MoaSk7CiAgICAgICAgcCA9IHRtLmdldE9yaWdpbigpOwogICAgICAgIHEgPSB0bS5nZXRSb3RhdGlvbigpOwogICAgICAgIGNvbnN0IHdoZWVsVVVJRCA9IHdoZWVsc1tpXTsKICAgICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHdoZWVsVVVJRCwgcCwgcSwgZHQpOwogICAgICB9CiAgICAgIHRtID0gdmVoaWNsZS5nZXRDaGFzc2lzV29ybGRUcmFuc2Zvcm0oKTsKICAgICAgcCA9IHRtLmdldE9yaWdpbigpOwogICAgICBxID0gdG0uZ2V0Um90YXRpb24oKTsKICAgICAgY29uc3QgZGlyZWN0aW9uID0gdmVoaWNsZS5nZXRGb3J3YXJkVmVjdG9yKCk7CiAgICAgIGNvbnN0IHNwZWVkID0gdmVoaWNsZS5nZXRDdXJyZW50U3BlZWRLbUhvdXIoKTsKICAgICAgY29uc3QgZXh0cmFEYXRhID0gewogICAgICAgIGRpcmVjdGlvbjogewogICAgICAgICAgeDogZGlyZWN0aW9uLngoKSwKICAgICAgICAgIHk6IGRpcmVjdGlvbi55KCksCiAgICAgICAgICB6OiBkaXJlY3Rpb24ueigpCiAgICAgICAgfSwKICAgICAgICBzcGVlZAogICAgICB9OwogICAgICBkaXNwYXRjaGVyLnNlbmRCb2R5VXBkYXRlKHV1aWQsIHAsIHEsIGR0LCBleHRyYURhdGEpOwogICAgICB3b3JsZC51cGRhdGVCb2R5U3RhdGUodXVpZCwgc3RhdGUpOwogICAgfTsKCiAgICBjb25zdCBjcmVhdGVHaG9zdENvbGxpZGVyID0gKHJhZGl1cywgcG9zaXRpb24pID0+IHsKICAgICAgY29uc3QgZ2hvc3RDb2xsaWRlciA9IG5ldyBBbW1vLmJ0R2hvc3RPYmplY3QoKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgZ2hvc3RDb2xsaWRlci5zZXRDb2xsaXNpb25TaGFwZShuZXcgQW1tby5idFNwaGVyZVNoYXBlKHJhZGl1cykpOwogICAgICBnaG9zdENvbGxpZGVyLmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHRyYW5zZm9ybS5zZXRJZGVudGl0eSgpOwogICAgICB0cmFuc2Zvcm0uc2V0T3JpZ2luKHBvc2l0aW9uKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbigwLCAwLCAwLCAxKSk7CiAgICAgIGdob3N0Q29sbGlkZXIuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgcmV0dXJuIHsKICAgICAgICBnaG9zdENvbGxpZGVyLAogICAgICAgIHRyYW5zZm9ybQogICAgICB9OwogICAgfTsKICAgIGNvbnN0IGZvckVhY2hHaG9zdENvbGxpc2lvbiA9IChnaG9zdENvbGxpZGVyLCBmb3JFYWNoQ2FsbGJhY2sgPSAoKSA9PiB7fSkgPT4gewogICAgICBjb25zdCBjb2xsaXNpb25zID0gZ2hvc3RDb2xsaWRlci5nZXROdW1PdmVybGFwcGluZ09iamVjdHMoKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2xsaXNpb25zOyBpKyspIHsKICAgICAgICBjb25zdCBvYmplY3QgPSBBbW1vLmNhc3RPYmplY3QoZ2hvc3RDb2xsaWRlci5nZXRPdmVybGFwcGluZ09iamVjdChpKSwgQW1tby5idFJpZ2lkQm9keSk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBvYmplY3QuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICBmb3JFYWNoQ2FsbGJhY2sob2JqZWN0LCB0cmFuc2Zvcm0sIGkpOwogICAgICAgIEFtbW8uZGVzdHJveSh0cmFuc2Zvcm0pOwogICAgICB9CiAgICB9OwogICAgY29uc3QgZ2V0RXhwbG9zaW9uUG9zaXRpb24gPSAodXVpZCwgcG9zaXRpb24pID0+IHsKICAgICAgbGV0IGV4cGxvc2lvblBvc2l0aW9uID0gcG9zaXRpb247CiAgICAgIGlmICghZXhwbG9zaW9uUG9zaXRpb24pIHsKICAgICAgICBjb25zdCB7CiAgICAgICAgICBib2R5CiAgICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBtb3Rpb25TdGF0ZS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIGV4cGxvc2lvblBvc2l0aW9uID0gdHJhbnNmb3JtLmdldE9yaWdpbigpOwogICAgICB9CiAgICAgIHJldHVybiBleHBsb3Npb25Qb3NpdGlvbjsKICAgIH07CiAgICBjb25zdCBnZXRFeHBsb3Npb25JbXB1bHNlID0gKHBvc2l0aW9uLCBleHBsb3Npb25Qb3NpdGlvbiwgc3RyZW5ndGgpID0+IHsKICAgICAgLy8gQ2FsY3VsYXRlIGRpcmVjdGlvbiB2ZWN0b3IgV0lUSE9VVCBtdXRhdGluZyB0aGUgaW5wdXQgYnRWZWN0b3IzIG9iamVjdHMuCiAgICAgIC8vIG9wX3N1Yi9vcF9tdWwgbXV0YXRlIGluIHBsYWNlIGluIEFtbW8uanMsIHdoaWNoIHdvdWxkIGNvcnJ1cHQgdGhlIGJvZHkncyB0cmFuc2Zvcm0gb3JpZ2luLgogICAgICBjb25zdCBkeCA9IHBvc2l0aW9uLngoKSAtIGV4cGxvc2lvblBvc2l0aW9uLngoKTsKICAgICAgY29uc3QgZHkgPSBwb3NpdGlvbi55KCkgLSBleHBsb3Npb25Qb3NpdGlvbi55KCk7CiAgICAgIGNvbnN0IGR6ID0gcG9zaXRpb24ueigpIC0gZXhwbG9zaW9uUG9zaXRpb24ueigpOwogICAgICBsZXQgbGVuZ3RoID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5ICsgZHogKiBkeik7CgogICAgICAvLyBJZiB0aGUgb2JqZWN0IGlzIGF0IHRoZSBleHBsb3Npb24gY2VudGVyLCBwdXNoIGl0IHN0cmFpZ2h0IHVwIGluc3RlYWQgb2YKICAgICAgLy8gcHJvZHVjaW5nIGFuIHVuc3RhYmxlIG5lYXItemVybyBub3JtYWxpemF0aW9uLgogICAgICBpZiAobGVuZ3RoIDwgMC4wMDEpIHsKICAgICAgICBjb25zdCBpbXB1bHNlID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIHN0cmVuZ3RoICogMiwgMCk7CiAgICAgICAgcmV0dXJuIGltcHVsc2U7CiAgICAgIH0KCiAgICAgIC8vIE5vcm1hbGl6ZSBkaXJlY3Rpb24KICAgICAgY29uc3QgbnggPSBkeCAvIGxlbmd0aDsKICAgICAgY29uc3QgbnkgPSBkeSAvIGxlbmd0aDsKICAgICAgY29uc3QgbnogPSBkeiAvIGxlbmd0aDsKCiAgICAgIC8vIFNjYWxlIGJ5IHN0cmVuZ3RoIGFuZCBhZGQgdXB3YXJkIGJpYXMKICAgICAgY29uc3QgaW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhueCAqIHN0cmVuZ3RoLCBueSAqIHN0cmVuZ3RoICsgc3RyZW5ndGgsIG56ICogc3RyZW5ndGgpOwogICAgICByZXR1cm4gaW1wdWxzZTsKICAgIH07CiAgICBjb25zdCBjcmVhdGVFeHBsb3Npb24gPSAoewogICAgICB1dWlkLAogICAgICBwb3NpdGlvbiwKICAgICAgcmFkaXVzID0gRVhQTE9TSU9OX1NJWkVTLlNNQUxMLAogICAgICBzdHJlbmd0aCA9IEVYUExPU0lPTl9TVFJFTkdUSFMuTUVESVVNCiAgICB9KSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgLy8gR2V0IHRoZSBzb3VyY2UgYm9keSdzIEFtbW8gcG9pbnRlciBzbyB3ZSBjYW4gcmVsaWFibHkgc2tpcCBpdC4KICAgICAgICAvLyBBbW1vLmNhc3RPYmplY3QoKSBjcmVhdGVzIG5ldyBKUyB3cmFwcGVycywgc28gY3VzdG9tIHByb3BlcnRpZXMgbGlrZQogICAgICAgIC8vIC51dWlkIHNldCBvbiB0aGUgb3JpZ2luYWwgd3JhcHBlciBhcmUgTk9UIGF2YWlsYWJsZSBvbiBjYXN0IHJlc3VsdHMuCiAgICAgICAgLy8gV2UgY29tcGFyZSB0aGUgdW5kZXJseWluZyBDKysgcG9pbnRlciBpbnN0ZWFkLgogICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGNvbnN0IHNvdXJjZUJvZHlQdHIgPSBzb3VyY2VFbGVtZW50ICYmIHNvdXJjZUVsZW1lbnQuYm9keSA/IHNvdXJjZUVsZW1lbnQuYm9keS5hIHx8IHNvdXJjZUVsZW1lbnQuYm9keS5wdHIgOiBudWxsOwogICAgICAgIGNvbnN0IGV4cGxvc2lvblBvc2l0aW9uID0gZ2V0RXhwbG9zaW9uUG9zaXRpb24odXVpZCwgcG9zaXRpb24pOwogICAgICAgIGNvbnN0IHsKICAgICAgICAgIGdob3N0Q29sbGlkZXIsCiAgICAgICAgICB0cmFuc2Zvcm0KICAgICAgICB9ID0gY3JlYXRlR2hvc3RDb2xsaWRlcihyYWRpdXMsIGV4cGxvc2lvblBvc2l0aW9uKTsKICAgICAgICB3b3JsZC5hZGRDb2xsaXNpb25PYmplY3QoZ2hvc3RDb2xsaWRlcik7CgogICAgICAgIC8vIEZvcmNlIGEgY29sbGlzaW9uIGRldGVjdGlvbiBwYXNzIHNvIHRoZSBnaG9zdCBjb2xsaWRlciBkaXNjb3ZlcnMKICAgICAgICAvLyBvdmVybGFwcGluZyBib2RpZXMuIFdpdGhvdXQgdGhpcywgZ2V0TnVtT3ZlcmxhcHBpbmdPYmplY3RzKCkgcmV0dXJucyAwCiAgICAgICAgLy8gYmVjYXVzZSBidEdob3N0UGFpckNhbGxiYWNrIG9ubHkgdXBkYXRlcyBkdXJpbmcgYSBzaW11bGF0aW9uIHN0ZXAuCiAgICAgICAgd29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpLnBlcmZvcm1EaXNjcmV0ZUNvbGxpc2lvbkRldGVjdGlvbigpOwogICAgICAgIGZvckVhY2hHaG9zdENvbGxpc2lvbihnaG9zdENvbGxpZGVyLCAob2JqZWN0LCBvYmplY3RUcmFuc2Zvcm0pID0+IHsKICAgICAgICAgIC8vIFNraXAgdGhlIHNvdXJjZSBlbnRpdHkgdXNpbmcgcG9pbnRlciBjb21wYXJpc29uLgogICAgICAgICAgY29uc3Qgb2JqZWN0UHRyID0gb2JqZWN0LmEgfHwgb2JqZWN0LnB0cjsKICAgICAgICAgIGlmIChzb3VyY2VCb2R5UHRyICYmIG9iamVjdFB0ciA9PT0gc291cmNlQm9keVB0cikgcmV0dXJuOwogICAgICAgICAgY29uc3Qgb3JpZ2luID0gb2JqZWN0VHJhbnNmb3JtLmdldE9yaWdpbigpOwogICAgICAgICAgb2JqZWN0LmFjdGl2YXRlKHRydWUpOwogICAgICAgICAgY29uc3QgaW1wdWxzZSA9IGdldEV4cGxvc2lvbkltcHVsc2Uob3JpZ2luLCBleHBsb3Npb25Qb3NpdGlvbiwgc3RyZW5ndGgpOwogICAgICAgICAgb2JqZWN0LmFwcGx5Q2VudHJhbEltcHVsc2UoaW1wdWxzZSk7CiAgICAgICAgICBBbW1vLmRlc3Ryb3koaW1wdWxzZSk7CiAgICAgICAgfSk7CiAgICAgICAgd29ybGQuZ2V0RHluYW1pY3NXb3JsZCgpLnJlbW92ZUNvbGxpc2lvbk9iamVjdChnaG9zdENvbGxpZGVyKTsKICAgICAgICBBbW1vLmRlc3Ryb3koZ2hvc3RDb2xsaWRlcik7CiAgICAgICAgQW1tby5kZXN0cm95KHRyYW5zZm9ybSk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCJbUGh5c2ljcyBXb3JrZXJdIGNyZWF0ZUV4cGxvc2lvbiBlcnJvcjoiLCBlKTsKICAgICAgfQogICAgfTsKCiAgICBjb25zdCBoYW5kbGVMb2FkRXZlbnQgPSBvcHRpb25zID0+IEFtbW8gPT4gewogICAgICBzZWxmLkFtbW8gPSBBbW1vOwogICAgICBvbm1lc3NhZ2UgPSAoewogICAgICAgIGRhdGEKICAgICAgfSkgPT4gewogICAgICAgIHN3aXRjaCAoZGF0YS5ldmVudCkgewogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuQk9YOgogICAgICAgICAgICBhZGRCb3goZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuU1BIRVJFOgogICAgICAgICAgICBhZGRTcGhlcmUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuVkVISUNMRToKICAgICAgICAgICAgYWRkVmVoaWNsZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkFERC5NT0RFTDoKICAgICAgICAgICAgYWRkTW9kZWwoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuUExBWUVSOgogICAgICAgICAgICBhZGRQbGF5ZXIoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULlNFVC5MSU5FQVJfVkVMT0NJVFk6CiAgICAgICAgICAgIHNldExpbmVhclZlbG9jaXR5KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5SRVNFVDoKICAgICAgICAgICAgcmVzZXRFbGVtZW50KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuUE9TSVRJT046CiAgICAgICAgICAgIHNldFBvc2l0aW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuUVVBVEVSTklPTjoKICAgICAgICAgICAgc2V0UXVhdGVybmlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLlZFSElDTEUuU0VULlBPU0lUSU9OOgogICAgICAgICAgICBzZXRWZWhpY2xlUG9zaXRpb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlNFVC5RVUFURVJOSU9OOgogICAgICAgICAgICBzZXRWZWhpY2xlUXVhdGVybmlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLlZFSElDTEUuUkVTRVQ6CiAgICAgICAgICAgIHJlc2V0VmVoaWNsZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuQVBQTFkuSU1QVUxTRToKICAgICAgICAgICAgYXBwbHlJbXB1c2UoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULlVQREFURToKICAgICAgICAgICAgd29ybGQudXBkYXRlQm9keVN0YXRlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5ESVNQT1NFOgogICAgICAgICAgICB3b3JsZC5kaXNwb3NlQm9keShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVGRkVDVFMuRVhQTE9TSU9OOgogICAgICAgICAgICBjcmVhdGVFeHBsb3Npb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5URVJNSU5BVEU6CiAgICAgICAgICAgIHdvcmxkLnRlcm1pbmF0ZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHdvcmxkLmluaXQob3B0aW9ucyk7CiAgICAgIGRpc3BhdGNoZXIuc2VuZFJlYWR5RXZlbnQoKTsKICAgICAgd29ybGQuc2ltdWxhdGUoKTsKICAgIH07CiAgICBjb25zdCBsb2FkQW1tbyA9IG9wdGlvbnMgPT4gewogICAgICBjb25zdCBzY3JpcHRVcmwgPSBvcHRpb25zLmhvc3QgKyAiLyIgKyAob3B0aW9ucy5wYXRoIHx8IExJQlJBUllfTkFNRSk7CiAgICAgIGltcG9ydFNjcmlwdHMoc2NyaXB0VXJsKTsKICAgICAgQW1tbygpLnRoZW4oaGFuZGxlTG9hZEV2ZW50KG9wdGlvbnMpKTsKICAgIH07CiAgICBvbm1lc3NhZ2UgPSAoewogICAgICBkYXRhCiAgICB9KSA9PiB7CiAgICAgIHN3aXRjaCAoZGF0YS5ldmVudCkgewogICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuTE9BRC5BTU1POgogICAgICAgICAgbG9hZEFtbW8oZGF0YSk7CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfTsKCn0pKCk7Cgo=', 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
@@ -61301,7 +61301,7 @@ function applyMiddleware() {
61301
61301
 
61302
61302
  var thunk = createThunkMiddleware();
61303
61303
  thunk.withExtraArgument = createThunkMiddleware;var name = "mage-engine";
61304
- var version$1 = "3.25.4";
61304
+ var version$1 = "3.25.6";
61305
61305
  var description = "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.";
61306
61306
  var main = "dist/mage.js";
61307
61307
  var author$1 = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mage-engine",
3
- "version": "3.25.4",
3
+ "version": "3.25.6",
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": {
@@ -1,29 +0,0 @@
1
- name: Tests
2
-
3
- on:
4
- pull_request:
5
- branches: [master, main]
6
- push:
7
- branches: [master, main]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
-
13
- steps:
14
- - uses: actions/checkout@v4
15
-
16
- - name: Use Node.js 20
17
- uses: actions/setup-node@v4
18
- with:
19
- node-version: 20
20
- cache: npm
21
-
22
- - name: Install dependencies
23
- run: npm ci
24
-
25
- - name: Lint
26
- run: npm run lint
27
-
28
- - name: Run tests
29
- run: npm test
@@ -1,20 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- printWidth: 100,
5
- trailingComma: "all",
6
- arrowParens: "avoid",
7
- semi: true,
8
- tabWidth: 4,
9
-
10
- overrides: [
11
- {
12
- files: ["*.md"],
13
- options: { printWidth: 120 },
14
- },
15
- {
16
- files: [".toolsharerc"],
17
- options: { parser: "yaml" },
18
- },
19
- ],
20
- };
@@ -1,35 +0,0 @@
1
- Copyright (c) 2015 - 2018 by Marco Stagni and contributors.
2
-
3
- Some rights reserved.
4
-
5
- Redistribution and use in source and binary forms, with or without
6
- modification, are permitted provided that the following conditions are
7
- met:
8
-
9
- * Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
11
-
12
- * Redistributions in binary form must reproduce the above
13
- copyright notice, this list of conditions and the following
14
- disclaimer in the documentation and/or other materials provided
15
- with the distribution.
16
-
17
- * The names of the contributors may not be used to endorse or
18
- promote products derived from this software without specific
19
- prior written permission.
20
-
21
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
-
33
-
34
- Mage contains third party software in the 'app/vendor' directory: each
35
- file/module in this directory is distributed under its original license.
@@ -1,56 +0,0 @@
1
- # Mage
2
-
3
- ![npm](https://img.shields.io/npm/v/mage-engine?color=%232ecc71)
4
- ![npm](https://img.shields.io/npm/dy/mage-engine?color=%23e67e22)
5
- ![npm bundle size](https://img.shields.io/bundlephobia/min/mage-engine)
6
- ![GitHub repo size](https://img.shields.io/github/repo-size/MageStudio/Mage)
7
- ![Discord](https://badgen.net/discord/members/NR5ZDGFG5j)
8
-
9
- ---
10
-
11
- Mage is a game engine built on top of THREEJS. It features all you need to create fully interactive 3D application that can be distributed via web, desktop or mobile.
12
-
13
- [Documentation](https://www.mage.studio/docs)
14
-
15
- ## Development
16
- The engine is under heavy development. The best way to stay up to date with changes, new features and bug fixes is to [join the Discord server](https://discord.gg/NR5ZDGFG5j).
17
-
18
- ---
19
-
20
- ## Licence
21
-
22
- Copyright (c) 2015 - 2018 by Marco Stagni and contributors.
23
-
24
- Some rights reserved.
25
-
26
- Redistribution and use in source and binary forms, with or without
27
- modification, are permitted provided that the following conditions are
28
- met:
29
-
30
- * Redistributions of source code must retain the above copyright
31
- notice, this list of conditions and the following disclaimer.
32
-
33
- * Redistributions in binary form must reproduce the above
34
- copyright notice, this list of conditions and the following
35
- disclaimer in the documentation and/or other materials provided
36
- with the distribution.
37
-
38
- * The names of the contributors may not be used to endorse or
39
- promote products derived from this software without specific
40
- prior written permission.
41
-
42
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53
-
54
-
55
- Mage contains third party software in the 'app/vendor' directory: each
56
- file/module in this directory is distributed under its original license.
@@ -1,178 +0,0 @@
1
- // Lightweight mock of THREE.js for unit tests.
2
- // Only stubs the APIs actually used by src/lib/ modules.
3
- // Grow this file incrementally as more tests need additional THREE APIs.
4
-
5
- class Vector3 {
6
- constructor(x = 0, y = 0, z = 0) {
7
- this.x = x;
8
- this.y = y;
9
- this.z = z;
10
- }
11
- set(x, y, z) { this.x = x; this.y = y; this.z = z; return this; }
12
- clone() { return new Vector3(this.x, this.y, this.z); }
13
- add(v) { this.x += v.x; this.y += v.y; this.z += v.z; return this; }
14
- sub(v) { this.x -= v.x; this.y -= v.y; this.z -= v.z; return this; }
15
- normalize() {
16
- const len = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
17
- if (len > 0) { this.x /= len; this.y /= len; this.z /= len; }
18
- return this;
19
- }
20
- multiplyScalar(s) { this.x *= s; this.y *= s; this.z *= s; return this; }
21
- lerp(v, t) {
22
- this.x += (v.x - this.x) * t;
23
- this.y += (v.y - this.y) * t;
24
- this.z += (v.z - this.z) * t;
25
- return this;
26
- }
27
- }
28
-
29
- class Vector2 {
30
- constructor(x = 0, y = 0) {
31
- this.x = x;
32
- this.y = y;
33
- }
34
- }
35
-
36
- const MathUtils = {
37
- lerp: (x, y, t) => x + (y - x) * t,
38
- };
39
-
40
- class Color {
41
- constructor(color) {
42
- this.value = color;
43
- }
44
- }
45
-
46
- class AnimationMixer {
47
- constructor() {
48
- this.time = 0;
49
- }
50
- clipAction() {
51
- return {
52
- reset: function() { return this; },
53
- setLoop: function() { return this; },
54
- setEffectiveTimeScale: function() { return this; },
55
- setEffectiveWeight: function() { return this; },
56
- play: function() {},
57
- stop: function() {},
58
- fadeIn: function() { return this; },
59
- fadeOut: function() { return this; },
60
- isRunning: function() { return false; },
61
- time: 0,
62
- };
63
- }
64
- stopAllAction() {}
65
- addEventListener() {}
66
- update() {}
67
- }
68
-
69
- class AnimationClip {
70
- static findByName(clips, name) {
71
- return clips.find(c => c.name === name);
72
- }
73
- }
74
-
75
- class EventDispatcher {
76
- constructor() {
77
- this._listeners = {};
78
- }
79
- addEventListener(type, listener) {
80
- if (!this._listeners[type]) this._listeners[type] = [];
81
- this._listeners[type].push(listener);
82
- }
83
- removeEventListener(type, listener) {
84
- if (this._listeners[type]) {
85
- this._listeners[type] = this._listeners[type].filter(l => l !== listener);
86
- }
87
- }
88
- dispatchEvent(event) {
89
- if (this._listeners[event.type]) {
90
- this._listeners[event.type].forEach(l => l(event));
91
- }
92
- }
93
- }
94
-
95
- class Quaternion {
96
- constructor(x = 0, y = 0, z = 0, w = 1) {
97
- this.x = x; this.y = y; this.z = z; this.w = w;
98
- }
99
- identity() { this.x = 0; this.y = 0; this.z = 0; this.w = 1; return this; }
100
- copy(q) { this.x = q.x; this.y = q.y; this.z = q.z; this.w = q.w; return this; }
101
- clone() { return new Quaternion(this.x, this.y, this.z, this.w); }
102
- }
103
-
104
- class Euler {
105
- constructor(x = 0, y = 0, z = 0, order = "XYZ") {
106
- this.x = x; this.y = y; this.z = z; this.order = order;
107
- }
108
- }
109
-
110
- class Matrix4 {
111
- constructor() {
112
- this.elements = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
113
- }
114
- identity() { this.elements = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; return this; }
115
- getInverse() { return this; }
116
- multiplyMatrices() { return this; }
117
- setFromMatrixScale() { return this; }
118
- }
119
-
120
- // Material stubs
121
- class MeshBasicMaterial { constructor(opts) { Object.assign(this, opts); } }
122
- class MeshLambertMaterial { constructor(opts) { Object.assign(this, opts); } }
123
- class MeshPhongMaterial { constructor(opts) { Object.assign(this, opts); } }
124
- class MeshDepthMaterial { constructor(opts) { Object.assign(this, opts); } }
125
- class MeshStandardMaterial { constructor(opts) { Object.assign(this, opts); } }
126
- class MeshToonMaterial { constructor(opts) { Object.assign(this, opts); } }
127
-
128
- // Encoding constants
129
- const LinearEncoding = 3000;
130
- const sRGBEncoding = 3001;
131
- const GammaEncoding = 3007;
132
- const RGBEEncoding = 3002;
133
- const RGBM7Encoding = 3004;
134
- const RGBM16Encoding = 3005;
135
- const RGBDEncoding = 3006;
136
- const BasicDepthPacking = 3200;
137
- const RGBADepthPacking = 3201;
138
-
139
- // Side constants
140
- const FrontSide = 0;
141
- const BackSide = 1;
142
- const DoubleSide = 2;
143
-
144
- const LoopRepeat = 2201;
145
- const LoopOnce = 2200;
146
-
147
- module.exports = {
148
- Vector3,
149
- Vector2,
150
- Quaternion,
151
- Euler,
152
- Matrix4,
153
- MathUtils,
154
- Color,
155
- AnimationMixer,
156
- AnimationClip,
157
- EventDispatcher,
158
- MeshBasicMaterial,
159
- MeshLambertMaterial,
160
- MeshPhongMaterial,
161
- MeshDepthMaterial,
162
- MeshStandardMaterial,
163
- MeshToonMaterial,
164
- LinearEncoding,
165
- sRGBEncoding,
166
- GammaEncoding,
167
- RGBEEncoding,
168
- RGBM7Encoding,
169
- RGBM16Encoding,
170
- RGBDEncoding,
171
- BasicDepthPacking,
172
- RGBADepthPacking,
173
- FrontSide,
174
- BackSide,
175
- DoubleSide,
176
- LoopRepeat,
177
- LoopOnce,
178
- };