diff --git a/client/TODO.txt b/client/TODO.txt index 43ba41c2..5b8b49aa 100644 --- a/client/TODO.txt +++ b/client/TODO.txt @@ -4,6 +4,4 @@ scenario dropdown explosion wrong name for ground units improve map zIndex -fuel is wrong (either 0 or 1, its is casting it to int somewhere) -weapons should not be selectable human symbol if user \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 4e0499d0..6a973207 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -23,12 +23,754 @@ "@types/gtag.js": "^0.0.12", "browserify": "^17.0.0", "concurrently": "^7.6.0", + "firebase": "^9.17.1", "nodemon": "^2.0.20", "tsify": "^5.0.4", "typescript": "^4.9.4", "watchify": "^4.0.0" } }, + "node_modules/@firebase/analytics": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.3.tgz", + "integrity": "sha512-XdYHBi6RvHYVAHGyLxXX0uRPwZmGeqw1JuWS1rMEeRF/jvbxnrL81kcFAHZVRkEvG9bXAJgL2fX9wmDo3e622w==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.3.tgz", + "integrity": "sha512-HmvbB4GMgh8AUlIDIo/OuFENLCGRXxMvtOueK+m8+DcfqBvG+mkii0Mi9ovo0TnMM62cy3oBYG7PHdjIQNLSLA==", + "dev": true, + "dependencies": { + "@firebase/analytics": "0.9.3", + "@firebase/analytics-types": "0.8.0", + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", + "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==", + "dev": true + }, + "node_modules/@firebase/app": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.3.tgz", + "integrity": "sha512-G79JUceVDaHRZ4WkA11GyVldVXhdyRJRwWVQFFvAAVfQJLvy2TA6lQjeUn28F6FmeUWxDGwPC30bxCRWq7Op8Q==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.3.tgz", + "integrity": "sha512-T9f9ceFLs7x4D2T6whu5a6j7B3qPuYHiZHZxW6DkMh/FoMmRA4/q/HVyu01i9+LyJJx2Xdo6eCcj6ofs9YZjqA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.3.tgz", + "integrity": "sha512-25AQ4W7WUL8OWas40GsABuNU622Dm1ojbfeZ03uKtLj5Af7FerJ25u7zkgm+11pc6rpr5v8E5oxEG9vmNRndEA==", + "dev": true, + "dependencies": { + "@firebase/app-check": "0.6.3", + "@firebase/app-check-types": "0.5.0", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz", + "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==", + "dev": true + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", + "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==", + "dev": true + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.3.tgz", + "integrity": "sha512-sX6rD1KFX6K2CuCnQvc9jZLOgAFZ+sv2jKKahIl4SbTM561D682B8n4Jtx/SgDrvcTVTdb05g4NhZOws9hxYxA==", + "dev": true, + "dependencies": { + "@firebase/app": "0.9.3", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==", + "dev": true + }, + "node_modules/@firebase/auth": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.3.tgz", + "integrity": "sha512-HPbcwgArLBVTowFcn4qaQr6LCx7BidI9yrQ5MRbQNv4PsgK/3UGpzCYaNPPbvgr9fe+0jNdJO+uC0+dk4xIzCQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.3.tgz", + "integrity": "sha512-9asUuGtkzUVELH3LYXdiom1nVVV9bqEPqzHohanoofHL/oVTNcHZ4AQ5CXjNATfb6c1WH32U+nEuPiYg26UUIw==", + "dev": true, + "dependencies": { + "@firebase/auth": "0.21.3", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==", + "dev": true + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.3.tgz", + "integrity": "sha512-rnhq5SOsB5nuJphZF50iwqnBiuuyg9kdnlUn1rBrKfu7/cUVJZF5IG1cWrL0rXXyiZW1WBI/J2pmTvVO8dStGQ==", + "dev": true, + "dependencies": { + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.3.tgz", + "integrity": "sha512-J76W6N7JiVkLaAtPyjaGRkrsIu9pi6iZikuGGtGjqvV19vkn7oiL4Hbo5uTYCMd4waTUWoL9iI08eX184W+5GQ==", + "dev": true, + "dependencies": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.3.tgz", + "integrity": "sha512-r+L9jTbvsnb7sD+xz6UKU39DgBWqB2pyjzPNdBeriGC9Ssa2MAZe0bIqjCQg51RRXYc/aa/zK1Q2/4uesZeVgQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/database": "0.14.3", + "@firebase/database-types": "0.10.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.3.tgz", + "integrity": "sha512-Hu34CDhHYZsd2eielr0jeaWrTJk8Hz0nd7WsnYDnXtQX4i49ppgPesUzPdXVBdIBLJmT0ZZRvT7qWHknkOT+zg==", + "dev": true, + "dependencies": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.2" + } + }, + "node_modules/@firebase/firestore": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.8.3.tgz", + "integrity": "sha512-4xR3Mqj95bxHg3hZnz0O+LQrHkjq+siT2y+B9da6u68qJ8bzzT42JaFgd1vifhbBpVbBzpFaS2RuCq2E+kGv9g==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "@firebase/webchannel-wrapper": "0.9.0", + "@grpc/grpc-js": "~1.7.0", + "@grpc/proto-loader": "^0.6.13", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10.10.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.3.tgz", + "integrity": "sha512-fMTsSC0s2cF5w2+JoB0dWD/o4kXtLrUCPGnZPuz4S0bqTN2t0vHr3gdAsQLtnadgwB78ACtinYmf4Udwx7TzDg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/firestore": "3.8.3", + "@firebase/firestore-types": "2.5.1", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz", + "integrity": "sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.3.tgz", + "integrity": "sha512-tPJgYY2ROQSYuzvgxZRoHeDj+Ic07/bWHwaftgTriawtupmFOkt5iikuhJSJUhaOpFh9TB335OvCXJw1N+BIlQ==", + "dev": true, + "dependencies": { + "@firebase/app-check-interop-types": "0.2.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.3", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.3.tgz", + "integrity": "sha512-UIAJ2gzNq0p/61cXqkpi9DnlQt0hdlGqgmL5an7KuJth2Iv5uGpKg/+OapAZxPuiUNZgTEyZDB7kNBHvnxWq5w==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/functions": "0.9.3", + "@firebase/functions-types": "0.6.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", + "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==", + "dev": true + }, + "node_modules/@firebase/installations": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.3.tgz", + "integrity": "sha512-20JFWm+tweNoRjRbz8/Y4I7O5pUJGZsFKCkLl1qNxfNYECSfrZUuozIDJDZC/MeVn5+kB9CwjThDlgQEPrfLdg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.3.tgz", + "integrity": "sha512-K9rKM/ym06lkpaKz7bMLxzHK/HEk65XfLJBV+dJkIuWeO0EqqC9VFGrpWAo0QmgC4BqbU58T6VBbzoJjb0gaFw==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/installations-types": "0.5.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", + "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.3.tgz", + "integrity": "sha512-a3ZKcGDiV2sKmQDB56PpgL1yjFxXCtff2+v1grnAZZ4GnfNQ74t2EHCbmgY7xRX7ThzMqug54oxhuk4ur0MIoA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.3.tgz", + "integrity": "sha512-MmuuohXV2YRzIoJmDngI5qqO/cF2q7SdAaw7k4r61W3ReJy7x4/rtqrIvwNVhM6X/X8NFGBbsYKsCfRHWjFdkg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/messaging": "0.12.3", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", + "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==", + "dev": true + }, + "node_modules/@firebase/performance": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.3.tgz", + "integrity": "sha512-NQmQN6Ete7i9jz1mzULJZEGvsOmwwdUy6vpqnhUxSFMYPnlBKjX+yypCUUJDDN5zff5+kfwSD1qCyUAaS0xWUA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.3.tgz", + "integrity": "sha512-I3rqZsIhauXn4iApfj1ttKQdlti/r8OZBG4YK10vxKSdhAzTIDWDKEsdoCXvvKLwplcMv36sM3WPAPGQLqY5MQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/performance": "0.6.3", + "@firebase/performance-types": "0.2.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", + "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==", + "dev": true + }, + "node_modules/@firebase/remote-config": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.3.tgz", + "integrity": "sha512-Q6d4jBWZoNt6SYq87bjtDGUHFkKwAmGnNjWyRjl14AZqE1ilgd9NZHmutharlYJ3LvxMsid80HdK5SgGEpIPfg==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.3.tgz", + "integrity": "sha512-w/ZL03YgYaXq03xIRyJ5oPhXZi6iDsY/v0J9Y7I7SqxCYytEnHVrL9nvBqd9R94y5LRAVNPCLokJeeizaUz4VQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/remote-config": "0.4.3", + "@firebase/remote-config-types": "0.3.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", + "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==", + "dev": true + }, + "node_modules/@firebase/storage": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.1.tgz", + "integrity": "sha512-Xv8EG2j52ugF2xayBz26U9J0VBXHXPMVxSN+ph3R3BSoHxvMLaPu+qUYKHavSt+zbcgPH2GyBhrCdJK6SaDFPA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.1.tgz", + "integrity": "sha512-6HaTvWsT5Yy3j4UpCZpMcFUYEkJ2XYWukdyTl02u6VjSBRLvkhOXPzEfMvgVWqhnF/rYVfPdjrZ904wk5OxtmQ==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.3", + "@firebase/storage": "0.11.1", + "@firebase/storage-types": "0.8.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", + "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.2.tgz", + "integrity": "sha512-9l0uMGPGw3GsoD5khjMmYCCcMq/OR/OOSViiWMN+s2Q0pxM+fYzrii1H+r8qC/uoMjSVXomjLZt0vZIyryCqtQ==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz", + "integrity": "sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==", + "dev": true + }, + "node_modules/@grpc/grpc-js": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz", + "integrity": "sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==", + "dev": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz", + "integrity": "sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg==", + "dev": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/grpc-js/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz", + "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", + "dev": true + }, + "node_modules/@grpc/grpc-js/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/grpc-js/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dev": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "dev": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dev": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "dev": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "dev": true + }, "node_modules/@types/geojson": { "version": "7946.0.10", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", @@ -48,6 +790,18 @@ "@types/geojson": "*" } }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1155,6 +1909,18 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -1211,6 +1977,40 @@ "node": ">= 0.8" } }, + "node_modules/firebase": { + "version": "9.17.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.17.1.tgz", + "integrity": "sha512-MSZaTRaaRLgDFLqoEnoPYK8zkLwQNvYeLZ3YSKdcQxG8hDifNO22ywS1cSA1ZCGHlQeOsDtfDwBejKcANf/RQw==", + "dev": true, + "dependencies": { + "@firebase/analytics": "0.9.3", + "@firebase/analytics-compat": "0.2.3", + "@firebase/app": "0.9.3", + "@firebase/app-check": "0.6.3", + "@firebase/app-check-compat": "0.3.3", + "@firebase/app-compat": "0.2.3", + "@firebase/app-types": "0.9.0", + "@firebase/auth": "0.21.3", + "@firebase/auth-compat": "0.3.3", + "@firebase/database": "0.14.3", + "@firebase/database-compat": "0.3.3", + "@firebase/firestore": "3.8.3", + "@firebase/firestore-compat": "0.3.3", + "@firebase/functions": "0.9.3", + "@firebase/functions-compat": "0.3.3", + "@firebase/installations": "0.6.3", + "@firebase/installations-compat": "0.2.3", + "@firebase/messaging": "0.12.3", + "@firebase/messaging-compat": "0.2.3", + "@firebase/performance": "0.6.3", + "@firebase/performance-compat": "0.2.3", + "@firebase/remote-config": "0.4.3", + "@firebase/remote-config-compat": "0.2.3", + "@firebase/storage": "0.11.1", + "@firebase/storage-compat": "0.3.1", + "@firebase/util": "1.9.2" + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1485,6 +2285,12 @@ "node": ">= 0.6" } }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -1502,6 +2308,12 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==", + "dev": true + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -1798,12 +2610,24 @@ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "node_modules/lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", "dev": true }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + }, "node_modules/map-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", @@ -1992,6 +2816,26 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -2275,6 +3119,32 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2914,6 +3784,12 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -3139,6 +4015,45 @@ "readable-stream": "3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which-typed-array": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", @@ -3229,6 +4144,648 @@ } }, "dependencies": { + "@firebase/analytics": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.3.tgz", + "integrity": "sha512-XdYHBi6RvHYVAHGyLxXX0uRPwZmGeqw1JuWS1rMEeRF/jvbxnrL81kcFAHZVRkEvG9bXAJgL2fX9wmDo3e622w==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/analytics-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.3.tgz", + "integrity": "sha512-HmvbB4GMgh8AUlIDIo/OuFENLCGRXxMvtOueK+m8+DcfqBvG+mkii0Mi9ovo0TnMM62cy3oBYG7PHdjIQNLSLA==", + "dev": true, + "requires": { + "@firebase/analytics": "0.9.3", + "@firebase/analytics-types": "0.8.0", + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/analytics-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", + "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==", + "dev": true + }, + "@firebase/app": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.3.tgz", + "integrity": "sha512-G79JUceVDaHRZ4WkA11GyVldVXhdyRJRwWVQFFvAAVfQJLvy2TA6lQjeUn28F6FmeUWxDGwPC30bxCRWq7Op8Q==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "@firebase/app-check": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.3.tgz", + "integrity": "sha512-T9f9ceFLs7x4D2T6whu5a6j7B3qPuYHiZHZxW6DkMh/FoMmRA4/q/HVyu01i9+LyJJx2Xdo6eCcj6ofs9YZjqA==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/app-check-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.3.tgz", + "integrity": "sha512-25AQ4W7WUL8OWas40GsABuNU622Dm1ojbfeZ03uKtLj5Af7FerJ25u7zkgm+11pc6rpr5v8E5oxEG9vmNRndEA==", + "dev": true, + "requires": { + "@firebase/app-check": "0.6.3", + "@firebase/app-check-types": "0.5.0", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/app-check-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz", + "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==", + "dev": true + }, + "@firebase/app-check-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", + "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==", + "dev": true + }, + "@firebase/app-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.3.tgz", + "integrity": "sha512-sX6rD1KFX6K2CuCnQvc9jZLOgAFZ+sv2jKKahIl4SbTM561D682B8n4Jtx/SgDrvcTVTdb05g4NhZOws9hxYxA==", + "dev": true, + "requires": { + "@firebase/app": "0.9.3", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==", + "dev": true + }, + "@firebase/auth": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.3.tgz", + "integrity": "sha512-HPbcwgArLBVTowFcn4qaQr6LCx7BidI9yrQ5MRbQNv4PsgK/3UGpzCYaNPPbvgr9fe+0jNdJO+uC0+dk4xIzCQ==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/auth-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.3.tgz", + "integrity": "sha512-9asUuGtkzUVELH3LYXdiom1nVVV9bqEPqzHohanoofHL/oVTNcHZ4AQ5CXjNATfb6c1WH32U+nEuPiYg26UUIw==", + "dev": true, + "requires": { + "@firebase/auth": "0.21.3", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==", + "dev": true + }, + "@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "dev": true, + "requires": {} + }, + "@firebase/component": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.3.tgz", + "integrity": "sha512-rnhq5SOsB5nuJphZF50iwqnBiuuyg9kdnlUn1rBrKfu7/cUVJZF5IG1cWrL0rXXyiZW1WBI/J2pmTvVO8dStGQ==", + "dev": true, + "requires": { + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/database": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.3.tgz", + "integrity": "sha512-J76W6N7JiVkLaAtPyjaGRkrsIu9pi6iZikuGGtGjqvV19vkn7oiL4Hbo5uTYCMd4waTUWoL9iI08eX184W+5GQ==", + "dev": true, + "requires": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.3.tgz", + "integrity": "sha512-r+L9jTbvsnb7sD+xz6UKU39DgBWqB2pyjzPNdBeriGC9Ssa2MAZe0bIqjCQg51RRXYc/aa/zK1Q2/4uesZeVgQ==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/database": "0.14.3", + "@firebase/database-types": "0.10.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/database-types": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.3.tgz", + "integrity": "sha512-Hu34CDhHYZsd2eielr0jeaWrTJk8Hz0nd7WsnYDnXtQX4i49ppgPesUzPdXVBdIBLJmT0ZZRvT7qWHknkOT+zg==", + "dev": true, + "requires": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.2" + } + }, + "@firebase/firestore": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.8.3.tgz", + "integrity": "sha512-4xR3Mqj95bxHg3hZnz0O+LQrHkjq+siT2y+B9da6u68qJ8bzzT42JaFgd1vifhbBpVbBzpFaS2RuCq2E+kGv9g==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "@firebase/webchannel-wrapper": "0.9.0", + "@grpc/grpc-js": "~1.7.0", + "@grpc/proto-loader": "^0.6.13", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/firestore-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.3.tgz", + "integrity": "sha512-fMTsSC0s2cF5w2+JoB0dWD/o4kXtLrUCPGnZPuz4S0bqTN2t0vHr3gdAsQLtnadgwB78ACtinYmf4Udwx7TzDg==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/firestore": "3.8.3", + "@firebase/firestore-types": "2.5.1", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/firestore-types": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz", + "integrity": "sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==", + "dev": true, + "requires": {} + }, + "@firebase/functions": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.3.tgz", + "integrity": "sha512-tPJgYY2ROQSYuzvgxZRoHeDj+Ic07/bWHwaftgTriawtupmFOkt5iikuhJSJUhaOpFh9TB335OvCXJw1N+BIlQ==", + "dev": true, + "requires": { + "@firebase/app-check-interop-types": "0.2.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.3", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/functions-compat": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.3.tgz", + "integrity": "sha512-UIAJ2gzNq0p/61cXqkpi9DnlQt0hdlGqgmL5an7KuJth2Iv5uGpKg/+OapAZxPuiUNZgTEyZDB7kNBHvnxWq5w==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/functions": "0.9.3", + "@firebase/functions-types": "0.6.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/functions-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", + "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==", + "dev": true + }, + "@firebase/installations": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.3.tgz", + "integrity": "sha512-20JFWm+tweNoRjRbz8/Y4I7O5pUJGZsFKCkLl1qNxfNYECSfrZUuozIDJDZC/MeVn5+kB9CwjThDlgQEPrfLdg==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "@firebase/installations-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.3.tgz", + "integrity": "sha512-K9rKM/ym06lkpaKz7bMLxzHK/HEk65XfLJBV+dJkIuWeO0EqqC9VFGrpWAo0QmgC4BqbU58T6VBbzoJjb0gaFw==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/installations-types": "0.5.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/installations-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", + "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", + "dev": true, + "requires": {} + }, + "@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/messaging": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.3.tgz", + "integrity": "sha512-a3ZKcGDiV2sKmQDB56PpgL1yjFxXCtff2+v1grnAZZ4GnfNQ74t2EHCbmgY7xRX7ThzMqug54oxhuk4ur0MIoA==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.2", + "idb": "7.0.1", + "tslib": "^2.1.0" + } + }, + "@firebase/messaging-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.3.tgz", + "integrity": "sha512-MmuuohXV2YRzIoJmDngI5qqO/cF2q7SdAaw7k4r61W3ReJy7x4/rtqrIvwNVhM6X/X8NFGBbsYKsCfRHWjFdkg==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/messaging": "0.12.3", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/messaging-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", + "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==", + "dev": true + }, + "@firebase/performance": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.3.tgz", + "integrity": "sha512-NQmQN6Ete7i9jz1mzULJZEGvsOmwwdUy6vpqnhUxSFMYPnlBKjX+yypCUUJDDN5zff5+kfwSD1qCyUAaS0xWUA==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/performance-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.3.tgz", + "integrity": "sha512-I3rqZsIhauXn4iApfj1ttKQdlti/r8OZBG4YK10vxKSdhAzTIDWDKEsdoCXvvKLwplcMv36sM3WPAPGQLqY5MQ==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/performance": "0.6.3", + "@firebase/performance-types": "0.2.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/performance-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", + "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==", + "dev": true + }, + "@firebase/remote-config": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.3.tgz", + "integrity": "sha512-Q6d4jBWZoNt6SYq87bjtDGUHFkKwAmGnNjWyRjl14AZqE1ilgd9NZHmutharlYJ3LvxMsid80HdK5SgGEpIPfg==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/installations": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/remote-config-compat": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.3.tgz", + "integrity": "sha512-w/ZL03YgYaXq03xIRyJ5oPhXZi6iDsY/v0J9Y7I7SqxCYytEnHVrL9nvBqd9R94y5LRAVNPCLokJeeizaUz4VQ==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/logger": "0.4.0", + "@firebase/remote-config": "0.4.3", + "@firebase/remote-config-types": "0.3.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/remote-config-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", + "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==", + "dev": true + }, + "@firebase/storage": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.1.tgz", + "integrity": "sha512-Xv8EG2j52ugF2xayBz26U9J0VBXHXPMVxSN+ph3R3BSoHxvMLaPu+qUYKHavSt+zbcgPH2GyBhrCdJK6SaDFPA==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/util": "1.9.2", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + } + }, + "@firebase/storage-compat": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.1.tgz", + "integrity": "sha512-6HaTvWsT5Yy3j4UpCZpMcFUYEkJ2XYWukdyTl02u6VjSBRLvkhOXPzEfMvgVWqhnF/rYVfPdjrZ904wk5OxtmQ==", + "dev": true, + "requires": { + "@firebase/component": "0.6.3", + "@firebase/storage": "0.11.1", + "@firebase/storage-types": "0.8.0", + "@firebase/util": "1.9.2", + "tslib": "^2.1.0" + } + }, + "@firebase/storage-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", + "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", + "dev": true, + "requires": {} + }, + "@firebase/util": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.2.tgz", + "integrity": "sha512-9l0uMGPGw3GsoD5khjMmYCCcMq/OR/OOSViiWMN+s2Q0pxM+fYzrii1H+r8qC/uoMjSVXomjLZt0vZIyryCqtQ==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz", + "integrity": "sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==", + "dev": true + }, + "@grpc/grpc-js": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz", + "integrity": "sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==", + "dev": true, + "requires": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "dependencies": { + "@grpc/proto-loader": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz", + "integrity": "sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg==", + "dev": true, + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "protobufjs": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz", + "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==", + "dev": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "dependencies": { + "long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", + "dev": true + } + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dev": true, + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "dev": true + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dev": true, + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "dev": true + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "dev": true + }, "@types/geojson": { "version": "7946.0.10", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", @@ -3248,6 +4805,18 @@ "@types/geojson": "*" } }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "dev": true + }, + "@types/node": { + "version": "18.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -4176,6 +5745,15 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -4225,6 +5803,40 @@ "unpipe": "~1.0.0" } }, + "firebase": { + "version": "9.17.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.17.1.tgz", + "integrity": "sha512-MSZaTRaaRLgDFLqoEnoPYK8zkLwQNvYeLZ3YSKdcQxG8hDifNO22ywS1cSA1ZCGHlQeOsDtfDwBejKcANf/RQw==", + "dev": true, + "requires": { + "@firebase/analytics": "0.9.3", + "@firebase/analytics-compat": "0.2.3", + "@firebase/app": "0.9.3", + "@firebase/app-check": "0.6.3", + "@firebase/app-check-compat": "0.3.3", + "@firebase/app-compat": "0.2.3", + "@firebase/app-types": "0.9.0", + "@firebase/auth": "0.21.3", + "@firebase/auth-compat": "0.3.3", + "@firebase/database": "0.14.3", + "@firebase/database-compat": "0.3.3", + "@firebase/firestore": "3.8.3", + "@firebase/firestore-compat": "0.3.3", + "@firebase/functions": "0.9.3", + "@firebase/functions-compat": "0.3.3", + "@firebase/installations": "0.6.3", + "@firebase/installations-compat": "0.2.3", + "@firebase/messaging": "0.12.3", + "@firebase/messaging-compat": "0.2.3", + "@firebase/performance": "0.6.3", + "@firebase/performance-compat": "0.2.3", + "@firebase/remote-config": "0.4.3", + "@firebase/remote-config-compat": "0.2.3", + "@firebase/storage": "0.11.1", + "@firebase/storage-compat": "0.3.1", + "@firebase/util": "1.9.2" + } + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4426,6 +6038,12 @@ "statuses": ">= 1.4.0 < 2" } }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -4440,6 +6058,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==", + "dev": true + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -4659,12 +6283,24 @@ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", "dev": true }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + }, "map-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", @@ -4819,6 +6455,15 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, "nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -5043,6 +6688,27 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "dev": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5569,6 +7235,12 @@ "nopt": "~1.0.10" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -5754,6 +7426,39 @@ } } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which-typed-array": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", diff --git a/client/package.json b/client/package.json index 80775352..e17f19f9 100644 --- a/client/package.json +++ b/client/package.json @@ -25,6 +25,7 @@ "@types/gtag.js": "^0.0.12", "browserify": "^17.0.0", "concurrently": "^7.6.0", + "firebase": "^9.17.1", "nodemon": "^2.0.20", "tsify": "^5.0.4", "typescript": "^4.9.4", diff --git a/client/public/stylesheets/button.css b/client/public/stylesheets/button.css index 5540c792..d5910387 100644 --- a/client/public/stylesheets/button.css +++ b/client/public/stylesheets/button.css @@ -1,4 +1,4 @@ -.olympus-button { +.ol-button { width: 24px; height: 24px; background-color: transparent; @@ -7,11 +7,11 @@ align-items: center; } -.olympus-button img { +.ol-button img { width: 24px; height: 24px; } -.olympus-button:hover {} +.ol-button:hover {} -.olympus-button:active {} \ No newline at end of file +.ol-button:active {} \ No newline at end of file diff --git a/client/public/stylesheets/connectionstatuspanel.css b/client/public/stylesheets/connectionstatuspanel.css index fce5a084..6acc1021 100644 --- a/client/public/stylesheets/connectionstatuspanel.css +++ b/client/public/stylesheets/connectionstatuspanel.css @@ -10,7 +10,7 @@ color: white; } -.olympus-status-disconnected::after { +.ol-status-disconnected::after { content: ""; position: absolute; right: 5px; @@ -21,7 +21,7 @@ background-color: red; } -.olympus-status-connected::after { +.ol-status-connected::after { content: ""; position: absolute; right: 5px; diff --git a/client/public/stylesheets/dropdown.css b/client/public/stylesheets/dropdown.css index a9faaa44..ca735077 100644 --- a/client/public/stylesheets/dropdown.css +++ b/client/public/stylesheets/dropdown.css @@ -1,4 +1,4 @@ -.olympus-dropdown { +.ol-dropdown { width: 100%; min-width: 100px; height: 30px; @@ -18,7 +18,7 @@ padding-left: 15px; } -.olympus-dropdown::before { +.ol-dropdown::before { content: ""; position: absolute; height: 30px; @@ -31,11 +31,11 @@ border-bottom-right-radius: 15px; } -.olympus-dropdown-open { +.ol-dropdown-open { border-bottom-left-radius: 0px; } -.olympus-dropdown-open::after { +.ol-dropdown-open::after { content: ""; position: absolute; top: 13px; @@ -50,7 +50,7 @@ -webkit-transform: rotate(-135deg); } -.olympus-dropdown-closed::after { +.ol-dropdown-closed::after { content: ""; position: absolute; top: 9px; @@ -65,7 +65,7 @@ -webkit-transform: rotate(45deg); } -.olympus-dropdown-content { +.ol-dropdown-content { position: fixed; /*overflow: visible; overflow-y: scroll;*/ @@ -75,7 +75,7 @@ border-bottom-right-radius: 4px; } -.olympus-dropdown-element { +.ol-dropdown-element { margin: 2px; font-family: Verdana, Geneva, Tahoma, sans-serif; color: var(--background-color-dark); @@ -85,6 +85,6 @@ padding-left: 5px; } -.olympus-dropdown-element:hover { +.ol-dropdown-element:hover { background-color: var(--highlight-color); } \ No newline at end of file diff --git a/client/public/stylesheets/elements.css b/client/public/stylesheets/elements.css index 1ac11c9f..570c8c95 100644 --- a/client/public/stylesheets/elements.css +++ b/client/public/stylesheets/elements.css @@ -1,4 +1,4 @@ -.olympus-element-1 { +.ol-element-1 { background-color: #247be2; height: 28; border-radius: 14px; diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index ec6e1e20..2184f6f5 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -76,7 +76,7 @@ body { position: absolute; left: 230px; height: 30px; - width: 150; + width: fit-content; top: 10px; z-index: 1000; display: flex; diff --git a/client/public/stylesheets/panels.css b/client/public/stylesheets/panels.css index 0b00f8a6..74153621 100644 --- a/client/public/stylesheets/panels.css +++ b/client/public/stylesheets/panels.css @@ -1,5 +1,5 @@ /* Panels style */ -.olympus-panel { +.ol-panel { background-color: var(--background-color-dark); font-size: 12px; transition: bottom 0.2s; diff --git a/client/public/stylesheets/selectionscroll.css b/client/public/stylesheets/selectionscroll.css index 70cd38d3..b2913d86 100644 --- a/client/public/stylesheets/selectionscroll.css +++ b/client/public/stylesheets/selectionscroll.css @@ -1,4 +1,4 @@ -.olympus-selection-scroll-container { +.ol-selection-scroll-container { position: absolute; font-size: 12px; border-radius: 5px; @@ -13,7 +13,7 @@ align-items: center; } -#olympus-selection-scroll-top-bar { +#ol-selection-scroll-top-bar { color: white; font-size: 14px; opacity: 1; @@ -30,30 +30,30 @@ padding-right: 15px; } -.olympus-selection-scroll { +.ol-selection-scroll { overflow-x: hidden; overflow-y: auto; height: 100%; width: 100%; } -.olympus-selection-scroll::-webkit-scrollbar { +.ol-selection-scroll::-webkit-scrollbar { width: 10px; } -.olympus-selection-scroll::-webkit-scrollbar-track { +.ol-selection-scroll::-webkit-scrollbar-track { background-color: transparent; border-radius: 100px; } -.olympus-selection-scroll::-webkit-scrollbar-thumb { +.ol-selection-scroll::-webkit-scrollbar-thumb { background-color: white; border-radius: 100px; opacity: 0.8; margin-top: 10px; } -.olympus-selection-scroll-element { +.ol-selection-scroll-element { border-bottom: 1px solid #FFF5; color: white; cursor: pointer; @@ -66,25 +66,25 @@ font-weight: 600; } -.olympus-selection-scroll:last-child { +.ol-selection-scroll:last-child { border-radius: 5px; border-bottom: 0px transparent !important; } -.olympus-selection-scroll-container label { +.ol-selection-scroll-container label { display: inline-block; width: 40px; height: 24px; } -.olympus-selection-scroll-container input { +.ol-selection-scroll-container input { display: inline-block; width: 0; height: 0; margin: 0px; } -.olympus-selection-scroll-switch { +.ol-selection-scroll-switch { position: relative; display: inline-block; width: 40px; @@ -94,7 +94,7 @@ cursor: pointer; } -.olympus-selection-scroll-switch:before { +.ol-selection-scroll-switch:before { position: absolute; content: ""; height: 16px; @@ -107,13 +107,13 @@ border-radius: 999px; } -input:checked+.olympus-selection-scroll-switch:before { +input:checked+.ol-selection-scroll-switch:before { -webkit-transform: translateX(16px); -ms-transform: translateX(16px); transform: translateX(16px); } -.olympus-selection-scroll-title { +.ol-selection-scroll-title { font-size: 11px; font-weight: 600; } \ No newline at end of file diff --git a/client/public/stylesheets/selectionwheel.css b/client/public/stylesheets/selectionwheel.css index d0d56f50..a3ff61f7 100644 --- a/client/public/stylesheets/selectionwheel.css +++ b/client/public/stylesheets/selectionwheel.css @@ -1,4 +1,4 @@ -.olympus-selection-wheel { +.ol-selection-wheel { margin: 0; position: fixed; z-index: 1000; @@ -10,7 +10,7 @@ justify-content: center; } -.olympus-wheel { +.ol-wheel { width: 100%; border-radius: 50%; background-color: var(--background-color-dark); @@ -19,7 +19,7 @@ transition: background-color 0.2s; } -.olympus-wheel:before { +.ol-wheel:before { content: ""; display: block; padding-top: 100%; @@ -57,17 +57,17 @@ /*filter: invert(21%) sepia(23%) saturate(775%) hue-rotate(170deg) brightness(92%) contrast(90%);*/ } -.olympus-selection-wheel label { +.ol-selection-wheel label { width: 0; height: 0; } -.olympus-selection-wheel input { +.ol-selection-wheel input { width: 0; height: 0; } -.olympus-selection-wheel-switch { +.ol-selection-wheel-switch { position: absolute; top: 50%; left: 50%; @@ -81,7 +81,7 @@ cursor: pointer; } -.olympus-selection-wheel-switch:before { +.ol-selection-wheel-switch:before { position: absolute; content: ""; height: 26px; @@ -95,7 +95,7 @@ } -input:checked+.olympus-selection-wheel-switch:before { +input:checked+.ol-selection-wheel-switch:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); diff --git a/client/public/stylesheets/style.css b/client/public/stylesheets/style.css index b68fd52a..d4c01fcc 100644 --- a/client/public/stylesheets/style.css +++ b/client/public/stylesheets/style.css @@ -184,4 +184,23 @@ html { font-size: 12px; z-index: 2000; font-weight: 600; +} + +.ol-scrollable { + overflow-y: auto; +} + +.ol-scrollable::-webkit-scrollbar { + width: 10px; +} + +.ol-scrollable::-webkit-scrollbar-track { + background-color: transparent; + border-radius: 100px; +} + +.ol-scrollable::-webkit-scrollbar-thumb { + background-color: white; + border-radius: 100px; + opacity: 0.8; } \ No newline at end of file diff --git a/client/public/stylesheets/unitcontrolpanel.css b/client/public/stylesheets/unitcontrolpanel.css index f01d791a..fc7c0eac 100644 --- a/client/public/stylesheets/unitcontrolpanel.css +++ b/client/public/stylesheets/unitcontrolpanel.css @@ -29,7 +29,10 @@ flex-direction: column; row-gap: 5px; width: 100%; - height: 100%; + height: fit-content; + max-height: 200px; + padding-top: 10px; + padding-bottom: 10px; } #formation-buttons-container { diff --git a/client/public/stylesheets/unitinfopanel.css b/client/public/stylesheets/unitinfopanel.css index ec6f24d8..ca311143 100644 --- a/client/public/stylesheets/unitinfopanel.css +++ b/client/public/stylesheets/unitinfopanel.css @@ -119,3 +119,12 @@ font-weight: 600; } +#loadout-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + column-gap: 2px; + row-gap: 2px; + min-height: 0px; + max-height: 70px; /* TODO: fix me, magic number */ +} diff --git a/client/public/stylesheets/visibilitycontrolpanel.css b/client/public/stylesheets/visibilitycontrolpanel.css index 92ad6bef..5e637c0a 100644 --- a/client/public/stylesheets/visibilitycontrolpanel.css +++ b/client/public/stylesheets/visibilitycontrolpanel.css @@ -1,4 +1,16 @@ -#visibility-control-panel .olympus-button { - filter: invert(100%); - opacity: 0.8; -} \ No newline at end of file +#visibility-control-panel +{ + display: flex; + column-gap: 10px; +} + +#visibility-control-panel .label { + color: white; + font-size: 12px; + font-weight: 600; +} + +#visibility-control-panel .vl { + height: 60%; +} + diff --git a/client/src/atc/ATCAPI.ts b/client/src/atc/ATCAPI.ts new file mode 100644 index 00000000..38f1ce5c --- /dev/null +++ b/client/src/atc/ATCAPI.ts @@ -0,0 +1,15 @@ +import { firestore } from "../firebase"; + +export interface ATCAPIInterface { + get: CallableFunction +} + +export abstract class ATCAPI { + + firestore; + + constructor() { + this.firestore = firestore; + } + +} \ No newline at end of file diff --git a/client/src/atc/FlightBoard.ts b/client/src/atc/FlightBoard.ts new file mode 100644 index 00000000..7f7470f1 --- /dev/null +++ b/client/src/atc/FlightBoard.ts @@ -0,0 +1 @@ +export class ATCFlightBoard {} \ No newline at end of file diff --git a/client/src/atc/api/Flights.ts b/client/src/atc/api/Flights.ts new file mode 100644 index 00000000..96090257 --- /dev/null +++ b/client/src/atc/api/Flights.ts @@ -0,0 +1,24 @@ +import { ATCAPI, ATCAPIInterface } from "../ATCAPI"; +import { collection, getDocs } from "firebase/firestore"; +import { firebase } from "../../firebase"; + +export class ATCAPI_Flights extends ATCAPI implements ATCAPIInterface { + + constructor() { + super(); + } + + get() { + + async () => { + const snapshot = await getDocs( collection( this.firestore, "flights" ) ); + + snapshot.forEach( doc => { + console.log( doc.data() ); + }); + + } + + } + +} \ No newline at end of file diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts index 68b73a2a..aded3cd6 100644 --- a/client/src/controls/dropdown.ts +++ b/client/src/controls/dropdown.ts @@ -20,10 +20,10 @@ export class Dropdown { open() { if (this.#container != null) { this.#open = true; - this.#container.classList.add("olympus-dropdown-open"); - this.#container.classList.remove("olympus-dropdown-closed"); + this.#container.classList.add("ol-dropdown-open"); + this.#container.classList.remove("ol-dropdown-closed"); this.#content = document.createElement("div"); - this.#content.classList.add("olympus-dropdown-content"); + this.#content.classList.add("ol-dropdown-content"); this.#content.style.width = (this.#container.offsetWidth - this.#container.offsetHeight) + "px"; this.#content.style.left = this.#container.offsetLeft + "px"; @@ -34,7 +34,7 @@ export class Dropdown { var height = 2; for (let optionID in this.#options) { var node = document.createElement("div"); - node.classList.add("olympus-dropdown-element"); + node.classList.add("ol-dropdown-element"); node.appendChild(document.createTextNode(this.#options[optionID])); this.#content.appendChild(node); height += node.offsetHeight + 2; @@ -53,8 +53,8 @@ export class Dropdown { close() { if (this.#container != null) { this.#open = false; - this.#container?.classList.remove("olympus-dropdown-open"); - this.#container?.classList.add("olympus-dropdown-closed"); + this.#container?.classList.remove("ol-dropdown-open"); + this.#container?.classList.add("ol-dropdown-closed"); if (this.#content != null) document.body.removeChild(this.#content); } diff --git a/client/src/controls/selectionscroll.ts b/client/src/controls/selectionscroll.ts index 7a518371..e4322e73 100644 --- a/client/src/controls/selectionscroll.ts +++ b/client/src/controls/selectionscroll.ts @@ -20,18 +20,17 @@ export class SelectionScroll { this.hide(); if (this.#container != null && options.length >= 1) { - var titleDiv = this.#container.querySelector("#olympus-selection-scroll-top-bar")?.querySelector(".olympus-selection-scroll-title"); + var titleDiv = this.#container.querySelector("#ol-selection-scroll-top-bar")?.querySelector(".ol-selection-scroll-title"); if (titleDiv) titleDiv.innerHTML = title; this.#container.style.display = this.#display; - this.#container.style.left = x - this.#container.offsetWidth / 2 + "px"; - this.#container.style.top = y - 20 + "px"; - var scroll = this.#container.querySelector(".olympus-selection-scroll"); + + var scroll = this.#container.querySelector(".ol-selection-scroll"); if (scroll != null) { for (let optionID in options) { var node = document.createElement("div"); - node.classList.add("olympus-selection-scroll-element"); + node.classList.add("ol-selection-scroll-element"); if (typeof options[optionID] === 'string' || options[optionID] instanceof String){ node.appendChild(document.createTextNode(options[optionID])); node.addEventListener('click', () => callback(options[optionID])); @@ -45,7 +44,7 @@ export class SelectionScroll { } /* Hide the coalition switch if required */ - var switchContainer = this.#container.querySelector("#olympus-selection-scroll-top-bar")?.querySelector("#coalition-switch-container"); + var switchContainer = this.#container.querySelector("#ol-selection-scroll-top-bar")?.querySelector("#coalition-switch-container"); if (showCoalition == false) { switchContainer.style.display = "none"; document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--neutral-coalition-color")); @@ -57,14 +56,26 @@ export class SelectionScroll { else document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--red-coalition-color")); } + + if (x - this.#container.offsetWidth / 2 + this.#container.offsetWidth < window.innerWidth) + this.#container.style.left = x - this.#container.offsetWidth / 2 + "px"; + else + this.#container.style.left = window.innerWidth - this.#container.offsetWidth + "px"; + + console.log(y - 20 + this.#container.offsetHeight) + if (y - 20 + this.#container.offsetHeight < window.innerHeight) + this.#container.style.top = y - 20 + "px"; + else + this.#container.style.top = window.innerHeight - this.#container.offsetHeight + "px"; + } } hide() { if (this.#container != null) { this.#container.style.display = "none"; - var buttons = this.#container.querySelectorAll(".olympus-selection-scroll-element"); - var scroll = this.#container.querySelector(".olympus-selection-scroll"); + var buttons = this.#container.querySelectorAll(".ol-selection-scroll-element"); + var scroll = this.#container.querySelector(".ol-selection-scroll"); if (scroll != null) { for (let child of buttons) { diff --git a/client/src/firebase.ts b/client/src/firebase.ts new file mode 100644 index 00000000..9082bbd3 --- /dev/null +++ b/client/src/firebase.ts @@ -0,0 +1,28 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from "firebase/app"; +import { getAnalytics } from "firebase/analytics"; +import { getFirestore } from "firebase/firestore"; + +// TODO: Add SDKs for Firebase products that you want to use +// https://firebase.google.com/docs/web/setup#available-libraries + +// Your web app's Firebase configuration +// For Firebase JS SDK v7.20.0 and later, measurementId is optional +const firebaseConfig = { + apiKey: "AIzaSyArFxFtLvZqV6RKMxZR-zCH-TT3LV43aVg", + authDomain: "dcs-olympus.firebaseapp.com", + projectId: "dcs-olympus", + storageBucket: "dcs-olympus.appspot.com", + messagingSenderId: "393187308632", + appId: "1:393187308632:web:545dc9551716a84d3c462d", + measurementId: "G-10E10S2WBN" +}; + +// Initialize Firebase +const firebase = initializeApp( firebaseConfig ); + +const analytics = getAnalytics( firebase ); +const firestore = getFirestore( firebase ); + + +export { firebase, analytics, firestore }; \ No newline at end of file diff --git a/client/src/index.ts b/client/src/index.ts index eae8675f..b3448dd8 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -13,6 +13,7 @@ import { MouseInfoPanel } from "./panels/mouseInfoPanel"; import { Slider } from "./controls/slider"; import { AIC } from "./aic/AIC"; +import { VisibilityControlPanel } from "./panels/visibilitycontrolpanel"; /* TODO: should this be a class? */ var map: Map; @@ -26,6 +27,7 @@ var unitInfoPanel: UnitInfoPanel; var connectionStatusPanel: ConnectionStatusPanel; var unitControlPanel: UnitControlPanel; var mouseInfoPanel: MouseInfoPanel; +var visibilityControlPanel: VisibilityControlPanel; var scenarioDropdown: Dropdown; var mapSourceDropdown: Dropdown; @@ -34,11 +36,6 @@ var slowButton: Button; var fastButton: Button; var climbButton: Button; var descendButton: Button; -var userVisibilityButton: Button; -var aiVisibilityButton: Button; -var uncontrolledVisibilityButton: Button; -var weaponVisibilityButton: Button; -var deadVisibilityButton: Button; var aic: AIC; var aicToggleButton: Button; @@ -53,15 +50,22 @@ var activeCoalition: string; function setup() { /* Initialize */ map = new Map('map-container'); + unitsManager = new UnitsManager(); + selectionWheel = new SelectionWheel("selection-wheel"); selectionScroll = new SelectionScroll("selection-scroll"); - unitsManager = new UnitsManager(); + unitInfoPanel = new UnitInfoPanel("unit-info-panel"); unitControlPanel = new UnitControlPanel("unit-control-panel"); scenarioDropdown = new Dropdown("scenario-dropdown", ["Caucasus", "Marianas", "Nevada", "South Atlantic", "Syria", "The Channel"], () => { }); mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option)); connectionStatusPanel = new ConnectionStatusPanel("connection-status-panel"); mouseInfoPanel = new MouseInfoPanel("mouse-info-panel"); + visibilityControlPanel = new VisibilityControlPanel("visibility-control-panel"); + + scenarioDropdown = new Dropdown("scenario-dropdown", ["Caucasus", "Syria", "Marianas", "Nevada", "South Atlantic", "The channel"], () => { }); + mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option)); + missionData = new MissionData(); /* Unit control buttons */ @@ -74,18 +78,6 @@ function setup() { altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => getUnitsManager().selectedUnitsSetAltitude(value * 0.3048)); airspeedSlider = new Slider("airspeed-slider", 0, 100, "kts", (value: number) => getUnitsManager().selectedUnitsSetSpeed(value / 1.94384)); - /* Visibility buttons */ - userVisibilityButton = new Button("user-visibility-button", ["images/buttons/user-full.svg", "images/buttons/user-partial.svg", "images/buttons/user-none.svg", "images/buttons/user-hidden.svg"], () => { getUnitsManager().forceUpdate() }); - aiVisibilityButton = new Button("ai-visibility-button", ["images/buttons/ai-full.svg", "images/buttons/ai-partial.svg", "images/buttons/ai-none.svg", "images/buttons/ai-hidden.svg"], () => { getUnitsManager().forceUpdate() }); - uncontrolledVisibilityButton = new Button("uncontrolled-visibility-button", ["images/buttons/ai-full.svg", "images/buttons/ai-partial.svg", "images/buttons/ai-none.svg", "images/buttons/ai-hidden.svg"], () => { getUnitsManager().forceUpdate() }); - weaponVisibilityButton = new Button("weapon-visibility-button", ["images/buttons/weapon-partial.svg", "images/buttons/weapon-none.svg", "images/buttons/weapon-hidden.svg"], () => { getUnitsManager().forceUpdate() }); - deadVisibilityButton = new Button("dead-visibility-button", ["images/buttons/dead.svg", "images/buttons/dead-hidden.svg"], () => { getUnitsManager().forceUpdate() }); - - aiVisibilityButton.setState(1); - uncontrolledVisibilityButton.setState(3); - weaponVisibilityButton.setState(1); - deadVisibilityButton.setState(1); - /* AIC */ aic = new AIC(); @@ -193,70 +185,6 @@ export function getConnected() { return connected; } -export function getVisibilitySettings() { - var visibility = { - user: "", - ai: "", - uncontrolled: "", - weapon: "", - dead: "" - }; - - switch (userVisibilityButton.getState()) { - case 0: - visibility.user = "full"; break; - case 1: - visibility.user = "partial"; break; - case 2: - visibility.user = "none"; break; - case 3: - visibility.user = "hidden"; break; - } - - switch (aiVisibilityButton.getState()) { - case 0: - visibility.ai = "full"; break; - case 1: - visibility.ai = "partial"; break; - case 2: - visibility.ai = "none"; break; - case 3: - visibility.ai = "hidden"; break; - } - - switch (uncontrolledVisibilityButton.getState()) { - case 0: - visibility.uncontrolled = "full"; break; - case 1: - visibility.uncontrolled = "partial"; break; - case 2: - visibility.uncontrolled = "none"; break; - case 3: - visibility.uncontrolled = "hidden"; break; - } - - switch (weaponVisibilityButton.getState()) { - case 0: - visibility.weapon = "partial"; break; - case 1: - visibility.weapon = "none"; break; - case 2: - visibility.weapon = "hidden"; break; - } - - switch (deadVisibilityButton.getState()) { - case 0: - visibility.dead = "none"; break; - case 1: - visibility.dead = "hidden"; break; - } - return visibility; -} - -export function getVisibilityButtons() { - return {user: userVisibilityButton, ai: aiVisibilityButton, weapon: weaponVisibilityButton, dead: deadVisibilityButton} -} - export function getUnitControlSliders() { return {altitude: altitudeSlider, airspeed: airspeedSlider} } diff --git a/client/src/panels/connectionstatuspanel.ts b/client/src/panels/connectionstatuspanel.ts index f1ece049..87525048 100644 --- a/client/src/panels/connectionstatuspanel.ts +++ b/client/src/panels/connectionstatuspanel.ts @@ -11,13 +11,13 @@ export class ConnectionStatusPanel { if (div != null) { if (connected) { div.innerHTML = "Connected"; - div.classList.add("olympus-status-connected"); - div.classList.remove("olympus-status-disconnected"); + div.classList.add("ol-status-connected"); + div.classList.remove("ol-status-disconnected"); } else { div.innerHTML = "Disconnected"; - div.classList.add("olympus-status-disconnected"); - div.classList.remove("olympus-status-connected"); + div.classList.add("ol-status-disconnected"); + div.classList.remove("ol-status-connected"); } } } diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 070d1dda..2887c0ed 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -26,7 +26,7 @@ export class UnitInfoPanel { if (this.#element != null) { var els = this.#element.getElementsByClassName("js-loadout-element"); while (els.length > 0) - this.#element.querySelector("#loadout-data")?.removeChild(els[0]); + this.#element.querySelector("#loadout-container")?.removeChild(els[0]); for (let index in unit.ammo) { var ammo = unit.ammo[index]; @@ -35,7 +35,7 @@ export class UnitInfoPanel { var el = document.createElement("div") el.classList.add("js-loadout-element", "rectangular-container-dark") el.innerHTML = amount + "x" + displayName; - this.#element.querySelector("#loadout-data")?.appendChild(el); + this.#element.querySelector("#loadout-container")?.appendChild(el); } this.#element.querySelector("#unit-name")!.innerHTML = unit.unitName; diff --git a/client/src/panels/visibilitycontrolpanel.ts b/client/src/panels/visibilitycontrolpanel.ts new file mode 100644 index 00000000..e4c6b402 --- /dev/null +++ b/client/src/panels/visibilitycontrolpanel.ts @@ -0,0 +1,80 @@ +import { AirUnit, GroundUnit, NavyUnit, Weapon } from "../units/unit"; + +export class VisibilityControlPanel { + #element: HTMLElement + + constructor(ID: string) { + this.#element = document.getElementById(ID); + + if (this.#element != null) + { + var airVisibilityCheckbox = this.#element.querySelector("#air-visibility"); + var groundVisibilityCheckbox = this.#element.querySelector("#ground-visibility"); + var navyVisibilityCheckbox = this.#element.querySelector("#navy-visibility"); + var weaponVisibilityCheckbox = this.#element.querySelector("#weapon-visibility"); + + airVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); + groundVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); + navyVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); + weaponVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); + + var fullVisibilitySelection = this.#element.querySelector("#full-visibility"); + var partialVisibilitySelection = this.#element.querySelector("#partial-visibility"); + var minimalVisibilitySelection = this.#element.querySelector("#minimal-visibility"); + + fullVisibilitySelection?.addEventListener("change", () => this.#onChange()); + partialVisibilitySelection?.addEventListener("change", () => this.#onChange()); + minimalVisibilitySelection?.addEventListener("change", () => this.#onChange()); + + var uncontrolledVisibilityCheckbox = this.#element.querySelector("#uncontrolled-visibility"); + uncontrolledVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); + } + } + + #onChange(){ + if (this.#element != null) + { + var fullVisibilitySelection = this.#element.querySelector("#full-visibility"); + var partialVisibilitySelection = this.#element.querySelector("#partial-visibility"); + var minimalVisibilitySelection = this.#element.querySelector("#minimal-visibility"); + + var activeVisibility = ""; + if (fullVisibilitySelection.checked) + activeVisibility = "full"; + else if (partialVisibilitySelection.checked) + activeVisibility = "partial"; + else if (minimalVisibilitySelection.checked) + activeVisibility = "minimal"; + + var uncontrolledVisibilityCheckbox = this.#element.querySelector("#uncontrolled-visibility"); + var uncontrolledVisibility = !uncontrolledVisibilityCheckbox.checked; + + var airVisibilityCheckbox = this.#element.querySelector("#air-visibility"); + if (airVisibilityCheckbox.checked) + AirUnit.setVisibility({human: activeVisibility, ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); + else + AirUnit.setVisibility({human: "hidden", ai: "hidden", uncontrolled: "hidden", dead: "hidden"}); + + var groundVisibilityCheckbox = this.#element.querySelector("#ground-visibility"); + if (groundVisibilityCheckbox.checked) + GroundUnit.setVisibility({human: activeVisibility, ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); + else + GroundUnit.setVisibility({human: "hidden", ai: "hidden", uncontrolled: "hidden", dead: "hidden"}); + + var navyVisibilityCheckbox = this.#element.querySelector("#navy-visibility"); + if (navyVisibilityCheckbox.checked) + NavyUnit.setVisibility({human: activeVisibility, ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); + else + NavyUnit.setVisibility({human: "hidden", ai: "hidden", uncontrolled: "hidden", dead: "hidden"}); + + var weaponVisibilityCheckbox = this.#element.querySelector("#weapon-visibility"); + if (weaponVisibilityCheckbox.checked) + Weapon.setVisibility({human: activeVisibility, ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); + else + Weapon.setVisibility({human: "hidden", ai: "hidden", uncontrolled: "hidden", dead: "hidden"}); + } + + } + + +} \ No newline at end of file diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 9e9c1b3a..918967b6 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -1,9 +1,15 @@ import { Marker, LatLng, Polyline, Icon } from 'leaflet'; -import { ConvertDDToDMS } from '../other/utils'; -import { getMap, getUnitsManager, getVisibilitySettings } from '..'; +import { getMap, getUnitsManager} from '..'; import { UnitMarker, MarkerOptions, AircraftMarker, HelicopterMarker, GroundUnitMarker, NavyUnitMarker, WeaponMarker } from './unitmarker'; import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, landAt, setAltitude, setReactionToThreat, setROE, setSpeed } from '../dcs/dcs'; +interface visibilityOptions { + dead: string; + ai: string; + uncontrolled: string; + human: string; +} + var pathIcon = new Icon({ iconUrl: 'images/marker-icon.png', shadowUrl: 'images/marker-shadow.png', @@ -387,20 +393,33 @@ export class Unit { } export class AirUnit extends Unit { - getHidden() { - if (this.AI == false && getVisibilitySettings().uncontrolled === "hidden") - return true + static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: visibilityOptions) + { + getUnitsManager().forceUpdate(); + AirUnit.visibility = visibility; + } + static getVisibility() + { + return AirUnit.visibility; + } + + getHidden() { if (this.alive) { - if (this.flags.user && getVisibilitySettings().user === "hidden") - return true - else if (!this.flags.user && getVisibilitySettings().ai === "hidden") - return true + if (this.flags.user) + return AirUnit.getVisibility().human === "hidden" + + if (this.AI) + return AirUnit.getVisibility().ai === "hidden" + else + return AirUnit.getVisibility().uncontrolled === "hidden" } else - return getVisibilitySettings().dead === "hidden" - return false; + { + return AirUnit.getVisibility().dead === "hidden" + } } } @@ -419,52 +438,87 @@ export class Helicopter extends AirUnit { } export class GroundUnit extends Unit { + static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: visibilityOptions) + { + getUnitsManager().forceUpdate(); + GroundUnit.visibility = visibility; + } + + static getVisibility() + { + return GroundUnit.visibility; + } + constructor(ID: number, options: MarkerOptions) { var marker = new GroundUnitMarker(options); super(ID, marker); } getHidden() { - if (this.AI == false && getVisibilitySettings().uncontrolled === "hidden") - return true - if (this.alive) { - if (this.flags.user && getVisibilitySettings().user === "hidden") - return true - else if (!this.flags.user && getVisibilitySettings().ai === "hidden") - return true + if (this.flags.user) + return GroundUnit.getVisibility().human === "hidden" + + if (this.AI) + return GroundUnit.getVisibility().ai === "hidden" + else + return GroundUnit.getVisibility().uncontrolled === "hidden" } else - return getVisibilitySettings().dead === "hidden" - return false; + { + return GroundUnit.getVisibility().dead === "hidden" + } } } export class NavyUnit extends Unit { + static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: visibilityOptions) + { + getUnitsManager().forceUpdate(); + NavyUnit.visibility = visibility; + } + + static getVisibility() + { + return NavyUnit.visibility; + } + constructor(ID: number, options: MarkerOptions) { var marker = new NavyUnitMarker(options); super(ID, marker); } getHidden() { - if (this.AI == false && getVisibilitySettings().uncontrolled === "hidden") - return true - if (this.alive) { - if (this.flags.user && getVisibilitySettings().user === "hidden") - return true - else if (!this.flags.user && getVisibilitySettings().ai === "hidden") - return true + if (this.AI) + return NavyUnit.getVisibility().ai === "hidden" + else + return NavyUnit.getVisibility().uncontrolled === "hidden" } else - return getVisibilitySettings().dead === "hidden" - return false; + { + return NavyUnit.getVisibility().dead === "hidden" + } } } export class Weapon extends Unit { + static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: visibilityOptions) + { + getUnitsManager().forceUpdate(); + Weapon.visibility = visibility; + } + + static getVisibility() + { + return Weapon.visibility; + } + constructor(ID: number, marker: UnitMarker) { super(ID, marker); @@ -473,13 +527,9 @@ export class Weapon extends Unit { getHidden() { if (this.alive) - { - if (!this.flags.user && getVisibilitySettings().weapon === "hidden") - return true - } + return Weapon.getVisibility().uncontrolled === "hidden" else - return getVisibilitySettings().dead === "hidden" - return false; + return true; } } diff --git a/client/src/units/unitmarker.ts b/client/src/units/unitmarker.ts index c981a6f6..55c2297a 100644 --- a/client/src/units/unitmarker.ts +++ b/client/src/units/unitmarker.ts @@ -1,6 +1,6 @@ import * as L from 'leaflet' import { Symbol } from 'milsymbol' -import { getVisibilitySettings } from '..' +import { AirUnit, GroundUnit, NavyUnit, Weapon } from './unit' export interface MarkerOptions { unitName: string @@ -88,13 +88,13 @@ export class UnitMarker extends L.Marker { speedDiv.style.display = ''; /* If visibility is partial shown only icon and unit name. If none, shown only icon. */ - if (this.getVisibility() === "partial" || this.getVisibility() === "none") + if (this.getVisibility() === "partial" || this.getVisibility() === "minimal") { unitNameDiv.style.display = 'none'; altitudeDiv.style.display = 'none'; speedDiv.style.display = 'none'; } - if (this.getVisibility() === "none" && nameDiv.style.display != 'none') + if (this.getVisibility() === "minimal" && nameDiv.style.display != 'none') nameDiv.style.display = 'none'; nameDiv.style.left = (-(nameDiv.offsetWidth - container.offsetWidth) / 2) + "px"; @@ -225,15 +225,19 @@ export class UnitMarker extends L.Marker { export class AirUnitMarker extends UnitMarker { getVisibility() { - if (this.getSelected()) - return "full"; - - if (this.getHuman()) - return getVisibilitySettings().user; - else if (!this.getAlive()) - return "none"; - else - return this.getAI()? getVisibilitySettings().ai: getVisibilitySettings().uncontrolled; + if (this.getAlive()) + { + if (this.getSelected()) + return "full"; + else if (this.getHuman()) + return AirUnit.getVisibility().human; + else if (this.getAI()) + return AirUnit.getVisibility().ai; + else + return AirUnit.getVisibility().uncontrolled; + } + else + return "minimal"; } } @@ -246,38 +250,54 @@ export class HelicopterMarker extends AirUnitMarker { export class GroundUnitMarker extends UnitMarker { /* Are user driven units recognized as human? */ getVisibility() { - if (this.getSelected()) - return "full"; - - if (this.getHuman()) - return getVisibilitySettings().user; - else if (!this.getAlive()) - return "none"; - else - return this.getAI()? getVisibilitySettings().ai: getVisibilitySettings().uncontrolled; + if (this.getAlive()) + { + if (this.getSelected()) + return "full"; + else if (this.getHuman()) + return GroundUnit.getVisibility().human; + else if (this.getAI()) + return GroundUnit.getVisibility().ai; + else + return GroundUnit.getVisibility().uncontrolled; + } + else + return "minimal"; } } export class NavyUnitMarker extends UnitMarker { getVisibility() { - if (this.getSelected()) - return "full"; - - if (!this.getAlive()) - return "none"; - else - return this.getAI()? getVisibilitySettings().ai: getVisibilitySettings().uncontrolled; + if (this.getAlive()) + { + if (this.getSelected()) + return "full"; + else if (this.getHuman()) + return NavyUnit.getVisibility().human; + else if (this.getAI()) + return NavyUnit.getVisibility().ai; + else + return NavyUnit.getVisibility().uncontrolled; + } + else + return "minimal"; } } export class WeaponMarker extends UnitMarker { getVisibility() { - if (this.getSelected()) - return "full"; - - if (!this.getAlive()) - return "none"; - else - return getVisibilitySettings().weapon; + if (this.getAlive()) + { + if (this.getSelected()) + return "full"; + else if (this.getHuman()) + return Weapon.getVisibility().human; + else if (this.getAI()) + return Weapon.getVisibility().ai; + else + return Weapon.getVisibility().uncontrolled; + } + else + return "minimal"; } } \ No newline at end of file diff --git a/client/views/connectionstatuspanel.ejs b/client/views/connectionstatuspanel.ejs index 47f4636f..ad74ea88 100644 --- a/client/views/connectionstatuspanel.ejs +++ b/client/views/connectionstatuspanel.ejs @@ -1,3 +1,3 @@ -
-
Connected
+
+
Connected
\ No newline at end of file diff --git a/client/views/index.ejs b/client/views/index.ejs index 206abffe..0b5b8691 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -24,14 +24,8 @@
<%- include('selectionwheel.ejs') %> <%- include('selectionscroll.ejs') %> -
-<<<<<<< HEAD -
- <%- include('aiccontrolpanel.ejs') %> - <%- include('aicformationpanel.ejs') %> -======= - ->>>>>>> 433b4bdf569d0aca79794685ee41021190722f5b +
+ <%- include('unitinfopanel.ejs') %> <%- include('unitcontrolpanel.ejs') %> <%- include('visibilitycontrolpanel.ejs') %> diff --git a/client/views/mouseinfopanel.ejs b/client/views/mouseinfopanel.ejs index 4e6bac2c..bfa98c02 100644 --- a/client/views/mouseinfopanel.ejs +++ b/client/views/mouseinfopanel.ejs @@ -1,4 +1,4 @@ -
+
---° / --- NM
---° / --- NM
---° / --- NM
diff --git a/client/views/selectionscroll.ejs b/client/views/selectionscroll.ejs index 3a78b420..581a4f97 100644 --- a/client/views/selectionscroll.ejs +++ b/client/views/selectionscroll.ejs @@ -1,11 +1,11 @@ -
-
-
+
+
+
-
+
\ No newline at end of file diff --git a/client/views/selectionwheel.ejs b/client/views/selectionwheel.ejs index f8a149c6..bf714b7c 100644 --- a/client/views/selectionwheel.ejs +++ b/client/views/selectionwheel.ejs @@ -1,8 +1,8 @@ -
-
+
+
\ No newline at end of file diff --git a/client/views/unitcontrolpanel.ejs b/client/views/unitcontrolpanel.ejs index fba42229..b589f4ec 100644 --- a/client/views/unitcontrolpanel.ejs +++ b/client/views/unitcontrolpanel.ejs @@ -1,14 +1,14 @@ -
-
-
-
-
-
+
+
+
+
+
+
Selected units
-
+
diff --git a/client/views/unitinfopanel.ejs b/client/views/unitinfopanel.ejs index 03ffd10f..345bbd77 100644 --- a/client/views/unitinfopanel.ejs +++ b/client/views/unitinfopanel.ejs @@ -1,4 +1,4 @@ -
+
@@ -26,5 +26,8 @@
Fuel
+
+ +
\ No newline at end of file diff --git a/client/views/visibilitycontrolpanel.ejs b/client/views/visibilitycontrolpanel.ejs index 8001dd5b..861028b9 100644 --- a/client/views/visibilitycontrolpanel.ejs +++ b/client/views/visibilitycontrolpanel.ejs @@ -1,7 +1,44 @@ -
-
-
-
-
-
+
+
Air:
+
+ +
+ +
Ground:
+
+ +
+ +
Navy:
+
+ +
+ +
Weapons:
+
+ +
+ +
+ +
Full:
+
+ +
+ +
Partial:
+
+ +
+ +
Minimal:
+
+ +
+ +
+
Olympus only:
+
+ +
\ No newline at end of file diff --git a/img/icon-38x38.png b/img/icon-38x38.png new file mode 100644 index 00000000..9ddcb4b9 Binary files /dev/null and b/img/icon-38x38.png differ diff --git a/img/icon.xcf b/img/icon.xcf new file mode 100644 index 00000000..c33dd3ed Binary files /dev/null and b/img/icon.xcf differ diff --git a/img/incon_active.png b/img/incon_active.png new file mode 100644 index 00000000..3b69985d Binary files /dev/null and b/img/incon_active.png differ diff --git a/installer/DCSOlympus.iss b/installer/DCSOlympus.iss index 61c67383..479b72a5 100644 --- a/installer/DCSOlympus.iss +++ b/installer/DCSOlympus.iss @@ -2,10 +2,11 @@ [Setup] AppName=DCS Olympus -AppVerName=DCS Olympus Alpha v0.0.5 +AppVerName=DCS Olympus Alpha v0.0.7 DefaultDirName={usersavedgames}\DCS.openbeta DefaultGroupName=DCSOlympus OutputBaseFilename=DCSOlympus +UninstallFilesDir={app}\Mods\Services\Olympus [Tasks] ; NOTE: The following entry contains English phrases ("Create a desktop icon" and "Additional icons"). You are free to translate them into another language if required. @@ -15,11 +16,13 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{ [Files] ; NOTE: Don't use "Flags: ignoreversion" on any shared system files Source: "..\scripts\OlympusExport.lua"; DestDir: "{app}\Scripts"; Flags: ignoreversion +Source: "..\scripts\OlympusPatcher.exe"; DestDir: "{app}\Scripts"; Flags: ignoreversion Source: "..\scripts\OlympusHook.lua"; DestDir: "{app}\Scripts\Hooks"; Flags: ignoreversion Source: "..\scripts\OlympusCommand.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion Source: "..\scripts\unitPayloads.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion Source: "..\scripts\OlympusMission.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion Source: "..\scripts\mist_4_4_90.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion +Source: "..\mod\*.*"; DestDir: "{app}\Mods\Services\Olympus"; Flags: ignoreversion; Source: "..\bin\*.dll"; DestDir: "{app}\Mods\Services\Olympus\bin"; Flags: ignoreversion; Source: "..\client\bin\*"; DestDir: "{app}\Mods\Services\Olympus\client\bin"; Flags: ignoreversion; Source: "..\client\node_modules\*"; DestDir: "{app}\Mods\Services\Olympus\client\node_modules"; Flags: ignoreversion recursesubdirs; @@ -55,4 +58,10 @@ Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; Value ChangesEnvironment=yes [Icons] -Name: "{userdesktop}\DCS Olympus Client"; Filename: "{app}\Mods\Services\Olympus\client\nw.exe"; Tasks: desktopicon \ No newline at end of file +Name: "{userdesktop}\DCS Olympus Client"; Filename: "{app}\Mods\Services\Olympus\client\nw.exe"; Tasks: desktopicon + +[Run] +Filename: "{app}\Scripts\OlympusPatcher.exe"; Parameters: "-i" + +[UninstallRun] +Filename: "{app}\Scripts\OlympusPatcher.exe"; Parameters: "-u" \ No newline at end of file diff --git a/mod/Options/options.dlg b/mod/Options/options.dlg new file mode 100644 index 00000000..db77ba48 --- /dev/null +++ b/mod/Options/options.dlg @@ -0,0 +1,163 @@ + +-- Olympus + +-- Layout + +local TopMargin = 48 +local LeftMargin = 32 +local CenterMargin = 80 + +local LeftColumnX = LeftMargin +local LeftColumnLabelWidth = 232 +local LeftColumnOptionWidth = 272 +local LeftColumnWidth = LeftColumnLabelWidth + LeftColumnOptionWidth + +local RightColumnX = LeftColumnX + LeftColumnWidth + CenterMargin +local RightColumnLabelWidth = 192 +local RightColumnOptionWidth = 128 +local RightColumnWidth = RightColumnLabelWidth + RightColumnOptionWidth + +local LineHeight = 24 +local TotalLineHeight = LineHeight + 8 + +local HelpLineHeight = 16 + +-- Styles + +local TitleSkin = { + ["params"] = { + ["name"] = "staticOptionsTitleSkin", + }, + ["states"] = { + ["released"] = { + [1] = { + ["text"] = { + ["horzAlign"] = { + ["type"] = "min" + } + } + } + } + } + } + +local OptionLabelSkin = { + ["params"] = { + ["name"] = "staticOptionsCaptionSkin", + } + } + +local WarningSkin = { + ["params"] = { + ["name"] = "staticOptionsCaptionSkin", + }, + ["states"] = { + ["released"] = { + [1] = { + ["text"] = { + ["horzAlign"] = { + ["type"] = "min" + }, + ["color"] = "0xEFB441ff", + } + } + } + } + } + +local CheckBoxSkin = { + ["params"] = { + ["name"] = "checkBoxSkin_options", + } + } + +local ComboListSkin = { + ["params"] = { + ["name"] = "comboListSkin_options", + } + } + +local EditBoxSkin = { + ["params"] = { + ["name"] = "editBoxSkin_login", + } + } + +-- Content + +dialog = { + ["children"] = { + ["containerPlugin"] = { + ["children"] = { + + ----------------------------------------------- + -- [X] Enable Olympus Module + ----------------------------------------------- + + -- Olympus Module Enabled + + ["olympusModuleEnabledCheckbox"] = { + ["params"] = { + ["bounds"] = { + ["x"] = LeftColumnX, + ["y"] = TopMargin, + ["w"] = 256, + ["h"] = LineHeight, + }, + ["enabled"] = true, + ["state"] = false, + ["text"] = "$Olympus_MODULE_ENABLED_LABEL", + ["tooltip"] = "", + ["visible"] = true, + ["zindex"] = 0, + ["tabOrder"] = 1, + }, + ["skin"] = CheckBoxSkin, + ["type"] = "CheckBox", + }, + }, + ["params"] = { + ["bounds"] = { + ["h"] = 600, + ["w"] = 974, + ["x"] = 0, + ["y"] = 0, + }, + ["enabled"] = true, + ["text"] = "", + ["tooltip"] = "", + ["visible"] = true, + ["zindex"] = 0, + }, + ["skin"] = { + ["params"] = { + ["name"] = "panelSkin", + }, + }, + ["type"] = "Panel", + }, + }, + ["params"] = { + ["bounds"] = { + ["h"] = 851, + ["w"] = 1135, + ["x"] = 0, + ["y"] = 0, + }, + ["draggable"] = true, + ["enabled"] = true, + ["hasCursor"] = true, + ["lockFlow"] = false, + ["modal"] = false, + ["offscreen"] = false, + ["resizable"] = false, + ["text"] = "New dialog", + ["zOrder"] = 0, + }, + ["skin"] = { + ["params"] = { + ["name"] = "windowSkin", + }, + }, + ["type"] = "Window", +} \ No newline at end of file diff --git a/mod/Options/optionsData.lua b/mod/Options/optionsData.lua new file mode 100644 index 00000000..68c333d3 --- /dev/null +++ b/mod/Options/optionsData.lua @@ -0,0 +1,7 @@ +cdata = +{ + -- Module on/off + + Olympus_MODULE_ENABLED_LABEL = _("Olympus Module Enabled"), + +} diff --git a/mod/Options/optionsDb.lua b/mod/Options/optionsDb.lua new file mode 100644 index 00000000..6379b762 --- /dev/null +++ b/mod/Options/optionsDb.lua @@ -0,0 +1,60 @@ +local DbOption = require("Options.DbOption") +local i18n = require('i18n') + +-- Constants + + +-- Local variables + +local olympusConfigDialog = nil + +-- Update UI + +local function UpdateOptions() + + -- Check parameters + + if olympusConfigDialog == nil then + return + end + + local moduleEnabled = olympusConfigDialog.olympusModuleEnabledCheckbox:getState() + +end + +-- Callbacks + +local function OnShowDialog(dialogBox) + + -- Setup local variables + + if olympusConfigDialog ~= dialogBox then + olympusConfigDialog = dialogBox + end + + -- Update dialog box state + + UpdateOptions() + +end + +-- Module on/off + +local olympusModuleEnabled = DbOption.new():setValue(true):checkbox() +:callback(function(value) + UpdateOptions() +end) + +-- Returns dialog box controls and callbacks + +return +{ + -- Events + + callbackOnShowDialog = OnShowDialog, + + -- Module on/off + + olympusModuleEnabled = olympusModuleEnabled, + +} diff --git a/mod/Theme/icon-38x38.png b/mod/Theme/icon-38x38.png new file mode 100644 index 00000000..9ddcb4b9 Binary files /dev/null and b/mod/Theme/icon-38x38.png differ diff --git a/mod/Theme/icon.png b/mod/Theme/icon.png new file mode 100644 index 00000000..d4b60c09 Binary files /dev/null and b/mod/Theme/icon.png differ diff --git a/mod/Theme/icon_active.png b/mod/Theme/icon_active.png new file mode 100644 index 00000000..3b69985d Binary files /dev/null and b/mod/Theme/icon_active.png differ diff --git a/mod/Theme/icon_select.png b/mod/Theme/icon_select.png new file mode 100644 index 00000000..3b69985d Binary files /dev/null and b/mod/Theme/icon_select.png differ diff --git a/mod/entry.lua b/mod/entry.lua new file mode 100644 index 00000000..4cd8d578 --- /dev/null +++ b/mod/entry.lua @@ -0,0 +1,42 @@ +local self_ID = "DCS-Olympus" + +declare_plugin(self_ID, +{ + image = "Olympus.png", + installed = true, -- if false that will be place holder , or advertising + dirName = current_mod_path, + binaries = + { +-- 'Olympus', + }, + load_immediately = true, + + displayName = "Olympus", + shortName = "Olympus", + fileMenuName = "Olympus", + + version = "0.0.7", + state = "installed", + developerName= "DCS Refugees 767 squadron", + info = _("DCS Olympus is a mod for DCS World. It allows users to spawn, control, task, group, and remove units from a DCS World server using a real-time map interface, similarly to Real Time Strategy games. The user interface also provides useful informations units, like loadouts, fuel, tasking, and so on. In the future, more features for DCS World GCI and JTAC will be available."), + + Skins = + { + { + name = "Olympus", + dir = "Theme" + }, + }, + + Options = + { + { + name = "Olympus", + nameId = "Olympus", + dir = "Options", + CLSID = "{Olympus-options}" + }, + }, +}) + +plugin_done() \ No newline at end of file diff --git a/scripts/Export.lua b/scripts/Export.lua deleted file mode 100644 index f60c236d..00000000 --- a/scripts/Export.lua +++ /dev/null @@ -1 +0,0 @@ -local Olympuslfs=require('lfs');dofile(Olympuslfs.writedir()..'Scripts/OlympusExport.lua') diff --git a/scripts/OlympusCommand.lua b/scripts/OlympusCommand.lua index 6f45160f..65a58eed 100644 --- a/scripts/OlympusCommand.lua +++ b/scripts/OlympusCommand.lua @@ -137,7 +137,7 @@ function Olympus.move(ID, lat, lng, altitude, speed, category, taskOptions) Olympus.notify("Olympus.move not implemented yet for " .. category, 2) end else - Olympus.notify("Error in Olympus.move " .. unitName, 2) + Olympus.notify("Error in Olympus.move " .. ID, 2) end end diff --git a/scripts/OlympusPatcher.exe b/scripts/OlympusPatcher.exe new file mode 100644 index 00000000..ee35a74d Binary files /dev/null and b/scripts/OlympusPatcher.exe differ diff --git a/scripts/OlympusPatcher.py b/scripts/OlympusPatcher.py new file mode 100644 index 00000000..bcfc1ce1 --- /dev/null +++ b/scripts/OlympusPatcher.py @@ -0,0 +1,42 @@ +import shutil +import sys + +START_STRING = "/* Olympus START */\n" +END_STRING = "/* Olympus END */\n" +EXPORT_STRING = "local Olympuslfs=require('lfs');dofile(Olympuslfs.writedir()..'Scripts/OlympusExport.lua')\n" + +def main(flag): + if flag == "-i": + try: + with open("Export.lua", "r") as f: + shutil.copyfile("Export.lua", "Export.lua.bak") + lines = f.readlines() + if START_STRING in lines: + return + except FileNotFoundError: + print('File does not exist') + + with open("Export.lua", "a") as f: + f.writelines(["\n", START_STRING, EXPORT_STRING, END_STRING, "\n"]) + elif flag == "-u": + try: + with open("Export.lua", "r") as f: + shutil.copyfile("Export.lua", "Export.lua.bak") + lines = f.readlines() + except FileNotFoundError: + print('File does not exist') + + with open("Export.lua", "w") as f: + block = False + for line in lines: + if line == START_STRING: + block = True + + if not block: + f.write(line) + + if line == END_STRING: + block = False + +if __name__ == "__main__": + main(sys.argv[1]) diff --git a/src/core/include/Scheduler.h b/src/core/include/Scheduler.h index a7f1210f..68792841 100644 --- a/src/core/include/Scheduler.h +++ b/src/core/include/Scheduler.h @@ -13,9 +13,7 @@ public: void execute(lua_State* L); void handleRequest(wstring key, json::value value); - private: list commands; - mutex mutexLock; }; diff --git a/src/core/include/Unit.h b/src/core/include/Unit.h index 3b99897b..4b0a30b2 100644 --- a/src/core/include/Unit.h +++ b/src/core/include/Unit.h @@ -105,9 +105,6 @@ protected: Coords oldPosition = Coords(0); // Used to approximate speed virtual void AIloop() = 0; - -private: - mutex mutexLock; }; diff --git a/src/core/src/Scheduler.cpp b/src/core/src/Scheduler.cpp index 119c9f87..d855dbfa 100644 --- a/src/core/src/Scheduler.cpp +++ b/src/core/src/Scheduler.cpp @@ -24,8 +24,6 @@ void Scheduler::appendCommand(Command* command) void Scheduler::execute(lua_State* L) { - /* Lock for thread safety */ - lock_guard guard(mutexLock); int priority = CommandPriority::HIGH; while (priority >= CommandPriority::LOW) { @@ -51,8 +49,6 @@ void Scheduler::execute(lua_State* L) void Scheduler::handleRequest(wstring key, json::value value) { - /* Lock for thread safety */ - lock_guard guard(mutexLock); Command* command = nullptr; log(L"Received request with ID: " + key); diff --git a/src/core/src/Unit.cpp b/src/core/src/Unit.cpp index 86f4c36d..5b814869 100644 --- a/src/core/src/Unit.cpp +++ b/src/core/src/Unit.cpp @@ -25,9 +25,6 @@ Unit::~Unit() void Unit::updateExportData(json::value json) { - /* Lock for thread safety */ - lock_guard guard(mutexLock); - /* Compute speed (loGetWorldObjects does not provide speed, we compute it for better performance instead of relying on many lua calls) */ if (oldPosition != NULL) { @@ -77,11 +74,8 @@ void Unit::updateExportData(json::value json) void Unit::updateMissionData(json::value json) { - /* Lock for thread safety */ - lock_guard guard(mutexLock); - if (json.has_number_field(L"fuel")) - fuel = json[L"fuel"].as_number().to_int32(); + fuel = int(json[L"fuel"].as_number().to_double() * 100); if (json.has_object_field(L"ammo")) ammo = json[L"ammo"]; if (json.has_object_field(L"targets")) @@ -92,9 +86,6 @@ void Unit::updateMissionData(json::value json) json::value Unit::json() { - /* Lock for thread safety */ - lock_guard guard(mutexLock); - auto json = json::value::object(); json[L"alive"] = alive; diff --git a/src/core/src/core.cpp b/src/core/src/core.cpp index 24849509..cd2740e1 100644 --- a/src/core/src/core.cpp +++ b/src/core/src/core.cpp @@ -13,11 +13,15 @@ Server* server = nullptr; Scheduler* scheduler = nullptr; json::value airbasesData; json::value bullseyeData; - +mutex mutexLock; +bool initialized = false; /* Called when DCS simulation stops. All singleton instances are deleted. */ extern "C" DllExport int coreDeinit(lua_State* L) { + if (!initialized) + return (0); + log("Olympus coreDeinit called successfully"); delete unitsFactory; @@ -38,11 +42,18 @@ extern "C" DllExport int coreInit(lua_State* L) registerLuaFunctions(L); + initialized = true; return(0); } extern "C" DllExport int coreFrame(lua_State* L) { + if (!initialized) + return (0); + + /* Lock for thread safety */ + lock_guard guard(mutexLock); + const std::chrono::duration duration = std::chrono::system_clock::now() - before; // TODO make intervals editable @@ -65,6 +76,12 @@ extern "C" DllExport int coreFrame(lua_State* L) extern "C" DllExport int coreMissionData(lua_State * L) { + if (!initialized) + return (0); + + /* Lock for thread safety */ + lock_guard guard(mutexLock); + lua_getglobal(L, "Olympus"); lua_getfield(L, -1, "missionData"); json::value missionData = luaTableToJSON(L, -1); diff --git a/src/core/src/server.cpp b/src/core/src/server.cpp index f70ff8c5..a33e4eab 100644 --- a/src/core/src/server.cpp +++ b/src/core/src/server.cpp @@ -11,6 +11,7 @@ extern UnitsFactory* unitsFactory; extern Scheduler* scheduler; extern json::value airbasesData; extern json::value bullseyeData; +extern mutex mutexLock; void handle_eptr(std::exception_ptr eptr) { @@ -49,6 +50,9 @@ void Server::handle_options(http_request request) void Server::handle_get(http_request request) { + /* Lock for thread safety */ + lock_guard guard(mutexLock); + http_response response(status_codes::OK); response.headers().add(U("Allow"), U("GET, POST, PUT, OPTIONS")); response.headers().add(U("Access-Control-Allow-Origin"), U("*")); @@ -107,6 +111,9 @@ void Server::handle_put(http_request request) request, [](json::value const& jvalue, json::value& answer) { + /* Lock for thread safety */ + lock_guard guard(mutexLock); + for (auto const& e : jvalue.as_object()) { auto key = e.first;