diff --git a/package-lock.json b/package-lock.json index 6f2ddf992..57e91ddf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1671,7 +1671,7 @@ "integrity": "sha1-zsTbis5u9KrL8Q7vCXekVxRo1Ks=", "dev": true, "requires": { - "global": "^4.3.1" + "global": "4.3.2" } }, "aws-sign2": { @@ -2130,12 +2130,12 @@ }, "bl": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "readable-stream": "2.3.6", + "safe-buffer": "5.1.1" }, "dependencies": { "process-nextick-args": { @@ -2146,17 +2146,17 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": 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" + "core-util-is": "1.0.2", + "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.2" } }, "string_decoder": { @@ -2165,7 +2165,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } } } @@ -2301,10 +2301,10 @@ "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", "dev": true, "requires": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" + "quote-stream": "1.0.2", + "resolve": "1.8.1", + "static-module": "2.2.5", + "through2": "2.0.3" } }, "brorand": { @@ -2945,14 +2945,14 @@ "integrity": "sha512-0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ==", "dev": true, "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "globby": "^7.1.1", - "is-glob": "^4.0.0", - "loader-utils": "^1.1.0", - "minimatch": "^3.0.4", - "p-limit": "^1.0.0", - "serialize-javascript": "^1.4.0" + "cacache": "10.0.4", + "find-cache-dir": "1.0.0", + "globby": "7.1.1", + "is-glob": "4.0.0", + "loader-utils": "1.1.0", + "minimatch": "3.0.4", + "p-limit": "1.3.0", + "serialize-javascript": "1.5.0" }, "dependencies": { "globby": { @@ -2961,12 +2961,12 @@ "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", "dev": true, "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" + "array-union": "1.0.2", + "dir-glob": "2.0.0", + "glob": "7.1.2", + "ignore": "3.3.10", + "pify": "3.0.0", + "slash": "1.0.0" } }, "pify": { @@ -3463,8 +3463,8 @@ "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", "dev": true, "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" + "arrify": "1.0.1", + "path-type": "3.0.0" } }, "dns-equal": { @@ -3563,7 +3563,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.2.9" } }, "duplexify": { @@ -3832,11 +3832,11 @@ "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" }, "dependencies": { "esprima": { @@ -4415,8 +4415,8 @@ "integrity": "sha1-V9x4kX9wm5byR/qR5ptVTIVQE8g=", "dev": true, "requires": { - "loader-utils": "0.2.x", - "source-map": "0.1.x" + "loader-utils": "0.2.17", + "source-map": "0.1.43" }, "dependencies": { "loader-utils": { @@ -4425,10 +4425,10 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" } }, "source-map": { @@ -4437,7 +4437,7 @@ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -4628,10 +4628,10 @@ "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", "dev": true, "requires": { - "acorn": "^5.0.0", - "foreach": "^2.0.5", + "acorn": "5.5.3", + "foreach": "2.0.5", "isarray": "0.0.1", - "object-keys": "^1.0.6" + "object-keys": "1.0.11" }, "dependencies": { "isarray": { @@ -4791,7 +4791,7 @@ }, "file-type": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", "dev": true }, @@ -4903,13 +4903,13 @@ "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=", "dev": true, "requires": { - "colors": "~0.6.0-1", - "commander": "~2.1.0" + "colors": "0.6.2", + "commander": "2.1.0" }, "dependencies": { "commander": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz", "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", "dev": true } @@ -5383,7 +5383,7 @@ "integrity": "sha1-6vwWtl9uJxm81X/cGGkAWsEzLNY=", "dev": true, "requires": { - "from2": "^2.0.3" + "from2": "2.3.0" } }, "fs-exists-cached": { @@ -5463,14 +5463,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -5485,20 +5483,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5615,8 +5610,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5628,7 +5622,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "1.0.1" } @@ -5643,7 +5636,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "1.1.11" } @@ -5651,14 +5643,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "5.1.1", "yallist": "3.0.2" @@ -5677,7 +5667,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5758,8 +5747,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5771,7 +5759,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1.0.2" } @@ -5894,7 +5881,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -6209,8 +6195,8 @@ "integrity": "sha1-W55reMODJFLSuiuxy4MPlidkEKw=", "dev": true, "requires": { - "brfs": "^1.2.0", - "unicode-trie": "^0.3.1" + "brfs": "1.6.1", + "unicode-trie": "0.3.1" } }, "growl": { @@ -6547,13 +6533,13 @@ "integrity": "sha1-fpGe6A3RBYv9Q508GPY8CKixayo=", "dev": true, "requires": { - "bl": "^1.0.0", - "findup": "^0.1.5", + "bl": "1.2.2", + "findup": "0.1.5", "from2-array": "0.0.4", "map-limit": "0.0.1", - "multipipe": "^0.3.0", - "read-package-json": "^2.0.2", - "resolve": "^1.1.6" + "multipipe": "0.3.1", + "read-package-json": "2.0.13", + "resolve": "1.8.1" } }, "ignore": { @@ -6588,8 +6574,8 @@ "integrity": "sha1-rnRlMDHVnjezwvslRKxhrq41MKY=", "dev": true, "requires": { - "loader-utils": "0.2.x", - "source-map": "0.1.x" + "loader-utils": "0.2.17", + "source-map": "0.1.43" }, "dependencies": { "loader-utils": { @@ -6598,10 +6584,10 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" } }, "source-map": { @@ -6610,7 +6596,7 @@ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -7082,25 +7068,25 @@ }, "jimp": { "version": "0.2.27", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.2.27.tgz", + "resolved": "http://registry.npmjs.org/jimp/-/jimp-0.2.27.tgz", "integrity": "sha1-Qe9Qgti2MgHVR0fgT+i8rLryVHQ=", "dev": true, "requires": { - "bignumber.js": "^2.1.0", + "bignumber.js": "2.4.0", "bmp-js": "0.0.1", - "es6-promise": "^3.0.2", - "exif-parser": "^0.1.9", - "file-type": "^3.1.0", - "jpeg-js": "^0.2.0", - "load-bmfont": "^1.2.3", - "mime": "^1.3.4", - "pixelmatch": "^4.0.0", - "pngjs": "^3.0.0", - "read-chunk": "^1.0.1", - "request": "^2.65.0", - "stream-to-buffer": "^0.1.0", - "tinycolor2": "^1.1.2", - "url-regex": "^3.0.0" + "es6-promise": "3.0.2", + "exif-parser": "0.1.12", + "file-type": "3.9.0", + "jpeg-js": "0.2.0", + "load-bmfont": "1.4.0", + "mime": "1.4.1", + "pixelmatch": "4.0.2", + "pngjs": "3.3.3", + "read-chunk": "1.0.1", + "request": "2.79.0", + "stream-to-buffer": "0.1.0", + "tinycolor2": "1.4.1", + "url-regex": "3.2.0" } }, "jpeg-js": { @@ -7115,12 +7101,6 @@ "integrity": "sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow==", "dev": true }, - "js-md5": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.6.1.tgz", - "integrity": "sha512-lyUTXOqMEaA9mm38mHxbTo83WsYAvMJm850kxJcRno3T2qL+e40B2G89E0/4r9TdAeB3jN0TdSVp/VHNI6/WyQ==", - "dev": true - }, "js-tokens": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", @@ -7391,8 +7371,8 @@ "dev": true, "requires": { "base64-js": "0.0.8", - "brfs": "^1.3.0", - "unicode-trie": "^0.3.0" + "brfs": "1.6.1", + "unicode-trie": "0.3.1" }, "dependencies": { "base64-js": { @@ -7410,13 +7390,13 @@ "dev": true, "requires": { "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" + "mime": "1.4.1", + "parse-bmfont-ascii": "1.0.6", + "parse-bmfont-binary": "1.0.6", + "parse-bmfont-xml": "1.1.4", + "phin": "2.9.3", + "xhr": "2.4.0", + "xtend": "4.0.1" } }, "loader-runner": { @@ -7561,11 +7541,11 @@ }, "magic-string": { "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", "dev": true, "requires": { - "vlq": "^0.2.2" + "vlq": "0.2.3" } }, "make-dir": { @@ -7603,7 +7583,7 @@ "integrity": "sha1-63lhAxwPDo0AG/LVb6toXViCLzg=", "dev": true, "requires": { - "once": "~1.3.0" + "once": "1.3.3" }, "dependencies": { "once": { @@ -7612,7 +7592,7 @@ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } } } @@ -7793,7 +7773,7 @@ "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.6" } }, "methods": { @@ -8019,7 +7999,7 @@ "integrity": "sha1-kmJVJXYboE/qoJYFtjgrziyR8R8=", "dev": true, "requires": { - "duplexer2": "^0.1.2" + "duplexer2": "0.1.4" } }, "mute-stream": { @@ -8265,7 +8245,6 @@ "version": "0.1.4", "bundled": true, "dev": true, - "optional": true, "requires": { "kind-of": "3.2.2", "longest": "1.0.1", @@ -9448,8 +9427,7 @@ "longest": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.3.1", @@ -11161,8 +11139,8 @@ "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", "dev": true, "requires": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" + "xml-parse-from-string": "1.0.1", + "xml2js": "0.4.19" } }, "parse-headers": { @@ -11256,7 +11234,7 @@ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "^3.0.0" + "pify": "3.0.0" }, "dependencies": { "pify": { @@ -11287,9 +11265,9 @@ "dev": true }, "phin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.2.tgz", - "integrity": "sha512-j+UOz1qs+k8NlBRws2IF+Qd+YsVKcqIjvYPBEP9IpmhyvLvyN6GTuqsGbsqH3fIgHufqVqLQSttidIgshkgT7w==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", "dev": true }, "pify": { @@ -11317,7 +11295,7 @@ "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", "dev": true, "requires": { - "pngjs": "^3.0.0" + "pngjs": "3.3.3" } }, "pkg-dir": { @@ -11527,13 +11505,13 @@ "dev": true, "requires": { "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" + "minimist": "1.2.0", + "through2": "2.0.3" }, "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -11620,11 +11598,11 @@ "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", "dev": true, "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", - "slash": "^1.0.0" + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "json-parse-better-errors": "1.0.2", + "normalize-package-data": "2.4.0", + "slash": "1.0.0" } }, "readable-stream": { @@ -12006,20 +11984,20 @@ } }, "scratch-audio": { - "version": "0.1.0-prerelease.20180625202813", - "resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20180625202813.tgz", - "integrity": "sha512-LX7FnJqDVEnPk0wuopb8fiEfp3GaS1BYA9NYC7ew5iIPMSq2Z5IJtPCXMRccLwDfz2ohqSqHprd2j9ohscuyrw==", + "version": "0.1.0-prerelease.20181023202904", + "resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20181023202904.tgz", + "integrity": "sha512-0cf+snpT04RFWFgMsMzbztzNVyh2PkUaT8mjlwNNoIRy5p7yDN3EMC2zGbR71nZMus1tO2EDxqrpan2ix4IWDw==", "dev": true, "requires": { "audio-context": "1.0.1", - "minilog": "^3.0.1", + "minilog": "3.1.0", "startaudiocontext": "1.2.1" } }, "scratch-blocks": { - "version": "0.1.0-prerelease.1539267627", - "resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.1539267627.tgz", - "integrity": "sha512-zBTNfrImKs7QAegB7aNAqu+5t3TfXOMQAiF0HlnKtZDB6ddRzZB9plWEkub2eMy3qVSs00vFm2JEl3uN1/Elbg==", + "version": "0.1.0-prerelease.1540328358", + "resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.1540328358.tgz", + "integrity": "sha512-U72BcSg9f7M+o6QyDu23XGqaLrpF8xWYdX1/xNSeShyDIgzZcKrc1xzqbjVuICDRSnTWQuvxmM38crKnQ9/z6w==", "dev": true, "requires": { "exports-loader": "0.6.3", @@ -12050,9 +12028,9 @@ } }, "scratch-render": { - "version": "0.1.0-prerelease.20181017195657", - "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20181017195657.tgz", - "integrity": "sha512-ovwD6kotWBJtWDK5DQT5X8EmfIgpBuNQ1yJK6aLdzAtFWPxJ1LwZCKScuJqXFJv7VNen7LHfJQ5Fer9gdz31Yw==", + "version": "0.1.0-prerelease.20181023192935", + "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20181023192935.tgz", + "integrity": "sha512-6M6opV7WjlgfyFrHTYQ6Ny8TJ1rURnDDhG6x9FYv2dpyjLhpikim4XUT+2QiEv+9eC2Txzy2ZRSv7+27j2yGSg==", "dev": true, "requires": { "grapheme-breaker": "0.3.2", @@ -12060,8 +12038,8 @@ "ify-loader": "1.0.4", "linebreak": "0.3.0", "minilog": "3.1.0", - "raw-loader": "^0.5.1", - "scratch-storage": "^1.0.0", + "raw-loader": "0.5.1", + "scratch-storage": "1.1.0", "scratch-svg-renderer": "0.2.0-prerelease.20181017193458", "twgl.js": "4.4.0" } @@ -12076,23 +12054,29 @@ } }, "scratch-storage": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.0.0.tgz", - "integrity": "sha512-5uDvEo6NVRu4AekwUjfoqIP2VM0Yo4mBd+xFgUPe642QXW207inQ30gdQRFZgzl6tuEZ+hF3D/mtO7UoxJKGEA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.1.0.tgz", + "integrity": "sha512-4gtQW5ST5RDIWjfflK6k7Jxq7rQWgvhfM+oqL2Ld+eyQIbhZ4BwX0R3aRtwhupntv3tCa+2lBhRm+CGnaCijvA==", "dev": true, "requires": { "arraybuffer-loader": "1.0.6", - "base64-js": "1.2.1", - "js-md5": "0.6.1", + "base64-js": "1.3.0", + "js-md5": "0.7.3", "minilog": "3.1.0", "nets": "3.2.0", - "text-encoding": "0.6.4" + "text-encoding": "0.7.0" }, "dependencies": { - "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "js-md5": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", + "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==", + "dev": true + }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==", "dev": true } } @@ -12750,7 +12734,7 @@ "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==", "dev": true, "requires": { - "escodegen": "^1.8.1" + "escodegen": "1.9.1" } }, "static-extend": { @@ -12780,20 +12764,20 @@ "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", "dev": true, "requires": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", + "concat-stream": "1.6.0", + "convert-source-map": "1.5.1", + "duplexer2": "0.1.4", + "escodegen": "1.9.1", + "falafel": "2.1.0", + "has": "1.0.1", + "magic-string": "0.22.5", "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" + "object-inspect": "1.4.1", + "quote-stream": "1.0.2", + "readable-stream": "2.3.6", + "shallow-copy": "0.0.1", + "static-eval": "2.0.0", + "through2": "2.0.3" }, "dependencies": { "process-nextick-args": { @@ -12804,17 +12788,17 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": 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" + "core-util-is": "1.0.2", + "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.2" } }, "string_decoder": { @@ -12823,7 +12807,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } } } @@ -12923,7 +12907,7 @@ "integrity": "sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=", "dev": true, "requires": { - "stream-to": "~0.2.0" + "stream-to": "0.2.2" } }, "strict-uri-encode": { @@ -13654,8 +13638,8 @@ "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=", "dev": true, "requires": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" + "pako": "0.2.9", + "tiny-inflate": "1.0.2" }, "dependencies": { "pako": { @@ -13838,7 +13822,7 @@ "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", "dev": true, "requires": { - "ip-regex": "^1.0.1" + "ip-regex": "1.0.3" } }, "use": { @@ -14545,13 +14529,13 @@ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "dev": true, "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "sax": "1.2.4", + "xmlbuilder": "9.0.7" } }, "xmlbuilder": { "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, diff --git a/package.json b/package.json index 15a69665f..7c2d6a76d 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "scratch-audio": "latest", "scratch-blocks": "latest", "scratch-render": "latest", - "scratch-storage": "^1.0.0", + "scratch-storage": "^1.1.0", "scratch-svg-renderer": "latest", "script-loader": "0.7.2", "stats.js": "^0.17.0", diff --git a/src/import/load-costume.js b/src/import/load-costume.js index bf8505b7a..31eac9dbc 100644 --- a/src/import/load-costume.js +++ b/src/import/load-costume.js @@ -11,12 +11,8 @@ const loadVector_ = function (costume, costumeAsset, runtime, rotationCenter, op svgString = runtime.v2SvgAdapter.toString(); // Put back into storage const storage = runtime.storage; - costumeAsset.encodeTextData(svgString, storage.DataFormat.SVG); - costume.assetId = storage.builtinHelper.cache( - storage.AssetType.ImageVector, - storage.DataFormat.SVG, - costumeAsset.data - ); + costume.asset.encodeTextData(svgString, storage.DataFormat.SVG, true); + costume.assetId = costume.asset.assetId; costume.md5 = `${costume.assetId}.${costume.dataFormat}`; } // createSVGSkin does the right thing if rotationCenter isn't provided, so it's okay if it's @@ -63,11 +59,14 @@ const loadBitmap_ = function (costume, costumeAsset, runtime, rotationCenter) { } else if (dataURI) { // Put back into storage const storage = runtime.storage; - costume.assetId = storage.builtinHelper.cache( + costume.asset = storage.createAsset( storage.AssetType.ImageBitmap, storage.DataFormat.PNG, - runtime.v2BitmapAdapter.convertDataURIToBinary(dataURI) + runtime.v2BitmapAdapter.convertDataURIToBinary(dataURI), + null, + true // generate md5 ); + costume.assetId = costume.asset.assetId; costume.md5 = `${costume.assetId}.${costume.dataFormat}`; } // Regardless of if conversion succeeds, convert it to bitmap resolution 2, @@ -163,9 +162,12 @@ const loadCostume = function (md5ext, costume, runtime, optVersion) { const md5 = idParts[0]; const ext = idParts[1].toLowerCase(); const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap; - - return runtime.storage.load(assetType, md5, ext).then(costumeAsset => { - costume.dataFormat = ext; + costume.dataFormat = ext; + return ( + (costume.asset && Promise.resolve(costume.asset)) || + runtime.storage.load(assetType, md5, ext) + ).then(costumeAsset => { + costume.asset = costumeAsset; return loadCostumeFromAsset(costume, costumeAsset, runtime, optVersion); }) .catch(e => { diff --git a/src/import/load-sound.js b/src/import/load-sound.js index 8f4f7a1a6..548eb3276 100644 --- a/src/import/load-sound.js +++ b/src/import/load-sound.js @@ -55,11 +55,14 @@ const loadSound = function (sound, runtime, sprite) { const idParts = StringUtil.splitFirst(sound.md5, '.'); const md5 = idParts[0]; const ext = idParts[1].toLowerCase(); - return runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext) - .then(soundAsset => { - sound.dataFormat = ext; - return loadSoundFromAsset(sound, soundAsset, runtime, sprite); - }); + sound.dataFormat = ext; + return ( + (sound.asset && Promise.resolve(sound.asset)) || + runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext) + ).then(soundAsset => { + sound.asset = soundAsset; + return loadSoundFromAsset(sound, soundAsset, runtime, sprite); + }); }; module.exports = { diff --git a/src/serialization/deserialize-assets.js b/src/serialization/deserialize-assets.js index 6a49b9a2e..a3bb6e408 100644 --- a/src/serialization/deserialize-assets.js +++ b/src/serialization/deserialize-assets.js @@ -22,37 +22,29 @@ const deserializeSound = function (sound, runtime, zip, assetFileName) { return Promise.resolve(null); } - const assetId = sound.assetId; - - // TODO Is there a faster way to check that this asset - // has already been initialized? - if (storage.get(assetId)) { - // This sound has already been cached. - return Promise.resolve(null); - } if (!zip) { // Zip will not be provided if loading project json from server return Promise.resolve(null); } + const soundFile = zip.file(fileName); if (!soundFile) { log.error(`Could not find sound file associated with the ${sound.name} sound.`); return Promise.resolve(null); } - const dataFormat = sound.dataFormat.toLowerCase() === 'mp3' ? - storage.DataFormat.MP3 : storage.DataFormat.WAV; + if (!JSZip.support.uint8array) { log.error('JSZip uint8array is not supported in this browser.'); return Promise.resolve(null); } - return soundFile.async('uint8array').then(data => { - storage.builtinHelper.cache( - storage.AssetType.Sound, - dataFormat, - data, - assetId - ); - }); + const dataFormat = sound.dataFormat.toLowerCase() === 'mp3' ? + storage.DataFormat.MP3 : storage.DataFormat.WAV; + return soundFile.async('uint8array').then(data => storage.createAsset( + storage.AssetType.Sound, + dataFormat, + data, + sound.assetId + )); }; /** @@ -79,14 +71,6 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName) { return Promise.resolve(null); } - - // TODO Is there a faster way to check that this asset - // has already been initialized? - if (storage.get(assetId)) { - // This costume has already been cached. - return Promise.resolve(null); - } - if (!zip) { // Zip will not be provided if loading project json from server return Promise.resolve(null); } @@ -110,15 +94,13 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName) { return Promise.resolve(null); } - return costumeFile.async('uint8array').then(data => { - storage.builtinHelper.cache( - assetType, - // TODO eventually we want to map non-png's to their actual file types? - costumeFormat, - data, - assetId - ); - }); + return costumeFile.async('uint8array').then(data => storage.createAsset( + assetType, + // TODO eventually we want to map non-png's to their actual file types? + costumeFormat, + data, + assetId + )); }; module.exports = { diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index 197095968..5021c14df 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -413,7 +413,11 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip) // the file name of the costume should be the baseLayerID followed by the file ext const assetFileName = `${costumeSource.baseLayerID}.${ext}`; costumePromises.push(deserializeCostume(costume, runtime, zip, assetFileName) - .then(() => loadCostume(costume.md5, costume, runtime, 2 /* optVersion */))); + .then(asset => { + costume.asset = asset; + return loadCostume(costume.md5, costume, runtime, 2 /* optVersion */); + }) + ); } } // Sounds from JSON @@ -447,7 +451,10 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip) // followed by the file ext const assetFileName = `${soundSource.soundID}.${ext}`; soundPromises.push(deserializeSound(sound, runtime, zip, assetFileName) - .then(() => loadSound(sound, runtime, sprite))); + .then(asset => { + sound.asset = asset; + return loadSound(sound, runtime, sprite); + })); } } diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js index ad5982f78..7012aa949 100644 --- a/src/serialization/sb3.js +++ b/src/serialization/sb3.js @@ -844,7 +844,10 @@ const parseScratchObject = function (object, runtime, extensions, zip) { // any translation that needs to happen will happen in the process // of building up the costume object into an sb3 format return deserializeCostume(costume, runtime, zip) - .then(() => loadCostume(costumeMd5Ext, costume, runtime)); + .then(asset => { + costume.asset = asset; + return loadCostume(costumeMd5Ext, costume, runtime); + }); // Only attempt to load the costume after the deserialization // process has been completed }); @@ -869,7 +872,10 @@ const parseScratchObject = function (object, runtime, extensions, zip) { // any translation that needs to happen will happen in the process // of building up the costume object into an sb3 format return deserializeSound(sound, runtime, zip) - .then(() => loadSound(sound, runtime, sprite)); + .then(asset => { + sound.asset = asset; + return loadSound(sound, runtime, sprite); + }); // Only attempt to load the sound after the deserialization // process has been completed. }); diff --git a/src/serialization/serialize-assets.js b/src/serialization/serialize-assets.js index ac444f11a..c1d063949 100644 --- a/src/serialization/serialize-assets.js +++ b/src/serialization/serialize-assets.js @@ -16,12 +16,10 @@ const serializeAssets = function (runtime, assetType, optTargetId) { const currAssets = currTarget.sprite[assetType]; for (let j = 0; j < currAssets.length; j++) { const currAsset = currAssets[j]; - const assetId = currAsset.assetId; - const storage = runtime.storage; - const storedAsset = storage.get(assetId); + const asset = currAsset.asset; assetDescs.push({ - fileName: `${assetId}.${storedAsset.dataFormat}`, - fileContent: storedAsset.data}); + fileName: `${asset.assetId}.${asset.dataFormat}`, + fileContent: asset.data}); } } return assetDescs; diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js index f02f41a0e..e922d4d89 100644 --- a/src/sprites/sprite.js +++ b/src/sprites/sprite.js @@ -146,14 +146,14 @@ class Sprite { newSprite.costumes = this.costumes_.map(costume => { const newCostume = Object.assign({}, costume); - const costumeAsset = this.runtime.storage.get(costume.assetId); + const costumeAsset = costume.asset; assetPromises.push(loadCostumeFromAsset(newCostume, costumeAsset, this.runtime)); return newCostume; }); newSprite.sounds = this.sounds.map(sound => { const newSound = Object.assign({}, sound); - const soundAsset = this.runtime.storage.get(sound.assetId); + const soundAsset = sound.asset; assetPromises.push(loadSoundFromAsset(newSound, soundAsset, this.runtime, newSprite)); return newSound; }); diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 43a5e34a9..96ab30411 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -690,11 +690,14 @@ class VirtualMachine extends EventEmitter { // is updated as below. sound.format = ''; const storage = this.runtime.storage; - sound.assetId = storage.builtinHelper.cache( + sound.asset = storage.createAsset( storage.AssetType.Sound, storage.DataFormat.WAV, - soundEncoding + soundEncoding, + null, + true // generate md5 ); + sound.assetId = sound.asset.assetId; sound.dataFormat = storage.DataFormat.WAV; sound.md5 = `${sound.assetId}.${sound.dataFormat}`; } @@ -731,16 +734,16 @@ class VirtualMachine extends EventEmitter { * a dataURI if it's a PNG or JPG, or null if it couldn't be found or decoded. */ getCostume (costumeIndex) { - const id = this.editingTarget.getCostumes()[costumeIndex].assetId; - if (!id || !this.runtime || !this.runtime.storage) return null; - const format = this.runtime.storage.get(id).dataFormat; + const asset = this.editingTarget.getCostumes()[costumeIndex].asset; + if (!asset || !this.runtime || !this.runtime.storage) return null; + const format = asset.dataFormat; if (format === this.runtime.storage.DataFormat.SVG) { - return this.runtime.storage.get(id).decodeText(); + return asset.decodeText(); } else if (format === this.runtime.storage.DataFormat.PNG || format === this.runtime.storage.DataFormat.JPG) { - return this.runtime.storage.get(id).encodeDataURI(); + return asset.encodeDataURI(); } - log.error(`Unhandled format: ${this.runtime.storage.get(id).dataFormat}`); + log.error(`Unhandled format: ${asset.dataFormat}`); return null; } @@ -781,14 +784,17 @@ class VirtualMachine extends EventEmitter { const reader = new FileReader(); reader.addEventListener('loadend', () => { const storage = this.runtime.storage; - costume.assetId = storage.builtinHelper.cache( - storage.AssetType.ImageBitmap, - storage.DataFormat.PNG, - Buffer.from(reader.result) - ); costume.dataFormat = storage.DataFormat.PNG; costume.bitmapResolution = bitmapResolution; costume.size = [bitmap.width, bitmap.height]; + costume.asset = storage.createAsset( + storage.AssetType.ImageBitmap, + costume.dataFormat, + Buffer.from(reader.result), + null, // id + true // generate md5 + ); + costume.assetId = costume.asset.assetId; costume.md5 = `${costume.assetId}.${costume.dataFormat}`; this.emitTargetsUpdate(); }); @@ -812,16 +818,19 @@ class VirtualMachine extends EventEmitter { costume.size = this.runtime.renderer.getSkinSize(costume.skinId); } const storage = this.runtime.storage; - costume.assetId = storage.builtinHelper.cache( - storage.AssetType.ImageVector, - storage.DataFormat.SVG, - (new TextEncoder()).encode(svg) - ); // If we're in here, we've edited an svg in the vector editor, // so the dataFormat should be 'svg' costume.dataFormat = storage.DataFormat.SVG; - costume.md5 = `${costume.assetId}.${costume.dataFormat}`; costume.bitmapResolution = 1; + costume.asset = storage.createAsset( + storage.AssetType.ImageVector, + costume.dataFormat, + (new TextEncoder()).encode(svg), + null, + true // generate md5 + ); + costume.assetId = costume.asset.assetId; + costume.md5 = `${costume.assetId}.${costume.dataFormat}`; this.emitTargetsUpdate(); } diff --git a/test/integration/offline-custom-assets.js b/test/integration/offline-custom-assets.js index 929500971..c67deb852 100644 --- a/test/integration/offline-custom-assets.js +++ b/test/integration/offline-custom-assets.js @@ -10,7 +10,6 @@ const test = require('tap').test; const AdmZip = require('adm-zip'); const ScratchStorage = require('scratch-storage'); const VirtualMachine = require('../../src/index'); -const StringUtil = require('../../src/util/string-util'); const projectUri = path.resolve(__dirname, '../fixtures/offline-custom-assets.sb2'); const projectZip = AdmZip(projectUri); @@ -52,11 +51,8 @@ test('offline-custom-assets', t => { t.equals(costumes.length, 1); const customCostume = costumes[0]; t.equals(customCostume.name, 'A_Test_Costume'); - const costumeMd5Ext = customCostume.md5; - const costumeIdParts = StringUtil.splitFirst(costumeMd5Ext, '.'); - const costumeMd5 = costumeIdParts[0]; - const storedCostume = vm.runtime.storage.get(costumeMd5); + const storedCostume = customCostume.asset; t.type(storedCostume, 'object'); t.deepEquals(storedCostume.data, costumeData); @@ -64,10 +60,7 @@ test('offline-custom-assets', t => { t.equals(sounds.length, 1); const customSound = sounds[0]; t.equals(customSound.name, 'A_Test_Recording'); - const soundMd5Ext = customSound.md5; - const soundIdParts = StringUtil.splitFirst(soundMd5Ext, '.'); - const soundMd5 = soundIdParts[0]; - const storedSound = vm.runtime.storage.get(soundMd5); + const storedSound = customSound.asset; t.type(storedSound, 'object'); t.deepEquals(storedSound.data, soundData);