From 21f77fa4c3dfe04e98d95f69d2238cf335973db4 Mon Sep 17 00:00:00 2001 From: Josh Burman Date: Thu, 14 Mar 2019 10:14:42 -0400 Subject: [PATCH] unit tests, and some cleaning up --- dist/server/client/sites/mhsClient.js | 8 - dist/server/client/sites/mhsClient.js.map | 1 - dist/server/clients/base.js | 22 - dist/server/clients/base.js.map | 1 - dist/server/config/app.js | 2 +- dist/server/config/app.js.map | 2 +- dist/server/server.js | 107 +- dist/server/server.js.map | 2 +- dist/server/test/appController.spec.js | 2 - dist/server/test/appController.spec.js.map | 1 - dist/server/test/authController.spec.js | 2 - dist/server/test/authController.spec.js.map | 1 - dist/server/test/channelBase.spec.js | 11 +- dist/server/test/channelBase.spec.js.map | 2 +- dist/server/test/clientManager.spec.js | 4 - dist/server/test/clientManager.spec.js.map | 2 +- logs/access.log | 163 +- logs/errors.log | 66 +- ...bb5f5e3698894e5207c6ebd8a349f344baa729f.js | 37 + ...b5f5e3698894e5207c6ebd8a349f344baa729f.map | 1 + ...7c53972f008d85c26ff3d09e1c9508c8490cac7.js | 42 + ...c53972f008d85c26ff3d09e1c9508c8490cac7.map | 1 + ...854228e014465cb70224d86bd7e0d0d3576c097.js | 6 + ...54228e014465cb70224d86bd7e0d0d3576c097.map | 1 + ...7b691f6bdd7027d1c482ad1d1d20efccaf8de17.js | 38 + ...b691f6bdd7027d1c482ad1d1d20efccaf8de17.map | 1 + ...76d5a448d42eed986015f79bc677cfe06cbb037.js | 43 + ...6d5a448d42eed986015f79bc677cfe06cbb037.map | 1 + ...19b92dcca3b3274c7865c4226d073a5285933dc.js | 3 + ...9b92dcca3b3274c7865c4226d073a5285933dc.map | 1 + ...ea802c7ff192af1b8d5d7545dd1950677dae31c.js | 13 + ...a802c7ff192af1b8d5d7545dd1950677dae31c.map | 1 + ...54395416e6909d1afb212c496932b2bf5af9f4b.js | 1 + ...4395416e6909d1afb212c496932b2bf5af9f4b.map | 1 + ...0902b12567d616735df2488d81f2ce4caa5643b.js | 1 + ...902b12567d616735df2488d81f2ce4caa5643b.map | 1 + ...d047950891dfc741dc1d16b985a0385923cd0b7.js | 12 + ...047950891dfc741dc1d16b985a0385923cd0b7.map | 1 + ...a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.js | 54 + ...05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.map | 1 + ...68ad2b130337e6d1c43060ff0610380cc65a4e4.js | 11 + ...8ad2b130337e6d1c43060ff0610380cc65a4e4.map | 1 + ...8c1a5e06fc7281e0c5d074594adfd900a467522.js | 3 + ...c1a5e06fc7281e0c5d074594adfd900a467522.map | 1 + ...4512ce27fb483347b3026158f3d9c2a4feba72a.js | 1 + ...512ce27fb483347b3026158f3d9c2a4feba72a.map | 1 + ...aa471b95ddd2824da4b6de8287260f94fe2b3b8.js | 11 + ...a471b95ddd2824da4b6de8287260f94fe2b3b8.map | 1 + ...7ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.js | 38 + ...ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.map | 1 + ...70325e0af7bfdf09cdea91c0148c3581965ff65.js | 13 + ...0325e0af7bfdf09cdea91c0148c3581965ff65.map | 1 + ...233a1b58eabf0ae0d6b6381642375164f1b936d.js | 10 + ...33a1b58eabf0ae0d6b6381642375164f1b936d.map | 1 + ...ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.js | 37 + ...f4000d0bd118c1a6e1e59e57bb8c2e27544e83.map | 1 + ...93fee750d6e06b7fe856aa05434635d74c6d6b6.js | 39 + ...3fee750d6e06b7fe856aa05434635d74c6d6b6.map | 1 + ...10272a916c592a420461fd4ec671f34671ffb9d.js | 11 + ...0272a916c592a420461fd4ec671f34671ffb9d.map | 1 + ...7452b98f1240bc1dfe93fcb0ce5768fe5afd128.js | 8 + ...452b98f1240bc1dfe93fcb0ce5768fe5afd128.map | 1 + ...839581dc423b7f4e43933e7ca4c8ec3c87446f7.js | 49 + ...39581dc423b7f4e43933e7ca4c8ec3c87446f7.map | 1 + ...827e0e87582161ff944a8c33b095ed58e75095d.js | 37 + ...27e0e87582161ff944a8c33b095ed58e75095d.map | 1 + ...2d12caf4edb87f9aa02eeac9b59a111d8b07d66.js | 1 + ...d12caf4edb87f9aa02eeac9b59a111d8b07d66.map | 1 + ...3ebbb4fc39d82447f61881a06efe1e3a1e52ff8.js | 13 + ...ebbb4fc39d82447f61881a06efe1e3a1e52ff8.map | 1 + ...f88ea0bf88307b9716f0729f7021233f92a8fea.js | 3 + ...88ea0bf88307b9716f0729f7021233f92a8fea.map | 1 + ...95140ddab41575f0486b8b9ad1631188e28b6d1.js | 3 + ...5140ddab41575f0486b8b9ad1631188e28b6d1.map | 1 + ...a256727293c319a8fe2e8c442e7e4b14aabf780.js | 11 + ...256727293c319a8fe2e8c442e7e4b14aabf780.map | 1 + ...e8ebe623fade57a9408c8f31121f7003ef7449c.js | 38 + ...8ebe623fade57a9408c8f31121f7003ef7449c.map | 1 + node_modules/mock-socket/LICENSE.txt | 21 + node_modules/mock-socket/README.md | 232 + .../mock-socket/dist/mock-socket.amd.js | 1928 +++++++ .../mock-socket/dist/mock-socket.cjs.js | 1926 +++++++ .../mock-socket/dist/mock-socket.es.js | 1920 +++++++ node_modules/mock-socket/dist/mock-socket.js | 1932 +++++++ node_modules/mock-socket/index.d.ts | 84 + node_modules/mock-socket/package.json | 108 + .../mock-socket/src/algorithms/close.js | 57 + node_modules/mock-socket/src/constants.js | 29 + node_modules/mock-socket/src/event/close.js | 34 + node_modules/mock-socket/src/event/event.js | 31 + node_modules/mock-socket/src/event/factory.js | 75 + node_modules/mock-socket/src/event/message.js | 35 + .../mock-socket/src/event/prototype.js | 13 + node_modules/mock-socket/src/event/target.js | 73 + .../mock-socket/src/helpers/array-helpers.js | 21 + .../mock-socket/src/helpers/byte-length.js | 5 + .../mock-socket/src/helpers/dedupe.js | 5 + node_modules/mock-socket/src/helpers/delay.js | 11 + .../mock-socket/src/helpers/global-object.js | 7 + .../mock-socket/src/helpers/logger.js | 7 + .../mock-socket/src/helpers/normalize-send.js | 7 + .../src/helpers/protocol-verification.js | 24 + .../mock-socket/src/helpers/proxy-factory.js | 45 + .../src/helpers/url-verification.js | 37 + node_modules/mock-socket/src/index.js | 7 + .../mock-socket/src/network-bridge.js | 135 + node_modules/mock-socket/src/server.js | 217 + node_modules/mock-socket/src/socket-io.js | 279 + node_modules/mock-socket/src/websocket.js | 191 + node_modules/mock-socket/yarn.lock | 4687 +++++++++++++++++ node_modules/querystringify/LICENSE | 22 + node_modules/querystringify/README.md | 60 + node_modules/querystringify/index.js | 88 + node_modules/querystringify/package.json | 66 + node_modules/requires-port/.npmignore | 2 + node_modules/requires-port/.travis.yml | 19 + node_modules/requires-port/LICENSE | 22 + node_modules/requires-port/README.md | 47 + node_modules/requires-port/index.js | 38 + node_modules/requires-port/package.json | 74 + node_modules/requires-port/test.js | 98 + node_modules/url-parse/LICENSE | 22 + node_modules/url-parse/README.md | 147 + node_modules/url-parse/dist/url-parse.js | 555 ++ node_modules/url-parse/dist/url-parse.min.js | 1 + .../url-parse/dist/url-parse.min.js.map | 1 + node_modules/url-parse/index.js | 432 ++ node_modules/url-parse/package.json | 80 + package-lock.json | 31 + package.json | 3 +- src/config/app.ts | 2 +- src/server.ts | 121 +- src/test/channelBase.spec.ts | 11 +- src/test/clientManager.spec.ts | 5 - 134 files changed, 16787 insertions(+), 359 deletions(-) delete mode 100644 dist/server/client/sites/mhsClient.js delete mode 100644 dist/server/client/sites/mhsClient.js.map delete mode 100644 dist/server/clients/base.js delete mode 100644 dist/server/clients/base.js.map mode change 100755 => 100644 dist/server/server.js mode change 100755 => 100644 dist/server/server.js.map delete mode 100644 dist/server/test/appController.spec.js delete mode 100644 dist/server/test/appController.spec.js.map delete mode 100644 dist/server/test/authController.spec.js delete mode 100644 dist/server/test/authController.spec.js.map create mode 100644 node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.js create mode 100644 node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.map create mode 100644 node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.js create mode 100644 node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.map create mode 100644 node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.js create mode 100644 node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.map create mode 100644 node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.js create mode 100644 node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.map create mode 100644 node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.js create mode 100644 node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.map create mode 100644 node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.js create mode 100644 node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.map create mode 100644 node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.js create mode 100644 node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.map create mode 100644 node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.js create mode 100644 node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.map create mode 100644 node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.js create mode 100644 node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.map create mode 100644 node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.js create mode 100644 node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.map create mode 100644 node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.js create mode 100644 node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.map create mode 100644 node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.js create mode 100644 node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.map create mode 100644 node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.js create mode 100644 node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.map create mode 100644 node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.js create mode 100644 node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.map create mode 100644 node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.js create mode 100644 node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.map create mode 100644 node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.js create mode 100644 node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.map create mode 100644 node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.js create mode 100644 node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.map create mode 100644 node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.js create mode 100644 node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.map create mode 100644 node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.js create mode 100644 node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.map create mode 100644 node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.js create mode 100644 node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.map create mode 100644 node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.js create mode 100644 node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.map create mode 100644 node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.js create mode 100644 node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.map create mode 100644 node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.js create mode 100644 node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.map create mode 100644 node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.js create mode 100644 node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.map create mode 100644 node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.js create mode 100644 node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.map create mode 100644 node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.js create mode 100644 node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.map create mode 100644 node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.js create mode 100644 node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.map create mode 100644 node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.js create mode 100644 node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.map create mode 100644 node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.js create mode 100644 node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.map create mode 100644 node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.js create mode 100644 node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.map create mode 100644 node_modules/mock-socket/LICENSE.txt create mode 100644 node_modules/mock-socket/README.md create mode 100644 node_modules/mock-socket/dist/mock-socket.amd.js create mode 100644 node_modules/mock-socket/dist/mock-socket.cjs.js create mode 100644 node_modules/mock-socket/dist/mock-socket.es.js create mode 100644 node_modules/mock-socket/dist/mock-socket.js create mode 100644 node_modules/mock-socket/index.d.ts create mode 100644 node_modules/mock-socket/package.json create mode 100644 node_modules/mock-socket/src/algorithms/close.js create mode 100644 node_modules/mock-socket/src/constants.js create mode 100644 node_modules/mock-socket/src/event/close.js create mode 100644 node_modules/mock-socket/src/event/event.js create mode 100644 node_modules/mock-socket/src/event/factory.js create mode 100644 node_modules/mock-socket/src/event/message.js create mode 100644 node_modules/mock-socket/src/event/prototype.js create mode 100644 node_modules/mock-socket/src/event/target.js create mode 100644 node_modules/mock-socket/src/helpers/array-helpers.js create mode 100644 node_modules/mock-socket/src/helpers/byte-length.js create mode 100644 node_modules/mock-socket/src/helpers/dedupe.js create mode 100644 node_modules/mock-socket/src/helpers/delay.js create mode 100644 node_modules/mock-socket/src/helpers/global-object.js create mode 100644 node_modules/mock-socket/src/helpers/logger.js create mode 100644 node_modules/mock-socket/src/helpers/normalize-send.js create mode 100644 node_modules/mock-socket/src/helpers/protocol-verification.js create mode 100644 node_modules/mock-socket/src/helpers/proxy-factory.js create mode 100644 node_modules/mock-socket/src/helpers/url-verification.js create mode 100644 node_modules/mock-socket/src/index.js create mode 100644 node_modules/mock-socket/src/network-bridge.js create mode 100644 node_modules/mock-socket/src/server.js create mode 100644 node_modules/mock-socket/src/socket-io.js create mode 100644 node_modules/mock-socket/src/websocket.js create mode 100644 node_modules/mock-socket/yarn.lock create mode 100644 node_modules/querystringify/LICENSE create mode 100644 node_modules/querystringify/README.md create mode 100644 node_modules/querystringify/index.js create mode 100644 node_modules/querystringify/package.json create mode 100644 node_modules/requires-port/.npmignore create mode 100644 node_modules/requires-port/.travis.yml create mode 100644 node_modules/requires-port/LICENSE create mode 100644 node_modules/requires-port/README.md create mode 100644 node_modules/requires-port/index.js create mode 100644 node_modules/requires-port/package.json create mode 100644 node_modules/requires-port/test.js create mode 100644 node_modules/url-parse/LICENSE create mode 100644 node_modules/url-parse/README.md create mode 100644 node_modules/url-parse/dist/url-parse.js create mode 100644 node_modules/url-parse/dist/url-parse.min.js create mode 100644 node_modules/url-parse/dist/url-parse.min.js.map create mode 100644 node_modules/url-parse/index.js create mode 100644 node_modules/url-parse/package.json diff --git a/dist/server/client/sites/mhsClient.js b/dist/server/client/sites/mhsClient.js deleted file mode 100644 index 803c961..0000000 --- a/dist/server/client/sites/mhsClient.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const base_1 = require("../base"); -class MHSClient extends base_1.default { -} -; -module.exports = MHSClient; -//# sourceMappingURL=mhsClient.js.map \ No newline at end of file diff --git a/dist/server/client/sites/mhsClient.js.map b/dist/server/client/sites/mhsClient.js.map deleted file mode 100644 index 014b117..0000000 --- a/dist/server/client/sites/mhsClient.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"mhsClient.js","sourceRoot":"","sources":["../../../../src/client/sites/mhsClient.ts"],"names":[],"mappings":";;AAAA,kCAA2B;AAE3B,MAAM,SAAU,SAAQ,cAAI;CAE3B;AAAA,CAAC;AAEF,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC"} \ No newline at end of file diff --git a/dist/server/clients/base.js b/dist/server/clients/base.js deleted file mode 100644 index 45ffb4f..0000000 --- a/dist/server/clients/base.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -class ClientBase { - constructor(data, ws) { - this.ws = ws; - this.data = data; - this.id = data.user_id; - this.channel = null; - } - getData() { - return this.data; - } - type() { - return this.data.client_type; - } - connectToChannel(channel) { - this.channel = channel; - } -} -; -exports.default = ClientBase; -//# sourceMappingURL=Base.js.map \ No newline at end of file diff --git a/dist/server/clients/base.js.map b/dist/server/clients/base.js.map deleted file mode 100644 index 8c92b10..0000000 --- a/dist/server/clients/base.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Base.js","sourceRoot":"","sources":["../../../src/clients/Base.ts"],"names":[],"mappings":";;AAIA,MAAM,UAAU;IAMd,YAAY,IAAS,EAAE,EAAa;QAClC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;IAC/B,CAAC;IAED,gBAAgB,CAAC,OAAoB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAAA,CAAC;AAEF,kBAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/server/config/app.js b/dist/server/config/app.js index ce00e80..b4f6d81 100644 --- a/dist/server/config/app.js +++ b/dist/server/config/app.js @@ -3,7 +3,7 @@ module.exports = { version: '0.7.1', whitelist: (process.env.WHITELIST || "http://admin.localhost").split(','), secret: process.env.SECRET || "test", - devToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoidGVzdCBkYXRhIiwiYXVkIjoiaW50ZXJuYWwiLCJpc3MiOiJZYXJkc3RpY2sgU29mdHdhcmUiLCJzdWIiOiJCcmFpZCBKV1QifQ.t6LFXWPEVz3aLXwtrucarggqTkGY_2NnZB8ZTMaJ2oI', + devToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ', port: process.env.PORT || 8443, hostname: process.env.HOSTNAME || 'ysbraid.localhost', environment: process.env.ENVIRONMENT || 'development', diff --git a/dist/server/config/app.js.map b/dist/server/config/app.js.map index cbc1cf1..441a0f9 100644 --- a/dist/server/config/app.js.map +++ b/dist/server/config/app.js.map @@ -1 +1 @@ -{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/config/app.ts"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAG,OAAO;IACjB,SAAS,EAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1E,MAAM,EAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM;IACrC,QAAQ,EAAE,iMAAiM;IAC3M,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mBAAmB;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,aAAa;IACrD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO;IAC3C,WAAW,EAAG;QACZ,MAAM,EAAG,oBAAoB;QAC7B,OAAO,EAAG,WAAW;QACrB,QAAQ,EAAG,UAAU;QACrB,SAAS,EAAG,CAAC,OAAO,CAAC;KACtB;CACF,CAAA"} \ No newline at end of file +{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/config/app.ts"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAG,OAAO;IACjB,SAAS,EAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1E,MAAM,EAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM;IACrC,QAAQ,EAAE,kTAAkT;IAC5T,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mBAAmB;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,aAAa;IACrD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO;IAC3C,WAAW,EAAG;QACZ,MAAM,EAAG,oBAAoB;QAC7B,OAAO,EAAG,WAAW;QACrB,QAAQ,EAAG,UAAU;QACrB,SAAS,EAAG,CAAC,OAAO,CAAC;KACtB;CACF,CAAA"} \ No newline at end of file diff --git a/dist/server/server.js b/dist/server/server.js old mode 100755 new mode 100644 index 6db0d01..623732f --- a/dist/server/server.js +++ b/dist/server/server.js @@ -31,60 +31,67 @@ application.use(express.json()); application.use('', routes); let clientManager = new clientManager_1.default(); let channelManager = new channelManager_1.default(); -wss.on('connection', (ws, request, args) => { - var data = JSON.parse(args).data; - logger.accessLog.info(`Client Connected: ${data.user_id}`); - if (!channelManager.channelExists(data.channel)) { - channelManager.createChannel(data); - } - if (clientManager.clientExists(data.user_id)) { - var client = clientManager.getClient(data.user_id); +function startServer() { + wss.on('connection', (ws, request, args) => { + var data = JSON.parse(args).data; + logger.accessLog.info(`Client Connected: ${data.user_id}`); + if (!channelManager.channelExists(data.channel)) { + channelManager.createChannel(data); + } + if (clientManager.clientExists(data.user_id)) { + var client = clientManager.getClient(data.user_id); + if (client != null) { + client.replaceWebSocket(ws); + } + } + else { + var client = clientManager.addClient(data, ws); + } if (client != null) { - client.replaceWebSocket(ws); + channelManager.addClientToChannel(client, data.channel); } - } - else { - var client = clientManager.addClient(data, ws); - } - if (client != null) { - channelManager.addClientToChannel(client, data.channel); - } - ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!'); -}); -server.on('upgrade', function upgrade(request, socket, head) { - return __awaiter(this, void 0, void 0, function* () { - let args; - try { - args = yield verifyConnection(); - } - catch (e) { - socket.destroy(); - logger.accessLog.info('Connection Terminated'); - return; - } - function verifyConnection() { - return new Promise((resolve, reject) => { - var data = url.parse(request.url, true).query; - var token = data.token || (app.environment == 'development' ? app.devToken : ''); - var accepted = true; - var result; - jwt.verify(token, app.secret, app.signOptions, function (err, decoded) { - if (err) { - console.log(err); - accepted = false; - } - result = JSON.stringify(decoded); - accepted ? resolve(result) : reject('rejected'); + ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!'); + }); + server.on('upgrade', function upgrade(request, socket, head) { + return __awaiter(this, void 0, void 0, function* () { + let args; + try { + args = yield verifyConnection(); + } + catch (e) { + socket.destroy(); + logger.accessLog.info('Connection Terminated'); + return; + } + function verifyConnection() { + return new Promise((resolve, reject) => { + var data = url.parse(request.url, true).query; + var token = data.token || (app.environment == 'development' ? app.devToken : ''); + var accepted = true; + var result; + jwt.verify(token, app.secret, app.signOptions, function (err, decoded) { + if (err) { + console.log(err); + accepted = false; + } + result = JSON.stringify(decoded); + accepted ? resolve(result) : reject('rejected'); + }); }); + } + wss.handleUpgrade(request, socket, head, function done(ws) { + wss.emit('connection', ws, request, args); }); - } - wss.handleUpgrade(request, socket, head, function done(ws) { - wss.emit('connection', ws, request, args); }); }); -}); -server.listen(app.port, () => { - console.log(`Braid v${app.version} is running!\n`); - logger.accessLog.info(`Braid v${app.version} is running!\n`); -}); + server.listen(app.port, () => { + console.log(`Braid v${app.version} is running!\n`); + logger.accessLog.info(`Braid v${app.version} is running!\n`); + }); +} +startServer(); +module.exports = { + clientManager: clientManager, + channelManager: channelManager +}; //# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/dist/server/server.js.map b/dist/server/server.js.map old mode 100755 new mode 100644 index 2998358..74f0b77 --- a/dist/server/server.js.map +++ b/dist/server/server.js.map @@ -1 +1 @@ -{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/server/test/appController.spec.js b/dist/server/test/appController.spec.js deleted file mode 100644 index 4edb4b6..0000000 --- a/dist/server/test/appController.spec.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=appController.spec.js.map \ No newline at end of file diff --git a/dist/server/test/appController.spec.js.map b/dist/server/test/appController.spec.js.map deleted file mode 100644 index 4fdc4f7..0000000 --- a/dist/server/test/appController.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"appController.spec.js","sourceRoot":"","sources":["../../../src/test/appController.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/server/test/authController.spec.js b/dist/server/test/authController.spec.js deleted file mode 100644 index 45b19d2..0000000 --- a/dist/server/test/authController.spec.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=authController.spec.js.map \ No newline at end of file diff --git a/dist/server/test/authController.spec.js.map b/dist/server/test/authController.spec.js.map deleted file mode 100644 index dd71681..0000000 --- a/dist/server/test/authController.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"authController.spec.js","sourceRoot":"","sources":["../../../src/test/authController.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/server/test/channelBase.spec.js b/dist/server/test/channelBase.spec.js index 2e85bbe..5919f3d 100644 --- a/dist/server/test/channelBase.spec.js +++ b/dist/server/test/channelBase.spec.js @@ -2,14 +2,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); const channelBase_1 = require("../channels/channelBase"); const clientBase_1 = require("../clients/clientBase"); +var exec = require('child_process').exec; var expect = require('chai').expect; var sinon = require('sinon'); var WebSocketClient = require('websocket').client; var app = require('../config/app'); var name = 'test channel'; -var channel; -var wsLink = `wss://${app.hostname}:${app.port}`; var wsClient = new WebSocketClient(); +var channel; var data = { 'client': 'test', 'client_type': 'site', 'user_id': 125, 'user_type': 'user', 'channel': name }; var client = new clientBase_1.default(data, wsClient); describe('ChannelBase', function () { @@ -30,12 +30,7 @@ describe('ChannelBase', function () { var result = exist ? true : false; expect(result).to.be.equal(true); }); - it('should not broadcase a message to self', function () { - // var wstClient = new WebSocketClient(wsLink); - // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } - // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); - // channel.addClient(client); - // channel.addClient(teacher); + it('should not broadcast a message to self', function () { var result = channel.broadcastMessage(client, 'test message'); expect(result.status).to.be.equal('success'); }); diff --git a/dist/server/test/channelBase.spec.js.map b/dist/server/test/channelBase.spec.js.map index 80b4cc6..7892bd8 100644 --- a/dist/server/test/channelBase.spec.js.map +++ b/dist/server/test/channelBase.spec.js.map @@ -1 +1 @@ -{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,MAAM,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AACzD,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,+CAA+C;QAC/C,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/server/test/clientManager.spec.js b/dist/server/test/clientManager.spec.js index 3958ec6..38a9bdc 100644 --- a/dist/server/test/clientManager.spec.js +++ b/dist/server/test/clientManager.spec.js @@ -45,9 +45,5 @@ describe('ClientManager', function () { var result = clientManager.getClientType(data, wsClient); expect(result.clientType()).to.be.equal('mhs'); }); - // it('should remove a client', function () { - // clientManager.removeClient(data.user_id); - // expect(clientManager.clients.length).to.be.equal(0); - // }); }); //# sourceMappingURL=clientManager.spec.js.map \ No newline at end of file diff --git a/dist/server/test/clientManager.spec.js.map b/dist/server/test/clientManager.spec.js.map index 72bcc1e..9c05d24 100644 --- a/dist/server/test/clientManager.spec.js.map +++ b/dist/server/test/clientManager.spec.js.map @@ -1 +1 @@ -{"version":3,"file":"clientManager.spec.js","sourceRoot":"","sources":["../../../src/test/clientManager.spec.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"clientManager.spec.js","sourceRoot":"","sources":["../../../src/test/clientManager.spec.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/logs/access.log b/logs/access.log index 29b353b..a2baf5a 100644 --- a/logs/access.log +++ b/logs/access.log @@ -1,123 +1,40 @@ -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:19:11.985Z"} -{"message":"Braid v0.6.2 is running!\n","level":"info","timestamp":"2019-03-13T15:19:11.996Z"} -{"message":"Client Connected: 125","level":"info","timestamp":"2019-03-13T15:19:14.143Z"} -{"message":"attempting to create channel of type mhs, channel id: mhs_1239...","level":"info","timestamp":"2019-03-13T15:19:14.144Z"} -{"channelId":"mhs_1239","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:19:14.144Z"} -{"message":"Added channel to channel manager: mhs_1239","level":"info","timestamp":"2019-03-13T15:19:14.144Z"} -{"message":"attempting to create client of type mhs, client id: 125...","level":"info","timestamp":"2019-03-13T15:19:14.144Z"} -{"data":{"client":"mhs","client_type":"site","user_type":"user","user_id":125,"channel":"mhs_1239"},"level":"info","message":"MHS Client Created","timestamp":"2019-03-13T15:19:14.145Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T15:19:14.145Z"} -{"channelId":"mhs_1239","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T15:19:14.145Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:59:39.366Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:59:39.500Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T15:59:39.502Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T15:59:39.503Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T15:59:39.504Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:59:39.504Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T15:59:39.504Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T15:59:39.505Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T15:59:39.506Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T15:59:39.506Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T15:59:39.508Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T15:59:39.508Z"} -{"message":"no client type designated or client already exists, socket disconnected: undefined","level":"info","timestamp":"2019-03-13T15:59:39.509Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:02:34.044Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:02:34.242Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:02:34.244Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:02:34.245Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:02:34.247Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:02:34.247Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:02:34.247Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:02:34.247Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:02:34.248Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:02:34.249Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:02:34.250Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:02:34.251Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:02:34.252Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:02:34.252Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:20.911Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:20.935Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:07:20.942Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:07:20.951Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:07:20.953Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:20.953Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:07:20.953Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:07:20.954Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:07:20.955Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:07:20.956Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:07:20.958Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:20.959Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:07:20.960Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:07:20.960Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:31.328Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:31.508Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:07:31.516Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:07:31.518Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:07:31.519Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:31.519Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:07:31.520Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:07:31.520Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:07:31.521Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:07:31.521Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:07:31.522Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:07:31.522Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:07:31.523Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:07:31.523Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:15:40.382Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:15:40.591Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:15:40.592Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:15:40.594Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:15:40.595Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:15:40.595Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:15:40.595Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:15:40.596Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:15:40.599Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:15:40.600Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:15:40.601Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:15:40.602Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:15:40.603Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:15:40.603Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:17:13.735Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:17:13.968Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:17:13.969Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:17:13.970Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:17:13.971Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:17:13.972Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:17:13.972Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:17:13.972Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:17:13.973Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:17:13.973Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:17:13.975Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:17:13.975Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:17:13.976Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:17:13.976Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:19:41.379Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:19:41.612Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:19:41.620Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:19:41.621Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:19:41.623Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:19:41.623Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:19:41.623Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:19:41.623Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:19:41.624Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:19:41.624Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:19:41.626Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:19:41.626Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:19:41.627Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:19:41.627Z"} -{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:25:45.893Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:25:45.988Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:25:45.990Z"} -{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-13T16:25:45.991Z"} -{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-13T16:25:45.993Z"} -{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:25:45.993Z"} -{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-13T16:25:45.993Z"} -{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-13T16:25:45.993Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-13T16:25:45.994Z"} -{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-13T16:25:45.995Z"} -{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-13T16:25:45.996Z"} -{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-13T16:25:45.997Z"} -{"message":"creating base client: 125","level":"info","timestamp":"2019-03-13T16:25:45.998Z"} -{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-13T16:25:45.998Z"} -{"message":"attempting to create client of type mhs, client id: 125...","level":"info","timestamp":"2019-03-13T16:25:46.017Z"} -{"data":{"client":"mhs","client_type":"site","user_id":125,"user_type":"user","channel":"test channel"},"level":"info","message":"MHS Client Created","timestamp":"2019-03-13T16:25:46.017Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T21:04:31.620Z"} +{"message":"Braid v0.7.1 is running!\n","level":"info","timestamp":"2019-03-13T21:04:31.656Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T21:05:53.237Z"} +{"message":"Braid v0.7.1 is running!\n","level":"info","timestamp":"2019-03-13T21:05:53.265Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-13T21:08:22.440Z"} +{"message":"Braid v0.7.1 is running!\n","level":"info","timestamp":"2019-03-13T21:08:22.467Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:11:02.005Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:11:02.010Z"} +{"message":"Braid v0.7.1 is running!\n","level":"info","timestamp":"2019-03-14T14:11:02.015Z"} +{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:11:02.023Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-14T14:11:02.029Z"} +{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-14T14:11:02.031Z"} +{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-14T14:11:02.032Z"} +{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:11:02.033Z"} +{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-14T14:11:02.033Z"} +{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-14T14:11:02.033Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-14T14:11:02.034Z"} +{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-14T14:11:02.034Z"} +{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-14T14:11:02.034Z"} +{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:11:02.035Z"} +{"message":"creating base client: 125","level":"info","timestamp":"2019-03-14T14:11:02.035Z"} +{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-14T14:11:02.035Z"} +{"message":"attempting to create client of type mhs, client id: 125...","level":"info","timestamp":"2019-03-14T14:11:02.037Z"} +{"data":{"client":"mhs","client_type":"site","user_id":125,"user_type":"user","channel":"test channel"},"level":"info","message":"MHS Client Created","timestamp":"2019-03-14T14:11:02.038Z"} +{"channelId":"default","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:13:06.708Z"} +{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:13:06.724Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-14T14:13:06.733Z"} +{"message":"client is same as sender: 125 - test message","level":"info","timestamp":"2019-03-14T14:13:06.735Z"} +{"message":"creating base channel: test channel","level":"info","timestamp":"2019-03-14T14:13:06.736Z"} +{"channelId":"test channel","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:13:06.736Z"} +{"message":"Added channel to channel manager: test channel","level":"info","timestamp":"2019-03-14T14:13:06.736Z"} +{"message":"Channel already exists: test channel","level":"info","timestamp":"2019-03-14T14:13:06.737Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Added client to channel","timestamp":"2019-03-14T14:13:06.738Z"} +{"message":"channel with id no channel does not exist.","level":"info","timestamp":"2019-03-14T14:13:06.738Z"} +{"message":"attempting to create channel of type mhs, channel id: test channel 2...","level":"info","timestamp":"2019-03-14T14:13:06.739Z"} +{"channelId":"test channel 2","level":"info","message":"Channel Created","timestamp":"2019-03-14T14:13:06.739Z"} +{"message":"creating base client: 125","level":"info","timestamp":"2019-03-14T14:13:06.741Z"} +{"message":"client added to client manager: 125","level":"info","timestamp":"2019-03-14T14:13:06.741Z"} +{"message":"attempting to create client of type mhs, client id: 125...","level":"info","timestamp":"2019-03-14T14:13:06.743Z"} +{"data":{"client":"mhs","client_type":"site","user_id":125,"user_type":"user","channel":"test channel"},"level":"info","message":"MHS Client Created","timestamp":"2019-03-14T14:13:06.743Z"} diff --git a/logs/errors.log b/logs/errors.log index 757be3f..38e6544 100644 --- a/logs/errors.log +++ b/logs/errors.log @@ -1,60 +1,6 @@ -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T00:58:40.375Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:00:18.870Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:04:44.443Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:08:09.752Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:13:18.359Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:52:25.081Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:52:53.438Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:58:27.639Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T01:58:27.642Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:59:01.515Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T01:59:01.517Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T01:59:17.271Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T01:59:17.273Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:00:09.871Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:00:09.873Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:01:10.969Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:01:10.971Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:07:17.120Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:07:17.122Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:10:06.964Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:10:06.966Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:16:24.530Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:16:24.532Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:17:49.026Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:17:49.029Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:19:58.838Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:19:58.840Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:24:46.854Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:24:46.856Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:24:46.858Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:25:22.349Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:25:22.351Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:25:22.354Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T02:26:19.605Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T02:26:19.607Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T15:10:50.955Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T15:10:50.958Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T15:59:39.502Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T15:59:39.504Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:02:34.245Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:02:34.247Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:02:34.252Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:07:20.950Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:07:20.953Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:07:20.960Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:07:31.517Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:07:31.519Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:07:31.523Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:15:40.593Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:15:40.595Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:15:40.603Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:17:13.970Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:17:13.971Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:17:13.976Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:19:41.620Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:19:41.623Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:19:41.627Z"} -{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-13T16:25:45.991Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:25:45.993Z"} -{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-13T16:25:45.998Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-14T14:11:02.030Z"} +{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-14T14:11:02.032Z"} +{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-14T14:11:02.035Z"} +{"channelId":"test channel","clientId":125,"level":"info","message":"Client already exits in channel","timestamp":"2019-03-14T14:13:06.734Z"} +{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-14T14:13:06.736Z"} +{"code":"MODULE_NOT_FOUND","level":"info","timestamp":"2019-03-14T14:13:06.741Z"} diff --git a/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.js b/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.js new file mode 100644 index 0000000..4169b26 --- /dev/null +++ b/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.js @@ -0,0 +1,37 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="d5a5c0b1c501b10faedee0bc82acc612e2afecb4";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:11},end:{line:3,column:40}},"2":{start:{line:4,column:13},end:{line:4,column:35}},"3":{start:{line:5,column:12},end:{line:5,column:28}},"4":{start:{line:6,column:16},end:{line:6,column:29}},"5":{start:{line:7,column:10},end:{line:7,column:34}},"6":{start:{line:8,column:13},end:{line:8,column:33}},"7":{start:{line:9,column:11},end:{line:9,column:25}},"8":{start:{line:10,column:10},end:{line:10,column:67}},"9":{start:{line:11,column:15},end:{line:11,column:33}},"10":{start:{line:15,column:0},end:{line:50,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:50,column:1}},line:15}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[6]++,require('../server'));var name=(cov_h9a3mwwe1.s[7]++,'test channel');var url=(cov_h9a3mwwe1.s[8]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocket(url));var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[10]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.map b/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.map new file mode 100644 index 0000000..5a41cbd --- /dev/null +++ b/node_modules/.cache/nyc/015128acb467cebb4cd4bdd42bb5f5e3698894e5207c6ebd8a349f344baa729f.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAGA,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.js b/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.js new file mode 100644 index 0000000..edfeadd --- /dev/null +++ b/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.js @@ -0,0 +1,42 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="4d8f0fc7ce68fac26e9178a0ef3264e5c0687664";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:11},end:{line:3,column:40}},"2":{start:{line:4,column:13},end:{line:4,column:35}},"3":{start:{line:5,column:12},end:{line:5,column:28}},"4":{start:{line:6,column:16},end:{line:6,column:29}},"5":{start:{line:7,column:10},end:{line:7,column:34}},"6":{start:{line:15,column:0},end:{line:50,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:50,column:1}},line:15}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));// var server = require('../server'); +// var name: string = 'test channel'; +// var url: string = `wss://${app.hostname}:${app.port}?token=${app.devToken}`; +// var wsClient = new WebSocket(url); +// var channel: ChannelBase; +// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[6]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.map b/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.map new file mode 100644 index 0000000..374c3d7 --- /dev/null +++ b/node_modules/.cache/nyc/120c7cc1df9fcfc4b08ff2e947c53972f008d85c26ff3d09e1c9508c8490cac7.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAGA,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,qCAAqC;AAErC,qCAAqC;AACrC,+EAA+E;AAC/E,qCAAqC;AACrC,4BAA4B;AAC5B,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.js b/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.js new file mode 100644 index 0000000..f21cf0c --- /dev/null +++ b/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.js @@ -0,0 +1,6 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="e921c01b9adf32e454cb9bddb95d00912ebba6dc";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:11},end:{line:10,column:25}},"9":{start:{line:12,column:13},end:{line:12,column:48}},"10":{start:{line:13,column:15},end:{line:13,column:36}},"11":{start:{line:14,column:11},end:{line:14,column:108}},"12":{start:{line:15,column:13},end:{line:15,column:53}},"13":{start:{line:16,column:0},end:{line:45,column:3}},"14":{start:{line:17,column:4},end:{line:17,column:68}},"15":{start:{line:17,column:25},end:{line:17,column:64}},"16":{start:{line:18,column:4},end:{line:21,column:7}},"17":{start:{line:19,column:8},end:{line:19,column:50}},"18":{start:{line:20,column:8},end:{line:20,column:45}},"19":{start:{line:22,column:4},end:{line:25,column:7}},"20":{start:{line:23,column:21},end:{line:23,column:46}},"21":{start:{line:24,column:8},end:{line:24,column:53}},"22":{start:{line:26,column:4},end:{line:29,column:7}},"23":{start:{line:27,column:21},end:{line:27,column:46}},"24":{start:{line:28,column:8},end:{line:28,column:52}},"25":{start:{line:30,column:4},end:{line:34,column:7}},"26":{start:{line:31,column:20},end:{line:31,column:51}},"27":{start:{line:32,column:21},end:{line:32,column:41}},"28":{start:{line:33,column:8},end:{line:33,column:41}},"29":{start:{line:35,column:4},end:{line:43,column:7}},"30":{start:{line:41,column:21},end:{line:41,column:69}},"31":{start:{line:42,column:8},end:{line:42,column:53}},"32":{start:{line:44,column:4},end:{line:44,column:55}},"33":{start:{line:44,column:24},end:{line:44,column:51}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:16,column:24},end:{line:16,column:25}},loc:{start:{line:16,column:36},end:{line:45,column:1}},line:16},"1":{name:"(anonymous_1)",decl:{start:{line:17,column:11},end:{line:17,column:12}},loc:{start:{line:17,column:23},end:{line:17,column:66}},line:17},"2":{name:"(anonymous_2)",decl:{start:{line:18,column:47},end:{line:18,column:48}},loc:{start:{line:18,column:59},end:{line:21,column:5}},line:18},"3":{name:"(anonymous_3)",decl:{start:{line:22,column:41},end:{line:22,column:42}},loc:{start:{line:22,column:53},end:{line:25,column:5}},line:22},"4":{name:"(anonymous_4)",decl:{start:{line:26,column:73},end:{line:26,column:74}},loc:{start:{line:26,column:85},end:{line:29,column:5}},line:26},"5":{name:"(anonymous_5)",decl:{start:{line:30,column:31},end:{line:30,column:32}},loc:{start:{line:30,column:43},end:{line:34,column:5}},line:30},"6":{name:"(anonymous_6)",decl:{start:{line:35,column:49},end:{line:35,column:50}},loc:{start:{line:35,column:61},end:{line:43,column:5}},line:35},"7":{name:"(anonymous_7)",decl:{start:{line:44,column:10},end:{line:44,column:11}},loc:{start:{line:44,column:22},end:{line:44,column:53}},line:44}},branchMap:{"0":{loc:{start:{line:32,column:21},end:{line:32,column:41}},type:"cond-expr",locations:[{start:{line:32,column:29},end:{line:32,column:33}},{start:{line:32,column:36},end:{line:32,column:41}}],line:32}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var channel;var wsLink=(cov_h9a3mwwe1.s[9]++,`wss://${app.hostname}:${app.port}`);var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocketClient());var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;before(function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;exec("node ./dist/server/server.js &");});cov_h9a3mwwe1.s[16]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[2]++;cov_h9a3mwwe1.s[17]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[18]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[19]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[22]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[4]++;var result=(cov_h9a3mwwe1.s[23]++,channel.addClient(client));cov_h9a3mwwe1.s[24]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[25]++;it('should find a client',function(){cov_h9a3mwwe1.f[5]++;var exist=(cov_h9a3mwwe1.s[26]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[27]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[28]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[29]++;it('should not broadcase a message to self',function(){cov_h9a3mwwe1.f[6]++;// var wstClient = new WebSocketClient(wsLink); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +var result=(cov_h9a3mwwe1.s[30]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[31]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[32]++;after(function(){cov_h9a3mwwe1.f[7]++;cov_h9a3mwwe1.s[33]++;exec("kill $(pgrep node)");});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.map b/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.map new file mode 100644 index 0000000..5ded7b8 --- /dev/null +++ b/node_modules/.cache/nyc/1bf7c936cee0caa3e98d3ee85854228e014465cb70224d86bd7e0d0d3576c097.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,MAAM,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AACzD,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,MAAM,CAAE,cAAY,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/D,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,+CAA+C;QAC/C,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,KAAK,CAAE,cAAY,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.js b/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.js new file mode 100644 index 0000000..2c4484f --- /dev/null +++ b/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.js @@ -0,0 +1,38 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="68e52daa9db4e6b4d68f38008a1b8576c8b6849d";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:11},end:{line:3,column:40}},"2":{start:{line:4,column:13},end:{line:4,column:35}},"3":{start:{line:5,column:12},end:{line:5,column:28}},"4":{start:{line:6,column:16},end:{line:6,column:29}},"5":{start:{line:7,column:10},end:{line:7,column:34}},"6":{start:{line:8,column:13},end:{line:8,column:33}},"7":{start:{line:9,column:11},end:{line:9,column:25}},"8":{start:{line:11,column:10},end:{line:11,column:367}},"9":{start:{line:12,column:15},end:{line:12,column:33}},"10":{start:{line:16,column:0},end:{line:51,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:16,column:24},end:{line:16,column:25}},loc:{start:{line:16,column:36},end:{line:51,column:1}},line:16}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[6]++,require('../server'));var name=(cov_h9a3mwwe1.s[7]++,'test channel');// var url: string = `wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ`; +var url=(cov_h9a3mwwe1.s[8]++,"wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6Im1ocyIsImNsaWVudF90eXBlIjoic2l0ZSIsInVzZXJfdHlwZSI6InVzZXIiLCJ1c2VyX2lkIjoxMjUsImNoYW5uZWwiOiJtaHNfMTIzOSJ9LCJleHAiOjE1NTI4NDYzOTQsImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5a_s8rgln4rwhVqJLcSS9Uw7yw1_PmYgslWKZllgK6g");var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocket(url));var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[10]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.map b/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.map new file mode 100644 index 0000000..c12b26e --- /dev/null +++ b/node_modules/.cache/nyc/1ee11a1b21104d3b582244d887b691f6bdd7027d1c482ad1d1d20efccaf8de17.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAGA,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,2WAA2W;AAC3W,IAAI,GAAG,GAAW,qWAAqW,CAAC;AACxX,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.js b/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.js new file mode 100644 index 0000000..50b4490 --- /dev/null +++ b/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.js @@ -0,0 +1,43 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="558185a080af0ed59a3e157c724f2d28ab4e47f6";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:4,column:11},end:{line:4,column:40}},"2":{start:{line:5,column:13},end:{line:5,column:35}},"3":{start:{line:6,column:12},end:{line:6,column:28}},"4":{start:{line:7,column:16},end:{line:7,column:29}},"5":{start:{line:8,column:10},end:{line:8,column:34}},"6":{start:{line:16,column:0},end:{line:51,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:16,column:24},end:{line:16,column:25}},loc:{start:{line:16,column:36},end:{line:51,column:1}},line:16}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});// import ChannelManager from '../channelManager'; +var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));// var server = require('../server'); +// var name: string = 'test channel'; +// var url: string = `wss://${app.hostname}:${app.port}?token=${app.devToken}`; +// var wsClient = new WebSocket(url); +// var channel: ChannelBase; +// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[6]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.map b/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.map new file mode 100644 index 0000000..b79d185 --- /dev/null +++ b/node_modules/.cache/nyc/1f23747d5503bc46867b16b4276d5a448d42eed986015f79bc677cfe06cbb037.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAEA,kDAAkD;AAElD,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,qCAAqC;AAErC,qCAAqC;AACrC,+EAA+E;AAC/E,qCAAqC;AACrC,4BAA4B;AAC5B,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.js b/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.js new file mode 100644 index 0000000..b050019 --- /dev/null +++ b/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.js @@ -0,0 +1,3 @@ +"use strict";var cov_1hb41h5zwr=function(){var path="/Users/josh.burman/Projects/braid/dist/server/routes.js";var hash="c4d590f2c6dcf78a827ead7408903c087e1921c2";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/routes.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:13},end:{line:3,column:28}},"2":{start:{line:4,column:16},end:{line:4,column:34}},"3":{start:{line:5,column:10},end:{line:5,column:33}},"4":{start:{line:6,column:18},end:{line:15,column:1}},"5":{start:{line:8,column:8},end:{line:13,column:9}},"6":{start:{line:9,column:12},end:{line:9,column:33}},"7":{start:{line:12,column:12},end:{line:12,column:74}},"8":{start:{line:16,column:13},end:{line:16,column:29}},"9":{start:{line:18,column:20},end:{line:18,column:58}},"10":{start:{line:19,column:0},end:{line:19,column:53}},"11":{start:{line:21,column:21},end:{line:21,column:60}},"12":{start:{line:22,column:0},end:{line:22,column:80}},"13":{start:{line:23,column:0},end:{line:23,column:24}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:7,column:12},end:{line:7,column:13}},loc:{start:{line:7,column:34},end:{line:14,column:5}},line:7}},branchMap:{"0":{loc:{start:{line:8,column:8},end:{line:13,column:9}},type:"if",locations:[{start:{line:8,column:8},end:{line:13,column:9}},{start:{line:8,column:8},end:{line:13,column:9}}],line:8}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0},f:{"0":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_1hb41h5zwr.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const cors=(cov_1hb41h5zwr.s[1]++,require("cors"));const express=(cov_1hb41h5zwr.s[2]++,require("express"));var app=(cov_1hb41h5zwr.s[3]++,require('./config/app'));var corsOptions=(cov_1hb41h5zwr.s[4]++,{origin:(origin,callback)=>{cov_1hb41h5zwr.f[0]++;cov_1hb41h5zwr.s[5]++;if(app.whitelist.indexOf(origin)!==-1){cov_1hb41h5zwr.b[0][0]++;cov_1hb41h5zwr.s[6]++;callback(null,true);}else{cov_1hb41h5zwr.b[0][1]++;cov_1hb41h5zwr.s[7]++;callback(new Error(`Not allowed by CORS. Origin: ${origin}`));}}});var router=(cov_1hb41h5zwr.s[8]++,express.Router());//application +var appController=(cov_1hb41h5zwr.s[9]++,require('./controllers/appController'));cov_1hb41h5zwr.s[10]++;router.route(['/','/home']).get(appController.home);//auth +var authController=(cov_1hb41h5zwr.s[11]++,require('./controllers/authController'));cov_1hb41h5zwr.s[12]++;router.route('/auth/user').post(cors(corsOptions),authController.confirmToken);cov_1hb41h5zwr.s[13]++;module.exports=router;//# sourceMappingURL=routes.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.map b/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.map new file mode 100644 index 0000000..55426f2 --- /dev/null +++ b/node_modules/.cache/nyc/202e048885d60be1cd0b170a819b92dcca3b3274c7865c4226d073a5285933dc.map @@ -0,0 +1 @@ +{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":";;AAAA,6BAA6B;AAC7B,mCAAmC;AAEnC,IAAI,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;AACjC,IAAI,WAAW,GAAG;IAChB,MAAM,EAAE,CAAC,MAAc,EAAE,QAAkB,EAAE,EAAE;QAC7C,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;YACxC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;SACrB;aAAM;YACL,QAAQ,CAAC,IAAI,KAAK,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC,CAAA;SAC9D;IACH,CAAC;CACF,CAAA;AAED,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;AAE9B,aAAa;AACb,IAAI,aAAa,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;AAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;AAEpD,MAAM;AACN,IAAI,cAAc,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;AAC7D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;AAEhF,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.js b/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.js new file mode 100644 index 0000000..997f0ee --- /dev/null +++ b/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.js @@ -0,0 +1,13 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="1d390f7f6f20afb0b77ddae87a3c8c87eeb22334";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:21},end:{line:3,column:53}},"2":{start:{line:5,column:11},end:{line:5,column:40}},"3":{start:{line:6,column:13},end:{line:6,column:35}},"4":{start:{line:7,column:12},end:{line:7,column:28}},"5":{start:{line:8,column:16},end:{line:8,column:29}},"6":{start:{line:9,column:10},end:{line:9,column:34}},"7":{start:{line:10,column:13},end:{line:10,column:33}},"8":{start:{line:11,column:11},end:{line:11,column:25}},"9":{start:{line:12,column:10},end:{line:12,column:67}},"10":{start:{line:13,column:15},end:{line:13,column:33}},"11":{start:{line:15,column:11},end:{line:15,column:118}},"12":{start:{line:16,column:13},end:{line:16,column:53}},"13":{start:{line:17,column:0},end:{line:52,column:3}},"14":{start:{line:19,column:4},end:{line:22,column:7}},"15":{start:{line:20,column:8},end:{line:20,column:53}},"16":{start:{line:21,column:8},end:{line:21,column:45}},"17":{start:{line:23,column:4},end:{line:26,column:7}},"18":{start:{line:24,column:21},end:{line:24,column:46}},"19":{start:{line:25,column:8},end:{line:25,column:53}},"20":{start:{line:27,column:4},end:{line:30,column:7}},"21":{start:{line:28,column:21},end:{line:28,column:46}},"22":{start:{line:29,column:8},end:{line:29,column:52}},"23":{start:{line:31,column:4},end:{line:35,column:7}},"24":{start:{line:32,column:20},end:{line:32,column:51}},"25":{start:{line:33,column:21},end:{line:33,column:41}},"26":{start:{line:34,column:8},end:{line:34,column:41}},"27":{start:{line:36,column:4},end:{line:44,column:7}},"28":{start:{line:45,column:4},end:{line:51,column:7}},"29":{start:{line:49,column:21},end:{line:49,column:69}},"30":{start:{line:50,column:8},end:{line:50,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17},"1":{name:"(anonymous_1)",decl:{start:{line:19,column:47},end:{line:19,column:48}},loc:{start:{line:19,column:59},end:{line:22,column:5}},line:19},"2":{name:"(anonymous_2)",decl:{start:{line:23,column:41},end:{line:23,column:42}},loc:{start:{line:23,column:53},end:{line:26,column:5}},line:23},"3":{name:"(anonymous_3)",decl:{start:{line:27,column:73},end:{line:27,column:74}},loc:{start:{line:27,column:85},end:{line:30,column:5}},line:27},"4":{name:"(anonymous_4)",decl:{start:{line:31,column:31},end:{line:31,column:32}},loc:{start:{line:31,column:43},end:{line:35,column:5}},line:31},"5":{name:"(anonymous_5)",decl:{start:{line:36,column:47},end:{line:36,column:48}},loc:{start:{line:36,column:59},end:{line:44,column:5}},line:36},"6":{name:"(anonymous_6)",decl:{start:{line:45,column:49},end:{line:45,column:50}},loc:{start:{line:45,column:61},end:{line:51,column:5}},line:45}},branchMap:{"0":{loc:{start:{line:33,column:21},end:{line:33,column:41}},type:"cond-expr",locations:[{start:{line:33,column:29},end:{line:33,column:33}},{start:{line:33,column:36},end:{line:33,column:41}}],line:33}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const clientBase_1=(cov_h9a3mwwe1.s[1]++,require("../clients/clientBase"));// import ChannelManager from '../channelManager'; +var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[5]++,require('ws'));var app=(cov_h9a3mwwe1.s[6]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[7]++,require('../server'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var url=(cov_h9a3mwwe1.s[9]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':'test channel'});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;// before ( function () { server.startServer; }); +it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;channel=server.channelManager.sadsdf(name);cov_h9a3mwwe1.s[16]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[17]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[18]++,channel.addClient(client));cov_h9a3mwwe1.s[19]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[20]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[21]++,channel.addClient(client));cov_h9a3mwwe1.s[22]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[23]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[24]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[25]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[26]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[27]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[28]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[29]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[30]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.map b/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.map new file mode 100644 index 0000000..f203da5 --- /dev/null +++ b/node_modules/.cache/nyc/2233940ccfa054a267a3e8553ea802c7ff192af1b8d5d7545dd1950677dae31c.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AACA,sDAA+C;AAC/C,kDAAkD;AAElD,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,CAAA;AAC1H,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.js b/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.js new file mode 100644 index 0000000..7b7bbb7 --- /dev/null +++ b/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.js @@ -0,0 +1 @@ +"use strict";var cov_2gwmauqsnp=function(){var path="/Users/josh.burman/Projects/braid/dist/server/controllers/appController.js";var hash="8493a8aacdbdcb9a24015c3d3540033d7988cd1a";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/controllers/appController.js",statementMap:{"0":{start:{line:2,column:10},end:{line:2,column:34}},"1":{start:{line:3,column:0},end:{line:7,column:2}},"2":{start:{line:5,column:8},end:{line:5,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:4,column:10},end:{line:4,column:11}},loc:{start:{line:4,column:24},end:{line:6,column:5}},line:4}},branchMap:{},s:{"0":0,"1":0,"2":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();var app=(cov_2gwmauqsnp.s[0]++,require('../config/app'));cov_2gwmauqsnp.s[1]++;module.exports={home:(req,res)=>{cov_2gwmauqsnp.f[0]++;cov_2gwmauqsnp.s[2]++;res.send(`Welcome to Braid v${app.version}`);}};//# sourceMappingURL=appController.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.map b/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.map new file mode 100644 index 0000000..bba4e2b --- /dev/null +++ b/node_modules/.cache/nyc/250a0a2fc5cc9a448481faecc54395416e6909d1afb212c496932b2bf5af9f4b.map @@ -0,0 +1 @@ +{"version":3,"file":"appController.js","sourceRoot":"","sources":["../../../src/controllers/appController.ts"],"names":[],"mappings":";AAAA,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;AAElC,MAAM,CAAC,OAAO,GAAG;IACf,IAAI,EAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE;QAC5B,GAAG,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9C,CAAC;CACF,CAAA"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.js b/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.js new file mode 100644 index 0000000..4cdebc5 --- /dev/null +++ b/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.js @@ -0,0 +1 @@ +"use strict";var cov_240eder9dd=function(){var path="/Users/josh.burman/Projects/braid/dist/server/config/app.js";var hash="6a61ae0c1c6bc8407a3235ea60cb4230cd775842";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/config/app.js",statementMap:{"0":{start:{line:2,column:0},end:{line:17,column:2}}},fnMap:{},branchMap:{"0":{loc:{start:{line:4,column:16},end:{line:4,column:65}},type:"binary-expr",locations:[{start:{line:4,column:16},end:{line:4,column:37}},{start:{line:4,column:41},end:{line:4,column:65}}],line:4},"1":{loc:{start:{line:5,column:12},end:{line:5,column:40}},type:"binary-expr",locations:[{start:{line:5,column:12},end:{line:5,column:30}},{start:{line:5,column:34},end:{line:5,column:40}}],line:5},"2":{loc:{start:{line:7,column:10},end:{line:7,column:34}},type:"binary-expr",locations:[{start:{line:7,column:10},end:{line:7,column:26}},{start:{line:7,column:30},end:{line:7,column:34}}],line:7},"3":{loc:{start:{line:8,column:14},end:{line:8,column:57}},type:"binary-expr",locations:[{start:{line:8,column:14},end:{line:8,column:34}},{start:{line:8,column:38},end:{line:8,column:57}}],line:8},"4":{loc:{start:{line:9,column:17},end:{line:9,column:57}},type:"binary-expr",locations:[{start:{line:9,column:17},end:{line:9,column:40}},{start:{line:9,column:44},end:{line:9,column:57}}],line:9},"5":{loc:{start:{line:10,column:15},end:{line:10,column:47}},type:"binary-expr",locations:[{start:{line:10,column:15},end:{line:10,column:36}},{start:{line:10,column:40},end:{line:10,column:47}}],line:10}},s:{"0":0},f:{},b:{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_240eder9dd.s[0]++;module.exports={version:'0.7.1',whitelist:((cov_240eder9dd.b[0][0]++,process.env.WHITELIST)||(cov_240eder9dd.b[0][1]++,"http://admin.localhost")).split(','),secret:(cov_240eder9dd.b[1][0]++,process.env.SECRET)||(cov_240eder9dd.b[1][1]++,"test"),devToken:'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6Im1ocyIsImNsaWVudF90eXBlIjoic2l0ZSIsInVzZXJfdHlwZSI6InVzZXIiLCJ1c2VyX2lkIjoxMjUsImNoYW5uZWwiOiJtaHNfMTIzOSJ9LCJleHAiOjE1NTI4NDYzOTQsImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5a_s8rgln4rwhVqJLcSS9Uw7yw1_PmYgslWKZllgK6g',port:(cov_240eder9dd.b[2][0]++,process.env.PORT)||(cov_240eder9dd.b[2][1]++,8443),hostname:(cov_240eder9dd.b[3][0]++,process.env.HOSTNAME)||(cov_240eder9dd.b[3][1]++,'ysbraid.localhost'),environment:(cov_240eder9dd.b[4][0]++,process.env.ENVIRONMENT)||(cov_240eder9dd.b[4][1]++,'development'),log_level:(cov_240eder9dd.b[5][0]++,process.env.LOG_LEVEL)||(cov_240eder9dd.b[5][1]++,'debug'),signOptions:{issuer:'Yardstick Software',subject:'Braid JWT',audience:'internal',algorithm:["HS256"]}};//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.map b/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.map new file mode 100644 index 0000000..6acc157 --- /dev/null +++ b/node_modules/.cache/nyc/397e18ac919959415c3575ffc0902b12567d616735df2488d81f2ce4caa5643b.map @@ -0,0 +1 @@ +{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/config/app.ts"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAG,OAAO;IACjB,SAAS,EAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1E,MAAM,EAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM;IACrC,QAAQ,EAAE,kUAAkU;IAC5U,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mBAAmB;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,aAAa;IACrD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO;IAC3C,WAAW,EAAG;QACZ,MAAM,EAAG,oBAAoB;QAC7B,OAAO,EAAG,WAAW;QACrB,QAAQ,EAAG,UAAU;QACrB,SAAS,EAAG,CAAC,OAAO,CAAC;KACtB;CACF,CAAA"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.js b/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.js new file mode 100644 index 0000000..2f83eb0 --- /dev/null +++ b/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.js @@ -0,0 +1,12 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="4990a771bb61377b310e73bb0949bccf49143fe6";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:16},end:{line:8,column:29}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:13},end:{line:10,column:33}},"9":{start:{line:11,column:11},end:{line:11,column:25}},"10":{start:{line:12,column:10},end:{line:12,column:67}},"11":{start:{line:13,column:15},end:{line:13,column:33}},"12":{start:{line:15,column:11},end:{line:15,column:108}},"13":{start:{line:16,column:13},end:{line:16,column:53}},"14":{start:{line:17,column:0},end:{line:52,column:3}},"15":{start:{line:19,column:4},end:{line:22,column:7}},"16":{start:{line:20,column:8},end:{line:20,column:50}},"17":{start:{line:21,column:8},end:{line:21,column:45}},"18":{start:{line:23,column:4},end:{line:26,column:7}},"19":{start:{line:24,column:21},end:{line:24,column:46}},"20":{start:{line:25,column:8},end:{line:25,column:53}},"21":{start:{line:27,column:4},end:{line:30,column:7}},"22":{start:{line:28,column:21},end:{line:28,column:46}},"23":{start:{line:29,column:8},end:{line:29,column:52}},"24":{start:{line:31,column:4},end:{line:35,column:7}},"25":{start:{line:32,column:20},end:{line:32,column:51}},"26":{start:{line:33,column:21},end:{line:33,column:41}},"27":{start:{line:34,column:8},end:{line:34,column:41}},"28":{start:{line:36,column:4},end:{line:44,column:7}},"29":{start:{line:45,column:4},end:{line:51,column:7}},"30":{start:{line:49,column:21},end:{line:49,column:69}},"31":{start:{line:50,column:8},end:{line:50,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17},"1":{name:"(anonymous_1)",decl:{start:{line:19,column:47},end:{line:19,column:48}},loc:{start:{line:19,column:59},end:{line:22,column:5}},line:19},"2":{name:"(anonymous_2)",decl:{start:{line:23,column:41},end:{line:23,column:42}},loc:{start:{line:23,column:53},end:{line:26,column:5}},line:23},"3":{name:"(anonymous_3)",decl:{start:{line:27,column:73},end:{line:27,column:74}},loc:{start:{line:27,column:85},end:{line:30,column:5}},line:27},"4":{name:"(anonymous_4)",decl:{start:{line:31,column:31},end:{line:31,column:32}},loc:{start:{line:31,column:43},end:{line:35,column:5}},line:31},"5":{name:"(anonymous_5)",decl:{start:{line:36,column:47},end:{line:36,column:48}},loc:{start:{line:36,column:59},end:{line:44,column:5}},line:36},"6":{name:"(anonymous_6)",decl:{start:{line:45,column:49},end:{line:45,column:50}},loc:{start:{line:45,column:61},end:{line:51,column:5}},line:45}},branchMap:{"0":{loc:{start:{line:33,column:21},end:{line:33,column:41}},type:"cond-expr",locations:[{start:{line:33,column:29},end:{line:33,column:33}},{start:{line:33,column:36},end:{line:33,column:41}}],line:33}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[6]++,require('ws'));var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[8]++,require('../server'));var name=(cov_h9a3mwwe1.s[9]++,'test channel');var url=(cov_h9a3mwwe1.s[10]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[11]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[12]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[13]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[14]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[15]++;// before ( function () { server.startServer; }); +it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[16]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[17]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[18]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[19]++,channel.addClient(client));cov_h9a3mwwe1.s[20]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[21]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[22]++,channel.addClient(client));cov_h9a3mwwe1.s[23]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[24]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[25]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[26]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[27]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[28]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[29]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[30]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[31]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.map b/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.map new file mode 100644 index 0000000..c61a1b6 --- /dev/null +++ b/node_modules/.cache/nyc/4293581c6b9cfa8dcc04d88dcd047950891dfc741dc1d16b985a0385923cd0b7.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.js b/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.js new file mode 100644 index 0000000..2ce4719 --- /dev/null +++ b/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.js @@ -0,0 +1,54 @@ +"use strict";// import * as WebSocket from 'ws'; +// import ClientBase from '../clients/clientBase'; +// import MHSClient from '../clients/sites/mhsClient'; +// import ClientManager from '../clientManager'; +// var expect = require('chai').expect; +// var assert = require('chai').assert; +// var sinon = require('sinon'); +// var name: string = 'test channel'; +// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name } +// var WebSocketClient = require('websocket').client; +// var wsClient = new WebSocketClient(); +// var client: ClientBase = new ClientBase(data, wsClient); +// let clientManager = new ClientManager(); +// describe('ClientManager', function () { +// it('should add a client', function () { +// var result = clientManager.addClient(data, wsClient); +// expect(result.id).to.be.equal(125); +// }); +// it('should get clients of type', function () { +// var result = clientManager.clientsOfType('site'); +// assert(result.length > 0, 'returns one client'); +// }); +// it('should see client exists', function () { +// var exists = clientManager.clientExists(data.user_id); +// var result = exists ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should see client does not exists', function () { +// var exists = clientManager.clientExists(200); +// var result = exists ? true : false; +// expect(result).to.be.equal(false); +// }); +// it('should get an existing client', function () { +// var exists = clientManager.getClient(data.user_id); +// var result = exists ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should not get an existing client', function () { +// var exists = clientManager.getClient(200); +// var result = exists ? true : false; +// expect(result).to.be.equal(false); +// }); +// it('should add client of type MHSClient', function () { +// var data: any = { 'client': 'mhs', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name } +// var result = clientManager.getClientType(data, wsClient); +// expect(result.clientType()).to.be.equal('mhs'); +// }); +// // it('should remove a client', function () { +// // clientManager.removeClient(data.user_id); +// // expect(clientManager.clients.length).to.be.equal(0); +// // }); +// }); +//# sourceMappingURL=clientManager.spec.js.map +var cov_1wd6f9mhef=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/clientManager.spec.js";var hash="58341126b5dbf87407cd4141f560d34c63bb7c65";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/clientManager.spec.js",statementMap:{},fnMap:{},branchMap:{},s:{},f:{},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}(); \ No newline at end of file diff --git a/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.map b/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.map new file mode 100644 index 0000000..1c33b52 --- /dev/null +++ b/node_modules/.cache/nyc/4ee2d3f13f77ed002783e3a13a05f31c8e55fbd6cdcf7b77bbf8da8698b4de67.map @@ -0,0 +1 @@ +{"version":3,"file":"clientManager.spec.js","sourceRoot":"","sources":["../../../src/test/clientManager.spec.ts"],"names":[],"mappings":";AAAA,mCAAmC;AACnC,kDAAkD;AAClD,sDAAsD;AACtD,gDAAgD;AAEhD,uCAAuC;AACvC,uCAAuC;AACvC,gCAAgC;AAEhC,qCAAqC;AACrC,mHAAmH;AACnH,qDAAqD;AACrD,wCAAwC;AACxC,2DAA2D;AAE3D,2CAA2C;AAE3C,0CAA0C;AAC1C,4CAA4C;AAC5C,4DAA4D;AAC5D,0CAA0C;AAC1C,QAAQ;AAER,mDAAmD;AACnD,wDAAwD;AACxD,uDAAuD;AACvD,QAAQ;AAER,iDAAiD;AACjD,6DAA6D;AAC7D,0CAA0C;AAC1C,wCAAwC;AACxC,QAAQ;AAER,0DAA0D;AAC1D,oDAAoD;AACpD,0CAA0C;AAC1C,yCAAyC;AACzC,QAAQ;AAER,sDAAsD;AACtD,0DAA0D;AAC1D,0CAA0C;AAC1C,wCAAwC;AACxC,QAAQ;AAER,0DAA0D;AAC1D,iDAAiD;AACjD,0CAA0C;AAC1C,yCAAyC;AACzC,QAAQ;AAER,4DAA4D;AAC5D,sHAAsH;AACtH,gEAAgE;AAChE,sDAAsD;AACtD,QAAQ;AAER,kDAAkD;AAClD,mDAAmD;AACnD,8DAA8D;AAC9D,WAAW;AACX,MAAM"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.js b/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.js new file mode 100644 index 0000000..ab89839 --- /dev/null +++ b/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.js @@ -0,0 +1,11 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="aee439813da4b9a4900a64ec5c6452a2ece0db90";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:11},end:{line:10,column:25}},"9":{start:{line:11,column:15},end:{line:11,column:36}},"10":{start:{line:13,column:11},end:{line:13,column:108}},"11":{start:{line:14,column:13},end:{line:14,column:53}},"12":{start:{line:15,column:0},end:{line:49,column:3}},"13":{start:{line:16,column:4},end:{line:19,column:7}},"14":{start:{line:17,column:8},end:{line:17,column:50}},"15":{start:{line:18,column:8},end:{line:18,column:45}},"16":{start:{line:20,column:4},end:{line:23,column:7}},"17":{start:{line:21,column:21},end:{line:21,column:46}},"18":{start:{line:22,column:8},end:{line:22,column:53}},"19":{start:{line:24,column:4},end:{line:27,column:7}},"20":{start:{line:25,column:21},end:{line:25,column:46}},"21":{start:{line:26,column:8},end:{line:26,column:52}},"22":{start:{line:28,column:4},end:{line:32,column:7}},"23":{start:{line:29,column:20},end:{line:29,column:51}},"24":{start:{line:30,column:21},end:{line:30,column:41}},"25":{start:{line:31,column:8},end:{line:31,column:41}},"26":{start:{line:33,column:4},end:{line:41,column:7}},"27":{start:{line:42,column:4},end:{line:48,column:7}},"28":{start:{line:46,column:21},end:{line:46,column:69}},"29":{start:{line:47,column:8},end:{line:47,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:49,column:1}},line:15},"1":{name:"(anonymous_1)",decl:{start:{line:16,column:47},end:{line:16,column:48}},loc:{start:{line:16,column:59},end:{line:19,column:5}},line:16},"2":{name:"(anonymous_2)",decl:{start:{line:20,column:41},end:{line:20,column:42}},loc:{start:{line:20,column:53},end:{line:23,column:5}},line:20},"3":{name:"(anonymous_3)",decl:{start:{line:24,column:73},end:{line:24,column:74}},loc:{start:{line:24,column:85},end:{line:27,column:5}},line:24},"4":{name:"(anonymous_4)",decl:{start:{line:28,column:31},end:{line:28,column:32}},loc:{start:{line:28,column:43},end:{line:32,column:5}},line:28},"5":{name:"(anonymous_5)",decl:{start:{line:33,column:47},end:{line:33,column:48}},loc:{start:{line:33,column:59},end:{line:41,column:5}},line:33},"6":{name:"(anonymous_6)",decl:{start:{line:42,column:49},end:{line:42,column:50}},loc:{start:{line:42,column:61},end:{line:48,column:5}},line:42}},branchMap:{"0":{loc:{start:{line:30,column:21},end:{line:30,column:41}},type:"cond-expr",locations:[{start:{line:30,column:29},end:{line:30,column:33}},{start:{line:30,column:36},end:{line:30,column:41}}],line:30}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocketClient());var channel;var data=(cov_h9a3mwwe1.s[10]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[11]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[12]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[13]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[14]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[15]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[16]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[17]++,channel.addClient(client));cov_h9a3mwwe1.s[18]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[19]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[22]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[23]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[24]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[25]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[26]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[27]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[28]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[29]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.map b/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.map new file mode 100644 index 0000000..9131eb4 --- /dev/null +++ b/node_modules/.cache/nyc/559b3cb31385c1e04e53f0e6068ad2b130337e6d1c43060ff0610380cc65a4e4.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.js b/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.js new file mode 100644 index 0000000..89bb366 --- /dev/null +++ b/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.js @@ -0,0 +1,3 @@ +"use strict";var cov_2ayw7o7ftd=function(){var path="/Users/josh.burman/Projects/braid/dist/server/server.js";var hash="ae896b273caab42043ef75c35fa7d4b8e71933b1";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/server.js",statementMap:{"0":{start:{line:2,column:16},end:{line:9,column:1}},"1":{start:{line:3,column:4},end:{line:8,column:7}},"2":{start:{line:4,column:36},end:{line:4,column:97}},"3":{start:{line:4,column:42},end:{line:4,column:70}},"4":{start:{line:4,column:85},end:{line:4,column:95}},"5":{start:{line:5,column:35},end:{line:5,column:100}},"6":{start:{line:5,column:41},end:{line:5,column:73}},"7":{start:{line:5,column:88},end:{line:5,column:98}},"8":{start:{line:6,column:32},end:{line:6,column:149}},"9":{start:{line:6,column:97},end:{line:6,column:119}},"10":{start:{line:7,column:8},end:{line:7,column:78}},"11":{start:{line:10,column:0},end:{line:10,column:62}},"12":{start:{line:12,column:16},end:{line:12,column:34}},"13":{start:{line:13,column:14},end:{line:13,column:29}},"14":{start:{line:14,column:18},end:{line:14,column:31}},"15":{start:{line:15,column:11},end:{line:15,column:24}},"16":{start:{line:16,column:12},end:{line:16,column:35}},"17":{start:{line:17,column:12},end:{line:17,column:26}},"18":{start:{line:19,column:13},end:{line:19,column:32}},"19":{start:{line:20,column:10},end:{line:20,column:33}},"20":{start:{line:21,column:13},end:{line:21,column:32}},"21":{start:{line:22,column:24},end:{line:22,column:50}},"22":{start:{line:23,column:25},end:{line:23,column:52}},"23":{start:{line:24,column:17},end:{line:24,column:57}},"24":{start:{line:25,column:18},end:{line:25,column:59}},"25":{start:{line:26,column:14},end:{line:26,column:76}},"26":{start:{line:27,column:20},end:{line:27,column:29}},"27":{start:{line:28,column:15},end:{line:28,column:46}},"28":{start:{line:29,column:12},end:{line:29,column:92}},"29":{start:{line:30,column:0},end:{line:30,column:32}},"30":{start:{line:31,column:0},end:{line:31,column:28}},"31":{start:{line:32,column:20},end:{line:32,column:49}},"32":{start:{line:33,column:21},end:{line:33,column:51}},"33":{start:{line:35,column:4},end:{line:54,column:7}},"34":{start:{line:36,column:19},end:{line:36,column:40}},"35":{start:{line:37,column:8},end:{line:37,column:67}},"36":{start:{line:38,column:8},end:{line:40,column:9}},"37":{start:{line:39,column:12},end:{line:39,column:47}},"38":{start:{line:41,column:8},end:{line:49,column:9}},"39":{start:{line:42,column:25},end:{line:42,column:62}},"40":{start:{line:43,column:12},end:{line:45,column:13}},"41":{start:{line:44,column:16},end:{line:44,column:44}},"42":{start:{line:48,column:25},end:{line:48,column:58}},"43":{start:{line:50,column:8},end:{line:52,column:9}},"44":{start:{line:51,column:12},end:{line:51,column:68}},"45":{start:{line:53,column:8},end:{line:53,column:105}},"46":{start:{line:55,column:4},end:{line:86,column:7}},"47":{start:{line:56,column:8},end:{line:85,column:11}},"48":{start:{line:58,column:12},end:{line:65,column:13}},"49":{start:{line:59,column:16},end:{line:59,column:48}},"50":{start:{line:62,column:16},end:{line:62,column:33}},"51":{start:{line:63,column:16},end:{line:63,column:63}},"52":{start:{line:64,column:16},end:{line:64,column:23}},"53":{start:{line:67,column:16},end:{line:80,column:19}},"54":{start:{line:68,column:31},end:{line:68,column:65}},"55":{start:{line:69,column:32},end:{line:69,column:100}},"56":{start:{line:70,column:35},end:{line:70,column:39}},"57":{start:{line:72,column:20},end:{line:79,column:23}},"58":{start:{line:73,column:24},end:{line:76,column:25}},"59":{start:{line:74,column:28},end:{line:74,column:45}},"60":{start:{line:75,column:28},end:{line:75,column:45}},"61":{start:{line:77,column:24},end:{line:77,column:57}},"62":{start:{line:78,column:24},end:{line:78,column:72}},"63":{start:{line:82,column:12},end:{line:84,column:15}},"64":{start:{line:83,column:16},end:{line:83,column:58}},"65":{start:{line:87,column:4},end:{line:90,column:7}},"66":{start:{line:88,column:8},end:{line:88,column:59}},"67":{start:{line:89,column:8},end:{line:89,column:69}},"68":{start:{line:92,column:0},end:{line:92,column:14}},"69":{start:{line:93,column:0},end:{line:96,column:2}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:2,column:44},end:{line:2,column:45}},loc:{start:{line:2,column:89},end:{line:9,column:1}},line:2},"1":{name:"(anonymous_1)",decl:{start:{line:3,column:36},end:{line:3,column:37}},loc:{start:{line:3,column:63},end:{line:8,column:5}},line:3},"2":{name:"fulfilled",decl:{start:{line:4,column:17},end:{line:4,column:26}},loc:{start:{line:4,column:34},end:{line:4,column:99}},line:4},"3":{name:"rejected",decl:{start:{line:5,column:17},end:{line:5,column:25}},loc:{start:{line:5,column:33},end:{line:5,column:102}},line:5},"4":{name:"step",decl:{start:{line:6,column:17},end:{line:6,column:21}},loc:{start:{line:6,column:30},end:{line:6,column:151}},line:6},"5":{name:"(anonymous_5)",decl:{start:{line:6,column:76},end:{line:6,column:77}},loc:{start:{line:6,column:95},end:{line:6,column:121}},line:6},"6":{name:"startServer",decl:{start:{line:34,column:9},end:{line:34,column:20}},loc:{start:{line:34,column:23},end:{line:91,column:1}},line:34},"7":{name:"(anonymous_7)",decl:{start:{line:35,column:25},end:{line:35,column:26}},loc:{start:{line:35,column:48},end:{line:54,column:5}},line:35},"8":{name:"upgrade",decl:{start:{line:55,column:34},end:{line:55,column:41}},loc:{start:{line:55,column:65},end:{line:86,column:5}},line:55},"9":{name:"(anonymous_9)",decl:{start:{line:56,column:47},end:{line:56,column:48}},loc:{start:{line:56,column:60},end:{line:85,column:9}},line:56},"10":{name:"verifyConnection",decl:{start:{line:66,column:21},end:{line:66,column:37}},loc:{start:{line:66,column:40},end:{line:81,column:13}},line:66},"11":{name:"(anonymous_11)",decl:{start:{line:67,column:35},end:{line:67,column:36}},loc:{start:{line:67,column:56},end:{line:80,column:17}},line:67},"12":{name:"(anonymous_12)",decl:{start:{line:72,column:67},end:{line:72,column:68}},loc:{start:{line:72,column:91},end:{line:79,column:21}},line:72},"13":{name:"done",decl:{start:{line:82,column:62},end:{line:82,column:66}},loc:{start:{line:82,column:71},end:{line:84,column:13}},line:82},"14":{name:"(anonymous_14)",decl:{start:{line:87,column:28},end:{line:87,column:29}},loc:{start:{line:87,column:34},end:{line:90,column:5}},line:87}},branchMap:{"0":{loc:{start:{line:2,column:16},end:{line:9,column:1}},type:"binary-expr",locations:[{start:{line:2,column:17},end:{line:2,column:21}},{start:{line:2,column:25},end:{line:2,column:39}},{start:{line:2,column:44},end:{line:9,column:1}}],line:2},"1":{loc:{start:{line:3,column:16},end:{line:3,column:34}},type:"binary-expr",locations:[{start:{line:3,column:16},end:{line:3,column:17}},{start:{line:3,column:22},end:{line:3,column:33}}],line:3},"2":{loc:{start:{line:6,column:32},end:{line:6,column:148}},type:"cond-expr",locations:[{start:{line:6,column:46},end:{line:6,column:67}},{start:{line:6,column:70},end:{line:6,column:148}}],line:6},"3":{loc:{start:{line:7,column:51},end:{line:7,column:67}},type:"binary-expr",locations:[{start:{line:7,column:51},end:{line:7,column:61}},{start:{line:7,column:65},end:{line:7,column:67}}],line:7},"4":{loc:{start:{line:38,column:8},end:{line:40,column:9}},type:"if",locations:[{start:{line:38,column:8},end:{line:40,column:9}},{start:{line:38,column:8},end:{line:40,column:9}}],line:38},"5":{loc:{start:{line:41,column:8},end:{line:49,column:9}},type:"if",locations:[{start:{line:41,column:8},end:{line:49,column:9}},{start:{line:41,column:8},end:{line:49,column:9}}],line:41},"6":{loc:{start:{line:43,column:12},end:{line:45,column:13}},type:"if",locations:[{start:{line:43,column:12},end:{line:45,column:13}},{start:{line:43,column:12},end:{line:45,column:13}}],line:43},"7":{loc:{start:{line:50,column:8},end:{line:52,column:9}},type:"if",locations:[{start:{line:50,column:8},end:{line:52,column:9}},{start:{line:50,column:8},end:{line:52,column:9}}],line:50},"8":{loc:{start:{line:69,column:32},end:{line:69,column:100}},type:"binary-expr",locations:[{start:{line:69,column:32},end:{line:69,column:42}},{start:{line:69,column:47},end:{line:69,column:99}}],line:69},"9":{loc:{start:{line:69,column:47},end:{line:69,column:99}},type:"cond-expr",locations:[{start:{line:69,column:82},end:{line:69,column:94}},{start:{line:69,column:97},end:{line:69,column:99}}],line:69},"10":{loc:{start:{line:73,column:24},end:{line:76,column:25}},type:"if",locations:[{start:{line:73,column:24},end:{line:76,column:25}},{start:{line:73,column:24},end:{line:76,column:25}}],line:73},"11":{loc:{start:{line:78,column:24},end:{line:78,column:71}},type:"cond-expr",locations:[{start:{line:78,column:35},end:{line:78,column:50}},{start:{line:78,column:53},end:{line:78,column:71}}],line:78}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},b:{"0":[0,0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();var __awaiter=(cov_2ayw7o7ftd.s[0]++,(cov_2ayw7o7ftd.b[0][0]++,this)&&(cov_2ayw7o7ftd.b[0][1]++,this.__awaiter)||(cov_2ayw7o7ftd.b[0][2]++,function(thisArg,_arguments,P,generator){cov_2ayw7o7ftd.f[0]++;cov_2ayw7o7ftd.s[1]++;return new((cov_2ayw7o7ftd.b[1][0]++,P)||(cov_2ayw7o7ftd.b[1][1]++,P=Promise))(function(resolve,reject){cov_2ayw7o7ftd.f[1]++;function fulfilled(value){cov_2ayw7o7ftd.f[2]++;cov_2ayw7o7ftd.s[2]++;try{cov_2ayw7o7ftd.s[3]++;step(generator.next(value));}catch(e){cov_2ayw7o7ftd.s[4]++;reject(e);}}function rejected(value){cov_2ayw7o7ftd.f[3]++;cov_2ayw7o7ftd.s[5]++;try{cov_2ayw7o7ftd.s[6]++;step(generator["throw"](value));}catch(e){cov_2ayw7o7ftd.s[7]++;reject(e);}}function step(result){cov_2ayw7o7ftd.f[4]++;cov_2ayw7o7ftd.s[8]++;result.done?(cov_2ayw7o7ftd.b[2][0]++,resolve(result.value)):(cov_2ayw7o7ftd.b[2][1]++,new P(function(resolve){cov_2ayw7o7ftd.f[5]++;cov_2ayw7o7ftd.s[9]++;resolve(result.value);}).then(fulfilled,rejected));}cov_2ayw7o7ftd.s[10]++;step((generator=generator.apply(thisArg,(cov_2ayw7o7ftd.b[3][0]++,_arguments)||(cov_2ayw7o7ftd.b[3][1]++,[]))).next());});}));cov_2ayw7o7ftd.s[11]++;Object.defineProperty(exports,"__esModule",{value:true});//external imports +const express=(cov_2ayw7o7ftd.s[12]++,require("express"));const https=(cov_2ayw7o7ftd.s[13]++,require("http"));const WebSocket=(cov_2ayw7o7ftd.s[14]++,require("ws"));const fs=(cov_2ayw7o7ftd.s[15]++,require("fs"));const jwt=(cov_2ayw7o7ftd.s[16]++,require("jsonwebtoken"));const url=(cov_2ayw7o7ftd.s[17]++,require("url"));//internal imports +var routes=(cov_2ayw7o7ftd.s[18]++,require('./routes'));var app=(cov_2ayw7o7ftd.s[19]++,require('./config/app'));var logger=(cov_2ayw7o7ftd.s[20]++,require('./logger'));const clientManager_1=(cov_2ayw7o7ftd.s[21]++,require("./clientManager"));const channelManager_1=(cov_2ayw7o7ftd.s[22]++,require("./channelManager"));var privateKey=(cov_2ayw7o7ftd.s[23]++,fs.readFileSync('certs/key.pem','utf8'));var certificate=(cov_2ayw7o7ftd.s[24]++,fs.readFileSync('certs/cert.pem','utf8'));var options=(cov_2ayw7o7ftd.s[25]++,{key:privateKey,cert:certificate,hostname:app.hostname});const application=(cov_2ayw7o7ftd.s[26]++,express());const server=(cov_2ayw7o7ftd.s[27]++,https.createServer(application));const wss=(cov_2ayw7o7ftd.s[28]++,new WebSocket.Server({noServer:true,maxPayload:250000,host:app.hostname}));cov_2ayw7o7ftd.s[29]++;application.use(express.json());cov_2ayw7o7ftd.s[30]++;application.use('',routes);let clientManager=(cov_2ayw7o7ftd.s[31]++,new clientManager_1.default());let channelManager=(cov_2ayw7o7ftd.s[32]++,new channelManager_1.default());function startServer(){cov_2ayw7o7ftd.f[6]++;cov_2ayw7o7ftd.s[33]++;wss.on('connection',(ws,request,args)=>{cov_2ayw7o7ftd.f[7]++;var data=(cov_2ayw7o7ftd.s[34]++,JSON.parse(args).data);cov_2ayw7o7ftd.s[35]++;logger.accessLog.info(`Client Connected: ${data.user_id}`);cov_2ayw7o7ftd.s[36]++;if(!channelManager.channelExists(data.channel)){cov_2ayw7o7ftd.b[4][0]++;cov_2ayw7o7ftd.s[37]++;channelManager.createChannel(data);}else{cov_2ayw7o7ftd.b[4][1]++;}cov_2ayw7o7ftd.s[38]++;if(clientManager.clientExists(data.user_id)){cov_2ayw7o7ftd.b[5][0]++;var client=(cov_2ayw7o7ftd.s[39]++,clientManager.getClient(data.user_id));cov_2ayw7o7ftd.s[40]++;if(client!=null){cov_2ayw7o7ftd.b[6][0]++;cov_2ayw7o7ftd.s[41]++;client.replaceWebSocket(ws);}else{cov_2ayw7o7ftd.b[6][1]++;}}else{cov_2ayw7o7ftd.b[5][1]++;var client=(cov_2ayw7o7ftd.s[42]++,clientManager.addClient(data,ws));}cov_2ayw7o7ftd.s[43]++;if(client!=null){cov_2ayw7o7ftd.b[7][0]++;cov_2ayw7o7ftd.s[44]++;channelManager.addClientToChannel(client,data.channel);}else{cov_2ayw7o7ftd.b[7][1]++;}cov_2ayw7o7ftd.s[45]++;ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!');});cov_2ayw7o7ftd.s[46]++;server.on('upgrade',function upgrade(request,socket,head){cov_2ayw7o7ftd.f[8]++;cov_2ayw7o7ftd.s[47]++;return __awaiter(this,void 0,void 0,function*(){cov_2ayw7o7ftd.f[9]++;let args;cov_2ayw7o7ftd.s[48]++;try{cov_2ayw7o7ftd.s[49]++;args=yield verifyConnection();}catch(e){cov_2ayw7o7ftd.s[50]++;socket.destroy();cov_2ayw7o7ftd.s[51]++;logger.accessLog.info('Connection Terminated');cov_2ayw7o7ftd.s[52]++;return;}function verifyConnection(){cov_2ayw7o7ftd.f[10]++;cov_2ayw7o7ftd.s[53]++;return new Promise((resolve,reject)=>{cov_2ayw7o7ftd.f[11]++;var data=(cov_2ayw7o7ftd.s[54]++,url.parse(request.url,true).query);var token=(cov_2ayw7o7ftd.s[55]++,(cov_2ayw7o7ftd.b[8][0]++,data.token)||(cov_2ayw7o7ftd.b[8][1]++,app.environment=='development'?(cov_2ayw7o7ftd.b[9][0]++,app.devToken):(cov_2ayw7o7ftd.b[9][1]++,'')));var accepted=(cov_2ayw7o7ftd.s[56]++,true);var result;cov_2ayw7o7ftd.s[57]++;jwt.verify(token,app.secret,app.signOptions,function(err,decoded){cov_2ayw7o7ftd.f[12]++;cov_2ayw7o7ftd.s[58]++;if(err){cov_2ayw7o7ftd.b[10][0]++;cov_2ayw7o7ftd.s[59]++;console.log(err);cov_2ayw7o7ftd.s[60]++;accepted=false;}else{cov_2ayw7o7ftd.b[10][1]++;}cov_2ayw7o7ftd.s[61]++;result=JSON.stringify(decoded);cov_2ayw7o7ftd.s[62]++;accepted?(cov_2ayw7o7ftd.b[11][0]++,resolve(result)):(cov_2ayw7o7ftd.b[11][1]++,reject('rejected'));});});}cov_2ayw7o7ftd.s[63]++;wss.handleUpgrade(request,socket,head,function done(ws){cov_2ayw7o7ftd.f[13]++;cov_2ayw7o7ftd.s[64]++;wss.emit('connection',ws,request,args);});});});cov_2ayw7o7ftd.s[65]++;server.listen(app.port,()=>{cov_2ayw7o7ftd.f[14]++;cov_2ayw7o7ftd.s[66]++;console.log(`Braid v${app.version} is running!\n`);cov_2ayw7o7ftd.s[67]++;logger.accessLog.info(`Braid v${app.version} is running!\n`);});}cov_2ayw7o7ftd.s[68]++;startServer();cov_2ayw7o7ftd.s[69]++;module.exports={clientManager:clientManager,channelManager:channelManager};//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.map b/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.map new file mode 100644 index 0000000..843e764 --- /dev/null +++ b/node_modules/.cache/nyc/632aaa54b53332d95475476c08c1a5e06fc7281e0c5d074594adfd900a467522.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.js b/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.js new file mode 100644 index 0000000..2a583cd --- /dev/null +++ b/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.js @@ -0,0 +1 @@ +"use strict";var cov_240eder9dd=function(){var path="/Users/josh.burman/Projects/braid/dist/server/config/app.js";var hash="6a61ae0c1c6bc8407a3235ea60cb4230cd775842";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/config/app.js",statementMap:{"0":{start:{line:2,column:0},end:{line:17,column:2}}},fnMap:{},branchMap:{"0":{loc:{start:{line:4,column:16},end:{line:4,column:65}},type:"binary-expr",locations:[{start:{line:4,column:16},end:{line:4,column:37}},{start:{line:4,column:41},end:{line:4,column:65}}],line:4},"1":{loc:{start:{line:5,column:12},end:{line:5,column:40}},type:"binary-expr",locations:[{start:{line:5,column:12},end:{line:5,column:30}},{start:{line:5,column:34},end:{line:5,column:40}}],line:5},"2":{loc:{start:{line:7,column:10},end:{line:7,column:34}},type:"binary-expr",locations:[{start:{line:7,column:10},end:{line:7,column:26}},{start:{line:7,column:30},end:{line:7,column:34}}],line:7},"3":{loc:{start:{line:8,column:14},end:{line:8,column:57}},type:"binary-expr",locations:[{start:{line:8,column:14},end:{line:8,column:34}},{start:{line:8,column:38},end:{line:8,column:57}}],line:8},"4":{loc:{start:{line:9,column:17},end:{line:9,column:57}},type:"binary-expr",locations:[{start:{line:9,column:17},end:{line:9,column:40}},{start:{line:9,column:44},end:{line:9,column:57}}],line:9},"5":{loc:{start:{line:10,column:15},end:{line:10,column:47}},type:"binary-expr",locations:[{start:{line:10,column:15},end:{line:10,column:36}},{start:{line:10,column:40},end:{line:10,column:47}}],line:10}},s:{"0":0},f:{},b:{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_240eder9dd.s[0]++;module.exports={version:'0.7.1',whitelist:((cov_240eder9dd.b[0][0]++,process.env.WHITELIST)||(cov_240eder9dd.b[0][1]++,"http://admin.localhost")).split(','),secret:(cov_240eder9dd.b[1][0]++,process.env.SECRET)||(cov_240eder9dd.b[1][1]++,"test"),devToken:'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ',port:(cov_240eder9dd.b[2][0]++,process.env.PORT)||(cov_240eder9dd.b[2][1]++,8443),hostname:(cov_240eder9dd.b[3][0]++,process.env.HOSTNAME)||(cov_240eder9dd.b[3][1]++,'ysbraid.localhost'),environment:(cov_240eder9dd.b[4][0]++,process.env.ENVIRONMENT)||(cov_240eder9dd.b[4][1]++,'development'),log_level:(cov_240eder9dd.b[5][0]++,process.env.LOG_LEVEL)||(cov_240eder9dd.b[5][1]++,'debug'),signOptions:{issuer:'Yardstick Software',subject:'Braid JWT',audience:'internal',algorithm:["HS256"]}};//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.map b/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.map new file mode 100644 index 0000000..441a0f9 --- /dev/null +++ b/node_modules/.cache/nyc/6fd53629ba5226b2cb23a686c4512ce27fb483347b3026158f3d9c2a4feba72a.map @@ -0,0 +1 @@ +{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/config/app.ts"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAG,OAAO;IACjB,SAAS,EAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1E,MAAM,EAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM;IACrC,QAAQ,EAAE,kTAAkT;IAC5T,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mBAAmB;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,aAAa;IACrD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO;IAC3C,WAAW,EAAG;QACZ,MAAM,EAAG,oBAAoB;QAC7B,OAAO,EAAG,WAAW;QACrB,QAAQ,EAAG,UAAU;QACrB,SAAS,EAAG,CAAC,OAAO,CAAC;KACtB;CACF,CAAA"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.js b/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.js new file mode 100644 index 0000000..5ad57e4 --- /dev/null +++ b/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.js @@ -0,0 +1,11 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="c0cd9f1364cdb10d352477e1154c1a9d2ba22de9";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:16},end:{line:8,column:29}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:13},end:{line:10,column:33}},"9":{start:{line:11,column:11},end:{line:11,column:25}},"10":{start:{line:12,column:10},end:{line:12,column:67}},"11":{start:{line:13,column:15},end:{line:13,column:33}},"12":{start:{line:15,column:11},end:{line:15,column:108}},"13":{start:{line:16,column:13},end:{line:16,column:53}},"14":{start:{line:17,column:0},end:{line:52,column:3}},"15":{start:{line:18,column:4},end:{line:18,column:48}},"16":{start:{line:18,column:25},end:{line:18,column:44}},"17":{start:{line:19,column:4},end:{line:22,column:7}},"18":{start:{line:20,column:8},end:{line:20,column:50}},"19":{start:{line:21,column:8},end:{line:21,column:45}},"20":{start:{line:23,column:4},end:{line:26,column:7}},"21":{start:{line:24,column:21},end:{line:24,column:46}},"22":{start:{line:25,column:8},end:{line:25,column:53}},"23":{start:{line:27,column:4},end:{line:30,column:7}},"24":{start:{line:28,column:21},end:{line:28,column:46}},"25":{start:{line:29,column:8},end:{line:29,column:52}},"26":{start:{line:31,column:4},end:{line:35,column:7}},"27":{start:{line:32,column:20},end:{line:32,column:51}},"28":{start:{line:33,column:21},end:{line:33,column:41}},"29":{start:{line:34,column:8},end:{line:34,column:41}},"30":{start:{line:36,column:4},end:{line:44,column:7}},"31":{start:{line:45,column:4},end:{line:51,column:7}},"32":{start:{line:49,column:21},end:{line:49,column:69}},"33":{start:{line:50,column:8},end:{line:50,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17},"1":{name:"(anonymous_1)",decl:{start:{line:18,column:11},end:{line:18,column:12}},loc:{start:{line:18,column:23},end:{line:18,column:46}},line:18},"2":{name:"(anonymous_2)",decl:{start:{line:19,column:47},end:{line:19,column:48}},loc:{start:{line:19,column:59},end:{line:22,column:5}},line:19},"3":{name:"(anonymous_3)",decl:{start:{line:23,column:41},end:{line:23,column:42}},loc:{start:{line:23,column:53},end:{line:26,column:5}},line:23},"4":{name:"(anonymous_4)",decl:{start:{line:27,column:73},end:{line:27,column:74}},loc:{start:{line:27,column:85},end:{line:30,column:5}},line:27},"5":{name:"(anonymous_5)",decl:{start:{line:31,column:31},end:{line:31,column:32}},loc:{start:{line:31,column:43},end:{line:35,column:5}},line:31},"6":{name:"(anonymous_6)",decl:{start:{line:36,column:47},end:{line:36,column:48}},loc:{start:{line:36,column:59},end:{line:44,column:5}},line:36},"7":{name:"(anonymous_7)",decl:{start:{line:45,column:49},end:{line:45,column:50}},loc:{start:{line:45,column:61},end:{line:51,column:5}},line:45}},branchMap:{"0":{loc:{start:{line:33,column:21},end:{line:33,column:41}},type:"cond-expr",locations:[{start:{line:33,column:29},end:{line:33,column:33}},{start:{line:33,column:36},end:{line:33,column:41}}],line:33}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[6]++,require('ws'));var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[8]++,require('../server'));var name=(cov_h9a3mwwe1.s[9]++,'test channel');var url=(cov_h9a3mwwe1.s[10]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[11]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[12]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[13]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[14]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[15]++;before(function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[16]++;server.startServer;});cov_h9a3mwwe1.s[17]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[2]++;cov_h9a3mwwe1.s[18]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[19]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[20]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[21]++,channel.addClient(client));cov_h9a3mwwe1.s[22]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[23]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[4]++;var result=(cov_h9a3mwwe1.s[24]++,channel.addClient(client));cov_h9a3mwwe1.s[25]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[26]++;it('should find a client',function(){cov_h9a3mwwe1.f[5]++;var exist=(cov_h9a3mwwe1.s[27]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[28]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[29]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[30]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[6]++;});cov_h9a3mwwe1.s[31]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[7]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[32]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[33]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.map b/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.map new file mode 100644 index 0000000..6f1a760 --- /dev/null +++ b/node_modules/.cache/nyc/6ff21ee9e46ef5145fc3d352faa471b95ddd2824da4b6de8287260f94fe2b3b8.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.js b/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.js new file mode 100644 index 0000000..1c4b364 --- /dev/null +++ b/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.js @@ -0,0 +1,38 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="afd95f93e5b730e5fc84aaa29ba8fc51245618fa";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:18},end:{line:3,column:31}},"2":{start:{line:4,column:11},end:{line:4,column:40}},"3":{start:{line:5,column:13},end:{line:5,column:35}},"4":{start:{line:6,column:12},end:{line:6,column:28}},"5":{start:{line:8,column:10},end:{line:8,column:34}},"6":{start:{line:9,column:11},end:{line:9,column:25}},"7":{start:{line:11,column:10},end:{line:11,column:367}},"8":{start:{line:15,column:0},end:{line:54,column:3}},"9":{start:{line:17,column:4},end:{line:20,column:7}},"10":{start:{line:18,column:8},end:{line:18,column:38}},"11":{start:{line:19,column:23},end:{line:19,column:41}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:54,column:1}},line:15},"1":{name:"(anonymous_1)",decl:{start:{line:17,column:11},end:{line:17,column:12}},loc:{start:{line:17,column:23},end:{line:20,column:5}},line:17}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0},f:{"0":0,"1":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const WebSocket=(cov_h9a3mwwe1.s[1]++,require("ws"));var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));// var WebSocket = require('ws');s +var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));var name=(cov_h9a3mwwe1.s[6]++,'test channel');// var url: string = `wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ`; +var url=(cov_h9a3mwwe1.s[7]++,"wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6Im1ocyIsImNsaWVudF90eXBlIjoic2l0ZSIsInVzZXJfdHlwZSI6InVzZXIiLCJ1c2VyX2lkIjoxMjUsImNoYW5uZWwiOiJtaHNfMTIzOSJ9LCJleHAiOjE1NTI4NDYzOTQsImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5a_s8rgln4rwhVqJLcSS9Uw7yw1_PmYgslWKZllgK6g");var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[8]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;var server;cov_h9a3mwwe1.s[9]++;before(function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[10]++;server=require('../server');var wsClient=(cov_h9a3mwwe1.s[11]++,new WebSocket(url));});// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.map b/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.map new file mode 100644 index 0000000..71d4192 --- /dev/null +++ b/node_modules/.cache/nyc/88a4ef1f00c117b6c43947f787ab3c457d1fc69f1a619c17a30b5b40bbc8c18d.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAEA,gCAAgC;AAEhC,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,kCAAkC;AAClC,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,2WAA2W;AAC3W,IAAI,GAAG,GAAW,qWAAqW,CAAC;AACxX,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,IAAI,MAAW,CAAC;IAChB,MAAM,CAAG;QACP,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9B,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.js b/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.js new file mode 100644 index 0000000..1c4332a --- /dev/null +++ b/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.js @@ -0,0 +1,13 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="b0f58ae25bda40fbcab69503d969fb1beaaf0382";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:21},end:{line:3,column:53}},"2":{start:{line:5,column:11},end:{line:5,column:40}},"3":{start:{line:6,column:13},end:{line:6,column:35}},"4":{start:{line:7,column:12},end:{line:7,column:28}},"5":{start:{line:8,column:16},end:{line:8,column:29}},"6":{start:{line:9,column:10},end:{line:9,column:34}},"7":{start:{line:10,column:13},end:{line:10,column:33}},"8":{start:{line:11,column:11},end:{line:11,column:25}},"9":{start:{line:12,column:10},end:{line:12,column:67}},"10":{start:{line:13,column:15},end:{line:13,column:33}},"11":{start:{line:15,column:11},end:{line:15,column:118}},"12":{start:{line:16,column:13},end:{line:16,column:53}},"13":{start:{line:17,column:0},end:{line:52,column:3}},"14":{start:{line:19,column:4},end:{line:22,column:7}},"15":{start:{line:20,column:8},end:{line:20,column:60}},"16":{start:{line:21,column:8},end:{line:21,column:45}},"17":{start:{line:23,column:4},end:{line:26,column:7}},"18":{start:{line:24,column:21},end:{line:24,column:46}},"19":{start:{line:25,column:8},end:{line:25,column:53}},"20":{start:{line:27,column:4},end:{line:30,column:7}},"21":{start:{line:28,column:21},end:{line:28,column:46}},"22":{start:{line:29,column:8},end:{line:29,column:52}},"23":{start:{line:31,column:4},end:{line:35,column:7}},"24":{start:{line:32,column:20},end:{line:32,column:51}},"25":{start:{line:33,column:21},end:{line:33,column:41}},"26":{start:{line:34,column:8},end:{line:34,column:41}},"27":{start:{line:36,column:4},end:{line:44,column:7}},"28":{start:{line:45,column:4},end:{line:51,column:7}},"29":{start:{line:49,column:21},end:{line:49,column:69}},"30":{start:{line:50,column:8},end:{line:50,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17},"1":{name:"(anonymous_1)",decl:{start:{line:19,column:47},end:{line:19,column:48}},loc:{start:{line:19,column:59},end:{line:22,column:5}},line:19},"2":{name:"(anonymous_2)",decl:{start:{line:23,column:41},end:{line:23,column:42}},loc:{start:{line:23,column:53},end:{line:26,column:5}},line:23},"3":{name:"(anonymous_3)",decl:{start:{line:27,column:73},end:{line:27,column:74}},loc:{start:{line:27,column:85},end:{line:30,column:5}},line:27},"4":{name:"(anonymous_4)",decl:{start:{line:31,column:31},end:{line:31,column:32}},loc:{start:{line:31,column:43},end:{line:35,column:5}},line:31},"5":{name:"(anonymous_5)",decl:{start:{line:36,column:47},end:{line:36,column:48}},loc:{start:{line:36,column:59},end:{line:44,column:5}},line:36},"6":{name:"(anonymous_6)",decl:{start:{line:45,column:49},end:{line:45,column:50}},loc:{start:{line:45,column:61},end:{line:51,column:5}},line:45}},branchMap:{"0":{loc:{start:{line:33,column:21},end:{line:33,column:41}},type:"cond-expr",locations:[{start:{line:33,column:29},end:{line:33,column:33}},{start:{line:33,column:36},end:{line:33,column:41}}],line:33}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const clientBase_1=(cov_h9a3mwwe1.s[1]++,require("../clients/clientBase"));// import ChannelManager from '../channelManager'; +var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[5]++,require('ws'));var app=(cov_h9a3mwwe1.s[6]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[7]++,require('../server'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var url=(cov_h9a3mwwe1.s[9]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':'test channel'});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;// before ( function () { server.startServer; }); +it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;channel=server.channelManager.channelExists(name);cov_h9a3mwwe1.s[16]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[17]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[18]++,channel.addClient(client));cov_h9a3mwwe1.s[19]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[20]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[21]++,channel.addClient(client));cov_h9a3mwwe1.s[22]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[23]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[24]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[25]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[26]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[27]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[28]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[29]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[30]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.map b/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.map new file mode 100644 index 0000000..27fb62a --- /dev/null +++ b/node_modules/.cache/nyc/98bb0be42df66b4e58041dcd970325e0af7bfdf09cdea91c0148c3581965ff65.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AACA,sDAA+C;AAC/C,kDAAkD;AAElD,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,CAAA;AAC1H,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.js b/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.js new file mode 100644 index 0000000..5c3c826 --- /dev/null +++ b/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.js @@ -0,0 +1,10 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="20d5e4fea81dbe8546c57009f17d28862dc4c754";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:11},end:{line:10,column:25}},"9":{start:{line:11,column:15},end:{line:11,column:36}},"10":{start:{line:13,column:11},end:{line:13,column:108}},"11":{start:{line:14,column:13},end:{line:14,column:53}},"12":{start:{line:15,column:0},end:{line:46,column:3}},"13":{start:{line:16,column:4},end:{line:19,column:7}},"14":{start:{line:17,column:8},end:{line:17,column:50}},"15":{start:{line:18,column:8},end:{line:18,column:45}},"16":{start:{line:20,column:4},end:{line:23,column:7}},"17":{start:{line:21,column:21},end:{line:21,column:46}},"18":{start:{line:22,column:8},end:{line:22,column:53}},"19":{start:{line:24,column:4},end:{line:27,column:7}},"20":{start:{line:25,column:21},end:{line:25,column:46}},"21":{start:{line:26,column:8},end:{line:26,column:52}},"22":{start:{line:28,column:4},end:{line:32,column:7}},"23":{start:{line:29,column:20},end:{line:29,column:51}},"24":{start:{line:30,column:21},end:{line:30,column:41}},"25":{start:{line:31,column:8},end:{line:31,column:41}},"26":{start:{line:42,column:4},end:{line:45,column:7}},"27":{start:{line:43,column:21},end:{line:43,column:69}},"28":{start:{line:44,column:8},end:{line:44,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:46,column:1}},line:15},"1":{name:"(anonymous_1)",decl:{start:{line:16,column:47},end:{line:16,column:48}},loc:{start:{line:16,column:59},end:{line:19,column:5}},line:16},"2":{name:"(anonymous_2)",decl:{start:{line:20,column:41},end:{line:20,column:42}},loc:{start:{line:20,column:53},end:{line:23,column:5}},line:20},"3":{name:"(anonymous_3)",decl:{start:{line:24,column:73},end:{line:24,column:74}},loc:{start:{line:24,column:85},end:{line:27,column:5}},line:24},"4":{name:"(anonymous_4)",decl:{start:{line:28,column:31},end:{line:28,column:32}},loc:{start:{line:28,column:43},end:{line:32,column:5}},line:28},"5":{name:"(anonymous_5)",decl:{start:{line:42,column:49},end:{line:42,column:50}},loc:{start:{line:42,column:61},end:{line:45,column:5}},line:42}},branchMap:{"0":{loc:{start:{line:30,column:21},end:{line:30,column:41}},type:"cond-expr",locations:[{start:{line:30,column:29},end:{line:30,column:33}},{start:{line:30,column:36},end:{line:30,column:41}}],line:30}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocketClient());var channel;var data=(cov_h9a3mwwe1.s[10]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[11]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[12]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[13]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[14]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[15]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[16]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[17]++,channel.addClient(client));cov_h9a3mwwe1.s[18]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[19]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[22]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[23]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[24]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[25]++;expect(result).to.be.equal(true);});// it('should broadcast a message to others', function () { +// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.s[26]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[5]++;var result=(cov_h9a3mwwe1.s[27]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[28]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.map b/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.map new file mode 100644 index 0000000..dc745d3 --- /dev/null +++ b/node_modules/.cache/nyc/a38d5931a5dde4cbab172e39a233a1b58eabf0ae0d6b6381642375164f1b936d.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,2DAA2D;IAC3D,2CAA2C;IAC3C,gIAAgI;IAChI,uEAAuE;IACvE,+BAA+B;IAC/B,gCAAgC;IAChC,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;IAEN,EAAE,CAAC,wCAAwC,EAAE;QAC3C,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.js b/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.js new file mode 100644 index 0000000..9f2fec9 --- /dev/null +++ b/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.js @@ -0,0 +1,37 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="aba088e297b0691d8a9517b176dd843212448a27";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:11},end:{line:3,column:40}},"2":{start:{line:4,column:13},end:{line:4,column:35}},"3":{start:{line:5,column:12},end:{line:5,column:28}},"4":{start:{line:6,column:16},end:{line:6,column:29}},"5":{start:{line:7,column:10},end:{line:7,column:34}},"6":{start:{line:8,column:13},end:{line:8,column:33}},"7":{start:{line:9,column:11},end:{line:9,column:25}},"8":{start:{line:10,column:10},end:{line:10,column:356}},"9":{start:{line:11,column:15},end:{line:11,column:33}},"10":{start:{line:15,column:0},end:{line:50,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:50,column:1}},line:15}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[6]++,require('../server'));var name=(cov_h9a3mwwe1.s[7]++,'test channel');var url=(cov_h9a3mwwe1.s[8]++,`wss://${app.hostname}:${app.port}?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ`);var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocket(url));var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[10]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.map b/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.map new file mode 100644 index 0000000..d116ef9 --- /dev/null +++ b/node_modules/.cache/nyc/a6f1ae03feb38747dd889af72ef4000d0bd118c1a6e1e59e57bb8c2e27544e83.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAGA,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,yTAAyT,CAAC;AAC7W,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.js b/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.js new file mode 100644 index 0000000..08456ab --- /dev/null +++ b/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.js @@ -0,0 +1,39 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="fde0ff071e915a256f767c8c02c7e97f611961f9";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:18},end:{line:3,column:31}},"2":{start:{line:4,column:11},end:{line:4,column:40}},"3":{start:{line:5,column:13},end:{line:5,column:35}},"4":{start:{line:6,column:12},end:{line:6,column:28}},"5":{start:{line:8,column:10},end:{line:8,column:34}},"6":{start:{line:9,column:13},end:{line:9,column:33}},"7":{start:{line:10,column:11},end:{line:10,column:25}},"8":{start:{line:12,column:10},end:{line:12,column:367}},"9":{start:{line:13,column:15},end:{line:13,column:33}},"10":{start:{line:17,column:0},end:{line:52,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const WebSocket=(cov_h9a3mwwe1.s[1]++,require("ws"));var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));// var WebSocket = require('ws');s +var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[6]++,require('../server'));var name=(cov_h9a3mwwe1.s[7]++,'test channel');// var url: string = `wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6InRlc3QiLCJjbGllbnRfdHlwZSI6InNpdGUiLCJ1c2VyX3R5cGUiOiJ1c2VyIiwidXNlcl9pZCI6MjAwLCJjaGFubmVsIjoidGVzdF9jaGFubmVsIn0sImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5KNCov_EW1cycT4Ay0oSvk4Z4PHFedd3bWOyqkHHTBQ`; +var url=(cov_h9a3mwwe1.s[8]++,"wss://ysbraid.localhost:8443?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImNsaWVudCI6Im1ocyIsImNsaWVudF90eXBlIjoic2l0ZSIsInVzZXJfdHlwZSI6InVzZXIiLCJ1c2VyX2lkIjoxMjUsImNoYW5uZWwiOiJtaHNfMTIzOSJ9LCJleHAiOjE1NTI4NDYzOTQsImF1ZCI6ImludGVybmFsIiwiaXNzIjoiWWFyZHN0aWNrIFNvZnR3YXJlIiwic3ViIjoiQnJhaWQgSldUIn0.5a_s8rgln4rwhVqJLcSS9Uw7yw1_PmYgslWKZllgK6g");var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocket(url));var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[10]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.map b/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.map new file mode 100644 index 0000000..c5549dd --- /dev/null +++ b/node_modules/.cache/nyc/b67ff3a81790499e21af4474593fee750d6e06b7fe856aa05434635d74c6d6b6.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAEA,gCAAgC;AAEhC,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,kCAAkC;AAClC,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,2WAA2W;AAC3W,IAAI,GAAG,GAAW,qWAAqW,CAAC;AACxX,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.js b/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.js new file mode 100644 index 0000000..4300b69 --- /dev/null +++ b/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.js @@ -0,0 +1,11 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="f59ae60ef03c2a8437d9b72f36e7aef049ef085b";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:13},end:{line:10,column:33}},"9":{start:{line:11,column:11},end:{line:11,column:25}},"10":{start:{line:12,column:15},end:{line:12,column:36}},"11":{start:{line:14,column:11},end:{line:14,column:108}},"12":{start:{line:15,column:13},end:{line:15,column:53}},"13":{start:{line:16,column:0},end:{line:51,column:3}},"14":{start:{line:17,column:4},end:{line:17,column:50}},"15":{start:{line:17,column:25},end:{line:17,column:46}},"16":{start:{line:18,column:4},end:{line:21,column:7}},"17":{start:{line:19,column:8},end:{line:19,column:50}},"18":{start:{line:20,column:8},end:{line:20,column:45}},"19":{start:{line:22,column:4},end:{line:25,column:7}},"20":{start:{line:23,column:21},end:{line:23,column:46}},"21":{start:{line:24,column:8},end:{line:24,column:53}},"22":{start:{line:26,column:4},end:{line:29,column:7}},"23":{start:{line:27,column:21},end:{line:27,column:46}},"24":{start:{line:28,column:8},end:{line:28,column:52}},"25":{start:{line:30,column:4},end:{line:34,column:7}},"26":{start:{line:31,column:20},end:{line:31,column:51}},"27":{start:{line:32,column:21},end:{line:32,column:41}},"28":{start:{line:33,column:8},end:{line:33,column:41}},"29":{start:{line:35,column:4},end:{line:43,column:7}},"30":{start:{line:44,column:4},end:{line:50,column:7}},"31":{start:{line:48,column:21},end:{line:48,column:69}},"32":{start:{line:49,column:8},end:{line:49,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:16,column:24},end:{line:16,column:25}},loc:{start:{line:16,column:36},end:{line:51,column:1}},line:16},"1":{name:"(anonymous_1)",decl:{start:{line:17,column:11},end:{line:17,column:12}},loc:{start:{line:17,column:23},end:{line:17,column:48}},line:17},"2":{name:"(anonymous_2)",decl:{start:{line:18,column:47},end:{line:18,column:48}},loc:{start:{line:18,column:59},end:{line:21,column:5}},line:18},"3":{name:"(anonymous_3)",decl:{start:{line:22,column:41},end:{line:22,column:42}},loc:{start:{line:22,column:53},end:{line:25,column:5}},line:22},"4":{name:"(anonymous_4)",decl:{start:{line:26,column:73},end:{line:26,column:74}},loc:{start:{line:26,column:85},end:{line:29,column:5}},line:26},"5":{name:"(anonymous_5)",decl:{start:{line:30,column:31},end:{line:30,column:32}},loc:{start:{line:30,column:43},end:{line:34,column:5}},line:30},"6":{name:"(anonymous_6)",decl:{start:{line:35,column:47},end:{line:35,column:48}},loc:{start:{line:35,column:59},end:{line:43,column:5}},line:35},"7":{name:"(anonymous_7)",decl:{start:{line:44,column:49},end:{line:44,column:50}},loc:{start:{line:44,column:61},end:{line:50,column:5}},line:44}},branchMap:{"0":{loc:{start:{line:32,column:21},end:{line:32,column:41}},type:"cond-expr",locations:[{start:{line:32,column:29},end:{line:32,column:33}},{start:{line:32,column:36},end:{line:32,column:41}}],line:32}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[8]++,require('../server'));var name=(cov_h9a3mwwe1.s[9]++,'test channel');var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocketClient());var channel;var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;before(function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;server.startServer();});cov_h9a3mwwe1.s[16]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[2]++;cov_h9a3mwwe1.s[17]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[18]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[19]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[22]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[4]++;var result=(cov_h9a3mwwe1.s[23]++,channel.addClient(client));cov_h9a3mwwe1.s[24]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[25]++;it('should find a client',function(){cov_h9a3mwwe1.f[5]++;var exist=(cov_h9a3mwwe1.s[26]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[27]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[28]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[29]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[6]++;});cov_h9a3mwwe1.s[30]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[7]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[31]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[32]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.map b/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.map new file mode 100644 index 0000000..22c03d0 --- /dev/null +++ b/node_modules/.cache/nyc/bc808cb3addb5a5d9107c807b10272a916c592a420461fd4ec671f34671ffb9d.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,MAAM,CAAG,cAAc,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhD,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.js b/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.js new file mode 100644 index 0000000..473e412 --- /dev/null +++ b/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.js @@ -0,0 +1,8 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="52bdfd41bba5fc7905d2b0ef266903d99064d30f";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:11},end:{line:10,column:25}},"9":{start:{line:11,column:15},end:{line:11,column:36}},"10":{start:{line:13,column:11},end:{line:13,column:108}},"11":{start:{line:14,column:13},end:{line:14,column:53}},"12":{start:{line:15,column:0},end:{line:49,column:3}},"13":{start:{line:16,column:4},end:{line:19,column:7}},"14":{start:{line:17,column:8},end:{line:17,column:50}},"15":{start:{line:18,column:8},end:{line:18,column:45}},"16":{start:{line:20,column:4},end:{line:23,column:7}},"17":{start:{line:21,column:21},end:{line:21,column:46}},"18":{start:{line:22,column:8},end:{line:22,column:53}},"19":{start:{line:24,column:4},end:{line:27,column:7}},"20":{start:{line:25,column:21},end:{line:25,column:46}},"21":{start:{line:26,column:8},end:{line:26,column:52}},"22":{start:{line:28,column:4},end:{line:32,column:7}},"23":{start:{line:29,column:20},end:{line:29,column:51}},"24":{start:{line:30,column:21},end:{line:30,column:41}},"25":{start:{line:31,column:8},end:{line:31,column:41}},"26":{start:{line:33,column:4},end:{line:41,column:7}},"27":{start:{line:42,column:4},end:{line:48,column:7}},"28":{start:{line:43,column:31},end:{line:45,column:10}},"29":{start:{line:44,column:12},end:{line:44,column:27}},"30":{start:{line:46,column:21},end:{line:46,column:69}},"31":{start:{line:47,column:8},end:{line:47,column:51}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:49,column:1}},line:15},"1":{name:"(anonymous_1)",decl:{start:{line:16,column:47},end:{line:16,column:48}},loc:{start:{line:16,column:59},end:{line:19,column:5}},line:16},"2":{name:"(anonymous_2)",decl:{start:{line:20,column:41},end:{line:20,column:42}},loc:{start:{line:20,column:53},end:{line:23,column:5}},line:20},"3":{name:"(anonymous_3)",decl:{start:{line:24,column:73},end:{line:24,column:74}},loc:{start:{line:24,column:85},end:{line:27,column:5}},line:24},"4":{name:"(anonymous_4)",decl:{start:{line:28,column:31},end:{line:28,column:32}},loc:{start:{line:28,column:43},end:{line:32,column:5}},line:28},"5":{name:"(anonymous_5)",decl:{start:{line:33,column:47},end:{line:33,column:48}},loc:{start:{line:33,column:59},end:{line:41,column:5}},line:33},"6":{name:"(anonymous_6)",decl:{start:{line:42,column:49},end:{line:42,column:50}},loc:{start:{line:42,column:61},end:{line:48,column:5}},line:42},"7":{name:"(anonymous_7)",decl:{start:{line:43,column:81},end:{line:43,column:82}},loc:{start:{line:43,column:108},end:{line:45,column:9}},line:43}},branchMap:{"0":{loc:{start:{line:30,column:21},end:{line:30,column:41}},type:"cond-expr",locations:[{start:{line:30,column:29},end:{line:30,column:33}},{start:{line:30,column:36},end:{line:30,column:41}}],line:30}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocketClient());var channel;var data=(cov_h9a3mwwe1.s[10]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[11]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[12]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[13]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[14]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[15]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[16]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[17]++,channel.addClient(client));cov_h9a3mwwe1.s[18]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[19]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[22]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[23]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[24]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[25]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[26]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[27]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;var broadcastMessage=(cov_h9a3mwwe1.s[28]++,sinon.stub(channel,'broadcastMessage').callsFake(function(client,message){cov_h9a3mwwe1.f[7]++;cov_h9a3mwwe1.s[29]++;return message;}));var result=(cov_h9a3mwwe1.s[30]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[31]++;expect(result).to.be.equal('test message');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.map b/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.map new file mode 100644 index 0000000..670b61a --- /dev/null +++ b/node_modules/.cache/nyc/c89323b2bcdc1b21bf9c29de27452b98f1240bc1dfe93fcb0ce5768fe5afd128.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAEnC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,IAAI,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,SAAS,CAAC,UAAU,MAAuB,EAAE,OAAe;YACzH,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAA;QACF,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.js b/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.js new file mode 100644 index 0000000..12d0615 --- /dev/null +++ b/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.js @@ -0,0 +1,49 @@ +"use strict";// import ChannelBase from '../channels/channelBase'; +// import ClientBase from '../clients/clientBase'; +// import MHSClient from '../clients/sites/mhsClient'; +// import MHSChannel from '../channels/sites/mhsChannel'; +// import ChannelManager from '../channelManager'; +// var expect = require('chai').expect; +// var sinon = require('sinon'); +// var name: string = 'test channel'; +// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name } +// var WebSocketClient = require('websocket').client; +// var wsClient = new WebSocketClient(); +// var client: ClientBase = new ClientBase(data, wsClient); +// let channelManager = new ChannelManager(); +// describe('ChannelManager', function () { +// var channel: ChannelBase; +// it('should create a channel', function () { +// channel = channelManager.createChannel(data); +// expect(channel.id).to.be.equal(name); +// }); +// it('should return existing channel when attempting to create a channel', function () { +// channel = channelManager.createChannel(data); +// expect(channel.id).to.be.equal(name); +// }); +// it('should return a channel when searching if channel exists', function () { +// var exists = channelManager.channelExists(channel.id); +// var result = exists ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should not return a channel when serachingif channel exists', function () { +// var exists = channelManager.channelExists('no channel'); +// var result = exists ? true : false; +// expect(result).to.be.equal(false); +// }); +// it('should add a client to channel', function () { +// var result = channelManager.addClientToChannel(client, channel.id); +// expect(result.status).to.be.equal('success'); +// }); +// it('should not add a client to channel', function () { +// var result = channelManager.addClientToChannel(client, 'no channel'); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should create a channel of type MHSChannel', function () { +// var data2 = { 'channel': 'test channel 2', 'client': 'mhs', 'client_type':'site' }; +// var result = channelManager.createByChannelType(data2); +// expect(result.id).to.be.equal('test channel 2'); +// }); +// }); +//# sourceMappingURL=channelManager.spec.js.map +var cov_2ekv66b3zw=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelManager.spec.js";var hash="f222a0ce55557ab9204e7e683e44bdf3f4fa25dc";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelManager.spec.js",statementMap:{},fnMap:{},branchMap:{},s:{},f:{},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}(); \ No newline at end of file diff --git a/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.map b/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.map new file mode 100644 index 0000000..86f35b2 --- /dev/null +++ b/node_modules/.cache/nyc/cb9c465e48b9a9603626f4787839581dc423b7f4e43933e7ca4c8ec3c87446f7.map @@ -0,0 +1 @@ +{"version":3,"file":"channelManager.spec.js","sourceRoot":"","sources":["../../../src/test/channelManager.spec.ts"],"names":[],"mappings":";AAAA,qDAAqD;AACrD,kDAAkD;AAClD,sDAAsD;AACtD,yDAAyD;AACzD,kDAAkD;AAElD,uCAAuC;AACvC,gCAAgC;AAEhC,qCAAqC;AACrC,mHAAmH;AACnH,qDAAqD;AACrD,wCAAwC;AACxC,2DAA2D;AAE3D,6CAA6C;AAE7C,2CAA2C;AAC3C,8BAA8B;AAE9B,gDAAgD;AAChD,oDAAoD;AACpD,4CAA4C;AAC5C,QAAQ;AAER,2FAA2F;AAC3F,oDAAoD;AACpD,4CAA4C;AAC5C,QAAQ;AAER,iFAAiF;AACjF,6DAA6D;AAC7D,0CAA0C;AAC1C,wCAAwC;AACxC,QAAQ;AAER,oFAAoF;AACpF,+DAA+D;AAC/D,0CAA0C;AAC1C,yCAAyC;AACzC,QAAQ;AAER,uDAAuD;AACvD,0EAA0E;AAC1E,oDAAoD;AACpD,QAAQ;AAER,2DAA2D;AAC3D,4EAA4E;AAC5E,mDAAmD;AACnD,QAAQ;AAER,mEAAmE;AACnE,0FAA0F;AAC1F,8DAA8D;AAC9D,uDAAuD;AACvD,QAAQ;AACR,MAAM"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.js b/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.js new file mode 100644 index 0000000..a01c054 --- /dev/null +++ b/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.js @@ -0,0 +1,37 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="63ffcce8be98f330812dd9c1afd8ea3d74aa9946";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:21},end:{line:3,column:53}},"2":{start:{line:5,column:11},end:{line:5,column:40}},"3":{start:{line:6,column:13},end:{line:6,column:35}},"4":{start:{line:7,column:12},end:{line:7,column:28}},"5":{start:{line:8,column:16},end:{line:8,column:29}},"6":{start:{line:9,column:10},end:{line:9,column:34}},"7":{start:{line:11,column:11},end:{line:11,column:25}},"8":{start:{line:12,column:10},end:{line:12,column:67}},"9":{start:{line:13,column:15},end:{line:13,column:33}},"10":{start:{line:15,column:11},end:{line:15,column:118}},"11":{start:{line:16,column:13},end:{line:16,column:53}},"12":{start:{line:17,column:0},end:{line:52,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const clientBase_1=(cov_h9a3mwwe1.s[1]++,require("../clients/clientBase"));// import ChannelManager from '../channelManager'; +var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[5]++,require('ws'));var app=(cov_h9a3mwwe1.s[6]++,require('../config/app'));// var server = require('../server'); +var name=(cov_h9a3mwwe1.s[7]++,'test channel');var url=(cov_h9a3mwwe1.s[8]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[9]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[10]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':'test channel'});var client=(cov_h9a3mwwe1.s[11]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[12]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.map b/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.map new file mode 100644 index 0000000..91cbd05 --- /dev/null +++ b/node_modules/.cache/nyc/cbbca393669923fb6638463fe827e0e87582161ff944a8c33b095ed58e75095d.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AACA,sDAA+C;AAC/C,kDAAkD;AAElD,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,qCAAqC;AAErC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,CAAA;AAC1H,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.js b/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.js new file mode 100644 index 0000000..d30fc38 --- /dev/null +++ b/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.js @@ -0,0 +1 @@ +"use strict";var cov_168kex5smj=function(){var path="/Users/josh.burman/Projects/braid/dist/server/controllers/authController.js";var hash="9b244a5d65883cecf9b9d7f1e2724f50100deff5";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/controllers/authController.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:12},end:{line:3,column:35}},"2":{start:{line:4,column:10},end:{line:4,column:34}},"3":{start:{line:5,column:0},end:{line:12,column:2}},"4":{start:{line:7,column:20},end:{line:7,column:34}},"5":{start:{line:8,column:8},end:{line:10,column:11}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:6,column:18},end:{line:6,column:19}},loc:{start:{line:6,column:32},end:{line:11,column:5}},line:6}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_168kex5smj.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const jwt=(cov_168kex5smj.s[1]++,require("jsonwebtoken"));var app=(cov_168kex5smj.s[2]++,require('../config/app'));cov_168kex5smj.s[3]++;module.exports={confirmToken:(req,res)=>{cov_168kex5smj.f[0]++;var token=(cov_168kex5smj.s[4]++,req.body.token);cov_168kex5smj.s[5]++;res.json({response:JSON.stringify(jwt.verify(token,app.secret,app.signOptions))});}};//# sourceMappingURL=authController.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.map b/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.map new file mode 100644 index 0000000..5068ab2 --- /dev/null +++ b/node_modules/.cache/nyc/d69ff0818274f59567de43bb62d12caf4edb87f9aa02eeac9b59a111d8b07d66.map @@ -0,0 +1 @@ +{"version":3,"file":"authController.js","sourceRoot":"","sources":["../../../src/controllers/authController.ts"],"names":[],"mappings":";;AAAA,oCAAoC;AAEpC,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;AAElC,MAAM,CAAC,OAAO,GAAG;IACf,YAAY,EAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE;QACpC,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAA;QAC1B,GAAG,CAAC,IAAI,CAAC;YACP,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;SACzE,CAAC,CAAC;IACL,CAAC;CACF,CAAA"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.js b/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.js new file mode 100644 index 0000000..b0c8a3e --- /dev/null +++ b/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.js @@ -0,0 +1,13 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="423cf496207f090eadafa33d7df60ffadb5cfa8f";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:21},end:{line:3,column:53}},"2":{start:{line:5,column:11},end:{line:5,column:40}},"3":{start:{line:6,column:13},end:{line:6,column:35}},"4":{start:{line:7,column:12},end:{line:7,column:28}},"5":{start:{line:8,column:16},end:{line:8,column:29}},"6":{start:{line:9,column:10},end:{line:9,column:34}},"7":{start:{line:10,column:13},end:{line:10,column:33}},"8":{start:{line:11,column:11},end:{line:11,column:25}},"9":{start:{line:12,column:10},end:{line:12,column:67}},"10":{start:{line:13,column:15},end:{line:13,column:33}},"11":{start:{line:15,column:11},end:{line:15,column:108}},"12":{start:{line:16,column:13},end:{line:16,column:53}},"13":{start:{line:17,column:0},end:{line:52,column:3}},"14":{start:{line:19,column:4},end:{line:22,column:7}},"15":{start:{line:20,column:8},end:{line:20,column:60}},"16":{start:{line:21,column:8},end:{line:21,column:45}},"17":{start:{line:23,column:4},end:{line:26,column:7}},"18":{start:{line:24,column:21},end:{line:24,column:46}},"19":{start:{line:25,column:8},end:{line:25,column:53}},"20":{start:{line:27,column:4},end:{line:30,column:7}},"21":{start:{line:28,column:21},end:{line:28,column:46}},"22":{start:{line:29,column:8},end:{line:29,column:52}},"23":{start:{line:31,column:4},end:{line:35,column:7}},"24":{start:{line:32,column:20},end:{line:32,column:51}},"25":{start:{line:33,column:21},end:{line:33,column:41}},"26":{start:{line:34,column:8},end:{line:34,column:41}},"27":{start:{line:36,column:4},end:{line:44,column:7}},"28":{start:{line:45,column:4},end:{line:51,column:7}},"29":{start:{line:49,column:21},end:{line:49,column:69}},"30":{start:{line:50,column:8},end:{line:50,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:17,column:24},end:{line:17,column:25}},loc:{start:{line:17,column:36},end:{line:52,column:1}},line:17},"1":{name:"(anonymous_1)",decl:{start:{line:19,column:47},end:{line:19,column:48}},loc:{start:{line:19,column:59},end:{line:22,column:5}},line:19},"2":{name:"(anonymous_2)",decl:{start:{line:23,column:41},end:{line:23,column:42}},loc:{start:{line:23,column:53},end:{line:26,column:5}},line:23},"3":{name:"(anonymous_3)",decl:{start:{line:27,column:73},end:{line:27,column:74}},loc:{start:{line:27,column:85},end:{line:30,column:5}},line:27},"4":{name:"(anonymous_4)",decl:{start:{line:31,column:31},end:{line:31,column:32}},loc:{start:{line:31,column:43},end:{line:35,column:5}},line:31},"5":{name:"(anonymous_5)",decl:{start:{line:36,column:47},end:{line:36,column:48}},loc:{start:{line:36,column:59},end:{line:44,column:5}},line:36},"6":{name:"(anonymous_6)",decl:{start:{line:45,column:49},end:{line:45,column:50}},loc:{start:{line:45,column:61},end:{line:51,column:5}},line:45}},branchMap:{"0":{loc:{start:{line:33,column:21},end:{line:33,column:41}},type:"cond-expr",locations:[{start:{line:33,column:29},end:{line:33,column:33}},{start:{line:33,column:36},end:{line:33,column:41}}],line:33}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const clientBase_1=(cov_h9a3mwwe1.s[1]++,require("../clients/clientBase"));// import ChannelManager from '../channelManager'; +var exec=(cov_h9a3mwwe1.s[2]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[3]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[4]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[5]++,require('ws'));var app=(cov_h9a3mwwe1.s[6]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[7]++,require('../server'));var name=(cov_h9a3mwwe1.s[8]++,'test channel');var url=(cov_h9a3mwwe1.s[9]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocket(url));var channel;var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;// before ( function () { server.startServer; }); +it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;channel=server.channelManager.channelExists(name);cov_h9a3mwwe1.s[16]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[17]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[2]++;var result=(cov_h9a3mwwe1.s[18]++,channel.addClient(client));cov_h9a3mwwe1.s[19]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[20]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[21]++,channel.addClient(client));cov_h9a3mwwe1.s[22]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[23]++;it('should find a client',function(){cov_h9a3mwwe1.f[4]++;var exist=(cov_h9a3mwwe1.s[24]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[25]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[26]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[27]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[5]++;});cov_h9a3mwwe1.s[28]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[6]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[29]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[30]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.map b/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.map new file mode 100644 index 0000000..310ad10 --- /dev/null +++ b/node_modules/.cache/nyc/ec3a14285012fe0bb5684d6903ebbb4fc39d82447f61881a06efe1e3a1e52ff8.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AACA,sDAA+C;AAC/C,kDAAkD;AAElD,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.js b/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.js new file mode 100644 index 0000000..2c80a14 --- /dev/null +++ b/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.js @@ -0,0 +1,3 @@ +"use strict";var cov_2ayw7o7ftd=function(){var path="/Users/josh.burman/Projects/braid/dist/server/server.js";var hash="344dd786307be8555b144cc54cff114b32143a90";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/server.js",statementMap:{"0":{start:{line:2,column:16},end:{line:9,column:1}},"1":{start:{line:3,column:4},end:{line:8,column:7}},"2":{start:{line:4,column:36},end:{line:4,column:97}},"3":{start:{line:4,column:42},end:{line:4,column:70}},"4":{start:{line:4,column:85},end:{line:4,column:95}},"5":{start:{line:5,column:35},end:{line:5,column:100}},"6":{start:{line:5,column:41},end:{line:5,column:73}},"7":{start:{line:5,column:88},end:{line:5,column:98}},"8":{start:{line:6,column:32},end:{line:6,column:149}},"9":{start:{line:6,column:97},end:{line:6,column:119}},"10":{start:{line:7,column:8},end:{line:7,column:78}},"11":{start:{line:10,column:0},end:{line:10,column:62}},"12":{start:{line:12,column:16},end:{line:12,column:34}},"13":{start:{line:13,column:14},end:{line:13,column:30}},"14":{start:{line:14,column:18},end:{line:14,column:31}},"15":{start:{line:15,column:11},end:{line:15,column:24}},"16":{start:{line:16,column:12},end:{line:16,column:35}},"17":{start:{line:17,column:12},end:{line:17,column:26}},"18":{start:{line:19,column:13},end:{line:19,column:32}},"19":{start:{line:20,column:10},end:{line:20,column:33}},"20":{start:{line:21,column:13},end:{line:21,column:32}},"21":{start:{line:22,column:24},end:{line:22,column:50}},"22":{start:{line:23,column:25},end:{line:23,column:52}},"23":{start:{line:24,column:17},end:{line:24,column:57}},"24":{start:{line:25,column:18},end:{line:25,column:59}},"25":{start:{line:26,column:14},end:{line:26,column:76}},"26":{start:{line:27,column:20},end:{line:27,column:29}},"27":{start:{line:28,column:15},end:{line:28,column:55}},"28":{start:{line:29,column:12},end:{line:29,column:92}},"29":{start:{line:30,column:0},end:{line:30,column:32}},"30":{start:{line:31,column:0},end:{line:31,column:28}},"31":{start:{line:32,column:20},end:{line:32,column:49}},"32":{start:{line:33,column:21},end:{line:33,column:51}},"33":{start:{line:35,column:4},end:{line:54,column:7}},"34":{start:{line:36,column:19},end:{line:36,column:40}},"35":{start:{line:37,column:8},end:{line:37,column:67}},"36":{start:{line:38,column:8},end:{line:40,column:9}},"37":{start:{line:39,column:12},end:{line:39,column:47}},"38":{start:{line:41,column:8},end:{line:49,column:9}},"39":{start:{line:42,column:25},end:{line:42,column:62}},"40":{start:{line:43,column:12},end:{line:45,column:13}},"41":{start:{line:44,column:16},end:{line:44,column:44}},"42":{start:{line:48,column:25},end:{line:48,column:58}},"43":{start:{line:50,column:8},end:{line:52,column:9}},"44":{start:{line:51,column:12},end:{line:51,column:68}},"45":{start:{line:53,column:8},end:{line:53,column:105}},"46":{start:{line:55,column:4},end:{line:86,column:7}},"47":{start:{line:56,column:8},end:{line:85,column:11}},"48":{start:{line:58,column:12},end:{line:65,column:13}},"49":{start:{line:59,column:16},end:{line:59,column:48}},"50":{start:{line:62,column:16},end:{line:62,column:33}},"51":{start:{line:63,column:16},end:{line:63,column:63}},"52":{start:{line:64,column:16},end:{line:64,column:23}},"53":{start:{line:67,column:16},end:{line:80,column:19}},"54":{start:{line:68,column:31},end:{line:68,column:65}},"55":{start:{line:69,column:32},end:{line:69,column:100}},"56":{start:{line:70,column:35},end:{line:70,column:39}},"57":{start:{line:72,column:20},end:{line:79,column:23}},"58":{start:{line:73,column:24},end:{line:76,column:25}},"59":{start:{line:74,column:28},end:{line:74,column:45}},"60":{start:{line:75,column:28},end:{line:75,column:45}},"61":{start:{line:77,column:24},end:{line:77,column:57}},"62":{start:{line:78,column:24},end:{line:78,column:72}},"63":{start:{line:82,column:12},end:{line:84,column:15}},"64":{start:{line:83,column:16},end:{line:83,column:58}},"65":{start:{line:87,column:4},end:{line:90,column:7}},"66":{start:{line:88,column:8},end:{line:88,column:59}},"67":{start:{line:89,column:8},end:{line:89,column:69}},"68":{start:{line:92,column:0},end:{line:92,column:14}},"69":{start:{line:93,column:0},end:{line:97,column:2}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:2,column:44},end:{line:2,column:45}},loc:{start:{line:2,column:89},end:{line:9,column:1}},line:2},"1":{name:"(anonymous_1)",decl:{start:{line:3,column:36},end:{line:3,column:37}},loc:{start:{line:3,column:63},end:{line:8,column:5}},line:3},"2":{name:"fulfilled",decl:{start:{line:4,column:17},end:{line:4,column:26}},loc:{start:{line:4,column:34},end:{line:4,column:99}},line:4},"3":{name:"rejected",decl:{start:{line:5,column:17},end:{line:5,column:25}},loc:{start:{line:5,column:33},end:{line:5,column:102}},line:5},"4":{name:"step",decl:{start:{line:6,column:17},end:{line:6,column:21}},loc:{start:{line:6,column:30},end:{line:6,column:151}},line:6},"5":{name:"(anonymous_5)",decl:{start:{line:6,column:76},end:{line:6,column:77}},loc:{start:{line:6,column:95},end:{line:6,column:121}},line:6},"6":{name:"startServer",decl:{start:{line:34,column:9},end:{line:34,column:20}},loc:{start:{line:34,column:23},end:{line:91,column:1}},line:34},"7":{name:"(anonymous_7)",decl:{start:{line:35,column:25},end:{line:35,column:26}},loc:{start:{line:35,column:48},end:{line:54,column:5}},line:35},"8":{name:"upgrade",decl:{start:{line:55,column:34},end:{line:55,column:41}},loc:{start:{line:55,column:65},end:{line:86,column:5}},line:55},"9":{name:"(anonymous_9)",decl:{start:{line:56,column:47},end:{line:56,column:48}},loc:{start:{line:56,column:60},end:{line:85,column:9}},line:56},"10":{name:"verifyConnection",decl:{start:{line:66,column:21},end:{line:66,column:37}},loc:{start:{line:66,column:40},end:{line:81,column:13}},line:66},"11":{name:"(anonymous_11)",decl:{start:{line:67,column:35},end:{line:67,column:36}},loc:{start:{line:67,column:56},end:{line:80,column:17}},line:67},"12":{name:"(anonymous_12)",decl:{start:{line:72,column:67},end:{line:72,column:68}},loc:{start:{line:72,column:91},end:{line:79,column:21}},line:72},"13":{name:"done",decl:{start:{line:82,column:62},end:{line:82,column:66}},loc:{start:{line:82,column:71},end:{line:84,column:13}},line:82},"14":{name:"(anonymous_14)",decl:{start:{line:87,column:28},end:{line:87,column:29}},loc:{start:{line:87,column:34},end:{line:90,column:5}},line:87}},branchMap:{"0":{loc:{start:{line:2,column:16},end:{line:9,column:1}},type:"binary-expr",locations:[{start:{line:2,column:17},end:{line:2,column:21}},{start:{line:2,column:25},end:{line:2,column:39}},{start:{line:2,column:44},end:{line:9,column:1}}],line:2},"1":{loc:{start:{line:3,column:16},end:{line:3,column:34}},type:"binary-expr",locations:[{start:{line:3,column:16},end:{line:3,column:17}},{start:{line:3,column:22},end:{line:3,column:33}}],line:3},"2":{loc:{start:{line:6,column:32},end:{line:6,column:148}},type:"cond-expr",locations:[{start:{line:6,column:46},end:{line:6,column:67}},{start:{line:6,column:70},end:{line:6,column:148}}],line:6},"3":{loc:{start:{line:7,column:51},end:{line:7,column:67}},type:"binary-expr",locations:[{start:{line:7,column:51},end:{line:7,column:61}},{start:{line:7,column:65},end:{line:7,column:67}}],line:7},"4":{loc:{start:{line:38,column:8},end:{line:40,column:9}},type:"if",locations:[{start:{line:38,column:8},end:{line:40,column:9}},{start:{line:38,column:8},end:{line:40,column:9}}],line:38},"5":{loc:{start:{line:41,column:8},end:{line:49,column:9}},type:"if",locations:[{start:{line:41,column:8},end:{line:49,column:9}},{start:{line:41,column:8},end:{line:49,column:9}}],line:41},"6":{loc:{start:{line:43,column:12},end:{line:45,column:13}},type:"if",locations:[{start:{line:43,column:12},end:{line:45,column:13}},{start:{line:43,column:12},end:{line:45,column:13}}],line:43},"7":{loc:{start:{line:50,column:8},end:{line:52,column:9}},type:"if",locations:[{start:{line:50,column:8},end:{line:52,column:9}},{start:{line:50,column:8},end:{line:52,column:9}}],line:50},"8":{loc:{start:{line:69,column:32},end:{line:69,column:100}},type:"binary-expr",locations:[{start:{line:69,column:32},end:{line:69,column:42}},{start:{line:69,column:47},end:{line:69,column:99}}],line:69},"9":{loc:{start:{line:69,column:47},end:{line:69,column:99}},type:"cond-expr",locations:[{start:{line:69,column:82},end:{line:69,column:94}},{start:{line:69,column:97},end:{line:69,column:99}}],line:69},"10":{loc:{start:{line:73,column:24},end:{line:76,column:25}},type:"if",locations:[{start:{line:73,column:24},end:{line:76,column:25}},{start:{line:73,column:24},end:{line:76,column:25}}],line:73},"11":{loc:{start:{line:78,column:24},end:{line:78,column:71}},type:"cond-expr",locations:[{start:{line:78,column:35},end:{line:78,column:50}},{start:{line:78,column:53},end:{line:78,column:71}}],line:78}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},b:{"0":[0,0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();var __awaiter=(cov_2ayw7o7ftd.s[0]++,(cov_2ayw7o7ftd.b[0][0]++,this)&&(cov_2ayw7o7ftd.b[0][1]++,this.__awaiter)||(cov_2ayw7o7ftd.b[0][2]++,function(thisArg,_arguments,P,generator){cov_2ayw7o7ftd.f[0]++;cov_2ayw7o7ftd.s[1]++;return new((cov_2ayw7o7ftd.b[1][0]++,P)||(cov_2ayw7o7ftd.b[1][1]++,P=Promise))(function(resolve,reject){cov_2ayw7o7ftd.f[1]++;function fulfilled(value){cov_2ayw7o7ftd.f[2]++;cov_2ayw7o7ftd.s[2]++;try{cov_2ayw7o7ftd.s[3]++;step(generator.next(value));}catch(e){cov_2ayw7o7ftd.s[4]++;reject(e);}}function rejected(value){cov_2ayw7o7ftd.f[3]++;cov_2ayw7o7ftd.s[5]++;try{cov_2ayw7o7ftd.s[6]++;step(generator["throw"](value));}catch(e){cov_2ayw7o7ftd.s[7]++;reject(e);}}function step(result){cov_2ayw7o7ftd.f[4]++;cov_2ayw7o7ftd.s[8]++;result.done?(cov_2ayw7o7ftd.b[2][0]++,resolve(result.value)):(cov_2ayw7o7ftd.b[2][1]++,new P(function(resolve){cov_2ayw7o7ftd.f[5]++;cov_2ayw7o7ftd.s[9]++;resolve(result.value);}).then(fulfilled,rejected));}cov_2ayw7o7ftd.s[10]++;step((generator=generator.apply(thisArg,(cov_2ayw7o7ftd.b[3][0]++,_arguments)||(cov_2ayw7o7ftd.b[3][1]++,[]))).next());});}));cov_2ayw7o7ftd.s[11]++;Object.defineProperty(exports,"__esModule",{value:true});//external imports +const express=(cov_2ayw7o7ftd.s[12]++,require("express"));const https=(cov_2ayw7o7ftd.s[13]++,require("https"));const WebSocket=(cov_2ayw7o7ftd.s[14]++,require("ws"));const fs=(cov_2ayw7o7ftd.s[15]++,require("fs"));const jwt=(cov_2ayw7o7ftd.s[16]++,require("jsonwebtoken"));const url=(cov_2ayw7o7ftd.s[17]++,require("url"));//internal imports +var routes=(cov_2ayw7o7ftd.s[18]++,require('./routes'));var app=(cov_2ayw7o7ftd.s[19]++,require('./config/app'));var logger=(cov_2ayw7o7ftd.s[20]++,require('./logger'));const clientManager_1=(cov_2ayw7o7ftd.s[21]++,require("./clientManager"));const channelManager_1=(cov_2ayw7o7ftd.s[22]++,require("./channelManager"));var privateKey=(cov_2ayw7o7ftd.s[23]++,fs.readFileSync('certs/key.pem','utf8'));var certificate=(cov_2ayw7o7ftd.s[24]++,fs.readFileSync('certs/cert.pem','utf8'));var options=(cov_2ayw7o7ftd.s[25]++,{key:privateKey,cert:certificate,hostname:app.hostname});const application=(cov_2ayw7o7ftd.s[26]++,express());const server=(cov_2ayw7o7ftd.s[27]++,https.createServer(options,application));const wss=(cov_2ayw7o7ftd.s[28]++,new WebSocket.Server({noServer:true,maxPayload:250000,host:app.hostname}));cov_2ayw7o7ftd.s[29]++;application.use(express.json());cov_2ayw7o7ftd.s[30]++;application.use('',routes);let clientManager=(cov_2ayw7o7ftd.s[31]++,new clientManager_1.default());let channelManager=(cov_2ayw7o7ftd.s[32]++,new channelManager_1.default());function startServer(){cov_2ayw7o7ftd.f[6]++;cov_2ayw7o7ftd.s[33]++;wss.on('connection',(ws,request,args)=>{cov_2ayw7o7ftd.f[7]++;var data=(cov_2ayw7o7ftd.s[34]++,JSON.parse(args).data);cov_2ayw7o7ftd.s[35]++;logger.accessLog.info(`Client Connected: ${data.user_id}`);cov_2ayw7o7ftd.s[36]++;if(!channelManager.channelExists(data.channel)){cov_2ayw7o7ftd.b[4][0]++;cov_2ayw7o7ftd.s[37]++;channelManager.createChannel(data);}else{cov_2ayw7o7ftd.b[4][1]++;}cov_2ayw7o7ftd.s[38]++;if(clientManager.clientExists(data.user_id)){cov_2ayw7o7ftd.b[5][0]++;var client=(cov_2ayw7o7ftd.s[39]++,clientManager.getClient(data.user_id));cov_2ayw7o7ftd.s[40]++;if(client!=null){cov_2ayw7o7ftd.b[6][0]++;cov_2ayw7o7ftd.s[41]++;client.replaceWebSocket(ws);}else{cov_2ayw7o7ftd.b[6][1]++;}}else{cov_2ayw7o7ftd.b[5][1]++;var client=(cov_2ayw7o7ftd.s[42]++,clientManager.addClient(data,ws));}cov_2ayw7o7ftd.s[43]++;if(client!=null){cov_2ayw7o7ftd.b[7][0]++;cov_2ayw7o7ftd.s[44]++;channelManager.addClientToChannel(client,data.channel);}else{cov_2ayw7o7ftd.b[7][1]++;}cov_2ayw7o7ftd.s[45]++;ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!');});cov_2ayw7o7ftd.s[46]++;server.on('upgrade',function upgrade(request,socket,head){cov_2ayw7o7ftd.f[8]++;cov_2ayw7o7ftd.s[47]++;return __awaiter(this,void 0,void 0,function*(){cov_2ayw7o7ftd.f[9]++;let args;cov_2ayw7o7ftd.s[48]++;try{cov_2ayw7o7ftd.s[49]++;args=yield verifyConnection();}catch(e){cov_2ayw7o7ftd.s[50]++;socket.destroy();cov_2ayw7o7ftd.s[51]++;logger.accessLog.info('Connection Terminated');cov_2ayw7o7ftd.s[52]++;return;}function verifyConnection(){cov_2ayw7o7ftd.f[10]++;cov_2ayw7o7ftd.s[53]++;return new Promise((resolve,reject)=>{cov_2ayw7o7ftd.f[11]++;var data=(cov_2ayw7o7ftd.s[54]++,url.parse(request.url,true).query);var token=(cov_2ayw7o7ftd.s[55]++,(cov_2ayw7o7ftd.b[8][0]++,data.token)||(cov_2ayw7o7ftd.b[8][1]++,app.environment=='development'?(cov_2ayw7o7ftd.b[9][0]++,app.devToken):(cov_2ayw7o7ftd.b[9][1]++,'')));var accepted=(cov_2ayw7o7ftd.s[56]++,true);var result;cov_2ayw7o7ftd.s[57]++;jwt.verify(token,app.secret,app.signOptions,function(err,decoded){cov_2ayw7o7ftd.f[12]++;cov_2ayw7o7ftd.s[58]++;if(err){cov_2ayw7o7ftd.b[10][0]++;cov_2ayw7o7ftd.s[59]++;console.log(err);cov_2ayw7o7ftd.s[60]++;accepted=false;}else{cov_2ayw7o7ftd.b[10][1]++;}cov_2ayw7o7ftd.s[61]++;result=JSON.stringify(decoded);cov_2ayw7o7ftd.s[62]++;accepted?(cov_2ayw7o7ftd.b[11][0]++,resolve(result)):(cov_2ayw7o7ftd.b[11][1]++,reject('rejected'));});});}cov_2ayw7o7ftd.s[63]++;wss.handleUpgrade(request,socket,head,function done(ws){cov_2ayw7o7ftd.f[13]++;cov_2ayw7o7ftd.s[64]++;wss.emit('connection',ws,request,args);});});});cov_2ayw7o7ftd.s[65]++;server.listen(app.port,()=>{cov_2ayw7o7ftd.f[14]++;cov_2ayw7o7ftd.s[66]++;console.log(`Braid v${app.version} is running!\n`);cov_2ayw7o7ftd.s[67]++;logger.accessLog.info(`Braid v${app.version} is running!\n`);});}cov_2ayw7o7ftd.s[68]++;startServer();cov_2ayw7o7ftd.s[69]++;module.exports={startServer:startServer,clientManager:clientManager,channelManager:channelManager};//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.map b/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.map new file mode 100644 index 0000000..d751af8 --- /dev/null +++ b/node_modules/.cache/nyc/ed0c79906672e9bebfd0afe9af88ea0bf88307b9716f0729f7021233f92a8fea.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.js b/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.js new file mode 100644 index 0000000..5813029 --- /dev/null +++ b/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.js @@ -0,0 +1,3 @@ +"use strict";var cov_2ayw7o7ftd=function(){var path="/Users/josh.burman/Projects/braid/dist/server/server.js";var hash="c780d6fc120cad9e61f119927865ba970810d09e";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/server.js",statementMap:{"0":{start:{line:2,column:16},end:{line:9,column:1}},"1":{start:{line:3,column:4},end:{line:8,column:7}},"2":{start:{line:4,column:36},end:{line:4,column:97}},"3":{start:{line:4,column:42},end:{line:4,column:70}},"4":{start:{line:4,column:85},end:{line:4,column:95}},"5":{start:{line:5,column:35},end:{line:5,column:100}},"6":{start:{line:5,column:41},end:{line:5,column:73}},"7":{start:{line:5,column:88},end:{line:5,column:98}},"8":{start:{line:6,column:32},end:{line:6,column:149}},"9":{start:{line:6,column:97},end:{line:6,column:119}},"10":{start:{line:7,column:8},end:{line:7,column:78}},"11":{start:{line:10,column:0},end:{line:10,column:62}},"12":{start:{line:12,column:16},end:{line:12,column:34}},"13":{start:{line:13,column:14},end:{line:13,column:30}},"14":{start:{line:14,column:18},end:{line:14,column:31}},"15":{start:{line:15,column:11},end:{line:15,column:24}},"16":{start:{line:16,column:12},end:{line:16,column:35}},"17":{start:{line:17,column:12},end:{line:17,column:26}},"18":{start:{line:19,column:13},end:{line:19,column:32}},"19":{start:{line:20,column:10},end:{line:20,column:33}},"20":{start:{line:21,column:13},end:{line:21,column:32}},"21":{start:{line:22,column:24},end:{line:22,column:50}},"22":{start:{line:23,column:25},end:{line:23,column:52}},"23":{start:{line:24,column:17},end:{line:24,column:57}},"24":{start:{line:25,column:18},end:{line:25,column:59}},"25":{start:{line:26,column:14},end:{line:26,column:76}},"26":{start:{line:27,column:20},end:{line:27,column:29}},"27":{start:{line:28,column:15},end:{line:28,column:55}},"28":{start:{line:29,column:12},end:{line:29,column:92}},"29":{start:{line:30,column:0},end:{line:30,column:32}},"30":{start:{line:31,column:0},end:{line:31,column:28}},"31":{start:{line:32,column:20},end:{line:32,column:49}},"32":{start:{line:33,column:21},end:{line:33,column:51}},"33":{start:{line:35,column:4},end:{line:54,column:7}},"34":{start:{line:36,column:19},end:{line:36,column:40}},"35":{start:{line:37,column:8},end:{line:37,column:67}},"36":{start:{line:38,column:8},end:{line:40,column:9}},"37":{start:{line:39,column:12},end:{line:39,column:47}},"38":{start:{line:41,column:8},end:{line:49,column:9}},"39":{start:{line:42,column:25},end:{line:42,column:62}},"40":{start:{line:43,column:12},end:{line:45,column:13}},"41":{start:{line:44,column:16},end:{line:44,column:44}},"42":{start:{line:48,column:25},end:{line:48,column:58}},"43":{start:{line:50,column:8},end:{line:52,column:9}},"44":{start:{line:51,column:12},end:{line:51,column:68}},"45":{start:{line:53,column:8},end:{line:53,column:105}},"46":{start:{line:55,column:4},end:{line:86,column:7}},"47":{start:{line:56,column:8},end:{line:85,column:11}},"48":{start:{line:58,column:12},end:{line:65,column:13}},"49":{start:{line:59,column:16},end:{line:59,column:48}},"50":{start:{line:62,column:16},end:{line:62,column:33}},"51":{start:{line:63,column:16},end:{line:63,column:63}},"52":{start:{line:64,column:16},end:{line:64,column:23}},"53":{start:{line:67,column:16},end:{line:80,column:19}},"54":{start:{line:68,column:31},end:{line:68,column:65}},"55":{start:{line:69,column:32},end:{line:69,column:100}},"56":{start:{line:70,column:35},end:{line:70,column:39}},"57":{start:{line:72,column:20},end:{line:79,column:23}},"58":{start:{line:73,column:24},end:{line:76,column:25}},"59":{start:{line:74,column:28},end:{line:74,column:45}},"60":{start:{line:75,column:28},end:{line:75,column:45}},"61":{start:{line:77,column:24},end:{line:77,column:57}},"62":{start:{line:78,column:24},end:{line:78,column:72}},"63":{start:{line:82,column:12},end:{line:84,column:15}},"64":{start:{line:83,column:16},end:{line:83,column:58}},"65":{start:{line:87,column:4},end:{line:90,column:7}},"66":{start:{line:88,column:8},end:{line:88,column:59}},"67":{start:{line:89,column:8},end:{line:89,column:69}},"68":{start:{line:92,column:0},end:{line:92,column:14}},"69":{start:{line:93,column:0},end:{line:96,column:2}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:2,column:44},end:{line:2,column:45}},loc:{start:{line:2,column:89},end:{line:9,column:1}},line:2},"1":{name:"(anonymous_1)",decl:{start:{line:3,column:36},end:{line:3,column:37}},loc:{start:{line:3,column:63},end:{line:8,column:5}},line:3},"2":{name:"fulfilled",decl:{start:{line:4,column:17},end:{line:4,column:26}},loc:{start:{line:4,column:34},end:{line:4,column:99}},line:4},"3":{name:"rejected",decl:{start:{line:5,column:17},end:{line:5,column:25}},loc:{start:{line:5,column:33},end:{line:5,column:102}},line:5},"4":{name:"step",decl:{start:{line:6,column:17},end:{line:6,column:21}},loc:{start:{line:6,column:30},end:{line:6,column:151}},line:6},"5":{name:"(anonymous_5)",decl:{start:{line:6,column:76},end:{line:6,column:77}},loc:{start:{line:6,column:95},end:{line:6,column:121}},line:6},"6":{name:"startServer",decl:{start:{line:34,column:9},end:{line:34,column:20}},loc:{start:{line:34,column:23},end:{line:91,column:1}},line:34},"7":{name:"(anonymous_7)",decl:{start:{line:35,column:25},end:{line:35,column:26}},loc:{start:{line:35,column:48},end:{line:54,column:5}},line:35},"8":{name:"upgrade",decl:{start:{line:55,column:34},end:{line:55,column:41}},loc:{start:{line:55,column:65},end:{line:86,column:5}},line:55},"9":{name:"(anonymous_9)",decl:{start:{line:56,column:47},end:{line:56,column:48}},loc:{start:{line:56,column:60},end:{line:85,column:9}},line:56},"10":{name:"verifyConnection",decl:{start:{line:66,column:21},end:{line:66,column:37}},loc:{start:{line:66,column:40},end:{line:81,column:13}},line:66},"11":{name:"(anonymous_11)",decl:{start:{line:67,column:35},end:{line:67,column:36}},loc:{start:{line:67,column:56},end:{line:80,column:17}},line:67},"12":{name:"(anonymous_12)",decl:{start:{line:72,column:67},end:{line:72,column:68}},loc:{start:{line:72,column:91},end:{line:79,column:21}},line:72},"13":{name:"done",decl:{start:{line:82,column:62},end:{line:82,column:66}},loc:{start:{line:82,column:71},end:{line:84,column:13}},line:82},"14":{name:"(anonymous_14)",decl:{start:{line:87,column:28},end:{line:87,column:29}},loc:{start:{line:87,column:34},end:{line:90,column:5}},line:87}},branchMap:{"0":{loc:{start:{line:2,column:16},end:{line:9,column:1}},type:"binary-expr",locations:[{start:{line:2,column:17},end:{line:2,column:21}},{start:{line:2,column:25},end:{line:2,column:39}},{start:{line:2,column:44},end:{line:9,column:1}}],line:2},"1":{loc:{start:{line:3,column:16},end:{line:3,column:34}},type:"binary-expr",locations:[{start:{line:3,column:16},end:{line:3,column:17}},{start:{line:3,column:22},end:{line:3,column:33}}],line:3},"2":{loc:{start:{line:6,column:32},end:{line:6,column:148}},type:"cond-expr",locations:[{start:{line:6,column:46},end:{line:6,column:67}},{start:{line:6,column:70},end:{line:6,column:148}}],line:6},"3":{loc:{start:{line:7,column:51},end:{line:7,column:67}},type:"binary-expr",locations:[{start:{line:7,column:51},end:{line:7,column:61}},{start:{line:7,column:65},end:{line:7,column:67}}],line:7},"4":{loc:{start:{line:38,column:8},end:{line:40,column:9}},type:"if",locations:[{start:{line:38,column:8},end:{line:40,column:9}},{start:{line:38,column:8},end:{line:40,column:9}}],line:38},"5":{loc:{start:{line:41,column:8},end:{line:49,column:9}},type:"if",locations:[{start:{line:41,column:8},end:{line:49,column:9}},{start:{line:41,column:8},end:{line:49,column:9}}],line:41},"6":{loc:{start:{line:43,column:12},end:{line:45,column:13}},type:"if",locations:[{start:{line:43,column:12},end:{line:45,column:13}},{start:{line:43,column:12},end:{line:45,column:13}}],line:43},"7":{loc:{start:{line:50,column:8},end:{line:52,column:9}},type:"if",locations:[{start:{line:50,column:8},end:{line:52,column:9}},{start:{line:50,column:8},end:{line:52,column:9}}],line:50},"8":{loc:{start:{line:69,column:32},end:{line:69,column:100}},type:"binary-expr",locations:[{start:{line:69,column:32},end:{line:69,column:42}},{start:{line:69,column:47},end:{line:69,column:99}}],line:69},"9":{loc:{start:{line:69,column:47},end:{line:69,column:99}},type:"cond-expr",locations:[{start:{line:69,column:82},end:{line:69,column:94}},{start:{line:69,column:97},end:{line:69,column:99}}],line:69},"10":{loc:{start:{line:73,column:24},end:{line:76,column:25}},type:"if",locations:[{start:{line:73,column:24},end:{line:76,column:25}},{start:{line:73,column:24},end:{line:76,column:25}}],line:73},"11":{loc:{start:{line:78,column:24},end:{line:78,column:71}},type:"cond-expr",locations:[{start:{line:78,column:35},end:{line:78,column:50}},{start:{line:78,column:53},end:{line:78,column:71}}],line:78}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},b:{"0":[0,0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();var __awaiter=(cov_2ayw7o7ftd.s[0]++,(cov_2ayw7o7ftd.b[0][0]++,this)&&(cov_2ayw7o7ftd.b[0][1]++,this.__awaiter)||(cov_2ayw7o7ftd.b[0][2]++,function(thisArg,_arguments,P,generator){cov_2ayw7o7ftd.f[0]++;cov_2ayw7o7ftd.s[1]++;return new((cov_2ayw7o7ftd.b[1][0]++,P)||(cov_2ayw7o7ftd.b[1][1]++,P=Promise))(function(resolve,reject){cov_2ayw7o7ftd.f[1]++;function fulfilled(value){cov_2ayw7o7ftd.f[2]++;cov_2ayw7o7ftd.s[2]++;try{cov_2ayw7o7ftd.s[3]++;step(generator.next(value));}catch(e){cov_2ayw7o7ftd.s[4]++;reject(e);}}function rejected(value){cov_2ayw7o7ftd.f[3]++;cov_2ayw7o7ftd.s[5]++;try{cov_2ayw7o7ftd.s[6]++;step(generator["throw"](value));}catch(e){cov_2ayw7o7ftd.s[7]++;reject(e);}}function step(result){cov_2ayw7o7ftd.f[4]++;cov_2ayw7o7ftd.s[8]++;result.done?(cov_2ayw7o7ftd.b[2][0]++,resolve(result.value)):(cov_2ayw7o7ftd.b[2][1]++,new P(function(resolve){cov_2ayw7o7ftd.f[5]++;cov_2ayw7o7ftd.s[9]++;resolve(result.value);}).then(fulfilled,rejected));}cov_2ayw7o7ftd.s[10]++;step((generator=generator.apply(thisArg,(cov_2ayw7o7ftd.b[3][0]++,_arguments)||(cov_2ayw7o7ftd.b[3][1]++,[]))).next());});}));cov_2ayw7o7ftd.s[11]++;Object.defineProperty(exports,"__esModule",{value:true});//external imports +const express=(cov_2ayw7o7ftd.s[12]++,require("express"));const https=(cov_2ayw7o7ftd.s[13]++,require("https"));const WebSocket=(cov_2ayw7o7ftd.s[14]++,require("ws"));const fs=(cov_2ayw7o7ftd.s[15]++,require("fs"));const jwt=(cov_2ayw7o7ftd.s[16]++,require("jsonwebtoken"));const url=(cov_2ayw7o7ftd.s[17]++,require("url"));//internal imports +var routes=(cov_2ayw7o7ftd.s[18]++,require('./routes'));var app=(cov_2ayw7o7ftd.s[19]++,require('./config/app'));var logger=(cov_2ayw7o7ftd.s[20]++,require('./logger'));const clientManager_1=(cov_2ayw7o7ftd.s[21]++,require("./clientManager"));const channelManager_1=(cov_2ayw7o7ftd.s[22]++,require("./channelManager"));var privateKey=(cov_2ayw7o7ftd.s[23]++,fs.readFileSync('certs/key.pem','utf8'));var certificate=(cov_2ayw7o7ftd.s[24]++,fs.readFileSync('certs/cert.pem','utf8'));var options=(cov_2ayw7o7ftd.s[25]++,{key:privateKey,cert:certificate,hostname:app.hostname});const application=(cov_2ayw7o7ftd.s[26]++,express());const server=(cov_2ayw7o7ftd.s[27]++,https.createServer(options,application));const wss=(cov_2ayw7o7ftd.s[28]++,new WebSocket.Server({noServer:true,maxPayload:250000,host:app.hostname}));cov_2ayw7o7ftd.s[29]++;application.use(express.json());cov_2ayw7o7ftd.s[30]++;application.use('',routes);let clientManager=(cov_2ayw7o7ftd.s[31]++,new clientManager_1.default());let channelManager=(cov_2ayw7o7ftd.s[32]++,new channelManager_1.default());function startServer(){cov_2ayw7o7ftd.f[6]++;cov_2ayw7o7ftd.s[33]++;wss.on('connection',(ws,request,args)=>{cov_2ayw7o7ftd.f[7]++;var data=(cov_2ayw7o7ftd.s[34]++,JSON.parse(args).data);cov_2ayw7o7ftd.s[35]++;logger.accessLog.info(`Client Connected: ${data.user_id}`);cov_2ayw7o7ftd.s[36]++;if(!channelManager.channelExists(data.channel)){cov_2ayw7o7ftd.b[4][0]++;cov_2ayw7o7ftd.s[37]++;channelManager.createChannel(data);}else{cov_2ayw7o7ftd.b[4][1]++;}cov_2ayw7o7ftd.s[38]++;if(clientManager.clientExists(data.user_id)){cov_2ayw7o7ftd.b[5][0]++;var client=(cov_2ayw7o7ftd.s[39]++,clientManager.getClient(data.user_id));cov_2ayw7o7ftd.s[40]++;if(client!=null){cov_2ayw7o7ftd.b[6][0]++;cov_2ayw7o7ftd.s[41]++;client.replaceWebSocket(ws);}else{cov_2ayw7o7ftd.b[6][1]++;}}else{cov_2ayw7o7ftd.b[5][1]++;var client=(cov_2ayw7o7ftd.s[42]++,clientManager.addClient(data,ws));}cov_2ayw7o7ftd.s[43]++;if(client!=null){cov_2ayw7o7ftd.b[7][0]++;cov_2ayw7o7ftd.s[44]++;channelManager.addClientToChannel(client,data.channel);}else{cov_2ayw7o7ftd.b[7][1]++;}cov_2ayw7o7ftd.s[45]++;ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!');});cov_2ayw7o7ftd.s[46]++;server.on('upgrade',function upgrade(request,socket,head){cov_2ayw7o7ftd.f[8]++;cov_2ayw7o7ftd.s[47]++;return __awaiter(this,void 0,void 0,function*(){cov_2ayw7o7ftd.f[9]++;let args;cov_2ayw7o7ftd.s[48]++;try{cov_2ayw7o7ftd.s[49]++;args=yield verifyConnection();}catch(e){cov_2ayw7o7ftd.s[50]++;socket.destroy();cov_2ayw7o7ftd.s[51]++;logger.accessLog.info('Connection Terminated');cov_2ayw7o7ftd.s[52]++;return;}function verifyConnection(){cov_2ayw7o7ftd.f[10]++;cov_2ayw7o7ftd.s[53]++;return new Promise((resolve,reject)=>{cov_2ayw7o7ftd.f[11]++;var data=(cov_2ayw7o7ftd.s[54]++,url.parse(request.url,true).query);var token=(cov_2ayw7o7ftd.s[55]++,(cov_2ayw7o7ftd.b[8][0]++,data.token)||(cov_2ayw7o7ftd.b[8][1]++,app.environment=='development'?(cov_2ayw7o7ftd.b[9][0]++,app.devToken):(cov_2ayw7o7ftd.b[9][1]++,'')));var accepted=(cov_2ayw7o7ftd.s[56]++,true);var result;cov_2ayw7o7ftd.s[57]++;jwt.verify(token,app.secret,app.signOptions,function(err,decoded){cov_2ayw7o7ftd.f[12]++;cov_2ayw7o7ftd.s[58]++;if(err){cov_2ayw7o7ftd.b[10][0]++;cov_2ayw7o7ftd.s[59]++;console.log(err);cov_2ayw7o7ftd.s[60]++;accepted=false;}else{cov_2ayw7o7ftd.b[10][1]++;}cov_2ayw7o7ftd.s[61]++;result=JSON.stringify(decoded);cov_2ayw7o7ftd.s[62]++;accepted?(cov_2ayw7o7ftd.b[11][0]++,resolve(result)):(cov_2ayw7o7ftd.b[11][1]++,reject('rejected'));});});}cov_2ayw7o7ftd.s[63]++;wss.handleUpgrade(request,socket,head,function done(ws){cov_2ayw7o7ftd.f[13]++;cov_2ayw7o7ftd.s[64]++;wss.emit('connection',ws,request,args);});});});cov_2ayw7o7ftd.s[65]++;server.listen(app.port,()=>{cov_2ayw7o7ftd.f[14]++;cov_2ayw7o7ftd.s[66]++;console.log(`Braid v${app.version} is running!\n`);cov_2ayw7o7ftd.s[67]++;logger.accessLog.info(`Braid v${app.version} is running!\n`);});}cov_2ayw7o7ftd.s[68]++;startServer();cov_2ayw7o7ftd.s[69]++;module.exports={clientManager:clientManager,channelManager:channelManager};//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.map b/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.map new file mode 100644 index 0000000..74f0b77 --- /dev/null +++ b/node_modules/.cache/nyc/f18ce5b5ce259dd484a30d38695140ddab41575f0486b8b9ad1631188e28b6d1.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.js b/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.js new file mode 100644 index 0000000..4d07057 --- /dev/null +++ b/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.js @@ -0,0 +1,11 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="6f94883c1d55b0c4b92836fb1a08d4c411648968";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:22},end:{line:3,column:56}},"2":{start:{line:4,column:21},end:{line:4,column:53}},"3":{start:{line:5,column:11},end:{line:5,column:40}},"4":{start:{line:6,column:13},end:{line:6,column:35}},"5":{start:{line:7,column:12},end:{line:7,column:28}},"6":{start:{line:8,column:22},end:{line:8,column:49}},"7":{start:{line:9,column:10},end:{line:9,column:34}},"8":{start:{line:10,column:13},end:{line:10,column:33}},"9":{start:{line:11,column:11},end:{line:11,column:25}},"10":{start:{line:12,column:15},end:{line:12,column:36}},"11":{start:{line:14,column:11},end:{line:14,column:108}},"12":{start:{line:15,column:13},end:{line:15,column:53}},"13":{start:{line:16,column:0},end:{line:51,column:3}},"14":{start:{line:17,column:4},end:{line:17,column:48}},"15":{start:{line:17,column:25},end:{line:17,column:44}},"16":{start:{line:18,column:4},end:{line:21,column:7}},"17":{start:{line:19,column:8},end:{line:19,column:50}},"18":{start:{line:20,column:8},end:{line:20,column:45}},"19":{start:{line:22,column:4},end:{line:25,column:7}},"20":{start:{line:23,column:21},end:{line:23,column:46}},"21":{start:{line:24,column:8},end:{line:24,column:53}},"22":{start:{line:26,column:4},end:{line:29,column:7}},"23":{start:{line:27,column:21},end:{line:27,column:46}},"24":{start:{line:28,column:8},end:{line:28,column:52}},"25":{start:{line:30,column:4},end:{line:34,column:7}},"26":{start:{line:31,column:20},end:{line:31,column:51}},"27":{start:{line:32,column:21},end:{line:32,column:41}},"28":{start:{line:33,column:8},end:{line:33,column:41}},"29":{start:{line:35,column:4},end:{line:43,column:7}},"30":{start:{line:44,column:4},end:{line:50,column:7}},"31":{start:{line:48,column:21},end:{line:48,column:69}},"32":{start:{line:49,column:8},end:{line:49,column:53}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:16,column:24},end:{line:16,column:25}},loc:{start:{line:16,column:36},end:{line:51,column:1}},line:16},"1":{name:"(anonymous_1)",decl:{start:{line:17,column:11},end:{line:17,column:12}},loc:{start:{line:17,column:23},end:{line:17,column:46}},line:17},"2":{name:"(anonymous_2)",decl:{start:{line:18,column:47},end:{line:18,column:48}},loc:{start:{line:18,column:59},end:{line:21,column:5}},line:18},"3":{name:"(anonymous_3)",decl:{start:{line:22,column:41},end:{line:22,column:42}},loc:{start:{line:22,column:53},end:{line:25,column:5}},line:22},"4":{name:"(anonymous_4)",decl:{start:{line:26,column:73},end:{line:26,column:74}},loc:{start:{line:26,column:85},end:{line:29,column:5}},line:26},"5":{name:"(anonymous_5)",decl:{start:{line:30,column:31},end:{line:30,column:32}},loc:{start:{line:30,column:43},end:{line:34,column:5}},line:30},"6":{name:"(anonymous_6)",decl:{start:{line:35,column:47},end:{line:35,column:48}},loc:{start:{line:35,column:59},end:{line:43,column:5}},line:35},"7":{name:"(anonymous_7)",decl:{start:{line:44,column:49},end:{line:44,column:50}},loc:{start:{line:44,column:61},end:{line:50,column:5}},line:44}},branchMap:{"0":{loc:{start:{line:32,column:21},end:{line:32,column:41}},type:"cond-expr",locations:[{start:{line:32,column:29},end:{line:32,column:33}},{start:{line:32,column:36},end:{line:32,column:41}}],line:32}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0},f:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},b:{"0":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});const channelBase_1=(cov_h9a3mwwe1.s[1]++,require("../channels/channelBase"));const clientBase_1=(cov_h9a3mwwe1.s[2]++,require("../clients/clientBase"));var exec=(cov_h9a3mwwe1.s[3]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[4]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[5]++,require('sinon'));var WebSocketClient=(cov_h9a3mwwe1.s[6]++,require('websocket').client);var app=(cov_h9a3mwwe1.s[7]++,require('../config/app'));var server=(cov_h9a3mwwe1.s[8]++,require('../server'));var name=(cov_h9a3mwwe1.s[9]++,'test channel');var wsClient=(cov_h9a3mwwe1.s[10]++,new WebSocketClient());var channel;var data=(cov_h9a3mwwe1.s[11]++,{'client':'test','client_type':'site','user_id':125,'user_type':'user','channel':name});var client=(cov_h9a3mwwe1.s[12]++,new clientBase_1.default(data,wsClient));cov_h9a3mwwe1.s[13]++;describe('ChannelBase',function(){cov_h9a3mwwe1.f[0]++;cov_h9a3mwwe1.s[14]++;before(function(){cov_h9a3mwwe1.f[1]++;cov_h9a3mwwe1.s[15]++;server.startServer;});cov_h9a3mwwe1.s[16]++;it('should create a class of ChannelBase',function(){cov_h9a3mwwe1.f[2]++;cov_h9a3mwwe1.s[17]++;channel=new channelBase_1.default(name);cov_h9a3mwwe1.s[18]++;expect(channel.id).to.be.equal(name);});cov_h9a3mwwe1.s[19]++;it('should add a client to channel',function(){cov_h9a3mwwe1.f[3]++;var result=(cov_h9a3mwwe1.s[20]++,channel.addClient(client));cov_h9a3mwwe1.s[21]++;expect(result.status).to.be.equal('success');});cov_h9a3mwwe1.s[22]++;it('should find a client when trying to add said client to channel',function(){cov_h9a3mwwe1.f[4]++;var result=(cov_h9a3mwwe1.s[23]++,channel.addClient(client));cov_h9a3mwwe1.s[24]++;expect(result.status).to.be.equal('notice');});cov_h9a3mwwe1.s[25]++;it('should find a client',function(){cov_h9a3mwwe1.f[5]++;var exist=(cov_h9a3mwwe1.s[26]++,channel.clientExists(client.id));var result=(cov_h9a3mwwe1.s[27]++,exist?(cov_h9a3mwwe1.b[0][0]++,true):(cov_h9a3mwwe1.b[0][1]++,false));cov_h9a3mwwe1.s[28]++;expect(result).to.be.equal(true);});cov_h9a3mwwe1.s[29]++;it('should broadcast a message to others',function(){// var wstClient = new WebSocketClient(); +// var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// channel.addClient(client); +// channel.addClient(teacher); +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +cov_h9a3mwwe1.f[6]++;});cov_h9a3mwwe1.s[30]++;it('should not broadcast a message to self',function(){cov_h9a3mwwe1.f[7]++;// var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// return message; +// }) +var result=(cov_h9a3mwwe1.s[31]++,channel.broadcastMessage(client,'test message'));cov_h9a3mwwe1.s[32]++;expect(result.status).to.be.equal('success');});});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.map b/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.map new file mode 100644 index 0000000..5191036 --- /dev/null +++ b/node_modules/.cache/nyc/f48f2a9409b14ee0bc24273c5a256727293c319a8fe2e8c442e7e4b14aabf780.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAAA,yDAAkD;AAClD,sDAA+C;AAE/C,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;AAClD,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;AACrC,IAAI,OAAoB,CAAC;AACzB,IAAI,IAAI,GAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAChH,IAAI,MAAM,GAAe,IAAI,oBAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,QAAQ,CAAC,aAAa,EAAE;IACtB,MAAM,CAAG,cAAc,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9C,EAAE,CAAC,sCAAsC,EAAE;QACzC,OAAO,GAAG,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE;QACnC,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAI,MAAM,GAAQ,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,IAAI,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE;QACzC,yCAAyC;QACzC,8HAA8H;QAC9H,qEAAqE;QACrE,6BAA6B;QAC7B,8BAA8B;QAC9B,iEAAiE;QACjE,gDAAgD;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;QAC3C,iIAAiI;QACjI,oBAAoB;QACpB,KAAK;QACL,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.js b/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.js new file mode 100644 index 0000000..2f93695 --- /dev/null +++ b/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.js @@ -0,0 +1,38 @@ +"use strict";var cov_h9a3mwwe1=function(){var path="/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js";var hash="d1bcf0cdba10b9c476b1df1c9aa192473a158583";var Function=function(){}.constructor;var global=new Function("return this")();var gcv="__coverage__";var coverageData={path:"/Users/josh.burman/Projects/braid/dist/server/test/channelBase.spec.js",statementMap:{"0":{start:{line:2,column:0},end:{line:2,column:62}},"1":{start:{line:3,column:11},end:{line:3,column:40}},"2":{start:{line:4,column:13},end:{line:4,column:35}},"3":{start:{line:5,column:12},end:{line:5,column:28}},"4":{start:{line:6,column:16},end:{line:6,column:29}},"5":{start:{line:7,column:10},end:{line:7,column:34}},"6":{start:{line:9,column:11},end:{line:9,column:25}},"7":{start:{line:10,column:10},end:{line:10,column:67}},"8":{start:{line:11,column:15},end:{line:11,column:33}},"9":{start:{line:15,column:0},end:{line:50,column:3}}},fnMap:{"0":{name:"(anonymous_0)",decl:{start:{line:15,column:24},end:{line:15,column:25}},loc:{start:{line:15,column:36},end:{line:50,column:1}},line:15}},branchMap:{},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0},f:{"0":0},b:{},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}coverageData.hash=hash;return coverage[path]=coverageData;}();cov_h9a3mwwe1.s[0]++;Object.defineProperty(exports,"__esModule",{value:true});var exec=(cov_h9a3mwwe1.s[1]++,require('child_process').exec);var expect=(cov_h9a3mwwe1.s[2]++,require('chai').expect);var sinon=(cov_h9a3mwwe1.s[3]++,require('sinon'));var WebSocket=(cov_h9a3mwwe1.s[4]++,require('ws'));var app=(cov_h9a3mwwe1.s[5]++,require('../config/app'));// var server = require('../server'); +var name=(cov_h9a3mwwe1.s[6]++,'test channel');var url=(cov_h9a3mwwe1.s[7]++,`wss://${app.hostname}:${app.port}?token=${app.devToken}`);var wsClient=(cov_h9a3mwwe1.s[8]++,new WebSocket(url));var channel;// var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': 'test channel' } +// var client: ClientBase = new ClientBase(data, wsClient); +cov_h9a3mwwe1.s[9]++;describe('ChannelBase',function(){// before ( function () { server.startServer; }); +// it('should create a class of ChannelBase', function () { +// channel = server.channelManager.channelExists(name); +// expect(channel.id).to.be.equal(name); +// }); +// it('should add a client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('success'); +// }); +// it('should find a client when trying to add said client to channel', function () { +// var result: any = channel.addClient(client); +// expect(result.status).to.be.equal('notice'); +// }); +// it('should find a client', function () { +// var exist = channel.clientExists(client.id); +// var result = exist ? true : false; +// expect(result).to.be.equal(true); +// }); +// it('should broadcast a message to others', function () { +// // var wstClient = new WebSocketClient(); +// // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } +// // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); +// // channel.addClient(client); +// // channel.addClient(teacher); +// // var result = channel.broadcastMessage(client, 'test message'); +// // expect(result.status).to.be.equal('success'); +// }); +// it('should not broadcast a message to self', function () { +// // var broadcastMessage = sinon.stub(channel, 'broadcastMessage').callsFake(function (client: ClientBase|null, message: string) { +// // return message; +// // }) +// var result = channel.broadcastMessage(client, 'test message'); +// expect(result.status).to.be.equal('success'); +// }); +cov_h9a3mwwe1.f[0]++;});//# sourceMappingURL=channelBase.spec.js.map \ No newline at end of file diff --git a/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.map b/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.map new file mode 100644 index 0000000..7d8eeea --- /dev/null +++ b/node_modules/.cache/nyc/f741072c8ce0d49a827b8f7c8e8ebe623fade57a9408c8f31121f7003ef7449c.map @@ -0,0 +1 @@ +{"version":3,"file":"channelBase.spec.js","sourceRoot":"","sources":["../../../src/test/channelBase.spec.ts"],"names":[],"mappings":";;AAGA,IAAI,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;AACzC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACpC,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AACnC,qCAAqC;AAErC,IAAI,IAAI,GAAW,cAAc,CAAC;AAClC,IAAI,GAAG,GAAW,SAAS,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC5E,IAAI,QAAQ,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,IAAI,OAAoB,CAAC;AACzB,6HAA6H;AAC7H,2DAA2D;AAE3D,QAAQ,CAAC,aAAa,EAAE;IACtB,iDAAiD;IAEjD,2DAA2D;IAC3D,yDAAyD;IACzD,0CAA0C;IAC1C,MAAM;IAEN,qDAAqD;IACrD,iDAAiD;IACjD,kDAAkD;IAClD,MAAM;IAEN,qFAAqF;IACrF,iDAAiD;IACjD,iDAAiD;IACjD,MAAM;IAEN,2CAA2C;IAC3C,iDAAiD;IACjD,uCAAuC;IACvC,sCAAsC;IACtC,MAAM;IAEN,2DAA2D;IAC3D,8CAA8C;IAC9C,mIAAmI;IACnI,0EAA0E;IAC1E,kCAAkC;IAClC,mCAAmC;IACnC,sEAAsE;IACtE,qDAAqD;IACrD,MAAM;IAEN,6DAA6D;IAC7D,sIAAsI;IACtI,yBAAyB;IACzB,UAAU;IACV,mEAAmE;IACnE,kDAAkD;IAClD,MAAM;AACR,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/mock-socket/LICENSE.txt b/node_modules/mock-socket/LICENSE.txt new file mode 100644 index 0000000..a9d44c5 --- /dev/null +++ b/node_modules/mock-socket/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Travis Hoover + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/mock-socket/README.md b/node_modules/mock-socket/README.md new file mode 100644 index 0000000..f9610f9 --- /dev/null +++ b/node_modules/mock-socket/README.md @@ -0,0 +1,232 @@ +

+ +

+ +

+Javascript mocking library for websockets and socket.io +

+ +

+ + Build Status + + + Code Coverage + + + NPM Version + +

+ +## Contents + +- [Installation](#installation) +- [Basic Usage](#usage) +- [Advanced Usage](#advanced-usage) +- [Typescript Support](#typescript-support) +- [Socket.IO](#socket-io) +- [Contributing](#contributing) +- [Feedback](#feedback) + +## Installation + +```shell +npm install mock-socket +``` + +```js +import { WebSocket, Server } from 'mock-socket'; +``` + +## Usage + +```js +import test from 'ava'; +import { Server } from 'mock-socket'; + +class ChatApp { + constructor(url) { + this.messages = []; + this.connection = new WebSocket(url); + + this.connection.onmessage = (event) => { + this.messages.push(event.data); + }; + } + + sendMessage(message) { + this.connection.send(message); + } +} + +test.cb('that chat app can be mocked', t => { + const fakeURL = 'ws://localhost:8080'; + const mockServer = new Server(fakeURL); + + mockServer.on('connection', socket => { + socket.on('message', data => { + t.is(data, 'test message from app', 'we have intercepted the message and can assert on it'); + socket.send('test message from mock server'); + }); + }); + + const app = new ChatApp(fakeURL); + app.sendMessage('test message from app'); // NOTE: this line creates a micro task + + // NOTE: this timeout is for creating another micro task that will happen after the above one + setTimeout(() => { + t.is(app.messages.length, 1); + t.is(app.messages[0], 'test message from mock server', 'we have subbed our websocket backend'); + mockServer.stop(t.done); + }, 100); +}); +``` + +## Advanced Usage + +### Stubbing the "global" + +```js +import { WebSocket, Server } from 'mock-socket'; + +/* + * By default the global WebSocket object is stubbed out. However, + * if you need to stub something else out you can like so: + */ + +window.WebSocket = WebSocket; // Here we stub out the window object +``` + +### Server Methods + +```js +const mockServer = new Server('ws://localhost:8080'); + +mockServer.on('connection', socket => { + socket.on('message', () => {}); + socket.on('close', () => {}); + + socket.send('message'); + socket.close(); +}); + +mockServer.clients() // array of all connected clients +mockServer.emit('room', 'message'); +mockServer.stop(optionalCallback); +``` +## Typescript Support + +A [declaration file](https://github.com/thoov/mock-socket/blob/master/index.d.ts) is included by default. If you notice any issues with the types please create an issue or a PR! + +## Socket IO + +[Socket.IO](https://socket.io/) has **limited support**. Below is a similar example to the one above but modified to show off socket.io support. + +```js +import test from 'ava'; +import { SocketIO, Server } from 'mock-socket'; + +class ChatApp { + constructor(url) { + this.messages = []; + this.connection = new io(url); + + this.connection.on('chat-message', data => { + this.messages.push(event.data); + }; + } + + sendMessage(message) { + this.connection.emit('chat-message', message); + } +} + +test.cb('that socket.io works', t => { + const fakeURL = 'ws://localhost:8080'; + const mockServer = new Server(fakeURL); + + window.io = SocketIO; + + mockServer.on('connection', socket => { + socket.on('chat-message', data => { + t.is(data, 'test message from app', 'we have intercepted the message and can assert on it'); + socket.emit('chat-message', 'test message from mock server'); + }); + }); + + const app = new ChatApp(fakeURL); + app.sendMessage('test message from app'); + + setTimeout(() => { + t.is(app.messages.length, 1); + t.is(app.messages[0], 'test message from mock server', 'we have subbed our websocket backend'); + + mockServer.stop(t.done); + }, 100); +}); +``` + +## Contributing + +The easiest way to work on the project is to clone the repo down via: + +```shell +git clone git@github.com:thoov/mock-socket.git +cd mock-socket +yarn install +``` + +Then to create a local build via: + +```shell +yarn build +``` + +Then create a local npm link via: + +```shell +yarn link +``` + +At this point you can create other projects / apps locally and reference this local build via: + +```shell +yarn link mock-socket +``` + +from within your other projects folder. Make sure that after any changes you run `yarn build`! + +### Tests +This project uses [ava.js](https://github.com/avajs/ava) as its test framework. Tests are located in /tests. To run tests: + +```shell +yarn test +``` + +### Linting + +This project uses eslint and a rules set from [airbnb's javascript style guides](https://github.com/airbnb/javascript). To run linting: + +```shell +yarn lint +``` + +### Formatting + +This project uses [prettier](https://github.com/prettier/prettier). To run the formatting: + +```shell +yarn format +``` + +### Code Coverage + +Code coverage reports are created in /coverage after all of the tests have successfully passed. To run the coverage: + +```shell +yarn test:coverage +``` + +## Feedback + +If you have any feedback, encounter any bugs, or just have a question, please feel free to create a [github issue](https://github.com/thoov/mock-socket/issues/new) or send me a tweet at [@thoov](https://twitter.com/thoov). diff --git a/node_modules/mock-socket/dist/mock-socket.amd.js b/node_modules/mock-socket/dist/mock-socket.amd.js new file mode 100644 index 0000000..b5e76c9 --- /dev/null +++ b/node_modules/mock-socket/dist/mock-socket.amd.js @@ -0,0 +1,1928 @@ +define(['exports'], function (exports) { 'use strict'; + +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +var requiresPort = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) { return false; } + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; + +var has = Object.prototype.hasOwnProperty; + +/** + * Decode a URI encoded string. + * + * @param {String} input The URI encoded string. + * @returns {String} The decoded string. + * @api private + */ +function decode(input) { + return decodeURIComponent(input.replace(/\+/g, ' ')); +} + +/** + * Simple query string parser. + * + * @param {String} query The query string that needs to be parsed. + * @returns {Object} + * @api public + */ +function querystring(query) { + var parser = /([^=?&]+)=?([^&]*)/g + , result = {} + , part; + + while (part = parser.exec(query)) { + var key = decode(part[1]) + , value = decode(part[2]); + + // + // Prevent overriding of existing properties. This ensures that build-in + // methods like `toString` or __proto__ are not overriden by malicious + // querystrings. + // + if (key in result) { continue; } + result[key] = value; + } + + return result; +} + +/** + * Transform a query string to an object. + * + * @param {Object} obj Object that should be transformed. + * @param {String} prefix Optional prefix. + * @returns {String} + * @api public + */ +function querystringify(obj, prefix) { + prefix = prefix || ''; + + var pairs = []; + + // + // Optionally prefix with a '?' if needed + // + if ('string' !== typeof prefix) { prefix = '?'; } + + for (var key in obj) { + if (has.call(obj, key)) { + pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key])); + } + } + + return pairs.length ? prefix + pairs.join('&') : ''; +} + +// +// Expose the module. +// +var stringify = querystringify; +var parse = querystring; + +var querystringify_1 = { + stringify: stringify, + parse: parse +}; + +var protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; +var slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//; + +/** + * These are the parse rules for the URL parser, it informs the parser + * about: + * + * 0. The char it Needs to parse, if it's a string it should be done using + * indexOf, RegExp using exec and NaN means set as current value. + * 1. The property we should set when parsing this value. + * 2. Indication if it's backwards or forward parsing, when set as number it's + * the value of extra chars that should be split off. + * 3. Inherit from location if non existing in the parser. + * 4. `toLowerCase` the resulting value. + */ +var rules = [ + ['#', 'hash'], // Extract from the back. + ['?', 'query'], // Extract from the back. + ['/', 'pathname'], // Extract from the back. + ['@', 'auth', 1], // Extract from the front. + [NaN, 'host', undefined, 1, 1], // Set left over value. + [/:(\d+)$/, 'port', undefined, 1], // RegExp the back. + [NaN, 'hostname', undefined, 1, 1] // Set left over. +]; + +/** + * These properties should not be copied or inherited from. This is only needed + * for all non blob URL's as a blob URL does not include a hash, only the + * origin. + * + * @type {Object} + * @private + */ +var ignore = { hash: 1, query: 1 }; + +/** + * The location object differs when your code is loaded through a normal page, + * Worker or through a worker using a blob. And with the blobble begins the + * trouble as the location object will contain the URL of the blob, not the + * location of the page where our code is loaded in. The actual origin is + * encoded in the `pathname` so we can thankfully generate a good "default" + * location from it so we can generate proper relative URL's again. + * + * @param {Object|String} loc Optional default location object. + * @returns {Object} lolcation object. + * @api public + */ +function lolcation(loc) { + var location = commonjsGlobal && commonjsGlobal.location || {}; + loc = loc || location; + + var finaldestination = {} + , type = typeof loc + , key; + + if ('blob:' === loc.protocol) { + finaldestination = new URL(unescape(loc.pathname), {}); + } else if ('string' === type) { + finaldestination = new URL(loc, {}); + for (key in ignore) { delete finaldestination[key]; } + } else if ('object' === type) { + for (key in loc) { + if (key in ignore) { continue; } + finaldestination[key] = loc[key]; + } + + if (finaldestination.slashes === undefined) { + finaldestination.slashes = slashes.test(loc.href); + } + } + + return finaldestination; +} + +/** + * @typedef ProtocolExtract + * @type Object + * @property {String} protocol Protocol matched in the URL, in lowercase. + * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`. + * @property {String} rest Rest of the URL that is not part of the protocol. + */ + +/** + * Extract protocol information from a URL with/without double slash ("//"). + * + * @param {String} address URL we want to extract from. + * @return {ProtocolExtract} Extracted information. + * @api private + */ +function extractProtocol(address) { + var match = protocolre.exec(address); + + return { + protocol: match[1] ? match[1].toLowerCase() : '', + slashes: !!match[2], + rest: match[3] + }; +} + +/** + * Resolve a relative URL pathname against a base URL pathname. + * + * @param {String} relative Pathname of the relative URL. + * @param {String} base Pathname of the base URL. + * @return {String} Resolved pathname. + * @api private + */ +function resolve(relative, base) { + var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/')) + , i = path.length + , last = path[i - 1] + , unshift = false + , up = 0; + + while (i--) { + if (path[i] === '.') { + path.splice(i, 1); + } else if (path[i] === '..') { + path.splice(i, 1); + up++; + } else if (up) { + if (i === 0) { unshift = true; } + path.splice(i, 1); + up--; + } + } + + if (unshift) { path.unshift(''); } + if (last === '.' || last === '..') { path.push(''); } + + return path.join('/'); +} + +/** + * The actual URL instance. Instead of returning an object we've opted-in to + * create an actual constructor as it's much more memory efficient and + * faster and it pleases my OCD. + * + * @constructor + * @param {String} address URL we want to parse. + * @param {Object|String} location Location defaults for relative paths. + * @param {Boolean|Function} parser Parser for the query string. + * @api public + */ +function URL(address, location, parser) { + if (!(this instanceof URL)) { + return new URL(address, location, parser); + } + + var relative, extracted, parse, instruction, index, key + , instructions = rules.slice() + , type = typeof location + , url = this + , i = 0; + + // + // The following if statements allows this module two have compatibility with + // 2 different API: + // + // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments + // where the boolean indicates that the query string should also be parsed. + // + // 2. The `URL` interface of the browser which accepts a URL, object as + // arguments. The supplied object will be used as default values / fall-back + // for relative paths. + // + if ('object' !== type && 'string' !== type) { + parser = location; + location = null; + } + + if (parser && 'function' !== typeof parser) { parser = querystringify_1.parse; } + + location = lolcation(location); + + // + // Extract protocol information before running the instructions. + // + extracted = extractProtocol(address || ''); + relative = !extracted.protocol && !extracted.slashes; + url.slashes = extracted.slashes || relative && location.slashes; + url.protocol = extracted.protocol || location.protocol || ''; + address = extracted.rest; + + // + // When the authority component is absent the URL starts with a path + // component. + // + if (!extracted.slashes) { instructions[2] = [/(.*)/, 'pathname']; } + + for (; i < instructions.length; i++) { + instruction = instructions[i]; + parse = instruction[0]; + key = instruction[1]; + + if (parse !== parse) { + url[key] = address; + } else if ('string' === typeof parse) { + if (~(index = address.indexOf(parse))) { + if ('number' === typeof instruction[2]) { + url[key] = address.slice(0, index); + address = address.slice(index + instruction[2]); + } else { + url[key] = address.slice(index); + address = address.slice(0, index); + } + } + } else if ((index = parse.exec(address))) { + url[key] = index[1]; + address = address.slice(0, index.index); + } + + url[key] = url[key] || ( + relative && instruction[3] ? location[key] || '' : '' + ); + + // + // Hostname, host and protocol should be lowercased so they can be used to + // create a proper `origin`. + // + if (instruction[4]) { url[key] = url[key].toLowerCase(); } + } + + // + // Also parse the supplied query string in to an object. If we're supplied + // with a custom parser as function use that instead of the default build-in + // parser. + // + if (parser) { url.query = parser(url.query); } + + // + // If the URL is relative, resolve the pathname against the base URL. + // + if ( + relative + && location.slashes + && url.pathname.charAt(0) !== '/' + && (url.pathname !== '' || location.pathname !== '') + ) { + url.pathname = resolve(url.pathname, location.pathname); + } + + // + // We should not add port numbers if they are already the default port number + // for a given protocol. As the host also contains the port number we're going + // override it with the hostname which contains no port number. + // + if (!requiresPort(url.port, url.protocol)) { + url.host = url.hostname; + url.port = ''; + } + + // + // Parse down the `auth` for the username and password. + // + url.username = url.password = ''; + if (url.auth) { + instruction = url.auth.split(':'); + url.username = instruction[0] || ''; + url.password = instruction[1] || ''; + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + // + // The href is just the compiled result. + // + url.href = url.toString(); +} + +/** + * This is convenience method for changing properties in the URL instance to + * insure that they all propagate correctly. + * + * @param {String} part Property we need to adjust. + * @param {Mixed} value The newly assigned value. + * @param {Boolean|Function} fn When setting the query, it will be the function + * used to parse the query. + * When setting the protocol, double slash will be + * removed from the final url if it is true. + * @returns {URL} + * @api public + */ +function set(part, value, fn) { + var url = this; + + switch (part) { + case 'query': + if ('string' === typeof value && value.length) { + value = (fn || querystringify_1.parse)(value); + } + + url[part] = value; + break; + + case 'port': + url[part] = value; + + if (!requiresPort(value, url.protocol)) { + url.host = url.hostname; + url[part] = ''; + } else if (value) { + url.host = url.hostname +':'+ value; + } + + break; + + case 'hostname': + url[part] = value; + + if (url.port) { value += ':'+ url.port; } + url.host = value; + break; + + case 'host': + url[part] = value; + + if (/:\d+$/.test(value)) { + value = value.split(':'); + url.port = value.pop(); + url.hostname = value.join(':'); + } else { + url.hostname = value; + url.port = ''; + } + + break; + + case 'protocol': + url.protocol = value.toLowerCase(); + url.slashes = !fn; + break; + + case 'pathname': + case 'hash': + if (value) { + var char = part === 'pathname' ? '/' : '#'; + url[part] = value.charAt(0) !== char ? char + value : value; + } else { + url[part] = value; + } + break; + + default: + url[part] = value; + } + + for (var i = 0; i < rules.length; i++) { + var ins = rules[i]; + + if (ins[4]) { url[ins[1]] = url[ins[1]].toLowerCase(); } + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + url.href = url.toString(); + + return url; +} + +/** + * Transform the properties back in to a valid and full URL string. + * + * @param {Function} stringify Optional query stringify function. + * @returns {String} + * @api public + */ +function toString(stringify) { + if (!stringify || 'function' !== typeof stringify) { stringify = querystringify_1.stringify; } + + var query + , url = this + , protocol = url.protocol; + + if (protocol && protocol.charAt(protocol.length - 1) !== ':') { protocol += ':'; } + + var result = protocol + (url.slashes ? '//' : ''); + + if (url.username) { + result += url.username; + if (url.password) { result += ':'+ url.password; } + result += '@'; + } + + result += url.host + url.pathname; + + query = 'object' === typeof url.query ? stringify(url.query) : url.query; + if (query) { result += '?' !== query.charAt(0) ? '?'+ query : query; } + + if (url.hash) { result += url.hash; } + + return result; +} + +URL.prototype = { set: set, toString: toString }; + +// +// Expose the URL parser and some additional properties that might be useful for +// others or testing. +// +URL.extractProtocol = extractProtocol; +URL.location = lolcation; +URL.qs = querystringify_1; + +var urlParse = URL; + +/* +* This delay allows the thread to finish assigning its on* methods +* before invoking the delay callback. This is purely a timing hack. +* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html +* +* @param {callback: function} the callback which will be invoked after the timeout +* @parma {context: object} the context in which to invoke the function +*/ +function delay(callback, context) { + setTimeout(function (timeoutContext) { return callback.call(timeoutContext); }, 4, context); +} + +function log(method, message) { + /* eslint-disable no-console */ + if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') { + console[method].call(null, message); + } + /* eslint-enable no-console */ +} + +function reject(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (!callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +function filter(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +/* +* EventTarget is an interface implemented by objects that can +* receive events and may have listeners for them. +* +* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget +*/ +var EventTarget = function EventTarget() { + this.listeners = {}; +}; + +/* +* Ties a listener function to an event type which can later be invoked via the +* dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.addEventListener = function addEventListener (type, listener /* , useCapture */) { + if (typeof listener === 'function') { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], function (item) { return item === listener; }).length === 0) { + this.listeners[type].push(listener); + } + } +}; + +/* +* Removes the listener so it will no longer be invoked via the dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.removeEventListener = function removeEventListener (type, removingListener /* , useCapture */) { + var arrayOfListeners = this.listeners[type]; + this.listeners[type] = reject(arrayOfListeners, function (listener) { return listener === removingListener; }); +}; + +/* +* Invokes all listener functions that are listening to the given event.type property. Each +* listener will be passed the event as the first argument. +* +* @param {object} event - event object which will be passed to all listeners of the event.type property +*/ +EventTarget.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + listener.call(this$1, event); + } + }); + + return true; +}; + +/* +* The network bridge is a way for the mock websocket object to 'communicate' with +* all available servers. This is a singleton object so it is important that you +* clean up urlMap whenever you are finished. +*/ +var NetworkBridge = function NetworkBridge() { + this.urlMap = {}; +}; + +/* +* Attaches a websocket object to the urlMap hash so that it can find the server +* it is connected to and the server in turn can find it. +* +* @param {object} websocket - websocket object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachWebSocket = function attachWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) { + connectionLookup.websockets.push(websocket); + return connectionLookup.server; + } +}; + +/* +* Attaches a websocket to a room +*/ +NetworkBridge.prototype.addMembershipToRoom = function addMembershipToRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) { + if (!connectionLookup.roomMemberships[room]) { + connectionLookup.roomMemberships[room] = []; + } + + connectionLookup.roomMemberships[room].push(websocket); + } +}; + +/* +* Attaches a server object to the urlMap hash so that it can find a websockets +* which are connected to it and so that websockets can in turn can find it. +* +* @param {object} server - server object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachServer = function attachServer (server, url) { + var connectionLookup = this.urlMap[url]; + + if (!connectionLookup) { + this.urlMap[url] = { + server: server, + websockets: [], + roomMemberships: {} + }; + + return server; + } +}; + +/* +* Finds the server which is 'running' on the given url. +* +* @param {string} url - the url to use to find which server is running on it +*/ +NetworkBridge.prototype.serverLookup = function serverLookup (url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + return connectionLookup.server; + } +}; + +/* +* Finds all websockets which is 'listening' on the given url. +* +* @param {string} url - the url to use to find all websockets which are associated with it +* @param {string} room - if a room is provided, will only return sockets in this room +* @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup +*/ +NetworkBridge.prototype.websocketsLookup = function websocketsLookup (url, room, broadcaster) { + var websockets; + var connectionLookup = this.urlMap[url]; + + websockets = connectionLookup ? connectionLookup.websockets : []; + + if (room) { + var members = connectionLookup.roomMemberships[room]; + websockets = members || []; + } + + return broadcaster ? websockets.filter(function (websocket) { return websocket !== broadcaster; }) : websockets; +}; + +/* +* Removes the entry associated with the url. +* +* @param {string} url +*/ +NetworkBridge.prototype.removeServer = function removeServer (url) { + delete this.urlMap[url]; +}; + +/* +* Removes the individual websocket from the map of associated websockets. +* +* @param {object} websocket - websocket object to remove from the url map +* @param {string} url +*/ +NetworkBridge.prototype.removeWebSocket = function removeWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + connectionLookup.websockets = reject(connectionLookup.websockets, function (socket) { return socket === websocket; }); + } +}; + +/* +* Removes a websocket from a room +*/ +NetworkBridge.prototype.removeMembershipFromRoom = function removeMembershipFromRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + var memberships = connectionLookup.roomMemberships[room]; + + if (connectionLookup && memberships !== null) { + connectionLookup.roomMemberships[room] = reject(memberships, function (socket) { return socket === websocket; }); + } +}; + +var networkBridge = new NetworkBridge(); // Note: this is a singleton + +/* + * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent + */ +var CLOSE_CODES = { + CLOSE_NORMAL: 1000, + CLOSE_GOING_AWAY: 1001, + CLOSE_PROTOCOL_ERROR: 1002, + CLOSE_UNSUPPORTED: 1003, + CLOSE_NO_STATUS: 1005, + CLOSE_ABNORMAL: 1006, + UNSUPPORTED_DATA: 1007, + POLICY_VIOLATION: 1008, + CLOSE_TOO_LARGE: 1009, + MISSING_EXTENSION: 1010, + INTERNAL_ERROR: 1011, + SERVICE_RESTART: 1012, + TRY_AGAIN_LATER: 1013, + TLS_HANDSHAKE: 1015 +}; + +var ERROR_PREFIX = { + CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':", + CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':", + EVENT: { + CONSTRUCT: "Failed to construct 'Event':", + MESSAGE: "Failed to construct 'MessageEvent':", + CLOSE: "Failed to construct 'CloseEvent':" + } +}; + +var EventPrototype = function EventPrototype () {}; + +EventPrototype.prototype.stopPropagation = function stopPropagation () {}; +EventPrototype.prototype.stopImmediatePropagation = function stopImmediatePropagation () {}; + +// if no arguments are passed then the type is set to "undefined" on +// chrome and safari. +EventPrototype.prototype.initEvent = function initEvent (type, bubbles, cancelable) { + if ( type === void 0 ) type = 'undefined'; + if ( bubbles === void 0 ) bubbles = false; + if ( cancelable === void 0 ) cancelable = false; + + this.type = "" + type; + this.bubbles = Boolean(bubbles); + this.cancelable = Boolean(cancelable); +}; + +var Event = (function (EventPrototype$$1) { + function Event(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " parameter 2 ('eventInitDict') is not an object.")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + } + + if ( EventPrototype$$1 ) Event.__proto__ = EventPrototype$$1; + Event.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + Event.prototype.constructor = Event; + + return Event; +}(EventPrototype)); + +var MessageEvent = (function (EventPrototype$$1) { + function MessageEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var data = eventInitConfig.data; + var origin = eventInitConfig.origin; + var lastEventId = eventInitConfig.lastEventId; + var ports = eventInitConfig.ports; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.origin = "" + origin; + this.ports = typeof ports === 'undefined' ? null : ports; + this.data = typeof data === 'undefined' ? null : data; + this.lastEventId = "" + (lastEventId || ''); + } + + if ( EventPrototype$$1 ) MessageEvent.__proto__ = EventPrototype$$1; + MessageEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + MessageEvent.prototype.constructor = MessageEvent; + + return MessageEvent; +}(EventPrototype)); + +var CloseEvent = (function (EventPrototype$$1) { + function CloseEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var code = eventInitConfig.code; + var reason = eventInitConfig.reason; + var wasClean = eventInitConfig.wasClean; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.cancelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.code = typeof code === 'number' ? parseInt(code, 10) : 0; + this.reason = "" + (reason || ''); + this.wasClean = wasClean ? Boolean(wasClean) : false; + } + + if ( EventPrototype$$1 ) CloseEvent.__proto__ = EventPrototype$$1; + CloseEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + CloseEvent.prototype.constructor = CloseEvent; + + return CloseEvent; +}(EventPrototype)); + +/* +* Creates an Event object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config you will need to pass type and optionally target +*/ +function createEvent(config) { + var type = config.type; + var target = config.target; + var eventObject = new Event(type); + + if (target) { + eventObject.target = target; + eventObject.srcElement = target; + eventObject.currentTarget = target; + } + + return eventObject; +} + +/* +* Creates a MessageEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type, origin, data and optionally target +*/ +function createMessageEvent(config) { + var type = config.type; + var origin = config.origin; + var data = config.data; + var target = config.target; + var messageEvent = new MessageEvent(type, { + data: data, + origin: origin + }); + + if (target) { + messageEvent.target = target; + messageEvent.srcElement = target; + messageEvent.currentTarget = target; + } + + return messageEvent; +} + +/* +* Creates a CloseEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type and optionally target, code, and reason +*/ +function createCloseEvent(config) { + var code = config.code; + var reason = config.reason; + var type = config.type; + var target = config.target; + var wasClean = config.wasClean; + + if (!wasClean) { + wasClean = code === 1000; + } + + var closeEvent = new CloseEvent(type, { + code: code, + reason: reason, + wasClean: wasClean + }); + + if (target) { + closeEvent.target = target; + closeEvent.srcElement = target; + closeEvent.currentTarget = target; + } + + return closeEvent; +} + +function closeWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function failWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason, + wasClean: false + }); + + var errorEvent = createEvent({ + type: 'error', + target: context + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(errorEvent); + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function normalizeSendData(data) { + if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) { + data = String(data); + } + + return data; +} + +function proxyFactory(target) { + var handler = { + get: function get(obj, prop) { + if (prop === 'close') { + return function close(options) { + if ( options === void 0 ) options = {}; + + var code = options.code || CLOSE_CODES.CLOSE_NORMAL; + var reason = options.reason || ''; + + closeWebSocketConnection(target, code, reason); + }; + } + + if (prop === 'send') { + return function send(data) { + data = normalizeSendData(data); + + target.dispatchEvent( + createMessageEvent({ + type: 'message', + data: data, + origin: this.url, + target: target + }) + ); + }; + } + + if (prop === 'on') { + return function onWrapper(type, cb) { + target.addEventListener(("server::" + type), cb); + }; + } + + return obj[prop]; + } + }; + + var proxy = new Proxy(target, handler); + return proxy; +} + +function lengthInUtf8Bytes(str) { + // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. + var m = encodeURIComponent(str).match(/%[89ABab]/g); + return str.length + (m ? m.length : 0); +} + +function urlVerification(url) { + var urlRecord = new urlParse(url); + var pathname = urlRecord.pathname; + var protocol = urlRecord.protocol; + var hash = urlRecord.hash; + + if (!url) { + throw new TypeError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (!pathname) { + urlRecord.pathname = '/'; + } + + if (protocol === '') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL '" + (urlRecord.toString()) + "' is invalid.")); + } + + if (protocol !== 'ws:' && protocol !== 'wss:') { + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL's scheme must be either 'ws' or 'wss'. '" + protocol + "' is not allowed.") + ); + } + + if (hash !== '') { + /* eslint-disable max-len */ + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL contains a fragment identifier ('" + hash + "'). Fragment identifiers are not allowed in WebSocket URLs.") + ); + /* eslint-enable max-len */ + } + + return urlRecord.toString(); +} + +function protocolVerification(protocols) { + if ( protocols === void 0 ) protocols = []; + + if (!Array.isArray(protocols) && typeof protocols !== 'string') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (protocols.toString()) + "' is invalid.")); + } + + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + var uniq = protocols.map(function (p) { return ({ count: 1, protocol: p }); }).reduce(function (a, b) { + a[b.protocol] = (a[b.protocol] || 0) + b.count; + return a; + }, {}); + + var duplicates = Object.keys(uniq).filter(function (a) { return uniq[a] > 1; }); + + if (duplicates.length > 0) { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (duplicates[0]) + "' is duplicated.")); + } + + return protocols; +} + +/* + * The main websocket class which is designed to mimick the native WebSocket class as close + * as possible. + * + * https://html.spec.whatwg.org/multipage/web-sockets.html + */ +var WebSocket$1 = (function (EventTarget$$1) { + function WebSocket(url, protocols) { + EventTarget$$1.call(this); + + this.url = urlVerification(url); + protocols = protocolVerification(protocols); + this.protocol = protocols[0] || ''; + + this.binaryType = 'blob'; + this.readyState = WebSocket.CONNECTING; + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * This delay is needed so that we dont trigger an event before the callbacks have been + * setup. For example: + * + * var socket = new WebSocket('ws://localhost'); + * + * If we dont have the delay then the event would be triggered right here and this is + * before the onopen had a chance to register itself. + * + * socket.onopen = () => { // this would never be called }; + * + * and with the delay the event gets triggered here after all of the callbacks have been + * registered :-) + */ + delay(function delayCallback() { + if (server) { + if ( + server.options.verifyClient && + typeof server.options.verifyClient === 'function' && + !server.options.verifyClient() + ) { + this.readyState = WebSocket.CLOSED; + + log( + 'error', + ("WebSocket connection to '" + (this.url) + "' failed: HTTP Authentication failed; no valid credentials available") + ); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + } else { + if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') { + var selectedProtocol = server.options.selectProtocol(protocols); + var isFilled = selectedProtocol !== ''; + var isRequested = protocols.indexOf(selectedProtocol) !== -1; + if (isFilled && !isRequested) { + this.readyState = WebSocket.CLOSED; + + log('error', ("WebSocket connection to '" + (this.url) + "' failed: Invalid Sub-Protocol")); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + return; + } + this.protocol = selectedProtocol; + } + this.readyState = WebSocket.OPEN; + this.dispatchEvent(createEvent({ type: 'open', target: this })); + server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this)); + } + } else { + this.readyState = WebSocket.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + + log('error', ("WebSocket connection to '" + (this.url) + "' failed")); + } + }, this); + } + + if ( EventTarget$$1 ) WebSocket.__proto__ = EventTarget$$1; + WebSocket.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + WebSocket.prototype.constructor = WebSocket; + + var prototypeAccessors = { onopen: {},onmessage: {},onclose: {},onerror: {} }; + + prototypeAccessors.onopen.get = function () { + return this.listeners.open; + }; + + prototypeAccessors.onmessage.get = function () { + return this.listeners.message; + }; + + prototypeAccessors.onclose.get = function () { + return this.listeners.close; + }; + + prototypeAccessors.onerror.get = function () { + return this.listeners.error; + }; + + prototypeAccessors.onopen.set = function (listener) { + delete this.listeners.open; + this.addEventListener('open', listener); + }; + + prototypeAccessors.onmessage.set = function (listener) { + delete this.listeners.message; + this.addEventListener('message', listener); + }; + + prototypeAccessors.onclose.set = function (listener) { + delete this.listeners.close; + this.addEventListener('close', listener); + }; + + prototypeAccessors.onerror.set = function (listener) { + delete this.listeners.error; + this.addEventListener('error', listener); + }; + + WebSocket.prototype.send = function send (data) { + var this$1 = this; + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + throw new Error('WebSocket is already in CLOSING or CLOSED state'); + } + + // TODO: handle bufferedAmount + + var messageEvent = createMessageEvent({ + type: 'server::message', + origin: this.url, + data: normalizeSendData(data) + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + delay(function () { + this$1.dispatchEvent(messageEvent, data); + }, server); + } + }; + + WebSocket.prototype.close = function close (code, reason) { + if (code !== undefined) { + if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) { + throw new TypeError( + ((ERROR_PREFIX.CLOSE_ERROR) + " The code must be either 1000, or between 3000 and 4999. " + code + " is neither.") + ); + } + } + + if (reason !== undefined) { + var length = lengthInUtf8Bytes(reason); + + if (length > 123) { + throw new SyntaxError(((ERROR_PREFIX.CLOSE_ERROR) + " The message must not be greater than 123 bytes.")); + } + } + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + return; + } + + if (this.readyState === WebSocket.CONNECTING) { + failWebSocketConnection(this, code, reason); + } else { + closeWebSocketConnection(this, code, reason); + } + }; + + Object.defineProperties( WebSocket.prototype, prototypeAccessors ); + + return WebSocket; +}(EventTarget)); + +WebSocket$1.CONNECTING = 0; +WebSocket$1.prototype.CONNECTING = WebSocket$1.CONNECTING; +WebSocket$1.OPEN = 1; +WebSocket$1.prototype.OPEN = WebSocket$1.OPEN; +WebSocket$1.CLOSING = 2; +WebSocket$1.prototype.CLOSING = WebSocket$1.CLOSING; +WebSocket$1.CLOSED = 3; +WebSocket$1.prototype.CLOSED = WebSocket$1.CLOSED; + +var dedupe = function (arr) { return arr.reduce(function (deduped, b) { + if (deduped.indexOf(b) > -1) { return deduped; } + return deduped.concat(b); + }, []); }; + +function retrieveGlobalObject() { + if (typeof window !== 'undefined') { + return window; + } + + return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this; +} + +var Server$1 = (function (EventTarget$$1) { + function Server(url, options) { + if ( options === void 0 ) options = {}; + + EventTarget$$1.call(this); + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + + this.originalWebSocket = null; + var server = networkBridge.attachServer(this, this.url); + + if (!server) { + this.dispatchEvent(createEvent({ type: 'error' })); + throw new Error('A mock server is already listening on this url'); + } + + if (typeof options.verifyClient === 'undefined') { + options.verifyClient = null; + } + + if (typeof options.selectProtocol === 'undefined') { + options.selectProtocol = null; + } + + this.options = options; + this.start(); + } + + if ( EventTarget$$1 ) Server.__proto__ = EventTarget$$1; + Server.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + Server.prototype.constructor = Server; + + /* + * Attaches the mock websocket object to the global object + */ + Server.prototype.start = function start () { + var globalObj = retrieveGlobalObject(); + + if (globalObj.WebSocket) { + this.originalWebSocket = globalObj.WebSocket; + } + + globalObj.WebSocket = WebSocket$1; + }; + + /* + * Removes the mock websocket object from the global object + */ + Server.prototype.stop = function stop (callback) { + if ( callback === void 0 ) callback = function () {}; + + var globalObj = retrieveGlobalObject(); + + if (this.originalWebSocket) { + globalObj.WebSocket = this.originalWebSocket; + } else { + delete globalObj.WebSocket; + } + + this.originalWebSocket = null; + + networkBridge.removeServer(this.url); + + if (typeof callback === 'function') { + callback(); + } + }; + + /* + * This is the main function for the mock server to subscribe to the on events. + * + * ie: mockServer.on('connection', function() { console.log('a mock client connected'); }); + * + * @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close. + * @param {function} callback - The callback which should be called when a certain event is fired. + */ + Server.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + }; + + /* + * Closes the connection and triggers the onclose method of all listening + * websockets. After that it removes itself from the urlMap so another server + * could add itself to the url. + * + * @param {object} options + */ + Server.prototype.close = function close (options) { + if ( options === void 0 ) options = {}; + + var code = options.code; + var reason = options.reason; + var wasClean = options.wasClean; + var listeners = networkBridge.websocketsLookup(this.url); + + // Remove server before notifications to prevent immediate reconnects from + // socket onclose handlers + networkBridge.removeServer(this.url); + + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent( + createCloseEvent({ + type: 'close', + target: socket, + code: code || CLOSE_CODES.CLOSE_NORMAL, + reason: reason || '', + wasClean: wasClean + }) + ); + }); + + this.dispatchEvent(createCloseEvent({ type: 'close' }), this); + }; + + /* + * Sends a generic message event to all mock clients. + */ + Server.prototype.emit = function emit (event, data, options) { + var this$1 = this; + if ( options === void 0 ) options = {}; + + var websockets = options.websockets; + + if (!websockets) { + websockets = networkBridge.websocketsLookup(this.url); + } + + if (typeof options !== 'object' || arguments.length > 3) { + data = Array.prototype.slice.call(arguments, 1, arguments.length); + data = data.map(function (item) { return normalizeSendData(item); }); + } else { + data = normalizeSendData(data); + } + + websockets.forEach(function (socket) { + if (Array.isArray(data)) { + socket.dispatchEvent.apply( + socket, [ createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) ].concat( data ) + ); + } else { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) + ); + } + }); + }; + + /* + * Returns an array of websockets which are listening to this server + * TOOD: this should return a set and not be a method + */ + Server.prototype.clients = function clients () { + return networkBridge.websocketsLookup(this.url); + }; + + /* + * Prepares a method to submit an event to members of the room + * + * e.g. server.to('my-room').emit('hi!'); + */ + Server.prototype.to = function to (room, broadcaster, broadcastList) { + var this$1 = this; + if ( broadcastList === void 0 ) broadcastList = []; + + var self = this; + var websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster))); + + return { + to: function (chainedRoom, chainedBroadcaster) { return this$1.to.call(this$1, chainedRoom, chainedBroadcaster, websockets); }, + emit: function emit(event, data) { + self.emit(event, data, { websockets: websockets }); + } + }; + }; + + /* + * Alias for Server.to + */ + Server.prototype.in = function in$1 () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return this.to.apply(null, args); + }; + + /* + * Simulate an event from the server to the clients. Useful for + * simulating errors. + */ + Server.prototype.simulate = function simulate (event) { + var listeners = networkBridge.websocketsLookup(this.url); + + if (event === 'error') { + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent(createEvent({ type: 'error' })); + }); + } + }; + + return Server; +}(EventTarget)); + +/* + * Alternative constructor to support namespaces in socket.io + * + * http://socket.io/docs/rooms-and-namespaces/#custom-namespaces + */ +Server$1.of = function of(url) { + return new Server$1(url); +}; + +/* +* The socket-io class is designed to mimick the real API as closely as possible. +* +* http://socket.io/docs/ +*/ +var SocketIO$1 = (function (EventTarget$$1) { + function SocketIO(url, protocol) { + var this$1 = this; + if ( url === void 0 ) url = 'socket.io'; + if ( protocol === void 0 ) protocol = ''; + + EventTarget$$1.call(this); + + this.binaryType = 'blob'; + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + this.readyState = SocketIO.CONNECTING; + this.protocol = ''; + + if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) { + this.protocol = protocol; + } else if (Array.isArray(protocol) && protocol.length > 0) { + this.protocol = protocol[0]; + } + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * Delay triggering the connection events so they can be defined in time. + */ + delay(function delayCallback() { + if (server) { + this.readyState = SocketIO.OPEN; + server.dispatchEvent(createEvent({ type: 'connection' }), server, this); + server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias + this.dispatchEvent(createEvent({ type: 'connect', target: this })); + } else { + this.readyState = SocketIO.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + log('error', ("Socket.io connection to '" + (this.url) + "' failed")); + } + }, this); + + /** + Add an aliased event listener for close / disconnect + */ + this.addEventListener('close', function (event) { + this$1.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: event.target, + code: event.code + }) + ); + }); + } + + if ( EventTarget$$1 ) SocketIO.__proto__ = EventTarget$$1; + SocketIO.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + SocketIO.prototype.constructor = SocketIO; + + var prototypeAccessors = { broadcast: {} }; + + /* + * Closes the SocketIO connection or connection attempt, if any. + * If the connection is already CLOSED, this method does nothing. + */ + SocketIO.prototype.close = function close () { + if (this.readyState !== SocketIO.OPEN) { + return undefined; + } + + var server = networkBridge.serverLookup(this.url); + networkBridge.removeWebSocket(this, this.url); + + this.readyState = SocketIO.CLOSED; + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + if (server) { + server.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }), + server + ); + } + + return this; + }; + + /* + * Alias for Socket#close + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383 + */ + SocketIO.prototype.disconnect = function disconnect () { + return this.close(); + }; + + /* + * Submits an event to the server with a payload + */ + SocketIO.prototype.emit = function emit (event) { + var data = [], len = arguments.length - 1; + while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ]; + + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var messageEvent = createMessageEvent({ + type: event, + origin: this.url, + data: data + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + server.dispatchEvent.apply(server, [ messageEvent ].concat( data )); + } + + return this; + }; + + /* + * Submits a 'message' event to the server. + * + * Should behave exactly like WebSocket#send + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113 + */ + SocketIO.prototype.send = function send (data) { + this.emit('message', data); + return this; + }; + + /* + * For broadcasting events to other connected sockets. + * + * e.g. socket.broadcast.emit('hi!'); + * e.g. socket.broadcast.to('my-room').emit('hi!'); + */ + prototypeAccessors.broadcast.get = function () { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var self = this; + var server = networkBridge.serverLookup(this.url); + if (!server) { + throw new Error(("SocketIO can not find a server at the specified URL (" + (this.url) + ")")); + } + + return { + emit: function emit(event, data) { + server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) }); + return self; + }, + to: function to(room) { + return server.to(room, self); + }, + in: function in$1(room) { + return server.in(room, self); + } + }; + }; + + /* + * For registering events to be received from the server + */ + SocketIO.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + return this; + }; + + /* + * Remove event listener + * + * https://socket.io/docs/client-api/#socket-on-eventname-callback + */ + SocketIO.prototype.off = function off (type) { + this.removeEventListener(type); + }; + + /* + * Join a room on a server + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.join = function join (room) { + networkBridge.addMembershipToRoom(this, room); + }; + + /* + * Get the websocket to leave the room + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.leave = function leave (room) { + networkBridge.removeMembershipFromRoom(this, room); + }; + + SocketIO.prototype.to = function to (room) { + return this.broadcast.to(room); + }; + + SocketIO.prototype.in = function in$1 () { + return this.to.apply(null, arguments); + }; + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + SocketIO.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + // Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data + // payload instanceof MessageEvent works, but you can't isntance of NodeEvent + // for now we detect if the output has data defined on it + listener.call(this$1, event.data ? event.data : event); + } + }); + }; + + Object.defineProperties( SocketIO.prototype, prototypeAccessors ); + + return SocketIO; +}(EventTarget)); + +SocketIO$1.CONNECTING = 0; +SocketIO$1.OPEN = 1; +SocketIO$1.CLOSING = 2; +SocketIO$1.CLOSED = 3; + +/* +* Static constructor methods for the IO Socket +*/ +var IO = function ioConstructor(url, protocol) { + return new SocketIO$1(url, protocol); +}; + +/* +* Alias the raw IO() constructor +*/ +IO.connect = function ioConnect(url, protocol) { + /* eslint-disable new-cap */ + return IO(url, protocol); + /* eslint-enable new-cap */ +}; + +var Server = Server$1; +var WebSocket = WebSocket$1; +var SocketIO = IO; + +exports.Server = Server; +exports.WebSocket = WebSocket; +exports.SocketIO = SocketIO; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zb2NrZXQuYW1kLmpzIiwic291cmNlcyI6WyIuLi9ub2RlX21vZHVsZXMvcmVxdWlyZXMtcG9ydC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZ2lmeS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91cmwtcGFyc2UvaW5kZXguanMiLCIuLi9zcmMvaGVscGVycy9kZWxheS5qcyIsIi4uL3NyYy9oZWxwZXJzL2xvZ2dlci5qcyIsIi4uL3NyYy9oZWxwZXJzL2FycmF5LWhlbHBlcnMuanMiLCIuLi9zcmMvZXZlbnQvdGFyZ2V0LmpzIiwiLi4vc3JjL25ldHdvcmstYnJpZGdlLmpzIiwiLi4vc3JjL2NvbnN0YW50cy5qcyIsIi4uL3NyYy9ldmVudC9wcm90b3R5cGUuanMiLCIuLi9zcmMvZXZlbnQvZXZlbnQuanMiLCIuLi9zcmMvZXZlbnQvbWVzc2FnZS5qcyIsIi4uL3NyYy9ldmVudC9jbG9zZS5qcyIsIi4uL3NyYy9ldmVudC9mYWN0b3J5LmpzIiwiLi4vc3JjL2FsZ29yaXRobXMvY2xvc2UuanMiLCIuLi9zcmMvaGVscGVycy9ub3JtYWxpemUtc2VuZC5qcyIsIi4uL3NyYy9oZWxwZXJzL3Byb3h5LWZhY3RvcnkuanMiLCIuLi9zcmMvaGVscGVycy9ieXRlLWxlbmd0aC5qcyIsIi4uL3NyYy9oZWxwZXJzL3VybC12ZXJpZmljYXRpb24uanMiLCIuLi9zcmMvaGVscGVycy9wcm90b2NvbC12ZXJpZmljYXRpb24uanMiLCIuLi9zcmMvd2Vic29ja2V0LmpzIiwiLi4vc3JjL2hlbHBlcnMvZGVkdXBlLmpzIiwiLi4vc3JjL2hlbHBlcnMvZ2xvYmFsLW9iamVjdC5qcyIsIi4uL3NyYy9zZXJ2ZXIuanMiLCIuLi9zcmMvc29ja2V0LWlvLmpzIiwiLi4vc3JjL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSdyZSByZXF1aXJlZCB0byBhZGQgYSBwb3J0IG51bWJlci5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jZGVmYXVsdC1wb3J0XG4gKiBAcGFyYW0ge051bWJlcnxTdHJpbmd9IHBvcnQgUG9ydCBudW1iZXIgd2UgbmVlZCB0byBjaGVja1xuICogQHBhcmFtIHtTdHJpbmd9IHByb3RvY29sIFByb3RvY29sIHdlIG5lZWQgdG8gY2hlY2sgYWdhaW5zdC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBJcyBpdCBhIGRlZmF1bHQgcG9ydCBmb3IgdGhlIGdpdmVuIHByb3RvY29sXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXF1aXJlZChwb3J0LCBwcm90b2NvbCkge1xuICBwcm90b2NvbCA9IHByb3RvY29sLnNwbGl0KCc6JylbMF07XG4gIHBvcnQgPSArcG9ydDtcblxuICBpZiAoIXBvcnQpIHJldHVybiBmYWxzZTtcblxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAnaHR0cCc6XG4gICAgY2FzZSAnd3MnOlxuICAgIHJldHVybiBwb3J0ICE9PSA4MDtcblxuICAgIGNhc2UgJ2h0dHBzJzpcbiAgICBjYXNlICd3c3MnOlxuICAgIHJldHVybiBwb3J0ICE9PSA0NDM7XG5cbiAgICBjYXNlICdmdHAnOlxuICAgIHJldHVybiBwb3J0ICE9PSAyMTtcblxuICAgIGNhc2UgJ2dvcGhlcic6XG4gICAgcmV0dXJuIHBvcnQgIT09IDcwO1xuXG4gICAgY2FzZSAnZmlsZSc6XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHBvcnQgIT09IDA7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBEZWNvZGUgYSBVUkkgZW5jb2RlZCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBVUkkgZW5jb2RlZCBzdHJpbmcuXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgZGVjb2RlZCBzdHJpbmcuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG4gIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoaW5wdXQucmVwbGFjZSgvXFwrL2csICcgJykpO1xufVxuXG4vKipcbiAqIFNpbXBsZSBxdWVyeSBzdHJpbmcgcGFyc2VyLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBxdWVyeSBUaGUgcXVlcnkgc3RyaW5nIHRoYXQgbmVlZHMgdG8gYmUgcGFyc2VkLlxuICogQHJldHVybnMge09iamVjdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5c3RyaW5nKHF1ZXJ5KSB7XG4gIHZhciBwYXJzZXIgPSAvKFtePT8mXSspPT8oW14mXSopL2dcbiAgICAsIHJlc3VsdCA9IHt9XG4gICAgLCBwYXJ0O1xuXG4gIHdoaWxlIChwYXJ0ID0gcGFyc2VyLmV4ZWMocXVlcnkpKSB7XG4gICAgdmFyIGtleSA9IGRlY29kZShwYXJ0WzFdKVxuICAgICAgLCB2YWx1ZSA9IGRlY29kZShwYXJ0WzJdKTtcblxuICAgIC8vXG4gICAgLy8gUHJldmVudCBvdmVycmlkaW5nIG9mIGV4aXN0aW5nIHByb3BlcnRpZXMuIFRoaXMgZW5zdXJlcyB0aGF0IGJ1aWxkLWluXG4gICAgLy8gbWV0aG9kcyBsaWtlIGB0b1N0cmluZ2Agb3IgX19wcm90b19fIGFyZSBub3Qgb3ZlcnJpZGVuIGJ5IG1hbGljaW91c1xuICAgIC8vIHF1ZXJ5c3RyaW5ncy5cbiAgICAvL1xuICAgIGlmIChrZXkgaW4gcmVzdWx0KSBjb250aW51ZTtcbiAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBUcmFuc2Zvcm0gYSBxdWVyeSBzdHJpbmcgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogT2JqZWN0IHRoYXQgc2hvdWxkIGJlIHRyYW5zZm9ybWVkLlxuICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeCBPcHRpb25hbCBwcmVmaXguXG4gKiBAcmV0dXJucyB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gcXVlcnlzdHJpbmdpZnkob2JqLCBwcmVmaXgpIHtcbiAgcHJlZml4ID0gcHJlZml4IHx8ICcnO1xuXG4gIHZhciBwYWlycyA9IFtdO1xuXG4gIC8vXG4gIC8vIE9wdGlvbmFsbHkgcHJlZml4IHdpdGggYSAnPycgaWYgbmVlZGVkXG4gIC8vXG4gIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIHByZWZpeCkgcHJlZml4ID0gJz8nO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzLmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsnPScrIGVuY29kZVVSSUNvbXBvbmVudChvYmpba2V5XSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWlycy5sZW5ndGggPyBwcmVmaXggKyBwYWlycy5qb2luKCcmJykgOiAnJztcbn1cblxuLy9cbi8vIEV4cG9zZSB0aGUgbW9kdWxlLlxuLy9cbmV4cG9ydHMuc3RyaW5naWZ5ID0gcXVlcnlzdHJpbmdpZnk7XG5leHBvcnRzLnBhcnNlID0gcXVlcnlzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZXF1aXJlZCA9IHJlcXVpcmUoJ3JlcXVpcmVzLXBvcnQnKVxuICAsIHFzID0gcmVxdWlyZSgncXVlcnlzdHJpbmdpZnknKVxuICAsIHByb3RvY29scmUgPSAvXihbYS16XVthLXowLTkuKy1dKjopPyhcXC9cXC8pPyhbXFxTXFxzXSopL2lcbiAgLCBzbGFzaGVzID0gL15bQS1aYS16XVtBLVphLXowLTkrLS5dKjpcXC9cXC8vO1xuXG4vKipcbiAqIFRoZXNlIGFyZSB0aGUgcGFyc2UgcnVsZXMgZm9yIHRoZSBVUkwgcGFyc2VyLCBpdCBpbmZvcm1zIHRoZSBwYXJzZXJcbiAqIGFib3V0OlxuICpcbiAqIDAuIFRoZSBjaGFyIGl0IE5lZWRzIHRvIHBhcnNlLCBpZiBpdCdzIGEgc3RyaW5nIGl0IHNob3VsZCBiZSBkb25lIHVzaW5nXG4gKiAgICBpbmRleE9mLCBSZWdFeHAgdXNpbmcgZXhlYyBhbmQgTmFOIG1lYW5zIHNldCBhcyBjdXJyZW50IHZhbHVlLlxuICogMS4gVGhlIHByb3BlcnR5IHdlIHNob3VsZCBzZXQgd2hlbiBwYXJzaW5nIHRoaXMgdmFsdWUuXG4gKiAyLiBJbmRpY2F0aW9uIGlmIGl0J3MgYmFja3dhcmRzIG9yIGZvcndhcmQgcGFyc2luZywgd2hlbiBzZXQgYXMgbnVtYmVyIGl0J3NcbiAqICAgIHRoZSB2YWx1ZSBvZiBleHRyYSBjaGFycyB0aGF0IHNob3VsZCBiZSBzcGxpdCBvZmYuXG4gKiAzLiBJbmhlcml0IGZyb20gbG9jYXRpb24gaWYgbm9uIGV4aXN0aW5nIGluIHRoZSBwYXJzZXIuXG4gKiA0LiBgdG9Mb3dlckNhc2VgIHRoZSByZXN1bHRpbmcgdmFsdWUuXG4gKi9cbnZhciBydWxlcyA9IFtcbiAgWycjJywgJ2hhc2gnXSwgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGJhY2suXG4gIFsnPycsICdxdWVyeSddLCAgICAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBmcm9tIHRoZSBiYWNrLlxuICBbJy8nLCAncGF0aG5hbWUnXSwgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgYmFjay5cbiAgWydAJywgJ2F1dGgnLCAxXSwgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGZyb250LlxuICBbTmFOLCAnaG9zdCcsIHVuZGVmaW5lZCwgMSwgMV0sICAgICAgIC8vIFNldCBsZWZ0IG92ZXIgdmFsdWUuXG4gIFsvOihcXGQrKSQvLCAncG9ydCcsIHVuZGVmaW5lZCwgMV0sICAgIC8vIFJlZ0V4cCB0aGUgYmFjay5cbiAgW05hTiwgJ2hvc3RuYW1lJywgdW5kZWZpbmVkLCAxLCAxXSAgICAvLyBTZXQgbGVmdCBvdmVyLlxuXTtcblxuLyoqXG4gKiBUaGVzZSBwcm9wZXJ0aWVzIHNob3VsZCBub3QgYmUgY29waWVkIG9yIGluaGVyaXRlZCBmcm9tLiBUaGlzIGlzIG9ubHkgbmVlZGVkXG4gKiBmb3IgYWxsIG5vbiBibG9iIFVSTCdzIGFzIGEgYmxvYiBVUkwgZG9lcyBub3QgaW5jbHVkZSBhIGhhc2gsIG9ubHkgdGhlXG4gKiBvcmlnaW4uXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcml2YXRlXG4gKi9cbnZhciBpZ25vcmUgPSB7IGhhc2g6IDEsIHF1ZXJ5OiAxIH07XG5cbi8qKlxuICogVGhlIGxvY2F0aW9uIG9iamVjdCBkaWZmZXJzIHdoZW4geW91ciBjb2RlIGlzIGxvYWRlZCB0aHJvdWdoIGEgbm9ybWFsIHBhZ2UsXG4gKiBXb3JrZXIgb3IgdGhyb3VnaCBhIHdvcmtlciB1c2luZyBhIGJsb2IuIEFuZCB3aXRoIHRoZSBibG9iYmxlIGJlZ2lucyB0aGVcbiAqIHRyb3VibGUgYXMgdGhlIGxvY2F0aW9uIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhlIFVSTCBvZiB0aGUgYmxvYiwgbm90IHRoZVxuICogbG9jYXRpb24gb2YgdGhlIHBhZ2Ugd2hlcmUgb3VyIGNvZGUgaXMgbG9hZGVkIGluLiBUaGUgYWN0dWFsIG9yaWdpbiBpc1xuICogZW5jb2RlZCBpbiB0aGUgYHBhdGhuYW1lYCBzbyB3ZSBjYW4gdGhhbmtmdWxseSBnZW5lcmF0ZSBhIGdvb2QgXCJkZWZhdWx0XCJcbiAqIGxvY2F0aW9uIGZyb20gaXQgc28gd2UgY2FuIGdlbmVyYXRlIHByb3BlciByZWxhdGl2ZSBVUkwncyBhZ2Fpbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGxvYyBPcHRpb25hbCBkZWZhdWx0IGxvY2F0aW9uIG9iamVjdC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IGxvbGNhdGlvbiBvYmplY3QuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBsb2xjYXRpb24obG9jKSB7XG4gIHZhciBsb2NhdGlvbiA9IGdsb2JhbCAmJiBnbG9iYWwubG9jYXRpb24gfHwge307XG4gIGxvYyA9IGxvYyB8fCBsb2NhdGlvbjtcblxuICB2YXIgZmluYWxkZXN0aW5hdGlvbiA9IHt9XG4gICAgLCB0eXBlID0gdHlwZW9mIGxvY1xuICAgICwga2V5O1xuXG4gIGlmICgnYmxvYjonID09PSBsb2MucHJvdG9jb2wpIHtcbiAgICBmaW5hbGRlc3RpbmF0aW9uID0gbmV3IFVSTCh1bmVzY2FwZShsb2MucGF0aG5hbWUpLCB7fSk7XG4gIH0gZWxzZSBpZiAoJ3N0cmluZycgPT09IHR5cGUpIHtcbiAgICBmaW5hbGRlc3RpbmF0aW9uID0gbmV3IFVSTChsb2MsIHt9KTtcbiAgICBmb3IgKGtleSBpbiBpZ25vcmUpIGRlbGV0ZSBmaW5hbGRlc3RpbmF0aW9uW2tleV07XG4gIH0gZWxzZSBpZiAoJ29iamVjdCcgPT09IHR5cGUpIHtcbiAgICBmb3IgKGtleSBpbiBsb2MpIHtcbiAgICAgIGlmIChrZXkgaW4gaWdub3JlKSBjb250aW51ZTtcbiAgICAgIGZpbmFsZGVzdGluYXRpb25ba2V5XSA9IGxvY1trZXldO1xuICAgIH1cblxuICAgIGlmIChmaW5hbGRlc3RpbmF0aW9uLnNsYXNoZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmluYWxkZXN0aW5hdGlvbi5zbGFzaGVzID0gc2xhc2hlcy50ZXN0KGxvYy5ocmVmKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmluYWxkZXN0aW5hdGlvbjtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBQcm90b2NvbEV4dHJhY3RcbiAqIEB0eXBlIE9iamVjdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHByb3RvY29sIFByb3RvY29sIG1hdGNoZWQgaW4gdGhlIFVSTCwgaW4gbG93ZXJjYXNlLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBzbGFzaGVzIGB0cnVlYCBpZiBwcm90b2NvbCBpcyBmb2xsb3dlZCBieSBcIi8vXCIsIGVsc2UgYGZhbHNlYC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZXN0IFJlc3Qgb2YgdGhlIFVSTCB0aGF0IGlzIG5vdCBwYXJ0IG9mIHRoZSBwcm90b2NvbC5cbiAqL1xuXG4vKipcbiAqIEV4dHJhY3QgcHJvdG9jb2wgaW5mb3JtYXRpb24gZnJvbSBhIFVSTCB3aXRoL3dpdGhvdXQgZG91YmxlIHNsYXNoIChcIi8vXCIpLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzIFVSTCB3ZSB3YW50IHRvIGV4dHJhY3QgZnJvbS5cbiAqIEByZXR1cm4ge1Byb3RvY29sRXh0cmFjdH0gRXh0cmFjdGVkIGluZm9ybWF0aW9uLlxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQcm90b2NvbChhZGRyZXNzKSB7XG4gIHZhciBtYXRjaCA9IHByb3RvY29scmUuZXhlYyhhZGRyZXNzKTtcblxuICByZXR1cm4ge1xuICAgIHByb3RvY29sOiBtYXRjaFsxXSA/IG1hdGNoWzFdLnRvTG93ZXJDYXNlKCkgOiAnJyxcbiAgICBzbGFzaGVzOiAhIW1hdGNoWzJdLFxuICAgIHJlc3Q6IG1hdGNoWzNdXG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlbGF0aXZlIFVSTCBwYXRobmFtZSBhZ2FpbnN0IGEgYmFzZSBVUkwgcGF0aG5hbWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlbGF0aXZlIFBhdGhuYW1lIG9mIHRoZSByZWxhdGl2ZSBVUkwuXG4gKiBAcGFyYW0ge1N0cmluZ30gYmFzZSBQYXRobmFtZSBvZiB0aGUgYmFzZSBVUkwuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IFJlc29sdmVkIHBhdGhuYW1lLlxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmUocmVsYXRpdmUsIGJhc2UpIHtcbiAgdmFyIHBhdGggPSAoYmFzZSB8fCAnLycpLnNwbGl0KCcvJykuc2xpY2UoMCwgLTEpLmNvbmNhdChyZWxhdGl2ZS5zcGxpdCgnLycpKVxuICAgICwgaSA9IHBhdGgubGVuZ3RoXG4gICAgLCBsYXN0ID0gcGF0aFtpIC0gMV1cbiAgICAsIHVuc2hpZnQgPSBmYWxzZVxuICAgICwgdXAgPSAwO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAocGF0aFtpXSA9PT0gJy4nKSB7XG4gICAgICBwYXRoLnNwbGljZShpLCAxKTtcbiAgICB9IGVsc2UgaWYgKHBhdGhbaV0gPT09ICcuLicpIHtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBpZiAoaSA9PT0gMCkgdW5zaGlmdCA9IHRydWU7XG4gICAgICBwYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwLS07XG4gICAgfVxuICB9XG5cbiAgaWYgKHVuc2hpZnQpIHBhdGgudW5zaGlmdCgnJyk7XG4gIGlmIChsYXN0ID09PSAnLicgfHwgbGFzdCA9PT0gJy4uJykgcGF0aC5wdXNoKCcnKTtcblxuICByZXR1cm4gcGF0aC5qb2luKCcvJyk7XG59XG5cbi8qKlxuICogVGhlIGFjdHVhbCBVUkwgaW5zdGFuY2UuIEluc3RlYWQgb2YgcmV0dXJuaW5nIGFuIG9iamVjdCB3ZSd2ZSBvcHRlZC1pbiB0b1xuICogY3JlYXRlIGFuIGFjdHVhbCBjb25zdHJ1Y3RvciBhcyBpdCdzIG11Y2ggbW9yZSBtZW1vcnkgZWZmaWNpZW50IGFuZFxuICogZmFzdGVyIGFuZCBpdCBwbGVhc2VzIG15IE9DRC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzIFVSTCB3ZSB3YW50IHRvIHBhcnNlLlxuICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBsb2NhdGlvbiBMb2NhdGlvbiBkZWZhdWx0cyBmb3IgcmVsYXRpdmUgcGF0aHMuXG4gKiBAcGFyYW0ge0Jvb2xlYW58RnVuY3Rpb259IHBhcnNlciBQYXJzZXIgZm9yIHRoZSBxdWVyeSBzdHJpbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBVUkwoYWRkcmVzcywgbG9jYXRpb24sIHBhcnNlcikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVVJMKSkge1xuICAgIHJldHVybiBuZXcgVVJMKGFkZHJlc3MsIGxvY2F0aW9uLCBwYXJzZXIpO1xuICB9XG5cbiAgdmFyIHJlbGF0aXZlLCBleHRyYWN0ZWQsIHBhcnNlLCBpbnN0cnVjdGlvbiwgaW5kZXgsIGtleVxuICAgICwgaW5zdHJ1Y3Rpb25zID0gcnVsZXMuc2xpY2UoKVxuICAgICwgdHlwZSA9IHR5cGVvZiBsb2NhdGlvblxuICAgICwgdXJsID0gdGhpc1xuICAgICwgaSA9IDA7XG5cbiAgLy9cbiAgLy8gVGhlIGZvbGxvd2luZyBpZiBzdGF0ZW1lbnRzIGFsbG93cyB0aGlzIG1vZHVsZSB0d28gaGF2ZSBjb21wYXRpYmlsaXR5IHdpdGhcbiAgLy8gMiBkaWZmZXJlbnQgQVBJOlxuICAvL1xuICAvLyAxLiBOb2RlLmpzJ3MgYHVybC5wYXJzZWAgYXBpIHdoaWNoIGFjY2VwdHMgYSBVUkwsIGJvb2xlYW4gYXMgYXJndW1lbnRzXG4gIC8vICAgIHdoZXJlIHRoZSBib29sZWFuIGluZGljYXRlcyB0aGF0IHRoZSBxdWVyeSBzdHJpbmcgc2hvdWxkIGFsc28gYmUgcGFyc2VkLlxuICAvL1xuICAvLyAyLiBUaGUgYFVSTGAgaW50ZXJmYWNlIG9mIHRoZSBicm93c2VyIHdoaWNoIGFjY2VwdHMgYSBVUkwsIG9iamVjdCBhc1xuICAvLyAgICBhcmd1bWVudHMuIFRoZSBzdXBwbGllZCBvYmplY3Qgd2lsbCBiZSB1c2VkIGFzIGRlZmF1bHQgdmFsdWVzIC8gZmFsbC1iYWNrXG4gIC8vICAgIGZvciByZWxhdGl2ZSBwYXRocy5cbiAgLy9cbiAgaWYgKCdvYmplY3QnICE9PSB0eXBlICYmICdzdHJpbmcnICE9PSB0eXBlKSB7XG4gICAgcGFyc2VyID0gbG9jYXRpb247XG4gICAgbG9jYXRpb24gPSBudWxsO1xuICB9XG5cbiAgaWYgKHBhcnNlciAmJiAnZnVuY3Rpb24nICE9PSB0eXBlb2YgcGFyc2VyKSBwYXJzZXIgPSBxcy5wYXJzZTtcblxuICBsb2NhdGlvbiA9IGxvbGNhdGlvbihsb2NhdGlvbik7XG5cbiAgLy9cbiAgLy8gRXh0cmFjdCBwcm90b2NvbCBpbmZvcm1hdGlvbiBiZWZvcmUgcnVubmluZyB0aGUgaW5zdHJ1Y3Rpb25zLlxuICAvL1xuICBleHRyYWN0ZWQgPSBleHRyYWN0UHJvdG9jb2woYWRkcmVzcyB8fCAnJyk7XG4gIHJlbGF0aXZlID0gIWV4dHJhY3RlZC5wcm90b2NvbCAmJiAhZXh0cmFjdGVkLnNsYXNoZXM7XG4gIHVybC5zbGFzaGVzID0gZXh0cmFjdGVkLnNsYXNoZXMgfHwgcmVsYXRpdmUgJiYgbG9jYXRpb24uc2xhc2hlcztcbiAgdXJsLnByb3RvY29sID0gZXh0cmFjdGVkLnByb3RvY29sIHx8IGxvY2F0aW9uLnByb3RvY29sIHx8ICcnO1xuICBhZGRyZXNzID0gZXh0cmFjdGVkLnJlc3Q7XG5cbiAgLy9cbiAgLy8gV2hlbiB0aGUgYXV0aG9yaXR5IGNvbXBvbmVudCBpcyBhYnNlbnQgdGhlIFVSTCBzdGFydHMgd2l0aCBhIHBhdGhcbiAgLy8gY29tcG9uZW50LlxuICAvL1xuICBpZiAoIWV4dHJhY3RlZC5zbGFzaGVzKSBpbnN0cnVjdGlvbnNbMl0gPSBbLyguKikvLCAncGF0aG5hbWUnXTtcblxuICBmb3IgKDsgaSA8IGluc3RydWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIGluc3RydWN0aW9uID0gaW5zdHJ1Y3Rpb25zW2ldO1xuICAgIHBhcnNlID0gaW5zdHJ1Y3Rpb25bMF07XG4gICAga2V5ID0gaW5zdHJ1Y3Rpb25bMV07XG5cbiAgICBpZiAocGFyc2UgIT09IHBhcnNlKSB7XG4gICAgICB1cmxba2V5XSA9IGFkZHJlc3M7XG4gICAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHBhcnNlKSB7XG4gICAgICBpZiAofihpbmRleCA9IGFkZHJlc3MuaW5kZXhPZihwYXJzZSkpKSB7XG4gICAgICAgIGlmICgnbnVtYmVyJyA9PT0gdHlwZW9mIGluc3RydWN0aW9uWzJdKSB7XG4gICAgICAgICAgdXJsW2tleV0gPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgICBhZGRyZXNzID0gYWRkcmVzcy5zbGljZShpbmRleCArIGluc3RydWN0aW9uWzJdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cmxba2V5XSA9IGFkZHJlc3Muc2xpY2UoaW5kZXgpO1xuICAgICAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKGluZGV4ID0gcGFyc2UuZXhlYyhhZGRyZXNzKSkpIHtcbiAgICAgIHVybFtrZXldID0gaW5kZXhbMV07XG4gICAgICBhZGRyZXNzID0gYWRkcmVzcy5zbGljZSgwLCBpbmRleC5pbmRleCk7XG4gICAgfVxuXG4gICAgdXJsW2tleV0gPSB1cmxba2V5XSB8fCAoXG4gICAgICByZWxhdGl2ZSAmJiBpbnN0cnVjdGlvblszXSA/IGxvY2F0aW9uW2tleV0gfHwgJycgOiAnJ1xuICAgICk7XG5cbiAgICAvL1xuICAgIC8vIEhvc3RuYW1lLCBob3N0IGFuZCBwcm90b2NvbCBzaG91bGQgYmUgbG93ZXJjYXNlZCBzbyB0aGV5IGNhbiBiZSB1c2VkIHRvXG4gICAgLy8gY3JlYXRlIGEgcHJvcGVyIGBvcmlnaW5gLlxuICAgIC8vXG4gICAgaWYgKGluc3RydWN0aW9uWzRdKSB1cmxba2V5XSA9IHVybFtrZXldLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvL1xuICAvLyBBbHNvIHBhcnNlIHRoZSBzdXBwbGllZCBxdWVyeSBzdHJpbmcgaW4gdG8gYW4gb2JqZWN0LiBJZiB3ZSdyZSBzdXBwbGllZFxuICAvLyB3aXRoIGEgY3VzdG9tIHBhcnNlciBhcyBmdW5jdGlvbiB1c2UgdGhhdCBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IGJ1aWxkLWluXG4gIC8vIHBhcnNlci5cbiAgLy9cbiAgaWYgKHBhcnNlcikgdXJsLnF1ZXJ5ID0gcGFyc2VyKHVybC5xdWVyeSk7XG5cbiAgLy9cbiAgLy8gSWYgdGhlIFVSTCBpcyByZWxhdGl2ZSwgcmVzb2x2ZSB0aGUgcGF0aG5hbWUgYWdhaW5zdCB0aGUgYmFzZSBVUkwuXG4gIC8vXG4gIGlmIChcbiAgICAgIHJlbGF0aXZlXG4gICAgJiYgbG9jYXRpb24uc2xhc2hlc1xuICAgICYmIHVybC5wYXRobmFtZS5jaGFyQXQoMCkgIT09ICcvJ1xuICAgICYmICh1cmwucGF0aG5hbWUgIT09ICcnIHx8IGxvY2F0aW9uLnBhdGhuYW1lICE9PSAnJylcbiAgKSB7XG4gICAgdXJsLnBhdGhuYW1lID0gcmVzb2x2ZSh1cmwucGF0aG5hbWUsIGxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgfVxuXG4gIC8vXG4gIC8vIFdlIHNob3VsZCBub3QgYWRkIHBvcnQgbnVtYmVycyBpZiB0aGV5IGFyZSBhbHJlYWR5IHRoZSBkZWZhdWx0IHBvcnQgbnVtYmVyXG4gIC8vIGZvciBhIGdpdmVuIHByb3RvY29sLiBBcyB0aGUgaG9zdCBhbHNvIGNvbnRhaW5zIHRoZSBwb3J0IG51bWJlciB3ZSdyZSBnb2luZ1xuICAvLyBvdmVycmlkZSBpdCB3aXRoIHRoZSBob3N0bmFtZSB3aGljaCBjb250YWlucyBubyBwb3J0IG51bWJlci5cbiAgLy9cbiAgaWYgKCFyZXF1aXJlZCh1cmwucG9ydCwgdXJsLnByb3RvY29sKSkge1xuICAgIHVybC5ob3N0ID0gdXJsLmhvc3RuYW1lO1xuICAgIHVybC5wb3J0ID0gJyc7XG4gIH1cblxuICAvL1xuICAvLyBQYXJzZSBkb3duIHRoZSBgYXV0aGAgZm9yIHRoZSB1c2VybmFtZSBhbmQgcGFzc3dvcmQuXG4gIC8vXG4gIHVybC51c2VybmFtZSA9IHVybC5wYXNzd29yZCA9ICcnO1xuICBpZiAodXJsLmF1dGgpIHtcbiAgICBpbnN0cnVjdGlvbiA9IHVybC5hdXRoLnNwbGl0KCc6Jyk7XG4gICAgdXJsLnVzZXJuYW1lID0gaW5zdHJ1Y3Rpb25bMF0gfHwgJyc7XG4gICAgdXJsLnBhc3N3b3JkID0gaW5zdHJ1Y3Rpb25bMV0gfHwgJyc7XG4gIH1cblxuICB1cmwub3JpZ2luID0gdXJsLnByb3RvY29sICYmIHVybC5ob3N0ICYmIHVybC5wcm90b2NvbCAhPT0gJ2ZpbGU6J1xuICAgID8gdXJsLnByb3RvY29sICsnLy8nKyB1cmwuaG9zdFxuICAgIDogJ251bGwnO1xuXG4gIC8vXG4gIC8vIFRoZSBocmVmIGlzIGp1c3QgdGhlIGNvbXBpbGVkIHJlc3VsdC5cbiAgLy9cbiAgdXJsLmhyZWYgPSB1cmwudG9TdHJpbmcoKTtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IgY2hhbmdpbmcgcHJvcGVydGllcyBpbiB0aGUgVVJMIGluc3RhbmNlIHRvXG4gKiBpbnN1cmUgdGhhdCB0aGV5IGFsbCBwcm9wYWdhdGUgY29ycmVjdGx5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXJ0ICAgICAgICAgIFByb3BlcnR5IHdlIG5lZWQgdG8gYWRqdXN0LlxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgICAgICAgICAgVGhlIG5ld2x5IGFzc2lnbmVkIHZhbHVlLlxuICogQHBhcmFtIHtCb29sZWFufEZ1bmN0aW9ufSBmbiAgV2hlbiBzZXR0aW5nIHRoZSBxdWVyeSwgaXQgd2lsbCBiZSB0aGUgZnVuY3Rpb25cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgdG8gcGFyc2UgdGhlIHF1ZXJ5LlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2hlbiBzZXR0aW5nIHRoZSBwcm90b2NvbCwgZG91YmxlIHNsYXNoIHdpbGwgYmVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgZnJvbSB0aGUgZmluYWwgdXJsIGlmIGl0IGlzIHRydWUuXG4gKiBAcmV0dXJucyB7VVJMfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gc2V0KHBhcnQsIHZhbHVlLCBmbikge1xuICB2YXIgdXJsID0gdGhpcztcblxuICBzd2l0Y2ggKHBhcnQpIHtcbiAgICBjYXNlICdxdWVyeSc6XG4gICAgICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB2YWx1ZSAmJiB2YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgdmFsdWUgPSAoZm4gfHwgcXMucGFyc2UpKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3BvcnQnOlxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG5cbiAgICAgIGlmICghcmVxdWlyZWQodmFsdWUsIHVybC5wcm90b2NvbCkpIHtcbiAgICAgICAgdXJsLmhvc3QgPSB1cmwuaG9zdG5hbWU7XG4gICAgICAgIHVybFtwYXJ0XSA9ICcnO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgICB1cmwuaG9zdCA9IHVybC5ob3N0bmFtZSArJzonKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdob3N0bmFtZSc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKHVybC5wb3J0KSB2YWx1ZSArPSAnOicrIHVybC5wb3J0O1xuICAgICAgdXJsLmhvc3QgPSB2YWx1ZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaG9zdCc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKC86XFxkKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoJzonKTtcbiAgICAgICAgdXJsLnBvcnQgPSB2YWx1ZS5wb3AoKTtcbiAgICAgICAgdXJsLmhvc3RuYW1lID0gdmFsdWUuam9pbignOicpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJsLmhvc3RuYW1lID0gdmFsdWU7XG4gICAgICAgIHVybC5wb3J0ID0gJyc7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncHJvdG9jb2wnOlxuICAgICAgdXJsLnByb3RvY29sID0gdmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIHVybC5zbGFzaGVzID0gIWZuO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwYXRobmFtZSc6XG4gICAgY2FzZSAnaGFzaCc6XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFyIGNoYXIgPSBwYXJ0ID09PSAncGF0aG5hbWUnID8gJy8nIDogJyMnO1xuICAgICAgICB1cmxbcGFydF0gPSB2YWx1ZS5jaGFyQXQoMCkgIT09IGNoYXIgPyBjaGFyICsgdmFsdWUgOiB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJ1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGlucyA9IHJ1bGVzW2ldO1xuXG4gICAgaWYgKGluc1s0XSkgdXJsW2luc1sxXV0gPSB1cmxbaW5zWzFdXS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgdXJsLm9yaWdpbiA9IHVybC5wcm90b2NvbCAmJiB1cmwuaG9zdCAmJiB1cmwucHJvdG9jb2wgIT09ICdmaWxlOidcbiAgICA/IHVybC5wcm90b2NvbCArJy8vJysgdXJsLmhvc3RcbiAgICA6ICdudWxsJztcblxuICB1cmwuaHJlZiA9IHVybC50b1N0cmluZygpO1xuXG4gIHJldHVybiB1cmw7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBwcm9wZXJ0aWVzIGJhY2sgaW4gdG8gYSB2YWxpZCBhbmQgZnVsbCBVUkwgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZ2lmeSBPcHRpb25hbCBxdWVyeSBzdHJpbmdpZnkgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gdG9TdHJpbmcoc3RyaW5naWZ5KSB7XG4gIGlmICghc3RyaW5naWZ5IHx8ICdmdW5jdGlvbicgIT09IHR5cGVvZiBzdHJpbmdpZnkpIHN0cmluZ2lmeSA9IHFzLnN0cmluZ2lmeTtcblxuICB2YXIgcXVlcnlcbiAgICAsIHVybCA9IHRoaXNcbiAgICAsIHByb3RvY29sID0gdXJsLnByb3RvY29sO1xuXG4gIGlmIChwcm90b2NvbCAmJiBwcm90b2NvbC5jaGFyQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09ICc6JykgcHJvdG9jb2wgKz0gJzonO1xuXG4gIHZhciByZXN1bHQgPSBwcm90b2NvbCArICh1cmwuc2xhc2hlcyA/ICcvLycgOiAnJyk7XG5cbiAgaWYgKHVybC51c2VybmFtZSkge1xuICAgIHJlc3VsdCArPSB1cmwudXNlcm5hbWU7XG4gICAgaWYgKHVybC5wYXNzd29yZCkgcmVzdWx0ICs9ICc6JysgdXJsLnBhc3N3b3JkO1xuICAgIHJlc3VsdCArPSAnQCc7XG4gIH1cblxuICByZXN1bHQgKz0gdXJsLmhvc3QgKyB1cmwucGF0aG5hbWU7XG5cbiAgcXVlcnkgPSAnb2JqZWN0JyA9PT0gdHlwZW9mIHVybC5xdWVyeSA/IHN0cmluZ2lmeSh1cmwucXVlcnkpIDogdXJsLnF1ZXJ5O1xuICBpZiAocXVlcnkpIHJlc3VsdCArPSAnPycgIT09IHF1ZXJ5LmNoYXJBdCgwKSA/ICc/JysgcXVlcnkgOiBxdWVyeTtcblxuICBpZiAodXJsLmhhc2gpIHJlc3VsdCArPSB1cmwuaGFzaDtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5VUkwucHJvdG90eXBlID0geyBzZXQ6IHNldCwgdG9TdHJpbmc6IHRvU3RyaW5nIH07XG5cbi8vXG4vLyBFeHBvc2UgdGhlIFVSTCBwYXJzZXIgYW5kIHNvbWUgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRoYXQgbWlnaHQgYmUgdXNlZnVsIGZvclxuLy8gb3RoZXJzIG9yIHRlc3RpbmcuXG4vL1xuVVJMLmV4dHJhY3RQcm90b2NvbCA9IGV4dHJhY3RQcm90b2NvbDtcblVSTC5sb2NhdGlvbiA9IGxvbGNhdGlvbjtcblVSTC5xcyA9IHFzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFVSTDtcbiIsIi8qXG4qIFRoaXMgZGVsYXkgYWxsb3dzIHRoZSB0aHJlYWQgdG8gZmluaXNoIGFzc2lnbmluZyBpdHMgb24qIG1ldGhvZHNcbiogYmVmb3JlIGludm9raW5nIHRoZSBkZWxheSBjYWxsYmFjay4gVGhpcyBpcyBwdXJlbHkgYSB0aW1pbmcgaGFjay5cbiogaHR0cDovL2dlZWthYnl0ZS5ibG9nc3BvdC5jb20vMjAxNC8wMS9qYXZhc2NyaXB0LWVmZmVjdC1vZi1zZXR0aW5nLXNldHRpbWVvdXQuaHRtbFxuKlxuKiBAcGFyYW0ge2NhbGxiYWNrOiBmdW5jdGlvbn0gdGhlIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgaW52b2tlZCBhZnRlciB0aGUgdGltZW91dFxuKiBAcGFybWEge2NvbnRleHQ6IG9iamVjdH0gdGhlIGNvbnRleHQgaW4gd2hpY2ggdG8gaW52b2tlIHRoZSBmdW5jdGlvblxuKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRlbGF5KGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIHNldFRpbWVvdXQodGltZW91dENvbnRleHQgPT4gY2FsbGJhY2suY2FsbCh0aW1lb3V0Q29udGV4dCksIDQsIGNvbnRleHQpO1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbG9nKG1ldGhvZCwgbWVzc2FnZSkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0Jykge1xuICAgIGNvbnNvbGVbbWV0aG9kXS5jYWxsKG51bGwsIG1lc3NhZ2UpO1xuICB9XG4gIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIHJlamVjdChhcnJheSwgY2FsbGJhY2spIHtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBhcnJheS5mb3JFYWNoKGl0ZW1JbkFycmF5ID0+IHtcbiAgICBpZiAoIWNhbGxiYWNrKGl0ZW1JbkFycmF5KSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGl0ZW1JbkFycmF5KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyKGFycmF5LCBjYWxsYmFjaykge1xuICBjb25zdCByZXN1bHRzID0gW107XG4gIGFycmF5LmZvckVhY2goaXRlbUluQXJyYXkgPT4ge1xuICAgIGlmIChjYWxsYmFjayhpdGVtSW5BcnJheSkpIHtcbiAgICAgIHJlc3VsdHMucHVzaChpdGVtSW5BcnJheSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0cztcbn1cbiIsImltcG9ydCB7IHJlamVjdCwgZmlsdGVyIH0gZnJvbSAnLi4vaGVscGVycy9hcnJheS1oZWxwZXJzJztcblxuLypcbiogRXZlbnRUYXJnZXQgaXMgYW4gaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IG9iamVjdHMgdGhhdCBjYW5cbiogcmVjZWl2ZSBldmVudHMgYW5kIG1heSBoYXZlIGxpc3RlbmVycyBmb3IgdGhlbS5cbipcbiogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0XG4qL1xuY2xhc3MgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpc3RlbmVycyA9IHt9O1xuICB9XG5cbiAgLypcbiAgKiBUaWVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYW4gZXZlbnQgdHlwZSB3aGljaCBjYW4gbGF0ZXIgYmUgaW52b2tlZCB2aWEgdGhlXG4gICogZGlzcGF0Y2hFdmVudCBtZXRob2QuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIHRoZSB0eXBlIG9mIGV2ZW50IChpZTogJ29wZW4nLCAnbWVzc2FnZScsIGV0Yy4pXG4gICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWQgbWF0Y2hpbmcgdGhlIGdpdmVuIHR5cGVcbiAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUNhcHR1cmUgLSBOL0EgVE9ETzogaW1wbGVtZW50IHVzZUNhcHR1cmUgZnVuY3Rpb25hbGl0eVxuICAqL1xuICBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyIC8qICwgdXNlQ2FwdHVyZSAqLykge1xuICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmxpc3RlbmVyc1t0eXBlXSkpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbdHlwZV0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBhZGQgdGhlIHNhbWUgZnVuY3Rpb24gb25jZVxuICAgICAgaWYgKGZpbHRlcih0aGlzLmxpc3RlbmVyc1t0eXBlXSwgaXRlbSA9PiBpdGVtID09PSBsaXN0ZW5lcikubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgc28gaXQgd2lsbCBubyBsb25nZXIgYmUgaW52b2tlZCB2aWEgdGhlIGRpc3BhdGNoRXZlbnQgbWV0aG9kLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSB0aGUgdHlwZSBvZiBldmVudCAoaWU6ICdvcGVuJywgJ21lc3NhZ2UnLCBldGMuKVxuICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIC0gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGludm9rZSB3aGVuZXZlciBhbiBldmVudCBpcyBkaXNwYXRjaGVkIG1hdGNoaW5nIHRoZSBnaXZlbiB0eXBlXG4gICogQHBhcmFtIHtib29sZWFufSB1c2VDYXB0dXJlIC0gTi9BIFRPRE86IGltcGxlbWVudCB1c2VDYXB0dXJlIGZ1bmN0aW9uYWxpdHlcbiAgKi9cbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCByZW1vdmluZ0xpc3RlbmVyIC8qICwgdXNlQ2FwdHVyZSAqLykge1xuICAgIGNvbnN0IGFycmF5T2ZMaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1t0eXBlXTtcbiAgICB0aGlzLmxpc3RlbmVyc1t0eXBlXSA9IHJlamVjdChhcnJheU9mTGlzdGVuZXJzLCBsaXN0ZW5lciA9PiBsaXN0ZW5lciA9PT0gcmVtb3ZpbmdMaXN0ZW5lcik7XG4gIH1cblxuICAvKlxuICAqIEludm9rZXMgYWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyB0aGF0IGFyZSBsaXN0ZW5pbmcgdG8gdGhlIGdpdmVuIGV2ZW50LnR5cGUgcHJvcGVydHkuIEVhY2hcbiAgKiBsaXN0ZW5lciB3aWxsIGJlIHBhc3NlZCB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gZXZlbnQgb2JqZWN0IHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGFsbCBsaXN0ZW5lcnMgb2YgdGhlIGV2ZW50LnR5cGUgcHJvcGVydHlcbiAgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgLi4uY3VzdG9tQXJndW1lbnRzKSB7XG4gICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQudHlwZTtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3RlbmVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgICBpZiAoY3VzdG9tQXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgY3VzdG9tQXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRUYXJnZXQ7XG4iLCJpbXBvcnQgeyByZWplY3QgfSBmcm9tICcuL2hlbHBlcnMvYXJyYXktaGVscGVycyc7XG5cbi8qXG4qIFRoZSBuZXR3b3JrIGJyaWRnZSBpcyBhIHdheSBmb3IgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCB0byAnY29tbXVuaWNhdGUnIHdpdGhcbiogYWxsIGF2YWlsYWJsZSBzZXJ2ZXJzLiBUaGlzIGlzIGEgc2luZ2xldG9uIG9iamVjdCBzbyBpdCBpcyBpbXBvcnRhbnQgdGhhdCB5b3VcbiogY2xlYW4gdXAgdXJsTWFwIHdoZW5ldmVyIHlvdSBhcmUgZmluaXNoZWQuXG4qL1xuY2xhc3MgTmV0d29ya0JyaWRnZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudXJsTWFwID0ge307XG4gIH1cblxuICAvKlxuICAqIEF0dGFjaGVzIGEgd2Vic29ja2V0IG9iamVjdCB0byB0aGUgdXJsTWFwIGhhc2ggc28gdGhhdCBpdCBjYW4gZmluZCB0aGUgc2VydmVyXG4gICogaXQgaXMgY29ubmVjdGVkIHRvIGFuZCB0aGUgc2VydmVyIGluIHR1cm4gY2FuIGZpbmQgaXQuXG4gICpcbiAgKiBAcGFyYW0ge29iamVjdH0gd2Vic29ja2V0IC0gd2Vic29ja2V0IG9iamVjdCB0byBhZGQgdG8gdGhlIHVybE1hcCBoYXNoXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICBhdHRhY2hXZWJTb2NrZXQod2Vic29ja2V0LCB1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwICYmIGNvbm5lY3Rpb25Mb29rdXAuc2VydmVyICYmIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cy5pbmRleE9mKHdlYnNvY2tldCkgPT09IC0xKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMucHVzaCh3ZWJzb2NrZXQpO1xuICAgICAgcmV0dXJuIGNvbm5lY3Rpb25Mb29rdXAuc2VydmVyO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSB3ZWJzb2NrZXQgdG8gYSByb29tXG4gICovXG4gIGFkZE1lbWJlcnNoaXBUb1Jvb20od2Vic29ja2V0LCByb29tKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3dlYnNvY2tldC51cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXAgJiYgY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXIgJiYgY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLmluZGV4T2Yod2Vic29ja2V0KSAhPT0gLTEpIHtcbiAgICAgIGlmICghY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0pIHtcbiAgICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0ucHVzaCh3ZWJzb2NrZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSBzZXJ2ZXIgb2JqZWN0IHRvIHRoZSB1cmxNYXAgaGFzaCBzbyB0aGF0IGl0IGNhbiBmaW5kIGEgd2Vic29ja2V0c1xuICAqIHdoaWNoIGFyZSBjb25uZWN0ZWQgdG8gaXQgYW5kIHNvIHRoYXQgd2Vic29ja2V0cyBjYW4gaW4gdHVybiBjYW4gZmluZCBpdC5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSBzZXJ2ZXIgLSBzZXJ2ZXIgb2JqZWN0IHRvIGFkZCB0byB0aGUgdXJsTWFwIGhhc2hcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIGF0dGFjaFNlcnZlcihzZXJ2ZXIsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKCFjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICB0aGlzLnVybE1hcFt1cmxdID0ge1xuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIHdlYnNvY2tldHM6IFtdLFxuICAgICAgICByb29tTWVtYmVyc2hpcHM6IHt9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VydmVyO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogRmluZHMgdGhlIHNlcnZlciB3aGljaCBpcyAncnVubmluZycgb24gdGhlIGdpdmVuIHVybC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSB0aGUgdXJsIHRvIHVzZSB0byBmaW5kIHdoaWNoIHNlcnZlciBpcyBydW5uaW5nIG9uIGl0XG4gICovXG4gIHNlcnZlckxvb2t1cCh1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICByZXR1cm4gY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBGaW5kcyBhbGwgd2Vic29ja2V0cyB3aGljaCBpcyAnbGlzdGVuaW5nJyBvbiB0aGUgZ2l2ZW4gdXJsLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIHRoZSB1cmwgdG8gdXNlIHRvIGZpbmQgYWxsIHdlYnNvY2tldHMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBpdFxuICAqIEBwYXJhbSB7c3RyaW5nfSByb29tIC0gaWYgYSByb29tIGlzIHByb3ZpZGVkLCB3aWxsIG9ubHkgcmV0dXJuIHNvY2tldHMgaW4gdGhpcyByb29tXG4gICogQHBhcmFtIHtjbGFzc30gYnJvYWRjYXN0ZXIgLSBzb2NrZXQgdGhhdCBpcyBicm9hZGNhc3RpbmcgYW5kIGlzIHRvIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIGxvb2t1cFxuICAqL1xuICB3ZWJzb2NrZXRzTG9va3VwKHVybCwgcm9vbSwgYnJvYWRjYXN0ZXIpIHtcbiAgICBsZXQgd2Vic29ja2V0cztcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIHdlYnNvY2tldHMgPSBjb25uZWN0aW9uTG9va3VwID8gY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzIDogW107XG5cbiAgICBpZiAocm9vbSkge1xuICAgICAgY29uc3QgbWVtYmVycyA9IGNvbm5lY3Rpb25Mb29rdXAucm9vbU1lbWJlcnNoaXBzW3Jvb21dO1xuICAgICAgd2Vic29ja2V0cyA9IG1lbWJlcnMgfHwgW107XG4gICAgfVxuXG4gICAgcmV0dXJuIGJyb2FkY2FzdGVyID8gd2Vic29ja2V0cy5maWx0ZXIod2Vic29ja2V0ID0+IHdlYnNvY2tldCAhPT0gYnJvYWRjYXN0ZXIpIDogd2Vic29ja2V0cztcbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgZW50cnkgYXNzb2NpYXRlZCB3aXRoIHRoZSB1cmwuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIHJlbW92ZVNlcnZlcih1cmwpIHtcbiAgICBkZWxldGUgdGhpcy51cmxNYXBbdXJsXTtcbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgaW5kaXZpZHVhbCB3ZWJzb2NrZXQgZnJvbSB0aGUgbWFwIG9mIGFzc29jaWF0ZWQgd2Vic29ja2V0cy5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSB3ZWJzb2NrZXQgLSB3ZWJzb2NrZXQgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoZSB1cmwgbWFwXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICByZW1vdmVXZWJTb2NrZXQod2Vic29ja2V0LCB1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMgPSByZWplY3QoY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLCBzb2NrZXQgPT4gc29ja2V0ID09PSB3ZWJzb2NrZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyBhIHdlYnNvY2tldCBmcm9tIGEgcm9vbVxuICAqL1xuICByZW1vdmVNZW1iZXJzaGlwRnJvbVJvb20od2Vic29ja2V0LCByb29tKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3dlYnNvY2tldC51cmxdO1xuICAgIGNvbnN0IG1lbWJlcnNoaXBzID0gY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV07XG5cbiAgICBpZiAoY29ubmVjdGlvbkxvb2t1cCAmJiBtZW1iZXJzaGlwcyAhPT0gbnVsbCkge1xuICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0gPSByZWplY3QobWVtYmVyc2hpcHMsIHNvY2tldCA9PiBzb2NrZXQgPT09IHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBOZXR3b3JrQnJpZGdlKCk7IC8vIE5vdGU6IHRoaXMgaXMgYSBzaW5nbGV0b25cbiIsIi8qXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ2xvc2VFdmVudFxuICovXG5leHBvcnQgY29uc3QgQ0xPU0VfQ09ERVMgPSB7XG4gIENMT1NFX05PUk1BTDogMTAwMCxcbiAgQ0xPU0VfR09JTkdfQVdBWTogMTAwMSxcbiAgQ0xPU0VfUFJPVE9DT0xfRVJST1I6IDEwMDIsXG4gIENMT1NFX1VOU1VQUE9SVEVEOiAxMDAzLFxuICBDTE9TRV9OT19TVEFUVVM6IDEwMDUsXG4gIENMT1NFX0FCTk9STUFMOiAxMDA2LFxuICBVTlNVUFBPUlRFRF9EQVRBOiAxMDA3LFxuICBQT0xJQ1lfVklPTEFUSU9OOiAxMDA4LFxuICBDTE9TRV9UT09fTEFSR0U6IDEwMDksXG4gIE1JU1NJTkdfRVhURU5TSU9OOiAxMDEwLFxuICBJTlRFUk5BTF9FUlJPUjogMTAxMSxcbiAgU0VSVklDRV9SRVNUQVJUOiAxMDEyLFxuICBUUllfQUdBSU5fTEFURVI6IDEwMTMsXG4gIFRMU19IQU5EU0hBS0U6IDEwMTVcbn07XG5cbmV4cG9ydCBjb25zdCBFUlJPUl9QUkVGSVggPSB7XG4gIENPTlNUUlVDVE9SX0VSUk9SOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ1dlYlNvY2tldCc6XCIsXG4gIENMT1NFX0VSUk9SOiBcIkZhaWxlZCB0byBleGVjdXRlICdjbG9zZScgb24gJ1dlYlNvY2tldCc6XCIsXG4gIEVWRU5UOiB7XG4gICAgQ09OU1RSVUNUOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ0V2ZW50JzpcIixcbiAgICBNRVNTQUdFOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ01lc3NhZ2VFdmVudCc6XCIsXG4gICAgQ0xPU0U6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnQ2xvc2VFdmVudCc6XCJcbiAgfVxufTtcbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50UHJvdG90eXBlIHtcbiAgLy8gTm9vcHNcbiAgc3RvcFByb3BhZ2F0aW9uKCkge31cbiAgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge31cblxuICAvLyBpZiBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCB0aGVuIHRoZSB0eXBlIGlzIHNldCB0byBcInVuZGVmaW5lZFwiIG9uXG4gIC8vIGNocm9tZSBhbmQgc2FmYXJpLlxuICBpbml0RXZlbnQodHlwZSA9ICd1bmRlZmluZWQnLCBidWJibGVzID0gZmFsc2UsIGNhbmNlbGFibGUgPSBmYWxzZSkge1xuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLmJ1YmJsZXMgPSBCb29sZWFuKGJ1YmJsZXMpO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IEJvb2xlYW4oY2FuY2VsYWJsZSk7XG4gIH1cbn1cbiIsImltcG9ydCBFdmVudFByb3RvdHlwZSBmcm9tICcuL3Byb3RvdHlwZSc7XG5pbXBvcnQgeyBFUlJPUl9QUkVGSVggfSBmcm9tICcuLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVF9FUlJPUn0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXZlbnRJbml0Q29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlRfRVJST1J9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3QuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5uY2VsQnViYmxlID0gZmFsc2U7XG4gICAgdGhpcy5idWJibGVzID0gYnViYmxlcyA/IEJvb2xlYW4oYnViYmxlcykgOiBmYWxzZTtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1lc3NhZ2VFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5NRVNTQUdFfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBldmVudEluaXRDb25maWcgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5NRVNTQUdFfSBwYXJhbWV0ZXIgMiAoJ2V2ZW50SW5pdERpY3QnKSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlLCBkYXRhLCBvcmlnaW4sIGxhc3RFdmVudElkLCBwb3J0cyB9ID0gZXZlbnRJbml0Q29uZmlnO1xuXG4gICAgdGhpcy50eXBlID0gYCR7dHlwZX1gO1xuICAgIHRoaXMudGltZVN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5zcmNFbGVtZW50ID0gbnVsbDtcbiAgICB0aGlzLnJldHVyblZhbHVlID0gdHJ1ZTtcbiAgICB0aGlzLmlzVHJ1c3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuZXZlbnRQaGFzZSA9IDA7XG4gICAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG4gICAgdGhpcy5jdXJyZW50VGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlID8gQm9vbGVhbihjYW5jZWxhYmxlKSA6IGZhbHNlO1xuICAgIHRoaXMuY2FubmNlbEJ1YmJsZSA9IGZhbHNlO1xuICAgIHRoaXMuYnViYmxlcyA9IGJ1YmJsZXMgPyBCb29sZWFuKGJ1YmJsZXMpIDogZmFsc2U7XG4gICAgdGhpcy5vcmlnaW4gPSBgJHtvcmlnaW59YDtcbiAgICB0aGlzLnBvcnRzID0gdHlwZW9mIHBvcnRzID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBwb3J0cztcbiAgICB0aGlzLmRhdGEgPSB0eXBlb2YgZGF0YSA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogZGF0YTtcbiAgICB0aGlzLmxhc3RFdmVudElkID0gYCR7bGFzdEV2ZW50SWQgfHwgJyd9YDtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENsb3NlRXZlbnQgZXh0ZW5kcyBFdmVudFByb3RvdHlwZSB7XG4gIGNvbnN0cnVjdG9yKHR5cGUsIGV2ZW50SW5pdENvbmZpZyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICghdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlQuQ0xPU0V9IDEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC5gKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50SW5pdENvbmZpZyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULkNMT1NFfSBwYXJhbWV0ZXIgMiAoJ2V2ZW50SW5pdERpY3QnKSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlLCBjb2RlLCByZWFzb24sIHdhc0NsZWFuIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5jZWxCdWJibGUgPSBmYWxzZTtcbiAgICB0aGlzLmJ1YmJsZXMgPSBidWJibGVzID8gQm9vbGVhbihidWJibGVzKSA6IGZhbHNlO1xuICAgIHRoaXMuY29kZSA9IHR5cGVvZiBjb2RlID09PSAnbnVtYmVyJyA/IHBhcnNlSW50KGNvZGUsIDEwKSA6IDA7XG4gICAgdGhpcy5yZWFzb24gPSBgJHtyZWFzb24gfHwgJyd9YDtcbiAgICB0aGlzLndhc0NsZWFuID0gd2FzQ2xlYW4gPyBCb29sZWFuKHdhc0NsZWFuKSA6IGZhbHNlO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnQgZnJvbSAnLi9ldmVudCc7XG5pbXBvcnQgTWVzc2FnZUV2ZW50IGZyb20gJy4vbWVzc2FnZSc7XG5pbXBvcnQgQ2xvc2VFdmVudCBmcm9tICcuL2Nsb3NlJztcblxuLypcbiogQ3JlYXRlcyBhbiBFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnIHlvdSB3aWxsIG5lZWQgdG8gcGFzcyB0eXBlIGFuZCBvcHRpb25hbGx5IHRhcmdldFxuKi9cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IHR5cGUsIHRhcmdldCB9ID0gY29uZmlnO1xuICBjb25zdCBldmVudE9iamVjdCA9IG5ldyBFdmVudCh0eXBlKTtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgZXZlbnRPYmplY3QudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGV2ZW50T2JqZWN0LnNyY0VsZW1lbnQgPSB0YXJnZXQ7XG4gICAgZXZlbnRPYmplY3QuY3VycmVudFRhcmdldCA9IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBldmVudE9iamVjdDtcbn1cblxuLypcbiogQ3JlYXRlcyBhIE1lc3NhZ2VFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnOiB0eXBlLCBvcmlnaW4sIGRhdGEgYW5kIG9wdGlvbmFsbHkgdGFyZ2V0XG4qL1xuZnVuY3Rpb24gY3JlYXRlTWVzc2FnZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IHR5cGUsIG9yaWdpbiwgZGF0YSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGNvbnN0IG1lc3NhZ2VFdmVudCA9IG5ldyBNZXNzYWdlRXZlbnQodHlwZSwge1xuICAgIGRhdGEsXG4gICAgb3JpZ2luXG4gIH0pO1xuXG4gIGlmICh0YXJnZXQpIHtcbiAgICBtZXNzYWdlRXZlbnQudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIG1lc3NhZ2VFdmVudC5zcmNFbGVtZW50ID0gdGFyZ2V0O1xuICAgIG1lc3NhZ2VFdmVudC5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIG1lc3NhZ2VFdmVudDtcbn1cblxuLypcbiogQ3JlYXRlcyBhIENsb3NlRXZlbnQgb2JqZWN0IGFuZCBleHRlbmRzIGl0IHRvIGFsbG93IGZ1bGwgbW9kaWZpY2F0aW9uIG9mXG4qIGl0cyBwcm9wZXJ0aWVzLlxuKlxuKiBAcGFyYW0ge29iamVjdH0gY29uZmlnIC0gd2l0aGluIGNvbmZpZzogdHlwZSBhbmQgb3B0aW9uYWxseSB0YXJnZXQsIGNvZGUsIGFuZCByZWFzb25cbiovXG5mdW5jdGlvbiBjcmVhdGVDbG9zZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IGNvZGUsIHJlYXNvbiwgdHlwZSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGxldCB7IHdhc0NsZWFuIH0gPSBjb25maWc7XG5cbiAgaWYgKCF3YXNDbGVhbikge1xuICAgIHdhc0NsZWFuID0gY29kZSA9PT0gMTAwMDtcbiAgfVxuXG4gIGNvbnN0IGNsb3NlRXZlbnQgPSBuZXcgQ2xvc2VFdmVudCh0eXBlLCB7XG4gICAgY29kZSxcbiAgICByZWFzb24sXG4gICAgd2FzQ2xlYW5cbiAgfSk7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIGNsb3NlRXZlbnQudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGNsb3NlRXZlbnQuc3JjRWxlbWVudCA9IHRhcmdldDtcbiAgICBjbG9zZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cblxuICByZXR1cm4gY2xvc2VFdmVudDtcbn1cblxuZXhwb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9O1xuIiwiaW1wb3J0IFdlYlNvY2tldCBmcm9tICcuLi93ZWJzb2NrZXQnO1xuaW1wb3J0IGRlbGF5IGZyb20gJy4uL2hlbHBlcnMvZGVsYXknO1xuaW1wb3J0IG5ldHdvcmtCcmlkZ2UgZnJvbSAnLi4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHsgY3JlYXRlQ2xvc2VFdmVudCwgY3JlYXRlRXZlbnQgfSBmcm9tICcuLi9ldmVudC9mYWN0b3J5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbihjb250ZXh0LCBjb2RlLCByZWFzb24pIHtcbiAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NJTkc7XG5cbiAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAoY29udGV4dC51cmwpO1xuICBjb25zdCBjbG9zZUV2ZW50ID0gY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgdHlwZTogJ2Nsb3NlJyxcbiAgICB0YXJnZXQ6IGNvbnRleHQsXG4gICAgY29kZSxcbiAgICByZWFzb25cbiAgfSk7XG5cbiAgZGVsYXkoKCkgPT4ge1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KGNvbnRleHQsIGNvbnRleHQudXJsKTtcblxuICAgIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgY29udGV4dC5kaXNwYXRjaEV2ZW50KGNsb3NlRXZlbnQpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCwgc2VydmVyKTtcbiAgICB9XG4gIH0sIGNvbnRleHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmFpbFdlYlNvY2tldENvbm5lY3Rpb24oY29udGV4dCwgY29kZSwgcmVhc29uKSB7XG4gIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TSU5HO1xuXG4gIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2Uuc2VydmVyTG9va3VwKGNvbnRleHQudXJsKTtcbiAgY29uc3QgY2xvc2VFdmVudCA9IGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgIHR5cGU6ICdjbG9zZScsXG4gICAgdGFyZ2V0OiBjb250ZXh0LFxuICAgIGNvZGUsXG4gICAgcmVhc29uLFxuICAgIHdhc0NsZWFuOiBmYWxzZVxuICB9KTtcblxuICBjb25zdCBlcnJvckV2ZW50ID0gY3JlYXRlRXZlbnQoe1xuICAgIHR5cGU6ICdlcnJvcicsXG4gICAgdGFyZ2V0OiBjb250ZXh0XG4gIH0pO1xuXG4gIGRlbGF5KCgpID0+IHtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldChjb250ZXh0LCBjb250ZXh0LnVybCk7XG5cbiAgICBjb250ZXh0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuICAgIGNvbnRleHQuZGlzcGF0Y2hFdmVudChlcnJvckV2ZW50KTtcbiAgICBjb250ZXh0LmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50LCBzZXJ2ZXIpO1xuICAgIH1cbiAgfSwgY29udGV4dCk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBub3JtYWxpemVTZW5kRGF0YShkYXRhKSB7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkgIT09ICdbb2JqZWN0IEJsb2JdJyAmJiAhKGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICBkYXRhID0gU3RyaW5nKGRhdGEpO1xuICB9XG5cbiAgcmV0dXJuIGRhdGE7XG59XG4iLCJpbXBvcnQgeyBDTE9TRV9DT0RFUyB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24gfSBmcm9tICcuLi9hbGdvcml0aG1zL2Nsb3NlJztcbmltcG9ydCBub3JtYWxpemVTZW5kRGF0YSBmcm9tICcuL25vcm1hbGl6ZS1zZW5kJztcbmltcG9ydCB7IGNyZWF0ZU1lc3NhZ2VFdmVudCB9IGZyb20gJy4uL2V2ZW50L2ZhY3RvcnknO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwcm94eUZhY3RvcnkodGFyZ2V0KSB7XG4gIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgZ2V0KG9iaiwgcHJvcCkge1xuICAgICAgaWYgKHByb3AgPT09ICdjbG9zZScpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNsb3NlKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSBvcHRpb25zLmNvZGUgfHwgQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMO1xuICAgICAgICAgIGNvbnN0IHJlYXNvbiA9IG9wdGlvbnMucmVhc29uIHx8ICcnO1xuXG4gICAgICAgICAgY2xvc2VXZWJTb2NrZXRDb25uZWN0aW9uKHRhcmdldCwgY29kZSwgcmVhc29uKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3AgPT09ICdzZW5kJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gc2VuZChkYXRhKSB7XG4gICAgICAgICAgZGF0YSA9IG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpO1xuXG4gICAgICAgICAgdGFyZ2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgICB0eXBlOiAnbWVzc2FnZScsXG4gICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICAgICAgICAgIHRhcmdldFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcCA9PT0gJ29uJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gb25XcmFwcGVyKHR5cGUsIGNiKSB7XG4gICAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoYHNlcnZlcjo6JHt0eXBlfWAsIGNiKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9ialtwcm9wXTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVyKTtcbiAgcmV0dXJuIHByb3h5O1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGVuZ3RoSW5VdGY4Qnl0ZXMoc3RyKSB7XG4gIC8vIE1hdGNoZXMgb25seSB0aGUgMTAuLiBieXRlcyB0aGF0IGFyZSBub24taW5pdGlhbCBjaGFyYWN0ZXJzIGluIGEgbXVsdGktYnl0ZSBzZXF1ZW5jZS5cbiAgY29uc3QgbSA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIpLm1hdGNoKC8lWzg5QUJhYl0vZyk7XG4gIHJldHVybiBzdHIubGVuZ3RoICsgKG0gPyBtLmxlbmd0aCA6IDApO1xufVxuIiwiaW1wb3J0IFVSTCBmcm9tICd1cmwtcGFyc2UnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXJsVmVyaWZpY2F0aW9uKHVybCkge1xuICBjb25zdCB1cmxSZWNvcmQgPSBuZXcgVVJMKHVybCk7XG4gIGNvbnN0IHsgcGF0aG5hbWUsIHByb3RvY29sLCBoYXNoIH0gPSB1cmxSZWNvcmQ7XG5cbiAgaWYgKCF1cmwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICB9XG5cbiAgaWYgKCFwYXRobmFtZSkge1xuICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgfVxuXG4gIGlmIChwcm90b2NvbCA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgVVJMICcke3VybFJlY29yZC50b1N0cmluZygpfScgaXMgaW52YWxpZC5gKTtcbiAgfVxuXG4gIGlmIChwcm90b2NvbCAhPT0gJ3dzOicgJiYgcHJvdG9jb2wgIT09ICd3c3M6Jykge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcbiAgICAgIGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gVGhlIFVSTCdzIHNjaGVtZSBtdXN0IGJlIGVpdGhlciAnd3MnIG9yICd3c3MnLiAnJHtwcm90b2NvbH0nIGlzIG5vdCBhbGxvd2VkLmBcbiAgICApO1xuICB9XG5cbiAgaWYgKGhhc2ggIT09ICcnKSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcbiAgICAgIGAke1xuICAgICAgICBFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1JcbiAgICAgIH0gVGhlIFVSTCBjb250YWlucyBhIGZyYWdtZW50IGlkZW50aWZpZXIgKCcke2hhc2h9JykuIEZyYWdtZW50IGlkZW50aWZpZXJzIGFyZSBub3QgYWxsb3dlZCBpbiBXZWJTb2NrZXQgVVJMcy5gXG4gICAgKTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cbiAgfVxuXG4gIHJldHVybiB1cmxSZWNvcmQudG9TdHJpbmcoKTtcbn1cbiIsImltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHByb3RvY29sVmVyaWZpY2F0aW9uKHByb3RvY29scyA9IFtdKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShwcm90b2NvbHMpICYmIHR5cGVvZiBwcm90b2NvbHMgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gVGhlIHN1YnByb3RvY29sICcke3Byb3RvY29scy50b1N0cmluZygpfScgaXMgaW52YWxpZC5gKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcHJvdG9jb2xzID09PSAnc3RyaW5nJykge1xuICAgIHByb3RvY29scyA9IFtwcm90b2NvbHNdO1xuICB9XG5cbiAgY29uc3QgdW5pcSA9IHByb3RvY29scy5tYXAocCA9PiAoeyBjb3VudDogMSwgcHJvdG9jb2w6IHAgfSkpLnJlZHVjZSgoYSwgYikgPT4ge1xuICAgIGFbYi5wcm90b2NvbF0gPSAoYVtiLnByb3RvY29sXSB8fCAwKSArIGIuY291bnQ7XG4gICAgcmV0dXJuIGE7XG4gIH0sIHt9KTtcblxuICBjb25zdCBkdXBsaWNhdGVzID0gT2JqZWN0LmtleXModW5pcSkuZmlsdGVyKGEgPT4gdW5pcVthXSA+IDEpO1xuXG4gIGlmIChkdXBsaWNhdGVzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgc3VicHJvdG9jb2wgJyR7ZHVwbGljYXRlc1swXX0nIGlzIGR1cGxpY2F0ZWQuYCk7XG4gIH1cblxuICByZXR1cm4gcHJvdG9jb2xzO1xufVxuIiwiaW1wb3J0IGRlbGF5IGZyb20gJy4vaGVscGVycy9kZWxheSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vaGVscGVycy9sb2dnZXInO1xuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4vZXZlbnQvdGFyZ2V0JztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHByb3h5RmFjdG9yeSBmcm9tICcuL2hlbHBlcnMvcHJveHktZmFjdG9yeSc7XG5pbXBvcnQgbGVuZ3RoSW5VdGY4Qnl0ZXMgZnJvbSAnLi9oZWxwZXJzL2J5dGUtbGVuZ3RoJztcbmltcG9ydCB7IENMT1NFX0NPREVTLCBFUlJPUl9QUkVGSVggfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgdXJsVmVyaWZpY2F0aW9uIGZyb20gJy4vaGVscGVycy91cmwtdmVyaWZpY2F0aW9uJztcbmltcG9ydCBub3JtYWxpemVTZW5kRGF0YSBmcm9tICcuL2hlbHBlcnMvbm9ybWFsaXplLXNlbmQnO1xuaW1wb3J0IHByb3RvY29sVmVyaWZpY2F0aW9uIGZyb20gJy4vaGVscGVycy9wcm90b2NvbC12ZXJpZmljYXRpb24nO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9IGZyb20gJy4vZXZlbnQvZmFjdG9yeSc7XG5pbXBvcnQgeyBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24sIGZhaWxXZWJTb2NrZXRDb25uZWN0aW9uIH0gZnJvbSAnLi9hbGdvcml0aG1zL2Nsb3NlJztcblxuLypcbiAqIFRoZSBtYWluIHdlYnNvY2tldCBjbGFzcyB3aGljaCBpcyBkZXNpZ25lZCB0byBtaW1pY2sgdGhlIG5hdGl2ZSBXZWJTb2NrZXQgY2xhc3MgYXMgY2xvc2VcbiAqIGFzIHBvc3NpYmxlLlxuICpcbiAqIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3dlYi1zb2NrZXRzLmh0bWxcbiAqL1xuY2xhc3MgV2ViU29ja2V0IGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3Rvcih1cmwsIHByb3RvY29scykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnVybCA9IHVybFZlcmlmaWNhdGlvbih1cmwpO1xuICAgIHByb3RvY29scyA9IHByb3RvY29sVmVyaWZpY2F0aW9uKHByb3RvY29scyk7XG4gICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sc1swXSB8fCAnJztcblxuICAgIHRoaXMuYmluYXJ5VHlwZSA9ICdibG9iJztcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ09OTkVDVElORztcblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2UuYXR0YWNoV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIC8qXG4gICAgICogVGhpcyBkZWxheSBpcyBuZWVkZWQgc28gdGhhdCB3ZSBkb250IHRyaWdnZXIgYW4gZXZlbnQgYmVmb3JlIHRoZSBjYWxsYmFja3MgaGF2ZSBiZWVuXG4gICAgICogc2V0dXAuIEZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogdmFyIHNvY2tldCA9IG5ldyBXZWJTb2NrZXQoJ3dzOi8vbG9jYWxob3N0Jyk7XG4gICAgICpcbiAgICAgKiBJZiB3ZSBkb250IGhhdmUgdGhlIGRlbGF5IHRoZW4gdGhlIGV2ZW50IHdvdWxkIGJlIHRyaWdnZXJlZCByaWdodCBoZXJlIGFuZCB0aGlzIGlzXG4gICAgICogYmVmb3JlIHRoZSBvbm9wZW4gaGFkIGEgY2hhbmNlIHRvIHJlZ2lzdGVyIGl0c2VsZi5cbiAgICAgKlxuICAgICAqIHNvY2tldC5vbm9wZW4gPSAoKSA9PiB7IC8vIHRoaXMgd291bGQgbmV2ZXIgYmUgY2FsbGVkIH07XG4gICAgICpcbiAgICAgKiBhbmQgd2l0aCB0aGUgZGVsYXkgdGhlIGV2ZW50IGdldHMgdHJpZ2dlcmVkIGhlcmUgYWZ0ZXIgYWxsIG9mIHRoZSBjYWxsYmFja3MgaGF2ZSBiZWVuXG4gICAgICogcmVnaXN0ZXJlZCA6LSlcbiAgICAgKi9cbiAgICBkZWxheShmdW5jdGlvbiBkZWxheUNhbGxiYWNrKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VydmVyLm9wdGlvbnMudmVyaWZ5Q2xpZW50ICYmXG4gICAgICAgICAgdHlwZW9mIHNlcnZlci5vcHRpb25zLnZlcmlmeUNsaWVudCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAgICFzZXJ2ZXIub3B0aW9ucy52ZXJpZnlDbGllbnQoKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuXG4gICAgICAgICAgbG9nZ2VyKFxuICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgIGBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZDogSFRUUCBBdXRoZW50aWNhdGlvbiBmYWlsZWQ7IG5vIHZhbGlkIGNyZWRlbnRpYWxzIGF2YWlsYWJsZWBcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbmV0d29ya0JyaWRnZS5yZW1vdmVXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUNsb3NlRXZlbnQoeyB0eXBlOiAnY2xvc2UnLCB0YXJnZXQ6IHRoaXMsIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sICYmIHR5cGVvZiBzZXJ2ZXIub3B0aW9ucy5zZWxlY3RQcm90b2NvbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRQcm90b2NvbCA9IHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sKHByb3RvY29scyk7XG4gICAgICAgICAgICBjb25zdCBpc0ZpbGxlZCA9IHNlbGVjdGVkUHJvdG9jb2wgIT09ICcnO1xuICAgICAgICAgICAgY29uc3QgaXNSZXF1ZXN0ZWQgPSBwcm90b2NvbHMuaW5kZXhPZihzZWxlY3RlZFByb3RvY29sKSAhPT0gLTE7XG4gICAgICAgICAgICBpZiAoaXNGaWxsZWQgJiYgIWlzUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbiAgICAgICAgICAgICAgbG9nZ2VyKCdlcnJvcicsIGBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZDogSW52YWxpZCBTdWItUHJvdG9jb2xgKTtcblxuICAgICAgICAgICAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJywgdGFyZ2V0OiB0aGlzLCBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwgfSkpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnByb3RvY29sID0gc2VsZWN0ZWRQcm90b2NvbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gV2ViU29ja2V0Lk9QRU47XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ29wZW4nLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3Rpb24nIH0pLCBwcm94eUZhY3RvcnkodGhpcykpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScsIHRhcmdldDogdGhpcywgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMIH0pKTtcblxuICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkYCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG4gIH1cblxuICBnZXQgb25vcGVuKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5vcGVuO1xuICB9XG5cbiAgZ2V0IG9ubWVzc2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5saXN0ZW5lcnMubWVzc2FnZTtcbiAgfVxuXG4gIGdldCBvbmNsb3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5jbG9zZTtcbiAgfVxuXG4gIGdldCBvbmVycm9yKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5lcnJvcjtcbiAgfVxuXG4gIHNldCBvbm9wZW4obGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMub3BlbjtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZXQgb25tZXNzYWdlKGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMubGlzdGVuZXJzLm1lc3NhZ2U7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpO1xuICB9XG5cbiAgc2V0IG9uY2xvc2UobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMuY2xvc2U7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNldCBvbmVycm9yKGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMubGlzdGVuZXJzLmVycm9yO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZW5kKGRhdGEpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ0xPU0lORyB8fCB0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TRUQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViU29ja2V0IGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBoYW5kbGUgYnVmZmVyZWRBbW91bnRcblxuICAgIGNvbnN0IG1lc3NhZ2VFdmVudCA9IGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICB0eXBlOiAnc2VydmVyOjptZXNzYWdlJyxcbiAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICBkYXRhOiBub3JtYWxpemVTZW5kRGF0YShkYXRhKVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgZGVsYXkoKCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobWVzc2FnZUV2ZW50LCBkYXRhKTtcbiAgICAgIH0sIHNlcnZlcik7XG4gICAgfVxuICB9XG5cbiAgY2xvc2UoY29kZSwgcmVhc29uKSB7XG4gICAgaWYgKGNvZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGVvZiBjb2RlICE9PSAnbnVtYmVyJyB8fCAoY29kZSAhPT0gMTAwMCAmJiAoY29kZSA8IDMwMDAgfHwgY29kZSA+IDQ5OTkpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIGAke0VSUk9SX1BSRUZJWC5DTE9TRV9FUlJPUn0gVGhlIGNvZGUgbXVzdCBiZSBlaXRoZXIgMTAwMCwgb3IgYmV0d2VlbiAzMDAwIGFuZCA0OTk5LiAke2NvZGV9IGlzIG5laXRoZXIuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZWFzb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbGVuZ3RoID0gbGVuZ3RoSW5VdGY4Qnl0ZXMocmVhc29uKTtcblxuICAgICAgaWYgKGxlbmd0aCA+IDEyMykge1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNMT1NFX0VSUk9SfSBUaGUgbWVzc2FnZSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4gMTIzIGJ5dGVzLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TSU5HIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DT05ORUNUSU5HKSB7XG4gICAgICBmYWlsV2ViU29ja2V0Q29ubmVjdGlvbih0aGlzLCBjb2RlLCByZWFzb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24odGhpcywgY29kZSwgcmVhc29uKTtcbiAgICB9XG4gIH1cbn1cblxuV2ViU29ja2V0LkNPTk5FQ1RJTkcgPSAwO1xuV2ViU29ja2V0LnByb3RvdHlwZS5DT05ORUNUSU5HID0gV2ViU29ja2V0LkNPTk5FQ1RJTkc7XG5XZWJTb2NrZXQuT1BFTiA9IDE7XG5XZWJTb2NrZXQucHJvdG90eXBlLk9QRU4gPSBXZWJTb2NrZXQuT1BFTjtcbldlYlNvY2tldC5DTE9TSU5HID0gMjtcbldlYlNvY2tldC5wcm90b3R5cGUuQ0xPU0lORyA9IFdlYlNvY2tldC5DTE9TSU5HO1xuV2ViU29ja2V0LkNMT1NFRCA9IDM7XG5XZWJTb2NrZXQucHJvdG90eXBlLkNMT1NFRCA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbmV4cG9ydCBkZWZhdWx0IFdlYlNvY2tldDtcbiIsImV4cG9ydCBkZWZhdWx0IGFyciA9PlxuICBhcnIucmVkdWNlKChkZWR1cGVkLCBiKSA9PiB7XG4gICAgaWYgKGRlZHVwZWQuaW5kZXhPZihiKSA+IC0xKSByZXR1cm4gZGVkdXBlZDtcbiAgICByZXR1cm4gZGVkdXBlZC5jb25jYXQoYik7XG4gIH0sIFtdKTtcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJldHJpZXZlR2xvYmFsT2JqZWN0KCkge1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG5cbiAgcmV0dXJuIHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyA/IGdsb2JhbCA6IHRoaXM7XG59XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgV2ViU29ja2V0IGZyb20gJy4vd2Vic29ja2V0JztcbmltcG9ydCBkZWR1cGUgZnJvbSAnLi9oZWxwZXJzL2RlZHVwZSc7XG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudC90YXJnZXQnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuL25ldHdvcmstYnJpZGdlJztcbmltcG9ydCBnbG9iYWxPYmplY3QgZnJvbSAnLi9oZWxwZXJzL2dsb2JhbC1vYmplY3QnO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vaGVscGVycy9ub3JtYWxpemUtc2VuZCc7XG5pbXBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH0gZnJvbSAnLi9ldmVudC9mYWN0b3J5JztcblxuY2xhc3MgU2VydmVyIGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3Rvcih1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgY29uc3QgdXJsUmVjb3JkID0gbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKCF1cmxSZWNvcmQucGF0aG5hbWUpIHtcbiAgICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICB0aGlzLnVybCA9IHVybFJlY29yZC50b1N0cmluZygpO1xuXG4gICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IG51bGw7XG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hTZXJ2ZXIodGhpcywgdGhpcy51cmwpO1xuXG4gICAgaWYgKCFzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicgfSkpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG1vY2sgc2VydmVyIGlzIGFscmVhZHkgbGlzdGVuaW5nIG9uIHRoaXMgdXJsJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnZlcmlmeUNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnMudmVyaWZ5Q2xpZW50ID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvcHRpb25zLnNlbGVjdFByb3RvY29sID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuc3RhcnQoKTtcbiAgfVxuXG4gIC8qXG4gICAqIEF0dGFjaGVzIHRoZSBtb2NrIHdlYnNvY2tldCBvYmplY3QgdG8gdGhlIGdsb2JhbCBvYmplY3RcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnN0IGdsb2JhbE9iaiA9IGdsb2JhbE9iamVjdCgpO1xuXG4gICAgaWYgKGdsb2JhbE9iai5XZWJTb2NrZXQpIHtcbiAgICAgIHRoaXMub3JpZ2luYWxXZWJTb2NrZXQgPSBnbG9iYWxPYmouV2ViU29ja2V0O1xuICAgIH1cblxuICAgIGdsb2JhbE9iai5XZWJTb2NrZXQgPSBXZWJTb2NrZXQ7XG4gIH1cblxuICAvKlxuICAgKiBSZW1vdmVzIHRoZSBtb2NrIHdlYnNvY2tldCBvYmplY3QgZnJvbSB0aGUgZ2xvYmFsIG9iamVjdFxuICAgKi9cbiAgc3RvcChjYWxsYmFjayA9ICgpID0+IHt9KSB7XG4gICAgY29uc3QgZ2xvYmFsT2JqID0gZ2xvYmFsT2JqZWN0KCk7XG5cbiAgICBpZiAodGhpcy5vcmlnaW5hbFdlYlNvY2tldCkge1xuICAgICAgZ2xvYmFsT2JqLldlYlNvY2tldCA9IHRoaXMub3JpZ2luYWxXZWJTb2NrZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSBnbG9iYWxPYmouV2ViU29ja2V0O1xuICAgIH1cblxuICAgIHRoaXMub3JpZ2luYWxXZWJTb2NrZXQgPSBudWxsO1xuXG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVTZXJ2ZXIodGhpcy51cmwpO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uIGZvciB0aGUgbW9jayBzZXJ2ZXIgdG8gc3Vic2NyaWJlIHRvIHRoZSBvbiBldmVudHMuXG4gICAqXG4gICAqIGllOiBtb2NrU2VydmVyLm9uKCdjb25uZWN0aW9uJywgZnVuY3Rpb24oKSB7IGNvbnNvbGUubG9nKCdhIG1vY2sgY2xpZW50IGNvbm5lY3RlZCcpOyB9KTtcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgZXZlbnQga2V5IHRvIHN1YnNjcmliZSB0by4gVmFsaWQga2V5cyBhcmU6IGNvbm5lY3Rpb24sIG1lc3NhZ2UsIGFuZCBjbG9zZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgd2hpY2ggc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGEgY2VydGFpbiBldmVudCBpcyBmaXJlZC5cbiAgICovXG4gIG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qXG4gICAqIENsb3NlcyB0aGUgY29ubmVjdGlvbiBhbmQgdHJpZ2dlcnMgdGhlIG9uY2xvc2UgbWV0aG9kIG9mIGFsbCBsaXN0ZW5pbmdcbiAgICogd2Vic29ja2V0cy4gQWZ0ZXIgdGhhdCBpdCByZW1vdmVzIGl0c2VsZiBmcm9tIHRoZSB1cmxNYXAgc28gYW5vdGhlciBzZXJ2ZXJcbiAgICogY291bGQgYWRkIGl0c2VsZiB0byB0aGUgdXJsLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKi9cbiAgY2xvc2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgeyBjb2RlLCByZWFzb24sIHdhc0NsZWFuIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG5cbiAgICAvLyBSZW1vdmUgc2VydmVyIGJlZm9yZSBub3RpZmljYXRpb25zIHRvIHByZXZlbnQgaW1tZWRpYXRlIHJlY29ubmVjdHMgZnJvbVxuICAgIC8vIHNvY2tldCBvbmNsb3NlIGhhbmRsZXJzXG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVTZXJ2ZXIodGhpcy51cmwpO1xuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goc29ja2V0ID0+IHtcbiAgICAgIHNvY2tldC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFO1xuICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgICAgICAgIHR5cGU6ICdjbG9zZScsXG4gICAgICAgICAgdGFyZ2V0OiBzb2NrZXQsXG4gICAgICAgICAgY29kZTogY29kZSB8fCBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwsXG4gICAgICAgICAgcmVhc29uOiByZWFzb24gfHwgJycsXG4gICAgICAgICAgd2FzQ2xlYW5cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScgfSksIHRoaXMpO1xuICB9XG5cbiAgLypcbiAgICogU2VuZHMgYSBnZW5lcmljIG1lc3NhZ2UgZXZlbnQgdG8gYWxsIG1vY2sgY2xpZW50cy5cbiAgICovXG4gIGVtaXQoZXZlbnQsIGRhdGEsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCB7IHdlYnNvY2tldHMgfSA9IG9wdGlvbnM7XG5cbiAgICBpZiAoIXdlYnNvY2tldHMpIHtcbiAgICAgIHdlYnNvY2tldHMgPSBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgfHwgYXJndW1lbnRzLmxlbmd0aCA+IDMpIHtcbiAgICAgIGRhdGEgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEsIGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgZGF0YSA9IGRhdGEubWFwKGl0ZW0gPT4gbm9ybWFsaXplU2VuZERhdGEoaXRlbSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhID0gbm9ybWFsaXplU2VuZERhdGEoZGF0YSk7XG4gICAgfVxuXG4gICAgd2Vic29ja2V0cy5mb3JFYWNoKHNvY2tldCA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogZXZlbnQsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHRhcmdldDogc29ja2V0XG4gICAgICAgICAgfSksXG4gICAgICAgICAgLi4uZGF0YVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgY3JlYXRlTWVzc2FnZUV2ZW50KHtcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50LFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICAgICAgICB0YXJnZXQ6IHNvY2tldFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKlxuICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHdlYnNvY2tldHMgd2hpY2ggYXJlIGxpc3RlbmluZyB0byB0aGlzIHNlcnZlclxuICAgKiBUT09EOiB0aGlzIHNob3VsZCByZXR1cm4gYSBzZXQgYW5kIG5vdCBiZSBhIG1ldGhvZFxuICAgKi9cbiAgY2xpZW50cygpIHtcbiAgICByZXR1cm4gbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHRoaXMudXJsKTtcbiAgfVxuXG4gIC8qXG4gICAqIFByZXBhcmVzIGEgbWV0aG9kIHRvIHN1Ym1pdCBhbiBldmVudCB0byBtZW1iZXJzIG9mIHRoZSByb29tXG4gICAqXG4gICAqIGUuZy4gc2VydmVyLnRvKCdteS1yb29tJykuZW1pdCgnaGkhJyk7XG4gICAqL1xuICB0byhyb29tLCBicm9hZGNhc3RlciwgYnJvYWRjYXN0TGlzdCA9IFtdKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3Qgd2Vic29ja2V0cyA9IGRlZHVwZShicm9hZGNhc3RMaXN0LmNvbmNhdChuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwsIHJvb20sIGJyb2FkY2FzdGVyKSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvOiAoY2hhaW5lZFJvb20sIGNoYWluZWRCcm9hZGNhc3RlcikgPT4gdGhpcy50by5jYWxsKHRoaXMsIGNoYWluZWRSb29tLCBjaGFpbmVkQnJvYWRjYXN0ZXIsIHdlYnNvY2tldHMpLFxuICAgICAgZW1pdChldmVudCwgZGF0YSkge1xuICAgICAgICBzZWxmLmVtaXQoZXZlbnQsIGRhdGEsIHsgd2Vic29ja2V0cyB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLypcbiAgICogQWxpYXMgZm9yIFNlcnZlci50b1xuICAgKi9cbiAgaW4oLi4uYXJncykge1xuICAgIHJldHVybiB0aGlzLnRvLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9XG5cbiAgLypcbiAgICogU2ltdWxhdGUgYW4gZXZlbnQgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjbGllbnRzLiBVc2VmdWwgZm9yXG4gICAqIHNpbXVsYXRpbmcgZXJyb3JzLlxuICAgKi9cbiAgc2ltdWxhdGUoZXZlbnQpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKGV2ZW50ID09PSAnZXJyb3InKSB7XG4gICAgICBsaXN0ZW5lcnMuZm9yRWFjaChzb2NrZXQgPT4ge1xuICAgICAgICBzb2NrZXQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRTtcbiAgICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InIH0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQWx0ZXJuYXRpdmUgY29uc3RydWN0b3IgdG8gc3VwcG9ydCBuYW1lc3BhY2VzIGluIHNvY2tldC5pb1xuICpcbiAqIGh0dHA6Ly9zb2NrZXQuaW8vZG9jcy9yb29tcy1hbmQtbmFtZXNwYWNlcy8jY3VzdG9tLW5hbWVzcGFjZXNcbiAqL1xuU2VydmVyLm9mID0gZnVuY3Rpb24gb2YodXJsKSB7XG4gIHJldHVybiBuZXcgU2VydmVyKHVybCk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTZXJ2ZXI7XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi9oZWxwZXJzL2RlbGF5JztcbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50L3RhcmdldCc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuL25ldHdvcmstYnJpZGdlJztcbmltcG9ydCB7IENMT1NFX0NPREVTIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuL2hlbHBlcnMvbG9nZ2VyJztcbmltcG9ydCB7IGNyZWF0ZUV2ZW50LCBjcmVhdGVNZXNzYWdlRXZlbnQsIGNyZWF0ZUNsb3NlRXZlbnQgfSBmcm9tICcuL2V2ZW50L2ZhY3RvcnknO1xuXG4vKlxuKiBUaGUgc29ja2V0LWlvIGNsYXNzIGlzIGRlc2lnbmVkIHRvIG1pbWljayB0aGUgcmVhbCBBUEkgYXMgY2xvc2VseSBhcyBwb3NzaWJsZS5cbipcbiogaHR0cDovL3NvY2tldC5pby9kb2NzL1xuKi9cbmNsYXNzIFNvY2tldElPIGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICAvKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgY29uc3RydWN0b3IodXJsID0gJ3NvY2tldC5pbycsIHByb3RvY29sID0gJycpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5iaW5hcnlUeXBlID0gJ2Jsb2InO1xuICAgIGNvbnN0IHVybFJlY29yZCA9IG5ldyBVUkwodXJsKTtcblxuICAgIGlmICghdXJsUmVjb3JkLnBhdGhuYW1lKSB7XG4gICAgICB1cmxSZWNvcmQucGF0aG5hbWUgPSAnLyc7XG4gICAgfVxuXG4gICAgdGhpcy51cmwgPSB1cmxSZWNvcmQudG9TdHJpbmcoKTtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5DT05ORUNUSU5HO1xuICAgIHRoaXMucHJvdG9jb2wgPSAnJztcblxuICAgIGlmICh0eXBlb2YgcHJvdG9jb2wgPT09ICdzdHJpbmcnIHx8ICh0eXBlb2YgcHJvdG9jb2wgPT09ICdvYmplY3QnICYmIHByb3RvY29sICE9PSBudWxsKSkge1xuICAgICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwcm90b2NvbCkgJiYgcHJvdG9jb2wubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sWzBdO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2UuYXR0YWNoV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIC8qXG4gICAgKiBEZWxheSB0cmlnZ2VyaW5nIHRoZSBjb25uZWN0aW9uIGV2ZW50cyBzbyB0aGV5IGNhbiBiZSBkZWZpbmVkIGluIHRpbWUuXG4gICAgKi9cbiAgICBkZWxheShmdW5jdGlvbiBkZWxheUNhbGxiYWNrKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5PUEVOO1xuICAgICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0aW9uJyB9KSwgc2VydmVyLCB0aGlzKTtcbiAgICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnY29ubmVjdCcgfSksIHNlcnZlciwgdGhpcyk7IC8vIGFsaWFzXG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0JywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNMT1NFRDtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgICAgIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgbG9nZ2VyKCdlcnJvcicsIGBTb2NrZXQuaW8gY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZGApO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICBBZGQgYW4gYWxpYXNlZCBldmVudCBsaXN0ZW5lciBmb3IgY2xvc2UgLyBkaXNjb25uZWN0XG4gICAgICovXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIGV2ZW50ID0+IHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Rpc2Nvbm5lY3QnLFxuICAgICAgICAgIHRhcmdldDogZXZlbnQudGFyZ2V0LFxuICAgICAgICAgIGNvZGU6IGV2ZW50LmNvZGVcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvKlxuICAqIENsb3NlcyB0aGUgU29ja2V0SU8gY29ubmVjdGlvbiBvciBjb25uZWN0aW9uIGF0dGVtcHQsIGlmIGFueS5cbiAgKiBJZiB0aGUgY29ubmVjdGlvbiBpcyBhbHJlYWR5IENMT1NFRCwgdGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLlxuICAqL1xuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2Uuc2VydmVyTG9va3VwKHRoaXMudXJsKTtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG5cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5DTE9TRUQ7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgIHR5cGU6ICdjbG9zZScsXG4gICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Rpc2Nvbm5lY3QnLFxuICAgICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgICBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUxcbiAgICAgICAgfSksXG4gICAgICAgIHNlcnZlclxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogQWxpYXMgZm9yIFNvY2tldCNjbG9zZVxuICAqXG4gICogaHR0cHM6Ly9naXRodWIuY29tL3NvY2tldGlvL3NvY2tldC5pby1jbGllbnQvYmxvYi9tYXN0ZXIvbGliL3NvY2tldC5qcyNMMzgzXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvc2UoKTtcbiAgfVxuXG4gIC8qXG4gICogU3VibWl0cyBhbiBldmVudCB0byB0aGUgc2VydmVyIHdpdGggYSBwYXlsb2FkXG4gICovXG4gIGVtaXQoZXZlbnQsIC4uLmRhdGEpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvY2tldElPIGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlRXZlbnQgPSBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgdHlwZTogZXZlbnQsXG4gICAgICBvcmlnaW46IHRoaXMudXJsLFxuICAgICAgZGF0YVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQobWVzc2FnZUV2ZW50LCAuLi5kYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogU3VibWl0cyBhICdtZXNzYWdlJyBldmVudCB0byB0aGUgc2VydmVyLlxuICAqXG4gICogU2hvdWxkIGJlaGF2ZSBleGFjdGx5IGxpa2UgV2ViU29ja2V0I3NlbmRcbiAgKlxuICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9zb2NrZXRpby9zb2NrZXQuaW8tY2xpZW50L2Jsb2IvbWFzdGVyL2xpYi9zb2NrZXQuanMjTDExM1xuICAqL1xuICBzZW5kKGRhdGEpIHtcbiAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCBkYXRhKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogRm9yIGJyb2FkY2FzdGluZyBldmVudHMgdG8gb3RoZXIgY29ubmVjdGVkIHNvY2tldHMuXG4gICpcbiAgKiBlLmcuIHNvY2tldC5icm9hZGNhc3QuZW1pdCgnaGkhJyk7XG4gICogZS5nLiBzb2NrZXQuYnJvYWRjYXN0LnRvKCdteS1yb29tJykuZW1pdCgnaGkhJyk7XG4gICovXG4gIGdldCBicm9hZGNhc3QoKSB7XG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSAhPT0gU29ja2V0SU8uT1BFTikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb2NrZXRJTyBpcyBhbHJlYWR5IGluIENMT1NJTkcgb3IgQ0xPU0VEIHN0YXRlJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuICAgIGlmICghc2VydmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNvY2tldElPIGNhbiBub3QgZmluZCBhIHNlcnZlciBhdCB0aGUgc3BlY2lmaWVkIFVSTCAoJHt0aGlzLnVybH0pYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVtaXQoZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgc2VydmVyLmVtaXQoZXZlbnQsIGRhdGEsIHsgd2Vic29ja2V0czogbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHNlbGYudXJsLCBudWxsLCBzZWxmKSB9KTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgICB9LFxuICAgICAgdG8ocm9vbSkge1xuICAgICAgICByZXR1cm4gc2VydmVyLnRvKHJvb20sIHNlbGYpO1xuICAgICAgfSxcbiAgICAgIGluKHJvb20pIHtcbiAgICAgICAgcmV0dXJuIHNlcnZlci5pbihyb29tLCBzZWxmKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLypcbiAgKiBGb3IgcmVnaXN0ZXJpbmcgZXZlbnRzIHRvIGJlIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICAqL1xuICBvbih0eXBlLCBjYWxsYmFjaykge1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKlxuICAgKiBSZW1vdmUgZXZlbnQgbGlzdGVuZXJcbiAgICpcbiAgICogaHR0cHM6Ly9zb2NrZXQuaW8vZG9jcy9jbGllbnQtYXBpLyNzb2NrZXQtb24tZXZlbnRuYW1lLWNhbGxiYWNrXG4gICAqL1xuICBvZmYodHlwZSkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlKTtcbiAgfVxuXG4gIC8qXG4gICAqIEpvaW4gYSByb29tIG9uIGEgc2VydmVyXG4gICAqXG4gICAqIGh0dHA6Ly9zb2NrZXQuaW8vZG9jcy9yb29tcy1hbmQtbmFtZXNwYWNlcy8jam9pbmluZy1hbmQtbGVhdmluZ1xuICAgKi9cbiAgam9pbihyb29tKSB7XG4gICAgbmV0d29ya0JyaWRnZS5hZGRNZW1iZXJzaGlwVG9Sb29tKHRoaXMsIHJvb20pO1xuICB9XG5cbiAgLypcbiAgICogR2V0IHRoZSB3ZWJzb2NrZXQgdG8gbGVhdmUgdGhlIHJvb21cbiAgICpcbiAgICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNqb2luaW5nLWFuZC1sZWF2aW5nXG4gICAqL1xuICBsZWF2ZShyb29tKSB7XG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVNZW1iZXJzaGlwRnJvbVJvb20odGhpcywgcm9vbSk7XG4gIH1cblxuICB0byhyb29tKSB7XG4gICAgcmV0dXJuIHRoaXMuYnJvYWRjYXN0LnRvKHJvb20pO1xuICB9XG5cbiAgaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxuXG4gIC8qXG4gICAqIEludm9rZXMgYWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyB0aGF0IGFyZSBsaXN0ZW5pbmcgdG8gdGhlIGdpdmVuIGV2ZW50LnR5cGUgcHJvcGVydHkuIEVhY2hcbiAgICogbGlzdGVuZXIgd2lsbCBiZSBwYXNzZWQgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gZXZlbnQgb2JqZWN0IHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGFsbCBsaXN0ZW5lcnMgb2YgdGhlIGV2ZW50LnR5cGUgcHJvcGVydHlcbiAgICovXG4gIGRpc3BhdGNoRXZlbnQoZXZlbnQsIC4uLmN1c3RvbUFyZ3VtZW50cykge1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnR5cGU7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNbZXZlbnROYW1lXTtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheShsaXN0ZW5lcnMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZvckVhY2gobGlzdGVuZXIgPT4ge1xuICAgICAgaWYgKGN1c3RvbUFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGN1c3RvbUFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZWd1bGFyIFdlYlNvY2tldHMgZXhwZWN0IGEgTWVzc2FnZUV2ZW50IGJ1dCBTb2NrZXRpby5pbyBqdXN0IHdhbnRzIHJhdyBkYXRhXG4gICAgICAgIC8vICBwYXlsb2FkIGluc3RhbmNlb2YgTWVzc2FnZUV2ZW50IHdvcmtzLCBidXQgeW91IGNhbid0IGlzbnRhbmNlIG9mIE5vZGVFdmVudFxuICAgICAgICAvLyAgZm9yIG5vdyB3ZSBkZXRlY3QgaWYgdGhlIG91dHB1dCBoYXMgZGF0YSBkZWZpbmVkIG9uIGl0XG4gICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQuZGF0YSA/IGV2ZW50LmRhdGEgOiBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuU29ja2V0SU8uQ09OTkVDVElORyA9IDA7XG5Tb2NrZXRJTy5PUEVOID0gMTtcblNvY2tldElPLkNMT1NJTkcgPSAyO1xuU29ja2V0SU8uQ0xPU0VEID0gMztcblxuLypcbiogU3RhdGljIGNvbnN0cnVjdG9yIG1ldGhvZHMgZm9yIHRoZSBJTyBTb2NrZXRcbiovXG5jb25zdCBJTyA9IGZ1bmN0aW9uIGlvQ29uc3RydWN0b3IodXJsLCBwcm90b2NvbCkge1xuICByZXR1cm4gbmV3IFNvY2tldElPKHVybCwgcHJvdG9jb2wpO1xufTtcblxuLypcbiogQWxpYXMgdGhlIHJhdyBJTygpIGNvbnN0cnVjdG9yXG4qL1xuSU8uY29ubmVjdCA9IGZ1bmN0aW9uIGlvQ29ubmVjdCh1cmwsIHByb3RvY29sKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5ldy1jYXAgKi9cbiAgcmV0dXJuIElPKHVybCwgcHJvdG9jb2wpO1xuICAvKiBlc2xpbnQtZW5hYmxlIG5ldy1jYXAgKi9cbn07XG5cbmV4cG9ydCBkZWZhdWx0IElPO1xuIiwiaW1wb3J0IE1vY2tTZXJ2ZXIgZnJvbSAnLi9zZXJ2ZXInO1xuaW1wb3J0IE1vY2tTb2NrZXRJTyBmcm9tICcuL3NvY2tldC1pbyc7XG5pbXBvcnQgTW9ja1dlYlNvY2tldCBmcm9tICcuL3dlYnNvY2tldCc7XG5cbmV4cG9ydCBjb25zdCBTZXJ2ZXIgPSBNb2NrU2VydmVyO1xuZXhwb3J0IGNvbnN0IFdlYlNvY2tldCA9IE1vY2tXZWJTb2NrZXQ7XG5leHBvcnQgY29uc3QgU29ja2V0SU8gPSBNb2NrU29ja2V0SU87XG4iXSwibmFtZXMiOlsiZ2xvYmFsIiwicXMiLCJyZXF1aXJlZCIsImNvbnN0IiwidGhpcyIsInN1cGVyIiwiV2ViU29ja2V0IiwiVVJMIiwibG9nZ2VyIiwiU2VydmVyIiwiZ2xvYmFsT2JqZWN0IiwiU29ja2V0SU8iLCJNb2NrU2VydmVyIiwiTW9ja1dlYlNvY2tldCIsIk1vY2tTb2NrZXRJTyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQVdBLGdCQUFjLEdBQUcsU0FBUyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtFQUNqRCxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNsQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUM7O0VBRWIsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFBLE9BQU8sS0FBSyxDQUFDLEVBQUE7O0VBRXhCLFFBQVEsUUFBUTtJQUNkLEtBQUssTUFBTSxD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 diff --git a/node_modules/mock-socket/dist/mock-socket.cjs.js b/node_modules/mock-socket/dist/mock-socket.cjs.js new file mode 100644 index 0000000..f903b4e --- /dev/null +++ b/node_modules/mock-socket/dist/mock-socket.cjs.js @@ -0,0 +1,1926 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +var requiresPort = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) { return false; } + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; + +var has = Object.prototype.hasOwnProperty; + +/** + * Decode a URI encoded string. + * + * @param {String} input The URI encoded string. + * @returns {String} The decoded string. + * @api private + */ +function decode(input) { + return decodeURIComponent(input.replace(/\+/g, ' ')); +} + +/** + * Simple query string parser. + * + * @param {String} query The query string that needs to be parsed. + * @returns {Object} + * @api public + */ +function querystring(query) { + var parser = /([^=?&]+)=?([^&]*)/g + , result = {} + , part; + + while (part = parser.exec(query)) { + var key = decode(part[1]) + , value = decode(part[2]); + + // + // Prevent overriding of existing properties. This ensures that build-in + // methods like `toString` or __proto__ are not overriden by malicious + // querystrings. + // + if (key in result) { continue; } + result[key] = value; + } + + return result; +} + +/** + * Transform a query string to an object. + * + * @param {Object} obj Object that should be transformed. + * @param {String} prefix Optional prefix. + * @returns {String} + * @api public + */ +function querystringify(obj, prefix) { + prefix = prefix || ''; + + var pairs = []; + + // + // Optionally prefix with a '?' if needed + // + if ('string' !== typeof prefix) { prefix = '?'; } + + for (var key in obj) { + if (has.call(obj, key)) { + pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key])); + } + } + + return pairs.length ? prefix + pairs.join('&') : ''; +} + +// +// Expose the module. +// +var stringify = querystringify; +var parse = querystring; + +var querystringify_1 = { + stringify: stringify, + parse: parse +}; + +var protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; +var slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//; + +/** + * These are the parse rules for the URL parser, it informs the parser + * about: + * + * 0. The char it Needs to parse, if it's a string it should be done using + * indexOf, RegExp using exec and NaN means set as current value. + * 1. The property we should set when parsing this value. + * 2. Indication if it's backwards or forward parsing, when set as number it's + * the value of extra chars that should be split off. + * 3. Inherit from location if non existing in the parser. + * 4. `toLowerCase` the resulting value. + */ +var rules = [ + ['#', 'hash'], // Extract from the back. + ['?', 'query'], // Extract from the back. + ['/', 'pathname'], // Extract from the back. + ['@', 'auth', 1], // Extract from the front. + [NaN, 'host', undefined, 1, 1], // Set left over value. + [/:(\d+)$/, 'port', undefined, 1], // RegExp the back. + [NaN, 'hostname', undefined, 1, 1] // Set left over. +]; + +/** + * These properties should not be copied or inherited from. This is only needed + * for all non blob URL's as a blob URL does not include a hash, only the + * origin. + * + * @type {Object} + * @private + */ +var ignore = { hash: 1, query: 1 }; + +/** + * The location object differs when your code is loaded through a normal page, + * Worker or through a worker using a blob. And with the blobble begins the + * trouble as the location object will contain the URL of the blob, not the + * location of the page where our code is loaded in. The actual origin is + * encoded in the `pathname` so we can thankfully generate a good "default" + * location from it so we can generate proper relative URL's again. + * + * @param {Object|String} loc Optional default location object. + * @returns {Object} lolcation object. + * @api public + */ +function lolcation(loc) { + var location = commonjsGlobal && commonjsGlobal.location || {}; + loc = loc || location; + + var finaldestination = {} + , type = typeof loc + , key; + + if ('blob:' === loc.protocol) { + finaldestination = new URL(unescape(loc.pathname), {}); + } else if ('string' === type) { + finaldestination = new URL(loc, {}); + for (key in ignore) { delete finaldestination[key]; } + } else if ('object' === type) { + for (key in loc) { + if (key in ignore) { continue; } + finaldestination[key] = loc[key]; + } + + if (finaldestination.slashes === undefined) { + finaldestination.slashes = slashes.test(loc.href); + } + } + + return finaldestination; +} + +/** + * @typedef ProtocolExtract + * @type Object + * @property {String} protocol Protocol matched in the URL, in lowercase. + * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`. + * @property {String} rest Rest of the URL that is not part of the protocol. + */ + +/** + * Extract protocol information from a URL with/without double slash ("//"). + * + * @param {String} address URL we want to extract from. + * @return {ProtocolExtract} Extracted information. + * @api private + */ +function extractProtocol(address) { + var match = protocolre.exec(address); + + return { + protocol: match[1] ? match[1].toLowerCase() : '', + slashes: !!match[2], + rest: match[3] + }; +} + +/** + * Resolve a relative URL pathname against a base URL pathname. + * + * @param {String} relative Pathname of the relative URL. + * @param {String} base Pathname of the base URL. + * @return {String} Resolved pathname. + * @api private + */ +function resolve(relative, base) { + var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/')) + , i = path.length + , last = path[i - 1] + , unshift = false + , up = 0; + + while (i--) { + if (path[i] === '.') { + path.splice(i, 1); + } else if (path[i] === '..') { + path.splice(i, 1); + up++; + } else if (up) { + if (i === 0) { unshift = true; } + path.splice(i, 1); + up--; + } + } + + if (unshift) { path.unshift(''); } + if (last === '.' || last === '..') { path.push(''); } + + return path.join('/'); +} + +/** + * The actual URL instance. Instead of returning an object we've opted-in to + * create an actual constructor as it's much more memory efficient and + * faster and it pleases my OCD. + * + * @constructor + * @param {String} address URL we want to parse. + * @param {Object|String} location Location defaults for relative paths. + * @param {Boolean|Function} parser Parser for the query string. + * @api public + */ +function URL(address, location, parser) { + if (!(this instanceof URL)) { + return new URL(address, location, parser); + } + + var relative, extracted, parse, instruction, index, key + , instructions = rules.slice() + , type = typeof location + , url = this + , i = 0; + + // + // The following if statements allows this module two have compatibility with + // 2 different API: + // + // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments + // where the boolean indicates that the query string should also be parsed. + // + // 2. The `URL` interface of the browser which accepts a URL, object as + // arguments. The supplied object will be used as default values / fall-back + // for relative paths. + // + if ('object' !== type && 'string' !== type) { + parser = location; + location = null; + } + + if (parser && 'function' !== typeof parser) { parser = querystringify_1.parse; } + + location = lolcation(location); + + // + // Extract protocol information before running the instructions. + // + extracted = extractProtocol(address || ''); + relative = !extracted.protocol && !extracted.slashes; + url.slashes = extracted.slashes || relative && location.slashes; + url.protocol = extracted.protocol || location.protocol || ''; + address = extracted.rest; + + // + // When the authority component is absent the URL starts with a path + // component. + // + if (!extracted.slashes) { instructions[2] = [/(.*)/, 'pathname']; } + + for (; i < instructions.length; i++) { + instruction = instructions[i]; + parse = instruction[0]; + key = instruction[1]; + + if (parse !== parse) { + url[key] = address; + } else if ('string' === typeof parse) { + if (~(index = address.indexOf(parse))) { + if ('number' === typeof instruction[2]) { + url[key] = address.slice(0, index); + address = address.slice(index + instruction[2]); + } else { + url[key] = address.slice(index); + address = address.slice(0, index); + } + } + } else if ((index = parse.exec(address))) { + url[key] = index[1]; + address = address.slice(0, index.index); + } + + url[key] = url[key] || ( + relative && instruction[3] ? location[key] || '' : '' + ); + + // + // Hostname, host and protocol should be lowercased so they can be used to + // create a proper `origin`. + // + if (instruction[4]) { url[key] = url[key].toLowerCase(); } + } + + // + // Also parse the supplied query string in to an object. If we're supplied + // with a custom parser as function use that instead of the default build-in + // parser. + // + if (parser) { url.query = parser(url.query); } + + // + // If the URL is relative, resolve the pathname against the base URL. + // + if ( + relative + && location.slashes + && url.pathname.charAt(0) !== '/' + && (url.pathname !== '' || location.pathname !== '') + ) { + url.pathname = resolve(url.pathname, location.pathname); + } + + // + // We should not add port numbers if they are already the default port number + // for a given protocol. As the host also contains the port number we're going + // override it with the hostname which contains no port number. + // + if (!requiresPort(url.port, url.protocol)) { + url.host = url.hostname; + url.port = ''; + } + + // + // Parse down the `auth` for the username and password. + // + url.username = url.password = ''; + if (url.auth) { + instruction = url.auth.split(':'); + url.username = instruction[0] || ''; + url.password = instruction[1] || ''; + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + // + // The href is just the compiled result. + // + url.href = url.toString(); +} + +/** + * This is convenience method for changing properties in the URL instance to + * insure that they all propagate correctly. + * + * @param {String} part Property we need to adjust. + * @param {Mixed} value The newly assigned value. + * @param {Boolean|Function} fn When setting the query, it will be the function + * used to parse the query. + * When setting the protocol, double slash will be + * removed from the final url if it is true. + * @returns {URL} + * @api public + */ +function set(part, value, fn) { + var url = this; + + switch (part) { + case 'query': + if ('string' === typeof value && value.length) { + value = (fn || querystringify_1.parse)(value); + } + + url[part] = value; + break; + + case 'port': + url[part] = value; + + if (!requiresPort(value, url.protocol)) { + url.host = url.hostname; + url[part] = ''; + } else if (value) { + url.host = url.hostname +':'+ value; + } + + break; + + case 'hostname': + url[part] = value; + + if (url.port) { value += ':'+ url.port; } + url.host = value; + break; + + case 'host': + url[part] = value; + + if (/:\d+$/.test(value)) { + value = value.split(':'); + url.port = value.pop(); + url.hostname = value.join(':'); + } else { + url.hostname = value; + url.port = ''; + } + + break; + + case 'protocol': + url.protocol = value.toLowerCase(); + url.slashes = !fn; + break; + + case 'pathname': + case 'hash': + if (value) { + var char = part === 'pathname' ? '/' : '#'; + url[part] = value.charAt(0) !== char ? char + value : value; + } else { + url[part] = value; + } + break; + + default: + url[part] = value; + } + + for (var i = 0; i < rules.length; i++) { + var ins = rules[i]; + + if (ins[4]) { url[ins[1]] = url[ins[1]].toLowerCase(); } + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + url.href = url.toString(); + + return url; +} + +/** + * Transform the properties back in to a valid and full URL string. + * + * @param {Function} stringify Optional query stringify function. + * @returns {String} + * @api public + */ +function toString(stringify) { + if (!stringify || 'function' !== typeof stringify) { stringify = querystringify_1.stringify; } + + var query + , url = this + , protocol = url.protocol; + + if (protocol && protocol.charAt(protocol.length - 1) !== ':') { protocol += ':'; } + + var result = protocol + (url.slashes ? '//' : ''); + + if (url.username) { + result += url.username; + if (url.password) { result += ':'+ url.password; } + result += '@'; + } + + result += url.host + url.pathname; + + query = 'object' === typeof url.query ? stringify(url.query) : url.query; + if (query) { result += '?' !== query.charAt(0) ? '?'+ query : query; } + + if (url.hash) { result += url.hash; } + + return result; +} + +URL.prototype = { set: set, toString: toString }; + +// +// Expose the URL parser and some additional properties that might be useful for +// others or testing. +// +URL.extractProtocol = extractProtocol; +URL.location = lolcation; +URL.qs = querystringify_1; + +var urlParse = URL; + +/* +* This delay allows the thread to finish assigning its on* methods +* before invoking the delay callback. This is purely a timing hack. +* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html +* +* @param {callback: function} the callback which will be invoked after the timeout +* @parma {context: object} the context in which to invoke the function +*/ +function delay(callback, context) { + setTimeout(function (timeoutContext) { return callback.call(timeoutContext); }, 4, context); +} + +function log(method, message) { + /* eslint-disable no-console */ + if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') { + console[method].call(null, message); + } + /* eslint-enable no-console */ +} + +function reject(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (!callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +function filter(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +/* +* EventTarget is an interface implemented by objects that can +* receive events and may have listeners for them. +* +* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget +*/ +var EventTarget = function EventTarget() { + this.listeners = {}; +}; + +/* +* Ties a listener function to an event type which can later be invoked via the +* dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.addEventListener = function addEventListener (type, listener /* , useCapture */) { + if (typeof listener === 'function') { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], function (item) { return item === listener; }).length === 0) { + this.listeners[type].push(listener); + } + } +}; + +/* +* Removes the listener so it will no longer be invoked via the dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.removeEventListener = function removeEventListener (type, removingListener /* , useCapture */) { + var arrayOfListeners = this.listeners[type]; + this.listeners[type] = reject(arrayOfListeners, function (listener) { return listener === removingListener; }); +}; + +/* +* Invokes all listener functions that are listening to the given event.type property. Each +* listener will be passed the event as the first argument. +* +* @param {object} event - event object which will be passed to all listeners of the event.type property +*/ +EventTarget.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + listener.call(this$1, event); + } + }); + + return true; +}; + +/* +* The network bridge is a way for the mock websocket object to 'communicate' with +* all available servers. This is a singleton object so it is important that you +* clean up urlMap whenever you are finished. +*/ +var NetworkBridge = function NetworkBridge() { + this.urlMap = {}; +}; + +/* +* Attaches a websocket object to the urlMap hash so that it can find the server +* it is connected to and the server in turn can find it. +* +* @param {object} websocket - websocket object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachWebSocket = function attachWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) { + connectionLookup.websockets.push(websocket); + return connectionLookup.server; + } +}; + +/* +* Attaches a websocket to a room +*/ +NetworkBridge.prototype.addMembershipToRoom = function addMembershipToRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) { + if (!connectionLookup.roomMemberships[room]) { + connectionLookup.roomMemberships[room] = []; + } + + connectionLookup.roomMemberships[room].push(websocket); + } +}; + +/* +* Attaches a server object to the urlMap hash so that it can find a websockets +* which are connected to it and so that websockets can in turn can find it. +* +* @param {object} server - server object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachServer = function attachServer (server, url) { + var connectionLookup = this.urlMap[url]; + + if (!connectionLookup) { + this.urlMap[url] = { + server: server, + websockets: [], + roomMemberships: {} + }; + + return server; + } +}; + +/* +* Finds the server which is 'running' on the given url. +* +* @param {string} url - the url to use to find which server is running on it +*/ +NetworkBridge.prototype.serverLookup = function serverLookup (url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + return connectionLookup.server; + } +}; + +/* +* Finds all websockets which is 'listening' on the given url. +* +* @param {string} url - the url to use to find all websockets which are associated with it +* @param {string} room - if a room is provided, will only return sockets in this room +* @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup +*/ +NetworkBridge.prototype.websocketsLookup = function websocketsLookup (url, room, broadcaster) { + var websockets; + var connectionLookup = this.urlMap[url]; + + websockets = connectionLookup ? connectionLookup.websockets : []; + + if (room) { + var members = connectionLookup.roomMemberships[room]; + websockets = members || []; + } + + return broadcaster ? websockets.filter(function (websocket) { return websocket !== broadcaster; }) : websockets; +}; + +/* +* Removes the entry associated with the url. +* +* @param {string} url +*/ +NetworkBridge.prototype.removeServer = function removeServer (url) { + delete this.urlMap[url]; +}; + +/* +* Removes the individual websocket from the map of associated websockets. +* +* @param {object} websocket - websocket object to remove from the url map +* @param {string} url +*/ +NetworkBridge.prototype.removeWebSocket = function removeWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + connectionLookup.websockets = reject(connectionLookup.websockets, function (socket) { return socket === websocket; }); + } +}; + +/* +* Removes a websocket from a room +*/ +NetworkBridge.prototype.removeMembershipFromRoom = function removeMembershipFromRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + var memberships = connectionLookup.roomMemberships[room]; + + if (connectionLookup && memberships !== null) { + connectionLookup.roomMemberships[room] = reject(memberships, function (socket) { return socket === websocket; }); + } +}; + +var networkBridge = new NetworkBridge(); // Note: this is a singleton + +/* + * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent + */ +var CLOSE_CODES = { + CLOSE_NORMAL: 1000, + CLOSE_GOING_AWAY: 1001, + CLOSE_PROTOCOL_ERROR: 1002, + CLOSE_UNSUPPORTED: 1003, + CLOSE_NO_STATUS: 1005, + CLOSE_ABNORMAL: 1006, + UNSUPPORTED_DATA: 1007, + POLICY_VIOLATION: 1008, + CLOSE_TOO_LARGE: 1009, + MISSING_EXTENSION: 1010, + INTERNAL_ERROR: 1011, + SERVICE_RESTART: 1012, + TRY_AGAIN_LATER: 1013, + TLS_HANDSHAKE: 1015 +}; + +var ERROR_PREFIX = { + CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':", + CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':", + EVENT: { + CONSTRUCT: "Failed to construct 'Event':", + MESSAGE: "Failed to construct 'MessageEvent':", + CLOSE: "Failed to construct 'CloseEvent':" + } +}; + +var EventPrototype = function EventPrototype () {}; + +EventPrototype.prototype.stopPropagation = function stopPropagation () {}; +EventPrototype.prototype.stopImmediatePropagation = function stopImmediatePropagation () {}; + +// if no arguments are passed then the type is set to "undefined" on +// chrome and safari. +EventPrototype.prototype.initEvent = function initEvent (type, bubbles, cancelable) { + if ( type === void 0 ) type = 'undefined'; + if ( bubbles === void 0 ) bubbles = false; + if ( cancelable === void 0 ) cancelable = false; + + this.type = "" + type; + this.bubbles = Boolean(bubbles); + this.cancelable = Boolean(cancelable); +}; + +var Event = (function (EventPrototype$$1) { + function Event(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " parameter 2 ('eventInitDict') is not an object.")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + } + + if ( EventPrototype$$1 ) Event.__proto__ = EventPrototype$$1; + Event.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + Event.prototype.constructor = Event; + + return Event; +}(EventPrototype)); + +var MessageEvent = (function (EventPrototype$$1) { + function MessageEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var data = eventInitConfig.data; + var origin = eventInitConfig.origin; + var lastEventId = eventInitConfig.lastEventId; + var ports = eventInitConfig.ports; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.origin = "" + origin; + this.ports = typeof ports === 'undefined' ? null : ports; + this.data = typeof data === 'undefined' ? null : data; + this.lastEventId = "" + (lastEventId || ''); + } + + if ( EventPrototype$$1 ) MessageEvent.__proto__ = EventPrototype$$1; + MessageEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + MessageEvent.prototype.constructor = MessageEvent; + + return MessageEvent; +}(EventPrototype)); + +var CloseEvent = (function (EventPrototype$$1) { + function CloseEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var code = eventInitConfig.code; + var reason = eventInitConfig.reason; + var wasClean = eventInitConfig.wasClean; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.cancelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.code = typeof code === 'number' ? parseInt(code, 10) : 0; + this.reason = "" + (reason || ''); + this.wasClean = wasClean ? Boolean(wasClean) : false; + } + + if ( EventPrototype$$1 ) CloseEvent.__proto__ = EventPrototype$$1; + CloseEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + CloseEvent.prototype.constructor = CloseEvent; + + return CloseEvent; +}(EventPrototype)); + +/* +* Creates an Event object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config you will need to pass type and optionally target +*/ +function createEvent(config) { + var type = config.type; + var target = config.target; + var eventObject = new Event(type); + + if (target) { + eventObject.target = target; + eventObject.srcElement = target; + eventObject.currentTarget = target; + } + + return eventObject; +} + +/* +* Creates a MessageEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type, origin, data and optionally target +*/ +function createMessageEvent(config) { + var type = config.type; + var origin = config.origin; + var data = config.data; + var target = config.target; + var messageEvent = new MessageEvent(type, { + data: data, + origin: origin + }); + + if (target) { + messageEvent.target = target; + messageEvent.srcElement = target; + messageEvent.currentTarget = target; + } + + return messageEvent; +} + +/* +* Creates a CloseEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type and optionally target, code, and reason +*/ +function createCloseEvent(config) { + var code = config.code; + var reason = config.reason; + var type = config.type; + var target = config.target; + var wasClean = config.wasClean; + + if (!wasClean) { + wasClean = code === 1000; + } + + var closeEvent = new CloseEvent(type, { + code: code, + reason: reason, + wasClean: wasClean + }); + + if (target) { + closeEvent.target = target; + closeEvent.srcElement = target; + closeEvent.currentTarget = target; + } + + return closeEvent; +} + +function closeWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function failWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason, + wasClean: false + }); + + var errorEvent = createEvent({ + type: 'error', + target: context + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(errorEvent); + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function normalizeSendData(data) { + if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) { + data = String(data); + } + + return data; +} + +function proxyFactory(target) { + var handler = { + get: function get(obj, prop) { + if (prop === 'close') { + return function close(options) { + if ( options === void 0 ) options = {}; + + var code = options.code || CLOSE_CODES.CLOSE_NORMAL; + var reason = options.reason || ''; + + closeWebSocketConnection(target, code, reason); + }; + } + + if (prop === 'send') { + return function send(data) { + data = normalizeSendData(data); + + target.dispatchEvent( + createMessageEvent({ + type: 'message', + data: data, + origin: this.url, + target: target + }) + ); + }; + } + + if (prop === 'on') { + return function onWrapper(type, cb) { + target.addEventListener(("server::" + type), cb); + }; + } + + return obj[prop]; + } + }; + + var proxy = new Proxy(target, handler); + return proxy; +} + +function lengthInUtf8Bytes(str) { + // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. + var m = encodeURIComponent(str).match(/%[89ABab]/g); + return str.length + (m ? m.length : 0); +} + +function urlVerification(url) { + var urlRecord = new urlParse(url); + var pathname = urlRecord.pathname; + var protocol = urlRecord.protocol; + var hash = urlRecord.hash; + + if (!url) { + throw new TypeError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (!pathname) { + urlRecord.pathname = '/'; + } + + if (protocol === '') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL '" + (urlRecord.toString()) + "' is invalid.")); + } + + if (protocol !== 'ws:' && protocol !== 'wss:') { + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL's scheme must be either 'ws' or 'wss'. '" + protocol + "' is not allowed.") + ); + } + + if (hash !== '') { + /* eslint-disable max-len */ + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL contains a fragment identifier ('" + hash + "'). Fragment identifiers are not allowed in WebSocket URLs.") + ); + /* eslint-enable max-len */ + } + + return urlRecord.toString(); +} + +function protocolVerification(protocols) { + if ( protocols === void 0 ) protocols = []; + + if (!Array.isArray(protocols) && typeof protocols !== 'string') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (protocols.toString()) + "' is invalid.")); + } + + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + var uniq = protocols.map(function (p) { return ({ count: 1, protocol: p }); }).reduce(function (a, b) { + a[b.protocol] = (a[b.protocol] || 0) + b.count; + return a; + }, {}); + + var duplicates = Object.keys(uniq).filter(function (a) { return uniq[a] > 1; }); + + if (duplicates.length > 0) { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (duplicates[0]) + "' is duplicated.")); + } + + return protocols; +} + +/* + * The main websocket class which is designed to mimick the native WebSocket class as close + * as possible. + * + * https://html.spec.whatwg.org/multipage/web-sockets.html + */ +var WebSocket$1 = (function (EventTarget$$1) { + function WebSocket(url, protocols) { + EventTarget$$1.call(this); + + this.url = urlVerification(url); + protocols = protocolVerification(protocols); + this.protocol = protocols[0] || ''; + + this.binaryType = 'blob'; + this.readyState = WebSocket.CONNECTING; + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * This delay is needed so that we dont trigger an event before the callbacks have been + * setup. For example: + * + * var socket = new WebSocket('ws://localhost'); + * + * If we dont have the delay then the event would be triggered right here and this is + * before the onopen had a chance to register itself. + * + * socket.onopen = () => { // this would never be called }; + * + * and with the delay the event gets triggered here after all of the callbacks have been + * registered :-) + */ + delay(function delayCallback() { + if (server) { + if ( + server.options.verifyClient && + typeof server.options.verifyClient === 'function' && + !server.options.verifyClient() + ) { + this.readyState = WebSocket.CLOSED; + + log( + 'error', + ("WebSocket connection to '" + (this.url) + "' failed: HTTP Authentication failed; no valid credentials available") + ); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + } else { + if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') { + var selectedProtocol = server.options.selectProtocol(protocols); + var isFilled = selectedProtocol !== ''; + var isRequested = protocols.indexOf(selectedProtocol) !== -1; + if (isFilled && !isRequested) { + this.readyState = WebSocket.CLOSED; + + log('error', ("WebSocket connection to '" + (this.url) + "' failed: Invalid Sub-Protocol")); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + return; + } + this.protocol = selectedProtocol; + } + this.readyState = WebSocket.OPEN; + this.dispatchEvent(createEvent({ type: 'open', target: this })); + server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this)); + } + } else { + this.readyState = WebSocket.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + + log('error', ("WebSocket connection to '" + (this.url) + "' failed")); + } + }, this); + } + + if ( EventTarget$$1 ) WebSocket.__proto__ = EventTarget$$1; + WebSocket.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + WebSocket.prototype.constructor = WebSocket; + + var prototypeAccessors = { onopen: {},onmessage: {},onclose: {},onerror: {} }; + + prototypeAccessors.onopen.get = function () { + return this.listeners.open; + }; + + prototypeAccessors.onmessage.get = function () { + return this.listeners.message; + }; + + prototypeAccessors.onclose.get = function () { + return this.listeners.close; + }; + + prototypeAccessors.onerror.get = function () { + return this.listeners.error; + }; + + prototypeAccessors.onopen.set = function (listener) { + delete this.listeners.open; + this.addEventListener('open', listener); + }; + + prototypeAccessors.onmessage.set = function (listener) { + delete this.listeners.message; + this.addEventListener('message', listener); + }; + + prototypeAccessors.onclose.set = function (listener) { + delete this.listeners.close; + this.addEventListener('close', listener); + }; + + prototypeAccessors.onerror.set = function (listener) { + delete this.listeners.error; + this.addEventListener('error', listener); + }; + + WebSocket.prototype.send = function send (data) { + var this$1 = this; + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + throw new Error('WebSocket is already in CLOSING or CLOSED state'); + } + + // TODO: handle bufferedAmount + + var messageEvent = createMessageEvent({ + type: 'server::message', + origin: this.url, + data: normalizeSendData(data) + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + delay(function () { + this$1.dispatchEvent(messageEvent, data); + }, server); + } + }; + + WebSocket.prototype.close = function close (code, reason) { + if (code !== undefined) { + if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) { + throw new TypeError( + ((ERROR_PREFIX.CLOSE_ERROR) + " The code must be either 1000, or between 3000 and 4999. " + code + " is neither.") + ); + } + } + + if (reason !== undefined) { + var length = lengthInUtf8Bytes(reason); + + if (length > 123) { + throw new SyntaxError(((ERROR_PREFIX.CLOSE_ERROR) + " The message must not be greater than 123 bytes.")); + } + } + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + return; + } + + if (this.readyState === WebSocket.CONNECTING) { + failWebSocketConnection(this, code, reason); + } else { + closeWebSocketConnection(this, code, reason); + } + }; + + Object.defineProperties( WebSocket.prototype, prototypeAccessors ); + + return WebSocket; +}(EventTarget)); + +WebSocket$1.CONNECTING = 0; +WebSocket$1.prototype.CONNECTING = WebSocket$1.CONNECTING; +WebSocket$1.OPEN = 1; +WebSocket$1.prototype.OPEN = WebSocket$1.OPEN; +WebSocket$1.CLOSING = 2; +WebSocket$1.prototype.CLOSING = WebSocket$1.CLOSING; +WebSocket$1.CLOSED = 3; +WebSocket$1.prototype.CLOSED = WebSocket$1.CLOSED; + +var dedupe = function (arr) { return arr.reduce(function (deduped, b) { + if (deduped.indexOf(b) > -1) { return deduped; } + return deduped.concat(b); + }, []); }; + +function retrieveGlobalObject() { + if (typeof window !== 'undefined') { + return window; + } + + return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this; +} + +var Server$1 = (function (EventTarget$$1) { + function Server(url, options) { + if ( options === void 0 ) options = {}; + + EventTarget$$1.call(this); + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + + this.originalWebSocket = null; + var server = networkBridge.attachServer(this, this.url); + + if (!server) { + this.dispatchEvent(createEvent({ type: 'error' })); + throw new Error('A mock server is already listening on this url'); + } + + if (typeof options.verifyClient === 'undefined') { + options.verifyClient = null; + } + + if (typeof options.selectProtocol === 'undefined') { + options.selectProtocol = null; + } + + this.options = options; + this.start(); + } + + if ( EventTarget$$1 ) Server.__proto__ = EventTarget$$1; + Server.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + Server.prototype.constructor = Server; + + /* + * Attaches the mock websocket object to the global object + */ + Server.prototype.start = function start () { + var globalObj = retrieveGlobalObject(); + + if (globalObj.WebSocket) { + this.originalWebSocket = globalObj.WebSocket; + } + + globalObj.WebSocket = WebSocket$1; + }; + + /* + * Removes the mock websocket object from the global object + */ + Server.prototype.stop = function stop (callback) { + if ( callback === void 0 ) callback = function () {}; + + var globalObj = retrieveGlobalObject(); + + if (this.originalWebSocket) { + globalObj.WebSocket = this.originalWebSocket; + } else { + delete globalObj.WebSocket; + } + + this.originalWebSocket = null; + + networkBridge.removeServer(this.url); + + if (typeof callback === 'function') { + callback(); + } + }; + + /* + * This is the main function for the mock server to subscribe to the on events. + * + * ie: mockServer.on('connection', function() { console.log('a mock client connected'); }); + * + * @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close. + * @param {function} callback - The callback which should be called when a certain event is fired. + */ + Server.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + }; + + /* + * Closes the connection and triggers the onclose method of all listening + * websockets. After that it removes itself from the urlMap so another server + * could add itself to the url. + * + * @param {object} options + */ + Server.prototype.close = function close (options) { + if ( options === void 0 ) options = {}; + + var code = options.code; + var reason = options.reason; + var wasClean = options.wasClean; + var listeners = networkBridge.websocketsLookup(this.url); + + // Remove server before notifications to prevent immediate reconnects from + // socket onclose handlers + networkBridge.removeServer(this.url); + + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent( + createCloseEvent({ + type: 'close', + target: socket, + code: code || CLOSE_CODES.CLOSE_NORMAL, + reason: reason || '', + wasClean: wasClean + }) + ); + }); + + this.dispatchEvent(createCloseEvent({ type: 'close' }), this); + }; + + /* + * Sends a generic message event to all mock clients. + */ + Server.prototype.emit = function emit (event, data, options) { + var this$1 = this; + if ( options === void 0 ) options = {}; + + var websockets = options.websockets; + + if (!websockets) { + websockets = networkBridge.websocketsLookup(this.url); + } + + if (typeof options !== 'object' || arguments.length > 3) { + data = Array.prototype.slice.call(arguments, 1, arguments.length); + data = data.map(function (item) { return normalizeSendData(item); }); + } else { + data = normalizeSendData(data); + } + + websockets.forEach(function (socket) { + if (Array.isArray(data)) { + socket.dispatchEvent.apply( + socket, [ createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) ].concat( data ) + ); + } else { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) + ); + } + }); + }; + + /* + * Returns an array of websockets which are listening to this server + * TOOD: this should return a set and not be a method + */ + Server.prototype.clients = function clients () { + return networkBridge.websocketsLookup(this.url); + }; + + /* + * Prepares a method to submit an event to members of the room + * + * e.g. server.to('my-room').emit('hi!'); + */ + Server.prototype.to = function to (room, broadcaster, broadcastList) { + var this$1 = this; + if ( broadcastList === void 0 ) broadcastList = []; + + var self = this; + var websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster))); + + return { + to: function (chainedRoom, chainedBroadcaster) { return this$1.to.call(this$1, chainedRoom, chainedBroadcaster, websockets); }, + emit: function emit(event, data) { + self.emit(event, data, { websockets: websockets }); + } + }; + }; + + /* + * Alias for Server.to + */ + Server.prototype.in = function in$1 () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return this.to.apply(null, args); + }; + + /* + * Simulate an event from the server to the clients. Useful for + * simulating errors. + */ + Server.prototype.simulate = function simulate (event) { + var listeners = networkBridge.websocketsLookup(this.url); + + if (event === 'error') { + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent(createEvent({ type: 'error' })); + }); + } + }; + + return Server; +}(EventTarget)); + +/* + * Alternative constructor to support namespaces in socket.io + * + * http://socket.io/docs/rooms-and-namespaces/#custom-namespaces + */ +Server$1.of = function of(url) { + return new Server$1(url); +}; + +/* +* The socket-io class is designed to mimick the real API as closely as possible. +* +* http://socket.io/docs/ +*/ +var SocketIO$1 = (function (EventTarget$$1) { + function SocketIO(url, protocol) { + var this$1 = this; + if ( url === void 0 ) url = 'socket.io'; + if ( protocol === void 0 ) protocol = ''; + + EventTarget$$1.call(this); + + this.binaryType = 'blob'; + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + this.readyState = SocketIO.CONNECTING; + this.protocol = ''; + + if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) { + this.protocol = protocol; + } else if (Array.isArray(protocol) && protocol.length > 0) { + this.protocol = protocol[0]; + } + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * Delay triggering the connection events so they can be defined in time. + */ + delay(function delayCallback() { + if (server) { + this.readyState = SocketIO.OPEN; + server.dispatchEvent(createEvent({ type: 'connection' }), server, this); + server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias + this.dispatchEvent(createEvent({ type: 'connect', target: this })); + } else { + this.readyState = SocketIO.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + log('error', ("Socket.io connection to '" + (this.url) + "' failed")); + } + }, this); + + /** + Add an aliased event listener for close / disconnect + */ + this.addEventListener('close', function (event) { + this$1.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: event.target, + code: event.code + }) + ); + }); + } + + if ( EventTarget$$1 ) SocketIO.__proto__ = EventTarget$$1; + SocketIO.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + SocketIO.prototype.constructor = SocketIO; + + var prototypeAccessors = { broadcast: {} }; + + /* + * Closes the SocketIO connection or connection attempt, if any. + * If the connection is already CLOSED, this method does nothing. + */ + SocketIO.prototype.close = function close () { + if (this.readyState !== SocketIO.OPEN) { + return undefined; + } + + var server = networkBridge.serverLookup(this.url); + networkBridge.removeWebSocket(this, this.url); + + this.readyState = SocketIO.CLOSED; + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + if (server) { + server.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }), + server + ); + } + + return this; + }; + + /* + * Alias for Socket#close + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383 + */ + SocketIO.prototype.disconnect = function disconnect () { + return this.close(); + }; + + /* + * Submits an event to the server with a payload + */ + SocketIO.prototype.emit = function emit (event) { + var data = [], len = arguments.length - 1; + while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ]; + + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var messageEvent = createMessageEvent({ + type: event, + origin: this.url, + data: data + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + server.dispatchEvent.apply(server, [ messageEvent ].concat( data )); + } + + return this; + }; + + /* + * Submits a 'message' event to the server. + * + * Should behave exactly like WebSocket#send + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113 + */ + SocketIO.prototype.send = function send (data) { + this.emit('message', data); + return this; + }; + + /* + * For broadcasting events to other connected sockets. + * + * e.g. socket.broadcast.emit('hi!'); + * e.g. socket.broadcast.to('my-room').emit('hi!'); + */ + prototypeAccessors.broadcast.get = function () { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var self = this; + var server = networkBridge.serverLookup(this.url); + if (!server) { + throw new Error(("SocketIO can not find a server at the specified URL (" + (this.url) + ")")); + } + + return { + emit: function emit(event, data) { + server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) }); + return self; + }, + to: function to(room) { + return server.to(room, self); + }, + in: function in$1(room) { + return server.in(room, self); + } + }; + }; + + /* + * For registering events to be received from the server + */ + SocketIO.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + return this; + }; + + /* + * Remove event listener + * + * https://socket.io/docs/client-api/#socket-on-eventname-callback + */ + SocketIO.prototype.off = function off (type) { + this.removeEventListener(type); + }; + + /* + * Join a room on a server + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.join = function join (room) { + networkBridge.addMembershipToRoom(this, room); + }; + + /* + * Get the websocket to leave the room + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.leave = function leave (room) { + networkBridge.removeMembershipFromRoom(this, room); + }; + + SocketIO.prototype.to = function to (room) { + return this.broadcast.to(room); + }; + + SocketIO.prototype.in = function in$1 () { + return this.to.apply(null, arguments); + }; + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + SocketIO.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + // Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data + // payload instanceof MessageEvent works, but you can't isntance of NodeEvent + // for now we detect if the output has data defined on it + listener.call(this$1, event.data ? event.data : event); + } + }); + }; + + Object.defineProperties( SocketIO.prototype, prototypeAccessors ); + + return SocketIO; +}(EventTarget)); + +SocketIO$1.CONNECTING = 0; +SocketIO$1.OPEN = 1; +SocketIO$1.CLOSING = 2; +SocketIO$1.CLOSED = 3; + +/* +* Static constructor methods for the IO Socket +*/ +var IO = function ioConstructor(url, protocol) { + return new SocketIO$1(url, protocol); +}; + +/* +* Alias the raw IO() constructor +*/ +IO.connect = function ioConnect(url, protocol) { + /* eslint-disable new-cap */ + return IO(url, protocol); + /* eslint-enable new-cap */ +}; + +var Server = Server$1; +var WebSocket = WebSocket$1; +var SocketIO = IO; + +exports.Server = Server; +exports.WebSocket = WebSocket; +exports.SocketIO = SocketIO; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zb2NrZXQuY2pzLmpzIiwic291cmNlcyI6WyIuLi9ub2RlX21vZHVsZXMvcmVxdWlyZXMtcG9ydC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZ2lmeS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91cmwtcGFyc2UvaW5kZXguanMiLCIuLi9zcmMvaGVscGVycy9kZWxheS5qcyIsIi4uL3NyYy9oZWxwZXJzL2xvZ2dlci5qcyIsIi4uL3NyYy9oZWxwZXJzL2FycmF5LWhlbHBlcnMuanMiLCIuLi9zcmMvZXZlbnQvdGFyZ2V0LmpzIiwiLi4vc3JjL25ldHdvcmstYnJpZGdlLmpzIiwiLi4vc3JjL2NvbnN0YW50cy5qcyIsIi4uL3NyYy9ldmVudC9wcm90b3R5cGUuanMiLCIuLi9zcmMvZXZlbnQvZXZlbnQuanMiLCIuLi9zcmMvZXZlbnQvbWVzc2FnZS5qcyIsIi4uL3NyYy9ldmVudC9jbG9zZS5qcyIsIi4uL3NyYy9ldmVudC9mYWN0b3J5LmpzIiwiLi4vc3JjL2FsZ29yaXRobXMvY2xvc2UuanMiLCIuLi9zcmMvaGVscGVycy9ub3JtYWxpemUtc2VuZC5qcyIsIi4uL3NyYy9oZWxwZXJzL3Byb3h5LWZhY3RvcnkuanMiLCIuLi9zcmMvaGVscGVycy9ieXRlLWxlbmd0aC5qcyIsIi4uL3NyYy9oZWxwZXJzL3VybC12ZXJpZmljYXRpb24uanMiLCIuLi9zcmMvaGVscGVycy9wcm90b2NvbC12ZXJpZmljYXRpb24uanMiLCIuLi9zcmMvd2Vic29ja2V0LmpzIiwiLi4vc3JjL2hlbHBlcnMvZGVkdXBlLmpzIiwiLi4vc3JjL2hlbHBlcnMvZ2xvYmFsLW9iamVjdC5qcyIsIi4uL3NyYy9zZXJ2ZXIuanMiLCIuLi9zcmMvc29ja2V0LWlvLmpzIiwiLi4vc3JjL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSdyZSByZXF1aXJlZCB0byBhZGQgYSBwb3J0IG51bWJlci5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jZGVmYXVsdC1wb3J0XG4gKiBAcGFyYW0ge051bWJlcnxTdHJpbmd9IHBvcnQgUG9ydCBudW1iZXIgd2UgbmVlZCB0byBjaGVja1xuICogQHBhcmFtIHtTdHJpbmd9IHByb3RvY29sIFByb3RvY29sIHdlIG5lZWQgdG8gY2hlY2sgYWdhaW5zdC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBJcyBpdCBhIGRlZmF1bHQgcG9ydCBmb3IgdGhlIGdpdmVuIHByb3RvY29sXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXF1aXJlZChwb3J0LCBwcm90b2NvbCkge1xuICBwcm90b2NvbCA9IHByb3RvY29sLnNwbGl0KCc6JylbMF07XG4gIHBvcnQgPSArcG9ydDtcblxuICBpZiAoIXBvcnQpIHJldHVybiBmYWxzZTtcblxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAnaHR0cCc6XG4gICAgY2FzZSAnd3MnOlxuICAgIHJldHVybiBwb3J0ICE9PSA4MDtcblxuICAgIGNhc2UgJ2h0dHBzJzpcbiAgICBjYXNlICd3c3MnOlxuICAgIHJldHVybiBwb3J0ICE9PSA0NDM7XG5cbiAgICBjYXNlICdmdHAnOlxuICAgIHJldHVybiBwb3J0ICE9PSAyMTtcblxuICAgIGNhc2UgJ2dvcGhlcic6XG4gICAgcmV0dXJuIHBvcnQgIT09IDcwO1xuXG4gICAgY2FzZSAnZmlsZSc6XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHBvcnQgIT09IDA7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBEZWNvZGUgYSBVUkkgZW5jb2RlZCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBVUkkgZW5jb2RlZCBzdHJpbmcuXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgZGVjb2RlZCBzdHJpbmcuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG4gIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoaW5wdXQucmVwbGFjZSgvXFwrL2csICcgJykpO1xufVxuXG4vKipcbiAqIFNpbXBsZSBxdWVyeSBzdHJpbmcgcGFyc2VyLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBxdWVyeSBUaGUgcXVlcnkgc3RyaW5nIHRoYXQgbmVlZHMgdG8gYmUgcGFyc2VkLlxuICogQHJldHVybnMge09iamVjdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5c3RyaW5nKHF1ZXJ5KSB7XG4gIHZhciBwYXJzZXIgPSAvKFtePT8mXSspPT8oW14mXSopL2dcbiAgICAsIHJlc3VsdCA9IHt9XG4gICAgLCBwYXJ0O1xuXG4gIHdoaWxlIChwYXJ0ID0gcGFyc2VyLmV4ZWMocXVlcnkpKSB7XG4gICAgdmFyIGtleSA9IGRlY29kZShwYXJ0WzFdKVxuICAgICAgLCB2YWx1ZSA9IGRlY29kZShwYXJ0WzJdKTtcblxuICAgIC8vXG4gICAgLy8gUHJldmVudCBvdmVycmlkaW5nIG9mIGV4aXN0aW5nIHByb3BlcnRpZXMuIFRoaXMgZW5zdXJlcyB0aGF0IGJ1aWxkLWluXG4gICAgLy8gbWV0aG9kcyBsaWtlIGB0b1N0cmluZ2Agb3IgX19wcm90b19fIGFyZSBub3Qgb3ZlcnJpZGVuIGJ5IG1hbGljaW91c1xuICAgIC8vIHF1ZXJ5c3RyaW5ncy5cbiAgICAvL1xuICAgIGlmIChrZXkgaW4gcmVzdWx0KSBjb250aW51ZTtcbiAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBUcmFuc2Zvcm0gYSBxdWVyeSBzdHJpbmcgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogT2JqZWN0IHRoYXQgc2hvdWxkIGJlIHRyYW5zZm9ybWVkLlxuICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeCBPcHRpb25hbCBwcmVmaXguXG4gKiBAcmV0dXJucyB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gcXVlcnlzdHJpbmdpZnkob2JqLCBwcmVmaXgpIHtcbiAgcHJlZml4ID0gcHJlZml4IHx8ICcnO1xuXG4gIHZhciBwYWlycyA9IFtdO1xuXG4gIC8vXG4gIC8vIE9wdGlvbmFsbHkgcHJlZml4IHdpdGggYSAnPycgaWYgbmVlZGVkXG4gIC8vXG4gIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIHByZWZpeCkgcHJlZml4ID0gJz8nO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzLmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsnPScrIGVuY29kZVVSSUNvbXBvbmVudChvYmpba2V5XSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWlycy5sZW5ndGggPyBwcmVmaXggKyBwYWlycy5qb2luKCcmJykgOiAnJztcbn1cblxuLy9cbi8vIEV4cG9zZSB0aGUgbW9kdWxlLlxuLy9cbmV4cG9ydHMuc3RyaW5naWZ5ID0gcXVlcnlzdHJpbmdpZnk7XG5leHBvcnRzLnBhcnNlID0gcXVlcnlzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZXF1aXJlZCA9IHJlcXVpcmUoJ3JlcXVpcmVzLXBvcnQnKVxuICAsIHFzID0gcmVxdWlyZSgncXVlcnlzdHJpbmdpZnknKVxuICAsIHByb3RvY29scmUgPSAvXihbYS16XVthLXowLTkuKy1dKjopPyhcXC9cXC8pPyhbXFxTXFxzXSopL2lcbiAgLCBzbGFzaGVzID0gL15bQS1aYS16XVtBLVphLXowLTkrLS5dKjpcXC9cXC8vO1xuXG4vKipcbiAqIFRoZXNlIGFyZSB0aGUgcGFyc2UgcnVsZXMgZm9yIHRoZSBVUkwgcGFyc2VyLCBpdCBpbmZvcm1zIHRoZSBwYXJzZXJcbiAqIGFib3V0OlxuICpcbiAqIDAuIFRoZSBjaGFyIGl0IE5lZWRzIHRvIHBhcnNlLCBpZiBpdCdzIGEgc3RyaW5nIGl0IHNob3VsZCBiZSBkb25lIHVzaW5nXG4gKiAgICBpbmRleE9mLCBSZWdFeHAgdXNpbmcgZXhlYyBhbmQgTmFOIG1lYW5zIHNldCBhcyBjdXJyZW50IHZhbHVlLlxuICogMS4gVGhlIHByb3BlcnR5IHdlIHNob3VsZCBzZXQgd2hlbiBwYXJzaW5nIHRoaXMgdmFsdWUuXG4gKiAyLiBJbmRpY2F0aW9uIGlmIGl0J3MgYmFja3dhcmRzIG9yIGZvcndhcmQgcGFyc2luZywgd2hlbiBzZXQgYXMgbnVtYmVyIGl0J3NcbiAqICAgIHRoZSB2YWx1ZSBvZiBleHRyYSBjaGFycyB0aGF0IHNob3VsZCBiZSBzcGxpdCBvZmYuXG4gKiAzLiBJbmhlcml0IGZyb20gbG9jYXRpb24gaWYgbm9uIGV4aXN0aW5nIGluIHRoZSBwYXJzZXIuXG4gKiA0LiBgdG9Mb3dlckNhc2VgIHRoZSByZXN1bHRpbmcgdmFsdWUuXG4gKi9cbnZhciBydWxlcyA9IFtcbiAgWycjJywgJ2hhc2gnXSwgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGJhY2suXG4gIFsnPycsICdxdWVyeSddLCAgICAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBmcm9tIHRoZSBiYWNrLlxuICBbJy8nLCAncGF0aG5hbWUnXSwgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgYmFjay5cbiAgWydAJywgJ2F1dGgnLCAxXSwgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGZyb250LlxuICBbTmFOLCAnaG9zdCcsIHVuZGVmaW5lZCwgMSwgMV0sICAgICAgIC8vIFNldCBsZWZ0IG92ZXIgdmFsdWUuXG4gIFsvOihcXGQrKSQvLCAncG9ydCcsIHVuZGVmaW5lZCwgMV0sICAgIC8vIFJlZ0V4cCB0aGUgYmFjay5cbiAgW05hTiwgJ2hvc3RuYW1lJywgdW5kZWZpbmVkLCAxLCAxXSAgICAvLyBTZXQgbGVmdCBvdmVyLlxuXTtcblxuLyoqXG4gKiBUaGVzZSBwcm9wZXJ0aWVzIHNob3VsZCBub3QgYmUgY29waWVkIG9yIGluaGVyaXRlZCBmcm9tLiBUaGlzIGlzIG9ubHkgbmVlZGVkXG4gKiBmb3IgYWxsIG5vbiBibG9iIFVSTCdzIGFzIGEgYmxvYiBVUkwgZG9lcyBub3QgaW5jbHVkZSBhIGhhc2gsIG9ubHkgdGhlXG4gKiBvcmlnaW4uXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcml2YXRlXG4gKi9cbnZhciBpZ25vcmUgPSB7IGhhc2g6IDEsIHF1ZXJ5OiAxIH07XG5cbi8qKlxuICogVGhlIGxvY2F0aW9uIG9iamVjdCBkaWZmZXJzIHdoZW4geW91ciBjb2RlIGlzIGxvYWRlZCB0aHJvdWdoIGEgbm9ybWFsIHBhZ2UsXG4gKiBXb3JrZXIgb3IgdGhyb3VnaCBhIHdvcmtlciB1c2luZyBhIGJsb2IuIEFuZCB3aXRoIHRoZSBibG9iYmxlIGJlZ2lucyB0aGVcbiAqIHRyb3VibGUgYXMgdGhlIGxvY2F0aW9uIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhlIFVSTCBvZiB0aGUgYmxvYiwgbm90IHRoZVxuICogbG9jYXRpb24gb2YgdGhlIHBhZ2Ugd2hlcmUgb3VyIGNvZGUgaXMgbG9hZGVkIGluLiBUaGUgYWN0dWFsIG9yaWdpbiBpc1xuICogZW5jb2RlZCBpbiB0aGUgYHBhdGhuYW1lYCBzbyB3ZSBjYW4gdGhhbmtmdWxseSBnZW5lcmF0ZSBhIGdvb2QgXCJkZWZhdWx0XCJcbiAqIGxvY2F0aW9uIGZyb20gaXQgc28gd2UgY2FuIGdlbmVyYXRlIHByb3BlciByZWxhdGl2ZSBVUkwncyBhZ2Fpbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGxvYyBPcHRpb25hbCBkZWZhdWx0IGxvY2F0aW9uIG9iamVjdC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IGxvbGNhdGlvbiBvYmplY3QuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBsb2xjYXRpb24obG9jKSB7XG4gIHZhciBsb2NhdGlvbiA9IGdsb2JhbCAmJiBnbG9iYWwubG9jYXRpb24gfHwge307XG4gIGxvYyA9IGxvYyB8fCBsb2NhdGlvbjtcblxuICB2YXIgZmluYWxkZXN0aW5hdGlvbiA9IHt9XG4gICAgLCB0eXBlID0gdHlwZW9mIGxvY1xuICAgICwga2V5O1xuXG4gIGlmICgnYmxvYjonID09PSBsb2MucHJvdG9jb2wpIHtcbiAgICBmaW5hbGRlc3RpbmF0aW9uID0gbmV3IFVSTCh1bmVzY2FwZShsb2MucGF0aG5hbWUpLCB7fSk7XG4gIH0gZWxzZSBpZiAoJ3N0cmluZycgPT09IHR5cGUpIHtcbiAgICBmaW5hbGRlc3RpbmF0aW9uID0gbmV3IFVSTChsb2MsIHt9KTtcbiAgICBmb3IgKGtleSBpbiBpZ25vcmUpIGRlbGV0ZSBmaW5hbGRlc3RpbmF0aW9uW2tleV07XG4gIH0gZWxzZSBpZiAoJ29iamVjdCcgPT09IHR5cGUpIHtcbiAgICBmb3IgKGtleSBpbiBsb2MpIHtcbiAgICAgIGlmIChrZXkgaW4gaWdub3JlKSBjb250aW51ZTtcbiAgICAgIGZpbmFsZGVzdGluYXRpb25ba2V5XSA9IGxvY1trZXldO1xuICAgIH1cblxuICAgIGlmIChmaW5hbGRlc3RpbmF0aW9uLnNsYXNoZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmluYWxkZXN0aW5hdGlvbi5zbGFzaGVzID0gc2xhc2hlcy50ZXN0KGxvYy5ocmVmKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmluYWxkZXN0aW5hdGlvbjtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBQcm90b2NvbEV4dHJhY3RcbiAqIEB0eXBlIE9iamVjdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHByb3RvY29sIFByb3RvY29sIG1hdGNoZWQgaW4gdGhlIFVSTCwgaW4gbG93ZXJjYXNlLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBzbGFzaGVzIGB0cnVlYCBpZiBwcm90b2NvbCBpcyBmb2xsb3dlZCBieSBcIi8vXCIsIGVsc2UgYGZhbHNlYC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZXN0IFJlc3Qgb2YgdGhlIFVSTCB0aGF0IGlzIG5vdCBwYXJ0IG9mIHRoZSBwcm90b2NvbC5cbiAqL1xuXG4vKipcbiAqIEV4dHJhY3QgcHJvdG9jb2wgaW5mb3JtYXRpb24gZnJvbSBhIFVSTCB3aXRoL3dpdGhvdXQgZG91YmxlIHNsYXNoIChcIi8vXCIpLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzIFVSTCB3ZSB3YW50IHRvIGV4dHJhY3QgZnJvbS5cbiAqIEByZXR1cm4ge1Byb3RvY29sRXh0cmFjdH0gRXh0cmFjdGVkIGluZm9ybWF0aW9uLlxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQcm90b2NvbChhZGRyZXNzKSB7XG4gIHZhciBtYXRjaCA9IHByb3RvY29scmUuZXhlYyhhZGRyZXNzKTtcblxuICByZXR1cm4ge1xuICAgIHByb3RvY29sOiBtYXRjaFsxXSA/IG1hdGNoWzFdLnRvTG93ZXJDYXNlKCkgOiAnJyxcbiAgICBzbGFzaGVzOiAhIW1hdGNoWzJdLFxuICAgIHJlc3Q6IG1hdGNoWzNdXG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlbGF0aXZlIFVSTCBwYXRobmFtZSBhZ2FpbnN0IGEgYmFzZSBVUkwgcGF0aG5hbWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlbGF0aXZlIFBhdGhuYW1lIG9mIHRoZSByZWxhdGl2ZSBVUkwuXG4gKiBAcGFyYW0ge1N0cmluZ30gYmFzZSBQYXRobmFtZSBvZiB0aGUgYmFzZSBVUkwuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IFJlc29sdmVkIHBhdGhuYW1lLlxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmUocmVsYXRpdmUsIGJhc2UpIHtcbiAgdmFyIHBhdGggPSAoYmFzZSB8fCAnLycpLnNwbGl0KCcvJykuc2xpY2UoMCwgLTEpLmNvbmNhdChyZWxhdGl2ZS5zcGxpdCgnLycpKVxuICAgICwgaSA9IHBhdGgubGVuZ3RoXG4gICAgLCBsYXN0ID0gcGF0aFtpIC0gMV1cbiAgICAsIHVuc2hpZnQgPSBmYWxzZVxuICAgICwgdXAgPSAwO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAocGF0aFtpXSA9PT0gJy4nKSB7XG4gICAgICBwYXRoLnNwbGljZShpLCAxKTtcbiAgICB9IGVsc2UgaWYgKHBhdGhbaV0gPT09ICcuLicpIHtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBpZiAoaSA9PT0gMCkgdW5zaGlmdCA9IHRydWU7XG4gICAgICBwYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwLS07XG4gICAgfVxuICB9XG5cbiAgaWYgKHVuc2hpZnQpIHBhdGgudW5zaGlmdCgnJyk7XG4gIGlmIChsYXN0ID09PSAnLicgfHwgbGFzdCA9PT0gJy4uJykgcGF0aC5wdXNoKCcnKTtcblxuICByZXR1cm4gcGF0aC5qb2luKCcvJyk7XG59XG5cbi8qKlxuICogVGhlIGFjdHVhbCBVUkwgaW5zdGFuY2UuIEluc3RlYWQgb2YgcmV0dXJuaW5nIGFuIG9iamVjdCB3ZSd2ZSBvcHRlZC1pbiB0b1xuICogY3JlYXRlIGFuIGFjdHVhbCBjb25zdHJ1Y3RvciBhcyBpdCdzIG11Y2ggbW9yZSBtZW1vcnkgZWZmaWNpZW50IGFuZFxuICogZmFzdGVyIGFuZCBpdCBwbGVhc2VzIG15IE9DRC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzIFVSTCB3ZSB3YW50IHRvIHBhcnNlLlxuICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBsb2NhdGlvbiBMb2NhdGlvbiBkZWZhdWx0cyBmb3IgcmVsYXRpdmUgcGF0aHMuXG4gKiBAcGFyYW0ge0Jvb2xlYW58RnVuY3Rpb259IHBhcnNlciBQYXJzZXIgZm9yIHRoZSBxdWVyeSBzdHJpbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBVUkwoYWRkcmVzcywgbG9jYXRpb24sIHBhcnNlcikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVVJMKSkge1xuICAgIHJldHVybiBuZXcgVVJMKGFkZHJlc3MsIGxvY2F0aW9uLCBwYXJzZXIpO1xuICB9XG5cbiAgdmFyIHJlbGF0aXZlLCBleHRyYWN0ZWQsIHBhcnNlLCBpbnN0cnVjdGlvbiwgaW5kZXgsIGtleVxuICAgICwgaW5zdHJ1Y3Rpb25zID0gcnVsZXMuc2xpY2UoKVxuICAgICwgdHlwZSA9IHR5cGVvZiBsb2NhdGlvblxuICAgICwgdXJsID0gdGhpc1xuICAgICwgaSA9IDA7XG5cbiAgLy9cbiAgLy8gVGhlIGZvbGxvd2luZyBpZiBzdGF0ZW1lbnRzIGFsbG93cyB0aGlzIG1vZHVsZSB0d28gaGF2ZSBjb21wYXRpYmlsaXR5IHdpdGhcbiAgLy8gMiBkaWZmZXJlbnQgQVBJOlxuICAvL1xuICAvLyAxLiBOb2RlLmpzJ3MgYHVybC5wYXJzZWAgYXBpIHdoaWNoIGFjY2VwdHMgYSBVUkwsIGJvb2xlYW4gYXMgYXJndW1lbnRzXG4gIC8vICAgIHdoZXJlIHRoZSBib29sZWFuIGluZGljYXRlcyB0aGF0IHRoZSBxdWVyeSBzdHJpbmcgc2hvdWxkIGFsc28gYmUgcGFyc2VkLlxuICAvL1xuICAvLyAyLiBUaGUgYFVSTGAgaW50ZXJmYWNlIG9mIHRoZSBicm93c2VyIHdoaWNoIGFjY2VwdHMgYSBVUkwsIG9iamVjdCBhc1xuICAvLyAgICBhcmd1bWVudHMuIFRoZSBzdXBwbGllZCBvYmplY3Qgd2lsbCBiZSB1c2VkIGFzIGRlZmF1bHQgdmFsdWVzIC8gZmFsbC1iYWNrXG4gIC8vICAgIGZvciByZWxhdGl2ZSBwYXRocy5cbiAgLy9cbiAgaWYgKCdvYmplY3QnICE9PSB0eXBlICYmICdzdHJpbmcnICE9PSB0eXBlKSB7XG4gICAgcGFyc2VyID0gbG9jYXRpb247XG4gICAgbG9jYXRpb24gPSBudWxsO1xuICB9XG5cbiAgaWYgKHBhcnNlciAmJiAnZnVuY3Rpb24nICE9PSB0eXBlb2YgcGFyc2VyKSBwYXJzZXIgPSBxcy5wYXJzZTtcblxuICBsb2NhdGlvbiA9IGxvbGNhdGlvbihsb2NhdGlvbik7XG5cbiAgLy9cbiAgLy8gRXh0cmFjdCBwcm90b2NvbCBpbmZvcm1hdGlvbiBiZWZvcmUgcnVubmluZyB0aGUgaW5zdHJ1Y3Rpb25zLlxuICAvL1xuICBleHRyYWN0ZWQgPSBleHRyYWN0UHJvdG9jb2woYWRkcmVzcyB8fCAnJyk7XG4gIHJlbGF0aXZlID0gIWV4dHJhY3RlZC5wcm90b2NvbCAmJiAhZXh0cmFjdGVkLnNsYXNoZXM7XG4gIHVybC5zbGFzaGVzID0gZXh0cmFjdGVkLnNsYXNoZXMgfHwgcmVsYXRpdmUgJiYgbG9jYXRpb24uc2xhc2hlcztcbiAgdXJsLnByb3RvY29sID0gZXh0cmFjdGVkLnByb3RvY29sIHx8IGxvY2F0aW9uLnByb3RvY29sIHx8ICcnO1xuICBhZGRyZXNzID0gZXh0cmFjdGVkLnJlc3Q7XG5cbiAgLy9cbiAgLy8gV2hlbiB0aGUgYXV0aG9yaXR5IGNvbXBvbmVudCBpcyBhYnNlbnQgdGhlIFVSTCBzdGFydHMgd2l0aCBhIHBhdGhcbiAgLy8gY29tcG9uZW50LlxuICAvL1xuICBpZiAoIWV4dHJhY3RlZC5zbGFzaGVzKSBpbnN0cnVjdGlvbnNbMl0gPSBbLyguKikvLCAncGF0aG5hbWUnXTtcblxuICBmb3IgKDsgaSA8IGluc3RydWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIGluc3RydWN0aW9uID0gaW5zdHJ1Y3Rpb25zW2ldO1xuICAgIHBhcnNlID0gaW5zdHJ1Y3Rpb25bMF07XG4gICAga2V5ID0gaW5zdHJ1Y3Rpb25bMV07XG5cbiAgICBpZiAocGFyc2UgIT09IHBhcnNlKSB7XG4gICAgICB1cmxba2V5XSA9IGFkZHJlc3M7XG4gICAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHBhcnNlKSB7XG4gICAgICBpZiAofihpbmRleCA9IGFkZHJlc3MuaW5kZXhPZihwYXJzZSkpKSB7XG4gICAgICAgIGlmICgnbnVtYmVyJyA9PT0gdHlwZW9mIGluc3RydWN0aW9uWzJdKSB7XG4gICAgICAgICAgdXJsW2tleV0gPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgICBhZGRyZXNzID0gYWRkcmVzcy5zbGljZShpbmRleCArIGluc3RydWN0aW9uWzJdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cmxba2V5XSA9IGFkZHJlc3Muc2xpY2UoaW5kZXgpO1xuICAgICAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKGluZGV4ID0gcGFyc2UuZXhlYyhhZGRyZXNzKSkpIHtcbiAgICAgIHVybFtrZXldID0gaW5kZXhbMV07XG4gICAgICBhZGRyZXNzID0gYWRkcmVzcy5zbGljZSgwLCBpbmRleC5pbmRleCk7XG4gICAgfVxuXG4gICAgdXJsW2tleV0gPSB1cmxba2V5XSB8fCAoXG4gICAgICByZWxhdGl2ZSAmJiBpbnN0cnVjdGlvblszXSA/IGxvY2F0aW9uW2tleV0gfHwgJycgOiAnJ1xuICAgICk7XG5cbiAgICAvL1xuICAgIC8vIEhvc3RuYW1lLCBob3N0IGFuZCBwcm90b2NvbCBzaG91bGQgYmUgbG93ZXJjYXNlZCBzbyB0aGV5IGNhbiBiZSB1c2VkIHRvXG4gICAgLy8gY3JlYXRlIGEgcHJvcGVyIGBvcmlnaW5gLlxuICAgIC8vXG4gICAgaWYgKGluc3RydWN0aW9uWzRdKSB1cmxba2V5XSA9IHVybFtrZXldLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvL1xuICAvLyBBbHNvIHBhcnNlIHRoZSBzdXBwbGllZCBxdWVyeSBzdHJpbmcgaW4gdG8gYW4gb2JqZWN0LiBJZiB3ZSdyZSBzdXBwbGllZFxuICAvLyB3aXRoIGEgY3VzdG9tIHBhcnNlciBhcyBmdW5jdGlvbiB1c2UgdGhhdCBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IGJ1aWxkLWluXG4gIC8vIHBhcnNlci5cbiAgLy9cbiAgaWYgKHBhcnNlcikgdXJsLnF1ZXJ5ID0gcGFyc2VyKHVybC5xdWVyeSk7XG5cbiAgLy9cbiAgLy8gSWYgdGhlIFVSTCBpcyByZWxhdGl2ZSwgcmVzb2x2ZSB0aGUgcGF0aG5hbWUgYWdhaW5zdCB0aGUgYmFzZSBVUkwuXG4gIC8vXG4gIGlmIChcbiAgICAgIHJlbGF0aXZlXG4gICAgJiYgbG9jYXRpb24uc2xhc2hlc1xuICAgICYmIHVybC5wYXRobmFtZS5jaGFyQXQoMCkgIT09ICcvJ1xuICAgICYmICh1cmwucGF0aG5hbWUgIT09ICcnIHx8IGxvY2F0aW9uLnBhdGhuYW1lICE9PSAnJylcbiAgKSB7XG4gICAgdXJsLnBhdGhuYW1lID0gcmVzb2x2ZSh1cmwucGF0aG5hbWUsIGxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgfVxuXG4gIC8vXG4gIC8vIFdlIHNob3VsZCBub3QgYWRkIHBvcnQgbnVtYmVycyBpZiB0aGV5IGFyZSBhbHJlYWR5IHRoZSBkZWZhdWx0IHBvcnQgbnVtYmVyXG4gIC8vIGZvciBhIGdpdmVuIHByb3RvY29sLiBBcyB0aGUgaG9zdCBhbHNvIGNvbnRhaW5zIHRoZSBwb3J0IG51bWJlciB3ZSdyZSBnb2luZ1xuICAvLyBvdmVycmlkZSBpdCB3aXRoIHRoZSBob3N0bmFtZSB3aGljaCBjb250YWlucyBubyBwb3J0IG51bWJlci5cbiAgLy9cbiAgaWYgKCFyZXF1aXJlZCh1cmwucG9ydCwgdXJsLnByb3RvY29sKSkge1xuICAgIHVybC5ob3N0ID0gdXJsLmhvc3RuYW1lO1xuICAgIHVybC5wb3J0ID0gJyc7XG4gIH1cblxuICAvL1xuICAvLyBQYXJzZSBkb3duIHRoZSBgYXV0aGAgZm9yIHRoZSB1c2VybmFtZSBhbmQgcGFzc3dvcmQuXG4gIC8vXG4gIHVybC51c2VybmFtZSA9IHVybC5wYXNzd29yZCA9ICcnO1xuICBpZiAodXJsLmF1dGgpIHtcbiAgICBpbnN0cnVjdGlvbiA9IHVybC5hdXRoLnNwbGl0KCc6Jyk7XG4gICAgdXJsLnVzZXJuYW1lID0gaW5zdHJ1Y3Rpb25bMF0gfHwgJyc7XG4gICAgdXJsLnBhc3N3b3JkID0gaW5zdHJ1Y3Rpb25bMV0gfHwgJyc7XG4gIH1cblxuICB1cmwub3JpZ2luID0gdXJsLnByb3RvY29sICYmIHVybC5ob3N0ICYmIHVybC5wcm90b2NvbCAhPT0gJ2ZpbGU6J1xuICAgID8gdXJsLnByb3RvY29sICsnLy8nKyB1cmwuaG9zdFxuICAgIDogJ251bGwnO1xuXG4gIC8vXG4gIC8vIFRoZSBocmVmIGlzIGp1c3QgdGhlIGNvbXBpbGVkIHJlc3VsdC5cbiAgLy9cbiAgdXJsLmhyZWYgPSB1cmwudG9TdHJpbmcoKTtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IgY2hhbmdpbmcgcHJvcGVydGllcyBpbiB0aGUgVVJMIGluc3RhbmNlIHRvXG4gKiBpbnN1cmUgdGhhdCB0aGV5IGFsbCBwcm9wYWdhdGUgY29ycmVjdGx5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXJ0ICAgICAgICAgIFByb3BlcnR5IHdlIG5lZWQgdG8gYWRqdXN0LlxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgICAgICAgICAgVGhlIG5ld2x5IGFzc2lnbmVkIHZhbHVlLlxuICogQHBhcmFtIHtCb29sZWFufEZ1bmN0aW9ufSBmbiAgV2hlbiBzZXR0aW5nIHRoZSBxdWVyeSwgaXQgd2lsbCBiZSB0aGUgZnVuY3Rpb25cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgdG8gcGFyc2UgdGhlIHF1ZXJ5LlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2hlbiBzZXR0aW5nIHRoZSBwcm90b2NvbCwgZG91YmxlIHNsYXNoIHdpbGwgYmVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgZnJvbSB0aGUgZmluYWwgdXJsIGlmIGl0IGlzIHRydWUuXG4gKiBAcmV0dXJucyB7VVJMfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gc2V0KHBhcnQsIHZhbHVlLCBmbikge1xuICB2YXIgdXJsID0gdGhpcztcblxuICBzd2l0Y2ggKHBhcnQpIHtcbiAgICBjYXNlICdxdWVyeSc6XG4gICAgICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB2YWx1ZSAmJiB2YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgdmFsdWUgPSAoZm4gfHwgcXMucGFyc2UpKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3BvcnQnOlxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG5cbiAgICAgIGlmICghcmVxdWlyZWQodmFsdWUsIHVybC5wcm90b2NvbCkpIHtcbiAgICAgICAgdXJsLmhvc3QgPSB1cmwuaG9zdG5hbWU7XG4gICAgICAgIHVybFtwYXJ0XSA9ICcnO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgICB1cmwuaG9zdCA9IHVybC5ob3N0bmFtZSArJzonKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdob3N0bmFtZSc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKHVybC5wb3J0KSB2YWx1ZSArPSAnOicrIHVybC5wb3J0O1xuICAgICAgdXJsLmhvc3QgPSB2YWx1ZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaG9zdCc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKC86XFxkKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoJzonKTtcbiAgICAgICAgdXJsLnBvcnQgPSB2YWx1ZS5wb3AoKTtcbiAgICAgICAgdXJsLmhvc3RuYW1lID0gdmFsdWUuam9pbignOicpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJsLmhvc3RuYW1lID0gdmFsdWU7XG4gICAgICAgIHVybC5wb3J0ID0gJyc7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncHJvdG9jb2wnOlxuICAgICAgdXJsLnByb3RvY29sID0gdmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIHVybC5zbGFzaGVzID0gIWZuO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwYXRobmFtZSc6XG4gICAgY2FzZSAnaGFzaCc6XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFyIGNoYXIgPSBwYXJ0ID09PSAncGF0aG5hbWUnID8gJy8nIDogJyMnO1xuICAgICAgICB1cmxbcGFydF0gPSB2YWx1ZS5jaGFyQXQoMCkgIT09IGNoYXIgPyBjaGFyICsgdmFsdWUgOiB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJ1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGlucyA9IHJ1bGVzW2ldO1xuXG4gICAgaWYgKGluc1s0XSkgdXJsW2luc1sxXV0gPSB1cmxbaW5zWzFdXS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgdXJsLm9yaWdpbiA9IHVybC5wcm90b2NvbCAmJiB1cmwuaG9zdCAmJiB1cmwucHJvdG9jb2wgIT09ICdmaWxlOidcbiAgICA/IHVybC5wcm90b2NvbCArJy8vJysgdXJsLmhvc3RcbiAgICA6ICdudWxsJztcblxuICB1cmwuaHJlZiA9IHVybC50b1N0cmluZygpO1xuXG4gIHJldHVybiB1cmw7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBwcm9wZXJ0aWVzIGJhY2sgaW4gdG8gYSB2YWxpZCBhbmQgZnVsbCBVUkwgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZ2lmeSBPcHRpb25hbCBxdWVyeSBzdHJpbmdpZnkgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gdG9TdHJpbmcoc3RyaW5naWZ5KSB7XG4gIGlmICghc3RyaW5naWZ5IHx8ICdmdW5jdGlvbicgIT09IHR5cGVvZiBzdHJpbmdpZnkpIHN0cmluZ2lmeSA9IHFzLnN0cmluZ2lmeTtcblxuICB2YXIgcXVlcnlcbiAgICAsIHVybCA9IHRoaXNcbiAgICAsIHByb3RvY29sID0gdXJsLnByb3RvY29sO1xuXG4gIGlmIChwcm90b2NvbCAmJiBwcm90b2NvbC5jaGFyQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09ICc6JykgcHJvdG9jb2wgKz0gJzonO1xuXG4gIHZhciByZXN1bHQgPSBwcm90b2NvbCArICh1cmwuc2xhc2hlcyA/ICcvLycgOiAnJyk7XG5cbiAgaWYgKHVybC51c2VybmFtZSkge1xuICAgIHJlc3VsdCArPSB1cmwudXNlcm5hbWU7XG4gICAgaWYgKHVybC5wYXNzd29yZCkgcmVzdWx0ICs9ICc6JysgdXJsLnBhc3N3b3JkO1xuICAgIHJlc3VsdCArPSAnQCc7XG4gIH1cblxuICByZXN1bHQgKz0gdXJsLmhvc3QgKyB1cmwucGF0aG5hbWU7XG5cbiAgcXVlcnkgPSAnb2JqZWN0JyA9PT0gdHlwZW9mIHVybC5xdWVyeSA/IHN0cmluZ2lmeSh1cmwucXVlcnkpIDogdXJsLnF1ZXJ5O1xuICBpZiAocXVlcnkpIHJlc3VsdCArPSAnPycgIT09IHF1ZXJ5LmNoYXJBdCgwKSA/ICc/JysgcXVlcnkgOiBxdWVyeTtcblxuICBpZiAodXJsLmhhc2gpIHJlc3VsdCArPSB1cmwuaGFzaDtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5VUkwucHJvdG90eXBlID0geyBzZXQ6IHNldCwgdG9TdHJpbmc6IHRvU3RyaW5nIH07XG5cbi8vXG4vLyBFeHBvc2UgdGhlIFVSTCBwYXJzZXIgYW5kIHNvbWUgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRoYXQgbWlnaHQgYmUgdXNlZnVsIGZvclxuLy8gb3RoZXJzIG9yIHRlc3RpbmcuXG4vL1xuVVJMLmV4dHJhY3RQcm90b2NvbCA9IGV4dHJhY3RQcm90b2NvbDtcblVSTC5sb2NhdGlvbiA9IGxvbGNhdGlvbjtcblVSTC5xcyA9IHFzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFVSTDtcbiIsIi8qXG4qIFRoaXMgZGVsYXkgYWxsb3dzIHRoZSB0aHJlYWQgdG8gZmluaXNoIGFzc2lnbmluZyBpdHMgb24qIG1ldGhvZHNcbiogYmVmb3JlIGludm9raW5nIHRoZSBkZWxheSBjYWxsYmFjay4gVGhpcyBpcyBwdXJlbHkgYSB0aW1pbmcgaGFjay5cbiogaHR0cDovL2dlZWthYnl0ZS5ibG9nc3BvdC5jb20vMjAxNC8wMS9qYXZhc2NyaXB0LWVmZmVjdC1vZi1zZXR0aW5nLXNldHRpbWVvdXQuaHRtbFxuKlxuKiBAcGFyYW0ge2NhbGxiYWNrOiBmdW5jdGlvbn0gdGhlIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgaW52b2tlZCBhZnRlciB0aGUgdGltZW91dFxuKiBAcGFybWEge2NvbnRleHQ6IG9iamVjdH0gdGhlIGNvbnRleHQgaW4gd2hpY2ggdG8gaW52b2tlIHRoZSBmdW5jdGlvblxuKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRlbGF5KGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIHNldFRpbWVvdXQodGltZW91dENvbnRleHQgPT4gY2FsbGJhY2suY2FsbCh0aW1lb3V0Q29udGV4dCksIDQsIGNvbnRleHQpO1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbG9nKG1ldGhvZCwgbWVzc2FnZSkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0Jykge1xuICAgIGNvbnNvbGVbbWV0aG9kXS5jYWxsKG51bGwsIG1lc3NhZ2UpO1xuICB9XG4gIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIHJlamVjdChhcnJheSwgY2FsbGJhY2spIHtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBhcnJheS5mb3JFYWNoKGl0ZW1JbkFycmF5ID0+IHtcbiAgICBpZiAoIWNhbGxiYWNrKGl0ZW1JbkFycmF5KSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGl0ZW1JbkFycmF5KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyKGFycmF5LCBjYWxsYmFjaykge1xuICBjb25zdCByZXN1bHRzID0gW107XG4gIGFycmF5LmZvckVhY2goaXRlbUluQXJyYXkgPT4ge1xuICAgIGlmIChjYWxsYmFjayhpdGVtSW5BcnJheSkpIHtcbiAgICAgIHJlc3VsdHMucHVzaChpdGVtSW5BcnJheSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0cztcbn1cbiIsImltcG9ydCB7IHJlamVjdCwgZmlsdGVyIH0gZnJvbSAnLi4vaGVscGVycy9hcnJheS1oZWxwZXJzJztcblxuLypcbiogRXZlbnRUYXJnZXQgaXMgYW4gaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5IG9iamVjdHMgdGhhdCBjYW5cbiogcmVjZWl2ZSBldmVudHMgYW5kIG1heSBoYXZlIGxpc3RlbmVycyBmb3IgdGhlbS5cbipcbiogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0XG4qL1xuY2xhc3MgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmxpc3RlbmVycyA9IHt9O1xuICB9XG5cbiAgLypcbiAgKiBUaWVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYW4gZXZlbnQgdHlwZSB3aGljaCBjYW4gbGF0ZXIgYmUgaW52b2tlZCB2aWEgdGhlXG4gICogZGlzcGF0Y2hFdmVudCBtZXRob2QuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIHRoZSB0eXBlIG9mIGV2ZW50IChpZTogJ29wZW4nLCAnbWVzc2FnZScsIGV0Yy4pXG4gICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWQgbWF0Y2hpbmcgdGhlIGdpdmVuIHR5cGVcbiAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUNhcHR1cmUgLSBOL0EgVE9ETzogaW1wbGVtZW50IHVzZUNhcHR1cmUgZnVuY3Rpb25hbGl0eVxuICAqL1xuICBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyIC8qICwgdXNlQ2FwdHVyZSAqLykge1xuICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmxpc3RlbmVyc1t0eXBlXSkpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbdHlwZV0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBhZGQgdGhlIHNhbWUgZnVuY3Rpb24gb25jZVxuICAgICAgaWYgKGZpbHRlcih0aGlzLmxpc3RlbmVyc1t0eXBlXSwgaXRlbSA9PiBpdGVtID09PSBsaXN0ZW5lcikubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgc28gaXQgd2lsbCBubyBsb25nZXIgYmUgaW52b2tlZCB2aWEgdGhlIGRpc3BhdGNoRXZlbnQgbWV0aG9kLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSB0aGUgdHlwZSBvZiBldmVudCAoaWU6ICdvcGVuJywgJ21lc3NhZ2UnLCBldGMuKVxuICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIC0gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGludm9rZSB3aGVuZXZlciBhbiBldmVudCBpcyBkaXNwYXRjaGVkIG1hdGNoaW5nIHRoZSBnaXZlbiB0eXBlXG4gICogQHBhcmFtIHtib29sZWFufSB1c2VDYXB0dXJlIC0gTi9BIFRPRE86IGltcGxlbWVudCB1c2VDYXB0dXJlIGZ1bmN0aW9uYWxpdHlcbiAgKi9cbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCByZW1vdmluZ0xpc3RlbmVyIC8qICwgdXNlQ2FwdHVyZSAqLykge1xuICAgIGNvbnN0IGFycmF5T2ZMaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1t0eXBlXTtcbiAgICB0aGlzLmxpc3RlbmVyc1t0eXBlXSA9IHJlamVjdChhcnJheU9mTGlzdGVuZXJzLCBsaXN0ZW5lciA9PiBsaXN0ZW5lciA9PT0gcmVtb3ZpbmdMaXN0ZW5lcik7XG4gIH1cblxuICAvKlxuICAqIEludm9rZXMgYWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyB0aGF0IGFyZSBsaXN0ZW5pbmcgdG8gdGhlIGdpdmVuIGV2ZW50LnR5cGUgcHJvcGVydHkuIEVhY2hcbiAgKiBsaXN0ZW5lciB3aWxsIGJlIHBhc3NlZCB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gZXZlbnQgb2JqZWN0IHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGFsbCBsaXN0ZW5lcnMgb2YgdGhlIGV2ZW50LnR5cGUgcHJvcGVydHlcbiAgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgLi4uY3VzdG9tQXJndW1lbnRzKSB7XG4gICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQudHlwZTtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3RlbmVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgICBpZiAoY3VzdG9tQXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgY3VzdG9tQXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRUYXJnZXQ7XG4iLCJpbXBvcnQgeyByZWplY3QgfSBmcm9tICcuL2hlbHBlcnMvYXJyYXktaGVscGVycyc7XG5cbi8qXG4qIFRoZSBuZXR3b3JrIGJyaWRnZSBpcyBhIHdheSBmb3IgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCB0byAnY29tbXVuaWNhdGUnIHdpdGhcbiogYWxsIGF2YWlsYWJsZSBzZXJ2ZXJzLiBUaGlzIGlzIGEgc2luZ2xldG9uIG9iamVjdCBzbyBpdCBpcyBpbXBvcnRhbnQgdGhhdCB5b3VcbiogY2xlYW4gdXAgdXJsTWFwIHdoZW5ldmVyIHlvdSBhcmUgZmluaXNoZWQuXG4qL1xuY2xhc3MgTmV0d29ya0JyaWRnZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudXJsTWFwID0ge307XG4gIH1cblxuICAvKlxuICAqIEF0dGFjaGVzIGEgd2Vic29ja2V0IG9iamVjdCB0byB0aGUgdXJsTWFwIGhhc2ggc28gdGhhdCBpdCBjYW4gZmluZCB0aGUgc2VydmVyXG4gICogaXQgaXMgY29ubmVjdGVkIHRvIGFuZCB0aGUgc2VydmVyIGluIHR1cm4gY2FuIGZpbmQgaXQuXG4gICpcbiAgKiBAcGFyYW0ge29iamVjdH0gd2Vic29ja2V0IC0gd2Vic29ja2V0IG9iamVjdCB0byBhZGQgdG8gdGhlIHVybE1hcCBoYXNoXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICBhdHRhY2hXZWJTb2NrZXQod2Vic29ja2V0LCB1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwICYmIGNvbm5lY3Rpb25Mb29rdXAuc2VydmVyICYmIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cy5pbmRleE9mKHdlYnNvY2tldCkgPT09IC0xKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMucHVzaCh3ZWJzb2NrZXQpO1xuICAgICAgcmV0dXJuIGNvbm5lY3Rpb25Mb29rdXAuc2VydmVyO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSB3ZWJzb2NrZXQgdG8gYSByb29tXG4gICovXG4gIGFkZE1lbWJlcnNoaXBUb1Jvb20od2Vic29ja2V0LCByb29tKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3dlYnNvY2tldC51cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXAgJiYgY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXIgJiYgY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLmluZGV4T2Yod2Vic29ja2V0KSAhPT0gLTEpIHtcbiAgICAgIGlmICghY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0pIHtcbiAgICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0ucHVzaCh3ZWJzb2NrZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSBzZXJ2ZXIgb2JqZWN0IHRvIHRoZSB1cmxNYXAgaGFzaCBzbyB0aGF0IGl0IGNhbiBmaW5kIGEgd2Vic29ja2V0c1xuICAqIHdoaWNoIGFyZSBjb25uZWN0ZWQgdG8gaXQgYW5kIHNvIHRoYXQgd2Vic29ja2V0cyBjYW4gaW4gdHVybiBjYW4gZmluZCBpdC5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSBzZXJ2ZXIgLSBzZXJ2ZXIgb2JqZWN0IHRvIGFkZCB0byB0aGUgdXJsTWFwIGhhc2hcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIGF0dGFjaFNlcnZlcihzZXJ2ZXIsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKCFjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICB0aGlzLnVybE1hcFt1cmxdID0ge1xuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIHdlYnNvY2tldHM6IFtdLFxuICAgICAgICByb29tTWVtYmVyc2hpcHM6IHt9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VydmVyO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogRmluZHMgdGhlIHNlcnZlciB3aGljaCBpcyAncnVubmluZycgb24gdGhlIGdpdmVuIHVybC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSB0aGUgdXJsIHRvIHVzZSB0byBmaW5kIHdoaWNoIHNlcnZlciBpcyBydW5uaW5nIG9uIGl0XG4gICovXG4gIHNlcnZlckxvb2t1cCh1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICByZXR1cm4gY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBGaW5kcyBhbGwgd2Vic29ja2V0cyB3aGljaCBpcyAnbGlzdGVuaW5nJyBvbiB0aGUgZ2l2ZW4gdXJsLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIHRoZSB1cmwgdG8gdXNlIHRvIGZpbmQgYWxsIHdlYnNvY2tldHMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBpdFxuICAqIEBwYXJhbSB7c3RyaW5nfSByb29tIC0gaWYgYSByb29tIGlzIHByb3ZpZGVkLCB3aWxsIG9ubHkgcmV0dXJuIHNvY2tldHMgaW4gdGhpcyByb29tXG4gICogQHBhcmFtIHtjbGFzc30gYnJvYWRjYXN0ZXIgLSBzb2NrZXQgdGhhdCBpcyBicm9hZGNhc3RpbmcgYW5kIGlzIHRvIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIGxvb2t1cFxuICAqL1xuICB3ZWJzb2NrZXRzTG9va3VwKHVybCwgcm9vbSwgYnJvYWRjYXN0ZXIpIHtcbiAgICBsZXQgd2Vic29ja2V0cztcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIHdlYnNvY2tldHMgPSBjb25uZWN0aW9uTG9va3VwID8gY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzIDogW107XG5cbiAgICBpZiAocm9vbSkge1xuICAgICAgY29uc3QgbWVtYmVycyA9IGNvbm5lY3Rpb25Mb29rdXAucm9vbU1lbWJlcnNoaXBzW3Jvb21dO1xuICAgICAgd2Vic29ja2V0cyA9IG1lbWJlcnMgfHwgW107XG4gICAgfVxuXG4gICAgcmV0dXJuIGJyb2FkY2FzdGVyID8gd2Vic29ja2V0cy5maWx0ZXIod2Vic29ja2V0ID0+IHdlYnNvY2tldCAhPT0gYnJvYWRjYXN0ZXIpIDogd2Vic29ja2V0cztcbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgZW50cnkgYXNzb2NpYXRlZCB3aXRoIHRoZSB1cmwuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIHJlbW92ZVNlcnZlcih1cmwpIHtcbiAgICBkZWxldGUgdGhpcy51cmxNYXBbdXJsXTtcbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyB0aGUgaW5kaXZpZHVhbCB3ZWJzb2NrZXQgZnJvbSB0aGUgbWFwIG9mIGFzc29jaWF0ZWQgd2Vic29ja2V0cy5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSB3ZWJzb2NrZXQgLSB3ZWJzb2NrZXQgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoZSB1cmwgbWFwXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICByZW1vdmVXZWJTb2NrZXQod2Vic29ja2V0LCB1cmwpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbdXJsXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMgPSByZWplY3QoY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLCBzb2NrZXQgPT4gc29ja2V0ID09PSB3ZWJzb2NrZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICogUmVtb3ZlcyBhIHdlYnNvY2tldCBmcm9tIGEgcm9vbVxuICAqL1xuICByZW1vdmVNZW1iZXJzaGlwRnJvbVJvb20od2Vic29ja2V0LCByb29tKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3dlYnNvY2tldC51cmxdO1xuICAgIGNvbnN0IG1lbWJlcnNoaXBzID0gY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV07XG5cbiAgICBpZiAoY29ubmVjdGlvbkxvb2t1cCAmJiBtZW1iZXJzaGlwcyAhPT0gbnVsbCkge1xuICAgICAgY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV0gPSByZWplY3QobWVtYmVyc2hpcHMsIHNvY2tldCA9PiBzb2NrZXQgPT09IHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBOZXR3b3JrQnJpZGdlKCk7IC8vIE5vdGU6IHRoaXMgaXMgYSBzaW5nbGV0b25cbiIsIi8qXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ2xvc2VFdmVudFxuICovXG5leHBvcnQgY29uc3QgQ0xPU0VfQ09ERVMgPSB7XG4gIENMT1NFX05PUk1BTDogMTAwMCxcbiAgQ0xPU0VfR09JTkdfQVdBWTogMTAwMSxcbiAgQ0xPU0VfUFJPVE9DT0xfRVJST1I6IDEwMDIsXG4gIENMT1NFX1VOU1VQUE9SVEVEOiAxMDAzLFxuICBDTE9TRV9OT19TVEFUVVM6IDEwMDUsXG4gIENMT1NFX0FCTk9STUFMOiAxMDA2LFxuICBVTlNVUFBPUlRFRF9EQVRBOiAxMDA3LFxuICBQT0xJQ1lfVklPTEFUSU9OOiAxMDA4LFxuICBDTE9TRV9UT09fTEFSR0U6IDEwMDksXG4gIE1JU1NJTkdfRVhURU5TSU9OOiAxMDEwLFxuICBJTlRFUk5BTF9FUlJPUjogMTAxMSxcbiAgU0VSVklDRV9SRVNUQVJUOiAxMDEyLFxuICBUUllfQUdBSU5fTEFURVI6IDEwMTMsXG4gIFRMU19IQU5EU0hBS0U6IDEwMTVcbn07XG5cbmV4cG9ydCBjb25zdCBFUlJPUl9QUkVGSVggPSB7XG4gIENPTlNUUlVDVE9SX0VSUk9SOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ1dlYlNvY2tldCc6XCIsXG4gIENMT1NFX0VSUk9SOiBcIkZhaWxlZCB0byBleGVjdXRlICdjbG9zZScgb24gJ1dlYlNvY2tldCc6XCIsXG4gIEVWRU5UOiB7XG4gICAgQ09OU1RSVUNUOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ0V2ZW50JzpcIixcbiAgICBNRVNTQUdFOiBcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ01lc3NhZ2VFdmVudCc6XCIsXG4gICAgQ0xPU0U6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnQ2xvc2VFdmVudCc6XCJcbiAgfVxufTtcbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50UHJvdG90eXBlIHtcbiAgLy8gTm9vcHNcbiAgc3RvcFByb3BhZ2F0aW9uKCkge31cbiAgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge31cblxuICAvLyBpZiBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCB0aGVuIHRoZSB0eXBlIGlzIHNldCB0byBcInVuZGVmaW5lZFwiIG9uXG4gIC8vIGNocm9tZSBhbmQgc2FmYXJpLlxuICBpbml0RXZlbnQodHlwZSA9ICd1bmRlZmluZWQnLCBidWJibGVzID0gZmFsc2UsIGNhbmNlbGFibGUgPSBmYWxzZSkge1xuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLmJ1YmJsZXMgPSBCb29sZWFuKGJ1YmJsZXMpO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IEJvb2xlYW4oY2FuY2VsYWJsZSk7XG4gIH1cbn1cbiIsImltcG9ydCBFdmVudFByb3RvdHlwZSBmcm9tICcuL3Byb3RvdHlwZSc7XG5pbXBvcnQgeyBFUlJPUl9QUkVGSVggfSBmcm9tICcuLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVF9FUlJPUn0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXZlbnRJbml0Q29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlRfRVJST1J9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3QuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5uY2VsQnViYmxlID0gZmFsc2U7XG4gICAgdGhpcy5idWJibGVzID0gYnViYmxlcyA/IEJvb2xlYW4oYnViYmxlcykgOiBmYWxzZTtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1lc3NhZ2VFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5NRVNTQUdFfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBldmVudEluaXRDb25maWcgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5NRVNTQUdFfSBwYXJhbWV0ZXIgMiAoJ2V2ZW50SW5pdERpY3QnKSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlLCBkYXRhLCBvcmlnaW4sIGxhc3RFdmVudElkLCBwb3J0cyB9ID0gZXZlbnRJbml0Q29uZmlnO1xuXG4gICAgdGhpcy50eXBlID0gYCR7dHlwZX1gO1xuICAgIHRoaXMudGltZVN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5zcmNFbGVtZW50ID0gbnVsbDtcbiAgICB0aGlzLnJldHVyblZhbHVlID0gdHJ1ZTtcbiAgICB0aGlzLmlzVHJ1c3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuZXZlbnRQaGFzZSA9IDA7XG4gICAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG4gICAgdGhpcy5jdXJyZW50VGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlID8gQm9vbGVhbihjYW5jZWxhYmxlKSA6IGZhbHNlO1xuICAgIHRoaXMuY2FubmNlbEJ1YmJsZSA9IGZhbHNlO1xuICAgIHRoaXMuYnViYmxlcyA9IGJ1YmJsZXMgPyBCb29sZWFuKGJ1YmJsZXMpIDogZmFsc2U7XG4gICAgdGhpcy5vcmlnaW4gPSBgJHtvcmlnaW59YDtcbiAgICB0aGlzLnBvcnRzID0gdHlwZW9mIHBvcnRzID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBwb3J0cztcbiAgICB0aGlzLmRhdGEgPSB0eXBlb2YgZGF0YSA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogZGF0YTtcbiAgICB0aGlzLmxhc3RFdmVudElkID0gYCR7bGFzdEV2ZW50SWQgfHwgJyd9YDtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENsb3NlRXZlbnQgZXh0ZW5kcyBFdmVudFByb3RvdHlwZSB7XG4gIGNvbnN0cnVjdG9yKHR5cGUsIGV2ZW50SW5pdENvbmZpZyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICghdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlQuQ0xPU0V9IDEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC5gKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50SW5pdENvbmZpZyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULkNMT1NFfSBwYXJhbWV0ZXIgMiAoJ2V2ZW50SW5pdERpY3QnKSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBidWJibGVzLCBjYW5jZWxhYmxlLCBjb2RlLCByZWFzb24sIHdhc0NsZWFuIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5jZWxCdWJibGUgPSBmYWxzZTtcbiAgICB0aGlzLmJ1YmJsZXMgPSBidWJibGVzID8gQm9vbGVhbihidWJibGVzKSA6IGZhbHNlO1xuICAgIHRoaXMuY29kZSA9IHR5cGVvZiBjb2RlID09PSAnbnVtYmVyJyA/IHBhcnNlSW50KGNvZGUsIDEwKSA6IDA7XG4gICAgdGhpcy5yZWFzb24gPSBgJHtyZWFzb24gfHwgJyd9YDtcbiAgICB0aGlzLndhc0NsZWFuID0gd2FzQ2xlYW4gPyBCb29sZWFuKHdhc0NsZWFuKSA6IGZhbHNlO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnQgZnJvbSAnLi9ldmVudCc7XG5pbXBvcnQgTWVzc2FnZUV2ZW50IGZyb20gJy4vbWVzc2FnZSc7XG5pbXBvcnQgQ2xvc2VFdmVudCBmcm9tICcuL2Nsb3NlJztcblxuLypcbiogQ3JlYXRlcyBhbiBFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnIHlvdSB3aWxsIG5lZWQgdG8gcGFzcyB0eXBlIGFuZCBvcHRpb25hbGx5IHRhcmdldFxuKi9cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IHR5cGUsIHRhcmdldCB9ID0gY29uZmlnO1xuICBjb25zdCBldmVudE9iamVjdCA9IG5ldyBFdmVudCh0eXBlKTtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgZXZlbnRPYmplY3QudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGV2ZW50T2JqZWN0LnNyY0VsZW1lbnQgPSB0YXJnZXQ7XG4gICAgZXZlbnRPYmplY3QuY3VycmVudFRhcmdldCA9IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBldmVudE9iamVjdDtcbn1cblxuLypcbiogQ3JlYXRlcyBhIE1lc3NhZ2VFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnOiB0eXBlLCBvcmlnaW4sIGRhdGEgYW5kIG9wdGlvbmFsbHkgdGFyZ2V0XG4qL1xuZnVuY3Rpb24gY3JlYXRlTWVzc2FnZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IHR5cGUsIG9yaWdpbiwgZGF0YSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGNvbnN0IG1lc3NhZ2VFdmVudCA9IG5ldyBNZXNzYWdlRXZlbnQodHlwZSwge1xuICAgIGRhdGEsXG4gICAgb3JpZ2luXG4gIH0pO1xuXG4gIGlmICh0YXJnZXQpIHtcbiAgICBtZXNzYWdlRXZlbnQudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIG1lc3NhZ2VFdmVudC5zcmNFbGVtZW50ID0gdGFyZ2V0O1xuICAgIG1lc3NhZ2VFdmVudC5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIG1lc3NhZ2VFdmVudDtcbn1cblxuLypcbiogQ3JlYXRlcyBhIENsb3NlRXZlbnQgb2JqZWN0IGFuZCBleHRlbmRzIGl0IHRvIGFsbG93IGZ1bGwgbW9kaWZpY2F0aW9uIG9mXG4qIGl0cyBwcm9wZXJ0aWVzLlxuKlxuKiBAcGFyYW0ge29iamVjdH0gY29uZmlnIC0gd2l0aGluIGNvbmZpZzogdHlwZSBhbmQgb3B0aW9uYWxseSB0YXJnZXQsIGNvZGUsIGFuZCByZWFzb25cbiovXG5mdW5jdGlvbiBjcmVhdGVDbG9zZUV2ZW50KGNvbmZpZykge1xuICBjb25zdCB7IGNvZGUsIHJlYXNvbiwgdHlwZSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGxldCB7IHdhc0NsZWFuIH0gPSBjb25maWc7XG5cbiAgaWYgKCF3YXNDbGVhbikge1xuICAgIHdhc0NsZWFuID0gY29kZSA9PT0gMTAwMDtcbiAgfVxuXG4gIGNvbnN0IGNsb3NlRXZlbnQgPSBuZXcgQ2xvc2VFdmVudCh0eXBlLCB7XG4gICAgY29kZSxcbiAgICByZWFzb24sXG4gICAgd2FzQ2xlYW5cbiAgfSk7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIGNsb3NlRXZlbnQudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGNsb3NlRXZlbnQuc3JjRWxlbWVudCA9IHRhcmdldDtcbiAgICBjbG9zZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cblxuICByZXR1cm4gY2xvc2VFdmVudDtcbn1cblxuZXhwb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9O1xuIiwiaW1wb3J0IFdlYlNvY2tldCBmcm9tICcuLi93ZWJzb2NrZXQnO1xuaW1wb3J0IGRlbGF5IGZyb20gJy4uL2hlbHBlcnMvZGVsYXknO1xuaW1wb3J0IG5ldHdvcmtCcmlkZ2UgZnJvbSAnLi4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHsgY3JlYXRlQ2xvc2VFdmVudCwgY3JlYXRlRXZlbnQgfSBmcm9tICcuLi9ldmVudC9mYWN0b3J5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbihjb250ZXh0LCBjb2RlLCByZWFzb24pIHtcbiAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NJTkc7XG5cbiAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAoY29udGV4dC51cmwpO1xuICBjb25zdCBjbG9zZUV2ZW50ID0gY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgdHlwZTogJ2Nsb3NlJyxcbiAgICB0YXJnZXQ6IGNvbnRleHQsXG4gICAgY29kZSxcbiAgICByZWFzb25cbiAgfSk7XG5cbiAgZGVsYXkoKCkgPT4ge1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KGNvbnRleHQsIGNvbnRleHQudXJsKTtcblxuICAgIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgY29udGV4dC5kaXNwYXRjaEV2ZW50KGNsb3NlRXZlbnQpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCwgc2VydmVyKTtcbiAgICB9XG4gIH0sIGNvbnRleHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmFpbFdlYlNvY2tldENvbm5lY3Rpb24oY29udGV4dCwgY29kZSwgcmVhc29uKSB7XG4gIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TSU5HO1xuXG4gIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2Uuc2VydmVyTG9va3VwKGNvbnRleHQudXJsKTtcbiAgY29uc3QgY2xvc2VFdmVudCA9IGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgIHR5cGU6ICdjbG9zZScsXG4gICAgdGFyZ2V0OiBjb250ZXh0LFxuICAgIGNvZGUsXG4gICAgcmVhc29uLFxuICAgIHdhc0NsZWFuOiBmYWxzZVxuICB9KTtcblxuICBjb25zdCBlcnJvckV2ZW50ID0gY3JlYXRlRXZlbnQoe1xuICAgIHR5cGU6ICdlcnJvcicsXG4gICAgdGFyZ2V0OiBjb250ZXh0XG4gIH0pO1xuXG4gIGRlbGF5KCgpID0+IHtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldChjb250ZXh0LCBjb250ZXh0LnVybCk7XG5cbiAgICBjb250ZXh0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuICAgIGNvbnRleHQuZGlzcGF0Y2hFdmVudChlcnJvckV2ZW50KTtcbiAgICBjb250ZXh0LmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50LCBzZXJ2ZXIpO1xuICAgIH1cbiAgfSwgY29udGV4dCk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBub3JtYWxpemVTZW5kRGF0YShkYXRhKSB7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkgIT09ICdbb2JqZWN0IEJsb2JdJyAmJiAhKGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICBkYXRhID0gU3RyaW5nKGRhdGEpO1xuICB9XG5cbiAgcmV0dXJuIGRhdGE7XG59XG4iLCJpbXBvcnQgeyBDTE9TRV9DT0RFUyB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24gfSBmcm9tICcuLi9hbGdvcml0aG1zL2Nsb3NlJztcbmltcG9ydCBub3JtYWxpemVTZW5kRGF0YSBmcm9tICcuL25vcm1hbGl6ZS1zZW5kJztcbmltcG9ydCB7IGNyZWF0ZU1lc3NhZ2VFdmVudCB9IGZyb20gJy4uL2V2ZW50L2ZhY3RvcnknO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwcm94eUZhY3RvcnkodGFyZ2V0KSB7XG4gIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgZ2V0KG9iaiwgcHJvcCkge1xuICAgICAgaWYgKHByb3AgPT09ICdjbG9zZScpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNsb3NlKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSBvcHRpb25zLmNvZGUgfHwgQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMO1xuICAgICAgICAgIGNvbnN0IHJlYXNvbiA9IG9wdGlvbnMucmVhc29uIHx8ICcnO1xuXG4gICAgICAgICAgY2xvc2VXZWJTb2NrZXRDb25uZWN0aW9uKHRhcmdldCwgY29kZSwgcmVhc29uKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3AgPT09ICdzZW5kJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gc2VuZChkYXRhKSB7XG4gICAgICAgICAgZGF0YSA9IG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpO1xuXG4gICAgICAgICAgdGFyZ2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgICB0eXBlOiAnbWVzc2FnZScsXG4gICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICAgICAgICAgIHRhcmdldFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcCA9PT0gJ29uJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gb25XcmFwcGVyKHR5cGUsIGNiKSB7XG4gICAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoYHNlcnZlcjo6JHt0eXBlfWAsIGNiKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9ialtwcm9wXTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCBoYW5kbGVyKTtcbiAgcmV0dXJuIHByb3h5O1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGVuZ3RoSW5VdGY4Qnl0ZXMoc3RyKSB7XG4gIC8vIE1hdGNoZXMgb25seSB0aGUgMTAuLiBieXRlcyB0aGF0IGFyZSBub24taW5pdGlhbCBjaGFyYWN0ZXJzIGluIGEgbXVsdGktYnl0ZSBzZXF1ZW5jZS5cbiAgY29uc3QgbSA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIpLm1hdGNoKC8lWzg5QUJhYl0vZyk7XG4gIHJldHVybiBzdHIubGVuZ3RoICsgKG0gPyBtLmxlbmd0aCA6IDApO1xufVxuIiwiaW1wb3J0IFVSTCBmcm9tICd1cmwtcGFyc2UnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXJsVmVyaWZpY2F0aW9uKHVybCkge1xuICBjb25zdCB1cmxSZWNvcmQgPSBuZXcgVVJMKHVybCk7XG4gIGNvbnN0IHsgcGF0aG5hbWUsIHByb3RvY29sLCBoYXNoIH0gPSB1cmxSZWNvcmQ7XG5cbiAgaWYgKCF1cmwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICB9XG5cbiAgaWYgKCFwYXRobmFtZSkge1xuICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgfVxuXG4gIGlmIChwcm90b2NvbCA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgVVJMICcke3VybFJlY29yZC50b1N0cmluZygpfScgaXMgaW52YWxpZC5gKTtcbiAgfVxuXG4gIGlmIChwcm90b2NvbCAhPT0gJ3dzOicgJiYgcHJvdG9jb2wgIT09ICd3c3M6Jykge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcbiAgICAgIGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gVGhlIFVSTCdzIHNjaGVtZSBtdXN0IGJlIGVpdGhlciAnd3MnIG9yICd3c3MnLiAnJHtwcm90b2NvbH0nIGlzIG5vdCBhbGxvd2VkLmBcbiAgICApO1xuICB9XG5cbiAgaWYgKGhhc2ggIT09ICcnKSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcbiAgICAgIGAke1xuICAgICAgICBFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1JcbiAgICAgIH0gVGhlIFVSTCBjb250YWlucyBhIGZyYWdtZW50IGlkZW50aWZpZXIgKCcke2hhc2h9JykuIEZyYWdtZW50IGlkZW50aWZpZXJzIGFyZSBub3QgYWxsb3dlZCBpbiBXZWJTb2NrZXQgVVJMcy5gXG4gICAgKTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cbiAgfVxuXG4gIHJldHVybiB1cmxSZWNvcmQudG9TdHJpbmcoKTtcbn1cbiIsImltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHByb3RvY29sVmVyaWZpY2F0aW9uKHByb3RvY29scyA9IFtdKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShwcm90b2NvbHMpICYmIHR5cGVvZiBwcm90b2NvbHMgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGAke0VSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUn0gVGhlIHN1YnByb3RvY29sICcke3Byb3RvY29scy50b1N0cmluZygpfScgaXMgaW52YWxpZC5gKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcHJvdG9jb2xzID09PSAnc3RyaW5nJykge1xuICAgIHByb3RvY29scyA9IFtwcm90b2NvbHNdO1xuICB9XG5cbiAgY29uc3QgdW5pcSA9IHByb3RvY29scy5tYXAocCA9PiAoeyBjb3VudDogMSwgcHJvdG9jb2w6IHAgfSkpLnJlZHVjZSgoYSwgYikgPT4ge1xuICAgIGFbYi5wcm90b2NvbF0gPSAoYVtiLnByb3RvY29sXSB8fCAwKSArIGIuY291bnQ7XG4gICAgcmV0dXJuIGE7XG4gIH0sIHt9KTtcblxuICBjb25zdCBkdXBsaWNhdGVzID0gT2JqZWN0LmtleXModW5pcSkuZmlsdGVyKGEgPT4gdW5pcVthXSA+IDEpO1xuXG4gIGlmIChkdXBsaWNhdGVzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgc3VicHJvdG9jb2wgJyR7ZHVwbGljYXRlc1swXX0nIGlzIGR1cGxpY2F0ZWQuYCk7XG4gIH1cblxuICByZXR1cm4gcHJvdG9jb2xzO1xufVxuIiwiaW1wb3J0IGRlbGF5IGZyb20gJy4vaGVscGVycy9kZWxheSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vaGVscGVycy9sb2dnZXInO1xuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4vZXZlbnQvdGFyZ2V0JztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHByb3h5RmFjdG9yeSBmcm9tICcuL2hlbHBlcnMvcHJveHktZmFjdG9yeSc7XG5pbXBvcnQgbGVuZ3RoSW5VdGY4Qnl0ZXMgZnJvbSAnLi9oZWxwZXJzL2J5dGUtbGVuZ3RoJztcbmltcG9ydCB7IENMT1NFX0NPREVTLCBFUlJPUl9QUkVGSVggfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgdXJsVmVyaWZpY2F0aW9uIGZyb20gJy4vaGVscGVycy91cmwtdmVyaWZpY2F0aW9uJztcbmltcG9ydCBub3JtYWxpemVTZW5kRGF0YSBmcm9tICcuL2hlbHBlcnMvbm9ybWFsaXplLXNlbmQnO1xuaW1wb3J0IHByb3RvY29sVmVyaWZpY2F0aW9uIGZyb20gJy4vaGVscGVycy9wcm90b2NvbC12ZXJpZmljYXRpb24nO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9IGZyb20gJy4vZXZlbnQvZmFjdG9yeSc7XG5pbXBvcnQgeyBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24sIGZhaWxXZWJTb2NrZXRDb25uZWN0aW9uIH0gZnJvbSAnLi9hbGdvcml0aG1zL2Nsb3NlJztcblxuLypcbiAqIFRoZSBtYWluIHdlYnNvY2tldCBjbGFzcyB3aGljaCBpcyBkZXNpZ25lZCB0byBtaW1pY2sgdGhlIG5hdGl2ZSBXZWJTb2NrZXQgY2xhc3MgYXMgY2xvc2VcbiAqIGFzIHBvc3NpYmxlLlxuICpcbiAqIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3dlYi1zb2NrZXRzLmh0bWxcbiAqL1xuY2xhc3MgV2ViU29ja2V0IGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3Rvcih1cmwsIHByb3RvY29scykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnVybCA9IHVybFZlcmlmaWNhdGlvbih1cmwpO1xuICAgIHByb3RvY29scyA9IHByb3RvY29sVmVyaWZpY2F0aW9uKHByb3RvY29scyk7XG4gICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sc1swXSB8fCAnJztcblxuICAgIHRoaXMuYmluYXJ5VHlwZSA9ICdibG9iJztcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ09OTkVDVElORztcblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2UuYXR0YWNoV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIC8qXG4gICAgICogVGhpcyBkZWxheSBpcyBuZWVkZWQgc28gdGhhdCB3ZSBkb250IHRyaWdnZXIgYW4gZXZlbnQgYmVmb3JlIHRoZSBjYWxsYmFja3MgaGF2ZSBiZWVuXG4gICAgICogc2V0dXAuIEZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogdmFyIHNvY2tldCA9IG5ldyBXZWJTb2NrZXQoJ3dzOi8vbG9jYWxob3N0Jyk7XG4gICAgICpcbiAgICAgKiBJZiB3ZSBkb250IGhhdmUgdGhlIGRlbGF5IHRoZW4gdGhlIGV2ZW50IHdvdWxkIGJlIHRyaWdnZXJlZCByaWdodCBoZXJlIGFuZCB0aGlzIGlzXG4gICAgICogYmVmb3JlIHRoZSBvbm9wZW4gaGFkIGEgY2hhbmNlIHRvIHJlZ2lzdGVyIGl0c2VsZi5cbiAgICAgKlxuICAgICAqIHNvY2tldC5vbm9wZW4gPSAoKSA9PiB7IC8vIHRoaXMgd291bGQgbmV2ZXIgYmUgY2FsbGVkIH07XG4gICAgICpcbiAgICAgKiBhbmQgd2l0aCB0aGUgZGVsYXkgdGhlIGV2ZW50IGdldHMgdHJpZ2dlcmVkIGhlcmUgYWZ0ZXIgYWxsIG9mIHRoZSBjYWxsYmFja3MgaGF2ZSBiZWVuXG4gICAgICogcmVnaXN0ZXJlZCA6LSlcbiAgICAgKi9cbiAgICBkZWxheShmdW5jdGlvbiBkZWxheUNhbGxiYWNrKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VydmVyLm9wdGlvbnMudmVyaWZ5Q2xpZW50ICYmXG4gICAgICAgICAgdHlwZW9mIHNlcnZlci5vcHRpb25zLnZlcmlmeUNsaWVudCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAgICFzZXJ2ZXIub3B0aW9ucy52ZXJpZnlDbGllbnQoKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuXG4gICAgICAgICAgbG9nZ2VyKFxuICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgIGBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZDogSFRUUCBBdXRoZW50aWNhdGlvbiBmYWlsZWQ7IG5vIHZhbGlkIGNyZWRlbnRpYWxzIGF2YWlsYWJsZWBcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbmV0d29ya0JyaWRnZS5yZW1vdmVXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUNsb3NlRXZlbnQoeyB0eXBlOiAnY2xvc2UnLCB0YXJnZXQ6IHRoaXMsIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sICYmIHR5cGVvZiBzZXJ2ZXIub3B0aW9ucy5zZWxlY3RQcm90b2NvbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRQcm90b2NvbCA9IHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sKHByb3RvY29scyk7XG4gICAgICAgICAgICBjb25zdCBpc0ZpbGxlZCA9IHNlbGVjdGVkUHJvdG9jb2wgIT09ICcnO1xuICAgICAgICAgICAgY29uc3QgaXNSZXF1ZXN0ZWQgPSBwcm90b2NvbHMuaW5kZXhPZihzZWxlY3RlZFByb3RvY29sKSAhPT0gLTE7XG4gICAgICAgICAgICBpZiAoaXNGaWxsZWQgJiYgIWlzUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbiAgICAgICAgICAgICAgbG9nZ2VyKCdlcnJvcicsIGBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZDogSW52YWxpZCBTdWItUHJvdG9jb2xgKTtcblxuICAgICAgICAgICAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJywgdGFyZ2V0OiB0aGlzLCBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwgfSkpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnByb3RvY29sID0gc2VsZWN0ZWRQcm90b2NvbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gV2ViU29ja2V0Lk9QRU47XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ29wZW4nLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3Rpb24nIH0pLCBwcm94eUZhY3RvcnkodGhpcykpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0VEO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScsIHRhcmdldDogdGhpcywgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMIH0pKTtcblxuICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkYCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG4gIH1cblxuICBnZXQgb25vcGVuKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5vcGVuO1xuICB9XG5cbiAgZ2V0IG9ubWVzc2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5saXN0ZW5lcnMubWVzc2FnZTtcbiAgfVxuXG4gIGdldCBvbmNsb3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5jbG9zZTtcbiAgfVxuXG4gIGdldCBvbmVycm9yKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5lcnJvcjtcbiAgfVxuXG4gIHNldCBvbm9wZW4obGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMub3BlbjtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZXQgb25tZXNzYWdlKGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMubGlzdGVuZXJzLm1lc3NhZ2U7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpO1xuICB9XG5cbiAgc2V0IG9uY2xvc2UobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMuY2xvc2U7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNldCBvbmVycm9yKGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMubGlzdGVuZXJzLmVycm9yO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZW5kKGRhdGEpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ0xPU0lORyB8fCB0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TRUQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViU29ja2V0IGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBoYW5kbGUgYnVmZmVyZWRBbW91bnRcblxuICAgIGNvbnN0IG1lc3NhZ2VFdmVudCA9IGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICB0eXBlOiAnc2VydmVyOjptZXNzYWdlJyxcbiAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICBkYXRhOiBub3JtYWxpemVTZW5kRGF0YShkYXRhKVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgZGVsYXkoKCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobWVzc2FnZUV2ZW50LCBkYXRhKTtcbiAgICAgIH0sIHNlcnZlcik7XG4gICAgfVxuICB9XG5cbiAgY2xvc2UoY29kZSwgcmVhc29uKSB7XG4gICAgaWYgKGNvZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGVvZiBjb2RlICE9PSAnbnVtYmVyJyB8fCAoY29kZSAhPT0gMTAwMCAmJiAoY29kZSA8IDMwMDAgfHwgY29kZSA+IDQ5OTkpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIGAke0VSUk9SX1BSRUZJWC5DTE9TRV9FUlJPUn0gVGhlIGNvZGUgbXVzdCBiZSBlaXRoZXIgMTAwMCwgb3IgYmV0d2VlbiAzMDAwIGFuZCA0OTk5LiAke2NvZGV9IGlzIG5laXRoZXIuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZWFzb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbGVuZ3RoID0gbGVuZ3RoSW5VdGY4Qnl0ZXMocmVhc29uKTtcblxuICAgICAgaWYgKGxlbmd0aCA+IDEyMykge1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNMT1NFX0VSUk9SfSBUaGUgbWVzc2FnZSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4gMTIzIGJ5dGVzLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TSU5HIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DT05ORUNUSU5HKSB7XG4gICAgICBmYWlsV2ViU29ja2V0Q29ubmVjdGlvbih0aGlzLCBjb2RlLCByZWFzb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24odGhpcywgY29kZSwgcmVhc29uKTtcbiAgICB9XG4gIH1cbn1cblxuV2ViU29ja2V0LkNPTk5FQ1RJTkcgPSAwO1xuV2ViU29ja2V0LnByb3RvdHlwZS5DT05ORUNUSU5HID0gV2ViU29ja2V0LkNPTk5FQ1RJTkc7XG5XZWJTb2NrZXQuT1BFTiA9IDE7XG5XZWJTb2NrZXQucHJvdG90eXBlLk9QRU4gPSBXZWJTb2NrZXQuT1BFTjtcbldlYlNvY2tldC5DTE9TSU5HID0gMjtcbldlYlNvY2tldC5wcm90b3R5cGUuQ0xPU0lORyA9IFdlYlNvY2tldC5DTE9TSU5HO1xuV2ViU29ja2V0LkNMT1NFRCA9IDM7XG5XZWJTb2NrZXQucHJvdG90eXBlLkNMT1NFRCA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbmV4cG9ydCBkZWZhdWx0IFdlYlNvY2tldDtcbiIsImV4cG9ydCBkZWZhdWx0IGFyciA9PlxuICBhcnIucmVkdWNlKChkZWR1cGVkLCBiKSA9PiB7XG4gICAgaWYgKGRlZHVwZWQuaW5kZXhPZihiKSA+IC0xKSByZXR1cm4gZGVkdXBlZDtcbiAgICByZXR1cm4gZGVkdXBlZC5jb25jYXQoYik7XG4gIH0sIFtdKTtcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJldHJpZXZlR2xvYmFsT2JqZWN0KCkge1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG5cbiAgcmV0dXJuIHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyA/IGdsb2JhbCA6IHRoaXM7XG59XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgV2ViU29ja2V0IGZyb20gJy4vd2Vic29ja2V0JztcbmltcG9ydCBkZWR1cGUgZnJvbSAnLi9oZWxwZXJzL2RlZHVwZSc7XG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudC90YXJnZXQnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuL25ldHdvcmstYnJpZGdlJztcbmltcG9ydCBnbG9iYWxPYmplY3QgZnJvbSAnLi9oZWxwZXJzL2dsb2JhbC1vYmplY3QnO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vaGVscGVycy9ub3JtYWxpemUtc2VuZCc7XG5pbXBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH0gZnJvbSAnLi9ldmVudC9mYWN0b3J5JztcblxuY2xhc3MgU2VydmVyIGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICBjb25zdHJ1Y3Rvcih1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgY29uc3QgdXJsUmVjb3JkID0gbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKCF1cmxSZWNvcmQucGF0aG5hbWUpIHtcbiAgICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICB0aGlzLnVybCA9IHVybFJlY29yZC50b1N0cmluZygpO1xuXG4gICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IG51bGw7XG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hTZXJ2ZXIodGhpcywgdGhpcy51cmwpO1xuXG4gICAgaWYgKCFzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicgfSkpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG1vY2sgc2VydmVyIGlzIGFscmVhZHkgbGlzdGVuaW5nIG9uIHRoaXMgdXJsJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnZlcmlmeUNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnMudmVyaWZ5Q2xpZW50ID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvcHRpb25zLnNlbGVjdFByb3RvY29sID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuc3RhcnQoKTtcbiAgfVxuXG4gIC8qXG4gICAqIEF0dGFjaGVzIHRoZSBtb2NrIHdlYnNvY2tldCBvYmplY3QgdG8gdGhlIGdsb2JhbCBvYmplY3RcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnN0IGdsb2JhbE9iaiA9IGdsb2JhbE9iamVjdCgpO1xuXG4gICAgaWYgKGdsb2JhbE9iai5XZWJTb2NrZXQpIHtcbiAgICAgIHRoaXMub3JpZ2luYWxXZWJTb2NrZXQgPSBnbG9iYWxPYmouV2ViU29ja2V0O1xuICAgIH1cblxuICAgIGdsb2JhbE9iai5XZWJTb2NrZXQgPSBXZWJTb2NrZXQ7XG4gIH1cblxuICAvKlxuICAgKiBSZW1vdmVzIHRoZSBtb2NrIHdlYnNvY2tldCBvYmplY3QgZnJvbSB0aGUgZ2xvYmFsIG9iamVjdFxuICAgKi9cbiAgc3RvcChjYWxsYmFjayA9ICgpID0+IHt9KSB7XG4gICAgY29uc3QgZ2xvYmFsT2JqID0gZ2xvYmFsT2JqZWN0KCk7XG5cbiAgICBpZiAodGhpcy5vcmlnaW5hbFdlYlNvY2tldCkge1xuICAgICAgZ2xvYmFsT2JqLldlYlNvY2tldCA9IHRoaXMub3JpZ2luYWxXZWJTb2NrZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSBnbG9iYWxPYmouV2ViU29ja2V0O1xuICAgIH1cblxuICAgIHRoaXMub3JpZ2luYWxXZWJTb2NrZXQgPSBudWxsO1xuXG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVTZXJ2ZXIodGhpcy51cmwpO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uIGZvciB0aGUgbW9jayBzZXJ2ZXIgdG8gc3Vic2NyaWJlIHRvIHRoZSBvbiBldmVudHMuXG4gICAqXG4gICAqIGllOiBtb2NrU2VydmVyLm9uKCdjb25uZWN0aW9uJywgZnVuY3Rpb24oKSB7IGNvbnNvbGUubG9nKCdhIG1vY2sgY2xpZW50IGNvbm5lY3RlZCcpOyB9KTtcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgZXZlbnQga2V5IHRvIHN1YnNjcmliZSB0by4gVmFsaWQga2V5cyBhcmU6IGNvbm5lY3Rpb24sIG1lc3NhZ2UsIGFuZCBjbG9zZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgd2hpY2ggc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGEgY2VydGFpbiBldmVudCBpcyBmaXJlZC5cbiAgICovXG4gIG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qXG4gICAqIENsb3NlcyB0aGUgY29ubmVjdGlvbiBhbmQgdHJpZ2dlcnMgdGhlIG9uY2xvc2UgbWV0aG9kIG9mIGFsbCBsaXN0ZW5pbmdcbiAgICogd2Vic29ja2V0cy4gQWZ0ZXIgdGhhdCBpdCByZW1vdmVzIGl0c2VsZiBmcm9tIHRoZSB1cmxNYXAgc28gYW5vdGhlciBzZXJ2ZXJcbiAgICogY291bGQgYWRkIGl0c2VsZiB0byB0aGUgdXJsLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKi9cbiAgY2xvc2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgeyBjb2RlLCByZWFzb24sIHdhc0NsZWFuIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG5cbiAgICAvLyBSZW1vdmUgc2VydmVyIGJlZm9yZSBub3RpZmljYXRpb25zIHRvIHByZXZlbnQgaW1tZWRpYXRlIHJlY29ubmVjdHMgZnJvbVxuICAgIC8vIHNvY2tldCBvbmNsb3NlIGhhbmRsZXJzXG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVTZXJ2ZXIodGhpcy51cmwpO1xuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goc29ja2V0ID0+IHtcbiAgICAgIHNvY2tldC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFO1xuICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgICAgICAgIHR5cGU6ICdjbG9zZScsXG4gICAgICAgICAgdGFyZ2V0OiBzb2NrZXQsXG4gICAgICAgICAgY29kZTogY29kZSB8fCBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwsXG4gICAgICAgICAgcmVhc29uOiByZWFzb24gfHwgJycsXG4gICAgICAgICAgd2FzQ2xlYW5cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScgfSksIHRoaXMpO1xuICB9XG5cbiAgLypcbiAgICogU2VuZHMgYSBnZW5lcmljIG1lc3NhZ2UgZXZlbnQgdG8gYWxsIG1vY2sgY2xpZW50cy5cbiAgICovXG4gIGVtaXQoZXZlbnQsIGRhdGEsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCB7IHdlYnNvY2tldHMgfSA9IG9wdGlvbnM7XG5cbiAgICBpZiAoIXdlYnNvY2tldHMpIHtcbiAgICAgIHdlYnNvY2tldHMgPSBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgfHwgYXJndW1lbnRzLmxlbmd0aCA+IDMpIHtcbiAgICAgIGRhdGEgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEsIGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgZGF0YSA9IGRhdGEubWFwKGl0ZW0gPT4gbm9ybWFsaXplU2VuZERhdGEoaXRlbSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhID0gbm9ybWFsaXplU2VuZERhdGEoZGF0YSk7XG4gICAgfVxuXG4gICAgd2Vic29ja2V0cy5mb3JFYWNoKHNvY2tldCA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogZXZlbnQsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHRhcmdldDogc29ja2V0XG4gICAgICAgICAgfSksXG4gICAgICAgICAgLi4uZGF0YVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgY3JlYXRlTWVzc2FnZUV2ZW50KHtcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50LFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICAgICAgICB0YXJnZXQ6IHNvY2tldFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKlxuICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHdlYnNvY2tldHMgd2hpY2ggYXJlIGxpc3RlbmluZyB0byB0aGlzIHNlcnZlclxuICAgKiBUT09EOiB0aGlzIHNob3VsZCByZXR1cm4gYSBzZXQgYW5kIG5vdCBiZSBhIG1ldGhvZFxuICAgKi9cbiAgY2xpZW50cygpIHtcbiAgICByZXR1cm4gbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHRoaXMudXJsKTtcbiAgfVxuXG4gIC8qXG4gICAqIFByZXBhcmVzIGEgbWV0aG9kIHRvIHN1Ym1pdCBhbiBldmVudCB0byBtZW1iZXJzIG9mIHRoZSByb29tXG4gICAqXG4gICAqIGUuZy4gc2VydmVyLnRvKCdteS1yb29tJykuZW1pdCgnaGkhJyk7XG4gICAqL1xuICB0byhyb29tLCBicm9hZGNhc3RlciwgYnJvYWRjYXN0TGlzdCA9IFtdKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3Qgd2Vic29ja2V0cyA9IGRlZHVwZShicm9hZGNhc3RMaXN0LmNvbmNhdChuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwsIHJvb20sIGJyb2FkY2FzdGVyKSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvOiAoY2hhaW5lZFJvb20sIGNoYWluZWRCcm9hZGNhc3RlcikgPT4gdGhpcy50by5jYWxsKHRoaXMsIGNoYWluZWRSb29tLCBjaGFpbmVkQnJvYWRjYXN0ZXIsIHdlYnNvY2tldHMpLFxuICAgICAgZW1pdChldmVudCwgZGF0YSkge1xuICAgICAgICBzZWxmLmVtaXQoZXZlbnQsIGRhdGEsIHsgd2Vic29ja2V0cyB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLypcbiAgICogQWxpYXMgZm9yIFNlcnZlci50b1xuICAgKi9cbiAgaW4oLi4uYXJncykge1xuICAgIHJldHVybiB0aGlzLnRvLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9XG5cbiAgLypcbiAgICogU2ltdWxhdGUgYW4gZXZlbnQgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjbGllbnRzLiBVc2VmdWwgZm9yXG4gICAqIHNpbXVsYXRpbmcgZXJyb3JzLlxuICAgKi9cbiAgc2ltdWxhdGUoZXZlbnQpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKGV2ZW50ID09PSAnZXJyb3InKSB7XG4gICAgICBsaXN0ZW5lcnMuZm9yRWFjaChzb2NrZXQgPT4ge1xuICAgICAgICBzb2NrZXQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRTtcbiAgICAgICAgc29ja2V0LmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InIH0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQWx0ZXJuYXRpdmUgY29uc3RydWN0b3IgdG8gc3VwcG9ydCBuYW1lc3BhY2VzIGluIHNvY2tldC5pb1xuICpcbiAqIGh0dHA6Ly9zb2NrZXQuaW8vZG9jcy9yb29tcy1hbmQtbmFtZXNwYWNlcy8jY3VzdG9tLW5hbWVzcGFjZXNcbiAqL1xuU2VydmVyLm9mID0gZnVuY3Rpb24gb2YodXJsKSB7XG4gIHJldHVybiBuZXcgU2VydmVyKHVybCk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTZXJ2ZXI7XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi9oZWxwZXJzL2RlbGF5JztcbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50L3RhcmdldCc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuL25ldHdvcmstYnJpZGdlJztcbmltcG9ydCB7IENMT1NFX0NPREVTIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuL2hlbHBlcnMvbG9nZ2VyJztcbmltcG9ydCB7IGNyZWF0ZUV2ZW50LCBjcmVhdGVNZXNzYWdlRXZlbnQsIGNyZWF0ZUNsb3NlRXZlbnQgfSBmcm9tICcuL2V2ZW50L2ZhY3RvcnknO1xuXG4vKlxuKiBUaGUgc29ja2V0LWlvIGNsYXNzIGlzIGRlc2lnbmVkIHRvIG1pbWljayB0aGUgcmVhbCBBUEkgYXMgY2xvc2VseSBhcyBwb3NzaWJsZS5cbipcbiogaHR0cDovL3NvY2tldC5pby9kb2NzL1xuKi9cbmNsYXNzIFNvY2tldElPIGV4dGVuZHMgRXZlbnRUYXJnZXQge1xuICAvKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgY29uc3RydWN0b3IodXJsID0gJ3NvY2tldC5pbycsIHByb3RvY29sID0gJycpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5iaW5hcnlUeXBlID0gJ2Jsb2InO1xuICAgIGNvbnN0IHVybFJlY29yZCA9IG5ldyBVUkwodXJsKTtcblxuICAgIGlmICghdXJsUmVjb3JkLnBhdGhuYW1lKSB7XG4gICAgICB1cmxSZWNvcmQucGF0aG5hbWUgPSAnLyc7XG4gICAgfVxuXG4gICAgdGhpcy51cmwgPSB1cmxSZWNvcmQudG9TdHJpbmcoKTtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5DT05ORUNUSU5HO1xuICAgIHRoaXMucHJvdG9jb2wgPSAnJztcblxuICAgIGlmICh0eXBlb2YgcHJvdG9jb2wgPT09ICdzdHJpbmcnIHx8ICh0eXBlb2YgcHJvdG9jb2wgPT09ICdvYmplY3QnICYmIHByb3RvY29sICE9PSBudWxsKSkge1xuICAgICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwcm90b2NvbCkgJiYgcHJvdG9jb2wubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5wcm90b2NvbCA9IHByb3RvY29sWzBdO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2UuYXR0YWNoV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIC8qXG4gICAgKiBEZWxheSB0cmlnZ2VyaW5nIHRoZSBjb25uZWN0aW9uIGV2ZW50cyBzbyB0aGV5IGNhbiBiZSBkZWZpbmVkIGluIHRpbWUuXG4gICAgKi9cbiAgICBkZWxheShmdW5jdGlvbiBkZWxheUNhbGxiYWNrKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5PUEVOO1xuICAgICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0aW9uJyB9KSwgc2VydmVyLCB0aGlzKTtcbiAgICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnY29ubmVjdCcgfSksIHNlcnZlciwgdGhpcyk7IC8vIGFsaWFzXG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0JywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNMT1NFRDtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIGNyZWF0ZUNsb3NlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgICAgIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgICAgbG9nZ2VyKCdlcnJvcicsIGBTb2NrZXQuaW8gY29ubmVjdGlvbiB0byAnJHt0aGlzLnVybH0nIGZhaWxlZGApO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICBBZGQgYW4gYWxpYXNlZCBldmVudCBsaXN0ZW5lciBmb3IgY2xvc2UgLyBkaXNjb25uZWN0XG4gICAgICovXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIGV2ZW50ID0+IHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Rpc2Nvbm5lY3QnLFxuICAgICAgICAgIHRhcmdldDogZXZlbnQudGFyZ2V0LFxuICAgICAgICAgIGNvZGU6IGV2ZW50LmNvZGVcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvKlxuICAqIENsb3NlcyB0aGUgU29ja2V0SU8gY29ubmVjdGlvbiBvciBjb25uZWN0aW9uIGF0dGVtcHQsIGlmIGFueS5cbiAgKiBJZiB0aGUgY29ubmVjdGlvbiBpcyBhbHJlYWR5IENMT1NFRCwgdGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLlxuICAqL1xuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IG5ldHdvcmtCcmlkZ2Uuc2VydmVyTG9va3VwKHRoaXMudXJsKTtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG5cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTb2NrZXRJTy5DTE9TRUQ7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgIHR5cGU6ICdjbG9zZScsXG4gICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Rpc2Nvbm5lY3QnLFxuICAgICAgICAgIHRhcmdldDogdGhpcyxcbiAgICAgICAgICBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUxcbiAgICAgICAgfSksXG4gICAgICAgIHNlcnZlclxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogQWxpYXMgZm9yIFNvY2tldCNjbG9zZVxuICAqXG4gICogaHR0cHM6Ly9naXRodWIuY29tL3NvY2tldGlvL3NvY2tldC5pby1jbGllbnQvYmxvYi9tYXN0ZXIvbGliL3NvY2tldC5qcyNMMzgzXG4gICovXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvc2UoKTtcbiAgfVxuXG4gIC8qXG4gICogU3VibWl0cyBhbiBldmVudCB0byB0aGUgc2VydmVyIHdpdGggYSBwYXlsb2FkXG4gICovXG4gIGVtaXQoZXZlbnQsIC4uLmRhdGEpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvY2tldElPIGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlRXZlbnQgPSBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgdHlwZTogZXZlbnQsXG4gICAgICBvcmlnaW46IHRoaXMudXJsLFxuICAgICAgZGF0YVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuXG4gICAgaWYgKHNlcnZlcikge1xuICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQobWVzc2FnZUV2ZW50LCAuLi5kYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogU3VibWl0cyBhICdtZXNzYWdlJyBldmVudCB0byB0aGUgc2VydmVyLlxuICAqXG4gICogU2hvdWxkIGJlaGF2ZSBleGFjdGx5IGxpa2UgV2ViU29ja2V0I3NlbmRcbiAgKlxuICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9zb2NrZXRpby9zb2NrZXQuaW8tY2xpZW50L2Jsb2IvbWFzdGVyL2xpYi9zb2NrZXQuanMjTDExM1xuICAqL1xuICBzZW5kKGRhdGEpIHtcbiAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCBkYXRhKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICogRm9yIGJyb2FkY2FzdGluZyBldmVudHMgdG8gb3RoZXIgY29ubmVjdGVkIHNvY2tldHMuXG4gICpcbiAgKiBlLmcuIHNvY2tldC5icm9hZGNhc3QuZW1pdCgnaGkhJyk7XG4gICogZS5nLiBzb2NrZXQuYnJvYWRjYXN0LnRvKCdteS1yb29tJykuZW1pdCgnaGkhJyk7XG4gICovXG4gIGdldCBicm9hZGNhc3QoKSB7XG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSAhPT0gU29ja2V0SU8uT1BFTikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb2NrZXRJTyBpcyBhbHJlYWR5IGluIENMT1NJTkcgb3IgQ0xPU0VEIHN0YXRlJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuICAgIGlmICghc2VydmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNvY2tldElPIGNhbiBub3QgZmluZCBhIHNlcnZlciBhdCB0aGUgc3BlY2lmaWVkIFVSTCAoJHt0aGlzLnVybH0pYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVtaXQoZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgc2VydmVyLmVtaXQoZXZlbnQsIGRhdGEsIHsgd2Vic29ja2V0czogbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHNlbGYudXJsLCBudWxsLCBzZWxmKSB9KTtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgICB9LFxuICAgICAgdG8ocm9vbSkge1xuICAgICAgICByZXR1cm4gc2VydmVyLnRvKHJvb20sIHNlbGYpO1xuICAgICAgfSxcbiAgICAgIGluKHJvb20pIHtcbiAgICAgICAgcmV0dXJuIHNlcnZlci5pbihyb29tLCBzZWxmKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLypcbiAgKiBGb3IgcmVnaXN0ZXJpbmcgZXZlbnRzIHRvIGJlIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICAqL1xuICBvbih0eXBlLCBjYWxsYmFjaykge1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKlxuICAgKiBSZW1vdmUgZXZlbnQgbGlzdGVuZXJcbiAgICpcbiAgICogaHR0cHM6Ly9zb2NrZXQuaW8vZG9jcy9jbGllbnQtYXBpLyNzb2NrZXQtb24tZXZlbnRuYW1lLWNhbGxiYWNrXG4gICAqL1xuICBvZmYodHlwZSkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlKTtcbiAgfVxuXG4gIC8qXG4gICAqIEpvaW4gYSByb29tIG9uIGEgc2VydmVyXG4gICAqXG4gICAqIGh0dHA6Ly9zb2NrZXQuaW8vZG9jcy9yb29tcy1hbmQtbmFtZXNwYWNlcy8jam9pbmluZy1hbmQtbGVhdmluZ1xuICAgKi9cbiAgam9pbihyb29tKSB7XG4gICAgbmV0d29ya0JyaWRnZS5hZGRNZW1iZXJzaGlwVG9Sb29tKHRoaXMsIHJvb20pO1xuICB9XG5cbiAgLypcbiAgICogR2V0IHRoZSB3ZWJzb2NrZXQgdG8gbGVhdmUgdGhlIHJvb21cbiAgICpcbiAgICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNqb2luaW5nLWFuZC1sZWF2aW5nXG4gICAqL1xuICBsZWF2ZShyb29tKSB7XG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVNZW1iZXJzaGlwRnJvbVJvb20odGhpcywgcm9vbSk7XG4gIH1cblxuICB0byhyb29tKSB7XG4gICAgcmV0dXJuIHRoaXMuYnJvYWRjYXN0LnRvKHJvb20pO1xuICB9XG5cbiAgaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxuXG4gIC8qXG4gICAqIEludm9rZXMgYWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyB0aGF0IGFyZSBsaXN0ZW5pbmcgdG8gdGhlIGdpdmVuIGV2ZW50LnR5cGUgcHJvcGVydHkuIEVhY2hcbiAgICogbGlzdGVuZXIgd2lsbCBiZSBwYXNzZWQgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gZXZlbnQgb2JqZWN0IHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGFsbCBsaXN0ZW5lcnMgb2YgdGhlIGV2ZW50LnR5cGUgcHJvcGVydHlcbiAgICovXG4gIGRpc3BhdGNoRXZlbnQoZXZlbnQsIC4uLmN1c3RvbUFyZ3VtZW50cykge1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnR5cGU7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNbZXZlbnROYW1lXTtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheShsaXN0ZW5lcnMpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZvckVhY2gobGlzdGVuZXIgPT4ge1xuICAgICAgaWYgKGN1c3RvbUFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGN1c3RvbUFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZWd1bGFyIFdlYlNvY2tldHMgZXhwZWN0IGEgTWVzc2FnZUV2ZW50IGJ1dCBTb2NrZXRpby5pbyBqdXN0IHdhbnRzIHJhdyBkYXRhXG4gICAgICAgIC8vICBwYXlsb2FkIGluc3RhbmNlb2YgTWVzc2FnZUV2ZW50IHdvcmtzLCBidXQgeW91IGNhbid0IGlzbnRhbmNlIG9mIE5vZGVFdmVudFxuICAgICAgICAvLyAgZm9yIG5vdyB3ZSBkZXRlY3QgaWYgdGhlIG91dHB1dCBoYXMgZGF0YSBkZWZpbmVkIG9uIGl0XG4gICAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQuZGF0YSA/IGV2ZW50LmRhdGEgOiBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuU29ja2V0SU8uQ09OTkVDVElORyA9IDA7XG5Tb2NrZXRJTy5PUEVOID0gMTtcblNvY2tldElPLkNMT1NJTkcgPSAyO1xuU29ja2V0SU8uQ0xPU0VEID0gMztcblxuLypcbiogU3RhdGljIGNvbnN0cnVjdG9yIG1ldGhvZHMgZm9yIHRoZSBJTyBTb2NrZXRcbiovXG5jb25zdCBJTyA9IGZ1bmN0aW9uIGlvQ29uc3RydWN0b3IodXJsLCBwcm90b2NvbCkge1xuICByZXR1cm4gbmV3IFNvY2tldElPKHVybCwgcHJvdG9jb2wpO1xufTtcblxuLypcbiogQWxpYXMgdGhlIHJhdyBJTygpIGNvbnN0cnVjdG9yXG4qL1xuSU8uY29ubmVjdCA9IGZ1bmN0aW9uIGlvQ29ubmVjdCh1cmwsIHByb3RvY29sKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5ldy1jYXAgKi9cbiAgcmV0dXJuIElPKHVybCwgcHJvdG9jb2wpO1xuICAvKiBlc2xpbnQtZW5hYmxlIG5ldy1jYXAgKi9cbn07XG5cbmV4cG9ydCBkZWZhdWx0IElPO1xuIiwiaW1wb3J0IE1vY2tTZXJ2ZXIgZnJvbSAnLi9zZXJ2ZXInO1xuaW1wb3J0IE1vY2tTb2NrZXRJTyBmcm9tICcuL3NvY2tldC1pbyc7XG5pbXBvcnQgTW9ja1dlYlNvY2tldCBmcm9tICcuL3dlYnNvY2tldCc7XG5cbmV4cG9ydCBjb25zdCBTZXJ2ZXIgPSBNb2NrU2VydmVyO1xuZXhwb3J0IGNvbnN0IFdlYlNvY2tldCA9IE1vY2tXZWJTb2NrZXQ7XG5leHBvcnQgY29uc3QgU29ja2V0SU8gPSBNb2NrU29ja2V0SU87XG4iXSwibmFtZXMiOlsiZ2xvYmFsIiwicXMiLCJyZXF1aXJlZCIsImNvbnN0IiwidGhpcyIsInN1cGVyIiwiV2ViU29ja2V0IiwiVVJMIiwibG9nZ2VyIiwiU2VydmVyIiwiZ2xvYmFsT2JqZWN0IiwiU29ja2V0SU8iLCJNb2NrU2VydmVyIiwiTW9ja1dlYlNvY2tldCIsIk1vY2tTb2NrZXRJTyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBV0EsZ0JBQWMsR0FBRyxTQUFTLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO0VBQ2pELFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ2xDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQzs7RUFFYixJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUEsT0FBTyxLQUFLLENBQUMsRUFBQTs7RUFFeEIsUUFBUSxRQUFRO0lBQ2QsS0FBSyxNQUFN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 diff --git a/node_modules/mock-socket/dist/mock-socket.es.js b/node_modules/mock-socket/dist/mock-socket.es.js new file mode 100644 index 0000000..12518f0 --- /dev/null +++ b/node_modules/mock-socket/dist/mock-socket.es.js @@ -0,0 +1,1920 @@ +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +var requiresPort = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) { return false; } + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; + +var has = Object.prototype.hasOwnProperty; + +/** + * Decode a URI encoded string. + * + * @param {String} input The URI encoded string. + * @returns {String} The decoded string. + * @api private + */ +function decode(input) { + return decodeURIComponent(input.replace(/\+/g, ' ')); +} + +/** + * Simple query string parser. + * + * @param {String} query The query string that needs to be parsed. + * @returns {Object} + * @api public + */ +function querystring(query) { + var parser = /([^=?&]+)=?([^&]*)/g + , result = {} + , part; + + while (part = parser.exec(query)) { + var key = decode(part[1]) + , value = decode(part[2]); + + // + // Prevent overriding of existing properties. This ensures that build-in + // methods like `toString` or __proto__ are not overriden by malicious + // querystrings. + // + if (key in result) { continue; } + result[key] = value; + } + + return result; +} + +/** + * Transform a query string to an object. + * + * @param {Object} obj Object that should be transformed. + * @param {String} prefix Optional prefix. + * @returns {String} + * @api public + */ +function querystringify(obj, prefix) { + prefix = prefix || ''; + + var pairs = []; + + // + // Optionally prefix with a '?' if needed + // + if ('string' !== typeof prefix) { prefix = '?'; } + + for (var key in obj) { + if (has.call(obj, key)) { + pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key])); + } + } + + return pairs.length ? prefix + pairs.join('&') : ''; +} + +// +// Expose the module. +// +var stringify = querystringify; +var parse = querystring; + +var querystringify_1 = { + stringify: stringify, + parse: parse +}; + +var protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; +var slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//; + +/** + * These are the parse rules for the URL parser, it informs the parser + * about: + * + * 0. The char it Needs to parse, if it's a string it should be done using + * indexOf, RegExp using exec and NaN means set as current value. + * 1. The property we should set when parsing this value. + * 2. Indication if it's backwards or forward parsing, when set as number it's + * the value of extra chars that should be split off. + * 3. Inherit from location if non existing in the parser. + * 4. `toLowerCase` the resulting value. + */ +var rules = [ + ['#', 'hash'], // Extract from the back. + ['?', 'query'], // Extract from the back. + ['/', 'pathname'], // Extract from the back. + ['@', 'auth', 1], // Extract from the front. + [NaN, 'host', undefined, 1, 1], // Set left over value. + [/:(\d+)$/, 'port', undefined, 1], // RegExp the back. + [NaN, 'hostname', undefined, 1, 1] // Set left over. +]; + +/** + * These properties should not be copied or inherited from. This is only needed + * for all non blob URL's as a blob URL does not include a hash, only the + * origin. + * + * @type {Object} + * @private + */ +var ignore = { hash: 1, query: 1 }; + +/** + * The location object differs when your code is loaded through a normal page, + * Worker or through a worker using a blob. And with the blobble begins the + * trouble as the location object will contain the URL of the blob, not the + * location of the page where our code is loaded in. The actual origin is + * encoded in the `pathname` so we can thankfully generate a good "default" + * location from it so we can generate proper relative URL's again. + * + * @param {Object|String} loc Optional default location object. + * @returns {Object} lolcation object. + * @api public + */ +function lolcation(loc) { + var location = commonjsGlobal && commonjsGlobal.location || {}; + loc = loc || location; + + var finaldestination = {} + , type = typeof loc + , key; + + if ('blob:' === loc.protocol) { + finaldestination = new URL(unescape(loc.pathname), {}); + } else if ('string' === type) { + finaldestination = new URL(loc, {}); + for (key in ignore) { delete finaldestination[key]; } + } else if ('object' === type) { + for (key in loc) { + if (key in ignore) { continue; } + finaldestination[key] = loc[key]; + } + + if (finaldestination.slashes === undefined) { + finaldestination.slashes = slashes.test(loc.href); + } + } + + return finaldestination; +} + +/** + * @typedef ProtocolExtract + * @type Object + * @property {String} protocol Protocol matched in the URL, in lowercase. + * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`. + * @property {String} rest Rest of the URL that is not part of the protocol. + */ + +/** + * Extract protocol information from a URL with/without double slash ("//"). + * + * @param {String} address URL we want to extract from. + * @return {ProtocolExtract} Extracted information. + * @api private + */ +function extractProtocol(address) { + var match = protocolre.exec(address); + + return { + protocol: match[1] ? match[1].toLowerCase() : '', + slashes: !!match[2], + rest: match[3] + }; +} + +/** + * Resolve a relative URL pathname against a base URL pathname. + * + * @param {String} relative Pathname of the relative URL. + * @param {String} base Pathname of the base URL. + * @return {String} Resolved pathname. + * @api private + */ +function resolve(relative, base) { + var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/')) + , i = path.length + , last = path[i - 1] + , unshift = false + , up = 0; + + while (i--) { + if (path[i] === '.') { + path.splice(i, 1); + } else if (path[i] === '..') { + path.splice(i, 1); + up++; + } else if (up) { + if (i === 0) { unshift = true; } + path.splice(i, 1); + up--; + } + } + + if (unshift) { path.unshift(''); } + if (last === '.' || last === '..') { path.push(''); } + + return path.join('/'); +} + +/** + * The actual URL instance. Instead of returning an object we've opted-in to + * create an actual constructor as it's much more memory efficient and + * faster and it pleases my OCD. + * + * @constructor + * @param {String} address URL we want to parse. + * @param {Object|String} location Location defaults for relative paths. + * @param {Boolean|Function} parser Parser for the query string. + * @api public + */ +function URL(address, location, parser) { + if (!(this instanceof URL)) { + return new URL(address, location, parser); + } + + var relative, extracted, parse, instruction, index, key + , instructions = rules.slice() + , type = typeof location + , url = this + , i = 0; + + // + // The following if statements allows this module two have compatibility with + // 2 different API: + // + // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments + // where the boolean indicates that the query string should also be parsed. + // + // 2. The `URL` interface of the browser which accepts a URL, object as + // arguments. The supplied object will be used as default values / fall-back + // for relative paths. + // + if ('object' !== type && 'string' !== type) { + parser = location; + location = null; + } + + if (parser && 'function' !== typeof parser) { parser = querystringify_1.parse; } + + location = lolcation(location); + + // + // Extract protocol information before running the instructions. + // + extracted = extractProtocol(address || ''); + relative = !extracted.protocol && !extracted.slashes; + url.slashes = extracted.slashes || relative && location.slashes; + url.protocol = extracted.protocol || location.protocol || ''; + address = extracted.rest; + + // + // When the authority component is absent the URL starts with a path + // component. + // + if (!extracted.slashes) { instructions[2] = [/(.*)/, 'pathname']; } + + for (; i < instructions.length; i++) { + instruction = instructions[i]; + parse = instruction[0]; + key = instruction[1]; + + if (parse !== parse) { + url[key] = address; + } else if ('string' === typeof parse) { + if (~(index = address.indexOf(parse))) { + if ('number' === typeof instruction[2]) { + url[key] = address.slice(0, index); + address = address.slice(index + instruction[2]); + } else { + url[key] = address.slice(index); + address = address.slice(0, index); + } + } + } else if ((index = parse.exec(address))) { + url[key] = index[1]; + address = address.slice(0, index.index); + } + + url[key] = url[key] || ( + relative && instruction[3] ? location[key] || '' : '' + ); + + // + // Hostname, host and protocol should be lowercased so they can be used to + // create a proper `origin`. + // + if (instruction[4]) { url[key] = url[key].toLowerCase(); } + } + + // + // Also parse the supplied query string in to an object. If we're supplied + // with a custom parser as function use that instead of the default build-in + // parser. + // + if (parser) { url.query = parser(url.query); } + + // + // If the URL is relative, resolve the pathname against the base URL. + // + if ( + relative + && location.slashes + && url.pathname.charAt(0) !== '/' + && (url.pathname !== '' || location.pathname !== '') + ) { + url.pathname = resolve(url.pathname, location.pathname); + } + + // + // We should not add port numbers if they are already the default port number + // for a given protocol. As the host also contains the port number we're going + // override it with the hostname which contains no port number. + // + if (!requiresPort(url.port, url.protocol)) { + url.host = url.hostname; + url.port = ''; + } + + // + // Parse down the `auth` for the username and password. + // + url.username = url.password = ''; + if (url.auth) { + instruction = url.auth.split(':'); + url.username = instruction[0] || ''; + url.password = instruction[1] || ''; + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + // + // The href is just the compiled result. + // + url.href = url.toString(); +} + +/** + * This is convenience method for changing properties in the URL instance to + * insure that they all propagate correctly. + * + * @param {String} part Property we need to adjust. + * @param {Mixed} value The newly assigned value. + * @param {Boolean|Function} fn When setting the query, it will be the function + * used to parse the query. + * When setting the protocol, double slash will be + * removed from the final url if it is true. + * @returns {URL} + * @api public + */ +function set(part, value, fn) { + var url = this; + + switch (part) { + case 'query': + if ('string' === typeof value && value.length) { + value = (fn || querystringify_1.parse)(value); + } + + url[part] = value; + break; + + case 'port': + url[part] = value; + + if (!requiresPort(value, url.protocol)) { + url.host = url.hostname; + url[part] = ''; + } else if (value) { + url.host = url.hostname +':'+ value; + } + + break; + + case 'hostname': + url[part] = value; + + if (url.port) { value += ':'+ url.port; } + url.host = value; + break; + + case 'host': + url[part] = value; + + if (/:\d+$/.test(value)) { + value = value.split(':'); + url.port = value.pop(); + url.hostname = value.join(':'); + } else { + url.hostname = value; + url.port = ''; + } + + break; + + case 'protocol': + url.protocol = value.toLowerCase(); + url.slashes = !fn; + break; + + case 'pathname': + case 'hash': + if (value) { + var char = part === 'pathname' ? '/' : '#'; + url[part] = value.charAt(0) !== char ? char + value : value; + } else { + url[part] = value; + } + break; + + default: + url[part] = value; + } + + for (var i = 0; i < rules.length; i++) { + var ins = rules[i]; + + if (ins[4]) { url[ins[1]] = url[ins[1]].toLowerCase(); } + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + url.href = url.toString(); + + return url; +} + +/** + * Transform the properties back in to a valid and full URL string. + * + * @param {Function} stringify Optional query stringify function. + * @returns {String} + * @api public + */ +function toString(stringify) { + if (!stringify || 'function' !== typeof stringify) { stringify = querystringify_1.stringify; } + + var query + , url = this + , protocol = url.protocol; + + if (protocol && protocol.charAt(protocol.length - 1) !== ':') { protocol += ':'; } + + var result = protocol + (url.slashes ? '//' : ''); + + if (url.username) { + result += url.username; + if (url.password) { result += ':'+ url.password; } + result += '@'; + } + + result += url.host + url.pathname; + + query = 'object' === typeof url.query ? stringify(url.query) : url.query; + if (query) { result += '?' !== query.charAt(0) ? '?'+ query : query; } + + if (url.hash) { result += url.hash; } + + return result; +} + +URL.prototype = { set: set, toString: toString }; + +// +// Expose the URL parser and some additional properties that might be useful for +// others or testing. +// +URL.extractProtocol = extractProtocol; +URL.location = lolcation; +URL.qs = querystringify_1; + +var urlParse = URL; + +/* +* This delay allows the thread to finish assigning its on* methods +* before invoking the delay callback. This is purely a timing hack. +* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html +* +* @param {callback: function} the callback which will be invoked after the timeout +* @parma {context: object} the context in which to invoke the function +*/ +function delay(callback, context) { + setTimeout(function (timeoutContext) { return callback.call(timeoutContext); }, 4, context); +} + +function log(method, message) { + /* eslint-disable no-console */ + if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') { + console[method].call(null, message); + } + /* eslint-enable no-console */ +} + +function reject(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (!callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +function filter(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +/* +* EventTarget is an interface implemented by objects that can +* receive events and may have listeners for them. +* +* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget +*/ +var EventTarget = function EventTarget() { + this.listeners = {}; +}; + +/* +* Ties a listener function to an event type which can later be invoked via the +* dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.addEventListener = function addEventListener (type, listener /* , useCapture */) { + if (typeof listener === 'function') { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], function (item) { return item === listener; }).length === 0) { + this.listeners[type].push(listener); + } + } +}; + +/* +* Removes the listener so it will no longer be invoked via the dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.removeEventListener = function removeEventListener (type, removingListener /* , useCapture */) { + var arrayOfListeners = this.listeners[type]; + this.listeners[type] = reject(arrayOfListeners, function (listener) { return listener === removingListener; }); +}; + +/* +* Invokes all listener functions that are listening to the given event.type property. Each +* listener will be passed the event as the first argument. +* +* @param {object} event - event object which will be passed to all listeners of the event.type property +*/ +EventTarget.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + listener.call(this$1, event); + } + }); + + return true; +}; + +/* +* The network bridge is a way for the mock websocket object to 'communicate' with +* all available servers. This is a singleton object so it is important that you +* clean up urlMap whenever you are finished. +*/ +var NetworkBridge = function NetworkBridge() { + this.urlMap = {}; +}; + +/* +* Attaches a websocket object to the urlMap hash so that it can find the server +* it is connected to and the server in turn can find it. +* +* @param {object} websocket - websocket object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachWebSocket = function attachWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) { + connectionLookup.websockets.push(websocket); + return connectionLookup.server; + } +}; + +/* +* Attaches a websocket to a room +*/ +NetworkBridge.prototype.addMembershipToRoom = function addMembershipToRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) { + if (!connectionLookup.roomMemberships[room]) { + connectionLookup.roomMemberships[room] = []; + } + + connectionLookup.roomMemberships[room].push(websocket); + } +}; + +/* +* Attaches a server object to the urlMap hash so that it can find a websockets +* which are connected to it and so that websockets can in turn can find it. +* +* @param {object} server - server object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachServer = function attachServer (server, url) { + var connectionLookup = this.urlMap[url]; + + if (!connectionLookup) { + this.urlMap[url] = { + server: server, + websockets: [], + roomMemberships: {} + }; + + return server; + } +}; + +/* +* Finds the server which is 'running' on the given url. +* +* @param {string} url - the url to use to find which server is running on it +*/ +NetworkBridge.prototype.serverLookup = function serverLookup (url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + return connectionLookup.server; + } +}; + +/* +* Finds all websockets which is 'listening' on the given url. +* +* @param {string} url - the url to use to find all websockets which are associated with it +* @param {string} room - if a room is provided, will only return sockets in this room +* @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup +*/ +NetworkBridge.prototype.websocketsLookup = function websocketsLookup (url, room, broadcaster) { + var websockets; + var connectionLookup = this.urlMap[url]; + + websockets = connectionLookup ? connectionLookup.websockets : []; + + if (room) { + var members = connectionLookup.roomMemberships[room]; + websockets = members || []; + } + + return broadcaster ? websockets.filter(function (websocket) { return websocket !== broadcaster; }) : websockets; +}; + +/* +* Removes the entry associated with the url. +* +* @param {string} url +*/ +NetworkBridge.prototype.removeServer = function removeServer (url) { + delete this.urlMap[url]; +}; + +/* +* Removes the individual websocket from the map of associated websockets. +* +* @param {object} websocket - websocket object to remove from the url map +* @param {string} url +*/ +NetworkBridge.prototype.removeWebSocket = function removeWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + connectionLookup.websockets = reject(connectionLookup.websockets, function (socket) { return socket === websocket; }); + } +}; + +/* +* Removes a websocket from a room +*/ +NetworkBridge.prototype.removeMembershipFromRoom = function removeMembershipFromRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + var memberships = connectionLookup.roomMemberships[room]; + + if (connectionLookup && memberships !== null) { + connectionLookup.roomMemberships[room] = reject(memberships, function (socket) { return socket === websocket; }); + } +}; + +var networkBridge = new NetworkBridge(); // Note: this is a singleton + +/* + * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent + */ +var CLOSE_CODES = { + CLOSE_NORMAL: 1000, + CLOSE_GOING_AWAY: 1001, + CLOSE_PROTOCOL_ERROR: 1002, + CLOSE_UNSUPPORTED: 1003, + CLOSE_NO_STATUS: 1005, + CLOSE_ABNORMAL: 1006, + UNSUPPORTED_DATA: 1007, + POLICY_VIOLATION: 1008, + CLOSE_TOO_LARGE: 1009, + MISSING_EXTENSION: 1010, + INTERNAL_ERROR: 1011, + SERVICE_RESTART: 1012, + TRY_AGAIN_LATER: 1013, + TLS_HANDSHAKE: 1015 +}; + +var ERROR_PREFIX = { + CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':", + CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':", + EVENT: { + CONSTRUCT: "Failed to construct 'Event':", + MESSAGE: "Failed to construct 'MessageEvent':", + CLOSE: "Failed to construct 'CloseEvent':" + } +}; + +var EventPrototype = function EventPrototype () {}; + +EventPrototype.prototype.stopPropagation = function stopPropagation () {}; +EventPrototype.prototype.stopImmediatePropagation = function stopImmediatePropagation () {}; + +// if no arguments are passed then the type is set to "undefined" on +// chrome and safari. +EventPrototype.prototype.initEvent = function initEvent (type, bubbles, cancelable) { + if ( type === void 0 ) type = 'undefined'; + if ( bubbles === void 0 ) bubbles = false; + if ( cancelable === void 0 ) cancelable = false; + + this.type = "" + type; + this.bubbles = Boolean(bubbles); + this.cancelable = Boolean(cancelable); +}; + +var Event = (function (EventPrototype$$1) { + function Event(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " parameter 2 ('eventInitDict') is not an object.")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + } + + if ( EventPrototype$$1 ) Event.__proto__ = EventPrototype$$1; + Event.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + Event.prototype.constructor = Event; + + return Event; +}(EventPrototype)); + +var MessageEvent = (function (EventPrototype$$1) { + function MessageEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var data = eventInitConfig.data; + var origin = eventInitConfig.origin; + var lastEventId = eventInitConfig.lastEventId; + var ports = eventInitConfig.ports; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.origin = "" + origin; + this.ports = typeof ports === 'undefined' ? null : ports; + this.data = typeof data === 'undefined' ? null : data; + this.lastEventId = "" + (lastEventId || ''); + } + + if ( EventPrototype$$1 ) MessageEvent.__proto__ = EventPrototype$$1; + MessageEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + MessageEvent.prototype.constructor = MessageEvent; + + return MessageEvent; +}(EventPrototype)); + +var CloseEvent = (function (EventPrototype$$1) { + function CloseEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var code = eventInitConfig.code; + var reason = eventInitConfig.reason; + var wasClean = eventInitConfig.wasClean; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.cancelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.code = typeof code === 'number' ? parseInt(code, 10) : 0; + this.reason = "" + (reason || ''); + this.wasClean = wasClean ? Boolean(wasClean) : false; + } + + if ( EventPrototype$$1 ) CloseEvent.__proto__ = EventPrototype$$1; + CloseEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + CloseEvent.prototype.constructor = CloseEvent; + + return CloseEvent; +}(EventPrototype)); + +/* +* Creates an Event object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config you will need to pass type and optionally target +*/ +function createEvent(config) { + var type = config.type; + var target = config.target; + var eventObject = new Event(type); + + if (target) { + eventObject.target = target; + eventObject.srcElement = target; + eventObject.currentTarget = target; + } + + return eventObject; +} + +/* +* Creates a MessageEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type, origin, data and optionally target +*/ +function createMessageEvent(config) { + var type = config.type; + var origin = config.origin; + var data = config.data; + var target = config.target; + var messageEvent = new MessageEvent(type, { + data: data, + origin: origin + }); + + if (target) { + messageEvent.target = target; + messageEvent.srcElement = target; + messageEvent.currentTarget = target; + } + + return messageEvent; +} + +/* +* Creates a CloseEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type and optionally target, code, and reason +*/ +function createCloseEvent(config) { + var code = config.code; + var reason = config.reason; + var type = config.type; + var target = config.target; + var wasClean = config.wasClean; + + if (!wasClean) { + wasClean = code === 1000; + } + + var closeEvent = new CloseEvent(type, { + code: code, + reason: reason, + wasClean: wasClean + }); + + if (target) { + closeEvent.target = target; + closeEvent.srcElement = target; + closeEvent.currentTarget = target; + } + + return closeEvent; +} + +function closeWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function failWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason, + wasClean: false + }); + + var errorEvent = createEvent({ + type: 'error', + target: context + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(errorEvent); + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function normalizeSendData(data) { + if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) { + data = String(data); + } + + return data; +} + +function proxyFactory(target) { + var handler = { + get: function get(obj, prop) { + if (prop === 'close') { + return function close(options) { + if ( options === void 0 ) options = {}; + + var code = options.code || CLOSE_CODES.CLOSE_NORMAL; + var reason = options.reason || ''; + + closeWebSocketConnection(target, code, reason); + }; + } + + if (prop === 'send') { + return function send(data) { + data = normalizeSendData(data); + + target.dispatchEvent( + createMessageEvent({ + type: 'message', + data: data, + origin: this.url, + target: target + }) + ); + }; + } + + if (prop === 'on') { + return function onWrapper(type, cb) { + target.addEventListener(("server::" + type), cb); + }; + } + + return obj[prop]; + } + }; + + var proxy = new Proxy(target, handler); + return proxy; +} + +function lengthInUtf8Bytes(str) { + // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. + var m = encodeURIComponent(str).match(/%[89ABab]/g); + return str.length + (m ? m.length : 0); +} + +function urlVerification(url) { + var urlRecord = new urlParse(url); + var pathname = urlRecord.pathname; + var protocol = urlRecord.protocol; + var hash = urlRecord.hash; + + if (!url) { + throw new TypeError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (!pathname) { + urlRecord.pathname = '/'; + } + + if (protocol === '') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL '" + (urlRecord.toString()) + "' is invalid.")); + } + + if (protocol !== 'ws:' && protocol !== 'wss:') { + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL's scheme must be either 'ws' or 'wss'. '" + protocol + "' is not allowed.") + ); + } + + if (hash !== '') { + /* eslint-disable max-len */ + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL contains a fragment identifier ('" + hash + "'). Fragment identifiers are not allowed in WebSocket URLs.") + ); + /* eslint-enable max-len */ + } + + return urlRecord.toString(); +} + +function protocolVerification(protocols) { + if ( protocols === void 0 ) protocols = []; + + if (!Array.isArray(protocols) && typeof protocols !== 'string') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (protocols.toString()) + "' is invalid.")); + } + + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + var uniq = protocols.map(function (p) { return ({ count: 1, protocol: p }); }).reduce(function (a, b) { + a[b.protocol] = (a[b.protocol] || 0) + b.count; + return a; + }, {}); + + var duplicates = Object.keys(uniq).filter(function (a) { return uniq[a] > 1; }); + + if (duplicates.length > 0) { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (duplicates[0]) + "' is duplicated.")); + } + + return protocols; +} + +/* + * The main websocket class which is designed to mimick the native WebSocket class as close + * as possible. + * + * https://html.spec.whatwg.org/multipage/web-sockets.html + */ +var WebSocket$1 = (function (EventTarget$$1) { + function WebSocket(url, protocols) { + EventTarget$$1.call(this); + + this.url = urlVerification(url); + protocols = protocolVerification(protocols); + this.protocol = protocols[0] || ''; + + this.binaryType = 'blob'; + this.readyState = WebSocket.CONNECTING; + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * This delay is needed so that we dont trigger an event before the callbacks have been + * setup. For example: + * + * var socket = new WebSocket('ws://localhost'); + * + * If we dont have the delay then the event would be triggered right here and this is + * before the onopen had a chance to register itself. + * + * socket.onopen = () => { // this would never be called }; + * + * and with the delay the event gets triggered here after all of the callbacks have been + * registered :-) + */ + delay(function delayCallback() { + if (server) { + if ( + server.options.verifyClient && + typeof server.options.verifyClient === 'function' && + !server.options.verifyClient() + ) { + this.readyState = WebSocket.CLOSED; + + log( + 'error', + ("WebSocket connection to '" + (this.url) + "' failed: HTTP Authentication failed; no valid credentials available") + ); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + } else { + if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') { + var selectedProtocol = server.options.selectProtocol(protocols); + var isFilled = selectedProtocol !== ''; + var isRequested = protocols.indexOf(selectedProtocol) !== -1; + if (isFilled && !isRequested) { + this.readyState = WebSocket.CLOSED; + + log('error', ("WebSocket connection to '" + (this.url) + "' failed: Invalid Sub-Protocol")); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + return; + } + this.protocol = selectedProtocol; + } + this.readyState = WebSocket.OPEN; + this.dispatchEvent(createEvent({ type: 'open', target: this })); + server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this)); + } + } else { + this.readyState = WebSocket.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + + log('error', ("WebSocket connection to '" + (this.url) + "' failed")); + } + }, this); + } + + if ( EventTarget$$1 ) WebSocket.__proto__ = EventTarget$$1; + WebSocket.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + WebSocket.prototype.constructor = WebSocket; + + var prototypeAccessors = { onopen: {},onmessage: {},onclose: {},onerror: {} }; + + prototypeAccessors.onopen.get = function () { + return this.listeners.open; + }; + + prototypeAccessors.onmessage.get = function () { + return this.listeners.message; + }; + + prototypeAccessors.onclose.get = function () { + return this.listeners.close; + }; + + prototypeAccessors.onerror.get = function () { + return this.listeners.error; + }; + + prototypeAccessors.onopen.set = function (listener) { + delete this.listeners.open; + this.addEventListener('open', listener); + }; + + prototypeAccessors.onmessage.set = function (listener) { + delete this.listeners.message; + this.addEventListener('message', listener); + }; + + prototypeAccessors.onclose.set = function (listener) { + delete this.listeners.close; + this.addEventListener('close', listener); + }; + + prototypeAccessors.onerror.set = function (listener) { + delete this.listeners.error; + this.addEventListener('error', listener); + }; + + WebSocket.prototype.send = function send (data) { + var this$1 = this; + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + throw new Error('WebSocket is already in CLOSING or CLOSED state'); + } + + // TODO: handle bufferedAmount + + var messageEvent = createMessageEvent({ + type: 'server::message', + origin: this.url, + data: normalizeSendData(data) + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + delay(function () { + this$1.dispatchEvent(messageEvent, data); + }, server); + } + }; + + WebSocket.prototype.close = function close (code, reason) { + if (code !== undefined) { + if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) { + throw new TypeError( + ((ERROR_PREFIX.CLOSE_ERROR) + " The code must be either 1000, or between 3000 and 4999. " + code + " is neither.") + ); + } + } + + if (reason !== undefined) { + var length = lengthInUtf8Bytes(reason); + + if (length > 123) { + throw new SyntaxError(((ERROR_PREFIX.CLOSE_ERROR) + " The message must not be greater than 123 bytes.")); + } + } + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + return; + } + + if (this.readyState === WebSocket.CONNECTING) { + failWebSocketConnection(this, code, reason); + } else { + closeWebSocketConnection(this, code, reason); + } + }; + + Object.defineProperties( WebSocket.prototype, prototypeAccessors ); + + return WebSocket; +}(EventTarget)); + +WebSocket$1.CONNECTING = 0; +WebSocket$1.prototype.CONNECTING = WebSocket$1.CONNECTING; +WebSocket$1.OPEN = 1; +WebSocket$1.prototype.OPEN = WebSocket$1.OPEN; +WebSocket$1.CLOSING = 2; +WebSocket$1.prototype.CLOSING = WebSocket$1.CLOSING; +WebSocket$1.CLOSED = 3; +WebSocket$1.prototype.CLOSED = WebSocket$1.CLOSED; + +var dedupe = function (arr) { return arr.reduce(function (deduped, b) { + if (deduped.indexOf(b) > -1) { return deduped; } + return deduped.concat(b); + }, []); }; + +function retrieveGlobalObject() { + if (typeof window !== 'undefined') { + return window; + } + + return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this; +} + +var Server$1 = (function (EventTarget$$1) { + function Server(url, options) { + if ( options === void 0 ) options = {}; + + EventTarget$$1.call(this); + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + + this.originalWebSocket = null; + var server = networkBridge.attachServer(this, this.url); + + if (!server) { + this.dispatchEvent(createEvent({ type: 'error' })); + throw new Error('A mock server is already listening on this url'); + } + + if (typeof options.verifyClient === 'undefined') { + options.verifyClient = null; + } + + if (typeof options.selectProtocol === 'undefined') { + options.selectProtocol = null; + } + + this.options = options; + this.start(); + } + + if ( EventTarget$$1 ) Server.__proto__ = EventTarget$$1; + Server.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + Server.prototype.constructor = Server; + + /* + * Attaches the mock websocket object to the global object + */ + Server.prototype.start = function start () { + var globalObj = retrieveGlobalObject(); + + if (globalObj.WebSocket) { + this.originalWebSocket = globalObj.WebSocket; + } + + globalObj.WebSocket = WebSocket$1; + }; + + /* + * Removes the mock websocket object from the global object + */ + Server.prototype.stop = function stop (callback) { + if ( callback === void 0 ) callback = function () {}; + + var globalObj = retrieveGlobalObject(); + + if (this.originalWebSocket) { + globalObj.WebSocket = this.originalWebSocket; + } else { + delete globalObj.WebSocket; + } + + this.originalWebSocket = null; + + networkBridge.removeServer(this.url); + + if (typeof callback === 'function') { + callback(); + } + }; + + /* + * This is the main function for the mock server to subscribe to the on events. + * + * ie: mockServer.on('connection', function() { console.log('a mock client connected'); }); + * + * @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close. + * @param {function} callback - The callback which should be called when a certain event is fired. + */ + Server.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + }; + + /* + * Closes the connection and triggers the onclose method of all listening + * websockets. After that it removes itself from the urlMap so another server + * could add itself to the url. + * + * @param {object} options + */ + Server.prototype.close = function close (options) { + if ( options === void 0 ) options = {}; + + var code = options.code; + var reason = options.reason; + var wasClean = options.wasClean; + var listeners = networkBridge.websocketsLookup(this.url); + + // Remove server before notifications to prevent immediate reconnects from + // socket onclose handlers + networkBridge.removeServer(this.url); + + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent( + createCloseEvent({ + type: 'close', + target: socket, + code: code || CLOSE_CODES.CLOSE_NORMAL, + reason: reason || '', + wasClean: wasClean + }) + ); + }); + + this.dispatchEvent(createCloseEvent({ type: 'close' }), this); + }; + + /* + * Sends a generic message event to all mock clients. + */ + Server.prototype.emit = function emit (event, data, options) { + var this$1 = this; + if ( options === void 0 ) options = {}; + + var websockets = options.websockets; + + if (!websockets) { + websockets = networkBridge.websocketsLookup(this.url); + } + + if (typeof options !== 'object' || arguments.length > 3) { + data = Array.prototype.slice.call(arguments, 1, arguments.length); + data = data.map(function (item) { return normalizeSendData(item); }); + } else { + data = normalizeSendData(data); + } + + websockets.forEach(function (socket) { + if (Array.isArray(data)) { + socket.dispatchEvent.apply( + socket, [ createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) ].concat( data ) + ); + } else { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) + ); + } + }); + }; + + /* + * Returns an array of websockets which are listening to this server + * TOOD: this should return a set and not be a method + */ + Server.prototype.clients = function clients () { + return networkBridge.websocketsLookup(this.url); + }; + + /* + * Prepares a method to submit an event to members of the room + * + * e.g. server.to('my-room').emit('hi!'); + */ + Server.prototype.to = function to (room, broadcaster, broadcastList) { + var this$1 = this; + if ( broadcastList === void 0 ) broadcastList = []; + + var self = this; + var websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster))); + + return { + to: function (chainedRoom, chainedBroadcaster) { return this$1.to.call(this$1, chainedRoom, chainedBroadcaster, websockets); }, + emit: function emit(event, data) { + self.emit(event, data, { websockets: websockets }); + } + }; + }; + + /* + * Alias for Server.to + */ + Server.prototype.in = function in$1 () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return this.to.apply(null, args); + }; + + /* + * Simulate an event from the server to the clients. Useful for + * simulating errors. + */ + Server.prototype.simulate = function simulate (event) { + var listeners = networkBridge.websocketsLookup(this.url); + + if (event === 'error') { + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent(createEvent({ type: 'error' })); + }); + } + }; + + return Server; +}(EventTarget)); + +/* + * Alternative constructor to support namespaces in socket.io + * + * http://socket.io/docs/rooms-and-namespaces/#custom-namespaces + */ +Server$1.of = function of(url) { + return new Server$1(url); +}; + +/* +* The socket-io class is designed to mimick the real API as closely as possible. +* +* http://socket.io/docs/ +*/ +var SocketIO$1 = (function (EventTarget$$1) { + function SocketIO(url, protocol) { + var this$1 = this; + if ( url === void 0 ) url = 'socket.io'; + if ( protocol === void 0 ) protocol = ''; + + EventTarget$$1.call(this); + + this.binaryType = 'blob'; + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + this.readyState = SocketIO.CONNECTING; + this.protocol = ''; + + if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) { + this.protocol = protocol; + } else if (Array.isArray(protocol) && protocol.length > 0) { + this.protocol = protocol[0]; + } + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * Delay triggering the connection events so they can be defined in time. + */ + delay(function delayCallback() { + if (server) { + this.readyState = SocketIO.OPEN; + server.dispatchEvent(createEvent({ type: 'connection' }), server, this); + server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias + this.dispatchEvent(createEvent({ type: 'connect', target: this })); + } else { + this.readyState = SocketIO.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + log('error', ("Socket.io connection to '" + (this.url) + "' failed")); + } + }, this); + + /** + Add an aliased event listener for close / disconnect + */ + this.addEventListener('close', function (event) { + this$1.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: event.target, + code: event.code + }) + ); + }); + } + + if ( EventTarget$$1 ) SocketIO.__proto__ = EventTarget$$1; + SocketIO.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + SocketIO.prototype.constructor = SocketIO; + + var prototypeAccessors = { broadcast: {} }; + + /* + * Closes the SocketIO connection or connection attempt, if any. + * If the connection is already CLOSED, this method does nothing. + */ + SocketIO.prototype.close = function close () { + if (this.readyState !== SocketIO.OPEN) { + return undefined; + } + + var server = networkBridge.serverLookup(this.url); + networkBridge.removeWebSocket(this, this.url); + + this.readyState = SocketIO.CLOSED; + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + if (server) { + server.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }), + server + ); + } + + return this; + }; + + /* + * Alias for Socket#close + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383 + */ + SocketIO.prototype.disconnect = function disconnect () { + return this.close(); + }; + + /* + * Submits an event to the server with a payload + */ + SocketIO.prototype.emit = function emit (event) { + var data = [], len = arguments.length - 1; + while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ]; + + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var messageEvent = createMessageEvent({ + type: event, + origin: this.url, + data: data + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + server.dispatchEvent.apply(server, [ messageEvent ].concat( data )); + } + + return this; + }; + + /* + * Submits a 'message' event to the server. + * + * Should behave exactly like WebSocket#send + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113 + */ + SocketIO.prototype.send = function send (data) { + this.emit('message', data); + return this; + }; + + /* + * For broadcasting events to other connected sockets. + * + * e.g. socket.broadcast.emit('hi!'); + * e.g. socket.broadcast.to('my-room').emit('hi!'); + */ + prototypeAccessors.broadcast.get = function () { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var self = this; + var server = networkBridge.serverLookup(this.url); + if (!server) { + throw new Error(("SocketIO can not find a server at the specified URL (" + (this.url) + ")")); + } + + return { + emit: function emit(event, data) { + server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) }); + return self; + }, + to: function to(room) { + return server.to(room, self); + }, + in: function in$1(room) { + return server.in(room, self); + } + }; + }; + + /* + * For registering events to be received from the server + */ + SocketIO.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + return this; + }; + + /* + * Remove event listener + * + * https://socket.io/docs/client-api/#socket-on-eventname-callback + */ + SocketIO.prototype.off = function off (type) { + this.removeEventListener(type); + }; + + /* + * Join a room on a server + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.join = function join (room) { + networkBridge.addMembershipToRoom(this, room); + }; + + /* + * Get the websocket to leave the room + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.leave = function leave (room) { + networkBridge.removeMembershipFromRoom(this, room); + }; + + SocketIO.prototype.to = function to (room) { + return this.broadcast.to(room); + }; + + SocketIO.prototype.in = function in$1 () { + return this.to.apply(null, arguments); + }; + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + SocketIO.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + // Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data + // payload instanceof MessageEvent works, but you can't isntance of NodeEvent + // for now we detect if the output has data defined on it + listener.call(this$1, event.data ? event.data : event); + } + }); + }; + + Object.defineProperties( SocketIO.prototype, prototypeAccessors ); + + return SocketIO; +}(EventTarget)); + +SocketIO$1.CONNECTING = 0; +SocketIO$1.OPEN = 1; +SocketIO$1.CLOSING = 2; +SocketIO$1.CLOSED = 3; + +/* +* Static constructor methods for the IO Socket +*/ +var IO = function ioConstructor(url, protocol) { + return new SocketIO$1(url, protocol); +}; + +/* +* Alias the raw IO() constructor +*/ +IO.connect = function ioConnect(url, protocol) { + /* eslint-disable new-cap */ + return IO(url, protocol); + /* eslint-enable new-cap */ +}; + +var Server = Server$1; +var WebSocket = WebSocket$1; +var SocketIO = IO; + +export { Server, WebSocket, SocketIO }; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zb2NrZXQuZXMuanMiLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9yZXF1aXJlcy1wb3J0L2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5naWZ5L2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3VybC1wYXJzZS9pbmRleC5qcyIsIi4uL3NyYy9oZWxwZXJzL2RlbGF5LmpzIiwiLi4vc3JjL2hlbHBlcnMvbG9nZ2VyLmpzIiwiLi4vc3JjL2hlbHBlcnMvYXJyYXktaGVscGVycy5qcyIsIi4uL3NyYy9ldmVudC90YXJnZXQuanMiLCIuLi9zcmMvbmV0d29yay1icmlkZ2UuanMiLCIuLi9zcmMvY29uc3RhbnRzLmpzIiwiLi4vc3JjL2V2ZW50L3Byb3RvdHlwZS5qcyIsIi4uL3NyYy9ldmVudC9ldmVudC5qcyIsIi4uL3NyYy9ldmVudC9tZXNzYWdlLmpzIiwiLi4vc3JjL2V2ZW50L2Nsb3NlLmpzIiwiLi4vc3JjL2V2ZW50L2ZhY3RvcnkuanMiLCIuLi9zcmMvYWxnb3JpdGhtcy9jbG9zZS5qcyIsIi4uL3NyYy9oZWxwZXJzL25vcm1hbGl6ZS1zZW5kLmpzIiwiLi4vc3JjL2hlbHBlcnMvcHJveHktZmFjdG9yeS5qcyIsIi4uL3NyYy9oZWxwZXJzL2J5dGUtbGVuZ3RoLmpzIiwiLi4vc3JjL2hlbHBlcnMvdXJsLXZlcmlmaWNhdGlvbi5qcyIsIi4uL3NyYy9oZWxwZXJzL3Byb3RvY29sLXZlcmlmaWNhdGlvbi5qcyIsIi4uL3NyYy93ZWJzb2NrZXQuanMiLCIuLi9zcmMvaGVscGVycy9kZWR1cGUuanMiLCIuLi9zcmMvaGVscGVycy9nbG9iYWwtb2JqZWN0LmpzIiwiLi4vc3JjL3NlcnZlci5qcyIsIi4uL3NyYy9zb2NrZXQtaW8uanMiLCIuLi9zcmMvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIENoZWNrIGlmIHdlJ3JlIHJlcXVpcmVkIHRvIGFkZCBhIHBvcnQgbnVtYmVyLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly91cmwuc3BlYy53aGF0d2cub3JnLyNkZWZhdWx0LXBvcnRcbiAqIEBwYXJhbSB7TnVtYmVyfFN0cmluZ30gcG9ydCBQb3J0IG51bWJlciB3ZSBuZWVkIHRvIGNoZWNrXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJvdG9jb2wgUHJvdG9jb2wgd2UgbmVlZCB0byBjaGVjayBhZ2FpbnN0LlxuICogQHJldHVybnMge0Jvb2xlYW59IElzIGl0IGEgZGVmYXVsdCBwb3J0IGZvciB0aGUgZ2l2ZW4gcHJvdG9jb2xcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcXVpcmVkKHBvcnQsIHByb3RvY29sKSB7XG4gIHByb3RvY29sID0gcHJvdG9jb2wuc3BsaXQoJzonKVswXTtcbiAgcG9ydCA9ICtwb3J0O1xuXG4gIGlmICghcG9ydCkgcmV0dXJuIGZhbHNlO1xuXG4gIHN3aXRjaCAocHJvdG9jb2wpIHtcbiAgICBjYXNlICdodHRwJzpcbiAgICBjYXNlICd3cyc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDgwO1xuXG4gICAgY2FzZSAnaHR0cHMnOlxuICAgIGNhc2UgJ3dzcyc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDQ0MztcblxuICAgIGNhc2UgJ2Z0cCc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDIxO1xuXG4gICAgY2FzZSAnZ29waGVyJzpcbiAgICByZXR1cm4gcG9ydCAhPT0gNzA7XG5cbiAgICBjYXNlICdmaWxlJzpcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gcG9ydCAhPT0gMDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIERlY29kZSBhIFVSSSBlbmNvZGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIFVSSSBlbmNvZGVkIHN0cmluZy5cbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBkZWNvZGVkIHN0cmluZy5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkZWNvZGUoaW5wdXQpIHtcbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChpbnB1dC5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG59XG5cbi8qKlxuICogU2ltcGxlIHF1ZXJ5IHN0cmluZyBwYXJzZXIuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHF1ZXJ5IFRoZSBxdWVyeSBzdHJpbmcgdGhhdCBuZWVkcyB0byBiZSBwYXJzZWQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gcXVlcnlzdHJpbmcocXVlcnkpIHtcbiAgdmFyIHBhcnNlciA9IC8oW149PyZdKyk9PyhbXiZdKikvZ1xuICAgICwgcmVzdWx0ID0ge31cbiAgICAsIHBhcnQ7XG5cbiAgd2hpbGUgKHBhcnQgPSBwYXJzZXIuZXhlYyhxdWVyeSkpIHtcbiAgICB2YXIga2V5ID0gZGVjb2RlKHBhcnRbMV0pXG4gICAgICAsIHZhbHVlID0gZGVjb2RlKHBhcnRbMl0pO1xuXG4gICAgLy9cbiAgICAvLyBQcmV2ZW50IG92ZXJyaWRpbmcgb2YgZXhpc3RpbmcgcHJvcGVydGllcy4gVGhpcyBlbnN1cmVzIHRoYXQgYnVpbGQtaW5cbiAgICAvLyBtZXRob2RzIGxpa2UgYHRvU3RyaW5nYCBvciBfX3Byb3RvX18gYXJlIG5vdCBvdmVycmlkZW4gYnkgbWFsaWNpb3VzXG4gICAgLy8gcXVlcnlzdHJpbmdzLlxuICAgIC8vXG4gICAgaWYgKGtleSBpbiByZXN1bHQpIGNvbnRpbnVlO1xuICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybSBhIHF1ZXJ5IHN0cmluZyB0byBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBPYmplY3QgdGhhdCBzaG91bGQgYmUgdHJhbnNmb3JtZWQuXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4IE9wdGlvbmFsIHByZWZpeC5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBxdWVyeXN0cmluZ2lmeShvYmosIHByZWZpeCkge1xuICBwcmVmaXggPSBwcmVmaXggfHwgJyc7XG5cbiAgdmFyIHBhaXJzID0gW107XG5cbiAgLy9cbiAgLy8gT3B0aW9uYWxseSBwcmVmaXggd2l0aCBhICc/JyBpZiBuZWVkZWRcbiAgLy9cbiAgaWYgKCdzdHJpbmcnICE9PSB0eXBlb2YgcHJlZml4KSBwcmVmaXggPSAnPyc7XG5cbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyc9JysgZW5jb2RlVVJJQ29tcG9uZW50KG9ialtrZXldKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhaXJzLmxlbmd0aCA/IHByZWZpeCArIHBhaXJzLmpvaW4oJyYnKSA6ICcnO1xufVxuXG4vL1xuLy8gRXhwb3NlIHRoZSBtb2R1bGUuXG4vL1xuZXhwb3J0cy5zdHJpbmdpZnkgPSBxdWVyeXN0cmluZ2lmeTtcbmV4cG9ydHMucGFyc2UgPSBxdWVyeXN0cmluZztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlcXVpcmVkID0gcmVxdWlyZSgncmVxdWlyZXMtcG9ydCcpXG4gICwgcXMgPSByZXF1aXJlKCdxdWVyeXN0cmluZ2lmeScpXG4gICwgcHJvdG9jb2xyZSA9IC9eKFthLXpdW2EtejAtOS4rLV0qOik/KFxcL1xcLyk/KFtcXFNcXHNdKikvaVxuICAsIHNsYXNoZXMgPSAvXltBLVphLXpdW0EtWmEtejAtOSstLl0qOlxcL1xcLy87XG5cbi8qKlxuICogVGhlc2UgYXJlIHRoZSBwYXJzZSBydWxlcyBmb3IgdGhlIFVSTCBwYXJzZXIsIGl0IGluZm9ybXMgdGhlIHBhcnNlclxuICogYWJvdXQ6XG4gKlxuICogMC4gVGhlIGNoYXIgaXQgTmVlZHMgdG8gcGFyc2UsIGlmIGl0J3MgYSBzdHJpbmcgaXQgc2hvdWxkIGJlIGRvbmUgdXNpbmdcbiAqICAgIGluZGV4T2YsIFJlZ0V4cCB1c2luZyBleGVjIGFuZCBOYU4gbWVhbnMgc2V0IGFzIGN1cnJlbnQgdmFsdWUuXG4gKiAxLiBUaGUgcHJvcGVydHkgd2Ugc2hvdWxkIHNldCB3aGVuIHBhcnNpbmcgdGhpcyB2YWx1ZS5cbiAqIDIuIEluZGljYXRpb24gaWYgaXQncyBiYWNrd2FyZHMgb3IgZm9yd2FyZCBwYXJzaW5nLCB3aGVuIHNldCBhcyBudW1iZXIgaXQnc1xuICogICAgdGhlIHZhbHVlIG9mIGV4dHJhIGNoYXJzIHRoYXQgc2hvdWxkIGJlIHNwbGl0IG9mZi5cbiAqIDMuIEluaGVyaXQgZnJvbSBsb2NhdGlvbiBpZiBub24gZXhpc3RpbmcgaW4gdGhlIHBhcnNlci5cbiAqIDQuIGB0b0xvd2VyQ2FzZWAgdGhlIHJlc3VsdGluZyB2YWx1ZS5cbiAqL1xudmFyIHJ1bGVzID0gW1xuICBbJyMnLCAnaGFzaCddLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgYmFjay5cbiAgWyc/JywgJ3F1ZXJ5J10sICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGJhY2suXG4gIFsnLycsICdwYXRobmFtZSddLCAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBmcm9tIHRoZSBiYWNrLlxuICBbJ0AnLCAnYXV0aCcsIDFdLCAgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgZnJvbnQuXG4gIFtOYU4sICdob3N0JywgdW5kZWZpbmVkLCAxLCAxXSwgICAgICAgLy8gU2V0IGxlZnQgb3ZlciB2YWx1ZS5cbiAgWy86KFxcZCspJC8sICdwb3J0JywgdW5kZWZpbmVkLCAxXSwgICAgLy8gUmVnRXhwIHRoZSBiYWNrLlxuICBbTmFOLCAnaG9zdG5hbWUnLCB1bmRlZmluZWQsIDEsIDFdICAgIC8vIFNldCBsZWZ0IG92ZXIuXG5dO1xuXG4vKipcbiAqIFRoZXNlIHByb3BlcnRpZXMgc2hvdWxkIG5vdCBiZSBjb3BpZWQgb3IgaW5oZXJpdGVkIGZyb20uIFRoaXMgaXMgb25seSBuZWVkZWRcbiAqIGZvciBhbGwgbm9uIGJsb2IgVVJMJ3MgYXMgYSBibG9iIFVSTCBkb2VzIG5vdCBpbmNsdWRlIGEgaGFzaCwgb25seSB0aGVcbiAqIG9yaWdpbi5cbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByaXZhdGVcbiAqL1xudmFyIGlnbm9yZSA9IHsgaGFzaDogMSwgcXVlcnk6IDEgfTtcblxuLyoqXG4gKiBUaGUgbG9jYXRpb24gb2JqZWN0IGRpZmZlcnMgd2hlbiB5b3VyIGNvZGUgaXMgbG9hZGVkIHRocm91Z2ggYSBub3JtYWwgcGFnZSxcbiAqIFdvcmtlciBvciB0aHJvdWdoIGEgd29ya2VyIHVzaW5nIGEgYmxvYi4gQW5kIHdpdGggdGhlIGJsb2JibGUgYmVnaW5zIHRoZVxuICogdHJvdWJsZSBhcyB0aGUgbG9jYXRpb24gb2JqZWN0IHdpbGwgY29udGFpbiB0aGUgVVJMIG9mIHRoZSBibG9iLCBub3QgdGhlXG4gKiBsb2NhdGlvbiBvZiB0aGUgcGFnZSB3aGVyZSBvdXIgY29kZSBpcyBsb2FkZWQgaW4uIFRoZSBhY3R1YWwgb3JpZ2luIGlzXG4gKiBlbmNvZGVkIGluIHRoZSBgcGF0aG5hbWVgIHNvIHdlIGNhbiB0aGFua2Z1bGx5IGdlbmVyYXRlIGEgZ29vZCBcImRlZmF1bHRcIlxuICogbG9jYXRpb24gZnJvbSBpdCBzbyB3ZSBjYW4gZ2VuZXJhdGUgcHJvcGVyIHJlbGF0aXZlIFVSTCdzIGFnYWluLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gbG9jIE9wdGlvbmFsIGRlZmF1bHQgbG9jYXRpb24gb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gbG9sY2F0aW9uIG9iamVjdC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIGxvbGNhdGlvbihsb2MpIHtcbiAgdmFyIGxvY2F0aW9uID0gZ2xvYmFsICYmIGdsb2JhbC5sb2NhdGlvbiB8fCB7fTtcbiAgbG9jID0gbG9jIHx8IGxvY2F0aW9uO1xuXG4gIHZhciBmaW5hbGRlc3RpbmF0aW9uID0ge31cbiAgICAsIHR5cGUgPSB0eXBlb2YgbG9jXG4gICAgLCBrZXk7XG5cbiAgaWYgKCdibG9iOicgPT09IGxvYy5wcm90b2NvbCkge1xuICAgIGZpbmFsZGVzdGluYXRpb24gPSBuZXcgVVJMKHVuZXNjYXBlKGxvYy5wYXRobmFtZSksIHt9KTtcbiAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PT0gdHlwZSkge1xuICAgIGZpbmFsZGVzdGluYXRpb24gPSBuZXcgVVJMKGxvYywge30pO1xuICAgIGZvciAoa2V5IGluIGlnbm9yZSkgZGVsZXRlIGZpbmFsZGVzdGluYXRpb25ba2V5XTtcbiAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PT0gdHlwZSkge1xuICAgIGZvciAoa2V5IGluIGxvYykge1xuICAgICAgaWYgKGtleSBpbiBpZ25vcmUpIGNvbnRpbnVlO1xuICAgICAgZmluYWxkZXN0aW5hdGlvbltrZXldID0gbG9jW2tleV07XG4gICAgfVxuXG4gICAgaWYgKGZpbmFsZGVzdGluYXRpb24uc2xhc2hlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaW5hbGRlc3RpbmF0aW9uLnNsYXNoZXMgPSBzbGFzaGVzLnRlc3QobG9jLmhyZWYpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmaW5hbGRlc3RpbmF0aW9uO1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIFByb3RvY29sRXh0cmFjdFxuICogQHR5cGUgT2JqZWN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gcHJvdG9jb2wgUHJvdG9jb2wgbWF0Y2hlZCBpbiB0aGUgVVJMLCBpbiBsb3dlcmNhc2UuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNsYXNoZXMgYHRydWVgIGlmIHByb3RvY29sIGlzIGZvbGxvd2VkIGJ5IFwiLy9cIiwgZWxzZSBgZmFsc2VgLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlc3QgUmVzdCBvZiB0aGUgVVJMIHRoYXQgaXMgbm90IHBhcnQgb2YgdGhlIHByb3RvY29sLlxuICovXG5cbi8qKlxuICogRXh0cmFjdCBwcm90b2NvbCBpbmZvcm1hdGlvbiBmcm9tIGEgVVJMIHdpdGgvd2l0aG91dCBkb3VibGUgc2xhc2ggKFwiLy9cIikuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgVVJMIHdlIHdhbnQgdG8gZXh0cmFjdCBmcm9tLlxuICogQHJldHVybiB7UHJvdG9jb2xFeHRyYWN0fSBFeHRyYWN0ZWQgaW5mb3JtYXRpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdFByb3RvY29sKGFkZHJlc3MpIHtcbiAgdmFyIG1hdGNoID0gcHJvdG9jb2xyZS5leGVjKGFkZHJlc3MpO1xuXG4gIHJldHVybiB7XG4gICAgcHJvdG9jb2w6IG1hdGNoWzFdID8gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKSA6ICcnLFxuICAgIHNsYXNoZXM6ICEhbWF0Y2hbMl0sXG4gICAgcmVzdDogbWF0Y2hbM11cbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcmVsYXRpdmUgVVJMIHBhdGhuYW1lIGFnYWluc3QgYSBiYXNlIFVSTCBwYXRobmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVsYXRpdmUgUGF0aG5hbWUgb2YgdGhlIHJlbGF0aXZlIFVSTC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlIFBhdGhuYW1lIG9mIHRoZSBiYXNlIFVSTC5cbiAqIEByZXR1cm4ge1N0cmluZ30gUmVzb2x2ZWQgcGF0aG5hbWUuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZShyZWxhdGl2ZSwgYmFzZSkge1xuICB2YXIgcGF0aCA9IChiYXNlIHx8ICcvJykuc3BsaXQoJy8nKS5zbGljZSgwLCAtMSkuY29uY2F0KHJlbGF0aXZlLnNwbGl0KCcvJykpXG4gICAgLCBpID0gcGF0aC5sZW5ndGhcbiAgICAsIGxhc3QgPSBwYXRoW2kgLSAxXVxuICAgICwgdW5zaGlmdCA9IGZhbHNlXG4gICAgLCB1cCA9IDA7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIGlmIChwYXRoW2ldID09PSAnLicpIHtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAocGF0aFtpXSA9PT0gJy4uJykge1xuICAgICAgcGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIGlmIChpID09PSAwKSB1bnNoaWZ0ID0gdHJ1ZTtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICBpZiAodW5zaGlmdCkgcGF0aC51bnNoaWZ0KCcnKTtcbiAgaWYgKGxhc3QgPT09ICcuJyB8fCBsYXN0ID09PSAnLi4nKSBwYXRoLnB1c2goJycpO1xuXG4gIHJldHVybiBwYXRoLmpvaW4oJy8nKTtcbn1cblxuLyoqXG4gKiBUaGUgYWN0dWFsIFVSTCBpbnN0YW5jZS4gSW5zdGVhZCBvZiByZXR1cm5pbmcgYW4gb2JqZWN0IHdlJ3ZlIG9wdGVkLWluIHRvXG4gKiBjcmVhdGUgYW4gYWN0dWFsIGNvbnN0cnVjdG9yIGFzIGl0J3MgbXVjaCBtb3JlIG1lbW9yeSBlZmZpY2llbnQgYW5kXG4gKiBmYXN0ZXIgYW5kIGl0IHBsZWFzZXMgbXkgT0NELlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgVVJMIHdlIHdhbnQgdG8gcGFyc2UuXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGxvY2F0aW9uIExvY2F0aW9uIGRlZmF1bHRzIGZvciByZWxhdGl2ZSBwYXRocy5cbiAqIEBwYXJhbSB7Qm9vbGVhbnxGdW5jdGlvbn0gcGFyc2VyIFBhcnNlciBmb3IgdGhlIHF1ZXJ5IHN0cmluZy5cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIFVSTChhZGRyZXNzLCBsb2NhdGlvbiwgcGFyc2VyKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBVUkwpKSB7XG4gICAgcmV0dXJuIG5ldyBVUkwoYWRkcmVzcywgbG9jYXRpb24sIHBhcnNlcik7XG4gIH1cblxuICB2YXIgcmVsYXRpdmUsIGV4dHJhY3RlZCwgcGFyc2UsIGluc3RydWN0aW9uLCBpbmRleCwga2V5XG4gICAgLCBpbnN0cnVjdGlvbnMgPSBydWxlcy5zbGljZSgpXG4gICAgLCB0eXBlID0gdHlwZW9mIGxvY2F0aW9uXG4gICAgLCB1cmwgPSB0aGlzXG4gICAgLCBpID0gMDtcblxuICAvL1xuICAvLyBUaGUgZm9sbG93aW5nIGlmIHN0YXRlbWVudHMgYWxsb3dzIHRoaXMgbW9kdWxlIHR3byBoYXZlIGNvbXBhdGliaWxpdHkgd2l0aFxuICAvLyAyIGRpZmZlcmVudCBBUEk6XG4gIC8vXG4gIC8vIDEuIE5vZGUuanMncyBgdXJsLnBhcnNlYCBhcGkgd2hpY2ggYWNjZXB0cyBhIFVSTCwgYm9vbGVhbiBhcyBhcmd1bWVudHNcbiAgLy8gICAgd2hlcmUgdGhlIGJvb2xlYW4gaW5kaWNhdGVzIHRoYXQgdGhlIHF1ZXJ5IHN0cmluZyBzaG91bGQgYWxzbyBiZSBwYXJzZWQuXG4gIC8vXG4gIC8vIDIuIFRoZSBgVVJMYCBpbnRlcmZhY2Ugb2YgdGhlIGJyb3dzZXIgd2hpY2ggYWNjZXB0cyBhIFVSTCwgb2JqZWN0IGFzXG4gIC8vICAgIGFyZ3VtZW50cy4gVGhlIHN1cHBsaWVkIG9iamVjdCB3aWxsIGJlIHVzZWQgYXMgZGVmYXVsdCB2YWx1ZXMgLyBmYWxsLWJhY2tcbiAgLy8gICAgZm9yIHJlbGF0aXZlIHBhdGhzLlxuICAvL1xuICBpZiAoJ29iamVjdCcgIT09IHR5cGUgJiYgJ3N0cmluZycgIT09IHR5cGUpIHtcbiAgICBwYXJzZXIgPSBsb2NhdGlvbjtcbiAgICBsb2NhdGlvbiA9IG51bGw7XG4gIH1cblxuICBpZiAocGFyc2VyICYmICdmdW5jdGlvbicgIT09IHR5cGVvZiBwYXJzZXIpIHBhcnNlciA9IHFzLnBhcnNlO1xuXG4gIGxvY2F0aW9uID0gbG9sY2F0aW9uKGxvY2F0aW9uKTtcblxuICAvL1xuICAvLyBFeHRyYWN0IHByb3RvY29sIGluZm9ybWF0aW9uIGJlZm9yZSBydW5uaW5nIHRoZSBpbnN0cnVjdGlvbnMuXG4gIC8vXG4gIGV4dHJhY3RlZCA9IGV4dHJhY3RQcm90b2NvbChhZGRyZXNzIHx8ICcnKTtcbiAgcmVsYXRpdmUgPSAhZXh0cmFjdGVkLnByb3RvY29sICYmICFleHRyYWN0ZWQuc2xhc2hlcztcbiAgdXJsLnNsYXNoZXMgPSBleHRyYWN0ZWQuc2xhc2hlcyB8fCByZWxhdGl2ZSAmJiBsb2NhdGlvbi5zbGFzaGVzO1xuICB1cmwucHJvdG9jb2wgPSBleHRyYWN0ZWQucHJvdG9jb2wgfHwgbG9jYXRpb24ucHJvdG9jb2wgfHwgJyc7XG4gIGFkZHJlc3MgPSBleHRyYWN0ZWQucmVzdDtcblxuICAvL1xuICAvLyBXaGVuIHRoZSBhdXRob3JpdHkgY29tcG9uZW50IGlzIGFic2VudCB0aGUgVVJMIHN0YXJ0cyB3aXRoIGEgcGF0aFxuICAvLyBjb21wb25lbnQuXG4gIC8vXG4gIGlmICghZXh0cmFjdGVkLnNsYXNoZXMpIGluc3RydWN0aW9uc1syXSA9IFsvKC4qKS8sICdwYXRobmFtZSddO1xuXG4gIGZvciAoOyBpIDwgaW5zdHJ1Y3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgaW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbnNbaV07XG4gICAgcGFyc2UgPSBpbnN0cnVjdGlvblswXTtcbiAgICBrZXkgPSBpbnN0cnVjdGlvblsxXTtcblxuICAgIGlmIChwYXJzZSAhPT0gcGFyc2UpIHtcbiAgICAgIHVybFtrZXldID0gYWRkcmVzcztcbiAgICB9IGVsc2UgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgcGFyc2UpIHtcbiAgICAgIGlmICh+KGluZGV4ID0gYWRkcmVzcy5pbmRleE9mKHBhcnNlKSkpIHtcbiAgICAgICAgaWYgKCdudW1iZXInID09PSB0eXBlb2YgaW5zdHJ1Y3Rpb25bMl0pIHtcbiAgICAgICAgICB1cmxba2V5XSA9IGFkZHJlc3Muc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKGluZGV4ICsgaW5zdHJ1Y3Rpb25bMl0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHVybFtrZXldID0gYWRkcmVzcy5zbGljZShpbmRleCk7XG4gICAgICAgICAgYWRkcmVzcyA9IGFkZHJlc3Muc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICgoaW5kZXggPSBwYXJzZS5leGVjKGFkZHJlc3MpKSkge1xuICAgICAgdXJsW2tleV0gPSBpbmRleFsxXTtcbiAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4LmluZGV4KTtcbiAgICB9XG5cbiAgICB1cmxba2V5XSA9IHVybFtrZXldIHx8IChcbiAgICAgIHJlbGF0aXZlICYmIGluc3RydWN0aW9uWzNdID8gbG9jYXRpb25ba2V5XSB8fCAnJyA6ICcnXG4gICAgKTtcblxuICAgIC8vXG4gICAgLy8gSG9zdG5hbWUsIGhvc3QgYW5kIHByb3RvY29sIHNob3VsZCBiZSBsb3dlcmNhc2VkIHNvIHRoZXkgY2FuIGJlIHVzZWQgdG9cbiAgICAvLyBjcmVhdGUgYSBwcm9wZXIgYG9yaWdpbmAuXG4gICAgLy9cbiAgICBpZiAoaW5zdHJ1Y3Rpb25bNF0pIHVybFtrZXldID0gdXJsW2tleV0udG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8vXG4gIC8vIEFsc28gcGFyc2UgdGhlIHN1cHBsaWVkIHF1ZXJ5IHN0cmluZyBpbiB0byBhbiBvYmplY3QuIElmIHdlJ3JlIHN1cHBsaWVkXG4gIC8vIHdpdGggYSBjdXN0b20gcGFyc2VyIGFzIGZ1bmN0aW9uIHVzZSB0aGF0IGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgYnVpbGQtaW5cbiAgLy8gcGFyc2VyLlxuICAvL1xuICBpZiAocGFyc2VyKSB1cmwucXVlcnkgPSBwYXJzZXIodXJsLnF1ZXJ5KTtcblxuICAvL1xuICAvLyBJZiB0aGUgVVJMIGlzIHJlbGF0aXZlLCByZXNvbHZlIHRoZSBwYXRobmFtZSBhZ2FpbnN0IHRoZSBiYXNlIFVSTC5cbiAgLy9cbiAgaWYgKFxuICAgICAgcmVsYXRpdmVcbiAgICAmJiBsb2NhdGlvbi5zbGFzaGVzXG4gICAgJiYgdXJsLnBhdGhuYW1lLmNoYXJBdCgwKSAhPT0gJy8nXG4gICAgJiYgKHVybC5wYXRobmFtZSAhPT0gJycgfHwgbG9jYXRpb24ucGF0aG5hbWUgIT09ICcnKVxuICApIHtcbiAgICB1cmwucGF0aG5hbWUgPSByZXNvbHZlKHVybC5wYXRobmFtZSwgbG9jYXRpb24ucGF0aG5hbWUpO1xuICB9XG5cbiAgLy9cbiAgLy8gV2Ugc2hvdWxkIG5vdCBhZGQgcG9ydCBudW1iZXJzIGlmIHRoZXkgYXJlIGFscmVhZHkgdGhlIGRlZmF1bHQgcG9ydCBudW1iZXJcbiAgLy8gZm9yIGEgZ2l2ZW4gcHJvdG9jb2wuIEFzIHRoZSBob3N0IGFsc28gY29udGFpbnMgdGhlIHBvcnQgbnVtYmVyIHdlJ3JlIGdvaW5nXG4gIC8vIG92ZXJyaWRlIGl0IHdpdGggdGhlIGhvc3RuYW1lIHdoaWNoIGNvbnRhaW5zIG5vIHBvcnQgbnVtYmVyLlxuICAvL1xuICBpZiAoIXJlcXVpcmVkKHVybC5wb3J0LCB1cmwucHJvdG9jb2wpKSB7XG4gICAgdXJsLmhvc3QgPSB1cmwuaG9zdG5hbWU7XG4gICAgdXJsLnBvcnQgPSAnJztcbiAgfVxuXG4gIC8vXG4gIC8vIFBhcnNlIGRvd24gdGhlIGBhdXRoYCBmb3IgdGhlIHVzZXJuYW1lIGFuZCBwYXNzd29yZC5cbiAgLy9cbiAgdXJsLnVzZXJuYW1lID0gdXJsLnBhc3N3b3JkID0gJyc7XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIGluc3RydWN0aW9uID0gdXJsLmF1dGguc3BsaXQoJzonKTtcbiAgICB1cmwudXNlcm5hbWUgPSBpbnN0cnVjdGlvblswXSB8fCAnJztcbiAgICB1cmwucGFzc3dvcmQgPSBpbnN0cnVjdGlvblsxXSB8fCAnJztcbiAgfVxuXG4gIHVybC5vcmlnaW4gPSB1cmwucHJvdG9jb2wgJiYgdXJsLmhvc3QgJiYgdXJsLnByb3RvY29sICE9PSAnZmlsZTonXG4gICAgPyB1cmwucHJvdG9jb2wgKycvLycrIHVybC5ob3N0XG4gICAgOiAnbnVsbCc7XG5cbiAgLy9cbiAgLy8gVGhlIGhyZWYgaXMganVzdCB0aGUgY29tcGlsZWQgcmVzdWx0LlxuICAvL1xuICB1cmwuaHJlZiA9IHVybC50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIFRoaXMgaXMgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjaGFuZ2luZyBwcm9wZXJ0aWVzIGluIHRoZSBVUkwgaW5zdGFuY2UgdG9cbiAqIGluc3VyZSB0aGF0IHRoZXkgYWxsIHByb3BhZ2F0ZSBjb3JyZWN0bHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhcnQgICAgICAgICAgUHJvcGVydHkgd2UgbmVlZCB0byBhZGp1c3QuXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSAgICAgICAgICBUaGUgbmV3bHkgYXNzaWduZWQgdmFsdWUuXG4gKiBAcGFyYW0ge0Jvb2xlYW58RnVuY3Rpb259IGZuICBXaGVuIHNldHRpbmcgdGhlIHF1ZXJ5LCBpdCB3aWxsIGJlIHRoZSBmdW5jdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlZCB0byBwYXJzZSB0aGUgcXVlcnkuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaGVuIHNldHRpbmcgdGhlIHByb3RvY29sLCBkb3VibGUgc2xhc2ggd2lsbCBiZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCBmcm9tIHRoZSBmaW5hbCB1cmwgaWYgaXQgaXMgdHJ1ZS5cbiAqIEByZXR1cm5zIHtVUkx9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBzZXQocGFydCwgdmFsdWUsIGZuKSB7XG4gIHZhciB1cmwgPSB0aGlzO1xuXG4gIHN3aXRjaCAocGFydCkge1xuICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHZhbHVlICYmIHZhbHVlLmxlbmd0aCkge1xuICAgICAgICB2YWx1ZSA9IChmbiB8fCBxcy5wYXJzZSkodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncG9ydCc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKCFyZXF1aXJlZCh2YWx1ZSwgdXJsLnByb3RvY29sKSkge1xuICAgICAgICB1cmwuaG9zdCA9IHVybC5ob3N0bmFtZTtcbiAgICAgICAgdXJsW3BhcnRdID0gJyc7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlKSB7XG4gICAgICAgIHVybC5ob3N0ID0gdXJsLmhvc3RuYW1lICsnOicrIHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2hvc3RuYW1lJzpcbiAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuXG4gICAgICBpZiAodXJsLnBvcnQpIHZhbHVlICs9ICc6JysgdXJsLnBvcnQ7XG4gICAgICB1cmwuaG9zdCA9IHZhbHVlO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdob3N0JzpcbiAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuXG4gICAgICBpZiAoLzpcXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5zcGxpdCgnOicpO1xuICAgICAgICB1cmwucG9ydCA9IHZhbHVlLnBvcCgpO1xuICAgICAgICB1cmwuaG9zdG5hbWUgPSB2YWx1ZS5qb2luKCc6Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmwuaG9zdG5hbWUgPSB2YWx1ZTtcbiAgICAgICAgdXJsLnBvcnQgPSAnJztcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwcm90b2NvbCc6XG4gICAgICB1cmwucHJvdG9jb2wgPSB2YWx1ZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdXJsLnNsYXNoZXMgPSAhZm47XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3BhdGhuYW1lJzpcbiAgICBjYXNlICdoYXNoJzpcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB2YXIgY2hhciA9IHBhcnQgPT09ICdwYXRobmFtZScgPyAnLycgOiAnIyc7XG4gICAgICAgIHVybFtwYXJ0XSA9IHZhbHVlLmNoYXJBdCgwKSAhPT0gY2hhciA/IGNoYXIgKyB2YWx1ZSA6IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaW5zID0gcnVsZXNbaV07XG5cbiAgICBpZiAoaW5zWzRdKSB1cmxbaW5zWzFdXSA9IHVybFtpbnNbMV1dLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICB1cmwub3JpZ2luID0gdXJsLnByb3RvY29sICYmIHVybC5ob3N0ICYmIHVybC5wcm90b2NvbCAhPT0gJ2ZpbGU6J1xuICAgID8gdXJsLnByb3RvY29sICsnLy8nKyB1cmwuaG9zdFxuICAgIDogJ251bGwnO1xuXG4gIHVybC5ocmVmID0gdXJsLnRvU3RyaW5nKCk7XG5cbiAgcmV0dXJuIHVybDtcbn1cblxuLyoqXG4gKiBUcmFuc2Zvcm0gdGhlIHByb3BlcnRpZXMgYmFjayBpbiB0byBhIHZhbGlkIGFuZCBmdWxsIFVSTCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5naWZ5IE9wdGlvbmFsIHF1ZXJ5IHN0cmluZ2lmeSBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB0b1N0cmluZyhzdHJpbmdpZnkpIHtcbiAgaWYgKCFzdHJpbmdpZnkgfHwgJ2Z1bmN0aW9uJyAhPT0gdHlwZW9mIHN0cmluZ2lmeSkgc3RyaW5naWZ5ID0gcXMuc3RyaW5naWZ5O1xuXG4gIHZhciBxdWVyeVxuICAgICwgdXJsID0gdGhpc1xuICAgICwgcHJvdG9jb2wgPSB1cmwucHJvdG9jb2w7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJBdChwcm90b2NvbC5sZW5ndGggLSAxKSAhPT0gJzonKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIHJlc3VsdCA9IHByb3RvY29sICsgKHVybC5zbGFzaGVzID8gJy8vJyA6ICcnKTtcblxuICBpZiAodXJsLnVzZXJuYW1lKSB7XG4gICAgcmVzdWx0ICs9IHVybC51c2VybmFtZTtcbiAgICBpZiAodXJsLnBhc3N3b3JkKSByZXN1bHQgKz0gJzonKyB1cmwucGFzc3dvcmQ7XG4gICAgcmVzdWx0ICs9ICdAJztcbiAgfVxuXG4gIHJlc3VsdCArPSB1cmwuaG9zdCArIHVybC5wYXRobmFtZTtcblxuICBxdWVyeSA9ICdvYmplY3QnID09PSB0eXBlb2YgdXJsLnF1ZXJ5ID8gc3RyaW5naWZ5KHVybC5xdWVyeSkgOiB1cmwucXVlcnk7XG4gIGlmIChxdWVyeSkgcmVzdWx0ICs9ICc/JyAhPT0gcXVlcnkuY2hhckF0KDApID8gJz8nKyBxdWVyeSA6IHF1ZXJ5O1xuXG4gIGlmICh1cmwuaGFzaCkgcmVzdWx0ICs9IHVybC5oYXNoO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblVSTC5wcm90b3R5cGUgPSB7IHNldDogc2V0LCB0b1N0cmluZzogdG9TdHJpbmcgfTtcblxuLy9cbi8vIEV4cG9zZSB0aGUgVVJMIHBhcnNlciBhbmQgc29tZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdGhhdCBtaWdodCBiZSB1c2VmdWwgZm9yXG4vLyBvdGhlcnMgb3IgdGVzdGluZy5cbi8vXG5VUkwuZXh0cmFjdFByb3RvY29sID0gZXh0cmFjdFByb3RvY29sO1xuVVJMLmxvY2F0aW9uID0gbG9sY2F0aW9uO1xuVVJMLnFzID0gcXM7XG5cbm1vZHVsZS5leHBvcnRzID0gVVJMO1xuIiwiLypcbiogVGhpcyBkZWxheSBhbGxvd3MgdGhlIHRocmVhZCB0byBmaW5pc2ggYXNzaWduaW5nIGl0cyBvbiogbWV0aG9kc1xuKiBiZWZvcmUgaW52b2tpbmcgdGhlIGRlbGF5IGNhbGxiYWNrLiBUaGlzIGlzIHB1cmVseSBhIHRpbWluZyBoYWNrLlxuKiBodHRwOi8vZ2Vla2FieXRlLmJsb2dzcG90LmNvbS8yMDE0LzAxL2phdmFzY3JpcHQtZWZmZWN0LW9mLXNldHRpbmctc2V0dGltZW91dC5odG1sXG4qXG4qIEBwYXJhbSB7Y2FsbGJhY2s6IGZ1bmN0aW9ufSB0aGUgY2FsbGJhY2sgd2hpY2ggd2lsbCBiZSBpbnZva2VkIGFmdGVyIHRoZSB0aW1lb3V0XG4qIEBwYXJtYSB7Y29udGV4dDogb2JqZWN0fSB0aGUgY29udGV4dCBpbiB3aGljaCB0byBpbnZva2UgdGhlIGZ1bmN0aW9uXG4qL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVsYXkoY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgc2V0VGltZW91dCh0aW1lb3V0Q29udGV4dCA9PiBjYWxsYmFjay5jYWxsKHRpbWVvdXRDb250ZXh0KSwgNCwgY29udGV4dCk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBsb2cobWV0aG9kLCBtZXNzYWdlKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgY29uc29sZVttZXRob2RdLmNhbGwobnVsbCwgbWVzc2FnZSk7XG4gIH1cbiAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG59XG4iLCJleHBvcnQgZnVuY3Rpb24gcmVqZWN0KGFycmF5LCBjYWxsYmFjaykge1xuICBjb25zdCByZXN1bHRzID0gW107XG4gIGFycmF5LmZvckVhY2goaXRlbUluQXJyYXkgPT4ge1xuICAgIGlmICghY2FsbGJhY2soaXRlbUluQXJyYXkpKSB7XG4gICAgICByZXN1bHRzLnB1c2goaXRlbUluQXJyYXkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXIoYXJyYXksIGNhbGxiYWNrKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgYXJyYXkuZm9yRWFjaChpdGVtSW5BcnJheSA9PiB7XG4gICAgaWYgKGNhbGxiYWNrKGl0ZW1JbkFycmF5KSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGl0ZW1JbkFycmF5KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHRzO1xufVxuIiwiaW1wb3J0IHsgcmVqZWN0LCBmaWx0ZXIgfSBmcm9tICcuLi9oZWxwZXJzL2FycmF5LWhlbHBlcnMnO1xuXG4vKlxuKiBFdmVudFRhcmdldCBpcyBhbiBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgb2JqZWN0cyB0aGF0IGNhblxuKiByZWNlaXZlIGV2ZW50cyBhbmQgbWF5IGhhdmUgbGlzdGVuZXJzIGZvciB0aGVtLlxuKlxuKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXRcbiovXG5jbGFzcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubGlzdGVuZXJzID0ge307XG4gIH1cblxuICAvKlxuICAqIFRpZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhbiBldmVudCB0eXBlIHdoaWNoIGNhbiBsYXRlciBiZSBpbnZva2VkIHZpYSB0aGVcbiAgKiBkaXNwYXRjaEV2ZW50IG1ldGhvZC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gdGhlIHR5cGUgb2YgZXZlbnQgKGllOiAnb3BlbicsICdtZXNzYWdlJywgZXRjLilcbiAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lciAtIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBpbnZva2Ugd2hlbmV2ZXIgYW4gZXZlbnQgaXMgZGlzcGF0Y2hlZCBtYXRjaGluZyB0aGUgZ2l2ZW4gdHlwZVxuICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlQ2FwdHVyZSAtIE4vQSBUT0RPOiBpbXBsZW1lbnQgdXNlQ2FwdHVyZSBmdW5jdGlvbmFsaXR5XG4gICovXG4gIGFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIgLyogLCB1c2VDYXB0dXJlICovKSB7XG4gICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMubGlzdGVuZXJzW3R5cGVdKSkge1xuICAgICAgICB0aGlzLmxpc3RlbmVyc1t0eXBlXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICAvLyBPbmx5IGFkZCB0aGUgc2FtZSBmdW5jdGlvbiBvbmNlXG4gICAgICBpZiAoZmlsdGVyKHRoaXMubGlzdGVuZXJzW3R5cGVdLCBpdGVtID0+IGl0ZW0gPT09IGxpc3RlbmVyKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBzbyBpdCB3aWxsIG5vIGxvbmdlciBiZSBpbnZva2VkIHZpYSB0aGUgZGlzcGF0Y2hFdmVudCBtZXRob2QuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIHRoZSB0eXBlIG9mIGV2ZW50IChpZTogJ29wZW4nLCAnbWVzc2FnZScsIGV0Yy4pXG4gICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWQgbWF0Y2hpbmcgdGhlIGdpdmVuIHR5cGVcbiAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUNhcHR1cmUgLSBOL0EgVE9ETzogaW1wbGVtZW50IHVzZUNhcHR1cmUgZnVuY3Rpb25hbGl0eVxuICAqL1xuICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHJlbW92aW5nTGlzdGVuZXIgLyogLCB1c2VDYXB0dXJlICovKSB7XG4gICAgY29uc3QgYXJyYXlPZkxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzW3R5cGVdO1xuICAgIHRoaXMubGlzdGVuZXJzW3R5cGVdID0gcmVqZWN0KGFycmF5T2ZMaXN0ZW5lcnMsIGxpc3RlbmVyID0+IGxpc3RlbmVyID09PSByZW1vdmluZ0xpc3RlbmVyKTtcbiAgfVxuXG4gIC8qXG4gICogSW52b2tlcyBhbGwgbGlzdGVuZXIgZnVuY3Rpb25zIHRoYXQgYXJlIGxpc3RlbmluZyB0byB0aGUgZ2l2ZW4gZXZlbnQudHlwZSBwcm9wZXJ0eS4gRWFjaFxuICAqIGxpc3RlbmVyIHdpbGwgYmUgcGFzc2VkIHRoZSBldmVudCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICpcbiAgKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBldmVudCBvYmplY3Qgd2hpY2ggd2lsbCBiZSBwYXNzZWQgdG8gYWxsIGxpc3RlbmVycyBvZiB0aGUgZXZlbnQudHlwZSBwcm9wZXJ0eVxuICAqL1xuICBkaXNwYXRjaEV2ZW50KGV2ZW50LCAuLi5jdXN0b21Bcmd1bWVudHMpIHtcbiAgICBjb25zdCBldmVudE5hbWUgPSBldmVudC50eXBlO1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzW2V2ZW50TmFtZV07XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdGVuZXJzKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcbiAgICAgIGlmIChjdXN0b21Bcmd1bWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBjdXN0b21Bcmd1bWVudHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudFRhcmdldDtcbiIsImltcG9ydCB7IHJlamVjdCB9IGZyb20gJy4vaGVscGVycy9hcnJheS1oZWxwZXJzJztcblxuLypcbiogVGhlIG5ldHdvcmsgYnJpZGdlIGlzIGEgd2F5IGZvciB0aGUgbW9jayB3ZWJzb2NrZXQgb2JqZWN0IHRvICdjb21tdW5pY2F0ZScgd2l0aFxuKiBhbGwgYXZhaWxhYmxlIHNlcnZlcnMuIFRoaXMgaXMgYSBzaW5nbGV0b24gb2JqZWN0IHNvIGl0IGlzIGltcG9ydGFudCB0aGF0IHlvdVxuKiBjbGVhbiB1cCB1cmxNYXAgd2hlbmV2ZXIgeW91IGFyZSBmaW5pc2hlZC5cbiovXG5jbGFzcyBOZXR3b3JrQnJpZGdlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy51cmxNYXAgPSB7fTtcbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSB3ZWJzb2NrZXQgb2JqZWN0IHRvIHRoZSB1cmxNYXAgaGFzaCBzbyB0aGF0IGl0IGNhbiBmaW5kIHRoZSBzZXJ2ZXJcbiAgKiBpdCBpcyBjb25uZWN0ZWQgdG8gYW5kIHRoZSBzZXJ2ZXIgaW4gdHVybiBjYW4gZmluZCBpdC5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSB3ZWJzb2NrZXQgLSB3ZWJzb2NrZXQgb2JqZWN0IHRvIGFkZCB0byB0aGUgdXJsTWFwIGhhc2hcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIGF0dGFjaFdlYlNvY2tldCh3ZWJzb2NrZXQsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXAgJiYgY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXIgJiYgY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLmluZGV4T2Yod2Vic29ja2V0KSA9PT0gLTEpIHtcbiAgICAgIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cy5wdXNoKHdlYnNvY2tldCk7XG4gICAgICByZXR1cm4gY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBBdHRhY2hlcyBhIHdlYnNvY2tldCB0byBhIHJvb21cbiAgKi9cbiAgYWRkTWVtYmVyc2hpcFRvUm9vbSh3ZWJzb2NrZXQsIHJvb20pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbd2Vic29ja2V0LnVybF07XG5cbiAgICBpZiAoY29ubmVjdGlvbkxvb2t1cCAmJiBjb25uZWN0aW9uTG9va3VwLnNlcnZlciAmJiBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMuaW5kZXhPZih3ZWJzb2NrZXQpICE9PSAtMSkge1xuICAgICAgaWYgKCFjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSkge1xuICAgICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXS5wdXNoKHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBBdHRhY2hlcyBhIHNlcnZlciBvYmplY3QgdG8gdGhlIHVybE1hcCBoYXNoIHNvIHRoYXQgaXQgY2FuIGZpbmQgYSB3ZWJzb2NrZXRzXG4gICogd2hpY2ggYXJlIGNvbm5lY3RlZCB0byBpdCBhbmQgc28gdGhhdCB3ZWJzb2NrZXRzIGNhbiBpbiB0dXJuIGNhbiBmaW5kIGl0LlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IHNlcnZlciAtIHNlcnZlciBvYmplY3QgdG8gYWRkIHRvIHRoZSB1cmxNYXAgaGFzaFxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgYXR0YWNoU2VydmVyKHNlcnZlciwgdXJsKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3VybF07XG5cbiAgICBpZiAoIWNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIHRoaXMudXJsTWFwW3VybF0gPSB7XG4gICAgICAgIHNlcnZlcixcbiAgICAgICAgd2Vic29ja2V0czogW10sXG4gICAgICAgIHJvb21NZW1iZXJzaGlwczoge31cbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBzZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBGaW5kcyB0aGUgc2VydmVyIHdoaWNoIGlzICdydW5uaW5nJyBvbiB0aGUgZ2l2ZW4gdXJsLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIHRoZSB1cmwgdG8gdXNlIHRvIGZpbmQgd2hpY2ggc2VydmVyIGlzIHJ1bm5pbmcgb24gaXRcbiAgKi9cbiAgc2VydmVyTG9va3VwKHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIHJldHVybiBjb25uZWN0aW9uTG9va3VwLnNlcnZlcjtcbiAgICB9XG4gIH1cblxuICAvKlxuICAqIEZpbmRzIGFsbCB3ZWJzb2NrZXRzIHdoaWNoIGlzICdsaXN0ZW5pbmcnIG9uIHRoZSBnaXZlbiB1cmwuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gdGhlIHVybCB0byB1c2UgdG8gZmluZCBhbGwgd2Vic29ja2V0cyB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIGl0XG4gICogQHBhcmFtIHtzdHJpbmd9IHJvb20gLSBpZiBhIHJvb20gaXMgcHJvdmlkZWQsIHdpbGwgb25seSByZXR1cm4gc29ja2V0cyBpbiB0aGlzIHJvb21cbiAgKiBAcGFyYW0ge2NsYXNzfSBicm9hZGNhc3RlciAtIHNvY2tldCB0aGF0IGlzIGJyb2FkY2FzdGluZyBhbmQgaXMgdG8gYmUgZXhjbHVkZWQgZnJvbSB0aGUgbG9va3VwXG4gICovXG4gIHdlYnNvY2tldHNMb29rdXAodXJsLCByb29tLCBicm9hZGNhc3Rlcikge1xuICAgIGxldCB3ZWJzb2NrZXRzO1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgd2Vic29ja2V0cyA9IGNvbm5lY3Rpb25Mb29rdXAgPyBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMgOiBbXTtcblxuICAgIGlmIChyb29tKSB7XG4gICAgICBjb25zdCBtZW1iZXJzID0gY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV07XG4gICAgICB3ZWJzb2NrZXRzID0gbWVtYmVycyB8fCBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnJvYWRjYXN0ZXIgPyB3ZWJzb2NrZXRzLmZpbHRlcih3ZWJzb2NrZXQgPT4gd2Vic29ja2V0ICE9PSBicm9hZGNhc3RlcikgOiB3ZWJzb2NrZXRzO1xuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBlbnRyeSBhc3NvY2lhdGVkIHdpdGggdGhlIHVybC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgcmVtb3ZlU2VydmVyKHVybCkge1xuICAgIGRlbGV0ZSB0aGlzLnVybE1hcFt1cmxdO1xuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBpbmRpdmlkdWFsIHdlYnNvY2tldCBmcm9tIHRoZSBtYXAgb2YgYXNzb2NpYXRlZCB3ZWJzb2NrZXRzLlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IHdlYnNvY2tldCAtIHdlYnNvY2tldCBvYmplY3QgdG8gcmVtb3ZlIGZyb20gdGhlIHVybCBtYXBcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIHJlbW92ZVdlYlNvY2tldCh3ZWJzb2NrZXQsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cyA9IHJlamVjdChjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMsIHNvY2tldCA9PiBzb2NrZXQgPT09IHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIGEgd2Vic29ja2V0IGZyb20gYSByb29tXG4gICovXG4gIHJlbW92ZU1lbWJlcnNoaXBGcm9tUm9vbSh3ZWJzb2NrZXQsIHJvb20pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbd2Vic29ja2V0LnVybF07XG4gICAgY29uc3QgbWVtYmVyc2hpcHMgPSBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwICYmIG1lbWJlcnNoaXBzICE9PSBudWxsKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSA9IHJlamVjdChtZW1iZXJzaGlwcywgc29ja2V0ID0+IHNvY2tldCA9PT0gd2Vic29ja2V0KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IE5ldHdvcmtCcmlkZ2UoKTsgLy8gTm90ZTogdGhpcyBpcyBhIHNpbmdsZXRvblxuIiwiLypcbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DbG9zZUV2ZW50XG4gKi9cbmV4cG9ydCBjb25zdCBDTE9TRV9DT0RFUyA9IHtcbiAgQ0xPU0VfTk9STUFMOiAxMDAwLFxuICBDTE9TRV9HT0lOR19BV0FZOiAxMDAxLFxuICBDTE9TRV9QUk9UT0NPTF9FUlJPUjogMTAwMixcbiAgQ0xPU0VfVU5TVVBQT1JURUQ6IDEwMDMsXG4gIENMT1NFX05PX1NUQVRVUzogMTAwNSxcbiAgQ0xPU0VfQUJOT1JNQUw6IDEwMDYsXG4gIFVOU1VQUE9SVEVEX0RBVEE6IDEwMDcsXG4gIFBPTElDWV9WSU9MQVRJT046IDEwMDgsXG4gIENMT1NFX1RPT19MQVJHRTogMTAwOSxcbiAgTUlTU0lOR19FWFRFTlNJT046IDEwMTAsXG4gIElOVEVSTkFMX0VSUk9SOiAxMDExLFxuICBTRVJWSUNFX1JFU1RBUlQ6IDEwMTIsXG4gIFRSWV9BR0FJTl9MQVRFUjogMTAxMyxcbiAgVExTX0hBTkRTSEFLRTogMTAxNVxufTtcblxuZXhwb3J0IGNvbnN0IEVSUk9SX1BSRUZJWCA9IHtcbiAgQ09OU1RSVUNUT1JfRVJST1I6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnV2ViU29ja2V0JzpcIixcbiAgQ0xPU0VfRVJST1I6IFwiRmFpbGVkIHRvIGV4ZWN1dGUgJ2Nsb3NlJyBvbiAnV2ViU29ja2V0JzpcIixcbiAgRVZFTlQ6IHtcbiAgICBDT05TVFJVQ1Q6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnRXZlbnQnOlwiLFxuICAgIE1FU1NBR0U6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnTWVzc2FnZUV2ZW50JzpcIixcbiAgICBDTE9TRTogXCJGYWlsZWQgdG8gY29uc3RydWN0ICdDbG9zZUV2ZW50JzpcIlxuICB9XG59O1xuIiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRQcm90b3R5cGUge1xuICAvLyBOb29wc1xuICBzdG9wUHJvcGFnYXRpb24oKSB7fVxuICBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSB7fVxuXG4gIC8vIGlmIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRoZW4gdGhlIHR5cGUgaXMgc2V0IHRvIFwidW5kZWZpbmVkXCIgb25cbiAgLy8gY2hyb21lIGFuZCBzYWZhcmkuXG4gIGluaXRFdmVudCh0eXBlID0gJ3VuZGVmaW5lZCcsIGJ1YmJsZXMgPSBmYWxzZSwgY2FuY2VsYWJsZSA9IGZhbHNlKSB7XG4gICAgdGhpcy50eXBlID0gYCR7dHlwZX1gO1xuICAgIHRoaXMuYnViYmxlcyA9IEJvb2xlYW4oYnViYmxlcyk7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gQm9vbGVhbihjYW5jZWxhYmxlKTtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50IGV4dGVuZHMgRXZlbnRQcm90b3R5cGUge1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBldmVudEluaXRDb25maWcgPSB7fSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5UX0VSUk9SfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBldmVudEluaXRDb25maWcgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVF9FUlJPUn0gcGFyYW1ldGVyIDIgKCdldmVudEluaXREaWN0JykgaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUgfSA9IGV2ZW50SW5pdENvbmZpZztcblxuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLnRpbWVTdGFtcCA9IERhdGUubm93KCk7XG4gICAgdGhpcy50YXJnZXQgPSBudWxsO1xuICAgIHRoaXMuc3JjRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5yZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgdGhpcy5pc1RydXN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmV2ZW50UGhhc2UgPSAwO1xuICAgIHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZSA/IEJvb2xlYW4oY2FuY2VsYWJsZSkgOiBmYWxzZTtcbiAgICB0aGlzLmNhbm5jZWxCdWJibGUgPSBmYWxzZTtcbiAgICB0aGlzLmJ1YmJsZXMgPSBidWJibGVzID8gQm9vbGVhbihidWJibGVzKSA6IGZhbHNlO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnRQcm90b3R5cGUgZnJvbSAnLi9wcm90b3R5cGUnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzc2FnZUV2ZW50IGV4dGVuZHMgRXZlbnRQcm90b3R5cGUge1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBldmVudEluaXRDb25maWcgPSB7fSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULk1FU1NBR0V9IDEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC5gKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50SW5pdENvbmZpZyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULk1FU1NBR0V9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3RgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUsIGRhdGEsIG9yaWdpbiwgbGFzdEV2ZW50SWQsIHBvcnRzIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5uY2VsQnViYmxlID0gZmFsc2U7XG4gICAgdGhpcy5idWJibGVzID0gYnViYmxlcyA/IEJvb2xlYW4oYnViYmxlcykgOiBmYWxzZTtcbiAgICB0aGlzLm9yaWdpbiA9IGAke29yaWdpbn1gO1xuICAgIHRoaXMucG9ydHMgPSB0eXBlb2YgcG9ydHMgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IHBvcnRzO1xuICAgIHRoaXMuZGF0YSA9IHR5cGVvZiBkYXRhID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBkYXRhO1xuICAgIHRoaXMubGFzdEV2ZW50SWQgPSBgJHtsYXN0RXZlbnRJZCB8fCAnJ31gO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnRQcm90b3R5cGUgZnJvbSAnLi9wcm90b3R5cGUnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xvc2VFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5DTE9TRX0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXZlbnRJbml0Q29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlQuQ0xPU0V9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3RgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUsIGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSA9IGV2ZW50SW5pdENvbmZpZztcblxuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLnRpbWVTdGFtcCA9IERhdGUubm93KCk7XG4gICAgdGhpcy50YXJnZXQgPSBudWxsO1xuICAgIHRoaXMuc3JjRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5yZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgdGhpcy5pc1RydXN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmV2ZW50UGhhc2UgPSAwO1xuICAgIHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZSA/IEJvb2xlYW4oY2FuY2VsYWJsZSkgOiBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbEJ1YmJsZSA9IGZhbHNlO1xuICAgIHRoaXMuYnViYmxlcyA9IGJ1YmJsZXMgPyBCb29sZWFuKGJ1YmJsZXMpIDogZmFsc2U7XG4gICAgdGhpcy5jb2RlID0gdHlwZW9mIGNvZGUgPT09ICdudW1iZXInID8gcGFyc2VJbnQoY29kZSwgMTApIDogMDtcbiAgICB0aGlzLnJlYXNvbiA9IGAke3JlYXNvbiB8fCAnJ31gO1xuICAgIHRoaXMud2FzQ2xlYW4gPSB3YXNDbGVhbiA/IEJvb2xlYW4od2FzQ2xlYW4pIDogZmFsc2U7XG4gIH1cbn1cbiIsImltcG9ydCBFdmVudCBmcm9tICcuL2V2ZW50JztcbmltcG9ydCBNZXNzYWdlRXZlbnQgZnJvbSAnLi9tZXNzYWdlJztcbmltcG9ydCBDbG9zZUV2ZW50IGZyb20gJy4vY2xvc2UnO1xuXG4vKlxuKiBDcmVhdGVzIGFuIEV2ZW50IG9iamVjdCBhbmQgZXh0ZW5kcyBpdCB0byBhbGxvdyBmdWxsIG1vZGlmaWNhdGlvbiBvZlxuKiBpdHMgcHJvcGVydGllcy5cbipcbiogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyAtIHdpdGhpbiBjb25maWcgeW91IHdpbGwgbmVlZCB0byBwYXNzIHR5cGUgYW5kIG9wdGlvbmFsbHkgdGFyZ2V0XG4qL1xuZnVuY3Rpb24gY3JlYXRlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgdHlwZSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGNvbnN0IGV2ZW50T2JqZWN0ID0gbmV3IEV2ZW50KHR5cGUpO1xuXG4gIGlmICh0YXJnZXQpIHtcbiAgICBldmVudE9iamVjdC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZXZlbnRPYmplY3Quc3JjRWxlbWVudCA9IHRhcmdldDtcbiAgICBldmVudE9iamVjdC5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIGV2ZW50T2JqZWN0O1xufVxuXG4vKlxuKiBDcmVhdGVzIGEgTWVzc2FnZUV2ZW50IG9iamVjdCBhbmQgZXh0ZW5kcyBpdCB0byBhbGxvdyBmdWxsIG1vZGlmaWNhdGlvbiBvZlxuKiBpdHMgcHJvcGVydGllcy5cbipcbiogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyAtIHdpdGhpbiBjb25maWc6IHR5cGUsIG9yaWdpbiwgZGF0YSBhbmQgb3B0aW9uYWxseSB0YXJnZXRcbiovXG5mdW5jdGlvbiBjcmVhdGVNZXNzYWdlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgdHlwZSwgb3JpZ2luLCBkYXRhLCB0YXJnZXQgfSA9IGNvbmZpZztcbiAgY29uc3QgbWVzc2FnZUV2ZW50ID0gbmV3IE1lc3NhZ2VFdmVudCh0eXBlLCB7XG4gICAgZGF0YSxcbiAgICBvcmlnaW5cbiAgfSk7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIG1lc3NhZ2VFdmVudC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgbWVzc2FnZUV2ZW50LnNyY0VsZW1lbnQgPSB0YXJnZXQ7XG4gICAgbWVzc2FnZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cblxuICByZXR1cm4gbWVzc2FnZUV2ZW50O1xufVxuXG4vKlxuKiBDcmVhdGVzIGEgQ2xvc2VFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnOiB0eXBlIGFuZCBvcHRpb25hbGx5IHRhcmdldCwgY29kZSwgYW5kIHJlYXNvblxuKi9cbmZ1bmN0aW9uIGNyZWF0ZUNsb3NlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgY29kZSwgcmVhc29uLCB0eXBlLCB0YXJnZXQgfSA9IGNvbmZpZztcbiAgbGV0IHsgd2FzQ2xlYW4gfSA9IGNvbmZpZztcblxuICBpZiAoIXdhc0NsZWFuKSB7XG4gICAgd2FzQ2xlYW4gPSBjb2RlID09PSAxMDAwO1xuICB9XG5cbiAgY29uc3QgY2xvc2VFdmVudCA9IG5ldyBDbG9zZUV2ZW50KHR5cGUsIHtcbiAgICBjb2RlLFxuICAgIHJlYXNvbixcbiAgICB3YXNDbGVhblxuICB9KTtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgY2xvc2VFdmVudC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgY2xvc2VFdmVudC5zcmNFbGVtZW50ID0gdGFyZ2V0O1xuICAgIGNsb3NlRXZlbnQuY3VycmVudFRhcmdldCA9IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBjbG9zZUV2ZW50O1xufVxuXG5leHBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH07XG4iLCJpbXBvcnQgV2ViU29ja2V0IGZyb20gJy4uL3dlYnNvY2tldCc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vaGVscGVycy9kZWxheSc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuLi9uZXR3b3JrLWJyaWRnZSc7XG5pbXBvcnQgeyBjcmVhdGVDbG9zZUV2ZW50LCBjcmVhdGVFdmVudCB9IGZyb20gJy4uL2V2ZW50L2ZhY3RvcnknO1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VXZWJTb2NrZXRDb25uZWN0aW9uKGNvbnRleHQsIGNvZGUsIHJlYXNvbikge1xuICBjb250ZXh0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0lORztcblxuICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cChjb250ZXh0LnVybCk7XG4gIGNvbnN0IGNsb3NlRXZlbnQgPSBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICB0eXBlOiAnY2xvc2UnLFxuICAgIHRhcmdldDogY29udGV4dCxcbiAgICBjb2RlLFxuICAgIHJlYXNvblxuICB9KTtcblxuICBkZWxheSgoKSA9PiB7XG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVXZWJTb2NrZXQoY29udGV4dCwgY29udGV4dC51cmwpO1xuXG4gICAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFRDtcbiAgICBjb250ZXh0LmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50LCBzZXJ2ZXIpO1xuICAgIH1cbiAgfSwgY29udGV4dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmYWlsV2ViU29ja2V0Q29ubmVjdGlvbihjb250ZXh0LCBjb2RlLCByZWFzb24pIHtcbiAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NJTkc7XG5cbiAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAoY29udGV4dC51cmwpO1xuICBjb25zdCBjbG9zZUV2ZW50ID0gY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgdHlwZTogJ2Nsb3NlJyxcbiAgICB0YXJnZXQ6IGNvbnRleHQsXG4gICAgY29kZSxcbiAgICByZWFzb24sXG4gICAgd2FzQ2xlYW46IGZhbHNlXG4gIH0pO1xuXG4gIGNvbnN0IGVycm9yRXZlbnQgPSBjcmVhdGVFdmVudCh7XG4gICAgdHlwZTogJ2Vycm9yJyxcbiAgICB0YXJnZXQ6IGNvbnRleHRcbiAgfSk7XG5cbiAgZGVsYXkoKCkgPT4ge1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KGNvbnRleHQsIGNvbnRleHQudXJsKTtcblxuICAgIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgY29udGV4dC5kaXNwYXRjaEV2ZW50KGVycm9yRXZlbnQpO1xuICAgIGNvbnRleHQuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50KTtcblxuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNsb3NlRXZlbnQsIHNlcnZlcik7XG4gICAgfVxuICB9LCBjb250ZXh0KTtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpIHtcbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkYXRhKSAhPT0gJ1tvYmplY3QgQmxvYl0nICYmICEoZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIGRhdGEgPSBTdHJpbmcoZGF0YSk7XG4gIH1cblxuICByZXR1cm4gZGF0YTtcbn1cbiIsImltcG9ydCB7IENMT1NFX0NPREVTIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2FsZ29yaXRobXMvY2xvc2UnO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vbm9ybWFsaXplLXNlbmQnO1xuaW1wb3J0IHsgY3JlYXRlTWVzc2FnZUV2ZW50IH0gZnJvbSAnLi4vZXZlbnQvZmFjdG9yeSc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHByb3h5RmFjdG9yeSh0YXJnZXQpIHtcbiAgY29uc3QgaGFuZGxlciA9IHtcbiAgICBnZXQob2JqLCBwcm9wKSB7XG4gICAgICBpZiAocHJvcCA9PT0gJ2Nsb3NlJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2xvc2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgY29uc3QgY29kZSA9IG9wdGlvbnMuY29kZSB8fCBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUw7XG4gICAgICAgICAgY29uc3QgcmVhc29uID0gb3B0aW9ucy5yZWFzb24gfHwgJyc7XG5cbiAgICAgICAgICBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24odGFyZ2V0LCBjb2RlLCByZWFzb24pO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcCA9PT0gJ3NlbmQnKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBzZW5kKGRhdGEpIHtcbiAgICAgICAgICBkYXRhID0gbm9ybWFsaXplU2VuZERhdGEoZGF0YSk7XG5cbiAgICAgICAgICB0YXJnZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgIGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICAgICAgICAgIHR5cGU6ICdtZXNzYWdlJyxcbiAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgICAgdGFyZ2V0XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wID09PSAnb24nKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBvbldyYXBwZXIodHlwZSwgY2IpIHtcbiAgICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihgc2VydmVyOjoke3R5cGV9YCwgY2IpO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JqW3Byb3BdO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0YXJnZXQsIGhhbmRsZXIpO1xuICByZXR1cm4gcHJveHk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBsZW5ndGhJblV0ZjhCeXRlcyhzdHIpIHtcbiAgLy8gTWF0Y2hlcyBvbmx5IHRoZSAxMC4uIGJ5dGVzIHRoYXQgYXJlIG5vbi1pbml0aWFsIGNoYXJhY3RlcnMgaW4gYSBtdWx0aS1ieXRlIHNlcXVlbmNlLlxuICBjb25zdCBtID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0cikubWF0Y2goLyVbODlBQmFiXS9nKTtcbiAgcmV0dXJuIHN0ci5sZW5ndGggKyAobSA/IG0ubGVuZ3RoIDogMCk7XG59XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgeyBFUlJPUl9QUkVGSVggfSBmcm9tICcuLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1cmxWZXJpZmljYXRpb24odXJsKSB7XG4gIGNvbnN0IHVybFJlY29yZCA9IG5ldyBVUkwodXJsKTtcbiAgY29uc3QgeyBwYXRobmFtZSwgcHJvdG9jb2wsIGhhc2ggfSA9IHVybFJlY29yZDtcblxuICBpZiAoIXVybCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gIH1cblxuICBpZiAoIXBhdGhuYW1lKSB7XG4gICAgdXJsUmVjb3JkLnBhdGhuYW1lID0gJy8nO1xuICB9XG5cbiAgaWYgKHByb3RvY29sID09PSAnJykge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1J9IFRoZSBVUkwgJyR7dXJsUmVjb3JkLnRvU3RyaW5nKCl9JyBpcyBpbnZhbGlkLmApO1xuICB9XG5cbiAgaWYgKHByb3RvY29sICE9PSAnd3M6JyAmJiBwcm90b2NvbCAhPT0gJ3dzczonKSB7XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgVVJMJ3Mgc2NoZW1lIG11c3QgYmUgZWl0aGVyICd3cycgb3IgJ3dzcycuICcke3Byb3RvY29sfScgaXMgbm90IGFsbG93ZWQuYFxuICAgICk7XG4gIH1cblxuICBpZiAoaGFzaCAhPT0gJycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgYCR7XG4gICAgICAgIEVSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUlxuICAgICAgfSBUaGUgVVJMIGNvbnRhaW5zIGEgZnJhZ21lbnQgaWRlbnRpZmllciAoJyR7aGFzaH0nKS4gRnJhZ21lbnQgaWRlbnRpZmllcnMgYXJlIG5vdCBhbGxvd2VkIGluIFdlYlNvY2tldCBVUkxzLmBcbiAgICApO1xuICAgIC8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuICB9XG5cbiAgcmV0dXJuIHVybFJlY29yZC50b1N0cmluZygpO1xufVxuIiwiaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcHJvdG9jb2xWZXJpZmljYXRpb24ocHJvdG9jb2xzID0gW10pIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHByb3RvY29scykgJiYgdHlwZW9mIHByb3RvY29scyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgc3VicHJvdG9jb2wgJyR7cHJvdG9jb2xzLnRvU3RyaW5nKCl9JyBpcyBpbnZhbGlkLmApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwcm90b2NvbHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcHJvdG9jb2xzID0gW3Byb3RvY29sc107XG4gIH1cblxuICBjb25zdCB1bmlxID0gcHJvdG9jb2xzLm1hcChwID0+ICh7IGNvdW50OiAxLCBwcm90b2NvbDogcCB9KSkucmVkdWNlKChhLCBiKSA9PiB7XG4gICAgYVtiLnByb3RvY29sXSA9IChhW2IucHJvdG9jb2xdIHx8IDApICsgYi5jb3VudDtcbiAgICByZXR1cm4gYTtcbiAgfSwge30pO1xuXG4gIGNvbnN0IGR1cGxpY2F0ZXMgPSBPYmplY3Qua2V5cyh1bmlxKS5maWx0ZXIoYSA9PiB1bmlxW2FdID4gMSk7XG5cbiAgaWYgKGR1cGxpY2F0ZXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1J9IFRoZSBzdWJwcm90b2NvbCAnJHtkdXBsaWNhdGVzWzBdfScgaXMgZHVwbGljYXRlZC5gKTtcbiAgfVxuXG4gIHJldHVybiBwcm90b2NvbHM7XG59XG4iLCJpbXBvcnQgZGVsYXkgZnJvbSAnLi9oZWxwZXJzL2RlbGF5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi9oZWxwZXJzL2xvZ2dlcic7XG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudC90YXJnZXQnO1xuaW1wb3J0IG5ldHdvcmtCcmlkZ2UgZnJvbSAnLi9uZXR3b3JrLWJyaWRnZSc7XG5pbXBvcnQgcHJveHlGYWN0b3J5IGZyb20gJy4vaGVscGVycy9wcm94eS1mYWN0b3J5JztcbmltcG9ydCBsZW5ndGhJblV0ZjhCeXRlcyBmcm9tICcuL2hlbHBlcnMvYnl0ZS1sZW5ndGgnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMsIEVSUk9SX1BSRUZJWCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB1cmxWZXJpZmljYXRpb24gZnJvbSAnLi9oZWxwZXJzL3VybC12ZXJpZmljYXRpb24nO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vaGVscGVycy9ub3JtYWxpemUtc2VuZCc7XG5pbXBvcnQgcHJvdG9jb2xWZXJpZmljYXRpb24gZnJvbSAnLi9oZWxwZXJzL3Byb3RvY29sLXZlcmlmaWNhdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH0gZnJvbSAnLi9ldmVudC9mYWN0b3J5JztcbmltcG9ydCB7IGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbiwgZmFpbFdlYlNvY2tldENvbm5lY3Rpb24gfSBmcm9tICcuL2FsZ29yaXRobXMvY2xvc2UnO1xuXG4vKlxuICogVGhlIG1haW4gd2Vic29ja2V0IGNsYXNzIHdoaWNoIGlzIGRlc2lnbmVkIHRvIG1pbWljayB0aGUgbmF0aXZlIFdlYlNvY2tldCBjbGFzcyBhcyBjbG9zZVxuICogYXMgcG9zc2libGUuXG4gKlxuICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViLXNvY2tldHMuaHRtbFxuICovXG5jbGFzcyBXZWJTb2NrZXQgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgcHJvdG9jb2xzKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMudXJsID0gdXJsVmVyaWZpY2F0aW9uKHVybCk7XG4gICAgcHJvdG9jb2xzID0gcHJvdG9jb2xWZXJpZmljYXRpb24ocHJvdG9jb2xzKTtcbiAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2xzWzBdIHx8ICcnO1xuXG4gICAgdGhpcy5iaW5hcnlUeXBlID0gJ2Jsb2InO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DT05ORUNUSU5HO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuXG4gICAgLypcbiAgICAgKiBUaGlzIGRlbGF5IGlzIG5lZWRlZCBzbyB0aGF0IHdlIGRvbnQgdHJpZ2dlciBhbiBldmVudCBiZWZvcmUgdGhlIGNhbGxiYWNrcyBoYXZlIGJlZW5cbiAgICAgKiBzZXR1cC4gRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiB2YXIgc29ja2V0ID0gbmV3IFdlYlNvY2tldCgnd3M6Ly9sb2NhbGhvc3QnKTtcbiAgICAgKlxuICAgICAqIElmIHdlIGRvbnQgaGF2ZSB0aGUgZGVsYXkgdGhlbiB0aGUgZXZlbnQgd291bGQgYmUgdHJpZ2dlcmVkIHJpZ2h0IGhlcmUgYW5kIHRoaXMgaXNcbiAgICAgKiBiZWZvcmUgdGhlIG9ub3BlbiBoYWQgYSBjaGFuY2UgdG8gcmVnaXN0ZXIgaXRzZWxmLlxuICAgICAqXG4gICAgICogc29ja2V0Lm9ub3BlbiA9ICgpID0+IHsgLy8gdGhpcyB3b3VsZCBuZXZlciBiZSBjYWxsZWQgfTtcbiAgICAgKlxuICAgICAqIGFuZCB3aXRoIHRoZSBkZWxheSB0aGUgZXZlbnQgZ2V0cyB0cmlnZ2VyZWQgaGVyZSBhZnRlciBhbGwgb2YgdGhlIGNhbGxiYWNrcyBoYXZlIGJlZW5cbiAgICAgKiByZWdpc3RlcmVkIDotKVxuICAgICAqL1xuICAgIGRlbGF5KGZ1bmN0aW9uIGRlbGF5Q2FsbGJhY2soKSB7XG4gICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZXJ2ZXIub3B0aW9ucy52ZXJpZnlDbGllbnQgJiZcbiAgICAgICAgICB0eXBlb2Ygc2VydmVyLm9wdGlvbnMudmVyaWZ5Q2xpZW50ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgIXNlcnZlci5vcHRpb25zLnZlcmlmeUNsaWVudCgpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbiAgICAgICAgICBsb2dnZXIoXG4gICAgICAgICAgICAnZXJyb3InLFxuICAgICAgICAgICAgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkOiBIVFRQIEF1dGhlbnRpY2F0aW9uIGZhaWxlZDsgbm8gdmFsaWQgY3JlZGVudGlhbHMgYXZhaWxhYmxlYFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScsIHRhcmdldDogdGhpcywgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMIH0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoc2VydmVyLm9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgJiYgdHlwZW9mIHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZFByb3RvY29sID0gc2VydmVyLm9wdGlvbnMuc2VsZWN0UHJvdG9jb2wocHJvdG9jb2xzKTtcbiAgICAgICAgICAgIGNvbnN0IGlzRmlsbGVkID0gc2VsZWN0ZWRQcm90b2NvbCAhPT0gJyc7XG4gICAgICAgICAgICBjb25zdCBpc1JlcXVlc3RlZCA9IHByb3RvY29scy5pbmRleE9mKHNlbGVjdGVkUHJvdG9jb2wpICE9PSAtMTtcbiAgICAgICAgICAgIGlmIChpc0ZpbGxlZCAmJiAhaXNSZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFRDtcblxuICAgICAgICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkOiBJbnZhbGlkIFN1Yi1Qcm90b2NvbGApO1xuXG4gICAgICAgICAgICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcbiAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUNsb3NlRXZlbnQoeyB0eXBlOiAnY2xvc2UnLCB0YXJnZXQ6IHRoaXMsIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCB9KSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucHJvdG9jb2wgPSBzZWxlY3RlZFByb3RvY29sO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuT1BFTjtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnb3BlbicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnY29ubmVjdGlvbicgfSksIHByb3h5RmFjdG9yeSh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJywgdGFyZ2V0OiB0aGlzLCBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwgfSkpO1xuXG4gICAgICAgIGxvZ2dlcignZXJyb3InLCBgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gJyR7dGhpcy51cmx9JyBmYWlsZWRgKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgfVxuXG4gIGdldCBvbm9wZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLm9wZW47XG4gIH1cblxuICBnZXQgb25tZXNzYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5tZXNzYWdlO1xuICB9XG5cbiAgZ2V0IG9uY2xvc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLmNsb3NlO1xuICB9XG5cbiAgZ2V0IG9uZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLmVycm9yO1xuICB9XG5cbiAgc2V0IG9ub3BlbihsaXN0ZW5lcikge1xuICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVycy5vcGVuO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNldCBvbm1lc3NhZ2UobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMubWVzc2FnZTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZXQgb25jbG9zZShsaXN0ZW5lcikge1xuICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVycy5jbG9zZTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgbGlzdGVuZXIpO1xuICB9XG5cbiAgc2V0IG9uZXJyb3IobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMuZXJyb3I7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNlbmQoZGF0YSkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TSU5HIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJTb2NrZXQgaXMgYWxyZWFkeSBpbiBDTE9TSU5HIG9yIENMT1NFRCBzdGF0ZScpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGhhbmRsZSBidWZmZXJlZEFtb3VudFxuXG4gICAgY29uc3QgbWVzc2FnZUV2ZW50ID0gY3JlYXRlTWVzc2FnZUV2ZW50KHtcbiAgICAgIHR5cGU6ICdzZXJ2ZXI6Om1lc3NhZ2UnLFxuICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgIGRhdGE6IG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBkZWxheSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChtZXNzYWdlRXZlbnQsIGRhdGEpO1xuICAgICAgfSwgc2VydmVyKTtcbiAgICB9XG4gIH1cblxuICBjbG9zZShjb2RlLCByZWFzb24pIHtcbiAgICBpZiAoY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvZGUgIT09ICdudW1iZXInIHx8IChjb2RlICE9PSAxMDAwICYmIChjb2RlIDwgMzAwMCB8fCBjb2RlID4gNDk5OSkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgYCR7RVJST1JfUFJFRklYLkNMT1NFX0VSUk9SfSBUaGUgY29kZSBtdXN0IGJlIGVpdGhlciAxMDAwLCBvciBiZXR3ZWVuIDMwMDAgYW5kIDQ5OTkuICR7Y29kZX0gaXMgbmVpdGhlci5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlYXNvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBsZW5ndGhJblV0ZjhCeXRlcyhyZWFzb24pO1xuXG4gICAgICBpZiAobGVuZ3RoID4gMTIzKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ0xPU0VfRVJST1J9IFRoZSBtZXNzYWdlIG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiAxMjMgYnl0ZXMuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NJTkcgfHwgdGhpcy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ0xPU0VEKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNPTk5FQ1RJTkcpIHtcbiAgICAgIGZhaWxXZWJTb2NrZXRDb25uZWN0aW9uKHRoaXMsIGNvZGUsIHJlYXNvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbih0aGlzLCBjb2RlLCByZWFzb24pO1xuICAgIH1cbiAgfVxufVxuXG5XZWJTb2NrZXQuQ09OTkVDVElORyA9IDA7XG5XZWJTb2NrZXQucHJvdG90eXBlLkNPTk5FQ1RJTkcgPSBXZWJTb2NrZXQuQ09OTkVDVElORztcbldlYlNvY2tldC5PUEVOID0gMTtcbldlYlNvY2tldC5wcm90b3R5cGUuT1BFTiA9IFdlYlNvY2tldC5PUEVOO1xuV2ViU29ja2V0LkNMT1NJTkcgPSAyO1xuV2ViU29ja2V0LnByb3RvdHlwZS5DTE9TSU5HID0gV2ViU29ja2V0LkNMT1NJTkc7XG5XZWJTb2NrZXQuQ0xPU0VEID0gMztcbldlYlNvY2tldC5wcm90b3R5cGUuQ0xPU0VEID0gV2ViU29ja2V0LkNMT1NFRDtcblxuZXhwb3J0IGRlZmF1bHQgV2ViU29ja2V0O1xuIiwiZXhwb3J0IGRlZmF1bHQgYXJyID0+XG4gIGFyci5yZWR1Y2UoKGRlZHVwZWQsIGIpID0+IHtcbiAgICBpZiAoZGVkdXBlZC5pbmRleE9mKGIpID4gLTEpIHJldHVybiBkZWR1cGVkO1xuICAgIHJldHVybiBkZWR1cGVkLmNvbmNhdChiKTtcbiAgfSwgW10pO1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmV0cmlldmVHbG9iYWxPYmplY3QoKSB7XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnICYmIHR5cGVvZiByZXF1aXJlID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBnbG9iYWwgPT09ICdvYmplY3QnID8gZ2xvYmFsIDogdGhpcztcbn1cbiIsImltcG9ydCBVUkwgZnJvbSAndXJsLXBhcnNlJztcbmltcG9ydCBXZWJTb2NrZXQgZnJvbSAnLi93ZWJzb2NrZXQnO1xuaW1wb3J0IGRlZHVwZSBmcm9tICcuL2hlbHBlcnMvZGVkdXBlJztcbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50L3RhcmdldCc7XG5pbXBvcnQgeyBDTE9TRV9DT0RFUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IGdsb2JhbE9iamVjdCBmcm9tICcuL2hlbHBlcnMvZ2xvYmFsLW9iamVjdCc7XG5pbXBvcnQgbm9ybWFsaXplU2VuZERhdGEgZnJvbSAnLi9oZWxwZXJzL25vcm1hbGl6ZS1zZW5kJztcbmltcG9ydCB7IGNyZWF0ZUV2ZW50LCBjcmVhdGVNZXNzYWdlRXZlbnQsIGNyZWF0ZUNsb3NlRXZlbnQgfSBmcm9tICcuL2V2ZW50L2ZhY3RvcnknO1xuXG5jbGFzcyBTZXJ2ZXIgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcbiAgICBjb25zdCB1cmxSZWNvcmQgPSBuZXcgVVJMKHVybCk7XG5cbiAgICBpZiAoIXVybFJlY29yZC5wYXRobmFtZSkge1xuICAgICAgdXJsUmVjb3JkLnBhdGhuYW1lID0gJy8nO1xuICAgIH1cblxuICAgIHRoaXMudXJsID0gdXJsUmVjb3JkLnRvU3RyaW5nKCk7XG5cbiAgICB0aGlzLm9yaWdpbmFsV2ViU29ja2V0ID0gbnVsbDtcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLmF0dGFjaFNlcnZlcih0aGlzLCB0aGlzLnVybCk7XG5cbiAgICBpZiAoIXNlcnZlcikge1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJyB9KSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbW9jayBzZXJ2ZXIgaXMgYWxyZWFkeSBsaXN0ZW5pbmcgb24gdGhpcyB1cmwnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudmVyaWZ5Q2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb3B0aW9ucy52ZXJpZnlDbGllbnQgPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5zZWxlY3RQcm90b2NvbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5zdGFydCgpO1xuICB9XG5cbiAgLypcbiAgICogQXR0YWNoZXMgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCB0byB0aGUgZ2xvYmFsIG9iamVjdFxuICAgKi9cbiAgc3RhcnQoKSB7XG4gICAgY29uc3QgZ2xvYmFsT2JqID0gZ2xvYmFsT2JqZWN0KCk7XG5cbiAgICBpZiAoZ2xvYmFsT2JqLldlYlNvY2tldCkge1xuICAgICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IGdsb2JhbE9iai5XZWJTb2NrZXQ7XG4gICAgfVxuXG4gICAgZ2xvYmFsT2JqLldlYlNvY2tldCA9IFdlYlNvY2tldDtcbiAgfVxuXG4gIC8qXG4gICAqIFJlbW92ZXMgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCBmcm9tIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAqL1xuICBzdG9wKGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBjb25zdCBnbG9iYWxPYmogPSBnbG9iYWxPYmplY3QoKTtcblxuICAgIGlmICh0aGlzLm9yaWdpbmFsV2ViU29ja2V0KSB7XG4gICAgICBnbG9iYWxPYmouV2ViU29ja2V0ID0gdGhpcy5vcmlnaW5hbFdlYlNvY2tldDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIGdsb2JhbE9iai5XZWJTb2NrZXQ7XG4gICAgfVxuXG4gICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IG51bGw7XG5cbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVNlcnZlcih0aGlzLnVybCk7XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gZm9yIHRoZSBtb2NrIHNlcnZlciB0byBzdWJzY3JpYmUgdG8gdGhlIG9uIGV2ZW50cy5cbiAgICpcbiAgICogaWU6IG1vY2tTZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2EgbW9jayBjbGllbnQgY29ubmVjdGVkJyk7IH0pO1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSBldmVudCBrZXkgdG8gc3Vic2NyaWJlIHRvLiBWYWxpZCBrZXlzIGFyZTogY29ubmVjdGlvbiwgbWVzc2FnZSwgYW5kIGNsb3NlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayB3aGljaCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYSBjZXJ0YWluIGV2ZW50IGlzIGZpcmVkLlxuICAgKi9cbiAgb24odHlwZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICB9XG5cbiAgLypcbiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIGFuZCB0cmlnZ2VycyB0aGUgb25jbG9zZSBtZXRob2Qgb2YgYWxsIGxpc3RlbmluZ1xuICAgKiB3ZWJzb2NrZXRzLiBBZnRlciB0aGF0IGl0IHJlbW92ZXMgaXRzZWxmIGZyb20gdGhlIHVybE1hcCBzbyBhbm90aGVyIHNlcnZlclxuICAgKiBjb3VsZCBhZGQgaXRzZWxmIHRvIHRoZSB1cmwuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBjbG9zZShvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7IGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHRoaXMudXJsKTtcblxuICAgIC8vIFJlbW92ZSBzZXJ2ZXIgYmVmb3JlIG5vdGlmaWNhdGlvbnMgdG8gcHJldmVudCBpbW1lZGlhdGUgcmVjb25uZWN0cyBmcm9tXG4gICAgLy8gc29ja2V0IG9uY2xvc2UgaGFuZGxlcnNcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVNlcnZlcih0aGlzLnVybCk7XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChzb2NrZXQgPT4ge1xuICAgICAgc29ja2V0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0U7XG4gICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgICB0YXJnZXQ6IHNvY2tldCxcbiAgICAgICAgICBjb2RlOiBjb2RlIHx8IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCxcbiAgICAgICAgICByZWFzb246IHJlYXNvbiB8fCAnJyxcbiAgICAgICAgICB3YXNDbGVhblxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJyB9KSwgdGhpcyk7XG4gIH1cblxuICAvKlxuICAgKiBTZW5kcyBhIGdlbmVyaWMgbWVzc2FnZSBldmVudCB0byBhbGwgbW9jayBjbGllbnRzLlxuICAgKi9cbiAgZW1pdChldmVudCwgZGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgbGV0IHsgd2Vic29ja2V0cyB9ID0gb3B0aW9ucztcblxuICAgIGlmICghd2Vic29ja2V0cykge1xuICAgICAgd2Vic29ja2V0cyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JyB8fCBhcmd1bWVudHMubGVuZ3RoID4gMykge1xuICAgICAgZGF0YSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSwgYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICBkYXRhID0gZGF0YS5tYXAoaXRlbSA9PiBub3JtYWxpemVTZW5kRGF0YShpdGVtKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEgPSBub3JtYWxpemVTZW5kRGF0YShkYXRhKTtcbiAgICB9XG5cbiAgICB3ZWJzb2NrZXRzLmZvckVhY2goc29ja2V0ID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgIHNvY2tldC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICAgICAgICB0eXBlOiBldmVudCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBvcmlnaW46IHRoaXMudXJsLFxuICAgICAgICAgICAgdGFyZ2V0OiBzb2NrZXRcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5kYXRhXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogZXZlbnQsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHRhcmdldDogc29ja2V0XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qXG4gICAqIFJldHVybnMgYW4gYXJyYXkgb2Ygd2Vic29ja2V0cyB3aGljaCBhcmUgbGlzdGVuaW5nIHRvIHRoaXMgc2VydmVyXG4gICAqIFRPT0Q6IHRoaXMgc2hvdWxkIHJldHVybiBhIHNldCBhbmQgbm90IGJlIGEgbWV0aG9kXG4gICAqL1xuICBjbGllbnRzKCkge1xuICAgIHJldHVybiBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuICB9XG5cbiAgLypcbiAgICogUHJlcGFyZXMgYSBtZXRob2QgdG8gc3VibWl0IGFuIGV2ZW50IHRvIG1lbWJlcnMgb2YgdGhlIHJvb21cbiAgICpcbiAgICogZS5nLiBzZXJ2ZXIudG8oJ215LXJvb20nKS5lbWl0KCdoaSEnKTtcbiAgICovXG4gIHRvKHJvb20sIGJyb2FkY2FzdGVyLCBicm9hZGNhc3RMaXN0ID0gW10pIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCB3ZWJzb2NrZXRzID0gZGVkdXBlKGJyb2FkY2FzdExpc3QuY29uY2F0KG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCwgcm9vbSwgYnJvYWRjYXN0ZXIpKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG86IChjaGFpbmVkUm9vbSwgY2hhaW5lZEJyb2FkY2FzdGVyKSA9PiB0aGlzLnRvLmNhbGwodGhpcywgY2hhaW5lZFJvb20sIGNoYWluZWRCcm9hZGNhc3Rlciwgd2Vic29ja2V0cyksXG4gICAgICBlbWl0KGV2ZW50LCBkYXRhKSB7XG4gICAgICAgIHNlbGYuZW1pdChldmVudCwgZGF0YSwgeyB3ZWJzb2NrZXRzIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAgKiBBbGlhcyBmb3IgU2VydmVyLnRvXG4gICAqL1xuICBpbiguLi5hcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMudG8uYXBwbHkobnVsbCwgYXJncyk7XG4gIH1cblxuICAvKlxuICAgKiBTaW11bGF0ZSBhbiBldmVudCBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNsaWVudHMuIFVzZWZ1bCBmb3JcbiAgICogc2ltdWxhdGluZyBlcnJvcnMuXG4gICAqL1xuICBzaW11bGF0ZShldmVudCkge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoZXZlbnQgPT09ICdlcnJvcicpIHtcbiAgICAgIGxpc3RlbmVycy5mb3JFYWNoKHNvY2tldCA9PiB7XG4gICAgICAgIHNvY2tldC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFO1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicgfSkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBBbHRlcm5hdGl2ZSBjb25zdHJ1Y3RvciB0byBzdXBwb3J0IG5hbWVzcGFjZXMgaW4gc29ja2V0LmlvXG4gKlxuICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNjdXN0b20tbmFtZXNwYWNlc1xuICovXG5TZXJ2ZXIub2YgPSBmdW5jdGlvbiBvZih1cmwpIHtcbiAgcmV0dXJuIG5ldyBTZXJ2ZXIodXJsKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNlcnZlcjtcbiIsImltcG9ydCBVUkwgZnJvbSAndXJsLXBhcnNlJztcbmltcG9ydCBkZWxheSBmcm9tICcuL2hlbHBlcnMvZGVsYXknO1xuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4vZXZlbnQvdGFyZ2V0JztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vaGVscGVycy9sb2dnZXInO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9IGZyb20gJy4vZXZlbnQvZmFjdG9yeSc7XG5cbi8qXG4qIFRoZSBzb2NrZXQtaW8gY2xhc3MgaXMgZGVzaWduZWQgdG8gbWltaWNrIHRoZSByZWFsIEFQSSBhcyBjbG9zZWx5IGFzIHBvc3NpYmxlLlxuKlxuKiBodHRwOi8vc29ja2V0LmlvL2RvY3MvXG4qL1xuY2xhc3MgU29ja2V0SU8gZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIC8qXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICBjb25zdHJ1Y3Rvcih1cmwgPSAnc29ja2V0LmlvJywgcHJvdG9jb2wgPSAnJykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmJpbmFyeVR5cGUgPSAnYmxvYic7XG4gICAgY29uc3QgdXJsUmVjb3JkID0gbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKCF1cmxSZWNvcmQucGF0aG5hbWUpIHtcbiAgICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICB0aGlzLnVybCA9IHVybFJlY29yZC50b1N0cmluZygpO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNPTk5FQ1RJTkc7XG4gICAgdGhpcy5wcm90b2NvbCA9ICcnO1xuXG4gICAgaWYgKHR5cGVvZiBwcm90b2NvbCA9PT0gJ3N0cmluZycgfHwgKHR5cGVvZiBwcm90b2NvbCA9PT0gJ29iamVjdCcgJiYgcHJvdG9jb2wgIT09IG51bGwpKSB7XG4gICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHByb3RvY29sKSAmJiBwcm90b2NvbC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2xbMF07XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuXG4gICAgLypcbiAgICAqIERlbGF5IHRyaWdnZXJpbmcgdGhlIGNvbm5lY3Rpb24gZXZlbnRzIHNvIHRoZXkgY2FuIGJlIGRlZmluZWQgaW4gdGltZS5cbiAgICAqL1xuICAgIGRlbGF5KGZ1bmN0aW9uIGRlbGF5Q2FsbGJhY2soKSB7XG4gICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLk9QRU47XG4gICAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3Rpb24nIH0pLCBzZXJ2ZXIsIHRoaXMpO1xuICAgICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0JyB9KSwgc2VydmVyLCB0aGlzKTsgLy8gYWxpYXNcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3QnLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gU29ja2V0SU8uQ0xPU0VEO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgICB0eXBlOiAnY2xvc2UnLFxuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICAgICAgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFNvY2tldC5pbyBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkYCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG5cbiAgICAvKipcbiAgICAgIEFkZCBhbiBhbGlhc2VkIGV2ZW50IGxpc3RlbmVyIGZvciBjbG9zZSAvIGRpc2Nvbm5lY3RcbiAgICAgKi9cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgZXZlbnQgPT4ge1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiAnZGlzY29ubmVjdCcsXG4gICAgICAgICAgdGFyZ2V0OiBldmVudC50YXJnZXQsXG4gICAgICAgICAgY29kZTogZXZlbnQuY29kZVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qXG4gICogQ2xvc2VzIHRoZSBTb2NrZXRJTyBjb25uZWN0aW9uIG9yIGNvbm5lY3Rpb24gYXR0ZW1wdCwgaWYgYW55LlxuICAqIElmIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgQ0xPU0VELCB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuXG4gICovXG4gIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgIT09IFNvY2tldElPLk9QRU4pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNMT1NFRDtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoXG4gICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiAnZGlzY29ubmVjdCcsXG4gICAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICAgIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTFxuICAgICAgICB9KSxcbiAgICAgICAgc2VydmVyXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBBbGlhcyBmb3IgU29ja2V0I2Nsb3NlXG4gICpcbiAgKiBodHRwczovL2dpdGh1Yi5jb20vc29ja2V0aW8vc29ja2V0LmlvLWNsaWVudC9ibG9iL21hc3Rlci9saWIvc29ja2V0LmpzI0wzODNcbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgLypcbiAgKiBTdWJtaXRzIGFuIGV2ZW50IHRvIHRoZSBzZXJ2ZXIgd2l0aCBhIHBheWxvYWRcbiAgKi9cbiAgZW1pdChldmVudCwgLi4uZGF0YSkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgIT09IFNvY2tldElPLk9QRU4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU29ja2V0SU8gaXMgYWxyZWFkeSBpbiBDTE9TSU5HIG9yIENMT1NFRCBzdGF0ZScpO1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2VFdmVudCA9IGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICB0eXBlOiBldmVudCxcbiAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICBkYXRhXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChtZXNzYWdlRXZlbnQsIC4uLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBTdWJtaXRzIGEgJ21lc3NhZ2UnIGV2ZW50IHRvIHRoZSBzZXJ2ZXIuXG4gICpcbiAgKiBTaG91bGQgYmVoYXZlIGV4YWN0bHkgbGlrZSBXZWJTb2NrZXQjc2VuZFxuICAqXG4gICogaHR0cHM6Ly9naXRodWIuY29tL3NvY2tldGlvL3NvY2tldC5pby1jbGllbnQvYmxvYi9tYXN0ZXIvbGliL3NvY2tldC5qcyNMMTEzXG4gICovXG4gIHNlbmQoZGF0YSkge1xuICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGRhdGEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBGb3IgYnJvYWRjYXN0aW5nIGV2ZW50cyB0byBvdGhlciBjb25uZWN0ZWQgc29ja2V0cy5cbiAgKlxuICAqIGUuZy4gc29ja2V0LmJyb2FkY2FzdC5lbWl0KCdoaSEnKTtcbiAgKiBlLmcuIHNvY2tldC5icm9hZGNhc3QudG8oJ215LXJvb20nKS5lbWl0KCdoaSEnKTtcbiAgKi9cbiAgZ2V0IGJyb2FkY2FzdCgpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvY2tldElPIGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG4gICAgaWYgKCFzZXJ2ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU29ja2V0SU8gY2FuIG5vdCBmaW5kIGEgc2VydmVyIGF0IHRoZSBzcGVjaWZpZWQgVVJMICgke3RoaXMudXJsfSlgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZW1pdChldmVudCwgZGF0YSkge1xuICAgICAgICBzZXJ2ZXIuZW1pdChldmVudCwgZGF0YSwgeyB3ZWJzb2NrZXRzOiBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAoc2VsZi51cmwsIG51bGwsIHNlbGYpIH0pO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICAgIH0sXG4gICAgICB0byhyb29tKSB7XG4gICAgICAgIHJldHVybiBzZXJ2ZXIudG8ocm9vbSwgc2VsZik7XG4gICAgICB9LFxuICAgICAgaW4ocm9vbSkge1xuICAgICAgICByZXR1cm4gc2VydmVyLmluKHJvb20sIHNlbGYpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAqIEZvciByZWdpc3RlcmluZyBldmVudHMgdG8gYmUgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyXG4gICovXG4gIG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICAqIFJlbW92ZSBldmVudCBsaXN0ZW5lclxuICAgKlxuICAgKiBodHRwczovL3NvY2tldC5pby9kb2NzL2NsaWVudC1hcGkvI3NvY2tldC1vbi1ldmVudG5hbWUtY2FsbGJhY2tcbiAgICovXG4gIG9mZih0eXBlKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUpO1xuICB9XG5cbiAgLypcbiAgICogSm9pbiBhIHJvb20gb24gYSBzZXJ2ZXJcbiAgICpcbiAgICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNqb2luaW5nLWFuZC1sZWF2aW5nXG4gICAqL1xuICBqb2luKHJvb20pIHtcbiAgICBuZXR3b3JrQnJpZGdlLmFkZE1lbWJlcnNoaXBUb1Jvb20odGhpcywgcm9vbSk7XG4gIH1cblxuICAvKlxuICAgKiBHZXQgdGhlIHdlYnNvY2tldCB0byBsZWF2ZSB0aGUgcm9vbVxuICAgKlxuICAgKiBodHRwOi8vc29ja2V0LmlvL2RvY3Mvcm9vbXMtYW5kLW5hbWVzcGFjZXMvI2pvaW5pbmctYW5kLWxlYXZpbmdcbiAgICovXG4gIGxlYXZlKHJvb20pIHtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZU1lbWJlcnNoaXBGcm9tUm9vbSh0aGlzLCByb29tKTtcbiAgfVxuXG4gIHRvKHJvb20pIHtcbiAgICByZXR1cm4gdGhpcy5icm9hZGNhc3QudG8ocm9vbSk7XG4gIH1cblxuICBpbigpIHtcbiAgICByZXR1cm4gdGhpcy50by5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLypcbiAgICogSW52b2tlcyBhbGwgbGlzdGVuZXIgZnVuY3Rpb25zIHRoYXQgYXJlIGxpc3RlbmluZyB0byB0aGUgZ2l2ZW4gZXZlbnQudHlwZSBwcm9wZXJ0eS4gRWFjaFxuICAgKiBsaXN0ZW5lciB3aWxsIGJlIHBhc3NlZCB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBldmVudCBvYmplY3Qgd2hpY2ggd2lsbCBiZSBwYXNzZWQgdG8gYWxsIGxpc3RlbmVycyBvZiB0aGUgZXZlbnQudHlwZSBwcm9wZXJ0eVxuICAgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgLi4uY3VzdG9tQXJndW1lbnRzKSB7XG4gICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQudHlwZTtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3RlbmVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgICBpZiAoY3VzdG9tQXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgY3VzdG9tQXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlZ3VsYXIgV2ViU29ja2V0cyBleHBlY3QgYSBNZXNzYWdlRXZlbnQgYnV0IFNvY2tldGlvLmlvIGp1c3Qgd2FudHMgcmF3IGRhdGFcbiAgICAgICAgLy8gIHBheWxvYWQgaW5zdGFuY2VvZiBNZXNzYWdlRXZlbnQgd29ya3MsIGJ1dCB5b3UgY2FuJ3QgaXNudGFuY2Ugb2YgTm9kZUV2ZW50XG4gICAgICAgIC8vICBmb3Igbm93IHdlIGRldGVjdCBpZiB0aGUgb3V0cHV0IGhhcyBkYXRhIGRlZmluZWQgb24gaXRcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudC5kYXRhID8gZXZlbnQuZGF0YSA6IGV2ZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5Tb2NrZXRJTy5DT05ORUNUSU5HID0gMDtcblNvY2tldElPLk9QRU4gPSAxO1xuU29ja2V0SU8uQ0xPU0lORyA9IDI7XG5Tb2NrZXRJTy5DTE9TRUQgPSAzO1xuXG4vKlxuKiBTdGF0aWMgY29uc3RydWN0b3IgbWV0aG9kcyBmb3IgdGhlIElPIFNvY2tldFxuKi9cbmNvbnN0IElPID0gZnVuY3Rpb24gaW9Db25zdHJ1Y3Rvcih1cmwsIHByb3RvY29sKSB7XG4gIHJldHVybiBuZXcgU29ja2V0SU8odXJsLCBwcm90b2NvbCk7XG59O1xuXG4vKlxuKiBBbGlhcyB0aGUgcmF3IElPKCkgY29uc3RydWN0b3JcbiovXG5JTy5jb25uZWN0ID0gZnVuY3Rpb24gaW9Db25uZWN0KHVybCwgcHJvdG9jb2wpIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbmV3LWNhcCAqL1xuICByZXR1cm4gSU8odXJsLCBwcm90b2NvbCk7XG4gIC8qIGVzbGludC1lbmFibGUgbmV3LWNhcCAqL1xufTtcblxuZXhwb3J0IGRlZmF1bHQgSU87XG4iLCJpbXBvcnQgTW9ja1NlcnZlciBmcm9tICcuL3NlcnZlcic7XG5pbXBvcnQgTW9ja1NvY2tldElPIGZyb20gJy4vc29ja2V0LWlvJztcbmltcG9ydCBNb2NrV2ViU29ja2V0IGZyb20gJy4vd2Vic29ja2V0JztcblxuZXhwb3J0IGNvbnN0IFNlcnZlciA9IE1vY2tTZXJ2ZXI7XG5leHBvcnQgY29uc3QgV2ViU29ja2V0ID0gTW9ja1dlYlNvY2tldDtcbmV4cG9ydCBjb25zdCBTb2NrZXRJTyA9IE1vY2tTb2NrZXRJTztcbiJdLCJuYW1lcyI6WyJnbG9iYWwiLCJxcyIsInJlcXVpcmVkIiwiY29uc3QiLCJ0aGlzIiwic3VwZXIiLCJXZWJTb2NrZXQiLCJVUkwiLCJsb2dnZXIiLCJTZXJ2ZXIiLCJnbG9iYWxPYmplY3QiLCJTb2NrZXRJTyIsIk1vY2tTZXJ2ZXIiLCJNb2NrV2ViU29ja2V0IiwiTW9ja1NvY2tldElPIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQVdBLGdCQUFjLEdBQUcsU0FBUyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtFQUNqRCxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNsQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUM7O0VBRWIsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFBLE9BQU8sS0FBSyxDQUFDLEVBQUE7O0VBRXhCLFFBQVEsUUFBUTtJQUNkLEtBQUssTUFBTSxDQUFD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 diff --git a/node_modules/mock-socket/dist/mock-socket.js b/node_modules/mock-socket/dist/mock-socket.js new file mode 100644 index 0000000..5365015 --- /dev/null +++ b/node_modules/mock-socket/dist/mock-socket.js @@ -0,0 +1,1932 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.Mock = global.Mock || {}))); +}(this, (function (exports) { 'use strict'; + +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +var requiresPort = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) { return false; } + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; + +var has = Object.prototype.hasOwnProperty; + +/** + * Decode a URI encoded string. + * + * @param {String} input The URI encoded string. + * @returns {String} The decoded string. + * @api private + */ +function decode(input) { + return decodeURIComponent(input.replace(/\+/g, ' ')); +} + +/** + * Simple query string parser. + * + * @param {String} query The query string that needs to be parsed. + * @returns {Object} + * @api public + */ +function querystring(query) { + var parser = /([^=?&]+)=?([^&]*)/g + , result = {} + , part; + + while (part = parser.exec(query)) { + var key = decode(part[1]) + , value = decode(part[2]); + + // + // Prevent overriding of existing properties. This ensures that build-in + // methods like `toString` or __proto__ are not overriden by malicious + // querystrings. + // + if (key in result) { continue; } + result[key] = value; + } + + return result; +} + +/** + * Transform a query string to an object. + * + * @param {Object} obj Object that should be transformed. + * @param {String} prefix Optional prefix. + * @returns {String} + * @api public + */ +function querystringify(obj, prefix) { + prefix = prefix || ''; + + var pairs = []; + + // + // Optionally prefix with a '?' if needed + // + if ('string' !== typeof prefix) { prefix = '?'; } + + for (var key in obj) { + if (has.call(obj, key)) { + pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key])); + } + } + + return pairs.length ? prefix + pairs.join('&') : ''; +} + +// +// Expose the module. +// +var stringify = querystringify; +var parse = querystring; + +var querystringify_1 = { + stringify: stringify, + parse: parse +}; + +var protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; +var slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//; + +/** + * These are the parse rules for the URL parser, it informs the parser + * about: + * + * 0. The char it Needs to parse, if it's a string it should be done using + * indexOf, RegExp using exec and NaN means set as current value. + * 1. The property we should set when parsing this value. + * 2. Indication if it's backwards or forward parsing, when set as number it's + * the value of extra chars that should be split off. + * 3. Inherit from location if non existing in the parser. + * 4. `toLowerCase` the resulting value. + */ +var rules = [ + ['#', 'hash'], // Extract from the back. + ['?', 'query'], // Extract from the back. + ['/', 'pathname'], // Extract from the back. + ['@', 'auth', 1], // Extract from the front. + [NaN, 'host', undefined, 1, 1], // Set left over value. + [/:(\d+)$/, 'port', undefined, 1], // RegExp the back. + [NaN, 'hostname', undefined, 1, 1] // Set left over. +]; + +/** + * These properties should not be copied or inherited from. This is only needed + * for all non blob URL's as a blob URL does not include a hash, only the + * origin. + * + * @type {Object} + * @private + */ +var ignore = { hash: 1, query: 1 }; + +/** + * The location object differs when your code is loaded through a normal page, + * Worker or through a worker using a blob. And with the blobble begins the + * trouble as the location object will contain the URL of the blob, not the + * location of the page where our code is loaded in. The actual origin is + * encoded in the `pathname` so we can thankfully generate a good "default" + * location from it so we can generate proper relative URL's again. + * + * @param {Object|String} loc Optional default location object. + * @returns {Object} lolcation object. + * @api public + */ +function lolcation(loc) { + var location = commonjsGlobal && commonjsGlobal.location || {}; + loc = loc || location; + + var finaldestination = {} + , type = typeof loc + , key; + + if ('blob:' === loc.protocol) { + finaldestination = new URL(unescape(loc.pathname), {}); + } else if ('string' === type) { + finaldestination = new URL(loc, {}); + for (key in ignore) { delete finaldestination[key]; } + } else if ('object' === type) { + for (key in loc) { + if (key in ignore) { continue; } + finaldestination[key] = loc[key]; + } + + if (finaldestination.slashes === undefined) { + finaldestination.slashes = slashes.test(loc.href); + } + } + + return finaldestination; +} + +/** + * @typedef ProtocolExtract + * @type Object + * @property {String} protocol Protocol matched in the URL, in lowercase. + * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`. + * @property {String} rest Rest of the URL that is not part of the protocol. + */ + +/** + * Extract protocol information from a URL with/without double slash ("//"). + * + * @param {String} address URL we want to extract from. + * @return {ProtocolExtract} Extracted information. + * @api private + */ +function extractProtocol(address) { + var match = protocolre.exec(address); + + return { + protocol: match[1] ? match[1].toLowerCase() : '', + slashes: !!match[2], + rest: match[3] + }; +} + +/** + * Resolve a relative URL pathname against a base URL pathname. + * + * @param {String} relative Pathname of the relative URL. + * @param {String} base Pathname of the base URL. + * @return {String} Resolved pathname. + * @api private + */ +function resolve(relative, base) { + var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/')) + , i = path.length + , last = path[i - 1] + , unshift = false + , up = 0; + + while (i--) { + if (path[i] === '.') { + path.splice(i, 1); + } else if (path[i] === '..') { + path.splice(i, 1); + up++; + } else if (up) { + if (i === 0) { unshift = true; } + path.splice(i, 1); + up--; + } + } + + if (unshift) { path.unshift(''); } + if (last === '.' || last === '..') { path.push(''); } + + return path.join('/'); +} + +/** + * The actual URL instance. Instead of returning an object we've opted-in to + * create an actual constructor as it's much more memory efficient and + * faster and it pleases my OCD. + * + * @constructor + * @param {String} address URL we want to parse. + * @param {Object|String} location Location defaults for relative paths. + * @param {Boolean|Function} parser Parser for the query string. + * @api public + */ +function URL(address, location, parser) { + if (!(this instanceof URL)) { + return new URL(address, location, parser); + } + + var relative, extracted, parse, instruction, index, key + , instructions = rules.slice() + , type = typeof location + , url = this + , i = 0; + + // + // The following if statements allows this module two have compatibility with + // 2 different API: + // + // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments + // where the boolean indicates that the query string should also be parsed. + // + // 2. The `URL` interface of the browser which accepts a URL, object as + // arguments. The supplied object will be used as default values / fall-back + // for relative paths. + // + if ('object' !== type && 'string' !== type) { + parser = location; + location = null; + } + + if (parser && 'function' !== typeof parser) { parser = querystringify_1.parse; } + + location = lolcation(location); + + // + // Extract protocol information before running the instructions. + // + extracted = extractProtocol(address || ''); + relative = !extracted.protocol && !extracted.slashes; + url.slashes = extracted.slashes || relative && location.slashes; + url.protocol = extracted.protocol || location.protocol || ''; + address = extracted.rest; + + // + // When the authority component is absent the URL starts with a path + // component. + // + if (!extracted.slashes) { instructions[2] = [/(.*)/, 'pathname']; } + + for (; i < instructions.length; i++) { + instruction = instructions[i]; + parse = instruction[0]; + key = instruction[1]; + + if (parse !== parse) { + url[key] = address; + } else if ('string' === typeof parse) { + if (~(index = address.indexOf(parse))) { + if ('number' === typeof instruction[2]) { + url[key] = address.slice(0, index); + address = address.slice(index + instruction[2]); + } else { + url[key] = address.slice(index); + address = address.slice(0, index); + } + } + } else if ((index = parse.exec(address))) { + url[key] = index[1]; + address = address.slice(0, index.index); + } + + url[key] = url[key] || ( + relative && instruction[3] ? location[key] || '' : '' + ); + + // + // Hostname, host and protocol should be lowercased so they can be used to + // create a proper `origin`. + // + if (instruction[4]) { url[key] = url[key].toLowerCase(); } + } + + // + // Also parse the supplied query string in to an object. If we're supplied + // with a custom parser as function use that instead of the default build-in + // parser. + // + if (parser) { url.query = parser(url.query); } + + // + // If the URL is relative, resolve the pathname against the base URL. + // + if ( + relative + && location.slashes + && url.pathname.charAt(0) !== '/' + && (url.pathname !== '' || location.pathname !== '') + ) { + url.pathname = resolve(url.pathname, location.pathname); + } + + // + // We should not add port numbers if they are already the default port number + // for a given protocol. As the host also contains the port number we're going + // override it with the hostname which contains no port number. + // + if (!requiresPort(url.port, url.protocol)) { + url.host = url.hostname; + url.port = ''; + } + + // + // Parse down the `auth` for the username and password. + // + url.username = url.password = ''; + if (url.auth) { + instruction = url.auth.split(':'); + url.username = instruction[0] || ''; + url.password = instruction[1] || ''; + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + // + // The href is just the compiled result. + // + url.href = url.toString(); +} + +/** + * This is convenience method for changing properties in the URL instance to + * insure that they all propagate correctly. + * + * @param {String} part Property we need to adjust. + * @param {Mixed} value The newly assigned value. + * @param {Boolean|Function} fn When setting the query, it will be the function + * used to parse the query. + * When setting the protocol, double slash will be + * removed from the final url if it is true. + * @returns {URL} + * @api public + */ +function set(part, value, fn) { + var url = this; + + switch (part) { + case 'query': + if ('string' === typeof value && value.length) { + value = (fn || querystringify_1.parse)(value); + } + + url[part] = value; + break; + + case 'port': + url[part] = value; + + if (!requiresPort(value, url.protocol)) { + url.host = url.hostname; + url[part] = ''; + } else if (value) { + url.host = url.hostname +':'+ value; + } + + break; + + case 'hostname': + url[part] = value; + + if (url.port) { value += ':'+ url.port; } + url.host = value; + break; + + case 'host': + url[part] = value; + + if (/:\d+$/.test(value)) { + value = value.split(':'); + url.port = value.pop(); + url.hostname = value.join(':'); + } else { + url.hostname = value; + url.port = ''; + } + + break; + + case 'protocol': + url.protocol = value.toLowerCase(); + url.slashes = !fn; + break; + + case 'pathname': + case 'hash': + if (value) { + var char = part === 'pathname' ? '/' : '#'; + url[part] = value.charAt(0) !== char ? char + value : value; + } else { + url[part] = value; + } + break; + + default: + url[part] = value; + } + + for (var i = 0; i < rules.length; i++) { + var ins = rules[i]; + + if (ins[4]) { url[ins[1]] = url[ins[1]].toLowerCase(); } + } + + url.origin = url.protocol && url.host && url.protocol !== 'file:' + ? url.protocol +'//'+ url.host + : 'null'; + + url.href = url.toString(); + + return url; +} + +/** + * Transform the properties back in to a valid and full URL string. + * + * @param {Function} stringify Optional query stringify function. + * @returns {String} + * @api public + */ +function toString(stringify) { + if (!stringify || 'function' !== typeof stringify) { stringify = querystringify_1.stringify; } + + var query + , url = this + , protocol = url.protocol; + + if (protocol && protocol.charAt(protocol.length - 1) !== ':') { protocol += ':'; } + + var result = protocol + (url.slashes ? '//' : ''); + + if (url.username) { + result += url.username; + if (url.password) { result += ':'+ url.password; } + result += '@'; + } + + result += url.host + url.pathname; + + query = 'object' === typeof url.query ? stringify(url.query) : url.query; + if (query) { result += '?' !== query.charAt(0) ? '?'+ query : query; } + + if (url.hash) { result += url.hash; } + + return result; +} + +URL.prototype = { set: set, toString: toString }; + +// +// Expose the URL parser and some additional properties that might be useful for +// others or testing. +// +URL.extractProtocol = extractProtocol; +URL.location = lolcation; +URL.qs = querystringify_1; + +var urlParse = URL; + +/* +* This delay allows the thread to finish assigning its on* methods +* before invoking the delay callback. This is purely a timing hack. +* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html +* +* @param {callback: function} the callback which will be invoked after the timeout +* @parma {context: object} the context in which to invoke the function +*/ +function delay(callback, context) { + setTimeout(function (timeoutContext) { return callback.call(timeoutContext); }, 4, context); +} + +function log(method, message) { + /* eslint-disable no-console */ + if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') { + console[method].call(null, message); + } + /* eslint-enable no-console */ +} + +function reject(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (!callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +function filter(array, callback) { + var results = []; + array.forEach(function (itemInArray) { + if (callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +/* +* EventTarget is an interface implemented by objects that can +* receive events and may have listeners for them. +* +* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget +*/ +var EventTarget = function EventTarget() { + this.listeners = {}; +}; + +/* +* Ties a listener function to an event type which can later be invoked via the +* dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.addEventListener = function addEventListener (type, listener /* , useCapture */) { + if (typeof listener === 'function') { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], function (item) { return item === listener; }).length === 0) { + this.listeners[type].push(listener); + } + } +}; + +/* +* Removes the listener so it will no longer be invoked via the dispatchEvent method. +* +* @param {string} type - the type of event (ie: 'open', 'message', etc.) +* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type +* @param {boolean} useCapture - N/A TODO: implement useCapture functionality +*/ +EventTarget.prototype.removeEventListener = function removeEventListener (type, removingListener /* , useCapture */) { + var arrayOfListeners = this.listeners[type]; + this.listeners[type] = reject(arrayOfListeners, function (listener) { return listener === removingListener; }); +}; + +/* +* Invokes all listener functions that are listening to the given event.type property. Each +* listener will be passed the event as the first argument. +* +* @param {object} event - event object which will be passed to all listeners of the event.type property +*/ +EventTarget.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + listener.call(this$1, event); + } + }); + + return true; +}; + +/* +* The network bridge is a way for the mock websocket object to 'communicate' with +* all available servers. This is a singleton object so it is important that you +* clean up urlMap whenever you are finished. +*/ +var NetworkBridge = function NetworkBridge() { + this.urlMap = {}; +}; + +/* +* Attaches a websocket object to the urlMap hash so that it can find the server +* it is connected to and the server in turn can find it. +* +* @param {object} websocket - websocket object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachWebSocket = function attachWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) { + connectionLookup.websockets.push(websocket); + return connectionLookup.server; + } +}; + +/* +* Attaches a websocket to a room +*/ +NetworkBridge.prototype.addMembershipToRoom = function addMembershipToRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) { + if (!connectionLookup.roomMemberships[room]) { + connectionLookup.roomMemberships[room] = []; + } + + connectionLookup.roomMemberships[room].push(websocket); + } +}; + +/* +* Attaches a server object to the urlMap hash so that it can find a websockets +* which are connected to it and so that websockets can in turn can find it. +* +* @param {object} server - server object to add to the urlMap hash +* @param {string} url +*/ +NetworkBridge.prototype.attachServer = function attachServer (server, url) { + var connectionLookup = this.urlMap[url]; + + if (!connectionLookup) { + this.urlMap[url] = { + server: server, + websockets: [], + roomMemberships: {} + }; + + return server; + } +}; + +/* +* Finds the server which is 'running' on the given url. +* +* @param {string} url - the url to use to find which server is running on it +*/ +NetworkBridge.prototype.serverLookup = function serverLookup (url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + return connectionLookup.server; + } +}; + +/* +* Finds all websockets which is 'listening' on the given url. +* +* @param {string} url - the url to use to find all websockets which are associated with it +* @param {string} room - if a room is provided, will only return sockets in this room +* @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup +*/ +NetworkBridge.prototype.websocketsLookup = function websocketsLookup (url, room, broadcaster) { + var websockets; + var connectionLookup = this.urlMap[url]; + + websockets = connectionLookup ? connectionLookup.websockets : []; + + if (room) { + var members = connectionLookup.roomMemberships[room]; + websockets = members || []; + } + + return broadcaster ? websockets.filter(function (websocket) { return websocket !== broadcaster; }) : websockets; +}; + +/* +* Removes the entry associated with the url. +* +* @param {string} url +*/ +NetworkBridge.prototype.removeServer = function removeServer (url) { + delete this.urlMap[url]; +}; + +/* +* Removes the individual websocket from the map of associated websockets. +* +* @param {object} websocket - websocket object to remove from the url map +* @param {string} url +*/ +NetworkBridge.prototype.removeWebSocket = function removeWebSocket (websocket, url) { + var connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + connectionLookup.websockets = reject(connectionLookup.websockets, function (socket) { return socket === websocket; }); + } +}; + +/* +* Removes a websocket from a room +*/ +NetworkBridge.prototype.removeMembershipFromRoom = function removeMembershipFromRoom (websocket, room) { + var connectionLookup = this.urlMap[websocket.url]; + var memberships = connectionLookup.roomMemberships[room]; + + if (connectionLookup && memberships !== null) { + connectionLookup.roomMemberships[room] = reject(memberships, function (socket) { return socket === websocket; }); + } +}; + +var networkBridge = new NetworkBridge(); // Note: this is a singleton + +/* + * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent + */ +var CLOSE_CODES = { + CLOSE_NORMAL: 1000, + CLOSE_GOING_AWAY: 1001, + CLOSE_PROTOCOL_ERROR: 1002, + CLOSE_UNSUPPORTED: 1003, + CLOSE_NO_STATUS: 1005, + CLOSE_ABNORMAL: 1006, + UNSUPPORTED_DATA: 1007, + POLICY_VIOLATION: 1008, + CLOSE_TOO_LARGE: 1009, + MISSING_EXTENSION: 1010, + INTERNAL_ERROR: 1011, + SERVICE_RESTART: 1012, + TRY_AGAIN_LATER: 1013, + TLS_HANDSHAKE: 1015 +}; + +var ERROR_PREFIX = { + CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':", + CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':", + EVENT: { + CONSTRUCT: "Failed to construct 'Event':", + MESSAGE: "Failed to construct 'MessageEvent':", + CLOSE: "Failed to construct 'CloseEvent':" + } +}; + +var EventPrototype = function EventPrototype () {}; + +EventPrototype.prototype.stopPropagation = function stopPropagation () {}; +EventPrototype.prototype.stopImmediatePropagation = function stopImmediatePropagation () {}; + +// if no arguments are passed then the type is set to "undefined" on +// chrome and safari. +EventPrototype.prototype.initEvent = function initEvent (type, bubbles, cancelable) { + if ( type === void 0 ) type = 'undefined'; + if ( bubbles === void 0 ) bubbles = false; + if ( cancelable === void 0 ) cancelable = false; + + this.type = "" + type; + this.bubbles = Boolean(bubbles); + this.cancelable = Boolean(cancelable); +}; + +var Event = (function (EventPrototype$$1) { + function Event(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT_ERROR) + " parameter 2 ('eventInitDict') is not an object.")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + } + + if ( EventPrototype$$1 ) Event.__proto__ = EventPrototype$$1; + Event.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + Event.prototype.constructor = Event; + + return Event; +}(EventPrototype)); + +var MessageEvent = (function (EventPrototype$$1) { + function MessageEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.MESSAGE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var data = eventInitConfig.data; + var origin = eventInitConfig.origin; + var lastEventId = eventInitConfig.lastEventId; + var ports = eventInitConfig.ports; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.origin = "" + origin; + this.ports = typeof ports === 'undefined' ? null : ports; + this.data = typeof data === 'undefined' ? null : data; + this.lastEventId = "" + (lastEventId || ''); + } + + if ( EventPrototype$$1 ) MessageEvent.__proto__ = EventPrototype$$1; + MessageEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + MessageEvent.prototype.constructor = MessageEvent; + + return MessageEvent; +}(EventPrototype)); + +var CloseEvent = (function (EventPrototype$$1) { + function CloseEvent(type, eventInitConfig) { + if ( eventInitConfig === void 0 ) eventInitConfig = {}; + + EventPrototype$$1.call(this); + + if (!type) { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " 1 argument required, but only 0 present.")); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(((ERROR_PREFIX.EVENT.CLOSE) + " parameter 2 ('eventInitDict') is not an object")); + } + + var bubbles = eventInitConfig.bubbles; + var cancelable = eventInitConfig.cancelable; + var code = eventInitConfig.code; + var reason = eventInitConfig.reason; + var wasClean = eventInitConfig.wasClean; + + this.type = "" + type; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.cancelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.code = typeof code === 'number' ? parseInt(code, 10) : 0; + this.reason = "" + (reason || ''); + this.wasClean = wasClean ? Boolean(wasClean) : false; + } + + if ( EventPrototype$$1 ) CloseEvent.__proto__ = EventPrototype$$1; + CloseEvent.prototype = Object.create( EventPrototype$$1 && EventPrototype$$1.prototype ); + CloseEvent.prototype.constructor = CloseEvent; + + return CloseEvent; +}(EventPrototype)); + +/* +* Creates an Event object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config you will need to pass type and optionally target +*/ +function createEvent(config) { + var type = config.type; + var target = config.target; + var eventObject = new Event(type); + + if (target) { + eventObject.target = target; + eventObject.srcElement = target; + eventObject.currentTarget = target; + } + + return eventObject; +} + +/* +* Creates a MessageEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type, origin, data and optionally target +*/ +function createMessageEvent(config) { + var type = config.type; + var origin = config.origin; + var data = config.data; + var target = config.target; + var messageEvent = new MessageEvent(type, { + data: data, + origin: origin + }); + + if (target) { + messageEvent.target = target; + messageEvent.srcElement = target; + messageEvent.currentTarget = target; + } + + return messageEvent; +} + +/* +* Creates a CloseEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type and optionally target, code, and reason +*/ +function createCloseEvent(config) { + var code = config.code; + var reason = config.reason; + var type = config.type; + var target = config.target; + var wasClean = config.wasClean; + + if (!wasClean) { + wasClean = code === 1000; + } + + var closeEvent = new CloseEvent(type, { + code: code, + reason: reason, + wasClean: wasClean + }); + + if (target) { + closeEvent.target = target; + closeEvent.srcElement = target; + closeEvent.currentTarget = target; + } + + return closeEvent; +} + +function closeWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function failWebSocketConnection(context, code, reason) { + context.readyState = WebSocket$1.CLOSING; + + var server = networkBridge.serverLookup(context.url); + var closeEvent = createCloseEvent({ + type: 'close', + target: context, + code: code, + reason: reason, + wasClean: false + }); + + var errorEvent = createEvent({ + type: 'error', + target: context + }); + + delay(function () { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket$1.CLOSED; + context.dispatchEvent(errorEvent); + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +function normalizeSendData(data) { + if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) { + data = String(data); + } + + return data; +} + +function proxyFactory(target) { + var handler = { + get: function get(obj, prop) { + if (prop === 'close') { + return function close(options) { + if ( options === void 0 ) options = {}; + + var code = options.code || CLOSE_CODES.CLOSE_NORMAL; + var reason = options.reason || ''; + + closeWebSocketConnection(target, code, reason); + }; + } + + if (prop === 'send') { + return function send(data) { + data = normalizeSendData(data); + + target.dispatchEvent( + createMessageEvent({ + type: 'message', + data: data, + origin: this.url, + target: target + }) + ); + }; + } + + if (prop === 'on') { + return function onWrapper(type, cb) { + target.addEventListener(("server::" + type), cb); + }; + } + + return obj[prop]; + } + }; + + var proxy = new Proxy(target, handler); + return proxy; +} + +function lengthInUtf8Bytes(str) { + // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. + var m = encodeURIComponent(str).match(/%[89ABab]/g); + return str.length + (m ? m.length : 0); +} + +function urlVerification(url) { + var urlRecord = new urlParse(url); + var pathname = urlRecord.pathname; + var protocol = urlRecord.protocol; + var hash = urlRecord.hash; + + if (!url) { + throw new TypeError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " 1 argument required, but only 0 present.")); + } + + if (!pathname) { + urlRecord.pathname = '/'; + } + + if (protocol === '') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL '" + (urlRecord.toString()) + "' is invalid.")); + } + + if (protocol !== 'ws:' && protocol !== 'wss:') { + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL's scheme must be either 'ws' or 'wss'. '" + protocol + "' is not allowed.") + ); + } + + if (hash !== '') { + /* eslint-disable max-len */ + throw new SyntaxError( + ((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The URL contains a fragment identifier ('" + hash + "'). Fragment identifiers are not allowed in WebSocket URLs.") + ); + /* eslint-enable max-len */ + } + + return urlRecord.toString(); +} + +function protocolVerification(protocols) { + if ( protocols === void 0 ) protocols = []; + + if (!Array.isArray(protocols) && typeof protocols !== 'string') { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (protocols.toString()) + "' is invalid.")); + } + + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + var uniq = protocols.map(function (p) { return ({ count: 1, protocol: p }); }).reduce(function (a, b) { + a[b.protocol] = (a[b.protocol] || 0) + b.count; + return a; + }, {}); + + var duplicates = Object.keys(uniq).filter(function (a) { return uniq[a] > 1; }); + + if (duplicates.length > 0) { + throw new SyntaxError(((ERROR_PREFIX.CONSTRUCTOR_ERROR) + " The subprotocol '" + (duplicates[0]) + "' is duplicated.")); + } + + return protocols; +} + +/* + * The main websocket class which is designed to mimick the native WebSocket class as close + * as possible. + * + * https://html.spec.whatwg.org/multipage/web-sockets.html + */ +var WebSocket$1 = (function (EventTarget$$1) { + function WebSocket(url, protocols) { + EventTarget$$1.call(this); + + this.url = urlVerification(url); + protocols = protocolVerification(protocols); + this.protocol = protocols[0] || ''; + + this.binaryType = 'blob'; + this.readyState = WebSocket.CONNECTING; + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * This delay is needed so that we dont trigger an event before the callbacks have been + * setup. For example: + * + * var socket = new WebSocket('ws://localhost'); + * + * If we dont have the delay then the event would be triggered right here and this is + * before the onopen had a chance to register itself. + * + * socket.onopen = () => { // this would never be called }; + * + * and with the delay the event gets triggered here after all of the callbacks have been + * registered :-) + */ + delay(function delayCallback() { + if (server) { + if ( + server.options.verifyClient && + typeof server.options.verifyClient === 'function' && + !server.options.verifyClient() + ) { + this.readyState = WebSocket.CLOSED; + + log( + 'error', + ("WebSocket connection to '" + (this.url) + "' failed: HTTP Authentication failed; no valid credentials available") + ); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + } else { + if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') { + var selectedProtocol = server.options.selectProtocol(protocols); + var isFilled = selectedProtocol !== ''; + var isRequested = protocols.indexOf(selectedProtocol) !== -1; + if (isFilled && !isRequested) { + this.readyState = WebSocket.CLOSED; + + log('error', ("WebSocket connection to '" + (this.url) + "' failed: Invalid Sub-Protocol")); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + return; + } + this.protocol = selectedProtocol; + } + this.readyState = WebSocket.OPEN; + this.dispatchEvent(createEvent({ type: 'open', target: this })); + server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this)); + } + } else { + this.readyState = WebSocket.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + + log('error', ("WebSocket connection to '" + (this.url) + "' failed")); + } + }, this); + } + + if ( EventTarget$$1 ) WebSocket.__proto__ = EventTarget$$1; + WebSocket.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + WebSocket.prototype.constructor = WebSocket; + + var prototypeAccessors = { onopen: {},onmessage: {},onclose: {},onerror: {} }; + + prototypeAccessors.onopen.get = function () { + return this.listeners.open; + }; + + prototypeAccessors.onmessage.get = function () { + return this.listeners.message; + }; + + prototypeAccessors.onclose.get = function () { + return this.listeners.close; + }; + + prototypeAccessors.onerror.get = function () { + return this.listeners.error; + }; + + prototypeAccessors.onopen.set = function (listener) { + delete this.listeners.open; + this.addEventListener('open', listener); + }; + + prototypeAccessors.onmessage.set = function (listener) { + delete this.listeners.message; + this.addEventListener('message', listener); + }; + + prototypeAccessors.onclose.set = function (listener) { + delete this.listeners.close; + this.addEventListener('close', listener); + }; + + prototypeAccessors.onerror.set = function (listener) { + delete this.listeners.error; + this.addEventListener('error', listener); + }; + + WebSocket.prototype.send = function send (data) { + var this$1 = this; + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + throw new Error('WebSocket is already in CLOSING or CLOSED state'); + } + + // TODO: handle bufferedAmount + + var messageEvent = createMessageEvent({ + type: 'server::message', + origin: this.url, + data: normalizeSendData(data) + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + delay(function () { + this$1.dispatchEvent(messageEvent, data); + }, server); + } + }; + + WebSocket.prototype.close = function close (code, reason) { + if (code !== undefined) { + if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) { + throw new TypeError( + ((ERROR_PREFIX.CLOSE_ERROR) + " The code must be either 1000, or between 3000 and 4999. " + code + " is neither.") + ); + } + } + + if (reason !== undefined) { + var length = lengthInUtf8Bytes(reason); + + if (length > 123) { + throw new SyntaxError(((ERROR_PREFIX.CLOSE_ERROR) + " The message must not be greater than 123 bytes.")); + } + } + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + return; + } + + if (this.readyState === WebSocket.CONNECTING) { + failWebSocketConnection(this, code, reason); + } else { + closeWebSocketConnection(this, code, reason); + } + }; + + Object.defineProperties( WebSocket.prototype, prototypeAccessors ); + + return WebSocket; +}(EventTarget)); + +WebSocket$1.CONNECTING = 0; +WebSocket$1.prototype.CONNECTING = WebSocket$1.CONNECTING; +WebSocket$1.OPEN = 1; +WebSocket$1.prototype.OPEN = WebSocket$1.OPEN; +WebSocket$1.CLOSING = 2; +WebSocket$1.prototype.CLOSING = WebSocket$1.CLOSING; +WebSocket$1.CLOSED = 3; +WebSocket$1.prototype.CLOSED = WebSocket$1.CLOSED; + +var dedupe = function (arr) { return arr.reduce(function (deduped, b) { + if (deduped.indexOf(b) > -1) { return deduped; } + return deduped.concat(b); + }, []); }; + +function retrieveGlobalObject() { + if (typeof window !== 'undefined') { + return window; + } + + return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this; +} + +var Server$1 = (function (EventTarget$$1) { + function Server(url, options) { + if ( options === void 0 ) options = {}; + + EventTarget$$1.call(this); + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + + this.originalWebSocket = null; + var server = networkBridge.attachServer(this, this.url); + + if (!server) { + this.dispatchEvent(createEvent({ type: 'error' })); + throw new Error('A mock server is already listening on this url'); + } + + if (typeof options.verifyClient === 'undefined') { + options.verifyClient = null; + } + + if (typeof options.selectProtocol === 'undefined') { + options.selectProtocol = null; + } + + this.options = options; + this.start(); + } + + if ( EventTarget$$1 ) Server.__proto__ = EventTarget$$1; + Server.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + Server.prototype.constructor = Server; + + /* + * Attaches the mock websocket object to the global object + */ + Server.prototype.start = function start () { + var globalObj = retrieveGlobalObject(); + + if (globalObj.WebSocket) { + this.originalWebSocket = globalObj.WebSocket; + } + + globalObj.WebSocket = WebSocket$1; + }; + + /* + * Removes the mock websocket object from the global object + */ + Server.prototype.stop = function stop (callback) { + if ( callback === void 0 ) callback = function () {}; + + var globalObj = retrieveGlobalObject(); + + if (this.originalWebSocket) { + globalObj.WebSocket = this.originalWebSocket; + } else { + delete globalObj.WebSocket; + } + + this.originalWebSocket = null; + + networkBridge.removeServer(this.url); + + if (typeof callback === 'function') { + callback(); + } + }; + + /* + * This is the main function for the mock server to subscribe to the on events. + * + * ie: mockServer.on('connection', function() { console.log('a mock client connected'); }); + * + * @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close. + * @param {function} callback - The callback which should be called when a certain event is fired. + */ + Server.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + }; + + /* + * Closes the connection and triggers the onclose method of all listening + * websockets. After that it removes itself from the urlMap so another server + * could add itself to the url. + * + * @param {object} options + */ + Server.prototype.close = function close (options) { + if ( options === void 0 ) options = {}; + + var code = options.code; + var reason = options.reason; + var wasClean = options.wasClean; + var listeners = networkBridge.websocketsLookup(this.url); + + // Remove server before notifications to prevent immediate reconnects from + // socket onclose handlers + networkBridge.removeServer(this.url); + + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent( + createCloseEvent({ + type: 'close', + target: socket, + code: code || CLOSE_CODES.CLOSE_NORMAL, + reason: reason || '', + wasClean: wasClean + }) + ); + }); + + this.dispatchEvent(createCloseEvent({ type: 'close' }), this); + }; + + /* + * Sends a generic message event to all mock clients. + */ + Server.prototype.emit = function emit (event, data, options) { + var this$1 = this; + if ( options === void 0 ) options = {}; + + var websockets = options.websockets; + + if (!websockets) { + websockets = networkBridge.websocketsLookup(this.url); + } + + if (typeof options !== 'object' || arguments.length > 3) { + data = Array.prototype.slice.call(arguments, 1, arguments.length); + data = data.map(function (item) { return normalizeSendData(item); }); + } else { + data = normalizeSendData(data); + } + + websockets.forEach(function (socket) { + if (Array.isArray(data)) { + socket.dispatchEvent.apply( + socket, [ createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) ].concat( data ) + ); + } else { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data: data, + origin: this$1.url, + target: socket + }) + ); + } + }); + }; + + /* + * Returns an array of websockets which are listening to this server + * TOOD: this should return a set and not be a method + */ + Server.prototype.clients = function clients () { + return networkBridge.websocketsLookup(this.url); + }; + + /* + * Prepares a method to submit an event to members of the room + * + * e.g. server.to('my-room').emit('hi!'); + */ + Server.prototype.to = function to (room, broadcaster, broadcastList) { + var this$1 = this; + if ( broadcastList === void 0 ) broadcastList = []; + + var self = this; + var websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster))); + + return { + to: function (chainedRoom, chainedBroadcaster) { return this$1.to.call(this$1, chainedRoom, chainedBroadcaster, websockets); }, + emit: function emit(event, data) { + self.emit(event, data, { websockets: websockets }); + } + }; + }; + + /* + * Alias for Server.to + */ + Server.prototype.in = function in$1 () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return this.to.apply(null, args); + }; + + /* + * Simulate an event from the server to the clients. Useful for + * simulating errors. + */ + Server.prototype.simulate = function simulate (event) { + var listeners = networkBridge.websocketsLookup(this.url); + + if (event === 'error') { + listeners.forEach(function (socket) { + socket.readyState = WebSocket$1.CLOSE; + socket.dispatchEvent(createEvent({ type: 'error' })); + }); + } + }; + + return Server; +}(EventTarget)); + +/* + * Alternative constructor to support namespaces in socket.io + * + * http://socket.io/docs/rooms-and-namespaces/#custom-namespaces + */ +Server$1.of = function of(url) { + return new Server$1(url); +}; + +/* +* The socket-io class is designed to mimick the real API as closely as possible. +* +* http://socket.io/docs/ +*/ +var SocketIO$1 = (function (EventTarget$$1) { + function SocketIO(url, protocol) { + var this$1 = this; + if ( url === void 0 ) url = 'socket.io'; + if ( protocol === void 0 ) protocol = ''; + + EventTarget$$1.call(this); + + this.binaryType = 'blob'; + var urlRecord = new urlParse(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + this.readyState = SocketIO.CONNECTING; + this.protocol = ''; + + if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) { + this.protocol = protocol; + } else if (Array.isArray(protocol) && protocol.length > 0) { + this.protocol = protocol[0]; + } + + var server = networkBridge.attachWebSocket(this, this.url); + + /* + * Delay triggering the connection events so they can be defined in time. + */ + delay(function delayCallback() { + if (server) { + this.readyState = SocketIO.OPEN; + server.dispatchEvent(createEvent({ type: 'connection' }), server, this); + server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias + this.dispatchEvent(createEvent({ type: 'connect', target: this })); + } else { + this.readyState = SocketIO.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + log('error', ("Socket.io connection to '" + (this.url) + "' failed")); + } + }, this); + + /** + Add an aliased event listener for close / disconnect + */ + this.addEventListener('close', function (event) { + this$1.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: event.target, + code: event.code + }) + ); + }); + } + + if ( EventTarget$$1 ) SocketIO.__proto__ = EventTarget$$1; + SocketIO.prototype = Object.create( EventTarget$$1 && EventTarget$$1.prototype ); + SocketIO.prototype.constructor = SocketIO; + + var prototypeAccessors = { broadcast: {} }; + + /* + * Closes the SocketIO connection or connection attempt, if any. + * If the connection is already CLOSED, this method does nothing. + */ + SocketIO.prototype.close = function close () { + if (this.readyState !== SocketIO.OPEN) { + return undefined; + } + + var server = networkBridge.serverLookup(this.url); + networkBridge.removeWebSocket(this, this.url); + + this.readyState = SocketIO.CLOSED; + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + if (server) { + server.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }), + server + ); + } + + return this; + }; + + /* + * Alias for Socket#close + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383 + */ + SocketIO.prototype.disconnect = function disconnect () { + return this.close(); + }; + + /* + * Submits an event to the server with a payload + */ + SocketIO.prototype.emit = function emit (event) { + var data = [], len = arguments.length - 1; + while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ]; + + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var messageEvent = createMessageEvent({ + type: event, + origin: this.url, + data: data + }); + + var server = networkBridge.serverLookup(this.url); + + if (server) { + server.dispatchEvent.apply(server, [ messageEvent ].concat( data )); + } + + return this; + }; + + /* + * Submits a 'message' event to the server. + * + * Should behave exactly like WebSocket#send + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113 + */ + SocketIO.prototype.send = function send (data) { + this.emit('message', data); + return this; + }; + + /* + * For broadcasting events to other connected sockets. + * + * e.g. socket.broadcast.emit('hi!'); + * e.g. socket.broadcast.to('my-room').emit('hi!'); + */ + prototypeAccessors.broadcast.get = function () { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + var self = this; + var server = networkBridge.serverLookup(this.url); + if (!server) { + throw new Error(("SocketIO can not find a server at the specified URL (" + (this.url) + ")")); + } + + return { + emit: function emit(event, data) { + server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) }); + return self; + }, + to: function to(room) { + return server.to(room, self); + }, + in: function in$1(room) { + return server.in(room, self); + } + }; + }; + + /* + * For registering events to be received from the server + */ + SocketIO.prototype.on = function on (type, callback) { + this.addEventListener(type, callback); + return this; + }; + + /* + * Remove event listener + * + * https://socket.io/docs/client-api/#socket-on-eventname-callback + */ + SocketIO.prototype.off = function off (type) { + this.removeEventListener(type); + }; + + /* + * Join a room on a server + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.join = function join (room) { + networkBridge.addMembershipToRoom(this, room); + }; + + /* + * Get the websocket to leave the room + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + SocketIO.prototype.leave = function leave (room) { + networkBridge.removeMembershipFromRoom(this, room); + }; + + SocketIO.prototype.to = function to (room) { + return this.broadcast.to(room); + }; + + SocketIO.prototype.in = function in$1 () { + return this.to.apply(null, arguments); + }; + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + SocketIO.prototype.dispatchEvent = function dispatchEvent (event) { + var this$1 = this; + var customArguments = [], len = arguments.length - 1; + while ( len-- > 0 ) customArguments[ len ] = arguments[ len + 1 ]; + + var eventName = event.type; + var listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(function (listener) { + if (customArguments.length > 0) { + listener.apply(this$1, customArguments); + } else { + // Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data + // payload instanceof MessageEvent works, but you can't isntance of NodeEvent + // for now we detect if the output has data defined on it + listener.call(this$1, event.data ? event.data : event); + } + }); + }; + + Object.defineProperties( SocketIO.prototype, prototypeAccessors ); + + return SocketIO; +}(EventTarget)); + +SocketIO$1.CONNECTING = 0; +SocketIO$1.OPEN = 1; +SocketIO$1.CLOSING = 2; +SocketIO$1.CLOSED = 3; + +/* +* Static constructor methods for the IO Socket +*/ +var IO = function ioConstructor(url, protocol) { + return new SocketIO$1(url, protocol); +}; + +/* +* Alias the raw IO() constructor +*/ +IO.connect = function ioConnect(url, protocol) { + /* eslint-disable new-cap */ + return IO(url, protocol); + /* eslint-enable new-cap */ +}; + +var Server = Server$1; +var WebSocket = WebSocket$1; +var SocketIO = IO; + +exports.Server = Server; +exports.WebSocket = WebSocket; +exports.SocketIO = SocketIO; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zb2NrZXQuanMiLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9yZXF1aXJlcy1wb3J0L2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5naWZ5L2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3VybC1wYXJzZS9pbmRleC5qcyIsIi4uL3NyYy9oZWxwZXJzL2RlbGF5LmpzIiwiLi4vc3JjL2hlbHBlcnMvbG9nZ2VyLmpzIiwiLi4vc3JjL2hlbHBlcnMvYXJyYXktaGVscGVycy5qcyIsIi4uL3NyYy9ldmVudC90YXJnZXQuanMiLCIuLi9zcmMvbmV0d29yay1icmlkZ2UuanMiLCIuLi9zcmMvY29uc3RhbnRzLmpzIiwiLi4vc3JjL2V2ZW50L3Byb3RvdHlwZS5qcyIsIi4uL3NyYy9ldmVudC9ldmVudC5qcyIsIi4uL3NyYy9ldmVudC9tZXNzYWdlLmpzIiwiLi4vc3JjL2V2ZW50L2Nsb3NlLmpzIiwiLi4vc3JjL2V2ZW50L2ZhY3RvcnkuanMiLCIuLi9zcmMvYWxnb3JpdGhtcy9jbG9zZS5qcyIsIi4uL3NyYy9oZWxwZXJzL25vcm1hbGl6ZS1zZW5kLmpzIiwiLi4vc3JjL2hlbHBlcnMvcHJveHktZmFjdG9yeS5qcyIsIi4uL3NyYy9oZWxwZXJzL2J5dGUtbGVuZ3RoLmpzIiwiLi4vc3JjL2hlbHBlcnMvdXJsLXZlcmlmaWNhdGlvbi5qcyIsIi4uL3NyYy9oZWxwZXJzL3Byb3RvY29sLXZlcmlmaWNhdGlvbi5qcyIsIi4uL3NyYy93ZWJzb2NrZXQuanMiLCIuLi9zcmMvaGVscGVycy9kZWR1cGUuanMiLCIuLi9zcmMvaGVscGVycy9nbG9iYWwtb2JqZWN0LmpzIiwiLi4vc3JjL3NlcnZlci5qcyIsIi4uL3NyYy9zb2NrZXQtaW8uanMiLCIuLi9zcmMvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIENoZWNrIGlmIHdlJ3JlIHJlcXVpcmVkIHRvIGFkZCBhIHBvcnQgbnVtYmVyLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly91cmwuc3BlYy53aGF0d2cub3JnLyNkZWZhdWx0LXBvcnRcbiAqIEBwYXJhbSB7TnVtYmVyfFN0cmluZ30gcG9ydCBQb3J0IG51bWJlciB3ZSBuZWVkIHRvIGNoZWNrXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJvdG9jb2wgUHJvdG9jb2wgd2UgbmVlZCB0byBjaGVjayBhZ2FpbnN0LlxuICogQHJldHVybnMge0Jvb2xlYW59IElzIGl0IGEgZGVmYXVsdCBwb3J0IGZvciB0aGUgZ2l2ZW4gcHJvdG9jb2xcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcXVpcmVkKHBvcnQsIHByb3RvY29sKSB7XG4gIHByb3RvY29sID0gcHJvdG9jb2wuc3BsaXQoJzonKVswXTtcbiAgcG9ydCA9ICtwb3J0O1xuXG4gIGlmICghcG9ydCkgcmV0dXJuIGZhbHNlO1xuXG4gIHN3aXRjaCAocHJvdG9jb2wpIHtcbiAgICBjYXNlICdodHRwJzpcbiAgICBjYXNlICd3cyc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDgwO1xuXG4gICAgY2FzZSAnaHR0cHMnOlxuICAgIGNhc2UgJ3dzcyc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDQ0MztcblxuICAgIGNhc2UgJ2Z0cCc6XG4gICAgcmV0dXJuIHBvcnQgIT09IDIxO1xuXG4gICAgY2FzZSAnZ29waGVyJzpcbiAgICByZXR1cm4gcG9ydCAhPT0gNzA7XG5cbiAgICBjYXNlICdmaWxlJzpcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gcG9ydCAhPT0gMDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIERlY29kZSBhIFVSSSBlbmNvZGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIFVSSSBlbmNvZGVkIHN0cmluZy5cbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBkZWNvZGVkIHN0cmluZy5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkZWNvZGUoaW5wdXQpIHtcbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChpbnB1dC5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG59XG5cbi8qKlxuICogU2ltcGxlIHF1ZXJ5IHN0cmluZyBwYXJzZXIuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHF1ZXJ5IFRoZSBxdWVyeSBzdHJpbmcgdGhhdCBuZWVkcyB0byBiZSBwYXJzZWQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gcXVlcnlzdHJpbmcocXVlcnkpIHtcbiAgdmFyIHBhcnNlciA9IC8oW149PyZdKyk9PyhbXiZdKikvZ1xuICAgICwgcmVzdWx0ID0ge31cbiAgICAsIHBhcnQ7XG5cbiAgd2hpbGUgKHBhcnQgPSBwYXJzZXIuZXhlYyhxdWVyeSkpIHtcbiAgICB2YXIga2V5ID0gZGVjb2RlKHBhcnRbMV0pXG4gICAgICAsIHZhbHVlID0gZGVjb2RlKHBhcnRbMl0pO1xuXG4gICAgLy9cbiAgICAvLyBQcmV2ZW50IG92ZXJyaWRpbmcgb2YgZXhpc3RpbmcgcHJvcGVydGllcy4gVGhpcyBlbnN1cmVzIHRoYXQgYnVpbGQtaW5cbiAgICAvLyBtZXRob2RzIGxpa2UgYHRvU3RyaW5nYCBvciBfX3Byb3RvX18gYXJlIG5vdCBvdmVycmlkZW4gYnkgbWFsaWNpb3VzXG4gICAgLy8gcXVlcnlzdHJpbmdzLlxuICAgIC8vXG4gICAgaWYgKGtleSBpbiByZXN1bHQpIGNvbnRpbnVlO1xuICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybSBhIHF1ZXJ5IHN0cmluZyB0byBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBPYmplY3QgdGhhdCBzaG91bGQgYmUgdHJhbnNmb3JtZWQuXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4IE9wdGlvbmFsIHByZWZpeC5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBxdWVyeXN0cmluZ2lmeShvYmosIHByZWZpeCkge1xuICBwcmVmaXggPSBwcmVmaXggfHwgJyc7XG5cbiAgdmFyIHBhaXJzID0gW107XG5cbiAgLy9cbiAgLy8gT3B0aW9uYWxseSBwcmVmaXggd2l0aCBhICc/JyBpZiBuZWVkZWRcbiAgLy9cbiAgaWYgKCdzdHJpbmcnICE9PSB0eXBlb2YgcHJlZml4KSBwcmVmaXggPSAnPyc7XG5cbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyc9JysgZW5jb2RlVVJJQ29tcG9uZW50KG9ialtrZXldKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhaXJzLmxlbmd0aCA/IHByZWZpeCArIHBhaXJzLmpvaW4oJyYnKSA6ICcnO1xufVxuXG4vL1xuLy8gRXhwb3NlIHRoZSBtb2R1bGUuXG4vL1xuZXhwb3J0cy5zdHJpbmdpZnkgPSBxdWVyeXN0cmluZ2lmeTtcbmV4cG9ydHMucGFyc2UgPSBxdWVyeXN0cmluZztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlcXVpcmVkID0gcmVxdWlyZSgncmVxdWlyZXMtcG9ydCcpXG4gICwgcXMgPSByZXF1aXJlKCdxdWVyeXN0cmluZ2lmeScpXG4gICwgcHJvdG9jb2xyZSA9IC9eKFthLXpdW2EtejAtOS4rLV0qOik/KFxcL1xcLyk/KFtcXFNcXHNdKikvaVxuICAsIHNsYXNoZXMgPSAvXltBLVphLXpdW0EtWmEtejAtOSstLl0qOlxcL1xcLy87XG5cbi8qKlxuICogVGhlc2UgYXJlIHRoZSBwYXJzZSBydWxlcyBmb3IgdGhlIFVSTCBwYXJzZXIsIGl0IGluZm9ybXMgdGhlIHBhcnNlclxuICogYWJvdXQ6XG4gKlxuICogMC4gVGhlIGNoYXIgaXQgTmVlZHMgdG8gcGFyc2UsIGlmIGl0J3MgYSBzdHJpbmcgaXQgc2hvdWxkIGJlIGRvbmUgdXNpbmdcbiAqICAgIGluZGV4T2YsIFJlZ0V4cCB1c2luZyBleGVjIGFuZCBOYU4gbWVhbnMgc2V0IGFzIGN1cnJlbnQgdmFsdWUuXG4gKiAxLiBUaGUgcHJvcGVydHkgd2Ugc2hvdWxkIHNldCB3aGVuIHBhcnNpbmcgdGhpcyB2YWx1ZS5cbiAqIDIuIEluZGljYXRpb24gaWYgaXQncyBiYWNrd2FyZHMgb3IgZm9yd2FyZCBwYXJzaW5nLCB3aGVuIHNldCBhcyBudW1iZXIgaXQnc1xuICogICAgdGhlIHZhbHVlIG9mIGV4dHJhIGNoYXJzIHRoYXQgc2hvdWxkIGJlIHNwbGl0IG9mZi5cbiAqIDMuIEluaGVyaXQgZnJvbSBsb2NhdGlvbiBpZiBub24gZXhpc3RpbmcgaW4gdGhlIHBhcnNlci5cbiAqIDQuIGB0b0xvd2VyQ2FzZWAgdGhlIHJlc3VsdGluZyB2YWx1ZS5cbiAqL1xudmFyIHJ1bGVzID0gW1xuICBbJyMnLCAnaGFzaCddLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgYmFjay5cbiAgWyc/JywgJ3F1ZXJ5J10sICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gdGhlIGJhY2suXG4gIFsnLycsICdwYXRobmFtZSddLCAgICAgICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBmcm9tIHRoZSBiYWNrLlxuICBbJ0AnLCAnYXV0aCcsIDFdLCAgICAgICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSB0aGUgZnJvbnQuXG4gIFtOYU4sICdob3N0JywgdW5kZWZpbmVkLCAxLCAxXSwgICAgICAgLy8gU2V0IGxlZnQgb3ZlciB2YWx1ZS5cbiAgWy86KFxcZCspJC8sICdwb3J0JywgdW5kZWZpbmVkLCAxXSwgICAgLy8gUmVnRXhwIHRoZSBiYWNrLlxuICBbTmFOLCAnaG9zdG5hbWUnLCB1bmRlZmluZWQsIDEsIDFdICAgIC8vIFNldCBsZWZ0IG92ZXIuXG5dO1xuXG4vKipcbiAqIFRoZXNlIHByb3BlcnRpZXMgc2hvdWxkIG5vdCBiZSBjb3BpZWQgb3IgaW5oZXJpdGVkIGZyb20uIFRoaXMgaXMgb25seSBuZWVkZWRcbiAqIGZvciBhbGwgbm9uIGJsb2IgVVJMJ3MgYXMgYSBibG9iIFVSTCBkb2VzIG5vdCBpbmNsdWRlIGEgaGFzaCwgb25seSB0aGVcbiAqIG9yaWdpbi5cbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByaXZhdGVcbiAqL1xudmFyIGlnbm9yZSA9IHsgaGFzaDogMSwgcXVlcnk6IDEgfTtcblxuLyoqXG4gKiBUaGUgbG9jYXRpb24gb2JqZWN0IGRpZmZlcnMgd2hlbiB5b3VyIGNvZGUgaXMgbG9hZGVkIHRocm91Z2ggYSBub3JtYWwgcGFnZSxcbiAqIFdvcmtlciBvciB0aHJvdWdoIGEgd29ya2VyIHVzaW5nIGEgYmxvYi4gQW5kIHdpdGggdGhlIGJsb2JibGUgYmVnaW5zIHRoZVxuICogdHJvdWJsZSBhcyB0aGUgbG9jYXRpb24gb2JqZWN0IHdpbGwgY29udGFpbiB0aGUgVVJMIG9mIHRoZSBibG9iLCBub3QgdGhlXG4gKiBsb2NhdGlvbiBvZiB0aGUgcGFnZSB3aGVyZSBvdXIgY29kZSBpcyBsb2FkZWQgaW4uIFRoZSBhY3R1YWwgb3JpZ2luIGlzXG4gKiBlbmNvZGVkIGluIHRoZSBgcGF0aG5hbWVgIHNvIHdlIGNhbiB0aGFua2Z1bGx5IGdlbmVyYXRlIGEgZ29vZCBcImRlZmF1bHRcIlxuICogbG9jYXRpb24gZnJvbSBpdCBzbyB3ZSBjYW4gZ2VuZXJhdGUgcHJvcGVyIHJlbGF0aXZlIFVSTCdzIGFnYWluLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gbG9jIE9wdGlvbmFsIGRlZmF1bHQgbG9jYXRpb24gb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gbG9sY2F0aW9uIG9iamVjdC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIGxvbGNhdGlvbihsb2MpIHtcbiAgdmFyIGxvY2F0aW9uID0gZ2xvYmFsICYmIGdsb2JhbC5sb2NhdGlvbiB8fCB7fTtcbiAgbG9jID0gbG9jIHx8IGxvY2F0aW9uO1xuXG4gIHZhciBmaW5hbGRlc3RpbmF0aW9uID0ge31cbiAgICAsIHR5cGUgPSB0eXBlb2YgbG9jXG4gICAgLCBrZXk7XG5cbiAgaWYgKCdibG9iOicgPT09IGxvYy5wcm90b2NvbCkge1xuICAgIGZpbmFsZGVzdGluYXRpb24gPSBuZXcgVVJMKHVuZXNjYXBlKGxvYy5wYXRobmFtZSksIHt9KTtcbiAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PT0gdHlwZSkge1xuICAgIGZpbmFsZGVzdGluYXRpb24gPSBuZXcgVVJMKGxvYywge30pO1xuICAgIGZvciAoa2V5IGluIGlnbm9yZSkgZGVsZXRlIGZpbmFsZGVzdGluYXRpb25ba2V5XTtcbiAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PT0gdHlwZSkge1xuICAgIGZvciAoa2V5IGluIGxvYykge1xuICAgICAgaWYgKGtleSBpbiBpZ25vcmUpIGNvbnRpbnVlO1xuICAgICAgZmluYWxkZXN0aW5hdGlvbltrZXldID0gbG9jW2tleV07XG4gICAgfVxuXG4gICAgaWYgKGZpbmFsZGVzdGluYXRpb24uc2xhc2hlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaW5hbGRlc3RpbmF0aW9uLnNsYXNoZXMgPSBzbGFzaGVzLnRlc3QobG9jLmhyZWYpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmaW5hbGRlc3RpbmF0aW9uO1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIFByb3RvY29sRXh0cmFjdFxuICogQHR5cGUgT2JqZWN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gcHJvdG9jb2wgUHJvdG9jb2wgbWF0Y2hlZCBpbiB0aGUgVVJMLCBpbiBsb3dlcmNhc2UuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNsYXNoZXMgYHRydWVgIGlmIHByb3RvY29sIGlzIGZvbGxvd2VkIGJ5IFwiLy9cIiwgZWxzZSBgZmFsc2VgLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlc3QgUmVzdCBvZiB0aGUgVVJMIHRoYXQgaXMgbm90IHBhcnQgb2YgdGhlIHByb3RvY29sLlxuICovXG5cbi8qKlxuICogRXh0cmFjdCBwcm90b2NvbCBpbmZvcm1hdGlvbiBmcm9tIGEgVVJMIHdpdGgvd2l0aG91dCBkb3VibGUgc2xhc2ggKFwiLy9cIikuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgVVJMIHdlIHdhbnQgdG8gZXh0cmFjdCBmcm9tLlxuICogQHJldHVybiB7UHJvdG9jb2xFeHRyYWN0fSBFeHRyYWN0ZWQgaW5mb3JtYXRpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdFByb3RvY29sKGFkZHJlc3MpIHtcbiAgdmFyIG1hdGNoID0gcHJvdG9jb2xyZS5leGVjKGFkZHJlc3MpO1xuXG4gIHJldHVybiB7XG4gICAgcHJvdG9jb2w6IG1hdGNoWzFdID8gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKSA6ICcnLFxuICAgIHNsYXNoZXM6ICEhbWF0Y2hbMl0sXG4gICAgcmVzdDogbWF0Y2hbM11cbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcmVsYXRpdmUgVVJMIHBhdGhuYW1lIGFnYWluc3QgYSBiYXNlIFVSTCBwYXRobmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVsYXRpdmUgUGF0aG5hbWUgb2YgdGhlIHJlbGF0aXZlIFVSTC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlIFBhdGhuYW1lIG9mIHRoZSBiYXNlIFVSTC5cbiAqIEByZXR1cm4ge1N0cmluZ30gUmVzb2x2ZWQgcGF0aG5hbWUuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZShyZWxhdGl2ZSwgYmFzZSkge1xuICB2YXIgcGF0aCA9IChiYXNlIHx8ICcvJykuc3BsaXQoJy8nKS5zbGljZSgwLCAtMSkuY29uY2F0KHJlbGF0aXZlLnNwbGl0KCcvJykpXG4gICAgLCBpID0gcGF0aC5sZW5ndGhcbiAgICAsIGxhc3QgPSBwYXRoW2kgLSAxXVxuICAgICwgdW5zaGlmdCA9IGZhbHNlXG4gICAgLCB1cCA9IDA7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIGlmIChwYXRoW2ldID09PSAnLicpIHtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAocGF0aFtpXSA9PT0gJy4uJykge1xuICAgICAgcGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIGlmIChpID09PSAwKSB1bnNoaWZ0ID0gdHJ1ZTtcbiAgICAgIHBhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICBpZiAodW5zaGlmdCkgcGF0aC51bnNoaWZ0KCcnKTtcbiAgaWYgKGxhc3QgPT09ICcuJyB8fCBsYXN0ID09PSAnLi4nKSBwYXRoLnB1c2goJycpO1xuXG4gIHJldHVybiBwYXRoLmpvaW4oJy8nKTtcbn1cblxuLyoqXG4gKiBUaGUgYWN0dWFsIFVSTCBpbnN0YW5jZS4gSW5zdGVhZCBvZiByZXR1cm5pbmcgYW4gb2JqZWN0IHdlJ3ZlIG9wdGVkLWluIHRvXG4gKiBjcmVhdGUgYW4gYWN0dWFsIGNvbnN0cnVjdG9yIGFzIGl0J3MgbXVjaCBtb3JlIG1lbW9yeSBlZmZpY2llbnQgYW5kXG4gKiBmYXN0ZXIgYW5kIGl0IHBsZWFzZXMgbXkgT0NELlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgVVJMIHdlIHdhbnQgdG8gcGFyc2UuXG4gKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGxvY2F0aW9uIExvY2F0aW9uIGRlZmF1bHRzIGZvciByZWxhdGl2ZSBwYXRocy5cbiAqIEBwYXJhbSB7Qm9vbGVhbnxGdW5jdGlvbn0gcGFyc2VyIFBhcnNlciBmb3IgdGhlIHF1ZXJ5IHN0cmluZy5cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIFVSTChhZGRyZXNzLCBsb2NhdGlvbiwgcGFyc2VyKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBVUkwpKSB7XG4gICAgcmV0dXJuIG5ldyBVUkwoYWRkcmVzcywgbG9jYXRpb24sIHBhcnNlcik7XG4gIH1cblxuICB2YXIgcmVsYXRpdmUsIGV4dHJhY3RlZCwgcGFyc2UsIGluc3RydWN0aW9uLCBpbmRleCwga2V5XG4gICAgLCBpbnN0cnVjdGlvbnMgPSBydWxlcy5zbGljZSgpXG4gICAgLCB0eXBlID0gdHlwZW9mIGxvY2F0aW9uXG4gICAgLCB1cmwgPSB0aGlzXG4gICAgLCBpID0gMDtcblxuICAvL1xuICAvLyBUaGUgZm9sbG93aW5nIGlmIHN0YXRlbWVudHMgYWxsb3dzIHRoaXMgbW9kdWxlIHR3byBoYXZlIGNvbXBhdGliaWxpdHkgd2l0aFxuICAvLyAyIGRpZmZlcmVudCBBUEk6XG4gIC8vXG4gIC8vIDEuIE5vZGUuanMncyBgdXJsLnBhcnNlYCBhcGkgd2hpY2ggYWNjZXB0cyBhIFVSTCwgYm9vbGVhbiBhcyBhcmd1bWVudHNcbiAgLy8gICAgd2hlcmUgdGhlIGJvb2xlYW4gaW5kaWNhdGVzIHRoYXQgdGhlIHF1ZXJ5IHN0cmluZyBzaG91bGQgYWxzbyBiZSBwYXJzZWQuXG4gIC8vXG4gIC8vIDIuIFRoZSBgVVJMYCBpbnRlcmZhY2Ugb2YgdGhlIGJyb3dzZXIgd2hpY2ggYWNjZXB0cyBhIFVSTCwgb2JqZWN0IGFzXG4gIC8vICAgIGFyZ3VtZW50cy4gVGhlIHN1cHBsaWVkIG9iamVjdCB3aWxsIGJlIHVzZWQgYXMgZGVmYXVsdCB2YWx1ZXMgLyBmYWxsLWJhY2tcbiAgLy8gICAgZm9yIHJlbGF0aXZlIHBhdGhzLlxuICAvL1xuICBpZiAoJ29iamVjdCcgIT09IHR5cGUgJiYgJ3N0cmluZycgIT09IHR5cGUpIHtcbiAgICBwYXJzZXIgPSBsb2NhdGlvbjtcbiAgICBsb2NhdGlvbiA9IG51bGw7XG4gIH1cblxuICBpZiAocGFyc2VyICYmICdmdW5jdGlvbicgIT09IHR5cGVvZiBwYXJzZXIpIHBhcnNlciA9IHFzLnBhcnNlO1xuXG4gIGxvY2F0aW9uID0gbG9sY2F0aW9uKGxvY2F0aW9uKTtcblxuICAvL1xuICAvLyBFeHRyYWN0IHByb3RvY29sIGluZm9ybWF0aW9uIGJlZm9yZSBydW5uaW5nIHRoZSBpbnN0cnVjdGlvbnMuXG4gIC8vXG4gIGV4dHJhY3RlZCA9IGV4dHJhY3RQcm90b2NvbChhZGRyZXNzIHx8ICcnKTtcbiAgcmVsYXRpdmUgPSAhZXh0cmFjdGVkLnByb3RvY29sICYmICFleHRyYWN0ZWQuc2xhc2hlcztcbiAgdXJsLnNsYXNoZXMgPSBleHRyYWN0ZWQuc2xhc2hlcyB8fCByZWxhdGl2ZSAmJiBsb2NhdGlvbi5zbGFzaGVzO1xuICB1cmwucHJvdG9jb2wgPSBleHRyYWN0ZWQucHJvdG9jb2wgfHwgbG9jYXRpb24ucHJvdG9jb2wgfHwgJyc7XG4gIGFkZHJlc3MgPSBleHRyYWN0ZWQucmVzdDtcblxuICAvL1xuICAvLyBXaGVuIHRoZSBhdXRob3JpdHkgY29tcG9uZW50IGlzIGFic2VudCB0aGUgVVJMIHN0YXJ0cyB3aXRoIGEgcGF0aFxuICAvLyBjb21wb25lbnQuXG4gIC8vXG4gIGlmICghZXh0cmFjdGVkLnNsYXNoZXMpIGluc3RydWN0aW9uc1syXSA9IFsvKC4qKS8sICdwYXRobmFtZSddO1xuXG4gIGZvciAoOyBpIDwgaW5zdHJ1Y3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgaW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbnNbaV07XG4gICAgcGFyc2UgPSBpbnN0cnVjdGlvblswXTtcbiAgICBrZXkgPSBpbnN0cnVjdGlvblsxXTtcblxuICAgIGlmIChwYXJzZSAhPT0gcGFyc2UpIHtcbiAgICAgIHVybFtrZXldID0gYWRkcmVzcztcbiAgICB9IGVsc2UgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgcGFyc2UpIHtcbiAgICAgIGlmICh+KGluZGV4ID0gYWRkcmVzcy5pbmRleE9mKHBhcnNlKSkpIHtcbiAgICAgICAgaWYgKCdudW1iZXInID09PSB0eXBlb2YgaW5zdHJ1Y3Rpb25bMl0pIHtcbiAgICAgICAgICB1cmxba2V5XSA9IGFkZHJlc3Muc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKGluZGV4ICsgaW5zdHJ1Y3Rpb25bMl0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHVybFtrZXldID0gYWRkcmVzcy5zbGljZShpbmRleCk7XG4gICAgICAgICAgYWRkcmVzcyA9IGFkZHJlc3Muc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICgoaW5kZXggPSBwYXJzZS5leGVjKGFkZHJlc3MpKSkge1xuICAgICAgdXJsW2tleV0gPSBpbmRleFsxXTtcbiAgICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDAsIGluZGV4LmluZGV4KTtcbiAgICB9XG5cbiAgICB1cmxba2V5XSA9IHVybFtrZXldIHx8IChcbiAgICAgIHJlbGF0aXZlICYmIGluc3RydWN0aW9uWzNdID8gbG9jYXRpb25ba2V5XSB8fCAnJyA6ICcnXG4gICAgKTtcblxuICAgIC8vXG4gICAgLy8gSG9zdG5hbWUsIGhvc3QgYW5kIHByb3RvY29sIHNob3VsZCBiZSBsb3dlcmNhc2VkIHNvIHRoZXkgY2FuIGJlIHVzZWQgdG9cbiAgICAvLyBjcmVhdGUgYSBwcm9wZXIgYG9yaWdpbmAuXG4gICAgLy9cbiAgICBpZiAoaW5zdHJ1Y3Rpb25bNF0pIHVybFtrZXldID0gdXJsW2tleV0udG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8vXG4gIC8vIEFsc28gcGFyc2UgdGhlIHN1cHBsaWVkIHF1ZXJ5IHN0cmluZyBpbiB0byBhbiBvYmplY3QuIElmIHdlJ3JlIHN1cHBsaWVkXG4gIC8vIHdpdGggYSBjdXN0b20gcGFyc2VyIGFzIGZ1bmN0aW9uIHVzZSB0aGF0IGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgYnVpbGQtaW5cbiAgLy8gcGFyc2VyLlxuICAvL1xuICBpZiAocGFyc2VyKSB1cmwucXVlcnkgPSBwYXJzZXIodXJsLnF1ZXJ5KTtcblxuICAvL1xuICAvLyBJZiB0aGUgVVJMIGlzIHJlbGF0aXZlLCByZXNvbHZlIHRoZSBwYXRobmFtZSBhZ2FpbnN0IHRoZSBiYXNlIFVSTC5cbiAgLy9cbiAgaWYgKFxuICAgICAgcmVsYXRpdmVcbiAgICAmJiBsb2NhdGlvbi5zbGFzaGVzXG4gICAgJiYgdXJsLnBhdGhuYW1lLmNoYXJBdCgwKSAhPT0gJy8nXG4gICAgJiYgKHVybC5wYXRobmFtZSAhPT0gJycgfHwgbG9jYXRpb24ucGF0aG5hbWUgIT09ICcnKVxuICApIHtcbiAgICB1cmwucGF0aG5hbWUgPSByZXNvbHZlKHVybC5wYXRobmFtZSwgbG9jYXRpb24ucGF0aG5hbWUpO1xuICB9XG5cbiAgLy9cbiAgLy8gV2Ugc2hvdWxkIG5vdCBhZGQgcG9ydCBudW1iZXJzIGlmIHRoZXkgYXJlIGFscmVhZHkgdGhlIGRlZmF1bHQgcG9ydCBudW1iZXJcbiAgLy8gZm9yIGEgZ2l2ZW4gcHJvdG9jb2wuIEFzIHRoZSBob3N0IGFsc28gY29udGFpbnMgdGhlIHBvcnQgbnVtYmVyIHdlJ3JlIGdvaW5nXG4gIC8vIG92ZXJyaWRlIGl0IHdpdGggdGhlIGhvc3RuYW1lIHdoaWNoIGNvbnRhaW5zIG5vIHBvcnQgbnVtYmVyLlxuICAvL1xuICBpZiAoIXJlcXVpcmVkKHVybC5wb3J0LCB1cmwucHJvdG9jb2wpKSB7XG4gICAgdXJsLmhvc3QgPSB1cmwuaG9zdG5hbWU7XG4gICAgdXJsLnBvcnQgPSAnJztcbiAgfVxuXG4gIC8vXG4gIC8vIFBhcnNlIGRvd24gdGhlIGBhdXRoYCBmb3IgdGhlIHVzZXJuYW1lIGFuZCBwYXNzd29yZC5cbiAgLy9cbiAgdXJsLnVzZXJuYW1lID0gdXJsLnBhc3N3b3JkID0gJyc7XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIGluc3RydWN0aW9uID0gdXJsLmF1dGguc3BsaXQoJzonKTtcbiAgICB1cmwudXNlcm5hbWUgPSBpbnN0cnVjdGlvblswXSB8fCAnJztcbiAgICB1cmwucGFzc3dvcmQgPSBpbnN0cnVjdGlvblsxXSB8fCAnJztcbiAgfVxuXG4gIHVybC5vcmlnaW4gPSB1cmwucHJvdG9jb2wgJiYgdXJsLmhvc3QgJiYgdXJsLnByb3RvY29sICE9PSAnZmlsZTonXG4gICAgPyB1cmwucHJvdG9jb2wgKycvLycrIHVybC5ob3N0XG4gICAgOiAnbnVsbCc7XG5cbiAgLy9cbiAgLy8gVGhlIGhyZWYgaXMganVzdCB0aGUgY29tcGlsZWQgcmVzdWx0LlxuICAvL1xuICB1cmwuaHJlZiA9IHVybC50b1N0cmluZygpO1xufVxuXG4vKipcbiAqIFRoaXMgaXMgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjaGFuZ2luZyBwcm9wZXJ0aWVzIGluIHRoZSBVUkwgaW5zdGFuY2UgdG9cbiAqIGluc3VyZSB0aGF0IHRoZXkgYWxsIHByb3BhZ2F0ZSBjb3JyZWN0bHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhcnQgICAgICAgICAgUHJvcGVydHkgd2UgbmVlZCB0byBhZGp1c3QuXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSAgICAgICAgICBUaGUgbmV3bHkgYXNzaWduZWQgdmFsdWUuXG4gKiBAcGFyYW0ge0Jvb2xlYW58RnVuY3Rpb259IGZuICBXaGVuIHNldHRpbmcgdGhlIHF1ZXJ5LCBpdCB3aWxsIGJlIHRoZSBmdW5jdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlZCB0byBwYXJzZSB0aGUgcXVlcnkuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaGVuIHNldHRpbmcgdGhlIHByb3RvY29sLCBkb3VibGUgc2xhc2ggd2lsbCBiZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCBmcm9tIHRoZSBmaW5hbCB1cmwgaWYgaXQgaXMgdHJ1ZS5cbiAqIEByZXR1cm5zIHtVUkx9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBzZXQocGFydCwgdmFsdWUsIGZuKSB7XG4gIHZhciB1cmwgPSB0aGlzO1xuXG4gIHN3aXRjaCAocGFydCkge1xuICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHZhbHVlICYmIHZhbHVlLmxlbmd0aCkge1xuICAgICAgICB2YWx1ZSA9IChmbiB8fCBxcy5wYXJzZSkodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAncG9ydCc6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcblxuICAgICAgaWYgKCFyZXF1aXJlZCh2YWx1ZSwgdXJsLnByb3RvY29sKSkge1xuICAgICAgICB1cmwuaG9zdCA9IHVybC5ob3N0bmFtZTtcbiAgICAgICAgdXJsW3BhcnRdID0gJyc7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlKSB7XG4gICAgICAgIHVybC5ob3N0ID0gdXJsLmhvc3RuYW1lICsnOicrIHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2hvc3RuYW1lJzpcbiAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuXG4gICAgICBpZiAodXJsLnBvcnQpIHZhbHVlICs9ICc6JysgdXJsLnBvcnQ7XG4gICAgICB1cmwuaG9zdCA9IHZhbHVlO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdob3N0JzpcbiAgICAgIHVybFtwYXJ0XSA9IHZhbHVlO1xuXG4gICAgICBpZiAoLzpcXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5zcGxpdCgnOicpO1xuICAgICAgICB1cmwucG9ydCA9IHZhbHVlLnBvcCgpO1xuICAgICAgICB1cmwuaG9zdG5hbWUgPSB2YWx1ZS5qb2luKCc6Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmwuaG9zdG5hbWUgPSB2YWx1ZTtcbiAgICAgICAgdXJsLnBvcnQgPSAnJztcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwcm90b2NvbCc6XG4gICAgICB1cmwucHJvdG9jb2wgPSB2YWx1ZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdXJsLnNsYXNoZXMgPSAhZm47XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3BhdGhuYW1lJzpcbiAgICBjYXNlICdoYXNoJzpcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB2YXIgY2hhciA9IHBhcnQgPT09ICdwYXRobmFtZScgPyAnLycgOiAnIyc7XG4gICAgICAgIHVybFtwYXJ0XSA9IHZhbHVlLmNoYXJBdCgwKSAhPT0gY2hhciA/IGNoYXIgKyB2YWx1ZSA6IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJsW3BhcnRdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB1cmxbcGFydF0gPSB2YWx1ZTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaW5zID0gcnVsZXNbaV07XG5cbiAgICBpZiAoaW5zWzRdKSB1cmxbaW5zWzFdXSA9IHVybFtpbnNbMV1dLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICB1cmwub3JpZ2luID0gdXJsLnByb3RvY29sICYmIHVybC5ob3N0ICYmIHVybC5wcm90b2NvbCAhPT0gJ2ZpbGU6J1xuICAgID8gdXJsLnByb3RvY29sICsnLy8nKyB1cmwuaG9zdFxuICAgIDogJ251bGwnO1xuXG4gIHVybC5ocmVmID0gdXJsLnRvU3RyaW5nKCk7XG5cbiAgcmV0dXJuIHVybDtcbn1cblxuLyoqXG4gKiBUcmFuc2Zvcm0gdGhlIHByb3BlcnRpZXMgYmFjayBpbiB0byBhIHZhbGlkIGFuZCBmdWxsIFVSTCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5naWZ5IE9wdGlvbmFsIHF1ZXJ5IHN0cmluZ2lmeSBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB0b1N0cmluZyhzdHJpbmdpZnkpIHtcbiAgaWYgKCFzdHJpbmdpZnkgfHwgJ2Z1bmN0aW9uJyAhPT0gdHlwZW9mIHN0cmluZ2lmeSkgc3RyaW5naWZ5ID0gcXMuc3RyaW5naWZ5O1xuXG4gIHZhciBxdWVyeVxuICAgICwgdXJsID0gdGhpc1xuICAgICwgcHJvdG9jb2wgPSB1cmwucHJvdG9jb2w7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJBdChwcm90b2NvbC5sZW5ndGggLSAxKSAhPT0gJzonKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIHJlc3VsdCA9IHByb3RvY29sICsgKHVybC5zbGFzaGVzID8gJy8vJyA6ICcnKTtcblxuICBpZiAodXJsLnVzZXJuYW1lKSB7XG4gICAgcmVzdWx0ICs9IHVybC51c2VybmFtZTtcbiAgICBpZiAodXJsLnBhc3N3b3JkKSByZXN1bHQgKz0gJzonKyB1cmwucGFzc3dvcmQ7XG4gICAgcmVzdWx0ICs9ICdAJztcbiAgfVxuXG4gIHJlc3VsdCArPSB1cmwuaG9zdCArIHVybC5wYXRobmFtZTtcblxuICBxdWVyeSA9ICdvYmplY3QnID09PSB0eXBlb2YgdXJsLnF1ZXJ5ID8gc3RyaW5naWZ5KHVybC5xdWVyeSkgOiB1cmwucXVlcnk7XG4gIGlmIChxdWVyeSkgcmVzdWx0ICs9ICc/JyAhPT0gcXVlcnkuY2hhckF0KDApID8gJz8nKyBxdWVyeSA6IHF1ZXJ5O1xuXG4gIGlmICh1cmwuaGFzaCkgcmVzdWx0ICs9IHVybC5oYXNoO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblVSTC5wcm90b3R5cGUgPSB7IHNldDogc2V0LCB0b1N0cmluZzogdG9TdHJpbmcgfTtcblxuLy9cbi8vIEV4cG9zZSB0aGUgVVJMIHBhcnNlciBhbmQgc29tZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdGhhdCBtaWdodCBiZSB1c2VmdWwgZm9yXG4vLyBvdGhlcnMgb3IgdGVzdGluZy5cbi8vXG5VUkwuZXh0cmFjdFByb3RvY29sID0gZXh0cmFjdFByb3RvY29sO1xuVVJMLmxvY2F0aW9uID0gbG9sY2F0aW9uO1xuVVJMLnFzID0gcXM7XG5cbm1vZHVsZS5leHBvcnRzID0gVVJMO1xuIiwiLypcbiogVGhpcyBkZWxheSBhbGxvd3MgdGhlIHRocmVhZCB0byBmaW5pc2ggYXNzaWduaW5nIGl0cyBvbiogbWV0aG9kc1xuKiBiZWZvcmUgaW52b2tpbmcgdGhlIGRlbGF5IGNhbGxiYWNrLiBUaGlzIGlzIHB1cmVseSBhIHRpbWluZyBoYWNrLlxuKiBodHRwOi8vZ2Vla2FieXRlLmJsb2dzcG90LmNvbS8yMDE0LzAxL2phdmFzY3JpcHQtZWZmZWN0LW9mLXNldHRpbmctc2V0dGltZW91dC5odG1sXG4qXG4qIEBwYXJhbSB7Y2FsbGJhY2s6IGZ1bmN0aW9ufSB0aGUgY2FsbGJhY2sgd2hpY2ggd2lsbCBiZSBpbnZva2VkIGFmdGVyIHRoZSB0aW1lb3V0XG4qIEBwYXJtYSB7Y29udGV4dDogb2JqZWN0fSB0aGUgY29udGV4dCBpbiB3aGljaCB0byBpbnZva2UgdGhlIGZ1bmN0aW9uXG4qL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVsYXkoY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgc2V0VGltZW91dCh0aW1lb3V0Q29udGV4dCA9PiBjYWxsYmFjay5jYWxsKHRpbWVvdXRDb250ZXh0KSwgNCwgY29udGV4dCk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBsb2cobWV0aG9kLCBtZXNzYWdlKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgY29uc29sZVttZXRob2RdLmNhbGwobnVsbCwgbWVzc2FnZSk7XG4gIH1cbiAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG59XG4iLCJleHBvcnQgZnVuY3Rpb24gcmVqZWN0KGFycmF5LCBjYWxsYmFjaykge1xuICBjb25zdCByZXN1bHRzID0gW107XG4gIGFycmF5LmZvckVhY2goaXRlbUluQXJyYXkgPT4ge1xuICAgIGlmICghY2FsbGJhY2soaXRlbUluQXJyYXkpKSB7XG4gICAgICByZXN1bHRzLnB1c2goaXRlbUluQXJyYXkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXIoYXJyYXksIGNhbGxiYWNrKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgYXJyYXkuZm9yRWFjaChpdGVtSW5BcnJheSA9PiB7XG4gICAgaWYgKGNhbGxiYWNrKGl0ZW1JbkFycmF5KSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGl0ZW1JbkFycmF5KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHRzO1xufVxuIiwiaW1wb3J0IHsgcmVqZWN0LCBmaWx0ZXIgfSBmcm9tICcuLi9oZWxwZXJzL2FycmF5LWhlbHBlcnMnO1xuXG4vKlxuKiBFdmVudFRhcmdldCBpcyBhbiBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgb2JqZWN0cyB0aGF0IGNhblxuKiByZWNlaXZlIGV2ZW50cyBhbmQgbWF5IGhhdmUgbGlzdGVuZXJzIGZvciB0aGVtLlxuKlxuKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXRcbiovXG5jbGFzcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubGlzdGVuZXJzID0ge307XG4gIH1cblxuICAvKlxuICAqIFRpZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhbiBldmVudCB0eXBlIHdoaWNoIGNhbiBsYXRlciBiZSBpbnZva2VkIHZpYSB0aGVcbiAgKiBkaXNwYXRjaEV2ZW50IG1ldGhvZC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gdGhlIHR5cGUgb2YgZXZlbnQgKGllOiAnb3BlbicsICdtZXNzYWdlJywgZXRjLilcbiAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lciAtIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBpbnZva2Ugd2hlbmV2ZXIgYW4gZXZlbnQgaXMgZGlzcGF0Y2hlZCBtYXRjaGluZyB0aGUgZ2l2ZW4gdHlwZVxuICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlQ2FwdHVyZSAtIE4vQSBUT0RPOiBpbXBsZW1lbnQgdXNlQ2FwdHVyZSBmdW5jdGlvbmFsaXR5XG4gICovXG4gIGFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIgLyogLCB1c2VDYXB0dXJlICovKSB7XG4gICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMubGlzdGVuZXJzW3R5cGVdKSkge1xuICAgICAgICB0aGlzLmxpc3RlbmVyc1t0eXBlXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICAvLyBPbmx5IGFkZCB0aGUgc2FtZSBmdW5jdGlvbiBvbmNlXG4gICAgICBpZiAoZmlsdGVyKHRoaXMubGlzdGVuZXJzW3R5cGVdLCBpdGVtID0+IGl0ZW0gPT09IGxpc3RlbmVyKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBzbyBpdCB3aWxsIG5vIGxvbmdlciBiZSBpbnZva2VkIHZpYSB0aGUgZGlzcGF0Y2hFdmVudCBtZXRob2QuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIHRoZSB0eXBlIG9mIGV2ZW50IChpZTogJ29wZW4nLCAnbWVzc2FnZScsIGV0Yy4pXG4gICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWQgbWF0Y2hpbmcgdGhlIGdpdmVuIHR5cGVcbiAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUNhcHR1cmUgLSBOL0EgVE9ETzogaW1wbGVtZW50IHVzZUNhcHR1cmUgZnVuY3Rpb25hbGl0eVxuICAqL1xuICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHJlbW92aW5nTGlzdGVuZXIgLyogLCB1c2VDYXB0dXJlICovKSB7XG4gICAgY29uc3QgYXJyYXlPZkxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzW3R5cGVdO1xuICAgIHRoaXMubGlzdGVuZXJzW3R5cGVdID0gcmVqZWN0KGFycmF5T2ZMaXN0ZW5lcnMsIGxpc3RlbmVyID0+IGxpc3RlbmVyID09PSByZW1vdmluZ0xpc3RlbmVyKTtcbiAgfVxuXG4gIC8qXG4gICogSW52b2tlcyBhbGwgbGlzdGVuZXIgZnVuY3Rpb25zIHRoYXQgYXJlIGxpc3RlbmluZyB0byB0aGUgZ2l2ZW4gZXZlbnQudHlwZSBwcm9wZXJ0eS4gRWFjaFxuICAqIGxpc3RlbmVyIHdpbGwgYmUgcGFzc2VkIHRoZSBldmVudCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICpcbiAgKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBldmVudCBvYmplY3Qgd2hpY2ggd2lsbCBiZSBwYXNzZWQgdG8gYWxsIGxpc3RlbmVycyBvZiB0aGUgZXZlbnQudHlwZSBwcm9wZXJ0eVxuICAqL1xuICBkaXNwYXRjaEV2ZW50KGV2ZW50LCAuLi5jdXN0b21Bcmd1bWVudHMpIHtcbiAgICBjb25zdCBldmVudE5hbWUgPSBldmVudC50eXBlO1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzW2V2ZW50TmFtZV07XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdGVuZXJzKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcbiAgICAgIGlmIChjdXN0b21Bcmd1bWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBjdXN0b21Bcmd1bWVudHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudFRhcmdldDtcbiIsImltcG9ydCB7IHJlamVjdCB9IGZyb20gJy4vaGVscGVycy9hcnJheS1oZWxwZXJzJztcblxuLypcbiogVGhlIG5ldHdvcmsgYnJpZGdlIGlzIGEgd2F5IGZvciB0aGUgbW9jayB3ZWJzb2NrZXQgb2JqZWN0IHRvICdjb21tdW5pY2F0ZScgd2l0aFxuKiBhbGwgYXZhaWxhYmxlIHNlcnZlcnMuIFRoaXMgaXMgYSBzaW5nbGV0b24gb2JqZWN0IHNvIGl0IGlzIGltcG9ydGFudCB0aGF0IHlvdVxuKiBjbGVhbiB1cCB1cmxNYXAgd2hlbmV2ZXIgeW91IGFyZSBmaW5pc2hlZC5cbiovXG5jbGFzcyBOZXR3b3JrQnJpZGdlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy51cmxNYXAgPSB7fTtcbiAgfVxuXG4gIC8qXG4gICogQXR0YWNoZXMgYSB3ZWJzb2NrZXQgb2JqZWN0IHRvIHRoZSB1cmxNYXAgaGFzaCBzbyB0aGF0IGl0IGNhbiBmaW5kIHRoZSBzZXJ2ZXJcbiAgKiBpdCBpcyBjb25uZWN0ZWQgdG8gYW5kIHRoZSBzZXJ2ZXIgaW4gdHVybiBjYW4gZmluZCBpdC5cbiAgKlxuICAqIEBwYXJhbSB7b2JqZWN0fSB3ZWJzb2NrZXQgLSB3ZWJzb2NrZXQgb2JqZWN0IHRvIGFkZCB0byB0aGUgdXJsTWFwIGhhc2hcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIGF0dGFjaFdlYlNvY2tldCh3ZWJzb2NrZXQsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXAgJiYgY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXIgJiYgY29ubmVjdGlvbkxvb2t1cC53ZWJzb2NrZXRzLmluZGV4T2Yod2Vic29ja2V0KSA9PT0gLTEpIHtcbiAgICAgIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cy5wdXNoKHdlYnNvY2tldCk7XG4gICAgICByZXR1cm4gY29ubmVjdGlvbkxvb2t1cC5zZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBBdHRhY2hlcyBhIHdlYnNvY2tldCB0byBhIHJvb21cbiAgKi9cbiAgYWRkTWVtYmVyc2hpcFRvUm9vbSh3ZWJzb2NrZXQsIHJvb20pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbd2Vic29ja2V0LnVybF07XG5cbiAgICBpZiAoY29ubmVjdGlvbkxvb2t1cCAmJiBjb25uZWN0aW9uTG9va3VwLnNlcnZlciAmJiBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMuaW5kZXhPZih3ZWJzb2NrZXQpICE9PSAtMSkge1xuICAgICAgaWYgKCFjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSkge1xuICAgICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXS5wdXNoKHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBBdHRhY2hlcyBhIHNlcnZlciBvYmplY3QgdG8gdGhlIHVybE1hcCBoYXNoIHNvIHRoYXQgaXQgY2FuIGZpbmQgYSB3ZWJzb2NrZXRzXG4gICogd2hpY2ggYXJlIGNvbm5lY3RlZCB0byBpdCBhbmQgc28gdGhhdCB3ZWJzb2NrZXRzIGNhbiBpbiB0dXJuIGNhbiBmaW5kIGl0LlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IHNlcnZlciAtIHNlcnZlciBvYmplY3QgdG8gYWRkIHRvIHRoZSB1cmxNYXAgaGFzaFxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgYXR0YWNoU2VydmVyKHNlcnZlciwgdXJsKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkxvb2t1cCA9IHRoaXMudXJsTWFwW3VybF07XG5cbiAgICBpZiAoIWNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIHRoaXMudXJsTWFwW3VybF0gPSB7XG4gICAgICAgIHNlcnZlcixcbiAgICAgICAgd2Vic29ja2V0czogW10sXG4gICAgICAgIHJvb21NZW1iZXJzaGlwczoge31cbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBzZXJ2ZXI7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBGaW5kcyB0aGUgc2VydmVyIHdoaWNoIGlzICdydW5uaW5nJyBvbiB0aGUgZ2l2ZW4gdXJsLlxuICAqXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIHRoZSB1cmwgdG8gdXNlIHRvIGZpbmQgd2hpY2ggc2VydmVyIGlzIHJ1bm5pbmcgb24gaXRcbiAgKi9cbiAgc2VydmVyTG9va3VwKHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIHJldHVybiBjb25uZWN0aW9uTG9va3VwLnNlcnZlcjtcbiAgICB9XG4gIH1cblxuICAvKlxuICAqIEZpbmRzIGFsbCB3ZWJzb2NrZXRzIHdoaWNoIGlzICdsaXN0ZW5pbmcnIG9uIHRoZSBnaXZlbiB1cmwuXG4gICpcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gdGhlIHVybCB0byB1c2UgdG8gZmluZCBhbGwgd2Vic29ja2V0cyB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIGl0XG4gICogQHBhcmFtIHtzdHJpbmd9IHJvb20gLSBpZiBhIHJvb20gaXMgcHJvdmlkZWQsIHdpbGwgb25seSByZXR1cm4gc29ja2V0cyBpbiB0aGlzIHJvb21cbiAgKiBAcGFyYW0ge2NsYXNzfSBicm9hZGNhc3RlciAtIHNvY2tldCB0aGF0IGlzIGJyb2FkY2FzdGluZyBhbmQgaXMgdG8gYmUgZXhjbHVkZWQgZnJvbSB0aGUgbG9va3VwXG4gICovXG4gIHdlYnNvY2tldHNMb29rdXAodXJsLCByb29tLCBicm9hZGNhc3Rlcikge1xuICAgIGxldCB3ZWJzb2NrZXRzO1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgd2Vic29ja2V0cyA9IGNvbm5lY3Rpb25Mb29rdXAgPyBjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMgOiBbXTtcblxuICAgIGlmIChyb29tKSB7XG4gICAgICBjb25zdCBtZW1iZXJzID0gY29ubmVjdGlvbkxvb2t1cC5yb29tTWVtYmVyc2hpcHNbcm9vbV07XG4gICAgICB3ZWJzb2NrZXRzID0gbWVtYmVycyB8fCBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnJvYWRjYXN0ZXIgPyB3ZWJzb2NrZXRzLmZpbHRlcih3ZWJzb2NrZXQgPT4gd2Vic29ja2V0ICE9PSBicm9hZGNhc3RlcikgOiB3ZWJzb2NrZXRzO1xuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBlbnRyeSBhc3NvY2lhdGVkIHdpdGggdGhlIHVybC5cbiAgKlxuICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgKi9cbiAgcmVtb3ZlU2VydmVyKHVybCkge1xuICAgIGRlbGV0ZSB0aGlzLnVybE1hcFt1cmxdO1xuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIHRoZSBpbmRpdmlkdWFsIHdlYnNvY2tldCBmcm9tIHRoZSBtYXAgb2YgYXNzb2NpYXRlZCB3ZWJzb2NrZXRzLlxuICAqXG4gICogQHBhcmFtIHtvYmplY3R9IHdlYnNvY2tldCAtIHdlYnNvY2tldCBvYmplY3QgdG8gcmVtb3ZlIGZyb20gdGhlIHVybCBtYXBcbiAgKiBAcGFyYW0ge3N0cmluZ30gdXJsXG4gICovXG4gIHJlbW92ZVdlYlNvY2tldCh3ZWJzb2NrZXQsIHVybCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25Mb29rdXAgPSB0aGlzLnVybE1hcFt1cmxdO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25Mb29rdXApIHtcbiAgICAgIGNvbm5lY3Rpb25Mb29rdXAud2Vic29ja2V0cyA9IHJlamVjdChjb25uZWN0aW9uTG9va3VwLndlYnNvY2tldHMsIHNvY2tldCA9PiBzb2NrZXQgPT09IHdlYnNvY2tldCk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgKiBSZW1vdmVzIGEgd2Vic29ja2V0IGZyb20gYSByb29tXG4gICovXG4gIHJlbW92ZU1lbWJlcnNoaXBGcm9tUm9vbSh3ZWJzb2NrZXQsIHJvb20pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uTG9va3VwID0gdGhpcy51cmxNYXBbd2Vic29ja2V0LnVybF07XG4gICAgY29uc3QgbWVtYmVyc2hpcHMgPSBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXTtcblxuICAgIGlmIChjb25uZWN0aW9uTG9va3VwICYmIG1lbWJlcnNoaXBzICE9PSBudWxsKSB7XG4gICAgICBjb25uZWN0aW9uTG9va3VwLnJvb21NZW1iZXJzaGlwc1tyb29tXSA9IHJlamVjdChtZW1iZXJzaGlwcywgc29ja2V0ID0+IHNvY2tldCA9PT0gd2Vic29ja2V0KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IE5ldHdvcmtCcmlkZ2UoKTsgLy8gTm90ZTogdGhpcyBpcyBhIHNpbmdsZXRvblxuIiwiLypcbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DbG9zZUV2ZW50XG4gKi9cbmV4cG9ydCBjb25zdCBDTE9TRV9DT0RFUyA9IHtcbiAgQ0xPU0VfTk9STUFMOiAxMDAwLFxuICBDTE9TRV9HT0lOR19BV0FZOiAxMDAxLFxuICBDTE9TRV9QUk9UT0NPTF9FUlJPUjogMTAwMixcbiAgQ0xPU0VfVU5TVVBQT1JURUQ6IDEwMDMsXG4gIENMT1NFX05PX1NUQVRVUzogMTAwNSxcbiAgQ0xPU0VfQUJOT1JNQUw6IDEwMDYsXG4gIFVOU1VQUE9SVEVEX0RBVEE6IDEwMDcsXG4gIFBPTElDWV9WSU9MQVRJT046IDEwMDgsXG4gIENMT1NFX1RPT19MQVJHRTogMTAwOSxcbiAgTUlTU0lOR19FWFRFTlNJT046IDEwMTAsXG4gIElOVEVSTkFMX0VSUk9SOiAxMDExLFxuICBTRVJWSUNFX1JFU1RBUlQ6IDEwMTIsXG4gIFRSWV9BR0FJTl9MQVRFUjogMTAxMyxcbiAgVExTX0hBTkRTSEFLRTogMTAxNVxufTtcblxuZXhwb3J0IGNvbnN0IEVSUk9SX1BSRUZJWCA9IHtcbiAgQ09OU1RSVUNUT1JfRVJST1I6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnV2ViU29ja2V0JzpcIixcbiAgQ0xPU0VfRVJST1I6IFwiRmFpbGVkIHRvIGV4ZWN1dGUgJ2Nsb3NlJyBvbiAnV2ViU29ja2V0JzpcIixcbiAgRVZFTlQ6IHtcbiAgICBDT05TVFJVQ1Q6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnRXZlbnQnOlwiLFxuICAgIE1FU1NBR0U6IFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnTWVzc2FnZUV2ZW50JzpcIixcbiAgICBDTE9TRTogXCJGYWlsZWQgdG8gY29uc3RydWN0ICdDbG9zZUV2ZW50JzpcIlxuICB9XG59O1xuIiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRQcm90b3R5cGUge1xuICAvLyBOb29wc1xuICBzdG9wUHJvcGFnYXRpb24oKSB7fVxuICBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSB7fVxuXG4gIC8vIGlmIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRoZW4gdGhlIHR5cGUgaXMgc2V0IHRvIFwidW5kZWZpbmVkXCIgb25cbiAgLy8gY2hyb21lIGFuZCBzYWZhcmkuXG4gIGluaXRFdmVudCh0eXBlID0gJ3VuZGVmaW5lZCcsIGJ1YmJsZXMgPSBmYWxzZSwgY2FuY2VsYWJsZSA9IGZhbHNlKSB7XG4gICAgdGhpcy50eXBlID0gYCR7dHlwZX1gO1xuICAgIHRoaXMuYnViYmxlcyA9IEJvb2xlYW4oYnViYmxlcyk7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gQm9vbGVhbihjYW5jZWxhYmxlKTtcbiAgfVxufVxuIiwiaW1wb3J0IEV2ZW50UHJvdG90eXBlIGZyb20gJy4vcHJvdG90eXBlJztcbmltcG9ydCB7IEVSUk9SX1BSRUZJWCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50IGV4dGVuZHMgRXZlbnRQcm90b3R5cGUge1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBldmVudEluaXRDb25maWcgPSB7fSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5UX0VSUk9SfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBldmVudEluaXRDb25maWcgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVF9FUlJPUn0gcGFyYW1ldGVyIDIgKCdldmVudEluaXREaWN0JykgaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUgfSA9IGV2ZW50SW5pdENvbmZpZztcblxuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLnRpbWVTdGFtcCA9IERhdGUubm93KCk7XG4gICAgdGhpcy50YXJnZXQgPSBudWxsO1xuICAgIHRoaXMuc3JjRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5yZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgdGhpcy5pc1RydXN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmV2ZW50UGhhc2UgPSAwO1xuICAgIHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZSA/IEJvb2xlYW4oY2FuY2VsYWJsZSkgOiBmYWxzZTtcbiAgICB0aGlzLmNhbm5jZWxCdWJibGUgPSBmYWxzZTtcbiAgICB0aGlzLmJ1YmJsZXMgPSBidWJibGVzID8gQm9vbGVhbihidWJibGVzKSA6IGZhbHNlO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnRQcm90b3R5cGUgZnJvbSAnLi9wcm90b3R5cGUnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzc2FnZUV2ZW50IGV4dGVuZHMgRXZlbnRQcm90b3R5cGUge1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBldmVudEluaXRDb25maWcgPSB7fSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULk1FU1NBR0V9IDEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC5gKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV2ZW50SW5pdENvbmZpZyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkVWRU5ULk1FU1NBR0V9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3RgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUsIGRhdGEsIG9yaWdpbiwgbGFzdEV2ZW50SWQsIHBvcnRzIH0gPSBldmVudEluaXRDb25maWc7XG5cbiAgICB0aGlzLnR5cGUgPSBgJHt0eXBlfWA7XG4gICAgdGhpcy50aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLnNyY0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMucmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIHRoaXMuaXNUcnVzdGVkID0gZmFsc2U7XG4gICAgdGhpcy5ldmVudFBoYXNlID0gMDtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGUgPyBCb29sZWFuKGNhbmNlbGFibGUpIDogZmFsc2U7XG4gICAgdGhpcy5jYW5uY2VsQnViYmxlID0gZmFsc2U7XG4gICAgdGhpcy5idWJibGVzID0gYnViYmxlcyA/IEJvb2xlYW4oYnViYmxlcykgOiBmYWxzZTtcbiAgICB0aGlzLm9yaWdpbiA9IGAke29yaWdpbn1gO1xuICAgIHRoaXMucG9ydHMgPSB0eXBlb2YgcG9ydHMgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IHBvcnRzO1xuICAgIHRoaXMuZGF0YSA9IHR5cGVvZiBkYXRhID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBkYXRhO1xuICAgIHRoaXMubGFzdEV2ZW50SWQgPSBgJHtsYXN0RXZlbnRJZCB8fCAnJ31gO1xuICB9XG59XG4iLCJpbXBvcnQgRXZlbnRQcm90b3R5cGUgZnJvbSAnLi9wcm90b3R5cGUnO1xuaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xvc2VFdmVudCBleHRlbmRzIEV2ZW50UHJvdG90eXBlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgZXZlbnRJbml0Q29uZmlnID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke0VSUk9SX1BSRUZJWC5FVkVOVC5DTE9TRX0gMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LmApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXZlbnRJbml0Q29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtFUlJPUl9QUkVGSVguRVZFTlQuQ0xPU0V9IHBhcmFtZXRlciAyICgnZXZlbnRJbml0RGljdCcpIGlzIG5vdCBhbiBvYmplY3RgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGJ1YmJsZXMsIGNhbmNlbGFibGUsIGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSA9IGV2ZW50SW5pdENvbmZpZztcblxuICAgIHRoaXMudHlwZSA9IGAke3R5cGV9YDtcbiAgICB0aGlzLnRpbWVTdGFtcCA9IERhdGUubm93KCk7XG4gICAgdGhpcy50YXJnZXQgPSBudWxsO1xuICAgIHRoaXMuc3JjRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5yZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgdGhpcy5pc1RydXN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmV2ZW50UGhhc2UgPSAwO1xuICAgIHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5jYW5jZWxhYmxlID0gY2FuY2VsYWJsZSA/IEJvb2xlYW4oY2FuY2VsYWJsZSkgOiBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbEJ1YmJsZSA9IGZhbHNlO1xuICAgIHRoaXMuYnViYmxlcyA9IGJ1YmJsZXMgPyBCb29sZWFuKGJ1YmJsZXMpIDogZmFsc2U7XG4gICAgdGhpcy5jb2RlID0gdHlwZW9mIGNvZGUgPT09ICdudW1iZXInID8gcGFyc2VJbnQoY29kZSwgMTApIDogMDtcbiAgICB0aGlzLnJlYXNvbiA9IGAke3JlYXNvbiB8fCAnJ31gO1xuICAgIHRoaXMud2FzQ2xlYW4gPSB3YXNDbGVhbiA/IEJvb2xlYW4od2FzQ2xlYW4pIDogZmFsc2U7XG4gIH1cbn1cbiIsImltcG9ydCBFdmVudCBmcm9tICcuL2V2ZW50JztcbmltcG9ydCBNZXNzYWdlRXZlbnQgZnJvbSAnLi9tZXNzYWdlJztcbmltcG9ydCBDbG9zZUV2ZW50IGZyb20gJy4vY2xvc2UnO1xuXG4vKlxuKiBDcmVhdGVzIGFuIEV2ZW50IG9iamVjdCBhbmQgZXh0ZW5kcyBpdCB0byBhbGxvdyBmdWxsIG1vZGlmaWNhdGlvbiBvZlxuKiBpdHMgcHJvcGVydGllcy5cbipcbiogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyAtIHdpdGhpbiBjb25maWcgeW91IHdpbGwgbmVlZCB0byBwYXNzIHR5cGUgYW5kIG9wdGlvbmFsbHkgdGFyZ2V0XG4qL1xuZnVuY3Rpb24gY3JlYXRlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgdHlwZSwgdGFyZ2V0IH0gPSBjb25maWc7XG4gIGNvbnN0IGV2ZW50T2JqZWN0ID0gbmV3IEV2ZW50KHR5cGUpO1xuXG4gIGlmICh0YXJnZXQpIHtcbiAgICBldmVudE9iamVjdC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZXZlbnRPYmplY3Quc3JjRWxlbWVudCA9IHRhcmdldDtcbiAgICBldmVudE9iamVjdC5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIGV2ZW50T2JqZWN0O1xufVxuXG4vKlxuKiBDcmVhdGVzIGEgTWVzc2FnZUV2ZW50IG9iamVjdCBhbmQgZXh0ZW5kcyBpdCB0byBhbGxvdyBmdWxsIG1vZGlmaWNhdGlvbiBvZlxuKiBpdHMgcHJvcGVydGllcy5cbipcbiogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyAtIHdpdGhpbiBjb25maWc6IHR5cGUsIG9yaWdpbiwgZGF0YSBhbmQgb3B0aW9uYWxseSB0YXJnZXRcbiovXG5mdW5jdGlvbiBjcmVhdGVNZXNzYWdlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgdHlwZSwgb3JpZ2luLCBkYXRhLCB0YXJnZXQgfSA9IGNvbmZpZztcbiAgY29uc3QgbWVzc2FnZUV2ZW50ID0gbmV3IE1lc3NhZ2VFdmVudCh0eXBlLCB7XG4gICAgZGF0YSxcbiAgICBvcmlnaW5cbiAgfSk7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIG1lc3NhZ2VFdmVudC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgbWVzc2FnZUV2ZW50LnNyY0VsZW1lbnQgPSB0YXJnZXQ7XG4gICAgbWVzc2FnZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cblxuICByZXR1cm4gbWVzc2FnZUV2ZW50O1xufVxuXG4vKlxuKiBDcmVhdGVzIGEgQ2xvc2VFdmVudCBvYmplY3QgYW5kIGV4dGVuZHMgaXQgdG8gYWxsb3cgZnVsbCBtb2RpZmljYXRpb24gb2ZcbiogaXRzIHByb3BlcnRpZXMuXG4qXG4qIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSB3aXRoaW4gY29uZmlnOiB0eXBlIGFuZCBvcHRpb25hbGx5IHRhcmdldCwgY29kZSwgYW5kIHJlYXNvblxuKi9cbmZ1bmN0aW9uIGNyZWF0ZUNsb3NlRXZlbnQoY29uZmlnKSB7XG4gIGNvbnN0IHsgY29kZSwgcmVhc29uLCB0eXBlLCB0YXJnZXQgfSA9IGNvbmZpZztcbiAgbGV0IHsgd2FzQ2xlYW4gfSA9IGNvbmZpZztcblxuICBpZiAoIXdhc0NsZWFuKSB7XG4gICAgd2FzQ2xlYW4gPSBjb2RlID09PSAxMDAwO1xuICB9XG5cbiAgY29uc3QgY2xvc2VFdmVudCA9IG5ldyBDbG9zZUV2ZW50KHR5cGUsIHtcbiAgICBjb2RlLFxuICAgIHJlYXNvbixcbiAgICB3YXNDbGVhblxuICB9KTtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgY2xvc2VFdmVudC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgY2xvc2VFdmVudC5zcmNFbGVtZW50ID0gdGFyZ2V0O1xuICAgIGNsb3NlRXZlbnQuY3VycmVudFRhcmdldCA9IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBjbG9zZUV2ZW50O1xufVxuXG5leHBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH07XG4iLCJpbXBvcnQgV2ViU29ja2V0IGZyb20gJy4uL3dlYnNvY2tldCc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vaGVscGVycy9kZWxheSc7XG5pbXBvcnQgbmV0d29ya0JyaWRnZSBmcm9tICcuLi9uZXR3b3JrLWJyaWRnZSc7XG5pbXBvcnQgeyBjcmVhdGVDbG9zZUV2ZW50LCBjcmVhdGVFdmVudCB9IGZyb20gJy4uL2V2ZW50L2ZhY3RvcnknO1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VXZWJTb2NrZXRDb25uZWN0aW9uKGNvbnRleHQsIGNvZGUsIHJlYXNvbikge1xuICBjb250ZXh0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0lORztcblxuICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cChjb250ZXh0LnVybCk7XG4gIGNvbnN0IGNsb3NlRXZlbnQgPSBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICB0eXBlOiAnY2xvc2UnLFxuICAgIHRhcmdldDogY29udGV4dCxcbiAgICBjb2RlLFxuICAgIHJlYXNvblxuICB9KTtcblxuICBkZWxheSgoKSA9PiB7XG4gICAgbmV0d29ya0JyaWRnZS5yZW1vdmVXZWJTb2NrZXQoY29udGV4dCwgY29udGV4dC51cmwpO1xuXG4gICAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFRDtcbiAgICBjb250ZXh0LmRpc3BhdGNoRXZlbnQoY2xvc2VFdmVudCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50LCBzZXJ2ZXIpO1xuICAgIH1cbiAgfSwgY29udGV4dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmYWlsV2ViU29ja2V0Q29ubmVjdGlvbihjb250ZXh0LCBjb2RlLCByZWFzb24pIHtcbiAgY29udGV4dC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NJTkc7XG5cbiAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAoY29udGV4dC51cmwpO1xuICBjb25zdCBjbG9zZUV2ZW50ID0gY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgdHlwZTogJ2Nsb3NlJyxcbiAgICB0YXJnZXQ6IGNvbnRleHQsXG4gICAgY29kZSxcbiAgICByZWFzb24sXG4gICAgd2FzQ2xlYW46IGZhbHNlXG4gIH0pO1xuXG4gIGNvbnN0IGVycm9yRXZlbnQgPSBjcmVhdGVFdmVudCh7XG4gICAgdHlwZTogJ2Vycm9yJyxcbiAgICB0YXJnZXQ6IGNvbnRleHRcbiAgfSk7XG5cbiAgZGVsYXkoKCkgPT4ge1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KGNvbnRleHQsIGNvbnRleHQudXJsKTtcblxuICAgIGNvbnRleHQucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgY29udGV4dC5kaXNwYXRjaEV2ZW50KGVycm9yRXZlbnQpO1xuICAgIGNvbnRleHQuZGlzcGF0Y2hFdmVudChjbG9zZUV2ZW50KTtcblxuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNsb3NlRXZlbnQsIHNlcnZlcik7XG4gICAgfVxuICB9LCBjb250ZXh0KTtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpIHtcbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkYXRhKSAhPT0gJ1tvYmplY3QgQmxvYl0nICYmICEoZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIGRhdGEgPSBTdHJpbmcoZGF0YSk7XG4gIH1cblxuICByZXR1cm4gZGF0YTtcbn1cbiIsImltcG9ydCB7IENMT1NFX0NPREVTIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2FsZ29yaXRobXMvY2xvc2UnO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vbm9ybWFsaXplLXNlbmQnO1xuaW1wb3J0IHsgY3JlYXRlTWVzc2FnZUV2ZW50IH0gZnJvbSAnLi4vZXZlbnQvZmFjdG9yeSc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHByb3h5RmFjdG9yeSh0YXJnZXQpIHtcbiAgY29uc3QgaGFuZGxlciA9IHtcbiAgICBnZXQob2JqLCBwcm9wKSB7XG4gICAgICBpZiAocHJvcCA9PT0gJ2Nsb3NlJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gY2xvc2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgY29uc3QgY29kZSA9IG9wdGlvbnMuY29kZSB8fCBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUw7XG4gICAgICAgICAgY29uc3QgcmVhc29uID0gb3B0aW9ucy5yZWFzb24gfHwgJyc7XG5cbiAgICAgICAgICBjbG9zZVdlYlNvY2tldENvbm5lY3Rpb24odGFyZ2V0LCBjb2RlLCByZWFzb24pO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcCA9PT0gJ3NlbmQnKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBzZW5kKGRhdGEpIHtcbiAgICAgICAgICBkYXRhID0gbm9ybWFsaXplU2VuZERhdGEoZGF0YSk7XG5cbiAgICAgICAgICB0YXJnZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgIGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICAgICAgICAgIHR5cGU6ICdtZXNzYWdlJyxcbiAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgICAgdGFyZ2V0XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wID09PSAnb24nKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBvbldyYXBwZXIodHlwZSwgY2IpIHtcbiAgICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihgc2VydmVyOjoke3R5cGV9YCwgY2IpO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JqW3Byb3BdO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0YXJnZXQsIGhhbmRsZXIpO1xuICByZXR1cm4gcHJveHk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBsZW5ndGhJblV0ZjhCeXRlcyhzdHIpIHtcbiAgLy8gTWF0Y2hlcyBvbmx5IHRoZSAxMC4uIGJ5dGVzIHRoYXQgYXJlIG5vbi1pbml0aWFsIGNoYXJhY3RlcnMgaW4gYSBtdWx0aS1ieXRlIHNlcXVlbmNlLlxuICBjb25zdCBtID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0cikubWF0Y2goLyVbODlBQmFiXS9nKTtcbiAgcmV0dXJuIHN0ci5sZW5ndGggKyAobSA/IG0ubGVuZ3RoIDogMCk7XG59XG4iLCJpbXBvcnQgVVJMIGZyb20gJ3VybC1wYXJzZSc7XG5pbXBvcnQgeyBFUlJPUl9QUkVGSVggfSBmcm9tICcuLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1cmxWZXJpZmljYXRpb24odXJsKSB7XG4gIGNvbnN0IHVybFJlY29yZCA9IG5ldyBVUkwodXJsKTtcbiAgY29uc3QgeyBwYXRobmFtZSwgcHJvdG9jb2wsIGhhc2ggfSA9IHVybFJlY29yZDtcblxuICBpZiAoIXVybCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSAxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuYCk7XG4gIH1cblxuICBpZiAoIXBhdGhuYW1lKSB7XG4gICAgdXJsUmVjb3JkLnBhdGhuYW1lID0gJy8nO1xuICB9XG5cbiAgaWYgKHByb3RvY29sID09PSAnJykge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1J9IFRoZSBVUkwgJyR7dXJsUmVjb3JkLnRvU3RyaW5nKCl9JyBpcyBpbnZhbGlkLmApO1xuICB9XG5cbiAgaWYgKHByb3RvY29sICE9PSAnd3M6JyAmJiBwcm90b2NvbCAhPT0gJ3dzczonKSB7XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgVVJMJ3Mgc2NoZW1lIG11c3QgYmUgZWl0aGVyICd3cycgb3IgJ3dzcycuICcke3Byb3RvY29sfScgaXMgbm90IGFsbG93ZWQuYFxuICAgICk7XG4gIH1cblxuICBpZiAoaGFzaCAhPT0gJycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgYCR7XG4gICAgICAgIEVSUk9SX1BSRUZJWC5DT05TVFJVQ1RPUl9FUlJPUlxuICAgICAgfSBUaGUgVVJMIGNvbnRhaW5zIGEgZnJhZ21lbnQgaWRlbnRpZmllciAoJyR7aGFzaH0nKS4gRnJhZ21lbnQgaWRlbnRpZmllcnMgYXJlIG5vdCBhbGxvd2VkIGluIFdlYlNvY2tldCBVUkxzLmBcbiAgICApO1xuICAgIC8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuICB9XG5cbiAgcmV0dXJuIHVybFJlY29yZC50b1N0cmluZygpO1xufVxuIiwiaW1wb3J0IHsgRVJST1JfUFJFRklYIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcHJvdG9jb2xWZXJpZmljYXRpb24ocHJvdG9jb2xzID0gW10pIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHByb3RvY29scykgJiYgdHlwZW9mIHByb3RvY29scyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYCR7RVJST1JfUFJFRklYLkNPTlNUUlVDVE9SX0VSUk9SfSBUaGUgc3VicHJvdG9jb2wgJyR7cHJvdG9jb2xzLnRvU3RyaW5nKCl9JyBpcyBpbnZhbGlkLmApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwcm90b2NvbHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcHJvdG9jb2xzID0gW3Byb3RvY29sc107XG4gIH1cblxuICBjb25zdCB1bmlxID0gcHJvdG9jb2xzLm1hcChwID0+ICh7IGNvdW50OiAxLCBwcm90b2NvbDogcCB9KSkucmVkdWNlKChhLCBiKSA9PiB7XG4gICAgYVtiLnByb3RvY29sXSA9IChhW2IucHJvdG9jb2xdIHx8IDApICsgYi5jb3VudDtcbiAgICByZXR1cm4gYTtcbiAgfSwge30pO1xuXG4gIGNvbnN0IGR1cGxpY2F0ZXMgPSBPYmplY3Qua2V5cyh1bmlxKS5maWx0ZXIoYSA9PiB1bmlxW2FdID4gMSk7XG5cbiAgaWYgKGR1cGxpY2F0ZXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ09OU1RSVUNUT1JfRVJST1J9IFRoZSBzdWJwcm90b2NvbCAnJHtkdXBsaWNhdGVzWzBdfScgaXMgZHVwbGljYXRlZC5gKTtcbiAgfVxuXG4gIHJldHVybiBwcm90b2NvbHM7XG59XG4iLCJpbXBvcnQgZGVsYXkgZnJvbSAnLi9oZWxwZXJzL2RlbGF5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi9oZWxwZXJzL2xvZ2dlcic7XG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudC90YXJnZXQnO1xuaW1wb3J0IG5ldHdvcmtCcmlkZ2UgZnJvbSAnLi9uZXR3b3JrLWJyaWRnZSc7XG5pbXBvcnQgcHJveHlGYWN0b3J5IGZyb20gJy4vaGVscGVycy9wcm94eS1mYWN0b3J5JztcbmltcG9ydCBsZW5ndGhJblV0ZjhCeXRlcyBmcm9tICcuL2hlbHBlcnMvYnl0ZS1sZW5ndGgnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMsIEVSUk9SX1BSRUZJWCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB1cmxWZXJpZmljYXRpb24gZnJvbSAnLi9oZWxwZXJzL3VybC12ZXJpZmljYXRpb24nO1xuaW1wb3J0IG5vcm1hbGl6ZVNlbmREYXRhIGZyb20gJy4vaGVscGVycy9ub3JtYWxpemUtc2VuZCc7XG5pbXBvcnQgcHJvdG9jb2xWZXJpZmljYXRpb24gZnJvbSAnLi9oZWxwZXJzL3Byb3RvY29sLXZlcmlmaWNhdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVFdmVudCwgY3JlYXRlTWVzc2FnZUV2ZW50LCBjcmVhdGVDbG9zZUV2ZW50IH0gZnJvbSAnLi9ldmVudC9mYWN0b3J5JztcbmltcG9ydCB7IGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbiwgZmFpbFdlYlNvY2tldENvbm5lY3Rpb24gfSBmcm9tICcuL2FsZ29yaXRobXMvY2xvc2UnO1xuXG4vKlxuICogVGhlIG1haW4gd2Vic29ja2V0IGNsYXNzIHdoaWNoIGlzIGRlc2lnbmVkIHRvIG1pbWljayB0aGUgbmF0aXZlIFdlYlNvY2tldCBjbGFzcyBhcyBjbG9zZVxuICogYXMgcG9zc2libGUuXG4gKlxuICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViLXNvY2tldHMuaHRtbFxuICovXG5jbGFzcyBXZWJTb2NrZXQgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgcHJvdG9jb2xzKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMudXJsID0gdXJsVmVyaWZpY2F0aW9uKHVybCk7XG4gICAgcHJvdG9jb2xzID0gcHJvdG9jb2xWZXJpZmljYXRpb24ocHJvdG9jb2xzKTtcbiAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2xzWzBdIHx8ICcnO1xuXG4gICAgdGhpcy5iaW5hcnlUeXBlID0gJ2Jsb2InO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DT05ORUNUSU5HO1xuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuXG4gICAgLypcbiAgICAgKiBUaGlzIGRlbGF5IGlzIG5lZWRlZCBzbyB0aGF0IHdlIGRvbnQgdHJpZ2dlciBhbiBldmVudCBiZWZvcmUgdGhlIGNhbGxiYWNrcyBoYXZlIGJlZW5cbiAgICAgKiBzZXR1cC4gRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiB2YXIgc29ja2V0ID0gbmV3IFdlYlNvY2tldCgnd3M6Ly9sb2NhbGhvc3QnKTtcbiAgICAgKlxuICAgICAqIElmIHdlIGRvbnQgaGF2ZSB0aGUgZGVsYXkgdGhlbiB0aGUgZXZlbnQgd291bGQgYmUgdHJpZ2dlcmVkIHJpZ2h0IGhlcmUgYW5kIHRoaXMgaXNcbiAgICAgKiBiZWZvcmUgdGhlIG9ub3BlbiBoYWQgYSBjaGFuY2UgdG8gcmVnaXN0ZXIgaXRzZWxmLlxuICAgICAqXG4gICAgICogc29ja2V0Lm9ub3BlbiA9ICgpID0+IHsgLy8gdGhpcyB3b3VsZCBuZXZlciBiZSBjYWxsZWQgfTtcbiAgICAgKlxuICAgICAqIGFuZCB3aXRoIHRoZSBkZWxheSB0aGUgZXZlbnQgZ2V0cyB0cmlnZ2VyZWQgaGVyZSBhZnRlciBhbGwgb2YgdGhlIGNhbGxiYWNrcyBoYXZlIGJlZW5cbiAgICAgKiByZWdpc3RlcmVkIDotKVxuICAgICAqL1xuICAgIGRlbGF5KGZ1bmN0aW9uIGRlbGF5Q2FsbGJhY2soKSB7XG4gICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZXJ2ZXIub3B0aW9ucy52ZXJpZnlDbGllbnQgJiZcbiAgICAgICAgICB0eXBlb2Ygc2VydmVyLm9wdGlvbnMudmVyaWZ5Q2xpZW50ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgIXNlcnZlci5vcHRpb25zLnZlcmlmeUNsaWVudCgpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG5cbiAgICAgICAgICBsb2dnZXIoXG4gICAgICAgICAgICAnZXJyb3InLFxuICAgICAgICAgICAgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkOiBIVFRQIEF1dGhlbnRpY2F0aW9uIGZhaWxlZDsgbm8gdmFsaWQgY3JlZGVudGlhbHMgYXZhaWxhYmxlYFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVdlYlNvY2tldCh0aGlzLCB0aGlzLnVybCk7XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlQ2xvc2VFdmVudCh7IHR5cGU6ICdjbG9zZScsIHRhcmdldDogdGhpcywgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMIH0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoc2VydmVyLm9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgJiYgdHlwZW9mIHNlcnZlci5vcHRpb25zLnNlbGVjdFByb3RvY29sID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZFByb3RvY29sID0gc2VydmVyLm9wdGlvbnMuc2VsZWN0UHJvdG9jb2wocHJvdG9jb2xzKTtcbiAgICAgICAgICAgIGNvbnN0IGlzRmlsbGVkID0gc2VsZWN0ZWRQcm90b2NvbCAhPT0gJyc7XG4gICAgICAgICAgICBjb25zdCBpc1JlcXVlc3RlZCA9IHByb3RvY29scy5pbmRleE9mKHNlbGVjdGVkUHJvdG9jb2wpICE9PSAtMTtcbiAgICAgICAgICAgIGlmIChpc0ZpbGxlZCAmJiAhaXNSZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFRDtcblxuICAgICAgICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFdlYlNvY2tldCBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkOiBJbnZhbGlkIFN1Yi1Qcm90b2NvbGApO1xuXG4gICAgICAgICAgICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcbiAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJywgdGFyZ2V0OiB0aGlzIH0pKTtcbiAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUNsb3NlRXZlbnQoeyB0eXBlOiAnY2xvc2UnLCB0YXJnZXQ6IHRoaXMsIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCB9KSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucHJvdG9jb2wgPSBzZWxlY3RlZFByb3RvY29sO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuT1BFTjtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnb3BlbicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgICAgc2VydmVyLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnY29ubmVjdGlvbicgfSksIHByb3h5RmFjdG9yeSh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFdlYlNvY2tldC5DTE9TRUQ7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicsIHRhcmdldDogdGhpcyB9KSk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJywgdGFyZ2V0OiB0aGlzLCBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUwgfSkpO1xuXG4gICAgICAgIGxvZ2dlcignZXJyb3InLCBgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gJyR7dGhpcy51cmx9JyBmYWlsZWRgKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgfVxuXG4gIGdldCBvbm9wZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLm9wZW47XG4gIH1cblxuICBnZXQgb25tZXNzYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVycy5tZXNzYWdlO1xuICB9XG5cbiAgZ2V0IG9uY2xvc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLmNsb3NlO1xuICB9XG5cbiAgZ2V0IG9uZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzLmVycm9yO1xuICB9XG5cbiAgc2V0IG9ub3BlbihsaXN0ZW5lcikge1xuICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVycy5vcGVuO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNldCBvbm1lc3NhZ2UobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMubWVzc2FnZTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lcik7XG4gIH1cblxuICBzZXQgb25jbG9zZShsaXN0ZW5lcikge1xuICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVycy5jbG9zZTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgbGlzdGVuZXIpO1xuICB9XG5cbiAgc2V0IG9uZXJyb3IobGlzdGVuZXIpIHtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcnMuZXJyb3I7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHNlbmQoZGF0YSkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5DTE9TSU5HIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NFRCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJTb2NrZXQgaXMgYWxyZWFkeSBpbiBDTE9TSU5HIG9yIENMT1NFRCBzdGF0ZScpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGhhbmRsZSBidWZmZXJlZEFtb3VudFxuXG4gICAgY29uc3QgbWVzc2FnZUV2ZW50ID0gY3JlYXRlTWVzc2FnZUV2ZW50KHtcbiAgICAgIHR5cGU6ICdzZXJ2ZXI6Om1lc3NhZ2UnLFxuICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgIGRhdGE6IG5vcm1hbGl6ZVNlbmREYXRhKGRhdGEpXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBkZWxheSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChtZXNzYWdlRXZlbnQsIGRhdGEpO1xuICAgICAgfSwgc2VydmVyKTtcbiAgICB9XG4gIH1cblxuICBjbG9zZShjb2RlLCByZWFzb24pIHtcbiAgICBpZiAoY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvZGUgIT09ICdudW1iZXInIHx8IChjb2RlICE9PSAxMDAwICYmIChjb2RlIDwgMzAwMCB8fCBjb2RlID4gNDk5OSkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgYCR7RVJST1JfUFJFRklYLkNMT1NFX0VSUk9SfSBUaGUgY29kZSBtdXN0IGJlIGVpdGhlciAxMDAwLCBvciBiZXR3ZWVuIDMwMDAgYW5kIDQ5OTkuICR7Y29kZX0gaXMgbmVpdGhlci5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlYXNvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBsZW5ndGhJblV0ZjhCeXRlcyhyZWFzb24pO1xuXG4gICAgICBpZiAobGVuZ3RoID4gMTIzKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgJHtFUlJPUl9QUkVGSVguQ0xPU0VfRVJST1J9IFRoZSBtZXNzYWdlIG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiAxMjMgYnl0ZXMuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNMT1NJTkcgfHwgdGhpcy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ0xPU0VEKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNPTk5FQ1RJTkcpIHtcbiAgICAgIGZhaWxXZWJTb2NrZXRDb25uZWN0aW9uKHRoaXMsIGNvZGUsIHJlYXNvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNsb3NlV2ViU29ja2V0Q29ubmVjdGlvbih0aGlzLCBjb2RlLCByZWFzb24pO1xuICAgIH1cbiAgfVxufVxuXG5XZWJTb2NrZXQuQ09OTkVDVElORyA9IDA7XG5XZWJTb2NrZXQucHJvdG90eXBlLkNPTk5FQ1RJTkcgPSBXZWJTb2NrZXQuQ09OTkVDVElORztcbldlYlNvY2tldC5PUEVOID0gMTtcbldlYlNvY2tldC5wcm90b3R5cGUuT1BFTiA9IFdlYlNvY2tldC5PUEVOO1xuV2ViU29ja2V0LkNMT1NJTkcgPSAyO1xuV2ViU29ja2V0LnByb3RvdHlwZS5DTE9TSU5HID0gV2ViU29ja2V0LkNMT1NJTkc7XG5XZWJTb2NrZXQuQ0xPU0VEID0gMztcbldlYlNvY2tldC5wcm90b3R5cGUuQ0xPU0VEID0gV2ViU29ja2V0LkNMT1NFRDtcblxuZXhwb3J0IGRlZmF1bHQgV2ViU29ja2V0O1xuIiwiZXhwb3J0IGRlZmF1bHQgYXJyID0+XG4gIGFyci5yZWR1Y2UoKGRlZHVwZWQsIGIpID0+IHtcbiAgICBpZiAoZGVkdXBlZC5pbmRleE9mKGIpID4gLTEpIHJldHVybiBkZWR1cGVkO1xuICAgIHJldHVybiBkZWR1cGVkLmNvbmNhdChiKTtcbiAgfSwgW10pO1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmV0cmlldmVHbG9iYWxPYmplY3QoKSB7XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnICYmIHR5cGVvZiByZXF1aXJlID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBnbG9iYWwgPT09ICdvYmplY3QnID8gZ2xvYmFsIDogdGhpcztcbn1cbiIsImltcG9ydCBVUkwgZnJvbSAndXJsLXBhcnNlJztcbmltcG9ydCBXZWJTb2NrZXQgZnJvbSAnLi93ZWJzb2NrZXQnO1xuaW1wb3J0IGRlZHVwZSBmcm9tICcuL2hlbHBlcnMvZGVkdXBlJztcbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50L3RhcmdldCc7XG5pbXBvcnQgeyBDTE9TRV9DT0RFUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IGdsb2JhbE9iamVjdCBmcm9tICcuL2hlbHBlcnMvZ2xvYmFsLW9iamVjdCc7XG5pbXBvcnQgbm9ybWFsaXplU2VuZERhdGEgZnJvbSAnLi9oZWxwZXJzL25vcm1hbGl6ZS1zZW5kJztcbmltcG9ydCB7IGNyZWF0ZUV2ZW50LCBjcmVhdGVNZXNzYWdlRXZlbnQsIGNyZWF0ZUNsb3NlRXZlbnQgfSBmcm9tICcuL2V2ZW50L2ZhY3RvcnknO1xuXG5jbGFzcyBTZXJ2ZXIgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcbiAgICBjb25zdCB1cmxSZWNvcmQgPSBuZXcgVVJMKHVybCk7XG5cbiAgICBpZiAoIXVybFJlY29yZC5wYXRobmFtZSkge1xuICAgICAgdXJsUmVjb3JkLnBhdGhuYW1lID0gJy8nO1xuICAgIH1cblxuICAgIHRoaXMudXJsID0gdXJsUmVjb3JkLnRvU3RyaW5nKCk7XG5cbiAgICB0aGlzLm9yaWdpbmFsV2ViU29ja2V0ID0gbnVsbDtcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLmF0dGFjaFNlcnZlcih0aGlzLCB0aGlzLnVybCk7XG5cbiAgICBpZiAoIXNlcnZlcikge1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Vycm9yJyB9KSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbW9jayBzZXJ2ZXIgaXMgYWxyZWFkeSBsaXN0ZW5pbmcgb24gdGhpcyB1cmwnKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudmVyaWZ5Q2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb3B0aW9ucy52ZXJpZnlDbGllbnQgPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5zZWxlY3RQcm90b2NvbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnMuc2VsZWN0UHJvdG9jb2wgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5zdGFydCgpO1xuICB9XG5cbiAgLypcbiAgICogQXR0YWNoZXMgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCB0byB0aGUgZ2xvYmFsIG9iamVjdFxuICAgKi9cbiAgc3RhcnQoKSB7XG4gICAgY29uc3QgZ2xvYmFsT2JqID0gZ2xvYmFsT2JqZWN0KCk7XG5cbiAgICBpZiAoZ2xvYmFsT2JqLldlYlNvY2tldCkge1xuICAgICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IGdsb2JhbE9iai5XZWJTb2NrZXQ7XG4gICAgfVxuXG4gICAgZ2xvYmFsT2JqLldlYlNvY2tldCA9IFdlYlNvY2tldDtcbiAgfVxuXG4gIC8qXG4gICAqIFJlbW92ZXMgdGhlIG1vY2sgd2Vic29ja2V0IG9iamVjdCBmcm9tIHRoZSBnbG9iYWwgb2JqZWN0XG4gICAqL1xuICBzdG9wKGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBjb25zdCBnbG9iYWxPYmogPSBnbG9iYWxPYmplY3QoKTtcblxuICAgIGlmICh0aGlzLm9yaWdpbmFsV2ViU29ja2V0KSB7XG4gICAgICBnbG9iYWxPYmouV2ViU29ja2V0ID0gdGhpcy5vcmlnaW5hbFdlYlNvY2tldDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIGdsb2JhbE9iai5XZWJTb2NrZXQ7XG4gICAgfVxuXG4gICAgdGhpcy5vcmlnaW5hbFdlYlNvY2tldCA9IG51bGw7XG5cbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVNlcnZlcih0aGlzLnVybCk7XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gZm9yIHRoZSBtb2NrIHNlcnZlciB0byBzdWJzY3JpYmUgdG8gdGhlIG9uIGV2ZW50cy5cbiAgICpcbiAgICogaWU6IG1vY2tTZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2EgbW9jayBjbGllbnQgY29ubmVjdGVkJyk7IH0pO1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSBldmVudCBrZXkgdG8gc3Vic2NyaWJlIHRvLiBWYWxpZCBrZXlzIGFyZTogY29ubmVjdGlvbiwgbWVzc2FnZSwgYW5kIGNsb3NlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayB3aGljaCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYSBjZXJ0YWluIGV2ZW50IGlzIGZpcmVkLlxuICAgKi9cbiAgb24odHlwZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICB9XG5cbiAgLypcbiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIGFuZCB0cmlnZ2VycyB0aGUgb25jbG9zZSBtZXRob2Qgb2YgYWxsIGxpc3RlbmluZ1xuICAgKiB3ZWJzb2NrZXRzLiBBZnRlciB0aGF0IGl0IHJlbW92ZXMgaXRzZWxmIGZyb20gdGhlIHVybE1hcCBzbyBhbm90aGVyIHNlcnZlclxuICAgKiBjb3VsZCBhZGQgaXRzZWxmIHRvIHRoZSB1cmwuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBjbG9zZShvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7IGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4gfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gbmV0d29ya0JyaWRnZS53ZWJzb2NrZXRzTG9va3VwKHRoaXMudXJsKTtcblxuICAgIC8vIFJlbW92ZSBzZXJ2ZXIgYmVmb3JlIG5vdGlmaWNhdGlvbnMgdG8gcHJldmVudCBpbW1lZGlhdGUgcmVjb25uZWN0cyBmcm9tXG4gICAgLy8gc29ja2V0IG9uY2xvc2UgaGFuZGxlcnNcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZVNlcnZlcih0aGlzLnVybCk7XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChzb2NrZXQgPT4ge1xuICAgICAgc29ja2V0LnJlYWR5U3RhdGUgPSBXZWJTb2NrZXQuQ0xPU0U7XG4gICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgICB0YXJnZXQ6IHNvY2tldCxcbiAgICAgICAgICBjb2RlOiBjb2RlIHx8IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTCxcbiAgICAgICAgICByZWFzb246IHJlYXNvbiB8fCAnJyxcbiAgICAgICAgICB3YXNDbGVhblxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjcmVhdGVDbG9zZUV2ZW50KHsgdHlwZTogJ2Nsb3NlJyB9KSwgdGhpcyk7XG4gIH1cblxuICAvKlxuICAgKiBTZW5kcyBhIGdlbmVyaWMgbWVzc2FnZSBldmVudCB0byBhbGwgbW9jayBjbGllbnRzLlxuICAgKi9cbiAgZW1pdChldmVudCwgZGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgbGV0IHsgd2Vic29ja2V0cyB9ID0gb3B0aW9ucztcblxuICAgIGlmICghd2Vic29ja2V0cykge1xuICAgICAgd2Vic29ja2V0cyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JyB8fCBhcmd1bWVudHMubGVuZ3RoID4gMykge1xuICAgICAgZGF0YSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSwgYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICBkYXRhID0gZGF0YS5tYXAoaXRlbSA9PiBub3JtYWxpemVTZW5kRGF0YShpdGVtKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEgPSBub3JtYWxpemVTZW5kRGF0YShkYXRhKTtcbiAgICB9XG5cbiAgICB3ZWJzb2NrZXRzLmZvckVhY2goc29ja2V0ID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgIHNvY2tldC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgIGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICAgICAgICB0eXBlOiBldmVudCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBvcmlnaW46IHRoaXMudXJsLFxuICAgICAgICAgICAgdGFyZ2V0OiBzb2NrZXRcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5kYXRhXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICBjcmVhdGVNZXNzYWdlRXZlbnQoe1xuICAgICAgICAgICAgdHlwZTogZXZlbnQsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgb3JpZ2luOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHRhcmdldDogc29ja2V0XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qXG4gICAqIFJldHVybnMgYW4gYXJyYXkgb2Ygd2Vic29ja2V0cyB3aGljaCBhcmUgbGlzdGVuaW5nIHRvIHRoaXMgc2VydmVyXG4gICAqIFRPT0Q6IHRoaXMgc2hvdWxkIHJldHVybiBhIHNldCBhbmQgbm90IGJlIGEgbWV0aG9kXG4gICAqL1xuICBjbGllbnRzKCkge1xuICAgIHJldHVybiBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAodGhpcy51cmwpO1xuICB9XG5cbiAgLypcbiAgICogUHJlcGFyZXMgYSBtZXRob2QgdG8gc3VibWl0IGFuIGV2ZW50IHRvIG1lbWJlcnMgb2YgdGhlIHJvb21cbiAgICpcbiAgICogZS5nLiBzZXJ2ZXIudG8oJ215LXJvb20nKS5lbWl0KCdoaSEnKTtcbiAgICovXG4gIHRvKHJvb20sIGJyb2FkY2FzdGVyLCBicm9hZGNhc3RMaXN0ID0gW10pIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCB3ZWJzb2NrZXRzID0gZGVkdXBlKGJyb2FkY2FzdExpc3QuY29uY2F0KG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCwgcm9vbSwgYnJvYWRjYXN0ZXIpKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG86IChjaGFpbmVkUm9vbSwgY2hhaW5lZEJyb2FkY2FzdGVyKSA9PiB0aGlzLnRvLmNhbGwodGhpcywgY2hhaW5lZFJvb20sIGNoYWluZWRCcm9hZGNhc3Rlciwgd2Vic29ja2V0cyksXG4gICAgICBlbWl0KGV2ZW50LCBkYXRhKSB7XG4gICAgICAgIHNlbGYuZW1pdChldmVudCwgZGF0YSwgeyB3ZWJzb2NrZXRzIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAgKiBBbGlhcyBmb3IgU2VydmVyLnRvXG4gICAqL1xuICBpbiguLi5hcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMudG8uYXBwbHkobnVsbCwgYXJncyk7XG4gIH1cblxuICAvKlxuICAgKiBTaW11bGF0ZSBhbiBldmVudCBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNsaWVudHMuIFVzZWZ1bCBmb3JcbiAgICogc2ltdWxhdGluZyBlcnJvcnMuXG4gICAqL1xuICBzaW11bGF0ZShldmVudCkge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IG5ldHdvcmtCcmlkZ2Uud2Vic29ja2V0c0xvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoZXZlbnQgPT09ICdlcnJvcicpIHtcbiAgICAgIGxpc3RlbmVycy5mb3JFYWNoKHNvY2tldCA9PiB7XG4gICAgICAgIHNvY2tldC5yZWFkeVN0YXRlID0gV2ViU29ja2V0LkNMT1NFO1xuICAgICAgICBzb2NrZXQuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdlcnJvcicgfSkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBBbHRlcm5hdGl2ZSBjb25zdHJ1Y3RvciB0byBzdXBwb3J0IG5hbWVzcGFjZXMgaW4gc29ja2V0LmlvXG4gKlxuICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNjdXN0b20tbmFtZXNwYWNlc1xuICovXG5TZXJ2ZXIub2YgPSBmdW5jdGlvbiBvZih1cmwpIHtcbiAgcmV0dXJuIG5ldyBTZXJ2ZXIodXJsKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNlcnZlcjtcbiIsImltcG9ydCBVUkwgZnJvbSAndXJsLXBhcnNlJztcbmltcG9ydCBkZWxheSBmcm9tICcuL2hlbHBlcnMvZGVsYXknO1xuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4vZXZlbnQvdGFyZ2V0JztcbmltcG9ydCBuZXR3b3JrQnJpZGdlIGZyb20gJy4vbmV0d29yay1icmlkZ2UnO1xuaW1wb3J0IHsgQ0xPU0VfQ09ERVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vaGVscGVycy9sb2dnZXInO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnQsIGNyZWF0ZU1lc3NhZ2VFdmVudCwgY3JlYXRlQ2xvc2VFdmVudCB9IGZyb20gJy4vZXZlbnQvZmFjdG9yeSc7XG5cbi8qXG4qIFRoZSBzb2NrZXQtaW8gY2xhc3MgaXMgZGVzaWduZWQgdG8gbWltaWNrIHRoZSByZWFsIEFQSSBhcyBjbG9zZWx5IGFzIHBvc3NpYmxlLlxuKlxuKiBodHRwOi8vc29ja2V0LmlvL2RvY3MvXG4qL1xuY2xhc3MgU29ja2V0SU8gZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIC8qXG4gICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICAqL1xuICBjb25zdHJ1Y3Rvcih1cmwgPSAnc29ja2V0LmlvJywgcHJvdG9jb2wgPSAnJykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmJpbmFyeVR5cGUgPSAnYmxvYic7XG4gICAgY29uc3QgdXJsUmVjb3JkID0gbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKCF1cmxSZWNvcmQucGF0aG5hbWUpIHtcbiAgICAgIHVybFJlY29yZC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICB0aGlzLnVybCA9IHVybFJlY29yZC50b1N0cmluZygpO1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNPTk5FQ1RJTkc7XG4gICAgdGhpcy5wcm90b2NvbCA9ICcnO1xuXG4gICAgaWYgKHR5cGVvZiBwcm90b2NvbCA9PT0gJ3N0cmluZycgfHwgKHR5cGVvZiBwcm90b2NvbCA9PT0gJ29iamVjdCcgJiYgcHJvdG9jb2wgIT09IG51bGwpKSB7XG4gICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2w7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHByb3RvY29sKSAmJiBwcm90b2NvbC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnByb3RvY29sID0gcHJvdG9jb2xbMF07XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5hdHRhY2hXZWJTb2NrZXQodGhpcywgdGhpcy51cmwpO1xuXG4gICAgLypcbiAgICAqIERlbGF5IHRyaWdnZXJpbmcgdGhlIGNvbm5lY3Rpb24gZXZlbnRzIHNvIHRoZXkgY2FuIGJlIGRlZmluZWQgaW4gdGltZS5cbiAgICAqL1xuICAgIGRlbGF5KGZ1bmN0aW9uIGRlbGF5Q2FsbGJhY2soKSB7XG4gICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLk9QRU47XG4gICAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3Rpb24nIH0pLCBzZXJ2ZXIsIHRoaXMpO1xuICAgICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCh7IHR5cGU6ICdjb25uZWN0JyB9KSwgc2VydmVyLCB0aGlzKTsgLy8gYWxpYXNcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KHsgdHlwZTogJ2Nvbm5lY3QnLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gU29ja2V0SU8uQ0xPU0VEO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoeyB0eXBlOiAnZXJyb3InLCB0YXJnZXQ6IHRoaXMgfSkpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgY3JlYXRlQ2xvc2VFdmVudCh7XG4gICAgICAgICAgICB0eXBlOiAnY2xvc2UnLFxuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICAgICAgY29kZTogQ0xPU0VfQ09ERVMuQ0xPU0VfTk9STUFMXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBsb2dnZXIoJ2Vycm9yJywgYFNvY2tldC5pbyBjb25uZWN0aW9uIHRvICcke3RoaXMudXJsfScgZmFpbGVkYCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG5cbiAgICAvKipcbiAgICAgIEFkZCBhbiBhbGlhc2VkIGV2ZW50IGxpc3RlbmVyIGZvciBjbG9zZSAvIGRpc2Nvbm5lY3RcbiAgICAgKi9cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgZXZlbnQgPT4ge1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiAnZGlzY29ubmVjdCcsXG4gICAgICAgICAgdGFyZ2V0OiBldmVudC50YXJnZXQsXG4gICAgICAgICAgY29kZTogZXZlbnQuY29kZVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qXG4gICogQ2xvc2VzIHRoZSBTb2NrZXRJTyBjb25uZWN0aW9uIG9yIGNvbm5lY3Rpb24gYXR0ZW1wdCwgaWYgYW55LlxuICAqIElmIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgQ0xPU0VELCB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuXG4gICovXG4gIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgIT09IFNvY2tldElPLk9QRU4pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gbmV0d29ya0JyaWRnZS5zZXJ2ZXJMb29rdXAodGhpcy51cmwpO1xuICAgIG5ldHdvcmtCcmlkZ2UucmVtb3ZlV2ViU29ja2V0KHRoaXMsIHRoaXMudXJsKTtcblxuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNvY2tldElPLkNMT1NFRDtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoXG4gICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgdHlwZTogJ2Nsb3NlJyxcbiAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICBjb2RlOiBDTE9TRV9DT0RFUy5DTE9TRV9OT1JNQUxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgIHNlcnZlci5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBjcmVhdGVDbG9zZUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiAnZGlzY29ubmVjdCcsXG4gICAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICAgIGNvZGU6IENMT1NFX0NPREVTLkNMT1NFX05PUk1BTFxuICAgICAgICB9KSxcbiAgICAgICAgc2VydmVyXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBBbGlhcyBmb3IgU29ja2V0I2Nsb3NlXG4gICpcbiAgKiBodHRwczovL2dpdGh1Yi5jb20vc29ja2V0aW8vc29ja2V0LmlvLWNsaWVudC9ibG9iL21hc3Rlci9saWIvc29ja2V0LmpzI0wzODNcbiAgKi9cbiAgZGlzY29ubmVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgLypcbiAgKiBTdWJtaXRzIGFuIGV2ZW50IHRvIHRoZSBzZXJ2ZXIgd2l0aCBhIHBheWxvYWRcbiAgKi9cbiAgZW1pdChldmVudCwgLi4uZGF0YSkge1xuICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgIT09IFNvY2tldElPLk9QRU4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU29ja2V0SU8gaXMgYWxyZWFkeSBpbiBDTE9TSU5HIG9yIENMT1NFRCBzdGF0ZScpO1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2VFdmVudCA9IGNyZWF0ZU1lc3NhZ2VFdmVudCh7XG4gICAgICB0eXBlOiBldmVudCxcbiAgICAgIG9yaWdpbjogdGhpcy51cmwsXG4gICAgICBkYXRhXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG5cbiAgICBpZiAoc2VydmVyKSB7XG4gICAgICBzZXJ2ZXIuZGlzcGF0Y2hFdmVudChtZXNzYWdlRXZlbnQsIC4uLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBTdWJtaXRzIGEgJ21lc3NhZ2UnIGV2ZW50IHRvIHRoZSBzZXJ2ZXIuXG4gICpcbiAgKiBTaG91bGQgYmVoYXZlIGV4YWN0bHkgbGlrZSBXZWJTb2NrZXQjc2VuZFxuICAqXG4gICogaHR0cHM6Ly9naXRodWIuY29tL3NvY2tldGlvL3NvY2tldC5pby1jbGllbnQvYmxvYi9tYXN0ZXIvbGliL3NvY2tldC5qcyNMMTEzXG4gICovXG4gIHNlbmQoZGF0YSkge1xuICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGRhdGEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgKiBGb3IgYnJvYWRjYXN0aW5nIGV2ZW50cyB0byBvdGhlciBjb25uZWN0ZWQgc29ja2V0cy5cbiAgKlxuICAqIGUuZy4gc29ja2V0LmJyb2FkY2FzdC5lbWl0KCdoaSEnKTtcbiAgKiBlLmcuIHNvY2tldC5icm9hZGNhc3QudG8oJ215LXJvb20nKS5lbWl0KCdoaSEnKTtcbiAgKi9cbiAgZ2V0IGJyb2FkY2FzdCgpIHtcbiAgICBpZiAodGhpcy5yZWFkeVN0YXRlICE9PSBTb2NrZXRJTy5PUEVOKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvY2tldElPIGlzIGFscmVhZHkgaW4gQ0xPU0lORyBvciBDTE9TRUQgc3RhdGUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXR3b3JrQnJpZGdlLnNlcnZlckxvb2t1cCh0aGlzLnVybCk7XG4gICAgaWYgKCFzZXJ2ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU29ja2V0SU8gY2FuIG5vdCBmaW5kIGEgc2VydmVyIGF0IHRoZSBzcGVjaWZpZWQgVVJMICgke3RoaXMudXJsfSlgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZW1pdChldmVudCwgZGF0YSkge1xuICAgICAgICBzZXJ2ZXIuZW1pdChldmVudCwgZGF0YSwgeyB3ZWJzb2NrZXRzOiBuZXR3b3JrQnJpZGdlLndlYnNvY2tldHNMb29rdXAoc2VsZi51cmwsIG51bGwsIHNlbGYpIH0pO1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICAgIH0sXG4gICAgICB0byhyb29tKSB7XG4gICAgICAgIHJldHVybiBzZXJ2ZXIudG8ocm9vbSwgc2VsZik7XG4gICAgICB9LFxuICAgICAgaW4ocm9vbSkge1xuICAgICAgICByZXR1cm4gc2VydmVyLmluKHJvb20sIHNlbGYpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAqIEZvciByZWdpc3RlcmluZyBldmVudHMgdG8gYmUgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyXG4gICovXG4gIG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICAqIFJlbW92ZSBldmVudCBsaXN0ZW5lclxuICAgKlxuICAgKiBodHRwczovL3NvY2tldC5pby9kb2NzL2NsaWVudC1hcGkvI3NvY2tldC1vbi1ldmVudG5hbWUtY2FsbGJhY2tcbiAgICovXG4gIG9mZih0eXBlKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUpO1xuICB9XG5cbiAgLypcbiAgICogSm9pbiBhIHJvb20gb24gYSBzZXJ2ZXJcbiAgICpcbiAgICogaHR0cDovL3NvY2tldC5pby9kb2NzL3Jvb21zLWFuZC1uYW1lc3BhY2VzLyNqb2luaW5nLWFuZC1sZWF2aW5nXG4gICAqL1xuICBqb2luKHJvb20pIHtcbiAgICBuZXR3b3JrQnJpZGdlLmFkZE1lbWJlcnNoaXBUb1Jvb20odGhpcywgcm9vbSk7XG4gIH1cblxuICAvKlxuICAgKiBHZXQgdGhlIHdlYnNvY2tldCB0byBsZWF2ZSB0aGUgcm9vbVxuICAgKlxuICAgKiBodHRwOi8vc29ja2V0LmlvL2RvY3Mvcm9vbXMtYW5kLW5hbWVzcGFjZXMvI2pvaW5pbmctYW5kLWxlYXZpbmdcbiAgICovXG4gIGxlYXZlKHJvb20pIHtcbiAgICBuZXR3b3JrQnJpZGdlLnJlbW92ZU1lbWJlcnNoaXBGcm9tUm9vbSh0aGlzLCByb29tKTtcbiAgfVxuXG4gIHRvKHJvb20pIHtcbiAgICByZXR1cm4gdGhpcy5icm9hZGNhc3QudG8ocm9vbSk7XG4gIH1cblxuICBpbigpIHtcbiAgICByZXR1cm4gdGhpcy50by5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLypcbiAgICogSW52b2tlcyBhbGwgbGlzdGVuZXIgZnVuY3Rpb25zIHRoYXQgYXJlIGxpc3RlbmluZyB0byB0aGUgZ2l2ZW4gZXZlbnQudHlwZSBwcm9wZXJ0eS4gRWFjaFxuICAgKiBsaXN0ZW5lciB3aWxsIGJlIHBhc3NlZCB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBldmVudCBvYmplY3Qgd2hpY2ggd2lsbCBiZSBwYXNzZWQgdG8gYWxsIGxpc3RlbmVycyBvZiB0aGUgZXZlbnQudHlwZSBwcm9wZXJ0eVxuICAgKi9cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgLi4uY3VzdG9tQXJndW1lbnRzKSB7XG4gICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQudHlwZTtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3RlbmVycykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgICBpZiAoY3VzdG9tQXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgY3VzdG9tQXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlZ3VsYXIgV2ViU29ja2V0cyBleHBlY3QgYSBNZXNzYWdlRXZlbnQgYnV0IFNvY2tldGlvLmlvIGp1c3Qgd2FudHMgcmF3IGRhdGFcbiAgICAgICAgLy8gIHBheWxvYWQgaW5zdGFuY2VvZiBNZXNzYWdlRXZlbnQgd29ya3MsIGJ1dCB5b3UgY2FuJ3QgaXNudGFuY2Ugb2YgTm9kZUV2ZW50XG4gICAgICAgIC8vICBmb3Igbm93IHdlIGRldGVjdCBpZiB0aGUgb3V0cHV0IGhhcyBkYXRhIGRlZmluZWQgb24gaXRcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudC5kYXRhID8gZXZlbnQuZGF0YSA6IGV2ZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5Tb2NrZXRJTy5DT05ORUNUSU5HID0gMDtcblNvY2tldElPLk9QRU4gPSAxO1xuU29ja2V0SU8uQ0xPU0lORyA9IDI7XG5Tb2NrZXRJTy5DTE9TRUQgPSAzO1xuXG4vKlxuKiBTdGF0aWMgY29uc3RydWN0b3IgbWV0aG9kcyBmb3IgdGhlIElPIFNvY2tldFxuKi9cbmNvbnN0IElPID0gZnVuY3Rpb24gaW9Db25zdHJ1Y3Rvcih1cmwsIHByb3RvY29sKSB7XG4gIHJldHVybiBuZXcgU29ja2V0SU8odXJsLCBwcm90b2NvbCk7XG59O1xuXG4vKlxuKiBBbGlhcyB0aGUgcmF3IElPKCkgY29uc3RydWN0b3JcbiovXG5JTy5jb25uZWN0ID0gZnVuY3Rpb24gaW9Db25uZWN0KHVybCwgcHJvdG9jb2wpIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbmV3LWNhcCAqL1xuICByZXR1cm4gSU8odXJsLCBwcm90b2NvbCk7XG4gIC8qIGVzbGludC1lbmFibGUgbmV3LWNhcCAqL1xufTtcblxuZXhwb3J0IGRlZmF1bHQgSU87XG4iLCJpbXBvcnQgTW9ja1NlcnZlciBmcm9tICcuL3NlcnZlcic7XG5pbXBvcnQgTW9ja1NvY2tldElPIGZyb20gJy4vc29ja2V0LWlvJztcbmltcG9ydCBNb2NrV2ViU29ja2V0IGZyb20gJy4vd2Vic29ja2V0JztcblxuZXhwb3J0IGNvbnN0IFNlcnZlciA9IE1vY2tTZXJ2ZXI7XG5leHBvcnQgY29uc3QgV2ViU29ja2V0ID0gTW9ja1dlYlNvY2tldDtcbmV4cG9ydCBjb25zdCBTb2NrZXRJTyA9IE1vY2tTb2NrZXRJTztcbiJdLCJuYW1lcyI6WyJnbG9iYWwiLCJxcyIsInJlcXVpcmVkIiwiY29uc3QiLCJ0aGlzIiwic3VwZXIiLCJXZWJTb2NrZXQiLCJVUkwiLCJsb2dnZXIiLCJTZXJ2ZXIiLCJnbG9iYWxPYmplY3QiLCJTb2NrZXRJTyIsIk1vY2tTZXJ2ZXIiLCJNb2NrV2ViU29ja2V0IiwiTW9ja1NvY2tldElPIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQVdBLGdCQUFjLEdBQUcsU0FBUyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtFQUNqRCxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNsQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUM7O0VBRWIsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFBLE9BQU8sS0FBSyxDQUFDLEVBQUE7O0VBRXhCLFFBQVEsUUFBUTtJQUNkLEtBQUssTUFBTSxDQUFDO0lBQ1osS0FBSyxJQUFJO0lBQ1QsT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDOztJQUVuQixLQUFLLE9BQU8sQ0FBQztJQUNiLEtBQUssS0FBSztJQUNWLE9BQU8sSUFBSSxLQUFLLEdBQUcsQ0FBQzs7SUFFcEIsS0FBSyxLQUFLO0lBQ1YsT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDOztJQUVuQixLQUFLLFFBQVE7SUFDYixPQUFPLElBQUksS0FBSyxFQUFFLENBQUM7O0lBRW5CLEtBQUssTUFBTTtJQUNYLE9BQU8sS0FBSyxDQUFDO0dBQ2Q7O0VBRUQsT0FBTyxJQUFJLEtBQUssQ0FBQyxDQUFDO0NBQ25CLENBQUM7O0FDbkNGLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDOzs7Ozs7Ozs7QUFTMUMsU0FBUyxNQUFNLENBQUMsS0FBSyxFQUFFO0VBQ3JCLE9BQU8sa0JBQWtCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztDQUN0RDs7Ozs7Ozs7O0FBU0QsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFO0VBQzFCLElBQUksTUFBTSxHQUFHLHFCQUFxQjtNQUM5QixNQUFNLEdBQUcsRUFBRTtNQUNYLElBQUksQ0FBQzs7RUFFVCxPQUFPLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQ2hDLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7Ozs7OztJQU81QixJQUFJLEdBQUcsSUFBSSxNQUFNLEVBQUUsRUFBQSxTQUFTLEVBQUE7SUFDNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztHQUNyQjs7RUFFRCxPQUFPLE1BQU0sQ0FBQztDQUNmOzs7Ozs7Ozs7O0FBVUQsU0FBUyxjQUFjLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRTtFQUNuQyxNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQzs7RUFFdEIsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDOzs7OztFQUtmLElBQUksUUFBUSxLQUFLLE9BQU8sTUFBTSxFQUFFLEVBQUEsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFBOztFQUU3QyxLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRTtJQUNuQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFO01BQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDeEU7R0FDRjs7RUFFRCxPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0NBQ3JEOzs7OztBQUtELGFBQWlCLEdBQUcsY0FBYyxDQUFDO0FBQ25DLFNBQWEsR0FBRyxXQUFXLENBQUM7Ozs7Ozs7QUN4RTVCLElBQUksVUFFVSxHQUFHLHlDQUF5QztJQUN0RCxPQUFPLEdBQUcsK0JBQStCLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBYzlDLElBQUksS0FBSyxHQUFHO0VBQ1YsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0VBQ2IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO0VBQ2QsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0VBQ2pCLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7RUFDaEIsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQzlCLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO0VBQ2pDLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztDQUNuQyxDQUFDOzs7Ozs7Ozs7O0FBVUYsSUFBSSxNQUFNLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUFjbkMsU0FBUyxTQUFTLENBQUMsR0FBRyxFQUFFO0VBQ3RCLElBQUksUUFBUSxHQUFHQSxjQUFNLElBQUlBLGNBQU0sQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO0VBQy9DLEdBQUcsR0FBRyxHQUFHLElBQUksUUFBUSxDQUFDOztFQUV0QixJQUFJLGdCQUFnQixHQUFHLEVBQUU7TUFDckIsSUFBSSxHQUFHLE9BQU8sR0FBRztNQUNqQixHQUFHLENBQUM7O0VBRVIsSUFBSSxPQUFPLEtBQUssR0FBRyxDQUFDLFFBQVEsRUFBRTtJQUM1QixnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0dBQ3hELE1BQU0sSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFO0lBQzVCLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNwQyxLQUFLLEdBQUcsSUFBSSxNQUFNLEVBQUUsRUFBQSxPQUFPLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUE7R0FDbEQsTUFBTSxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7SUFDNUIsS0FBSyxHQUFHLElBQUksR0FBRyxFQUFFO01BQ2YsSUFBSSxHQUFHLElBQUksTUFBTSxFQUFFLEVBQUEsU0FBUyxFQUFBO01BQzVCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUNsQzs7SUFFRCxJQUFJLGdCQUFnQixDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUU7TUFDMUMsZ0JBQWdCLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ25EO0dBQ0Y7O0VBRUQsT0FBTyxnQkFBZ0IsQ0FBQztDQUN6Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFpQkQsU0FBUyxlQUFlLENBQUMsT0FBTyxFQUFFO0VBQ2hDLElBQUksS0FBSyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7O0VBRXJDLE9BQU87SUFDTCxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxFQUFFO0lBQ2hELE9BQU8sRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNuQixJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztHQUNmLENBQUM7Q0FDSDs7Ozs7Ozs7OztBQVVELFNBQVMsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUU7RUFDL0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDeEUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNO01BQ2YsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO01BQ2xCLE9BQU8sR0FBRyxLQUFLO01BQ2YsRUFBRSxHQUFHLENBQUMsQ0FBQzs7RUFFWCxPQUFPLENBQUMsRUFBRSxFQUFFO0lBQ1YsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO01BQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0tBQ25CLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFO01BQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO01BQ2xCLEVBQUUsRUFBRSxDQUFDO0tBQ04sTUFBTSxJQUFJLEVBQUUsRUFBRTtNQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFBLE9BQU8sR0FBRyxJQUFJLENBQUMsRUFBQTtNQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztNQUNsQixFQUFFLEVBQUUsQ0FBQztLQUNOO0dBQ0Y7O0VBRUQsSUFBSSxPQUFPLEVBQUUsRUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUE7RUFDOUIsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsRUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUE7O0VBRWpELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztDQUN2Qjs7Ozs7Ozs7Ozs7OztBQWFELFNBQVMsR0FBRyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFO0VBQ3RDLElBQUksRUFBRSxJQUFJLFlBQVksR0FBRyxDQUFDLEVBQUU7SUFDMUIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0dBQzNDOztFQUVELElBQUksUUFBUSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxHQUFHO01BQ25ELFlBQVksR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFO01BQzVCLElBQUksR0FBRyxPQUFPLFFBQVE7TUFDdEIsR0FBRyxHQUFHLElBQUk7TUFDVixDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7O0VBYVYsSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7SUFDMUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztJQUNsQixRQUFRLEdBQUcsSUFBSSxDQUFDO0dBQ2pCOztFQUVELElBQUksTUFBTSxJQUFJLFVBQVUsS0FBSyxPQUFPLE1BQU0sRUFBRSxFQUFBLE1BQU0sR0FBR0MsZ0JBQUUsQ0FBQyxLQUFLLENBQUMsRUFBQTs7RUFFOUQsUUFBUSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7Ozs7RUFLL0IsU0FBUyxHQUFHLGVBQWUsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7RUFDM0MsUUFBUSxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7RUFDckQsR0FBRyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDO0VBQ2hFLEdBQUcsQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztFQUM3RCxPQUFPLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQzs7Ozs7O0VBTXpCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLEVBQUEsWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDLEVBQUE7O0VBRS9ELE9BQU8sQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDbkMsV0FBVyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixLQUFLLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZCLEdBQUcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7O0lBRXJCLElBQUksS0FBSyxLQUFLLEtBQUssRUFBRTtNQUNuQixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDO0tBQ3BCLE1BQU0sSUFBSSxRQUFRLEtBQUssT0FBTyxLQUFLLEVBQUU7TUFDcEMsSUFBSSxFQUFFLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7UUFDckMsSUFBSSxRQUFRLEtBQUssT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7VUFDdEMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1VBQ25DLE9BQU8sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNqRCxNQUFNO1VBQ0wsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7VUFDaEMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ25DO09BQ0Y7S0FDRixNQUFNLEtBQUssS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7TUFDeEMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUNwQixPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3pDOztJQUVELEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDO01BQ2pCLFFBQVEsSUFBSSxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO0tBQ3RELENBQUM7Ozs7OztJQU1GLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUEsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFBO0dBQ3ZEOzs7Ozs7O0VBT0QsSUFBSSxNQUFNLEVBQUUsRUFBQSxHQUFHLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBQTs7Ozs7RUFLMUM7TUFDSSxRQUFRO09BQ1AsUUFBUSxDQUFDLE9BQU87T0FDaEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztRQUM3QixHQUFHLENBQUMsUUFBUSxLQUFLLEVBQUUsSUFBSSxRQUFRLENBQUMsUUFBUSxLQUFLLEVBQUUsQ0FBQztJQUNwRDtJQUNBLEdBQUcsQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0dBQ3pEOzs7Ozs7O0VBT0QsSUFBSSxDQUFDQyxZQUFRLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7SUFDckMsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQ3hCLEdBQUcsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0dBQ2Y7Ozs7O0VBS0QsR0FBRyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztFQUNqQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUU7SUFDWixXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbEMsR0FBRyxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BDLEdBQUcsQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztHQUNyQzs7RUFFRCxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLE9BQU87TUFDN0QsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7TUFDNUIsTUFBTSxDQUFDOzs7OztFQUtYLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO0NBQzNCOzs7Ozs7Ozs7Ozs7Ozs7QUFlRCxTQUFTLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtFQUM1QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUM7O0VBRWYsUUFBUSxJQUFJO0lBQ1YsS0FBSyxPQUFPO01BQ1YsSUFBSSxRQUFRLEtBQUssT0FBTyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtRQUM3QyxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUlELGdCQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO09BQ2pDOztNQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7TUFDbEIsTUFBTTs7SUFFUixLQUFLLE1BQU07TUFDVCxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDOztNQUVsQixJQUFJLENBQUNDLFlBQVEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ2xDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUN4QixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO09BQ2hCLE1BQU0sSUFBSSxLQUFLLEVBQUU7UUFDaEIsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUM7T0FDckM7O01BRUQsTUFBTTs7SUFFUixLQUFLLFVBQVU7TUFDYixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDOztNQUVsQixJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBQSxLQUFLLElBQUksR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBQTtNQUNyQyxHQUFHLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztNQUNqQixNQUFNOztJQUVSLEtBQUssTUFBTTtNQUNULEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7O01BRWxCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN2QixLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixHQUFHLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixHQUFHLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7T0FDaEMsTUFBTTtRQUNMLEdBQUcsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO09BQ2Y7O01BRUQsTUFBTTs7SUFFUixLQUFLLFVBQVU7TUFDYixHQUFHLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztNQUNuQyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDO01BQ2xCLE1BQU07O0lBRVIsS0FBSyxVQUFVLENBQUM7SUFDaEIsS0FBSyxNQUFNO01BQ1QsSUFBSSxLQUFLLEVBQUU7UUFDVCxJQUFJLElBQUksR0FBRyxJQUFJLEtBQUssVUFBVSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDM0MsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDO09BQzdELE1BQU07UUFDTCxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO09BQ25CO01BQ0QsTUFBTTs7SUFFUjtNQUNFLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7R0FDckI7O0VBRUQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDckMsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDOztJQUVuQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFBLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBQTtHQUNyRDs7RUFFRCxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLE9BQU87TUFDN0QsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7TUFDNUIsTUFBTSxDQUFDOztFQUVYLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDOztFQUUxQixPQUFPLEdBQUcsQ0FBQztDQUNaOzs7Ozs7Ozs7QUFTRCxTQUFTLFFBQVEsQ0FBQyxTQUFTLEVBQUU7RUFDM0IsSUFBSSxDQUFDLFNBQVMsSUFBSSxVQUFVLEtBQUssT0FBTyxTQUFTLEVBQUUsRUFBQSxTQUFTLEdBQUdELGdCQUFFLENBQUMsU0FBUyxDQUFDLEVBQUE7O0VBRTVFLElBQUksS0FBSztNQUNMLEdBQUcsR0FBRyxJQUFJO01BQ1YsUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUM7O0VBRTVCLElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsRUFBQSxRQUFRLElBQUksR0FBRyxDQUFDLEVBQUE7O0VBRTlFLElBQUksTUFBTSxHQUFHLFFBQVEsSUFBSSxHQUFHLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQzs7RUFFbEQsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFO0lBQ2hCLE1BQU0sSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLElBQUksR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFBLE1BQU0sSUFBSSxHQUFHLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFBO0lBQzlDLE1BQU0sSUFBSSxHQUFHLENBQUM7R0FDZjs7RUFFRCxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDOztFQUVsQyxLQUFLLEdBQUcsUUFBUSxLQUFLLE9BQU8sR0FBRyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7RUFDekUsSUFBSSxLQUFLLEVBQUUsRUFBQSxNQUFNLElBQUksR0FBRyxLQUFLLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLEtBQUssR0FBRyxLQUFLLENBQUMsRUFBQTs7RUFFbEUsSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUEsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBQTs7RUFFakMsT0FBTyxNQUFNLENBQUM7Q0FDZjs7QUFFRCxHQUFHLENBQUMsU0FBUyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUM7Ozs7OztBQU1qRCxHQUFHLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztBQUN0QyxHQUFHLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQztBQUN6QixHQUFHLENBQUMsRUFBRSxHQUFHQSxnQkFBRSxDQUFDOztBQUVaLFlBQWMsR0FBRyxHQUFHLENBQUM7O0FDNVpyQjs7Ozs7Ozs7QUFRQSxBQUFlLFNBQVMsS0FBSyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUU7RUFDL0MsVUFBVSxDQUFDLFVBQUEsY0FBYyxFQUFDLFNBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBQSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztDQUN6RTs7QUNWYyxTQUFTLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFOztFQUUzQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxNQUFNLEVBQUU7SUFDckUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7R0FDckM7O0NBRUY7O0FDTk0sU0FBUyxNQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRTtFQUN0Q0UsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDO0VBQ25CLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQSxXQUFXLEVBQUM7SUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRTtNQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0tBQzNCO0dBQ0YsQ0FBQyxDQUFDOztFQUVILE9BQU8sT0FBTyxDQUFDO0NBQ2hCOztBQUVELEFBQU8sU0FBUyxNQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRTtFQUN0Q0EsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDO0VBQ25CLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQSxXQUFXLEVBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7TUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztLQUMzQjtHQUNGLENBQUMsQ0FBQzs7RUFFSCxPQUFPLE9BQU8sQ0FBQztDQUNoQjs7Ozs7Ozs7QUNaRCxJQUFNLFdBQVcsR0FBQyxvQkFDTCxHQUFHO0VBQ2QsSUFBTSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7Q0FDckIsQ0FBQTs7Ozs7Ozs7OztBQVVILHNCQUFFLGdCQUFnQiw4QkFBQyxJQUFJLEVBQUUsUUFBUSxxQkFBcUI7RUFDcEQsSUFBTSxPQUFPLFFBQVEsS0FBSyxVQUFVLEVBQUU7SUFDcEMsSUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO01BQzFDLElBQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0tBQzNCOzs7SUFHSCxJQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLFVBQUEsSUFBSSxFQUFDLFNBQUcsSUFBSSxLQUFLLFFBQVEsR0FBQSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtNQUMxRSxJQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztLQUNyQztHQUNGO0NBQ0YsQ0FBQTs7Ozs7Ozs7O0FBU0gsc0JBQUUsbUJBQW1CLGlDQUFDLElBQUksRUFBRSxnQkFBZ0IscUJBQXFCO0VBQy9ELElBQVEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUNoRCxJQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxVQUFBLFFBQVEsRUFBQyxTQUFHLFFBQVEsS0FBSyxnQkFBZ0IsR0FBQSxDQUFDLENBQUM7Q0FDNUYsQ0FBQTs7Ozs7Ozs7QUFRSCxzQkFBRSxhQUFhLDJCQUFDLEtBQUssRUFBc0I7Ozs7O0VBQ3pDLElBQVEsU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7RUFDL0IsSUFBUSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQzs7RUFFOUMsSUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUU7SUFDL0IsT0FBUyxLQUFLLENBQUM7R0FDZDs7RUFFSCxTQUFXLENBQUMsT0FBTyxDQUFDLFVBQUEsUUFBUSxFQUFDO0lBQzNCLElBQU0sZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7TUFDaEMsUUFBVSxDQUFDLEtBQUssQ0FBQ0MsTUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0tBQ3ZDLE1BQU07TUFDUCxRQUFVLENBQUMsSUFBSSxDQUFDQSxNQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDNUI7R0FDRixDQUFDLENBQUM7O0VBRUwsT0FBUyxJQUFJLENBQUM7Q0FDYixDQUFBLEFBR0gsQUFBMkI7Ozs7Ozs7QUNqRTNCLElBQU0sYUFBYSxHQUFDLHNCQUNQLEdBQUc7RUFDZCxJQUFNLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztDQUNsQixDQUFBOzs7Ozs7Ozs7QUFTSCx3QkFBRSxlQUFlLDZCQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7RUFDaEMsSUFBUSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztFQUU1QyxJQUFNLGdCQUFnQixJQUFJLGdCQUFnQixDQUFDLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO0lBQzFHLGdCQUFrQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDOUMsT0FBUyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7R0FDaEM7Q0FDRixDQUFBOzs7OztBQUtILHdCQUFFLG1CQUFtQixpQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFO0VBQ3JDLElBQVEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7O0VBRXRELElBQU0sZ0JBQWdCLElBQUksZ0JBQWdCLENBQUMsTUFBTSxJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7SUFDMUcsSUFBTSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUM3QyxnQkFBa0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0tBQzdDOztJQUVILGdCQUFrQixDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7R0FDeEQ7Q0FDRixDQUFBOzs7Ozs7Ozs7QUFTSCx3QkFBRSxZQUFZLDBCQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUU7RUFDMUIsSUFBUSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztFQUU1QyxJQUFNLENBQUMsZ0JBQWdCLEVBQUU7SUFDdkIsSUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRztNQUNuQixRQUFFLE1BQU07TUFDUixVQUFZLEVBQUUsRUFBRTtNQUNoQixlQUFpQixFQUFFLEVBQUU7S0FDcEIsQ0FBQzs7SUFFSixPQUFTLE1BQU0sQ0FBQztHQUNmO0NBQ0YsQ0FBQTs7Ozs7OztBQU9ILHdCQUFFLFlBQVksMEJBQUMsR0FBRyxFQUFFO0VBQ2xCLElBQVEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzs7RUFFNUMsSUFBTSxnQkFBZ0IsRUFBRTtJQUN0QixPQUFTLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztHQUNoQztDQUNGLENBQUE7Ozs7Ozs7OztBQVNILHdCQUFFLGdCQUFnQiw4QkFBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTtFQUN6QyxJQUFNLFVBQVUsQ0FBQztFQUNqQixJQUFRLGdCQUFnQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7O0VBRTVDLFVBQVksR0FBRyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDOztFQUVuRSxJQUFNLElBQUksRUFBRTtJQUNWLElBQVEsT0FBTyxHQUFHLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6RCxVQUFZLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztHQUM1Qjs7RUFFSCxPQUFTLFdBQVcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQUEsU0FBUyxFQUFDLFNBQUcsU0FBUyxLQUFLLFdBQVcsR0FBQSxDQUFDLEdBQUcsVUFBVSxDQUFDO0NBQzdGLENBQUE7Ozs7Ozs7QUFPSCx3QkFBRSxZQUFZLDBCQUFDLEdBQUcsRUFBRTtFQUNsQixPQUFTLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Q0FDekIsQ0FBQTs7Ozs7Ozs7QUFRSCx3QkFBRSxlQUFlLDZCQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7RUFDaEMsSUFBUSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztFQUU1QyxJQUFNLGdCQUFnQixFQUFFO0lBQ3RCLGdCQUFrQixDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFVBQUEsTUFBTSxFQUFDLFNBQUcsTUFBTSxLQUFLLFNBQVMsR0FBQSxDQUFDLENBQUM7R0FDbkc7Q0FDRixDQUFBOzs7OztBQUtILHdCQUFFLHdCQUF3QixzQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFO0VBQzFDLElBQVEsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7RUFDdEQsSUFBUSxXQUFXLEdBQUcsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDOztFQUU3RCxJQUFNLGdCQUFnQixJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUU7SUFDOUMsZ0JBQWtCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsVUFBQSxNQUFNLEVBQUMsU0FBRyxNQUFNLEtBQUssU0FBUyxHQUFBLENBQUMsQ0FBQztHQUM5RjtDQUNGLENBQUE7O0FBR0gsb0JBQWUsSUFBSSxhQUFhLEVBQUUsQ0FBQzs7QUN0SW5DOzs7QUFHQSxBQUFPRCxJQUFNLFdBQVcsR0FBRztFQUN6QixZQUFZLEVBQUUsSUFBSTtFQUNsQixnQkFBZ0IsRUFBRSxJQUFJO0VBQ3RCLG9CQUFvQixFQUFFLElBQUk7RUFDMUIsaUJBQWlCLEVBQUUsSUFBSTtFQUN2QixlQUFlLEVBQUUsSUFBSTtFQUNyQixjQUFjLEVBQUUsSUFBSTtFQUNwQixnQkFBZ0IsRUFBRSxJQUFJO0VBQ3RCLGdCQUFnQixFQUFFLElBQUk7RUFDdEIsZUFBZSxFQUFFLElBQUk7RUFDckIsaUJBQWlCLEVBQUUsSUFBSTtFQUN2QixjQUFjLEVBQUUsSUFBSTtFQUNwQixlQUFlLEVBQUUsSUFBSTtFQUNyQixlQUFlLEVBQUUsSUFBSTtFQUNyQixhQUFhLEVBQUUsSUFBSTtDQUNwQixDQUFDOztBQUVGLEFBQU9BLElBQU0sWUFBWSxHQUFHO0VBQzFCLGlCQUFpQixFQUFFLGtDQUFrQztFQUNyRCxXQUFXLEVBQUUsMkNBQTJDO0VBQ3hELEtBQUssRUFBRTtJQUNMLFNBQVMsRUFBRSw4QkFBOEI7SUFDekMsT0FBTyxFQUFFLHFDQUFxQztJQUM5QyxLQUFLLEVBQUUsbUNBQW1DO0dBQzNDO0NBQ0YsQ0FBQzs7QUM1QmEsSUFBTSxjQUFjLEdBQUM7O0FBQUEseUJBRWxDLGVBQWUsK0JBQUcsRUFBRSxDQUFBO0FBQ3RCLHlCQUFFLHdCQUF3Qix3Q0FBRyxFQUFFLENBQUE7Ozs7QUFJL0IseUJBQUUsU0FBUyx1QkFBQyxJQUFrQixFQUFFLE9BQWUsRUFBRSxVQUFrQixFQUFFOytCQUFyRCxHQUFHLFdBQVcsQ0FBUztxQ0FBQSxHQUFHLEtBQUssQ0FBWTsyQ0FBQSxHQUFHLEtBQUs7O0VBQ2pFLElBQU0sQ0FBQyxJQUFJLEdBQUcsRUFBQyxHQUFFLElBQUksQ0FBRztFQUN4QixJQUFNLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUNsQyxJQUFNLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztDQUN2QyxDQUFBLEFBQ0Y7O0FDVEQsSUFBcUIsS0FBSztFQUF3QixjQUNyQyxDQUFDLElBQUksRUFBRSxlQUFvQixFQUFFO3FEQUFQLEdBQUcsRUFBRTs7SUFDcENFLGlCQUFLLEtBQUEsQ0FBQyxJQUFBLENBQUMsQ0FBQzs7SUFFUixJQUFJLENBQUMsSUFBSSxFQUFFO01BQ1QsTUFBTSxJQUFJLFNBQVMsRUFBQyxDQUFHLFlBQVksQ0FBQyxXQUFXLCtDQUEwQyxFQUFFLENBQUM7S0FDN0Y7O0lBRUQsSUFBSSxPQUFPLGVBQWUsS0FBSyxRQUFRLEVBQUU7TUFDdkMsTUFBTSxJQUFJLFNBQVMsRUFBQyxDQUFHLFlBQVksQ0FBQyxXQUFXLHNEQUFpRCxFQUFFLENBQUM7S0FDcEc7O0lBRUQsSUFBUSxPQUFPO0lBQUUsSUFBQSxVQUFVLDhCQUFyQjs7SUFFTixJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUMsR0FBRSxJQUFJLENBQUc7SUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDcEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztJQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztJQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQzNELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQzNCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7R0FDbkQ7Ozs7c0NBQUE7OztFQTFCZ0MsY0EyQmxDLEdBQUE7O0FDM0JELElBQXFCLFlBQVk7RUFBd0IscUJBQzVDLENBQUMsSUFBSSxFQUFFLGVBQW9CLEVBQUU7cURBQVAsR0FBRyxFQUFFOztJQUNwQ0EsaUJBQUssS0FBQSxDQUFDLElBQUEsQ0FBQyxDQUFDOztJQUVSLElBQUksQ0FBQyxJQUFJLEVBQUU7TUFDVCxNQUFNLElBQUksU0FBUyxFQUFDLENBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLCtDQUEwQyxFQUFFLENBQUM7S0FDL0Y7O0lBRUQsSUFBSSxPQUFPLGVBQWUsS0FBSyxRQUFRLEVBQUU7TUFDdkMsTUFBTSxJQUFJLFNBQVMsRUFBQyxDQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsT0FBTyxxREFBZ0QsRUFBRSxDQUFDO0tBQ3JHOztJQUVELElBQVEsT0FBTztJQUFFLElBQUEsVUFBVTtJQUFFLElBQUEsSUFBSTtJQUFFLElBQUEsTUFBTTtJQUFFLElBQUEsV0FBVztJQUFFLElBQUEsS0FBSyx5QkFBdkQ7O0lBRU4sSUFBSSxDQUFDLElBQUksR0FBRyxFQUFDLEdBQUUsSUFBSSxDQUFHO0lBQ3RCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzVCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ3hCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7SUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUMzRCxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ2xELElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBQyxHQUFFLE1BQU0sQ0FBRztJQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sS0FBSyxLQUFLLFdBQVcsR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDO0lBQ3pELElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxJQUFJLEtBQUssV0FBVyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7SUFDdEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFDLElBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQSxDQUFHO0dBQzNDOzs7O29EQUFBOzs7RUE5QnVDLGNBK0J6QyxHQUFBOztBQy9CRCxJQUFxQixVQUFVO0VBQXdCLG1CQUMxQyxDQUFDLElBQUksRUFBRSxlQUFvQixFQUFFO3FEQUFQLEdBQUcsRUFBRTs7SUFDcENBLGlCQUFLLEtBQUEsQ0FBQyxJQUFBLENBQUMsQ0FBQzs7SUFFUixJQUFJLENBQUMsSUFBSSxFQUFFO01BQ1QsTUFBTSxJQUFJLFNBQVMsRUFBQyxDQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSywrQ0FBMEMsRUFBRSxDQUFDO0tBQzdGOztJQUVELElBQUksT0FBTyxlQUFlLEtBQUssUUFBUSxFQUFFO01BQ3ZDLE1BQU0sSUFBSSxTQUFTLEVBQUMsQ0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLEtBQUsscURBQWdELEVBQUUsQ0FBQztLQUNuRzs7SUFFRCxJQUFRLE9BQU87SUFBRSxJQUFBLFVBQVU7SUFBRSxJQUFBLElBQUk7SUFBRSxJQUFBLE1BQU07SUFBRSxJQUFBLFFBQVEsNEJBQTdDOztJQUVOLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBQyxHQUFFLElBQUksQ0FBRztJQUN0QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztJQUNuQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztJQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUN4QixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNwQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0lBQzlCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0lBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDM0QsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFDMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUNsRCxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sSUFBSSxLQUFLLFFBQVEsR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5RCxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUMsSUFBRSxNQUFNLElBQUksRUFBRSxDQUFBLENBQUc7SUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEtBQUssQ0FBQztHQUN0RDs7OztnREFBQTs7O0VBN0JxQyxjQThCdkMsR0FBQTs7Ozs7Ozs7QUN2QkQsU0FBUyxXQUFXLENBQUMsTUFBTSxFQUFFO0VBQzNCLElBQVEsSUFBSTtFQUFFLElBQUEsTUFBTSxpQkFBZDtFQUNORixJQUFNLFdBQVcsR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQzs7RUFFcEMsSUFBSSxNQUFNLEVBQUU7SUFDVixXQUFXLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUM1QixXQUFXLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztJQUNoQyxXQUFXLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztHQUNwQzs7RUFFRCxPQUFPLFdBQVcsQ0FBQztDQUNwQjs7Ozs7Ozs7QUFRRCxTQUFTLGtCQUFrQixDQUFDLE1BQU0sRUFBRTtFQUNsQyxJQUFRLElBQUk7RUFBRSxJQUFBLE1BQU07RUFBRSxJQUFBLElBQUk7RUFBRSxJQUFBLE1BQU0saUJBQTVCO0VBQ05BLElBQU0sWUFBWSxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtJQUMxQyxNQUFBLElBQUk7SUFDSixRQUFBLE1BQU07R0FDUCxDQUFDLENBQUM7O0VBRUgsSUFBSSxNQUFNLEVBQUU7SUFDVixZQUFZLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUM3QixZQUFZLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztJQUNqQyxZQUFZLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztHQUNyQzs7RUFFRCxPQUFPLFlBQVksQ0FBQztDQUNyQjs7Ozs7Ozs7QUFRRCxTQUFTLGdCQUFnQixDQUFDLE1BQU0sRUFBRTtFQUNoQyxJQUFRLElBQUk7RUFBRSxJQUFBLE1BQU07RUFBRSxJQUFBLElBQUk7RUFBRSxJQUFBLE1BQU0saUJBQTVCO0VBQ04sSUFBTSxRQUFRLG1CQUFWOztFQUVKLElBQUksQ0FBQyxRQUFRLEVBQUU7SUFDYixRQUFRLEdBQUcsSUFBSSxLQUFLLElBQUksQ0FBQztHQUMxQjs7RUFFREEsSUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO0lBQ3RDLE1BQUEsSUFBSTtJQUNKLFFBQUEsTUFBTTtJQUNOLFVBQUEsUUFBUTtHQUNULENBQUMsQ0FBQzs7RUFFSCxJQUFJLE1BQU0sRUFBRTtJQUNWLFVBQVUsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQzNCLFVBQVUsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0lBQy9CLFVBQVUsQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDO0dBQ25DOztFQUVELE9BQU8sVUFBVSxDQUFDO0NBQ25CLEFBRUQsQUFBNkQ7O0FDckV0RCxTQUFTLHdCQUF3QixDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0VBQzlELE9BQU8sQ0FBQyxVQUFVLEdBQUdHLFdBQVMsQ0FBQyxPQUFPLENBQUM7O0VBRXZDSCxJQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztFQUN2REEsSUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7SUFDbEMsSUFBSSxFQUFFLE9BQU87SUFDYixNQUFNLEVBQUUsT0FBTztJQUNmLE1BQUEsSUFBSTtJQUNKLFFBQUEsTUFBTTtHQUNQLENBQUMsQ0FBQzs7RUFFSCxLQUFLLENBQUMsWUFBRztJQUNQLGFBQWEsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFcEQsT0FBTyxDQUFDLFVBQVUsR0FBR0csV0FBUyxDQUFDLE1BQU0sQ0FBQztJQUN0QyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDOztJQUVsQyxJQUFJLE1BQU0sRUFBRTtNQUNWLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0tBQzFDO0dBQ0YsRUFBRSxPQUFPLENBQUMsQ0FBQztDQUNiOztBQUVELEFBQU8sU0FBUyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtFQUM3RCxPQUFPLENBQUMsVUFBVSxHQUFHQSxXQUFTLENBQUMsT0FBTyxDQUFDOztFQUV2Q0gsSUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7RUFDdkRBLElBQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDO0lBQ2xDLElBQUksRUFBRSxPQUFPO0lBQ2IsTUFBTSxFQUFFLE9BQU87SUFDZixNQUFBLElBQUk7SUFDSixRQUFBLE1BQU07SUFDTixRQUFRLEVBQUUsS0FBSztHQUNoQixDQUFDLENBQUM7O0VBRUhBLElBQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQztJQUM3QixJQUFJLEVBQUUsT0FBTztJQUNiLE1BQU0sRUFBRSxPQUFPO0dBQ2hCLENBQUMsQ0FBQzs7RUFFSCxLQUFLLENBQUMsWUFBRztJQUNQLGFBQWEsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFcEQsT0FBTyxDQUFDLFVBQVUsR0FBR0csV0FBUyxDQUFDLE1BQU0sQ0FBQztJQUN0QyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7O0lBRWxDLElBQUksTUFBTSxFQUFFO01BQ1YsTUFBTSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDMUM7R0FDRixFQUFFLE9BQU8sQ0FBQyxDQUFDO0NBQ2I7O0FDeERjLFNBQVMsaUJBQWlCLENBQUMsSUFBSSxFQUFFO0VBQzlDLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLGVBQWUsSUFBSSxFQUFFLElBQUksWUFBWSxXQUFXLENBQUMsRUFBRTtJQUM5RixJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQ3JCOztFQUVELE9BQU8sSUFBSSxDQUFDO0NBQ2I7O0FDRGMsU0FBUyxZQUFZLENBQUMsTUFBTSxFQUFFO0VBQzNDSCxJQUFNLE9BQU8sR0FBRztJQUNkLEdBQUcsY0FBQSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUU7TUFDYixJQUFJLElBQUksS0FBSyxPQUFPLEVBQUU7UUFDcEIsT0FBTyxTQUFTLEtBQUssQ0FBQyxPQUFZLEVBQUU7MkNBQVAsR0FBRyxFQUFFOztVQUNoQ0EsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxXQUFXLENBQUMsWUFBWSxDQUFDO1VBQ3REQSxJQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQzs7VUFFcEMsd0JBQXdCLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztTQUNoRCxDQUFDO09BQ0g7O01BRUQsSUFBSSxJQUFJLEtBQUssTUFBTSxFQUFFO1FBQ25CLE9BQU8sU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFO1VBQ3pCLElBQUksR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQzs7VUFFL0IsTUFBTSxDQUFDLGFBQWE7WUFDbEIsa0JBQWtCLENBQUM7Y0FDakIsSUFBSSxFQUFFLFNBQVM7Y0FDZixNQUFBLElBQUk7Y0FDSixNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUc7Y0FDaEIsUUFBQSxNQUFNO2FBQ1AsQ0FBQztXQUNILENBQUM7U0FDSCxDQUFDO09BQ0g7O01BRUQsSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFO1FBQ2pCLE9BQU8sU0FBUyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtVQUNsQyxNQUFNLENBQUMsZ0JBQWdCLEVBQUMsVUFBUyxHQUFFLElBQUksR0FBSSxFQUFFLENBQUMsQ0FBQztTQUNoRCxDQUFDO09BQ0g7O01BRUQsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDbEI7R0FDRixDQUFDOztFQUVGQSxJQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7RUFDekMsT0FBTyxLQUFLLENBQUM7Q0FDZDs7QUM1Q2MsU0FBUyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7O0VBRTdDQSxJQUFNLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7RUFDdEQsT0FBTyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0NBQ3hDOztBQ0RjLFNBQVMsZUFBZSxDQUFDLEdBQUcsRUFBRTtFQUMzQ0EsSUFBTSxTQUFTLEdBQUcsSUFBSUksUUFBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0VBQy9CLElBQVEsUUFBUTtFQUFFLElBQUEsUUFBUTtFQUFFLElBQUEsSUFBSSxrQkFBMUI7O0VBRU4sSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNSLE1BQU0sSUFBSSxTQUFTLEVBQUMsQ0FBRyxZQUFZLENBQUMsaUJBQWlCLCtDQUEwQyxFQUFFLENBQUM7R0FDbkc7O0VBRUQsSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUNiLFNBQVMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO0dBQzFCOztFQUVELElBQUksUUFBUSxLQUFLLEVBQUUsRUFBRTtJQUNuQixNQUFNLElBQUksV0FBVyxFQUFDLENBQUcsWUFBWSxDQUFDLGlCQUFpQixnQkFBVyxJQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQSxrQkFBYyxFQUFFLENBQUM7R0FDMUc7O0VBRUQsSUFBSSxRQUFRLEtBQUssS0FBSyxJQUFJLFFBQVEsS0FBSyxNQUFNLEVBQUU7SUFDN0MsTUFBTSxJQUFJLFdBQVc7T0FDbkIsQ0FBRyxZQUFZLENBQUMsaUJBQWlCLHVEQUFrRCxHQUFFLFFBQVEsc0JBQWtCO0tBQ2hILENBQUM7R0FDSDs7RUFFRCxJQUFJLElBQUksS0FBSyxFQUFFLEVBQUU7O0lBRWYsTUFBTSxJQUFJLFdBQVc7T0FDbkIsQ0FDRSxZQUFZLENBQUMsaUJBQWlCLGdEQUNXLEdBQUUsSUFBSSxnRUFBNEQ7S0FDOUcsQ0FBQzs7R0FFSDs7RUFFRCxPQUFPLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztDQUM3Qjs7QUNsQ2MsU0FBUyxvQkFBb0IsQ0FBQyxTQUFjLEVBQUU7dUNBQVAsR0FBRyxFQUFFOztFQUN6RCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLEVBQUU7SUFDOUQsTUFBTSxJQUFJLFdBQVcsRUFBQyxDQUFHLFlBQVksQ0FBQyxpQkFBaUIsd0JBQW1CLElBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFBLGtCQUFjLEVBQUUsQ0FBQztHQUNsSDs7RUFFRCxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVEsRUFBRTtJQUNqQyxTQUFTLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztHQUN6Qjs7RUFFREosSUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUMsRUFBQyxVQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDekUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDL0MsT0FBTyxDQUFDLENBQUM7R0FDVixFQUFFLEVBQUUsQ0FBQyxDQUFDOztFQUVQQSxJQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFBLENBQUMsRUFBQyxTQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUEsQ0FBQyxDQUFDOztFQUU5RCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0lBQ3pCLE1BQU0sSUFBSSxXQUFXLEVBQUMsQ0FBRyxZQUFZLENBQUMsaUJBQWlCLHdCQUFtQixJQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQSxxQkFBaUIsRUFBRSxDQUFDO0dBQzlHOztFQUVELE9BQU8sU0FBUyxDQUFDO0NBQ2xCOzs7Ozs7OztBQ0pELElBQU1HLFdBQVM7RUFBcUIsa0JBQ3ZCLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRTtJQUMxQkQsY0FBSyxLQUFBLENBQUMsSUFBQSxDQUFDLENBQUM7O0lBRVIsSUFBSSxDQUFDLEdBQUcsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsU0FBUyxHQUFHLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVDLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQzs7SUFFbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUM7SUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDOztJQUV2Q0YsSUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0lBZ0I3RCxLQUFLLENBQUMsU0FBUyxhQUFhLEdBQUc7TUFDN0IsSUFBSSxNQUFNLEVBQUU7UUFDVjtVQUNFLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWTtVQUMzQixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxLQUFLLFVBQVU7VUFDakQsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRTtVQUM5QjtVQUNBLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQzs7VUFFbkNLLEdBQU07WUFDSixPQUFPO2FBQ1AsMkJBQTBCLElBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQSx5RUFBcUU7V0FDMUcsQ0FBQzs7VUFFRixhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDOUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7VUFDakUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN2RyxNQUFNO1VBQ0wsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLFVBQVUsRUFBRTtZQUN4RkwsSUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNsRUEsSUFBTSxRQUFRLEdBQUcsZ0JBQWdCLEtBQUssRUFBRSxDQUFDO1lBQ3pDQSxJQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDL0QsSUFBSSxRQUFRLElBQUksQ0FBQyxXQUFXLEVBQUU7Y0FDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDOztjQUVuQ0ssR0FBTSxDQUFDLE9BQU8sR0FBRSwyQkFBMEIsSUFBRSxJQUFJLENBQUMsR0FBRyxDQUFBLG1DQUErQixFQUFFLENBQUM7O2NBRXRGLGFBQWEsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztjQUM5QyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztjQUNqRSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO2NBQ3RHLE9BQU87YUFDUjtZQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsZ0JBQWdCLENBQUM7V0FDbEM7VUFDRCxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7VUFDakMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7VUFDaEUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUMvRTtPQUNGLE1BQU07UUFDTCxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQzs7UUFFdEdBLEdBQU0sQ0FBQyxPQUFPLEdBQUUsMkJBQTBCLElBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQSxhQUFTLEVBQUUsQ0FBQztPQUNqRTtLQUNGLEVBQUUsSUFBSSxDQUFDLENBQUM7R0FDVjs7Ozs7O2dGQUFBOztFQUVELG1CQUFBLE1BQVUsbUJBQUc7SUFDWCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO0dBQzVCLENBQUE7O0VBRUQsbUJBQUEsU0FBYSxtQkFBRztJQUNkLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7R0FDL0IsQ0FBQTs7RUFFRCxtQkFBQSxPQUFXLG1CQUFHO0lBQ1osT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztHQUM3QixDQUFBOztFQUVELG1CQUFBLE9BQVcsbUJBQUc7SUFDWixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO0dBQzdCLENBQUE7O0VBRUQsbUJBQUEsTUFBVSxpQkFBQyxRQUFRLEVBQUU7SUFDbkIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztJQUMzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0dBQ3pDLENBQUE7O0VBRUQsbUJBQUEsU0FBYSxpQkFBQyxRQUFRLEVBQUU7SUFDdEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUM5QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0dBQzVDLENBQUE7O0VBRUQsbUJBQUEsT0FBVyxpQkFBQyxRQUFRLEVBQUU7SUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0dBQzFDLENBQUE7O0VBRUQsbUJBQUEsT0FBVyxpQkFBQyxRQUFRLEVBQUU7SUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0dBQzFDLENBQUE7O0VBRUQsb0JBQUEsSUFBSSxrQkFBQyxJQUFJLEVBQUU7OztJQUNULElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxDQUFDLE1BQU0sRUFBRTtNQUNqRixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7S0FDcEU7Ozs7SUFJREwsSUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUM7TUFDdEMsSUFBSSxFQUFFLGlCQUFpQjtNQUN2QixNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUc7TUFDaEIsSUFBSSxFQUFFLGlCQUFpQixDQUFDLElBQUksQ0FBQztLQUM5QixDQUFDLENBQUM7O0lBRUhBLElBQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztJQUVwRCxJQUFJLE1BQU0sRUFBRTtNQUNWLEtBQUssQ0FBQyxZQUFHO1FBQ1BDLE1BQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO09BQ3hDLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDWjtHQUNGLENBQUE7O0VBRUQsb0JBQUEsS0FBSyxtQkFBQyxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQ2xCLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtNQUN0QixJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsS0FBSyxJQUFJLEtBQUssSUFBSSxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUU7UUFDL0UsTUFBTSxJQUFJLFNBQVM7V0FDakIsQ0FBRyxZQUFZLENBQUMsV0FBVywrREFBMEQsR0FBRSxJQUFJLGlCQUFhO1NBQ3pHLENBQUM7T0FDSDtLQUNGOztJQUVELElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtNQUN4QkQsSUFBTSxNQUFNLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7O01BRXpDLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRTtRQUNoQixNQUFNLElBQUksV0FBVyxFQUFDLENBQUcsWUFBWSxDQUFDLFdBQVcsc0RBQWlELEVBQUUsQ0FBQztPQUN0RztLQUNGOztJQUVELElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxDQUFDLE1BQU0sRUFBRTtNQUNqRixPQUFPO0tBQ1I7O0lBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxVQUFVLEVBQUU7TUFDNUMsdUJBQXVCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM3QyxNQUFNO01BQ0wsd0JBQXdCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM5QztHQUNGLENBQUE7Ozs7O0VBL0pxQixXQWdLdkIsR0FBQTs7QUFFREcsV0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDekJBLFdBQVMsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHQSxXQUFTLENBQUMsVUFBVSxDQUFDO0FBQ3REQSxXQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNuQkEsV0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUdBLFdBQVMsQ0FBQyxJQUFJLENBQUM7QUFDMUNBLFdBQVMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCQSxXQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBR0EsV0FBUyxDQUFDLE9BQU8sQ0FBQztBQUNoREEsV0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDckJBLFdBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHQSxXQUFTLENBQUMsTUFBTSxDQUFDLEFBRTlDLEFBQXlCOztBQzlMekIsYUFBZSxVQUFBLEdBQUcsRUFBQyxTQUNqQixHQUFHLENBQUMsTUFBTSxDQUFDLFVBQUMsT0FBTyxFQUFFLENBQUMsRUFBRTtJQUN0QixJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBQSxPQUFPLE9BQU8sQ0FBQyxFQUFBO0lBQzVDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztHQUMxQixFQUFFLEVBQUUsQ0FBQyxHQUFBLENBQUEsQUFBQzs7QUNKTSxTQUFTLG9CQUFvQixHQUFHO0VBQzdDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFO0lBQ2pDLE9BQU8sTUFBTSxDQUFDO0dBQ2Y7O0VBRUQsT0FBTyxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxPQUFPLEtBQUssVUFBVSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDO0NBQ25IOztBQ0lELElBQU1HLFFBQU07RUFBcUIsZUFDcEIsQ0FBQyxHQUFHLEVBQUUsT0FBWSxFQUFFO3FDQUFQLEdBQUcsRUFBRTs7SUFDM0JKLGNBQUssS0FBQSxDQUFDLElBQUEsQ0FBQyxDQUFDO0lBQ1JGLElBQU0sU0FBUyxHQUFHLElBQUlJLFFBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFL0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7TUFDdkIsU0FBUyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7S0FDMUI7O0lBRUQsSUFBSSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7O0lBRWhDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFDOUJKLElBQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFMUQsSUFBSSxDQUFDLE1BQU0sRUFBRTtNQUNYLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztNQUNuRCxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7S0FDbkU7O0lBRUQsSUFBSSxPQUFPLE9BQU8sQ0FBQyxZQUFZLEtBQUssV0FBVyxFQUFFO01BQy9DLE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0tBQzdCOztJQUVELElBQUksT0FBTyxPQUFPLENBQUMsY0FBYyxLQUFLLFdBQVcsRUFBRTtNQUNqRCxPQUFPLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztLQUMvQjs7SUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN2QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7R0FDZDs7Ozt3Q0FBQTs7Ozs7RUFLRCxpQkFBQSxLQUFLLHFCQUFHO0lBQ05BLElBQU0sU0FBUyxHQUFHTyxvQkFBWSxFQUFFLENBQUM7O0lBRWpDLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRTtNQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztLQUM5Qzs7SUFFRCxTQUFTLENBQUMsU0FBUyxHQUFHSixXQUFTLENBQUM7R0FDakMsQ0FBQTs7Ozs7RUFLRCxpQkFBQSxJQUFJLGtCQUFDLFFBQW1CLEVBQUU7dUNBQWIsR0FBRyxZQUFHLEVBQUs7O0lBQ3RCSCxJQUFNLFNBQVMsR0FBR08sb0JBQVksRUFBRSxDQUFDOztJQUVqQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtNQUMxQixTQUFTLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztLQUM5QyxNQUFNO01BQ0wsT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDO0tBQzVCOztJQUVELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7O0lBRTlCLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztJQUVyQyxJQUFJLE9BQU8sUUFBUSxLQUFLLFVBQVUsRUFBRTtNQUNsQyxRQUFRLEVBQUUsQ0FBQztLQUNaO0dBQ0YsQ0FBQTs7Ozs7Ozs7OztFQVVELGlCQUFBLEVBQUUsZ0JBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtJQUNqQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0dBQ3ZDLENBQUE7Ozs7Ozs7OztFQVNELGlCQUFBLEtBQUssbUJBQUMsT0FBWSxFQUFFO3FDQUFQLEdBQUcsRUFBRTs7SUFDaEIsSUFBUSxJQUFJO0lBQUUsSUFBQSxNQUFNO0lBQUUsSUFBQSxRQUFRLG9CQUF4QjtJQUNOUCxJQUFNLFNBQVMsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7O0lBSTNELGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztJQUVyQyxTQUFTLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTSxFQUFDO01BQ3ZCLE1BQU0sQ0FBQyxVQUFVLEdBQUdHLFdBQVMsQ0FBQyxLQUFLLENBQUM7TUFDcEMsTUFBTSxDQUFDLGFBQWE7UUFDbEIsZ0JBQWdCLENBQUM7VUFDZixJQUFJLEVBQUUsT0FBTztVQUNiLE1BQU0sRUFBRSxNQUFNO1VBQ2QsSUFBSSxFQUFFLElBQUksSUFBSSxXQUFXLENBQUMsWUFBWTtVQUN0QyxNQUFNLEVBQUUsTUFBTSxJQUFJLEVBQUU7VUFDcEIsVUFBQSxRQUFRO1NBQ1QsQ0FBQztPQUNILENBQUM7S0FDSCxDQUFDLENBQUM7O0lBRUgsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0dBQy9ELENBQUE7Ozs7O0VBS0QsaUJBQUEsSUFBSSxrQkFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQVksRUFBRTtzQkFBUDtxQ0FBQSxHQUFHLEVBQUU7O0lBQzVCLElBQU0sVUFBVSxzQkFBWjs7SUFFSixJQUFJLENBQUMsVUFBVSxFQUFFO01BQ2YsVUFBVSxHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDdkQ7O0lBRUQsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7TUFDdkQsSUFBSSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztNQUNsRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFBLElBQUksRUFBQyxTQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFBLENBQUMsQ0FBQztLQUNsRCxNQUFNO01BQ0wsSUFBSSxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2hDOztJQUVELFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNLEVBQUM7TUFDeEIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3ZCLE1BQU0sQ0FBQyxhQUFhLE1BQUE7VUFDbEIsVUFBQSxrQkFBa0IsQ0FBQztZQUNqQixJQUFJLEVBQUUsS0FBSztZQUNYLE1BQUEsSUFBSTtZQUNKLE1BQU0sRUFBRUYsTUFBSSxDQUFDLEdBQUc7WUFDaEIsTUFBTSxFQUFFLE1BQU07V0FDZixDQUFDLFdBQ0YsSUFBTyxFQUFBO1NBQ1IsQ0FBQztPQUNILE1BQU07UUFDTCxNQUFNLENBQUMsYUFBYTtVQUNsQixrQkFBa0IsQ0FBQztZQUNqQixJQUFJLEVBQUUsS0FBSztZQUNYLE1BQUEsSUFBSTtZQUNKLE1BQU0sRUFBRUEsTUFBSSxDQUFDLEdBQUc7WUFDaEIsTUFBTSxFQUFFLE1BQU07V0FDZixDQUFDO1NBQ0gsQ0FBQztPQUNIO0tBQ0YsQ0FBQyxDQUFDO0dBQ0osQ0FBQTs7Ozs7O0VBTUQsaUJBQUEsT0FBTyx1QkFBRztJQUNSLE9BQU8sYUFBYSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNqRCxDQUFBOzs7Ozs7O0VBT0QsaUJBQUEsRUFBRSxnQkFBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLGFBQWtCLEVBQUU7c0JBQVA7aURBQUEsR0FBRyxFQUFFOztJQUN0Q0QsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xCQSxJQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDOztJQUU3RyxPQUFPO01BQ0wsRUFBRSxFQUFFLFVBQUMsV0FBVyxFQUFFLGtCQUFrQixFQUFFLFNBQUdDLE1BQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDQSxNQUFJLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxHQUFBO01BQ3hHLElBQUksZUFBQSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUU7UUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsWUFBQSxVQUFVLEVBQUUsQ0FBQyxDQUFDO09BQ3hDO0tBQ0YsQ0FBQztHQUNILENBQUE7Ozs7O0VBS0QsaUJBQUEsRUFBRSxvQkFBVTs7OztJQUNWLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0dBQ2xDLENBQUE7Ozs7OztFQU1ELGlCQUFBLFFBQVEsc0JBQUMsS0FBSyxFQUFFO0lBQ2RELElBQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0lBRTNELElBQUksS0FBSyxLQUFLLE9BQU8sRUFBRTtNQUNyQixTQUFTLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTSxFQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxVQUFVLEdBQUdHLFdBQVMsQ0FBQyxLQUFLLENBQUM7UUFDcEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO09BQ3RELENBQUMsQ0FBQztLQUNKO0dBQ0YsQ0FBQTs7O0VBbE1rQixXQW1NcEIsR0FBQTs7Ozs7OztBQU9ERyxRQUFNLENBQUMsRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRTtFQUMzQixPQUFPLElBQUlBLFFBQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztDQUN4QixDQUFDLEFBRUYsQUFBc0I7Ozs7Ozs7QUMzTXRCLElBQU1FLFVBQVE7RUFBcUIsaUJBSXRCLENBQUMsR0FBaUIsRUFBRSxRQUFhLEVBQUU7c0JBQS9COzZCQUFBLEdBQUcsV0FBVyxDQUFVO3VDQUFBLEdBQUcsRUFBRTs7SUFDMUNOLGNBQUssS0FBQSxDQUFDLElBQUEsQ0FBQyxDQUFDOztJQUVSLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0lBQ3pCRixJQUFNLFNBQVMsR0FBRyxJQUFJSSxRQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7O0lBRS9CLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO01BQ3ZCLFNBQVMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO0tBQzFCOztJQUVELElBQUksQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2hDLElBQUksQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQztJQUN0QyxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQzs7SUFFbkIsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEtBQUssT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUMsRUFBRTtNQUN2RixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztLQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtNQUN6RCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM3Qjs7SUFFREosSUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7OztJQUs3RCxLQUFLLENBQUMsU0FBUyxhQUFhLEdBQUc7TUFDN0IsSUFBSSxNQUFNLEVBQUU7UUFDVixJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDaEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDeEUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7T0FDcEUsTUFBTTtRQUNMLElBQUksQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUNsQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsYUFBYTtVQUNoQixnQkFBZ0IsQ0FBQztZQUNmLElBQUksRUFBRSxPQUFPO1lBQ2IsTUFBTSxFQUFFLElBQUk7WUFDWixJQUFJLEVBQUUsV0FBVyxDQUFDLFlBQVk7V0FDL0IsQ0FBQztTQUNILENBQUM7O1FBRUZLLEdBQU0sQ0FBQyxPQUFPLEdBQUUsMkJBQTBCLElBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQSxhQUFTLEVBQUUsQ0FBQztPQUNqRTtLQUNGLEVBQUUsSUFBSSxDQUFDLENBQUM7Ozs7O0lBS1QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxVQUFBLEtBQUssRUFBQztNQUNuQ0osTUFBSSxDQUFDLGFBQWE7UUFDaEIsZ0JBQWdCLENBQUM7VUFDZixJQUFJLEVBQUUsWUFBWTtVQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07VUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1NBQ2pCLENBQUM7T0FDSCxDQUFDO0tBQ0gsQ0FBQyxDQUFDO0dBQ0o7Ozs7Ozs2Q0FBQTs7Ozs7O0VBTUQsbUJBQUEsS0FBSyxxQkFBRztJQUNOLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsSUFBSSxFQUFFO01BQ3JDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCOztJQUVERCxJQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNwRCxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0lBRTlDLElBQUksQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxJQUFJLENBQUMsYUFBYTtNQUNoQixnQkFBZ0IsQ0FBQztRQUNmLElBQUksRUFBRSxPQUFPO1FBQ2IsTUFBTSxFQUFFLElBQUk7UUFDWixJQUFJLEVBQUUsV0FBVyxDQUFDLFlBQVk7T0FDL0IsQ0FBQztLQUNILENBQUM7O0lBRUYsSUFBSSxNQUFNLEVBQUU7TUFDVixNQUFNLENBQUMsYUFBYTtRQUNsQixnQkFBZ0IsQ0FBQztVQUNmLElBQUksRUFBRSxZQUFZO1VBQ2xCLE1BQU0sRUFBRSxJQUFJO1VBQ1osSUFBSSxFQUFFLFdBQVcsQ0FBQyxZQUFZO1NBQy9CLENBQUM7UUFDRixNQUFNO09BQ1AsQ0FBQztLQUNIOztJQUVELE9BQU8sSUFBSSxDQUFDO0dBQ2IsQ0FBQTs7Ozs7OztFQU9ELG1CQUFBLFVBQVUsMEJBQUc7SUFDWCxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztHQUNyQixDQUFBOzs7OztFQUtELG1CQUFBLElBQUksa0JBQUMsS0FBSyxFQUFXOzs7O0lBQ25CLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsSUFBSSxFQUFFO01BQ3JDLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztLQUNuRTs7SUFFREEsSUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUM7TUFDdEMsSUFBSSxFQUFFLEtBQUs7TUFDWCxNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUc7TUFDaEIsTUFBQSxJQUFJO0tBQ0wsQ0FBQyxDQUFDOztJQUVIQSxJQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFcEQsSUFBSSxNQUFNLEVBQUU7TUFDVixNQUFNLENBQUMsYUFBYSxNQUFBLENBQUMsVUFBQSxZQUFZLFdBQUUsSUFBTyxFQUFBLENBQUMsQ0FBQztLQUM3Qzs7SUFFRCxPQUFPLElBQUksQ0FBQztHQUNiLENBQUE7Ozs7Ozs7OztFQVNELG1CQUFBLElBQUksa0JBQUMsSUFBSSxFQUFFO0lBQ1QsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0IsT0FBTyxJQUFJLENBQUM7R0FDYixDQUFBOzs7Ozs7OztFQVFELG1CQUFBLFNBQWEsbUJBQUc7SUFDZCxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLElBQUksRUFBRTtNQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7S0FDbkU7O0lBRURBLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQztJQUNsQkEsSUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLE1BQU0sRUFBRTtNQUNYLE1BQU0sSUFBSSxLQUFLLEVBQUMsdURBQXNELElBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQSxNQUFFLEVBQUUsQ0FBQztLQUN0Rjs7SUFFRCxPQUFPO01BQ0wsSUFBSSxlQUFBLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRTtRQUNoQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsYUFBYSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvRixPQUFPLElBQUksQ0FBQztPQUNiO01BQ0QsRUFBRSxhQUFBLENBQUMsSUFBSSxFQUFFO1FBQ1AsT0FBTyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztPQUM5QjtNQUNELEVBQUUsZUFBQSxDQUFDLElBQUksRUFBRTtRQUNQLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7T0FDOUI7S0FDRixDQUFDO0dBQ0gsQ0FBQTs7Ozs7RUFLRCxtQkFBQSxFQUFFLGdCQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7SUFDakIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0QyxPQUFPLElBQUksQ0FBQztHQUNiLENBQUE7Ozs7Ozs7RUFPRCxtQkFBQSxHQUFHLGlCQUFDLElBQUksRUFBRTtJQUNSLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztHQUNoQyxDQUFBOzs7Ozs7O0VBT0QsbUJBQUEsSUFBSSxrQkFBQyxJQUFJLEVBQUU7SUFDVCxhQUFhLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0dBQy9DLENBQUE7Ozs7Ozs7RUFPRCxtQkFBQSxLQUFLLG1CQUFDLElBQUksRUFBRTtJQUNWLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7R0FDcEQsQ0FBQTs7RUFFRCxtQkFBQSxFQUFFLGdCQUFDLElBQUksRUFBRTtJQUNQLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7R0FDaEMsQ0FBQTs7RUFFRCxtQkFBQSxFQUFFLG9CQUFHO0lBQ0gsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7R0FDdkMsQ0FBQTs7Ozs7Ozs7RUFRRCxtQkFBQSxhQUFhLDJCQUFDLEtBQUssRUFBc0I7Ozs7O0lBQ3ZDQSxJQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQzdCQSxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDOztJQUU1QyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtNQUM3QixPQUFPLEtBQUssQ0FBQztLQUNkOztJQUVELFNBQVMsQ0FBQyxPQUFPLENBQUMsVUFBQSxRQUFRLEVBQUM7TUFDekIsSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUM5QixRQUFRLENBQUMsS0FBSyxDQUFDQyxNQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7T0FDdkMsTUFBTTs7OztRQUlMLFFBQVEsQ0FBQyxJQUFJLENBQUNBLE1BQUksRUFBRSxLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7T0FDdEQ7S0FDRixDQUFDLENBQUM7R0FDSixDQUFBOzs7OztFQWpQb0IsV0FrUHRCLEdBQUE7O0FBRURPLFVBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCQSxVQUFRLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNsQkEsVUFBUSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDckJBLFVBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDOzs7OztBQUtwQlIsSUFBTSxFQUFFLEdBQUcsU0FBUyxhQUFhLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRTtFQUMvQyxPQUFPLElBQUlRLFVBQVEsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7Q0FDcEMsQ0FBQzs7Ozs7QUFLRixFQUFFLENBQUMsT0FBTyxHQUFHLFNBQVMsU0FBUyxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUU7O0VBRTdDLE9BQU8sRUFBRSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQzs7Q0FFMUIsQ0FBQyxBQUVGLEFBQWtCOztBQ2xSWFIsSUFBTSxNQUFNLEdBQUdTLFFBQVUsQ0FBQztBQUNqQyxBQUFPVCxJQUFNLFNBQVMsR0FBR1UsV0FBYSxDQUFDO0FBQ3ZDLEFBQU9WLElBQU0sUUFBUSxHQUFHVyxFQUFZLENBQUM7Ozs7Ozs7OyJ9 diff --git a/node_modules/mock-socket/index.d.ts b/node_modules/mock-socket/index.d.ts new file mode 100644 index 0000000..fe2e641 --- /dev/null +++ b/node_modules/mock-socket/index.d.ts @@ -0,0 +1,84 @@ +// Type definitions for Mock Socket 8.X+ +// Project: Mock Socket +// Definitions by: Travis Hoover + +declare module 'mock-socket' { + class EventTarget { + listeners: any; + addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void; + dispatchEvent(evt: Event): boolean; + removeEventListener(type: string, listener?: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void; + } + + // + // https://html.spec.whatwg.org/multipage/web-sockets.html#websocket + // + class WebSocket extends EventTarget { + constructor(url?: string, protocols?: string|string[]); + + static readonly CONNECTING: 0; + static readonly OPEN: 1; + static readonly CLOSING: 2; + static readonly CLOSED: 3; + + readonly url: string; + + readonly CONNECTING: 0; + readonly OPEN: 1; + readonly CLOSING: 2; + readonly CLOSED: 3; + readonly readyState: number; + readonly bufferedAmount: number; + + onopen: EventHandlerNonNull; + onerror: EventHandlerNonNull; + onclose: EventHandlerNonNull; + readonly extensions: string; + readonly protocol: string; + close(code?: number, reason?: string): void; + + onmessage: EventHandlerNonNull; + binaryType: BinaryType; + send(data: string | Blob | ArrayBuffer | ArrayBufferView): void; + } + + class Server extends EventTarget { + constructor(url: string, options?: ServerOptions); + + readonly options?: ServerOptions; + + start(): void; + stop(callback?: () => void): void; + + on(type: string, callback: (socket: WebSocket) => void): void; + close(options?: CloseOptions): void; + emit(event: string, data: any, options?: EmitOptions): void; + + clients(): WebSocket[]; + to(room: any, broadcaster: any, broadcastList?: object): ToReturnObject; + in(any: any): ToReturnObject; + simulate(event: Event): void; + + public of(url: string): Server; + } + + interface CloseOptions { + code: number; + reason: string; + wasClean: boolean; + } + + interface EmitOptions { + websockets: WebSocket[]; + } + + interface ToReturnObject { + to: (chainedRoom: any, chainedBroadcaster: any) => ToReturnObject; + emit(event: Event, data: any): void; + } + + interface ServerOptions { + verifyClient: () => any; + selectProtocol: () => any; + } +} diff --git a/node_modules/mock-socket/package.json b/node_modules/mock-socket/package.json new file mode 100644 index 0000000..2fa7de2 --- /dev/null +++ b/node_modules/mock-socket/package.json @@ -0,0 +1,108 @@ +{ + "_from": "mock-socket", + "_id": "mock-socket@8.0.5", + "_inBundle": false, + "_integrity": "sha512-dE2EbcxJKQCeYLZSsI7BAiMZCe/bHbJ2LHb5aGwUuDmfoOINEJ8QI6qYJ85NHsSNkNa90F3s6onZcmt/+MppFA==", + "_location": "/mock-socket", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "mock-socket", + "name": "mock-socket", + "escapedName": "mock-socket", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-8.0.5.tgz", + "_shasum": "4ce8909601b2bcdf5f7680f35c2f7b34beb2afc4", + "_spec": "mock-socket", + "_where": "/Users/josh.burman/Projects/braid", + "author": { + "name": "Travis Hoover" + }, + "ava": { + "files": [ + "tests/**/*.test.js" + ], + "require": [ + "babel-register", + "babel-polyfill" + ], + "babel": "inherit" + }, + "bugs": { + "url": "https://github.com/thoov/mock-socket/issues" + }, + "bundleDependencies": false, + "dependencies": { + "url-parse": "^1.2.0" + }, + "deprecated": false, + "description": "Javascript mocking library for websockets and socket.io", + "devDependencies": { + "ava": "^0.19.1", + "babel-core": "^6.24.1", + "babel-loader": "^7.0.0", + "babel-polyfill": "^6.23.0", + "babel-preset-latest": "^6.24.1", + "cross-env": "^5.0.0", + "eslint": "^3.19.0", + "eslint-config-airbnb-base": "^11.2.0", + "eslint-plugin-import": "^2.0.1", + "husky": "^0.13.3", + "jsdom": "^11.5.1", + "lint-staged": "^3.4.1", + "nyc": "^10.3.2", + "prettier": "^1.3.1", + "rollup": "^0.41.6", + "rollup-plugin-buble": "^0.15.0", + "rollup-plugin-commonjs": "^8.2.6", + "rollup-plugin-node-resolve": "^3.0.0", + "systemjs": "^0.20.12", + "typescript": "^2.9.2", + "typescript-eslint-parser": "^16.0.1" + }, + "directories": { + "test": "tests" + }, + "engines": { + "node": ">= 6" + }, + "homepage": "https://github.com/thoov/mock-socket", + "keywords": [ + "websockets", + "mock", + "mocksocket", + "sockets" + ], + "license": "MIT", + "lint-staged": { + "*.js": [ + "format", + "lint", + "git add" + ] + }, + "main": "./dist/mock-socket", + "name": "mock-socket", + "repository": { + "type": "git", + "url": "git+https://github.com/thoov/mock-socket.git" + }, + "scripts": { + "build": "rm -rf dist && rollup -c rollup.config.js", + "format": "prettier --print-width 120 --single-quote --write '{src,tests}/**/*.js'", + "lint": "eslint src tests", + "precommit": "lint-staged", + "prepublishOnly": "yarn build", + "test": "cross-env NODE_ENV=test ava --serial --verbose", + "test:coverage": "cross-env NODE_ENV=test nyc ava --serial" + }, + "version": "8.0.5" +} diff --git a/node_modules/mock-socket/src/algorithms/close.js b/node_modules/mock-socket/src/algorithms/close.js new file mode 100644 index 0000000..7e28904 --- /dev/null +++ b/node_modules/mock-socket/src/algorithms/close.js @@ -0,0 +1,57 @@ +import WebSocket from '../websocket'; +import delay from '../helpers/delay'; +import networkBridge from '../network-bridge'; +import { createCloseEvent, createEvent } from '../event/factory'; + +export function closeWebSocketConnection(context, code, reason) { + context.readyState = WebSocket.CLOSING; + + const server = networkBridge.serverLookup(context.url); + const closeEvent = createCloseEvent({ + type: 'close', + target: context, + code, + reason + }); + + delay(() => { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket.CLOSED; + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} + +export function failWebSocketConnection(context, code, reason) { + context.readyState = WebSocket.CLOSING; + + const server = networkBridge.serverLookup(context.url); + const closeEvent = createCloseEvent({ + type: 'close', + target: context, + code, + reason, + wasClean: false + }); + + const errorEvent = createEvent({ + type: 'error', + target: context + }); + + delay(() => { + networkBridge.removeWebSocket(context, context.url); + + context.readyState = WebSocket.CLOSED; + context.dispatchEvent(errorEvent); + context.dispatchEvent(closeEvent); + + if (server) { + server.dispatchEvent(closeEvent, server); + } + }, context); +} diff --git a/node_modules/mock-socket/src/constants.js b/node_modules/mock-socket/src/constants.js new file mode 100644 index 0000000..a8a5346 --- /dev/null +++ b/node_modules/mock-socket/src/constants.js @@ -0,0 +1,29 @@ +/* + * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent + */ +export const CLOSE_CODES = { + CLOSE_NORMAL: 1000, + CLOSE_GOING_AWAY: 1001, + CLOSE_PROTOCOL_ERROR: 1002, + CLOSE_UNSUPPORTED: 1003, + CLOSE_NO_STATUS: 1005, + CLOSE_ABNORMAL: 1006, + UNSUPPORTED_DATA: 1007, + POLICY_VIOLATION: 1008, + CLOSE_TOO_LARGE: 1009, + MISSING_EXTENSION: 1010, + INTERNAL_ERROR: 1011, + SERVICE_RESTART: 1012, + TRY_AGAIN_LATER: 1013, + TLS_HANDSHAKE: 1015 +}; + +export const ERROR_PREFIX = { + CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':", + CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':", + EVENT: { + CONSTRUCT: "Failed to construct 'Event':", + MESSAGE: "Failed to construct 'MessageEvent':", + CLOSE: "Failed to construct 'CloseEvent':" + } +}; diff --git a/node_modules/mock-socket/src/event/close.js b/node_modules/mock-socket/src/event/close.js new file mode 100644 index 0000000..0d42dbd --- /dev/null +++ b/node_modules/mock-socket/src/event/close.js @@ -0,0 +1,34 @@ +import EventPrototype from './prototype'; +import { ERROR_PREFIX } from '../constants'; + +export default class CloseEvent extends EventPrototype { + constructor(type, eventInitConfig = {}) { + super(); + + if (!type) { + throw new TypeError(`${ERROR_PREFIX.EVENT.CLOSE} 1 argument required, but only 0 present.`); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(`${ERROR_PREFIX.EVENT.CLOSE} parameter 2 ('eventInitDict') is not an object`); + } + + const { bubbles, cancelable, code, reason, wasClean } = eventInitConfig; + + this.type = `${type}`; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.cancelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.code = typeof code === 'number' ? parseInt(code, 10) : 0; + this.reason = `${reason || ''}`; + this.wasClean = wasClean ? Boolean(wasClean) : false; + } +} diff --git a/node_modules/mock-socket/src/event/event.js b/node_modules/mock-socket/src/event/event.js new file mode 100644 index 0000000..610e5e8 --- /dev/null +++ b/node_modules/mock-socket/src/event/event.js @@ -0,0 +1,31 @@ +import EventPrototype from './prototype'; +import { ERROR_PREFIX } from '../constants'; + +export default class Event extends EventPrototype { + constructor(type, eventInitConfig = {}) { + super(); + + if (!type) { + throw new TypeError(`${ERROR_PREFIX.EVENT_ERROR} 1 argument required, but only 0 present.`); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(`${ERROR_PREFIX.EVENT_ERROR} parameter 2 ('eventInitDict') is not an object.`); + } + + const { bubbles, cancelable } = eventInitConfig; + + this.type = `${type}`; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + } +} diff --git a/node_modules/mock-socket/src/event/factory.js b/node_modules/mock-socket/src/event/factory.js new file mode 100644 index 0000000..608aa28 --- /dev/null +++ b/node_modules/mock-socket/src/event/factory.js @@ -0,0 +1,75 @@ +import Event from './event'; +import MessageEvent from './message'; +import CloseEvent from './close'; + +/* +* Creates an Event object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config you will need to pass type and optionally target +*/ +function createEvent(config) { + const { type, target } = config; + const eventObject = new Event(type); + + if (target) { + eventObject.target = target; + eventObject.srcElement = target; + eventObject.currentTarget = target; + } + + return eventObject; +} + +/* +* Creates a MessageEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type, origin, data and optionally target +*/ +function createMessageEvent(config) { + const { type, origin, data, target } = config; + const messageEvent = new MessageEvent(type, { + data, + origin + }); + + if (target) { + messageEvent.target = target; + messageEvent.srcElement = target; + messageEvent.currentTarget = target; + } + + return messageEvent; +} + +/* +* Creates a CloseEvent object and extends it to allow full modification of +* its properties. +* +* @param {object} config - within config: type and optionally target, code, and reason +*/ +function createCloseEvent(config) { + const { code, reason, type, target } = config; + let { wasClean } = config; + + if (!wasClean) { + wasClean = code === 1000; + } + + const closeEvent = new CloseEvent(type, { + code, + reason, + wasClean + }); + + if (target) { + closeEvent.target = target; + closeEvent.srcElement = target; + closeEvent.currentTarget = target; + } + + return closeEvent; +} + +export { createEvent, createMessageEvent, createCloseEvent }; diff --git a/node_modules/mock-socket/src/event/message.js b/node_modules/mock-socket/src/event/message.js new file mode 100644 index 0000000..976a53e --- /dev/null +++ b/node_modules/mock-socket/src/event/message.js @@ -0,0 +1,35 @@ +import EventPrototype from './prototype'; +import { ERROR_PREFIX } from '../constants'; + +export default class MessageEvent extends EventPrototype { + constructor(type, eventInitConfig = {}) { + super(); + + if (!type) { + throw new TypeError(`${ERROR_PREFIX.EVENT.MESSAGE} 1 argument required, but only 0 present.`); + } + + if (typeof eventInitConfig !== 'object') { + throw new TypeError(`${ERROR_PREFIX.EVENT.MESSAGE} parameter 2 ('eventInitDict') is not an object`); + } + + const { bubbles, cancelable, data, origin, lastEventId, ports } = eventInitConfig; + + this.type = `${type}`; + this.timeStamp = Date.now(); + this.target = null; + this.srcElement = null; + this.returnValue = true; + this.isTrusted = false; + this.eventPhase = 0; + this.defaultPrevented = false; + this.currentTarget = null; + this.cancelable = cancelable ? Boolean(cancelable) : false; + this.canncelBubble = false; + this.bubbles = bubbles ? Boolean(bubbles) : false; + this.origin = `${origin}`; + this.ports = typeof ports === 'undefined' ? null : ports; + this.data = typeof data === 'undefined' ? null : data; + this.lastEventId = `${lastEventId || ''}`; + } +} diff --git a/node_modules/mock-socket/src/event/prototype.js b/node_modules/mock-socket/src/event/prototype.js new file mode 100644 index 0000000..36d6e42 --- /dev/null +++ b/node_modules/mock-socket/src/event/prototype.js @@ -0,0 +1,13 @@ +export default class EventPrototype { + // Noops + stopPropagation() {} + stopImmediatePropagation() {} + + // if no arguments are passed then the type is set to "undefined" on + // chrome and safari. + initEvent(type = 'undefined', bubbles = false, cancelable = false) { + this.type = `${type}`; + this.bubbles = Boolean(bubbles); + this.cancelable = Boolean(cancelable); + } +} diff --git a/node_modules/mock-socket/src/event/target.js b/node_modules/mock-socket/src/event/target.js new file mode 100644 index 0000000..1d363d2 --- /dev/null +++ b/node_modules/mock-socket/src/event/target.js @@ -0,0 +1,73 @@ +import { reject, filter } from '../helpers/array-helpers'; + +/* +* EventTarget is an interface implemented by objects that can +* receive events and may have listeners for them. +* +* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget +*/ +class EventTarget { + constructor() { + this.listeners = {}; + } + + /* + * Ties a listener function to an event type which can later be invoked via the + * dispatchEvent method. + * + * @param {string} type - the type of event (ie: 'open', 'message', etc.) + * @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type + * @param {boolean} useCapture - N/A TODO: implement useCapture functionality + */ + addEventListener(type, listener /* , useCapture */) { + if (typeof listener === 'function') { + if (!Array.isArray(this.listeners[type])) { + this.listeners[type] = []; + } + + // Only add the same function once + if (filter(this.listeners[type], item => item === listener).length === 0) { + this.listeners[type].push(listener); + } + } + } + + /* + * Removes the listener so it will no longer be invoked via the dispatchEvent method. + * + * @param {string} type - the type of event (ie: 'open', 'message', etc.) + * @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type + * @param {boolean} useCapture - N/A TODO: implement useCapture functionality + */ + removeEventListener(type, removingListener /* , useCapture */) { + const arrayOfListeners = this.listeners[type]; + this.listeners[type] = reject(arrayOfListeners, listener => listener === removingListener); + } + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + dispatchEvent(event, ...customArguments) { + const eventName = event.type; + const listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(listener => { + if (customArguments.length > 0) { + listener.apply(this, customArguments); + } else { + listener.call(this, event); + } + }); + + return true; + } +} + +export default EventTarget; diff --git a/node_modules/mock-socket/src/helpers/array-helpers.js b/node_modules/mock-socket/src/helpers/array-helpers.js new file mode 100644 index 0000000..37f327e --- /dev/null +++ b/node_modules/mock-socket/src/helpers/array-helpers.js @@ -0,0 +1,21 @@ +export function reject(array, callback) { + const results = []; + array.forEach(itemInArray => { + if (!callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} + +export function filter(array, callback) { + const results = []; + array.forEach(itemInArray => { + if (callback(itemInArray)) { + results.push(itemInArray); + } + }); + + return results; +} diff --git a/node_modules/mock-socket/src/helpers/byte-length.js b/node_modules/mock-socket/src/helpers/byte-length.js new file mode 100644 index 0000000..aaf2032 --- /dev/null +++ b/node_modules/mock-socket/src/helpers/byte-length.js @@ -0,0 +1,5 @@ +export default function lengthInUtf8Bytes(str) { + // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence. + const m = encodeURIComponent(str).match(/%[89ABab]/g); + return str.length + (m ? m.length : 0); +} diff --git a/node_modules/mock-socket/src/helpers/dedupe.js b/node_modules/mock-socket/src/helpers/dedupe.js new file mode 100644 index 0000000..de4fd10 --- /dev/null +++ b/node_modules/mock-socket/src/helpers/dedupe.js @@ -0,0 +1,5 @@ +export default arr => + arr.reduce((deduped, b) => { + if (deduped.indexOf(b) > -1) return deduped; + return deduped.concat(b); + }, []); diff --git a/node_modules/mock-socket/src/helpers/delay.js b/node_modules/mock-socket/src/helpers/delay.js new file mode 100644 index 0000000..435dd49 --- /dev/null +++ b/node_modules/mock-socket/src/helpers/delay.js @@ -0,0 +1,11 @@ +/* +* This delay allows the thread to finish assigning its on* methods +* before invoking the delay callback. This is purely a timing hack. +* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html +* +* @param {callback: function} the callback which will be invoked after the timeout +* @parma {context: object} the context in which to invoke the function +*/ +export default function delay(callback, context) { + setTimeout(timeoutContext => callback.call(timeoutContext), 4, context); +} diff --git a/node_modules/mock-socket/src/helpers/global-object.js b/node_modules/mock-socket/src/helpers/global-object.js new file mode 100644 index 0000000..5ad22ed --- /dev/null +++ b/node_modules/mock-socket/src/helpers/global-object.js @@ -0,0 +1,7 @@ +export default function retrieveGlobalObject() { + if (typeof window !== 'undefined') { + return window; + } + + return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this; +} diff --git a/node_modules/mock-socket/src/helpers/logger.js b/node_modules/mock-socket/src/helpers/logger.js new file mode 100644 index 0000000..574feec --- /dev/null +++ b/node_modules/mock-socket/src/helpers/logger.js @@ -0,0 +1,7 @@ +export default function log(method, message) { + /* eslint-disable no-console */ + if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') { + console[method].call(null, message); + } + /* eslint-enable no-console */ +} diff --git a/node_modules/mock-socket/src/helpers/normalize-send.js b/node_modules/mock-socket/src/helpers/normalize-send.js new file mode 100644 index 0000000..ebb209b --- /dev/null +++ b/node_modules/mock-socket/src/helpers/normalize-send.js @@ -0,0 +1,7 @@ +export default function normalizeSendData(data) { + if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) { + data = String(data); + } + + return data; +} diff --git a/node_modules/mock-socket/src/helpers/protocol-verification.js b/node_modules/mock-socket/src/helpers/protocol-verification.js new file mode 100644 index 0000000..9ec3bd8 --- /dev/null +++ b/node_modules/mock-socket/src/helpers/protocol-verification.js @@ -0,0 +1,24 @@ +import { ERROR_PREFIX } from '../constants'; + +export default function protocolVerification(protocols = []) { + if (!Array.isArray(protocols) && typeof protocols !== 'string') { + throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The subprotocol '${protocols.toString()}' is invalid.`); + } + + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + const uniq = protocols.map(p => ({ count: 1, protocol: p })).reduce((a, b) => { + a[b.protocol] = (a[b.protocol] || 0) + b.count; + return a; + }, {}); + + const duplicates = Object.keys(uniq).filter(a => uniq[a] > 1); + + if (duplicates.length > 0) { + throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The subprotocol '${duplicates[0]}' is duplicated.`); + } + + return protocols; +} diff --git a/node_modules/mock-socket/src/helpers/proxy-factory.js b/node_modules/mock-socket/src/helpers/proxy-factory.js new file mode 100644 index 0000000..0f7356e --- /dev/null +++ b/node_modules/mock-socket/src/helpers/proxy-factory.js @@ -0,0 +1,45 @@ +import { CLOSE_CODES } from '../constants'; +import { closeWebSocketConnection } from '../algorithms/close'; +import normalizeSendData from './normalize-send'; +import { createMessageEvent } from '../event/factory'; + +export default function proxyFactory(target) { + const handler = { + get(obj, prop) { + if (prop === 'close') { + return function close(options = {}) { + const code = options.code || CLOSE_CODES.CLOSE_NORMAL; + const reason = options.reason || ''; + + closeWebSocketConnection(target, code, reason); + }; + } + + if (prop === 'send') { + return function send(data) { + data = normalizeSendData(data); + + target.dispatchEvent( + createMessageEvent({ + type: 'message', + data, + origin: this.url, + target + }) + ); + }; + } + + if (prop === 'on') { + return function onWrapper(type, cb) { + target.addEventListener(`server::${type}`, cb); + }; + } + + return obj[prop]; + } + }; + + const proxy = new Proxy(target, handler); + return proxy; +} diff --git a/node_modules/mock-socket/src/helpers/url-verification.js b/node_modules/mock-socket/src/helpers/url-verification.js new file mode 100644 index 0000000..41e4d0d --- /dev/null +++ b/node_modules/mock-socket/src/helpers/url-verification.js @@ -0,0 +1,37 @@ +import URL from 'url-parse'; +import { ERROR_PREFIX } from '../constants'; + +export default function urlVerification(url) { + const urlRecord = new URL(url); + const { pathname, protocol, hash } = urlRecord; + + if (!url) { + throw new TypeError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} 1 argument required, but only 0 present.`); + } + + if (!pathname) { + urlRecord.pathname = '/'; + } + + if (protocol === '') { + throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The URL '${urlRecord.toString()}' is invalid.`); + } + + if (protocol !== 'ws:' && protocol !== 'wss:') { + throw new SyntaxError( + `${ERROR_PREFIX.CONSTRUCTOR_ERROR} The URL's scheme must be either 'ws' or 'wss'. '${protocol}' is not allowed.` + ); + } + + if (hash !== '') { + /* eslint-disable max-len */ + throw new SyntaxError( + `${ + ERROR_PREFIX.CONSTRUCTOR_ERROR + } The URL contains a fragment identifier ('${hash}'). Fragment identifiers are not allowed in WebSocket URLs.` + ); + /* eslint-enable max-len */ + } + + return urlRecord.toString(); +} diff --git a/node_modules/mock-socket/src/index.js b/node_modules/mock-socket/src/index.js new file mode 100644 index 0000000..05539fa --- /dev/null +++ b/node_modules/mock-socket/src/index.js @@ -0,0 +1,7 @@ +import MockServer from './server'; +import MockSocketIO from './socket-io'; +import MockWebSocket from './websocket'; + +export const Server = MockServer; +export const WebSocket = MockWebSocket; +export const SocketIO = MockSocketIO; diff --git a/node_modules/mock-socket/src/network-bridge.js b/node_modules/mock-socket/src/network-bridge.js new file mode 100644 index 0000000..7d13d43 --- /dev/null +++ b/node_modules/mock-socket/src/network-bridge.js @@ -0,0 +1,135 @@ +import { reject } from './helpers/array-helpers'; + +/* +* The network bridge is a way for the mock websocket object to 'communicate' with +* all available servers. This is a singleton object so it is important that you +* clean up urlMap whenever you are finished. +*/ +class NetworkBridge { + constructor() { + this.urlMap = {}; + } + + /* + * Attaches a websocket object to the urlMap hash so that it can find the server + * it is connected to and the server in turn can find it. + * + * @param {object} websocket - websocket object to add to the urlMap hash + * @param {string} url + */ + attachWebSocket(websocket, url) { + const connectionLookup = this.urlMap[url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) { + connectionLookup.websockets.push(websocket); + return connectionLookup.server; + } + } + + /* + * Attaches a websocket to a room + */ + addMembershipToRoom(websocket, room) { + const connectionLookup = this.urlMap[websocket.url]; + + if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) { + if (!connectionLookup.roomMemberships[room]) { + connectionLookup.roomMemberships[room] = []; + } + + connectionLookup.roomMemberships[room].push(websocket); + } + } + + /* + * Attaches a server object to the urlMap hash so that it can find a websockets + * which are connected to it and so that websockets can in turn can find it. + * + * @param {object} server - server object to add to the urlMap hash + * @param {string} url + */ + attachServer(server, url) { + const connectionLookup = this.urlMap[url]; + + if (!connectionLookup) { + this.urlMap[url] = { + server, + websockets: [], + roomMemberships: {} + }; + + return server; + } + } + + /* + * Finds the server which is 'running' on the given url. + * + * @param {string} url - the url to use to find which server is running on it + */ + serverLookup(url) { + const connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + return connectionLookup.server; + } + } + + /* + * Finds all websockets which is 'listening' on the given url. + * + * @param {string} url - the url to use to find all websockets which are associated with it + * @param {string} room - if a room is provided, will only return sockets in this room + * @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup + */ + websocketsLookup(url, room, broadcaster) { + let websockets; + const connectionLookup = this.urlMap[url]; + + websockets = connectionLookup ? connectionLookup.websockets : []; + + if (room) { + const members = connectionLookup.roomMemberships[room]; + websockets = members || []; + } + + return broadcaster ? websockets.filter(websocket => websocket !== broadcaster) : websockets; + } + + /* + * Removes the entry associated with the url. + * + * @param {string} url + */ + removeServer(url) { + delete this.urlMap[url]; + } + + /* + * Removes the individual websocket from the map of associated websockets. + * + * @param {object} websocket - websocket object to remove from the url map + * @param {string} url + */ + removeWebSocket(websocket, url) { + const connectionLookup = this.urlMap[url]; + + if (connectionLookup) { + connectionLookup.websockets = reject(connectionLookup.websockets, socket => socket === websocket); + } + } + + /* + * Removes a websocket from a room + */ + removeMembershipFromRoom(websocket, room) { + const connectionLookup = this.urlMap[websocket.url]; + const memberships = connectionLookup.roomMemberships[room]; + + if (connectionLookup && memberships !== null) { + connectionLookup.roomMemberships[room] = reject(memberships, socket => socket === websocket); + } + } +} + +export default new NetworkBridge(); // Note: this is a singleton diff --git a/node_modules/mock-socket/src/server.js b/node_modules/mock-socket/src/server.js new file mode 100644 index 0000000..d8f465b --- /dev/null +++ b/node_modules/mock-socket/src/server.js @@ -0,0 +1,217 @@ +import URL from 'url-parse'; +import WebSocket from './websocket'; +import dedupe from './helpers/dedupe'; +import EventTarget from './event/target'; +import { CLOSE_CODES } from './constants'; +import networkBridge from './network-bridge'; +import globalObject from './helpers/global-object'; +import normalizeSendData from './helpers/normalize-send'; +import { createEvent, createMessageEvent, createCloseEvent } from './event/factory'; + +class Server extends EventTarget { + constructor(url, options = {}) { + super(); + const urlRecord = new URL(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + + this.originalWebSocket = null; + const server = networkBridge.attachServer(this, this.url); + + if (!server) { + this.dispatchEvent(createEvent({ type: 'error' })); + throw new Error('A mock server is already listening on this url'); + } + + if (typeof options.verifyClient === 'undefined') { + options.verifyClient = null; + } + + if (typeof options.selectProtocol === 'undefined') { + options.selectProtocol = null; + } + + this.options = options; + this.start(); + } + + /* + * Attaches the mock websocket object to the global object + */ + start() { + const globalObj = globalObject(); + + if (globalObj.WebSocket) { + this.originalWebSocket = globalObj.WebSocket; + } + + globalObj.WebSocket = WebSocket; + } + + /* + * Removes the mock websocket object from the global object + */ + stop(callback = () => {}) { + const globalObj = globalObject(); + + if (this.originalWebSocket) { + globalObj.WebSocket = this.originalWebSocket; + } else { + delete globalObj.WebSocket; + } + + this.originalWebSocket = null; + + networkBridge.removeServer(this.url); + + if (typeof callback === 'function') { + callback(); + } + } + + /* + * This is the main function for the mock server to subscribe to the on events. + * + * ie: mockServer.on('connection', function() { console.log('a mock client connected'); }); + * + * @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close. + * @param {function} callback - The callback which should be called when a certain event is fired. + */ + on(type, callback) { + this.addEventListener(type, callback); + } + + /* + * Closes the connection and triggers the onclose method of all listening + * websockets. After that it removes itself from the urlMap so another server + * could add itself to the url. + * + * @param {object} options + */ + close(options = {}) { + const { code, reason, wasClean } = options; + const listeners = networkBridge.websocketsLookup(this.url); + + // Remove server before notifications to prevent immediate reconnects from + // socket onclose handlers + networkBridge.removeServer(this.url); + + listeners.forEach(socket => { + socket.readyState = WebSocket.CLOSE; + socket.dispatchEvent( + createCloseEvent({ + type: 'close', + target: socket, + code: code || CLOSE_CODES.CLOSE_NORMAL, + reason: reason || '', + wasClean + }) + ); + }); + + this.dispatchEvent(createCloseEvent({ type: 'close' }), this); + } + + /* + * Sends a generic message event to all mock clients. + */ + emit(event, data, options = {}) { + let { websockets } = options; + + if (!websockets) { + websockets = networkBridge.websocketsLookup(this.url); + } + + if (typeof options !== 'object' || arguments.length > 3) { + data = Array.prototype.slice.call(arguments, 1, arguments.length); + data = data.map(item => normalizeSendData(item)); + } else { + data = normalizeSendData(data); + } + + websockets.forEach(socket => { + if (Array.isArray(data)) { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data, + origin: this.url, + target: socket + }), + ...data + ); + } else { + socket.dispatchEvent( + createMessageEvent({ + type: event, + data, + origin: this.url, + target: socket + }) + ); + } + }); + } + + /* + * Returns an array of websockets which are listening to this server + * TOOD: this should return a set and not be a method + */ + clients() { + return networkBridge.websocketsLookup(this.url); + } + + /* + * Prepares a method to submit an event to members of the room + * + * e.g. server.to('my-room').emit('hi!'); + */ + to(room, broadcaster, broadcastList = []) { + const self = this; + const websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster))); + + return { + to: (chainedRoom, chainedBroadcaster) => this.to.call(this, chainedRoom, chainedBroadcaster, websockets), + emit(event, data) { + self.emit(event, data, { websockets }); + } + }; + } + + /* + * Alias for Server.to + */ + in(...args) { + return this.to.apply(null, args); + } + + /* + * Simulate an event from the server to the clients. Useful for + * simulating errors. + */ + simulate(event) { + const listeners = networkBridge.websocketsLookup(this.url); + + if (event === 'error') { + listeners.forEach(socket => { + socket.readyState = WebSocket.CLOSE; + socket.dispatchEvent(createEvent({ type: 'error' })); + }); + } + } +} + +/* + * Alternative constructor to support namespaces in socket.io + * + * http://socket.io/docs/rooms-and-namespaces/#custom-namespaces + */ +Server.of = function of(url) { + return new Server(url); +}; + +export default Server; diff --git a/node_modules/mock-socket/src/socket-io.js b/node_modules/mock-socket/src/socket-io.js new file mode 100644 index 0000000..353fa82 --- /dev/null +++ b/node_modules/mock-socket/src/socket-io.js @@ -0,0 +1,279 @@ +import URL from 'url-parse'; +import delay from './helpers/delay'; +import EventTarget from './event/target'; +import networkBridge from './network-bridge'; +import { CLOSE_CODES } from './constants'; +import logger from './helpers/logger'; +import { createEvent, createMessageEvent, createCloseEvent } from './event/factory'; + +/* +* The socket-io class is designed to mimick the real API as closely as possible. +* +* http://socket.io/docs/ +*/ +class SocketIO extends EventTarget { + /* + * @param {string} url + */ + constructor(url = 'socket.io', protocol = '') { + super(); + + this.binaryType = 'blob'; + const urlRecord = new URL(url); + + if (!urlRecord.pathname) { + urlRecord.pathname = '/'; + } + + this.url = urlRecord.toString(); + this.readyState = SocketIO.CONNECTING; + this.protocol = ''; + + if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) { + this.protocol = protocol; + } else if (Array.isArray(protocol) && protocol.length > 0) { + this.protocol = protocol[0]; + } + + const server = networkBridge.attachWebSocket(this, this.url); + + /* + * Delay triggering the connection events so they can be defined in time. + */ + delay(function delayCallback() { + if (server) { + this.readyState = SocketIO.OPEN; + server.dispatchEvent(createEvent({ type: 'connection' }), server, this); + server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias + this.dispatchEvent(createEvent({ type: 'connect', target: this })); + } else { + this.readyState = SocketIO.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + logger('error', `Socket.io connection to '${this.url}' failed`); + } + }, this); + + /** + Add an aliased event listener for close / disconnect + */ + this.addEventListener('close', event => { + this.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: event.target, + code: event.code + }) + ); + }); + } + + /* + * Closes the SocketIO connection or connection attempt, if any. + * If the connection is already CLOSED, this method does nothing. + */ + close() { + if (this.readyState !== SocketIO.OPEN) { + return undefined; + } + + const server = networkBridge.serverLookup(this.url); + networkBridge.removeWebSocket(this, this.url); + + this.readyState = SocketIO.CLOSED; + this.dispatchEvent( + createCloseEvent({ + type: 'close', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }) + ); + + if (server) { + server.dispatchEvent( + createCloseEvent({ + type: 'disconnect', + target: this, + code: CLOSE_CODES.CLOSE_NORMAL + }), + server + ); + } + + return this; + } + + /* + * Alias for Socket#close + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383 + */ + disconnect() { + return this.close(); + } + + /* + * Submits an event to the server with a payload + */ + emit(event, ...data) { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + const messageEvent = createMessageEvent({ + type: event, + origin: this.url, + data + }); + + const server = networkBridge.serverLookup(this.url); + + if (server) { + server.dispatchEvent(messageEvent, ...data); + } + + return this; + } + + /* + * Submits a 'message' event to the server. + * + * Should behave exactly like WebSocket#send + * + * https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113 + */ + send(data) { + this.emit('message', data); + return this; + } + + /* + * For broadcasting events to other connected sockets. + * + * e.g. socket.broadcast.emit('hi!'); + * e.g. socket.broadcast.to('my-room').emit('hi!'); + */ + get broadcast() { + if (this.readyState !== SocketIO.OPEN) { + throw new Error('SocketIO is already in CLOSING or CLOSED state'); + } + + const self = this; + const server = networkBridge.serverLookup(this.url); + if (!server) { + throw new Error(`SocketIO can not find a server at the specified URL (${this.url})`); + } + + return { + emit(event, data) { + server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) }); + return self; + }, + to(room) { + return server.to(room, self); + }, + in(room) { + return server.in(room, self); + } + }; + } + + /* + * For registering events to be received from the server + */ + on(type, callback) { + this.addEventListener(type, callback); + return this; + } + + /* + * Remove event listener + * + * https://socket.io/docs/client-api/#socket-on-eventname-callback + */ + off(type) { + this.removeEventListener(type); + } + + /* + * Join a room on a server + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + join(room) { + networkBridge.addMembershipToRoom(this, room); + } + + /* + * Get the websocket to leave the room + * + * http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving + */ + leave(room) { + networkBridge.removeMembershipFromRoom(this, room); + } + + to(room) { + return this.broadcast.to(room); + } + + in() { + return this.to.apply(null, arguments); + } + + /* + * Invokes all listener functions that are listening to the given event.type property. Each + * listener will be passed the event as the first argument. + * + * @param {object} event - event object which will be passed to all listeners of the event.type property + */ + dispatchEvent(event, ...customArguments) { + const eventName = event.type; + const listeners = this.listeners[eventName]; + + if (!Array.isArray(listeners)) { + return false; + } + + listeners.forEach(listener => { + if (customArguments.length > 0) { + listener.apply(this, customArguments); + } else { + // Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data + // payload instanceof MessageEvent works, but you can't isntance of NodeEvent + // for now we detect if the output has data defined on it + listener.call(this, event.data ? event.data : event); + } + }); + } +} + +SocketIO.CONNECTING = 0; +SocketIO.OPEN = 1; +SocketIO.CLOSING = 2; +SocketIO.CLOSED = 3; + +/* +* Static constructor methods for the IO Socket +*/ +const IO = function ioConstructor(url, protocol) { + return new SocketIO(url, protocol); +}; + +/* +* Alias the raw IO() constructor +*/ +IO.connect = function ioConnect(url, protocol) { + /* eslint-disable new-cap */ + return IO(url, protocol); + /* eslint-enable new-cap */ +}; + +export default IO; diff --git a/node_modules/mock-socket/src/websocket.js b/node_modules/mock-socket/src/websocket.js new file mode 100644 index 0000000..e6b2682 --- /dev/null +++ b/node_modules/mock-socket/src/websocket.js @@ -0,0 +1,191 @@ +import delay from './helpers/delay'; +import logger from './helpers/logger'; +import EventTarget from './event/target'; +import networkBridge from './network-bridge'; +import proxyFactory from './helpers/proxy-factory'; +import lengthInUtf8Bytes from './helpers/byte-length'; +import { CLOSE_CODES, ERROR_PREFIX } from './constants'; +import urlVerification from './helpers/url-verification'; +import normalizeSendData from './helpers/normalize-send'; +import protocolVerification from './helpers/protocol-verification'; +import { createEvent, createMessageEvent, createCloseEvent } from './event/factory'; +import { closeWebSocketConnection, failWebSocketConnection } from './algorithms/close'; + +/* + * The main websocket class which is designed to mimick the native WebSocket class as close + * as possible. + * + * https://html.spec.whatwg.org/multipage/web-sockets.html + */ +class WebSocket extends EventTarget { + constructor(url, protocols) { + super(); + + this.url = urlVerification(url); + protocols = protocolVerification(protocols); + this.protocol = protocols[0] || ''; + + this.binaryType = 'blob'; + this.readyState = WebSocket.CONNECTING; + + const server = networkBridge.attachWebSocket(this, this.url); + + /* + * This delay is needed so that we dont trigger an event before the callbacks have been + * setup. For example: + * + * var socket = new WebSocket('ws://localhost'); + * + * If we dont have the delay then the event would be triggered right here and this is + * before the onopen had a chance to register itself. + * + * socket.onopen = () => { // this would never be called }; + * + * and with the delay the event gets triggered here after all of the callbacks have been + * registered :-) + */ + delay(function delayCallback() { + if (server) { + if ( + server.options.verifyClient && + typeof server.options.verifyClient === 'function' && + !server.options.verifyClient() + ) { + this.readyState = WebSocket.CLOSED; + + logger( + 'error', + `WebSocket connection to '${this.url}' failed: HTTP Authentication failed; no valid credentials available` + ); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + } else { + if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') { + const selectedProtocol = server.options.selectProtocol(protocols); + const isFilled = selectedProtocol !== ''; + const isRequested = protocols.indexOf(selectedProtocol) !== -1; + if (isFilled && !isRequested) { + this.readyState = WebSocket.CLOSED; + + logger('error', `WebSocket connection to '${this.url}' failed: Invalid Sub-Protocol`); + + networkBridge.removeWebSocket(this, this.url); + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + return; + } + this.protocol = selectedProtocol; + } + this.readyState = WebSocket.OPEN; + this.dispatchEvent(createEvent({ type: 'open', target: this })); + server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this)); + } + } else { + this.readyState = WebSocket.CLOSED; + this.dispatchEvent(createEvent({ type: 'error', target: this })); + this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL })); + + logger('error', `WebSocket connection to '${this.url}' failed`); + } + }, this); + } + + get onopen() { + return this.listeners.open; + } + + get onmessage() { + return this.listeners.message; + } + + get onclose() { + return this.listeners.close; + } + + get onerror() { + return this.listeners.error; + } + + set onopen(listener) { + delete this.listeners.open; + this.addEventListener('open', listener); + } + + set onmessage(listener) { + delete this.listeners.message; + this.addEventListener('message', listener); + } + + set onclose(listener) { + delete this.listeners.close; + this.addEventListener('close', listener); + } + + set onerror(listener) { + delete this.listeners.error; + this.addEventListener('error', listener); + } + + send(data) { + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + throw new Error('WebSocket is already in CLOSING or CLOSED state'); + } + + // TODO: handle bufferedAmount + + const messageEvent = createMessageEvent({ + type: 'server::message', + origin: this.url, + data: normalizeSendData(data) + }); + + const server = networkBridge.serverLookup(this.url); + + if (server) { + delay(() => { + this.dispatchEvent(messageEvent, data); + }, server); + } + } + + close(code, reason) { + if (code !== undefined) { + if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) { + throw new TypeError( + `${ERROR_PREFIX.CLOSE_ERROR} The code must be either 1000, or between 3000 and 4999. ${code} is neither.` + ); + } + } + + if (reason !== undefined) { + const length = lengthInUtf8Bytes(reason); + + if (length > 123) { + throw new SyntaxError(`${ERROR_PREFIX.CLOSE_ERROR} The message must not be greater than 123 bytes.`); + } + } + + if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) { + return; + } + + if (this.readyState === WebSocket.CONNECTING) { + failWebSocketConnection(this, code, reason); + } else { + closeWebSocketConnection(this, code, reason); + } + } +} + +WebSocket.CONNECTING = 0; +WebSocket.prototype.CONNECTING = WebSocket.CONNECTING; +WebSocket.OPEN = 1; +WebSocket.prototype.OPEN = WebSocket.OPEN; +WebSocket.CLOSING = 2; +WebSocket.prototype.CLOSING = WebSocket.CLOSING; +WebSocket.CLOSED = 3; +WebSocket.prototype.CLOSED = WebSocket.CLOSED; + +export default WebSocket; diff --git a/node_modules/mock-socket/yarn.lock b/node_modules/mock-socket/yarn.lock new file mode 100644 index 0000000..ecacd53 --- /dev/null +++ b/node_modules/mock-socket/yarn.lock @@ -0,0 +1,4687 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ava/babel-plugin-throws-helper@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" + +"@ava/babel-preset-stage-4@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.0.0.tgz#a613b5e152f529305422546b072d47facfb26291" + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.20.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-es2015-destructuring "^6.19.0" + babel-plugin-transform-es2015-function-name "^6.9.0" + babel-plugin-transform-es2015-modules-commonjs "^6.18.0" + babel-plugin-transform-es2015-parameters "^6.21.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-sticky-regex "^6.8.0" + babel-plugin-transform-es2015-unicode-regex "^6.11.0" + babel-plugin-transform-exponentiation-operator "^6.8.0" + package-hash "^1.2.0" + +"@ava/babel-preset-transform-test-files@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz#cded1196a8d8d9381a509240ab92e91a5ec069f7" + dependencies: + "@ava/babel-plugin-throws-helper" "^2.0.0" + babel-plugin-espower "^2.3.2" + +"@ava/pretty-format@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ava/pretty-format/-/pretty-format-1.1.0.tgz#d0a57d25eb9aeab9643bdd1a030642b91c123e28" + dependencies: + ansi-styles "^2.2.1" + esutils "^2.0.2" + +abab@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + +abbrev@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + +acorn-jsx@^3.0.0, acorn-jsx@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn-object-spread@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/acorn-object-spread/-/acorn-object-spread-1.0.0.tgz#48ead0f4a8eb16995a17a0db9ffc6acaada4ba68" + dependencies: + acorn "^3.1.0" + +acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.0.0, acorn@^5.2.1, acorn@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + +ajv-keywords@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.1.1.tgz#02550bc605a3e576041565628af972e06c549d50" + +ajv@^4.7.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.9.0.tgz#5a358085747b134eb567d6d15e015f1d7802f45c" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + +ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +app-root-path@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-exclude@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +auto-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.1.0.tgz#93b864dc7ee01a326281775d5c75ca0a751e5961" + +ava-init@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.0.tgz#9304c8b4c357d66e3dfdae1fbff47b1199d5c55d" + dependencies: + arr-exclude "^1.0.0" + execa "^0.5.0" + has-yarn "^1.0.0" + read-pkg-up "^2.0.0" + write-pkg "^2.0.0" + +ava@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.19.1.tgz#43dd82435ad19b3980ffca2488f05daab940b273" + dependencies: + "@ava/babel-preset-stage-4" "^1.0.0" + "@ava/babel-preset-transform-test-files" "^3.0.0" + "@ava/pretty-format" "^1.1.0" + arr-flatten "^1.0.1" + array-union "^1.0.1" + array-uniq "^1.0.2" + arrify "^1.0.0" + auto-bind "^1.1.0" + ava-init "^0.2.0" + babel-code-frame "^6.16.0" + babel-core "^6.17.0" + bluebird "^3.0.0" + caching-transform "^1.0.0" + chalk "^1.0.0" + chokidar "^1.4.2" + clean-stack "^1.1.1" + clean-yaml-object "^0.1.0" + cli-cursor "^2.1.0" + cli-spinners "^1.0.0" + cli-truncate "^1.0.0" + co-with-promise "^4.6.0" + code-excerpt "^2.1.0" + common-path-prefix "^1.0.0" + convert-source-map "^1.2.0" + core-assert "^0.2.0" + currently-unhandled "^0.4.1" + debug "^2.2.0" + diff "^3.0.1" + diff-match-patch "^1.0.0" + dot-prop "^4.1.0" + empower-core "^0.6.1" + equal-length "^1.0.0" + figures "^2.0.0" + find-cache-dir "^0.1.1" + fn-name "^2.0.0" + get-port "^3.0.0" + globby "^6.0.0" + has-flag "^2.0.0" + hullabaloo-config-manager "^1.0.0" + ignore-by-default "^1.0.0" + indent-string "^3.0.0" + is-ci "^1.0.7" + is-generator-fn "^1.0.0" + is-obj "^1.0.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + jest-diff "19.0.0" + jest-snapshot "19.0.2" + js-yaml "^3.8.2" + last-line-stream "^1.0.0" + lodash.debounce "^4.0.3" + lodash.difference "^4.3.0" + lodash.flatten "^4.2.0" + lodash.isequal "^4.5.0" + loud-rejection "^1.2.0" + matcher "^0.1.1" + md5-hex "^2.0.0" + meow "^3.7.0" + mkdirp "^0.5.1" + ms "^0.7.1" + multimatch "^2.1.0" + observable-to-promise "^0.5.0" + option-chain "^0.1.0" + package-hash "^2.0.0" + pkg-conf "^2.0.0" + plur "^2.0.0" + pretty-ms "^2.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^1.0.0" + slash "^1.0.0" + source-map-support "^0.4.0" + stack-utils "^1.0.0" + strip-ansi "^3.0.1" + strip-bom-buf "^1.0.0" + supports-color "^3.2.3" + time-require "^0.1.2" + unique-temp-dir "^1.0.0" + update-notifier "^2.1.0" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" + +aws4@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" + +babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-core@^6.17.0, babel-core@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.24.1" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.0.0.tgz#2e43a66bee1fff4470533d0402c8a4532fafbaf7" + dependencies: + find-cache-dir "^0.1.1" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-espower@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz#5516b8fcdb26c9f0e1d8160749f6e4c65e71271e" + dependencies: + babel-generator "^6.1.0" + babylon "^6.1.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^1.0.0" + espurify "^1.6.0" + estraverse "^4.1.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-plugin-transform-es2015-classes@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.22.0.tgz#8e0af2f885a0b2cf999d47c4c1dd23ce88cfa4c6" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.22.0.tgz#180467ad63aeea592a1caeee4bf1c8b3e2616265" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.24.1, babel-plugin-transform-es2015-function-name@^6.9.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.21.0, babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.24.1, babel-plugin-transform-es2015-sticky-regex@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.22.0.tgz#87faf2336d3b6a97f68c4d906b0cd0edeae676e1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.24.1, babel-plugin-transform-exponentiation-operator@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" + dependencies: + regenerator-transform "0.9.11" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-preset-es2015@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-es2016@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2016/-/babel-preset-es2016-6.24.1.tgz#f900bf93e2ebc0d276df9b8ab59724ebfd959f8b" + dependencies: + babel-plugin-transform-exponentiation-operator "^6.24.1" + +babel-preset-es2017@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2017/-/babel-preset-es2017-6.24.1.tgz#597beadfb9f7f208bcfd8a12e9b2b29b8b2f14d1" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.24.1" + +babel-preset-latest@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-latest/-/babel-preset-latest-6.24.1.tgz#677de069154a7485c2d25c577c02f624b85b85e8" + dependencies: + babel-preset-es2015 "^6.24.1" + babel-preset-es2016 "^6.24.1" + babel-preset-es2017 "^6.24.1" + +babel-register@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" + dependencies: + babel-core "^6.24.1" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.16.0, babel-template@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.18.0, babel-traverse@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.1.0, babylon@^6.13.0, babylon@^6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" + +babylon@^6.11.0: + version "6.14.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +binary-extensions@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.7.0.tgz#6c1610db163abfb34edfe42fa423343a1e01185d" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.0: + version "3.4.6" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boxen@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.1.0.tgz#b1b69dd522305e807a99deee777dbd6e5167b102" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^1.1.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^0.1.0" + widest-line "^1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +buble@^0.15.0: + version "0.15.1" + resolved "https://registry.yarnpkg.com/buble/-/buble-0.15.1.tgz#89fa32b8956d772c3cce2a27684245e64d8e930d" + dependencies: + acorn "^3.3.0" + acorn-jsx "^3.0.1" + acorn-object-spread "^1.0.0" + chalk "^1.1.3" + magic-string "^0.14.0" + minimist "^1.2.0" + os-homedir "^1.0.1" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + +buffer-shims@^1.0.0, buffer-shims@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-2.0.0.tgz#60b7ef5ae6546bd7deefa74b08b62a43a232648e" + +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +call-matcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.0.tgz#eafa31036dbfaa9c0d1716f12ddacfd9c69ef22f" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@^1.4.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +ci-info@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" + +circular-json@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + +clean-stack@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.2.0.tgz#a465128d62c31fb1a3606d00abfe59dcf652f568" + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +cli-cursor@^1.0.1, cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-spinners@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-truncate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.0.0.tgz#21eb91f47b3f6560f004db77a769b4668d9c5518" + dependencies: + slice-ansi "0.0.4" + string-width "^2.0.0" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +co-with-promise@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" + dependencies: + pinkie-promise "^1.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-excerpt@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.0.tgz#5dcc081e88f4a7e3b554e9e35d7ef232d47f8147" + dependencies: + convert-to-spaces "^1.0.1" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-convert@^1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + dependencies: + color-name "1.1.1" + +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + +combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.9.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +convert-source-map@^1.1.0, convert-source-map@^1.2.0, convert-source-map@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" + +convert-to-spaces@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" + +core-assert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js@^2.0.0, core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cosmiconfig@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-1.1.0.tgz#0dea0f9804efdfb929fbb1b188e25553ea053d37" + dependencies: + graceful-fs "^4.1.2" + js-yaml "^3.4.3" + minimist "^1.2.0" + object-assign "^4.0.1" + os-homedir "^1.0.1" + parse-json "^2.2.0" + pinkie-promise "^2.0.0" + require-from-string "^1.1.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cross-env@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + +cross-spawn-async@^2.1.1: + version "2.2.5" + resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" + dependencies: + lru-cache "^4.0.0" + which "^1.2.8" + +cross-spawn@^4, cross-spawn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + +"cssstyle@>= 0.3.1 < 0.4.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.3.1.tgz#6da9b4cff1bc5d716e6e5fe8e04fcb1b50a49adf" + dependencies: + cssom "0.3.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@^0.1.1, d@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" + dependencies: + es5-ext "~0.10.2" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f" + dependencies: + abab "^1.0.4" + whatwg-mimetype "^2.0.0" + whatwg-url "^6.4.0" + +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + +date-time@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" + +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + +debug@^2.1.1: + version "2.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" + dependencies: + ms "0.7.2" + +debug@^2.2.0, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^2.6.3: + version "2.6.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" + dependencies: + ms "2.0.0" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +diff-match-patch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" + +diff@^3.0.0, diff@^3.0.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +dot-prop@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" + dependencies: + is-obj "^1.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +empower-core@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.1.tgz#6c187f502fcef7554d57933396aac655483772b1" + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +equal-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: + version "0.10.12" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-error@^4.0.1, es6-error@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98" + +es6-iterator@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" + dependencies: + d "^0.1.1" + es5-ext "^0.10.7" + es6-symbol "3" + +es6-map@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-set "~0.1.3" + es6-symbol "~3.1.0" + event-emitter "~0.3.4" + +es6-set@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + es6-iterator "2" + es6-symbol "3" + event-emitter "~0.3.4" + +es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + +es6-weak-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + dependencies: + d "^0.1.1" + es5-ext "^0.10.8" + es6-iterator "2" + es6-symbol "3" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.10.0.tgz#f647395de22519fbd0d928ffcf1d17e0dec2603e" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-airbnb-base@^11.2.0: + version "11.3.2" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.2.tgz#8703b11abe3c88ac7ec2b745b7fdf52e00ae680a" + dependencies: + eslint-restricted-globals "^0.1.1" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-import@^2.0.1: + version "2.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz#df24f241175e312d91662dc91ca84064caec14ed" + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + +eslint@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espree@^3.4.0: + version "3.4.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" + dependencies: + acorn "^5.0.1" + acorn-jsx "^3.0.0" + +esprima@^3.1.1, esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +espurify@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.6.0.tgz#6cb993582d9422bd6f2d4b258aadb14833f394f0" + dependencies: + core-js "^2.0.0" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + dependencies: + estraverse "~4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" + +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + +estree-walker@^0.5.0, estree-walker@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" + dependencies: + d "~0.1.1" + es5-ext "~0.10.7" + +execa@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" + dependencies: + cross-spawn-async "^2.1.1" + is-stream "^1.1.0" + npm-run-path "^1.0.0" + object-assign "^4.0.1" + path-key "^1.0.0" + strip-eof "^1.0.0" + +execa@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" + dependencies: + cross-spawn "^4.0.0" + get-stream "^2.2.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^1.3.5, figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + +find-up@^1.0.0, find-up@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.1.tgz#6c837d6225a7de5659323740b36d5361f71691ff" + dependencies: + circular-json "^0.3.0" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +fn-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreground-child@^1.3.3, foreground-child@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.3.tgz#94dd6aba671389867de8e57e99f1c2ecfb15c01a" + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.0.15" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.15.tgz#fa63f590f3c2ad91275e4972a6cea545fb0aae44" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.1.tgz#388473894fe8be5e13ffcdb8b93e4ed0616428c7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-port@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.1.0.tgz#ef01b18a84ca6486970ff99e54446141a73ffd3e" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0, globals@^9.14.0: + version "9.14.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +handlebars@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@^0.1.7, has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +hullabaloo-config-manager@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.0.1.tgz#c72be7ba249a67c99b6ba3eb1f55837fa01acd8f" + dependencies: + dot-prop "^4.1.0" + es6-error "^4.0.2" + graceful-fs "^4.1.11" + indent-string "^3.1.0" + json5 "^0.5.1" + lodash.clonedeep "^4.5.0" + lodash.clonedeepwith "^4.5.0" + lodash.isequal "^4.5.0" + lodash.merge "^4.6.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + pkg-dir "^1.0.0" + resolve-from "^2.0.0" + +husky@^0.13.3: + version "0.13.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-0.13.4.tgz#48785c5028de3452a51c48c12c4f94b2124a1407" + dependencies: + chalk "^1.1.3" + find-parent-dir "^0.3.0" + is-ci "^1.0.9" + normalize-path "^1.0.0" + +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + +ignore@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.0.tgz#8d88f03c3002a0ac52114db25d2c673b0bf1e435" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +indent-string@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.1.0.tgz#08ff4334603388399b329e6b9538dc7a3cf5de7d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +irregular-plurals@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + dependencies: + ci-info "^1.0.0" + +is-ci@^1.0.9: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-error@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0, is-finite@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-url@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-lib-coverage@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#caca19decaef3525b5d6331d701f3f3b7ad48528" + +istanbul-lib-hook@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.6.tgz#c0866d1e81cf2d5319249510131fc16dee49231f" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.1.tgz#169e31bc62c778851a99439dd99c3cc12184d360" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.13.0" + istanbul-lib-coverage "^1.1.0" + semver "^5.3.0" + +istanbul-lib-report@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.0.tgz#444c4ecca9afa93cf584f56b10f195bf768c0770" + dependencies: + istanbul-lib-coverage "^1.1.0" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.0.tgz#8c7706d497e26feeb6af3e0c28fd5b0669598d0e" + dependencies: + debug "^2.6.3" + istanbul-lib-coverage "^1.1.0" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.0.tgz#1ef3b795889219cfb5fad16365f6ce108d5f8c66" + dependencies: + handlebars "^4.0.3" + +jest-diff@19.0.0, jest-diff@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-19.0.0.tgz#d1563cfc56c8b60232988fbc05d4d16ed90f063c" + dependencies: + chalk "^1.1.3" + diff "^3.0.0" + jest-matcher-utils "^19.0.0" + pretty-format "^19.0.0" + +jest-file-exists@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-19.0.0.tgz#cca2e587a11ec92e24cfeab3f8a94d657f3fceb8" + +jest-matcher-utils@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d" + dependencies: + chalk "^1.1.3" + pretty-format "^19.0.0" + +jest-message-util@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-19.0.0.tgz#721796b89c0e4d761606f9ba8cb828a3b6246416" + dependencies: + chalk "^1.1.1" + micromatch "^2.3.11" + +jest-mock@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-19.0.0.tgz#67038641e9607ab2ce08ec4a8cb83aabbc899d01" + +jest-snapshot@19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-19.0.2.tgz#9c1b216214f7187c38bfd5c70b1efab16b0ff50b" + dependencies: + chalk "^1.1.3" + jest-diff "^19.0.0" + jest-file-exists "^19.0.0" + jest-matcher-utils "^19.0.0" + jest-util "^19.0.2" + natural-compare "^1.4.0" + pretty-format "^19.0.0" + +jest-util@^19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-19.0.2.tgz#e0a0232a2ab9e6b2b53668bdb3534c2b5977ed41" + dependencies: + chalk "^1.1.1" + graceful-fs "^4.1.6" + jest-file-exists "^19.0.0" + jest-message-util "^19.0.0" + jest-mock "^19.0.0" + jest-validate "^19.0.2" + leven "^2.0.0" + mkdirp "^0.5.1" + +jest-validate@^19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.2.tgz#dc534df5f1278d5b63df32b14241d4dbf7244c0c" + dependencies: + chalk "^1.1.1" + jest-matcher-utils "^19.0.0" + leven "^2.0.0" + pretty-format "^19.0.0" + +js-tokens@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" + +js-tokens@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.4.3: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^3.5.1, js-yaml@^3.8.2: + version "3.8.4" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" + dependencies: + argparse "^1.0.7" + esprima "^3.1.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdom@^11.5.1: + version "11.11.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.11.0.tgz#df486efad41aee96c59ad7a190e2449c7eb1110e" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.3.1 < 0.4.0" + data-urls "^1.0.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwsapi "^2.0.0" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^4.0.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.0.tgz#9b20715b026cbe3778fd769edccd822d8332a5b2" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.0.tgz#6661e161d2fc445f19f98430231343722e1fcbd5" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +last-line-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" + dependencies: + through2 "^2.0.0" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lazy-req@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-2.0.0.tgz#c9450a363ecdda2e6f0c70132ad4f37f8f06f2b4" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +leven@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lint-staged@^3.4.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-3.6.1.tgz#24423c8b7bd99d96e15acd1ac8cb392a78e58582" + dependencies: + app-root-path "^2.0.0" + cosmiconfig "^1.1.0" + execa "^0.7.0" + listr "^0.12.0" + lodash.chunk "^4.2.0" + minimatch "^3.0.0" + npm-which "^3.0.1" + p-map "^1.1.1" + staged-git-files "0.0.4" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + +listr-update-renderer@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + figures "^1.7.0" + indent-string "^2.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.2.0" + listr-verbose-renderer "^0.4.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + ora "^0.2.3" + p-map "^1.1.1" + rxjs "^5.0.0-beta.11" + stream-to-observable "^0.1.0" + strip-ansi "^3.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-utils@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.chunk@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + +lodash.clonedeepwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" + +lodash.debounce@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash.difference@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + +lodash.merge@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash.unescape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" + +lodash@^4.0.0, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42" + +lodash@^4.13.1, lodash@^4.17.4: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.0.tgz#6b26248c42f6d4fa4b0d8542f78edfcde35642a8" + dependencies: + js-tokens "^2.0.0" + +loud-rejection@^1.0.0, loud-rejection@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.1.tgz#1343955edaf2e37d9b9e7ee7241e27c4b9fb72be" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +lru-cache@^4.0.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +magic-string@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.14.0.tgz#57224aef1701caeed273b17a39a956e72b172462" + dependencies: + vlq "^0.2.1" + +magic-string@^0.22.4: + version "0.22.5" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e" + dependencies: + vlq "^0.2.2" + +make-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" + dependencies: + pify "^2.3.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +matcher@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-0.1.2.tgz#ef20cbde64c24c50cc61af5b83ee0b1b8ff00101" + dependencies: + escape-string-regexp "^1.0.4" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + +md5-hex@^1.2.0, md5-hex@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-source-map@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.3.tgz#da1415f2722a5119db07b14c4f973410863a2abf" + dependencies: + source-map "^0.5.3" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392" + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + +mime-types@^2.1.12, mime-types@~2.1.17: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + +mime-types@~2.1.7: + version "2.1.13" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88" + dependencies: + mime-db "~1.25.0" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8, minimist@~0.0.1: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2, ms@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +nan@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + +node-pre-gyp@^0.6.29: + version "0.6.31" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.31.tgz#d8a00ddaa301a940615dbcc8caad4024d58f6017" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.0" + rc "~1.1.6" + request "^2.75.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + dependencies: + which "^1.2.10" + +npm-run-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f" + dependencies: + path-key "^1.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +npmlog@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.1.tgz#d14f503b4cd79710375553004ba96e6662fbc0b8" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nwsapi@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.4.tgz#dc79040a5f77b97716dc79565fc7fc3ef7d50570" + +nyc@^10.3.2: + version "10.3.2" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-10.3.2.tgz#f27f4d91f2a9db36c24f574ff5c6efff0233de46" + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^1.0.0" + convert-source-map "^1.3.0" + debug-log "^1.0.1" + default-require-extensions "^1.0.0" + find-cache-dir "^0.1.1" + find-up "^1.1.2" + foreground-child "^1.5.3" + glob "^7.0.6" + istanbul-lib-coverage "^1.1.0" + istanbul-lib-hook "^1.0.6" + istanbul-lib-instrument "^1.7.1" + istanbul-lib-report "^1.1.0" + istanbul-lib-source-maps "^1.2.0" + istanbul-reports "^1.1.0" + md5-hex "^1.2.0" + merge-source-map "^1.0.2" + micromatch "^2.3.11" + mkdirp "^0.5.0" + resolve-from "^2.0.0" + rimraf "^2.5.4" + signal-exit "^3.0.1" + spawn-wrap "1.2.4" + test-exclude "^4.1.0" + yargs "^7.1.0" + yargs-parser "^5.0.0" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +observable-to-promise@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.5.0.tgz#c828f0f0dc47e9f86af8a4977c5d55076ce7a91f" + dependencies: + is-observable "^0.2.0" + symbol-observable "^1.0.4" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +option-chain@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-0.1.1.tgz#e9b811e006f1c0f54802f28295bfc8970f8dcfbd" + dependencies: + object-assign "^4.0.1" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ora@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +package-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" + dependencies: + md5-hex "^1.3.0" + +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-ms@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af" + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" + dependencies: + pinkie "^1.0.0" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-conf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" + dependencies: + find-up "^2.0.0" + load-json-file "^2.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +plur@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" + +plur@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + dependencies: + irregular-plurals "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.3.1: + version "1.13.7" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" + +pretty-format@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84" + dependencies: + ansi-styles "^3.0.0" + +pretty-ms@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" + dependencies: + parse-ms "^0.1.0" + +pretty-ms@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" + dependencies: + is-finite "^1.0.1" + parse-ms "^1.0.0" + plur "^1.0.0" + +private@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +pseudomap@^1.0.1, pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +psl@^1.1.24: + version "1.1.28" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.28.tgz#4fb6ceb08a1e2214d4fd4de0ca22dae13740bc7b" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +qs@~6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" + +qs@~6.5.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +querystringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.0.0.tgz#fa3ed6e68eb15159457c89b37bc6472833195755" + +randomatic@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923" + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +rc@^1.0.1, rc@^1.1.6, rc@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~1.0.4" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.2.2: + version "2.2.9" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" + dependencies: + buffer-shims "~1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~1.0.0" + util-deprecate "~1.0.1" + +readable-stream@~2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb" + +regenerator-transform@0.9.11: + version "0.9.11" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.1.0.tgz#997c08256e0c7999837b90e944db39d8a790276b" + dependencies: + rc "^1.1.6" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + dependencies: + es6-error "^4.0.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.75.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +request@^2.83.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +resolve-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f" + dependencies: + resolve-from "^2.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +resolve@^1.1.6, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +rimraf@^2.5.4, rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +rollup-plugin-buble@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-buble/-/rollup-plugin-buble-0.15.0.tgz#83c3e89c7fd2266c7918f41ba3980313519c7fd0" + dependencies: + buble "^0.15.0" + rollup-pluginutils "^1.5.0" + +rollup-plugin-commonjs@^8.2.6: + version "8.4.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.4.1.tgz#5c9cea2b2c3de322f5fbccd147e07ed5e502d7a0" + dependencies: + acorn "^5.2.1" + estree-walker "^0.5.0" + magic-string "^0.22.4" + resolve "^1.4.0" + rollup-pluginutils "^2.0.1" + +rollup-plugin-node-resolve@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz#c26d110a36812cbefa7ce117cadcd3439aa1c713" + dependencies: + builtin-modules "^2.0.0" + is-module "^1.0.0" + resolve "^1.1.6" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup-pluginutils@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.3.0.tgz#478ace04bd7f6da2e724356ca798214884738fc4" + dependencies: + estree-walker "^0.5.2" + micromatch "^2.3.11" + +rollup@^0.41.6: + version "0.41.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" + dependencies: + source-map-support "^0.4.0" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +rxjs@^5.0.0-beta.11: + version "5.5.11" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87" + dependencies: + symbol-observable "1.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safer-buffer@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +semver@5.5.0, semver@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shelljs@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +signal-exit@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.1.tgz#5a4c884992b63a7acd9badb7894c3ee9cfccad81" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-keys@^1.1.1, sort-keys@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-map-support@^0.4.0, source-map-support@^0.4.2: + version "0.4.6" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.6.tgz#32552aa64b458392a85eab3b0b5ee61527167aeb" + dependencies: + source-map "^0.5.3" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spawn-wrap@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.2.4.tgz#920eb211a769c093eebfbd5b0e7a5d2e68ab2e40" + dependencies: + foreground-child "^1.3.3" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.3.3" + signal-exit "^2.0.0" + which "^1.2.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + safer-buffer "^2.0.2" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +staged-git-files@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35" + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +stream-to-observable@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" + dependencies: + buffer-shims "~1.0.0" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-buf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" + dependencies: + is-utf8 "^0.2.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2, supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +symbol-observable@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +systemjs@^0.20.12: + version "0.20.19" + resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-0.20.19.tgz#c2b9e79c19f4bea53a19b1ed3f974ffb463be949" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +term-size@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-0.1.1.tgz#87360b96396cab5760963714cda0d0cbeecad9ca" + dependencies: + execa "^0.4.0" + +test-exclude@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.0.tgz#04ca70b7390dd38c98d4a003a173806ca7991c91" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through2@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" + dependencies: + readable-stream "~2.0.0" + xtend "~4.0.0" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +time-require@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" + dependencies: + chalk "^0.4.0" + date-time "^0.1.1" + pretty-ms "^0.2.1" + text-table "^0.2.0" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@>=2.3.3, tough-cookie@^2.3.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +typescript-eslint-parser@^16.0.1: + version "16.0.1" + resolved "https://registry.yarnpkg.com/typescript-eslint-parser/-/typescript-eslint-parser-16.0.1.tgz#b40681c7043b222b9772748b700a000b241c031b" + dependencies: + lodash.unescape "4.0.1" + semver "5.5.0" + +typescript@^2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + +uglify-js@^2.6: + version "2.7.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.4.tgz#a295a0de12b6a650c031c40deb0dc40b14568bd2" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + +update-notifier@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.1.0.tgz#ec0c1e53536b76647a24b77cb83966d9315123d9" + dependencies: + boxen "^1.0.0" + chalk "^1.0.0" + configstore "^3.0.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + lazy-req "^2.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +url-parse@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.1.tgz#4dec9dad3dc8585f862fed461d2e19bbf623df30" + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" + +uuid@^3.1.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vlq@^0.2.1, vlq@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + dependencies: + iconv-lite "0.4.19" + +whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + +whatwg-url@^6.4.0, whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@^1.2.10, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +which@^1.2.4, which@^1.2.8: + version "1.2.12" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + dependencies: + isexe "^1.1.1" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.0.0.tgz#7d30f8f873f9a5bbc3a64dabc8d177e071ae426f" + dependencies: + string-width "^1.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.1.0.tgz#1769f4b551eedce419f0505deae2e26763542d37" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-json-file@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.1.0.tgz#ba1cf3ac7ee89db26c3d528986e48421389046b7" + dependencies: + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^2.0.0" + sort-keys "^1.1.1" + write-file-atomic "^2.0.0" + +write-pkg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-2.1.0.tgz#353aa44c39c48c21440f5c08ce6abd46141c9c08" + dependencies: + sort-keys "^1.1.2" + write-json-file "^2.0.0" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +xtend@^4.0.0, xtend@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0, yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + +yargs@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" diff --git a/node_modules/querystringify/LICENSE b/node_modules/querystringify/LICENSE new file mode 100644 index 0000000..6dc9316 --- /dev/null +++ b/node_modules/querystringify/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/querystringify/README.md b/node_modules/querystringify/README.md new file mode 100644 index 0000000..e87f7f4 --- /dev/null +++ b/node_modules/querystringify/README.md @@ -0,0 +1,60 @@ +# querystringify + +[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](http://img.shields.io/npm/v/querystringify.svg?style=flat-square)](http://browsenpm.org/package/querystringify)[![Build Status](http://img.shields.io/travis/unshiftio/querystringify/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/querystringify)[![Dependencies](https://img.shields.io/david/unshiftio/querystringify.svg?style=flat-square)](https://david-dm.org/unshiftio/querystringify)[![Coverage Status](http://img.shields.io/coveralls/unshiftio/querystringify/master.svg?style=flat-square)](https://coveralls.io/r/unshiftio/querystringify?branch=master)[![IRC channel](http://img.shields.io/badge/IRC-irc.freenode.net%23unshift-00a8ff.svg?style=flat-square)](http://webchat.freenode.net/?channels=unshift) + +A somewhat JSON compatible interface for query string parsing. This query string +parser is dumb, don't expect to much from it as it only wants to parse simple +query strings. If you want to parse complex, multi level and deeply nested +query strings then you should ask your self. WTF am I doing? + +## Installation + +This module is released in npm as `querystringify`. It's also compatible with +`browserify` so it can be used on the server as well as on the client. To +install it simply run the following command from your CLI: + +``` +npm install --save querystringify +``` + +## Usage + +In the following examples we assume that you've already required the library as: + +```js +'use strict'; + +var qs = require('querystringify'); +``` + +### qs.parse() + +The parse method transforms a given query string in to an object. Parameters +without values are set to empty strings. It does not care if your query string +is prefixed with a `?` or not. It just extracts the parts between the `=` and +`&`: + +```js +qs.parse('?foo=bar'); // { foo: 'bar' } +qs.parse('foo=bar'); // { foo: 'bar' } +qs.parse('foo=bar&bar=foo'); // { foo: 'bar', bar: 'foo' } +qs.parse('foo&bar=foo'); // { foo: '', bar: 'foo' } +``` + +### qs.stringify() + +This transforms a given object in to a query string. By default we return the +query string without a `?` prefix. If you want to prefix it by default simply +supply `true` as second argument. If it should be prefixed by something else +simply supply a string with the prefix value as second argument: + +```js +qs.stringify({ foo: bar }); // foo=bar +qs.stringify({ foo: bar }, true); // ?foo=bar +qs.stringify({ foo: bar }, '&'); // &foo=bar +qs.stringify({ foo: '' }, '&'); // &foo= +``` + +## License + +MIT diff --git a/node_modules/querystringify/index.js b/node_modules/querystringify/index.js new file mode 100644 index 0000000..df6f968 --- /dev/null +++ b/node_modules/querystringify/index.js @@ -0,0 +1,88 @@ +'use strict'; + +var has = Object.prototype.hasOwnProperty + , undef; + +/** + * Decode a URI encoded string. + * + * @param {String} input The URI encoded string. + * @returns {String} The decoded string. + * @api private + */ +function decode(input) { + return decodeURIComponent(input.replace(/\+/g, ' ')); +} + +/** + * Simple query string parser. + * + * @param {String} query The query string that needs to be parsed. + * @returns {Object} + * @api public + */ +function querystring(query) { + var parser = /([^=?&]+)=?([^&]*)/g + , result = {} + , part; + + while (part = parser.exec(query)) { + var key = decode(part[1]) + , value = decode(part[2]); + + // + // Prevent overriding of existing properties. This ensures that build-in + // methods like `toString` or __proto__ are not overriden by malicious + // querystrings. + // + if (key in result) continue; + result[key] = value; + } + + return result; +} + +/** + * Transform a query string to an object. + * + * @param {Object} obj Object that should be transformed. + * @param {String} prefix Optional prefix. + * @returns {String} + * @api public + */ +function querystringify(obj, prefix) { + prefix = prefix || ''; + + var pairs = [] + , value + , key; + + // + // Optionally prefix with a '?' if needed + // + if ('string' !== typeof prefix) prefix = '?'; + + for (key in obj) { + if (has.call(obj, key)) { + value = obj[key]; + + // + // Edge cases where we actually want to encode the value to an empty + // string instead of the stringified value. + // + if (!value && (value === null || value === undef || isNaN(value))) { + value = ''; + } + + pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(value)); + } + } + + return pairs.length ? prefix + pairs.join('&') : ''; +} + +// +// Expose the module. +// +exports.stringify = querystringify; +exports.parse = querystring; diff --git a/node_modules/querystringify/package.json b/node_modules/querystringify/package.json new file mode 100644 index 0000000..2a76a4a --- /dev/null +++ b/node_modules/querystringify/package.json @@ -0,0 +1,66 @@ +{ + "_from": "querystringify@^2.0.0", + "_id": "querystringify@2.1.0", + "_inBundle": false, + "_integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "_location": "/querystringify", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "querystringify@^2.0.0", + "name": "querystringify", + "escapedName": "querystringify", + "rawSpec": "^2.0.0", + "saveSpec": null, + "fetchSpec": "^2.0.0" + }, + "_requiredBy": [ + "/url-parse" + ], + "_resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", + "_shasum": "7ded8dfbf7879dcc60d0a644ac6754b283ad17ef", + "_spec": "querystringify@^2.0.0", + "_where": "/Users/josh.burman/Projects/braid/node_modules/url-parse", + "author": { + "name": "Arnout Kazemier" + }, + "bugs": { + "url": "https://github.com/unshiftio/querystringify/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Querystringify - Small, simple but powerful query string parser.", + "devDependencies": { + "assume": "^2.1.0", + "istanbul": "^0.4.5", + "mocha": "^5.2.0", + "pre-commit": "^1.2.2" + }, + "homepage": "https://github.com/unshiftio/querystringify", + "keywords": [ + "query", + "string", + "query-string", + "querystring", + "qs", + "stringify", + "parse", + "decode", + "encode" + ], + "license": "MIT", + "main": "index.js", + "name": "querystringify", + "repository": { + "type": "git", + "url": "git+https://github.com/unshiftio/querystringify.git" + }, + "scripts": { + "coverage": "istanbul cover _mocha -- test.js", + "test": "mocha test.js", + "test-travis": "istanbul cover _mocha --report lcovonly -- test.js", + "watch": "mocha --watch test.js" + }, + "version": "2.1.0" +} diff --git a/node_modules/requires-port/.npmignore b/node_modules/requires-port/.npmignore new file mode 100644 index 0000000..ba2a97b --- /dev/null +++ b/node_modules/requires-port/.npmignore @@ -0,0 +1,2 @@ +node_modules +coverage diff --git a/node_modules/requires-port/.travis.yml b/node_modules/requires-port/.travis.yml new file mode 100644 index 0000000..0765106 --- /dev/null +++ b/node_modules/requires-port/.travis.yml @@ -0,0 +1,19 @@ +sudo: false +language: node_js +node_js: + - "4" + - "iojs" + - "0.12" + - "0.10" +script: + - "npm run test-travis" +after_script: + - "npm install coveralls@2 && cat coverage/lcov.info | coveralls" +matrix: + fast_finish: true +notifications: + irc: + channels: + - "irc.freenode.org#unshift" + on_success: change + on_failure: change diff --git a/node_modules/requires-port/LICENSE b/node_modules/requires-port/LICENSE new file mode 100644 index 0000000..6dc9316 --- /dev/null +++ b/node_modules/requires-port/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/requires-port/README.md b/node_modules/requires-port/README.md new file mode 100644 index 0000000..3effe75 --- /dev/null +++ b/node_modules/requires-port/README.md @@ -0,0 +1,47 @@ +# requires-port + +[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](http://img.shields.io/npm/v/requires-port.svg?style=flat-square)](http://browsenpm.org/package/requires-port)[![Build Status](http://img.shields.io/travis/unshiftio/requires-port/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/requires-port)[![Dependencies](https://img.shields.io/david/unshiftio/requires-port.svg?style=flat-square)](https://david-dm.org/unshiftio/requires-port)[![Coverage Status](http://img.shields.io/coveralls/unshiftio/requires-port/master.svg?style=flat-square)](https://coveralls.io/r/unshiftio/requires-port?branch=master)[![IRC channel](http://img.shields.io/badge/IRC-irc.freenode.net%23unshift-00a8ff.svg?style=flat-square)](http://webchat.freenode.net/?channels=unshift) + +The module name says it all, check if a protocol requires a given port. + +## Installation + +This module is intended to be used with browserify or Node.js and is distributed +in the public npm registry. To install it simply run the following command from +your CLI: + +```j +npm install --save requires-port +``` + +## Usage + +The module exports it self as function and requires 2 arguments: + +1. The port number, can be a string or number. +2. Protocol, can be `http`, `http:` or even `https://yomoma.com`. We just split + it at `:` and use the first result. We currently accept the following + protocols: + - `http` + - `https` + - `ws` + - `wss` + - `ftp` + - `gopher` + - `file` + +It returns a boolean that indicates if protocol requires this port to be added +to your URL. + +```js +'use strict'; + +var required = require('requires-port'); + +console.log(required('8080', 'http')) // true +console.log(required('80', 'http')) // false +``` + +# License + +MIT diff --git a/node_modules/requires-port/index.js b/node_modules/requires-port/index.js new file mode 100644 index 0000000..4f267b2 --- /dev/null +++ b/node_modules/requires-port/index.js @@ -0,0 +1,38 @@ +'use strict'; + +/** + * Check if we're required to add a port number. + * + * @see https://url.spec.whatwg.org/#default-port + * @param {Number|String} port Port number we need to check + * @param {String} protocol Protocol we need to check against. + * @returns {Boolean} Is it a default port for the given protocol + * @api private + */ +module.exports = function required(port, protocol) { + protocol = protocol.split(':')[0]; + port = +port; + + if (!port) return false; + + switch (protocol) { + case 'http': + case 'ws': + return port !== 80; + + case 'https': + case 'wss': + return port !== 443; + + case 'ftp': + return port !== 21; + + case 'gopher': + return port !== 70; + + case 'file': + return false; + } + + return port !== 0; +}; diff --git a/node_modules/requires-port/package.json b/node_modules/requires-port/package.json new file mode 100644 index 0000000..427d396 --- /dev/null +++ b/node_modules/requires-port/package.json @@ -0,0 +1,74 @@ +{ + "_from": "requires-port@^1.0.0", + "_id": "requires-port@1.0.0", + "_inBundle": false, + "_integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "_location": "/requires-port", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "requires-port@^1.0.0", + "name": "requires-port", + "escapedName": "requires-port", + "rawSpec": "^1.0.0", + "saveSpec": null, + "fetchSpec": "^1.0.0" + }, + "_requiredBy": [ + "/url-parse" + ], + "_resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "_shasum": "925d2601d39ac485e091cf0da5c6e694dc3dcaff", + "_spec": "requires-port@^1.0.0", + "_where": "/Users/josh.burman/Projects/braid/node_modules/url-parse", + "author": { + "name": "Arnout Kazemier" + }, + "bugs": { + "url": "https://github.com/unshiftio/requires-port/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Check if a protocol requires a certain port number to be added to an URL.", + "devDependencies": { + "assume": "1.3.x", + "istanbul": "0.4.x", + "mocha": "2.3.x", + "pre-commit": "1.1.x" + }, + "homepage": "https://github.com/unshiftio/requires-port", + "keywords": [ + "port", + "require", + "http", + "https", + "ws", + "wss", + "gopher", + "file", + "ftp", + "requires", + "requried", + "portnumber", + "url", + "parsing", + "validation", + "cows" + ], + "license": "MIT", + "main": "index.js", + "name": "requires-port", + "repository": { + "type": "git", + "url": "git+https://github.com/unshiftio/requires-port.git" + }, + "scripts": { + "100%": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100", + "coverage": "istanbul cover _mocha -- test.js", + "test": "mocha test.js", + "test-travis": "istanbul cover _mocha --report lcovonly -- test.js", + "watch": "mocha --watch test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/requires-port/test.js b/node_modules/requires-port/test.js new file mode 100644 index 0000000..93a0c74 --- /dev/null +++ b/node_modules/requires-port/test.js @@ -0,0 +1,98 @@ +describe('requires-port', function () { + 'use strict'; + + var assume = require('assume') + , required = require('./'); + + it('is exported as a function', function () { + assume(required).is.a('function'); + }); + + it('does not require empty ports', function () { + assume(required('', 'http')).false(); + assume(required('', 'wss')).false(); + assume(required('', 'ws')).false(); + assume(required('', 'cowsack')).false(); + }); + + it('assumes true for unknown protocols',function () { + assume(required('808', 'foo')).true(); + assume(required('80', 'bar')).true(); + }); + + it('never requires port numbers for file', function () { + assume(required(8080, 'file')).false(); + }); + + it('does not require port 80 for http', function () { + assume(required('80', 'http')).false(); + assume(required(80, 'http')).false(); + assume(required(80, 'http://')).false(); + assume(required(80, 'http://www.google.com')).false(); + + assume(required('8080', 'http')).true(); + assume(required(8080, 'http')).true(); + assume(required(8080, 'http://')).true(); + assume(required(8080, 'http://www.google.com')).true(); + }); + + it('does not require port 80 for ws', function () { + assume(required('80', 'ws')).false(); + assume(required(80, 'ws')).false(); + assume(required(80, 'ws://')).false(); + assume(required(80, 'ws://www.google.com')).false(); + + assume(required('8080', 'ws')).true(); + assume(required(8080, 'ws')).true(); + assume(required(8080, 'ws://')).true(); + assume(required(8080, 'ws://www.google.com')).true(); + }); + + it('does not require port 443 for https', function () { + assume(required('443', 'https')).false(); + assume(required(443, 'https')).false(); + assume(required(443, 'https://')).false(); + assume(required(443, 'https://www.google.com')).false(); + + assume(required('8080', 'https')).true(); + assume(required(8080, 'https')).true(); + assume(required(8080, 'https://')).true(); + assume(required(8080, 'https://www.google.com')).true(); + }); + + it('does not require port 443 for wss', function () { + assume(required('443', 'wss')).false(); + assume(required(443, 'wss')).false(); + assume(required(443, 'wss://')).false(); + assume(required(443, 'wss://www.google.com')).false(); + + assume(required('8080', 'wss')).true(); + assume(required(8080, 'wss')).true(); + assume(required(8080, 'wss://')).true(); + assume(required(8080, 'wss://www.google.com')).true(); + }); + + it('does not require port 21 for ftp', function () { + assume(required('21', 'ftp')).false(); + assume(required(21, 'ftp')).false(); + assume(required(21, 'ftp://')).false(); + assume(required(21, 'ftp://www.google.com')).false(); + + assume(required('8080', 'ftp')).true(); + assume(required(8080, 'ftp')).true(); + assume(required(8080, 'ftp://')).true(); + assume(required(8080, 'ftp://www.google.com')).true(); + }); + + it('does not require port 70 for gopher', function () { + assume(required('70', 'gopher')).false(); + assume(required(70, 'gopher')).false(); + assume(required(70, 'gopher://')).false(); + assume(required(70, 'gopher://www.google.com')).false(); + + assume(required('8080', 'gopher')).true(); + assume(required(8080, 'gopher')).true(); + assume(required(8080, 'gopher://')).true(); + assume(required(8080, 'gopher://www.google.com')).true(); + }); +}); diff --git a/node_modules/url-parse/LICENSE b/node_modules/url-parse/LICENSE new file mode 100644 index 0000000..6dc9316 --- /dev/null +++ b/node_modules/url-parse/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node_modules/url-parse/README.md b/node_modules/url-parse/README.md new file mode 100644 index 0000000..f81f919 --- /dev/null +++ b/node_modules/url-parse/README.md @@ -0,0 +1,147 @@ +# url-parse + +[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](https://img.shields.io/npm/v/url-parse.svg?style=flat-square)](https://www.npmjs.com/package/url-parse)[![Build Status](https://img.shields.io/travis/unshiftio/url-parse/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/url-parse)[![Dependencies](https://img.shields.io/david/unshiftio/url-parse.svg?style=flat-square)](https://david-dm.org/unshiftio/url-parse)[![Coverage Status](https://img.shields.io/coveralls/unshiftio/url-parse/master.svg?style=flat-square)](https://coveralls.io/r/unshiftio/url-parse?branch=master)[![IRC channel](https://img.shields.io/badge/IRC-irc.freenode.net%23unshift-00a8ff.svg?style=flat-square)](https://webchat.freenode.net/?channels=unshift) + +[![Sauce Test Status](https://saucelabs.com/browser-matrix/url-parse.svg)](https://saucelabs.com/u/url-parse) + +The `url-parse` method exposes two different API interfaces. The +[`url`](https://nodejs.org/api/url.html) interface that you know from Node.js +and the new [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) +interface that is available in the latest browsers. + +In version `0.1` we moved from a DOM based parsing solution, using the `` +element, to a full Regular Expression solution. The main reason for this was +to make the URL parser available in different JavaScript environments as you +don't always have access to the DOM. An example of such environment is the +[`Worker`](https://developer.mozilla.org/en/docs/Web/API/Worker) interface. +The RegExp based solution didn't work well as it required a lot of lookups +causing major problems in FireFox. In version `1.0.0` we ditched the RegExp +based solution in favor of a pure string parsing solution which chops up the +URL into smaller pieces. This module still has a really small footprint as it +has been designed to be used on the client side. + +In addition to URL parsing we also expose the bundled `querystringify` module. + +## Installation + +This module is designed to be used using either browserify or Node.js it's +released in the public npm registry and can be installed using: + +``` +npm install url-parse +``` + +## Usage + +All examples assume that this library is bootstrapped using: + +```js +'use strict'; + +var Url = require('url-parse'); +``` + +To parse an URL simply call the `URL` method with the URL that needs to be +transformed into an object. + +```js +var url = new Url('https://github.com/foo/bar'); +``` + +The `new` keyword is optional but it will save you an extra function invocation. +The constructor takes the following arguments: + +- `url` (`String`): A string representing an absolute or relative URL. +- `baseURL` (`Object` | `String`): An object or string representing + the base URL to use in case `url` is a relative URL. This argument is + optional and defaults to [`location`](https://developer.mozilla.org/en-US/docs/Web/API/Location) + in the browser. +- `parser` (`Boolean` | `Function`): This argument is optional and specifies + how to parse the query string. By default it is `false` so the query string + is not parsed. If you pass `true` the query string is parsed using the + embedded `querystringify` module. If you pass a function the query string + will be parsed using this function. + +As said above we also support the Node.js interface so you can also use the +library in this way: + +```js +'use strict'; + +var parse = require('url-parse') + , url = parse('https://github.com/foo/bar', true); +``` + +The returned `url` instance contains the following properties: + +- `protocol`: The protocol scheme of the URL (e.g. `http:`). +- `slashes`: A boolean which indicates whether the `protocol` is followed by two + forward slashes (`//`). +- `auth`: Authentication information portion (e.g. `username:password`). +- `username`: Username of basic authentication. +- `password`: Password of basic authentication. +- `host`: Host name with port number. +- `hostname`: Host name without port number. +- `port`: Optional port number. +- `pathname`: URL path. +- `query`: Parsed object containing query string, unless parsing is set to false. +- `hash`: The "fragment" portion of the URL including the pound-sign (`#`). +- `href`: The full URL. +- `origin`: The origin of the URL. + +Note that when `url-parse` is used in a browser environment, it will default to +using the browser's current window location as the base URL when parsing all +inputs. To parse an input independently of the browser's current URL (e.g. for +functionality parity with the library in a Node environment), pass an empty +location object as the second parameter: + +```js +var parse = require('url-parse'); +parse('hostname', {}); +``` + +### Url.set(key, value) + +A simple helper function to change parts of the URL and propagating it through +all properties. When you set a new `host` you want the same value to be applied +to `port` if has a different port number, `hostname` so it has a correct name +again and `href` so you have a complete URL. + +```js +var parsed = parse('http://google.com/parse-things'); + +parsed.set('hostname', 'yahoo.com'); +console.log(parsed.href); // http://yahoo.com/parse-things +``` + +It's aware of default ports so you cannot set a port 80 on an URL which has +`http` as protocol. + +### Url.toString() + +The returned `url` object comes with a custom `toString` method which will +generate a full URL again when called. The method accepts an extra function +which will stringify the query string for you. If you don't supply a function we +will use our default method. + +```js +var location = url.toString(); // http://example.com/whatever/?qs=32 +``` + +You would rarely need to use this method as the full URL is also available as +`href` property. If you are using the `URL.set` method to make changes, this +will automatically update. + +## Testing + +The testing of this module is done in 3 different ways: + +1. We have unit tests that run under Node.js. You can run these tests with the + `npm test` command. +2. Code coverage can be run manually using `npm run coverage`. +3. For browser testing we use Sauce Labs and `zuul`. You can run browser tests + using the `npm run test-browser` command. + +## License + +[MIT](LICENSE) diff --git a/node_modules/url-parse/dist/url-parse.js b/node_modules/url-parse/dist/url-parse.js new file mode 100644 index 0000000..1e626d4 --- /dev/null +++ b/node_modules/url-parse/dist/url-parse.js @@ -0,0 +1,555 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.URLParse = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { - var data = JSON.parse(args).data - logger.accessLog.info(`Client Connected: ${data.user_id}`); +function startServer() { + wss.on('connection', (ws: WebSocket, request: object, args: string) => { + var data = JSON.parse(args).data + logger.accessLog.info(`Client Connected: ${data.user_id}`); - if (!channelManager.channelExists(data.channel)) { - channelManager.createChannel(data); - } + if (!channelManager.channelExists(data.channel)) { + channelManager.createChannel(data); + } - if (clientManager.clientExists(data.user_id)) { - var client: ClientBase|MHSClient|null = clientManager.getClient(data.user_id); + if (clientManager.clientExists(data.user_id)) { + var client: ClientBase|MHSClient|null = clientManager.getClient(data.user_id); + + if (client != null) { + client.replaceWebSocket(ws); + } + } else { + var client: ClientBase|MHSClient|null = clientManager.addClient(data, ws); + } if (client != null) { - client.replaceWebSocket(ws); + channelManager.addClientToChannel(client, data.channel); } - } else { - var client: ClientBase|MHSClient|null = clientManager.addClient(data, ws); - } - if (client != null) { - channelManager.addClientToChannel(client, data.channel); - } - - ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!'); -}); - -server.on('upgrade', async function upgrade(request, socket, head) { - let args: {}; - - try { - args = await verifyConnection() - } catch (e) { - socket.destroy(); - logger.accessLog.info('Connection Terminated'); - return; - } - - function verifyConnection() { - return new Promise((resolve, reject) => { - var data = url.parse(request.url, true).query; - var token = data.token || (app.environment == 'development' ? app.devToken : ''); - var accepted = true; - var result: string; - - jwt.verify(token, app.secret, app.signOptions, function(err, decoded) { - if (err) { - console.log(err); - accepted = false; - } - - result = JSON.stringify(decoded) - accepted ? resolve(result) : reject('rejected'); - }); - }); - } - - wss.handleUpgrade(request, socket, head, function done(ws) { - wss.emit('connection', ws, request, args); + ws.send('Hi there, welcome to braid, Measures Web Socket server.\nConnecting all our services!'); }); -}); -server.listen(app.port, () => { - console.log(`Braid v${app.version} is running!\n`); - logger.accessLog.info(`Braid v${app.version} is running!\n`); -}); + server.on('upgrade', async function upgrade(request, socket, head) { + let args: {}; + + try { + args = await verifyConnection() + } catch (e) { + socket.destroy(); + logger.accessLog.info('Connection Terminated'); + return; + } + + function verifyConnection() { + return new Promise((resolve, reject) => { + var data = url.parse(request.url, true).query; + var token = data.token || (app.environment == 'development' ? app.devToken : ''); + var accepted = true; + var result: string; + + jwt.verify(token, app.secret, app.signOptions, function(err, decoded) { + if (err) { + console.log(err); + accepted = false; + } + + result = JSON.stringify(decoded) + accepted ? resolve(result) : reject('rejected'); + }); + }); + } + + wss.handleUpgrade(request, socket, head, function done(ws) { + wss.emit('connection', ws, request, args); + }); + }); + + server.listen(app.port, () => { + console.log(`Braid v${app.version} is running!\n`); + logger.accessLog.info(`Braid v${app.version} is running!\n`); + }); +} + +startServer(); + +module.exports = { + clientManager: clientManager, + channelManager: channelManager +} diff --git a/src/test/channelBase.spec.ts b/src/test/channelBase.spec.ts index fa6bd68..1ba4a21 100644 --- a/src/test/channelBase.spec.ts +++ b/src/test/channelBase.spec.ts @@ -1,15 +1,15 @@ import ChannelBase from '../channels/channelBase'; import ClientBase from '../clients/clientBase'; +var exec = require('child_process').exec; var expect = require('chai').expect; var sinon = require('sinon'); var WebSocketClient = require('websocket').client; var app = require('../config/app'); var name: string = 'test channel'; -var channel: ChannelBase; -var wsLink: string = `wss://${app.hostname}:${app.port}`; var wsClient = new WebSocketClient(); +var channel: ChannelBase; var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name } var client: ClientBase = new ClientBase(data, wsClient); @@ -35,12 +35,7 @@ describe('ChannelBase', function () { expect(result).to.be.equal(true); }); - it('should not broadcase a message to self', function () { - // var wstClient = new WebSocketClient(wsLink); - // var teacher_data: any = { 'client': 'test', 'client_type':'site', 'user_id': 126, 'user_type': 'teacher', 'channel': name } - // var teacher: ClientBase = new ClientBase(teacher_data, wstClient); - // channel.addClient(client); - // channel.addClient(teacher); + it('should not broadcast a message to self', function () { var result = channel.broadcastMessage(client, 'test message'); expect(result.status).to.be.equal('success'); }); diff --git a/src/test/clientManager.spec.ts b/src/test/clientManager.spec.ts index 96d2841..61f965b 100644 --- a/src/test/clientManager.spec.ts +++ b/src/test/clientManager.spec.ts @@ -55,9 +55,4 @@ describe('ClientManager', function () { var result = clientManager.getClientType(data, wsClient); expect(result.clientType()).to.be.equal('mhs'); }); - - // it('should remove a client', function () { - // clientManager.removeClient(data.user_id); - // expect(clientManager.clients.length).to.be.equal(0); - // }); });