cacophony
Advanced tools
Comparing version 0.5.4 to 0.5.5
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("standardized-audio-context"),w="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class W{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],n=Uint8Array.from(atob(t),a=>a.charCodeAt(0));return I.decodeAudioData(n.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class d{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class b extends d{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(H(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function H(i,g,I){return Math.min(Math.max(i,g),I)}class l extends d{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new l(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new b(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const S=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function D(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let n=new ArrayBuffer(0);function a(){return t.read().then(({value:s,done:h})=>{let c=null;if(s){if(n.byteLength?c=S(n,s.buffer):(n=s.buffer.slice(0,44),c=s.buffer),g.decodeAudioData(c,function(r){I.push(r),I.length&&A()},function(r){console.log("err(decodeAudioData): "+r)}),h){console.log("done");return}a()}})}a()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class K{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new u.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",w):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new u.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new u.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new l("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new l(A,void 0,this.context,this.globalGainNode,"HTML",C)}return W.getAudioBuffer(A,this.context).then(e=>new l(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await D(g,this.context),new l(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:n,channelInterpretation:a,panningModel:s,refDistance:h,rolloffFactor:c,positionX:r,positionY:B,positionZ:y,orientationX:X,orientationY:V,orientationZ:R}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=n||"clamped-max",o.channelInterpretation=a||"speakers",o.panningModel=s||"HRTF",o.refDistance=h||1,o.rolloffFactor=c||1,o.positionX.value=r||0,o.positionY.value=B||0,o.positionZ.value=y||0,o.orientationX.value=X||0,o.orientationY.value=V||0,o.orientationZ.value=R||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new G(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[n,a,s]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(n,this.context.currentTime),this.listener.upY.setValueAtTime(a,this.context.currentTime),this.listener.upZ.setValueAtTime(s,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class p extends d{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class G extends d{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new p(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}exports.Cacophony=K;exports.Group=Z;exports.MicrophonePlayback=p;exports.MicrophoneStream=G;exports.Playback=b;exports.Sound=l;exports.SoundType=m; | ||
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("standardized-audio-context"),w="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class W{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],n=Uint8Array.from(atob(t),a=>a.charCodeAt(0));return I.decodeAudioData(n.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class d{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class b extends d{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(H(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function H(i,g,I){return Math.min(Math.max(i,g),I)}class l extends d{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new l(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new b(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const S=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function D(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let n=new ArrayBuffer(0);function a(){return t.read().then(({value:s,done:h})=>{let c=null;if(s){if(n.byteLength?c=S(n,s.buffer):(n=s.buffer.slice(0,44),c=s.buffer),g.decodeAudioData(c,function(r){I.push(r),I.length&&A()},function(r){console.log("err(decodeAudioData): "+r)}),h){console.log("done");return}a()}})}a()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class K{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new u.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",w):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new u.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new u.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new l("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new l(A,void 0,this.context,this.globalGainNode,"HTML",C)}return W.getAudioBuffer(A,this.context).then(e=>new l(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await D(g,this.context),new l(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:n,channelInterpretation:a,panningModel:s,refDistance:h,rolloffFactor:c,positionX:r,positionY:B,positionZ:y,orientationX:X,orientationY:V,orientationZ:R}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=n||"clamped-max",o.channelInterpretation=a||"speakers",o.panningModel=s||"HRTF",o.refDistance=h||1,o.rolloffFactor=c||1,o.positionX.value=r||0,o.positionY.value=B||0,o.positionZ.value=y||0,o.orientationX.value=X||0,o.orientationY.value=V||0,o.orientationZ.value=R||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new G(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[n,a,s]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(n,this.context.currentTime),this.listener.upY.setValueAtTime(a,this.context.currentTime),this.listener.upZ.setValueAtTime(s,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class p extends d{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class G extends d{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new p(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}exports.Cacophony=K;exports.Group=Z;exports.MicrophonePlayback=p;exports.MicrophoneStream=G;exports.Playback=b;exports.Sound=l;exports.SoundType=m; | ||
//# sourceMappingURL=cacophony.cjs.js.map |
@@ -1,2 +0,2 @@ | ||
var cacophony=function(n,u){"use strict";const y="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class X{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class h{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class G extends h{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(V(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function V(i,g,I){return Math.min(Math.max(i,g),I)}class c extends h{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new c(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new G(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const R=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function w(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:l,done:b})=>{let r=null;if(l){if(a.byteLength?r=R(a,l.buffer):(a=l.buffer.slice(0,44),r=l.buffer),g.decodeAudioData(r,function(d){I.push(d),I.length&&A()},function(d){console.log("err(decodeAudioData): "+d)}),b){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class W{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new u.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",y):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new u.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new u.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new c("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new c(A,void 0,this.context,this.globalGainNode,"HTML",C)}return X.getAudioBuffer(A,this.context).then(e=>new c(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await w(g,this.context),new c(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:l,refDistance:b,rolloffFactor:r,positionX:d,positionY:H,positionZ:S,orientationX:D,orientationY:K,orientationZ:Y}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=a||"clamped-max",o.channelInterpretation=s||"speakers",o.panningModel=l||"HRTF",o.refDistance=b||1,o.rolloffFactor=r||1,o.positionX.value=d||0,o.positionY.value=H||0,o.positionZ.value=S||0,o.orientationX.value=D||0,o.orientationY.value=K||0,o.orientationZ.value=Y||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new B(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,l]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(a,this.context.currentTime),this.listener.upY.setValueAtTime(s,this.context.currentTime),this.listener.upZ.setValueAtTime(l,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class p extends h{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class B extends h{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new p(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}return n.Cacophony=W,n.Group=Z,n.MicrophonePlayback=p,n.MicrophoneStream=B,n.Playback=G,n.Sound=c,n.SoundType=m,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),n}({},standardizedAudioContext); | ||
var cacophony=function(n,u){"use strict";const y="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class X{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class h{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class G extends h{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(V(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function V(i,g,I){return Math.min(Math.max(i,g),I)}class c extends h{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new c(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new G(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const R=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function w(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:l,done:b})=>{let r=null;if(l){if(a.byteLength?r=R(a,l.buffer):(a=l.buffer.slice(0,44),r=l.buffer),g.decodeAudioData(r,function(d){I.push(d),I.length&&A()},function(d){console.log("err(decodeAudioData): "+d)}),b){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class W{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new u.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",y):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new u.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new u.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new c("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new c(A,void 0,this.context,this.globalGainNode,"HTML",C)}return X.getAudioBuffer(A,this.context).then(e=>new c(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await w(g,this.context),new c(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:l,refDistance:b,rolloffFactor:r,positionX:d,positionY:H,positionZ:S,orientationX:D,orientationY:K,orientationZ:Y}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=a||"clamped-max",o.channelInterpretation=s||"speakers",o.panningModel=l||"HRTF",o.refDistance=b||1,o.rolloffFactor=r||1,o.positionX.value=d||0,o.positionY.value=H||0,o.positionZ.value=S||0,o.orientationX.value=D||0,o.orientationY.value=K||0,o.orientationZ.value=Y||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new B(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,l]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(a,this.context.currentTime),this.listener.upY.setValueAtTime(s,this.context.currentTime),this.listener.upZ.setValueAtTime(l,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class p extends h{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class B extends h{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new p(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}return n.Cacophony=W,n.Group=Z,n.MicrophonePlayback=p,n.MicrophoneStream=B,n.Playback=G,n.Sound=c,n.SoundType=m,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),n}({},standardizedAudioContext); | ||
//# sourceMappingURL=cacophony.iife.js.map |
@@ -1,2 +0,2 @@ | ||
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("standardized-audio-context")):typeof define=="function"&&define.amd?define(["exports","standardized-audio-context"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.cacophony={},n.standardizedAudioContext))})(this,function(n,c){"use strict";const y="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class X{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class u{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class p extends u{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(V(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function V(i,g,I){return Math.min(Math.max(i,g),I)}class r extends u{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new r(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new p(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const R=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function w(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:l,done:b})=>{let d=null;if(l){if(a.byteLength?d=R(a,l.buffer):(a=l.buffer.slice(0,44),d=l.buffer),g.decodeAudioData(d,function(h){I.push(h),I.length&&A()},function(h){console.log("err(decodeAudioData): "+h)}),b){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class W{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new c.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",y):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new c.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new c.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new r("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new r(A,void 0,this.context,this.globalGainNode,"HTML",C)}return X.getAudioBuffer(A,this.context).then(e=>new r(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await w(g,this.context),new r(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:l,refDistance:b,rolloffFactor:d,positionX:h,positionY:H,positionZ:S,orientationX:D,orientationY:K,orientationZ:Y}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=a||"clamped-max",o.channelInterpretation=s||"speakers",o.panningModel=l||"HRTF",o.refDistance=b||1,o.rolloffFactor=d||1,o.positionX.value=h||0,o.positionY.value=H||0,o.positionZ.value=S||0,o.orientationX.value=D||0,o.orientationY.value=K||0,o.orientationZ.value=Y||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new B(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,l]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(a,this.context.currentTime),this.listener.upY.setValueAtTime(s,this.context.currentTime),this.listener.upZ.setValueAtTime(l,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class G extends u{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class B extends u{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new G(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}n.Cacophony=W,n.Group=Z,n.MicrophonePlayback=G,n.MicrophoneStream=B,n.Playback=p,n.Sound=r,n.SoundType=m,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}); | ||
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("standardized-audio-context")):typeof define=="function"&&define.amd?define(["exports","standardized-audio-context"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.cacophony={},n.standardizedAudioContext))})(this,function(n,c){"use strict";const y="data:application/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class X{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class u{filters=[];addFilter(g){this.filters.push(g)}removeFilter(g){this.filters=this.filters.filter(I=>I!==g)}applyFilters(g){return this.filters.reduce((I,C)=>(I.connect(C),C),g),this.filters.length>0?this.filters[this.filters.length-1]:g}}class Z{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class p extends u{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");g.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(V(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(g=>{g&&g.disconnect()}),this.filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.setValueAtTime(I,this.context.currentTime),e.positionY.setValueAtTime(C,this.context.currentTime),e.positionZ.setValueAtTime(A,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}}function V(i,g,I){return Math.min(Math.max(i,g),I)}class r extends u{constructor(g,I,C,A,e=m.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(){const g=new r(this.url,this.buffer,this.context,this.globalGainNode,this.type);return g.loopCount=this.loopCount,g._playbackRate=this._playbackRate,g._volume=this._volume,g._position=this._position,g._threeDOptions=this._threeDOptions,g.filters=this.filters,g.panType=this.panType,g._stereoPan=this._stereoPan,g}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new p(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this.filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop())}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.sourceLoop=!0),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const R=(i,g)=>{var I=new Uint8Array(i.byteLength+g.byteLength);return I.set(new Uint8Array(i),0),I.set(new Uint8Array(g),i.byteLength),I.buffer};function w(i,g){const I=[];let C=0;fetch(i).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:l,done:b})=>{let d=null;if(l){if(a.byteLength?d=R(a,l.buffer):(a=l.buffer.slice(0,44),d=l.buffer),g.decodeAudioData(d,function(h){I.push(h),I.length&&A()},function(h){console.log("err(decodeAudioData): "+h)}),b){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var m=(i=>(i.HTML="HTML",i.Streaming="Streaming",i.Buffer="Buffer",i))(m||{});class W{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new c.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",y):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new c.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new c.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new r("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new r(A,void 0,this.context,this.globalGainNode,"HTML",C)}return X.getAudioBuffer(A,this.context).then(e=>new r(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new Z;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new Z;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await w(g,this.context),new r(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:l,refDistance:b,rolloffFactor:d,positionX:h,positionY:H,positionZ:S,orientationX:D,orientationY:K,orientationZ:Y}){const o=this.context.createPanner();return o.coneInnerAngle=g||360,o.coneOuterAngle=I||360,o.coneOuterGain=C||0,o.distanceModel=A||"inverse",o.maxDistance=e||1e4,o.channelCount=t||2,o.channelCountMode=a||"clamped-max",o.channelInterpretation=s||"speakers",o.panningModel=l||"HRTF",o.refDistance=b||1,o.rolloffFactor=d||1,o.positionX.value=h||0,o.positionY.value=H||0,o.positionZ.value=S||0,o.orientationX.value=D||0,o.orientationY.value=K||0,o.orientationZ.value=Y||0,o}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new B(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,l]=C;this.listener.forwardX.setValueAtTime(A,this.context.currentTime),this.listener.forwardY.setValueAtTime(e,this.context.currentTime),this.listener.forwardZ.setValueAtTime(t,this.context.currentTime),this.listener.upX.setValueAtTime(a,this.context.currentTime),this.listener.upY.setValueAtTime(s,this.context.currentTime),this.listener.upZ.setValueAtTime(l,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.setValueAtTime(I,this.context.currentTime),this.listener.upY.setValueAtTime(C,this.context.currentTime),this.listener.upZ.setValueAtTime(A,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.setValueAtTime(I,this.context.currentTime),this.listener.forwardY.setValueAtTime(C,this.context.currentTime),this.listener.forwardZ.setValueAtTime(A,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g;this.listener.positionX.setValueAtTime(I,this.context.currentTime),this.listener.positionY.setValueAtTime(C,this.context.currentTime),this.listener.positionZ.setValueAtTime(A,this.context.currentTime)}}class G extends u{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class B extends u{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new G(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}n.Cacophony=W,n.Group=Z,n.MicrophonePlayback=G,n.MicrophoneStream=B,n.Playback=p,n.Sound=r,n.SoundType=m,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}); | ||
//# sourceMappingURL=cacophony.umd.js.map |
@@ -63,4 +63,4 @@ /** | ||
/** | ||
* Stops all current playbacks of the sound immediately. This will halt the sound regardless of how many times it has been played. | ||
*/ | ||
* Stops all current playbacks of the sound immediately. This will halt the sound regardless of how many times it has been played. | ||
*/ | ||
stop(): void; | ||
@@ -78,4 +78,4 @@ /** | ||
* @param { number } time - The time in seconds to seek to. | ||
* This method iterates through all active `Playback` instances and calls their `seek()` method with the specified time. | ||
*/ | ||
* This method iterates through all active `Playback` instances and calls their `seek()` method with the specified time. | ||
*/ | ||
seek(time: number): void; | ||
@@ -90,9 +90,2 @@ /** | ||
/** | ||
* Sets the 3D spatial position of the sound in the audio context. | ||
* The position is an array of three values[x, y, z]. | ||
* This method updates the position of all active playbacks of the sound. | ||
* @param { Position } position - The new position of the sound. | ||
*/ | ||
set position(position: Position); | ||
/** | ||
* Retrieves the current 3D spatial position of the sound in the audio context. | ||
@@ -103,2 +96,9 @@ * The position is returned as an array of three values[x, y, z]. | ||
get position(): Position; | ||
/** | ||
* Sets the 3D spatial position of the sound in the audio context. | ||
* The position is an array of three values[x, y, z]. | ||
* This method updates the position of all active playbacks of the sound. | ||
* @param { Position } position - The new position of the sound. | ||
*/ | ||
set position(position: Position); | ||
get threeDOptions(): IPannerOptions; | ||
@@ -110,20 +110,20 @@ set threeDOptions(options: Partial<IPannerOptions>); | ||
* Sets or retrieves the loop behavior for the sound. | ||
* If loopCount is provided, the sound will loop the specified number of times. | ||
* If loopCount is 'infinite', the sound will loop indefinitely until stopped. | ||
* If no argument is provided, the method returns the current loop count setting. | ||
* @param { LoopCount } [loopCount] - The number of times to loop or 'infinite' for indefinite looping. | ||
* @returns { LoopCount } The current loop count setting if no argument is provided. | ||
*/ | ||
* If loopCount is provided, the sound will loop the specified number of times. | ||
* If loopCount is 'infinite', the sound will loop indefinitely until stopped. | ||
* If no argument is provided, the method returns the current loop count setting. | ||
* @param { LoopCount } [loopCount] - The number of times to loop or 'infinite' for indefinite looping. | ||
* @returns { LoopCount } The current loop count setting if no argument is provided. | ||
*/ | ||
loop(loopCount?: LoopCount): LoopCount; | ||
/** | ||
* Adds a BiquadFilterNode to the sound's filter chain. | ||
* Filters are applied in the order they are added. | ||
* @param { BiquadFilterNode } filter - The filter to add to the chain. | ||
*/ | ||
* Adds a BiquadFilterNode to the sound's filter chain. | ||
* Filters are applied in the order they are added. | ||
* @param { BiquadFilterNode } filter - The filter to add to the chain. | ||
*/ | ||
addFilter(filter: BiquadFilterNode): void; | ||
/** | ||
* Removes a BiquadFilterNode from the sound's filter chain. | ||
* If the filter is not part of the chain, the method has no effect. | ||
* @param { BiquadFilterNode } filter - The filter to remove from the chain. | ||
*/ | ||
* If the filter is not part of the chain, the method has no effect. | ||
* @param { BiquadFilterNode } filter - The filter to remove from the chain. | ||
*/ | ||
removeFilter(filter: BiquadFilterNode): void; | ||
@@ -133,5 +133,5 @@ get volume(): number; | ||
/** | ||
* Returns a boolean indicating whether the sound is currently playing. | ||
* @returns {boolean} True if the sound is playing, false otherwise. | ||
*/ | ||
* Returns a boolean indicating whether the sound is currently playing. | ||
* @returns {boolean} True if the sound is playing, false otherwise. | ||
*/ | ||
isPlaying(): boolean; | ||
@@ -138,0 +138,0 @@ get playbackRate(): number; |
"use strict"; | ||
"use strict";(()=>{var Pe=Object.create;var ne=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var _e=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var Me=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Fe=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Oe(e))!Re.call(t,i)&&i!==n&&ne(t,i,{get:()=>e[i],enumerable:!(r=Ie(e,i))||r.enumerable});return t};var De=(t,e,n)=>(n=t!=null?Pe(_e(t)):{},Fe(e||!t||!t.__esModule?ne(n,"default",{value:t,enumerable:!0}):n,t));var ae=Me((se,oe)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i<r.length;i++){var s=r[i],o=e[s];if(Array.isArray(o)){n[s]=o.slice();continue}if(typeof o=="string"||typeof o=="number"||typeof o=="boolean"){n[s]=o;continue}throw new TypeError("clone is not deep and does not support nested objects")}return n},t.FieldRef=function(e,n,r){this.docRef=e,this.fieldName=n,this._stringValue=r},t.FieldRef.joiner="/",t.FieldRef.fromString=function(e){var n=e.indexOf(t.FieldRef.joiner);if(n===-1)throw"malformed field ref string";var r=e.slice(0,n),i=e.slice(n+1);return new t.FieldRef(i,r,e)},t.FieldRef.prototype.toString=function(){return this._stringValue==null&&(this._stringValue=this.fieldName+t.FieldRef.joiner+this.docRef),this._stringValue};t.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var n=0;n<this.length;n++)this.elements[e[n]]=!0}else this.length=0},t.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},t.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},t.Set.prototype.contains=function(e){return!!this.elements[e]},t.Set.prototype.intersect=function(e){var n,r,i,s=[];if(e===t.Set.complete)return this;if(e===t.Set.empty)return e;this.length<e.length?(n=this,r=e):(n=e,r=this),i=Object.keys(n.elements);for(var o=0;o<i.length;o++){var a=i[o];a in r.elements&&s.push(a)}return new t.Set(s)},t.Set.prototype.union=function(e){return e===t.Set.complete?t.Set.complete:e===t.Set.empty?this:new t.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},t.idf=function(e,n){var r=0;for(var i in e)i!="_index"&&(r+=Object.keys(e[i]).length);var s=(n-r+.5)/(r+.5);return Math.log(1+Math.abs(s))},t.Token=function(e,n){this.str=e||"",this.metadata=n||{}},t.Token.prototype.toString=function(){return this.str},t.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},t.Token.prototype.clone=function(e){return e=e||function(n){return n},new t.Token(e(this.str,this.metadata),this.metadata)};t.tokenizer=function(e,n){if(e==null||e==null)return[];if(Array.isArray(e))return e.map(function(v){return new t.Token(t.utils.asString(v).toLowerCase(),t.utils.clone(n))});for(var r=e.toString().toLowerCase(),i=r.length,s=[],o=0,a=0;o<=i;o++){var l=r.charAt(o),u=o-a;if(l.match(t.tokenizer.separator)||o==i){if(u>0){var d=t.utils.clone(n)||{};d.position=[a,u],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. | ||
`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r<n;r++){for(var i=this._stack[r],s=[],o=0;o<e.length;o++){var a=i(e[o],o,e);if(!(a==null||a===""))if(Array.isArray(a))for(var l=0;l<a.length;l++)s.push(a[l]);else s.push(a)}e=s}return e},t.Pipeline.prototype.runString=function(e,n){var r=new t.Token(e,n);return this.run([r]).map(function(i){return i.toString()})},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})};t.Vector=function(e){this._magnitude=0,this.elements=e||[]},t.Vector.prototype.positionForIndex=function(e){if(this.elements.length==0)return 0;for(var n=0,r=this.elements.length/2,i=r-n,s=Math.floor(i/2),o=this.elements[s*2];i>1&&(o<e&&(n=s),o>e&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(o<e)return(s+1)*2},t.Vector.prototype.insert=function(e,n){this.upsert(e,n,function(){throw"duplicate index"})},t.Vector.prototype.upsert=function(e,n,r){this._magnitude=0;var i=this.positionForIndex(e);this.elements[i]==e?this.elements[i+1]=r(this.elements[i+1],n):this.elements.splice(i,0,e,n)},t.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,n=this.elements.length,r=1;r<n;r+=2){var i=this.elements[r];e+=i*i}return this._magnitude=Math.sqrt(e)},t.Vector.prototype.dot=function(e){for(var n=0,r=this.elements,i=e.elements,s=r.length,o=i.length,a=0,l=0,u=0,d=0;u<s&&d<o;)a=r[u],l=i[d],a<l?u+=2:a>l?d+=2:a==l&&(n+=r[u+1]*i[d+1],u+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n<this.elements.length;n+=2,r++)e[r]=this.elements[n];return e},t.Vector.prototype.toJSON=function(){return this.elements};t.stemmer=function(){var e={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},n={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},r="[^aeiou]",i="[aeiouy]",s=r+"[^aeiouy]*",o=i+"[aeiou]*",a="^("+s+")?"+o+s,l="^("+s+")?"+o+s+"("+o+")?$",u="^("+s+")?"+o+s+o+s,d="^("+s+")?"+i,v=new RegExp(a),f=new RegExp(u),b=new RegExp(l),g=new RegExp(d),L=/^(.+?)(ss|i)es$/,p=/^(.+?)([^s])s$/,m=/^(.+?)eed$/,S=/^(.+?)(ed|ing)$/,w=/.$/,k=/(at|bl|iz)$/,_=new RegExp("([^aeiouylsz])\\1$"),H=new RegExp("^"+s+i+"[^aeiouwxy]$"),A=/^(.+?[^aeiou])y$/,j=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,$=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,N=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,q=/^(.+?)(s|t)(ion)$/,P=/^(.+?)e$/,z=/ll$/,W=new RegExp("^"+s+i+"[^aeiouwxy]$"),V=function(c){var y,I,T,h,x,O,M;if(c.length<3)return c;if(T=c.substr(0,1),T=="y"&&(c=T.toUpperCase()+c.substr(1)),h=L,x=p,h.test(c)?c=c.replace(h,"$1$2"):x.test(c)&&(c=c.replace(x,"$1$2")),h=m,x=S,h.test(c)){var E=h.exec(c);h=v,h.test(E[1])&&(h=w,c=c.replace(h,""))}else if(x.test(c)){var E=x.exec(c);y=E[1],x=g,x.test(y)&&(c=y,x=k,O=_,M=H,x.test(c)?c=c+"e":O.test(c)?(h=w,c=c.replace(h,"")):M.test(c)&&(c=c+"e"))}if(h=A,h.test(c)){var E=h.exec(c);y=E[1],c=y+"i"}if(h=j,h.test(c)){var E=h.exec(c);y=E[1],I=E[2],h=v,h.test(y)&&(c=y+e[I])}if(h=$,h.test(c)){var E=h.exec(c);y=E[1],I=E[2],h=v,h.test(y)&&(c=y+n[I])}if(h=N,x=q,h.test(c)){var E=h.exec(c);y=E[1],h=f,h.test(y)&&(c=y)}else if(x.test(c)){var E=x.exec(c);y=E[1]+E[2],x=f,x.test(y)&&(c=y)}if(h=P,h.test(c)){var E=h.exec(c);y=E[1],h=f,x=b,O=W,(h.test(y)||x.test(y)&&!O.test(y))&&(c=y)}return h=z,x=f,h.test(c)&&x.test(c)&&(h=w,c=c.replace(h,"")),T=="y"&&(c=T.toLowerCase()+c.substr(1)),c};return function(R){return R.update(V)}}(),t.Pipeline.registerFunction(t.stemmer,"stemmer");t.generateStopWordFilter=function(e){var n=e.reduce(function(r,i){return r[i]=i,r},{});return function(r){if(r&&n[r.toString()]!==r.toString())return r}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter");t.trimmer=function(e){return e.update(function(n){return n.replace(/^\W+/,"").replace(/\W+$/,"")})},t.Pipeline.registerFunction(t.trimmer,"trimmer");t.TokenSet=function(){this.final=!1,this.edges={},this.id=t.TokenSet._nextId,t.TokenSet._nextId+=1},t.TokenSet._nextId=1,t.TokenSet.fromArray=function(e){for(var n=new t.TokenSet.Builder,r=0,i=e.length;r<i;r++)n.insert(e[r]);return n.finish(),n.root},t.TokenSet.fromClause=function(e){return"editDistance"in e?t.TokenSet.fromFuzzyString(e.term,e.editDistance):t.TokenSet.fromString(e.term)},t.TokenSet.fromFuzzyString=function(e,n){for(var r=new t.TokenSet,i=[{node:r,editsRemaining:n,str:e}];i.length;){var s=i.pop();if(s.str.length>0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),v=s.str.charAt(1),f;v in s.node.edges?f=s.node.edges[v]:(f=new t.TokenSet,s.node.edges[v]=f),s.str.length==1&&(f.final=!0),i.push({node:f,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i<s;i++){var o=e[i],a=i==s-1;if(o=="*")n.edges[o]=n,n.final=a;else{var l=new t.TokenSet;l.final=a,n.edges[o]=l,n=l}}return r},t.TokenSet.prototype.toArray=function(){for(var e=[],n=[{prefix:"",node:this}];n.length;){var r=n.pop(),i=Object.keys(r.node.edges),s=i.length;r.node.final&&(r.prefix.charAt(0),e.push(r.prefix));for(var o=0;o<s;o++){var a=i[o];n.push({prefix:r.prefix.concat(a),node:r.node.edges[a]})}}return e},t.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",n=Object.keys(this.edges).sort(),r=n.length,i=0;i<r;i++){var s=n[i],o=this.edges[s];e=e+s+o.id}return e},t.TokenSet.prototype.intersect=function(e){for(var n=new t.TokenSet,r=void 0,i=[{qNode:e,output:n,node:this}];i.length;){r=i.pop();for(var s=Object.keys(r.qNode.edges),o=s.length,a=Object.keys(r.node.edges),l=a.length,u=0;u<o;u++)for(var d=s[u],v=0;v<l;v++){var f=a[v];if(f==d||d=="*"){var b=r.node.edges[f],g=r.qNode.edges[d],L=b.final&&g.final,p=void 0;f in r.output.edges?(p=r.output.edges[f],p.final=p.final||L):(p=new t.TokenSet,p.final=L,r.output.edges[f]=p),i.push({qNode:g,output:p,node:b})}}}return n},t.TokenSet.Builder=function(){this.previousWord="",this.root=new t.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},t.TokenSet.Builder.prototype.insert=function(e){var n,r=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var i=0;i<e.length&&i<this.previousWord.length&&e[i]==this.previousWord[i];i++)r++;this.minimize(r),this.uncheckedNodes.length==0?n=this.root:n=this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(var i=r;i<e.length;i++){var s=new t.TokenSet,o=e[i];n.edges[o]=s,this.uncheckedNodes.push({parent:n,char:o,child:s}),n=s}n.final=!0,this.previousWord=e},t.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},t.TokenSet.Builder.prototype.minimize=function(e){for(var n=this.uncheckedNodes.length-1;n>=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l<this.fields.length;l++)i[this.fields[l]]=new t.Vector;e.call(n,n);for(var l=0;l<n.clauses.length;l++){var u=n.clauses[l],d=null,v=t.Set.empty;u.usePipeline?d=this.pipeline.runString(u.term,{fields:u.fields}):d=[u.term];for(var f=0;f<d.length;f++){var b=d[f];u.term=b;var g=t.TokenSet.fromClause(u),L=this.tokenSet.intersect(g).toArray();if(L.length===0&&u.presence===t.Query.presence.REQUIRED){for(var p=0;p<u.fields.length;p++){var m=u.fields[p];o[m]=t.Set.empty}break}for(var S=0;S<L.length;S++)for(var w=L[S],k=this.invertedIndex[w],_=k._index,p=0;p<u.fields.length;p++){var m=u.fields[p],H=k[m],A=Object.keys(H),j=w+"/"+m,$=new t.Set(A);if(u.presence==t.Query.presence.REQUIRED&&(v=v.union($),o[m]===void 0&&(o[m]=t.Set.complete)),u.presence==t.Query.presence.PROHIBITED){a[m]===void 0&&(a[m]=t.Set.empty),a[m]=a[m].union($);continue}if(i[m].upsert(_,u.boost,function(Qe,Ce){return Qe+Ce}),!s[j]){for(var N=0;N<A.length;N++){var q=A[N],P=new t.FieldRef(q,m),z=H[q],W;(W=r[P])===void 0?r[P]=new t.MatchData(w,m,z):W.add(w,m,z)}s[j]=!0}}}if(u.presence===t.Query.presence.REQUIRED)for(var p=0;p<u.fields.length;p++){var m=u.fields[p];o[m]=o[m].intersect(v)}}for(var V=t.Set.complete,R=t.Set.empty,l=0;l<this.fields.length;l++){var m=this.fields[l];o[m]&&(V=V.intersect(o[m])),a[m]&&(R=R.union(a[m]))}var c=Object.keys(r),y=[],I=Object.create(null);if(n.isNegated()){c=Object.keys(this.fieldVectors);for(var l=0;l<c.length;l++){var P=c[l],T=t.FieldRef.fromString(P);r[P]=new t.MatchData}}for(var l=0;l<c.length;l++){var T=t.FieldRef.fromString(c[l]),h=T.docRef;if(V.contains(h)&&!R.contains(h)){var x=this.fieldVectors[T],O=i[T.fieldName].similarity(x),M;if((M=I[h])!==void 0)M.score+=O,M.matchData.combine(r[T]);else{var E={ref:h,score:O,matchData:r[T]};I[h]=E,y.push(E)}}}return y.sort(function(Te,ke){return ke.score-Te.score})},t.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map(function(r){return[r,this.invertedIndex[r]]},this),n=Object.keys(this.fieldVectors).map(function(r){return[r,this.fieldVectors[r].toJSON()]},this);return{version:t.version,fields:this.fields,fieldVectors:n,invertedIndex:e,pipeline:this.pipeline.toJSON()}},t.Index.load=function(e){var n={},r={},i=e.fieldVectors,s=Object.create(null),o=e.invertedIndex,a=new t.TokenSet.Builder,l=t.Pipeline.load(e.pipeline);e.version!=t.version&&t.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+t.version+"' does not match serialized index '"+e.version+"'");for(var u=0;u<i.length;u++){var d=i[u],v=d[0],f=d[1];r[v]=new t.Vector(f)}for(var u=0;u<o.length;u++){var d=o[u],b=d[0],g=d[1];a.insert(b),s[b]=g}return a.finish(),n.fields=e.fields,n.fieldVectors=r,n.invertedIndex=s,n.tokenSet=a.root,n.pipeline=l,new t.Index(n)};t.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=t.tokenizer,this.pipeline=new t.Pipeline,this.searchPipeline=new t.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},t.Builder.prototype.ref=function(e){this._ref=e},t.Builder.prototype.field=function(e,n){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=n||{}},t.Builder.prototype.b=function(e){e<0?this._b=0:e>1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s<i.length;s++){var o=i[s],a=this._fields[o].extractor,l=a?a(e):e[o],u=this.tokenizer(l,{fields:[o]}),d=this.pipeline.run(u),v=new t.FieldRef(r,o),f=Object.create(null);this.fieldTermFrequencies[v]=f,this.fieldLengths[v]=0,this.fieldLengths[v]+=d.length;for(var b=0;b<d.length;b++){var g=d[b];if(f[g]==null&&(f[g]=0),f[g]+=1,this.invertedIndex[g]==null){var L=Object.create(null);L._index=this.termIndex,this.termIndex+=1;for(var p=0;p<i.length;p++)L[i[p]]=Object.create(null);this.invertedIndex[g]=L}this.invertedIndex[g][o][r]==null&&(this.invertedIndex[g][o][r]=Object.create(null));for(var m=0;m<this.metadataWhitelist.length;m++){var S=this.metadataWhitelist[m],w=g.metadata[S];this.invertedIndex[g][o][r][S]==null&&(this.invertedIndex[g][o][r][S]=[]),this.invertedIndex[g][o][r][S].push(w)}}}},t.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),n=e.length,r={},i={},s=0;s<n;s++){var o=t.FieldRef.fromString(e[s]),a=o.fieldName;i[a]||(i[a]=0),i[a]+=1,r[a]||(r[a]=0),r[a]+=this.fieldLengths[o]}for(var l=Object.keys(this._fields),s=0;s<l.length;s++){var u=l[s];r[u]=r[u]/i[u]}this.averageFieldLength=r},t.Builder.prototype.createFieldVectors=function(){for(var e={},n=Object.keys(this.fieldTermFrequencies),r=n.length,i=Object.create(null),s=0;s<r;s++){for(var o=t.FieldRef.fromString(n[s]),a=o.fieldName,l=this.fieldLengths[o],u=new t.Vector,d=this.fieldTermFrequencies[o],v=Object.keys(d),f=v.length,b=this._fields[a].boost||1,g=this._documents[o.docRef].boost||1,L=0;L<f;L++){var p=v[L],m=d[p],S=this.invertedIndex[p]._index,w,k,_;i[p]===void 0?(w=t.idf(this.invertedIndex[p],this.documentCount),i[p]=w):w=i[p],k=w*((this._k1+1)*m)/(this._k1*(1-this._b+this._b*(l/this.averageFieldLength[a]))+m),k*=b,k*=g,_=Math.round(k*1e3)/1e3,u.insert(S,_)}e[o]=u}this.fieldVectors=e},t.Builder.prototype.createTokenSet=function(){this.tokenSet=t.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},t.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new t.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},t.Builder.prototype.use=function(e){var n=Array.prototype.slice.call(arguments,1);n.unshift(this),e.apply(this,n)},t.MatchData=function(e,n,r){for(var i=Object.create(null),s=Object.keys(r||{}),o=0;o<s.length;o++){var a=s[o];i[a]=r[a].slice()}this.metadata=Object.create(null),e!==void 0&&(this.metadata[e]=Object.create(null),this.metadata[e][n]=i)},t.MatchData.prototype.combine=function(e){for(var n=Object.keys(e.metadata),r=0;r<n.length;r++){var i=n[r],s=Object.keys(e.metadata[i]);this.metadata[i]==null&&(this.metadata[i]=Object.create(null));for(var o=0;o<s.length;o++){var a=s[o],l=Object.keys(e.metadata[i][a]);this.metadata[i][a]==null&&(this.metadata[i][a]=Object.create(null));for(var u=0;u<l.length;u++){var d=l[u];this.metadata[i][a][d]==null?this.metadata[i][a][d]=e.metadata[i][a][d]:this.metadata[i][a][d]=this.metadata[i][a][d].concat(e.metadata[i][a][d])}}}},t.MatchData.prototype.add=function(e,n,r){if(!(e in this.metadata)){this.metadata[e]=Object.create(null),this.metadata[e][n]=r;return}if(!(n in this.metadata[e])){this.metadata[e][n]=r;return}for(var i=Object.keys(r),s=0;s<i.length;s++){var o=i[s];o in this.metadata[e][n]?this.metadata[e][n][o]=this.metadata[e][n][o].concat(r[o]):this.metadata[e][n][o]=r[o]}},t.Query=function(e){this.clauses=[],this.allFields=e},t.Query.wildcard=new String("*"),t.Query.wildcard.NONE=0,t.Query.wildcard.LEADING=1,t.Query.wildcard.TRAILING=2,t.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},t.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=t.Query.wildcard.NONE),e.wildcard&t.Query.wildcard.LEADING&&e.term.charAt(0)!=t.Query.wildcard&&(e.term="*"+e.term),e.wildcard&t.Query.wildcard.TRAILING&&e.term.slice(-1)!=t.Query.wildcard&&(e.term=""+e.term+"*"),"presence"in e||(e.presence=t.Query.presence.OPTIONAL),this.clauses.push(e),this},t.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=t.Query.presence.PROHIBITED)return!1;return!0},t.Query.prototype.term=function(e,n){if(Array.isArray(e))return e.forEach(function(i){this.term(i,t.utils.clone(n))},this),this;var r=n||{};return r.term=e.toString(),this.clause(r),this},t.QueryParseError=function(e,n,r){this.name="QueryParseError",this.message=e,this.start=n,this.end=r},t.QueryParseError.prototype=new Error,t.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},t.QueryLexer.prototype.run=function(){for(var e=t.QueryLexer.lexText;e;)e=e(this)},t.QueryLexer.prototype.sliceString=function(){for(var e=[],n=this.start,r=this.pos,i=0;i<this.escapeCharPositions.length;i++)r=this.escapeCharPositions[i],e.push(this.str.slice(n,r)),n=r+1;return e.push(this.str.slice(n,this.pos)),this.escapeCharPositions.length=0,e.join("")},t.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},t.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},t.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos<this.length},t.QueryLexer.EOS="EOS",t.QueryLexer.FIELD="FIELD",t.QueryLexer.TERM="TERM",t.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",t.QueryLexer.BOOST="BOOST",t.QueryLexer.PRESENCE="PRESENCE",t.QueryLexer.lexField=function(e){return e.backup(),e.emit(t.QueryLexer.FIELD),e.ignore(),t.QueryLexer.lexText},t.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof se=="object"?oe.exports=n():e.lunr=n()}(this,function(){return t})})()});var re=[];function G(t,e){re.push({selector:e,constructor:t})}var U=class{constructor(){this.alwaysVisibleMember=null;this.createComponents(document.body),this.ensureActivePageVisible(),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible())}createComponents(e){re.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r}}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(n&&n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let r=document.createElement("p");r.classList.add("warning"),r.textContent="This member is normally hidden due to your filter settings.",n.prepend(r)}}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent="Copied!",e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent="Copy"},100)},1e3)})})}};var ie=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var de=De(ae());async function le(t,e){if(!window.searchData)return;let n=await fetch(window.searchData),r=new Blob([await n.arrayBuffer()]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();t.data=i,t.index=de.Index.load(i.index),e.classList.remove("loading"),e.classList.add("ready")}function he(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:t.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{le(e,t)}),le(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");let s=!1;i.addEventListener("mousedown",()=>s=!0),i.addEventListener("mouseup",()=>{s=!1,t.classList.remove("has-focus")}),r.addEventListener("focus",()=>t.classList.add("has-focus")),r.addEventListener("blur",()=>{s||(s=!1,t.classList.remove("has-focus"))}),Ae(t,i,r,e)}function Ae(t,e,n,r){n.addEventListener("input",ie(()=>{Ne(t,e,n,r)},200));let i=!1;n.addEventListener("keydown",s=>{i=!0,s.key=="Enter"?Ve(e,n):s.key=="Escape"?n.blur():s.key=="ArrowUp"?ue(e,-1):s.key==="ArrowDown"?ue(e,1):i=!1}),n.addEventListener("keypress",s=>{i&&s.preventDefault()}),document.body.addEventListener("keydown",s=>{s.altKey||s.ctrlKey||s.metaKey||!n.matches(":focus")&&s.key==="/"&&(n.focus(),s.preventDefault())})}function Ne(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;o<s.length;o++){let a=s[o],l=r.data.rows[Number(a.ref)],u=1;l.name.toLowerCase().startsWith(i.toLowerCase())&&(u*=1+1/(1+Math.abs(l.name.length-i.length))),a.score*=u}if(s.length===0){let o=document.createElement("li");o.classList.add("no-results");let a=document.createElement("span");a.textContent="No results found",o.appendChild(a),e.appendChild(o)}s.sort((o,a)=>a.score-o.score);for(let o=0,a=Math.min(10,s.length);o<a;o++){let l=r.data.rows[Number(s[o].ref)],u=`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon"><use href="#icon-${l.kind}"></use></svg>`,d=ce(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=`<span class="parent"> | ||
${ce(l.parent,i)}.</span>${d}`);let v=document.createElement("li");v.classList.value=l.classes??"";let f=document.createElement("a");f.href=r.base+l.url,f.innerHTML=u+d,v.append(f),e.appendChild(v)}}function ue(t,e){let n=t.querySelector(".current");if(!n)n=t.querySelector(e==1?"li:first-child":"li:last-child"),n&&n.classList.add("current");else{let r=n;if(e===1)do r=r.nextElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);else do r=r.previousElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);r&&(n.classList.remove("current"),r.classList.add("current"))}}function Ve(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),e.blur()}}function ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(K(t.substring(s,o)),`<b>${K(t.substring(o,o+r.length))}</b>`),s=o+r.length,o=n.indexOf(r,s);return i.push(K(t.substring(s))),i.join("")}var Be={"&":"&","<":"<",">":">","'":"'",'"':"""};function K(t){return t.replace(/[&<>"'"]/g,e=>Be[e])}var C=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",pe="mousemove",B="mouseup",J={x:0,y:0},fe=!1,ee=!1,He=!1,D=!1,me=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(me?"is-mobile":"not-mobile");me&&"ontouchstart"in document.documentElement&&(He=!0,F="touchstart",pe="touchmove",B="touchend");document.addEventListener(F,t=>{ee=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(pe,t=>{if(ee&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(B,()=>{ee=!1});document.addEventListener("click",t=>{fe&&(t.preventDefault(),t.stopImmediatePropagation(),fe=!1)});var X=class extends C{constructor(n){super(n);this.className=this.el.dataset.toggle||"",this.el.addEventListener(B,r=>this.onPointerUp(r)),this.el.addEventListener("click",r=>r.preventDefault()),document.addEventListener(F,r=>this.onDocumentPointerDown(r)),document.addEventListener(B,r=>this.onDocumentPointerUp(r))}setActive(n){if(this.active==n)return;this.active=n,document.documentElement.classList.toggle("has-"+this.className,n),this.el.classList.toggle("active",n);let r=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(r),setTimeout(()=>document.documentElement.classList.remove(r),500)}onPointerUp(n){D||(this.setActive(!0),n.preventDefault())}onDocumentPointerDown(n){if(this.active){if(n.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(n){if(!D&&this.active&&n.target.closest(".col-sidebar")){let r=n.target.closest("a");if(r){let i=window.location.href;i.indexOf("#")!=-1&&(i=i.substring(0,i.indexOf("#"))),r.href.substring(0,i.length)==i&&setTimeout(()=>this.setActive(!1),250)}}}};var te;try{te=localStorage}catch{te={getItem(){return null},setItem(){}}}var Q=te;var ve=document.head.appendChild(document.createElement("style"));ve.dataset.for="filters";var Y=class extends C{constructor(n){super(n);this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ve.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } | ||
`}fromLocalStorage(){let n=Q.getItem(this.key);return n?n==="true":this.el.checked}setLocalStorage(n){Q.setItem(this.key,n.toString()),this.value=n,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),document.querySelectorAll(".tsd-index-section").forEach(n=>{n.style.display="block";let r=Array.from(n.querySelectorAll(".tsd-index-link")).every(i=>i.offsetParent==null);n.style.display=r?"none":"block"})}};var Z=class extends C{constructor(n){super(n);this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let r=Q.getItem(this.key);this.el.open=r?r==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let i=this.summary.querySelector("a");i&&i.addEventListener("click",()=>{location.assign(i.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function ge(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,ye(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),ye(t.value)})}function ye(t){document.documentElement.dataset.theme=t}var Le;function be(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",xe),xe())}async function xe(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();Le=t.dataset.base+"/",t.innerHTML="";for(let s of i)we(s,t,[]);window.app.createComponents(t),window.app.ensureActivePageVisible()}function we(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-index-accordion`:"tsd-index-accordion",s.dataset.key=i.join("$");let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.innerHTML='<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="#icon-chevronDown"></use></svg>',Ee(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)we(u,l,i)}else Ee(t,r,t.class)}function Ee(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=Le+t.path,n&&(r.className=n),location.href===r.href&&r.classList.add("current"),t.kind&&(r.innerHTML=`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon"><use href="#icon-${t.kind}"></use></svg>`),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-index-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Se=document.getElementById("tsd-theme");Se&&ge(Se);var je=new U;Object.defineProperty(window,"app",{value:je});he();be();})(); | ||
${ce(l.parent,i)}.</span>${d}`);let v=document.createElement("li");v.classList.value=l.classes??"";let f=document.createElement("a");f.href=r.base+l.url,f.innerHTML=u+d,v.append(f),e.appendChild(v)}}function ue(t,e){let n=t.querySelector(".current");if(!n)n=t.querySelector(e==1?"li:first-child":"li:last-child"),n&&n.classList.add("current");else{let r=n;if(e===1)do r=r.nextElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);else do r=r.previousElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);r&&(n.classList.remove("current"),r.classList.add("current"))}}function Ve(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),e.blur()}}function ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(K(t.substring(s,o)),`<b>${K(t.substring(o,o+r.length))}</b>`),s=o+r.length,o=n.indexOf(r,s);return i.push(K(t.substring(s))),i.join("")}var Be={"&":"&","<":"<",">":">","'":"'",'"':"""};function K(t){return t.replace(/[&<>"'"]/g,e=>Be[e])}var C=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",pe="mousemove",B="mouseup",J={x:0,y:0},fe=!1,ee=!1,He=!1,D=!1,me=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(me?"is-mobile":"not-mobile");me&&"ontouchstart"in document.documentElement&&(He=!0,F="touchstart",pe="touchmove",B="touchend");document.addEventListener(F,t=>{ee=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(pe,t=>{if(ee&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(B,()=>{ee=!1});document.addEventListener("click",t=>{fe&&(t.preventDefault(),t.stopImmediatePropagation(),fe=!1)});var X=class extends C{constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(B,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(F,n=>this.onDocumentPointerDown(n)),document.addEventListener(B,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var te;try{te=localStorage}catch{te={getItem(){return null},setItem(){}}}var Q=te;var ve=document.head.appendChild(document.createElement("style"));ve.dataset.for="filters";var Y=class extends C{constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ve.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } | ||
`,this.handleValueChange()}fromLocalStorage(){let e=Q.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){Q.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),document.querySelectorAll(".tsd-index-section").forEach(e=>{e.style.display="block";let n=Array.from(e.querySelectorAll(".tsd-index-link")).every(r=>r.offsetParent==null);e.style.display=n?"none":"block"})}};var Z=class extends C{constructor(e){super(e),this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let n=Q.getItem(this.key);this.el.open=n?n==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let r=this.summary.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function ge(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,ye(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),ye(t.value)})}function ye(t){document.documentElement.dataset.theme=t}var Le;function be(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",xe),xe())}async function xe(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();Le=t.dataset.base+"/",t.innerHTML="";for(let s of i)we(s,t,[]);window.app.createComponents(t),window.app.ensureActivePageVisible()}function we(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-index-accordion`:"tsd-index-accordion",s.dataset.key=i.join("$");let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.innerHTML='<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="#icon-chevronDown"></use></svg>',Ee(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)we(u,l,i)}else Ee(t,r,t.class)}function Ee(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=Le+t.path,n&&(r.className=n),location.href===r.href&&r.classList.add("current"),t.kind&&(r.innerHTML=`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon"><use href="#icon-${t.kind}"></use></svg>`),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-index-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Se=document.getElementById("tsd-theme");Se&&ge(Se);var je=new U;Object.defineProperty(window,"app",{value:je});he();be();})(); | ||
/*! Bundled license information: | ||
@@ -7,0 +7,0 @@ |
{ | ||
"name": "cacophony", | ||
"version": "0.5.4", | ||
"version": "0.5.5", | ||
"description": "Typescript audio library with caching", | ||
@@ -41,13 +41,13 @@ "type": "module", | ||
"@rollup/plugin-replace": "^5.0.5", | ||
"@rollup/plugin-typescript": "^11.1.5", | ||
"@types/jest": "^29.5.11", | ||
"@rollup/plugin-typescript": "^11.1.6", | ||
"@types/jest": "^29.5.12", | ||
"jest": "^29.7.0", | ||
"rimraf": "^5.0.5", | ||
"rollup": "^4.9.2", | ||
"standardized-audio-context-mock": "^9.6.31", | ||
"ts-jest": "^29.1.1", | ||
"typedoc": "^0.25.4", | ||
"rollup": "^4.9.6", | ||
"standardized-audio-context-mock": "^9.6.33", | ||
"ts-jest": "^29.1.2", | ||
"typedoc": "^0.25.7", | ||
"typescript": "^5.3.2", | ||
"vite": "^5.0.10", | ||
"vite-plugin-dts": "^3.6.4" | ||
"vite": "^5.0.12", | ||
"vite-plugin-dts": "^3.7.2" | ||
}, | ||
@@ -60,4 +60,4 @@ "jest": { | ||
"fft.js": "^4.0.4", | ||
"standardized-audio-context": "^25.3.60" | ||
"standardized-audio-context": "^25.3.64" | ||
} | ||
} |
@@ -30,5 +30,2 @@ /** | ||
export class Sound extends FilterManager implements BaseSound { | ||
@@ -141,4 +138,5 @@ buffer?: IAudioBuffer; | ||
/** | ||
* Stops all current playbacks of the sound immediately. This will halt the sound regardless of how many times it has been played. | ||
*/ | ||
* Stops all current playbacks of the sound immediately. This will halt the sound regardless of how many times it has been played. | ||
*/ | ||
stop() { | ||
@@ -151,2 +149,3 @@ this.playbacks.forEach(p => p.stop()); | ||
*/ | ||
pause(): void { | ||
@@ -167,4 +166,4 @@ this.playbacks.forEach(playback => playback.pause()); | ||
* @param { number } time - The time in seconds to seek to. | ||
* This method iterates through all active `Playback` instances and calls their `seek()` method with the specified time. | ||
*/ | ||
* This method iterates through all active `Playback` instances and calls their `seek()` method with the specified time. | ||
*/ | ||
@@ -187,15 +186,2 @@ seek(time: number): void { | ||
/** | ||
* Sets the 3D spatial position of the sound in the audio context. | ||
* The position is an array of three values[x, y, z]. | ||
* This method updates the position of all active playbacks of the sound. | ||
* @param { Position } position - The new position of the sound. | ||
*/ | ||
set position(position: Position) { | ||
this._threeDOptions.positionX = position[0]; | ||
this._threeDOptions.positionY = position[1]; | ||
this._threeDOptions.positionZ = position[2]; | ||
this.playbacks.forEach(p => p.position = position); | ||
} | ||
/** | ||
* Retrieves the current 3D spatial position of the sound in the audio context. | ||
@@ -210,2 +196,17 @@ * The position is returned as an array of three values[x, y, z]. | ||
/** | ||
* Sets the 3D spatial position of the sound in the audio context. | ||
* The position is an array of three values[x, y, z]. | ||
* This method updates the position of all active playbacks of the sound. | ||
* @param { Position } position - The new position of the sound. | ||
*/ | ||
set position(position: Position) { | ||
this._threeDOptions.positionX = position[0]; | ||
this._threeDOptions.positionY = position[1]; | ||
this._threeDOptions.positionZ = position[2]; | ||
this.playbacks.forEach(p => p.position = position); | ||
} | ||
get threeDOptions(): IPannerOptions { | ||
@@ -231,8 +232,9 @@ return this._threeDOptions; | ||
* Sets or retrieves the loop behavior for the sound. | ||
* If loopCount is provided, the sound will loop the specified number of times. | ||
* If loopCount is 'infinite', the sound will loop indefinitely until stopped. | ||
* If no argument is provided, the method returns the current loop count setting. | ||
* @param { LoopCount } [loopCount] - The number of times to loop or 'infinite' for indefinite looping. | ||
* @returns { LoopCount } The current loop count setting if no argument is provided. | ||
*/ | ||
* If loopCount is provided, the sound will loop the specified number of times. | ||
* If loopCount is 'infinite', the sound will loop indefinitely until stopped. | ||
* If no argument is provided, the method returns the current loop count setting. | ||
* @param { LoopCount } [loopCount] - The number of times to loop or 'infinite' for indefinite looping. | ||
* @returns { LoopCount } The current loop count setting if no argument is provided. | ||
*/ | ||
loop(loopCount?: LoopCount): LoopCount { | ||
@@ -248,6 +250,7 @@ if (loopCount === undefined) { | ||
/** | ||
* Adds a BiquadFilterNode to the sound's filter chain. | ||
* Filters are applied in the order they are added. | ||
* @param { BiquadFilterNode } filter - The filter to add to the chain. | ||
*/ | ||
* Adds a BiquadFilterNode to the sound's filter chain. | ||
* Filters are applied in the order they are added. | ||
* @param { BiquadFilterNode } filter - The filter to add to the chain. | ||
*/ | ||
addFilter(filter: BiquadFilterNode): void { | ||
@@ -260,5 +263,5 @@ super.addFilter(filter); | ||
* Removes a BiquadFilterNode from the sound's filter chain. | ||
* If the filter is not part of the chain, the method has no effect. | ||
* @param { BiquadFilterNode } filter - The filter to remove from the chain. | ||
*/ | ||
* If the filter is not part of the chain, the method has no effect. | ||
* @param { BiquadFilterNode } filter - The filter to remove from the chain. | ||
*/ | ||
@@ -280,5 +283,5 @@ removeFilter(filter: BiquadFilterNode): void { | ||
/** | ||
* Returns a boolean indicating whether the sound is currently playing. | ||
* @returns {boolean} True if the sound is playing, false otherwise. | ||
*/ | ||
* Returns a boolean indicating whether the sound is currently playing. | ||
* @returns {boolean} True if the sound is playing, false otherwise. | ||
*/ | ||
isPlaying(): boolean { | ||
@@ -285,0 +288,0 @@ return this.playbacks.some(p => p.isPlaying()); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1593753
59
6357