diff --git a/package-lock.json b/package-lock.json index 41232be..76850fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,170 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@firebase/app": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.3.4.tgz", + "integrity": "sha512-Q6sNpWZ3x+FeuBkLCCRrsOraGJOKVLUCc9Amj8zu2vAC1v2uWifRR6kZ60TrpaIxtY4N6pcPTaG0YIUT5lgeSA==", + "requires": { + "@firebase/app-types": "0.3.2", + "@firebase/util": "0.2.2", + "dom-storage": "2.1.0", + "tslib": "1.9.0", + "xmlhttprequest": "1.8.0" + } + }, + "@firebase/app-types": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.3.2.tgz", + "integrity": "sha512-ZD8lTgW07NGgo75bTyBJA8Lt9+NweNzot7lrsBtIvfciwUzaFJLsv2EShqjBeuhF7RpG6YFucJ6m67w5buCtzw==" + }, + "@firebase/auth": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.7.9.tgz", + "integrity": "sha512-m8e2KZ/WvToTMovoBI5K3N0Ku8Aqt6083oqzQODUYHjf94KsAfGdoQEaJono7T7vK4o7E5xpqFgFldOM5LdgiQ==", + "requires": { + "@firebase/auth-types": "0.3.4" + } + }, + "@firebase/auth-types": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.3.4.tgz", + "integrity": "sha512-0r3gSQk9jw5orFHCTUIgao0zan6dHt2J0BO3t/uEzbod+uwqvUn/gh+yg+kK6HX92Fg8E7y030KX4Bw/aXt0Ew==" + }, + "@firebase/database": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.3.6.tgz", + "integrity": "sha512-r02JOqTLcd2/qn7QkkJvIAxMiMxmeyd5B76kl9hHAs+3cil5mUzHnI3svtb4h0VIJYDHFKJMlVl/bE3GfcTR3A==", + "requires": { + "@firebase/database-types": "0.3.2", + "@firebase/logger": "0.1.1", + "@firebase/util": "0.2.2", + "faye-websocket": "0.11.1", + "tslib": "1.9.0" + }, + "dependencies": { + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "@firebase/database-types": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.3.2.tgz", + "integrity": "sha512-9ZYdvYQ6r3aaHJarhUM5Hf6lQWu3ZJme+RR0o8qfBb9L04TL3uNjt+AJFku1ysVPntTn+9GqJjiIB2/OC3JtwA==" + }, + "@firebase/firestore": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-0.8.7.tgz", + "integrity": "sha512-FdC8YKryht2Rp2CHguendS8VelP83MDY5p7EKBTlxPPZV7yb5Vt+cmLR6AG7TR+FsBzvdOUpbOEnAErUVgZAFQ==", + "requires": { + "@firebase/firestore-types": "0.7.0", + "@firebase/logger": "0.1.1", + "@firebase/webchannel-wrapper": "0.2.11", + "grpc": "1.16.0", + "tslib": "1.9.0" + } + }, + "@firebase/firestore-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-0.7.0.tgz", + "integrity": "sha512-jyKRcKnSh3CSEPL4xGOZNoOXEiv7YmFK/JEcdd/4cAH17/Xo+Pk67gk1E648LRKh6QPghgNvzNTY5R10mKbQNw==" + }, + "@firebase/functions": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.3.2.tgz", + "integrity": "sha512-jZdNzNrJplswIJXcdpXZr6vEbDrDKU4P0+nHv/D85LHeHnPkkdNO+Yh3tikbVEJpYCG8EVOhIEfAIEuFo37i4A==", + "requires": { + "@firebase/functions-types": "0.2.1", + "@firebase/messaging-types": "0.2.3", + "isomorphic-fetch": "2.2.1", + "tslib": "1.9.0" + } + }, + "@firebase/functions-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.2.1.tgz", + "integrity": "sha512-hH78lgDoa5E1peBSXnfQyshENmh/5a8aia+S4Ocjc53OUWRJ4VqYwWUV5gE4b2mqVKTpN4akJccLq2pCnNGZcA==" + }, + "@firebase/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-5jn3HHbEfdOwychyIEIkP1cik+MW/vvoOavTOzwDkH+fv6Bx+HBUOzh09M7sCYzXFtKzjbUax9+g39mJNBLklQ==" + }, + "@firebase/messaging": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.3.6.tgz", + "integrity": "sha512-Sz/fWOXMa3HxDZxE64Fm335kwP9um1rmun5PIka7od7I4hZ8US+SjYVyUe6jWTh1V/YjcqDi6Xkhoj2nF8yu9g==", + "requires": { + "@firebase/messaging-types": "0.2.3", + "@firebase/util": "0.2.2", + "tslib": "1.9.0" + } + }, + "@firebase/messaging-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.2.3.tgz", + "integrity": "sha512-avwCgZzcx2uxIW/wT3p3G/EyHftIrvMyiTS7AA7dxDlzfx+8dpAeTsb1+jsHJT4F6foSh5HG17Nw8sDzYuxH1Q==" + }, + "@firebase/polyfill": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.3.tgz", + "integrity": "sha512-xs8IZf1WEbufYXyfV8YjmiFZOaujRRq0T03NteihYfuGVTTym7z5SmvLvEHLEUjf2fgeobPEzZ2JgrCQHS+QHw==", + "requires": { + "core-js": "2.5.5", + "promise-polyfill": "7.1.2", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "core-js": { + "version": "2.5.5", + "resolved": "http://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=" + }, + "promise-polyfill": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.2.tgz", + "integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ==" + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "@firebase/storage": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.2.4.tgz", + "integrity": "sha512-uqA6CoZYkugk69ImqB16VBPP7JRPRfZwcUP9CsE0GPVGQkZQQfBGwzIyEoFA8lUfVLrvxQiL0sQvHUXZ945LMg==", + "requires": { + "@firebase/storage-types": "0.2.3", + "tslib": "1.9.0" + } + }, + "@firebase/storage-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.2.3.tgz", + "integrity": "sha512-RaZeam2LgsB7xwAtOQr4G0Geoyf7D5TnLF3a12By6Rh0Z9PqBSlWn0SVYGW3SkmxIdqvWZMZvCyamUlqQvQzWw==" + }, + "@firebase/util": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.2.tgz", + "integrity": "sha512-vfRjmCWuxtJx3txHocaNlDwCDwwv6KLL5YtlSNi73wBdvF3UfnpLGrth7G3X6gn5rDhOKamRg2+9L8cfsjSS1A==", + "requires": { + "tslib": "1.9.0" + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.11.tgz", + "integrity": "sha512-WyMXDxk/WZ+f2lOCeEvDWUce2f5Kk2sNfvArK8f+PlUnzFdy/MBzLXrmbMgyZXP7GP4ooUxYV8Sdmoh1hGk1Uw==" + }, "@tweenjs/tween.js": { "version": "16.11.0", "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-16.11.0.tgz", @@ -208,6 +372,7 @@ "sinon": "^1.17.5", "sinon-chai": "^2.8.0", "snazzy": "^4.0.0", + "uglify-js": "git://github.com/mishoo/UglifyJS2.git#278577f3cb75e72320564805ee91be63e5f9c806", "uglifyjs-webpack-plugin": "^0.4.6", "webpack": "^3.5.5", "webpack-cli": "^3.1.2", @@ -1037,7 +1202,7 @@ }, "uglify-js": { "version": "git://github.com/mishoo/UglifyJS2.git#278577f3cb75e72320564805ee91be63e5f9c806", - "from": "git://github.com/mishoo/UglifyJS2.git#278577f3cb75e72320564805ee91be63e5f9c806", + "from": "git://github.com/mishoo/UglifyJS2.git#harmony-v2.8.22", "requires": { "source-map": "~0.5.1", "uglify-to-browserify": "~1.0.0", @@ -1627,6 +1792,15 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, + "ascli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", + "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "requires": { + "colour": "~0.7.1", + "optjs": "~3.2.2" + } + }, "asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -3461,6 +3635,14 @@ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, + "bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "requires": { + "long": "~3" + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -3801,6 +3983,11 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" }, + "colour": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", + "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" + }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -4759,6 +4946,11 @@ "version": "github:dmarcos/document-register-element#8ccc532b7f3744be954574caf3072a5fd260ca90", "from": "github:dmarcos/document-register-element#8ccc532b7" }, + "dom-storage": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz", + "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==" + }, "dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", @@ -4872,6 +5064,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, "enhanced-resolve": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", @@ -5674,6 +5874,21 @@ "resolve-dir": "^0.1.0" } }, + "firebase": { + "version": "5.5.8", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-5.5.8.tgz", + "integrity": "sha512-aT75TO8JLX2bTsPLq/2FrX87sgsvSF7mFDJBKl+hC5yJeaT3fuqrn806lQ56TRGWXFi5oYENYn00hmy/4PR0AQ==", + "requires": { + "@firebase/app": "0.3.4", + "@firebase/auth": "0.7.9", + "@firebase/database": "0.3.6", + "@firebase/firestore": "0.8.7", + "@firebase/functions": "0.3.2", + "@firebase/messaging": "0.3.6", + "@firebase/polyfill": "0.3.3", + "@firebase/storage": "0.2.4" + } + }, "flat-cache": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", @@ -5889,13 +6104,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5908,18 +6121,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -6022,8 +6232,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -6033,7 +6242,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6046,20 +6254,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.2.4", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6076,7 +6281,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6149,8 +6353,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -6160,7 +6363,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6266,7 +6468,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6619,6 +6820,427 @@ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, + "grpc": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.16.0.tgz", + "integrity": "sha512-+p8YRIng7Gihkn2jycAXwXdA9aQ10SikRrcHY+/r3W1Z1Pr9NFIbLcmBZPoaTbzzLDv/ysqwqFEZriAdd8tveQ==", + "requires": { + "lodash": "^4.17.5", + "nan": "^2.0.0", + "node-pre-gyp": "^0.10.0", + "protobufjs": "^5.0.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.23", + "bundled": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "minipass": { + "version": "2.3.3", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "ms": { + "version": "2.0.0", + "bundled": true + }, + "needle": { + "version": "2.2.2", + "bundled": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true + }, + "npm-packlist": { + "version": "1.1.11", + "bundled": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "sax": { + "version": "1.2.4", + "bundled": true + }, + "semver": { + "version": "5.5.0", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + }, + "tar": { + "version": "4.4.6", + "bundled": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.3", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true + } + } + }, "handle-thing": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", @@ -7549,6 +8171,15 @@ } } }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, "js-base64": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz", @@ -7870,6 +8501,11 @@ "resolved": "http://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=" }, + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -8331,8 +8967,7 @@ "nan": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==", - "optional": true + "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" }, "nanomatch": { "version": "1.2.13", @@ -8431,6 +9066,15 @@ "lower-case": "^1.1.1" } }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", @@ -8764,6 +9408,11 @@ } } }, + "optjs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", + "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" + }, "original": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz", @@ -10948,6 +11597,32 @@ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" }, + "protobufjs": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", + "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", + "requires": { + "ascli": "~1", + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "protochain": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/protochain/-/protochain-1.0.5.tgz", @@ -13729,6 +14404,11 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, + "tslib": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==" + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -15241,6 +15921,11 @@ "resolved": "https://registry.npmjs.org/webvr-polyfill-dpdb/-/webvr-polyfill-dpdb-1.0.9.tgz", "integrity": "sha512-4Vc4SVqztKZHjRDyivtAnQMpGKbzhC6pgYt6qN4JYWjvK4p47xGu4y/8oogP2Qri1SamLyGeLd6szLu2Dt4SWg==" }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -15350,6 +16035,11 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "xregexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", diff --git a/package.json b/package.json index 77e583f..e8de423 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "body-parser": "1.18.2", "classnames": "^2.2.5", "css-loader": "^0.28.7", + "firebase": "^5.5.8", "html-entities": "^1.2.1", "html-minifier": "^3.5.11", "ip": "1.1.5", diff --git a/src/components/keyboard-raycastable.js b/src/components/keyboard-raycastable.js index b1482fd..38db1c3 100644 --- a/src/components/keyboard-raycastable.js +++ b/src/components/keyboard-raycastable.js @@ -1,8 +1,12 @@ AFRAME.registerComponent('keyboard-raycastable', { dependencies: ['super-keyboard'], + schema: { + condition: {default: ''} + }, + play: function () { this.el.components['super-keyboard'].kbImg.setAttribute('bind-toggle__raycastable', - 'isSearching'); + this.data.condition); } }); diff --git a/src/components/leaderboard.js b/src/components/leaderboard.js new file mode 100644 index 0000000..6dcdd3c --- /dev/null +++ b/src/components/leaderboard.js @@ -0,0 +1,142 @@ +const firebase = require('firebase/app'); +require('firebase/firestore'); + +const NUM_SCORES_DISPLAYED = 10; + +/** + * High score with Firebase cloud store. + * Index: challengeId ASC difficulty ASC score DESC time ASC + */ +AFRAME.registerComponent('leaderboard', { + schema: { + apiKey: {type: 'string'}, + authDomain: {type: 'string'}, + databaseURL: {type: 'string'}, + projectId: {type: 'string'}, + storageBucket: {type: 'string'}, + messagingSenderId: {type: 'string'}, + + challengeId: {default: ''}, + menuSelectedChallengeId: {default: ''}, + isVictory: {default: false} + }, + + init: function () { + this.qualifyingIndex = undefined; + this.scores = []; + this.eventDetail = {scores: this.scores}; + this.addEventDetail = {scoreData: undefined, index: undefined}; + + this.username = localStorage.getItem('supersaberusername') || 'Super Zealot'; + this.el.addEventListener('leaderboardusername', evt => { + this.username = evt.detail.value; + localStorage.setItem('supersaberusername', this.username); + }); + this.el.addEventListener('leaderboardsubmit', this.addScore.bind(this)); + }, + + update: function (oldData) { + // Initialize Cloud Firestore through Firebase. + if (!firebase.apps.length && this.data.apiKey) { + firebase.initializeApp({ + apiKey: this.data.apiKey, + authDomain: this.data.authDomain, + databaseURL: this.data.databaseURL, + projectId: this.data.projectId, + storageBucket: this.data.storageBucket, + messagingSenderId: this.data.messagingSenderId + }); + this.firestore = firebase.firestore(); + this.firestore.settings({timestampsInSnapshots: true}); + this.db = this.firestore.collection('scores'); + } + + if (!oldData.isVictory && this.data.isVictory) { + this.checkLeaderboardQualify(); + } + + if (oldData.menuSelectedChallengeId !== this.data.menuSelectedChallengeId) { + this.fetchScores(this.data.menuSelectedChallengeId); + } + + if (oldData.challengeId !== this.data.challengeId) { + this.fetchScores(this.data.challengeId); + } + }, + + addScore: function () { + const state = this.el.sceneEl.systems.state.state; + if (!state.isVictory) { return; } + const scoreData = { + challengeId: state.challenge.id, + score: state.score.score, + username: this.username, + difficulty: state.challenge.difficulty, + time: new Date() + }; + this.db.add(scoreData); + this.addEventDetail.scoreData = scoreData; + this.el.emit('leaderboardscoreadded', this.addEventDetail, false); + }, + + fetchScores: function (challengeId) { + const state = this.el.sceneEl.systems.state.state; + const query = this.db + .where('challengeId', '==', challengeId) + .where( + 'difficulty', '==', + state.menuSelectedChallenge.id + ? state.menuSelectedChallenge.difficulty + : state.challenge.difficulty) + .orderBy('score', 'desc') + .orderBy('time', 'asc') + .limit(10); + query.get().then(snapshot => { + this.eventDetail.challengeId = challengeId; + this.scores.length = 0; + if (!snapshot.empty) { + snapshot.forEach(score => this.scores.push(score.data())); + } + this.el.sceneEl.emit('leaderboard', this.eventDetail, false); + }).catch(e => { + console.error('[firestore]', e); + }); + }, + + /** + * Is high score? + */ + checkLeaderboardQualify: function () { + const state = this.el.sceneEl.systems.state.state; + const score = state.score.score; + + // If less than 10, then automatic high score. + if (this.scores.length < NUM_SCORES_DISPLAYED) { + this.qualifyingIndex = this.scores.length; + this.el.sceneEl.emit('leaderboardqualify', this.scores.length, false); + return; + } + + // Check if overtook any existing high score. + for (let i = 0; i < this.scores.length; i++) { + if (score > this.scores[i].score) { + this.qualifyingIndex = i; + this.el.sceneEl.emit('leaderboardqualify', i, false); + return; + } + } + } +}); + +AFRAME.registerComponent('leaderboard-title', { + schema: { + leaderboardQualified: {default: false} + }, + + update: function () { + const value = this.data.leaderboardQualified + ? 'NEW HIGH SCORE' + : 'LEADERBOARD'; + this.el.setAttribute('text', 'value', value); + } +}); diff --git a/src/components/search.js b/src/components/search.js index e260390..a8ac515 100644 --- a/src/components/search.js +++ b/src/components/search.js @@ -24,6 +24,7 @@ AFRAME.registerComponent('search', { }, superkeyboardchange: bindEvent(function (evt) { + if (evt.target !== this.el) { return; } this.search(evt.detail.value); }), diff --git a/src/components/visible-raycastable.js b/src/components/visible-raycastable.js new file mode 100644 index 0000000..0ddb040 --- /dev/null +++ b/src/components/visible-raycastable.js @@ -0,0 +1,17 @@ +/** + * Couple visibility and raycastability. + */ +AFRAME.registerComponent('visible-raycastable', { + schema: { + default: true + }, + + update: function () { + this.el.object3D.visible = this.data; + if (this.data) { + this.el.setAttribute('raycastable', ''); + } else { + this.el.removeAttribute('raycastable', ''); + } + } +}); diff --git a/src/index.html b/src/index.html index 08c2ac0..9b941cb 100644 --- a/src/index.html +++ b/src/index.html @@ -21,6 +21,7 @@ bind__beat-loader="challengeId: challenge.id; difficulty: menuSelectedChallenge.difficulty; isPlaying: isPlaying; menuSelectedChallengeId: menuSelectedChallenge.id" bind__gameover="isGameOver: isGameOver" bind__intro-song="isPlaying: menuActive && !menuSelectedChallenge.id; isSearching: isSearching" + bind__leaderboard="isVictory: isVictory; menuSelectedChallengeId: menuSelectedChallenge.id; challengeId: challenge.id" bind__overlay="enabled: !isPlaying" bind__song="challengeId: challenge.id; isPlaying: isPlaying; isBeatsPreloaded: challenge.isBeatsPreloaded; isGameOver: isGameOver; isVictory: isVictory" bind__song-preview-system="challengeId: challenge.id; isSearching: isSearching; isSongLoading: isSongLoading; selectedChallengeId: menuSelectedChallenge.id" @@ -33,6 +34,7 @@ debug-state effect-bloom="strength: 1" gpu-preloader + leaderboard="apiKey: AIzaSyBCnpzND3eN37CBSu1bSYfaKQoe6yD3SnY; authDomain: supersaberrr.firebaseapp.com; databaseURL: https://supersaberrr.firebaseio.com; projectId: supersaberrr; storageBucket: supersaberrr.appspot.com; messagingSenderId: 172125624222" loading-screen="backgroundColor: #000;" overlay="objects: .overlay" pool__beat-arrow-blue="mixin: arrowBlueBeat; size: 10; container: #beatContainer" @@ -74,6 +76,7 @@ {% include './templates/tutorial.html' %} {% include './templates/gameMenu.html' %} {% include './templates/victory.html' %} + {% include './templates/leaderboard.html' %} diff --git a/src/state/index.js b/src/state/index.js index 4953f35..c678e68 100644 --- a/src/state/index.js +++ b/src/state/index.js @@ -2,6 +2,7 @@ var utils = require('../utils'); const challengeDataStore = {}; +const NUM_LEADERBOARD_DISPLAY = 10; const SEARCH_PER_PAGE = 6; const SONG_NAME_TRUNCATE = 24; const SONG_SUB_NAME_TRUNCATE = 32; @@ -11,8 +12,8 @@ const DAMAGE_MAX = 10; const DEBUG_CHALLENGE = { author: 'Superman', - difficulty: 'Normal', - id: '517', + difficulty: 'Expert', + id: '31', image: 'assets/img/molerat.jpg', songName: 'Friday', songLength: 100, @@ -57,6 +58,10 @@ AFRAME.registerState({ isSongFetching: false, // Fetching stage. isSongLoading: false, // Either fetching or decoding. isVictory: false, // Victory screen. + leaderboard: [], + leaderboardFetched: false, + leaderboardQualified: false, + leaderboardText: '', menuActive: true, // Main menu active. menuDifficulties: [], // List of strings of available difficulties for selected. menuSelectedChallenge: { // Currently selected challenge in the main menu. @@ -207,6 +212,7 @@ AFRAME.registerState({ Object.assign(state.menuSelectedChallenge, DEBUG_CHALLENGE); Object.assign(state.challenge, DEBUG_CHALLENGE); state.isVictory = true; + state.leaderboardQualified = true; state.menuActive = false; state.score.accuracy = 74.99; state.score.beatsHit = 125; @@ -228,6 +234,7 @@ AFRAME.registerState({ state.isPaused = false; state.isSongLoading = true; state.isVictory = false; + state.leaderboardQualified = false; }, gamemenuexit: (state) => { @@ -238,6 +245,7 @@ AFRAME.registerState({ state.isVictory = false; state.menuActive = true; state.challenge.id = ''; + state.leaderboardQualified = false; }, genreclear: (state) => { @@ -261,6 +269,40 @@ AFRAME.registerState({ state.menuSelectedChallenge.id = ''; }, + /** + * High scores. + */ + leaderboard: (state, payload) => { + state.leaderboard.length = 0; + state.leaderboardFetched = true; + state.leaderboardText = ''; + for (let i = 0; i < payload.scores.length; i++) { + let score = payload.scores[i]; + state.leaderboard.push(score); + state.leaderboardText += `${score.username}\t${score.score}\n`; + } + }, + + leaderboardqualify: state => { + state.leaderboardQualified = true; + }, + + /** + * Insert new score into leaderboard locally. + */ + leaderboardscoreadded: (state, payload) => { + state.leaderboard.splice(payload.index, 0, payload.scoreData); + state.leaderboardText = ''; + for (let i = 0; i < NUM_LEADERBOARD_DISPLAY; i++) { + let score = state.leaderboard[i]; + state.leaderboardText += `${score.username}\t${score.score}\n`; + } + }, + + leaderboardsubmit: state => { + state.leaderboardQualified = false; + }, + /** * Song clicked from menu. */ @@ -284,14 +326,18 @@ AFRAME.registerState({ computeMenuSelectedChallengeIndex(state); state.isSearching = false; + + clearLeaderboard(state); }, menuchallengeunselect: state => { state.menuSelectedChallenge.id = ''; + clearLeaderboard(state); }, menudifficultyselect: (state, difficulty) => { state.menuSelectedChallenge.difficulty = difficulty; + clearLeaderboard(state); }, minehit: state => { @@ -551,3 +597,10 @@ function computeBeatsText (state) { state.score.beatsText = `${state.score.beatsHit} / ${state.score.beatsMissed + state.score.beatsHit} BEATS`; } + +function clearLeaderboard (state) { + state.leaderboard.length = 0; + state.leaderboard.__dirty = true; + state.leaderboardText = ''; + state.leaderboardFetched = false; +} diff --git a/src/templates/leaderboard.html b/src/templates/leaderboard.html new file mode 100644 index 0000000..bc9d64e --- /dev/null +++ b/src/templates/leaderboard.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/templates/menu.html b/src/templates/menu.html index c41932f..f5090b0 100644 --- a/src/templates/menu.html +++ b/src/templates/menu.html @@ -303,7 +303,7 @@ bind__super-keyboard="{% if not DEBUG_KEYBOARD %}hand: activeHand === 'left' && '#leftHand' || '#rightHand'; {% endif %}show: isSearching" super-keyboard="label: Search from over 6000 songs!; inputColor: #fff; labelColor: #FFF; width: 1.2; hand: {{ DEBUG_KEYBOARD and '#mouseCursor' or '#rightHand' }}; imagePath: assets/img/keyboard/; font: assets/fonts/Teko-Bold.json; align: center; model: supersaber; keyColor: #fff; injectToRaycasterObjects: false; filters: allupper; keyHoverColor: #fff" position="0.6 1.1 -1.999" - keyboard-raycastable + keyboard-raycastable="condition: isSearching" search proxy-event__dismiss="event: superkeyboarddismiss; to: a-scene; as: keyboardclose" proxy-event__accept="event: superkeyboardinput; to: a-scene; as: keyboardclose">