copy project from trumped.com, removing animation/pixi.js

This commit is contained in:
Brandon Thomas committed 2020-06-14 18:25:35 -04:00
1 parent 8537e44ead
commit 1cafead159
17 files changed
+1703 -27

No files matched your search

+644 -3
View File
@@ -1656,6 +1656,11 @@
"@types/node": "*"
}
},
"@types/howler": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@types/howler/-/howler-2.1.2.tgz",
"integrity": "sha512-gK7snhJcWVvTdiE6cCBAjeZ9od9Q8LmB5lEyB/3n6jMJOLn7EQ8Zvmkz8XPhnN5xB+b7QzCiqxJY3YiHrM3Jpg=="
},
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -2072,6 +2077,11 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
"integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg=="
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -2194,6 +2204,11 @@
"resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM="
},
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
},
"ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@@ -2246,6 +2261,39 @@
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"are-we-there-yet": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"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"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -2288,6 +2336,11 @@
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
},
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
},
"array-flatten": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
@@ -2406,6 +2459,11 @@
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
"integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
},
"async-foreach": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
@@ -2985,6 +3043,14 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
"integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow=="
},
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
"requires": {
"inherits": "~2.0.0"
}
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -3342,6 +3408,22 @@
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"camelcase-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"requires": {
"camelcase": "^2.0.0",
"map-obj": "^1.0.0"
},
"dependencies": {
"camelcase": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
}
}
},
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -3764,6 +3846,11 @@
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
"integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
"constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@@ -4213,6 +4300,14 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
"integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
},
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
"requires": {
"array-find-index": "^1.0.1"
}
},
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
@@ -4407,6 +4502,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -5958,6 +6058,17 @@
"integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
"optional": true
},
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@@ -5968,6 +6079,62 @@
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
},
"gauge": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"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"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
}
}
},
"gaze": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
"integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
"requires": {
"globule": "^1.0.0"
}
},
"gensync": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@@ -5983,6 +6150,11 @@
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
"integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g=="
},
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -6086,6 +6258,16 @@
}
}
},
"globule": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz",
"integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==",
"requires": {
"glob": "~7.1.1",
"lodash": "~4.17.10",
"minimatch": "~3.0.2"
}
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -6169,6 +6351,11 @@
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
"has-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -6249,6 +6436,11 @@
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
},
"howler": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/howler/-/howler-2.2.0.tgz",
"integrity": "sha512-sGPkrAQy7jh5mNDbkRNG0F82R2HFDYNsQXBcX4smXQT0y0F4UMsa/+jXaGwWvcrajWr2tDB7JUkH7G5qSnuIyQ=="
},
"hpack.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@@ -6530,6 +6722,11 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
},
"in-publish": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
"integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ=="
},
"indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
@@ -6797,6 +6994,11 @@
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-finite": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
"integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -6916,6 +7118,11 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"is-utf8": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
},
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -7237,7 +7444,10 @@
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true
"optional": true,
"requires": {
"nan": "^2.12.1"
}
}
}
},
@@ -7534,6 +7744,11 @@
}
}
},
"js-base64": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
"integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7895,6 +8110,15 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"loud-rejection": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
"integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
"requires": {
"currently-unhandled": "^0.4.1",
"signal-exit": "^3.0.0"
}
},
"lower-case": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz",
@@ -7965,6 +8189,11 @@
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
},
"map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
},
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -8036,6 +8265,129 @@
}
}
},
"meow": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"requires": {
"camelcase-keys": "^2.0.0",
"decamelize": "^1.1.2",
"loud-rejection": "^1.0.0",
"map-obj": "^1.0.1",
"minimist": "^1.1.3",
"normalize-package-data": "^2.3.4",
"object-assign": "^4.0.1",
"read-pkg-up": "^1.0.1",
"redent": "^1.0.0",
"trim-newlines": "^1.0.0"
},
"dependencies": {
"find-up": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"requires": {
"path-exists": "^2.0.0",
"pinkie-promise": "^2.0.0"
}
},
"indent-string": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
"integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
"requires": {
"repeating": "^2.0.0"
}
},
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"requires": {
"graceful-fs": "^4.1.2",
"parse-json": "^2.2.0",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0",
"strip-bom": "^2.0.0"
}
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"requires": {
"error-ex": "^1.2.0"
}
},
"path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"requires": {
"pinkie-promise": "^2.0.0"
}
},
"path-type": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
"requires": {
"graceful-fs": "^4.1.2",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
}
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
},
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
"requires": {
"load-json-file": "^1.0.0",
"normalize-package-data": "^2.3.2",
"path-type": "^1.0.0"
}
},
"read-pkg-up": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
"requires": {
"find-up": "^1.0.0",
"read-pkg": "^1.0.0"
}
},
"redent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
"integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
"requires": {
"indent-string": "^2.1.0",
"strip-indent": "^1.0.1"
}
},
"strip-bom": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"requires": {
"is-utf8": "^0.2.0"
}
},
"strip-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
"integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
"requires": {
"get-stdin": "^4.0.1"
}
}
}
},
"merge-deep": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz",
@@ -8317,6 +8669,11 @@
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"nan": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -8381,6 +8738,32 @@
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ=="
},
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
"integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
"requires": {
"fstream": "^1.0.0",
"glob": "^7.0.3",
"graceful-fs": "^4.1.2",
"mkdirp": "^0.5.0",
"nopt": "2 || 3",
"npmlog": "0 || 1 || 2 || 3 || 4",
"osenv": "0",
"request": "^2.87.0",
"rimraf": "2",
"semver": "~5.3.0",
"tar": "^2.0.0",
"which": "1"
},
"dependencies": {
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
}
}
},
"node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -8491,6 +8874,98 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz",
"integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg=="
},
"node-sass": {
"version": "4.14.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
"integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
"requires": {
"async-foreach": "^0.1.3",
"chalk": "^1.1.1",
"cross-spawn": "^3.0.0",
"gaze": "^1.0.0",
"get-stdin": "^4.0.1",
"glob": "^7.0.3",
"in-publish": "^2.0.0",
"lodash": "^4.17.15",
"meow": "^3.7.0",
"mkdirp": "^0.5.1",
"nan": "^2.13.2",
"node-gyp": "^3.8.0",
"npmlog": "^4.0.0",
"request": "^2.88.0",
"sass-graph": "2.2.5",
"stdout-stream": "^1.4.0",
"true-case-path": "^1.0.2"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"cross-spawn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
"integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
"requires": {
"lru-cache": "^4.0.1",
"which": "^1.2.9"
}
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
},
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"requires": {
"abbrev": "1"
}
},
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -8541,6 +9016,17 @@
"path-key": "^2.0.0"
}
},
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
}
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
@@ -8787,6 +9273,11 @@
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
@@ -8802,6 +9293,15 @@
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@@ -10199,6 +10699,11 @@
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@@ -10953,6 +11458,14 @@
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
"repeating": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
"integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
"requires": {
"is-finite": "^1.0.0"
}
},
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -11236,6 +11749,17 @@
"resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz",
"integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg=="
},
"sass-graph": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
"integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==",
"requires": {
"glob": "^7.0.0",
"lodash": "^4.0.0",
"scss-tokenizer": "^0.2.3",
"yargs": "^13.3.2"
}
},
"sass-loader": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
@@ -11305,6 +11829,25 @@
"ajv-keywords": "^3.4.1"
}
},
"scss-tokenizer": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
"integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
"requires": {
"js-base64": "^2.1.8",
"source-map": "^0.4.2"
},
"dependencies": {
"source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"requires": {
"amdefine": ">=0.0.4"
}
}
}
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -11907,6 +12450,38 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stdout-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
"integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
"requires": {
"readable-stream": "^2.0.1"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"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"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
@@ -12273,6 +12848,16 @@
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
},
"tar": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
"requires": {
"block-stream": "*",
"fstream": "^1.0.12",
"inherits": "2"
}
},
"terser": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz",
@@ -12554,6 +13139,19 @@
"punycode": "^2.1.0"
}
},
"trim-newlines": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
},
"true-case-path": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
"integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
"requires": {
"glob": "^7.1.2"
}
},
"ts-pnp": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.6.tgz",
@@ -12963,7 +13561,10 @@
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true
"optional": true,
"requires": {
"nan": "^2.12.1"
}
},
"glob-parent": {
"version": "3.1.0",
@@ -13284,7 +13885,10 @@
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true
"optional": true,
"requires": {
"nan": "^2.12.1"
}
},
"get-caller-file": {
"version": "1.0.3",
@@ -13621,6 +14225,43 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"requires": {
"string-width": "^1.0.2 || 2"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"requires": {
"ansi-regex": "^3.0.0"
}
}
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+1 -2
View File
@@ -42,6 +42,5 @@
"last 1 safari version"
]
},
"devDependencies": {
}
"devDependencies": {}
}
+357
View File
@@ -0,0 +1,357 @@
@import-normalize; /* bring in normalize.css styles */
$page-width: 800px;
$light-text-color: #777;
$button-text-color: #666;
$body-font-family: 'Nunito', serif;
$nav-font-family: 'Fira Sans', sans-serif;
$footer-font-family: 'Fira Sans', sans-serif;
$textarea-font-family: 'Fira Sans', sans-serif;
$headings-font-family: 'Merriweather', serif;
body {
margin: 0 auto;
width: $page-width;
font-family: $body-font-family;
}
p {
font-family: $body-font-family;
font-size: 1.2em;
a:link,
a:visited {
color: #c75;
font-weight: bold;
}
}
button {
background-color: #e5e5e5;
border: 0;
color: $button-text-color;
font-size: 1.2em;
margin: 20px;
min-width: 150px;
padding: 0.75em;
padding: 10px;
}
#main {
position: relative; // Footer attachment.
min-height: 100vh;
}
$footer-height: 6rem;
#viewable {
padding-bottom: $footer-height;
}
footer {
font-family: $footer-font-family;
width: $page-width;
text-align: center;
position: absolute; // Footer attachment.
bottom: 0;
// NB: Setting explicit height doesn't appear to be necessary, and
// it was creating an annoying scrollbar.
//height: $footer-height;
color: $light-text-color;
}
nav {
font-family: $nav-font-family;
width: $page-width;
text-align: justify;
a,
a:link {
text-decoration: none;
color: $light-text-color;
padding: 10px;
display: inline-block;
font-size: 1.3em;
cursor: pointer;
}
a:after {
content: '';
width: 99.5%;
}
a:hover,
a:active {
background-color: #fadada;
}
}
form {
width: $page-width;
textarea {
font-family: $textarea-font-family;
border: 1px solid #999;
width: $page-width;
box-sizing: border-box;
font-size: 1.2em;
resize: vertical;
padding: 1em;
margin: 0;
}
button {
display: block;
margin: 1.5em auto;
}
.left {
float: left;
width: 50%;
}
.right {
float: right;
width: 50%;
}
.clear {
clear: both;
}
}
#status {
.info {
color: #888888;
}
.warn {
color: #aaaa00;
}
.error {
color: #aa0000;
}
min-height: 1.5em;
}
#usage,
#updates,
#help-wanted,
#terms {
h1, h2 {
font-family: $headings-font-family;
}
p {
text-align: justify;
}
li {
font-size: 1.2em;
text-align: justify;
margin-bottom: 1em;
}
}
/** RESPONSIVENESS **/
@media screen and (min-width: 600px) {
$page-width: 600px;
button {
min-width: 250px;
}
}
@media screen and (min-width: 1px) {
$page-width: 200px;
body {
width: $page-width;
}
#animation canvas {
width: 200px;
}
#animation {
height: 117px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 300px) {
$page-width: 300px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 176px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 400px) {
$page-width: 400px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 235px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 450px) {
$page-width: 450px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 264px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 500px) {
$page-width: 500px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 293px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 600px) {
$page-width: 600px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 352px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 800px) {
$page-width: 800px;
body {
width: $page-width;
}
#animation canvas {
width: $page-width;
}
#animation {
height: 470px;
}
nav,
footer {
width: $page-width;
}
form {
width: $page-width;
textarea {
width: $page-width;
}
}
}
@media screen and (min-width: 1000px) {
#animation canvas {
width: 800px;
}
#animation {
height: 470px;
}
}
/** Hide footer when using onscreen keyboard. */
@media screen and (max-height: 550px) {
footer {
display: none;
}
nav {
display: none;
}
}
@media screen and (max-height: 740px) {
footer p {
display: inline;
}
footer p:after {
content: ' '; // Not sure why the space disappears when inline.
}
}
+61 -21
View File
@@ -1,26 +1,66 @@
import './App.scss';
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { Footer } from './navigation/Footer';
import { HelpWantedComponent } from './modes/help_wanted/HelpWantedComponent';
import { Mode } from './AppMode';
import { NewsComponent } from './modes/news/NewsComponent';
import { SpeakComponent } from './modes/speak/SpeakComponent';
import { TermsComponent } from './modes/terms/TermsComponent';
import { TopNav } from './navigation/TopNav';
import { UsageComponent } from './modes/usage/UsageComponent';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
interface Props {}
interface State {
mode: Mode,
}
class App extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
mode: Mode.SPEAK_MODE,
};
}
switchMode = (mode: Mode) => {
this.setState({ mode: mode });
}
resetMode = () => {
this.setState({ mode: Mode.SPEAK_MODE });
}
public render() {
let component;
switch (this.state.mode) {
case Mode.SPEAK_MODE:
component = <SpeakComponent />;
break;
case Mode.USAGE_MODE:
component = <UsageComponent resetModeCallback={this.resetMode} />;
break;
case Mode.NEWS_MODE:
component = <NewsComponent resetModeCallback={this.resetMode} />;
break;
case Mode.HELP_WANTED_MODE:
component = <HelpWantedComponent resetModeCallback={this.resetMode} />;
break;
case Mode.TERMS_MODE:
component = <TermsComponent resetModeCallback={this.resetMode} />;
break;
}
return (
<div id="main">
<div id="viewable">
<TopNav mode={this.state.mode} switchModeCallback={this.switchMode} />
{component}
</div>
<Footer mode={this.state.mode} switchModeCallback={this.switchMode} />
</div>
);
}
}
export default App;
+10
View File
@@ -0,0 +1,10 @@
enum Mode {
SPEAK_MODE,
USAGE_MODE,
NEWS_MODE,
HISTORY_MODE,
HELP_WANTED_MODE,
TERMS_MODE,
}
export { Mode };
+8
View File
@@ -0,0 +1,8 @@
function getRandomInt(min: number, max: number) : number {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
export { getRandomInt }
+4 -1
View File
@@ -1,4 +1,6 @@
body {
@import-normalize; /* bring in normalize.css styles */
/*body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
@@ -11,3 +13,4 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
*/
@@ -0,0 +1,41 @@
import React from 'react';
interface Props {
resetModeCallback: () => void,
}
function HelpWantedComponent(props: Props) {
return (
<div id="help-wanted">
<h1>Help Wanted</h1>
<h2>Training Data</h2>
<p>
Are you currently creating TTS models? I'd be happy to pay to license
your annotated audio samples. Tell me what voices you have, the sample
rate, how noisy the data is, and a little about your annotation process.
</p>
<h2>3D Modeller</h2>
<p>
I'm looking for a 3D artist or animator to make custom models and
animations for various characters (speaking, walking, articulating).
Environment, terrain, and world building skills are a huge plus.
I could rip models from VR Chat and make an attempt myself, but I'm
quite busy with working on the speech engine.
</p>
<p>
This is a paid position. It isn't necessarily for this project.
</p>
<h2>Contact</h2>
<p>Send me a message on Twitter or Gmail (same handle).</p>
<button onClick={() => props.resetModeCallback()}>Go Back</button>
</div>
)
}
export { HelpWantedComponent };
+63
View File
@@ -0,0 +1,63 @@
import React from 'react';
interface Props {
resetModeCallback: () => void,
}
function NewsComponent(props: Props) {
return (
<div id="updates">
<h1> Updates </h1>
<h2>
June 7, 2020: Website rewrite.
</h2>
<p>
I rewrote the incredibly dated frontend in React and added help, news, and other
information. The frontend won't be a huge concern for me going forward, but I'll
periodically continue to make upgrades. One critical feature I intend to add is the
ability to download audio files and replay them.
</p>
<h2>
June 4, 2020: There's a new model.
</h2>
<p>
I replaced the old model with a completely new one that doesn't crash and is a
10x speed up over the last one. While it doesn't currently sound as good as the
old model, the performance improvements were good enough to warrant using it
immediately. I'll make it sound better soon. So many things in the pipeline...
</p>
<h2>May 30, 2020: Intermittent failure.</h2>
<p>
There's now another issue with how models are distributed to the workers. I have
a solution in the works and expect it to be in place before morning tomorrow.
</p>
<h2>
May 25, 2020: I'm actively working on development.
</h2>
<p>
This site has been sitting in limbo for four years. It used to use concatenative
TTS, but now uses Tacotron. I've been working on ML for the past year, but haven't
taken the time to update this website.
</p>
<p>
I've got an improved model in the works, and I'm focused on scaling the cluster.
There's an occasional server crash bug I'm chasing down (right now the server
instances respawn when they die). The frontend will be updated soon to no longer
cache results.
</p>
<button onClick={() => props.resetModeCallback()}>Go Back</button>
</div>
)
}
export { NewsComponent };
+155
View File
@@ -0,0 +1,155 @@
import Howl from 'howler';
import React from 'react';
import { SpeakRequest } from './SpeakRequest';
interface Props {
clearStatusCallback: () => void,
setHintMessage: (message: string) => void,
onSpeakRequestCallback: () => void,
onSpeakSuccessCallback: () => void,
onSpeakErrorCallback: () => void,
onPlayCallback: () => void,
onStopCallback: () => void,
}
interface State {
text: string,
howl?: Howl,
}
class Form extends React.Component<Props, State> {
textarea: HTMLTextAreaElement | null | undefined;
constructor(props: Props) {
super(props);
this.state = {
text: '',
};
}
componentDidMount() {
this.textarea?.focus();
}
public speak(sentence: string, speaker: string) {
let request = new SpeakRequest(sentence, speaker);
console.log("Making SpeakRequest:", request);
//const url = this.props.apiConfig.getEndpoint('/speak');
const url = 'https://mumble.stream/speak';
this.props.onSpeakRequestCallback();
let that = this;
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
})
.then(res => res.blob())
.then(blob => {
this.props.onSpeakSuccessCallback();
console.log(blob);
const url = window.URL.createObjectURL(blob);
console.log(url);
const sound = new Howl.Howl({
src: [url],
format: 'wav',
// NB: Attempting to get this working on iPhone Safari
// https://github.com/goldfire/howler.js/issues/1093
// Other issues cite needing to cache a single player
// across all user interaction events.
html5: true,
onplay: () => {
that.props.onPlayCallback();
},
onend: () => {
that.props.onStopCallback();
},
});
this.setState({howl: sound});
sound.play();
(window as any).sound = sound;
})
.catch(e => {
this.props.onSpeakErrorCallback();
});
}
clear() {
this.setState({text: ''});
}
handleTextChange = (ev: React.FormEvent<HTMLTextAreaElement>) => {
const text = (ev.target as HTMLTextAreaElement).value;
let pseudoWords = text.split(' ');
if (text.length > 0) {
if (pseudoWords.length > 0 && pseudoWords.length < 4) {
this.props.setHintMessage("Hint: It sounds better when you type more words.");
} else if (pseudoWords.length > 5) {
this.props.setHintMessage("Hint: Use the ESC key to clear if you're on your computer.");
}
} else {
this.props.clearStatusCallback();
}
this.setState({text: text});
}
handleFormSubmit = (ev: React.FormEvent<HTMLFormElement>) : boolean => {
ev.preventDefault();
this.speak(this.state.text, 'trump');
return false;
}
handleCancelClick = (ev: React.FormEvent<HTMLButtonElement>) : boolean => {
ev.preventDefault();
this.clear();
return false;
}
handleKeyDown = (ev: React.KeyboardEvent<HTMLTextAreaElement>) : boolean => {
if (ev.keyCode === 27) {
// Escape key
this.clear();
}
return true;
}
public render() {
return (
<form onSubmit={this.handleFormSubmit}>
<textarea
onChange={this.handleTextChange}
onKeyDown={this.handleKeyDown}
value={this.state.text}
ref={(textarea) => { this.textarea = textarea; }}
/>
<div>
<div className="left">
<button>Speak</button>
</div>
<div className="right">
<button onClick={this.handleCancelClick}>Cancel</button>
</div>
<div className="clear"></div>
</div>
</form>
);
}
}
export { Form };
+122
View File
@@ -0,0 +1,122 @@
import React from 'react';
import { Form } from './Form';
import { StatusText } from './StatusText';
import { getRandomInt } from '../../Utils';
enum StatusState {
NONE,
INFO,
WARN,
ERROR,
}
interface Props {}
interface State {
statusState: StatusState;
statusMessage: string,
isTalking: boolean,
}
class SpeakComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
statusState: StatusState.NONE,
statusMessage: '',
isTalking: false,
};
}
setMessage = (statusState: StatusState, message: string) => {
this.setState({
statusState: statusState,
statusMessage: message,
})
}
setHintMessage = (message: string) => {
this.setMessage(StatusState.INFO, message);
}
clearMessage = () => {
this.setState({
statusState: StatusState.NONE,
statusMessage: '',
})
}
onSpeakRequest = () => {
let message;
switch (getRandomInt(0, 4)) {
case 0:
message = "Requesting...";
break;
case 1:
message = "Sending...";
break;
case 3:
message = "Calculating...";
break;
case 4:
default:
message = "Inferring...";
break;
}
this.setMessage(StatusState.INFO, message);
}
onSpeakSuccess = () => {
let message;
switch (getRandomInt(0, 4)) {
case 0:
message = "Success!";
break;
case 1:
message = "Playing.";
break;
case 3:
message = "Here's some Trump audio.";
break;
case 4:
default:
message = "Got it.";
break;
}
this.setMessage(StatusState.INFO, message);
}
onSpeakError = () => {
this.setMessage(StatusState.ERROR, "There was an error. Perhaps you sent too much text or the server is busy. Try again.");
}
onPlay = () => {
this.setState({ isTalking: true });
}
onStop = () => {
this.setState({ isTalking: false });
}
public render() {
return (
<div>
<StatusText
statusState={this.state.statusState}
statusMessage={this.state.statusMessage}/>
<Form
clearStatusCallback={this.clearMessage}
setHintMessage={this.setHintMessage}
onSpeakRequestCallback={this.onSpeakRequest}
onSpeakSuccessCallback={this.onSpeakSuccess}
onSpeakErrorCallback={this.onSpeakError}
onPlayCallback={this.onPlay}
onStopCallback={this.onStop}
/>
</div>
);
}
}
export { SpeakComponent, StatusState };
+13
View File
@@ -0,0 +1,13 @@
/// Requests to the "speak" endpoint.
class SpeakRequest {
text: string
speaker: string
constructor(text: string, speaker: string) {
this.text = text;
this.speaker = speaker;
}
}
export { SpeakRequest };
+41
View File
@@ -0,0 +1,41 @@
import React from 'react';
import { StatusState } from './SpeakComponent';
interface Props {
statusState: StatusState;
statusMessage: string,
}
interface State {}
class StatusText extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {};
}
public render() {
let className;
switch (this.props.statusState) {
case StatusState.INFO:
className = 'info';
break;
case StatusState.WARN:
className = 'warn';
break;
case StatusState.ERROR:
className = 'error';
break;
}
return (
<div id="status">
<p className={className}>{this.props.statusMessage}</p>
</div>
);
}
}
export { StatusText };
@@ -0,0 +1,60 @@
import React from 'react';
interface Props {
resetModeCallback: () => void,
}
function TermsComponent(props: Props) {
return (
<div id="terms">
<h1>Terms and Conditions.</h1>
<h2>Don't use this website for mischief.</h2>
<p>Please have fun with this app amongst your friends and colleages, but don't
do anything stupid. The actions you take are your own, and I am not responsible
for any trouble you might get into<sup>&dagger;</sup>. Use your best judgment.
For example, though you might find it funny, please don't use this app to harass
the poor people working at Gamestop. They don't have Battle Toads.</p>
<h2>Artistic intent.</h2>
<p>This website is a form of artistic expression, parody, and engineering creativity.
It is not meant to be harmful to anyone in any way. The audio generated is sufficiently
poor in quality and should not be confused with actual speech. Everyone should be
able to have a good laugh.</p>
<h2>Deep fakes are good.</h2>
<p>So-called <em>deep fakes</em> are not much different for us today than Photoshop
was for new users of the World Wide Web back in the 90s. It's impressive new technology
that defies our expectations. Instead of just pictures, machine learning can generate
complex shapes in all sorts of signal domains. It's really impressive stuff.</p>
<p>If you restrict the technology out of fear, it becomes the tool of state actors.
If it's left wide open, it's just a toy. Society will learn to accept and enjoy it just
as we did with Photoshop.</p>
<p>Our brains are already capable of reading passages in other people's voices and
picturing vivid scenes without them ever existing. Deep models give computers the
ability to do the same thing. That's powerful. This and related advances in computer
vision will unlock a higher order of creativity than was ever before possible.</p>
<p><em>Don't legislate deep fakes.</em></p>
<h2>What's next?</h2>
<p>I'll be improving trumped.com, adding more voices, and scaling the app.
I've got some new models baking in the GPU ovens right now.</p>
<p>I'm very busy between work and my startup, so please give me time.</p>
<p><sup>&dagger;</sup> Anyone can download Tacotron from Github to produce the same
results on their own. Trumped.com is not connected with your activities.</p>
<button onClick={() => props.resetModeCallback()}>Go Back</button>
</div>
)
}
export { TermsComponent };
@@ -0,0 +1,76 @@
import React from 'react';
interface Props {
resetModeCallback: () => void,
}
function UsageComponent(props: Props) {
return (
<div id="usage">
<h1>Usage Recommendations</h1>
<h2>Short sentences are bad</h2>
<p>
Don't say things like "hello" or "hi". They're too short for the current
model to generate good audio from. This may improve in the future, but it
is low on the list of priorities.
</p>
<h2>Try and try again</h2>
<p>
If you're unhappy with how the results sound, try changing the words a litle.
Experiment. Try adding punctuation, such as periods and question marks.
</p>
<h2>Use real words</h2>
<p>
"Asdfagdadf" is not a word, and Trump won't know how to say it.
</p>
<h2>Sound out difficult words</h2>
<p>
If the words you want to use aren't working, that's likely because I trained the
network on phonemes instead of raw text. This phonetic information
comes from a database, and although this database contains over 130,000 words, it
unfortunately doesn't have entries such as "Fortnite".
</p>
<p>
To make this work, try sounding out the problematic words: "pikachu is a pokemon"
can be rewritten as "peek ah choo is a poke ay mon". You can try "Fort Night"
instead of "Fortnite".
</p>
<p>
I'll fix this issue as soon as I can, because I know how important this is to you.
</p>
<h2>Example sentences</h2>
<p>Try getting Trump to say the following:</p>
<ul>
<li>Why does it always rain on Christmas? It's so depressing.</li>
<li>I really appreciate how good of a friend you are.</li>
<li>You're clearly not trying hard enough. What's up with you?</li>
<li>The Dinosaurs were the dominant land animals of the Mesozoic era.
Over 500 different genera of dinosaurs are known. Fossils of dinosaurs
have been found on every continent, and there are still frequent
new discoveries.</li>
<li>Dinosaurs had adaptations which helped make them successful.
The first known dinosaurs were small predators that walked on two legs.
All their descendants had an upright posture, with the legs underneath
the body. This transformed their whole lifestyle.</li>
<li>Are you really reading this far? Good for you.</li>
</ul>
<button onClick={() => props.resetModeCallback()}>Go Back</button>
</div>
)
}
export { UsageComponent };
+25
View File
@@ -0,0 +1,25 @@
import React from 'react';
import { Mode } from '../AppMode'
interface Props {
mode: Mode,
switchModeCallback: (mode: Mode) => void,
}
function Footer(props: Props) {
return (
<footer>
<p>
Made in Atlanta by&nbsp;
<a href="https://twitter.com/echelon">@echelon</a>.
</p>
<p>
By using this, you agree to&nbsp;
<a href="#terms"
onClick={() => props.switchModeCallback(Mode.TERMS_MODE)}>the things</a>.
</p>
</footer>
)
}
export { Footer };
+22
View File
@@ -0,0 +1,22 @@
import React from 'react';
import { Mode } from '../AppMode'
interface Props {
mode: Mode,
switchModeCallback: (mode: Mode) => void,
}
function TopNav(props: Props) {
return (
<nav>
<a href="#speak" onClick={() => props.switchModeCallback(Mode.SPEAK_MODE)}>Speak</a>
{/*<a onClick={() => props.switchModeCallback(Mode.HISTORY_MODE)}>Downloads</a>*/}
<a href="#use" onClick={() => props.switchModeCallback(Mode.USAGE_MODE)}>Usage</a>
<a href="#news" onClick={() => props.switchModeCallback(Mode.NEWS_MODE)}>News</a>
<a href="#help" onClick={() => props.switchModeCallback(Mode.HELP_WANTED_MODE)}>Help Wanted</a>
<hr />
</nav>
)
}
export { TopNav };