mage-engine 3.25.5 → 3.25.7
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 +989 -29
- package/package.json +1 -1
- package/.claude/worktrees/fix-onstart-error-handling/.github/workflows/test.yml +0 -29
- package/.claude/worktrees/fix-onstart-error-handling/.nvmrc +0 -1
- package/.claude/worktrees/fix-onstart-error-handling/.prettierrc.js +0 -20
- package/.claude/worktrees/fix-onstart-error-handling/LICENSE +0 -35
- package/.claude/worktrees/fix-onstart-error-handling/README.md +0 -56
- package/.claude/worktrees/fix-onstart-error-handling/__mocks__/three.js +0 -178
- package/.claude/worktrees/fix-onstart-error-handling/dist/ammo.js +0 -991
- package/.claude/worktrees/fix-onstart-error-handling/eslint.config.js +0 -73
- package/.claude/worktrees/fix-onstart-error-handling/jest.config.js +0 -31
- package/.claude/worktrees/fix-onstart-error-handling/package.json +0 -96
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+IHBvc3RNZXNzYWdlKHsKICAgICAgICBldmVudDogUEhZU0lDU19FVkVOVFMuRElTUEFUQ0gsCiAgICAgICAgdXVpZCwKICAgICAgICBldmVudE5hbWUsCiAgICAgICAgZXZlbnREYXRhCiAgICAgIH0pKTsKICAgIH0pOwogICAgdmFyIGRpc3BhdGNoZXIgPSBuZXcgRGlzcGF0Y2hlcigpOwoKICAgIGNvbnN0IGFwcGx5TWF0cml4NFRvVmVjdG9yMyA9ICh7CiAgICAgIHggPSAwLAogICAgICB5ID0gMCwKICAgICAgeiA9IDAKICAgIH0sIG1hdHJpeCA9IFtdKSA9PiB7CiAgICAgIGNvbnN0IHcgPSAxIC8gKG1hdHJpeFszXSAqIHggKyBtYXRyaXhbN10gKiB5ICsgbWF0cml4WzExXSAqIHogKyBtYXRyaXhbMTVdKTsKICAgICAgcmV0dXJuIHsKICAgICAgICB4OiAobWF0cml4WzBdICogeCArIG1hdHJpeFs0XSAqIHkgKyBtYXRyaXhbOF0gKiB6ICsgbWF0cml4WzEyXSkgKiB3LAogICAgICAgIHk6IChtYXRyaXhbMV0gKiB4ICsgbWF0cml4WzVdICogeSArIG1hdHJpeFs5XSAqIHogKyBtYXRyaXhbMTNdKSAqIHcsCiAgICAgICAgejogKG1hdHJpeFsyXSAqIHggKyBtYXRyaXhbNl0gKiB5ICsgbWF0cml4WzEwXSAqIHogKyBtYXRyaXhbMTRdKSAqIHcKICAgICAgfTsKICAgIH07CgogICAgY29uc3QgY3JlYXRlUmlnaWRCb2R5ID0gKHNoYXBlLCBvcHRpb25zKSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcyA9IDAsCiAgICAgICAgZnJpY3Rpb24sCiAgICAgICAgcmVzdGl0dXRpb24gPSAwLjksCiAgICAgICAgZGFtcGluZyA9IHsKICAgICAgICAgIGxpbmVhcjogMC4yLAogICAgICAgICAgYW5ndWxhcjogMC4yCiAgICAgICAgfQogICAgICB9ID0gb3B0aW9uczsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBuZXcgQW1tby5idERlZmF1bHRNb3Rpb25TdGF0ZSh0cmFuc2Zvcm0pOwogICAgICBjb25zdCBsb2NhbEluZXJ0aWEgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIHNoYXBlLmNhbGN1bGF0ZUxvY2FsSW5lcnRpYShtYXNzLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCByYkluZm8gPSBuZXcgQW1tby5idFJpZ2lkQm9keUNvbnN0cnVjdGlvbkluZm8obWFzcywgbW90aW9uU3RhdGUsIHNoYXBlLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCBib2R5ID0gbmV3IEFtbW8uYnRSaWdpZEJvZHkocmJJbmZvKTsKICAgICAgaWYgKG1hc3MgPiAwKSB7CiAgICAgICAgYm9keS5zZXRGcmljdGlvbihmcmljdGlvbik7CiAgICAgICAgYm9keS5zZXRSZXN0aXR1dGlvbihyZXN0aXR1dGlvbik7CiAgICAgICAgYm9keS5zZXREYW1waW5nKGRhbXBpbmcubGluZWFyLCBkYW1waW5nLmFuZ3VsYXIpOwogICAgICAgIGJvZHkuc2V0QWN0aXZhdGlvblN0YXRlKERJU0FCTEVfREVBQ1RJVkFUSU9OKTsKICAgICAgfQoKICAgICAgLy8gc3RvcmluZyB1dWlkIGZvciBmdXR1cmUgcmVmZXJlbmNlCiAgICAgIGJvZHkudXVpZCA9IHV1aWQ7CiAgICAgIHdvcmxkLmFkZFJpZ2lkQm9keShib2R5KTsKICAgICAgcmV0dXJuIGJvZHk7CiAgICB9OwogICAgY29uc3QgYWRkTW9kZWwgPSBvcHRpb25zID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgdmVydGljZXMsCiAgICAgICAgbWF0cmljZXMsCiAgICAgICAgaW5kZXhlcywKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gb3B0aW9uczsKICAgICAgY29uc3Qgc2NhbGUgPSBERUZBVUxUX1NDQUxFOwogICAgICBjb25zdCBidGEgPSBuZXcgQW1tby5idFZlY3RvcjMoKTsKICAgICAgY29uc3QgYnRiID0gbmV3IEFtbW8uYnRWZWN0b3IzKCk7CiAgICAgIGNvbnN0IGJ0YyA9IG5ldyBBbW1vLmJ0VmVjdG9yMygpOwogICAgICBjb25zdCB0cmlNZXNoID0gbmV3IEFtbW8uYnRUcmlhbmdsZU1lc2godHJ1ZSwgZmFsc2UpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZlcnRpY2VzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgY29uc3QgY29tcG9uZW50cyA9IHZlcnRpY2VzW2ldOwogICAgICAgIGNvbnN0IGluZGV4ID0gaW5kZXhlc1tpXSA/IGluZGV4ZXNbaV0gOiBudWxsOwogICAgICAgIGNvbnN0IG1hdHJpeCA9IEFycmF5LmZyb20obWF0cmljZXNbaV0pOwogICAgICAgIGlmIChpbmRleCkgewogICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRleC5sZW5ndGg7IGogKz0gMykgewogICAgICAgICAgICBjb25zdCBhaSA9IGluZGV4W2pdICogMzsKICAgICAgICAgICAgY29uc3QgYmkgPSBpbmRleFtqICsgMV0gKiAzOwogICAgICAgICAgICBjb25zdCBjaSA9IGluZGV4W2ogKyAyXSAqIDM7CiAgICAgICAgICAgIGNvbnN0IHZhID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2FpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2FpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1thaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZiID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2JpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2JpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tiaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZjID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2NpXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2NpICsgMV0sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tjaSArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGJ0YS5zZXRWYWx1ZSh2YS54LCB2YS55LCB2YS56KTsKICAgICAgICAgICAgYnRiLnNldFZhbHVlKHZiLngsIHZiLnksIHZiLnopOwogICAgICAgICAgICBidGMuc2V0VmFsdWUodmMueCwgdmMueSwgdmMueik7CiAgICAgICAgICAgIHRyaU1lc2guYWRkVHJpYW5nbGUoYnRhLCBidGIsIGJ0YywgZmFsc2UpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbXBvbmVudHMubGVuZ3RoOyBqICs9IDkpIHsKICAgICAgICAgICAgY29uc3QgdmEgPSBhcHBseU1hdHJpeDRUb1ZlY3RvcjMoewogICAgICAgICAgICAgIHg6IGNvbXBvbmVudHNbaiArIDBdLAogICAgICAgICAgICAgIHk6IGNvbXBvbmVudHNbaiArIDFdLAogICAgICAgICAgICAgIHo6IGNvbXBvbmVudHNbaiArIDJdCiAgICAgICAgICAgIH0sIG1hdHJpeCk7CiAgICAgICAgICAgIGNvbnN0IHZiID0gYXBwbHlNYXRyaXg0VG9WZWN0b3IzKHsKICAgICAgICAgICAgICB4OiBjb21wb25lbnRzW2ogKyAzXSwKICAgICAgICAgICAgICB5OiBjb21wb25lbnRzW2ogKyA0XSwKICAgICAgICAgICAgICB6OiBjb21wb25lbnRzW2ogKyA1XQogICAgICAgICAgICB9LCBtYXRyaXgpOwogICAgICAgICAgICBjb25zdCB2YyA9IGFwcGx5TWF0cml4NFRvVmVjdG9yMyh7CiAgICAgICAgICAgICAgeDogY29tcG9uZW50c1tqICsgNl0sCiAgICAgICAgICAgICAgeTogY29tcG9uZW50c1tqICsgN10sCiAgICAgICAgICAgICAgejogY29tcG9uZW50c1tqICsgOF0KICAgICAgICAgICAgfSwgbWF0cml4KTsKICAgICAgICAgICAgYnRhLnNldFZhbHVlKHZhLngsIHZhLnksIHZhLnopOwogICAgICAgICAgICBidGIuc2V0VmFsdWUodmIueCwgdmIueSwgdmIueik7CiAgICAgICAgICAgIGJ0Yy5zZXRWYWx1ZSh2Yy54LCB2Yy55LCB2Yy56KTsKICAgICAgICAgICAgdHJpTWVzaC5hZGRUcmlhbmdsZShidGEsIGJ0YiwgYnRjLCBmYWxzZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGNvbnN0IGxvY2FsU2NhbGUgPSBuZXcgQW1tby5idFZlY3RvcjMoc2NhbGUueCwgc2NhbGUueSwgc2NhbGUueik7CiAgICAgIHRyaU1lc2guc2V0U2NhbGluZyhsb2NhbFNjYWxlKTsKICAgICAgQW1tby5kZXN0cm95KGxvY2FsU2NhbGUpOwogICAgICBjb25zdCBjb2xsaXNpb25TaGFwZSA9IG5ldyBBbW1vLmJ0QnZoVHJpYW5nbGVNZXNoU2hhcGUodHJpTWVzaCwgdHJ1ZSwgdHJ1ZSk7CiAgICAgIGNvbGxpc2lvblNoYXBlLnJlc291cmNlcyA9IFt0cmlNZXNoXTsKICAgICAgQW1tby5kZXN0cm95KGJ0YSk7CiAgICAgIEFtbW8uZGVzdHJveShidGIpOwogICAgICBBbW1vLmRlc3Ryb3koYnRjKTsKICAgICAgY29uc3QgYm9keSA9IGNyZWF0ZVJpZ2lkQm9keShjb2xsaXNpb25TaGFwZSwgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uCiAgICAgIH0pOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB1dWlkLAogICAgICAgIGJvZHksCiAgICAgICAgdHlwZTogVFlQRVMuTUVTSCwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgYWRkQm94ID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHdpZHRoLAogICAgICAgIGxlbmd0aCwKICAgICAgICBoZWlnaHQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBtYXNzID0gMCwKICAgICAgICBmcmljdGlvbiA9IDIKICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IGdlb21ldHJ5ID0gbmV3IEFtbW8uYnRCb3hTaGFwZShuZXcgQW1tby5idFZlY3RvcjMod2lkdGggKiAwLjUsIGhlaWdodCAqIDAuNSwgbGVuZ3RoICogMC41KSk7CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoZ2VvbWV0cnksIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbgogICAgICB9KTsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLkJPWCwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3QgYWRkU3BoZXJlID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHJhZGl1cywKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBxdWF0ZXJuaW9uLAogICAgICAgIG1hc3MgPSAwLAogICAgICAgIGZyaWN0aW9uID0gMgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idFNwaGVyZVNoYXBlKHJhZGl1cyk7CiAgICAgIGNvbnN0IGJvZHkgPSBjcmVhdGVSaWdpZEJvZHkoZ2VvbWV0cnksIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uLAogICAgICAgIHF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbgogICAgICB9KTsKICAgICAgd29ybGQuYWRkRWxlbWVudCh7CiAgICAgICAgdXVpZCwKICAgICAgICBib2R5LAogICAgICAgIHR5cGU6IFRZUEVTLlNQSEVSRSwKICAgICAgICBzdGF0ZTogREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgICAgfSk7CiAgICB9OwogICAgY29uc3Qgc2V0TGluZWFyVmVsb2NpdHkgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgdmVsb2NpdHkgPSBERUZBVUxUX0xJTkVBUl9WRUxPQ0lUWQogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAobW90aW9uU3RhdGUpIHsKICAgICAgICBjb25zdCBsaW5lYXJWZWxvY2l0eSA9IG5ldyBBbW1vLmJ0VmVjdG9yMyh2ZWxvY2l0eS54LCB2ZWxvY2l0eS55LCB2ZWxvY2l0eS56KTsKICAgICAgICBib2R5LnNldExpbmVhclZlbG9jaXR5KGxpbmVhclZlbG9jaXR5KTsKICAgICAgICBBbW1vLmRlc3Ryb3kobGluZWFyVmVsb2NpdHkpOwogICAgICB9CiAgICB9OwogICAgY29uc3Qgc2V0UG9zaXRpb24gPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24KICAgICAgfSA9IGRhdGE7CiAgICAgIGNvbnN0IHsKICAgICAgICBib2R5CiAgICAgIH0gPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICBjb25zdCB0cmFuc2Zvcm0gPSBuZXcgQW1tby5idFRyYW5zZm9ybSgpOwogICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAvLyBBbHNvIHVwZGF0ZSBtb3Rpb24gc3RhdGUgc28gc3RhdGljIGJvZGllcyAobWFzcz0wKSByZWZsZWN0IHRoZSBjaGFuZ2UKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCByZXNldEVsZW1lbnQgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihuZXcgQW1tby5idFZlY3RvcjMocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueikpOwogICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIC8vIEFsc28gdXBkYXRlIG1vdGlvbiBzdGF0ZSBzbyBzdGF0aWMgYm9kaWVzIChtYXNzPTApIHJlZmxlY3QgdGhlIGNoYW5nZQogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgbW90aW9uU3RhdGUuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGFwcGx5SW1wdXNlID0gKHsKICAgICAgdXVpZCwKICAgICAgaW1wdWxzZSA9IERFRkFVTFRfSU1QVUxTRQogICAgfSkgPT4gewogICAgICB0cnkgewogICAgICAgIGNvbnN0IGVsZW1lbnQgPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGlmICghZWxlbWVudCkgewogICAgICAgICAgY29uc29sZS53YXJuKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZTogZWxlbWVudCBub3QgZm91bmQgZm9yIHV1aWQ6IiwgdXVpZCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IHsKICAgICAgICAgIGJvZHkKICAgICAgICB9ID0gZWxlbWVudDsKICAgICAgICBpZiAoIWJvZHkpIHsKICAgICAgICAgIGNvbnNvbGUud2FybigiW1BoeXNpY3MgV29ya2VyXSBhcHBseUltcHVsc2U6IGJvZHkgaXMgbnVsbCBmb3IgdXVpZDoiLCB1dWlkKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgYm9keS5hY3RpdmF0ZSh0cnVlKTsKICAgICAgICBjb25zdCBidEltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMoaW1wdWxzZS54LCBpbXB1bHNlLnksIGltcHVsc2Uueik7CiAgICAgICAgYm9keS5hcHBseUNlbnRyYWxJbXB1bHNlKGJ0SW1wdWxzZSk7CiAgICAgICAgQW1tby5kZXN0cm95KGJ0SW1wdWxzZSk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCJbUGh5c2ljcyBXb3JrZXJdIGFwcGx5SW1wdWxzZSBlcnJvcjoiLCBlKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IHNldFF1YXRlcm5pb24gPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcXVhdGVybmlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJvZHkKICAgICAgfSA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAvLyBBbHNvIHVwZGF0ZSBtb3Rpb24gc3RhdGUgc28gc3RhdGljIGJvZGllcyAobWFzcz0wKSByZWZsZWN0IHRoZSBjaGFuZ2UKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBib2R5LmdldE1vdGlvblN0YXRlKCk7CiAgICAgIGlmIChtb3Rpb25TdGF0ZSkgewogICAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBoYW5kbGVFbGVtZW50VXBkYXRlID0gKHsKICAgICAgYm9keSwKICAgICAgdXVpZCwKICAgICAgc3RhdGU6IF9zdGF0ZSA9IERFRkFVTFRfUklHSURCT0RZX1NUQVRFCiAgICB9LCBkdCkgPT4gewogICAgICAvLyBTdGF0aWMgYm9kaWVzIChtYXNzPTApIG5ldmVyIG1vdmUg4oCUIHNraXAgc2VuZGluZyB1cGRhdGVzIHNvIHRoZQogICAgICAvLyB2aXN1YWwgcG9zaXRpb24gc3RheXMgZXhhY3RseSB3aGVyZSB0aGUgYXV0aG9yIHBsYWNlZCBpdC4KICAgICAgaWYgKGJvZHkuaXNTdGF0aWNPYmplY3QoKSkgcmV0dXJuOwogICAgICBjb25zdCBtb3Rpb25TdGF0ZSA9IGJvZHkuZ2V0TW90aW9uU3RhdGUoKTsKICAgICAgaWYgKG1vdGlvblN0YXRlKSB7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBtb3Rpb25TdGF0ZS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIGxldCBvcmlnaW4gPSB0cmFuc2Zvcm0uZ2V0T3JpZ2luKCk7CiAgICAgICAgbGV0IHJvdGF0aW9uID0gdHJhbnNmb3JtLmdldFJvdGF0aW9uKCk7CiAgICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBvcmlnaW4sIHJvdGF0aW9uLCBkdCk7CiAgICAgICAgQW1tby5kZXN0cm95KHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CgogICAgY29uc3QgYWRkUGxheWVyID0gZGF0YSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICB1dWlkLAogICAgICAgIHdpZHRoLAogICAgICAgIGhlaWdodCwKICAgICAgICBwb3NpdGlvbiwKICAgICAgICBtYXNzLAogICAgICAgIGZyaWN0aW9uLAogICAgICAgIG9yaWdpbk9mZnNldCA9IHsKICAgICAgICAgIHg6IDAsCiAgICAgICAgICB5OiAwLAogICAgICAgICAgejogMAogICAgICAgIH0KICAgICAgfSA9IGRhdGE7CgogICAgICAvLyBidENhcHN1bGVTaGFwZSBleHBlY3RzIChyYWRpdXMsIGN5bGluZGVySGVpZ2h0KSDigJQgdXNlIGhhbGYtd2lkdGggYXMKICAgICAgLy8gcmFkaXVzIHNvIHRoZSBjYXBzdWxlIHdyYXBzIHRoZSBib3VuZGluZyBib3ggY29ycmVjdGx5LgogICAgICBjb25zdCByYWRpdXMgPSB3aWR0aCAqIDAuNTsKICAgICAgY29uc3QgY2Fwc3VsZSA9IG5ldyBBbW1vLmJ0Q2Fwc3VsZVNoYXBlKHJhZGl1cywgaGVpZ2h0KTsKCiAgICAgIC8vIEFsd2F5cyBjcmVhdGUgdGhlIHBsYXllciBib2R5IHVwcmlnaHQgKGlkZW50aXR5IHF1YXRlcm5pb24pLgogICAgICAvLyBUaGUgdmlzdWFsIHJvdGF0aW9uIGlzIGRyaXZlbiBieSB0aGUgY29udHJvbCwgbm90IGJ5IHBoeXNpY3MuCiAgICAgIGNvbnN0IHVwcmlnaHRRdWF0ZXJuaW9uID0gewogICAgICAgIHg6IDAsCiAgICAgICAgeTogMCwKICAgICAgICB6OiAwLAogICAgICAgIHc6IDEKICAgICAgfTsKCiAgICAgIC8vIFBvc2l0aW9uIHRoZSBjYXBzdWxlIGF0IHRoZSBtb2RlbCdzIEFBQkIgY2VudHJlIHNvIGl0IHdyYXBzIHRoZQogICAgICAvLyB2aXN1YWwgbWVzaCBjb3JyZWN0bHkuICBvcmlnaW5PZmZzZXQgaXMgdGhlIHZlY3RvciBmcm9tIHRoZSBtb2RlbCdzCiAgICAgIC8vIG9yaWdpbiB0byBpdHMgQUFCQiBjZW50cmUg4oCUIGNvbXB1dGVkIG9uIHRoZSBtYWluIHRocmVhZCB3aGVyZQogICAgICAvLyBUaHJlZS5qcyBnZW9tZXRyeSBpcyBhdmFpbGFibGUuCiAgICAgIGNvbnN0IGNhcHN1bGVQb3NpdGlvbiA9IHsKICAgICAgICB4OiBwb3NpdGlvbi54ICsgb3JpZ2luT2Zmc2V0LngsCiAgICAgICAgeTogcG9zaXRpb24ueSArIG9yaWdpbk9mZnNldC55LAogICAgICAgIHo6IHBvc2l0aW9uLnogKyBvcmlnaW5PZmZzZXQuegogICAgICB9OwogICAgICBjb25zdCBib2R5ID0gY3JlYXRlUmlnaWRCb2R5KGNhcHN1bGUsIHsKICAgICAgICB1dWlkLAogICAgICAgIHBvc2l0aW9uOiBjYXBzdWxlUG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbjogdXByaWdodFF1YXRlcm5pb24sCiAgICAgICAgbWFzcywKICAgICAgICBmcmljdGlvbiwKICAgICAgICByZXN0aXR1dGlvbjogMCwKICAgICAgICBkYW1waW5nOiB7CiAgICAgICAgICBsaW5lYXI6IDAuMSwKICAgICAgICAgIGFuZ3VsYXI6IDEKICAgICAgICB9CiAgICAgIH0pOwoKICAgICAgLy8gRGlzYWJsZSByb3RhdGlvbiBvbiBhbGwgYXhlcyDigJQgdGhlIHZpc3VhbCByb3RhdGlvbiBpcyBkcml2ZW4gYnkgdGhlIGNvbnRyb2wuCiAgICAgIC8vIFVzZSBidFZlY3RvcjMgaW5zdGVhZCBvZiBzY2FsYXIgZm9yIGNvbXBhdGliaWxpdHkgYWNyb3NzIEFtbW8uanMgYnVpbGRzLgogICAgICBjb25zdCB6ZXJvQW5ndWxhciA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCAwLCAwKTsKICAgICAgYm9keS5zZXRBbmd1bGFyRmFjdG9yKHplcm9Bbmd1bGFyKTsKICAgICAgQW1tby5kZXN0cm95KHplcm9Bbmd1bGFyKTsKCiAgICAgIC8vIEVuYWJsZSBjb250aW51b3VzIGNvbGxpc2lvbiBkZXRlY3Rpb24gdG8gcHJldmVudCB0dW5uZWxpbmcgYXQgaGlnaCBzcGVlZHMuCiAgICAgIGJvZHkuc2V0Q2NkTW90aW9uVGhyZXNob2xkKHJhZGl1cyAqIDAuNSk7CiAgICAgIGJvZHkuc2V0Q2NkU3dlcHRTcGhlcmVSYWRpdXMocmFkaXVzICogMC44KTsKCiAgICAgIC8vIFN0b3JlIGZvciB1c2UgaW4gaGFuZGxlUGxheWVyVXBkYXRlIOKAlCBvZmZzZXQgaXMgc3VidHJhY3RlZCB3aGVuCiAgICAgIC8vIHNlbmRpbmcgcG9zaXRpb24gYmFjayBzbyB0aGUgdmlzdWFsIHN0YXlzIGF0IHRoZSBtb2RlbCBvcmlnaW4uCiAgICAgIGJvZHkuX21hc3MgPSBtYXNzOwogICAgICBib2R5Ll9vcmlnaW5PZmZzZXQgPSBvcmlnaW5PZmZzZXQ7CiAgICAgIHdvcmxkLmFkZEVsZW1lbnQoewogICAgICAgIHV1aWQsCiAgICAgICAgYm9keSwKICAgICAgICB0eXBlOiBUWVBFUy5QTEFZRVIsCiAgICAgICAgc3RhdGU6IERFRkFVTFRfUklHSURCT0RZX1NUQVRFCiAgICAgIH0pOwogICAgfTsKICAgIGNvbnN0IGhhbmRsZVBsYXllclVwZGF0ZSA9ICh7CiAgICAgIGJvZHksCiAgICAgIHV1aWQsCiAgICAgIHN0YXRlID0gREVGQVVMVF9SSUdJREJPRFlfU1RBVEUKICAgIH0sIGR0KSA9PiB7CiAgICAgIGNvbnN0IHsKICAgICAgICBtb3ZlbWVudCwKICAgICAgICBjYW1lcmFEaXJlY3Rpb24sCiAgICAgICAganVtcCwKICAgICAgICBqdW1wU3BlZWQsCiAgICAgICAgc3BlZWQ6IG1vdmVTcGVlZAogICAgICB9ID0gc3RhdGU7CiAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICBpZiAoIW1vdGlvblN0YXRlKSByZXR1cm47CgogICAgICAvLyBGb3JjZS1jbGVhciBhbmd1bGFyIHZlbG9jaXR5IGV2ZXJ5IHRpY2suIFRoZSBwbGF5ZXIgY2Fwc3VsZSBtdXN0IHN0YXkKICAgICAgLy8gdXByaWdodCDigJQgcm90YXRpb24gaXMgaGFuZGxlZCB2aXN1YWxseSBieSB0aGUgY29udHJvbCwgbm90IGJ5IHBoeXNpY3MuCiAgICAgIGNvbnN0IHplcm9BbmdWZWwgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIGJvZHkuc2V0QW5ndWxhclZlbG9jaXR5KHplcm9BbmdWZWwpOwogICAgICBBbW1vLmRlc3Ryb3koemVyb0FuZ1ZlbCk7CgogICAgICAvLyBGb3JjZSB0aGUgcGh5c2ljcyBib2R5IHJvdGF0aW9uIHRvIGlkZW50aXR5ICh1cHJpZ2h0KSBldmVyeSB0aWNrLgogICAgICAvLyBDb250YWN0IGZvcmNlcyBjYW4gc3RpbGwgcm90YXRlIHRoZSBjYXBzdWxlIGluIHNvbWUgQW1tby5qcyBidWlsZHMKICAgICAgLy8gZXZlbiB3aXRoIGFuZ3VsYXJGYWN0b3I9KDAsMCwwKS4gV2UgbXVzdCByZXNldCBCT1RIIHRoZSBib2R5IHdvcmxkCiAgICAgIC8vIHRyYW5zZm9ybSBBTkQgdGhlIG1vdGlvblN0YXRlIOKAlCB0aGV5IGNhbiBkaXZlcmdlLgogICAgICBjb25zdCB3b3JsZFRyYW5zZm9ybSA9IGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0oKTsKICAgICAgY29uc3QgdXByaWdodFF1YXQgPSBuZXcgQW1tby5idFF1YXRlcm5pb24oMCwgMCwgMCwgMSk7CiAgICAgIHdvcmxkVHJhbnNmb3JtLnNldFJvdGF0aW9uKHVwcmlnaHRRdWF0KTsKICAgICAgYm9keS5zZXRXb3JsZFRyYW5zZm9ybSh3b3JsZFRyYW5zZm9ybSk7CiAgICAgIG1vdGlvblN0YXRlLnNldFdvcmxkVHJhbnNmb3JtKHdvcmxkVHJhbnNmb3JtKTsKICAgICAgQW1tby5kZXN0cm95KHVwcmlnaHRRdWF0KTsKICAgICAgY29uc3QgY2hhcmFjdGVyU3BlZWQgPSBtb3ZlU3BlZWQgfHwgNTsKCiAgICAgIC8vIEp1bXAg4oCUIGFwcGx5IGEgb25lLXRpbWUgaW1wdWxzZSwgdGhlbiBjbGVhciB0aGUgZmxhZyBzbyBpdCBkb2Vzbid0IHJlcGVhdAogICAgICBpZiAoanVtcCAmJiBqdW1wU3BlZWQpIHsKICAgICAgICBjb25zdCBtYXNzID0gYm9keS5fbWFzcyB8fCA4MDsKICAgICAgICBjb25zdCBpbXB1bHNlID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIGp1bXBTcGVlZCAqIG1hc3MsIDApOwogICAgICAgIGJvZHkuYXBwbHlDZW50cmFsSW1wdWxzZShpbXB1bHNlKTsKICAgICAgICBBbW1vLmRlc3Ryb3koaW1wdWxzZSk7CiAgICAgICAgc3RhdGUuanVtcCA9IGZhbHNlOwogICAgICB9CiAgICAgIGNvbnN0IGlzTW92aW5nID0gbW92ZW1lbnQgJiYgKG1vdmVtZW50LmZvcndhcmQgfHwgbW92ZW1lbnQuYmFja3dhcmRzIHx8IG1vdmVtZW50LmxlZnQgfHwgbW92ZW1lbnQucmlnaHQpOwogICAgICBjb25zdCBsaW5lYXJWZWxvY2l0eSA9IGJvZHkuZ2V0TGluZWFyVmVsb2NpdHkoKTsKICAgICAgY29uc3QgY3VycmVudFkgPSBsaW5lYXJWZWxvY2l0eS55KCk7CiAgICAgIGlmIChpc01vdmluZyAmJiBjYW1lcmFEaXJlY3Rpb24pIHsKICAgICAgICAvLyBDb21wdXRlIGNhbWVyYS1yZWxhdGl2ZSBtb3ZlbWVudCBkaXJlY3Rpb24KICAgICAgICBsZXQgbW92ZVggPSAwOwogICAgICAgIGxldCBtb3ZlWiA9IDA7CiAgICAgICAgaWYgKG1vdmVtZW50LmZvcndhcmQpIHsKICAgICAgICAgIG1vdmVYICs9IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgICAgbW92ZVogKz0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5iYWNrd2FyZHMpIHsKICAgICAgICAgIG1vdmVYIC09IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgICAgbW92ZVogLT0gY2FtZXJhRGlyZWN0aW9uLno7CiAgICAgICAgfQogICAgICAgIGlmIChtb3ZlbWVudC5sZWZ0KSB7CiAgICAgICAgICBtb3ZlWCArPSBjYW1lcmFEaXJlY3Rpb24uejsKICAgICAgICAgIG1vdmVaIC09IGNhbWVyYURpcmVjdGlvbi54OwogICAgICAgIH0KICAgICAgICBpZiAobW92ZW1lbnQucmlnaHQpIHsKICAgICAgICAgIG1vdmVYIC09IGNhbWVyYURpcmVjdGlvbi56OwogICAgICAgICAgbW92ZVogKz0gY2FtZXJhRGlyZWN0aW9uLng7CiAgICAgICAgfQoKICAgICAgICAvLyBOb3JtYWxpemUgZGlyZWN0aW9uCiAgICAgICAgY29uc3QgbGVuID0gTWF0aC5zcXJ0KG1vdmVYICogbW92ZVggKyBtb3ZlWiAqIG1vdmVaKTsKICAgICAgICBpZiAobGVuID4gMCkgewogICAgICAgICAgbW92ZVggLz0gbGVuOwogICAgICAgICAgbW92ZVogLz0gbGVuOwogICAgICAgIH0KCiAgICAgICAgLy8gU2V0IGhvcml6b250YWwgdmVsb2NpdHkgZGlyZWN0bHkgZm9yIHJlc3BvbnNpdmUgbW92ZW1lbnQKICAgICAgICBjb25zdCBuZXdWZWwgPSBuZXcgQW1tby5idFZlY3RvcjMobW92ZVggKiBjaGFyYWN0ZXJTcGVlZCwgY3VycmVudFksIG1vdmVaICogY2hhcmFjdGVyU3BlZWQpOwogICAgICAgIGJvZHkuc2V0TGluZWFyVmVsb2NpdHkobmV3VmVsKTsKICAgICAgICBBbW1vLmRlc3Ryb3kobmV3VmVsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBXaGVuIGlkbGUsIG9ubHkgZGFtcGVuIGlmIHRoZXJlJ3MgbWVhbmluZ2Z1bCBob3Jpem9udGFsIHZlbG9jaXR5LgogICAgICAgIC8vIEF2b2lkIHRvdWNoaW5nIHRoZSB2ZWxvY2l0eSBldmVyeSBmcmFtZSB0byBsZXQgdGhlIHNvbHZlcgogICAgICAgIC8vIGhhbmRsZSBmbG9vciBjb250YWN0IHdpdGhvdXQgaW50ZXJmZXJlbmNlLgogICAgICAgIGNvbnN0IHZ4ID0gbGluZWFyVmVsb2NpdHkueCgpOwogICAgICAgIGNvbnN0IHZ6ID0gbGluZWFyVmVsb2NpdHkueigpOwogICAgICAgIGlmIChNYXRoLmFicyh2eCkgPiAwLjAxIHx8IE1hdGguYWJzKHZ6KSA+IDAuMDEpIHsKICAgICAgICAgIGNvbnN0IG5ld1ZlbCA9IG5ldyBBbW1vLmJ0VmVjdG9yMyh2eCAqIDAuODUsIGN1cnJlbnRZLCB2eiAqIDAuODUpOwogICAgICAgICAgYm9keS5zZXRMaW5lYXJWZWxvY2l0eShuZXdWZWwpOwogICAgICAgICAgQW1tby5kZXN0cm95KG5ld1ZlbCk7CiAgICAgICAgfQogICAgICAgIC8vIE90aGVyd2lzZSBsZXQgcGh5c2ljcyBoYW5kbGUgZXZlcnl0aGluZyDigJQgZG9uJ3Qgb3ZlcnJpZGUgdmVsb2NpdHkKICAgICAgfQoKICAgICAgLy8gUmVhZCBmcm9tIHRoZSBib2R5J3Mgd29ybGQgdHJhbnNmb3JtIChub3QgbW90aW9uU3RhdGUpIGJlY2F1c2Ugd2UKICAgICAgLy8gbWFpbnRhaW4gaXQgZGlyZWN0bHkgYWJvdmUg4oCUIHBvc2l0aW9uIGNvbWVzIGZyb20gcGh5c2ljcywgcm90YXRpb24KICAgICAgLy8gaXMgYWx3YXlzIGlkZW50aXR5LgogICAgICBjb25zdCBmaW5hbFRyYW5zZm9ybSA9IGJvZHkuZ2V0V29ybGRUcmFuc2Zvcm0oKTsKICAgICAgY29uc3Qgb3JpZ2luID0gZmluYWxUcmFuc2Zvcm0uZ2V0T3JpZ2luKCk7CiAgICAgIGNvbnN0IHJvdGF0aW9uID0gZmluYWxUcmFuc2Zvcm0uZ2V0Um90YXRpb24oKTsKICAgICAgY29uc3QgZ3JvdW5kZWQgPSBNYXRoLmFicyhjdXJyZW50WSkgPCAwLjU7CgogICAgICAvLyBUaGUgcGh5c2ljcyBjYXBzdWxlIGlzIG9mZnNldCB1cHdhcmQgc28gaXRzIGJvdHRvbSBhbGlnbnMgd2l0aCB0aGUKICAgICAgLy8gY2hhcmFjdGVyJ3MgZmVldC4gIFN1YnRyYWN0IHRoZSBvZmZzZXQgYmVmb3JlIHNlbmRpbmcgdGhlIHBvc2l0aW9uCiAgICAgIC8vIGJhY2sgc28gdGhlIHZpc3VhbCBzdGF5cyBhdCB0aGUgZmVldCwgbm90IHRoZSBjYXBzdWxlIGNlbnRyZS4KICAgICAgLy8gU3VidHJhY3QgdGhlIG9yaWdpbiBvZmZzZXQgc28gdGhlIHBvc2l0aW9uIG1hcHMgYmFjayB0byBtb2RlbC1vcmlnaW4KICAgICAgLy8gc3BhY2UgKHRoZSB2aXN1YWwncyB0cmFuc2Zvcm0gb3JpZ2luKSwgbm90IHRoZSBBQUJCIGNlbnRyZS4KICAgICAgY29uc3Qgb2ZmID0gYm9keS5fb3JpZ2luT2Zmc2V0IHx8IHsKICAgICAgICB4OiAwLAogICAgICAgIHk6IDAsCiAgICAgICAgejogMAogICAgICB9OwogICAgICBjb25zdCBhZGp1c3RlZE9yaWdpbiA9IG5ldyBBbW1vLmJ0VmVjdG9yMyhvcmlnaW4ueCgpIC0gb2ZmLngsIG9yaWdpbi55KCkgLSBvZmYueSwgb3JpZ2luLnooKSAtIG9mZi56KTsKICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBhZGp1c3RlZE9yaWdpbiwgcm90YXRpb24sIGR0LCB7CiAgICAgICAgZ3JvdW5kZWQKICAgICAgfSk7CiAgICAgIEFtbW8uZGVzdHJveShhZGp1c3RlZE9yaWdpbik7CiAgICB9OwoKICAgIGNvbnN0IHJlcXVlc3ROZXh0RnJhbWUgPSBzZWxmLnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBzZWxmLm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgc2VsZi5tc1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIF9lbGVtZW50KSB7CiAgICAgIHNlbGYuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDEyMCk7CiAgICB9OwogICAgbGV0IENsb2NrID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHsKICAgICAgZnVuY3Rpb24gQ2xvY2soKSB7CiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENsb2NrKTsKICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIF9jcmVhdGVDbGFzcyhDbG9jaywgW3sKICAgICAgICBrZXk6ICJnZXREZWx0YSIsCiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldERlbHRhKCkgewogICAgICAgICAgY29uc3QgdGltZSA9IERhdGUubm93KCk7CiAgICAgICAgICBpZiAodGhpcy50aW1lc3RhbXApIHsKICAgICAgICAgICAgY29uc3QgZGVsdGEgPSB0aW1lIC0gdGhpcy50aW1lc3RhbXA7CiAgICAgICAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZTsKICAgICAgICAgICAgcmV0dXJuIGRlbHRhOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH1dKTsKICAgIH0oKTsKICAgIGxldCBXb3JsZCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7CiAgICAgIGZ1bmN0aW9uIFdvcmxkKCkgewogICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBXb3JsZCk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJpbml0Iiwgb3B0aW9ucyA9PiB7CiAgICAgICAgICBjb25zdCB7CiAgICAgICAgICAgIGdyYXZpdHkgPSBHUkFWSVRZCiAgICAgICAgICB9ID0gb3B0aW9uczsKICAgICAgICAgIHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbiA9IG5ldyBBbW1vLmJ0RGVmYXVsdENvbGxpc2lvbkNvbmZpZ3VyYXRpb24oKTsKICAgICAgICAgIHRoaXMuZGlzcGF0Y2hlciA9IG5ldyBBbW1vLmJ0Q29sbGlzaW9uRGlzcGF0Y2hlcih0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24pOwogICAgICAgICAgdGhpcy5icm9hZHBoYXNlID0gbmV3IEFtbW8uYnREYnZ0QnJvYWRwaGFzZSgpOwogICAgICAgICAgdGhpcy5zb2x2ZXIgPSBuZXcgQW1tby5idFNlcXVlbnRpYWxJbXB1bHNlQ29uc3RyYWludFNvbHZlcigpOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkID0gbmV3IEFtbW8uYnREaXNjcmV0ZUR5bmFtaWNzV29ybGQodGhpcy5kaXNwYXRjaGVyLCB0aGlzLmJyb2FkcGhhc2UsIHRoaXMuc29sdmVyLCB0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24pOwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLnNldEdyYXZpdHkobmV3IEFtbW8uYnRWZWN0b3IzKGdyYXZpdHkueCwgZ3Jhdml0eS55LCBncmF2aXR5LnopKTsKCiAgICAgICAgICAvLyB0aGlzIGlzIG5lZWRlZCBmb3IgZ2hvc3RPYmplY3QgY29sbGlzaW9ucwogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmdldEJyb2FkcGhhc2UoKS5nZXRPdmVybGFwcGluZ1BhaXJDYWNoZSgpLnNldEludGVybmFsR2hvc3RQYWlyQ2FsbGJhY2sobmV3IEFtbW8uYnRHaG9zdFBhaXJDYWxsYmFjaygpKTsKICAgICAgICAgIHRoaXMuaW5pdGlhbGlzZWQgPSB0cnVlOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAicmVtb3ZlRWxlbWVudCIsIHV1aWQgPT4gewogICAgICAgICAgaWYgKHRoaXMuaGFzRWxlbWVudCh1dWlkKSkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnRzW3V1aWRdLmRlbGV0ZWQgPSB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAicmVtb3ZlRGVsZXRlZEVsZW1lbnRzIiwgKCkgPT4gT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuZmlsdGVyKHV1aWQgPT4gdGhpcy5lbGVtZW50c1t1dWlkXS5kZWxldGVkKS5mb3JFYWNoKHV1aWQgPT4gewogICAgICAgICAgZGVsZXRlIHRoaXMuZWxlbWVudHNbdXVpZF07CiAgICAgICAgfSkpOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiaGFzRWxlbWVudCIsIHV1aWQgPT4gewogICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmluY2x1ZGVzKHV1aWQpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAiZ2V0RWxlbWVudCIsIHV1aWQgPT4gdGhpcy5lbGVtZW50c1t1dWlkXSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJpc0luaXRpYWxpc2VkIiwgKCkgPT4gdGhpcy5pbml0aWFsaXNlZCk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJnZXREeW5hbWljc1dvcmxkIiwgKCkgPT4gdGhpcy5keW5hbWljc1dvcmxkKTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZFJpZ2lkQm9keSIsIGJvZHkgPT4gewogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmFkZFJpZ2lkQm9keShib2R5KTsKICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZEFjdGlvbiIsIGFjdGlvbiA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuYWRkQWN0aW9uKGFjdGlvbik7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJhZGRDb2xsaXNpb25PYmplY3QiLCBjb2xsaXNpb25PYmplY3QgPT4gewogICAgICAgICAgdGhpcy5keW5hbWljc1dvcmxkLmFkZENvbGxpc2lvbk9iamVjdChjb2xsaXNpb25PYmplY3QpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic3RlcFNpbXVsYXRpb24iLCBkdCA9PiB7CiAgICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQuc3RlcFNpbXVsYXRpb24oZHQpOwogICAgICAgIH0pOwogICAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCAic2ltdWxhdGUiLCAoKSA9PiB7CiAgICAgICAgICBjb25zdCBkdCA9IHRoaXMuY2xvY2suZ2V0RGVsdGEoKSAvIDEwMDA7CiAgICAgICAgICB0aGlzLnN0ZXBTaW11bGF0aW9uKGR0KTsKICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmZvckVhY2godXVpZCA9PiB7CiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQodXVpZCk7CiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgICAgc3dpdGNoIChlbGVtZW50LnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuQk9YOgogICAgICAgICAgICAgICAgY2FzZSBUWVBFUy5TUEhFUkU6CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVTLk1FU0g6CiAgICAgICAgICAgICAgICAgIGhhbmRsZUVsZW1lbnRVcGRhdGUoZWxlbWVudCwgZHQpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuUExBWUVSOgogICAgICAgICAgICAgICAgICBoYW5kbGVQbGF5ZXJVcGRhdGUoZWxlbWVudCwgZHQpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVMuVkVISUNMRToKICAgICAgICAgICAgICAgICAgaGFuZGxlVmVoaWNsZVVwZGF0ZShlbGVtZW50LCBkdCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICB0aGlzLmNhbGN1bGF0ZUNvbGxpc2lvbnMoKTsKICAgICAgICAgIHRoaXMucmVtb3ZlRGVsZXRlZEVsZW1lbnRzKCk7CiAgICAgICAgICBkaXNwYXRjaGVyLnNlbmRQaHlzaWNzVXBkYXRlKGR0KTsKICAgICAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0TmV4dEZyYW1lKHRoaXMuc2ltdWxhdGUuYmluZCh0aGlzKSk7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJjYWxjdWxhdGVDb2xsaXNpb25zIiwgKCkgPT4gewogICAgICAgICAgbGV0IGFtbW9EaXNwYXRjaGVyID0gdGhpcy5keW5hbWljc1dvcmxkLmdldERpc3BhdGNoZXIoKTsKICAgICAgICAgIGxldCBudW1NYW5pZm9sZHMgPSBhbW1vRGlzcGF0Y2hlci5nZXROdW1NYW5pZm9sZHMoKTsKICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtTWFuaWZvbGRzOyBpKyspIHsKICAgICAgICAgICAgbGV0IGNvbnRhY3RNYW5pZm9sZCA9IGFtbW9EaXNwYXRjaGVyLmdldE1hbmlmb2xkQnlJbmRleEludGVybmFsKGkpOwogICAgICAgICAgICBsZXQgcmIwID0gQW1tby5jYXN0T2JqZWN0KGNvbnRhY3RNYW5pZm9sZC5nZXRCb2R5MCgpLCBBbW1vLmJ0UmlnaWRCb2R5KTsKICAgICAgICAgICAgbGV0IHJiMSA9IEFtbW8uY2FzdE9iamVjdChjb250YWN0TWFuaWZvbGQuZ2V0Qm9keTEoKSwgQW1tby5idFJpZ2lkQm9keSk7CiAgICAgICAgICAgIGxldCBudW1Db250YWN0cyA9IGNvbnRhY3RNYW5pZm9sZC5nZXROdW1Db250YWN0cygpOwoKICAgICAgICAgICAgLy8gdGhpcyBpdGVyYXRpb24gZG9lc24ndCBoYXZlIHV1aWRzCiAgICAgICAgICAgIGlmICghcmIwLnV1aWQgfHwgIXJiMS51dWlkKSBjb250aW51ZTsKICAgICAgICAgICAgbGV0IGNvbnRhY3RzID0gW107CiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbnVtQ29udGFjdHM7IGorKykgewogICAgICAgICAgICAgIGxldCBjb250YWN0UG9pbnQgPSBjb250YWN0TWFuaWZvbGQuZ2V0Q29udGFjdFBvaW50KGopOwogICAgICAgICAgICAgIGxldCBkaXN0YW5jZSA9IGNvbnRhY3RQb2ludC5nZXREaXN0YW5jZSgpOwogICAgICAgICAgICAgIGlmIChkaXN0YW5jZSA+IDAuMCkgY29udGludWU7CiAgICAgICAgICAgICAgbGV0IHZlbG9jaXR5MCA9IHJiMC5nZXRMaW5lYXJWZWxvY2l0eSgpOwogICAgICAgICAgICAgIGxldCB2ZWxvY2l0eTEgPSByYjEuZ2V0TGluZWFyVmVsb2NpdHkoKTsKICAgICAgICAgICAgICBsZXQgd29ybGRQb3MwID0gY29udGFjdFBvaW50LmdldF9tX3Bvc2l0aW9uV29ybGRPbkEoKTsKICAgICAgICAgICAgICBsZXQgd29ybGRQb3MxID0gY29udGFjdFBvaW50LmdldF9tX3Bvc2l0aW9uV29ybGRPbkIoKTsKICAgICAgICAgICAgICBsZXQgbG9jYWxQb3MwID0gY29udGFjdFBvaW50LmdldF9tX2xvY2FsUG9pbnRBKCk7CiAgICAgICAgICAgICAgbGV0IGxvY2FsUG9zMSA9IGNvbnRhY3RQb2ludC5nZXRfbV9sb2NhbFBvaW50QigpOwogICAgICAgICAgICAgIGNvbnRhY3RzLnB1c2goewogICAgICAgICAgICAgICAgZGlzdGFuY2UsCiAgICAgICAgICAgICAgICBlbGVtZW50czogW3sKICAgICAgICAgICAgICAgICAgdXVpZDogcmIwLnV1aWQsCiAgICAgICAgICAgICAgICAgIHZlbG9jaXR5OiB7CiAgICAgICAgICAgICAgICAgICAgeDogdmVsb2NpdHkwLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiB2ZWxvY2l0eTAueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IHZlbG9jaXR5MC56KCkKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgd29ybGRQb3M6IHsKICAgICAgICAgICAgICAgICAgICB4OiB3b3JsZFBvczAueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHdvcmxkUG9zMC55KCksCiAgICAgICAgICAgICAgICAgICAgejogd29ybGRQb3MwLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICBsb2NhbFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IGxvY2FsUG9zMC54KCksCiAgICAgICAgICAgICAgICAgICAgeTogbG9jYWxQb3MwLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiBsb2NhbFBvczAueigpCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgICAgdXVpZDogcmIxLnV1aWQsCiAgICAgICAgICAgICAgICAgIHZlbG9jaXR5OiB7CiAgICAgICAgICAgICAgICAgICAgeDogdmVsb2NpdHkxLngoKSwKICAgICAgICAgICAgICAgICAgICB5OiB2ZWxvY2l0eTEueSgpLAogICAgICAgICAgICAgICAgICAgIHo6IHZlbG9jaXR5MS56KCkKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgd29ybGRQb3M6IHsKICAgICAgICAgICAgICAgICAgICB4OiB3b3JsZFBvczEueCgpLAogICAgICAgICAgICAgICAgICAgIHk6IHdvcmxkUG9zMS55KCksCiAgICAgICAgICAgICAgICAgICAgejogd29ybGRQb3MxLnooKQogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICBsb2NhbFBvczogewogICAgICAgICAgICAgICAgICAgIHg6IGxvY2FsUG9zMS54KCksCiAgICAgICAgICAgICAgICAgICAgeTogbG9jYWxQb3MxLnkoKSwKICAgICAgICAgICAgICAgICAgICB6OiBsb2NhbFBvczEueigpCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH1dCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRGlzcGF0Y2hFdmVudChyYjAudXVpZCwgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5DT0xMSVNJT04sIHsKICAgICAgICAgICAgICBjb250YWN0cwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgZGlzcGF0Y2hlci5zZW5kRGlzcGF0Y2hFdmVudChyYjEudXVpZCwgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5DT0xMSVNJT04sIHsKICAgICAgICAgICAgICBjb250YWN0cwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgImFkZEVsZW1lbnQiLCBkYXRhID0+IHsKICAgICAgICAgIHRoaXMuZWxlbWVudHNbZGF0YS51dWlkXSA9IGRhdGE7CiAgICAgICAgfSk7CiAgICAgICAgX2RlZmluZVByb3BlcnR5KHRoaXMsICJ1cGRhdGVCb2R5U3RhdGUiLCAoewogICAgICAgICAgdXVpZCwKICAgICAgICAgIHN0YXRlCiAgICAgICAgfSkgPT4gewogICAgICAgICAgaWYgKHRoaXMuaGFzRWxlbWVudCh1dWlkKSkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnRzW3V1aWRdLnN0YXRlID0gewogICAgICAgICAgICAgIC4uLnRoaXMuZWxlbWVudHNbdXVpZF0uc3RhdGUsCiAgICAgICAgICAgICAgLi4uc3RhdGUKICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgInRlcm1pbmF0ZSIsICgpID0+IHsKICAgICAgICAgIEFtbW8uZGVzdHJveSh0aGlzLmR5bmFtaWNzV29ybGQpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuc29sdmVyKTsKICAgICAgICAgIEFtbW8uZGVzdHJveSh0aGlzLmRpc3BhdGNoZXIpOwogICAgICAgICAgQW1tby5kZXN0cm95KHRoaXMuY29sbGlzaW9uQ29uZmlndXJhdGlvbik7CiAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZUlkKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZFRlcm1pbmF0ZUV2ZW50KCk7CiAgICAgICAgfSk7CiAgICAgICAgdGhpcy5lbGVtZW50cyA9IHt9OwogICAgICAgIHRoaXMuaW5pdGlhbGlzZWQgPSBmYWxzZTsKICAgICAgICB0aGlzLmNvbGxpc2lvbkNvbmZpZ3VyYXRpb24gPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5kaXNwYXRjaGVyID0gdW5kZWZpbmVkOwogICAgICAgIHRoaXMuYnJvYWRwaGFzZSA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLnNvbHZlciA9IHVuZGVmaW5lZDsKICAgICAgICB0aGlzLmR5bmFtaWNzV29ybGQgPSB1bmRlZmluZWQ7CiAgICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWVJZCA9IG51bGw7CiAgICAgICAgdGhpcy5jbG9jayA9IG5ldyBDbG9jaygpOwogICAgICB9CiAgICAgIHJldHVybiBfY3JlYXRlQ2xhc3MoV29ybGQsIFt7CiAgICAgICAga2V5OiAiZGlzcG9zZUJvZHkiLAogICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNwb3NlQm9keSh7CiAgICAgICAgICB1dWlkCiAgICAgICAgfSkgewogICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICAgIHRoaXMuZHluYW1pY3NXb3JsZC5yZW1vdmVSaWdpZEJvZHkoZWxlbWVudC5ib2R5KTsKICAgICAgICAgIHRoaXMucmVtb3ZlRWxlbWVudCh1dWlkKTsKICAgICAgICAgIGRpc3BhdGNoZXIuc2VuZEVsZW1lbnREaXNwb3NlZCh7CiAgICAgICAgICAgIHV1aWQKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfV0pOwogICAgfSgpOwogICAgdmFyIHdvcmxkID0gbmV3IFdvcmxkKCk7CgogICAgY29uc3QgREVGQVVMVF9ST0xMX0lORkxVRU5DRSA9IDAuMjsKICAgIGNvbnN0IERFRkFVTFRfRlJJQ1RJT04gPSAxMDAwOwogICAgY29uc3QgREVGQVVMVF9NQVNTID0gODAwOwogICAgY29uc3QgYWRkVmVoaWNsZSA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgcG9zaXRpb24sCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICB1dWlkLAogICAgICAgIHdoZWVscywKICAgICAgICBtYXNzID0gREVGQVVMVF9NQVNTLAogICAgICAgIHdpZHRoID0gMS44LAogICAgICAgIGhlaWdodCA9IDAuNiwKICAgICAgICBsZW5ndGggPSA0LAogICAgICAgIGZyaWN0aW9uID0gREVGQVVMVF9GUklDVElPTiwKICAgICAgICByb2xsSW5mbHVlbmNlID0gREVGQVVMVF9ST0xMX0lORkxVRU5DRSwKICAgICAgICB3aGVlbHNPcHRpb25zID0ge30sCiAgICAgICAgc3VzcGVuc2lvbnMgPSB7fQogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgewogICAgICAgIGJhY2sgPSB7fSwKICAgICAgICBmcm9udCA9IHt9CiAgICAgIH0gPSB3aGVlbHNPcHRpb25zOwogICAgICBjb25zdCB7CiAgICAgICAgYXhpc1Bvc2l0aW9uOiBheGlzUG9zaXRpb25CYWNrID0gLTEsCiAgICAgICAgcmFkaXVzOiB3aGVlbFJhZGl1c0JhY2sgPSAwLjQsCiAgICAgICAgaGFsZlRyYWNrOiB3aGVlbEhhbGZUcmFja0JhY2sgPSAxLAogICAgICAgIGF4aXNIZWlnaHQ6IHdoZWVsQXhpc0hlaWdodEJhY2sgPSAwLjMKICAgICAgfSA9IGJhY2s7CiAgICAgIGNvbnN0IHsKICAgICAgICBheGlzUG9zaXRpb246IGF4aXNQb3NpdGlvbkZyb250ID0gMS43LAogICAgICAgIHJhZGl1czogd2hlZWxSYWRpdXNGcm9udCA9IDAuNCwKICAgICAgICBoYWxmVHJhY2s6IHdoZWVsSGFsZlRyYWNrRnJvbnQgPSAxLAogICAgICAgIGF4aXNIZWlnaHQ6IHdoZWVsQXhpc0hlaWdodEZyb250ID0gMC4zCiAgICAgIH0gPSBmcm9udDsKICAgICAgY29uc3QgewogICAgICAgIHN0aWZmbmVzcyA9IDIwLjAsCiAgICAgICAgZGFtcGluZyA9IDIuMywKICAgICAgICBjb21wcmVzc2lvbiA9IDQuNCwKICAgICAgICByZXN0TGVuZ3RoID0gMC42CiAgICAgIH0gPSBzdXNwZW5zaW9uczsKCiAgICAgIC8vIENoYXNzaXMKICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQW1tby5idEJveFNoYXBlKG5ldyBBbW1vLmJ0VmVjdG9yMyh3aWR0aCAqIDAuNSwgaGVpZ2h0ICogMC41LCBsZW5ndGggKiAwLjUpKTsKICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgdHJhbnNmb3JtLnNldElkZW50aXR5KCk7CiAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgY29uc3QgbW90aW9uU3RhdGUgPSBuZXcgQW1tby5idERlZmF1bHRNb3Rpb25TdGF0ZSh0cmFuc2Zvcm0pOwogICAgICBjb25zdCBsb2NhbEluZXJ0aWEgPSBuZXcgQW1tby5idFZlY3RvcjMoMCwgMCwgMCk7CiAgICAgIGdlb21ldHJ5LmNhbGN1bGF0ZUxvY2FsSW5lcnRpYShtYXNzLCBsb2NhbEluZXJ0aWEpOwogICAgICBjb25zdCBjaGFzc2lzID0gbmV3IEFtbW8uYnRSaWdpZEJvZHkobmV3IEFtbW8uYnRSaWdpZEJvZHlDb25zdHJ1Y3Rpb25JbmZvKG1hc3MsIG1vdGlvblN0YXRlLCBnZW9tZXRyeSwgbG9jYWxJbmVydGlhKSk7CiAgICAgIGNoYXNzaXMuc2V0QWN0aXZhdGlvblN0YXRlKERJU0FCTEVfREVBQ1RJVkFUSU9OKTsKICAgICAgd29ybGQuYWRkUmlnaWRCb2R5KGNoYXNzaXMpOwoKICAgICAgLy8gUmF5Y2FzdCBWZWhpY2xlCiAgICAgIGNvbnN0IHR1bmluZyA9IG5ldyBBbW1vLmJ0VmVoaWNsZVR1bmluZygpOwogICAgICBjb25zdCByYXlDYXN0ZXIgPSBuZXcgQW1tby5idERlZmF1bHRWZWhpY2xlUmF5Y2FzdGVyKHdvcmxkLmdldER5bmFtaWNzV29ybGQoKSk7CiAgICAgIGNvbnN0IHZlaGljbGUgPSBuZXcgQW1tby5idFJheWNhc3RWZWhpY2xlKHR1bmluZywgY2hhc3NpcywgcmF5Q2FzdGVyKTsKICAgICAgdmVoaWNsZS5zZXRDb29yZGluYXRlU3lzdGVtKDAsIDEsIDIpOwogICAgICB3b3JsZC5hZGRBY3Rpb24odmVoaWNsZSk7CiAgICAgIGNvbnN0IHdoZWVsRGlyZWN0aW9uQ1MwID0gbmV3IEFtbW8uYnRWZWN0b3IzKDAsIC0xLCAwKTsKICAgICAgY29uc3Qgd2hlZWxBeGxlQ1MgPSBuZXcgQW1tby5idFZlY3RvcjMoLTEsIDAsIDApOwogICAgICBjb25zdCBhZGRXaGVlbCA9IChpc0Zyb250LCBwb3MsIHJhZGl1cykgPT4gewogICAgICAgIHZhciB3aGVlbEluZm8gPSB2ZWhpY2xlLmFkZFdoZWVsKHBvcywgd2hlZWxEaXJlY3Rpb25DUzAsIHdoZWVsQXhsZUNTLCByZXN0TGVuZ3RoLCByYWRpdXMsIHR1bmluZywgaXNGcm9udCk7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3N1c3BlbnNpb25TdGlmZm5lc3Moc3RpZmZuZXNzKTsKICAgICAgICB3aGVlbEluZm8uc2V0X21fd2hlZWxzRGFtcGluZ1JlbGF4YXRpb24oZGFtcGluZyk7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3doZWVsc0RhbXBpbmdDb21wcmVzc2lvbihjb21wcmVzc2lvbik7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX2ZyaWN0aW9uU2xpcChmcmljdGlvbik7CiAgICAgICAgd2hlZWxJbmZvLnNldF9tX3JvbGxJbmZsdWVuY2Uocm9sbEluZmx1ZW5jZSk7CiAgICAgIH07CiAgICAgIGFkZFdoZWVsKHRydWUsIG5ldyBBbW1vLmJ0VmVjdG9yMyh3aGVlbEhhbGZUcmFja0Zyb250LCB3aGVlbEF4aXNIZWlnaHRGcm9udCwgYXhpc1Bvc2l0aW9uRnJvbnQpLCB3aGVlbFJhZGl1c0Zyb250KTsKICAgICAgYWRkV2hlZWwodHJ1ZSwgbmV3IEFtbW8uYnRWZWN0b3IzKC13aGVlbEhhbGZUcmFja0Zyb250LCB3aGVlbEF4aXNIZWlnaHRGcm9udCwgYXhpc1Bvc2l0aW9uRnJvbnQpLCB3aGVlbFJhZGl1c0Zyb250KTsKICAgICAgYWRkV2hlZWwoZmFsc2UsIG5ldyBBbW1vLmJ0VmVjdG9yMygtd2hlZWxIYWxmVHJhY2tCYWNrLCB3aGVlbEF4aXNIZWlnaHRCYWNrLCBheGlzUG9zaXRpb25CYWNrKSwgd2hlZWxSYWRpdXNCYWNrKTsKICAgICAgYWRkV2hlZWwoZmFsc2UsIG5ldyBBbW1vLmJ0VmVjdG9yMyh3aGVlbEhhbGZUcmFja0JhY2ssIHdoZWVsQXhpc0hlaWdodEJhY2ssIGF4aXNQb3NpdGlvbkJhY2spLCB3aGVlbFJhZGl1c0JhY2spOwogICAgICB2ZWhpY2xlLnV1aWQgPSB1dWlkOwogICAgICB3b3JsZC5hZGRFbGVtZW50KHsKICAgICAgICB0eXBlOiBUWVBFUy5WRUhJQ0xFLAogICAgICAgIHV1aWQsCiAgICAgICAgdmVoaWNsZTogdmVoaWNsZSwKICAgICAgICB3aGVlbHMsCiAgICAgICAgb3B0aW9uczogZGF0YSwKICAgICAgICBzdGF0ZTogREVGQVVMVF9WRUhJQ0xFX1NUQVRFCiAgICAgIH0pOwogICAgfTsKICAgIGNvbnN0IHNldFZlaGljbGVQb3NpdGlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFRZUEVTLlZFSElDTEUpIHsKICAgICAgICBjb25zdCBib2R5ID0gZWxlbWVudC52ZWhpY2xlLmdldFJpZ2lkQm9keSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCBzZXRWZWhpY2xlUXVhdGVybmlvbiA9IGRhdGEgPT4gewogICAgICBjb25zdCB7CiAgICAgICAgdXVpZCwKICAgICAgICBxdWF0ZXJuaW9uCiAgICAgIH0gPSBkYXRhOwogICAgICBjb25zdCBlbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gVFlQRVMuVkVISUNMRSkgewogICAgICAgIGNvbnN0IGJvZHkgPSBlbGVtZW50LnZlaGljbGUuZ2V0UmlnaWRCb2R5KCk7CiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gbmV3IEFtbW8uYnRUcmFuc2Zvcm0oKTsKICAgICAgICBib2R5LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgdHJhbnNmb3JtLnNldFJvdGF0aW9uKG5ldyBBbW1vLmJ0UXVhdGVybmlvbihxdWF0ZXJuaW9uLngsIHF1YXRlcm5pb24ueSwgcXVhdGVybmlvbi56LCBxdWF0ZXJuaW9uLncpKTsKICAgICAgICBib2R5LnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCByZXNldFZlaGljbGUgPSBkYXRhID0+IHsKICAgICAgY29uc3QgewogICAgICAgIHV1aWQsCiAgICAgICAgcXVhdGVybmlvbiwKICAgICAgICBwb3NpdGlvbgogICAgICB9ID0gZGF0YTsKICAgICAgY29uc3QgZWxlbWVudCA9IHdvcmxkLmdldEVsZW1lbnQodXVpZCk7CiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFRZUEVTLlZFSElDTEUpIHsKICAgICAgICBjb25zdCBib2R5ID0gZWxlbWVudC52ZWhpY2xlLmdldFJpZ2lkQm9keSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgYm9keS5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICAgIHRyYW5zZm9ybS5zZXRJZGVudGl0eSgpOwogICAgICAgIHRyYW5zZm9ybS5zZXRPcmlnaW4obmV3IEFtbW8uYnRWZWN0b3IzKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnopKTsKICAgICAgICB0cmFuc2Zvcm0uc2V0Um90YXRpb24obmV3IEFtbW8uYnRRdWF0ZXJuaW9uKHF1YXRlcm5pb24ueCwgcXVhdGVybmlvbi55LCBxdWF0ZXJuaW9uLnosIHF1YXRlcm5pb24udykpOwogICAgICAgIGJvZHkuc2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGhhbmRsZVZlaGljbGVVcGRhdGUgPSAoewogICAgICB2ZWhpY2xlLAogICAgICB3aGVlbHMsCiAgICAgIHV1aWQsCiAgICAgIHN0YXRlID0gREVGQVVMVF9WRUhJQ0xFX1NUQVRFLAogICAgICBvcHRpb25zID0ge30KICAgIH0sIGR0KSA9PiB7CiAgICAgIGxldCBicmVha2luZ0ZvcmNlID0gMDsKICAgICAgbGV0IGVuZ2luZUZvcmNlID0gMDsKICAgICAgY29uc3QgewogICAgICAgIHN0ZWVyaW5nQ2xhbXAgPSBERUZBVUxUX1NURUVSSU5HX0NMQU1QLAogICAgICAgIHN0ZWVyaW5nSW5jcmVtZW50ID0gREVGQVVMVF9TVEVFUklOR19JTkNSRU1FTlQsCiAgICAgICAgbWF4RW5naW5lRm9yY2UgPSBERUZBVUxUX01BWF9FTkdJTkVfRk9SQ0UsCiAgICAgICAgbWF4QnJlYWtpbmdGb3JjZSA9IERFRkFVTFRfTUFYX0JSRUFLSU5HX0ZPUkNFCiAgICAgIH0gPSBvcHRpb25zOwogICAgICBpZiAoc3RhdGUuYWNjZWxlcmF0aW9uKSB7CiAgICAgICAgaWYgKHNwZWVkIDwgLTEpIGJyZWFraW5nRm9yY2UgPSBtYXhCcmVha2luZ0ZvcmNlO2Vsc2UgZW5naW5lRm9yY2UgPSBtYXhFbmdpbmVGb3JjZTsKICAgICAgfQogICAgICBpZiAoc3RhdGUuYnJha2luZykgewogICAgICAgIGlmIChzcGVlZCA+IDEpIGJyZWFraW5nRm9yY2UgPSBtYXhCcmVha2luZ0ZvcmNlO2Vsc2UgZW5naW5lRm9yY2UgPSAtbWF4RW5naW5lRm9yY2UgLyAyOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS5sZWZ0KSB7CiAgICAgICAgaWYgKHN0YXRlLnZlaGljbGVTdGVlcmluZyA8IHN0ZWVyaW5nQ2xhbXApIHN0YXRlLnZlaGljbGVTdGVlcmluZyArPSBzdGVlcmluZ0luY3JlbWVudDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RhdGUucmlnaHQpIHsKICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPiAtc3RlZXJpbmdDbGFtcCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nIC09IHN0ZWVyaW5nSW5jcmVtZW50OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc3RhdGUudmVoaWNsZVN0ZWVyaW5nIDwgLXN0ZWVyaW5nSW5jcmVtZW50KSBzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgKz0gc3RlZXJpbmdJbmNyZW1lbnQ7ZWxzZSB7CiAgICAgICAgICAgIGlmIChzdGF0ZS52ZWhpY2xlU3RlZXJpbmcgPiBzdGVlcmluZ0luY3JlbWVudCkgc3RhdGUudmVoaWNsZVN0ZWVyaW5nIC09IHN0ZWVyaW5nSW5jcmVtZW50O2Vsc2UgewogICAgICAgICAgICAgIHN0YXRlLnZlaGljbGVTdGVlcmluZyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgdmVoaWNsZS5hcHBseUVuZ2luZUZvcmNlKGVuZ2luZUZvcmNlLCBCQUNLX0xFRlQpOwogICAgICB2ZWhpY2xlLmFwcGx5RW5naW5lRm9yY2UoZW5naW5lRm9yY2UsIEJBQ0tfUklHSFQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UgLyAyLCBGUk9OVF9MRUZUKTsKICAgICAgdmVoaWNsZS5zZXRCcmFrZShicmVha2luZ0ZvcmNlIC8gMiwgRlJPTlRfUklHSFQpOwogICAgICB2ZWhpY2xlLnNldEJyYWtlKGJyZWFraW5nRm9yY2UsIEJBQ0tfTEVGVCk7CiAgICAgIHZlaGljbGUuc2V0QnJha2UoYnJlYWtpbmdGb3JjZSwgQkFDS19SSUdIVCk7CiAgICAgIHZlaGljbGUuc2V0U3RlZXJpbmdWYWx1ZShzdGF0ZS52ZWhpY2xlU3RlZXJpbmcsIEZST05UX0xFRlQpOwogICAgICB2ZWhpY2xlLnNldFN0ZWVyaW5nVmFsdWUoc3RhdGUudmVoaWNsZVN0ZWVyaW5nLCBGUk9OVF9SSUdIVCk7CiAgICAgIGxldCB0bSwgcCwgcSwgaTsKICAgICAgY29uc3QgbiA9IHZlaGljbGUuZ2V0TnVtV2hlZWxzKCk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB2ZWhpY2xlLnVwZGF0ZVdoZWVsVHJhbnNmb3JtKGksIHRydWUpOwogICAgICAgIHRtID0gdmVoaWNsZS5nZXRXaGVlbFRyYW5zZm9ybVdTKGkpOwogICAgICAgIHAgPSB0bS5nZXRPcmlnaW4oKTsKICAgICAgICBxID0gdG0uZ2V0Um90YXRpb24oKTsKICAgICAgICBjb25zdCB3aGVlbFVVSUQgPSB3aGVlbHNbaV07CiAgICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh3aGVlbFVVSUQsIHAsIHEsIGR0KTsKICAgICAgfQogICAgICB0bSA9IHZlaGljbGUuZ2V0Q2hhc3Npc1dvcmxkVHJhbnNmb3JtKCk7CiAgICAgIHAgPSB0bS5nZXRPcmlnaW4oKTsKICAgICAgcSA9IHRtLmdldFJvdGF0aW9uKCk7CiAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IHZlaGljbGUuZ2V0Rm9yd2FyZFZlY3RvcigpOwogICAgICBjb25zdCBzcGVlZCA9IHZlaGljbGUuZ2V0Q3VycmVudFNwZWVkS21Ib3VyKCk7CiAgICAgIGNvbnN0IGV4dHJhRGF0YSA9IHsKICAgICAgICBkaXJlY3Rpb246IHsKICAgICAgICAgIHg6IGRpcmVjdGlvbi54KCksCiAgICAgICAgICB5OiBkaXJlY3Rpb24ueSgpLAogICAgICAgICAgejogZGlyZWN0aW9uLnooKQogICAgICAgIH0sCiAgICAgICAgc3BlZWQKICAgICAgfTsKICAgICAgZGlzcGF0Y2hlci5zZW5kQm9keVVwZGF0ZSh1dWlkLCBwLCBxLCBkdCwgZXh0cmFEYXRhKTsKICAgICAgd29ybGQudXBkYXRlQm9keVN0YXRlKHV1aWQsIHN0YXRlKTsKICAgIH07CgogICAgY29uc3QgY3JlYXRlR2hvc3RDb2xsaWRlciA9IChyYWRpdXMsIHBvc2l0aW9uKSA9PiB7CiAgICAgIGNvbnN0IGdob3N0Q29sbGlkZXIgPSBuZXcgQW1tby5idEdob3N0T2JqZWN0KCk7CiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgIGdob3N0Q29sbGlkZXIuc2V0Q29sbGlzaW9uU2hhcGUobmV3IEFtbW8uYnRTcGhlcmVTaGFwZShyYWRpdXMpKTsKICAgICAgZ2hvc3RDb2xsaWRlci5nZXRXb3JsZFRyYW5zZm9ybSh0cmFuc2Zvcm0pOwogICAgICB0cmFuc2Zvcm0uc2V0SWRlbnRpdHkoKTsKICAgICAgdHJhbnNmb3JtLnNldE9yaWdpbihwb3NpdGlvbik7CiAgICAgIHRyYW5zZm9ybS5zZXRSb3RhdGlvbihuZXcgQW1tby5idFF1YXRlcm5pb24oMCwgMCwgMCwgMSkpOwogICAgICBnaG9zdENvbGxpZGVyLnNldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgIHJldHVybiB7CiAgICAgICAgZ2hvc3RDb2xsaWRlciwKICAgICAgICB0cmFuc2Zvcm0KICAgICAgfTsKICAgIH07CiAgICBjb25zdCBmb3JFYWNoR2hvc3RDb2xsaXNpb24gPSAoZ2hvc3RDb2xsaWRlciwgZm9yRWFjaENhbGxiYWNrID0gKCkgPT4ge30pID0+IHsKICAgICAgY29uc3QgY29sbGlzaW9ucyA9IGdob3N0Q29sbGlkZXIuZ2V0TnVtT3ZlcmxhcHBpbmdPYmplY3RzKCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sbGlzaW9uczsgaSsrKSB7CiAgICAgICAgY29uc3Qgb2JqZWN0ID0gQW1tby5jYXN0T2JqZWN0KGdob3N0Q29sbGlkZXIuZ2V0T3ZlcmxhcHBpbmdPYmplY3QoaSksIEFtbW8uYnRSaWdpZEJvZHkpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgb2JqZWN0LmdldFdvcmxkVHJhbnNmb3JtKHRyYW5zZm9ybSk7CiAgICAgICAgZm9yRWFjaENhbGxiYWNrKG9iamVjdCwgdHJhbnNmb3JtLCBpKTsKICAgICAgICBBbW1vLmRlc3Ryb3kodHJhbnNmb3JtKTsKICAgICAgfQogICAgfTsKICAgIGNvbnN0IGdldEV4cGxvc2lvblBvc2l0aW9uID0gKHV1aWQsIHBvc2l0aW9uKSA9PiB7CiAgICAgIGxldCBleHBsb3Npb25Qb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICBpZiAoIWV4cGxvc2lvblBvc2l0aW9uKSB7CiAgICAgICAgY29uc3QgewogICAgICAgICAgYm9keQogICAgICAgIH0gPSB3b3JsZC5nZXRFbGVtZW50KHV1aWQpOwogICAgICAgIGNvbnN0IG1vdGlvblN0YXRlID0gYm9keS5nZXRNb3Rpb25TdGF0ZSgpOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBBbW1vLmJ0VHJhbnNmb3JtKCk7CiAgICAgICAgbW90aW9uU3RhdGUuZ2V0V29ybGRUcmFuc2Zvcm0odHJhbnNmb3JtKTsKICAgICAgICBleHBsb3Npb25Qb3NpdGlvbiA9IHRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgfQogICAgICByZXR1cm4gZXhwbG9zaW9uUG9zaXRpb247CiAgICB9OwogICAgY29uc3QgZ2V0RXhwbG9zaW9uSW1wdWxzZSA9IChwb3NpdGlvbiwgZXhwbG9zaW9uUG9zaXRpb24sIHN0cmVuZ3RoKSA9PiB7CiAgICAgIC8vIENhbGN1bGF0ZSBkaXJlY3Rpb24gdmVjdG9yIFdJVEhPVVQgbXV0YXRpbmcgdGhlIGlucHV0IGJ0VmVjdG9yMyBvYmplY3RzLgogICAgICAvLyBvcF9zdWIvb3BfbXVsIG11dGF0ZSBpbiBwbGFjZSBpbiBBbW1vLmpzLCB3aGljaCB3b3VsZCBjb3JydXB0IHRoZSBib2R5J3MgdHJhbnNmb3JtIG9yaWdpbi4KICAgICAgY29uc3QgZHggPSBwb3NpdGlvbi54KCkgLSBleHBsb3Npb25Qb3NpdGlvbi54KCk7CiAgICAgIGNvbnN0IGR5ID0gcG9zaXRpb24ueSgpIC0gZXhwbG9zaW9uUG9zaXRpb24ueSgpOwogICAgICBjb25zdCBkeiA9IHBvc2l0aW9uLnooKSAtIGV4cGxvc2lvblBvc2l0aW9uLnooKTsKICAgICAgbGV0IGxlbmd0aCA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSArIGR6ICogZHopOwoKICAgICAgLy8gSWYgdGhlIG9iamVjdCBpcyBhdCB0aGUgZXhwbG9zaW9uIGNlbnRlciwgcHVzaCBpdCBzdHJhaWdodCB1cCBpbnN0ZWFkIG9mCiAgICAgIC8vIHByb2R1Y2luZyBhbiB1bnN0YWJsZSBuZWFyLXplcm8gbm9ybWFsaXphdGlvbi4KICAgICAgaWYgKGxlbmd0aCA8IDAuMDAxKSB7CiAgICAgICAgY29uc3QgaW1wdWxzZSA9IG5ldyBBbW1vLmJ0VmVjdG9yMygwLCBzdHJlbmd0aCAqIDIsIDApOwogICAgICAgIHJldHVybiBpbXB1bHNlOwogICAgICB9CgogICAgICAvLyBOb3JtYWxpemUgZGlyZWN0aW9uCiAgICAgIGNvbnN0IG54ID0gZHggLyBsZW5ndGg7CiAgICAgIGNvbnN0IG55ID0gZHkgLyBsZW5ndGg7CiAgICAgIGNvbnN0IG56ID0gZHogLyBsZW5ndGg7CgogICAgICAvLyBTY2FsZSBieSBzdHJlbmd0aCBhbmQgYWRkIHVwd2FyZCBiaWFzCiAgICAgIGNvbnN0IGltcHVsc2UgPSBuZXcgQW1tby5idFZlY3RvcjMobnggKiBzdHJlbmd0aCwgbnkgKiBzdHJlbmd0aCArIHN0cmVuZ3RoLCBueiAqIHN0cmVuZ3RoKTsKICAgICAgcmV0dXJuIGltcHVsc2U7CiAgICB9OwogICAgY29uc3QgY3JlYXRlRXhwbG9zaW9uID0gKHsKICAgICAgdXVpZCwKICAgICAgcG9zaXRpb24sCiAgICAgIHJhZGl1cyA9IEVYUExPU0lPTl9TSVpFUy5TTUFMTCwKICAgICAgc3RyZW5ndGggPSBFWFBMT1NJT05fU1RSRU5HVEhTLk1FRElVTQogICAgfSkgPT4gewogICAgICB0cnkgewogICAgICAgIC8vIEdldCB0aGUgc291cmNlIGJvZHkncyBBbW1vIHBvaW50ZXIgc28gd2UgY2FuIHJlbGlhYmx5IHNraXAgaXQuCiAgICAgICAgLy8gQW1tby5jYXN0T2JqZWN0KCkgY3JlYXRlcyBuZXcgSlMgd3JhcHBlcnMsIHNvIGN1c3RvbSBwcm9wZXJ0aWVzIGxpa2UKICAgICAgICAvLyAudXVpZCBzZXQgb24gdGhlIG9yaWdpbmFsIHdyYXBwZXIgYXJlIE5PVCBhdmFpbGFibGUgb24gY2FzdCByZXN1bHRzLgogICAgICAgIC8vIFdlIGNvbXBhcmUgdGhlIHVuZGVybHlpbmcgQysrIHBvaW50ZXIgaW5zdGVhZC4KICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50ID0gd29ybGQuZ2V0RWxlbWVudCh1dWlkKTsKICAgICAgICBjb25zdCBzb3VyY2VCb2R5UHRyID0gc291cmNlRWxlbWVudCAmJiBzb3VyY2VFbGVtZW50LmJvZHkgPyBzb3VyY2VFbGVtZW50LmJvZHkuYSB8fCBzb3VyY2VFbGVtZW50LmJvZHkucHRyIDogbnVsbDsKICAgICAgICBjb25zdCBleHBsb3Npb25Qb3NpdGlvbiA9IGdldEV4cGxvc2lvblBvc2l0aW9uKHV1aWQsIHBvc2l0aW9uKTsKICAgICAgICBjb25zdCB7CiAgICAgICAgICBnaG9zdENvbGxpZGVyLAogICAgICAgICAgdHJhbnNmb3JtCiAgICAgICAgfSA9IGNyZWF0ZUdob3N0Q29sbGlkZXIocmFkaXVzLCBleHBsb3Npb25Qb3NpdGlvbik7CiAgICAgICAgd29ybGQuYWRkQ29sbGlzaW9uT2JqZWN0KGdob3N0Q29sbGlkZXIpOwoKICAgICAgICAvLyBGb3JjZSBhIGNvbGxpc2lvbiBkZXRlY3Rpb24gcGFzcyBzbyB0aGUgZ2hvc3QgY29sbGlkZXIgZGlzY292ZXJzCiAgICAgICAgLy8gb3ZlcmxhcHBpbmcgYm9kaWVzLiBXaXRob3V0IHRoaXMsIGdldE51bU92ZXJsYXBwaW5nT2JqZWN0cygpIHJldHVybnMgMAogICAgICAgIC8vIGJlY2F1c2UgYnRHaG9zdFBhaXJDYWxsYmFjayBvbmx5IHVwZGF0ZXMgZHVyaW5nIGEgc2ltdWxhdGlvbiBzdGVwLgogICAgICAgIHdvcmxkLmdldER5bmFtaWNzV29ybGQoKS5wZXJmb3JtRGlzY3JldGVDb2xsaXNpb25EZXRlY3Rpb24oKTsKICAgICAgICBmb3JFYWNoR2hvc3RDb2xsaXNpb24oZ2hvc3RDb2xsaWRlciwgKG9iamVjdCwgb2JqZWN0VHJhbnNmb3JtKSA9PiB7CiAgICAgICAgICAvLyBTa2lwIHRoZSBzb3VyY2UgZW50aXR5IHVzaW5nIHBvaW50ZXIgY29tcGFyaXNvbi4KICAgICAgICAgIGNvbnN0IG9iamVjdFB0ciA9IG9iamVjdC5hIHx8IG9iamVjdC5wdHI7CiAgICAgICAgICBpZiAoc291cmNlQm9keVB0ciAmJiBvYmplY3RQdHIgPT09IHNvdXJjZUJvZHlQdHIpIHJldHVybjsKICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IG9iamVjdFRyYW5zZm9ybS5nZXRPcmlnaW4oKTsKICAgICAgICAgIG9iamVjdC5hY3RpdmF0ZSh0cnVlKTsKICAgICAgICAgIGNvbnN0IGltcHVsc2UgPSBnZXRFeHBsb3Npb25JbXB1bHNlKG9yaWdpbiwgZXhwbG9zaW9uUG9zaXRpb24sIHN0cmVuZ3RoKTsKICAgICAgICAgIG9iamVjdC5hcHBseUNlbnRyYWxJbXB1bHNlKGltcHVsc2UpOwogICAgICAgICAgQW1tby5kZXN0cm95KGltcHVsc2UpOwogICAgICAgIH0pOwogICAgICAgIHdvcmxkLmdldER5bmFtaWNzV29ybGQoKS5yZW1vdmVDb2xsaXNpb25PYmplY3QoZ2hvc3RDb2xsaWRlcik7CiAgICAgICAgQW1tby5kZXN0cm95KGdob3N0Q29sbGlkZXIpOwogICAgICAgIEFtbW8uZGVzdHJveSh0cmFuc2Zvcm0pOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgY29uc29sZS5lcnJvcigiW1BoeXNpY3MgV29ya2VyXSBjcmVhdGVFeHBsb3Npb24gZXJyb3I6IiwgZSk7CiAgICAgIH0KICAgIH07CgogICAgY29uc3QgaGFuZGxlTG9hZEV2ZW50ID0gb3B0aW9ucyA9PiBBbW1vID0+IHsKICAgICAgc2VsZi5BbW1vID0gQW1tbzsKICAgICAgb25tZXNzYWdlID0gKHsKICAgICAgICBkYXRhCiAgICAgIH0pID0+IHsKICAgICAgICBzd2l0Y2ggKGRhdGEuZXZlbnQpIHsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELkJPWDoKICAgICAgICAgICAgYWRkQm94KGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlNQSEVSRToKICAgICAgICAgICAgYWRkU3BoZXJlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlZFSElDTEU6CiAgICAgICAgICAgIGFkZFZlaGljbGUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5BREQuTU9ERUw6CiAgICAgICAgICAgIGFkZE1vZGVsKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuQURELlBMQVlFUjoKICAgICAgICAgICAgYWRkUGxheWVyKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5TRVQuTElORUFSX1ZFTE9DSVRZOgogICAgICAgICAgICBzZXRMaW5lYXJWZWxvY2l0eShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuUkVTRVQ6CiAgICAgICAgICAgIHJlc2V0RWxlbWVudChkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuU0VULlBPU0lUSU9OOgogICAgICAgICAgICBzZXRQb3NpdGlvbihkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuU0VULlFVQVRFUk5JT046CiAgICAgICAgICAgIHNldFF1YXRlcm5pb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlNFVC5QT1NJVElPTjoKICAgICAgICAgICAgc2V0VmVoaWNsZVBvc2l0aW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuVkVISUNMRS5TRVQuUVVBVEVSTklPTjoKICAgICAgICAgICAgc2V0VmVoaWNsZVF1YXRlcm5pb24oZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5WRUhJQ0xFLlJFU0VUOgogICAgICAgICAgICByZXNldFZlaGljbGUoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FTEVNRU5ULkFQUExZLklNUFVMU0U6CiAgICAgICAgICAgIGFwcGx5SW1wdXNlKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuRUxFTUVOVC5VUERBVEU6CiAgICAgICAgICAgIHdvcmxkLnVwZGF0ZUJvZHlTdGF0ZShkYXRhKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkVMRU1FTlQuRElTUE9TRToKICAgICAgICAgICAgd29ybGQuZGlzcG9zZUJvZHkoZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBQSFlTSUNTX0VWRU5UUy5FRkZFQ1RTLkVYUExPU0lPTjoKICAgICAgICAgICAgY3JlYXRlRXhwbG9zaW9uKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgUEhZU0lDU19FVkVOVFMuVEVSTUlOQVRFOgogICAgICAgICAgICB3b3JsZC50ZXJtaW5hdGUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9OwogICAgICB3b3JsZC5pbml0KG9wdGlvbnMpOwogICAgICBkaXNwYXRjaGVyLnNlbmRSZWFkeUV2ZW50KCk7CiAgICAgIHdvcmxkLnNpbXVsYXRlKCk7CiAgICB9OwogICAgY29uc3QgbG9hZEFtbW8gPSBvcHRpb25zID0+IHsKICAgICAgY29uc3Qgc2NyaXB0VXJsID0gb3B0aW9ucy5ob3N0ICsgIi8iICsgKG9wdGlvbnMucGF0aCB8fCBMSUJSQVJZX05BTUUpOwogICAgICBpbXBvcnRTY3JpcHRzKHNjcmlwdFVybCk7CiAgICAgIEFtbW8oKS50aGVuKGhhbmRsZUxvYWRFdmVudChvcHRpb25zKSk7CiAgICB9OwogICAgb25tZXNzYWdlID0gKHsKICAgICAgZGF0YQogICAgfSkgPT4gewogICAgICBzd2l0Y2ggKGRhdGEuZXZlbnQpIHsKICAgICAgICBjYXNlIFBIWVNJQ1NfRVZFTlRTLkxPQUQuQU1NTzoKICAgICAgICAgIGxvYWRBbW1vKGRhdGEpOwogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH07Cgp9KSgpOwoK', 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",
|
|
@@ -56520,13 +56520,22 @@ let Physics = /*#__PURE__*/function (_EventDispatcher) {
|
|
|
56520
56520
|
value: function add(element, options = {}) {
|
|
56521
56521
|
if (Config$1.physics().enabled) {
|
|
56522
56522
|
const {
|
|
56523
|
-
colliderType = COLLIDER_TYPES$1.BOX
|
|
56523
|
+
colliderType = COLLIDER_TYPES$1.BOX,
|
|
56524
|
+
colliderWidth,
|
|
56525
|
+
colliderHeight,
|
|
56526
|
+
colliderLength,
|
|
56527
|
+
colliderRadius,
|
|
56528
|
+
...rest
|
|
56524
56529
|
} = options;
|
|
56525
56530
|
const uuid = element.uuid();
|
|
56526
56531
|
const description = {
|
|
56527
56532
|
...mapColliderTypeToDescription(colliderType)(element),
|
|
56528
|
-
...
|
|
56533
|
+
...rest
|
|
56529
56534
|
};
|
|
56535
|
+
if (colliderWidth != null) description.width = colliderWidth;
|
|
56536
|
+
if (colliderHeight != null) description.height = colliderHeight;
|
|
56537
|
+
if (colliderLength != null) description.length = colliderLength;
|
|
56538
|
+
if (colliderRadius != null) description.radius = colliderRadius;
|
|
56530
56539
|
this.storeElement(element, options);
|
|
56531
56540
|
this.worker.postMessage({
|
|
56532
56541
|
event: mapColliderTypeToAddEvent(description.collider),
|
|
@@ -58125,10 +58134,11 @@ var Physics$1 = new Physics();let Orbit = /*#__PURE__*/function (_EventDispatche
|
|
|
58125
58134
|
_this.gizmo = new Gizmo();
|
|
58126
58135
|
_this.plane = new TransformControlsPlane();
|
|
58127
58136
|
|
|
58128
|
-
// Set gizmo and plane to layer
|
|
58129
|
-
//
|
|
58130
|
-
|
|
58131
|
-
_this.
|
|
58137
|
+
// Set gizmo and plane to layer 2 ONLY so they render in a dedicated pass
|
|
58138
|
+
// on top of everything (sky, post-processing, etc.)
|
|
58139
|
+
// Layer 1 = editor helpers (togglable), Layer 2 = gizmo (always visible)
|
|
58140
|
+
_this.gizmo.layers.set(2);
|
|
58141
|
+
_this.plane.layers.set(2);
|
|
58132
58142
|
|
|
58133
58143
|
// Helper function to set depth properties on materials
|
|
58134
58144
|
const setMaterialDepth = material => {
|
|
@@ -58142,15 +58152,15 @@ var Physics$1 = new Physics();let Orbit = /*#__PURE__*/function (_EventDispatche
|
|
|
58142
58152
|
});
|
|
58143
58153
|
};
|
|
58144
58154
|
|
|
58145
|
-
// Also set layer
|
|
58146
|
-
//
|
|
58155
|
+
// Also set layer 2 on all children recursively
|
|
58156
|
+
// Disable depthTest so gizmos render on top of everything
|
|
58147
58157
|
_this.gizmo.traverse(child => {
|
|
58148
|
-
child.layers.set(
|
|
58158
|
+
child.layers.set(2);
|
|
58149
58159
|
child.renderOrder = 999;
|
|
58150
58160
|
setMaterialDepth(child.material);
|
|
58151
58161
|
});
|
|
58152
58162
|
_this.plane.traverse(child => {
|
|
58153
|
-
child.layers.set(
|
|
58163
|
+
child.layers.set(2);
|
|
58154
58164
|
child.renderOrder = 999;
|
|
58155
58165
|
setMaterialDepth(child.material);
|
|
58156
58166
|
});
|
|
@@ -58191,8 +58201,8 @@ var Physics$1 = new Physics();let Orbit = /*#__PURE__*/function (_EventDispatche
|
|
|
58191
58201
|
_this.setAndDispatch("showY", true);
|
|
58192
58202
|
_this.setAndDispatch("showZ", true);
|
|
58193
58203
|
_this.ray = new Raycaster();
|
|
58194
|
-
// Enable layer
|
|
58195
|
-
_this.ray.layers.enable(
|
|
58204
|
+
// Enable layer 2 so raycaster can pick gizmo objects (which are on layer 2)
|
|
58205
|
+
_this.ray.layers.enable(2);
|
|
58196
58206
|
_this._tempVector = new Vector3$1();
|
|
58197
58207
|
_this._tempVector2 = new Vector3$1();
|
|
58198
58208
|
_this._tempQuaternion = new Quaternion();
|
|
@@ -60103,10 +60113,12 @@ var Controls$1 = new Controls();let Scene = /*#__PURE__*/function () {
|
|
|
60103
60113
|
key: "createCamera",
|
|
60104
60114
|
value: function createCamera(camera) {
|
|
60105
60115
|
this.camera = camera;
|
|
60106
|
-
// Enable layer 1 so camera can see editor-only objects (helpers, grid
|
|
60116
|
+
// Enable layer 1 so camera can see editor-only objects (helpers, grid)
|
|
60117
|
+
// Enable layer 2 so camera can see gizmos (rendered in separate pass)
|
|
60107
60118
|
// Mirror cameras only use layer 0, so they won't render these
|
|
60108
60119
|
if (this.camera && this.camera.getBody()) {
|
|
60109
60120
|
this.camera.getBody().layers.enable(1);
|
|
60121
|
+
this.camera.getBody().layers.enable(2);
|
|
60110
60122
|
}
|
|
60111
60123
|
}
|
|
60112
60124
|
}, {
|
|
@@ -60204,6 +60216,53 @@ var Controls$1 = new Controls();let Scene = /*#__PURE__*/function () {
|
|
|
60204
60216
|
this.renderer.setRenderTarget(null);
|
|
60205
60217
|
this.renderer.render(this.scene, this.camera.getBody());
|
|
60206
60218
|
}
|
|
60219
|
+
|
|
60220
|
+
// Render gizmo layer (layer 2) on top of everything.
|
|
60221
|
+
// Called after main render or post-processing to ensure gizmos are always visible
|
|
60222
|
+
// regardless of sky, post-processing, or sortObjects setting.
|
|
60223
|
+
}, {
|
|
60224
|
+
key: "renderGizmoLayer",
|
|
60225
|
+
value: function renderGizmoLayer() {
|
|
60226
|
+
if (!this.renderer || !this.camera) return;
|
|
60227
|
+
const cameraBody = this.camera.getBody();
|
|
60228
|
+
|
|
60229
|
+
// Save current camera layer mask
|
|
60230
|
+
const savedLayers = cameraBody.layers.mask;
|
|
60231
|
+
|
|
60232
|
+
// Set camera to only see layer 2 (gizmo layer)
|
|
60233
|
+
cameraBody.layers.set(2);
|
|
60234
|
+
|
|
60235
|
+
// Ensure we render to screen (not a post-processing buffer)
|
|
60236
|
+
this.renderer.setRenderTarget(null);
|
|
60237
|
+
// Clear only depth so gizmo renders on top of the already-drawn frame
|
|
60238
|
+
this.renderer.autoClear = false;
|
|
60239
|
+
this.renderer.clearDepth();
|
|
60240
|
+
this.renderer.render(this.scene, cameraBody);
|
|
60241
|
+
this.renderer.autoClear = true;
|
|
60242
|
+
|
|
60243
|
+
// Restore camera layers
|
|
60244
|
+
cameraBody.layers.mask = savedLayers;
|
|
60245
|
+
}
|
|
60246
|
+
|
|
60247
|
+
// Toggle editor helpers visibility (layer 1: grid, light helpers, camera helpers)
|
|
60248
|
+
// Does NOT affect gizmos (layer 2) which are always visible
|
|
60249
|
+
}, {
|
|
60250
|
+
key: "setHelpersVisible",
|
|
60251
|
+
value: function setHelpersVisible(visible) {
|
|
60252
|
+
if (!this.camera || !this.camera.getBody()) return;
|
|
60253
|
+
const cameraBody = this.camera.getBody();
|
|
60254
|
+
if (visible) {
|
|
60255
|
+
cameraBody.layers.enable(1);
|
|
60256
|
+
} else {
|
|
60257
|
+
cameraBody.layers.disable(1);
|
|
60258
|
+
}
|
|
60259
|
+
this.helpersVisible = visible;
|
|
60260
|
+
}
|
|
60261
|
+
}, {
|
|
60262
|
+
key: "getHelpersVisible",
|
|
60263
|
+
value: function getHelpersVisible() {
|
|
60264
|
+
return this.helpersVisible !== false;
|
|
60265
|
+
}
|
|
60207
60266
|
}, {
|
|
60208
60267
|
key: "setFog",
|
|
60209
60268
|
value: function setFog(color, density) {
|
|
@@ -61301,7 +61360,7 @@ function applyMiddleware() {
|
|
|
61301
61360
|
|
|
61302
61361
|
var thunk = createThunkMiddleware();
|
|
61303
61362
|
thunk.withExtraArgument = createThunkMiddleware;var name = "mage-engine";
|
|
61304
|
-
var version$1 = "3.25.
|
|
61363
|
+
var version$1 = "3.25.7";
|
|
61305
61364
|
var description = "A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.";
|
|
61306
61365
|
var main = "dist/mage.js";
|
|
61307
61366
|
var author$1 = {
|
|
@@ -64742,6 +64801,26 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
|
|
|
64742
64801
|
setUpLightsAndShadows(this.getBody());
|
|
64743
64802
|
}
|
|
64744
64803
|
}
|
|
64804
|
+
}, {
|
|
64805
|
+
key: "getComputedColliderSize",
|
|
64806
|
+
value: function getComputedColliderSize() {
|
|
64807
|
+
const result = {};
|
|
64808
|
+
try {
|
|
64809
|
+
if (this.boundingBox) {
|
|
64810
|
+
const size = parseBoundingBoxSize(this.boundingBox);
|
|
64811
|
+
const scale = this.getScale();
|
|
64812
|
+
result.width = parseFloat((size.x * scale.x).toFixed(3));
|
|
64813
|
+
result.height = parseFloat((size.y * scale.y).toFixed(3));
|
|
64814
|
+
result.length = parseFloat((size.z * scale.z).toFixed(3));
|
|
64815
|
+
}
|
|
64816
|
+
if (this.boundingSphere) {
|
|
64817
|
+
result.radius = parseFloat(this.boundingSphere.radius.toFixed(3));
|
|
64818
|
+
}
|
|
64819
|
+
} catch {
|
|
64820
|
+
// bounding box/sphere not yet available
|
|
64821
|
+
}
|
|
64822
|
+
return result;
|
|
64823
|
+
}
|
|
64745
64824
|
}, {
|
|
64746
64825
|
key: "addToScene",
|
|
64747
64826
|
value: function addToScene() {
|
|
@@ -65675,7 +65754,8 @@ let Element$1 = /*#__PURE__*/function (_Entity) {
|
|
|
65675
65754
|
..._superPropGet(Element, "toJSON", this, 3)([parseJSON]),
|
|
65676
65755
|
// Physics options (state is not used by Importer, only options)
|
|
65677
65756
|
physics: {
|
|
65678
|
-
options: this.getPhysicsOptions()
|
|
65757
|
+
options: this.getPhysicsOptions(),
|
|
65758
|
+
computedSize: this.getComputedColliderSize()
|
|
65679
65759
|
},
|
|
65680
65760
|
// Textures with serialized map
|
|
65681
65761
|
textures: serializeMap(this.textures),
|
|
@@ -92772,6 +92852,11 @@ let Level = /*#__PURE__*/function (_EventDispatcher) {
|
|
|
92772
92852
|
} else {
|
|
92773
92853
|
Scene$1.render(dt);
|
|
92774
92854
|
}
|
|
92855
|
+
|
|
92856
|
+
// Render gizmo layer on top of everything (separate pass with depth clear)
|
|
92857
|
+
// This ensures gizmos are always visible regardless of sky, post-processing,
|
|
92858
|
+
// or the sortObjects=false setting used when shadows are enabled.
|
|
92859
|
+
Scene$1.renderGizmoLayer();
|
|
92775
92860
|
Particles$1.update(dt);
|
|
92776
92861
|
this.onUpdate(dt);
|
|
92777
92862
|
Scene$1.update(dt);
|
|
@@ -98062,7 +98147,877 @@ let Sound = /*#__PURE__*/function (_Entity) {
|
|
|
98062
98147
|
});
|
|
98063
98148
|
}
|
|
98064
98149
|
}]);
|
|
98065
|
-
}(Entity);
|
|
98150
|
+
}(Entity);var LineSegmentsGeometry = function () {
|
|
98151
|
+
|
|
98152
|
+
InstancedBufferGeometry.call( this );
|
|
98153
|
+
|
|
98154
|
+
this.type = 'LineSegmentsGeometry';
|
|
98155
|
+
|
|
98156
|
+
var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
|
|
98157
|
+
var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
|
|
98158
|
+
var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
|
|
98159
|
+
|
|
98160
|
+
this.setIndex( index );
|
|
98161
|
+
this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
|
|
98162
|
+
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
98163
|
+
|
|
98164
|
+
};
|
|
98165
|
+
|
|
98166
|
+
LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGeometry.prototype ), {
|
|
98167
|
+
|
|
98168
|
+
constructor: LineSegmentsGeometry,
|
|
98169
|
+
|
|
98170
|
+
isLineSegmentsGeometry: true,
|
|
98171
|
+
|
|
98172
|
+
applyMatrix4: function ( matrix ) {
|
|
98173
|
+
|
|
98174
|
+
var start = this.attributes.instanceStart;
|
|
98175
|
+
var end = this.attributes.instanceEnd;
|
|
98176
|
+
|
|
98177
|
+
if ( start !== undefined ) {
|
|
98178
|
+
|
|
98179
|
+
start.applyMatrix4( matrix );
|
|
98180
|
+
|
|
98181
|
+
end.applyMatrix4( matrix );
|
|
98182
|
+
|
|
98183
|
+
start.needsUpdate = true;
|
|
98184
|
+
|
|
98185
|
+
}
|
|
98186
|
+
|
|
98187
|
+
if ( this.boundingBox !== null ) {
|
|
98188
|
+
|
|
98189
|
+
this.computeBoundingBox();
|
|
98190
|
+
|
|
98191
|
+
}
|
|
98192
|
+
|
|
98193
|
+
if ( this.boundingSphere !== null ) {
|
|
98194
|
+
|
|
98195
|
+
this.computeBoundingSphere();
|
|
98196
|
+
|
|
98197
|
+
}
|
|
98198
|
+
|
|
98199
|
+
return this;
|
|
98200
|
+
|
|
98201
|
+
},
|
|
98202
|
+
|
|
98203
|
+
setPositions: function ( array ) {
|
|
98204
|
+
|
|
98205
|
+
var lineSegments;
|
|
98206
|
+
|
|
98207
|
+
if ( array instanceof Float32Array ) {
|
|
98208
|
+
|
|
98209
|
+
lineSegments = array;
|
|
98210
|
+
|
|
98211
|
+
} else if ( Array.isArray( array ) ) {
|
|
98212
|
+
|
|
98213
|
+
lineSegments = new Float32Array( array );
|
|
98214
|
+
|
|
98215
|
+
}
|
|
98216
|
+
|
|
98217
|
+
var instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
|
|
98218
|
+
|
|
98219
|
+
this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
|
|
98220
|
+
this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
|
|
98221
|
+
|
|
98222
|
+
//
|
|
98223
|
+
|
|
98224
|
+
this.computeBoundingBox();
|
|
98225
|
+
this.computeBoundingSphere();
|
|
98226
|
+
|
|
98227
|
+
return this;
|
|
98228
|
+
|
|
98229
|
+
},
|
|
98230
|
+
|
|
98231
|
+
setColors: function ( array ) {
|
|
98232
|
+
|
|
98233
|
+
var colors;
|
|
98234
|
+
|
|
98235
|
+
if ( array instanceof Float32Array ) {
|
|
98236
|
+
|
|
98237
|
+
colors = array;
|
|
98238
|
+
|
|
98239
|
+
} else if ( Array.isArray( array ) ) {
|
|
98240
|
+
|
|
98241
|
+
colors = new Float32Array( array );
|
|
98242
|
+
|
|
98243
|
+
}
|
|
98244
|
+
|
|
98245
|
+
var instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
|
|
98246
|
+
|
|
98247
|
+
this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
|
|
98248
|
+
this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
|
|
98249
|
+
|
|
98250
|
+
return this;
|
|
98251
|
+
|
|
98252
|
+
},
|
|
98253
|
+
|
|
98254
|
+
fromWireframeGeometry: function ( geometry ) {
|
|
98255
|
+
|
|
98256
|
+
this.setPositions( geometry.attributes.position.array );
|
|
98257
|
+
|
|
98258
|
+
return this;
|
|
98259
|
+
|
|
98260
|
+
},
|
|
98261
|
+
|
|
98262
|
+
fromEdgesGeometry: function ( geometry ) {
|
|
98263
|
+
|
|
98264
|
+
this.setPositions( geometry.attributes.position.array );
|
|
98265
|
+
|
|
98266
|
+
return this;
|
|
98267
|
+
|
|
98268
|
+
},
|
|
98269
|
+
|
|
98270
|
+
fromMesh: function ( mesh ) {
|
|
98271
|
+
|
|
98272
|
+
this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
|
|
98273
|
+
|
|
98274
|
+
// set colors, maybe
|
|
98275
|
+
|
|
98276
|
+
return this;
|
|
98277
|
+
|
|
98278
|
+
},
|
|
98279
|
+
|
|
98280
|
+
fromLineSegments: function ( lineSegments ) {
|
|
98281
|
+
|
|
98282
|
+
var geometry = lineSegments.geometry;
|
|
98283
|
+
|
|
98284
|
+
if ( geometry.isGeometry ) {
|
|
98285
|
+
|
|
98286
|
+
console.error( 'THREE.LineSegmentsGeometry no longer supports Geometry. Use THREE.BufferGeometry instead.' );
|
|
98287
|
+
return;
|
|
98288
|
+
|
|
98289
|
+
} else if ( geometry.isBufferGeometry ) {
|
|
98290
|
+
|
|
98291
|
+
this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
|
|
98292
|
+
|
|
98293
|
+
}
|
|
98294
|
+
|
|
98295
|
+
// set colors, maybe
|
|
98296
|
+
|
|
98297
|
+
return this;
|
|
98298
|
+
|
|
98299
|
+
},
|
|
98300
|
+
|
|
98301
|
+
computeBoundingBox: function () {
|
|
98302
|
+
|
|
98303
|
+
var box = new Box3();
|
|
98304
|
+
|
|
98305
|
+
return function computeBoundingBox() {
|
|
98306
|
+
|
|
98307
|
+
if ( this.boundingBox === null ) {
|
|
98308
|
+
|
|
98309
|
+
this.boundingBox = new Box3();
|
|
98310
|
+
|
|
98311
|
+
}
|
|
98312
|
+
|
|
98313
|
+
var start = this.attributes.instanceStart;
|
|
98314
|
+
var end = this.attributes.instanceEnd;
|
|
98315
|
+
|
|
98316
|
+
if ( start !== undefined && end !== undefined ) {
|
|
98317
|
+
|
|
98318
|
+
this.boundingBox.setFromBufferAttribute( start );
|
|
98319
|
+
|
|
98320
|
+
box.setFromBufferAttribute( end );
|
|
98321
|
+
|
|
98322
|
+
this.boundingBox.union( box );
|
|
98323
|
+
|
|
98324
|
+
}
|
|
98325
|
+
|
|
98326
|
+
};
|
|
98327
|
+
|
|
98328
|
+
}(),
|
|
98329
|
+
|
|
98330
|
+
computeBoundingSphere: function () {
|
|
98331
|
+
|
|
98332
|
+
var vector = new Vector3$1();
|
|
98333
|
+
|
|
98334
|
+
return function computeBoundingSphere() {
|
|
98335
|
+
|
|
98336
|
+
if ( this.boundingSphere === null ) {
|
|
98337
|
+
|
|
98338
|
+
this.boundingSphere = new Sphere$1();
|
|
98339
|
+
|
|
98340
|
+
}
|
|
98341
|
+
|
|
98342
|
+
if ( this.boundingBox === null ) {
|
|
98343
|
+
|
|
98344
|
+
this.computeBoundingBox();
|
|
98345
|
+
|
|
98346
|
+
}
|
|
98347
|
+
|
|
98348
|
+
var start = this.attributes.instanceStart;
|
|
98349
|
+
var end = this.attributes.instanceEnd;
|
|
98350
|
+
|
|
98351
|
+
if ( start !== undefined && end !== undefined ) {
|
|
98352
|
+
|
|
98353
|
+
var center = this.boundingSphere.center;
|
|
98354
|
+
|
|
98355
|
+
this.boundingBox.getCenter( center );
|
|
98356
|
+
|
|
98357
|
+
var maxRadiusSq = 0;
|
|
98358
|
+
|
|
98359
|
+
for ( var i = 0, il = start.count; i < il; i ++ ) {
|
|
98360
|
+
|
|
98361
|
+
vector.fromBufferAttribute( start, i );
|
|
98362
|
+
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
|
|
98363
|
+
|
|
98364
|
+
vector.fromBufferAttribute( end, i );
|
|
98365
|
+
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
|
|
98366
|
+
|
|
98367
|
+
}
|
|
98368
|
+
|
|
98369
|
+
this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
|
|
98370
|
+
|
|
98371
|
+
if ( isNaN( this.boundingSphere.radius ) ) {
|
|
98372
|
+
|
|
98373
|
+
console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
|
|
98374
|
+
|
|
98375
|
+
}
|
|
98376
|
+
|
|
98377
|
+
}
|
|
98378
|
+
|
|
98379
|
+
};
|
|
98380
|
+
|
|
98381
|
+
}(),
|
|
98382
|
+
|
|
98383
|
+
toJSON: function () {
|
|
98384
|
+
|
|
98385
|
+
// todo
|
|
98386
|
+
|
|
98387
|
+
},
|
|
98388
|
+
|
|
98389
|
+
applyMatrix: function ( matrix ) {
|
|
98390
|
+
|
|
98391
|
+
console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
|
|
98392
|
+
|
|
98393
|
+
return this.applyMatrix4( matrix );
|
|
98394
|
+
|
|
98395
|
+
}
|
|
98396
|
+
|
|
98397
|
+
} );/**
|
|
98398
|
+
* parameters = {
|
|
98399
|
+
* color: <hex>,
|
|
98400
|
+
* linewidth: <float>,
|
|
98401
|
+
* dashed: <boolean>,
|
|
98402
|
+
* dashScale: <float>,
|
|
98403
|
+
* dashSize: <float>,
|
|
98404
|
+
* dashOffset: <float>,
|
|
98405
|
+
* gapSize: <float>,
|
|
98406
|
+
* resolution: <Vector2>, // to be set by renderer
|
|
98407
|
+
* }
|
|
98408
|
+
*/
|
|
98409
|
+
|
|
98410
|
+
UniformsLib.line = {
|
|
98411
|
+
|
|
98412
|
+
linewidth: { value: 1 },
|
|
98413
|
+
resolution: { value: new Vector2( 1, 1 ) },
|
|
98414
|
+
dashScale: { value: 1 },
|
|
98415
|
+
dashSize: { value: 1 },
|
|
98416
|
+
dashOffset: { value: 0 },
|
|
98417
|
+
gapSize: { value: 1 }, // todo FIX - maybe change to totalSize
|
|
98418
|
+
opacity: { value: 1 }
|
|
98419
|
+
|
|
98420
|
+
};
|
|
98421
|
+
|
|
98422
|
+
ShaderLib[ 'line' ] = {
|
|
98423
|
+
|
|
98424
|
+
uniforms: UniformsUtils.merge( [
|
|
98425
|
+
UniformsLib.common,
|
|
98426
|
+
UniformsLib.fog,
|
|
98427
|
+
UniformsLib.line
|
|
98428
|
+
] ),
|
|
98429
|
+
|
|
98430
|
+
vertexShader:
|
|
98431
|
+
`
|
|
98432
|
+
#include <common>
|
|
98433
|
+
#include <color_pars_vertex>
|
|
98434
|
+
#include <fog_pars_vertex>
|
|
98435
|
+
#include <logdepthbuf_pars_vertex>
|
|
98436
|
+
#include <clipping_planes_pars_vertex>
|
|
98437
|
+
|
|
98438
|
+
uniform float linewidth;
|
|
98439
|
+
uniform vec2 resolution;
|
|
98440
|
+
|
|
98441
|
+
attribute vec3 instanceStart;
|
|
98442
|
+
attribute vec3 instanceEnd;
|
|
98443
|
+
|
|
98444
|
+
attribute vec3 instanceColorStart;
|
|
98445
|
+
attribute vec3 instanceColorEnd;
|
|
98446
|
+
|
|
98447
|
+
varying vec2 vUv;
|
|
98448
|
+
|
|
98449
|
+
#ifdef USE_DASH
|
|
98450
|
+
|
|
98451
|
+
uniform float dashScale;
|
|
98452
|
+
attribute float instanceDistanceStart;
|
|
98453
|
+
attribute float instanceDistanceEnd;
|
|
98454
|
+
varying float vLineDistance;
|
|
98455
|
+
|
|
98456
|
+
#endif
|
|
98457
|
+
|
|
98458
|
+
void trimSegment( const in vec4 start, inout vec4 end ) {
|
|
98459
|
+
|
|
98460
|
+
// trim end segment so it terminates between the camera plane and the near plane
|
|
98461
|
+
|
|
98462
|
+
// conservative estimate of the near plane
|
|
98463
|
+
float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
|
|
98464
|
+
float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
|
|
98465
|
+
float nearEstimate = - 0.5 * b / a;
|
|
98466
|
+
|
|
98467
|
+
float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );
|
|
98468
|
+
|
|
98469
|
+
end.xyz = mix( start.xyz, end.xyz, alpha );
|
|
98470
|
+
|
|
98471
|
+
}
|
|
98472
|
+
|
|
98473
|
+
void main() {
|
|
98474
|
+
|
|
98475
|
+
#ifdef USE_COLOR
|
|
98476
|
+
|
|
98477
|
+
vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
|
|
98478
|
+
|
|
98479
|
+
#endif
|
|
98480
|
+
|
|
98481
|
+
#ifdef USE_DASH
|
|
98482
|
+
|
|
98483
|
+
vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;
|
|
98484
|
+
|
|
98485
|
+
#endif
|
|
98486
|
+
|
|
98487
|
+
float aspect = resolution.x / resolution.y;
|
|
98488
|
+
|
|
98489
|
+
vUv = uv;
|
|
98490
|
+
|
|
98491
|
+
// camera space
|
|
98492
|
+
vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
|
|
98493
|
+
vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
|
|
98494
|
+
|
|
98495
|
+
// special case for perspective projection, and segments that terminate either in, or behind, the camera plane
|
|
98496
|
+
// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
|
|
98497
|
+
// but we need to perform ndc-space calculations in the shader, so we must address this issue directly
|
|
98498
|
+
// perhaps there is a more elegant solution -- WestLangley
|
|
98499
|
+
|
|
98500
|
+
bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
|
|
98501
|
+
|
|
98502
|
+
if ( perspective ) {
|
|
98503
|
+
|
|
98504
|
+
if ( start.z < 0.0 && end.z >= 0.0 ) {
|
|
98505
|
+
|
|
98506
|
+
trimSegment( start, end );
|
|
98507
|
+
|
|
98508
|
+
} else if ( end.z < 0.0 && start.z >= 0.0 ) {
|
|
98509
|
+
|
|
98510
|
+
trimSegment( end, start );
|
|
98511
|
+
|
|
98512
|
+
}
|
|
98513
|
+
|
|
98514
|
+
}
|
|
98515
|
+
|
|
98516
|
+
// clip space
|
|
98517
|
+
vec4 clipStart = projectionMatrix * start;
|
|
98518
|
+
vec4 clipEnd = projectionMatrix * end;
|
|
98519
|
+
|
|
98520
|
+
// ndc space
|
|
98521
|
+
vec2 ndcStart = clipStart.xy / clipStart.w;
|
|
98522
|
+
vec2 ndcEnd = clipEnd.xy / clipEnd.w;
|
|
98523
|
+
|
|
98524
|
+
// direction
|
|
98525
|
+
vec2 dir = ndcEnd - ndcStart;
|
|
98526
|
+
|
|
98527
|
+
// account for clip-space aspect ratio
|
|
98528
|
+
dir.x *= aspect;
|
|
98529
|
+
dir = normalize( dir );
|
|
98530
|
+
|
|
98531
|
+
// perpendicular to dir
|
|
98532
|
+
vec2 offset = vec2( dir.y, - dir.x );
|
|
98533
|
+
|
|
98534
|
+
// undo aspect ratio adjustment
|
|
98535
|
+
dir.x /= aspect;
|
|
98536
|
+
offset.x /= aspect;
|
|
98537
|
+
|
|
98538
|
+
// sign flip
|
|
98539
|
+
if ( position.x < 0.0 ) offset *= - 1.0;
|
|
98540
|
+
|
|
98541
|
+
// endcaps
|
|
98542
|
+
if ( position.y < 0.0 ) {
|
|
98543
|
+
|
|
98544
|
+
offset += - dir;
|
|
98545
|
+
|
|
98546
|
+
} else if ( position.y > 1.0 ) {
|
|
98547
|
+
|
|
98548
|
+
offset += dir;
|
|
98549
|
+
|
|
98550
|
+
}
|
|
98551
|
+
|
|
98552
|
+
// adjust for linewidth
|
|
98553
|
+
offset *= linewidth;
|
|
98554
|
+
|
|
98555
|
+
// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
|
|
98556
|
+
offset /= resolution.y;
|
|
98557
|
+
|
|
98558
|
+
// select end
|
|
98559
|
+
vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
|
|
98560
|
+
|
|
98561
|
+
// back to clip space
|
|
98562
|
+
offset *= clip.w;
|
|
98563
|
+
|
|
98564
|
+
clip.xy += offset;
|
|
98565
|
+
|
|
98566
|
+
gl_Position = clip;
|
|
98567
|
+
|
|
98568
|
+
vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation
|
|
98569
|
+
|
|
98570
|
+
#include <logdepthbuf_vertex>
|
|
98571
|
+
#include <clipping_planes_vertex>
|
|
98572
|
+
#include <fog_vertex>
|
|
98573
|
+
|
|
98574
|
+
}
|
|
98575
|
+
`,
|
|
98576
|
+
|
|
98577
|
+
fragmentShader:
|
|
98578
|
+
`
|
|
98579
|
+
uniform vec3 diffuse;
|
|
98580
|
+
uniform float opacity;
|
|
98581
|
+
|
|
98582
|
+
#ifdef USE_DASH
|
|
98583
|
+
|
|
98584
|
+
uniform float dashSize;
|
|
98585
|
+
uniform float dashOffset;
|
|
98586
|
+
uniform float gapSize;
|
|
98587
|
+
|
|
98588
|
+
#endif
|
|
98589
|
+
|
|
98590
|
+
varying float vLineDistance;
|
|
98591
|
+
|
|
98592
|
+
#include <common>
|
|
98593
|
+
#include <color_pars_fragment>
|
|
98594
|
+
#include <fog_pars_fragment>
|
|
98595
|
+
#include <logdepthbuf_pars_fragment>
|
|
98596
|
+
#include <clipping_planes_pars_fragment>
|
|
98597
|
+
|
|
98598
|
+
varying vec2 vUv;
|
|
98599
|
+
|
|
98600
|
+
void main() {
|
|
98601
|
+
|
|
98602
|
+
#include <clipping_planes_fragment>
|
|
98603
|
+
|
|
98604
|
+
#ifdef USE_DASH
|
|
98605
|
+
|
|
98606
|
+
if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
|
|
98607
|
+
|
|
98608
|
+
if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
|
|
98609
|
+
|
|
98610
|
+
#endif
|
|
98611
|
+
|
|
98612
|
+
if ( abs( vUv.y ) > 1.0 ) {
|
|
98613
|
+
|
|
98614
|
+
float a = vUv.x;
|
|
98615
|
+
float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
|
|
98616
|
+
float len2 = a * a + b * b;
|
|
98617
|
+
|
|
98618
|
+
if ( len2 > 1.0 ) discard;
|
|
98619
|
+
|
|
98620
|
+
}
|
|
98621
|
+
|
|
98622
|
+
vec4 diffuseColor = vec4( diffuse, opacity );
|
|
98623
|
+
|
|
98624
|
+
#include <logdepthbuf_fragment>
|
|
98625
|
+
#include <color_fragment>
|
|
98626
|
+
|
|
98627
|
+
gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );
|
|
98628
|
+
|
|
98629
|
+
#include <tonemapping_fragment>
|
|
98630
|
+
#include <encodings_fragment>
|
|
98631
|
+
#include <fog_fragment>
|
|
98632
|
+
#include <premultiplied_alpha_fragment>
|
|
98633
|
+
|
|
98634
|
+
}
|
|
98635
|
+
`
|
|
98636
|
+
};
|
|
98637
|
+
|
|
98638
|
+
var LineMaterial = function ( parameters ) {
|
|
98639
|
+
|
|
98640
|
+
ShaderMaterial.call( this, {
|
|
98641
|
+
|
|
98642
|
+
type: 'LineMaterial',
|
|
98643
|
+
|
|
98644
|
+
uniforms: UniformsUtils.clone( ShaderLib[ 'line' ].uniforms ),
|
|
98645
|
+
|
|
98646
|
+
vertexShader: ShaderLib[ 'line' ].vertexShader,
|
|
98647
|
+
fragmentShader: ShaderLib[ 'line' ].fragmentShader,
|
|
98648
|
+
|
|
98649
|
+
clipping: true // required for clipping support
|
|
98650
|
+
|
|
98651
|
+
} );
|
|
98652
|
+
|
|
98653
|
+
this.dashed = false;
|
|
98654
|
+
|
|
98655
|
+
Object.defineProperties( this, {
|
|
98656
|
+
|
|
98657
|
+
color: {
|
|
98658
|
+
|
|
98659
|
+
enumerable: true,
|
|
98660
|
+
|
|
98661
|
+
get: function () {
|
|
98662
|
+
|
|
98663
|
+
return this.uniforms.diffuse.value;
|
|
98664
|
+
|
|
98665
|
+
},
|
|
98666
|
+
|
|
98667
|
+
set: function ( value ) {
|
|
98668
|
+
|
|
98669
|
+
this.uniforms.diffuse.value = value;
|
|
98670
|
+
|
|
98671
|
+
}
|
|
98672
|
+
|
|
98673
|
+
},
|
|
98674
|
+
|
|
98675
|
+
linewidth: {
|
|
98676
|
+
|
|
98677
|
+
enumerable: true,
|
|
98678
|
+
|
|
98679
|
+
get: function () {
|
|
98680
|
+
|
|
98681
|
+
return this.uniforms.linewidth.value;
|
|
98682
|
+
|
|
98683
|
+
},
|
|
98684
|
+
|
|
98685
|
+
set: function ( value ) {
|
|
98686
|
+
|
|
98687
|
+
this.uniforms.linewidth.value = value;
|
|
98688
|
+
|
|
98689
|
+
}
|
|
98690
|
+
|
|
98691
|
+
},
|
|
98692
|
+
|
|
98693
|
+
dashScale: {
|
|
98694
|
+
|
|
98695
|
+
enumerable: true,
|
|
98696
|
+
|
|
98697
|
+
get: function () {
|
|
98698
|
+
|
|
98699
|
+
return this.uniforms.dashScale.value;
|
|
98700
|
+
|
|
98701
|
+
},
|
|
98702
|
+
|
|
98703
|
+
set: function ( value ) {
|
|
98704
|
+
|
|
98705
|
+
this.uniforms.dashScale.value = value;
|
|
98706
|
+
|
|
98707
|
+
}
|
|
98708
|
+
|
|
98709
|
+
},
|
|
98710
|
+
|
|
98711
|
+
dashSize: {
|
|
98712
|
+
|
|
98713
|
+
enumerable: true,
|
|
98714
|
+
|
|
98715
|
+
get: function () {
|
|
98716
|
+
|
|
98717
|
+
return this.uniforms.dashSize.value;
|
|
98718
|
+
|
|
98719
|
+
},
|
|
98720
|
+
|
|
98721
|
+
set: function ( value ) {
|
|
98722
|
+
|
|
98723
|
+
this.uniforms.dashSize.value = value;
|
|
98724
|
+
|
|
98725
|
+
}
|
|
98726
|
+
|
|
98727
|
+
},
|
|
98728
|
+
|
|
98729
|
+
dashOffset: {
|
|
98730
|
+
|
|
98731
|
+
enumerable: true,
|
|
98732
|
+
|
|
98733
|
+
get: function () {
|
|
98734
|
+
|
|
98735
|
+
return this.uniforms.dashOffset.value;
|
|
98736
|
+
|
|
98737
|
+
},
|
|
98738
|
+
|
|
98739
|
+
set: function ( value ) {
|
|
98740
|
+
|
|
98741
|
+
this.uniforms.dashOffset.value = value;
|
|
98742
|
+
|
|
98743
|
+
}
|
|
98744
|
+
|
|
98745
|
+
},
|
|
98746
|
+
|
|
98747
|
+
gapSize: {
|
|
98748
|
+
|
|
98749
|
+
enumerable: true,
|
|
98750
|
+
|
|
98751
|
+
get: function () {
|
|
98752
|
+
|
|
98753
|
+
return this.uniforms.gapSize.value;
|
|
98754
|
+
|
|
98755
|
+
},
|
|
98756
|
+
|
|
98757
|
+
set: function ( value ) {
|
|
98758
|
+
|
|
98759
|
+
this.uniforms.gapSize.value = value;
|
|
98760
|
+
|
|
98761
|
+
}
|
|
98762
|
+
|
|
98763
|
+
},
|
|
98764
|
+
|
|
98765
|
+
opacity: {
|
|
98766
|
+
|
|
98767
|
+
enumerable: true,
|
|
98768
|
+
|
|
98769
|
+
get: function () {
|
|
98770
|
+
|
|
98771
|
+
return this.uniforms.opacity.value;
|
|
98772
|
+
|
|
98773
|
+
},
|
|
98774
|
+
|
|
98775
|
+
set: function ( value ) {
|
|
98776
|
+
|
|
98777
|
+
this.uniforms.opacity.value = value;
|
|
98778
|
+
|
|
98779
|
+
}
|
|
98780
|
+
|
|
98781
|
+
},
|
|
98782
|
+
|
|
98783
|
+
resolution: {
|
|
98784
|
+
|
|
98785
|
+
enumerable: true,
|
|
98786
|
+
|
|
98787
|
+
get: function () {
|
|
98788
|
+
|
|
98789
|
+
return this.uniforms.resolution.value;
|
|
98790
|
+
|
|
98791
|
+
},
|
|
98792
|
+
|
|
98793
|
+
set: function ( value ) {
|
|
98794
|
+
|
|
98795
|
+
this.uniforms.resolution.value.copy( value );
|
|
98796
|
+
|
|
98797
|
+
}
|
|
98798
|
+
|
|
98799
|
+
}
|
|
98800
|
+
|
|
98801
|
+
} );
|
|
98802
|
+
|
|
98803
|
+
this.setValues( parameters );
|
|
98804
|
+
|
|
98805
|
+
};
|
|
98806
|
+
|
|
98807
|
+
LineMaterial.prototype = Object.create( ShaderMaterial.prototype );
|
|
98808
|
+
LineMaterial.prototype.constructor = LineMaterial;
|
|
98809
|
+
|
|
98810
|
+
LineMaterial.prototype.isLineMaterial = true;var LineSegments2 = function ( geometry, material ) {
|
|
98811
|
+
|
|
98812
|
+
if ( geometry === undefined ) geometry = new LineSegmentsGeometry();
|
|
98813
|
+
if ( material === undefined ) material = new LineMaterial( { color: Math.random() * 0xffffff } );
|
|
98814
|
+
|
|
98815
|
+
Mesh.call( this, geometry, material );
|
|
98816
|
+
|
|
98817
|
+
this.type = 'LineSegments2';
|
|
98818
|
+
|
|
98819
|
+
};
|
|
98820
|
+
|
|
98821
|
+
LineSegments2.prototype = Object.assign( Object.create( Mesh.prototype ), {
|
|
98822
|
+
|
|
98823
|
+
constructor: LineSegments2,
|
|
98824
|
+
|
|
98825
|
+
isLineSegments2: true,
|
|
98826
|
+
|
|
98827
|
+
computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
|
|
98828
|
+
|
|
98829
|
+
var start = new Vector3$1();
|
|
98830
|
+
var end = new Vector3$1();
|
|
98831
|
+
|
|
98832
|
+
return function computeLineDistances() {
|
|
98833
|
+
|
|
98834
|
+
var geometry = this.geometry;
|
|
98835
|
+
|
|
98836
|
+
var instanceStart = geometry.attributes.instanceStart;
|
|
98837
|
+
var instanceEnd = geometry.attributes.instanceEnd;
|
|
98838
|
+
var lineDistances = new Float32Array( 2 * instanceStart.data.count );
|
|
98839
|
+
|
|
98840
|
+
for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
|
|
98841
|
+
|
|
98842
|
+
start.fromBufferAttribute( instanceStart, i );
|
|
98843
|
+
end.fromBufferAttribute( instanceEnd, i );
|
|
98844
|
+
|
|
98845
|
+
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
|
|
98846
|
+
lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
|
|
98847
|
+
|
|
98848
|
+
}
|
|
98849
|
+
|
|
98850
|
+
var instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
|
|
98851
|
+
|
|
98852
|
+
geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
|
|
98853
|
+
geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
|
|
98854
|
+
|
|
98855
|
+
return this;
|
|
98856
|
+
|
|
98857
|
+
};
|
|
98858
|
+
|
|
98859
|
+
}() ),
|
|
98860
|
+
|
|
98861
|
+
raycast: ( function () {
|
|
98862
|
+
|
|
98863
|
+
var start = new Vector4();
|
|
98864
|
+
var end = new Vector4();
|
|
98865
|
+
|
|
98866
|
+
var ssOrigin = new Vector4();
|
|
98867
|
+
var ssOrigin3 = new Vector3$1();
|
|
98868
|
+
var mvMatrix = new Matrix4();
|
|
98869
|
+
var line = new Line3();
|
|
98870
|
+
var closestPoint = new Vector3$1();
|
|
98871
|
+
|
|
98872
|
+
return function raycast( raycaster, intersects ) {
|
|
98873
|
+
|
|
98874
|
+
if ( raycaster.camera === null ) {
|
|
98875
|
+
|
|
98876
|
+
console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
|
|
98877
|
+
|
|
98878
|
+
}
|
|
98879
|
+
|
|
98880
|
+
var threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
|
|
98881
|
+
|
|
98882
|
+
var ray = raycaster.ray;
|
|
98883
|
+
var camera = raycaster.camera;
|
|
98884
|
+
var projectionMatrix = camera.projectionMatrix;
|
|
98885
|
+
|
|
98886
|
+
var geometry = this.geometry;
|
|
98887
|
+
var material = this.material;
|
|
98888
|
+
var resolution = material.resolution;
|
|
98889
|
+
var lineWidth = material.linewidth + threshold;
|
|
98890
|
+
|
|
98891
|
+
var instanceStart = geometry.attributes.instanceStart;
|
|
98892
|
+
var instanceEnd = geometry.attributes.instanceEnd;
|
|
98893
|
+
|
|
98894
|
+
// camera forward is negative
|
|
98895
|
+
var near = - camera.near;
|
|
98896
|
+
|
|
98897
|
+
// pick a point 1 unit out along the ray to avoid the ray origin
|
|
98898
|
+
// sitting at the camera origin which will cause "w" to be 0 when
|
|
98899
|
+
// applying the projection matrix.
|
|
98900
|
+
ray.at( 1, ssOrigin );
|
|
98901
|
+
|
|
98902
|
+
// ndc space [ - 1.0, 1.0 ]
|
|
98903
|
+
ssOrigin.w = 1;
|
|
98904
|
+
ssOrigin.applyMatrix4( camera.matrixWorldInverse );
|
|
98905
|
+
ssOrigin.applyMatrix4( projectionMatrix );
|
|
98906
|
+
ssOrigin.multiplyScalar( 1 / ssOrigin.w );
|
|
98907
|
+
|
|
98908
|
+
// screen space
|
|
98909
|
+
ssOrigin.x *= resolution.x / 2;
|
|
98910
|
+
ssOrigin.y *= resolution.y / 2;
|
|
98911
|
+
ssOrigin.z = 0;
|
|
98912
|
+
|
|
98913
|
+
ssOrigin3.copy( ssOrigin );
|
|
98914
|
+
|
|
98915
|
+
var matrixWorld = this.matrixWorld;
|
|
98916
|
+
mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
|
|
98917
|
+
|
|
98918
|
+
for ( var i = 0, l = instanceStart.count; i < l; i ++ ) {
|
|
98919
|
+
|
|
98920
|
+
start.fromBufferAttribute( instanceStart, i );
|
|
98921
|
+
end.fromBufferAttribute( instanceEnd, i );
|
|
98922
|
+
|
|
98923
|
+
start.w = 1;
|
|
98924
|
+
end.w = 1;
|
|
98925
|
+
|
|
98926
|
+
// camera space
|
|
98927
|
+
start.applyMatrix4( mvMatrix );
|
|
98928
|
+
end.applyMatrix4( mvMatrix );
|
|
98929
|
+
|
|
98930
|
+
// skip the segment if it's entirely behind the camera
|
|
98931
|
+
var isBehindCameraNear = start.z > near && end.z > near;
|
|
98932
|
+
if ( isBehindCameraNear ) {
|
|
98933
|
+
|
|
98934
|
+
continue;
|
|
98935
|
+
|
|
98936
|
+
}
|
|
98937
|
+
|
|
98938
|
+
// trim the segment if it extends behind camera near
|
|
98939
|
+
if ( start.z > near ) {
|
|
98940
|
+
|
|
98941
|
+
const deltaDist = start.z - end.z;
|
|
98942
|
+
const t = ( start.z - near ) / deltaDist;
|
|
98943
|
+
start.lerp( end, t );
|
|
98944
|
+
|
|
98945
|
+
} else if ( end.z > near ) {
|
|
98946
|
+
|
|
98947
|
+
const deltaDist = end.z - start.z;
|
|
98948
|
+
const t = ( end.z - near ) / deltaDist;
|
|
98949
|
+
end.lerp( start, t );
|
|
98950
|
+
|
|
98951
|
+
}
|
|
98952
|
+
|
|
98953
|
+
// clip space
|
|
98954
|
+
start.applyMatrix4( projectionMatrix );
|
|
98955
|
+
end.applyMatrix4( projectionMatrix );
|
|
98956
|
+
|
|
98957
|
+
// ndc space [ - 1.0, 1.0 ]
|
|
98958
|
+
start.multiplyScalar( 1 / start.w );
|
|
98959
|
+
end.multiplyScalar( 1 / end.w );
|
|
98960
|
+
|
|
98961
|
+
// screen space
|
|
98962
|
+
start.x *= resolution.x / 2;
|
|
98963
|
+
start.y *= resolution.y / 2;
|
|
98964
|
+
|
|
98965
|
+
end.x *= resolution.x / 2;
|
|
98966
|
+
end.y *= resolution.y / 2;
|
|
98967
|
+
|
|
98968
|
+
// create 2d segment
|
|
98969
|
+
line.start.copy( start );
|
|
98970
|
+
line.start.z = 0;
|
|
98971
|
+
|
|
98972
|
+
line.end.copy( end );
|
|
98973
|
+
line.end.z = 0;
|
|
98974
|
+
|
|
98975
|
+
// get closest point on ray to segment
|
|
98976
|
+
var param = line.closestPointToPointParameter( ssOrigin3, true );
|
|
98977
|
+
line.at( param, closestPoint );
|
|
98978
|
+
|
|
98979
|
+
// check if the intersection point is within clip space
|
|
98980
|
+
var zPos = MathUtils.lerp( start.z, end.z, param );
|
|
98981
|
+
var isInClipSpace = zPos >= - 1 && zPos <= 1;
|
|
98982
|
+
|
|
98983
|
+
var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5;
|
|
98984
|
+
|
|
98985
|
+
if ( isInClipSpace && isInside ) {
|
|
98986
|
+
|
|
98987
|
+
line.start.fromBufferAttribute( instanceStart, i );
|
|
98988
|
+
line.end.fromBufferAttribute( instanceEnd, i );
|
|
98989
|
+
|
|
98990
|
+
line.start.applyMatrix4( matrixWorld );
|
|
98991
|
+
line.end.applyMatrix4( matrixWorld );
|
|
98992
|
+
|
|
98993
|
+
var pointOnLine = new Vector3$1();
|
|
98994
|
+
var point = new Vector3$1();
|
|
98995
|
+
|
|
98996
|
+
ray.distanceSqToSegment( line.start, line.end, point, pointOnLine );
|
|
98997
|
+
|
|
98998
|
+
intersects.push( {
|
|
98999
|
+
|
|
99000
|
+
point: point,
|
|
99001
|
+
pointOnLine: pointOnLine,
|
|
99002
|
+
distance: ray.origin.distanceTo( point ),
|
|
99003
|
+
|
|
99004
|
+
object: this,
|
|
99005
|
+
face: null,
|
|
99006
|
+
faceIndex: i,
|
|
99007
|
+
uv: null,
|
|
99008
|
+
uv2: null,
|
|
99009
|
+
|
|
99010
|
+
} );
|
|
99011
|
+
|
|
99012
|
+
}
|
|
99013
|
+
|
|
99014
|
+
}
|
|
99015
|
+
|
|
99016
|
+
};
|
|
99017
|
+
|
|
99018
|
+
}() )
|
|
99019
|
+
|
|
99020
|
+
} );const BLOB_TYPE = "application/javascript";
|
|
98066
99021
|
const createBlob = task => new Blob(["(", task.toString(), ")()"], {
|
|
98067
99022
|
type: BLOB_TYPE
|
|
98068
99023
|
});
|
|
@@ -98155,22 +99110,27 @@ const DEFAULT_HITBOX_OPTIONS = {
|
|
|
98155
99110
|
shadowsEnabled: false
|
|
98156
99111
|
};
|
|
98157
99112
|
const getBoxHitbox = element => {
|
|
98158
|
-
const
|
|
98159
|
-
|
|
98160
|
-
|
|
98161
|
-
|
|
98162
|
-
|
|
98163
|
-
|
|
98164
|
-
}
|
|
98165
|
-
|
|
98166
|
-
|
|
98167
|
-
|
|
99113
|
+
const opts = element.getPhysicsOptions() || {};
|
|
99114
|
+
let w, h, l;
|
|
99115
|
+
if (opts.colliderWidth != null || opts.colliderHeight != null || opts.colliderLength != null) {
|
|
99116
|
+
w = (opts.colliderWidth ?? 1) + HIT_BOX_INCREASE;
|
|
99117
|
+
h = (opts.colliderHeight ?? 1) + HIT_BOX_INCREASE;
|
|
99118
|
+
l = (opts.colliderLength ?? 1) + HIT_BOX_INCREASE;
|
|
99119
|
+
} else {
|
|
99120
|
+
const size = new Vector3$1();
|
|
99121
|
+
element.boundingBox.getSize(size);
|
|
99122
|
+
w = size.x + HIT_BOX_INCREASE;
|
|
99123
|
+
h = size.y + HIT_BOX_INCREASE;
|
|
99124
|
+
l = size.z + HIT_BOX_INCREASE;
|
|
99125
|
+
}
|
|
99126
|
+
const box = new Box(w, h, l, HIT_BOX_COLOR, DEFAULT_HITBOX_OPTIONS);
|
|
98168
99127
|
box.setWireframe(true);
|
|
98169
99128
|
box.setWireframeLineWidth(2);
|
|
98170
99129
|
return box;
|
|
98171
99130
|
};
|
|
98172
99131
|
const getSphereHitbox = element => {
|
|
98173
|
-
const
|
|
99132
|
+
const opts = element.getPhysicsOptions() || {};
|
|
99133
|
+
const radius = opts.colliderRadius != null ? opts.colliderRadius : element.boundingSphere.radius;
|
|
98174
99134
|
const sphere = new Sphere(radius, HIT_BOX_COLOR, DEFAULT_HITBOX_OPTIONS);
|
|
98175
99135
|
sphere.setWireframe(true);
|
|
98176
99136
|
sphere.setWireframeLineWidth(2);
|
|
@@ -100314,4 +101274,4 @@ var Shaders$1 = new Shaders();let Shader = /*#__PURE__*/_createClass(function Sh
|
|
|
100314
101274
|
...light_contants,
|
|
100315
101275
|
...material_constants,
|
|
100316
101276
|
...controls_contants
|
|
100317
|
-
};export{AUDIO_RAMPS,AmbientLight,AmbientSound,Atmosphere,Audio$1 as Audio,Axes,BUILTIN,BaseScript,Box,CONTROL_EVENTS,Camera,Color,Cone,Config$1 as Config,Controls$1 as Controls,Cube,CurveLine,Cylinder,DirectionalSound,ENTITY_EVENTS,ENTITY_TYPES,Element$1 as Element,Entity,EventDispatcher,Explosion,Exporter,FEATURES,Features$1 as Features,Fire,Fountain,GameRunner$1 as GameRunner,Grid,HelperSprite,HemisphereLight,INPUT_EVENTS,Images$1 as Images,Importer,Input$1 as Input,Label,LabelComponent,Level,Lights$1 as Lights,Line,MirrorElement as Mirror,Models$1 as Models,Ocean,PALETTES,PARTICLES,PHYSICS_CONSTANTS,PHYSICS_EVENTS,ParticleEmitter,ParticleEmitterGroup,Particles$1 as Particles,Physics$1 as Physics,Plane,PointLight,PostProcessing$1 as PostProcessing,Proton,ProtonParticleEmitter,Provider,Rain,Router$1 as Router,Scene$1 as Scene,Scripts$1 as Scripts,Shader,Sky,Skybox,Snow,Sound,Sphere,SpotLight,Sprite,Stats$1 as Stats,SunLight,three_module as THREE,THREEJS_CONTROL_EVENTS,Trail,Universe$1 as Universe,Vector3$1 as Vector3,Water,author,connect,constants,createElement,easing,functions,hitbox as hitboxUtils,index_esm as inferno,map$1 as map,math,object,physicsUtils,index$1 as rxjs,index as store,strings,uuid$1 as uuid,workers,index$2 as xstate};
|
|
101277
|
+
};export{AUDIO_RAMPS,AmbientLight,AmbientSound,Atmosphere,Audio$1 as Audio,Axes,BUILTIN,BaseScript,Box,CONTROL_EVENTS,Camera,Color,Cone,Config$1 as Config,Controls$1 as Controls,Cube,CurveLine,Cylinder,DirectionalSound,ENTITY_EVENTS,ENTITY_TYPES,Element$1 as Element,Entity,EventDispatcher,Explosion,Exporter,FEATURES,Features$1 as Features,Fire,Fountain,GameRunner$1 as GameRunner,Grid,HelperSprite,HemisphereLight,INPUT_EVENTS,Images$1 as Images,Importer,Input$1 as Input,Label,LabelComponent,Level,Lights$1 as Lights,Line,LineMaterial,LineSegments2,LineSegmentsGeometry,MirrorElement as Mirror,Models$1 as Models,Ocean,PALETTES,PARTICLES,PHYSICS_CONSTANTS,PHYSICS_EVENTS,ParticleEmitter,ParticleEmitterGroup,Particles$1 as Particles,Physics$1 as Physics,Plane,PointLight,PostProcessing$1 as PostProcessing,Proton,ProtonParticleEmitter,Provider,Rain,Router$1 as Router,Scene$1 as Scene,Scripts$1 as Scripts,Shader,Sky,Skybox,Snow,Sound,Sphere,SpotLight,Sprite,Stats$1 as Stats,SunLight,three_module as THREE,THREEJS_CONTROL_EVENTS,Trail,Universe$1 as Universe,Vector3$1 as Vector3,Water,author,connect,constants,createElement,easing,functions,hitbox as hitboxUtils,index_esm as inferno,map$1 as map,math,object,physicsUtils,index$1 as rxjs,index as store,strings,uuid$1 as uuid,workers,index$2 as xstate};
|